diff options
author | Scott Michel <scottm@aero.org> | 2008-02-15 23:05:48 +0000 |
---|---|---|
committer | Scott Michel <scottm@aero.org> | 2008-02-15 23:05:48 +0000 |
commit | ac7091cb9cc8672cb11befc1a333f79752be0fc6 (patch) | |
tree | 16f995f13d3b186a0d2c18e0893cfed8258413b9 /utils | |
parent | 3db8f776a4658beee52af12aa9275ad0282b1cdd (diff) | |
download | external_llvm-ac7091cb9cc8672cb11befc1a333f79752be0fc6.zip external_llvm-ac7091cb9cc8672cb11befc1a333f79752be0fc6.tar.gz external_llvm-ac7091cb9cc8672cb11befc1a333f79752be0fc6.tar.bz2 |
Make tblgen a little smarter about constants smaller than i32. Currently,
tblgen will complain if a sign-extended constant does not fit into a
data type smaller than i32, e.g., i16. This causes a problem when certain
hex constants are used, such as 0xff for byte masks or immediate xor
values.
tblgen will try the sign-extended value first and, if the sign extended
value would overflow, it tries to see if the unsigned value will fit.
Consequently, a software developer can now safely incant:
(XORHIr16 R16C:$rA, 0xffff)
which is somewhat clearer and more informative than incanting:
(XORHIr16 R16C:$rA, (i16 -1))
even if the two are bitwise equivalent.
Tblgen also outputs the 64-bit unsigned constant in the generated ISel code
when getTargetConstant() is invoked.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47188 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 15 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 11 |
2 files changed, 18 insertions, 8 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 146488e..ddfaaac 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -702,10 +702,17 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // Make sure that the value is representable for this type. if (Size < 32) { int Val = (II->getValue() << (32-Size)) >> (32-Size); - if (Val != II->getValue()) - TP.error("Sign-extended integer value '" + itostr(II->getValue())+ - "' is out of range for type '" + - getEnumName(getTypeNum(0)) + "'!"); + if (Val != II->getValue()) { + // If sign-extended doesn't fit, does it fit as unsigned? + unsigned ValueMask = unsigned(MVT::getIntVTBitMask(VT)); + unsigned UnsignedVal = unsigned(II->getValue()); + + if ((ValueMask & UnsignedVal) != UnsignedVal) { + TP.error("Integer value '" + itostr(II->getValue())+ + "' is out of range for type '" + + getEnumName(getTypeNum(0)) + "'!"); + } + } } } } diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 472edbc..bdf6b64 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -730,8 +730,11 @@ public: const std::string &VarName = N->getName(); std::string Val = VariableMap[VarName]; bool ModifiedVal = false; - assert(!Val.empty() && - "Variable referenced but not defined and not caught earlier!"); + if (Val.empty()) { + cerr << "Variable '" << VarName << " referenced but not defined " + << "and not caught earlier!\n"; + abort(); + } if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') { // Already selected this operand, just return the tmpval. NodeOps.push_back(Val); @@ -858,8 +861,8 @@ public: unsigned ResNo = TmpNo++; assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); emitCode("SDOperand Tmp" + utostr(ResNo) + - " = CurDAG->getTargetConstant(" + itostr(II->getValue()) + - ", " + getEnumName(N->getTypeNum(0)) + ");"); + " = CurDAG->getTargetConstant(0x" + itohexstr(II->getValue()) + + "ULL, " + getEnumName(N->getTypeNum(0)) + ");"); NodeOps.push_back("Tmp" + utostr(ResNo)); return NodeOps; } |