Skip to content

Commit 15fc6b8

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
Rewrote ilogbf and ilogbl in assembly
1 parent a11f44b commit 15fc6b8

File tree

6 files changed

+127
-99
lines changed

6 files changed

+127
-99
lines changed

src/libc/ilogbf.c

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/libc/ilogbf.src

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public _ilogbf, _ilogb
6+
7+
; int ilogbf(float)
8+
_ilogb:
9+
_ilogbf:
10+
ld hl, 6
11+
add hl, sp
12+
ld a, (hl)
13+
dec hl
14+
dec hl
15+
dec hl
16+
ld de, (hl)
17+
sbc hl, hl
18+
ex de, hl
19+
; DE is zero
20+
add hl, hl
21+
22+
adc a, a
23+
jr z, .maybe_subnormal
24+
inc a
25+
scf
26+
jr z, .inf_nan
27+
rr e ; E = 128 or float32_bias + 1
28+
sbc hl, hl
29+
ld l, a
30+
sbc hl, de
31+
ret
32+
33+
.maybe_subnormal:
34+
; DE is zero, Carry unknown
35+
add hl, de
36+
sbc hl, de
37+
jr z, .ret_zero
38+
call __ictlz
39+
; Carry flag will be set at the end of __ictlz
40+
; scf
41+
sbc hl, hl
42+
neg
43+
add a, 129
44+
ld l, a
45+
ret
46+
47+
.ret_zero:
48+
.inf_nan:
49+
ld hl, $800000 ; FP_ILOGB0
50+
sbc hl, de ; FP_ILOGBNAN or INT_MAX when carry is set
51+
ex de, hl
52+
; DE was zero, so HL is now zero
53+
ld l, 4 ; EDOM
54+
ld (_errno), hl
55+
ld hl, ___fe_cur_env
56+
set 4, (hl) ; FE_INVALID
57+
ex de, hl
58+
ret
59+
60+
extern _errno
61+
extern ___fe_cur_env
62+
extern __ictlz

src/libc/ilogbl.c

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/libc/ilogbl.src

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,65 @@
66

77
; int ilogbl(long double)
88
_ilogbl:
9-
; x = fabsl(x)
10-
ld hl, 10
11-
add hl, sp
12-
res 7, (hl)
13-
jq __ilogbl_c
9+
ld iy, 0
10+
lea de, iy + 0
11+
add iy, sp
12+
ld hl, (iy + 9)
13+
add hl, hl
14+
ld a, h
15+
rlca
16+
rlca
17+
rlca
18+
add hl, hl
19+
add hl, hl
20+
add.s hl, hl ; clears upper bits
21+
and a, $07
22+
ld l, h
23+
ld h, a
24+
; HL = exponent
25+
adc hl, de
26+
jr z, .maybe_subnormal
27+
inc hl
28+
bit 3, h
29+
jr nz, .inf_nan
30+
; Float64_exp_bias + 1
31+
ld de, -1024
32+
add hl, de
33+
ret
1434

15-
extern __ilogbl_c
35+
.maybe_subnormal:
36+
ld c, (iy + 9)
37+
ld b, e ; DE is zero
38+
ld de, (iy + 6)
39+
ld hl, (iy + 3)
40+
call __llctlz
41+
cp a, 64
42+
sbc hl, hl
43+
jr z, .ret_zero ; A was 64
44+
neg
45+
ld l, a
46+
; -1023 + 11 + 1
47+
; Float64_ilogb_subnorm_max + Float64_exponent_bits + Float64_sign_bits
48+
ld de, -1011
49+
add hl, de
50+
ret
51+
52+
.ret_zero:
53+
ex de, hl
54+
inc de
55+
.inf_nan:
56+
ld hl, $7FFFFF ; FP_ILOGBNAN or INT_MAX
57+
add hl, de ; FP_ILOGB0 when DE is one
58+
ex de, hl
59+
; DE was zero or one, so HL is now zero or one
60+
ld l, 4 ; EDOM
61+
ld (_errno), hl
62+
ld hl, ___fe_cur_env
63+
set 4, (hl) ; FE_INVALID
64+
ex de, hl
65+
ret
66+
67+
extern __fpclassifyl
68+
extern _errno
69+
extern ___fe_cur_env
70+
extern __llctlz

test/floating_point/float32_ilogb/src/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ size_t run_test(void) {
2323
for (size_t i = 0; i < length; i++) {
2424
int result = ilogbf(input[i]);
2525
if (result != output[i]) {
26+
// printf("%3zu: %08lX\n\t%d != %d\n", i, input[i], result, output[i]);
27+
// while (!os_GetCSC());
2628
return i;
2729
}
2830
}
@@ -32,6 +34,7 @@ size_t run_test(void) {
3234
}
3335

3436
int main(void) {
37+
3538
os_ClrHome();
3639
size_t fail_index = run_test();
3740
if (fail_index == SIZE_MAX) {

test/floating_point/float64_ilogb/src/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ size_t run_test(void) {
2323
for (size_t i = 0; i < length; i++) {
2424
int result = ilogbl(input[i]);
2525
if (result != output[i]) {
26+
// printf("%4zu: %016llX\n %d != %d\n", i, input[i], result, output[i]);
2627
return i;
2728
}
2829
}

0 commit comments

Comments
 (0)