~ubuntu-branches/debian/lenny/fpc/lenny

« back to all changes in this revision

Viewing changes to fpcsrc/compiler/x86/agx86att.pas

  • Committer: Bazaar Package Importer
  • Author(s): Mazen Neifer, Torsten Werner, Mazen Neifer
  • Date: 2008-05-17 17:12:11 UTC
  • mfrom: (3.1.9 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080517171211-9qi33xhd9evfa0kg
Tags: 2.2.0-dfsg1-9
[ Torsten Werner ]
* Add Mazen Neifer to Uploaders field.

[ Mazen Neifer ]
* Moved FPC sources into a version dependent directory from /usr/share/fpcsrc
  to /usr/share/fpcsrc/${FPCVERSION}. This allow installing more than on FPC
  release.
* Fixed far call issue in compiler preventing building huge binearies.
  (closes: #477743)
* Updated building dependencies, recomennded and suggested packages.
* Moved fppkg to fp-utils as it is just a helper tool and is not required by
  compiler.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{
 
2
    Copyright (c) 1998-2002 by Florian Klaempfl
 
3
 
 
4
    This unit implements an asmoutput class for i386 AT&T syntax
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
 ****************************************************************************
 
21
}
 
22
{ This unit implements an asmoutput class for i386 AT&T syntax
 
23
}
 
24
unit agx86att;
 
25
 
 
26
{$i fpcdefs.inc}
 
27
 
 
28
interface
 
29
 
 
30
    uses
 
31
      cclasses,cpubase,
 
32
      globals,cgutils,
 
33
      aasmbase,aasmtai,aasmdata,assemble,aggas;
 
34
 
 
35
    type
 
36
      Tx86ATTAssembler=class(TGNUassembler)
 
37
        constructor create(smart: boolean); override;
 
38
      end;
 
39
 
 
40
      Tx86AppleGNUAssembler=class(TAppleGNUassembler)
 
41
        constructor create(smart: boolean); override;
 
42
      end;
 
43
 
 
44
 
 
45
     Tx86InstrWriter=class(TCPUInstrWriter)
 
46
       private
 
47
        procedure WriteReference(var ref : treference);
 
48
        procedure WriteOper(const o:toper);
 
49
        procedure WriteOper_jmp(const o:toper);
 
50
       public
 
51
        procedure WriteInstruction(hp: tai);override;
 
52
     end;
 
53
 
 
54
      
 
55
 
 
56
  implementation
 
57
 
 
58
    uses
 
59
      cutils,systems,
 
60
      verbose,
 
61
      itcpugas,
 
62
      cgbase,
 
63
      aasmcpu;
 
64
 
 
65
 
 
66
{****************************************************************************
 
67
                            Tx86ATTAssembler
 
68
 ****************************************************************************}
 
69
 
 
70
    constructor Tx86ATTAssembler.create(smart: boolean);
 
71
      begin
 
72
        inherited create(smart);
 
73
        InstrWriter := Tx86InstrWriter.create(self);
 
74
      end;
 
75
 
 
76
{****************************************************************************
 
77
                          Tx86AppleGNUAssembler
 
78
 ****************************************************************************}
 
79
 
 
80
    constructor Tx86AppleGNUAssembler.create(smart: boolean);
 
81
      begin
 
82
        inherited create(smart);
 
83
        InstrWriter := Tx86InstrWriter.create(self);
 
84
      end;
 
85
 
 
86
{****************************************************************************
 
87
                            Tx86InstrWriter
 
88
 ****************************************************************************}
 
89
 
 
90
    procedure Tx86InstrWriter.WriteReference(var ref : treference);
 
91
      begin
 
92
        with ref do
 
93
         begin
 
94
           { do we have a segment prefix ? }
 
95
           { These are probably not correctly handled under GAS }
 
96
           { should be replaced by coding the segment override  }
 
97
           { directly! - DJGPP FAQ                              }
 
98
           if segment<>NR_NO then
 
99
             owner.AsmWrite(gas_regname(segment)+':');
 
100
           if assigned(symbol) then
 
101
             owner.AsmWrite(symbol.name);
 
102
           if ref.refaddr=addr_pic then
 
103
{$ifdef x86_64}
 
104
             owner.AsmWrite('@GOTPCREL');
 
105
{$else x86_64}
 
106
             owner.AsmWrite('@GOT');
 
107
{$endif x86_64}
 
108
           if offset<0 then
 
109
             owner.AsmWrite(tostr(offset))
 
110
           else
 
111
            if (offset>0) then
 
112
             begin
 
113
               if assigned(symbol) then
 
114
                owner.AsmWrite('+'+tostr(offset))
 
115
               else
 
116
                owner.AsmWrite(tostr(offset));
 
117
             end
 
118
           else if (index=NR_NO) and (base=NR_NO) and (not assigned(symbol)) then
 
119
             owner.AsmWrite('0');
 
120
           if (index<>NR_NO) and (base=NR_NO) then
 
121
            begin
 
122
              owner.AsmWrite('(,'+gas_regname(index));
 
123
              if scalefactor<>0 then
 
124
               owner.AsmWrite(','+tostr(scalefactor)+')')
 
125
              else
 
126
               owner.AsmWrite(')');
 
127
            end
 
128
           else
 
129
            if (index=NR_NO) and (base<>NR_NO) then
 
130
              owner.AsmWrite('('+gas_regname(base)+')')
 
131
            else
 
132
             if (index<>NR_NO) and (base<>NR_NO) then
 
133
              begin
 
134
                owner.AsmWrite('('+gas_regname(base)+','+gas_regname(index));
 
135
                if scalefactor<>0 then
 
136
                 owner.AsmWrite(','+tostr(scalefactor));
 
137
                owner.AsmWrite(')');
 
138
              end;
 
139
         end;
 
140
      end;
 
141
 
 
142
 
 
143
    procedure Tx86InstrWriter.WriteOper(const o:toper);
 
144
      begin
 
145
        case o.typ of
 
146
          top_reg :
 
147
            owner.AsmWrite(gas_regname(o.reg));
 
148
          top_ref :
 
149
            if o.ref^.refaddr in [addr_no,addr_pic] then
 
150
              WriteReference(o.ref^)
 
151
            else
 
152
              begin
 
153
                owner.AsmWrite('$');
 
154
                if assigned(o.ref^.symbol) then
 
155
                 owner.AsmWrite(o.ref^.symbol.name);
 
156
                if o.ref^.offset>0 then
 
157
                 owner.AsmWrite('+'+tostr(o.ref^.offset))
 
158
                else
 
159
                 if o.ref^.offset<0 then
 
160
                  owner.AsmWrite(tostr(o.ref^.offset))
 
161
                else
 
162
                 if not(assigned(o.ref^.symbol)) then
 
163
                   owner.AsmWrite('0');
 
164
              end;
 
165
          top_const :
 
166
              owner.AsmWrite('$'+tostr(o.val));
 
167
          else
 
168
            internalerror(10001);
 
169
        end;
 
170
      end;
 
171
 
 
172
 
 
173
    procedure Tx86InstrWriter.WriteOper_jmp(const o:toper);
 
174
      begin
 
175
        case o.typ of
 
176
          top_reg :
 
177
            owner.AsmWrite('*'+gas_regname(o.reg));
 
178
          top_ref :
 
179
            begin
 
180
              if o.ref^.refaddr=addr_no then
 
181
                begin
 
182
                  owner.AsmWrite('*');
 
183
                  WriteReference(o.ref^);
 
184
                end
 
185
              else
 
186
                begin
 
187
                  owner.AsmWrite(o.ref^.symbol.name);
 
188
                  if o.ref^.refaddr=addr_pic then
 
189
                    owner.AsmWrite('@PLT');
 
190
                  if o.ref^.offset>0 then
 
191
                   owner.AsmWrite('+'+tostr(o.ref^.offset))
 
192
                  else
 
193
                   if o.ref^.offset<0 then
 
194
                    owner.AsmWrite(tostr(o.ref^.offset));
 
195
                end;
 
196
            end;
 
197
          top_const :
 
198
            owner.AsmWrite(tostr(o.val));
 
199
          else
 
200
            internalerror(10001);
 
201
        end;
 
202
      end;
 
203
 
 
204
 
 
205
    procedure Tx86InstrWriter.WriteInstruction(hp: tai);
 
206
      var
 
207
       op       : tasmop;
 
208
       calljmp  : boolean;
 
209
       i        : integer;
 
210
      begin
 
211
        if hp.typ <> ait_instruction then
 
212
          exit;
 
213
        taicpu(hp).SetOperandOrder(op_att);
 
214
        op:=taicpu(hp).opcode;
 
215
        calljmp:=is_calljmp(op);
 
216
        owner.AsmWrite(#9);
 
217
        { movsd should not be translated to movsl when there
 
218
          are (xmm) arguments }
 
219
        if (op=A_MOVSD) and (taicpu(hp).ops>0) then
 
220
          owner.AsmWrite('movsd')
 
221
        else
 
222
          owner.AsmWrite(gas_op2str[op]);
 
223
        owner.AsmWrite(cond2str[taicpu(hp).condition]);
 
224
        { suffix needed ?  fnstsw,fldcw don't support suffixes
 
225
          with binutils 2.9.5 under linux }
 
226
{        if (Taicpu(hp).oper[0]^.typ=top_reg) and
 
227
            (Taicpu(hp).oper[0]^.reg.enum>lastreg) then
 
228
          internalerror(200301081);}
 
229
 
 
230
        if (not calljmp) and
 
231
           (gas_needsuffix[op]<>AttSufNONE) and
 
232
           (op<>A_FNSTSW) and
 
233
           (op<>A_FSTSW) and
 
234
           (op<>A_FNSTCW) and
 
235
           (op<>A_FSTCW) and
 
236
           (op<>A_FLDCW) and
 
237
           not(
 
238
               (taicpu(hp).ops<>0) and
 
239
               (taicpu(hp).oper[0]^.typ=top_reg) and
 
240
               (getregtype(taicpu(hp).oper[0]^.reg)=R_FPUREGISTER)
 
241
              ) then
 
242
          owner.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
 
243
        { process operands }
 
244
        if taicpu(hp).ops<>0 then
 
245
          begin
 
246
            if calljmp then
 
247
             begin
 
248
               owner.AsmWrite(#9);
 
249
               WriteOper_jmp(taicpu(hp).oper[0]^);
 
250
             end
 
251
            else
 
252
             begin
 
253
               for i:=0 to taicpu(hp).ops-1 do
 
254
                 begin
 
255
                   if i=0 then
 
256
                     owner.AsmWrite(#9)
 
257
                   else
 
258
                     owner.AsmWrite(',');
 
259
                   WriteOper(taicpu(hp).oper[i]^);
 
260
                 end;
 
261
             end;
 
262
          end;
 
263
        owner.AsmLn;
 
264
      end;
 
265
 
 
266
{*****************************************************************************
 
267
                                  Initialize
 
268
*****************************************************************************}
 
269
 
 
270
    const
 
271
{$ifdef x86_64}
 
272
       as_x86_64_as_info : tasminfo =
 
273
          (
 
274
            id     : as_gas;
 
275
            idtxt  : 'AS';
 
276
            asmbin : 'as';
 
277
            asmcmd : '--64 -o $OBJ $ASM';
 
278
            supported_target : system_any;
 
279
            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
 
280
            labelprefix : '.L';
 
281
            comment : '# ';
 
282
          );
 
283
{$else x86_64}
 
284
       as_i386_as_info : tasminfo =
 
285
          (
 
286
            id     : as_gas;
 
287
            idtxt  : 'AS';
 
288
            asmbin : 'as';
 
289
            asmcmd : '--32 -o $OBJ $ASM';
 
290
            supported_target : system_any;
 
291
            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
 
292
            labelprefix : '.L';
 
293
            comment : '# ';
 
294
          );
 
295
 
 
296
 
 
297
       as_i386_as_aout_info : tasminfo =
 
298
          (
 
299
            id           : as_i386_as_aout;
 
300
            idtxt  : 'AS_AOUT';
 
301
            asmbin : 'as';
 
302
            asmcmd : '-o $OBJ $ASM';
 
303
            supported_target : system_any;
 
304
            flags : [af_allowdirect,af_needar];
 
305
            labelprefix : 'L';
 
306
            comment : '# ';
 
307
          );
 
308
 
 
309
 
 
310
       as_i386_gas_darwin_info : tasminfo =
 
311
          (
 
312
            id     : as_darwin;
 
313
            idtxt  : 'AS-Darwin';
 
314
            asmbin : 'as';
 
315
            asmcmd : '-o $OBJ $ASM -arch i386';
 
316
            supported_target : system_any;
 
317
            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
 
318
            labelprefix : 'L';
 
319
            comment : '# ';
 
320
          );
 
321
 
 
322
       as_i386_gas_info : tasminfo =
 
323
          (
 
324
            id     : as_ggas;
 
325
            idtxt  : 'GAS';
 
326
            asmbin : 'gas';
 
327
            asmcmd : '--32 -o $OBJ $ASM';
 
328
            supported_target : system_any;
 
329
            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
 
330
            labelprefix : '.L';
 
331
            comment : '# ';
 
332
          );
 
333
{$endif x86_64}
 
334
 
 
335
initialization
 
336
{$ifdef x86_64}
 
337
  RegisterAssembler(as_x86_64_as_info,Tx86ATTAssembler);
 
338
{$else x86_64}
 
339
  RegisterAssembler(as_i386_as_info,Tx86ATTAssembler);
 
340
  RegisterAssembler(as_i386_gas_info,Tx86ATTAssembler);
 
341
  RegisterAssembler(as_i386_gas_darwin_info,Tx86AppleGNUAssembler);
 
342
  RegisterAssembler(as_i386_as_aout_info,Tx86ATTAssembler);
 
343
{$endif x86_64}
 
344
end.