mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 08:38:14 +02:00
+ RiscV: make use of the fmv.w.x/fmv.d.x instruction to load 0.0
This commit is contained in:
parent
366acce9ef
commit
971d97c179
@ -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,
|
||||
|
||||
|
@ -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',
|
||||
|
||||
|
@ -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
|
||||
|
@ -44,8 +44,8 @@ unit cpunode;
|
||||
nrvset,
|
||||
nrvinl,
|
||||
nrv32mat,
|
||||
nrv32cnv
|
||||
// ,nrvcon
|
||||
nrv32cnv,
|
||||
nrvcon
|
||||
;
|
||||
|
||||
end.
|
||||
|
@ -46,7 +46,8 @@ uses
|
||||
nrv64mat,
|
||||
nrv64cnv,
|
||||
nrv64ld,
|
||||
nrvutil
|
||||
nrvutil,
|
||||
nrvcon
|
||||
{$else not llvm}
|
||||
llvmnode
|
||||
{$endif not llvm}
|
||||
|
Loading…
Reference in New Issue
Block a user