瀏覽代碼

+ RiscV: initial support of pic generation

git-svn-id: trunk@48947 -
florian 4 年之前
父節點
當前提交
e047e7db91

+ 3 - 1
compiler/cgbase.pas

@@ -99,7 +99,9 @@ interface
          addr_lo12,
          addr_pcrel_hi20,
          addr_pcrel_lo12,
-         addr_pcrel
+         addr_pcrel,
+         addr_got_pcrel_hi,
+         addr_plt
          {$endif RISCV}
          {$IFDEF AVR}
          ,addr_lo8

+ 9 - 0
compiler/riscv/aasmcpu.pas

@@ -47,6 +47,7 @@ uses
 
          constructor op_reg(op : tasmop;_op1 : tregister);
          constructor op_const(op : tasmop;_op1 : aint);
+         constructor op_ref(op : tasmop;_op1 : treference);
 
          constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
          constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
@@ -144,6 +145,14 @@ uses cutils, cclasses;
       end;
 
 
+    constructor taicpu.op_ref(op : tasmop;_op1 : treference);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadref(0,_op1);
+      end;
+
+
     constructor taicpu.op_const(op : tasmop;_op1 : aint);
       begin
          inherited create(op);

+ 5 - 6
compiler/riscv/agrvgas.pas

@@ -74,7 +74,8 @@ unit agrvgas;
             else
               begin
                 s :='';
-                s := s+'(';
+                if not(refaddr in [addr_no,addr_pic_no_got,addr_plt]) then
+                  s := s+'(';
                 if assigned(symbol) then
                   begin
                     if asminfo^.dollarsign<>'$' then
@@ -103,14 +104,10 @@ unit agrvgas;
                 s:=s+tostr(offset);
             end;
 
-           if not(refaddr in [addr_no,addr_pic_no_got]) then
+           if not(refaddr in [addr_no,addr_pic_no_got,addr_plt]) then
              begin
                s := s+')';
              end;
-{$ifdef cpu64bitaddr}
-           if (refaddr=addr_pic) then
-             s := s + '@got';
-{$endif cpu64bitaddr}
 
            if (index=NR_NO) then
              begin
@@ -139,6 +136,8 @@ unit agrvgas;
              addr_hi20: s:='%hi'+s;
              addr_pcrel_lo12: s:='%pcrel_lo'+s;
              addr_pcrel_hi20: s:='%pcrel_hi'+s;
+             addr_got_pcrel_hi: s:='%got_pcrel_hi'+s;
+             addr_plt: s:=s+'@plt';
              else
                ;
            end;

+ 46 - 18
compiler/riscv/cgrv.pas

@@ -133,16 +133,24 @@ unit cgrv;
         else
           reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION),0,0,[]);
 
-        current_asmdata.getjumplabel(l);
+        if cs_create_pic in current_settings.moduleswitches then
+          begin
+            href.refaddr:=addr_plt;
+            list.concat(taicpu.op_ref(A_CALL,href));
+          end
+        else
+          begin
+            current_asmdata.getjumplabel(l);
 
-        a_label(list,l);
+            a_label(list,l);
 
-        href.refaddr:=addr_pcrel_hi20;
-        list.concat(taicpu.op_reg_ref(A_AUIPC,NR_RETURN_ADDRESS_REG,href));
+            href.refaddr:=addr_pcrel_hi20;
+            list.concat(taicpu.op_reg_ref(A_AUIPC,NR_RETURN_ADDRESS_REG,href));
 
-        reference_reset_symbol(href,l,0,0,[]);
-        href.refaddr:=addr_pcrel_lo12;
-        list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,NR_RETURN_ADDRESS_REG,href));
+            reference_reset_symbol(href,l,0,0,[]);
+            href.refaddr:=addr_pcrel_lo12;
+            list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,NR_RETURN_ADDRESS_REG,href));
+          end;
 
         { not assigned while generating external wrappers }
         if assigned(current_procinfo) then
@@ -721,20 +729,40 @@ unit cgrv;
 
         if assigned(ref.symbol) then
           begin
-            reference_reset_symbol(href,ref.symbol,ref.offset,ref.alignment,ref.volatility);
-            ref.symbol:=nil;
-            ref.offset:=0;
+            if cs_create_pic in current_settings.moduleswitches then
+              begin
+                reference_reset_symbol(href,ref.symbol,0,0,[]);
+                ref.symbol:=nil;
 
-            tmpreg:=getintregister(list,OS_INT);
+                tmpreg:=getintregister(list,OS_INT);
 
-            current_asmdata.getaddrlabel(l);
-            a_label(list,l);
+                current_asmdata.getaddrlabel(l);
+                a_label(list,l);
 
-            href.refaddr:=addr_pcrel_hi20;
-            list.concat(taicpu.op_reg_ref(A_AUIPC,tmpreg,href));
-            reference_reset_symbol(href,l,0,0,ref.volatility);
-            href.refaddr:=addr_pcrel_lo12;
-            list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,href));
+                href.refaddr:=addr_got_pcrel_hi;
+                list.concat(taicpu.op_reg_ref(A_AUIPC,tmpreg,href));
+                reference_reset_symbol(href,l,0,0,[]);
+                href.refaddr:=addr_pcrel_lo12;
+                href.base:=tmpreg;
+                list.concat(taicpu.op_reg_ref(A_LD,tmpreg,href));
+              end
+            else
+              begin
+                reference_reset_symbol(href,ref.symbol,ref.offset,ref.alignment,ref.volatility);
+                ref.symbol:=nil;
+                ref.offset:=0;
+
+                tmpreg:=getintregister(list,OS_INT);
+
+                current_asmdata.getaddrlabel(l);
+                a_label(list,l);
+
+                href.refaddr:=addr_pcrel_hi20;
+                list.concat(taicpu.op_reg_ref(A_AUIPC,tmpreg,href));
+                reference_reset_symbol(href,l,0,0,ref.volatility);
+                href.refaddr:=addr_pcrel_lo12;
+                list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,href));
+              end;
 
             if (ref.index<>NR_NO) and
                (ref.base<>NR_NO) then

+ 1 - 1
compiler/riscv64/cpubase.pas

@@ -38,7 +38,7 @@ uses
 type
       TAsmOp=(A_None,
         { Pseudo instructions }
-        A_NOP,
+        A_NOP,A_CALL,
         { normal opcodes }
         A_LUI,A_AUIPC,A_JAL,A_JALR,
         A_Bxx,A_LB,A_LH,A_LW,A_LBU,A_LHU,

+ 1 - 1
compiler/riscv64/itcpugas.pas

@@ -30,7 +30,7 @@ unit itcpugas;
 
     const
       gas_op2str: array[tasmop] of string[14] = ('<none>',
-        'nop',
+        'nop','call',
         'lui','auipc','jal','jalr',
         'b','lb','lh','lw','lbu','lhu',
         'sb','sh','sw',