mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-13 23:25:06 +00:00
Add an override to StringRef::getAsInteger which parses into an APInt.
It gets its own implementation totally divorced from the (presumably performance-sensitive) routines which parse into a uint64_t. Add APInt::operator|=(uint64_t), which is situationally much better than using a full APInt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97381 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@@ -172,23 +173,28 @@ size_t StringRef::count(StringRef Str) const {
|
||||
return Count;
|
||||
}
|
||||
|
||||
static unsigned GetAutoSenseRadix(StringRef &Str) {
|
||||
if (Str.startswith("0x")) {
|
||||
Str = Str.substr(2);
|
||||
return 16;
|
||||
} else if (Str.startswith("0b")) {
|
||||
Str = Str.substr(2);
|
||||
return 2;
|
||||
} else if (Str.startswith("0")) {
|
||||
return 8;
|
||||
} else {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// GetAsUnsignedInteger - Workhorse method that converts a integer character
|
||||
/// sequence of radix up to 36 to an unsigned long long value.
|
||||
static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
|
||||
unsigned long long &Result) {
|
||||
// Autosense radix if not specified.
|
||||
if (Radix == 0) {
|
||||
if (Str.startswith("0x")) {
|
||||
Str = Str.substr(2);
|
||||
Radix = 16;
|
||||
} else if (Str.startswith("0b")) {
|
||||
Str = Str.substr(2);
|
||||
Radix = 2;
|
||||
} else if (Str.startswith("0"))
|
||||
Radix = 8;
|
||||
else
|
||||
Radix = 10;
|
||||
}
|
||||
if (Radix == 0)
|
||||
Radix = GetAutoSenseRadix(Str);
|
||||
|
||||
// Empty strings (after the radix autosense) are invalid.
|
||||
if (Str.empty()) return true;
|
||||
@@ -272,3 +278,78 @@ bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const {
|
||||
Result = Val;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
|
||||
StringRef Str = *this;
|
||||
|
||||
// Autosense radix if not specified.
|
||||
if (Radix == 0)
|
||||
Radix = GetAutoSenseRadix(Str);
|
||||
|
||||
assert(Radix > 1 && Radix <= 36);
|
||||
|
||||
// Empty strings (after the radix autosense) are invalid.
|
||||
if (Str.empty()) return true;
|
||||
|
||||
// Skip leading zeroes. This can be a significant improvement if
|
||||
// it means we don't need > 64 bits.
|
||||
while (!Str.empty() && Str.front() == '0')
|
||||
Str = Str.substr(1);
|
||||
|
||||
// If it was nothing but zeroes....
|
||||
if (Str.empty()) {
|
||||
Result = APInt(64, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// (Over-)estimate the required number of bits.
|
||||
unsigned Log2Radix = 0;
|
||||
while ((1U << Log2Radix) < Radix) Log2Radix++;
|
||||
bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix);
|
||||
|
||||
unsigned BitWidth = Log2Radix * Str.size();
|
||||
if (BitWidth < Result.getBitWidth())
|
||||
BitWidth = Result.getBitWidth(); // don't shrink the result
|
||||
else
|
||||
Result.zext(BitWidth);
|
||||
|
||||
APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix
|
||||
if (!IsPowerOf2Radix) {
|
||||
// These must have the same bit-width as Result.
|
||||
RadixAP = APInt(BitWidth, Radix);
|
||||
CharAP = APInt(BitWidth, 0);
|
||||
}
|
||||
|
||||
// Parse all the bytes of the string given this radix.
|
||||
Result = 0;
|
||||
while (!Str.empty()) {
|
||||
unsigned CharVal;
|
||||
if (Str[0] >= '0' && Str[0] <= '9')
|
||||
CharVal = Str[0]-'0';
|
||||
else if (Str[0] >= 'a' && Str[0] <= 'z')
|
||||
CharVal = Str[0]-'a'+10;
|
||||
else if (Str[0] >= 'A' && Str[0] <= 'Z')
|
||||
CharVal = Str[0]-'A'+10;
|
||||
else
|
||||
return true;
|
||||
|
||||
// If the parsed value is larger than the integer radix, the string is
|
||||
// invalid.
|
||||
if (CharVal >= Radix)
|
||||
return true;
|
||||
|
||||
// Add in this character.
|
||||
if (IsPowerOf2Radix) {
|
||||
Result <<= Log2Radix;
|
||||
Result |= CharVal;
|
||||
} else {
|
||||
Result *= RadixAP;
|
||||
CharAP = CharVal;
|
||||
Result += CharAP;
|
||||
}
|
||||
|
||||
Str = Str.substr(1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user