소스 검색

+ PIC support for ARM jump tables (only for plain ARM right now, not
yet for thumb/thumb2)

git-svn-id: trunk@25323 -

Jonas Maebe 12 년 전
부모
커밋
b31e5c2536
1개의 변경된 파일28개의 추가작업 그리고 5개의 파일을 삭제
  1. 28 5
      compiler/arm/narmset.pas

+ 28 - 5
compiler/arm/narmset.pas

@@ -144,8 +144,9 @@ implementation
         basereg,
         indexreg : tregister;
         href : treference;
-        tablelabel: TAsmLabel;
+        tablelabel, piclabel : TAsmLabel;
         opcgsize : tcgsize;
+        picoffset : int64;
 
         procedure genitem(list:TAsmList;t : pcaselabel);
           var
@@ -155,9 +156,15 @@ implementation
               genitem(list,t^.less);
             { fill possible hole }
             for i:=last.svalue+1 to t^._low.svalue-1 do
-              list.concat(Tai_const.Create_sym(elselabel));
+              if cs_create_pic in current_settings.moduleswitches then
+                list.concat(Tai_const.Create_rel_sym_offset(aitconst_ptr,piclabel,elselabel,picoffset))
+              else
+                list.concat(Tai_const.Create_sym(elselabel));
             for i:=t^._low.svalue to t^._high.svalue do
-              list.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
+              if cs_create_pic in current_settings.moduleswitches then
+                list.concat(Tai_const.Create_rel_sym_offset(aitconst_ptr,piclabel,blocklabel(t^.blockid),picoffset))
+              else
+                list.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
             last:=t^._high.svalue;
             if assigned(t^.greater) then
               genitem(list,t^.greater);
@@ -194,6 +201,8 @@ implementation
 
         if current_settings.cputype in cpu_thumb2 then
           begin
+            if cs_create_pic in current_settings.moduleswitches then
+              internalerror(2013082101);
             { adjust index }
             cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_,indexreg,indexreg);
             { create reference and generate jump table }
@@ -211,6 +220,8 @@ implementation
           end
         else if current_settings.cputype in cpu_thumb then
           begin
+            if cs_create_pic in current_settings.moduleswitches then
+              internalerror(2013082102);
             cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_+1,indexreg,indexreg);
             current_asmdata.getaddrlabel(tablelabel);
 
@@ -232,14 +243,26 @@ implementation
         else
           begin
             { adjust index }
-            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_+1,indexreg,indexreg);
+            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,
+              min_+ord(not(cs_create_pic in current_settings.moduleswitches)),
+              indexreg,indexreg);
             { create reference and generate jump table }
             reference_reset(href,4);
             href.base:=NR_PC;
             href.index:=indexreg;
             href.shiftmode:=SM_LSL;
             href.shiftimm:=2;
-            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,NR_PC);
+            if cs_create_pic in current_settings.moduleswitches then
+              begin
+                picoffset:=-8;
+                current_asmdata.getaddrlabel(piclabel);
+                indexreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,indexreg);
+                cg.a_label(current_asmdata.CurrAsmList,piclabel);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,indexreg,NR_PC);
+              end
+            else
+              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,NR_PC);
             { generate jump table }
             last:=min_;
             genitem(current_asmdata.CurrAsmList,hp);