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