diff options
author | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-28 20:06:06 +0000 |
---|---|---|
committer | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-28 20:06:06 +0000 |
commit | e0c39ce1b21f7c35799446b5be789cc7bef0b229 (patch) | |
tree | f0aa669e58030daedc18dc055b8082c59fc54448 | |
parent | a310c613f7a252c132e350705dc987e7e54e1c21 (diff) | |
download | fpc-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.pas | 4 | ||||
-rw-r--r-- | riscv_new/compiler/riscv64/cpupara.pas | 61 | ||||
-rw-r--r-- | riscv_new/compiler/systems/t_linux.pas | 2 |
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} |