Last active
August 29, 2015 14:03
-
-
Save Measter/be47000f18c880b1026a to your computer and use it in GitHub Desktop.
Unsigned Longword Multiplication on the M68k
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*----------------------------------------------------------- | |
* Title : Unsigned Longword Multiplication. | |
* Written by : Stuart Haidon | |
* Date : 2014-06-22 | |
*----------------------------------------------------------- | |
* Longword Unsigned Multiplication. | |
* Pre: | |
* +4 : Multiplicand. | |
* +0 : Multiplier. | |
* Post: | |
* +4 : Result Low. | |
* +0 : Result High. | |
long_mulu: | |
move.l a6,-(a7) * A6 = Argument pointer. | |
move.l a7,a6 | |
add.l #8,a6 | |
movem.l d0-d6,-(a7) | |
move.l 4(a6),d0 * D0 = Multiplicand. | |
move.l 0(a6),d1 * D1 = Multiplier. | |
moveq.l #0,d2 | |
moveq.l #0,d3 | |
moveq.l #0,d4 | |
moveq.l #0,d5 | |
moveq.l #0,d6 | |
* Compute z0. | |
move.w d0,d2 | |
mulu d1,d2 * D2 = z0. | |
* Compute first term of z1. | |
* Multiplicand. | |
move.w d0,d3 | |
swap d0 | |
move.w d0,d5 | |
add.l d5,d3 * D3 = Multiplicand of first term of z1. | |
* Multiplier. | |
move.w d1,d4 | |
swap d1 | |
move.w d1,d5 | |
add.l d5,d4 * D4 = Multiplier of first term of z1. | |
* Multiply the two. | |
if.l d3 <gt> #$FFFF OR.l d4 <gt> #$FFFF then.s | |
move.l d3,-(a7) | |
move.l d4,-(a7) | |
jsr long_mulu | |
move.l (a7)+,d6 * D6 = Result high. | |
move.l (a7)+,d3 * D3 = Result low. | |
else.s | |
mulu d4,d3 | |
endi * D3 = First term of z1. | |
* Subtract z0. | |
sub.l d2,d3 * D3 = First and third terms of z1. | |
if.l <cs> then.s | |
sub.l #1,d6 | |
endi | |
* Compute z2. | |
moveq #0,d4 | |
move.w d0,d4 | |
mulu d1,d4 * D4 = z2. | |
* Complete z1. | |
sub.l d4,d3 * D3 = z1. | |
if.l <cs> then.s | |
sub.l #1,d6 | |
endi | |
moveq #0,d0 | |
moveq #0,d1 | |
* Calculate result. | |
move.l d4,d0 * D0 = High. | |
move.l d2,d1 * D1 = Low. | |
* Add high to lower word of D0, low to higher word of D1. | |
swap d3 | |
move.w d3,d5 | |
add.l d5,d0 | |
move.w #0,d3 | |
add.l d3,d1 | |
if.l <cs> then.s | |
add.l #1,d0 | |
endi | |
* Add D6 << 16 to D0. Can just swap as higher word is always 0. | |
swap d6 | |
add.l d6,d0 | |
move.l d0,0(a6) | |
move.l d1,4(a6) | |
movem.l (a7)+,d0-d6 | |
move.l (a7)+,a6 | |
rts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment