|
|
Message-ID: <4d479701dd2fb1944d2d8d34e0bd8047c5e2d3cb.1693396649.git.quic_mathbern@quicinc.com>
Date: Wed, 30 Aug 2023 09:22:27 -0300
From: Matheus Tavares Bernardino <quic_mathbern@...cinc.com>
To: <musl@...ts.openwall.com>
CC: Brian Cain <bcain@...cinc.com>, Sid Manning <sidneym@...cinc.com>,
"Rich
Felker" <dalias@...c.org>, Fangrui Song <i@...kray.me>,
Szabolcs Nagy
<nsz@...t70.net>
Subject: [RFC PATCH 2/5] hexagon: add fenv header and implementation
From: Brian Cain <bcain@...cinc.com>
---
arch/hexagon/bits/fenv.h | 20 ++++++
src/fenv/hexagon/fenv.S | 144 +++++++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+)
create mode 100644 arch/hexagon/bits/fenv.h
create mode 100644 src/fenv/hexagon/fenv.S
diff --git a/arch/hexagon/bits/fenv.h b/arch/hexagon/bits/fenv.h
new file mode 100644
index 00000000..d3349306
--- /dev/null
+++ b/arch/hexagon/bits/fenv.h
@@ -0,0 +1,20 @@
+#define FE_INVALID (1 << 1)
+#define FE_DIVBYZERO (1 << 2)
+#define FE_OVERFLOW (1 << 3)
+#define FE_UNDERFLOW (1 << 4)
+#define FE_INEXACT (1 << 5)
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+ FE_OVERFLOW | FE_UNDERFLOW)
+
+#define FE_TONEAREST 0x00
+#define FE_TOWARDZERO 0x01
+#define FE_DOWNWARD 0x02
+#define FE_UPWARD 0x03
+
+typedef unsigned long fexcept_t;
+
+typedef struct {
+ unsigned long __cw;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *) -1)
diff --git a/src/fenv/hexagon/fenv.S b/src/fenv/hexagon/fenv.S
new file mode 100644
index 00000000..f5080a22
--- /dev/null
+++ b/src/fenv/hexagon/fenv.S
@@ -0,0 +1,144 @@
+/*
+ * The Hexagon user status register includes five status fields which work
+ * as sticky flags for the five IEEE-defined exception conditions:
+ * inexact, overflow, underflow, divide by zero, and invalid.
+ * A sticky flag is set when the corresponding exception occurs,
+ * and remains set until explicitly cleared.
+ *
+ * usr:23:22 - Rounding Mode
+ * 00: Round toward nearest
+ * 01: Round toward zero
+ * 10: Downward Round toward negative infinity
+ * 11: Upward Round toward positive infinity
+ *
+ * usr:5 - Floating-point IEEE Inexact Sticky Flag.
+ * usr:4 - Floating-point IEEE Underflow Sticky Flag.
+ * usr:3 - Floating-point IEEE Overflow Sticky Flag.
+ * usr:2 - Floating-point IEEE Divide-By-Zero Sticky Flag.
+ * usr:1 - Floating-point IEEE Invalid Sticky Flag.
+ * usr:0 - Sticky Saturation Overflow, when 1 saturation occurred.
+ */
+
+#define FE_ALL_EXCEPT 0x3f
+
+#define USR_FE_MASK 0x3fc0003f
+#define RND_MASK (0x3 << 22)
+#define RND_NEAR (0x0 << 22)
+#define RND_ZERO (0x1 << 22)
+#define RND_DOWN (0x2 << 22)
+#define RND_UP (0x3 << 22)
+
+/*
+ * int feclearexcept(int mask)
+ */
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+ {
+ r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits.
+ r1 = usr
+ }
+ r1 = and(r1, ~r0)
+ {
+ usr = r1
+ r0 = #0
+ jumpr r31
+ }
+
+/*
+ * int feraiseexcept(int mask)
+ */
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+ {
+ r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits.
+ r1 = usr
+ }
+ r1 = or(r1, r0)
+ {
+ usr = r1
+ r0 = #0
+ jumpr r31
+ }
+
+
+/*
+ * int fetestexcept(int mask)
+ */
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+ {
+ r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits.
+ r1 = usr
+ }
+ {
+ r0 = and(r1, r0)
+ jumpr r31
+ }
+
+/*
+ *int fegetround(void)
+ */
+.global fegetround
+.type fegetround,@function
+fegetround:
+ r0 = usr
+ r0 = and(r0, ##RND_MASK)
+ r0 = lsr(r0, #22);
+ jumpr r31
+
+/*
+ * int __fesetround(int r)
+ */
+.global __fesetround
+.type __fesetround,@function
+__fesetround:
+ {
+ r0 = and(r0, #0x3) // Can only be 0,1,2, or 3
+ r1 = usr
+ r2 = ##RND_MASK
+ }
+ {
+ r1 = and (r1, ~r2) // Clear the current rounding bits.
+ r0 = asl (r0, #22)
+ }
+ r1 = or(r1, r0)
+ usr = r1
+ {
+ r0 = #0; jumpr r31
+ }
+
+/*
+ * int fegetenv(fenv_t *envp)
+ */
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+ r1 = usr
+ memw(r0) = r1
+ {
+ r0 = #0
+ jumpr r31
+ }
+
+/*
+ * int fesetenv(const fenv_t *envp)
+ */
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+ { p0 = cmp.eq(r0, #-1); if (p0.new) r1 = #0 } /* The default mode */
+ if (!p0) r1 = memw(r0) /* stored in fenv_t */
+
+ r2 = ##USR_FE_MASK // USR:FE bit mask
+ r1 = and(r1, r2) // MASK the input bits with the FE bits
+ r3 = usr
+ r3 = and(r3, ~r2) // Clear any currently set FE bits
+ r3 = or(r3, r1) // Set the newbits
+ usr = r3
+ {
+ r0 = #0
+ jumpr r31
+ }
--
2.37.2
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.