Skip to content

Commit 8bc9b6a

Browse files
committed
ldexpf now signals FE_OVERFLOW and FE_UNDERFLOW
1 parent f04acc2 commit 8bc9b6a

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

src/libc/ldexpf.src

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,24 +129,26 @@ _ldexpf:
129129
jr nc, _ldexpf.shru_common
130130
; .underflow:
131131
inc b ; ld b, 0 ; sets Z
132-
.underflow_to_zero: ; <-- Z is set when underflowing to zero
133132
.overflow_to_inf: ; <-- NZ is set when infinite
134-
.raise_erange_avoid_negative_zero:
133+
ld a, $28 ; FE_OVERFLOW | FE_INEXACT
134+
.underflow_to_zero: ; <-- Z is set when underflowing to zero
135+
.raise_erange:
135136
ld hl, $800000
136137
jr nz, .overflow
138+
ld a, $24 ; FE_UNDERFLOW | FE_INEXACT
137139
add hl, hl ; ld hl, 0
138140
if __ldexpf_avoid_negative_zero
139141
; prevents negative zero from being emitted on underflow
140142
res 7, (iy + 6)
141143
end if
142144
.overflow:
143145
ex de, hl
144-
.raise_erange:
145146
ld hl, 5 ; ERANGE
146147
ld (_errno), hl
147148
.raise_inexact:
148149
ld hl, ___fe_cur_env
149-
set 5, (hl) ; FE_INEXACT
150+
or a, (hl)
151+
ld (hl), a
150152
.result_is_exact:
151153
ld a, (iy + 6) ; expon
152154
rla ; extract signbit
@@ -214,13 +216,10 @@ end if
214216
ld a, c ; UDE
215217
or a, d
216218
or a, e
219+
ld a, $20 ; FE_INEXACT
217220
jr nz, .raise_inexact
218221
; NZ needs to be set here
219-
if __ldexpf_avoid_negative_zero
220-
jr .raise_erange_avoid_negative_zero
221-
else
222222
jr .raise_erange
223-
end if
224223

225224
extern _errno
226225
extern ___fe_cur_env

test/floating_point/float32_ldexp/src/main.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,18 @@ size_t run_test(void) {
6565
F32_pun mant_0, mant_1;
6666
mant_0.flt = frexpf(fabsf(input[i].value.flt), &temp);
6767
mant_1.flt = frexpf(fabsf(output[i].flt ), &temp);
68-
bool inexact_raised = fetestexcept(FE_INEXACT);
68+
unsigned char fe_val = __fe_cur_env;
69+
bool inexact_raised = (fe_val & FE_INEXACT);
70+
bool underflow_raised = (fe_val & FE_UNDERFLOW);
71+
bool overflow_raised = (fe_val & FE_OVERFLOW);
6972
bool mant_equal = (mant_0.bin == mant_1.bin);
7073
bool became_zero = (mant_0.bin != 0 && mant_1.bin == 0);
7174
bool became_infinite = (mant_0.bin != UINT32_C(0x7F800000) && mant_1.bin == UINT32_C(0x7F800000));
72-
if (!((mant_equal != inexact_raised) && ((became_zero || became_infinite) == (errno == ERANGE)))) {
75+
if (!(
76+
(mant_equal != inexact_raised) &&
77+
((became_zero || became_infinite) == (errno == ERANGE)) &&
78+
(became_zero == underflow_raised) && (became_infinite == overflow_raised)
79+
)) {
7380
test_printf(
7481
"%zu: FE: %02X errno: %d\nI: %08lX %+d\nO: %08lX\n",
7582
i, (unsigned int)__fe_cur_env, errno,

0 commit comments

Comments
 (0)