~ubuntu-branches/ubuntu/dapper/fpc/dapper

« back to all changes in this revision

Viewing changes to compiler/arm/rgcpu.pas

  • Committer: Bazaar Package Importer
  • Author(s): Carlos Laviola
  • Date: 2005-05-30 11:59:10 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050530115910-x5pbzm4qqta4i94h
Tags: 2.0.0-2
debian/fp-compiler.postinst.in: forgot to reapply the patch that
correctly creates the slave link to pc(1).  (Closes: #310907)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
{
2
 
    $Id: rgcpu.pas,v 1.10 2004/03/14 16:15:40 florian Exp $
 
2
    $Id: rgcpu.pas,v 1.17 2005/02/14 17:13:09 peter Exp $
3
3
    Copyright (c) 1998-2003 by Florian Klaempfl
4
4
 
5
5
    This unit implements the arm specific class for the register
29
29
  interface
30
30
 
31
31
     uses
32
 
       aasmbase,aasmtai,
33
 
       cgbase,
 
32
       aasmbase,aasmtai,aasmcpu,
 
33
       cgbase,cgutils,
34
34
       cpubase,
35
35
       rgobj;
36
36
 
37
37
     type
38
38
       trgcpu = class(trgobj)
 
39
         procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
 
40
         procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
 
41
       end;
 
42
 
 
43
       trgintcpu = class(trgcpu)
39
44
         procedure add_cpu_interferences(p : tai);override;
40
 
         procedure do_spill_read(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
41
 
          const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
42
 
         procedure do_spill_written(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
43
 
          const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
44
 
         procedure do_spill_readwritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
45
 
          const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
46
45
       end;
47
46
 
48
47
  implementation
49
48
 
50
49
    uses
51
50
      verbose, cutils,
52
 
      cgutils,cgobj,
53
 
      procinfo,
54
 
      aasmcpu;
55
 
 
56
 
 
57
 
    procedure trgcpu.add_cpu_interferences(p : tai);
58
 
      begin
59
 
        if p.typ=ait_instruction then
60
 
          begin
61
 
            if (taicpu(p).opcode=A_MUL) then
62
 
              add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
63
 
          end;
64
 
      end;
65
 
 
66
 
 
67
 
    procedure trgcpu.do_spill_read(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
68
 
     const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
 
51
      cgobj,
 
52
      procinfo;
 
53
 
 
54
 
 
55
    procedure trgcpu.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
69
56
      var
70
57
        helpins: tai;
71
 
        tmpref,ref : treference;
 
58
        tmpref : treference;
72
59
        helplist : taasmoutput;
73
60
        l : tasmlabel;
74
 
        tmpreg : tregister;
 
61
        hreg : tregister;
75
62
      begin
76
 
        ref:=spilltemplist[regs[regidx].orgreg];
77
 
        if abs(ref.offset)>4095 then
 
63
        if abs(spilltemp.offset)>4095 then
78
64
          begin
79
65
            helplist:=taasmoutput.create;
80
66
            reference_reset(tmpref);
83
69
            cg.a_label(current_procinfo.aktlocaldata,l);
84
70
            tmpref.symboldata:=current_procinfo.aktlocaldata.last;
85
71
 
86
 
            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
 
72
            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(spilltemp.offset));
87
73
 
88
74
            { load consts entry }
89
 
            getregisterinline(helplist,nil,defaultsub,tmpreg);
 
75
            if getregtype(tempreg)=R_INTREGISTER then
 
76
              hreg:=getregisterinline(helplist,R_SUBWHOLE)
 
77
            else
 
78
              hreg:=cg.getintregister(helplist,OS_ADDR);
 
79
 
90
80
            tmpref.symbol:=l;
91
81
            tmpref.base:=NR_R15;
92
 
            helplist.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
93
 
 
94
 
            if ref.index<>NR_NO then
 
82
            helplist.concat(taicpu.op_reg_ref(A_LDR,hreg,tmpref));
 
83
 
 
84
            reference_reset_base(tmpref,hreg,0);
 
85
 
 
86
            if spilltemp.index<>NR_NO then
95
87
              internalerror(200401263);
96
 
            ref.index:=tmpreg;
97
 
            ref.offset:=0;
98
88
 
99
 
            helpins:=taicpu.op_reg_ref(A_LDR,regs[regidx].tempreg,ref);
 
89
            helpins:=spilling_create_load(tmpref,tempreg);
100
90
            helplist.concat(helpins);
101
91
            if pos=nil then
102
92
              list.insertlistafter(list.first,helplist)
103
93
            else
104
94
              list.insertlistafter(pos.next,helplist);
105
95
 
106
 
            ungetregisterinline(helplist,tai(helplist.last),regs[regidx].tempreg);
107
 
 
108
 
            ungetregisterinline(list,instr,regs[regidx].tempreg);
109
 
            forward_allocation(tai(helpins.next),instr);
110
 
 
111
96
            helplist.free;
112
97
          end
113
98
        else
114
 
          begin
115
 
            helpins:=taicpu.op_reg_ref(A_LDR,regs[regidx].tempreg,ref);
116
 
            if pos=nil then
117
 
              list.insertafter(helpins,list.first)
118
 
            else
119
 
              list.insertafter(helpins,pos.next);
120
 
            ungetregisterinline(list,instr,regs[regidx].tempreg);
121
 
            forward_allocation(tai(helpins.next),instr);
122
 
          end;
 
99
          inherited do_spill_read(list,pos,spilltemp,tempreg);
123
100
      end;
124
101
 
125
102
 
126
 
    procedure trgcpu.do_spill_written(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
127
 
      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
 
103
    procedure trgcpu.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
128
104
      var
129
105
        helpins: tai;
130
 
        ref,tmpref : treference;
 
106
        tmpref : treference;
131
107
        helplist : taasmoutput;
132
108
        l : tasmlabel;
133
 
        tmpreg : tregister;
 
109
        hreg : tregister;
134
110
      begin
135
 
        ref:=spilltemplist[regs[regidx].orgreg];
136
 
        if abs(ref.offset)>4095 then
 
111
        if abs(spilltemp.offset)>4095 then
137
112
          begin
138
113
            helplist:=taasmoutput.create;
139
114
            reference_reset(tmpref);
142
117
            cg.a_label(current_procinfo.aktlocaldata,l);
143
118
            tmpref.symboldata:=current_procinfo.aktlocaldata.last;
144
119
 
145
 
            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
 
120
            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(spilltemp.offset));
146
121
 
147
122
            { load consts entry }
148
 
            getregisterinline(helplist,nil,defaultsub,tmpreg);
 
123
            if getregtype(tempreg)=R_INTREGISTER then
 
124
              hreg:=getregisterinline(helplist,R_SUBWHOLE)
 
125
            else
 
126
              hreg:=cg.getintregister(helplist,OS_ADDR);
149
127
            tmpref.symbol:=l;
150
128
            tmpref.base:=NR_R15;
151
 
            helplist.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
 
129
            helplist.concat(taicpu.op_reg_ref(A_LDR,hreg,tmpref));
152
130
 
153
 
            if ref.index<>NR_NO then
 
131
            if spilltemp.index<>NR_NO then
154
132
              internalerror(200401263);
155
 
            ref.index:=tmpreg;
156
 
            ref.offset:=0;
157
 
 
158
 
            helplist.concat(taicpu.op_reg_ref(A_STR,regs[regidx].tempreg,ref));
159
 
            ungetregisterinline(helplist,tai(helplist.last),regs[regidx].tempreg);
160
 
            ungetregisterinline(helplist,tai(helplist.last),tmpreg);
161
 
 
162
 
            list.insertlistafter(instr,helplist);
163
 
 
164
 
            helplist.free;
 
133
 
 
134
            reference_reset_base(tmpref,hreg,0);
 
135
 
 
136
            helplist.concat(spilling_create_store(tempreg,tmpref));
 
137
 
 
138
            if getregtype(tempreg)=R_INTREGISTER then
 
139
              ungetregisterinline(helplist,hreg);
 
140
 
 
141
            list.insertlistafter(pos,helplist)
165
142
          end
166
143
        else
167
 
          begin
168
 
            helpins:=taicpu.op_reg_ref(A_STR,regs[regidx].tempreg,ref);
169
 
            list.insertafter(helpins,instr);
170
 
            ungetregisterinline(list,helpins,regs[regidx].tempreg);
171
 
          end;
 
144
          inherited do_spill_written(list,pos,spilltemp,tempreg);
172
145
      end;
173
146
 
174
147
 
175
 
    procedure trgcpu.do_spill_readwritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: word;
176
 
      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
177
 
      var
178
 
        helpins1, helpins2: tai;
179
 
        tmpref,ref : treference;
180
 
        tmpreg : tregister;
181
 
 
 
148
    procedure trgintcpu.add_cpu_interferences(p : tai);
182
149
      begin
183
 
        ref:=spilltemplist[regs[regidx].orgreg];
184
 
        internalerror(200403141);
185
 
        {
186
 
        if abs(ref.offset)>4095 then
 
150
        if p.typ=ait_instruction then
187
151
          begin
188
 
            reference_reset(tmpref);
189
 
            { create consts entry }
190
 
            objectlibrary.getlabel(l);
191
 
            cg.a_label(current_procinfo.aktlocaldata,l);
192
 
            tmpref.symboldata:=current_procinfo.aktlocaldata.last;
193
 
 
194
 
            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
195
 
 
196
 
            { load consts entry }
197
 
            getregisterinline(list,pos,defaultsub,tmpreg);
198
 
            tmpref.symbol:=l;
199
 
            tmpref.base:=NR_R15;
200
 
            list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
201
 
 
202
 
            if ref.index<>NR_NO then
203
 
              internalerror(200401263);
204
 
            ref.index:=tmpreg;
205
 
            ref.offset:=0;
 
152
            case taicpu(p).opcode of
 
153
              A_MUL:
 
154
                add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
 
155
              A_UMULL,
 
156
              A_UMLAL,
 
157
              A_SMULL,
 
158
              A_SMLAL:
 
159
                begin
 
160
                  add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
 
161
                  add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(taicpu(p).oper[2]^.reg));
 
162
                  add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[2]^.reg));
 
163
                end;
 
164
            end;
206
165
          end;
207
 
        }
208
 
        helpins1:=taicpu.op_reg_ref(A_LDR,regs[regidx].tempreg,ref);
209
 
        if pos=nil then
210
 
          list.insertafter(helpins1,list.first)
211
 
        else
212
 
          list.insertafter(helpins1,pos.next);
213
 
        ref:=spilltemplist[regs[regidx].orgreg];
214
 
        ref.symboldata:=nil;
215
 
        helpins2:=taicpu.op_reg_ref(A_STR,regs[regidx].tempreg,ref);
216
 
        list.insertafter(helpins2,instr);
217
 
        ungetregisterinline(list,helpins2,regs[regidx].tempreg);
218
 
        forward_allocation(tai(helpins1.next),instr);
219
166
      end;
220
167
 
 
168
 
221
169
end.
222
170
 
223
171
{
224
172
  $Log: rgcpu.pas,v $
225
 
  Revision 1.10  2004/03/14 16:15:40  florian
226
 
    * spilling problem fixed
227
 
    * handling of floating point memory references fixed
228
 
 
229
 
  Revision 1.9  2004/03/06 20:35:20  florian
230
 
    * fixed arm compilation
231
 
    * cleaned up code generation for exported linux procedures
232
 
 
233
 
  Revision 1.8  2004/02/08 23:06:59  florian
234
 
    * fixed compilation problem
235
 
 
236
 
  Revision 1.7  2004/01/28 15:36:47  florian
237
 
    * fixed another couple of arm bugs
238
 
 
239
 
  Revision 1.6  2004/01/26 19:05:56  florian
240
 
    * fixed several arm issues
241
 
 
242
 
  Revision 1.5  2003/11/02 14:30:03  florian
243
 
    * fixed ARM for new reg. allocation scheme
244
 
 
245
 
  Revision 1.4  2003/09/11 11:55:00  florian
246
 
    * improved arm code generation
247
 
    * move some protected and private field around
248
 
    * the temp. register for register parameters/arguments are now released
249
 
      before the move to the parameter register is done. This improves
250
 
      the code in a lot of cases.
251
 
 
252
 
  Revision 1.3  2003/09/04 00:15:29  florian
253
 
    * first bunch of adaptions of arm compiler for new register type
254
 
 
255
 
  Revision 1.2  2003/08/25 23:20:38  florian
256
 
    + started to implement FPU support for the ARM
257
 
    * fixed a lot of other things
258
 
 
259
 
  Revision 1.1  2003/08/16 13:23:01  florian
260
 
    * several arm related stuff fixed
 
173
  Revision 1.17  2005/02/14 17:13:09  peter
 
174
    * truncate log
 
175
 
 
176
  Revision 1.16  2005/02/13 18:55:19  florian
 
177
    + overflow checking for the arm
 
178
 
261
179
}