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