mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 08:29:32 +01:00
* sparc assembler reader updates
This commit is contained in:
parent
06442fa677
commit
e380119e8c
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user