File tree Expand file tree Collapse file tree 5 files changed +605
-547
lines changed
test/floating_point/float64_to_integer/src Expand file tree Collapse file tree 5 files changed +605
-547
lines changed Original file line number Diff line number Diff line change 55 public __dtol
66 public __dtoul
77
8- ; __dtol_c correctly handles all non-UB cases for both
8+ ; __dtolll correctly handles all non-UB cases for both
99; (long)long double and (unsigned long)long double
10+
1011__dtol:
1112__dtoul:
12- ; f64_ret_i32
13- push af, iy
14- ld a, b
15- push bc, de, hl
16- ld hl, 7
17- add hl, sp
18- res 7, (hl) ; fabsl(x)
19- inc hl
20- rlca
21- ld (hl), a ; store the sign of x in the padding byte
22- call __dtol_c
23- pop af
24- ld a, e
13+ push bc
14+ push de
15+ call __dtoll
16+ ld c, e
2517 pop de
26- ld e, a
27- pop bc, iy, af
18+ ld e, c
19+ pop bc
2820 ret
2921
30- extern __dtol_c
22+ extern __dtoll
Original file line number Diff line number Diff line change 99; (long long)long double and (unsigned long long)long double
1010__dtoll:
1111__dtoull:
12- ; f64_ret_i64
13- push af, iy
14- ld a, b
15- res 7, b ; fabsl(x)
16- push bc, de, hl
17- ld hl, 8
18- add hl, sp
19- rlca
20- ld (hl), a ; store the sign of x in the padding byte
21- call __dtoll_c
22- pop af, af, af, iy, af
12+ bit 6, b ; set if |x| >= 2.0L
13+ jr z, .zero_or_one
14+ bit 7, b
15+ push af
16+ res 7, b
17+ push hl
18+ ; -((Float64_mant_bits + Float64_bias) << 4)
19+ ld hl, $FFC010 ; -16368 ; -$3FF0
20+
21+ ; clears the exponent field without touching the mantissa
22+ ; sets the LSB of the exponent since x is normalized
23+ ld a, c
24+ or a, l ; or a, $10
25+ and a, $1F
26+
27+ add hl, bc
28+ ; HL <<= 4
29+ add hl, hl
30+ add hl, hl
31+ add hl, hl
32+ add hl, hl
33+
34+ ld c, a
35+ ld b, 0
36+ ld a, h
37+ sub a, 52 + 1 ; float64 mantissa bits
38+ jr c, .shift_right
39+ ; shift_left
40+ ; expon >= 52 or [52, 63]
41+ ; A is one less than it should be here to allow for the CPL trick in shift_right
42+ ; A is [-1, 10]
43+ cp a, 11 ; only call __llshl if the shift amount is [0, 63]
44+ inc a ; positioning inc a after cp a allows __llshl to be skipped when the shift amount is zero
45+ ld l, a
46+ ex (sp), hl
47+ call c, __llshl
48+ jr .finish
49+ .shift_right:
50+ ; expon is [0, 51]
51+ cpl
52+ ld l, a
53+ ex (sp), hl
54+ call __llshru
55+ .finish:
56+ pop af ; reset SP
57+ pop af
58+ .finish_zero_or_one:
59+ jp nz, __llneg
2360 ret
2461
25- extern __dtoll_c
62+ .zero_or_one:
63+ ld hl, 16
64+ ld d, h
65+ ld e, h
66+ add hl, bc ; adds one to the exponent
67+ bit 6, h ; if |x| was [1, 2)
68+ jr z, .zero
69+ inc de
70+ bit 7, b ; sets NZ if the result should be -1
71+ .zero:
72+ ld c, d
73+ ld b, d
74+ ld h, d
75+ ld l, d
76+ ex.s de, hl
77+ jr .finish_zero_or_one
78+
79+ extern __llneg
80+ extern __llshl
81+ extern __llshru
Original file line number Diff line number Diff line change @@ -96,6 +96,8 @@ static uint64_t f64_to_unsigned(F64_pun val) {
9696 return val .bin ;
9797}
9898
99+
100+
99101/**
100102 * @brief the exact same routine is used for (long long)long double and
101103 * (unsigned long long)long double. If the input long double is out of range,
You can’t perform that action at this time.
0 commit comments