gcc-4.6.2: Update with patch for gengtype.c
[AROS.git] / rom / utility / udivmod32.c
blobc08c444a97afc605309fc0afea749441040d49b9
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: UDivMod32 - divide two 32 bit numbers.
6 Lang: english
7 */
8 #include "intern.h"
10 /*****************************************************************************
12 NAME */
13 #include <proto/utility.h>
15 AROS_LH2(ULONG, UDivMod32,
17 /* SYNOPSIS */
18 AROS_LHA(ULONG, dividend, D0),
19 AROS_LHA(ULONG, divisor, D1),
21 /* LOCATION */
22 struct Library *, UtilityBase, 26, Utility)
24 /* FUNCTION
25 Perform the 32 bit unsigned division and modulus of dividend by
26 divisor, that is dividend / divisor. Will return both the
27 quotient and the remainder.
29 INPUTS
30 dividend - The number to divide into (numerator).
31 divisor - The number to divide by (denominator).
33 RESULT
34 For m68k assembly programmers,
35 D0: quotient
36 D1: remainder
38 For HLL programmers,
39 the quotient
41 NOTES
42 The utility.library math functions are unlike all other utility
43 functions in that they don't require the library base to be
44 loaded in register A6, and they also save the values of the
45 address registers A0/A1.
47 This function is mainly to support assembly programers, and is
48 probably of limited use to higher-level language programmers.
50 EXAMPLE
52 BUGS
53 It is impossible for C programmers to obtain the value of
54 remainder.
56 SEE ALSO
57 SDivMod32(), SMult32(), SMult64(), UMult32(), UMult64()
59 INTERNALS
60 May actually be handled by code that is in config/$(KERNEL)
61 This is the case for m68k-native.
63 HISTORY
64 29-10-95 digulla automatically created from
65 utility_lib.fd and clib/utility_protos.h
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 return dividend / divisor;
73 #if 0
74 #error The UDivMod32() emulation code does NOT work!
76 /* This does _NOT_ work, so do not use it */
78 UWORD a,b,c,d;
79 UQUAD result;
80 LONG quo, rem;
82 a = dividend >> 16;
83 b = dividend & 0xFFFF;
84 c = divisor >> 16;
85 d = divisor & 0xFFFF;
87 /* See if the numerator is 32 bits or 16... */
88 if(a == 0)
90 /* 16 bits */
91 if(c != 0)
93 /* 16/32 -> quo = 0; rem = dividend */
94 quo = 0;
95 rem = dividend;
97 else
99 /* 16/16 -> can be done in native div */
100 quo = b / d;
101 rem = b % d;
104 else
106 /* 32 bit numerator */
107 if(c != 0)
109 /* 32 bit denominator, quo ~= a/c */
110 quo = a/c;
112 else
114 /* 16 bit denominator, quo ~= (a/d) * 65536 */
115 quo = (a / d) << 16;
117 /* Get the error */
118 rem = dividend - UMult32(quo,divisor);
120 /* Take the remainder down to zero */
121 while(rem > 0)
123 quo++;
124 rem -= divisor;
127 /* However a -ve remainder is silly,
128 this also catches the case when the remainder is < 0 from the
129 guess
131 while(rem < 0)
133 quo--;
134 rem += divisor;
137 SET_HIGH32OF64(result, quo);
138 SET_LOW32OF64(result, rem);
140 return result;
142 #endif
143 AROS_LIBFUNC_EXIT
145 } /* UDivMod32 */