The branch main has been updated by dchagin:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6e2caba7a1297eeda4f43e6377667d2e049f24f9

commit 6e2caba7a1297eeda4f43e6377667d2e049f24f9
Author:     Dmitry Chagin <[email protected]>
AuthorDate: 2022-05-19 16:53:56 +0000
Commit:     Dmitry Chagin <[email protected]>
CommitDate: 2022-05-19 16:53:56 +0000

    arm64: Enable the floating-point exception traps
    
    To enable it user-space needs to call feenableexcept().
    
    FPE_FLTIDO has been added as the IDF bit can't be mapped to any existing
    FPE code.
    
    Reviewed by:            andrew@
    Differential revision:  https://reviews.freebsd.org/D35247
    MFC after:              2 weeks
---
 sys/arm64/arm64/trap.c     | 32 +++++++++++++++++++++++++++++++-
 sys/arm64/include/armreg.h |  8 ++++++++
 sys/sys/signal.h           |  1 +
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index b664501b62fa..5bf6c3d1a81d 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -411,6 +411,29 @@ print_registers(struct trapframe *frame)
        printf("spsr:         %8x\n", frame->tf_spsr);
 }
 
+#ifdef VFP
+static void
+fpe_trap(struct thread *td, void *addr, uint32_t exception)
+{
+       int code;
+
+       code = FPE_FLTIDO;
+       if ((exception & ISS_FP_TFV) != 0) {
+               if ((exception & ISS_FP_IOF) != 0)
+                       code = FPE_FLTINV;
+               else if ((exception & ISS_FP_DZF) != 0)
+                       code = FPE_FLTDIV;
+               else if ((exception & ISS_FP_OFF) != 0)
+                       code = FPE_FLTOVF;
+               else if ((exception & ISS_FP_UFF) != 0)
+                       code = FPE_FLTUND;
+               else if ((exception & ISS_FP_IXF) != 0)
+                       code = FPE_FLTRES;
+       }
+       call_trapsignal(td, SIGFPE, code, addr, exception);
+}
+#endif
+
 void
 do_el1h_sync(struct thread *td, struct trapframe *frame)
 {
@@ -556,11 +579,18 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
 
        switch (exception) {
        case EXCP_FP_SIMD:
-       case EXCP_TRAP_FP:
 #ifdef VFP
                vfp_restore_state();
 #else
                panic("VFP exception in userland");
+#endif
+               break;
+       case EXCP_TRAP_FP:
+#ifdef VFP
+               fpe_trap(td, (void *)frame->tf_elr, esr);
+               userret(td, frame);
+#else
+               panic("VFP exception in userland");
 #endif
                break;
        case EXCP_SVC32:
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index fbed7aa79c38..44b11617fbf1 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -265,6 +265,14 @@
 
 /* ESR_ELx */
 #define        ESR_ELx_ISS_MASK        0x01ffffff
+#define         ISS_FP_TFV_SHIFT       23
+#define         ISS_FP_TFV             (0x01 << ISS_FP_TFV_SHIFT)
+#define         ISS_FP_IOF             0x01
+#define         ISS_FP_DZF             0x02
+#define         ISS_FP_OFF             0x04
+#define         ISS_FP_UFF             0x08
+#define         ISS_FP_IXF             0x10
+#define         ISS_FP_IDF             0x80
 #define         ISS_INSN_FnV           (0x01 << 10)
 #define         ISS_INSN_EA            (0x01 << 9)
 #define         ISS_INSN_S1PTW         (0x01 << 7)
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index 9dae3ce04745..27014c20973a 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -339,6 +339,7 @@ struct siginfo32 {
 #define FPE_FLTRES     6       /* Floating point inexact result.       */
 #define FPE_FLTINV     7       /* Invalid floating point operation.    */
 #define FPE_FLTSUB     8       /* Subscript out of range.              */
+#define FPE_FLTIDO     9       /* Input denormal operation             */
 
 /* codes for SIGTRAP */
 #define TRAP_BRKPT     1       /* Process breakpoint.                  */

Reply via email to