aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorScott Michel <scottm@aero.org>2008-02-15 23:05:48 +0000
committerScott Michel <scottm@aero.org>2008-02-15 23:05:48 +0000
commit0123b7dcfa9be97588926407163deb8d603487ce (patch)
tree16f995f13d3b186a0d2c18e0893cfed8258413b9 /utils
parent9f8ec25805595011bf33af3cae5d25795cb32976 (diff)
downloadexternal_llvm-0123b7dcfa9be97588926407163deb8d603487ce.zip
external_llvm-0123b7dcfa9be97588926407163deb8d603487ce.tar.gz
external_llvm-0123b7dcfa9be97588926407163deb8d603487ce.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.cpp15
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp11
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;
}