1 { 2 Copyright (c) 1998-2002 by Florian Klaempfl 3 4 This unit implements the powerpc specific class for the register 5 allocator 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 21 **************************************************************************** 22 } 23 24 unit rgcpu; 25 26 {$i fpcdefs.inc} 27 28 interface 29 30 uses 31 aasmbase,aasmtai,aasmdata,aasmcpu, 32 cgbase,cgutils, 33 cpubase, 34 rgobj; 35 36 type 37 trgcpu = class(trgobj) 38 procedure do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); override; 39 procedure do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); override; 40 end; 41 42 trgintcpu = class(trgcpu) 43 {$ifdef user0} 44 procedure add_cpu_interferences(p : tai);override; 45 {$endif user0} 46 end; 47 48 implementation 49 50 uses 51 verbose, cutils,globtype, 52 cgobj, 53 procinfo; 54 55 56 procedure trgcpu.do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); 57 var 58 tmpref : treference; 59 helplist : TAsmList; 60 hreg : tregister; 61 ins : Taicpu; 62 begin 63 if (spilltemp.offset<low(smallint)) or 64 (spilltemp.offset>high(smallint)) then 65 begin 66 helplist:=TAsmList.create; 67 68 if (spilltemp.index<>NR_NO) then 69 internalerror(200704201); 70 71 if getregtype(tempreg)=R_INTREGISTER then 72 begin 73 hreg:=getregisterinline(helplist,[R_SUBWHOLE]); 74 {Done by add_cpu_interferences now. 75 add_edge(getsupreg(hreg),RS_R0);} 76 end 77 else 78 hreg:=cg.getintregister(helplist,OS_ADDR); 79 80 reference_reset(tmpref,sizeof(aint),[]); 81 tmpref.offset:=spilltemp.offset; 82 tmpref.refaddr := addr_higha; 83 ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref); 84 add_cpu_interferences(ins); 85 helplist.concat(ins); 86 tmpref:=spilltemp; 87 tmpref.refaddr := addr_low; 88 tmpref.base:=hreg; 89 90 ins:=spilling_create_load(tmpref,tempreg); 91 add_cpu_interferences(ins); 92 93 94 helplist.concat(ins); 95 96 if getregtype(tempreg)=R_INTREGISTER then 97 ungetregisterinline(helplist,hreg); 98 99 list.insertlistafter(pos,helplist); 100 helplist.free; 101 end 102 else 103 inherited; 104 end; 105 106 107 procedure trgcpu.do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); 108 var 109 tmpref : treference; 110 helplist : TAsmList; 111 hreg : tregister; 112 ins : Taicpu; 113 begin 114 if (spilltemp.offset<low(smallint)) or 115 (spilltemp.offset>high(smallint)) then 116 begin 117 helplist:=TAsmList.create; 118 119 if (spilltemp.index<>NR_NO) then 120 internalerror(200704201); 121 122 if getregtype(tempreg)=R_INTREGISTER then 123 begin 124 hreg:=getregisterinline(helplist,[R_SUBWHOLE]); 125 {Done by add_cpu_interferences now. 126 add_edge(getsupreg(hreg),RS_R0);} 127 end 128 else 129 hreg:=cg.getintregister(helplist,OS_ADDR); 130 reference_reset(tmpref,sizeof(aint),[]); 131 tmpref.offset:=spilltemp.offset; 132 tmpref.refaddr := addr_higha; 133 ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref); 134 add_cpu_interferences(ins); 135 helplist.concat(ins); 136 tmpref:=spilltemp; 137 tmpref.refaddr := addr_low; 138 tmpref.base:=hreg; 139 ins:=spilling_create_store(tempreg,tmpref); 140 add_cpu_interferences(ins); 141 helplist.concat(ins); 142 143 if getregtype(tempreg)=R_INTREGISTER then 144 ungetregisterinline(helplist,hreg); 145 146 list.insertlistafter(pos,helplist); 147 helplist.free; 148 end 149 else 150 inherited; 151 end; 152 153 {$ifdef user0} 154 procedure trgintcpu.add_cpu_interferences(p : tai); 155 var 156 r : tregister; 157 begin 158 if p.typ=ait_instruction then 159 begin 160 case taicpu(p).opcode of 161 A_ADDI, A_ADDIS, 162 A_STB, A_LBZ, A_STBX, A_LBZX, A_STH, A_LHZ, A_STHX, A_LHZX, A_LHA, A_LHAX, 163 A_STW, A_LWZ, A_STWX, A_LWZX, 164 A_STFS, A_LFS, A_STFSX, A_LFSX, A_STFD, A_LFD, A_STFDX, A_LFDX, A_STFIWX, 165 A_STHBRX, A_LHBRX, A_STWBRX, A_LWBRX, A_STWCX_, A_LWARX, 166 A_ECIWX, A_ECOWX, 167 A_LMW, A_STMW,A_LSWI,A_LSWX,A_STSWI,A_STSWX 168 {$ifdef cpu64bitalu} 169 , A_STD, A_STDX, 170 A_LD, A_LDX, 171 A_LWA, A_LWAX, 172 A_STDCX_,A_LDARX 173 {$endif cpu64bitalu} 174 : 175 begin 176 case taicpu(p).oper[1]^.typ of 177 top_reg: 178 add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R0); 179 top_ref: 180 if (taicpu(p).oper[1]^.ref^.base <> NR_NO) then 181 add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0); 182 end; 183 end; 184 A_DCBA, A_DCBI, A_DCBST, A_DCBT, A_DCBTST, A_DCBZ, A_DCBF, A_ICBI: 185 begin 186 case taicpu(p).oper[0]^.typ of 187 top_reg: 188 add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R0); 189 top_ref: 190 if (taicpu(p).oper[0]^.ref^.base <> NR_NO) then 191 add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0); 192 end; 193 end; 194 end; 195 end; 196 end; 197 {$endif user0} 198 199 200 end. 201