From 16b298e61cee1be93d35b9701e9900ac4f7cbf5a Mon Sep 17 00:00:00 2001 From: unknown <71151164+ZERICO2005@users.noreply.github.com> Date: Fri, 9 May 2025 09:22:25 -0600 Subject: [PATCH] Optimized __setflag, removed float64_to_int.c --- src/crt/float64_to_int.c | 140 --------------------------------------- src/crt/os.src | 2 - src/crt/setflag.src | 24 +++++++ 3 files changed, 24 insertions(+), 142 deletions(-) delete mode 100644 src/crt/float64_to_int.c create mode 100644 src/crt/setflag.src diff --git a/src/crt/float64_to_int.c b/src/crt/float64_to_int.c deleted file mode 100644 index 3b32300ca..000000000 --- a/src/crt/float64_to_int.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include - -typedef union F64_pun { - long double flt; - uint64_t bin; - struct { - uint24_t UHL; - uint24_t UDE; - uint16_t BC; - } reg; -} F64_pun; - -#define Float64_pos_one UINT64_C(0x3FF0000000000000) - -#define Float64_bias 1023 -#define Float64_mant_bits 52 -#define Float64_u64_max_exp 64 -#define Float64_u32_max_exp 32 -#define Float64_i64_max_exp 63 -#define Float64_i32_max_exp 31 -#define Float64_exp_BC_shift 4 - -#if 0 -/** - * This routine can be used for specifically _dtoul and _dtoull - */ -uint64_t _dtoull_c(long double x) { - F64_pun val; - val.flt = x; - // if trunc(x) is zero or x is negative - if ((int64_t)val.bin < (int64_t)Float64_pos_one) { - #if 0 - if (iszero(x)) { - return 0; - } - return UINT32_MAX; - #else - /* undefined behaviour for negative values of x */ - return 0; - #endif - } - unsigned expon = val.reg.BC; - // exponent is stored in bits [4, 14], so we shift it to be bits [0, 10]. - expon >>= 4; - // doesn't underflow since 1.0 - Float64_bias gives us an exponent of zero - expon -= Float64_bias; - if (expon >= Float64_u64_max_exp) { - /* undefined return value for overflow */ - return UINT64_MAX; - } - // clears the exponent field without touching the mantissa - val.reg.BC &= 0x000F; - // sets the LSB of the exponent since x is normalized - val.reg.BC |= 0x0010; - if (expon < Float64_mant_bits) { - val.bin >>= Float64_mant_bits - expon; - return val.bin; - } - /* expon >= 52 or [52, 63] */ - val.bin <<= expon - 52; - return val.bin; -} -#endif - -typedef struct f64_sign { - long double flt; - bool sign; -} f64_sign; - -/** - * @note val must have the signbit cleared - */ -static uint64_t f64_to_unsigned(F64_pun val) { - // if trunc(x) is zero - if (val.bin < Float64_pos_one) { - return 0; - } - unsigned expon = val.reg.BC; - // exponent is stored in bits [4, 14], so we shift it to be bits [0, 10]. - expon >>= Float64_exp_BC_shift; - // doesn't underflow since 1.0 - Float64_bias gives us an exponent of zero - expon -= Float64_bias; - // clears the exponent field without touching the mantissa - val.reg.BC &= 0x000F; - // sets the LSB of the exponent since x is normalized - val.reg.BC |= 0x0010; - if (expon < Float64_mant_bits) { - /* expon is [0, 51] */ - val.bin >>= Float64_mant_bits - expon; - return val.bin; - } - /* expon >= 52 or [52, 63] */ - val.bin <<= expon - 52; - return val.bin; -} - - - -/** - * @brief the exact same routine is used for (long long)long double and - * (unsigned long long)long double. If the input long double is out of range, - * then the conversion is UB anyways. - */ -int64_t _dtoll_c(f64_sign arg) { - F64_pun val; - bool x_sign = arg.sign; - val.flt = arg.flt; - - /* overflow || isinf(x) || isnan(x) */ - if (val.reg.BC >= ((Float64_bias + Float64_u64_max_exp) << Float64_exp_BC_shift)) { - /* undefined return value for underflow/overflow/inf/NaN values of x */ - return 0; - } - - int64_t ret = (int64_t)f64_to_unsigned(val); - ret = x_sign ? -ret : ret; - return ret; -} - -/** - * @brief the exact same routine is used for (long)long double and - * (unsigned long)long double. If the input long double is out of range, - * then the conversion is UB anyways. - */ -int32_t _dtol_c(f64_sign arg) { - F64_pun val; - bool x_sign = arg.sign; - val.flt = arg.flt; - - /* overflow || isinf(x) || isnan(x) */ - if (val.reg.BC >= ((Float64_bias + Float64_u32_max_exp) << Float64_exp_BC_shift)) { - /* undefined return value for underflow/overflow/inf/NaN values of x */ - return 0; - } - int32_t ret = (int32_t)f64_to_unsigned(val); - ret = x_sign ? -ret : ret; - return ret; -} diff --git a/src/crt/os.src b/src/crt/os.src index 8365f4a94..dcf79294d 100644 --- a/src/crt/os.src +++ b/src/crt/os.src @@ -30,8 +30,6 @@ __ishru_b := 000188h __itol := 000194h public __ltof __ltof := 000284h - public __setflag -__setflag := 000218h public __sshl_b __sshl_b := 000244h public __sshrs_b diff --git a/src/crt/setflag.src b/src/crt/setflag.src new file mode 100644 index 000000000..09789d862 --- /dev/null +++ b/src/crt/setflag.src @@ -0,0 +1,24 @@ + assume adl=1 + + section .text + + public __setflag + +if PREFER_OS_CRT + +__setflag := 000218h + +else + +__setflag: + ret po + push af + ex (sp), hl + ld a, l + xor a, $80 ; invert S flag + ld l, a + ex (sp), hl + pop af + ret + +end if