summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-08-19 10:56:47 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-08-19 10:56:47 +0000
commit606b305dfa5f96c07338814a46c37f3c74f065b1 (patch)
treef41c31be2d66700baffc8f1c6fccc28de0c32525
parent7e3e75f1ddd29aab06e7efbeef4bb7320d752643 (diff)
downloadfpc-606b305dfa5f96c07338814a46c37f3c74f065b1.tar.gz
+ support to generate software based floating point exception checking
(enabled by -CE) git-svn-id: https://svn.freepascal.org/svn/fpc/branches/laksen@39639 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv_new/compiler/riscv/cgrv.pas26
-rw-r--r--riscv_new/compiler/riscv/nrvadd.pas4
-rw-r--r--riscv_new/compiler/riscv/nrvinl.pas17
3 files changed, 42 insertions, 5 deletions
diff --git a/riscv_new/compiler/riscv/cgrv.pas b/riscv_new/compiler/riscv/cgrv.pas
index d73c800549..0d5075f987 100644
--- a/riscv_new/compiler/riscv/cgrv.pas
+++ b/riscv_new/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/riscv_new/compiler/riscv/nrvadd.pas b/riscv_new/compiler/riscv/nrvadd.pas
index 672e9ee6f4..60f7095b2e 100644
--- a/riscv_new/compiler/riscv/nrvadd.pas
+++ b/riscv_new/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/riscv_new/compiler/riscv/nrvinl.pas b/riscv_new/compiler/riscv/nrvinl.pas
index cc6eaa211a..4d29506dc6 100644
--- a/riscv_new/compiler/riscv/nrvinl.pas
+++ b/riscv_new/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);