summaryrefslogtreecommitdiff
path: root/rtl/arm
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-07-28 21:06:36 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-07-28 21:06:36 +0000
commit3bc22edbd2fb539070dea8be47de7451980f70a1 (patch)
tree2d0611265142396fa17a6b075ff7d2a99cf4f5f9 /rtl/arm
parent0c3a1a51f1a1563494995e49b6c4bf3451630d61 (diff)
downloadfpc-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.inc57
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 }