Skip to content

Commit 65d118c

Browse files
authored
RISC-V __mulsf3: handle exponent increase due to rounding (#2086)
1 parent 39a7f97 commit 65d118c

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/rp2_common/pico_float/float_single_hazard3.S

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,10 @@ __mulsf3:
216216
clz a0, a4
217217
sll a4, a4, a0
218218
sub a2, a2, a0
219-
// After normalising we can calculate the final exponent, since rounding
220-
// cannot increase the exponent for multiplication (unlike addition)
221219
add a2, a2, a3
222220
// Subtract redundant bias term (127), add 1 for normalisation correction
223221
addi a2, a2, -126
224222
blez a2, __mulsf_underflow
225-
bge a2, t0, __mulsf_overflow
226223

227224
// Gather sticky bits from low fraction:
228225
snez a1, a1
@@ -231,13 +228,21 @@ __mulsf3:
231228
bexti a1, a4, 8
232229
add a4, a4, a1
233230
addi a4, a4, 127
231+
// Check carry-out: exponent may increase due to rounding
232+
bgez a4, 2f
233+
1:
234+
bge a2, t0, __mulsf_overflow
234235
// Pack it and ship it
235236
packh a2, a2, a6
236237
slli a2, a2, 23
237238
slli a4, a4, 1
238239
srli a4, a4, 9
239240
add a0, a4, a2
240241
ret
242+
2:
243+
srli a4, a4, 1
244+
addi a2, a2, 1
245+
j 1b
241246

242247
__mulsf_underflow:
243248
// Signed zero

test/pico_float_test/pico_float_test_hazard3.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ test_t mul_directed_tests[] = {
149149
// 1.25 x 2^-63 x 1.25 x 2^-64 = 0
150150
// (normal inputs with subnormal output, and we claim to be FTZ)
151151
{0x20200000u, 0x1fa00000u, 0x00000000u},
152+
// 1.333333 (rounded down) x 1.5 = 2 - 1 ulp
153+
{0x3faaaaaau, 0x3fc00000u, 0x3fffffffu},
154+
// 1.333333 (rounded down) x (1.5 + 1 ulp) = 2 exactly
155+
{0x3faaaaaau, 0x3fc00001u, 0x40000000u},
156+
// (1.333333 (rounded down) + 1 ulp) x 1.5 = 2 exactly
157+
{0x3faaaaabu, 0x3fc00000u, 0x40000000u},
158+
// (1.25 - 1 ulp) x (0.8 + 1 ulp) = 1 exactly (exponent increases after rounding)
159+
{0x3f9fffffu, 0x3f4cccceu, 0x3f800000u},
160+
// as above, but overflow on exponent increase -> +inf
161+
{0x3f9fffffu, 0x7f4cccceu, 0x7f800000u},
162+
// subtract 1 ulp from rhs -> largest normal
163+
{0x3f9fffffu, 0x7f4ccccdu, 0x7f7fffffu},
152164
};
153165

154166
#define N_RANDOM_TESTS 1000

0 commit comments

Comments
 (0)