Kaynağa Gözat

* Handle addr_pic { for small GOT table with GOT13 relocations, limited to 8K table }
+ Add $PIC to assembler commmandline.

git-svn-id: trunk@22475 -

pierre 13 yıl önce
ebeveyn
işleme
e0ff818a51
1 değiştirilmiş dosya ile 44 ekleme ve 12 silme
  1. 44 12
      compiler/sparc/cpugas.pas

+ 44 - 12
compiler/sparc/cpugas.pas

@@ -27,7 +27,8 @@ interface
 
     uses
       cpubase,
-      aasmtai,aasmdata,aasmcpu,assemble,aggas;
+      aasmtai,aasmdata,aasmcpu,assemble,aggas,
+      cgutils;
 
     type
       TGasSPARC=class(TGnuAssembler)
@@ -36,13 +37,15 @@ interface
 
      TSPARCInstrWriter=class(TCPUInstrWriter)
        procedure WriteInstruction(hp:Tai);override;
+       function GetReferenceString(var ref : TReference):string;
+       function getopstr(const Oper:TOper):string;
      end;
 
 implementation
 
     uses
-      cutils,systems,
-      verbose,itcpugas,cgbase,cgutils;
+      cutils,systems,procinfo,
+      verbose,itcpugas,cgbase;
 
 
 {****************************************************************************}
@@ -56,9 +59,12 @@ implementation
       end;
 
 
-    function GetReferenceString(var ref:TReference):string;
+    function TSPARCInstrWriter.GetReferenceString(var ref:TReference):string;
+      var
+        asm_comment : string;
       begin
         GetReferenceString:='';
+        asm_comment:='';
         with ref do
           begin
             if (base=NR_NO) and (index=NR_NO) then
@@ -74,17 +80,27 @@ implementation
                      GetReferenceString:='%hi('+GetReferenceString+')';
                    addr_low:
                      GetReferenceString:='%lo('+GetReferenceString+')';
+                   addr_pic:
+                     begin
+                       asm_comment:='addr_pic should use %l7 register as base or index: '+GetReferenceString;
+                       Comment(V_Warning,asm_comment);
+                       GetReferenceString:='%l7+'+GetReferenceString;
+                     end;
                  end;
               end
             else
               begin
+                if (base=NR_NO) and (index<>NR_NO) then
+                  begin
+                    base:=index;
+                    index:=NR_NO;
+                  end;
 {$ifdef extdebug}
                 if assigned(symbol) and
                   not(refaddr in [addr_pic,addr_low]) then
                   internalerror(2003052601);
 {$endif extdebug}
-                if base<>NR_NO then
-                  GetReferenceString:=GetReferenceString+gas_regname(base);
+                GetReferenceString:=GetReferenceString+gas_regname(base);
                 if index=NR_NO then
                   begin
                     { if (Offset<simm13lo) or (Offset>simm13hi) then
@@ -101,6 +117,15 @@ implementation
                       begin
                         if refaddr=addr_low then
                           GetReferenceString:='%lo('+symbol.name+')+'+GetReferenceString
+                        else if refaddr=addr_pic then
+                          begin
+                            if assigned(current_procinfo) and (base <> current_procinfo.got) then
+                              begin
+                                asm_comment:=' pic address should use %l7 register: '+GetReferenceString; 
+                                Comment(V_Warning,asm_comment);
+                              end;
+                            GetReferenceString:=GetReferenceString+'+'+symbol.name;
+                          end
                         else
                           GetReferenceString:=symbol.name+'+'+GetReferenceString;
                       end;
@@ -112,13 +137,19 @@ implementation
                       internalerror(2003052603);
 {$endif extdebug}
                     GetReferenceString:=GetReferenceString+'+'+gas_regname(index);
+                    
                   end;
               end;
           end;
+        if asm_comment <> '' then
+          begin
+            owner.AsmWrite(target_asm.comment+' '+asm_comment);
+            owner.AsmLn;
+          end;
       end;
 
 
-    function getopstr(const Oper:TOper):string;
+    function TSPARCInstrWriter.getopstr(const Oper:TOper):string;
       begin
         with Oper do
           case typ of
@@ -127,8 +158,9 @@ implementation
             top_const:
               getopstr:=tostr(longint(val));
             top_ref:
-              if (oper.ref^.refaddr in [addr_no,addr_pic]) or ((oper.ref^.refaddr=addr_low) and ((oper.ref^.base<>NR_NO) or
-                (oper.ref^.index<>NR_NO))) then
+              if (oper.ref^.refaddr in [addr_no,addr_pic]) or
+                 ((oper.ref^.refaddr=addr_low) and ((oper.ref^.base<>NR_NO) or
+                  (oper.ref^.index<>NR_NO))) then
                 getopstr:='['+getreferencestring(ref^)+']'
               else
                 getopstr:=getreferencestring(ref^);
@@ -209,9 +241,9 @@ implementation
            idtxt  : 'AS';
            asmbin : 'as';
 {$ifdef FPC_SPARC_V8_ONLY}
-           asmcmd : '-o $OBJ $ASM';
+           asmcmd : '$PIC -o $OBJ $ASM';
 {$else}
-           asmcmd : '-Av9 -o $OBJ $ASM';
+           asmcmd : '$PIC -Av9 -o $OBJ $ASM';
 {$endif}
            supported_targets : [system_sparc_solaris,system_sparc_linux,system_sparc_embedded];
            flags : [af_allowdirect,af_needar,af_smartlink_sections];
@@ -225,7 +257,7 @@ implementation
            id     : as_ggas;
            idtxt  : 'GAS';
            asmbin : 'gas';
-           asmcmd : '-Av9 -o $OBJ $ASM';
+           asmcmd : '$PIC -Av9 -o $OBJ $ASM';
            supported_targets : [system_sparc_solaris,system_sparc_linux,system_sparc_embedded];
            flags : [af_allowdirect,af_needar,af_smartlink_sections];
            labelprefix : '.L';