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
5
Does the parsing for the GAS styled inline assembler.
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.
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.
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.
21
****************************************************************************
35
cpubase,cpuinfo,aasmbase,aasmtai,aasmcpu,
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,
61
tasmkeyword = string[10];
64
{ These tokens should be modified accordingly to the modifications }
65
{ in the different enumerations. }
66
firstdirective = AS_DB;
67
lastdirective = AS_END;
69
token2str : array[tasmtoken] of tasmkeyword=(
70
'','Label','LLabel','string','integer',
72
')',':','.','+','-','*',
73
';','identifier','register','opcode','/','$',
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');
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;
100
function consume(t : tasmtoken):boolean;
101
procedure RecoverConsume(allowcomma:boolean);
102
procedure handlepercent;virtual;
104
tcattreader = class of tattreader;
107
cattreader : tcattreader;
117
symbase,symtype,symsym,symtable,
124
procedure tattreader.SetupTables;
125
{ creates uppercased symbol tables for speed access }
128
str2opentry: tstr2opentry;
131
iasmops:=TDictionary.Create;
132
iasmops.delete_doubles:=true;
133
for i:=firstop to lastop do
135
str2opentry:=tstr2opentry.createname(upper(gas_op2str[i]));
137
iasmops.insert(str2opentry);
142
function tattreader.is_asmdirective(const s: string):boolean;
147
{ GNU as is also not casesensitive with this }
149
for i:=firstdirective to lastdirective do
150
if hs=token2str[i] then
153
is_asmdirective:=true;
156
is_asmdirective:=false;
160
function tattreader.is_register(const s:string):boolean;
163
actasmregister:=gas_regnum_search(lower(s));
164
if actasmregister<>NR_NO then
167
actasmtoken:=AS_REGISTER;
172
function tattreader.is_locallabel(const s: string):boolean;
174
is_locallabel:=(length(s)>=2) and (s[1]='.') and (s[2]='L');
178
procedure tattreader.handlepercent;
180
c:=current_scanner.asmgetchar;
185
procedure tattreader.GetToken;
189
srsymtable : tsymtable;
191
{ save old token and reset new token }
192
prevasmtoken:=actasmtoken;
193
actasmtoken:=AS_NONE;
196
{ while space and tab , continue scan... }
197
while c in [' ',#9] do
198
c:=current_scanner.asmgetchar;
201
if not (c in [#10,#13,';']) then
202
current_scanner.gettokenpos;
204
if not (c in [#10,#13,'{',';']) then
205
current_scanner.gettokenpos;
208
{ Local Label, Label, Directive, Prefix or Opcode }
210
if firsttoken and not(c in [#10,#13,';']) then
212
if firsttoken and not(c in [#10,#13,'{',';']) then
217
{ directive or local label }
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
227
actasmpattern[len]:=c;
228
c:=current_scanner.asmgetchar;
230
actasmpattern[0]:=chr(len);
231
{ this is a local label... }
232
if (c=':') and is_locallabel(actasmpattern) then
234
{ local variables are case sensitive }
235
actasmtoken:=AS_LLABEL;
236
c:=current_scanner.asmgetchar;
240
{ must be a directive }
243
{ directives are case sensitive!! }
244
if is_asmdirective(actasmpattern) then
246
Message1(asmr_e_not_directive_or_local_symbol,actasmpattern);
249
{ only opcodes and global labels are allowed now. }
250
while c in ['A'..'Z','a'..'z','0'..'9','_'] do
253
actasmpattern[len]:=c;
254
c:=current_scanner.asmgetchar;
256
actasmpattern[0]:=chr(len);
260
actasmtoken:=AS_LABEL;
261
{ let us point to the next character }
262
c:=current_scanner.asmgetchar;
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)
274
actasmpattern:=actasmpattern+c;
275
c:=current_scanner.asmgetchar;
280
If is_asmopcode(upper(actasmpattern)) then
282
uppervar(actasmpattern);
285
{ End of assemblerblock ? }
286
if upper(actasmpattern) = 'END' then
291
message1(asmr_e_unknown_opcode,actasmpattern);
292
actasmtoken:=AS_NONE;
294
else { else firsttoken }
295
{ Here we must handle all possible cases }
298
'.' : { possiblities : - local label reference , such as in jmp @local1 }
299
{ - field of object/record }
302
if (prevasmtoken in [AS_ID,AS_RPAREN]) then
304
c:=current_scanner.asmgetchar;
309
c:=current_scanner.asmgetchar;
310
while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
312
actasmpattern:=actasmpattern + c;
313
c:=current_scanner.asmgetchar;
315
if is_asmdirective(actasmpattern) then
317
{ local label references and directives }
318
{ are case sensitive }
323
{ identifier, register, prefix or directive }
324
'_','A'..'Z','a'..'z':
327
while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
330
actasmpattern[len]:=c;
331
c:=current_scanner.asmgetchar;
333
actasmpattern[0]:=chr(len);
334
uppervar(actasmpattern);
336
{ only x86 architectures have instruction prefixes }
338
{ Opcode, can only be when the previous was a prefix }
339
If is_prefix(actopcode) and is_asmopcode(actasmpattern) then
341
uppervar(actasmpattern);
345
{ check for end which is a reserved word unlike the opcodes }
346
if actasmpattern = 'END' then
351
if actasmpattern = 'TYPE' then
353
actasmtoken:=AS_TYPE;
356
if is_register(actasmpattern) then
358
actasmtoken:=AS_REGISTER;
361
{ if next is a '.' and this is a unitsym then we also need to
362
parse the identifier }
365
searchsym(actasmpattern,srsym,srsymtable);
366
if assigned(srsym) and
367
(srsym.typ=unitsym) and
368
(srsym.owner.unitid=0) then
370
actasmpattern:=actasmpattern+c;
371
c:=current_scanner.asmgetchar;
372
while c in ['A'..'Z','a'..'z','0'..'9','_','$'] do
374
actasmpattern:=actasmpattern + upcase(c);
375
c:=current_scanner.asmgetchar;
383
'%' : { register or modulo }
386
'1'..'9': { integer number }
389
while c in ['0'..'9'] do
392
actasmpattern[len]:=c;
393
c:=current_scanner.asmgetchar;
395
actasmpattern[0]:=chr(len);
396
actasmpattern:=tostr(ValDecimal(actasmpattern));
397
actasmtoken:=AS_INTNUM;
400
'0' : { octal,hexa,real or binary number. }
403
c:=current_scanner.asmgetchar;
407
c:=current_scanner.asmgetchar;
408
while c in ['0','1'] do
410
actasmpattern:=actasmpattern + c;
411
c:=current_scanner.asmgetchar;
413
actasmpattern:=tostr(ValBinary(actasmpattern));
414
actasmtoken:=AS_INTNUM;
419
c:=current_scanner.asmgetchar;
420
{ get ridd of the 0d }
421
if (c in ['+','-']) then
424
c:=current_scanner.asmgetchar;
428
while c in ['0'..'9'] do
430
actasmpattern:=actasmpattern + c;
431
c:=current_scanner.asmgetchar;
435
actasmpattern:=actasmpattern + c;
436
c:=current_scanner.asmgetchar;
437
while c in ['0'..'9'] do
439
actasmpattern:=actasmpattern + c;
440
c:=current_scanner.asmgetchar;
442
if upcase(c) = 'E' then
444
actasmpattern:=actasmpattern + c;
445
c:=current_scanner.asmgetchar;
446
if (c in ['+','-']) then
448
actasmpattern:=actasmpattern + c;
449
c:=current_scanner.asmgetchar;
451
while c in ['0'..'9'] do
453
actasmpattern:=actasmpattern + c;
454
c:=current_scanner.asmgetchar;
457
actasmtoken:=AS_REALNUM;
462
Message1(asmr_e_invalid_float_const,actasmpattern+c);
463
actasmtoken:=AS_NONE;
468
c:=current_scanner.asmgetchar;
469
while c in ['0'..'9','a'..'f','A'..'F'] do
471
actasmpattern:=actasmpattern + c;
472
c:=current_scanner.asmgetchar;
474
actasmpattern:=tostr(ValHexaDecimal(actasmpattern));
475
actasmtoken:=AS_INTNUM;
480
actasmpattern:=actasmpattern + c;
481
while c in ['0'..'7'] do
483
actasmpattern:=actasmpattern + c;
484
c:=current_scanner.asmgetchar;
486
actasmpattern:=tostr(ValOctal(actasmpattern));
487
actasmtoken:=AS_INTNUM;
490
else { octal number zero value...}
492
actasmpattern:=tostr(ValOctal(actasmpattern));
493
actasmtoken:=AS_INTNUM;
501
c:=current_scanner.asmgetchar;
507
current_scanner.in_asm_string:=true;
510
c:=current_scanner.asmgetchar;
514
{ copy also the next char so \" is parsed correctly }
515
actasmpattern:=actasmpattern+c;
516
c:=current_scanner.asmgetchar;
517
actasmpattern:=actasmpattern+c;
521
c:=current_scanner.asmgetchar;
525
Message(scan_f_string_exceeds_line);
527
actasmpattern:=actasmpattern+c;
530
actasmpattern:=EscapeToPascal(actasmpattern);
531
actasmtoken:=AS_STRING;
532
current_scanner.in_asm_string:=false;
538
current_scanner.in_asm_string:=true;
541
c:=current_scanner.asmgetchar;
545
{ copy also the next char so \" is parsed correctly }
546
actasmpattern:=actasmpattern+c;
547
c:=current_scanner.asmgetchar;
548
actasmpattern:=actasmpattern+c;
552
c:=current_scanner.asmgetchar;
556
Message(scan_f_string_exceeds_line);
558
actasmpattern:=actasmpattern+c;
561
actasmpattern:=EscapeToPascal(actasmpattern);
562
actasmtoken:=AS_STRING;
563
current_scanner.in_asm_string:=false;
569
actasmtoken:=AS_DOLLAR;
570
c:=current_scanner.asmgetchar;
576
actasmtoken:=AS_HASH;
577
c:=current_scanner.asmgetchar;
583
actasmtoken:=AS_LBRACKET;
584
c:=current_scanner.asmgetchar;
590
actasmtoken:=AS_RBRACKET;
591
c:=current_scanner.asmgetchar;
595
// the arm assembler uses { ... } for register sets
598
actasmtoken:=AS_LSBRACKET;
599
c:=current_scanner.asmgetchar;
605
actasmtoken:=AS_RSBRACKET;
606
c:=current_scanner.asmgetchar;
613
actasmtoken:=AS_COMMA;
614
c:=current_scanner.asmgetchar;
621
c:=current_scanner.asmgetchar;
623
c:=current_scanner.asmgetchar;
630
c:=current_scanner.asmgetchar;
632
c:=current_scanner.asmgetchar;
639
c:=current_scanner.asmgetchar;
646
c:=current_scanner.asmgetchar;
653
actasmtoken:=AS_LPAREN;
654
c:=current_scanner.asmgetchar;
660
actasmtoken:=AS_RPAREN;
661
c:=current_scanner.asmgetchar;
667
actasmtoken:=AS_COLON;
668
c:=current_scanner.asmgetchar;
674
actasmtoken:=AS_PLUS;
675
c:=current_scanner.asmgetchar;
681
actasmtoken:=AS_MINUS;
682
c:=current_scanner.asmgetchar;
688
actasmtoken:=AS_STAR;
689
c:=current_scanner.asmgetchar;
695
actasmtoken:=AS_SLASH;
696
c:=current_scanner.asmgetchar;
703
c:=current_scanner.asmgetchar;
710
c:=current_scanner.asmgetchar;
719
{ the comment is read by asmgetchar }
720
c:=current_scanner.asmgetchar;
722
actasmtoken:=AS_SEPARATOR;
727
current_scanner.illegal_char(c);
733
function tattreader.consume(t : tasmtoken):boolean;
736
if t<>actasmtoken then
738
Message2(scan_f_syn_expected,token2str[t],token2str[actasmtoken]);
743
until actasmtoken<>AS_NONE;
747
procedure tattreader.RecoverConsume(allowcomma:boolean);
749
While not (actasmtoken in [AS_SEPARATOR,AS_END]) do
751
if allowcomma and (actasmtoken=AS_COMMA) then
753
Consume(actasmtoken);
758
Procedure tattreader.BuildConstant(maxvalue: longint);
769
if length(expr) > 1 then
770
Message(asmr_e_string_not_allowed_as_const);
773
AS_COMMA: Consume(AS_COMMA);
777
Message(asmr_e_invalid_string_expression);
779
ConcatString(curlist,expr);
788
BuildConstSymbolExpression(false,false,false,value,asmsym);
791
if maxvalue<>longint($ffffffff) then
792
Message(asmr_w_32bit_const_for_address);
793
ConcatConstSymbol(curlist,asmsym,value)
796
ConcatConstant(curlist,value,maxvalue);
805
Message(asmr_e_syn_constant);
806
RecoverConsume(false);
813
Procedure tattreader.BuildRealConstant(typ : tfloattype);
825
if actasmtoken=AS_PLUS then
828
if actasmtoken=AS_MINUS then
844
Message(asmr_e_invalid_float_expr);
846
ConcatRealConstant(curlist,r,typ);
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
863
Message(asmr_e_invalid_float_expr);
865
ConcatRealConstant(curlist,r,typ);
878
Consume(actasmtoken);
879
if not errorflag then
880
Message(asmr_e_invalid_float_expr);
888
Procedure tattreader.BuildStringConstant(asciiz: boolean);
901
ConcatPasString(curlist,expr);
915
Consume(actasmtoken);
916
if not errorflag then
917
Message(asmr_e_invalid_string_expression);
925
Function tattreader.Assemble: tlinkedlist;
932
Message1(asmr_d_start_reading,'GNU AS');
934
{ sets up all opcode and register tables in uppercase }
935
if not _asmsorted then
940
curlist:=TAAsmoutput.Create;
942
{ setup label linked list }
943
LocalLabelList:=TLocalLabelList.Create;
945
c:=current_scanner.asmgetcharstart;
952
if CreateLocalLabel(actasmpattern,hl,true) then
953
ConcatLabel(curlist,hl);
959
if SearchLabel(upper(actasmpattern),hl,true) then
960
ConcatLabel(curlist,hl)
962
Message1(asmr_e_unknown_label_identifier,actasmpattern);
969
BuildConstant($ffff);
974
curList.Concat(Tai_section.Create(sec_data));
981
curList.Concat(Tai_section.Create(sec_code));
995
BuildConstant(longint($ffffffff));
1001
BuildRealConstant(s64comp);
1007
BuildRealConstant(s32real);
1013
BuildRealConstant(s64real);
1018
Consume(AS_EXTENDED);
1019
BuildRealConstant(s80real);
1025
if actasmtoken=AS_ID then
1026
ConcatPublic(curlist,actasmpattern);
1028
if actasmtoken<>AS_SEPARATOR then
1029
Consume(AS_SEPARATOR);
1035
l1:=BuildConstExpression(false,false);
1036
if (target_info.system in [system_i386_GO32V2]) then
1039
if (l1>=0) and (l1<=16) then
1047
ConcatAlign(curlist,l1);
1048
Message(asmr_n_align_is_target_specific);
1049
if actasmtoken<>AS_SEPARATOR then
1050
Consume(AS_SEPARATOR);
1056
ConcatAlign(curlist,BuildConstExpression(false,false));
1057
if actasmtoken<>AS_SEPARATOR then
1058
Consume(AS_SEPARATOR);
1063
Consume(AS_P2ALIGN);
1064
l1:=BuildConstExpression(false,false);
1066
if (l1>=0) and (l1<=16) then
1073
ConcatAlign(curlist,l1);
1074
if actasmtoken<>AS_SEPARATOR then
1075
Consume(AS_SEPARATOR);
1081
BuildStringConstant(TRUE);
1087
BuildStringConstant(FALSE);
1093
commname:=actasmpattern;
1096
ConcatLocalBss(commname,BuildConstExpression(false,false));
1097
if actasmtoken<>AS_SEPARATOR then
1098
Consume(AS_SEPARATOR);
1104
commname:=actasmpattern;
1107
ConcatGlobalBss(commname,BuildConstExpression(false,false));
1108
if actasmtoken<>AS_SEPARATOR then
1109
Consume(AS_SEPARATOR);
1119
Consume(AS_SEPARATOR);
1124
break; { end assembly block }
1129
Message(asmr_e_syntax_error);
1130
RecoverConsume(false);
1134
{ Check LocalLabelList }
1135
LocalLabelList.CheckEmitted;
1136
LocalLabelList.Free;
1137
{ are we back in the code section? }
1138
if lasTSec<>sec_code then
1140
Message(asmr_w_assembler_code_not_returned_to_text);
1141
curList.Concat(Tai_section.Create(sec_code));
1143
{ Return the list in an asmnode }
1145
Message1(asmr_d_finish_reading,'GNU AS');
1149
{*****************************************************************************
1151
*****************************************************************************}
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 }
1163
while (actasmtoken=AS_DOT) do
1166
if actasmtoken=AS_ID then
1167
s:=s+'.'+actasmpattern;
1168
if not Consume(AS_ID) then
1170
RecoverConsume(true);
1174
if not GetRecordOffsetSize(s,offset,size) then
1175
Message(asmr_e_building_record_offset);
1179
procedure tattreader.BuildConstSymbolExpression(allowref,betweenbracket,needofs:boolean;var value:longint;var asmsym:string);
1181
hs,tempstr,expr : string;
1182
parenlevel,l,k : longint;
1183
errorflag : boolean;
1184
prevtok : tasmtoken;
1186
srsymtable : tsymtable;
1200
if allowref and (prevasmtoken in [AS_INTNUM,AS_ID]) then
1208
if betweenbracket then
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);
1220
if (parenlevel=0) and betweenbracket then
1283
expr:=expr + actasmpattern;
1289
if actasmtoken<>AS_ID then
1290
Message(asmr_e_dollar_without_identifier);
1295
case Length(actasmpattern) of
1297
l:=ord(actasmpattern[1]);
1299
l:=ord(actasmpattern[2]) + ord(actasmpattern[1]) shl 8;
1301
l:=ord(actasmpattern[3]) +
1302
Ord(actasmpattern[2]) shl 8 + ord(actasmpattern[1]) shl 16;
1304
l:=ord(actasmpattern[4]) + ord(actasmpattern[3]) shl 8 +
1305
Ord(actasmpattern[2]) shl 16 + ord(actasmpattern[1]) shl 24;
1307
Message1(asmr_e_invalid_string_as_opcode_operand,actasmpattern);
1310
expr:=expr + tempstr;
1317
if actasmtoken<>AS_ID then
1318
Message(asmr_e_type_without_identifier)
1321
tempstr:=actasmpattern;
1323
if actasmtoken=AS_DOT then
1324
BuildRecordOffsetSize(tempstr,k,l)
1327
searchsym(tempstr,sym,srsymtable);
1328
if assigned(sym) then
1332
l:=tvarsym(sym).getsize;
1334
l:=ttypedconstsym(sym).getsize;
1336
l:=ttypesym(sym).restype.def.size;
1338
Message(asmr_e_wrong_sym_type);
1342
Message1(sym_e_unknown_id,tempstr);
1346
expr:=expr + tempstr;
1351
tempstr:=actasmpattern;
1352
prevtok:=prevasmtoken;
1354
if SearchIConstant(tempstr,l) then
1357
expr:=expr + tempstr;
1361
if is_locallabel(tempstr) then
1363
CreateLocalLabel(tempstr,hl,false);
1367
if SearchLabel(tempstr,hl,false) then
1371
searchsym(tempstr,sym,srsymtable);
1372
if assigned(sym) then
1376
with Tvarsym(sym) do
1378
if owner.symtabletype in [localsymtable,parasymtable] then
1379
Message(asmr_e_no_local_or_para_allowed);
1383
hs:=ttypedconstsym(sym).mangledname;
1385
with Tprocsym(sym) do
1387
if procdef_count>1 then
1388
message(asmr_w_calling_overload_func);
1389
hs:=first_procdef.mangledname;
1393
if not(ttypesym(sym).restype.def.deftype in [recorddef,objectdef]) then
1394
Message(asmr_e_wrong_sym_type);
1397
Message(asmr_e_wrong_sym_type);
1401
Message1(sym_e_unknown_id,tempstr);
1406
if needofs and (prevtok<>AS_DOLLAR) then
1407
Message(asmr_e_need_dollar);
1411
Message(asmr_e_cant_have_multiple_relocatable_symbols);
1412
if (expr='') or (expr[length(expr)]='+') then
1414
{ don't remove the + if there could be a record field }
1415
if actasmtoken<>AS_DOT then
1416
delete(expr,length(expr),1);
1419
Message(asmr_e_only_add_relocatable_symbol);
1421
if actasmtoken=AS_DOT then
1423
BuildRecordOffsetSize(tempstr,l,k);
1425
expr:=expr + tempstr;
1429
if (expr='') or (expr[length(expr)] in ['+','-','/','*']) then
1430
delete(expr,length(expr),1);
1433
{ check if there are wrong operator used like / or mod etc. }
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);
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);
1454
{ calculate expression }
1455
if not ErrorFlag then
1456
value:=CalculateExpression(expr)
1462
function tattreader.BuildConstExpression(allowref,betweenbracket:boolean): longint;
1467
BuildConstSymbolExpression(allowref,betweenbracket,false,l,hs);
1469
Message(asmr_e_relocatable_symbol_not_allowed);
1470
BuildConstExpression:=l;
1474
Procedure tattreader.BuildConstantOperand(oper : toperand);
1479
BuildConstSymbolExpression(false,false,true,l,tempstr);
1482
oper.opr.typ:=OPR_SYMBOL;
1484
oper.opr.symbol:=objectlibrary.newasmsymbol(tempstr,AB_EXTERNAL,AT_FUNCTION);
1488
oper.opr.typ:=OPR_CONSTANT;
1497
Revision 1.10 2004/03/02 00:36:33 olle
1498
* big transformation of Tai_[const_]Symbol.Create[data]name*
1500
Revision 1.9 2004/02/07 23:28:34 daniel
1501
* Take advantage of our new with statement optimization
1503
Revision 1.8 2003/12/25 01:25:43 peter
1504
* sparc assembler reader updates
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
1511
Revision 1.6 2003/12/07 14:03:37 jonas
1512
* go to the next character after consuming a "%"
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
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??)
1524
Revision 1.3 2003/11/17 23:23:47 florian
1525
+ first part of arm assembler reader
1527
Revision 1.2 2003/11/15 19:00:10 florian
1528
* fixed ppc assembler reader
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