mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
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
This commit is contained in:
parent
9f8ec25805
commit
0123b7dcfa
@ -85,6 +85,10 @@ static inline std::string itostr(int64_t X) {
|
||||
return utostr(static_cast<uint64_t>(X));
|
||||
}
|
||||
|
||||
static inline std::string itohexstr(int64_t X) {
|
||||
return utohexstr(static_cast<uint64_t>(X));
|
||||
}
|
||||
|
||||
static inline std::string ftostr(double V) {
|
||||
char Buffer[200];
|
||||
sprintf(Buffer, "%20.6e", V);
|
||||
|
@ -3852,6 +3852,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
case Expand: assert(0 && "Shouldn't need to expand other operators here!");
|
||||
case Legal:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||
if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
|
||||
TargetLowering::Custom) {
|
||||
Tmp2 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp2.Val) {
|
||||
Tmp1 = Tmp2;
|
||||
}
|
||||
}
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1);
|
||||
break;
|
||||
case Promote:
|
||||
|
@ -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)) + "'!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user