Chromium Code Reviews| Index: src/PNaClTranslator.cpp |
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
| index cff46e7b7f687c013f93ba08e135badb3171dd35..ff53b3e79dabc319ad21094e7e73753649263117 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,55 @@ void ExtendedType::dump(Ice::Ostream &Stream) const { |
| } |
| } |
| +// Models integer literals as a sequence of bits. Based on llvm::APInt. |
| +class SzInt { |
|
Jim Stichnoth
2015/11/30 21:58:11
Can this go into an anonymous namespace?
And to a
Jim Stichnoth
2015/11/30 23:20:22
Sorry, I see now that it's already in a ginormous
|
| + SzInt() = delete; |
| + SzInt(const SzInt &) = delete; |
| + SzInt &operator=(const SzInt &) = delete; |
| + |
| +public: |
| + SzInt(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); |
|
rkotlerimgtec
2015/11/30 22:12:48
I think this form of using unions to do integer to
Jim Stichnoth
2015/11/30 23:20:22
This is a good point, unions aren't supposed to be
Karl
2015/12/01 00:00:49
Done.
|
| + union { |
| + IntType IntValue; |
| + FpType FpValue; |
| + } Converter; |
| + Converter.IntValue = static_cast<IntType>(Val); |
| + return Converter.FpValue; |
| + } |
| + |
| +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,8 +2581,8 @@ void FunctionParser::ProcessRecord() { |
| Error(StrBuf.str()); |
| return; |
| } |
| - Ice::APInt Value(BitWidth, |
| - NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2])); |
| + SzInt Value(BitWidth, |
| + NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2])); |
| if (isIRGenDisabled) |
| continue; |
| Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); |
| @@ -2924,8 +2971,8 @@ void ConstantsParser::ProcessRecord() { |
| return; |
| } |
| if (Ice::isScalarIntegerType(NextConstantType)) { |
| - Ice::APInt Value(Ice::getScalarIntBitWidth(NextConstantType), |
| - NaClDecodeSignRotatedValue(Values[0])); |
| + SzInt Value(Ice::getScalarIntBitWidth(NextConstantType), |
| + NaClDecodeSignRotatedValue(Values[0])); |
| if (Ice::Constant *C = getContext()->getConstantInt( |
| NextConstantType, Value.getSExtValue())) { |
| FuncParser->setNextConstantID(C); |
| @@ -2951,14 +2998,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 SzInt 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 SzInt Value(64, Values[0]); |
| + double FpValue = Value.convertToFp<uint64_t, double>(); |
| FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue)); |
| return; |
| } |