diff options
author | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2025-04-19 08:12:07 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-04-19 08:12:07 -0600 |
commit | 05c4e3ecb54d22836ba2ae0ec1efedf8b78d7522 (patch) | |
tree | 6386a27c276a394ebc18472c576ffc7b9fcab7bf | |
parent | 2a643f55f5acc05dcc7cee133647bf3193d5b563 (diff) | |
download | gcc-05c4e3ecb54d22836ba2ae0ec1efedf8b78d7522.zip gcc-05c4e3ecb54d22836ba2ae0ec1efedf8b78d7522.tar.gz gcc-05c4e3ecb54d22836ba2ae0ec1efedf8b78d7522.tar.bz2 |
[PATCH v2] sh: libgcc: Implement fenv rouding and exceptions for soft-fp [PR118257]
Implement fenv rouding and exceptions for soft-fp, as per SuperH
arch specification.
No new tests required, as it's already covered by many torture tests
with fenv_exceptions.
PR target/118257
libgcc/ChangeLog:
* config/sh/sfp-machine.h (_FPU_GETCW): Implement with builtin.
(_FPU_SETCW): Likewise.
(FP_EX_ENABLE_SHIFT): Derive from arch spec.
(FP_EX_CAUSE_SHIFT): Likewise.
(FP_RND_MASK): Likewise.
(FP_EX_INVALID): Likewise.
(FP_EX_DIVZERO): Likewise.
(FP_EX_ALL): Likewise.
(FP_EX_OVERFLOW): Likewise.
(FP_EX_UNDERFLOW): Likewise.
(FP_EX_INEXACT): Likewise.
(_FP_DECL_EX): Declear default FCSR value.
(FP_RND_NEAREST): Derive from arch spec.
(FP_RND_ZERO): Likewise.
(FP_INIT_ROUNDMODE): Likewise.
(FP_ROUNDMODE): Likewise.
(FP_TRAPPING_EXCEPTIONS): Likewise.
(FP_HANDLE_EXCEPTIONS): Implement with _FPU_SETCW.
-rw-r--r-- | libgcc/config/sh/sfp-machine.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/libgcc/config/sh/sfp-machine.h b/libgcc/config/sh/sfp-machine.h index 67bc415..8030c80 100644 --- a/libgcc/config/sh/sfp-machine.h +++ b/libgcc/config/sh/sfp-machine.h @@ -76,6 +76,52 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); R##_c = FP_CLS_NAN; \ } while (0) +#ifdef __SH_FPU_ANY__ +#define _FPU_GETCW(fpscr) fpscr = __builtin_sh_get_fpscr () +#define _FPU_SETCW(fpscr) __builtin_sh_set_fpscr (fpscr) +#define FP_EX_ENABLE_SHIFT 5 +#define FP_EX_CAUSE_SHIFT 10 + +#define FP_EX_INVALID 0x0040 +#define FP_EX_DIVZERO 0x0020 +#if defined (__SH2E__) +#define FP_EX_ALL (FP_EX_DIVZERO | FP_EX_INVALID) +#else +#define FP_EX_OVERFLOW 0x0010 +#define FP_EX_UNDERFLOW 0x0008 +#define FP_EX_INEXACT 0x0004 +#define FP_EX_ALL (FP_EX_DIVZERO | FP_EX_INEXACT | \ + FP_EX_INVALID | FP_EX_OVERFLOW | FP_EX_UNDERFLOW) +#endif +#define _FP_DECL_EX \ + unsigned int _fcsr __attribute__ ((unused)) = FP_RND_NEAREST +/* Rounding modes. */ +#define FP_RND_NEAREST 0x0 +#define FP_RND_ZERO 0x1 +/* Placeholder, hardware does not have PINF/MINF modes. */ +#define FP_RND_PINF 0x2 +#define FP_RND_MINF 0x3 +#define FP_RND_MASK 3 + +#define FP_INIT_ROUNDMODE _FPU_GETCW (_fcsr) +#define FP_ROUNDMODE (_fcsr & FP_RND_MASK) +#define FP_TRAPPING_EXCEPTIONS ((_fcsr >> FP_EX_ENABLE_SHIFT) & FP_EX_ALL) +#define FP_HANDLE_EXCEPTIONS \ + do { \ + _fcsr &= ~(FP_EX_ALL << FP_EX_CAUSE_SHIFT); \ + _fcsr |= _fex | (_fex << FP_EX_CAUSE_SHIFT); \ + _FPU_SETCW (_fcsr); \ + } while (0) +#else +#define FP_EX_INVALID (1 << 4) +#define FP_EX_DIVZERO (1 << 3) +#if !defined (__SH2E__) +#define FP_EX_OVERFLOW (1 << 2) +#define FP_EX_UNDERFLOW (1 << 1) +#define FP_EX_INEXACT (1 << 0) +#endif +#endif + #define _FP_TININESS_AFTER_ROUNDING 1 #define __LITTLE_ENDIAN 1234 |