Skip to content

Commit 8c75d54

Browse files
committed
implemented ftod in assembly (NaN payloads now preserved)
1 parent 5e5478c commit 8c75d54

File tree

3 files changed

+85
-107
lines changed

3 files changed

+85
-107
lines changed

src/crt/ftod.c

-91
This file was deleted.

src/crt/ftod.src

+81-16
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,89 @@
44

55
public __ftod
66

7+
; input E:UHL (float)
8+
; ouput BC:UDE:UHL (long double)
9+
; NaN payloads are bitshifted
710
__ftod:
8-
; f32_ret_f64
9-
ld d, a
10-
push iy
1111
bit 7, e
12-
jr nz, .negative_arg
13-
; positive
14-
push de, hl
15-
call __ftod_c
16-
pop af, af, iy
17-
ret
18-
.negative_arg:
19-
; return -_ftod_c(fabsf(x))
12+
push af
2013
res 7, e
21-
push de, hl
22-
call __ftod_c
14+
15+
xor a, a
16+
ld a, e
17+
18+
adc hl, hl
19+
ld b, $03 ; ld bc, $380 - 1
20+
jr z, .mant_zero ; zero inf or normal
21+
adc a, a
22+
jr z, .subnormal
23+
inc a
24+
jr z, .nan
25+
.normal:
26+
; (Float64_bias - Float32_bias) - 1 (undoing inc a)
27+
ld c, $80 - 1 ; ld bc, $380 - 1
28+
ld d, 0
29+
ld e, a
30+
; DE = expon
31+
ex de, hl
32+
add hl, bc
33+
ld a, h
34+
ld c, l
35+
ex de, hl
36+
; HL = mant
37+
; C = lo expon
38+
; A = hi expon
39+
.shift_28: ; Float64_mant_bits - Float32_mant_bits
40+
ld b, 4
41+
.loop:
42+
add hl, hl
43+
rl c
44+
rla
45+
djnz .loop
46+
ld b, a
47+
48+
; zero low bits
49+
.infinite:
50+
or a, a
51+
.zero:
52+
ex de, hl
53+
sbc hl, hl
54+
.finish:
55+
pop af
56+
ret z ; positive
2357
set 7, b
24-
pop af, af, iy
25-
ret
58+
ret ; negative
59+
60+
.mant_zero:
61+
adc a, a
62+
ld b, e ; maybe load all ones or all zeros including signbit
63+
ld c, l ; HL is zero here
64+
jr z, .zero
65+
inc a
66+
jr nz, .normal
67+
; infinite
68+
ld c, $F0
69+
jr .infinite
70+
71+
.subnormal:
72+
; since this is subnormal, the LSB of the exponent is already zero
73+
call __ictlz
74+
ld c, a
75+
; shift until the MSB of the mantissa is the LSB of the exponent
76+
call __ishl
77+
; (Float64_bias - Float32_bias) = $0380
78+
; expon = (Float64_bias - Float32_bias) - clz_result
79+
add hl, hl
80+
cpl
81+
adc a, $80
82+
ld c, a
83+
ld a, b ; ld a, $03
84+
jr .shift_28
85+
86+
.nan:
87+
ld a, $07
88+
ld c, $FF
89+
jr .shift_28
2690

27-
extern __ftod_c
91+
extern __ictlz
92+
extern __ishl

test/floating_point/float32_to_float64/src/main.c

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ size_t run_test(void) {
3030
result.flt = (long double)input[i];
3131
if (result.bin != output[i].bin) {
3232
if (!(isnan(result.flt) && isnan(output[i].flt))) {
33+
printf(
34+
"I: %08lX\nG: %016llX\nT: %016llX\n",
35+
*((const uint32_t*)input + i), result.bin, output[i].bin
36+
);
3337
return i;
3438
}
3539
}

0 commit comments

Comments
 (0)