Skip to content

Commit ef700af

Browse files
committed
added mulhs routines and fixed i48mulhu/llmulhu
1 parent c228650 commit ef700af

File tree

10 files changed

+475
-60
lines changed

10 files changed

+475
-60
lines changed

src/crt/i48mulhs.src

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __i48mulhs
6+
7+
; UDE:UHL = ((int96_t)UDE:UHL * (int96_t)UIY:UBC) >> 48
8+
__i48mulhs:
9+
push af
10+
push iy
11+
push bc
12+
push de
13+
push hl
14+
15+
push hl
16+
lea hl, iy
17+
add hl, hl
18+
sbc a, a
19+
20+
ld hl, $800000
21+
add hl, de
22+
pop hl
23+
rla
24+
25+
call __i48mulhu
26+
27+
; if (UDE:UHL < 0) { result -= UIY:UBC; }
28+
rrca
29+
call c, __i48sub
30+
31+
pop bc
32+
pop iy
33+
34+
; if (UIY:UBC < 0) { result -= UDE:UHL; }
35+
rrca
36+
call c, __i48sub
37+
38+
pop bc
39+
pop iy
40+
pop af
41+
ret
42+
43+
extern __i48mulhu
44+
extern __i48sub

src/crt/i48mulhu.src

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

77
; UDE:UHL = ((uint96_t)UDE:UHL * (uint96_t)UIY:UBC) >> 48
88
__i48mulhu:
9-
; CC: 88 bytes
10-
; minimum: 87F + 39R + 39W + 2
11-
; maximum: 89F + 39R + 39W + 3
9+
; CC: 93 bytes
10+
; minimum: 92F + 42R + 42W + 2
11+
; maximum: 94F + 42R + 42W + 4
1212
; including __i48mulu:
13-
; minimum: 895F + 243R + 179W + 342
14-
; maximum: 897F + 243R + 179W + 343
13+
; minimum: 900F + 246R + 182W + 342
14+
; maximum: 902F + 246R + 182W + 344
1515
push ix
1616
push iy
1717
push bc
@@ -45,6 +45,7 @@ __i48mulhu:
4545
adc hl, bc
4646

4747
pop bc ; UHL * UBC (low carry)
48+
push af ; upper carry
4849
ex de, hl
4950
add hl, bc
5051
jr nc, .no_low_carry
@@ -58,6 +59,10 @@ __i48mulhu:
5859
ld hl, (ix - 3)
5960
call __i48mulu
6061
pop bc ; high carry
62+
pop af ; upper carry
63+
jr nc, .no_upper_carry
64+
inc de
65+
.no_upper_carry:
6166
add hl, bc
6267
ld sp, ix
6368
pop bc

src/crt/imulhs.src

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __imulhs
6+
7+
; UHL = ((int48_t)UHL * (int48_t)UBC) >> 24
8+
__imulhs:
9+
push af
10+
push bc
11+
push hl
12+
13+
push hl
14+
add hl, hl
15+
rla
16+
ld hl, $800000
17+
add hl, bc
18+
rla
19+
pop hl
20+
21+
call __imulhu
22+
23+
; if (UBC < 0) { result -= UHL; }
24+
pop bc
25+
cpl
26+
rra
27+
jr c, .positive_bc
28+
sbc hl, bc
29+
.positive_bc:
30+
31+
; if (UHL < 0) { result -= UBC; }
32+
pop bc
33+
rra
34+
jr c, .positive_hl
35+
sbc hl, bc
36+
.positive_hl:
37+
38+
pop af
39+
ret
40+
41+
extern __imulhu

src/crt/llmulhs.src

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __llmulhs
6+
7+
; BC:UDE:UHL = ((int128_t)BC:UDE:UHL * (int128_t)(SP64)) >> 64
8+
__llmulhs:
9+
push iy
10+
ld iy, 0
11+
add iy, sp
12+
13+
push bc, de, hl
14+
15+
ld hl, (iy + 6)
16+
ld de, (iy + 9)
17+
ld bc, (iy + 12)
18+
19+
; argument order can be swapped since multiplication is commutative
20+
call __llmulhu
21+
22+
; if ((SP64) < 0) { result -= BC:UDE:UHL; }
23+
bit 7, (iy + 13)
24+
call nz, __llsub
25+
26+
; if (BC:UDE:UHL < 0) { result -= (SP64); }
27+
bit 7, (iy - 2)
28+
29+
ld sp, iy
30+
31+
pop iy
32+
ret z
33+
jp __llsub
34+
35+
extern __llmulhu
36+
extern __llsub

