1 { 2 Copyright (c) 1998-2008 by Florian Klaempfl 3 4 This unit implements the avr 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,aasmsym, 32 cgbase,cgutils, 33 cpubase, 34 rgobj; 35 36 type 37 trgcpu = class(trgobj) 38 procedure add_constraints(reg:tregister);override; 39 procedure do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); override; 40 procedure do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); override; do_spill_replacenull41 function do_spill_replace(list : TAsmList;instr : tai_cpu_abstract_sym; orgreg : tsuperregister;const spilltemp : treference) : boolean; override; 42 end; 43 44 trgintcpu = class(trgcpu) 45 procedure add_cpu_interferences(p : tai);override; 46 end; 47 48 implementation 49 50 uses 51 verbose, cutils, 52 cgobj, 53 procinfo; 54 55 56 procedure trgcpu.add_constraints(reg:tregister); 57 var 58 supreg,i : Tsuperregister; 59 begin 60 case getsubreg(reg) of 61 { Let 64bit floats conflict with all odd float regs } 62 R_SUBFD: 63 begin 64 { 65 supreg:=getsupreg(reg); 66 i:=RS_F1; 67 while (i<=RS_F31) do 68 begin 69 add_edge(supreg,i); 70 inc(i,2); 71 end; 72 } 73 end; 74 { Let 64bit ints conflict with all odd int regs } 75 R_SUBQ: 76 begin 77 supreg:=getsupreg(reg); 78 { 79 i:=RS_G1; 80 while (i<=RS_I7) do 81 begin 82 add_edge(supreg,i); 83 inc(i,2); 84 end; 85 } 86 end; 87 end; 88 end; 89 90 91 procedure trgcpu.do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); 92 var 93 helpins : tai; 94 tmpref : treference; 95 helplist : TAsmList; 96 hreg : tregister; 97 begin 98 if abs(spilltemp.offset)>63 then 99 begin 100 helplist:=TAsmList.create; 101 102 helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset)))); 103 helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset)))); 104 helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base)); 105 helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,cg.GetNextReg(spilltemp.base))); 106 107 reference_reset_base(tmpref,NR_R26,0,spilltemp.temppos,1,[]); 108 helpins:=spilling_create_load(tmpref,tempreg); 109 helplist.concat(helpins); 110 list.insertlistafter(pos,helplist); 111 helplist.free; 112 end 113 else 114 inherited; 115 end; 116 117 118 procedure trgcpu.do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); 119 var 120 tmpref : treference; 121 helplist : TAsmList; 122 hreg : tregister; 123 begin 124 if abs(spilltemp.offset)>63 then 125 begin 126 helplist:=TAsmList.create; 127 128 helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset)))); 129 helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset)))); 130 helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base)); 131 helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,cg.GetNextReg(spilltemp.base))); 132 133 reference_reset_base(tmpref,NR_R26,0,spilltemp.temppos,1,[]); 134 helplist.concat(spilling_create_store(tempreg,tmpref)); 135 list.insertlistafter(pos,helplist); 136 helplist.free; 137 end 138 else 139 inherited; 140 end; 141 142 143 procedure trgintcpu.add_cpu_interferences(p : tai); 144 var 145 r : tsuperregister; 146 begin 147 if p.typ=ait_instruction then 148 begin 149 case taicpu(p).opcode of 150 A_CPI, 151 A_ANDI, 152 A_ORI, 153 A_SUBI, 154 A_SBCI, 155 A_LDI: 156 for r:=RS_R0 to RS_R15 do 157 add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg)); 158 A_MULS: 159 begin 160 for r:=RS_R0 to RS_R15 do 161 add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg)); 162 for r:=RS_R0 to RS_R15 do 163 add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg)); 164 end; 165 end; 166 end; 167 end; 168 169 trgcpu.do_spill_replacenull170 function trgcpu.do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference):boolean; 171 var 172 b : byte; 173 begin 174 result:=false; 175 if not(spilltemp.offset in [0..63]) then 176 exit; 177 178 { Replace 'mov dst,orgreg' with 'ld dst,spilltemp' 179 and 'mov orgreg,src' with 'st dst,spilltemp' } 180 with instr do 181 begin 182 if (opcode=A_MOV) and (ops=2) and (oper[1]^.typ=top_reg) and (oper[0]^.typ=top_reg) then 183 begin 184 if (getregtype(oper[0]^.reg)=regtype) and 185 (get_alias(getsupreg(oper[0]^.reg))=orgreg) and 186 (get_alias(getsupreg(oper[1]^.reg))<>orgreg) then 187 begin 188 { str expects the register in oper[0] } 189 instr.loadreg(0,oper[1]^.reg); 190 instr.loadref(1,spilltemp); 191 opcode:=A_ST; 192 result:=true; 193 end 194 else if (getregtype(oper[1]^.reg)=regtype) and 195 (get_alias(getsupreg(oper[1]^.reg))=orgreg) and 196 (get_alias(getsupreg(oper[0]^.reg))<>orgreg) then 197 begin 198 instr.loadref(1,spilltemp); 199 opcode:=A_LD; 200 result:=true; 201 end; 202 end; 203 end; 204 end; 205 206 end. 207