home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1995-1997 AROS - The Amiga Replacement OS
- $Id: udivmod32.c,v 1.2 1997/02/03 02:58:32 ldp Exp $
-
- Desc: UDivMod32 - divide two 32 bit numbers.
- Lang: english
- */
- #include "utility_intern.h"
-
- /*****************************************************************************
-
- NAME */
- #include <proto/utility.h>
-
- AROS_LH2(ULONG, UDivMod32,
-
- /* SYNOPSIS */
- AROS_LHA(ULONG, dividend, D0),
- AROS_LHA(ULONG, divisor, D1),
-
- /* LOCATION */
- struct Library *, UtilityBase, 26, Utility)
-
- /* FUNCTION
- Perform the 32 bit unsigned division and modulus of dividend by
- divisor, that is dividend / divisor. Will return both the
- quotient and the remainder.
-
- INPUTS
- dividend - The number to divide into (numerator).
- divisor - The number to divide by (denominator).
-
- RESULT
- For m68k assembly programmers,
- D0: quotient
- D1: remainder
-
- For HLL programmers,
- the quotient
-
- NOTES
- The utility.library math functions are unlike all other utility
- functions in that they don't require the library base to be
- loaded in register A6, and they also save the values of the
- address registers A0/A1.
-
- This function is mainly to support assembly programers, and is
- probably of limited use to higher-level language programmers.
-
- EXAMPLE
-
- BUGS
- It is impossible for C programmers to obtain the value of
- remainder.
-
- SEE ALSO
- SDivMod32(), SMult32(), SMult64(), UMult32(), UMult64()
-
- INTERNALS
- May actually be handled by code that is in config/$(KERNEL)
- This is the case for m68k-native.
-
- HISTORY
- 29-10-95 digulla automatically created from
- utility_lib.fd and clib/utility_protos.h
-
- *****************************************************************************/
- {
- AROS_LIBFUNC_INIT
-
- return dividend / divisor;
-
- #if 0
- #error The UDivMod32() emulation code does NOT work!
-
- /* This does _NOT_ work, so do not use it */
-
- UWORD a,b,c,d;
- UQUAD result;
- LONG quo, rem;
-
- a = dividend >> 16;
- b = dividend & 0xFFFF;
- c = divisor >> 16;
- d = divisor & 0xFFFF;
-
- /* See if the numerator is 32 bits or 16... */
- if(a == 0)
- {
- /* 16 bits */
- if(c != 0)
- {
- /* 16/32 -> quo = 0; rem = dividend */
- quo = 0;
- rem = dividend;
- }
- else
- {
- /* 16/16 -> can be done in native div */
- quo = b / d;
- rem = b % d;
- }
- }
- else
- {
- /* 32 bit numerator */
- if(c != 0)
- {
- /* 32 bit denominator, quo ~= a/c */
- quo = a/c;
- }
- else
- {
- /* 16 bit denominator, quo ~= (a/d) * 65536 */
- quo = (a / d) << 16;
- }
- /* Get the error */
- rem = dividend - UMult32(quo,divisor);
-
- /* Take the remainder down to zero */
- while(rem > 0)
- {
- quo++;
- rem -= divisor;
- }
-
- /* However a -ve remainder is silly,
- this also catches the case when the remainder is < 0 from the
- guess
- */
- while(rem < 0)
- {
- quo--;
- rem += divisor;
- }
- }
- SET_HIGH32OF64(result, quo);
- SET_LOW32OF64(result, rem);
-
- return result;
-
- #endif
- AROS_LIBFUNC_EXIT
-
- } /* UDivMod32 */
-