|
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.