1 /*
2 Copyright (c) 1990 The Regents of the University of California.
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms are permitted
6 provided that the above copyright notice and this paragraph are
7 duplicated in all such forms and that any documentation,
8 and/or other materials related to such
9 distribution and use acknowledge that the software was developed
10 by the University of California, Berkeley.  The name of the
11 University may not be used to endorse or promote products derived
12 from this software without specific prior written permission.
13 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #define divnorm(num, den, sign) 		\
19 {						\
20   if (num < 0) 					\
21     {						\
22       num = -num;				\
23       sign = 1;					\
24     }						\
25   else 						\
26     {						\
27       sign = 0;					\
28     }						\
29 						\
30   if (den < 0) 					\
31     {						\
32       den = - den;				\
33       sign = 1 - sign;				\
34     } 						\
35 }
36 
37 
38 
39 
40 
41 static unsigned long
divmodsi4(int modwanted,unsigned long num,unsigned long den)42 divmodsi4(int modwanted, unsigned long num, unsigned long den)
43 {
44   long int bit = 1;
45   long int res = 0;
46   long prevden;
47   while (den < num && bit && !(den & (1L<<31)))
48     {
49       den <<=1;
50       bit <<=1;
51     }
52   while (bit)
53     {
54       if (num >= den)
55 	{
56 	  num -= den;
57 	  res |= bit;
58 	}
59       bit >>=1;
60       den >>=1;
61     }
62   if (modwanted) return num;
63   return res;
64 }
65 
66 
67 #define exitdiv(sign, res) if (sign) { res = - res;} return res;
68 
69 long
__modsi3(long numerator,long denominator)70 __modsi3 (long numerator, long denominator)
71 {
72   int sign = 0;
73   long dividend;
74   long modul;
75 
76 
77   if (numerator < 0)
78     {
79       numerator = -numerator;
80       sign = 1;
81     }
82   if (denominator < 0)
83     {
84       denominator = -denominator;
85     }
86 
87   modul =  divmodsi4 (1, numerator, denominator);
88   if (sign)
89     return - modul;
90   return modul;
91 }
92 
93 
94 long
__divsi3(long numerator,long denominator)95 __divsi3 (long numerator, long denominator)
96 {
97   int sign;
98   long dividend;
99   long modul;
100   divnorm (numerator, denominator, sign);
101 
102   dividend = divmodsi4 (0,  numerator, denominator);
103   exitdiv (sign, dividend);
104 }
105 
106 long
__umodsi3(unsigned long numerator,unsigned long denominator)107 __umodsi3 (unsigned long numerator, unsigned long denominator)
108 {
109   long dividend;
110   long modul;
111 
112 modul= divmodsi4 (1,  numerator, denominator);
113   return modul;
114 }
115 
116 long
__udivsi3(unsigned long numerator,unsigned long denominator)117 __udivsi3 (unsigned long numerator, unsigned long denominator)
118 {
119   int sign;
120   long dividend;
121   long modul;
122   dividend =   divmodsi4 (0, numerator, denominator);
123   return dividend;
124 }
125 
126 
127 
128 
129 
130 
131 #ifdef TEST
132 
133 
134 
main()135 main ()
136 {
137   long int i, j, k, m;
138   for (i = -10000; i < 10000; i += 8)
139     {
140       for (j = -10000; j < 10000; j += 11)
141 	{
142 	  k = i / j;
143 	  m = __divsi3 (i, j);
144 	  if (k != m)
145 	    printf ("fail %d %d %d %d\n", i, j, k, m);
146 	}
147     }
148 }
149 
150 #endif
151