diff options
| author | Mitchell Riedstra <mitch@riedstra.dev> | 2025-12-24 19:49:57 -0500 |
|---|---|---|
| committer | Mitchell Riedstra <mitch@riedstra.dev> | 2025-12-24 19:49:57 -0500 |
| commit | 939ac4319cb047a37ba46f84eff81948063f6954 (patch) | |
| tree | 5112cf8aad73125a13f5b52c0290a7f26f948b52 /jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h | |
| parent | 3a1b5ba15b89c907f9bf66a0761ffdd73b32208b (diff) | |
| download | unixv4-939ac4319cb047a37ba46f84eff81948063f6954.tar.gz unixv4-939ac4319cb047a37ba46f84eff81948063f6954.tar.xz | |
Add working webpage for unix v4
Diffstat (limited to 'jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h')
| -rw-r--r-- | jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h b/jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h new file mode 100644 index 0000000..9360ac1 --- /dev/null +++ b/jslinux-2019-12-21/tinyemu-2019-12-21/softfp_template_icvt.h @@ -0,0 +1,171 @@ +/* + * SoftFP Library + * + * Copyright (c) 2016 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#if ICVT_SIZE == 32 +#define ICVT_UINT uint32_t +#define ICVT_INT int32_t +#elif ICVT_SIZE == 64 +#define ICVT_UINT uint64_t +#define ICVT_INT int64_t +#elif ICVT_SIZE == 128 +#define ICVT_UINT uint128_t +#define ICVT_INT int128_t +#else +#error unsupported icvt +#endif + +/* conversions between float and integers */ +static ICVT_INT glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, + uint32_t *pfflags, BOOL is_unsigned) +{ + uint32_t a_sign, addend, rnd_bits; + int32_t a_exp; + F_UINT a_mant; + ICVT_UINT r, r_max; + + a_sign = a >> (F_SIZE - 1); + a_exp = (a >> MANT_SIZE) & EXP_MASK; + a_mant = a & MANT_MASK; + if (a_exp == EXP_MASK && a_mant != 0) + a_sign = 0; /* NaN is like +infinity */ + if (a_exp == 0) { + a_exp = 1; + } else { + a_mant |= (F_UINT)1 << MANT_SIZE; + } + a_mant <<= RND_SIZE; + a_exp = a_exp - (EXP_MASK / 2) - MANT_SIZE; + + if (is_unsigned) + r_max = (ICVT_UINT)a_sign - 1; + else + r_max = ((ICVT_UINT)1 << (ICVT_SIZE - 1)) - (ICVT_UINT)(a_sign ^ 1); + if (a_exp >= 0) { + if (a_exp <= (ICVT_SIZE - 1 - MANT_SIZE)) { + r = (ICVT_UINT)(a_mant >> RND_SIZE) << a_exp; + if (r > r_max) + goto overflow; + } else { + overflow: + *pfflags |= FFLAG_INVALID_OP; + return r_max; + } + } else { + a_mant = rshift_rnd(a_mant, -a_exp); + + switch(rm) { + case RM_RNE: + case RM_RMM: + addend = (1 << (RND_SIZE - 1)); + break; + case RM_RTZ: + addend = 0; + break; + default: + case RM_RDN: + case RM_RUP: + if (a_sign ^ (rm & 1)) + addend = (1 << RND_SIZE) - 1; + else + addend = 0; + break; + } + + rnd_bits = a_mant & ((1 << RND_SIZE ) - 1); + a_mant = (a_mant + addend) >> RND_SIZE; + /* half way: select even result */ + if (rm == RM_RNE && rnd_bits == (1 << (RND_SIZE - 1))) + a_mant &= ~1; + if (a_mant > r_max) + goto overflow; + r = a_mant; + if (rnd_bits != 0) + *pfflags |= FFLAG_INEXACT; + } + if (a_sign) + r = -r; + return r; +} + +ICVT_INT glue(glue(glue(cvt_sf, F_SIZE), _i), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, + uint32_t *pfflags) +{ + return glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE)(a, rm, + pfflags, FALSE); +} + +ICVT_UINT glue(glue(glue(cvt_sf, F_SIZE), _u), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, + uint32_t *pfflags) +{ + return glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE) (a, rm, + pfflags, TRUE); +} + +/* conversions between float and integers */ +static F_UINT glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(ICVT_INT a, + RoundingModeEnum rm, + uint32_t *pfflags, + BOOL is_unsigned) +{ + uint32_t a_sign; + int32_t a_exp; + F_UINT a_mant; + ICVT_UINT r, mask; + int l; + + if (!is_unsigned && a < 0) { + a_sign = 1; + r = -(ICVT_UINT)a; + } else { + a_sign = 0; + r = a; + } + a_exp = (EXP_MASK / 2) + F_SIZE - 2; + /* need to reduce range before generic float normalization */ + l = ICVT_SIZE - glue(clz, ICVT_SIZE)(r) - (F_SIZE - 1); + if (l > 0) { + mask = r & (((ICVT_UINT)1 << l) - 1); + r = (r >> l) | ((r & mask) != 0); + a_exp += l; + } + a_mant = r; + return normalize_sf(a_sign, a_exp, a_mant, rm, pfflags); +} + +F_UINT glue(glue(glue(cvt_i, ICVT_SIZE), _sf), F_SIZE)(ICVT_INT a, + RoundingModeEnum rm, + uint32_t *pfflags) +{ + return glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(a, rm, pfflags, FALSE); +} + +F_UINT glue(glue(glue(cvt_u, ICVT_SIZE), _sf), F_SIZE)(ICVT_UINT a, + RoundingModeEnum rm, + uint32_t *pfflags) +{ + return glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(a, rm, pfflags, TRUE); +} + +#undef ICVT_SIZE +#undef ICVT_INT +#undef ICVT_UINT |
