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

« back to all changes in this revision

Viewing changes to compiler/raatt.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
 
    $Id: raatt.pas,v 1.10 2004/03/02 00:36:33 olle Exp $
3
 
    Copyright (c) 1998-2002 by Carl Eric Codere and Peter Vreman
4
 
 
5
 
    Does the parsing for the GAS styled inline assembler.
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
 
unit raatt;
24
 
 
25
 
{$i fpcdefs.inc}
26
 
 
27
 
  interface
28
 
 
29
 
    uses
30
 
      { common }
31
 
      cutils,cclasses,
32
 
      { global }
33
 
      globtype,
34
 
      { aasm }
35
 
      cpubase,cpuinfo,aasmbase,aasmtai,aasmcpu,
36
 
      { assembler reader }
37
 
      rabase,
38
 
      rasm,
39
 
      rautils,
40
 
      { symtable }
41
 
      symconst,
42
 
      { cg }
43
 
      cgbase,node;
44
 
 
45
 
    type
46
 
      tasmtoken = (
47
 
        AS_NONE,AS_LABEL,AS_LLABEL,AS_STRING,AS_INTNUM,
48
 
        AS_REALNUM,AS_COMMA,AS_LPAREN,
49
 
        AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR,
50
 
        AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_SLASH,AS_DOLLAR,
51
 
        AS_HASH,AS_LSBRACKET,AS_RSBRACKET,AS_LBRACKET,AS_RBRACKET,
52
 
        {------------------ Assembler directives --------------------}
53
 
        AS_DB,AS_DW,AS_DD,AS_DQ,AS_GLOBAL,
54
 
        AS_ALIGN,AS_BALIGN,AS_P2ALIGN,AS_ASCII,
55
 
        AS_ASCIIZ,AS_LCOMM,AS_COMM,AS_SINGLE,AS_DOUBLE,AS_EXTENDED,
56
 
        AS_DATA,AS_TEXT,AS_END,
57
 
        {------------------ Assembler Operators  --------------------}
58
 
        AS_TYPE,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT,
59
 
        AS_LO,AS_HI);
60
 
 
61
 
        tasmkeyword = string[10];
62
 
 
63
 
    const
64
 
      { These tokens should be modified accordingly to the modifications }
65
 
      { in the different enumerations.                                   }
66
 
      firstdirective = AS_DB;
67
 
      lastdirective  = AS_END;
68
 
 
69
 
      token2str : array[tasmtoken] of tasmkeyword=(
70
 
        '','Label','LLabel','string','integer',
71
 
        'float',',','(',
72
 
        ')',':','.','+','-','*',
73
 
        ';','identifier','register','opcode','/','$',
74
 
        '#','{','}','[',']',
75
 
        '.byte','.word','.long','.quad','.globl',
76
 
        '.align','.balign','.p2align','.ascii',
77
 
        '.asciz','.lcomm','.comm','.single','.double','.tfloat',
78
 
        '.data','.text','END',
79
 
        'TYPE','%','<<','>>','!','&','|','^','~','@','lo','hi');
80
 
 
81
 
    type
82
 
       tattreader = class(tasmreader)
83
 
         actasmtoken    : tasmtoken;
84
 
         prevasmtoken   : tasmtoken;
85
 
         procedure SetupTables;
86
 
         procedure BuildConstant(maxvalue: longint);
87
 
         procedure BuildConstantOperand(oper : toperand);
88
 
         procedure BuildRealConstant(typ : tfloattype);
89
 
         procedure BuildStringConstant(asciiz: boolean);
90
 
         procedure BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
91
 
         procedure BuildConstSymbolExpression(allowref,betweenbracket,needofs:boolean;var value:longint;var asmsym:string);
92
 
         function BuildConstExpression(allowref,betweenbracket:boolean): longint;
93
 
         function Assemble: tlinkedlist;override;
94
 
         procedure handleopcode;virtual;abstract;
95
 
         function is_asmopcode(const s: string) : boolean;virtual;abstract;
96
 
         Function is_asmdirective(const s: string):boolean;
97
 
         function is_register(const s:string):boolean;virtual;
98
 
         function is_locallabel(const s: string):boolean;
99
 
         procedure GetToken;
100
 
         function consume(t : tasmtoken):boolean;
101
 
         procedure RecoverConsume(allowcomma:boolean);
102
 
         procedure handlepercent;virtual;
103
 
       end;
104
 
       tcattreader = class of tattreader;
105
 
 
106
 
    var
107
 
      cattreader : tcattreader;
108
 
 
109
 
  implementation
110
 
 
111
 
    uses
112
 
      { globals }
113
 
      verbose,systems,
114
 
      { input }
115
 
      scanner,
116
 
      { symtable }
117
 
      symbase,symtype,symsym,symtable,
118
 
{$ifdef x86}
119
 
      rax86,
120
 
{$endif x86}
121
 
      itcpugas;
122
 
 
123
 
 
124
 
    procedure tattreader.SetupTables;
125
 
      { creates uppercased symbol tables for speed access }
126
 
      var
127
 
        i : tasmop;
128
 
        str2opentry: tstr2opentry;
129
 
      Begin
130
 
        { opcodes }
131
 
        iasmops:=TDictionary.Create;
132
 
        iasmops.delete_doubles:=true;
133
 
        for i:=firstop to lastop do
134
 
          begin
135
 
            str2opentry:=tstr2opentry.createname(upper(gas_op2str[i]));
136
 
            str2opentry.op:=i;
137
 
            iasmops.insert(str2opentry);
138
 
          end;
139
 
      end;
140
 
 
141
 
 
142
 
    function tattreader.is_asmdirective(const s: string):boolean;
143
 
      var
144
 
        i : tasmtoken;
145
 
        hs : string;
146
 
      Begin
147
 
        { GNU as is also not casesensitive with this }
148
 
        hs:=lower(s);
149
 
        for i:=firstdirective to lastdirective do
150
 
         if hs=token2str[i] then
151
 
          begin
152
 
            actasmtoken:=i;
153
 
            is_asmdirective:=true;
154
 
            exit;
155
 
          end;
156
 
        is_asmdirective:=false;
157
 
      end;
158
 
 
159
 
 
160
 
    function tattreader.is_register(const s:string):boolean;
161
 
      begin
162
 
        is_register:=false;
163
 
        actasmregister:=gas_regnum_search(lower(s));
164
 
        if actasmregister<>NR_NO then
165
 
          begin
166
 
            is_register:=true;
167
 
            actasmtoken:=AS_REGISTER;
168
 
          end;
169
 
      end;
170
 
 
171
 
 
172
 
    function tattreader.is_locallabel(const s: string):boolean;
173
 
      begin
174
 
        is_locallabel:=(length(s)>=2) and (s[1]='.') and (s[2]='L');
175
 
      end;
176
 
 
177
 
 
178
 
    procedure tattreader.handlepercent;
179
 
      begin
180
 
        c:=current_scanner.asmgetchar;
181
 
        actasmtoken:=AS_MOD;
182
 
      end;
183
 
 
184
 
 
185
 
    procedure tattreader.GetToken;
186
 
      var
187
 
        len : longint;
188
 
        srsym : tsym;
189
 
        srsymtable : tsymtable;
190
 
      begin
191
 
        { save old token and reset new token }
192
 
        prevasmtoken:=actasmtoken;
193
 
        actasmtoken:=AS_NONE;
