diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-03-13 16:18:00 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-03-13 16:18:00 +0000 |
commit | 6c91aee6685d5f1d8e6faf2d536ca9aadcc91e25 (patch) | |
tree | a9c65fb392221c6cb39d397191470e6de9c6fd7f | |
parent | 0392eb5ebfa4ffbee63437a929f18b597d1acb60 (diff) | |
download | fpc-6c91aee6685d5f1d8e6faf2d536ca9aadcc91e25.tar.gz |
+ RiscV: initial support of pic generation
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@48947 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/cgbase.pas | 4 | ||||
-rw-r--r-- | compiler/riscv/aasmcpu.pas | 9 | ||||
-rw-r--r-- | compiler/riscv/agrvgas.pas | 11 | ||||
-rw-r--r-- | compiler/riscv/cgrv.pas | 64 | ||||
-rw-r--r-- | compiler/riscv64/cpubase.pas | 2 | ||||
-rw-r--r-- | compiler/riscv64/itcpugas.pas | 2 |
6 files changed, 65 insertions, 27 deletions
diff --git a/compiler/cgbase.pas b/compiler/cgbase.pas index 21c36c233b..4f55c9acf9 100644 --- a/compiler/cgbase.pas +++ b/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 diff --git a/compiler/riscv/aasmcpu.pas b/compiler/riscv/aasmcpu.pas index 01eb202ce7..2a5a6ce6e6 100644 --- a/compiler/riscv/aasmcpu.pas +++ b/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); diff --git a/compiler/riscv/agrvgas.pas b/compiler/riscv/agrvgas.pas index a71a06aa74..6c52e84057 100644 --- a/compiler/riscv/agrvgas.pas +++ b/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; diff --git a/compiler/riscv/cgrv.pas b/compiler/riscv/cgrv.pas index 9b5443b7cf..6921c8e88c 100644 --- a/compiler/riscv/cgrv.pas +++ b/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 diff --git a/compiler/riscv64/cpubase.pas b/compiler/riscv64/cpubase.pas index 13148d75ce..5e1d0f72d5 100644 --- a/compiler/riscv64/cpubase.pas +++ b/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, diff --git a/compiler/riscv64/itcpugas.pas b/compiler/riscv64/itcpugas.pas index 4fabace6e8..1cb3701d69 100644 --- a/compiler/riscv64/itcpugas.pas +++ b/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', |