Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index cff46e7b7f687c013f93ba08e135badb3171dd35..d5fac3d0ba586079e6806c2a1813dbf405cd61af 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -15,8 +15,6 @@ |
#include "PNaClTranslator.h" |
-#include "IceAPInt.h" |
-#include "IceAPFloat.h" |
#include "IceCfg.h" |
#include "IceCfgNode.h" |
#include "IceClFlags.h" |
@@ -167,6 +165,52 @@ void ExtendedType::dump(Ice::Ostream &Stream) const { |
} |
} |
+// Models integer literals as a sequence of bits. Used to read integer values |
+// from bitcode files. Based on llvm::APInt. |
+class BitcodeInt { |
+ BitcodeInt() = delete; |
+ BitcodeInt(const BitcodeInt &) = delete; |
+ BitcodeInt &operator=(const BitcodeInt &) = delete; |
+ |
+public: |
+ BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) { |
+ assert(Bits && "bitwidth too small"); |
+ assert(Bits <= BITS_PER_WORD && "bitwidth too big"); |
+ clearUnusedBits(); |
+ } |
+ |
+ int64_t getSExtValue() const { |
+ return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >> |
+ (BITS_PER_WORD - BitWidth); |
+ } |
+ |
+ template <typename IntType, typename FpType> |
+ inline FpType convertToFp() const { |
+ static_assert(sizeof(IntType) == sizeof(FpType), |
+ "IntType and FpType should be the same width"); |
+ assert(BitWidth == sizeof(IntType) * CHAR_BIT); |
+ auto V = static_cast<IntType>(Val); |
+ return reinterpret_cast<FpType &>(V); |
+ } |
+ |
+private: |
+ /// Bits in the (internal) value. |
+ static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT; |
+ |
+ uint32_t BitWidth; /// The number of bits in the floating point number. |
+ uint64_t Val; /// The (64-bit) equivalent integer value. |
+ |
+ /// Clear unused high order bits. |
+ void clearUnusedBits() { |
+ // If all bits are used, we want to leave the value alone. |
+ if (BitWidth == BITS_PER_WORD) |
+ return; |
+ |
+ // Mask out the high bits. |
+ Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth); |
+ } |
+}; |
+ |
class BlockParserBaseClass; |
// Top-level class to read PNaCl bitcode files, and translate to ICE. |
@@ -2534,7 +2578,7 @@ void FunctionParser::ProcessRecord() { |
Error(StrBuf.str()); |
return; |
} |
- Ice::APInt Value(BitWidth, |
+ BitcodeInt Value(BitWidth, |
NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2])); |
if (isIRGenDisabled) |
continue; |
@@ -2924,7 +2968,7 @@ void ConstantsParser::ProcessRecord() { |
return; |
} |
if (Ice::isScalarIntegerType(NextConstantType)) { |
- Ice::APInt Value(Ice::getScalarIntBitWidth(NextConstantType), |
+ BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType), |
NaClDecodeSignRotatedValue(Values[0])); |
if (Ice::Constant *C = getContext()->getConstantInt( |
NextConstantType, Value.getSExtValue())) { |
@@ -2951,14 +2995,14 @@ void ConstantsParser::ProcessRecord() { |
} |
switch (NextConstantType) { |
case Ice::IceType_f32: { |
- const Ice::APInt IntValue(32, static_cast<uint32_t>(Values[0])); |
- float FpValue = Ice::convertAPIntToFp<int32_t, float>(IntValue); |
+ const BitcodeInt Value(32, static_cast<uint32_t>(Values[0])); |
+ float FpValue = Value.convertToFp<int32_t, float>(); |
FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue)); |
return; |
} |
case Ice::IceType_f64: { |
- const Ice::APInt IntValue(64, Values[0]); |
- double FpValue = Ice::convertAPIntToFp<uint64_t, double>(IntValue); |
+ const BitcodeInt Value(64, Values[0]); |
+ double FpValue = Value.convertToFp<uint64_t, double>(); |
FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue)); |
return; |
} |