* Handle possible relocation types in assembler reader using a single AS_RELTYPE token, rather than with individual tokens for each case. Since possible relocations are target-dependent, this will allow to support any amount of them without modifying the base tattreader class.

git-svn-id: trunk@33117 -
This commit is contained in:
sergei 2016-02-23 21:28:46 +00:00
parent 4e7c0d0670
commit cc3e09ee46
3 changed files with 22 additions and 22 deletions

View File

@ -26,11 +26,13 @@ Unit racpugas;
Interface Interface
uses uses
cgbase,
rautils, rautils,
raatt; raatt;
type type
tMipsReader = class(tattreader) tMipsReader = class(tattreader)
actrel: trefaddr;
function is_asmopcode(const s: string):boolean;override; function is_asmopcode(const s: string):boolean;override;
procedure BuildOperand(oper : TOperand); procedure BuildOperand(oper : TOperand);
procedure BuildOpCode(instr : TInstruction); procedure BuildOpCode(instr : TInstruction);
@ -58,7 +60,7 @@ Interface
rabase, rabase,
rgbase, rgbase,
itcpugas, itcpugas,
cgbase,cgobj cgobj
; ;
@ -91,7 +93,6 @@ Interface
len:=1; len:=1;
actasmpattern[len]:='%'; actasmpattern[len]:='%';
c:=current_scanner.asmgetchar; c:=current_scanner.asmgetchar;
{ to be a register there must be a letter and not a number }
while c in ['a'..'z','A'..'Z','0'..'9'] do while c in ['a'..'z','A'..'Z','0'..'9'] do
Begin Begin
inc(len); inc(len);
@ -100,12 +101,15 @@ Interface
end; end;
actasmpattern[0]:=chr(len); actasmpattern[0]:=chr(len);
uppervar(actasmpattern); uppervar(actasmpattern);
actrel:=addr_no;
if (actasmpattern='%HI') then if (actasmpattern='%HI') then
actasmtoken:=AS_HI actrel:=addr_high
else if (actasmpattern='%LO')then else if (actasmpattern='%LO')then
actasmtoken:=AS_LO actrel:=addr_low
else else
Message(asmr_e_invalid_reference_syntax); Message(asmr_e_invalid_reference_syntax);
if actrel<>addr_no then
actasmtoken:=AS_RELTYPE;
end; end;
@ -253,16 +257,12 @@ Interface
gotplus:=false; gotplus:=false;
end; end;
AS_HI, AS_RELTYPE:
AS_LO:
begin begin
{ Low or High part of a constant (or constant { Low or High part of a constant (or constant
memory location) } memory location) }
oper.InitRef; oper.InitRef;
if actasmtoken=AS_LO then oper.opr.ref.refaddr:=actrel;
oper.opr.ref.refaddr:=addr_low
else
oper.opr.ref.refaddr:=addr_high;
Consume(actasmtoken); Consume(actasmtoken);
Consume(AS_LPAREN); Consume(AS_LPAREN);
BuildConstSymbolExpression(false, true,false,l,tempstr,tempsymtyp); BuildConstSymbolExpression(false, true,false,l,tempstr,tempsymtyp);

View File

@ -57,7 +57,7 @@ unit raatt;
AS_SET,AS_WEAK,AS_SECTION,AS_END, AS_SET,AS_WEAK,AS_SECTION,AS_END,
{------------------ Assembler Operators --------------------} {------------------ Assembler Operators --------------------}
AS_TYPE,AS_SIZEOF,AS_VMTOFFSET,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT, AS_TYPE,AS_SIZEOF,AS_VMTOFFSET,AS_MOD,AS_SHL,AS_SHR,AS_NOT,AS_AND,AS_OR,AS_XOR,AS_NOR,AS_AT,
AS_LO,AS_HI, AS_RELTYPE, // common token for relocation types
{------------------ Target-specific directive ---------------} {------------------ Target-specific directive ---------------}
AS_TARGET_DIRECTIVE AS_TARGET_DIRECTIVE
); );
@ -82,7 +82,7 @@ unit raatt;
'.asciz','.lcomm','.comm','.single','.double','.tfloat','.tcfloat', '.asciz','.lcomm','.comm','.single','.double','.tfloat','.tcfloat',
'.data','.text','.init','.fini','.rva', '.data','.text','.init','.fini','.rva',
'.set','.weak','.section','END', '.set','.weak','.section','END',
'TYPE','SIZEOF','VMTOFFSET','%','<<','>>','!','&','|','^','~','@','lo','hi', 'TYPE','SIZEOF','VMTOFFSET','%','<<','>>','!','&','|','^','~','@','reltype',
'directive'); 'directive');
type type

View File

@ -26,10 +26,11 @@ Unit racpugas;
Interface Interface
uses uses
raatt,racpu; cgbase,raatt,racpu;
type type
tSparcReader = class(tattreader) tSparcReader = class(tattreader)
actrel: trefaddr;
function is_asmopcode(const s: string):boolean;override; function is_asmopcode(const s: string):boolean;override;
procedure handleopcode;override; procedure handleopcode;override;
procedure BuildReference(oper : tSparcoperand); procedure BuildReference(oper : tSparcoperand);
@ -56,7 +57,7 @@ Interface
scanner, scanner,
procinfo, procinfo,
rabase,rautils, rabase,rautils,
cgbase,cgobj cgobj
; ;
@ -153,12 +154,15 @@ Interface
uppervar(actasmpattern); uppervar(actasmpattern);
if is_register(actasmpattern) then if is_register(actasmpattern) then
exit; exit;
actrel:=addr_no;
if (actasmpattern='%HI') then if (actasmpattern='%HI') then
actasmtoken:=AS_HI actrel:=addr_high
else if (actasmpattern='%LO')then else if (actasmpattern='%LO')then
actasmtoken:=AS_LO actrel:=addr_low
else else
Message(asmr_e_invalid_register); Message(asmr_e_invalid_register);
if (actrel<>addr_no) then
actasmtoken:=AS_RELTYPE;
end; end;
@ -292,16 +296,12 @@ Interface
gotplus:=false; gotplus:=false;
end; end;
AS_HI, AS_RELTYPE:
AS_LO:
begin begin
{ Low or High part of a constant (or constant { Low or High part of a constant (or constant
memory location) } memory location) }
oper.InitRef; oper.InitRef;
if actasmtoken=AS_LO then oper.opr.ref.refaddr:=actrel;
oper.opr.ref.refaddr:=addr_low
else
oper.opr.ref.refaddr:=addr_high;
Consume(actasmtoken); Consume(actasmtoken);
Consume(AS_LPAREN); Consume(AS_LPAREN);
BuildConstSymbolExpression(false, true,false,l,tempstr,tempsymtyp); BuildConstSymbolExpression(false, true,false,l,tempstr,tempsymtyp);