Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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.