Browse Source

* Use GOT-relative constants for i386 PIC jump tables, they don't need runtime relocations. Now almost ABI-compliant on Linux/BSD (Darwin targets unchanged). Also clean up i8086-specific stuff: using tai_const.create_type_sym(aitconst_ptr,...) generates near pointers on i8086, which is the desired goal.

git-svn-id: trunk@26942 -
sergei 11 năm trước cách đây
mục cha
commit
5e8f8f4755
1 tập tin đã thay đổi với 18 bổ sung11 xóa
  1. 18 11
      compiler/x86/nx86set.pas

+ 18 - 11
compiler/x86/nx86set.pas

@@ -73,6 +73,8 @@ implementation
         href : treference;
         href : treference;
         jtlist: tasmlist;
         jtlist: tasmlist;
         opcgsize: tcgsize;
         opcgsize: tcgsize;
+        jumpreg: tregister;
+        labeltyp: taiconst_type;
 
 
         procedure genitem(list:TAsmList;t : pcaselabel);
         procedure genitem(list:TAsmList;t : pcaselabel);
           var
           var
@@ -84,21 +86,13 @@ implementation
             i:=last.svalue+1;
             i:=last.svalue+1;
             while i<=t^._low.svalue-1 do
             while i<=t^._low.svalue-1 do
               begin
               begin
-{$ifdef i8086}
-                list.concat(Tai_const.Create_sym_near(elselabel));
-{$else i8086}
-                list.concat(Tai_const.Create_sym(elselabel));
-{$endif i8086}
+                list.concat(Tai_const.Create_type_sym(labeltyp,elselabel));
                 inc(i);
                 inc(i);
               end;
               end;
             i:=t^._low.svalue;
             i:=t^._low.svalue;
             while i<=t^._high.svalue do
             while i<=t^._high.svalue do
               begin
               begin
-{$ifdef i8086}
-                list.concat(Tai_const.Create_sym_near(blocklabel(t^.blockid)));
-{$else i8086}
-                list.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
-{$endif i8086}
+                list.concat(Tai_const.Create_type_sym(labeltyp,blocklabel(t^.blockid)));
                 inc(i);
                 inc(i);
               end;
               end;
             last:=t^._high;
             last:=t^._high;
@@ -108,6 +102,8 @@ implementation
 
 
       begin
       begin
         last:=min_;
         last:=min_;
+        { This generates near pointers on i8086 }
+        labeltyp:=aitconst_ptr;
         opcgsize:=def_cgsize(opsize);
         opcgsize:=def_cgsize(opsize);
         if not(jumptable_no_range) then
         if not(jumptable_no_range) then
           begin
           begin
@@ -130,7 +126,18 @@ implementation
 {$else i8086}
 {$else i8086}
         href.scalefactor:=sizeof(aint);
         href.scalefactor:=sizeof(aint);
 {$endif i8086}
 {$endif i8086}
-        emit_ref(A_JMP,S_NO,href);
+
+        if (not (target_info.system in [system_i386_darwin,system_i386_iphonesim])) and
+           (cs_create_pic in current_settings.moduleswitches) then
+          begin
+            labeltyp:=aitconst_gotoff_symbol;
+            jumpreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,jumpreg);
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,current_procinfo.got,jumpreg);
+            emit_reg(A_JMP,S_NO,jumpreg);
+          end
+        else
+          emit_ref(A_JMP,S_NO,href);
         { generate jump table }
         { generate jump table }
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) then
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) then
           jtlist:=current_asmdata.asmlists[al_const]
           jtlist:=current_asmdata.asmlists[al_const]