From c53d07f7419bdb6f0dd8440c6c51849350d8ba5c Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 5 Jul 2012 21:16:02 +0000 Subject: [PATCH] Improve addr_pic support git-svn-id: trunk@21796 - --- compiler/mips/cpugas.pas | 86 ++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/compiler/mips/cpugas.pas b/compiler/mips/cpugas.pas index 54c6cfb0a9..1f36324508 100644 --- a/compiler/mips/cpugas.pas +++ b/compiler/mips/cpugas.pas @@ -31,6 +31,7 @@ unit cpugas; type TMIPSGNUAssembler = class(TGNUassembler) + nomacro, noreorder, noat : boolean; constructor create(smart: boolean); override; end; @@ -38,13 +39,13 @@ unit cpugas; procedure WriteInstruction(hp : tai);override; end; - const - use_std_regnames : boolean = - {$ifndef USE_MIPS_GAS_REGS} - true; - {$else} - false; - {$endif} + const + use_std_regnames : boolean = + {$ifndef USE_MIPS_GAS_REGS} + true; + {$else} + false; + {$endif} implementation @@ -69,14 +70,14 @@ unit cpugas; end; - function asm_regname(reg : TRegister) : string; + function asm_regname(reg : TRegister) : string; - begin - if use_std_regnames then - asm_regname:='$'+gas_std_regname(reg) - else - asm_regname:=gas_regname(reg); - end; + begin + if use_std_regnames then + asm_regname:='$'+gas_std_regname(reg) + else + asm_regname:=gas_regname(reg); + end; {****************************************************************************} { GNU MIPS Assembler writer } @@ -86,6 +87,9 @@ unit cpugas; begin inherited create(smart); InstrWriter := TMIPSInstrWriter.create(self); + nomacro:=false; + noreorder:=false; + noat:=false; end; @@ -94,8 +98,8 @@ unit cpugas; {****************************************************************************} function GetReferenceString(var ref: TReference): string; - var - hasgot : boolean; + var + hasgot : boolean; gotprefix : string; begin GetReferenceString := ''; @@ -106,13 +110,13 @@ unit cpugas; begin if assigned(symbol) then begin - GetReferenceString := symbol.Name; - if symbol.typ=AT_FUNCTION then - gotprefix:='%call16(' - else - gotprefix:='%got('; - hasgot:=true; - end; + GetReferenceString := symbol.Name; + if symbol.typ=AT_FUNCTION then + gotprefix:='%call16(' + else + gotprefix:='%got('; + hasgot:=true; + end; if offset > 0 then GetReferenceString := GetReferenceString + '+' + ToStr(offset) else if offset < 0 then @@ -124,11 +128,11 @@ unit cpugas; GetReferenceString := '%lo(' + GetReferenceString + ')'; addr_pic: begin - if hasgot then - GetReferenceString := gotprefix + GetReferenceString + ')' - else - internalerror(2012070401); - end; + if hasgot then + GetReferenceString := gotprefix + GetReferenceString + ')' + else + internalerror(2012070401); + end; end; end else @@ -148,13 +152,14 @@ unit cpugas; begin if refaddr = addr_low then GetReferenceString := '%lo(' + symbol.Name + ')' + GetReferenceString - else if refaddr = addr_pic then + else if refaddr = addr_pic then begin - if hasgot then - GetReferenceString := gotprefix + GetReferenceString + ')' - else - internalerror(2012070401); - end + if symbol.typ=AT_FUNCTION then + gotprefix:='%call16(' + else + gotprefix:='%got('; + GetReferenceString := gotprefix + symbol.Name + ')' + GetReferenceString; + end else GetReferenceString := symbol.Name + {'+' +} GetReferenceString; end; @@ -230,6 +235,11 @@ unit cpugas; end; } + function is_macro_instruction(op : TAsmOp) : boolean; + begin + is_macro_instruction := + (op=A_SEQ) or (op=A_SNE); + end; procedure TMIPSInstrWriter.WriteInstruction(hp: Tai); var @@ -260,21 +270,25 @@ unit cpugas; begin s := #9 + '.set' + #9 + 'macro'; owner.AsmWriteLn(s); + TMIPSGNUAssembler(owner).nomacro:=false; end; A_P_SET_REORDER: begin s := #9 + '.set' + #9 + 'reorder'; owner.AsmWriteLn(s); + TMIPSGNUAssembler(owner).noreorder:=false; end; A_P_SET_NOMACRO: begin s := #9 + '.set' + #9 + 'nomacro'; owner.AsmWriteLn(s); + TMIPSGNUAssembler(owner).nomacro:=true; end; A_P_SET_NOREORDER: begin s := #9 + '.set' + #9 + 'noreorder'; owner.AsmWriteLn(s); + TMIPSGNUAssembler(owner).noreorder:=true; end; A_P_SW: begin @@ -337,6 +351,8 @@ unit cpugas; end; else begin + if is_macro_instruction(op) and TMIPSGNUAssembler(owner).nomacro then + owner.AsmWriteln(#9'.set'#9'macro'); s := #9 + gas_op2str[op] + cond2str[taicpu(hp).condition]; if taicpu(hp).delayslot_annulled then s := s + ',a'; @@ -347,6 +363,8 @@ unit cpugas; s := s + ',' + getopstr(taicpu(hp).oper[i]^); end; owner.AsmWriteLn(s); + if is_macro_instruction(op) and TMIPSGNUAssembler(owner).nomacro then + owner.AsmWriteln(#9'.set'#9'nomacro'); end; end; end;