ソースを参照

* fixed handling of max. distance of pc relative symbols

florian 21 年 前
コミット
af3d31eceb
4 ファイル変更109 行追加24 行削除
  1. 69 1
      compiler/arm/aasmcpu.pas
  2. 20 17
      compiler/arm/cgcpu.pas
  3. 9 5
      compiler/arm/cpubase.pas
  4. 11 1
      compiler/psub.pas

+ 69 - 1
compiler/arm/aasmcpu.pas

@@ -84,6 +84,9 @@ uses
     function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
     function setcondition(i : taicpu;c : tasmcond) : taicpu;
 
+    { inserts pc relative symbols at places where they are reachable }
+    procedure insertpcrelativedata(list,listtoinsert : taasmoutput);
+
     procedure InitAsm;
     procedure DoneAsm;
 
@@ -341,10 +344,75 @@ implementation
       end;
 
 
+    procedure insertpcrelativedata(list,listtoinsert : taasmoutput);
+      var
+        curpos : longint;
+        lastpos : longint;
+        curop : longint;
+        curtai : tai;
+        curdatatai,hp : tai;
+        curdata : taasmoutput;
+        l : tasmlabel;
+      begin
+        curdata:=taasmoutput.create;
+        lastpos:=-1;
+        curpos:=0;
+        curtai:=tai(list.first);
+        while assigned(curtai) do
+          begin
+            { instruction? }
+            if curtai.typ=ait_instruction then
+              begin
+                { walk through all operand of the instruction }
+                for curop:=0 to taicpu(curtai).ops-1 do
+                  begin
+                    { reference? }
+                    if (taicpu(curtai).oper[curop]^.typ=top_ref) then
+                      begin
+                        { pc relative symbol? }
+                        curdatatai:=tai(taicpu(curtai).oper[curop]^.ref^.symboldata);
+                        if assigned(curdatatai) then
+                          begin
+                            { if yes, insert till next symbol }
+                            repeat
+                              hp:=tai(curdatatai.next);
+                              listtoinsert.remove(curdatatai);
+                              curdata.concat(curdatatai);
+                              curdatatai:=hp;
+                            until (curdatatai=nil) or (curdatatai.typ=ait_label);
+                            if lastpos=-1 then
+                              lastpos:=curpos;
+                          end;
+                      end;
+                  end;
+                inc(curpos);
+              end;
+
+            if (curpos-lastpos)>1020 then
+              begin
+                lastpos:=curpos;
+                hp:=tai(curtai.next);
+                objectlibrary.getlabel(l);
+                curdata.insert(taicpu.op_sym(A_B,l));
+                curdata.concat(tai_label.create(l));
+                list.insertlistafter(curtai,curdata);
+                curtai:=hp;
+              end
+            else
+              curtai:=tai(curtai.next);
+          end;
+        list.concatlist(curdata);
+        curdata.free;
+      end;
+
+
 end.
 {
   $Log$
-  Revision 1.21  2004-01-20 21:02:55  florian
+  Revision 1.22  2004-01-21 19:01:03  florian
+    * fixed handling of max. distance of pc relative symbols
+
+  Revision 1.21  2004/01/20 21:02:55  florian
     * fixed symbol type writing for arm-linux
     * fixed assembler generation for abs
 

+ 20 - 17
compiler/arm/cgcpu.pas

@@ -428,10 +428,13 @@ unit cgcpu;
             list.concat(taicpu.op_reg_const(A_MVN,reg,not(a)))
           else
             begin
-               objectlibrary.getdatalabel(l);
-               current_procinfo.aktlocaldata.concat(tai_symbol.Create(l,0));
-               current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(longint(a)));
                reference_reset(hr);
+
+               objectlibrary.getlabel(l);
+               cg.a_label(current_procinfo.aktlocaldata,l);
+               hr.symboldata:=current_procinfo.aktlocaldata.last;
+               current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(longint(a)));
+
                hr.symbol:=l;
                list.concat(taicpu.op_reg_ref(A_LDR,reg,hr));
             end;
@@ -478,12 +481,12 @@ unit cgcpu;
             )
            ) then
           begin
-            { check consts distance }
-            { !!!! }
-
+            reference_reset(tmpref);
             { create consts entry }
