summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-03-13 16:18:00 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-03-13 16:18:00 +0000
commit6c91aee6685d5f1d8e6faf2d536ca9aadcc91e25 (patch)
treea9c65fb392221c6cb39d397191470e6de9c6fd7f
parent0392eb5ebfa4ffbee63437a929f18b597d1acb60 (diff)
downloadfpc-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.pas4
-rw-r--r--compiler/riscv/aasmcpu.pas9
-rw-r--r--compiler/riscv/agrvgas.pas11
-rw-r--r--compiler/riscv/cgrv.pas64
-rw-r--r--compiler/riscv64/cpubase.pas2
-rw-r--r--compiler/riscv64/itcpugas.pas2
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',