From 999cbd94b8f90cb5519fba1bdc93f3d3bdf86904 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 19 Aug 2018 10:56:47 +0000 Subject: [PATCH] + support to generate software based floating point exception checking (enabled by -CE) git-svn-id: branches/laksen/riscv_new@39639 - --- compiler/riscv/cgrv.pas | 26 ++++++++++++++++++++++++++ compiler/riscv/nrvadd.pas | 4 +++- compiler/riscv/nrvinl.pas | 17 +++++++++++++---- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/compiler/riscv/cgrv.pas b/compiler/riscv/cgrv.pas index d73c800549..0d5075f987 100644 --- a/compiler/riscv/cgrv.pas +++ b/compiler/riscv/cgrv.pas @@ -69,6 +69,8 @@ unit cgrv; procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override; procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override; procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override; + + procedure g_check_for_fpu_exception(list: TAsmList); override; protected function fixref(list: TAsmList; var ref: treference): boolean; procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister); @@ -555,6 +557,7 @@ unit cgrv; list.concat(ai); rg[R_FPUREGISTER].add_move_instruction(ai); end; + g_check_for_fpu_exception(list); end; @@ -713,4 +716,27 @@ unit cgrv; a_load_reg_reg(list,OS_INT,size,dst,dst) end; + + procedure tcgrv.g_check_for_fpu_exception(list: TAsmList); + var + r : TRegister; + ai: taicpu; + l: TAsmLabel; + begin + if cs_check_fpu_exceptions in current_settings.localswitches then + begin + r:=getintregister(list,OS_INT); + list.concat(taicpu.op_reg(A_FRFLAGS,r)); + current_asmdata.getjumplabel(l); + ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,r,NR_X0,l,0); + ai.is_jmp:=true; + ai.condition:=C_EQ; + list.concat(ai); + alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); + cg.a_call_name(current_asmdata.CurrAsmList,'FPC_THROWFPUEXCEPTION',false); + dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); + a_label(list,l); + end; + end; + end. diff --git a/compiler/riscv/nrvadd.pas b/compiler/riscv/nrvadd.pas index 672e9ee6f4..60f7095b2e 100644 --- a/compiler/riscv/nrvadd.pas +++ b/compiler/riscv/nrvadd.pas @@ -399,11 +399,13 @@ implementation // emit the actual operation if not cmpop then begin - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)) + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); end else begin current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); if inv then current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_XORI,location.register,location.register,1)); diff --git a/compiler/riscv/nrvinl.pas b/compiler/riscv/nrvinl.pas index cc6eaa211a..4d29506dc6 100644 --- a/compiler/riscv/nrvinl.pas +++ b/compiler/riscv/nrvinl.pas @@ -125,11 +125,17 @@ implementation load_fpu_location; case left.location.size of OS_F32: - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_S,location.register, - left.location.register)); + begin + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_S,location.register, + left.location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); + end; OS_F64: - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_D,location.register, - left.location.register)); + begin + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT_D,location.register, + left.location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); + end else inherited; end; @@ -161,8 +167,10 @@ implementation else op := A_FMUL_D; current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,left.location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); end; + procedure trvinlinenode.second_fma; const op : array[os_f32..os_f64,false..true,false..true] of TAsmOp = @@ -233,6 +241,7 @@ implementation location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size); current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_reg(op[def_cgsize(resultdef), negproduct,negop3],location.register,paraarray[1].location.register,paraarray[2].location.register,paraarray[2].location.register)); + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); end else internalerror(2014032301);