Skip to content

Commit a61a932

Browse files
committed
Add count-trailing-zero libcalls
1 parent dc85d6a commit a61a932

File tree

3 files changed

+162
-72
lines changed

3 files changed

+162
-72
lines changed

src/crt/cttz.src

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
assume adl=1
2+
3+
section .text
4+
public __bcttz
5+
__bcttz:
6+
tst a, 0Fh
7+
jr z, .high4
8+
tst a, 3
9+
jr z, .high6
10+
cpl
11+
and a, 1
12+
ret
13+
.high6:
14+
dec a
15+
and a, 6
16+
ret po
17+
rrca
18+
ret
19+
.high4:
20+
tst a, 030h
21+
jr z, .high2
22+
dec a
23+
and a, 014h
24+
ret po
25+
ld a, 5
26+
ret
27+
.high2:
28+
add a, a
29+
sbc a, -8
30+
ret p
31+
ld a, 6
32+
ret
33+
34+
section .text
35+
public __scttz
36+
__scttz:
37+
ld a, l
38+
or a, a
39+
jr nz, __bcttz
40+
ld a, h
41+
require __scttz.hijack
42+
43+
section .text
44+
private __scttz.hijack
45+
__scttz.hijack:
46+
call __bcttz
47+
add a, 8
48+
ret
49+
50+
section .text
51+
public __icttz
52+
__icttz:
53+
xor a, a
54+
require __icttz.hijack
55+
56+
section .text
57+
private __icttz.hijack
58+
__icttz.hijack:
59+
or a, l
60+
jr nz, __bcttz
61+
or a, h
62+
jr nz, __scttz.hijack
63+
dec sp
64+
push hl
65+
inc sp
66+
pop af
67+
call __bcttz
68+
add a, 16
69+
ret
70+
71+
section .text
72+
public __lcttz
73+
__lcttz:
74+
add hl, de
75+
xor a, a
76+
sbc hl, de
77+
jr nz, __icttz.hijack
78+
ld a, e
79+
call __bcttz
80+
add a, 24
81+
ret
82+
83+
section .text
84+
public __llcttz
85+
__llcttz:
86+
add hl, de
87+
xor a, a
88+
sbc hl, de
89+
jr nz, __icttz.hijack
90+
ex de, hl
91+
sbc hl, de
92+
jr nz, __i48cttz.hijack
93+
or a, c
94+
jr z, .high
95+
call __bcttz
96+
add a, 48
97+
ret
98+
.high:
99+
ld a, b
100+
call __bcttz
101+
add a, 56
102+
ret
103+
104+
section .text
105+
public __i48cttz
106+
__i48cttz:
107+
add hl, de
108+
xor a, a
109+
sbc hl, de
110+
jr nz, __icttz.hijack
111+
ex de, hl
112+
require __i48cttz.hijack
113+
114+
section .text
115+
private __i48cttz.hijack
116+
__i48cttz.hijack:
117+
call __icttz.hijack
118+
ex de, hl
119+
add a, 24
120+
ret

src/libc/ez80_builtin.src

+40-70
Original file line numberDiff line numberDiff line change
@@ -6,112 +6,80 @@
66

77
public ___ez80_ctzc
88
___ez80_ctzc:
9-
; unoptimized
109
ld hl, 3
1110
add hl, sp
12-
ld l, (hl)
13-
xor a, a
14-
sub a, l
15-
and a, l
16-
call __bctlz
17-
bit 3, a
18-
ret nz
19-
xor a, 7
20-
ret
11+
ld a, (hl)
12+
jp __bcttz
2113

2214
;-------------------------------------------------------------------------------
2315

2416
section .text
2517

2618
public ___ez80_ctzi48
2719
___ez80_ctzi48:
28-
; unoptimized
29-
ld hl, 3
20+
ld hl, 6
3021
add hl, sp
31-
ld bc, (hl)
32-
inc hl
33-
inc hl
34-
inc hl
35-
ld iy, (hl)
36-
sbc hl, hl
37-
add hl, bc
38-
lea de, iy
39-
call __i48neg
40-
call __i48and
41-
call __i48ctlz
42-
cpl
43-
add a, 48
44-
ret p
45-
ld a, 48
46-
ret
22+
ld de, (hl)
23+
dec hl
24+
dec hl
25+
dec hl
26+
ld hl, (hl)
27+
jp __i48cttz
4728

