Module Name: src
Committed By: riastradh
Date: Wed Nov 7 06:47:38 UTC 2018
Modified Files:
src/lib/libm/arch/aarch64: fenv.c
src/sys/arch/aarch64/aarch64: fpu.c
src/sys/arch/aarch64/include: armreg.h
Log Message:
When hardware subnormal support is available, disable flush-to-zero.
Similarly, when hardware NaN propagation is available, disable
default-NaN substitution.
This enables IEEE 754 semantics on any hardware that supports it by
default. Programs that want flush-to-zero or default-NaN substitution
can enable them explicitly.
ok ryo@
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libm/arch/aarch64/fenv.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/aarch64/aarch64/fpu.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/aarch64/include/armreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libm/arch/aarch64/fenv.c
diff -u src/lib/libm/arch/aarch64/fenv.c:1.3 src/lib/libm/arch/aarch64/fenv.c:1.4
--- src/lib/libm/arch/aarch64/fenv.c:1.3 Wed Mar 22 23:11:08 2017
+++ src/lib/libm/arch/aarch64/fenv.c Wed Nov 7 06:47:38 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fenv.c,v 1.3 2017/03/22 23:11:08 chs Exp $ */
+/* $NetBSD: fenv.c,v 1.4 2018/11/07 06:47:38 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: fenv.c,v 1.3 2017/03/22 23:11:08 chs Exp $");
+__RCSID("$NetBSD: fenv.c,v 1.4 2018/11/07 06:47:38 riastradh Exp $");
#include "namespace.h"
@@ -63,7 +63,7 @@ __weak_alias(feupdateenv,_feupdateenv)
const fenv_t __fe_dfl_env = {
.__fpsr = 0,
- .__fpcr = FPCR_FZ|FPCR_DN|FPCR_RN,
+ .__fpcr = __SHIFTIN(FPCR_RN, FPCR_RMODE),
};
/*
Index: src/sys/arch/aarch64/aarch64/fpu.c
diff -u src/sys/arch/aarch64/aarch64/fpu.c:1.2 src/sys/arch/aarch64/aarch64/fpu.c:1.3
--- src/sys/arch/aarch64/aarch64/fpu.c:1.2 Sun Apr 1 04:35:03 2018
+++ src/sys/arch/aarch64/aarch64/fpu.c Wed Nov 7 06:47:38 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.2 2018/04/01 04:35:03 ryo Exp $ */
+/* $NetBSD: fpu.c,v 1.3 2018/11/07 06:47:38 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: fpu.c,v 1.2 2018/04/01 04:35:03 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: fpu.c,v 1.3 2018/11/07 06:47:38 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -75,10 +75,62 @@ fpu_state_load(lwp_t *l, unsigned int fl
KASSERT(l == curlwp);
if (__predict_false((flags & PCU_VALID) == 0)) {
+ uint64_t mvfr1 = reg_mvfr1_el1_read();
+ bool fp16 = false;
+ uint32_t fpcr = 0;
+
+ /*
+ * Determine whether ARMv8.2-FP16 binary16
+ * floating-point arithmetic is supported.
+ */
+ switch (__SHIFTOUT(mvfr1, MVFR1_FPHP)) {
+ case MVFR1_FPHP_HALF_ARITH:
+ fp16 = true;
+ break;
+ }
+
+ /* Rounding mode: round to nearest, ties to even. */
+ fpcr |= __SHIFTIN(FPCR_RN, FPCR_RMODE);
+
+ /* NaN propagation or default NaN. */
+ switch (__SHIFTOUT(mvfr1, MVFR1_FPDNAN)) {
+ case MVFR1_FPDNAN_NAN:
+ /*
+ * IEEE 754 NaN propagation supported. Don't
+ * enable default NaN mode.
+ */
+ break;
+ default:
+ /*
+ * IEEE 754 NaN propagation not supported, so
+ * enable default NaN mode.
+ */
+ fpcr |= FPCR_DN;
+ }
+
+ /* Subnormal arithmetic or flush-to-zero. */
+ switch (__SHIFTOUT(mvfr1, MVFR1_FPFTZ)) {
+ case MVFR1_FPFTZ_DENORMAL:
+ /*
+ * IEEE 754 subnormal arithmetic supported.
+ * Don't enable flush-to-zero mode.
+ */
+ break;
+ default:
+ /*
+ * IEEE 754 subnormal arithmetic not supported,
+ * so enable flush-to-zero mode. If FP16 is
+ * supported, also enable flush-to-zero for
+ * binary16 arithmetic.
+ */
+ fpcr |= FPCR_FZ;
+ if (fp16)
+ fpcr |= FPCR_FZ16;
+ }
+
/* initialize fpregs */
memset(&pcb->pcb_fpregs, 0, sizeof(pcb->pcb_fpregs));
- pcb->pcb_fpregs.fpcr =
- FPCR_DN | FPCR_FZ | __SHIFTIN(FPCR_RN, FPCR_RMODE);
+ pcb->pcb_fpregs.fpcr = fpcr;
curcpu()->ci_vfp_use.ev_count++;
} else {
Index: src/sys/arch/aarch64/include/armreg.h
diff -u src/sys/arch/aarch64/include/armreg.h:1.19 src/sys/arch/aarch64/include/armreg.h:1.20
--- src/sys/arch/aarch64/include/armreg.h:1.19 Fri Oct 12 01:28:58 2018
+++ src/sys/arch/aarch64/include/armreg.h Wed Nov 7 06:47:38 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: armreg.h,v 1.19 2018/10/12 01:28:58 ryo Exp $ */
+/* $NetBSD: armreg.h,v 1.20 2018/11/07 06:47:38 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -102,6 +102,7 @@ AARCH64REG_WRITE_INLINE(fpcr)
#define FPCR_RM 2 // Round towards Minus infinity
#define FPCR_RZ 3 // Round towards Zero
#define FPCR_STRIDE __BITS(21,20)
+#define FPCR_FZ16 __BIT(19) // Flush-To-Zero for FP16
#define FPCR_LEN __BITS(18,16)
#define FPCR_IDE __BIT(15) // Input Denormal Exception enable
#define FPCR_IXE __BIT(12) // IneXact Exception enable
@@ -303,9 +304,11 @@ AARCH64REG_READ_INLINE(mvfr1_el1)
#define MVFR1_FPHP_NONE 0
#define MVFR1_FPHP_HALF_SINGLE 1
#define MVFR1_FPHP_HALF_DOUBLE 2
+#define MVFR1_FPHP_HALF_ARITH 3
#define MVFR1_SIMDHP __BITS(23,20)
#define MVFR1_SIMDHP_NONE 0
#define MVFR1_SIMDHP_HALF 1
+#define MVFR1_SIMDHP_HALF_ARITH 3
#define MVFR1_SIMDSP __BITS(19,16)
#define MVFR1_SIMDSP_NONE 0
#define MVFR1_SIMDSP_SINGLE 1