From 971d97c179dd4b81ba52910d708a6aa6336ddbc7 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 11 Jan 2025 21:03:15 +0100 Subject: [PATCH] + RiscV: make use of the fmv.w.x/fmv.d.x instruction to load 0.0 --- compiler/riscv/cpubase.pas | 5 +- compiler/riscv/itcpugas.pas | 5 +- compiler/riscv/nrvcon.pas | 105 ++++++++++++++--------------------- compiler/riscv32/cpunode.pas | 4 +- compiler/riscv64/cpunode.pas | 3 +- 5 files changed, 51 insertions(+), 71 deletions(-) diff --git a/compiler/riscv/cpubase.pas b/compiler/riscv/cpubase.pas index c3efb1d28e..dde805b84c 100644 --- a/compiler/riscv/cpubase.pas +++ b/compiler/riscv/cpubase.pas @@ -128,9 +128,10 @@ uses A_FADD_S,A_FSUB_S,A_FMUL_S,A_FDIV_S, A_FSQRT_S,A_FSGNJ_S,A_FSGNJN_S,A_FSGNJX_S, A_FMIN_S,A_FMAX_S, - A_FMV_X_S,A_FEQ_S,A_FLT_S,A_FLE_S,A_FCLASS_S, + A_FMV_X_S,A_FMV_X_W, + A_FEQ_S,A_FLT_S,A_FLE_S,A_FCLASS_S, A_FCVT_W_S,A_FCVT_WU_S,A_FCVT_S_W,A_FCVT_S_WU, - A_FMV_S_X, + A_FMV_S_X,A_FMV_W_X, A_FRCSR,A_FRRM,A_FRFLAGS,A_FSCSR,A_FSRM, A_FSFLAGS,A_FSRMI,A_FSFLAGSI, diff --git a/compiler/riscv/itcpugas.pas b/compiler/riscv/itcpugas.pas index b8f7464d5e..d864fd8112 100644 --- a/compiler/riscv/itcpugas.pas +++ b/compiler/riscv/itcpugas.pas @@ -119,9 +119,10 @@ unit itcpugas; 'fadd.s','fsub.s','fmul.s','fdiv.s', 'fsqrt.s','fsgnj.s','fsgnjn.s','fsgnjx.s', 'fmin.s','fmax.s', - 'fmv.x.s','feq.s','flt.s','fle.s','fclass.s', + 'fmv.x.s','fmv.x.w', + 'feq.s','flt.s','fle.s','fclass.s', 'fcvt.w.s','fcvt.wu.s','fcvt.s.w','fcvt.s.wu', - 'fmv.s.x', + 'fmv.s.x','fmv.w.x', 'frcsr','frrm','frflags','fscsr','fsrm', 'fsflags','fsrmi','fsflagsi', diff --git a/compiler/riscv/nrvcon.pas b/compiler/riscv/nrvcon.pas index 66698527b7..ca3ff88f68 100644 --- a/compiler/riscv/nrvcon.pas +++ b/compiler/riscv/nrvcon.pas @@ -26,10 +26,12 @@ unit nrvcon; interface uses - ncgcon,cpubase; + node,ncgcon,cpubase; type trvrealconstnode = class(tcgrealconstnode) + function pass_1 : tnode;override; + procedure pass_generate_code;override; end; @@ -40,9 +42,10 @@ implementation verbose, globtype,globals, cpuinfo, - aasmbase,aasmtai,aasmdata,symdef, + aasmbase,aasmtai,aasmcpu,aasmdata, + symdef, defutil, - cgbase,cgutils, + cgbase,cgobj,cgutils, procinfo, ncon; @@ -50,6 +53,22 @@ implementation TARMREALCONSTNODE *****************************************************************************} + function trvrealconstnode.pass_1 : tnode; + begin + result:=nil; + if is_number_float(value_real) and (value_real=0.0) and (get_real_sign(value_real)=1) and + ( + is_single(resultdef) +{$ifdef RISCV64} + or is_double(resultdef) +{$endif RISCV64} + ) then + expectloc:=LOC_FPUREGISTER + else + expectloc:=LOC_CREFERENCE; + end; + + procedure trvrealconstnode.pass_generate_code; { I suppose the parser/pass_1 must make sure the generated real } { constants are actually supported by the target processor? (JM) } @@ -61,69 +80,27 @@ implementation realait : tairealconsttype; begin - location_reset_ref(location,LOC_CREFERENCE,def_cgsize(resultdef),4); - lastlabel:=nil; - realait:=floattype2ait[tfloatdef(resultdef).floattype]; - { const already used ? } - if not assigned(lab_real) then + if is_number_float(value_real) and (value_real=0.0) and (get_real_sign(value_real)=1) and + ( + is_single(resultdef) +{$ifdef RISCV64} + or is_double(resultdef) +{$endif RISCV64} + ) then begin - current_asmdata.getjumplabel(lastlabel); - lab_real:=lastlabel; - current_procinfo.aktlocaldata.concat(Tai_label.Create(lastlabel)); - location.reference.symboldata:=current_procinfo.aktlocaldata.last; - case realait of - aitrealconst_s32bit : - begin - current_procinfo.aktlocaldata.concat(tai_realconst.create_s32real(ts32real(value_real))); - { range checking? } - if floating_point_range_check_error and - (tai_realconst(current_procinfo.aktlocaldata.last).value.s32val=MathInf.Value) then - Message(parser_e_range_check_error); - end; - - aitrealconst_s64bit : - begin - current_procinfo.aktlocaldata.concat(tai_realconst.create_s64real(ts64real(value_real))); - - { range checking? } - if floating_point_range_check_error and - (tai_realconst(current_procinfo.aktlocaldata.last).value.s64val=MathInf.Value) then - Message(parser_e_range_check_error); - end; - - aitrealconst_s80bit : - begin - current_procinfo.aktlocaldata.concat(tai_realconst.create_s80real(value_real,tfloatdef(resultdef).size)); - - { range checking? } - if floating_point_range_check_error and - (tai_realconst(current_procinfo.aktlocaldata.last).value.s80val=MathInf.Value) then - Message(parser_e_range_check_error); - end; -{$ifdef cpufloat128} - aitrealconst_s128bit : - begin - current_procinfo.aktlocaldata.concat(tai_realconst.create_s128real(value_real)); - - { range checking? } - if floating_point_range_check_error and - (tai_realconst(current_procinfo.aktlocaldata.last).value.s128val=MathInf.Value) then - Message(parser_e_range_check_error); - end; -{$endif cpufloat128} - - { the round is necessary for native compilers where comp isn't a float } - aitrealconst_s64comp : - if (value_real>9223372036854775807.0) or (value_real<-9223372036854775808.0) then - message(parser_e_range_check_error) - else - current_procinfo.aktlocaldata.concat(tai_realconst.create_s64compreal(round(value_real))); + location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef)); + location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size); + if is_single(resultdef) then + current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg(A_FMV_W_X,location.register,NR_X0)) +{$ifdef RISCV64} + else if is_double(resultdef) then + current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg(A_FMV_D_X,location.register,NR_X0)) +{$endif RISCV64} else - internalerror(2005092401); - end; - end; - location.reference.symbol:=lab_real; - location.reference.refaddr:=addr_pcrel; + Internalerror(2025011103); + end + else + inherited pass_generate_code; end; begin diff --git a/compiler/riscv32/cpunode.pas b/compiler/riscv32/cpunode.pas index 05b17ad24e..aeb872fc1b 100644 --- a/compiler/riscv32/cpunode.pas +++ b/compiler/riscv32/cpunode.pas @@ -44,8 +44,8 @@ unit cpunode; nrvset, nrvinl, nrv32mat, - nrv32cnv -// ,nrvcon + nrv32cnv, + nrvcon ; end. diff --git a/compiler/riscv64/cpunode.pas b/compiler/riscv64/cpunode.pas index 69a0b43047..7866afcf07 100644 --- a/compiler/riscv64/cpunode.pas +++ b/compiler/riscv64/cpunode.pas @@ -46,7 +46,8 @@ uses nrv64mat, nrv64cnv, nrv64ld, - nrvutil + nrvutil, + nrvcon {$else not llvm} llvmnode {$endif not llvm}