4829
;-------------------------------------------------------------------------------
4930

5031
section .text
5132

5233
public ___ez80_ffsc
5334
___ez80_ffsc:
54-
; unoptimized
5535
ld hl, 3
5636
add hl, sp
57-
ld l, (hl)
58-
xor a, a
59-
sub a, l
60-
and a, l
61-
call __bctlz
62-
cpl
63-
add a, 9
64-
ret
37+
ld a, (hl)
38+
or a, a
39+
ret z
40+
add a, a
41+
jp __bcttz
6542

6643
;-------------------------------------------------------------------------------
6744

6845
section .text
6946

7047
public ___ez80_ffss
7148
___ez80_ffss:
72-
; unoptimized
7349
ld hl, 3
7450
add hl, sp
7551
ld hl, (hl)
76-
; HL & -HL
77-
ld b, h
78-
ld c, l
79-
sbc hl, hl
80-
sbc hl, bc
8152
ld a, h
82-
and a, b
83-
ld h, a
84-
ld a, l
85-
and a, c
86-
ld l, a
87-
call __sctlz
88-
cpl
89-
add a, 17
90-
ret
53+
or a, l
54+
ret z
55+
add hl, hl
56+
jp __scttz
9157

9258
;-------------------------------------------------------------------------------
9359

9460
section .text
9561

9662
public ___ez80_ffsi48
9763
___ez80_ffsi48:
98-
; unoptimized
99-
ld hl, 3
64+
ld hl, 6
10065
add hl, sp
101-
ld bc, (hl)
102-
inc hl
103-
inc hl
104-
inc hl
105-
ld iy, (hl)
106-
sbc hl, hl
107-
add hl, bc
108-
lea de, iy
109-
call __i48neg
110-
call __i48and
111-
call __i48ctlz
112-
cpl
113-
add a, 49
114-
ret
66+
ld de, (hl)
67+
dec hl
68+
dec hl
69+
dec hl
70+
ld hl, (hl)
71+
xor a, a
72+
adc hl, de
73+
jr c, .nonzero
74+
ret z
75+
.nonzero:
76+
or a, a
77+
sbc hl, de
78+
add hl, hl
79+
ex de, hl
80+
adc hl, hl
81+
ex de, hl
82+
jp __i48cttz
11583

11684
;-------------------------------------------------------------------------------
11785

@@ -406,13 +374,15 @@ ___ez80_rotateright48:
406374

407375
extern __snot
408376
extern __i48not
409-
extern __i48and
410-
extern __i48neg
411377

412378
extern __bctlz
413379
extern __sctlz
414380
extern __i48ctlz
415381

382+
extern __bcttz
383+
extern __scttz
384+
extern __i48cttz
385+
416386
extern __bpopcnt
417387
extern __spopcnt
418388
extern __i48popcnt

test/standalone/ez80_builtin/src/main.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static int test_ctzc(void) {
121121
unsigned char input;
122122
for (int i = 0; i < 256; i++) {
123123
input = (unsigned char)i;
124-
truth = (input == 0) ? 8 : __builtin_ctz((unsigned int)input);
124+
truth = (input == 0) ? 8 : __builtin_ctz((unsigned int)input | INT_MIN);
125125
guess = __ez80_ctzc(input);
126126
CMP("%d", input, truth, guess);
127127
}
@@ -271,7 +271,7 @@ static int test_ctzi48(void) {
271271
CMP("%012llX", (uint64_t)UINT48_MAX, 0, __ez80_ctzi48(UINT48_MAX));
272272
for (int i = 0; i < RANDOM_TEST_COUNT; i++) {
273273
input = rand48();
274-
truth = (input == 0) ? 48 : __builtin_ctzll((unsigned long long)input);
274+
truth = (input == 0) ? 48 : __builtin_ctzll((unsigned long long)input | INT64_MIN);
275275
guess = __ez80_ctzi48(input);
276276
CMP("%012llX", (uint64_t)input, truth, guess);
277277
}

0 commit comments

Comments
 (0)