1 { 2 Copyright (c) 1998-2002 by Florian Klaempfl 3 4 This unit implements the i386 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 cpubase, 32 cpuinfo, 33 aasmbase,aasmtai,aasmsym,aasmdata,aasmcpu, 34 cclasses,globtype,cgbase,cgutils,rgobj,rgx86; 35 36 type 37 38 { trgcpu } 39 40 trgcpu = class(trgx86) do_spill_replacenull41 function do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference):boolean;override; 42 procedure add_constraints(reg:Tregister);override; 43 end; 44 45 trgintcpu = class(trgcpu) 46 procedure add_cpu_interferences(p : tai);override; 47 end; 48 49 50 implementation 51 52 uses 53 systems, 54 verbose; 55 56 const 57 { This value is used in tsaved. If the array value is equal 58 to this, then this means that this register is not used.} 59 reg_not_saved = $7fffffff; 60 61 {************************************************************************ 62 trgcpu 63 *************************************************************************} 64 trgcpu.do_spill_replacenull65 function trgcpu.do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference): boolean; 66 var 67 spilltemp2: treference; 68 begin 69 spilltemp2:=spilltemp; 70 if spilltemp2.segment=NR_SS then 71 spilltemp2.segment:=NR_NO; 72 Result:=inherited do_spill_replace(list, instr, orgreg, spilltemp2); 73 end; 74 75 76 procedure trgcpu.add_constraints(reg:Tregister); 77 var 78 supreg : tsuperregister; 79 begin 80 if getsubreg(reg) in [R_SUBL,R_SUBH] then 81 begin 82 { Some registers have no 8-bit subregister } 83 supreg:=getsupreg(reg); 84 add_edge(supreg,RS_SI); 85 add_edge(supreg,RS_DI); 86 add_edge(supreg,RS_BP); 87 end; 88 end; 89 90 91 procedure trgintcpu.add_cpu_interferences(p : tai); 92 var 93 href : treference; 94 i : integer; 95 begin 96 if p.typ=ait_instruction then 97 begin 98 for i:=0 to taicpu(p).ops-1 do 99 begin 100 if taicpu(p).oper[i]^.typ=top_ref then 101 begin 102 href:=taicpu(p).oper[i]^.ref^; 103 { in case there's exactly one register used, we can treat it 104 as either base or index and choose it from the larger set 105 of registers [BX, BP, SI, DI] } 106 if (href.base<>NR_NO) xor (href.index<>NR_NO) then 107 begin 108 if (href.base<>NR_NO) and (getsupreg(href.base)>=first_int_imreg) then 109 begin 110 add_edge(getsupreg(href.base),RS_AX); 111 add_edge(getsupreg(href.base),RS_CX); 112 add_edge(getsupreg(href.base),RS_DX); 113 end; 114 if (href.index<>NR_NO) and (getsupreg(href.index)>=first_int_imreg) then 115 begin 116 add_edge(getsupreg(href.index),RS_AX); 117 add_edge(getsupreg(href.index),RS_CX); 118 add_edge(getsupreg(href.index),RS_DX); 119 end; 120 end 121 else 122 begin 123 { base is chosen from the set [BX, BP] } 124 if (href.base<>NR_NO) and (getsupreg(href.base)>=first_int_imreg) then 125 begin 126 add_edge(getsupreg(href.base),RS_AX); 127 add_edge(getsupreg(href.base),RS_CX); 128 add_edge(getsupreg(href.base),RS_DX); 129 add_edge(getsupreg(href.base),RS_SI); 130 add_edge(getsupreg(href.base),RS_DI); 131 end; 132 { index is chosen from the set [SI, DI] } 133 if (href.index<>NR_NO) and (getsupreg(href.index)>=first_int_imreg) then 134 begin 135 add_edge(getsupreg(href.index),RS_AX); 136 add_edge(getsupreg(href.index),RS_BX); 137 add_edge(getsupreg(href.index),RS_CX); 138 add_edge(getsupreg(href.index),RS_DX); 139 add_edge(getsupreg(href.index),RS_BP); 140 end; 141 end; 142 end; 143 end; 144 end; 145 end; 146 147 end. 148