00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <genarch/softint/division.h>
00036
00037 #define ABSVAL(x) ( (x) > 0 ? (x) : -(x))
00038 #define SGN(x) ( (x) >= 0 ? 1 : 0 )
00039
00040 static unsigned int divandmod32(unsigned int a, unsigned int b, unsigned int *remainder)
00041 {
00042 unsigned int result;
00043 int steps = sizeof(unsigned int) * 8;
00044
00045 *remainder = 0;
00046 result = 0;
00047
00048 if (b == 0) {
00049
00050 return 0;
00051 }
00052
00053 if ( a < b) {
00054 *remainder = a;
00055 return 0;
00056 }
00057
00058 for ( ; steps > 0; steps--) {
00059
00060 *remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1);
00061 result <<= 1;
00062
00063 if (*remainder >= b) {
00064 *remainder -= b;
00065 result |= 0x1;
00066 }
00067 a <<= 1;
00068 }
00069
00070 return result;
00071 }
00072
00073
00074 static unsigned long long divandmod64(unsigned long long a, unsigned long long b, unsigned long long *remainder)
00075 {
00076 unsigned long long result;
00077 int steps = sizeof(unsigned long long) * 8;
00078
00079 *remainder = 0;
00080 result = 0;
00081
00082 if (b == 0) {
00083
00084 return 0;
00085 }
00086
00087 if ( a < b) {
00088 *remainder = a;
00089 return 0;
00090 }
00091
00092 for ( ; steps > 0; steps--) {
00093
00094 *remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1);
00095 result <<= 1;
00096
00097 if (*remainder >= b) {
00098 *remainder -= b;
00099 result |= 0x1;
00100 }
00101 a <<= 1;
00102 }
00103
00104 return result;
00105 }
00106
00107
00108 int __divsi3(int a, int b)
00109 {
00110 unsigned int rem;
00111 int result;
00112
00113 result = (int)divandmod32(ABSVAL(a), ABSVAL(b), &rem);
00114
00115 if ( SGN(a) == SGN(b)) return result;
00116 return -result;
00117 }
00118
00119
00120 long long __divdi3(long long a, long long b)
00121 {
00122 unsigned long long rem;
00123 long long result;
00124
00125 result = (long long)divandmod64(ABSVAL(a), ABSVAL(b), &rem);
00126
00127 if ( SGN(a) == SGN(b)) return result;
00128 return -result;
00129 }
00130
00131
00132 unsigned int __udivsi3(unsigned int a, unsigned int b)
00133 {
00134 unsigned int rem;
00135 return divandmod32(a, b, &rem);
00136 }
00137
00138
00139 unsigned long long __udivdi3(unsigned long long a, unsigned long long b)
00140 {
00141 unsigned long long rem;
00142 return divandmod64(a, b, &rem);
00143 }
00144
00145
00146 int __modsi3(int a, int b)
00147 {
00148 unsigned int rem;
00149 divandmod32(a, b, &rem);
00150
00151
00152 if (!(SGN(a))) {
00153 return -((int)rem);
00154 }
00155
00156 return (int)rem;
00157 }
00158
00159
00160 long long __moddi3(long long a,long long b)
00161 {
00162 unsigned long long rem;
00163 divandmod64(a, b, &rem);
00164
00165
00166 if (!(SGN(a))) {
00167 return -((long long)rem);
00168 }
00169
00170 return (long long)rem;
00171 }
00172
00173
00174 unsigned int __umodsi3(unsigned int a, unsigned int b)
00175 {
00176 unsigned int rem;
00177 divandmod32(a, b, &rem);
00178 return rem;
00179 }
00180
00181
00182 unsigned long long __umoddi3(unsigned long long a, unsigned long long b)
00183 {
00184 unsigned long long rem;
00185 divandmod64(a, b, &rem);
00186 return rem;
00187 }
00188
00189 unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c)
00190 {
00191 return divandmod64(a, b, c);
00192 }
00193
00194
00195