Changes in uspace/lib/softint/generic/division.c [88d5c1e:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softint/generic/division.c
r88d5c1e r9d58539 37 37 #include <division.h> 38 38 39 #define ABSVAL(x) ((x) > 0 ? (x) : -(x)) 40 #define SGN(x) ((x) >= 0 ? 1 : 0) 41 42 static unsigned int divandmod32(unsigned int a, unsigned int b, 43 unsigned int *remainder) 39 #define ABSVAL(x) ( (x) > 0 ? (x) : -(x)) 40 #define SGN(x) ( (x) >= 0 ? 1 : 0 ) 41 42 static unsigned int divandmod32(unsigned int a, unsigned int b, unsigned int *remainder) 44 43 { 45 44 unsigned int result; … … 54 53 } 55 54 56 if ( a < b) {55 if ( a < b) { 57 56 *remainder = a; 58 57 return 0; 59 58 } 60 61 for ( ; steps > 0; steps--) {59 60 for ( ; steps > 0; steps--) { 62 61 /* shift one bit to remainder */ 63 *remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1);62 *remainder = ( (*remainder) << 1) | (( a >> 31) & 0x1); 64 63 result <<= 1; 65 64 66 65 if (*remainder >= b) { 67 *remainder -= b;68 result |= 0x1;66 *remainder -= b; 67 result |= 0x1; 69 68 } 70 69 a <<= 1; 71 70 } 72 71 73 72 return result; 74 73 } 75 74 76 static unsigned long long divandmod64(unsigned long long a, 77 75 76 static unsigned long long divandmod64(unsigned long long a, unsigned long long b, unsigned long long *remainder) 78 77 { 79 78 unsigned long long result; 80 int steps = sizeof(unsigned long long) * 8; 79 int steps = sizeof(unsigned long long) * 8; 81 80 82 81 *remainder = 0; … … 88 87 } 89 88 90 if ( a < b) {89 if ( a < b) { 91 90 *remainder = a; 92 91 return 0; 93 92 } 94 95 for ( ; steps > 0; steps--) {93 94 for ( ; steps > 0; steps--) { 96 95 /* shift one bit to remainder */ 97 *remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1);96 *remainder = ( (*remainder) << 1) | ((a >> 63) & 0x1); 98 97 result <<= 1; 99 98 100 99 if (*remainder >= b) { 101 *remainder -= b;102 result |= 0x1;100 *remainder -= b; 101 result |= 0x1; 103 102 } 104 103 a <<= 1; 105 104 } 106 105 107 106 return result; 108 107 } 109 108 110 109 /* 32bit integer division */ 111 int __divsi3(int a, int b) 110 int __divsi3(int a, int b) 112 111 { 113 112 unsigned int rem; 114 int result = (int) divandmod32(ABSVAL(a), ABSVAL(b), &rem);113 int result; 115 114 116 if (SGN(a) == SGN(b))117 return result; 118 115 result = (int)divandmod32(ABSVAL(a), ABSVAL(b), &rem); 116 117 if ( SGN(a) == SGN(b)) return result; 119 118 return -result; 120 119 } 121 120 122 121 /* 64bit integer division */ 123 long long __divdi3(long long a, long long b) 122 long long __divdi3(long long a, long long b) 124 123 { 125 124 unsigned long long rem; 126 long long result = (long long) divandmod64(ABSVAL(a), ABSVAL(b), &rem);125 long long result; 127 126 128 if (SGN(a) == SGN(b))129 return result; 130 127 result = (long long)divandmod64(ABSVAL(a), ABSVAL(b), &rem); 128 129 if ( SGN(a) == SGN(b)) return result; 131 130 return -result; 132 131 } … … 142 141 unsigned long long __udivdi3(unsigned long long a, unsigned long long b) 143 142 { 144 unsigned long long rem;143 unsigned long long rem; 145 144 return divandmod64(a, b, &rem); 146 145 } … … 153 152 154 153 /* if divident is negative, remainder must be too */ 155 if (!(SGN(a))) 156 return -((int) rem); 154 if (!(SGN(a))) { 155 return -((int)rem); 156 } 157 157 158 return (int) 158 return (int)rem; 159 159 } 160 160 161 161 /* 64bit remainder of the signed division */ 162 long long __moddi3(long long a, longlong b)162 long long __moddi3(long long a,long long b) 163 163 { 164 164 unsigned long long rem; … … 166 166 167 167 /* if divident is negative, remainder must be too */ 168 if (!(SGN(a))) 169 return -((long long) rem); 168 if (!(SGN(a))) { 169 return -((long long)rem); 170 } 170 171 171 return (long long) 172 return (long long)rem; 172 173 } 173 174 … … 188 189 } 189 190 190 int __divmodsi3(int a, int b, int *c) 191 { 192 unsigned int rem; 193 int result = (int) divandmod32(ABSVAL(a), ABSVAL(b), &rem); 194 195 if (SGN(a) == SGN(b)) { 196 *c = rem; 197 return result; 198 } 199 200 *c = -rem; 201 return -result; 202 } 203 204 unsigned int __udivmodsi3(unsigned int a, unsigned int b, 205 unsigned int *c) 206 { 207 return divandmod32(a, b, c); 208 } 209 210 long long __divmoddi3(long long a, long long b, long long *c) 211 { 212 unsigned long long rem; 213 long long result = (int) divandmod64(ABSVAL(a), ABSVAL(b), &rem); 214 215 if (SGN(a) == SGN(b)) { 216 *c = rem; 217 return result; 218 } 219 220 *c = -rem; 221 return -result; 222 } 223 224 unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, 225 unsigned long long *c) 191 unsigned long long __udivmoddi3(unsigned long long a, unsigned long long b, unsigned long long *c) 226 192 { 227 193 return divandmod64(a, b, c);
Note:
See TracChangeset
for help on using the changeset viewer.