Ver Fonte

Improve addr_pic support

git-svn-id: trunk@21796 -
pierre há 13 anos atrás
pai
commit
c53d07f741
1 ficheiros alterados com 52 adições e 34 exclusões
  1. 52 34
      compiler/mips/cpugas.pas

+ 52 - 34
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;