revert between 56095 -> 55830 in arch
[AROS.git] / arch / .unmaintained / m68k-linux / utility / umult32.s
blob1903defc5faa9cd281c71274193d7a90f63fcd38
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Utility 32 bit multiplication routines. m68k version.
6 Lang: english
7 */
9 #include "machine.i"
11 /* SMult32()/UMult32():
12 These are the signed/unsigned 32 bit multiplication routines.
13 I have two different possibilities here since I could be running
14 on a system without the corresponding muls.l/mulu.l calls.
16 After some soul searching I am happy that these routines don't
17 have to be separated between signed/unsigned since the sign is
18 correct, or the number overflows.
20 The native versions do make the difference however.
22 What I do is SetFunction() the correct function in later.
24 .text
25 .balign 16
27 .globl AROS_SLIB_ENTRY(SMult32,Utility)
28 .globl AROS_SLIB_ENTRY(UMult32,Utility)
29 .globl AROS_SLIB_ENTRY(UMult32_020,Utility)
31 .type AROS_SLIB_ENTRY(SMult32,Utility),@function
32 .type AROS_SLIB_ENTRY(UMult32,Utility),@function
33 .type AROS_SLIB_ENTRY(UMult32_020,Utility),@function
35 AROS_SLIB_ENTRY(UMult32_020,Utility):
36 mulu.l %d1,%d0
37 rts
39 AROS_SLIB_ENTRY(SMult32,Utility):
40 AROS_SLIB_ENTRY(UMult32,Utility):
42 What do we have to do
43 d0 = (a^16 + b), d1 = (c^16 = d)
44 res = ac^32 + (ad + bc)^16 + bd
46 Now, ac^32 can be thrown away, as can the high 16 bits of ad + bd
48 movem.l %d2/%d3,-(%sp)
49 moveq.l #0,%d2
50 moveq.l #0,%d3
52 /* ad */
53 move.w %d1,%d3
54 swap %d0
55 mulu %d0,%d3
57 /* bc */
58 swap %d0
59 move.w %d0,%d2
60 swap %d1
61 mulu %d1,%d2
63 /* (ad + bc)^16 */
64 add.l %d3,%d2
65 swap %d2
66 clr.w %d2
68 /* bd + (ad + bc)^16 */
69 swap %d1
70 mulu %d1,%d0
71 add.l %d2,%d0
72 movem.l (%sp)+,%d2/%d3
73 rts