194
 
        { reset }
195
 
        actasmpattern:='';
196
 
        { while space and tab , continue scan... }
197
 
        while c in [' ',#9] do
198
 
         c:=current_scanner.asmgetchar;
199
 
        { get token pos }
200
 
{$ifdef arm}
201
 
        if not (c in [#10,#13,';']) then
202
 
          current_scanner.gettokenpos;
203
 
{$else arm}
204
 
        if not (c in [#10,#13,'{',';']) then
205
 
          current_scanner.gettokenpos;
206
 
{$endif arm}
207
 
 
208
 
        { Local Label, Label, Directive, Prefix or Opcode }
209
 
{$ifdef arm}
210
 
        if firsttoken and not(c in [#10,#13,';']) then
211
 
{$else arm}
212
 
        if firsttoken and not(c in [#10,#13,'{',';']) then
213
 
{$endif arm}
214
 
         begin
215
 
           firsttoken:=FALSE;
216
 
           len:=0;
217
 
           { directive or local label }
218
 
           if c = '.' then
219
 
            begin
220
 
              inc(len);
221
 
              actasmpattern[len]:=c;
222
 
              { Let us point to the next character }
223
 
              c:=current_scanner.asmgetchar;
224
 
              while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
225
 
               begin
226
 
                 inc(len);
227
 
                 actasmpattern[len]:=c;
228
 
                 c:=current_scanner.asmgetchar;
229
 
               end;
230
 
              actasmpattern[0]:=chr(len);
231
 
              { this is a local label... }
232
 
              if (c=':') and is_locallabel(actasmpattern) then
233
 
               Begin
234
 
                 { local variables are case sensitive }
235
 
                 actasmtoken:=AS_LLABEL;
236
 
                 c:=current_scanner.asmgetchar;
237
 
                 firsttoken:=true;
238
 
                 exit;
239
 
               end
240
 
              { must be a directive }
241
 
              else
242
 
               Begin
243
 
                 { directives are case sensitive!! }
244
 
                 if is_asmdirective(actasmpattern) then
245
 
                  exit;
246
 
                 Message1(asmr_e_not_directive_or_local_symbol,actasmpattern);
247
 
               end;
248
 
            end;
249
 
           { only opcodes and global labels are allowed now. }
250
 
           while c in ['A'..'Z','a'..'z','0'..'9','_'] do
251
 
            begin
252
 
              inc(len);
253
 
              actasmpattern[len]:=c;
254
 
              c:=current_scanner.asmgetchar;
255
 
            end;
256
 
           actasmpattern[0]:=chr(len);
257
 
           { Label ? }
258
 
           if c = ':' then
259
 
            begin
260
 
              actasmtoken:=AS_LABEL;
261
 
              { let us point to the next character }
262
 
              c:=current_scanner.asmgetchar;
263
 
              firsttoken:=true;
264
 
              exit;
265
 
            end;
266
 
{$ifdef POWERPC}
267
 
           { some PowerPC instructions can have the postfix -, + or .
268
 
             this code could be moved to is_asmopcode but I think
269
 
             it's better to ifdef it here (FK)
270
 
           }
271
 
           case c of
272
 
             '.', '-', '+':
273
 
               begin
274
 
                 actasmpattern:=actasmpattern+c;
275
 
                 c:=current_scanner.asmgetchar;
276
 
               end
277
 
           end;
278
 
{$endif POWERPC}
279
 
           { Opcode ? }
280
 
           If is_asmopcode(upper(actasmpattern)) then
281
 
            Begin
282
 
              uppervar(actasmpattern);
283
 
              exit;
284
 
            end;
285
 
           { End of assemblerblock ? }
286
 
           if upper(actasmpattern) = 'END' then
287
 
            begin
288
 
              actasmtoken:=AS_END;
289
 
              exit;
290
 
            end;
291
 
           message1(asmr_e_unknown_opcode,actasmpattern);
292
 
           actasmtoken:=AS_NONE;
293
 
         end
294
 
        else { else firsttoken }
295
 
        { Here we must handle all possible cases }
296
 
         begin
297
 
           case c of
298
 
             '.' :  { possiblities : - local label reference , such as in jmp @local1 }
299
 
                    {               - field of object/record                         }
300
 
                    {               - directive.                                     }
301
 
               begin
302
 
                 if (prevasmtoken in [AS_ID,AS_RPAREN]) then
303
 
                  begin
304
 
                    c:=current_scanner.asmgetchar;
305
 
                    actasmtoken:=AS_DOT;
306
 
                    exit;
307
 
                  end;
308
 
                 actasmpattern:=c;
309
 
                 c:=current_scanner.asmgetchar;
310
 
                 while c in  ['A'..'Z','a'..'z','0'..'9','_','$'] do
311
 
                  begin
312
 
                    actasmpattern:=actasmpattern + c;
313
 
                    c:=current_scanner.asmgetchar;
314
 
                  end;
315
 
                 if is_asmdirective(actasmpattern) then
316
 
                  exit;
317
 
                 { local label references and directives }
318
 
                 { are case sensitive                    }
319
 
                 actasmtoken:=AS_ID;
320
 
                 exit;
321
 
               end;
322
 
 
323
 
          { identifier, register, prefix or directive }
324
 
             '_','A'..'Z','a'..'z':
325
 
               begin
326
 
                 len:=0;
327
 
                 while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
328
 
                  begin
329
 
                    inc(len);
330
 
                    actasmpattern[len]:=c;
331
 
                    c:=current_scanner.asmgetchar;
332
 
                  end;
333
 
                 actasmpattern[0]:=chr(len);
334
 
                 uppervar(actasmpattern);
335
 
{$ifdef x86}
336
 
                 { only x86 architectures have instruction prefixes }
337
 
 
338
 
                 { Opcode, can only be when the previous was a prefix }
339
 
                 If is_prefix(actopcode) and is_asmopcode(actasmpattern) then
340
 
                  Begin
341
 
                    uppervar(actasmpattern);
342
 
                    exit;
343
 
                  end;
344
 
{$endif x86}
345
 
                 { check for end which is a reserved word unlike the opcodes }
346
 
                 if actasmpattern = 'END' then
347
 
                  Begin
348
 
                    actasmtoken:=AS_END;
349
 
                    exit;
350
 
                  end;
351
 
                 if actasmpattern = 'TYPE' then
352
 
                  Begin
353
 
                    actasmtoken:=AS_TYPE;
354
 
                    exit;
355
 
                  end;
356
 
                 if is_register(actasmpattern) then
357
 
                   begin
358
 
                     actasmtoken:=AS_REGISTER;
359
 
                     exit;
360
 
                   end;
361
 
                 { if next is a '.' and this is a unitsym then we also need to
362
 
                   parse the identifier }
363
 
                 if (c='.') then
364
 
                  begin
365
 
                    searchsym(actasmpattern,srsym,srsymtable);
366
 
                    if assigned(srsym) and
367
 
                       (srsym.typ=unitsym) and
368
 
                       (srsym.owner.unitid=0) then
369
 
                     begin
370
 
                       actasmpattern:=actasmpattern+c;
371
 
                       c:=current_scanner.asmgetchar;
372
 
                       while c in  ['A'..'Z','a'..'z','0'..'9','_','$'] do
373
 
                        begin
374
 
                          actasmpattern:=actasmpattern + upcase(c);
375
 
                          c:=current_scanner.asmgetchar;
376
 
                        end;
377
 
                     end;
378
 
                  end;
379
 
                 actasmtoken:=AS_ID;
380
 
                 exit;
381
 
               end;
382
 
 
383
 
             '%' : { register or modulo }
384
 
               handlepercent;
385
 
 
386
 
             '1'..'9': { integer number }
387
 
               begin
388
 
                 len:=0;
389
 
                 while c in ['0'..'9'] do
390
 
                  Begin
391
 
                    inc(len);
392
 
                    actasmpattern[len]:=c;
393
 
                    c:=current_scanner.asmgetchar;
394
 
                  end;
395
 
                 actasmpattern[0]:=chr(len);
396
 
                 actasmpattern:=tostr(ValDecimal(actasmpattern));
397
 
                 actasmtoken:=AS_INTNUM;
398
 
                 exit;
399
 
               end;
400
 
             '0' : { octal,hexa,real or binary number. }
401
 
               begin
402
 
                 actasmpattern:=c;
403
 
                 c:=current_scanner.asmgetchar;
404
 
                 case upcase(c) of
405
 
                   'B': { binary }
406
 
                     Begin
407
 
                       c:=current_scanner.asmgetchar;
408
 
                       while c in ['0','1'] do
409
 
                        Begin
410
 
                          actasmpattern:=actasmpattern + c;
411
 
                          c:=current_scanner.asmgetchar;
412
 
                        end;
413
 
                       actasmpattern:=tostr(ValBinary(actasmpattern));
414
 
                       actasmtoken:=AS_INTNUM;
415
 
                       exit;
416
 
                     end;
417
 
                   'D': { real }
418
 
                     Begin
419
 
                       c:=current_scanner.asmgetchar;
420
 
                       { get ridd of the 0d }
421
 
                       if (c in ['+','-']) then
422
 
                        begin
423
 
                          actasmpattern:=c;
424
 
                          c:=current_scanner.asmgetchar;
425
 
                        end
426
 
                       else
427
 
                        actasmpattern:='';
428
 
                       while c in ['0'..'9'] do
429
 
                        Begin
430
 
                          actasmpattern:=actasmpattern + c;
431
 
                          c:=current_scanner.asmgetchar;
432
 
                        end;
433
 
                       if c='.' then
434
 
                        begin
435
 
                          actasmpattern:=actasmpattern + c;
436
 
                          c:=current_scanner.asmgetchar;
437
 
                          while c in ['0'..'9'] do
438
 
                           Begin
439
 
                             actasmpattern:=actasmpattern + c;
440
 
                             c:=current_scanner.asmgetchar;
441
 
                           end;
442
 
                          if upcase(c) = 'E' then
443
 
                           begin
444
 
                             actasmpattern:=actasmpattern + c;
445
 
                             c:=current_scanner.asmgetchar;
446
 
                             if (c in ['+','-']) then
447
 
                              begin
448
 
                                actasmpattern:=actasmpattern + c;
449
 
                                c:=current_scanner.asmgetchar;
450
 
                              end;
451
 
                             while c in ['0'..'9'] do
452
 
                              Begin
453
 
                                actasmpattern:=actasmpattern + c;
454
 
                                c:=current_scanner.asmgetchar;
455
 
                              end;
456
 
                           end;
457
 
                          actasmtoken:=AS_REALNUM;
458
 
                          exit;
459
 
                        end
460
 
                       else
461
 
                        begin
462
 
                          Message1(asmr_e_invalid_float_const,actasmpattern+c);
463
 
                          actasmtoken:=AS_NONE;
464
 
                        end;
465
 
                     end;
466
 
                   'X': { hexadecimal }
467
 
                     Begin
468
 
                       c:=current_scanner.asmgetchar;
469
 
                       while c in ['0'..'9','a'..'f','A'..'F'] do
470
 
                        Begin
471
 
                          actasmpattern:=actasmpattern + c;
472
 
                          c:=current_scanner.asmgetchar;
473
 
                        end;
474
 
                       actasmpattern:=tostr(ValHexaDecimal(actasmpattern));
475
 
                       actasmtoken:=AS_INTNUM;
476
 
                       exit;
477
 
                     end;
478
 
                   '1'..'7': { octal }
479
 
                     begin
480
 
                       actasmpattern:=actasmpattern + c;
481
 
                       while c in ['0'..'7'] do
482
 
                        Begin
483
 
                          actasmpattern:=actasmpattern + c;
484
 
                          c:=current_scanner.asmgetchar;
485
 
                        end;
486
 
                       actasmpattern:=tostr(ValOctal(actasmpattern));
487
 
                       actasmtoken:=AS_INTNUM;
488
 
                       exit;
489
 
                     end;
490
 
                   else { octal number zero value...}
491
 
                     Begin
492
 
                       actasmpattern:=tostr(ValOctal(actasmpattern));
493
 
                       actasmtoken:=AS_INTNUM;
494
 
                       exit;
495
 
                     end;
496
 
                 end; { end case }
497
 
               end;
498
 
 
499
 
             '&' :
500
 
               begin
501
 
                 c:=current_scanner.asmgetchar;
502
 
                 actasmtoken:=AS_AND;
503
 
               end;
504
 
 
505
 
             '''' : { char }
506
 
               begin
507
 
                 current_scanner.in_asm_string:=true;
508
 
                 actasmpattern:='';
509
 
                 repeat
510
 
                   c:=current_scanner.asmgetchar;
511
 
                   case c of
512
 
                     '\' :
513
 
                       begin
514
 
                         { copy also the next char so \" is parsed correctly }
515
 
                         actasmpattern:=actasmpattern+c;
516
 
                         c:=current_scanner.asmgetchar;
517
 
                         actasmpattern:=actasmpattern+c;
518
 
                       end;
519
 
                     '''' :
520
 
                       begin
521
 
                         c:=current_scanner.asmgetchar;
522
 
                         break;
523
 
                       end;
524
 
                     #10,#13:
525
 
                       Message(scan_f_string_exceeds_line);
526
 
                     else
527
 
                       actasmpattern:=actasmpattern+c;
528
 
                   end;
529
 
                 until false;
530
 
                 actasmpattern:=EscapeToPascal(actasmpattern);
531
 
                 actasmtoken:=AS_STRING;
532
 
                 current_scanner.in_asm_string:=false;
533
 
                 exit;
534
 
               end;
535
 
 
536
 
             '"' : { string }
537
 
               begin
538
 
                 current_scanner.in_asm_string:=true;
539
 
                 actasmpattern:='';
540
 
                 repeat
541
 
                   c:=current_scanner.asmgetchar;
542
 
                   case c of
543
 
                     '\' :
544
 
                       begin
545
 
                         { copy also the next char so \" is parsed correctly }
546
 
                         actasmpattern:=actasmpattern+c;
547
 
                         c:=current_scanner.asmgetchar;
548
 
                         actasmpattern:=actasmpattern+c;
549
 
                       end;
550
 
                     '"' :
551
 
                       begin
552
 
                         c:=current_scanner.asmgetchar;
553
 
                         break;
554
 
                       end;
555
 
                     #10,#13:
556
 
                       Message(scan_f_string_exceeds_line);
557
 
                     else
558
 
                       actasmpattern:=actasmpattern+c;
559
 
                   end;
560
 
                 until false;
561
 
                 actasmpattern:=EscapeToPascal(actasmpattern);
562
 
                 actasmtoken:=AS_STRING;
563
 
                 current_scanner.in_asm_string:=false;
564
 
                 exit;
565
 
               end;
566
 
 
567
 
             '$' :
568
 
               begin
569
 
                 actasmtoken:=AS_DOLLAR;
570
 
                 c:=current_scanner.asmgetchar;
571
 
                 exit;
572
 
               end;
573
 
 
574
 
             '#' :
575
 
               begin
576
 
                 actasmtoken:=AS_HASH;
577
 
                 c:=current_scanner.asmgetchar;
578
 
                 exit;
579
 
               end;
580
 
 
581
 
             '[' :
582
 
               begin
583
 
                 actasmtoken:=AS_LBRACKET;
584
 
                 c:=current_scanner.asmgetchar;
585
 
                 exit;
586
 
               end;
587
 
 
588
 
             ']' :
589
 
               begin
590
 
                 actasmtoken:=AS_RBRACKET;
591
 
                 c:=current_scanner.asmgetchar;
592
 
                 exit;
593
 
               end;
594
 
{$ifdef arm}
595
 
             // the arm assembler uses { ... } for register sets
596
 
             '{' :
597
 
               begin
598
 
                 actasmtoken:=AS_LSBRACKET;
599
 
                 c:=current_scanner.asmgetchar;
600
 
                 exit;
601
 
               end;
602
 
 
603
 
             '}' :
604
 
               begin
605
 
                 actasmtoken:=AS_RSBRACKET;
606
 
                 c:=current_scanner.asmgetchar;
607
 
                 exit;
608
 
               end;
609
 
{$endif arm}
610
 
 
611
 
             ',' :
612
 
               begin
613
 
                 actasmtoken:=AS_COMMA;
614
 
                 c:=current_scanner.asmgetchar;
615
 
                 exit;
616
 
               end;
617
 
 
618
 
             '<' :
619
 
               begin
620
 
                 actasmtoken:=AS_SHL;
621
 
                 c:=current_scanner.asmgetchar;
622
 
                 if c = '<' then
623
 
                  c:=current_scanner.asmgetchar;
624
 
                 exit;
625
 
               end;
626
 
 
627
 
             '>' :
628
 
               begin
629
 
                 actasmtoken:=AS_SHL;
630
 
                 c:=current_scanner.asmgetchar;
631
 
                 if c = '>' then
632
 
                  c:=current_scanner.asmgetchar;
633
 
                 exit;
634
 
               end;
635
 
 
636
 
             '|' :
637
 
               begin
638
 
                 actasmtoken:=AS_OR;
639
 
                 c:=current_scanner.asmgetchar;
640
 
                 exit;
641
 
               end;
642
 
 
643
 
             '^' :
644
 
               begin
645
 
                 actasmtoken:=AS_XOR;
646
 
                 c:=current_scanner.asmgetchar;
647
 
                 exit;
648
 
               end;
649
 
 
650
 
 
651
 
             '(' :
652
 
               begin
653
 
                 actasmtoken:=AS_LPAREN;
654
 
                 c:=current_scanner.asmgetchar;
655
 
                 exit;
656
 
               end;
657
 
 
658
 
             ')' :
659
 
               begin
660
 
                 actasmtoken:=AS_RPAREN;
661
 
                 c:=current_scanner.asmgetchar;
662
 
                 exit;
663
 
               end;
664
 
 
665
 
             ':' :
666
 
               begin
667
 
                 actasmtoken:=AS_COLON;
668
 
                 c:=current_scanner.asmgetchar;
669
 
                 exit;
670
 
               end;
671
 
 
672
 
             '+' :
673
 
               begin
674
 
                 actasmtoken:=AS_PLUS;
675
 
                 c:=current_scanner.asmgetchar;
676
 
                 exit;
677
 
               end;
678
 
 
679
 
             '-' :
680
 
               begin
681
 
                 actasmtoken:=AS_MINUS;
682
 
                 c:=current_scanner.asmgetchar;
683
 
                 exit;
684
 
               end;
685
 
 
686
 
             '*' :
687
 
               begin
688
 
                 actasmtoken:=AS_STAR;
689
 
                 c:=current_scanner.asmgetchar;
690
 
                 exit;
691
 
               end;
692
 
 
693
 
             '/' :
694
 
               begin
695
 
                 actasmtoken:=AS_SLASH;
696
 
                 c:=current_scanner.asmgetchar;
697
 
                 exit;
698
 
               end;
699
 
 
700
 
             '!' :
701
 
               begin
702
 
                 actasmtoken:=AS_NOT;
703
 
                 c:=current_scanner.asmgetchar;
704
 
                 exit;
705
 
               end;
706
 
 
707
 
             '@' :
708
 
               begin
709
 
                 actasmtoken:=AS_AT;
710
 
                 c:=current_scanner.asmgetchar;
711
 
                 exit;
712
 
               end;
713
 
 
714
 
{$ifndef arm}
715
 
             '{',
716
 
{$endif arm}
717
 
             #13,#10,';' :
718
 
               begin
719
 
                 { the comment is read by asmgetchar }
720
 
                 c:=current_scanner.asmgetchar;
721
 
                 firsttoken:=TRUE;
722
 
                 actasmtoken:=AS_SEPARATOR;
723
 
                 exit;
724
 
               end;
725
 
 
726
 
             else
727
 
               current_scanner.illegal_char(c);
728
 
           end;
729
 
         end;
730
 
      end;
731
 
 
732
 
 
733
 
    function tattreader.consume(t : tasmtoken):boolean;
734
 
      begin
735
 
        Consume:=true;
736
 
        if t<>actasmtoken then
737
 
         begin
738
 
           Message2(scan_f_syn_expected,token2str[t],token2str[actasmtoken]);
739
 
           Consume:=false;
740
 
         end;
741
 
        repeat
742
 
          gettoken;
743
 
        until actasmtoken<>AS_NONE;
744
 
      end;
745
 
 
746
 
 
747
 
    procedure tattreader.RecoverConsume(allowcomma:boolean);
748
 
      begin
749
 
        While not (actasmtoken in [AS_SEPARATOR,AS_END]) do
750
 
         begin
751
 
           if allowcomma and (actasmtoken=AS_COMMA) then
752
 
            break;
753
 
           Consume(actasmtoken);
754
 
         end;
755
 
      end;
756
 
 
757
 
 
758
 
    Procedure tattreader.BuildConstant(maxvalue: longint);
759
 
      var
760
 
       asmsym,
761
 
       expr: string;
762
 
       value : longint;
763
 
      Begin
764
 
        Repeat
765
 
          Case actasmtoken of
766
 
            AS_STRING:
767
 
              Begin
768
 
                expr:=actasmpattern;
769
 
                if length(expr) > 1 then
770
 
                 Message(asmr_e_string_not_allowed_as_const);
771
 
                Consume(AS_STRING);
772
 
                Case actasmtoken of
773
 
                  AS_COMMA: Consume(AS_COMMA);
774
 
                  AS_END,
775
 
                  AS_SEPARATOR: ;
776
 
                else
777
 
                  Message(asmr_e_invalid_string_expression);
778
 
                end; { end case }
779
 
                ConcatString(curlist,expr);
780
 
              end;
781
 
            AS_INTNUM,
782
 
            AS_PLUS,
783
 
            AS_MINUS,
784
 
            AS_LPAREN,
785
 
            AS_NOT,
786
 
            AS_ID :
787
 
              Begin
788
 
                BuildConstSymbolExpression(false,false,false,value,asmsym);
789
 
                if asmsym<>'' then
790
 
                 begin
791
 
                   if maxvalue<>longint($ffffffff) then
792
 
                    Message(asmr_w_32bit_const_for_address);
793
 
                   ConcatConstSymbol(curlist,asmsym,value)
794
 
                 end
795
 
                else
796
 
                 ConcatConstant(curlist,value,maxvalue);
797
 
              end;
798
 
            AS_COMMA:
799
 
              Consume(AS_COMMA);
800
 
            AS_END,
801
 
            AS_SEPARATOR:
802
 
              break;
803
 
            else
804
 
              begin
805
 
                Message(asmr_e_syn_constant);
806
 
                RecoverConsume(false);
807
 
              end
808
 
         end; { end case }
809
 
       Until false;
810
 
      end;
811
 
 
812
 
 
813
 
    Procedure tattreader.BuildRealConstant(typ : tfloattype);
814
 
      var
815
 
        expr : string;
816
 
        r : bestreal;
817
 
        code : integer;
818
 
        negativ : boolean;
819
 
        errorflag: boolean;
820
 
      Begin
821
 
        errorflag:=FALSE;
822
 
        Repeat
823
 
          negativ:=false;
824
 
          expr:='';
825
 
          if actasmtoken=AS_PLUS then
826
 
            Consume(AS_PLUS)
827
 
          else
828
 
           if actasmtoken=AS_MINUS then
829
 
            begin
830
 
              negativ:=true;
831
 
              consume(AS_MINUS);
832
 
            end;
833
 
          Case actasmtoken of
834
 
            AS_INTNUM:
835
 
              Begin
836
 
                expr:=actasmpattern;
837
 
                Consume(AS_INTNUM);
838
 
                if negativ then
839
 
                 expr:='-'+expr;
840
 
                val(expr,r,code);
841
 
                if code<>0 then
842
 
                 Begin
843
 
                   r:=0;
844
 
                   Message(asmr_e_invalid_float_expr);
845
 
                 End;
846
 
                ConcatRealConstant(curlist,r,typ);
847
 
              end;
848
 
            AS_REALNUM:
849
 
              Begin
850
 
                expr:=actasmpattern;
851
 
                Consume(AS_REALNUM);
852
 
                { in ATT syntax you have 0d in front of the real }
853
 
                { should this be forced ?  yes i think so, as to }
854
 
                { conform to gas as much as possible.            }
855
 
                if (expr[1]='0') and (upper(expr[2])='D') then
856
 
                 Delete(expr,1,2);
857
 
                if negativ then
858
 
                 expr:='-'+expr;
859
 
                val(expr,r,code);
860
 
                if code<>0 then
861
 
                 Begin
862
 
                   r:=0;
863
 
                   Message(asmr_e_invalid_float_expr);
864
 
                 End;
865
 
                ConcatRealConstant(curlist,r,typ);
866
 
              end;
867
 
            AS_COMMA:
868
 
              begin
869
 
                Consume(AS_COMMA);
870
 
              end;
871
 
            AS_END,
872
 
            AS_SEPARATOR:
873
 
              begin
874
 
                break;
875
 
              end;
876
 
         else
877
 
           Begin
878
 
             Consume(actasmtoken);
879
 
             if not errorflag then
880
 
              Message(asmr_e_invalid_float_expr);
881
 
             errorflag:=TRUE;
882
 
           end;
883
 
         end;
884
 
       Until false;
885
 
      end;
886
 
 
887
 
 
888
 
    Procedure tattreader.BuildStringConstant(asciiz: boolean);
889
 
      var
890
 
        expr: string;
891
 
        errorflag : boolean;
892
 
      Begin
893
 
        errorflag:=FALSE;
894
 
        Repeat
895
 
          Case actasmtoken of
896
 
            AS_STRING:
897
 
              Begin
898
 
                expr:=actasmpattern;
899
 
                if asciiz then
900
 
                  expr:=expr+#0;
901
 
                ConcatPasString(curlist,expr);
902
 
                Consume(AS_STRING);
903
 
              end;
904
 
            AS_COMMA:
905
 
              begin
906
 
                Consume(AS_COMMA);
907
 
              end;
908
 
            AS_END,
909
 
            AS_SEPARATOR:
910
 
              begin
911
 
                break;
912
 
              end;
913
 
         else
914
 
           Begin
915
 
             Consume(actasmtoken);
916
 
             if not errorflag then
917
 
              Message(asmr_e_invalid_string_expression);
918
 
             errorflag:=TRUE;
919
 
           end;
920
 
         end;
921
 
       Until false;
922
 
      end;
923
 
 
924
 
 
925
 
   Function tattreader.Assemble: tlinkedlist;
926
 
     Var
927
 
       hl         : tasmlabel;
928
 
       commname   : string;
929
 
       lasTSec    : TSection;
930
 
       l1,l2      : longint;
931
 
     Begin
932
 
       Message1(asmr_d_start_reading,'GNU AS');
933
 
       firsttoken:=TRUE;
934
 
       { sets up all opcode and register tables in uppercase }
935
 
       if not _asmsorted then
936
 
        Begin
937
 
          SetupTables;
938
 
          _asmsorted:=TRUE;
939
 
        end;
940
 
       curlist:=TAAsmoutput.Create;
941
 
       lasTSec:=sec_code;
942
 
       { setup label linked list }
943
 
       LocalLabelList:=TLocalLabelList.Create;
944
 
       { start tokenizer }
945
 
       c:=current_scanner.asmgetcharstart;
946
 
       gettoken;
947
 
       { main loop }
948
 
       repeat
949
 
         case actasmtoken of
950
 
           AS_LLABEL:
951
 
             Begin
952
 
               if CreateLocalLabel(actasmpattern,hl,true) then
953
 
                 ConcatLabel(curlist,hl);
954
 
               Consume(AS_LLABEL);
955
 
             end;
956
 
 
957
 
           AS_LABEL:
958
 
             Begin
959
 
               if SearchLabel(upper(actasmpattern),hl,true) then
960
 
                ConcatLabel(curlist,hl)
961
 
               else
962
 
                Message1(asmr_e_unknown_label_identifier,actasmpattern);
963
 
               Consume(AS_LABEL);
964
 
             end;
965
 
 
966
 
           AS_DW:
967
 
             Begin
968
 
               Consume(AS_DW);
969
 
               BuildConstant($ffff);
970
 
             end;
971
 
 
972
 
           AS_DATA:
973
 
             Begin
974
 
               curList.Concat(Tai_section.Create(sec_data));
975
 
               lasTSec:=sec_data;
976
 
               Consume(AS_DATA);
977
 
             end;
978
 
 
979
 
           AS_TEXT:
980
 
             Begin
981
 
               curList.Concat(Tai_section.Create(sec_code));
982
 
               lasTSec:=sec_code;
983
 
               Consume(AS_TEXT);
984
 
             end;
985
 
 
986
 
           AS_DB:
987
 
             Begin
988
 
               Consume(AS_DB);
989
 
               BuildConstant($ff);
990
 
             end;
991
 
 
992
 
           AS_DD:
993
 
             Begin
994
 
               Consume(AS_DD);
995
 
               BuildConstant(longint($ffffffff));
996
 
             end;
997
 
 
998
 
           AS_DQ:
999
 
             Begin
1000
 
               Consume(AS_DQ);
1001
 
               BuildRealConstant(s64comp);
1002
 
             end;
1003
 
 
1004
 
           AS_SINGLE:
1005
 
             Begin
1006
 
               Consume(AS_SINGLE);
1007
 
               BuildRealConstant(s32real);
1008
 
             end;
1009
 
 
1010
 
           AS_DOUBLE:
1011
 
             Begin
1012
 
               Consume(AS_DOUBLE);
1013
 
               BuildRealConstant(s64real);
1014
 
             end;
1015
 
 
1016
 
           AS_EXTENDED:
1017
 
             Begin
1018
 
               Consume(AS_EXTENDED);
1019
 
               BuildRealConstant(s80real);
1020
 
             end;
1021
 
 
1022
 
           AS_GLOBAL:
1023
 
             Begin
1024
 
               Consume(AS_GLOBAL);
1025
 
               if actasmtoken=AS_ID then
1026
 
                 ConcatPublic(curlist,actasmpattern);
1027
 
               Consume(AS_ID);
1028
 
               if actasmtoken<>AS_SEPARATOR then
1029
 
                Consume(AS_SEPARATOR);
1030
 
             end;
1031
 
 
1032
 
           AS_ALIGN:
1033
 
             Begin
1034
 
               Consume(AS_ALIGN);
1035
 
               l1:=BuildConstExpression(false,false);
1036
 
               if (target_info.system in [system_i386_GO32V2]) then
1037
 
                 begin
1038
 
                    l2:=1;
1039
 
                    if (l1>=0) and (l1<=16) then
1040
 
                      while (l1>0) do
1041
 
                        begin
1042
 
                          l2:=2*l2;
1043
 
                          dec(l1);
1044
 
                        end;
1045
 
                    l1:=l2;
1046
 
                 end;
1047
 
               ConcatAlign(curlist,l1);
1048
 
               Message(asmr_n_align_is_target_specific);
1049
 
               if actasmtoken<>AS_SEPARATOR then
1050
 
                Consume(AS_SEPARATOR);
1051
 
             end;
1052
 
 
1053
 
           AS_BALIGN:
1054
 
             Begin
1055
 
               Consume(AS_BALIGN);
1056
 
               ConcatAlign(curlist,BuildConstExpression(false,false));
1057
 
               if actasmtoken<>AS_SEPARATOR then
1058
 
                Consume(AS_SEPARATOR);
1059
 
             end;
1060
 
 
1061
 
           AS_P2ALIGN:
1062
 
             Begin
1063
 
               Consume(AS_P2ALIGN);
1064
 
               l1:=BuildConstExpression(false,false);
1065
 
               l2:=1;
1066
 
               if (l1>=0) and (l1<=16) then
1067
 
                 while (l1>0) do
1068
 
                   begin
1069
 
                      l2:=2*l2;
1070
 
                      dec(l1);
1071
 
                   end;
1072
 
               l1:=l2;
1073
 
               ConcatAlign(curlist,l1);
1074
 
               if actasmtoken<>AS_SEPARATOR then
1075
 
                Consume(AS_SEPARATOR);
1076
 
             end;
1077
 
 
1078
 
           AS_ASCIIZ:
1079
 
             Begin
1080
 
               Consume(AS_ASCIIZ);
1081
 
               BuildStringConstant(TRUE);
1082
 
             end;
1083
 
 
1084
 
           AS_ASCII:
1085
 
             Begin
1086
 
               Consume(AS_ASCII);
1087
 
               BuildStringConstant(FALSE);
1088
 
             end;
1089
 
 
1090
 
           AS_LCOMM:
1091
 
             Begin
1092
 
               Consume(AS_LCOMM);
1093
 
               commname:=actasmpattern;
1094
 
               Consume(AS_ID);
1095
 
               Consume(AS_COMMA);
1096
 
               ConcatLocalBss(commname,BuildConstExpression(false,false));
1097
 
               if actasmtoken<>AS_SEPARATOR then
1098
 
                Consume(AS_SEPARATOR);
1099
 
             end;
1100
 
 
1101
 
           AS_COMM:
1102
 
             Begin
1103
 
               Consume(AS_COMM);
1104
 
               commname:=actasmpattern;
1105
 
               Consume(AS_ID);
1106
 
               Consume(AS_COMMA);
1107
 
               ConcatGlobalBss(commname,BuildConstExpression(false,false));
1108
 
               if actasmtoken<>AS_SEPARATOR then
1109
 
                Consume(AS_SEPARATOR);
1110
 
             end;
1111
 
 
1112
 
           AS_OPCODE:
1113
 
             Begin
1114
 
               HandleOpCode;
1115
 
             end;
1116
 
 
1117
 
           AS_SEPARATOR:
1118
 
             Begin
1119
 
               Consume(AS_SEPARATOR);
1120
 
             end;
1121
 
 
1122
 
           AS_END:
1123
 
             begin
1124
 
               break; { end assembly block }
1125
 
             end;
1126
 
 
1127
 
           else
1128
 
             Begin
1129
 
               Message(asmr_e_syntax_error);
1130
 
               RecoverConsume(false);
1131
 
             end;
1132
 
         end;
1133
 
       until false;
1134
 
       { Check LocalLabelList }
1135
 
       LocalLabelList.CheckEmitted;
1136
 
       LocalLabelList.Free;
1137
 
       { are we back in the code section? }
1138
 
       if lasTSec<>sec_code then
1139
 
        begin
1140
 
          Message(asmr_w_assembler_code_not_returned_to_text);
1141
 
          curList.Concat(Tai_section.Create(sec_code));
1142
 
        end;
1143
 
       { Return the list in an asmnode }
1144
 
       assemble:=curlist;
1145
 
       Message1(asmr_d_finish_reading,'GNU AS');
1146
 
     end;
1147
 
 
1148
 
 
1149
 
{*****************************************************************************
1150
 
                               Parsing Helpers
1151
 
*****************************************************************************}
1152
 
 
1153
 
    Procedure tattreader.BuildRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
1154
 
      { Description: This routine builds up a record offset after a AS_DOT }
1155
 
      { token is encountered.                                              }
1156
 
      { On entry actasmtoken should be equal to AS_DOT                     }
1157
 
      var
1158
 
        s : string;
1159
 
      Begin
1160
 
        offset:=0;
1161
 
        size:=0;
1162
 
        s:=expr;
1163
 
        while (actasmtoken=AS_DOT) do
1164
 
         begin
1165
 
           Consume(AS_DOT);
1166
 
           if actasmtoken=AS_ID then
1167
 
            s:=s+'.'+actasmpattern;
1168
 
           if not Consume(AS_ID) then
1169
 
            begin
1170
 
              RecoverConsume(true);
1171
 
              break;
1172
 
            end;
1173
 
         end;
1174
 
        if not GetRecordOffsetSize(s,offset,size) then
1175
 
         Message(asmr_e_building_record_offset);
1176
 
      end;
1177
 
 
1178
 
 
1179
 
    procedure tattreader.BuildConstSymbolExpression(allowref,betweenbracket,needofs:boolean;var value:longint;var asmsym:string);
1180
 
      var
1181
 
        hs,tempstr,expr : string;
1182
 
        parenlevel,l,k : longint;
1183
 
        errorflag : boolean;
1184
 
        prevtok : tasmtoken;
1185
 
        sym : tsym;
1186
 
        srsymtable : tsymtable;
1187
 
        hl  : tasmlabel;
1188
 
      Begin
1189
 
        asmsym:='';
1190
 
        value:=0;
1191
 
        errorflag:=FALSE;
1192
 
        tempstr:='';
1193
 
        expr:='';
1194
 
        parenlevel:=0;
1195
 
        Repeat
1196
 
          Case actasmtoken of
1197
 
            AS_LPAREN:
1198
 
              Begin
1199
 
                { Exit if ref? }
1200
 
                if allowref and (prevasmtoken in [AS_INTNUM,AS_ID]) then
1201
 
                 break;
1202
 
                Consume(AS_LPAREN);
1203
 
                expr:=expr + '(';
1204
 
                inc(parenlevel);
1205
 
              end;
1206
 
            AS_RBRACKET:
1207
 
              begin
1208
 
                if betweenbracket then
1209
 
                  break;
1210
 
                { write error only once. }
1211
 
                if not errorflag then
1212
 
                  Message(asmr_e_invalid_constant_expression);
1213
 
                { consume tokens until we find COMMA or SEPARATOR }
1214
 
                Consume(actasmtoken);
1215
 
                errorflag:=TRUE;
1216
 
              end;
1217
 
            AS_RPAREN:
1218
 
              Begin
1219
 
                { end of ref ? }
1220
 
                if (parenlevel=0) and betweenbracket then
1221
 
                 break;
1222
 
                Consume(AS_RPAREN);
1223
 
                expr:=expr + ')';
1224
 
                dec(parenlevel);
1225
 
              end;
1226
 
            AS_SHL:
1227
 
              Begin
1228
 
                Consume(AS_SHL);
1229
 
                expr:=expr + '<';
1230
 
              end;
1231
 
            AS_SHR:
1232
 
              Begin
1233
 
                Consume(AS_SHR);
1234
 
                expr:=expr + '>';
1235
 
              end;
1236
 
            AS_SLASH:
1237
 
              Begin
1238
 
                Consume(AS_SLASH);
1239
 
                expr:=expr + '/';
1240
 
              end;
1241
 
            AS_MOD:
1242
 
              Begin
1243
 
                Consume(AS_MOD);
1244
 
                expr:=expr + '%';
1245
 
              end;
1246
 
            AS_STAR:
1247
 
              Begin
1248
 
                Consume(AS_STAR);
1249
 
                expr:=expr + '*';
1250
 
              end;
1251
 
            AS_PLUS:
1252
 
              Begin
1253
 
                Consume(AS_PLUS);
1254
 
                expr:=expr + '+';
1255
 
              end;
1256
 
            AS_MINUS:
1257
 
              Begin
1258
 
                Consume(AS_MINUS);
1259
 
                expr:=expr + '-';
1260
 
              end;
1261
 
            AS_AND:
1262
 
              Begin
1263
 
                Consume(AS_AND);
1264
 
                expr:=expr + '&';
1265
 
              end;
1266
 
            AS_NOT:
1267
 
              Begin
1268
 
                Consume(AS_NOT);
1269
 
                expr:=expr + '~';
1270
 
              end;
1271
 
            AS_XOR:
1272
 
              Begin
1273
 
                Consume(AS_XOR);
1274
 
                expr:=expr + '^';
1275
 
              end;
1276
 
            AS_OR:
1277
 
              Begin
1278
 
                Consume(AS_OR);
1279
 
                expr:=expr + '|';
1280
 
              end;
1281
 
            AS_INTNUM:
1282
 
              Begin
1283
 
                expr:=expr + actasmpattern;
1284
 
                Consume(AS_INTNUM);
1285
 
              end;
1286
 
            AS_DOLLAR:
1287
 
              begin
1288
 
                Consume(AS_DOLLAR);
1289
 
                if actasmtoken<>AS_ID then
1290
 
                 Message(asmr_e_dollar_without_identifier);
1291
 
              end;
1292
 
            AS_STRING:
1293
 
              Begin
1294
 
                l:=0;
1295
 
                case Length(actasmpattern) of
1296
 
                 1 :
1297
 
                  l:=ord(actasmpattern[1]);
1298
 
                 2 :
1299
 
                  l:=ord(actasmpattern[2]) + ord(actasmpattern[1]) shl 8;
1300
 
                 3 :
1301
 
                  l:=ord(actasmpattern[3]) +
1302
 
                     Ord(actasmpattern[2]) shl 8 + ord(actasmpattern[1]) shl 16;
1303
 
                 4 :
1304
 
                  l:=ord(actasmpattern[4]) + ord(actasmpattern[3]) shl 8 +
1305
 
                     Ord(actasmpattern[2]) shl 16 + ord(actasmpattern[1]) shl 24;
1306
 
                else
1307
 
                  Message1(asmr_e_invalid_string_as_opcode_operand,actasmpattern);
1308
 
                end;
1309
 
                str(l, tempstr);
1310
 
                expr:=expr + tempstr;
1311
 
                Consume(AS_STRING);
1312
 
              end;
1313
 
            AS_TYPE:
1314
 
              begin
1315
 
                l:=0;
1316
 
                Consume(AS_TYPE);
1317
 
                if actasmtoken<>AS_ID then
1318
 
                 Message(asmr_e_type_without_identifier)
1319
 
                else
1320
 
                 begin
1321
 
                   tempstr:=actasmpattern;
1322
 
                   Consume(AS_ID);
1323
 
                   if actasmtoken=AS_DOT then
1324
 
                    BuildRecordOffsetSize(tempstr,k,l)
1325
 
                   else
1326
 
                    begin
1327
 
                      searchsym(tempstr,sym,srsymtable);
1328
 
                      if assigned(sym) then
1329
 
                       begin
1330
 
                         case sym.typ of
1331
 
                           varsym :
1332
 
                             l:=tvarsym(sym).getsize;
1333
 
                           typedconstsym :
1334
 
                             l:=ttypedconstsym(sym).getsize;
1335
 
                           typesym :
1336
 
                             l:=ttypesym(sym).restype.def.size;
1337
 
                           else
1338
 
                             Message(asmr_e_wrong_sym_type);
1339
 
                         end;
1340
 
                       end
1341
 
                      else
1342
 
                       Message1(sym_e_unknown_id,tempstr);
1343
 
                    end;
1344
 
                 end;
1345
 
                str(l, tempstr);
1346
 
                expr:=expr + tempstr;
1347
 
              end;
1348
 
            AS_ID:
1349
 
              Begin
1350
 
                hs:='';
1351
 
                tempstr:=actasmpattern;
1352
 
                prevtok:=prevasmtoken;
1353
 
                consume(AS_ID);
1354
 
                if SearchIConstant(tempstr,l) then
1355
 
                 begin
1356
 
                   str(l, tempstr);
1357
 
                   expr:=expr + tempstr;
1358
 
                 end
1359
 
                else
1360
 
                 begin
1361
 
                   if is_locallabel(tempstr) then
1362
 
                    begin
1363
 
                      CreateLocalLabel(tempstr,hl,false);
1364
 
                      hs:=hl.name
1365
 
                    end
1366
 
                   else
1367
 
                    if SearchLabel(tempstr,hl,false) then
1368
 
                     hs:=hl.name
1369
 
                   else
1370
 
                    begin
1371
 
                      searchsym(tempstr,sym,srsymtable);
1372
 
                      if assigned(sym) then
1373
 
                       begin
1374
 
                         case sym.typ of
1375
 
                           varsym :
1376
 
                             with Tvarsym(sym) do
1377
 
                               begin
1378
 
                                 if owner.symtabletype in [localsymtable,parasymtable] then
1379
 
                                  Message(asmr_e_no_local_or_para_allowed);
1380
 
                                 hs:=mangledname;
1381
 
                               end;
1382
 
                           typedconstsym :
1383
 
                             hs:=ttypedconstsym(sym).mangledname;
1384
 
                           procsym :
1385
 
                             with Tprocsym(sym) do
1386
 
                               begin
1387
 
                                 if procdef_count>1 then
1388
 
                                   message(asmr_w_calling_overload_func);
1389
 
                                 hs:=first_procdef.mangledname;
1390
 
                               end;
1391
 
                           typesym :
1392
 
                             begin
1393
 
                               if not(ttypesym(sym).restype.def.deftype in [recorddef,objectdef]) then
1394
 
                                Message(asmr_e_wrong_sym_type);
1395
 
                             end;
1396
 
                           else
1397
 
                             Message(asmr_e_wrong_sym_type);
1398
 
                         end;
1399
 
                       end
1400
 
                      else
1401
 
                       Message1(sym_e_unknown_id,tempstr);
1402
 
                    end;
1403
 
                   { symbol found? }
1404
 
                   if hs<>'' then
1405
 
                    begin
1406
 
                      if needofs and (prevtok<>AS_DOLLAR) then
1407
 
                       Message(asmr_e_need_dollar);
1408
 
                      if asmsym='' then
1409
 
                       asmsym:=hs
1410
 
                      else
1411
 
                       Message(asmr_e_cant_have_multiple_relocatable_symbols);
1412
 
                      if (expr='') or (expr[length(expr)]='+') then
1413
 
                       begin
1414
 
                         { don't remove the + if there could be a record field }
1415
 
                         if actasmtoken<>AS_DOT then
1416
 
                          delete(expr,length(expr),1);
1417
 
                       end
1418
 
                      else
1419
 
                       Message(asmr_e_only_add_relocatable_symbol);
1420
 
                    end;
1421
 
                   if actasmtoken=AS_DOT then
1422
 
                    begin
1423
 
                      BuildRecordOffsetSize(tempstr,l,k);
1424
 
                      str(l, tempstr);
1425
 
                      expr:=expr + tempstr;
1426
 
                    end
1427
 
                   else
1428
 
                    begin
1429
 
                      if (expr='') or (expr[length(expr)] in ['+','-','/','*']) then
1430
 
                       delete(expr,length(expr),1);
1431
 
                    end;
1432
 
                 end;
1433
 
                { check if there are wrong operator used like / or mod etc. }
1434
 
                if (hs<>'') and
1435
 
                   not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,
1436
 
                                       AS_LPAREN,AS_RPAREN,AS_RBRACKET,AS_END]) then
1437
 
                 Message(asmr_e_only_add_relocatable_symbol);
1438
 
              end;
1439
 
            AS_END,
1440
 
            AS_SEPARATOR,
1441
 
            AS_COMMA:
1442
 
              break;
1443
 
          else
1444
 
            Begin
1445
 
              { write error only once. }
1446
 
              if not errorflag then
1447
 
                Message(asmr_e_invalid_constant_expression);
1448
 
              { consume tokens until we find COMMA or SEPARATOR }
1449
 
              Consume(actasmtoken);
1450
 
              errorflag:=TRUE;
1451
 
            end;
1452
 
          end;
1453
 
        Until false;
1454
 
        { calculate expression }
1455
 
        if not ErrorFlag then
1456
 
          value:=CalculateExpression(expr)
1457
 
        else
1458
 
          value:=0;
1459
 
      end;
1460
 
 
1461
 
 
1462
 
    function tattreader.BuildConstExpression(allowref,betweenbracket:boolean): longint;
1463
 
      var
1464
 
        l : longint;
1465
 
        hs : string;
1466
 
      begin
1467
 
        BuildConstSymbolExpression(allowref,betweenbracket,false,l,hs);
1468
 
        if hs<>'' then
1469
 
         Message(asmr_e_relocatable_symbol_not_allowed);
1470
 
        BuildConstExpression:=l;
1471
 
      end;
1472
 
 
1473
 
 
1474
 
    Procedure tattreader.BuildConstantOperand(oper : toperand);
1475
 
      var
1476
 
        l : longint;
1477
 
        tempstr : string;
1478
 
      begin
1479
 
        BuildConstSymbolExpression(false,false,true,l,tempstr);
1480
 
        if tempstr<>'' then
1481
 
         begin
1482
 
           oper.opr.typ:=OPR_SYMBOL;
1483
 
           oper.opr.symofs:=l;
1484
 
           oper.opr.symbol:=objectlibrary.newasmsymbol(tempstr,AB_EXTERNAL,AT_FUNCTION);
1485
 
         end
1486
 
        else
1487
 
         begin
1488
 
           oper.opr.typ:=OPR_CONSTANT;
1489
 
           oper.opr.val:=l;
1490
 
         end;
1491
 
      end;
1492
 
 
1493
 
end.
1494
 
 
1495
 
{
1496
 
  $Log: raatt.pas,v $
1497
 
  Revision 1.10  2004/03/02 00:36:33  olle
1498
 
    * big transformation of Tai_[const_]Symbol.Create[data]name*
1499
 
 
1500
 
  Revision 1.9  2004/02/07 23:28:34  daniel
1501
 
    * Take advantage of our new with statement optimization
1502
 
 
1503
 
  Revision 1.8  2003/12/25 01:25:43  peter
1504
 
    * sparc assembler reader updates
1505
 
 
1506
 
  Revision 1.7  2003/12/08 17:43:57  florian
1507
 
    * fixed ldm/stm arm assembler reading
1508
 
    * fixed a_load_reg_reg with OS_8 on ARM
1509
 
    * non supported calling conventions cause only a warning now
1510
 
 
1511
 
  Revision 1.6  2003/12/07 14:03:37  jonas
1512
 
    * go to the next character after consuming a "%"
1513
 
 
1514
 
  Revision 1.5  2003/12/03 17:39:04  florian
1515
 
    * fixed several arm calling conventions issues
1516
 
    * fixed reference reading in the assembler reader
1517
 
    * fixed a_loadaddr_ref_reg
1518
 
 
1519
 
  Revision 1.4  2003/11/29 16:27:19  jonas
1520
 
    * fixed several ppc assembler reader related problems
1521
 
    * local vars in assembler procedures now start at offset 4
1522
 
    * fixed second_int_to_bool (apparently an integer can be in  LOC_JUMP??)
1523
 
 
1524
 
  Revision 1.3  2003/11/17 23:23:47  florian
1525
 
    + first part of arm assembler reader
1526
 
 
1527
 
  Revision 1.2  2003/11/15 19:00:10  florian
1528
 
    * fixed ppc assembler reader
1529
 
 
1530
 
  Revision 1.1  2003/11/12 16:05:39  florian
1531
 
    * assembler readers OOPed
1532
 
    + typed currency constants
1533
 
    + typed 128 bit float constants if the CPU supports it
1534
 
}