diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-07-28 21:06:36 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-07-28 21:06:36 +0000 |
commit | 3bc22edbd2fb539070dea8be47de7451980f70a1 (patch) | |
tree | 2d0611265142396fa17a6b075ff7d2a99cf4f5f9 /rtl/arm | |
parent | 0c3a1a51f1a1563494995e49b6c4bf3451630d61 (diff) | |
download | fpc-3bc22edbd2fb539070dea8be47de7451980f70a1.tar.gz |
+ software handling of exceptions on arm
* reworked software handling of exceptions so they can be check lazily
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@42525 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/arm')
-rw-r--r-- | rtl/arm/arm.inc | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc index 672968d449..5c3188c3f2 100644 --- a/rtl/arm/arm.inc +++ b/rtl/arm/arm.inc @@ -47,6 +47,63 @@ begin end; end; {$else} + + +const + fpu_nx = 1 shl 0; + fpu_uf = 1 shl 1; + fpu_of = 1 shl 2; + fpu_dz = 1 shl 3; + fpu_nv = 1 shl 4; + +function getfpscr: sizeuint; nostackframe; assembler; + asm + fmrx r0,fpscr + end; + + +procedure setfpscr(flags : sizeuint); nostackframe; assembler; + asm + fmxr fpscr,r0 + end; + + +const + FPSCR_IOC = 1; + FPSCR_DZC = 1 shl 1; + FPSCR_OFC = 1 shl 2; + FPSCR_UFC = 1 shl 3; + FPSCR_IXC = 1 shl 4; + FPSCR_IDC = 1 shl 7; + + +procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION']; + var + fpscr : longint; + f: TFPUException; + begin + { at this point, we know already, that an exception will be risen } + fpscr:=getfpscr; + + if (fpscr and FPSCR_DZC) <> 0 then + float_raise(exZeroDivide); + if (fpscr and FPSCR_OFC) <> 0 then + float_raise(exOverflow); + if (fpscr and FPSCR_UFC) <> 0 then + float_raise(exUnderflow); + if (fpscr and FPSCR_IOC) <> 0 then + float_raise(exInvalidOp); + if (fpscr and FPSCR_IXC) <> 0 then + float_raise(exPrecision); + if (fpscr and FPSCR_IDC) <> 0 then + float_raise(exDenormalized); + + { now the soft float exceptions } + for f in softfloat_exception_flags do + float_raise(f); + end; + + Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif} begin { Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL } |