Implement signed 16x16 to 32 bit multiplication
authorNick Downing <nick@ndcode.org>
Mon, 24 Jun 2019 11:34:38 +0000 (21:34 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 24 Jun 2019 11:34:38 +0000 (21:34 +1000)
sm3.asm

diff --git a/sm3.asm b/sm3.asm
index 986ff44..22bd08f 100644 (file)
--- a/sm3.asm
+++ b/sm3.asm
@@ -1914,26 +1914,51 @@ smul_l0:        rla
        exx
        ret
 
-math_mul_uw0: ; hl:de = hl * de, unsigned
 math_mul_sw0: ; hl:de = hl * de, signed
        ld      c,l
        ld      b,h
        ld      hl,0
-math_mul_uw: ; hl:de = hl + bc * de, unsigned
 math_mul_sw: ; hl:de = hl + bc * de, signed
+       ld      a,b
+       rla ; cf will be preserved through to the last rra below
        ld      a,e
        call    mul_uw
+       push    af
+       ld      a,d
+       call    mul_uw1 ; do only 7 bits, get sign of d into cf
+       jr      nc,1$
+       or      a
+       sbc     hl,bc
+1$:    rr      h
+       rr      l
+       rra
+       jr      nc,2$
+       or      a
+       sbc     hl,de
+2$:    ld      d,a
+       pop     af
        ld      e,a
+       ret
+
+math_mul_uw0: ; hl:de = hl * de, unsigned
+       ld      c,l
+       ld      b,h
+       ld      hl,0
+math_mul_uw: ; hl:de = hl + bc * de, unsigned
+       ld      a,e
+       call    mul_uw
        ld      a,d
        call    mul_uw
        ld      d,a
        ret
+
 mul_uw: rra
        ; bit 0
        jr      nc,1$
        add     hl,bc
 1$:    rr      h
        rr      l
+mul_uw1:
        rra
        ; bit 1
        jr      nc,2$