Skip to content

Commit

Permalink
r2ka - long long multiply
Browse files Browse the repository at this point in the history
  • Loading branch information
feilipu committed Aug 14, 2023
1 parent 5a56f26 commit 2682c8c
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 0 deletions.
9 changes: 9 additions & 0 deletions libsrc/_DEVELOPMENT/math/integer/l_mulu_64_32x32.asm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ IF __CPU_Z80N__ && ((__CLIB_OPT_IMATH = 0) || (__CLIB_OPT_IMATH = 100))
defc l_mulu_64_32x32 = l_z80n_mulu_64_32x32
defc l0_mulu_64_32x32 = l0_z80n_mulu_64_32x32

ELSE

IF (__CPU_R2KA__ || __CPU_R3K__) && ((__CLIB_OPT_IMATH = 0) || (__CLIB_OPT_IMATH = 100))

EXTERN l_r2ka_mulu_64_32x32, l0_r2ka_mulu_64_32x32
defc l_mulu_64_32x32 = l_r2ka_mulu_64_32x32
defc l0_mulu_64_32x32 = l0_r2ka_mulu_64_32x32

ELSE

Expand All @@ -52,3 +59,5 @@ ENDIF
ENDIF

ENDIF

ENDIF
9 changes: 9 additions & 0 deletions libsrc/_DEVELOPMENT/math/integer/l_mulu_64_64x64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ IF __CPU_Z80N__ && ((__CLIB_OPT_IMATH = 0) || (__CLIB_OPT_IMATH = 100))

ELSE

IF (__CPU_R2KA__ || __CPU_R3K__) && ((__CLIB_OPT_IMATH = 0) || (__CLIB_OPT_IMATH = 100))

EXTERN l_r2ka_mulu_64_64x64
defc l_mulu_64_64x64 = l_r2ka_mulu_64_64x64

ELSE

IF __CLIB_OPT_IMATH <= 50

EXTERN l_small_mul_64_64x64
Expand All @@ -55,3 +62,5 @@ ENDIF
ENDIF

ENDIF

ENDIF
137 changes: 137 additions & 0 deletions libsrc/_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_64_32x32.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
; 2023 August feilipu

SECTION code_clib
SECTION code_math

EXTERN l_mulu_32_16x16

PUBLIC l_r2ka_mulu_64_32x32, l0_r2ka_mulu_64_32x32

l0_r2ka_mulu_32_16x16:

; multiplication of two 16-bit numbers into a 32-bit product
;
; enter : hl'= 16-bit multiplier = y
; hl = 16-bit multiplicand = x
;
; exit : dehl = 32-bit product
; carry reset
;
; uses : af, bc, de, hl, bc', de', hl'

ex de,hl'
jp l_mulu_32_16x16

l_r2ka_mulu_64_32x32:

; multiplication of two 32-bit numbers into a 64-bit product
;
; enter : de hl = 32-bit multiplicand = x
; de'hl'= 32-bit multiplier = y
;
; exit : dehl dehl' = 64-bit product
; carry reset
;
; uses : af, bc, de, hl, bc', de', hl'

xor a
or e
or d
exx

or e
or d
jr Z,l0_r2ka_mulu_32_16x16 ; demote if both are uint16_t

ex de',hl
ld bc,hl
exx

ld bc,hl

l0_r2ka_mulu_64_32x32:

; multiplication of two 32-bit numbers into a 64-bit product
;
; enter : de'de = 32-bit multiplier = x
; bc'bc = 32-bit multiplicand = y
;
; exit : dehl dehl' = 64-bit product
; carry reset
;
; uses : af, bc, de, hl, bc', de', hl'

push de ; xl
push bc ; yl
ld hl,bc ; yl
call l_mulu_32_16x16 ; yl * xl = de*hl => dehl ; uses bc, hl'

ex de',hl ; p0 = (xl*yl)l <> xh
ex de,hl ; (xl*yl)h <> xh
ex (sp),hl ; yl <> (xl*yl)h
push de ; xh
call l_mulu_32_16x16 ; xh * yl = de*hl => dehl ; uses bc, hl'

ex de,hl' ; ?? > (xh*yl)h
pop de ; xh
pop bc ; (xl*yl)h
xor a ; clear p1 carry store
add hl,bc ; pp1 = (xh*yl)l + (xl*yl)h
adc a,a ; pp1 carry (xh*yl)l + (xl*yl)h
ex (sp),hl ; xl <> pp1
exx ;'

ex de,hl ;'(xh*yl)h <> p0
ex (sp),hl ;'p0 <> pp1
push hl ;'pp1
push af ;'pp1 carry

ex de',hl ;'pp1 <> xh
ld de',bc ;'yh
push hl ;'xh
exx

