mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
Convert APint::{fromString,APInt,getBitsNeeded} to use StringRef.
- Patch by Erick Tryzelaar, with some edits (and a bug fix) from me. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78885 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -27,6 +27,7 @@ namespace llvm {
|
|||||||
class Deserializer;
|
class Deserializer;
|
||||||
class FoldingSetNodeID;
|
class FoldingSetNodeID;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
class StringRef;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SmallVectorImpl;
|
class SmallVectorImpl;
|
||||||
@ -152,8 +153,7 @@ class APInt {
|
|||||||
|
|
||||||
/// This is used by the constructors that take string arguments.
|
/// This is used by the constructors that take string arguments.
|
||||||
/// @brief Convert a char array into an APInt
|
/// @brief Convert a char array into an APInt
|
||||||
void fromString(unsigned numBits, const char *strStart, unsigned slen,
|
void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
|
||||||
uint8_t radix);
|
|
||||||
|
|
||||||
/// This is used by the toString method to divide by the radix. It simply
|
/// This is used by the toString method to divide by the radix. It simply
|
||||||
/// provides a more convenient form of divide for internal use since KnuthDiv
|
/// provides a more convenient form of divide for internal use since KnuthDiv
|
||||||
@ -229,17 +229,17 @@ public:
|
|||||||
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
|
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
|
||||||
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
|
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
|
||||||
|
|
||||||
/// This constructor interprets the slen characters starting at StrStart as
|
/// This constructor interprets the string \arg str in the given radix. The
|
||||||
/// a string in the given radix. The interpretation stops when the first
|
/// interpretation stops when the first character that is not suitable for the
|
||||||
/// character that is not suitable for the radix is encountered. Acceptable
|
/// radix is encountered, or the end of the string. Acceptable radix values
|
||||||
/// radix values are 2, 8, 10 and 16. It is an error for the value implied by
|
/// are 2, 8, 10 and 16. It is an error for the value implied by the string to
|
||||||
/// the string to require more bits than numBits.
|
/// require more bits than numBits.
|
||||||
|
///
|
||||||
/// @param numBits the bit width of the constructed APInt
|
/// @param numBits the bit width of the constructed APInt
|
||||||
/// @param strStart the start of the string to be interpreted
|
/// @param str the string to be interpreted
|
||||||
/// @param slen the maximum number of characters to interpret
|
/// @param radix the radix to use for the conversion
|
||||||
/// @param radix the radix to use for the conversion
|
|
||||||
/// @brief Construct an APInt from a string representation.
|
/// @brief Construct an APInt from a string representation.
|
||||||
APInt(unsigned numBits, const char strStart[], unsigned slen, uint8_t radix);
|
APInt(unsigned numBits, const StringRef &str, uint8_t radix);
|
||||||
|
|
||||||
/// Simply makes *this a copy of that.
|
/// Simply makes *this a copy of that.
|
||||||
/// @brief Copy Constructor.
|
/// @brief Copy Constructor.
|
||||||
@ -1063,9 +1063,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This method determines how many bits are required to hold the APInt
|
/// This method determines how many bits are required to hold the APInt
|
||||||
/// equivalent of the string given by \p str of length \p slen.
|
/// equivalent of the string given by \arg str.
|
||||||
/// @brief Get bits required for string value.
|
/// @brief Get bits required for string value.
|
||||||
static unsigned getBitsNeeded(const char* str, unsigned slen, uint8_t radix);
|
static unsigned getBitsNeeded(const StringRef& str, uint8_t radix);
|
||||||
|
|
||||||
/// countLeadingZeros - This function is an APInt version of the
|
/// countLeadingZeros - This function is an APInt version of the
|
||||||
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
|
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
|
||||||
|
@ -659,7 +659,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) {
|
TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) {
|
||||||
int len = CurPtr-TokStart-3;
|
int len = CurPtr-TokStart-3;
|
||||||
uint32_t bits = len * 4;
|
uint32_t bits = len * 4;
|
||||||
APInt Tmp(bits, TokStart+3, len, 16);
|
APInt Tmp(bits, StringRef(TokStart+3, len), 16);
|
||||||
uint32_t activeBits = Tmp.getActiveBits();
|
uint32_t activeBits = Tmp.getActiveBits();
|
||||||
if (activeBits > 0 && activeBits < bits)
|
if (activeBits > 0 && activeBits < bits)
|
||||||
Tmp.trunc(activeBits);
|
Tmp.trunc(activeBits);
|
||||||
@ -785,7 +785,7 @@ lltok::Kind LLLexer::LexDigitOrNegative() {
|
|||||||
return Lex0x();
|
return Lex0x();
|
||||||
unsigned Len = CurPtr-TokStart;
|
unsigned Len = CurPtr-TokStart;
|
||||||
uint32_t numBits = ((Len * 64) / 19) + 2;
|
uint32_t numBits = ((Len * 64) / 19) + 2;
|
||||||
APInt Tmp(numBits, TokStart, Len, 10);
|
APInt Tmp(numBits, StringRef(TokStart, Len), 10);
|
||||||
if (TokStart[0] == '-') {
|
if (TokStart[0] == '-') {
|
||||||
uint32_t minBits = Tmp.getMinSignedBits();
|
uint32_t minBits = Tmp.getMinSignedBits();
|
||||||
if (minBits > 0 && minBits < numBits)
|
if (minBits > 0 && minBits < numBits)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "apint"
|
#define DEBUG_TYPE "apint"
|
||||||
#include "llvm/ADT/APInt.h"
|
#include "llvm/ADT/APInt.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -75,11 +76,10 @@ APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
|
|||||||
clearUnusedBits();
|
clearUnusedBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt::APInt(unsigned numbits, const char StrStart[], unsigned slen,
|
APInt::APInt(unsigned numbits, const StringRef& Str, uint8_t radix)
|
||||||
uint8_t radix)
|
|
||||||
: BitWidth(numbits), VAL(0) {
|
: BitWidth(numbits), VAL(0) {
|
||||||
assert(BitWidth && "bitwidth too small");
|
assert(BitWidth && "bitwidth too small");
|
||||||
fromString(numbits, StrStart, slen, radix);
|
fromString(numbits, Str, radix);
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt& APInt::AssignSlowCase(const APInt& RHS) {
|
APInt& APInt::AssignSlowCase(const APInt& RHS) {
|
||||||
@ -587,15 +587,16 @@ APInt& APInt::flip(unsigned bitPosition) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned APInt::getBitsNeeded(const char* str, unsigned slen, uint8_t radix) {
|
unsigned APInt::getBitsNeeded(const StringRef& str, uint8_t radix) {
|
||||||
assert(str != 0 && "Invalid value string");
|
assert(!str.empty() && "Invalid string length");
|
||||||
assert(slen > 0 && "Invalid string length");
|
|
||||||
|
size_t slen = str.size();
|
||||||
|
|
||||||
// Each computation below needs to know if its negative
|
// Each computation below needs to know if its negative
|
||||||
unsigned isNegative = str[0] == '-';
|
unsigned isNegative = str.front() == '-';
|
||||||
if (isNegative) {
|
if (isNegative) {
|
||||||
slen--;
|
slen--;
|
||||||
str++;
|
assert(slen && "string is only a minus!");
|
||||||
}
|
}
|
||||||
// For radixes of power-of-two values, the bits required is accurately and
|
// For radixes of power-of-two values, the bits required is accurately and
|
||||||
// easily computed
|
// easily computed
|
||||||
@ -618,7 +619,7 @@ unsigned APInt::getBitsNeeded(const char* str, unsigned slen, uint8_t radix) {
|
|||||||
unsigned sufficient = slen*64/18;
|
unsigned sufficient = slen*64/18;
|
||||||
|
|
||||||
// Convert to the actual binary value.
|
// Convert to the actual binary value.
|
||||||
APInt tmp(sufficient, str, slen, radix);
|
APInt tmp(sufficient, str.substr(isNegative), radix);
|
||||||
|
|
||||||
// Compute how many bits are required.
|
// Compute how many bits are required.
|
||||||
return isNegative + tmp.logBase2() + 1;
|
return isNegative + tmp.logBase2() + 1;
|
||||||
@ -2001,15 +2002,19 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
|
|||||||
divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
|
divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APInt::fromString(unsigned numbits, const char *str, unsigned slen,
|
void APInt::fromString(unsigned numbits, const StringRef& str, uint8_t radix) {
|
||||||
uint8_t radix) {
|
|
||||||
// Check our assumptions here
|
// Check our assumptions here
|
||||||
assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
|
assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
|
||||||
"Radix should be 2, 8, 10, or 16!");
|
"Radix should be 2, 8, 10, or 16!");
|
||||||
assert(str && "String is null?");
|
assert(!str.empty() && "Invalid string length");
|
||||||
bool isNeg = str[0] == '-';
|
StringRef::iterator p = str.begin();
|
||||||
if (isNeg)
|
size_t slen = str.size();
|
||||||
str++, slen--;
|
bool isNeg = *p == '-';
|
||||||
|
if (isNeg) {
|
||||||
|
p++;
|
||||||
|
slen--;
|
||||||
|
assert(slen && "string is only a minus!");
|
||||||
|
}
|
||||||
assert((slen <= numbits || radix != 2) && "Insufficient bit width");
|
assert((slen <= numbits || radix != 2) && "Insufficient bit width");
|
||||||
assert(((slen-1)*3 <= numbits || radix != 8) && "Insufficient bit width");
|
assert(((slen-1)*3 <= numbits || radix != 8) && "Insufficient bit width");
|
||||||
assert(((slen-1)*4 <= numbits || radix != 16) && "Insufficient bit width");
|
assert(((slen-1)*4 <= numbits || radix != 16) && "Insufficient bit width");
|
||||||
@ -2028,10 +2033,10 @@ void APInt::fromString(unsigned numbits, const char *str, unsigned slen,
|
|||||||
APInt apradix(getBitWidth(), radix);
|
APInt apradix(getBitWidth(), radix);
|
||||||
|
|
||||||
// Enter digit traversal loop
|
// Enter digit traversal loop
|
||||||
for (unsigned i = 0; i < slen; i++) {
|
for (StringRef::iterator e = str.end(); p != e; ++p) {
|
||||||
// Get a digit
|
// Get a digit
|
||||||
unsigned digit = 0;
|
unsigned digit = 0;
|
||||||
char cdigit = str[i];
|
char cdigit = *p;
|
||||||
if (radix == 16) {
|
if (radix == 16) {
|
||||||
if (!isxdigit(cdigit))
|
if (!isxdigit(cdigit))
|
||||||
llvm_unreachable("Invalid hex digit in string");
|
llvm_unreachable("Invalid hex digit in string");
|
||||||
|
@ -164,12 +164,12 @@ TEST(APIntTest, i1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(APIntTest, fromString) {
|
TEST(APIntTest, fromString) {
|
||||||
EXPECT_EQ(APInt(1, 0), APInt(1, "0", 1, 10));
|
EXPECT_EQ(APInt(1, 0), APInt(1, "0", 10));
|
||||||
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 10));
|
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 10));
|
||||||
EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 2, 10));
|
EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 10));
|
||||||
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 2));
|
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 2));
|
||||||
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 8));
|
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 8));
|
||||||
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 16));
|
EXPECT_EQ(APInt(1, 1), APInt(1, "1", 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user