diff options
author | peter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2005-10-20 19:20:38 +0000 |
---|---|---|
committer | peter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2005-10-20 19:20:38 +0000 |
commit | 5ed980d600661e3e77f429a510f093f4a001dee9 (patch) | |
tree | 40d655e7921c1019d039da654a9df550de3cd249 /compiler/sparc/rgcpu.pas | |
parent | 907c764cb881dab769452696fc5e6bee076c2656 (diff) | |
download | fpc-unitrw.tar.gz |
* retag for unitrwunitrw
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/unitrw@1551 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/sparc/rgcpu.pas')
-rw-r--r-- | compiler/sparc/rgcpu.pas | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/compiler/sparc/rgcpu.pas b/compiler/sparc/rgcpu.pas new file mode 100644 index 0000000000..943158fffb --- /dev/null +++ b/compiler/sparc/rgcpu.pas @@ -0,0 +1,163 @@ +{ + Copyright (c) 1998-2002 by Florian Klaempfl + + This unit implements the SPARC specific class for the register + allocator + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ****************************************************************************} +unit rgcpu; + +{$i fpcdefs.inc} + + interface + + uses + aasmbase,aasmcpu,aasmtai, + cgbase,cgutils, + cpubase, + rgobj; + + type + trgcpu=class(trgobj) + procedure add_constraints(reg:tregister);override; + function get_spill_subreg(r : tregister) : tsubregister;override; + procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override; + procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override; + end; + + +implementation + + uses + verbose,cutils, + cgobj; + + procedure trgcpu.add_constraints(reg:tregister); + var + supreg,i : Tsuperregister; + begin + case getsubreg(reg) of + { Let 64bit floats conflict with all odd float regs } + R_SUBFD: + begin + supreg:=getsupreg(reg); + i:=RS_F1; + while (i<=RS_F31) do + begin + add_edge(supreg,i); + inc(i,2); + end; + end; + { Let 64bit ints conflict with all odd int regs } + R_SUBQ: + begin + supreg:=getsupreg(reg); + i:=RS_G1; + while (i<=RS_I7) do + begin + add_edge(supreg,i); + inc(i,2); + end; + end; + end; + end; + + + function trgcpu.get_spill_subreg(r : tregister) : tsubregister; + begin + if getregtype(r)=R_FPUREGISTER then + result:=getsubreg(r) + else + result:=defaultsub; + end; + + + procedure trgcpu.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister); + var + helpins : tai; + tmpref : treference; + helplist : taasmoutput; + hreg : tregister; + begin + if abs(spilltemp.offset)>4095 then + begin + helplist:=taasmoutput.create; + + if getregtype(tempreg)=R_INTREGISTER then + hreg:=tempreg + else + hreg:=cg.getintregister(helplist,OS_ADDR); + + reference_reset(tmpref); + tmpref.offset:=spilltemp.offset; + tmpref.refaddr:=addr_hi; + helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg)); + + tmpref.refaddr:=addr_lo; + helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg)); + + reference_reset_base(tmpref,hreg,0); + tmpref.index:=spilltemp.base; + + helpins:=spilling_create_load(tmpref,tempreg); + helplist.concat(helpins); + list.insertlistafter(pos,helplist) + end + else + inherited do_spill_read(list,pos,spilltemp,tempreg); + end; + + + procedure trgcpu.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister); + var + helpins : tai; + tmpref : treference; + helplist : taasmoutput; + hreg : tregister; + begin + if abs(spilltemp.offset)>4095 then + begin + helplist:=taasmoutput.create; + + if getregtype(tempreg)=R_INTREGISTER then + hreg:=getregisterinline(helplist,R_SUBWHOLE) + else + hreg:=cg.getintregister(helplist,OS_ADDR); + + reference_reset(tmpref); + tmpref.offset:=spilltemp.offset; + tmpref.refaddr:=addr_hi; + helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg)); + + tmpref.refaddr:=addr_lo; + helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg)); + + reference_reset_base(tmpref,hreg,0); + tmpref.index:=spilltemp.base; + + helpins:=spilling_create_store(tempreg,tmpref); + helplist.concat(helpins); + if getregtype(tempreg)=R_INTREGISTER then + ungetregisterinline(helplist,hreg); + + list.insertlistafter(pos,helplist) + end + else + inherited do_spill_written(list,pos,spilltemp,tempreg); + end; + +end. |