call l_mulu_32_16x16 ; yh * xl = de*hl => dehl ; uses bc, hl'

ex de,hl' ; ?? > (xl*yh)h
pop bc ; xh
pop af ; pp1 carry
pop de ; pp1
add hl,de ; p1 = pp1 + (xl*yh)l
adc a,0 ; p1 carry
push hl ; p1
push af ; p1 carry
exx ;'

ld hl',bc ;'yh
exx

ex de,hl' ; ?? >> (xl*yh)h
ld bc',de ; (xl*yh)h
ld de,bc ; xh
call l_mulu_32_16x16 ; yh * xh = de*hl => dehl ; uses bc, hl'

exx ;'

pop af ;'p1 carry
ld l,a
xor a ;'p2 carry store
ld h,a
add hl,de ;'pp2 = p1 carry + (xh*yl)h
adc a,a ;'pp2 carry
add hl,bc ;'pp2 = pp2 + (xl*yh)h
adc a,0 ;'pp2 carry
ex de,hl ;'pp2
ld bc',de ;'pp2
pop de ;'p1
pop hl ;'p0
exx

add hl,bc ; p2 = pp2 + (xh*yh)l
adc a,0 ; p2 carry
add a,e ; p3 + p2 carry
ld e,a ; p3
ret NC

inc d
ret ;exit : DEHL DEHL' = 64-bit product
131 changes: 131 additions & 0 deletions libsrc/_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_64_64x64.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
; 2016 aralbrec

SECTION code_clib
SECTION code_math

PUBLIC l_r2ka_mulu_64_64x64

EXTERN l0_mulu_64_32x32
EXTERN l0_mulu_32_32x32

l_r2ka_mulu_64_64x64:

; 64-bit multiplication

; enter : +-------------------------------
; | +15
; | ... multiplicand AB (8 bytes)
; | + 8
; ix = |-------------------------------
; | + 7
; | ... multiplicand CD (8 bytes)
; | + 0
; +-------------------------------
;
; exit : ix structure unchanged
; dehl' dehl = 64-bit product
; carry reset
;
; uses : af, bc, de, hl, af', bc', de', hl'
ld b,(ix+11)
ld c,(ix+10)
ld d,(ix+3)
ld e,(ix+2)
exx
ld b,(ix+9)
ld c,(ix+8)
ld d,(ix+1)
ld e,(ix+0)
call l0_mulu_64_32x32 ; bc'bc de'de = B*D
exx
push de
push hl ; save LS32(B*D)
ld b,(ix+13)
ld c,(ix+12)
ld d,(ix+1)
ld e,(ix+0)
ld a,b
or c
exx
ld b,(ix+15)
ld c,(ix+14)
or b
or c
or (ix+7)
or (ix+6)
or (ix+5)
or (ix+4)
jr z, finished ; if multiplicands were 32 bit
push de
push hl ; save MS32(B*D)

ld d,(ix+3)
ld e,(ix+2)
call l0_mulu_32_32x32 ; dehl = LS32(A*D)
push de
push hl ; save LS32(A*D)
ld b,(ix+9)
ld c,(ix+8)
ld d,(ix+5)
ld e,(ix+4)
exx
ld b,(ix+11)
ld c,(ix+10)
ld d,(ix+7)
ld e,(ix+6)
call l0_mulu_32_32x32 ; dehl = LS32(B*C)
pop bc
add hl,bc
ex de,hl
pop bc
adc hl,bc
ex de,hl
; dehl = LS32(B*C) + LS32(A*D)
pop bc
add hl,bc
ex de,hl
pop bc
adc hl,bc
ex de,hl
finished:
; dehl = MS32(product) = LS32(B*C) + LS32(A*D) + MS32(B*D)
exx
pop hl
pop de
; dehl = LS32(product) = LS32(B*D)

or a
ret
2 changes: 2 additions & 0 deletions libsrc/_DEVELOPMENT/math/math_integer_r2ka.lst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ math/integer/r2ka/l_r2ka_mulu_16_16x16
math/integer/r2ka/l_r2ka_mulu_24_16x8
math/integer/r2ka/l_r2ka_mulu_32_16x16
math/integer/r2ka/l_r2ka_mulu_32_32x32
math/integer/r2ka/l_r2ka_mulu_64_32x32
math/integer/r2ka/l_r2ka_mulu_64_64x64
2 changes: 2 additions & 0 deletions libsrc/z80_crt0s/newlib-r2ka.lst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
../_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_24_16x8
../_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_32_16x16
../_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_32_32x32
../_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_64_32x32
../_DEVELOPMENT/math/integer/r2ka/l_r2ka_mulu_64_64x64

0 comments on commit 2682c8c

Please sign in to comment.