File tree 5 files changed +605
-548
lines changed
test/floating_point/float64_to_integer/src
5 files changed +605
-548
lines changed Original file line number Diff line number Diff line change 5
5
public __dtol
6
6
public __dtoul
7
7
8
- ; __dtol_c correctly handles all non-UB cases for both
8
+ ; correctly handles all non-UB cases for both
9
9
; (long)long double and (unsigned long)long double
10
10
__dtol:
11
11
__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
12
+ push bc
13
+ push de
14
+ call __dtoll ; same as __dtoull
15
+ ld c, e
25
16
pop de
26
- ld e, a
27
- pop bc, iy, af
17
+ ld e, c
18
+ pop bc
28
19
ret
29
20
30
- extern __dtol_c
21
+ extern __dtoll
Original file line number Diff line number Diff line change 5
5
public __dtoll
6
6
public __dtoull
7
7
8
- ; __dtoll_c correctly handles all non-UB cases for both
8
+ ; correctly handles all non-UB cases for both
9
9
; (long long)long double and (unsigned long long)long double
10
10
__dtoll:
11
11
__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
23
60
ret
24
61
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) {
96
96
return val .bin ;
97
97
}
98
98
99
+
100
+
99
101
/**
100
102
* @brief the exact same routine is used for (long long)long double and
101
103
* (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