Skip to content

Commit e235c8e

Browse files
committed
oops; fix double2int to include all lower mantissa bits
1 parent 5484c95 commit e235c8e

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

src/rp2_common/pico_double/double_aeabi_dcp.S

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,23 +203,22 @@ double_section double2int
203203
saving_func regular double2int
204204
double2int_entry:
205205
lsls r2, r1, #1
206-
// r1 = abs(zero) => r1 = 0x00000000
207-
// r1 = abs(denornaml) => r1 = 0x00.xxxxx
208-
// r1 = abs(1.0f) => r1 = 0x7f800000
209-
// r1 = abs(inf/nan) => r1 = 0xffXxxxxx
210206
bcc double2int_z_entry // positive is ok for int64_z
211207
orrs r3, r2, r0
212208
beq double2int_z_entry // 0 or -0 is ok for int64_z
213-
// r3 = last 3 bits of 23 significant bits of mantissa at position 32-23
214-
lsrs r3, r0, #32 - 3
215-
lsls r3, #9
216209

217210
lsrs r2, #21
218211
adds r2, #1
219212
subs r2, r2, #0x400
220213
bcc 1f // <1 means subtract 1
221-
// recreate the 23 significant bits of mantissa for float at the top of r3
222-
adds r3, r3, r1, lsl #12
214+
cmp r2, #52
215+
bge double2int_z_entry // must be an integer
216+
lsls r3, r1, #12
217+
adds r3, r3, r0, lsr #20
218+
// r3 now has highest 32 mantissa bits
219+
lsls r3, r2
220+
bne 1f // not integer as non zero fractional bits remain
221+
lsls r3, r0, #12
223222
lsls r3, r2
224223
beq double2int_z_entry // integer
225224
1:

test/pico_float_test/custom_double_funcs_test.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ int test() {
223223
test_checku64(double2ufix64_z(3.25, 2), 13, "double2ufix64_z7");
224224
test_checki64(double2ufix64_z(3.0, -1), 1, "double2fuix64_z8"); // not very useful
225225

226+
union {
227+
uint64_t u;
228+
double d;
229+
} u64d;
230+
226231
printf("double2int\n");
227232
test_checki(double2int(0.0), 0, "double2int1");
228233
test_checki(double2int(0.25), 0, "double2int1b");
@@ -236,12 +241,25 @@ int test() {
236241
test_checki(double2int(-0.75), -1, "double2int5");
237242
test_checki(double2int(-1.0), -1, "double2int5b");
238243
// todo test correct rounding around maximum precision
244+
test_checki(double2int(2147483646.0), INT32_MAX-1, "double2int6");
239245
test_checki(double2int(2147483647.0), INT32_MAX, "double2int6");
240246
test_checki(double2int(21474836470.0), INT32_MAX, "double2int7");
241247
test_checki(double2int(-2147483648.0), INT32_MIN, "double2int8");
242248
test_checki(double2int(-21474836480.0), INT32_MIN, "double2int9");
243249
test_checki(double2int(-2.5), -3, "double2int10");
244250
test_checki(double2int(-2.4), -3, "double2int11");
251+
u64d.u = 0xc000000000000000ull;
252+
test_checki(double2int(u64d.d), -2, "double2int12");
253+
u64d.u = 0xc008000000000000ull;
254+
test_checki(double2int(u64d.d), -3, "double2int12b");
255+
u64d.u = 0xc000000000000001ull;
256+
test_checki(double2int(u64d.d), -3, "double2int12c");
257+
u64d.u = 0xc000000080000000ull;
258+
test_checki(double2int(u64d.d), -3, "double2int12d");
259+
u64d.u = 0xc000000100000000ull;
260+
test_checki(double2int(u64d.d), -3, "double2int12e");
261+
u64d.u = 0xc000000100000001ull;
262+
test_checki(double2int(u64d.d), -3, "double2int12f");
245263

246264
printf("double2uint\n");
247265
test_checku(double2uint(0.0), 0, "double2uint1");
@@ -274,10 +292,6 @@ int test() {
274292
test_checki64(double2int64(-21474836480.0), -21474836480ll, "double2int649");
275293
test_checki64(double2int64(-2.5), -3, "double2int6410");
276294
test_checki64(double2int64(-2.4), -3, "double2int6411");
277-
union {
278-
uint64_t u;
279-
double d;
280-
} u64d;
281295
u64d.u = 0xc000000000000000ull;
282296
test_checki64(double2int64(u64d.d), -2, "double2int6412");
283297
u64d.u = 0xc008000000000000ull;

0 commit comments

Comments
 (0)