* sparc assembler reader updates

This commit is contained in:
peter 2003-12-25 01:25:43 +00:00
parent 06442fa677
commit e380119e8c
2 changed files with 133 additions and 186 deletions

View File

@ -55,7 +55,8 @@ unit raatt;
AS_ASCIIZ,AS_LCOMM,AS_COMM,AS_SINGLE,AS_DOUBLE,AS_EXTENDED,
AS_DATA,AS_TEXT,AS_END,
{------------------ Assembler Operators --------------------}
AS_TYPE,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT);
AS_TYPE,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT,
AS_LO,AS_HI);
tasmkeyword = string[10];
@ -75,7 +76,7 @@ unit raatt;
'.align','.balign','.p2align','.ascii',
'.asciz','.lcomm','.comm','.single','.double','.tfloat',
'.data','.text','END',
'TYPE','%','<<','>>','!','&','|','^','~','@');
'TYPE','%','<<','>>','!','&','|','^','~','@','lo','hi');
type
tattreader = class(tasmreader)
@ -1202,6 +1203,17 @@ unit raatt;
expr:=expr + '(';
inc(parenlevel);
end;
AS_RBRACKET:
begin
if betweenbracket then
break;
{ write error only once. }
if not errorflag then
Message(asmr_e_invalid_constant_expression);
{ consume tokens until we find COMMA or SEPARATOR }
Consume(actasmtoken);
errorflag:=TRUE;
end;
AS_RPAREN:
Begin
{ end of ref ? }
@ -1417,7 +1429,9 @@ unit raatt;
end;
end;
{ check if there are wrong operator used like / or mod etc. }
if (hs<>'') and not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,AS_LPAREN,AS_END]) then
if (hs<>'') and
not(actasmtoken in [AS_MINUS,AS_PLUS,AS_COMMA,AS_SEPARATOR,
AS_LPAREN,AS_RPAREN,AS_RBRACKET,AS_END]) then
Message(asmr_e_only_add_relocatable_symbol);
end;
AS_END,
@ -1478,7 +1492,10 @@ end.
{
$Log$
Revision 1.7 2003-12-08 17:43:57 florian
Revision 1.8 2003-12-25 01:25:43 peter
* sparc assembler reader updates
Revision 1.7 2003/12/08 17:43:57 florian
* fixed ldm/stm arm assembler reading
* fixed a_load_reg_reg with OS_8 on ARM
* non supported calling conventions cause only a warning now

View File

@ -119,126 +119,74 @@ Interface
Procedure tSparcReader.BuildReference(oper : tSparcoperand);
procedure Consume_RParen;
begin
if actasmtoken <> AS_RPAREN then
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
end
else
begin
Consume(AS_RPAREN);
if not (actasmtoken in [AS_COMMA,AS_SEPARATOR,AS_END]) then
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
end;
end;
end;
var
l : longint;
regs : byte;
hasimm : boolean;
begin
Consume(AS_LPAREN);
Case actasmtoken of
AS_INTNUM,
AS_MINUS,
AS_PLUS:
Begin
{ offset(offset) is invalid }
If oper.opr.Ref.Offset <> 0 Then
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
End
Else
Begin
oper.opr.Ref.Offset:=BuildConstExpression(false,true);
Consume(AS_RPAREN);
if actasmtoken=AS_MOD then
ReadPercent(oper);
end;
exit;
End;
AS_REGISTER: { (reg ... }
Begin
if ((oper.opr.typ=OPR_REFERENCE) and (oper.opr.ref.base<>NR_NO)) or
((oper.opr.typ=OPR_LOCAL) and (oper.opr.localsym.localloc.loc<>LOC_REGISTER)) then
message(asmr_e_cannot_index_relative_var);
oper.opr.ref.base:=actasmregister;
Consume(AS_REGISTER);
{ can either be a register or a right parenthesis }
{ (reg) }
if actasmtoken=AS_RPAREN then
Begin
Consume_RParen;
exit;
end;
{ (reg,reg .. }
Consume(AS_COMMA);
if (actasmtoken=AS_REGISTER) and
(oper.opr.Ref.Offset = 0) then
Begin
oper.opr.ref.index:=actasmregister;
Consume(AS_REGISTER);
Consume_RParen;
end
else
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(false);
end;
end; {end case }
AS_ID:
Begin
ReadSym(oper);
{ add a constant expression? }
if (actasmtoken=AS_PLUS) then
begin
l:=BuildConstExpression(true,true);
case oper.opr.typ of
OPR_CONSTANT :
inc(oper.opr.val,l);
OPR_LOCAL :
inc(oper.opr.localsymofs,l);
OPR_REFERENCE :
inc(oper.opr.ref.offset,l);
else
internalerror(200309202);
end;
end;
Consume(AS_RPAREN);
if actasmtoken=AS_MOD then
ReadPercent(oper);
End;
AS_COMMA: { (, ... can either be scaling, or index }
Begin
Consume(AS_COMMA);
{ Index }
if (actasmtoken=AS_REGISTER) then
Begin
oper.opr.ref.index:=actasmregister;
Consume(AS_REGISTER);
{ check for scaling ... }
Consume_RParen;
end
else
begin
regs:=0;
hasimm:=false;
Consume(AS_LBRACKET);
repeat
Case actasmtoken of
AS_INTNUM,
AS_MINUS,
AS_PLUS:
Begin
if hasimm or (regs>1) then
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
break;
End;
oper.opr.Ref.Offset:=BuildConstExpression(false,true);
hasimm:=true;
End;
AS_REGISTER:
Begin
if regs<2 then
begin
if regs=0 then
oper.opr.ref.base:=actasmregister
else
oper.opr.ref.index:=actasmregister;
inc(regs);
end
else
begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
break;
end;
Consume(AS_REGISTER);
end;
AS_ID:
Begin
l:=BuildConstExpression(true,true);
inc(oper.opr.ref.offset,l);
End;
AS_RBRACKET:
begin
if (regs=0) and (not hasimm) then
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(false);
end;
end;
else
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(false);
Consume(AS_RBRACKET);
break;
end;
else
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(false);
break;
end;
end;
end;
until false;
end;
procedure TSparcReader.handlepercent;
var
len : longint;
@ -257,18 +205,20 @@ Interface
uppervar(actasmpattern);
if is_register(actasmpattern) then
exit;
if(actasmpattern='%HI')or(actasmpattern='%LO')then
actasmtoken:=AS_MOD
if (actasmpattern='%HI') then
actasmtoken:=AS_HI
else if (actasmpattern='%LO')then
actasmtoken:=AS_LO
else
Message(asmr_e_invalid_register);
end;
Procedure tSparcReader.BuildOperand(oper : tSparcoperand);
var
expr : string;
typesize,l : longint;
procedure AddLabelOperand(hl:tasmlabel);
begin
if not(actasmtoken in [AS_PLUS,AS_MINUS,AS_LPAREN]) and
@ -328,60 +278,13 @@ Interface
end;
end;
function MaybeBuildReference:boolean;
{ Try to create a reference, if not a reference is found then false
is returned }
begin
MaybeBuildReference:=true;
case actasmtoken of
AS_INTNUM,
AS_MINUS,
AS_PLUS:
Begin
oper.opr.ref.offset:=BuildConstExpression(True,False);
if actasmtoken<>AS_LPAREN then
Message(asmr_e_invalid_reference_syntax)
else
BuildReference(oper);
end;
AS_LPAREN:
BuildReference(oper);
AS_ID: { only a variable is allowed ... }
Begin
ReadSym(oper);
case actasmtoken of
AS_END,
AS_SEPARATOR,
AS_COMMA: ;
AS_LPAREN:
BuildReference(oper);
else
Begin
Message(asmr_e_invalid_reference_syntax);
Consume(actasmtoken);
end;
end; {end case }
end;
else
MaybeBuildReference:=false;
end; { end case }
end;
var
tempreg : tregister;
tempstr : string;
hl : tasmlabel;
ofs : longint;
Begin
expr:='';
case actasmtoken of
AS_LPAREN: { Memory reference or constant expression }
Begin
oper.InitRef;
BuildReference(oper);
end;
AS_INTNUM,
AS_MINUS,
AS_PLUS,
@ -391,14 +294,42 @@ Interface
{ This must absolutely be followed by ( }
oper.InitRef;
oper.opr.ref.offset:=BuildConstExpression(True,False);
if actasmtoken<>AS_LPAREN then
begin
ofs:=oper.opr.ref.offset;
BuildConstantOperand(oper);
inc(oper.opr.val,ofs);
end
end;
AS_LBRACKET :
begin
{ memory reference }
BuildReference(oper);
end;
AS_HI,
AS_LO:
begin
{ Low or High part of a constant (or constant
memory location) }
oper.InitRef;
if actasmtoken=AS_LO then
oper.opr.ref.symaddr:=refs_lo
else
BuildReference(oper);
oper.opr.ref.symaddr:=refs_hi;
Consume(actasmtoken);
Consume(AS_LPAREN);
BuildConstSymbolExpression(false, true,false,l,tempstr);
if not assigned(oper.opr.ref.symbol) then
oper.opr.ref.symbol:=objectlibrary.newasmsymbol(tempstr)
else
Message(asmr_e_cant_have_multiple_relocatable_symbols);
case oper.opr.typ of
OPR_CONSTANT :
inc(oper.opr.val,l);
OPR_LOCAL :
inc(oper.opr.localsymofs,l);
OPR_REFERENCE :
inc(oper.opr.ref.offset,l);
else
internalerror(200309202);
end;
Consume(AS_RPAREN);
end;
AS_ID: { A constant expression, or a Variable ref. }
@ -503,9 +434,6 @@ Interface
end;
end
end;
{ Do we have a indexing reference, then parse it also }
if actasmtoken=AS_LPAREN then
BuildReference(oper);
end;
AS_REGISTER: { Register, a variable reference or a constant reference }
@ -520,7 +448,7 @@ Interface
oper.opr.typ:=OPR_REGISTER;
oper.opr.reg:=tempreg;
end
else
else
Message(asmr_e_syn_operand);
end;
AS_END,
@ -625,12 +553,11 @@ Interface
because we take the whole remaining string without the leading B }
actopcode := A_Bxx;
for cond:=low(TAsmCond) to high(TAsmCond) do
if(cond in [C_AE])and(Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
begin
WriteLn('Bxx');
actasmtoken:=AS_OPCODE;
is_asmopcode:=true;
end;
if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
begin
actasmtoken:=AS_OPCODE;
is_asmopcode:=true;
end;
end;
end;
procedure tSparcReader.ConvertCalljmp(instr : tSparcinstruction);
@ -694,7 +621,10 @@ initialization
end.
{
$Log$
Revision 1.2 2003-12-10 13:16:36 mazen
Revision 1.3 2003-12-25 01:25:43 peter
* sparc assembler reader updates
Revision 1.2 2003/12/10 13:16:36 mazen
* improve hadlign %hi and %lo operators
Revision 1.1 2003/12/08 13:02:21 mazen