2
* Copyright (c) 2006 Josef Cejka
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
/** @addtogroup softint
34
* SW implementation of 32 and 64 bit division and modulo.
39
#define ABSVAL(x) ( (x) > 0 ? (x) : -(x))
40
#define SGN(x) ( (x) >= 0 ? 1 : 0 )
42
static unsigned int divandmod32(unsigned int a, unsigned int b, unsigned int *remainder)
45
int steps = sizeof(unsigned int) * 8;
51
/* FIXME: division by zero */
60
for ( ; steps > 0; steps--) {
61
/* shift one bit to remainder */
62
*remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1);
65
if (*remainder >= b) {
76
static unsigned long long divandmod64(unsigned long long a, unsigned long long b, unsigned long long *remainder)
78
unsigned long long result;
79
int steps = sizeof(unsigned long long) * 8;
85
/* FIXME: division by zero */
94
for ( ; steps > 0; steps--) {
95
/* shift one bit to remainder */
96
*remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1);
99
if (*remainder >= b) {
109
/* 32bit integer division */
110
int __divsi3(int a, int b)
115
result = (int)divandmod32(ABSVAL(a), ABSVAL(b), &rem);
117
if ( SGN(a) == SGN(b)) return result;
121
/* 64bit integer division */
122
long long __divdi3(long long a, long long b)
124
unsigned long long rem;
127
result = (long long)divandmod64(ABSVAL(a), ABSVAL(b), &rem);
129
if ( SGN(a) == SGN(b)) return result;
133
/* 32bit unsigned integer division */
134
unsigned int __udivsi3(unsigned int a, unsigned int b)
137
return divandmod32(a, b, &rem);
140
/* 64bit unsigned integer division */
141
unsigned long long __udivdi3(unsigned long long a, unsigned long long b)
143
unsigned long long rem;
144
return divandmod64(a, b, &rem);
147
/* 32bit remainder of the signed division */
148
int __modsi3(int a, int b)
151
divandmod32(a, b, &rem);
153
/* if divident is negative, remainder must be too */
161
/* 64bit remainder of the signed division */
162
long long __moddi3(long long a,long long b)
164
unsigned long long rem;
165
divandmod64(a, b, &rem);
167
/* if divident is negative, remainder must be too */
169
return -((long long)rem);
172
return (long long)rem;
175
/* 32bit remainder of the unsigned division */
176
unsigned int __umodsi3(unsigned int a, unsigned int b)
179
divandmod32(a, b, &rem);
183
/* 64bit remainder of the unsigned division */
184
unsigned long long __umoddi3(unsigned long long a, unsigned long long b)
186
unsigned long long rem;
187
divandmod64(a, b, &rem);
191
unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c)
193
return divandmod64(a, b, c);