/*
    Copyright (C) 1995-97 AROS - The Amiga Replacement OS
    $Id: umult64.s,v 1.2 1997/02/03 02:54:50 ldp Exp $

    Desc: Utility 64 bit multiplication routines. m68k version.
    Lang: english
*/

#include "machine.i"

/* SMult64()/UMult64():
    These are the signed/unsigned 64 bit multiplication routines.
    There are two possibilities here because as of the 060 the
    32*32->64 bit result instructions are not supported, and I haven't
    quite figured out how to do this using the 32 bit ops yet (can't be
    that hard though).

    Still, emulating is faster than a unsup integer instruction except.

*/

    .balign 16

    .globl  AROS_SLIB_ENTRY(UMult64,Utility)
    .globl  AROS_SLIB_ENTRY(UMult64_020,Utility)

    .type   AROS_SLIB_ENTRY(UMult64,Utility),@function
    .type   AROS_SLIB_ENTRY(UMult64_020,Utility),@function


AROS_SLIB_ENTRY(UMult64_020,Utility):
    mulu.l  d0,d0:d1
    rts

/* How do I do this, again consider:
      (a^16 + b) * (c^16 + d)
    = ac^32 + (ad + bc)^16 + bd

    I tried to think of a way of doing this with the mulu.l instr,
    but I couldn't so I'll just use the mulu.w. Its quicker than
    an unsupp integer instruction anyway :)
*/

AROS_SLIB_ENTRY(UMult64,Utility):
    movem.l d2-d5,-(sp)
    /* Set up some registers */
    move.l  d0,d2
    move.l  d1,d3
    move.l  d0,d4   /* d */
    move.l  d1,d5   /* b */
    swap    d2      /* a */
    swap    d3      /* c */


    /* Firstly, find the product bd */
    mulu    d5,d1   /* d1 = bd */
    swap    d1      /* d1 = (bd)^16 */

    /* Then find ac, put in d0 */
    mulu    d3,d0   /* d0 = ac */

    /* Next find ad, bc, and add together */
    mulu    d2,d4
    mulu    d3,d5
    add.l   d5,d4

    /*
        Add the low 16 bits to d1, then add upper 16 bits to d0
        But make sure we carry the 1...

        Apparently swap doesn't affect the X bit.
    */
    add.w   d4,d1
    swap    d4
    addx.w  d4,d0

    /* All that remains to do is to flip d1 around the right way */
    swap    d1
    movem.l (sp)+,d2-d5

    rts