src/crt/llmulhu.src

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ __llmulhu:
1818
ld (ix - 9), hl
1919

2020
ld bc, 0
21+
ld (ix - 10), b
2122
ld (ix - 13), bc
2223
ld (ix - 30), bc
2324
ld c, (ix + 12)
@@ -31,17 +32,21 @@ __llmulhu:
3132
inc de
3233
dec.s de
3334
call __llmulu
35+
inc bc
36+
dec.s bc
3437
ld (ix - 16), bc
3538
ld (ix - 19), de
36-
ld bc, 0
37-
ld (ix - 14), b
39+
ld b, 0
40+
ld c, b
3841

3942
; x_hi * y_lo
4043
inc.s de
4144
ld d, b
4245
ld e, (ix - 2)
4346
ld hl, (ix - 5)
4447
call __llmulu
48+
inc bc
49+
dec.s bc
4550
ld (ix - 21), bc
4651
ld (ix - 24), de
4752
ld (ix - 27), hl
@@ -52,35 +57,39 @@ __llmulhu:
5257
ld (ix - 36), iy
5358

5459
; x_lo * y_hi
55-
ld bc, 0
60+
ld b, 0
61+
ld c, b
5662
inc.s de
5763
ld d, b
5864
ld e, (ix - 6)
5965
ld hl, (ix - 9)
6066
call __llmulu
67+
inc bc
68+
dec.s bc
6169
lea iy, ix - 27
62-
call __llmulhu_add
70+
call __llmulhu_i72add
6371
lea iy, ix - 18
64-
call __llmulhu_add
72+
call __llmulhu_i72add
6573
ld (ix - 16), bc
6674
ld (ix - 19), de
6775
ld bc, 0
68-
ld (ix - 14), b
6976

7077
; x_hi * y_hi
7178
inc.s de
7279
ld d, b
7380
ld e, (ix - 2)
7481
ld hl, (ix - 5)
7582
call __llmulu
83+
inc bc
84+
dec.s bc
7685
lea iy, ix - 18
77-
call __llmulhu_add
86+
call __llmulhu_i72add
7887
ld sp, ix
7988
pop iy
8089
pop ix
8190
ret
8291

83-
__llmulhu_add:
92+
__llmulhu_i72add:
8493
; similar to __lladd, except iy points to the stack and is destroyed
8594
push bc
8695
ld bc, (iy + 0)

src/crt/lmulhs.src

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __lmulhs
6+
7+
; E:UHL = ((int64_t)E:UHL * (int64_t)A:UBC) >> 32
8+
__lmulhs:
9+
push bc
10+
push af
11+
push hl
12+
push de
13+
14+
call __lmulhu
15+
16+
; if (A:UBC < 0) { result -= E:UHL; }
17+
rlca
18+
pop bc
19+
ld a, c ; ld a, E
20+
pop bc
21+
call c, __lsub
22+
23+
; if (E:UHL < 0) { result -= A:UBC; }
24+
rlca
25+
pop bc
26+
ld a, b ; ld a, A
27+
pop bc
28+
ret nc
29+
jp __lsub
30+
31+
extern __lmulhu
32+
extern __lsub

src/crt/smulhs.src

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __smulhs
6+
7+
; HL = ((int32_t)HL * (int32_t)BC) >> 16
8+
__smulhs:
9+
push bc
10+
push hl
11+
call __smulhu
12+
13+
; if (BC < 0) { result -= HL; }
14+
bit 7, b
15+
pop bc
16+
jr z, .positive_hl
17+
or a, a
18+
sbc hl, bc
19+
.positive_hl:
20+
21+
; if (HL < 0) { result -= BC; }
22+
bit 7, b
23+
pop bc
24+
ret z
25+
or a, a
26+
sbc hl, bc
27+
ret
28+
29+
extern __smulhu

test/standalone/mulhu/autotest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"sequence": [
1010
"action|launch",
11-
"delay|1000",
11+
"delay|2000",
1212
"hashWait|1",
1313
"key|enter",
1414
"delay|300",

0 commit comments

Comments
 (0)