2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Utility 64 bit multiplication routines. m68k version.
11 /* SMult64()/UMult64():
12 These are the signed/unsigned 64 bit multiplication routines.
13 There are two possibilities here because as of the 060 the
14 32*32->64 bit result instructions are not supported, and I haven't
15 quite figured out how to do this using the 32 bit ops yet (can't be
18 Still, emulating is faster than a unsup integer instruction except.
24 .globl AROS_SLIB_ENTRY(UMult64,Utility)
25 .globl AROS_SLIB_ENTRY(UMult64_020,Utility)
27 .type AROS_SLIB_ENTRY(UMult64,Utility),@function
28 .type AROS_SLIB_ENTRY(UMult64_020,Utility),@function
31 AROS_SLIB_ENTRY
(UMult64_020
,Utility
):
35 /* How do I do this, again consider:
36 (a^16 + b) * (c^16 + d)
37 = ac^32 + (ad + bc)^16 + bd
39 I tried to think of a way of doing this with the mulu.l instr,
40 but I couldn't so I'll just use the mulu.w. Its quicker than
41 an unsupp integer instruction anyway :)
44 AROS_SLIB_ENTRY
(UMult64
,Utility
):
45 movem.
l %d2-
%d5
,-(%sp
)
46 /* Set up some registers */
49 move.
l %d0
,%d4
/* d */
50 move.
l %d1
,%d5
/* b */
55 /* Firstly, find the product bd */
56 mulu
%d5
,%d1
/* d1 = bd */
57 swap
%d1
/* d1 = (bd)^16 */
59 /* Then find ac, put in d0 */
60 mulu
%d3
,%d0
/* d0 = ac */
62 /* Next find ad, bc, and add together */
68 Add the low 16 bits to d1, then add upper 16 bits to d0
69 But make sure we carry the 1...
71 Apparently swap doesn't affect the X bit.
77 /* All that remains to do is to flip d1 around the right way */
79 movem.
l (%sp
)+,%d2-
%d5