-            objectlibrary.getdatalabel(l);
-            current_procinfo.aktlocaldata.concat(Tai_symbol.Create(l,0));
+            objectlibrary.getlabel(l);
+            cg.a_label(current_procinfo.aktlocaldata,l);
+            tmpref.symboldata:=current_procinfo.aktlocaldata.last;
+
             if assigned(ref.symbol) then
               current_procinfo.aktlocaldata.concat(tai_const_symbol.Create_offset(ref.symbol,ref.offset))
             else
@@ -491,7 +494,6 @@ unit cgcpu;
 
             { load consts entry }
             tmpreg:=getintregister(list,OS_INT);
-            reference_reset(tmpref);
             tmpref.symbol:=l;
             tmpref.base:=NR_R15;
             list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
@@ -896,20 +898,18 @@ unit cgcpu;
           A proper solution would be to change refoptions to a set and store the information
           if the symbol is absolute or relative there.
         }
-
-        { check consts distance }
-        {!!!!!}
-
         { create consts entry }
-        objectlibrary.getdatalabel(l);
-        current_procinfo.aktlocaldata.concat(Tai_symbol.Create(l,0));
+        reference_reset(tmpref);
+        objectlibrary.getlabel(l);
+        cg.a_label(current_procinfo.aktlocaldata,l);
+        tmpref.symboldata:=current_procinfo.aktlocaldata.last;
+
         if assigned(ref.symbol) then
           current_procinfo.aktlocaldata.concat(tai_const_symbol.Create_offset(ref.symbol,ref.offset))
         else
           current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
 
         { load consts entry }
-        reference_reset(tmpref);
         tmpreg:=getintregister(list,OS_INT);
         tmpref.symbol:=l;
         tmpref.base:=NR_PC;
@@ -1207,7 +1207,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.33  2004-01-21 15:41:56  florian
+  Revision 1.34  2004-01-21 19:01:03  florian
+    * fixed handling of max. distance of pc relative symbols
+
+  Revision 1.33  2004/01/21 15:41:56  florian
     * fixed register allocator problems with concatcopy
 
   Revision 1.32  2004/01/21 14:22:00  florian

+ 9 - 5
compiler/arm/cpubase.pas

@@ -212,13 +212,14 @@ unit cpubase;
       { reference record }
       preference = ^treference;
       treference = packed record
+         symbol      : tasmsymbol;
+         offset      : longint;
+         offsetfixup : longint;
          base,
          index       : tregister;
-         shiftimm    : byte;
+         symboldata  : tlinkedlistitem;
          signindex   : shortint;
-         offset      : longint;
-         symbol      : tasmsymbol;
-         offsetfixup : longint;
+         shiftimm    : byte;
          options     : trefoptions;
          addressmode : taddressmode;
          shiftmode   : tshiftmode;
@@ -565,7 +566,10 @@ unit cpubase;
 end.
 {
   $Log$
-  Revision 1.22  2003-12-26 14:02:30  peter
+  Revision 1.23  2004-01-21 19:01:03  florian
+    * fixed handling of max. distance of pc relative symbols
+
+  Revision 1.22  2003/12/26 14:02:30  peter
     * sparc updates
     * use registertype in spill_register
 

+ 11 - 1
compiler/psub.pas

@@ -95,6 +95,9 @@ implementation
        { codegen }
        tgobj,cgobj,
        ncgutil,regvars
+{$ifdef arm}
+       ,aasmcpu
+{$endif arm}
        {$ifndef NOOPT}
          {$ifdef i386}
            ,aopt386
@@ -783,6 +786,10 @@ implementation
             gen_proc_symbol_end(templist);
             aktproccode.concatlist(templist);
 
+{$ifdef ARM}
+            insertpcrelativedata(aktproccode,aktlocaldata);
+{$endif ARM}
+
             { save local data (casetable) also in the same file }
             if assigned(aktlocaldata) and
                (not aktlocaldata.empty) then
@@ -1335,7 +1342,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.181  2003-12-21 19:42:43  florian
+  Revision 1.182  2004-01-21 19:01:03  florian
+    * fixed handling of max. distance of pc relative symbols
+
+  Revision 1.181  2003/12/21 19:42:43  florian
     * fixed ppc inlining stuff
     * fixed wrong unit writing
     + added some sse stuff