Changeset a35b458 in mainline for uspace/lib/softint
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/lib/softint/generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/softint/generic/division.c
r3061bc1 ra35b458 45 45 unsigned int result; 46 46 int steps = sizeof(unsigned int) * 8; 47 47 48 48 *remainder = 0; 49 49 result = 0; 50 50 51 51 if (b == 0) { 52 52 /* FIXME: division by zero */ 53 53 return 0; 54 54 } 55 55 56 56 if (a < b) { 57 57 *remainder = a; 58 58 return 0; 59 59 } 60 60 61 61 for (; steps > 0; steps--) { 62 62 /* shift one bit to remainder */ 63 63 *remainder = ((*remainder) << 1) | (( a >> 31) & 0x1); 64 64 result <<= 1; 65 65 66 66 if (*remainder >= b) { 67 67 *remainder -= b; … … 70 70 a <<= 1; 71 71 } 72 72 73 73 return result; 74 74 } … … 79 79 unsigned long long result; 80 80 int steps = sizeof(unsigned long long) * 8; 81 81 82 82 *remainder = 0; 83 83 result = 0; 84 84 85 85 if (b == 0) { 86 86 /* FIXME: division by zero */ 87 87 return 0; 88 88 } 89 89 90 90 if (a < b) { 91 91 *remainder = a; 92 92 return 0; 93 93 } 94 94 95 95 for (; steps > 0; steps--) { 96 96 /* shift one bit to remainder */ 97 97 *remainder = ((*remainder) << 1) | ((a >> 63) & 0x1); 98 98 result <<= 1; 99 99 100 100 if (*remainder >= b) { 101 101 *remainder -= b; … … 104 104 a <<= 1; 105 105 } 106 106 107 107 return result; 108 108 } … … 113 113 unsigned int rem; 114 114 int result = (int) divandmod32(ABSVAL(a), ABSVAL(b), &rem); 115 115 116 116 if (SGN(a) == SGN(b)) 117 117 return result; 118 118 119 119 return -result; 120 120 } … … 125 125 unsigned long long rem; 126 126 long long result = (long long) divandmod64(ABSVAL(a), ABSVAL(b), &rem); 127 127 128 128 if (SGN(a) == SGN(b)) 129 129 return result; 130 130 131 131 return -result; 132 132 } … … 151 151 unsigned int rem; 152 152 divandmod32(a, b, &rem); 153 153 154 154 /* if divident is negative, remainder must be too */ 155 155 if (!(SGN(a))) 156 156 return -((int) rem); 157 157 158 158 return (int) rem; 159 159 } … … 164 164 unsigned long long rem; 165 165 divandmod64(a, b, &rem); 166 166 167 167 /* if divident is negative, remainder must be too */ 168 168 if (!(SGN(a))) 169 169 return -((long long) rem); 170 170 171 171 return (long long) rem; 172 172 } … … 192 192 unsigned int rem; 193 193 int result = (int) divandmod32(ABSVAL(a), ABSVAL(b), &rem); 194 194 195 195 if (SGN(a) == SGN(b)) { 196 196 *c = rem; 197 197 return result; 198 198 } 199 199 200 200 *c = -rem; 201 201 return -result; … … 212 212 unsigned long long rem; 213 213 long long result = (int) divandmod64(ABSVAL(a), ABSVAL(b), &rem); 214 214 215 215 if (SGN(a) == SGN(b)) { 216 216 *c = rem; 217 217 return result; 218 218 } 219 219 220 220 *c = -rem; 221 221 return -result; … … 226 226 unsigned long long rem; 227 227 long long result = (int) divandmod64(ABSVAL(a), ABSVAL(b), &rem); 228 228 229 229 if (SGN(a) == SGN(b)) { 230 230 *c = rem; 231 231 return result; 232 232 } 233 233 234 234 *c = -rem; 235 235 return -result; -
uspace/lib/softint/generic/multiplication.c
r3061bc1 ra35b458 53 53 unsigned int b1 = b >> 16; 54 54 unsigned int b2 = b & UINT16_MAX; 55 55 56 56 unsigned long long t1 = a1 * b1; 57 57 unsigned long long t2 = a1 * b2; 58 58 t2 += a2 * b1; 59 59 unsigned long long t3 = a2 * b2; 60 60 61 61 t3 = (((t1 << 16) + t2) << 16) + t3; 62 62 63 63 return t3; 64 64 } … … 70 70 { 71 71 char neg = 0; 72 72 73 73 if (a < 0) { 74 74 neg = !neg; 75 75 a = -a; 76 76 } 77 77 78 78 if (b < 0) { 79 79 neg = !neg; 80 80 b = -b; 81 81 } 82 82 83 83 unsigned long long a1 = a >> 32; 84 84 unsigned long long b1 = b >> 32; 85 85 86 86 unsigned long long a2 = a & (UINT32_MAX); 87 87 unsigned long long b2 = b & (UINT32_MAX); 88 88 89 89 if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) { 90 90 /* Error (overflow) */ 91 91 return (neg ? INT64_MIN : INT64_MAX); 92 92 } 93 93 94 94 /* (if OF checked) a1 or b1 is zero => result fits in 64 bits, 95 95 * no need to another overflow check 96 96 */ 97 97 unsigned long long t1 = mul(a1, b2) + mul(b1, a2); 98 98 99 99 if ((SOFTINT_CHECK_OF) && (t1 > UINT32_MAX)) { 100 100 /* Error (overflow) */ 101 101 return (neg ? INT64_MIN : INT64_MAX); 102 102 } 103 103 104 104 t1 = t1 << 32; 105 105 unsigned long long t2 = mul(a2, b2); 106 106 t2 += t1; 107 107 108 108 /* t2 & (1ull << 63) - if this bit is set in unsigned long long, 109 109 * result does not fit in signed one */ … … 112 112 return (neg ? INT64_MIN : INT64_MAX); 113 113 } 114 114 115 115 long long result = t2; 116 116 if (neg) 117 117 result = -result; 118 118 119 119 return result; 120 120 } -
uspace/lib/softint/generic/shift.c
r3061bc1 ra35b458 42 42 43 43 ll.s_whole = val; 44 44 45 45 if (shift <= 0) { 46 46 return ll.s_whole; 47 47 } 48 48 49 49 if (shift >= (int) WHOLE_BIT_CNT) { 50 50 ll.u_half[HI] = 0;
Note:
See TracChangeset
for help on using the changeset viewer.