blob: c288f98ff9a275afa1b3b892fb7b4e17f2168a10 [file] [log] [blame]
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001//===-- APInt.cpp - Implement APInt class ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Sheng Zhou and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a class to represent arbitrary precision integral
11// constant values.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ADT/APInt.h"
Chris Lattner6ad4c142007-02-06 05:38:37 +000016
17#if 0
Zhou Shengfd43dcf2007-02-06 03:00:16 +000018#include "llvm/DerivedTypes.h"
19#include "llvm/Support/MathExtras.h"
Zhou Shenga3832fd2007-02-07 06:14:53 +000020#include <cstring>
Zhou Shengfd43dcf2007-02-06 03:00:16 +000021#include <cstdlib>
22using namespace llvm;
23
Zhou Sheng353815d2007-02-06 06:04:53 +000024/// mul_1 - This function performs the multiplication operation on a
25/// large integer (represented as an integer array) and a uint64_t integer.
26/// @returns the carry of the multiplication.
27static uint64_t mul_1(uint64_t dest[], uint64_t x[],
28 unsigned len, uint64_t y) {
29 // Split y into high 32-bit part and low 32-bit part.
30 uint64_t ly = y & 0xffffffffULL, hy = y >> 32;
31 uint64_t carry = 0, lx, hx;
32 for (unsigned i = 0; i < len; ++i) {
33 lx = x[i] & 0xffffffffULL;
34 hx = x[i] >> 32;
35 // hasCarry - A flag to indicate if has carry.
36 // hasCarry == 0, no carry
37 // hasCarry == 1, has carry
38 // hasCarry == 2, no carry and the calculation result == 0.
39 uint8_t hasCarry = 0;
40 dest[i] = carry + lx * ly;
41 // Determine if the add above introduces carry.
42 hasCarry = (dest[i] < carry) ? 1 : 0;
43 carry = hx * ly + (dest[i] >> 32) + (hasCarry ? (1ULL << 32) : 0);
44 // The upper limit of carry can be (2^32 - 1)(2^32 - 1) +
45 // (2^32 - 1) + 2^32 = 2^64.
46 hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0);
47
48 carry += (lx * hy) & 0xffffffffULL;
49 dest[i] = (carry << 32) | (dest[i] & 0xffffffffULL);
50 carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0) +
51 (carry >> 32) + ((lx * hy) >> 32) + hx * hy;
52 }
53
54 return carry;
55}
56
57/// mul - This function multiplies integer array x[] by integer array y[] and
58/// stores the result into integer array dest[].
59/// Note the array dest[]'s size should no less than xlen + ylen.
60static void mul(uint64_t dest[], uint64_t x[], unsigned xlen,
61 uint64_t y[], unsigned ylen) {
62 dest[xlen] = mul_1(dest, x, xlen, y[0]);
63
64 for (unsigned i = 1; i < ylen; ++i) {
65 uint64_t ly = y[i] & 0xffffffffULL, hy = y[i] >> 32;
66 uint64_t carry = 0, lx, hx;
67 for (unsigned j = 0; j < xlen; ++j) {
68 lx = x[j] & 0xffffffffULL;
69 hx = x[j] >> 32;
70 // hasCarry - A flag to indicate if has carry.
71 // hasCarry == 0, no carry
72 // hasCarry == 1, has carry
73 // hasCarry == 2, no carry and the calculation result == 0.
74 uint8_t hasCarry = 0;
75 uint64_t resul = carry + lx * ly;
76 hasCarry = (resul < carry) ? 1 : 0;
77 carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + (resul >> 32);
78 hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0);
79
80 carry += (lx * hy) & 0xffffffffULL;
81 resul = (carry << 32) | (resul & 0xffffffffULL);
82 dest[i+j] += resul;
83 carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+
84 (carry >> 32) + (dest[i+j] < resul ? 1 : 0) +
85 ((lx * hy) >> 32) + hx * hy;
86 }
87 dest[i+xlen] = carry;
88 }
89}
90
91/// add_1 - This function adds the integer array x[] by integer y and
92/// returns the carry.
93/// @returns the carry of the addition.
94static uint64_t add_1(uint64_t dest[], uint64_t x[],
95 unsigned len, uint64_t y) {
96 uint64_t carry = y;
97
98 for (unsigned i = 0; i < len; ++i) {
99 dest[i] = carry + x[i];
100 carry = (dest[i] < carry) ? 1 : 0;
101 }
102 return carry;
103}
104
105/// add - This function adds the integer array x[] by integer array
106/// y[] and returns the carry.
107static uint64_t add(uint64_t dest[], uint64_t x[],
108 uint64_t y[], unsigned len) {
109 unsigned carry = 0;
110
111 for (unsigned i = 0; i< len; ++i) {
112 carry += x[i];
113 dest[i] = carry + y[i];
114 carry = carry < x[i] ? 1 : (dest[i] < carry ? 1 : 0);
115 }
116 return carry;
117}
118
119/// sub_1 - This function subtracts the integer array x[] by
120/// integer y and returns the borrow-out carry.
121static uint64_t sub_1(uint64_t x[], unsigned len, uint64_t y) {
122 uint64_t cy = y;
123
124 for (unsigned i = 0; i < len; ++i) {
125 uint64_t X = x[i];
126 x[i] -= cy;
127 if (cy > X)
128 cy = 1;
129 else {
130 cy = 0;
131 break;
132 }
133 }
134
135 return cy;
136}
137
138/// sub - This function subtracts the integer array x[] by
139/// integer array y[], and returns the borrow-out carry.
140static uint64_t sub(uint64_t dest[], uint64_t x[],
141 uint64_t y[], unsigned len) {
142 // Carry indicator.
143 uint64_t cy = 0;
144
145 for (unsigned i = 0; i < len; ++i) {
146 uint64_t Y = y[i], X = x[i];
147 Y += cy;
148
149 cy = Y < cy ? 1 : 0;
150 Y = X - Y;
151 cy += Y > X ? 1 : 0;
152 dest[i] = Y;
153 }
154 return cy;
155}
156
157/// UnitDiv - This function divides N by D,
158/// and returns (remainder << 32) | quotient.
159/// Assumes (N >> 32) < D.
160static uint64_t unitDiv(uint64_t N, unsigned D) {
161 uint64_t q, r; // q: quotient, r: remainder.
162 uint64_t a1 = N >> 32; // a1: high 32-bit part of N.
163 uint64_t a0 = N & 0xffffffffL; // a0: low 32-bit part of N
164 if (a1 < ((D - a1 - (a0 >> 31)) & 0xffffffffL)) {
165 q = N / D;
166 r = N % D;
167 }
168 else {
169 // Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d
170 uint64_t c = N - ((uint64_t) D << 31);
171 // Divide (c1*2^32 + c0) by d
172 q = c / D;
173 r = c % D;
174 // Add 2^31 to quotient
175 q += 1 << 31;
176 }
177
178 return (r << 32) | (q & 0xFFFFFFFFl);
179}
180
181/// subMul - This function substracts x[len-1:0] * y from
182/// dest[offset+len-1:offset], and returns the most significant
183/// word of the product, minus the borrow-out from the subtraction.
184static unsigned subMul(unsigned dest[], unsigned offset,
185 unsigned x[], unsigned len, unsigned y) {
186 uint64_t yl = (uint64_t) y & 0xffffffffL;
187 unsigned carry = 0;
188 unsigned j = 0;
189 do {
190 uint64_t prod = ((uint64_t) x[j] & 0xffffffffL) * yl;
191 unsigned prod_low = (unsigned) prod;
192 unsigned prod_high = (unsigned) (prod >> 32);
193 prod_low += carry;
194 carry = (prod_low < carry ? 1 : 0) + prod_high;
195 unsigned x_j = dest[offset+j];
196 prod_low = x_j - prod_low;
197 if (prod_low > x_j) ++carry;
198 dest[offset+j] = prod_low;
199 } while (++j < len);
200 return carry;
201}
202
203/// div - This is basically Knuth's formulation of the classical algorithm.
204/// Correspondance with Knuth's notation:
205/// Knuth's u[0:m+n] == zds[nx:0].
206/// Knuth's v[1:n] == y[ny-1:0]
207/// Knuth's n == ny.
208/// Knuth's m == nx-ny.
209/// Our nx == Knuth's m+n.
210/// Could be re-implemented using gmp's mpn_divrem:
211/// zds[nx] = mpn_divrem (&zds[ny], 0, zds, nx, y, ny).
212static void div(unsigned zds[], unsigned nx, unsigned y[], unsigned ny) {
213 unsigned j = nx;
214 do { // loop over digits of quotient
215 // Knuth's j == our nx-j.
216 // Knuth's u[j:j+n] == our zds[j:j-ny].
217 unsigned qhat; // treated as unsigned
218 if (zds[j] == y[ny-1]) qhat = -1U; // 0xffffffff
219 else {
220 uint64_t w = (((uint64_t)(zds[j])) << 32) +
221 ((uint64_t)zds[j-1] & 0xffffffffL);
222 qhat = (unsigned) unitDiv(w, y[ny-1]);
223 }
224 if (qhat) {
225 unsigned borrow = subMul(zds, j - ny, y, ny, qhat);
226 unsigned save = zds[j];
227 uint64_t num = ((uint64_t)save&0xffffffffL) -
228 ((uint64_t)borrow&0xffffffffL);
229 while (num) {
230 qhat--;
231 uint64_t carry = 0;
232 for (unsigned i = 0; i < ny; i++) {
233 carry += ((uint64_t) zds[j-ny+i] & 0xffffffffL)
234 + ((uint64_t) y[i] & 0xffffffffL);
235 zds[j-ny+i] = (unsigned) carry;
236 carry >>= 32;
237 }
238 zds[j] += carry;
239 num = carry - 1;
240 }
241 }
242 zds[j] = qhat;
243 } while (--j >= ny);
244}
245
246/// lshift - This function shift x[0:len-1] left by shiftAmt bits, and
247/// store the len least significant words of the result in
248/// dest[d_offset:d_offset+len-1]. It returns the bits shifted out from
249/// the most significant digit.
250static uint64_t lshift(uint64_t dest[], unsigned d_offset,
251 uint64_t x[], unsigned len, unsigned shiftAmt) {
252 unsigned count = 64 - shiftAmt;
253 int i = len - 1;
254 uint64_t high_word = x[i], retVal = high_word >> count;
255 ++d_offset;
256 while (--i >= 0) {
257 uint64_t low_word = x[i];
258 dest[d_offset+i] = (high_word << shiftAmt) | (low_word >> count);
259 high_word = low_word;
260 }
261 dest[d_offset+i] = high_word << shiftAmt;
262 return retVal;
263}
264
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000265APInt::APInt(uint64_t val, unsigned numBits, bool sign)
Zhou Shenga3832fd2007-02-07 06:14:53 +0000266 : BitsNum(numBits), isSigned(sign) {
267 assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small");
268 assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large");
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000269 if (isSingleWord())
Zhou Shenga3832fd2007-02-07 06:14:53 +0000270 VAL = val & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitsNum));
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000271 else {
272 // Memory allocation and check if successful.
Zhou Shenga3832fd2007-02-07 06:14:53 +0000273 assert((pVal = new uint64_t[getNumWords()]) &&
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000274 "APInt memory allocation fails!");
Zhou Shenga3832fd2007-02-07 06:14:53 +0000275 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000276 pVal[0] = val;
277 }
278}
279
280APInt::APInt(unsigned numBits, uint64_t bigVal[], bool sign)
Zhou Shenga3832fd2007-02-07 06:14:53 +0000281 : BitsNum(numBits), isSigned(sign) {
282 assert(BitsNum >= IntegerType::MIN_INT_BITS && "bitwidth too small");
283 assert(BitsNum <= IntegerType::MAX_INT_BITS && "bitwidth too large");
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000284 assert(bigVal && "Null pointer detected!");
285 if (isSingleWord())
Zhou Shenga3832fd2007-02-07 06:14:53 +0000286 VAL = bigVal[0] & (~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - BitsNum));
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000287 else {
288 // Memory allocation and check if successful.
Zhou Shenga3832fd2007-02-07 06:14:53 +0000289 assert((pVal = new uint64_t[getNumWords()]) &&
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000290 "APInt memory allocation fails!");
291 // Calculate the actual length of bigVal[].
292 unsigned n = sizeof(*bigVal) / sizeof(bigVal[0]);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000293 unsigned maxN = std::max<unsigned>(n, getNumWords());
294 unsigned minN = std::min<unsigned>(n, getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000295 memcpy(pVal, bigVal, (minN - 1) * 8);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000296 pVal[minN-1] = bigVal[minN-1] & (~uint64_t(0ULL) >> (64 - BitsNum % 64));
297 if (maxN == getNumWords())
298 memset(pVal+n, 0, (getNumWords() - n) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000299 }
300}
301
Zhou Shenga3832fd2007-02-07 06:14:53 +0000302/// @brief Create a new APInt by translating the char array represented
303/// integer value.
304APInt::APInt(const char StrStart[], unsigned slen, uint8_t radix, bool sign)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000305 : isSigned(sign) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000306 StrToAPInt(StrStart, slen, radix);
307}
308
309/// @brief Create a new APInt by translating the string represented
310/// integer value.
311APInt::APInt(const std::string& Val, uint8_t radix, bool sign)
312 : isSigned(sign) {
313 assert(!Val.empty() && "String empty?");
314 StrToAPInt(Val.c_str(), Val.size(), radix);
315}
316
317/// @brief Converts a char array into an integer.
318void APInt::StrToAPInt(const char *StrStart, unsigned slen, uint8_t radix) {
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000319 assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
320 "Radix should be 2, 8, 10, or 16!");
Zhou Shenga3832fd2007-02-07 06:14:53 +0000321 assert(StrStart && "String empty?");
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000322 unsigned size = 0;
323 // If the radix is a power of 2, read the input
324 // from most significant to least significant.
325 if ((radix & (radix - 1)) == 0) {
326 unsigned nextBitPos = 0, bits_per_digit = radix / 8 + 2;
327 uint64_t resDigit = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000328 BitsNum = slen * bits_per_digit;
329 if (getNumWords() > 1)
330 assert((pVal = new uint64_t[getNumWords()]) &&
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000331 "APInt memory allocation fails!");
332 for (int i = slen - 1; i >= 0; --i) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000333 uint64_t digit = StrStart[i] - 48; // '0' == 48.
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000334 resDigit |= digit << nextBitPos;
335 nextBitPos += bits_per_digit;
336 if (nextBitPos >= 64) {
337 if (isSingleWord()) {
338 VAL = resDigit;
339 break;
340 }
341 pVal[size++] = resDigit;
342 nextBitPos -= 64;
343 resDigit = digit >> (bits_per_digit - nextBitPos);
344 }
345 }
Zhou Shenga3832fd2007-02-07 06:14:53 +0000346 if (!isSingleWord() && size <= getNumWords())
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000347 pVal[size] = resDigit;
348 } else { // General case. The radix is not a power of 2.
349 // For 10-radix, the max value of 64-bit integer is 18446744073709551615,
350 // and its digits number is 14.
351 const unsigned chars_per_word = 20;
352 if (slen < chars_per_word ||
Zhou Shenga3832fd2007-02-07 06:14:53 +0000353 (slen == chars_per_word && // In case the value <= 2^64 - 1
354 strcmp(StrStart, "18446744073709551615") <= 0)) {
355 BitsNum = 64;
356 VAL = strtoull(StrStart, 0, 10);
357 } else { // In case the value > 2^64 - 1
358 BitsNum = (slen / chars_per_word + 1) * 64;
359 assert((pVal = new uint64_t[getNumWords()]) &&
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000360 "APInt memory allocation fails!");
Zhou Shenga3832fd2007-02-07 06:14:53 +0000361 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000362 unsigned str_pos = 0;
363 while (str_pos < slen) {
364 unsigned chunk = slen - str_pos;
365 if (chunk > chars_per_word - 1)
366 chunk = chars_per_word - 1;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000367 uint64_t resDigit = StrStart[str_pos++] - 48; // 48 == '0'.
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000368 uint64_t big_base = radix;
369 while (--chunk > 0) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000370 resDigit = resDigit * radix + StrStart[str_pos++] - 48;
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000371 big_base *= radix;
372 }
373
374 uint64_t carry;
375 if (!size)
376 carry = resDigit;
377 else {
378 carry = mul_1(pVal, pVal, size, big_base);
379 carry += add_1(pVal, pVal, size, resDigit);
380 }
381
382 if (carry) pVal[size++] = carry;
383 }
384 }
385 }
386}
387
388APInt::APInt(const APInt& APIVal)
Zhou Shenga3832fd2007-02-07 06:14:53 +0000389 : BitsNum(APIVal.BitsNum), isSigned(APIVal.isSigned) {
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000390 if (isSingleWord()) VAL = APIVal.VAL;
391 else {
392 // Memory allocation and check if successful.
Zhou Shenga3832fd2007-02-07 06:14:53 +0000393 assert((pVal = new uint64_t[getNumWords()]) &&
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000394 "APInt memory allocation fails!");
Zhou Shenga3832fd2007-02-07 06:14:53 +0000395 memcpy(pVal, APIVal.pVal, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000396 }
397}
398
399APInt::~APInt() {
400 if (!isSingleWord() && pVal) delete[] pVal;
401}
402
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000403/// @brief Copy assignment operator. Create a new object from the given
404/// APInt one by initialization.
405APInt& APInt::operator=(const APInt& RHS) {
406 if (isSingleWord()) VAL = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
407 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000408 unsigned minN = std::min(getNumWords(), RHS.getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000409 memcpy(pVal, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, minN * 8);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000410 if (getNumWords() != minN)
411 memset(pVal + minN, 0, (getNumWords() - minN) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000412 }
413 return *this;
414}
415
416/// @brief Assignment operator. Assigns a common case integer value to
417/// the APInt.
418APInt& APInt::operator=(uint64_t RHS) {
419 if (isSingleWord()) VAL = RHS;
420 else {
421 pVal[0] = RHS;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000422 memset(pVal, 0, (getNumWords() - 1) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000423 }
424 return *this;
425}
426
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000427/// @brief Prefix increment operator. Increments the APInt by one.
428APInt& APInt::operator++() {
429 if (isSingleWord()) ++VAL;
430 else
Zhou Shenga3832fd2007-02-07 06:14:53 +0000431 add_1(pVal, pVal, getNumWords(), 1);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000432 TruncToBits();
433 return *this;
434}
435
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000436/// @brief Prefix decrement operator. Decrements the APInt by one.
437APInt& APInt::operator--() {
438 if (isSingleWord()) --VAL;
439 else
Zhou Shenga3832fd2007-02-07 06:14:53 +0000440 sub_1(pVal, getNumWords(), 1);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000441 TruncToBits();
442 return *this;
443}
444
445/// @brief Addition assignment operator. Adds this APInt by the given APInt&
446/// RHS and assigns the result to this APInt.
447APInt& APInt::operator+=(const APInt& RHS) {
448 if (isSingleWord()) VAL += RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
449 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000450 if (RHS.isSingleWord()) add_1(pVal, pVal, getNumWords(), RHS.VAL);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000451 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000452 if (getNumWords() <= RHS.getNumWords())
453 add(pVal, pVal, RHS.pVal, getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000454 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000455 uint64_t carry = add(pVal, pVal, RHS.pVal, RHS.getNumWords());
456 add_1(pVal + RHS.getNumWords(), pVal + RHS.getNumWords(),
457 getNumWords() - RHS.getNumWords(), carry);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000458 }
459 }
460 }
461 TruncToBits();
462 return *this;
463}
464
465/// @brief Subtraction assignment operator. Subtracts this APInt by the given
466/// APInt &RHS and assigns the result to this APInt.
467APInt& APInt::operator-=(const APInt& RHS) {
468 if (isSingleWord())
469 VAL -= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
470 else {
471 if (RHS.isSingleWord())
Zhou Shenga3832fd2007-02-07 06:14:53 +0000472 sub_1(pVal, getNumWords(), RHS.VAL);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000473 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000474 if (RHS.getNumWords() < getNumWords()) {
475 uint64_t carry = sub(pVal, pVal, RHS.pVal, RHS.getNumWords());
476 sub_1(pVal + RHS.getNumWords(), getNumWords() - RHS.getNumWords(), carry);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000477 }
478 else
Zhou Shenga3832fd2007-02-07 06:14:53 +0000479 sub(pVal, pVal, RHS.pVal, getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000480 }
481 }
482 TruncToBits();
483 return *this;
484}
485
486/// @brief Multiplication assignment operator. Multiplies this APInt by the
487/// given APInt& RHS and assigns the result to this APInt.
488APInt& APInt::operator*=(const APInt& RHS) {
489 if (isSingleWord()) VAL *= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
490 else {
491 // one-based first non-zero bit position.
Zhou Shenga3832fd2007-02-07 06:14:53 +0000492 unsigned first = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000493 unsigned xlen = !first ? 0 : whichWord(first - 1) + 1;
494 if (!xlen)
495 return *this;
496 else if (RHS.isSingleWord())
497 mul_1(pVal, pVal, xlen, RHS.VAL);
498 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000499 first = RHS.getNumWords() * APINT_BITS_PER_WORD - RHS.CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000500 unsigned ylen = !first ? 0 : whichWord(first - 1) + 1;
501 if (!ylen) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000502 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000503 return *this;
504 }
505 uint64_t *dest = new uint64_t[xlen+ylen];
506 assert(dest && "Memory Allocation Failed!");
507 mul(dest, pVal, xlen, RHS.pVal, ylen);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000508 memcpy(pVal, dest, ((xlen + ylen >= getNumWords()) ?
509 getNumWords() : xlen + ylen) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000510 delete[] dest;
511 }
512 }
513 TruncToBits();
514 return *this;
515}
516
517/// @brief Division assignment operator. Divides this APInt by the given APInt
518/// &RHS and assigns the result to this APInt.
519APInt& APInt::operator/=(const APInt& RHS) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000520 unsigned first = RHS.getNumWords() * APINT_BITS_PER_WORD -
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000521 RHS.CountLeadingZeros();
522 unsigned ylen = !first ? 0 : whichWord(first - 1) + 1;
523 assert(ylen && "Divided by zero???");
524 if (isSingleWord()) {
525 if (isSigned && RHS.isSigned)
526 VAL = RHS.isSingleWord() ? (int64_t(VAL) / int64_t(RHS.VAL)) :
527 (ylen > 1 ? 0 : int64_t(VAL) / int64_t(RHS.pVal[0]));
528 else
529 VAL = RHS.isSingleWord() ? (VAL / RHS.VAL) :
530 (ylen > 1 ? 0 : VAL / RHS.pVal[0]);
531 } else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000532 unsigned first2 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000533 unsigned xlen = !first2 ? 0 : whichWord(first2 - 1) + 1;
534 if (!xlen)
535 return *this;
536 else if ((*this) < RHS)
Zhou Shenga3832fd2007-02-07 06:14:53 +0000537 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000538 else if ((*this) == RHS) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000539 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000540 pVal[0] = 1;
541 } else if (xlen == 1)
542 pVal[0] /= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
543 else {
544 uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
545 assert(xwords && ywords && "Memory Allocation Failed!");
546 memcpy(xwords, pVal, xlen * 8);
547 xwords[xlen] = 0;
548 memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
549 if (unsigned nshift = 63 - (first - 1) % 64) {
550 lshift(ywords, 0, ywords, ylen, nshift);
551 unsigned xlentmp = xlen;
552 xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
553 }
554 div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000555 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000556 memcpy(pVal, xwords + ylen, (xlen - ylen) * 8);
557 delete[] xwords;
558 delete[] ywords;
559 }
560 }
561 return *this;
562}
563
564/// @brief Remainder assignment operator. Yields the remainder from the
565/// division of this APInt by the given APInt& RHS and assigns the remainder
566/// to this APInt.
567APInt& APInt::operator%=(const APInt& RHS) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000568 unsigned first = RHS.getNumWords() * APINT_BITS_PER_WORD -
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000569 RHS.CountLeadingZeros();
570 unsigned ylen = !first ? 0 : whichWord(first - 1) + 1;
571 assert(ylen && "Performing remainder operation by zero ???");
572 if (isSingleWord()) {
573 if (isSigned && RHS.isSigned)
574 VAL = RHS.isSingleWord() ? (int64_t(VAL) % int64_t(RHS.VAL)) :
575 (ylen > 1 ? VAL : int64_t(VAL) % int64_t(RHS.pVal[0]));
576 else
577 VAL = RHS.isSingleWord() ? (VAL % RHS.VAL) :
578 (ylen > 1 ? VAL : VAL % RHS.pVal[0]);
579 } else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000580 unsigned first2 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000581 unsigned xlen = !first2 ? 0 : whichWord(first2 - 1) + 1;
582 if (!xlen || (*this) < RHS)
583 return *this;
584 else if ((*this) == RHS)
Zhou Shenga3832fd2007-02-07 06:14:53 +0000585 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000586 else if (xlen == 1)
587 pVal[0] %= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
588 else {
589 uint64_t *xwords = new uint64_t[xlen+1], *ywords = new uint64_t[ylen];
590 assert(xwords && ywords && "Memory Allocation Failed!");
591 memcpy(xwords, pVal, xlen * 8);
592 xwords[xlen] = 0;
593 memcpy(ywords, RHS.isSingleWord() ? &RHS.VAL : RHS.pVal, ylen * 8);
594 unsigned nshift = 63 - (first - 1) % 64;
595 if (nshift) {
596 lshift(ywords, 0, ywords, ylen, nshift);
597 unsigned xlentmp = xlen;
598 xwords[xlen++] = lshift(xwords, 0, xwords, xlentmp, nshift);
599 }
600 div((unsigned*)xwords, xlen*2-1, (unsigned*)ywords, ylen*2);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000601 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000602 for (unsigned i = 0; i < ylen-1; ++i)
603 pVal[i] = (xwords[i] >> nshift) | (xwords[i+1] << (64 - nshift));
604 pVal[ylen-1] = xwords[ylen-1] >> nshift;
605 delete[] xwords;
606 delete[] ywords;
607 }
608 }
609 return *this;
610}
611
612/// @brief Bitwise AND assignment operator. Performs bitwise AND operation on
613/// this APInt and the given APInt& RHS, assigns the result to this APInt.
614APInt& APInt::operator&=(const APInt& RHS) {
615 if (isSingleWord()) {
616 if (RHS.isSingleWord()) VAL &= RHS.VAL;
617 else VAL &= RHS.pVal[0];
618 } else {
619 if (RHS.isSingleWord()) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000620 memset(pVal, 0, (getNumWords() - 1) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000621 pVal[0] &= RHS.VAL;
622 } else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000623 unsigned minwords = getNumWords() < RHS.getNumWords() ?
624 getNumWords() : RHS.getNumWords();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000625 for (unsigned i = 0; i < minwords; ++i)
626 pVal[i] &= RHS.pVal[i];
Zhou Shenga3832fd2007-02-07 06:14:53 +0000627 if (getNumWords() > minwords)
628 memset(pVal+minwords, 0, (getNumWords() - minwords) * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000629 }
630 }
631 return *this;
632}
633
634/// @brief Bitwise OR assignment operator. Performs bitwise OR operation on
635/// this APInt and the given APInt& RHS, assigns the result to this APInt.
636APInt& APInt::operator|=(const APInt& RHS) {
637 if (isSingleWord()) {
638 if (RHS.isSingleWord()) VAL |= RHS.VAL;
639 else VAL |= RHS.pVal[0];
640 } else {
641 if (RHS.isSingleWord()) {
642 pVal[0] |= RHS.VAL;
643 } else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000644 unsigned minwords = getNumWords() < RHS.getNumWords() ?
645 getNumWords() : RHS.getNumWords();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000646 for (unsigned i = 0; i < minwords; ++i)
647 pVal[i] |= RHS.pVal[i];
648 }
649 }
650 TruncToBits();
651 return *this;
652}
653
654/// @brief Bitwise XOR assignment operator. Performs bitwise XOR operation on
655/// this APInt and the given APInt& RHS, assigns the result to this APInt.
656APInt& APInt::operator^=(const APInt& RHS) {
657 if (isSingleWord()) {
658 if (RHS.isSingleWord()) VAL ^= RHS.VAL;
659 else VAL ^= RHS.pVal[0];
660 } else {
661 if (RHS.isSingleWord()) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000662 for (unsigned i = 0; i < getNumWords(); ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000663 pVal[i] ^= RHS.VAL;
664 } else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000665 unsigned minwords = getNumWords() < RHS.getNumWords() ?
666 getNumWords() : RHS.getNumWords();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000667 for (unsigned i = 0; i < minwords; ++i)
668 pVal[i] ^= RHS.pVal[i];
Zhou Shenga3832fd2007-02-07 06:14:53 +0000669 if (getNumWords() > minwords)
670 for (unsigned i = minwords; i < getNumWords(); ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000671 pVal[i] ^= 0;
672 }
673 }
674 TruncToBits();
675 return *this;
676}
677
678/// @brief Bitwise AND operator. Performs bitwise AND operation on this APInt
679/// and the given APInt& RHS.
680APInt APInt::operator&(const APInt& RHS) const {
681 APInt API(RHS);
682 return API &= *this;
683}
684
685/// @brief Bitwise OR operator. Performs bitwise OR operation on this APInt
686/// and the given APInt& RHS.
687APInt APInt::operator|(const APInt& RHS) const {
688 APInt API(RHS);
689 API |= *this;
690 API.TruncToBits();
691 return API;
692}
693
694/// @brief Bitwise XOR operator. Performs bitwise XOR operation on this APInt
695/// and the given APInt& RHS.
696APInt APInt::operator^(const APInt& RHS) const {
697 APInt API(RHS);
698 API ^= *this;
699 API.TruncToBits();
700 return API;
701}
702
703/// @brief Logical AND operator. Performs logical AND operation on this APInt
704/// and the given APInt& RHS.
705bool APInt::operator&&(const APInt& RHS) const {
706 if (isSingleWord())
707 return RHS.isSingleWord() ? VAL && RHS.VAL : VAL && RHS.pVal[0];
708 else if (RHS.isSingleWord())
709 return RHS.VAL && pVal[0];
710 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000711 unsigned minN = std::min(getNumWords(), RHS.getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000712 for (unsigned i = 0; i < minN; ++i)
713 if (pVal[i] && RHS.pVal[i])
714 return true;
715 }
716 return false;
717}
718
719/// @brief Logical OR operator. Performs logical OR operation on this APInt
720/// and the given APInt& RHS.
721bool APInt::operator||(const APInt& RHS) const {
722 if (isSingleWord())
723 return RHS.isSingleWord() ? VAL || RHS.VAL : VAL || RHS.pVal[0];
724 else if (RHS.isSingleWord())
725 return RHS.VAL || pVal[0];
726 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000727 unsigned minN = std::min(getNumWords(), RHS.getNumWords());
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000728 for (unsigned i = 0; i < minN; ++i)
729 if (pVal[i] || RHS.pVal[i])
730 return true;
731 }
732 return false;
733}
734
735/// @brief Logical negation operator. Performs logical negation operation on
736/// this APInt.
737bool APInt::operator !() const {
738 if (isSingleWord())
739 return !VAL;
740 else
Zhou Shenga3832fd2007-02-07 06:14:53 +0000741 for (unsigned i = 0; i < getNumWords(); ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000742 if (pVal[i])
743 return false;
744 return true;
745}
746
747/// @brief Multiplication operator. Multiplies this APInt by the given APInt&
748/// RHS.
749APInt APInt::operator*(const APInt& RHS) const {
750 APInt API(RHS);
751 API *= *this;
752 API.TruncToBits();
753 return API;
754}
755
756/// @brief Division operator. Divides this APInt by the given APInt& RHS.
757APInt APInt::operator/(const APInt& RHS) const {
758 APInt API(*this);
759 return API /= RHS;
760}
761
762/// @brief Remainder operator. Yields the remainder from the division of this
763/// APInt and the given APInt& RHS.
764APInt APInt::operator%(const APInt& RHS) const {
765 APInt API(*this);
766 return API %= RHS;
767}
768
769/// @brief Addition operator. Adds this APInt by the given APInt& RHS.
770APInt APInt::operator+(const APInt& RHS) const {
771 APInt API(*this);
772 API += RHS;
773 API.TruncToBits();
774 return API;
775}
776
777/// @brief Subtraction operator. Subtracts this APInt by the given APInt& RHS
778APInt APInt::operator-(const APInt& RHS) const {
779 APInt API(*this);
780 API -= RHS;
781 API.TruncToBits();
782 return API;
783}
784
785/// @brief Array-indexing support.
786bool APInt::operator[](unsigned bitPosition) const {
787 return maskBit(bitPosition) & (isSingleWord() ?
788 VAL : pVal[whichWord(bitPosition)]) != 0;
789}
790
791/// @brief Equality operator. Compare this APInt with the given APInt& RHS
792/// for the validity of the equality relationship.
793bool APInt::operator==(const APInt& RHS) const {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000794 unsigned n1 = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros(),
795 n2 = RHS.getNumWords() * APINT_BITS_PER_WORD - RHS.CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000796 if (n1 != n2) return false;
797 else if (isSingleWord())
798 return VAL == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
799 else {
800 if (n1 <= 64)
801 return pVal[0] == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
802 for (int i = whichWord(n1 - 1); i >= 0; --i)
803 if (pVal[i] != RHS.pVal[i]) return false;
804 }
805 return true;
806}
807
Zhou Shenga3832fd2007-02-07 06:14:53 +0000808/// @brief Equality operator. Compare this APInt with the given uint64_t value
809/// for the validity of the equality relationship.
810bool APInt::operator==(uint64_t Val) const {
811 if (isSingleWord())
812 return VAL == Val;
813 else {
814 unsigned n = getNumWords() * APINT_BITS_PER_WORD - CountLeadingZeros();
815 if (n <= 64)
816 return pVal[0] == Val;
817 else
818 return false;
819 }
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000820}
821
822/// @brief Less-than operator. Compare this APInt with the given APInt& RHS
823/// for the validity of the less-than relationship.
824bool APInt::operator <(const APInt& RHS) const {
825 if (isSigned && RHS.isSigned) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000826 if ((*this)[BitsNum-1] > RHS[RHS.BitsNum-1])
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000827 return false;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000828 else if ((*this)[BitsNum-1] < RHS[RHS.BitsNum-1])
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000829 return true;
830 }
Zhou Shenga3832fd2007-02-07 06:14:53 +0000831 unsigned n1 = getNumWords() * 64 - CountLeadingZeros(),
832 n2 = RHS.getNumWords() * 64 - RHS.CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000833 if (n1 < n2) return true;
834 else if (n1 > n2) return false;
835 else if (isSingleWord())
836 return VAL < (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
837 else {
838 if (n1 <= 64)
839 return pVal[0] < (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
840 for (int i = whichWord(n1 - 1); i >= 0; --i) {
841 if (pVal[i] > RHS.pVal[i]) return false;
842 else if (pVal[i] < RHS.pVal[i]) return true;
843 }
844 }
845 return false;
846}
847
848/// @brief Less-than-or-equal operator. Compare this APInt with the given
849/// APInt& RHS for the validity of the less-than-or-equal relationship.
850bool APInt::operator<=(const APInt& RHS) const {
851 return (*this) == RHS || (*this) < RHS;
852}
853
854/// @brief Greater-than operator. Compare this APInt with the given APInt& RHS
855/// for the validity of the greater-than relationship.
856bool APInt::operator >(const APInt& RHS) const {
857 return !((*this) <= RHS);
858}
859
860/// @brief Greater-than-or-equal operator. Compare this APInt with the given
861/// APInt& RHS for the validity of the greater-than-or-equal relationship.
862bool APInt::operator>=(const APInt& RHS) const {
863 return !((*this) < RHS);
864}
865
866/// Set the given bit to 1 whose poition is given as "bitPosition".
867/// @brief Set a given bit to 1.
868APInt& APInt::set(unsigned bitPosition) {
869 if (isSingleWord()) VAL |= maskBit(bitPosition);
870 else pVal[whichWord(bitPosition)] |= maskBit(bitPosition);
871 return *this;
872}
873
874/// @brief Set every bit to 1.
875APInt& APInt::set() {
876 if (isSingleWord()) VAL = -1ULL;
877 else
Zhou Shenga3832fd2007-02-07 06:14:53 +0000878 for (unsigned i = 0; i < getNumWords(); ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000879 pVal[i] = -1ULL;
880 return *this;
881}
882
883/// Set the given bit to 0 whose position is given as "bitPosition".
884/// @brief Set a given bit to 0.
885APInt& APInt::clear(unsigned bitPosition) {
886 if (isSingleWord()) VAL &= ~maskBit(bitPosition);
887 else pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition);
888 return *this;
889}
890
891/// @brief Set every bit to 0.
892APInt& APInt::clear() {
893 if (isSingleWord()) VAL = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000894 else
895 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000896 return *this;
897}
898
899/// @brief Left-shift assignment operator. Left-shift the APInt by shiftAmt
900/// and assigns the result to this APInt.
901APInt& APInt::operator<<=(unsigned shiftAmt) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000902 if (shiftAmt >= BitsNum) {
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000903 if (isSingleWord()) VAL = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000904 else
905 memset(pVal, 0, getNumWords() * 8);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000906 } else {
907 for (unsigned i = 0; i < shiftAmt; ++i) clear(i);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000908 for (unsigned i = shiftAmt; i < BitsNum; ++i) {
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000909 if ((*this)[i-shiftAmt]) set(i);
910 else clear(i);
911 }
912 }
913 return *this;
914}
915
916/// @brief Left-shift operator. Left-shift the APInt by shiftAmt.
917APInt APInt::operator<<(unsigned shiftAmt) const {
918 APInt API(*this);
919 API <<= shiftAmt;
920 return API;
921}
922
923/// @brief Right-shift assignment operator. Right-shift the APInt by shiftAmt
924/// and assigns the result to this APInt.
925APInt& APInt::operator>>=(unsigned shiftAmt) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000926 bool isAShr = isSigned && (*this)[BitsNum-1];
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000927 if (isSingleWord())
928 VAL = isAShr ? (int64_t(VAL) >> shiftAmt) : (VAL >> shiftAmt);
929 else {
930 unsigned i = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000931 for (i = 0; i < BitsNum - shiftAmt; ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000932 if ((*this)[i+shiftAmt]) set(i);
933 else clear(i);
Zhou Shenga3832fd2007-02-07 06:14:53 +0000934 for (; i < BitsNum; ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000935 isAShr ? set(i) : clear(i);
936 }
937 return *this;
938}
939
940/// @brief Right-shift operator. Right-shift the APInt by shiftAmt.
941APInt APInt::operator>>(unsigned shiftAmt) const {
942 APInt API(*this);
943 API >>= shiftAmt;
944 return API;
945}
946
947/// @brief Bitwise NOT operator. Performs a bitwise logical NOT operation on
948/// this APInt.
949APInt APInt::operator~() const {
950 APInt API(*this);
951 API.flip();
952 return API;
953}
954
955/// @brief Toggle every bit to its opposite value.
956APInt& APInt::flip() {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000957 if (isSingleWord()) VAL = (~(VAL << (64 - BitsNum))) >> (64 - BitsNum);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000958 else {
959 unsigned i = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +0000960 for (; i < getNumWords() - 1; ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000961 pVal[i] = ~pVal[i];
Zhou Shenga3832fd2007-02-07 06:14:53 +0000962 unsigned offset = 64 - (BitsNum - 64 * (i - 1));
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000963 pVal[i] = (~(pVal[i] << offset)) >> offset;
964 }
965 return *this;
966}
967
968/// Toggle a given bit to its opposite value whose position is given
969/// as "bitPosition".
970/// @brief Toggles a given bit to its opposite value.
971APInt& APInt::flip(unsigned bitPosition) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000972 assert(bitPosition < BitsNum && "Out of the bit-width range!");
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000973 if ((*this)[bitPosition]) clear(bitPosition);
974 else set(bitPosition);
975 return *this;
976}
977
978/// to_string - This function translates the APInt into a string.
979std::string APInt::to_string(uint8_t radix) const {
980 assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
981 "Radix should be 2, 8, 10, or 16!");
Zhou Shenga3832fd2007-02-07 06:14:53 +0000982 char *buf = 0;
983 unsigned n = getNumWords() * 64 - CountLeadingZeros();
984 std::string format = radix == 8 ?
985 "%0*llo" : (radix == 10 ? "%0*llu" : "%0*llx");
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000986 // If the radix is a power of 2, set the format of ostringstream,
987 // and output the value into buf.
988 if ((radix & (radix - 1)) == 0) {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000989 assert((buf = new char[n / Log2_32(radix) + 2]) &&
990 "Memory allocation failed");
991 if (isSingleWord())
992 sprintf(buf, format.c_str(), 0, VAL);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000993 else {
Zhou Shenga3832fd2007-02-07 06:14:53 +0000994 unsigned offset = sprintf(buf, format.c_str(), 0, pVal[whichWord(n-1)]);
995 for (int i = whichWord(n-1) - 1; i >= 0; --i)
996 offset += sprintf(buf + offset, format.c_str(),
997 64 / Log2_32(radix) + (64 % Log2_32(radix) ? 1 : 0), pVal[i]);
Zhou Shengfd43dcf2007-02-06 03:00:16 +0000998 }
999 }
1000 else { // If the radix = 10, need to translate the value into a
1001 // string.
Zhou Shenga3832fd2007-02-07 06:14:53 +00001002 assert((buf = new char[(n / 64 + 1) * 20]) && "Memory allocation failed");
1003 if (isSingleWord())
1004 sprintf(buf, format.c_str(), 0, VAL);
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001005 else {
1006 // FIXME: To be supported.
1007 }
1008 }
Zhou Shenga3832fd2007-02-07 06:14:53 +00001009 std::string retStr(buf);
1010 delete[] buf;
1011 return retStr;
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001012}
1013
1014/// getMaxValue - This function returns the largest value
1015/// for an APInt of the specified bit-width and if isSign == true,
1016/// it should be largest signed value, otherwise unsigned value.
1017APInt APInt::getMaxValue(unsigned numBits, bool isSign) {
1018 APInt APIVal(numBits, 1);
1019 APIVal.set();
1020 return isSign ? APIVal.clear(numBits) : APIVal;
1021}
1022
1023/// getMinValue - This function returns the smallest value for
1024/// an APInt of the given bit-width and if isSign == true,
1025/// it should be smallest signed value, otherwise zero.
1026APInt APInt::getMinValue(unsigned numBits, bool isSign) {
1027 APInt APIVal(0, numBits);
1028 return isSign ? APIVal : APIVal.set(numBits);
1029}
1030
1031/// getAllOnesValue - This function returns an all-ones value for
1032/// an APInt of the specified bit-width.
1033APInt APInt::getAllOnesValue(unsigned numBits) {
1034 return getMaxValue(numBits, false);
1035}
1036
1037/// getNullValue - This function creates an '0' value for an
1038/// APInt of the specified bit-width.
1039APInt APInt::getNullValue(unsigned numBits) {
1040 return getMinValue(numBits, true);
1041}
1042
1043/// HiBits - This function returns the high "numBits" bits of this APInt.
1044APInt APInt::HiBits(unsigned numBits) const {
Zhou Shenga3832fd2007-02-07 06:14:53 +00001045 return (*this) >> (BitsNum - numBits);
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001046}
1047
1048/// LoBits - This function returns the low "numBits" bits of this APInt.
1049APInt APInt::LoBits(unsigned numBits) const {
Zhou Shenga3832fd2007-02-07 06:14:53 +00001050 return ((*this) << (BitsNum - numBits)) >> (BitsNum - numBits);
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001051}
1052
1053/// CountLeadingZeros - This function is a APInt version corresponding to
1054/// llvm/include/llvm/Support/MathExtras.h's function
1055/// CountLeadingZeros_{32, 64}. It performs platform optimal form of counting
1056/// the number of zeros from the most significant bit to the first one bit.
1057/// @returns numWord() * 64 if the value is zero.
1058unsigned APInt::CountLeadingZeros() const {
1059 if (isSingleWord())
1060 return CountLeadingZeros_64(VAL);
1061 unsigned Count = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +00001062 for (int i = getNumWords() - 1; i >= 0; --i) {
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001063 unsigned tmp = CountLeadingZeros_64(pVal[i]);
1064 Count += tmp;
1065 if (tmp != 64)
1066 break;
1067 }
1068 return Count;
1069}
1070
1071/// CountTrailingZero - This function is a APInt version corresponding to
1072/// llvm/include/llvm/Support/MathExtras.h's function
1073/// CountTrailingZeros_{32, 64}. It performs platform optimal form of counting
1074/// the number of zeros from the least significant bit to the first one bit.
1075/// @returns numWord() * 64 if the value is zero.
1076unsigned APInt::CountTrailingZeros() const {
1077 if (isSingleWord())
1078 return CountTrailingZeros_64(~VAL & (VAL - 1));
1079 APInt Tmp = ~(*this) & ((*this) - 1);
Zhou Shenga3832fd2007-02-07 06:14:53 +00001080 return getNumWords() * 64 - Tmp.CountLeadingZeros();
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001081}
1082
1083/// CountPopulation - This function is a APInt version corresponding to
1084/// llvm/include/llvm/Support/MathExtras.h's function
1085/// CountPopulation_{32, 64}. It counts the number of set bits in a value.
1086/// @returns 0 if the value is zero.
1087unsigned APInt::CountPopulation() const {
1088 if (isSingleWord())
1089 return CountPopulation_64(VAL);
1090 unsigned Count = 0;
Zhou Shenga3832fd2007-02-07 06:14:53 +00001091 for (unsigned i = 0; i < getNumWords(); ++i)
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001092 Count += CountPopulation_64(pVal[i]);
1093 return Count;
1094}
1095
1096
1097/// ByteSwap - This function returns a byte-swapped representation of the
1098/// APInt argument, APIVal.
1099APInt llvm::ByteSwap(const APInt& APIVal) {
Zhou Shenga3832fd2007-02-07 06:14:53 +00001100 if (APIVal.BitsNum <= 32)
1101 return APInt(APIVal.BitsNum, ByteSwap_32(unsigned(APIVal.VAL)));
1102 else if (APIVal.BitsNum <= 64)
1103 return APInt(APIVal.BitsNum, ByteSwap_64(APIVal.VAL));
Zhou Shengfd43dcf2007-02-06 03:00:16 +00001104 else
1105 return APIVal;
1106}
1107
1108/// GreatestCommonDivisor - This function returns the greatest common
1109/// divisor of the two APInt values using Enclid's algorithm.
1110APInt llvm::GreatestCommonDivisor(const APInt& API1, const APInt& API2) {
1111 APInt A = API1, B = API2;
1112 while (!!B) {
1113 APInt T = B;
1114 B = A % B;
1115 A = T;
1116 }
1117 return A;
1118}
Chris Lattner6ad4c142007-02-06 05:38:37 +00001119
1120#endif
1121