summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-28 20:06:06 +0000
committerlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-28 20:06:06 +0000
commite0c39ce1b21f7c35799446b5be789cc7bef0b229 (patch)
treef0aa669e58030daedc18dc055b8082c59fc54448
parenta310c613f7a252c132e350705dc987e7e54e1c21 (diff)
downloadfpc-e0c39ce1b21f7c35799446b5be789cc7bef0b229.tar.gz
Updated dynlinker filename.
Fix passing of vararg register pairs. Fix passing of big record, and return of records. Disabled framepointer elimination for the time being. git-svn-id: https://svn.freepascal.org/svn/fpc/branches/laksen@39519 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv_new/compiler/psub.pas4
-rw-r--r--riscv_new/compiler/riscv64/cpupara.pas61
-rw-r--r--riscv_new/compiler/systems/t_linux.pas2
3 files changed, 21 insertions, 46 deletions
diff --git a/riscv_new/compiler/psub.pas b/riscv_new/compiler/psub.pas
index 39e9f2bdcf..291af4209b 100644
--- a/riscv_new/compiler/psub.pas
+++ b/riscv_new/compiler/psub.pas
@@ -1002,7 +1002,7 @@ implementation
begin
tg:=tgobjclass.create;
-{$if defined(i386) or defined(x86_64) or defined(arm) or defined(riscv32) or defined(riscv64)}
+{$if defined(i386) or defined(x86_64) or defined(arm)}
{$if defined(arm)}
{ frame and stack pointer must be always the same on arm thumb so it makes no
sense to fiddle with a frame pointer }
@@ -1100,7 +1100,7 @@ implementation
{$endif defined(arm)}
end;
end;
-{$endif defined(x86) or defined(arm) or defined(riscv32) or defined(riscv64)}
+{$endif defined(x86) or defined(arm)}
{ set the start offset to the start of the temp area in the stack }
set_first_temp_offset;
end;
diff --git a/riscv_new/compiler/riscv64/cpupara.pas b/riscv_new/compiler/riscv64/cpupara.pas
index 01b7b3586c..511dd5edb4 100644
--- a/riscv_new/compiler/riscv64/cpupara.pas
+++ b/riscv_new/compiler/riscv64/cpupara.pas
@@ -172,7 +172,7 @@ implementation
result := true;
procvardef,
recorddef:
- result := (def.size > 8);
+ result := (def.size > 16);
arraydef:
result := (tarraydef(def).highrange >= tarraydef(def).lowrange) or
is_open_array(def) or
@@ -196,13 +196,6 @@ implementation
{ general rule: passed in registers -> returned in registers }
result:=push_addr_param(vs_value,def,pd.proccalloption);
-
- case def.typ of
- procvardef:
- result:=def.size>8;
- recorddef:
- result:=true;
- end;
end;
procedure tcpuparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
@@ -224,41 +217,14 @@ implementation
if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
exit;
- paraloc:=result.add_location;
- { Return in FPU register? }
- if result.def.typ=floatdef then
- begin
- if (p.proccalloption in [pocall_softfloat]) or
- (cs_fp_emulation in current_settings.moduleswitches) or
- (current_settings.fputype in [fpu_soft]) then
- begin
- paraloc^.loc:=LOC_REGISTER;
- if side=callerside then
- paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
- else
- paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
- paraloc^.size:=retcgsize;
- paraloc^.def:=result.def;
- end
- else
- begin
- paraloc^.loc:=LOC_FPUREGISTER;
- paraloc^.register:=NR_FPU_RESULT_REG;
- paraloc^.size:=retcgsize;
- paraloc^.def:=result.def;
- end;
- end
- else
- { Return in register }
- begin
- paraloc^.loc:=LOC_REGISTER;
- if side=callerside then
- paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
- else
- paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
- paraloc^.size:=retcgsize;
- paraloc^.def:=result.def;
- end;
+ { in this case, it must be returned in registers as if it were passed
+ as the first parameter }
+ init_values(nextintreg,nextfloatreg,nextmmreg,stack_offset);
+ create_paraloc_for_def(result,vs_value,result.def,nextfloatreg,nextintreg,stack_offset,false,false,side,p);
+ { sanity check (LOC_VOID for empty records) }
+ if not assigned(result.location) or
+ not(result.location^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_VOID]) then
+ internalerror(2014113001);
end;
function tcpuparamanager.create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint;
@@ -415,6 +381,15 @@ implementation
paracgsize:=def_cgsize(locdef);
end;
firstparaloc:=true;
+
+ // Parameters passed in 2 registers are passed in a register starting with an even number.
+ if isVararg and
+ (paralen > 8) and
+ (loc = LOC_REGISTER) and
+ (nextintreg <= RS_X17) and
+ odd(nextintreg) then
+ inc(nextintreg);
+
{ can become < 0 for e.g. 3-byte records }
while (paralen > 0) do begin
paraloc := para.add_location;
diff --git a/riscv_new/compiler/systems/t_linux.pas b/riscv_new/compiler/systems/t_linux.pas
index 013667b8a8..f5ad6c98e1 100644
--- a/riscv_new/compiler/systems/t_linux.pas
+++ b/riscv_new/compiler/systems/t_linux.pas
@@ -238,7 +238,7 @@ const defdynlinker='/lib/ld-linux-aarch64.so.1';
const defdynlinker='/lib32/ld.so.1';
{$endif riscv32}
{$ifdef riscv64}
- const defdynlinker='/lib/ld.so.1';
+ const defdynlinker='/lib/ld-linux-riscv64-lp64d.so.1';
{$endif riscv64}