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 #include <picolibc.h>
19 
20 #define divnorm(num, den, sign) 		\
21 {						\
22   if (num < 0) 					\
23     {						\
24       num = -num;				\
25       sign = 1;					\
26     }						\
27   else 						\
28     {						\
29       sign = 0;					\
30     }						\
31 						\
32   if (den < 0) 					\
33     {						\
34       den = - den;				\
35       sign = 1 - sign;				\
36     } 						\
37 }
38 
39 
40 
41 
42 
43 unsigned long
divmodsi4(int modwanted,unsigned long num,unsigned long den)44 divmodsi4(int modwanted, unsigned long num, unsigned long den)
45 {
46   long int bit = 1;
47   long int res = 0;
48   long prevden;
49   while (den < num && bit && !(den & (1L<<31)))
50     {
51       den <<=1;
52       bit <<=1;
53     }
54   while (bit)
55     {
56       if (num >= den)
57 	{
58 	  num -= den;
59 	  res |= bit;
60 	}
61       bit >>=1;
62       den >>=1;
63     }
64   if (modwanted) return num;
65   return res;
66 }
67 
68 
69 #define exitdiv(sign, res) if (sign) { res = - res;} return res;
70 
71 long
__modsi3(long numerator,long denominator)72 __modsi3 (long numerator, long denominator)
73 {
74   int sign = 0;
75   long dividend;
76   long modul;
77 
78 
79   if (numerator < 0)
80     {
81       numerator = -numerator;
82       sign = 1;
83     }
84   if (denominator < 0)
85     {
86       denominator = -denominator;
87     }
88 
89   modul =  divmodsi4 (1, numerator, denominator);
90   if (sign)
91     return - modul;
92   return modul;
93 }
94 
95 
96 long
__divsi3(long numerator,long denominator)97 __divsi3 (long numerator, long denominator)
98 {
99   int sign;
100   long dividend;
101   long modul;
102   divnorm (numerator, denominator, sign);
103 
104   dividend = divmodsi4 (0,  numerator, denominator);
105   exitdiv (sign, dividend);
106 }
107 
108 long
__umodsi3(unsigned long numerator,unsigned long denominator)109 __umodsi3 (unsigned long numerator, unsigned long denominator)
110 {
111   long dividend;
112   long modul;
113 
114 modul= divmodsi4 (1,  numerator, denominator);
115   return modul;
116 }
117 
118 long
__udivsi3(unsigned long numerator,unsigned long denominator)119 __udivsi3 (unsigned long numerator, unsigned long denominator)
120 {
121   int sign;
122   long dividend;
123   long modul;
124   dividend =   divmodsi4 (0, numerator, denominator);
125   return dividend;
126 }
127 
128 
129 
130 
131 
132 
133 #include <picolibc.h>
134 
135 #ifdef TEST
136 
137 
138 
main()139 main ()
140 {
141   long int i, j, k, m;
142   for (i = -10000; i < 10000; i += 8)
143     {
144       for (j = -10000; j < 10000; j += 11)
145 	{
146 	  k = i / j;
147 	  m = __divsi3 (i, j);
148 	  if (k != m)
149 	    printf ("fail %d %d %d %d\n", i, j, k, m);
150 	}
151     }
152 }
153 
154 #endif
155