Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / arch / m68k-all / utility / umult64.s
blob8a1c1532a52abfe8d75ae2ade5ddc1bcc75476ef
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Utility 64 bit multiplication routines. m68k version.
6 Lang: english
7 */
9 /* SMult64()/UMult64():
10 These are the signed/unsigned 64 bit multiplication routines.
11 There are two possibilities here because as of the 060 the
12 32*32->64 bit result instructions are not supported, and I haven't
13 quite figured out how to do this using the 32 bit ops yet (can't be
14 that hard though).
16 Still, emulating is faster than a unsup integer instruction except.
20 #include "aros/m68k/asm.h"
22 .text
23 .balign 4
25 .globl AROS_SLIB_ENTRY(UMult64,Utility,34)
26 .globl AROS_SLIB_ENTRY(UMult64_020,Utility,34)
28 .type AROS_SLIB_ENTRY(UMult64,Utility,34),@function
29 .type AROS_SLIB_ENTRY(UMult64_020,Utility,34),@function
32 AROS_SLIB_ENTRY(UMult64_020,Utility,34):
33 mulu.l %d0,%d0:%d1
34 rts
36 /* How do I do this, again consider:
37 (a^16 + b) * (c^16 + d)
38 = ac^32 + (ad + bc)^16 + bd
40 I tried to think of a way of doing this with the mulu.l instr,
41 but I couldn't so I'll just use the mulu.w. Its quicker than
42 an unsupp integer instruction anyway :)
45 .balign 4
46 AROS_SLIB_ENTRY(UMult64,Utility,34):
47 movem.l %d2-%d5,-(%sp)
48 /* Set up some registers */
49 move.l %d0,%d2
50 move.l %d1,%d3
51 move.l %d0,%d4 /* d */
52 move.l %d1,%d5 /* b */
53 swap %d2 /* a */
54 swap %d3 /* c */
57 /* Firstly, find the product bd */
58 mulu %d5,%d1 /* d1 = bd */
59 swap %d1 /* d1 = (bd)^16 */
61 /* Then find ac, put in d0 */
62 mulu %d3,%d0 /* d0 = ac */
64 /* Next find ad, bc, and add together */
65 mulu %d2,%d4
66 mulu %d3,%d5
67 add.l %d5,%d4
70 Add the low 16 bits to d1, then add upper 16 bits to d0
71 But make sure we carry the 1...
73 Apparently swap doesn't affect the X bit.
75 add.w %d4,%d1
76 swap %d4
77 addx.w %d4,%d0
79 /* All that remains to do is to flip d1 around the right way */
80 swap %d1
81 movem.l (%sp)+,%d2-%d5
83 rts