default: llvm_unreachable("Invalid integer condition!");
case ISD::SETEQ:
TCC = MSP430CC::COND_E; // aka COND_Z
- // Minor optimization: if RHS is a constant, swap operands, then the
+ // Minor optimization: if LHS is a constant, swap operands, then the
// constant can be folded into comparison.
- if (RHS.getOpcode() == ISD::Constant)
+ if (LHS.getOpcode() == ISD::Constant)
std::swap(LHS, RHS);
break;
case ISD::SETNE:
TCC = MSP430CC::COND_NE; // aka COND_NZ
- // Minor optimization: if RHS is a constant, swap operands, then the
+ // Minor optimization: if LHS is a constant, swap operands, then the
// constant can be folded into comparison.
- if (RHS.getOpcode() == ISD::Constant)
+ if (LHS.getOpcode() == ISD::Constant)
std::swap(LHS, RHS);
break;
case ISD::SETULE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETUGE:
+ // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_LO;
+ break;
+ }
TCC = MSP430CC::COND_HS; // aka COND_C
break;
case ISD::SETUGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETULT:
+ // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_HS;
+ break;
+ }
TCC = MSP430CC::COND_LO; // aka COND_NC
break;
case ISD::SETLE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETGE:
+ // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_L;
+ break;
+ }
TCC = MSP430CC::COND_GE;
break;
case ISD::SETGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETLT:
+ // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_GE;
+ break;
+ }
TCC = MSP430CC::COND_L;
break;
}
// If we are doing an AND and testing against zero, then the CMP
// will not be generated. The AND (or BIT) will generate the condition codes,
// but they are different from CMP.
+ // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
+ // lowering & isel wouldn't diverge.
bool andCC = false;
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
if (RHSC->isNullValue() && LHS.hasOneUse() &&
case MSP430CC::COND_HS:
// Res = SRW & 1, no processing is required
break;
- case MSP430CC::COND_LO:
+ case MSP430CC::COND_LO:
// Res = ~(SRW & 1)
Invert = true;
break;
- case MSP430CC::COND_NE:
+ case MSP430CC::COND_NE:
if (andCC) {
// C = ~Z, thus Res = SRW & 1, no processing is required
} else {
Shift = true;
}
break;
- case MSP430CC::COND_E:
+ case MSP430CC::COND_E:
if (andCC) {
// C = ~Z, thus Res = ~(SRW & 1)
} else {
SDValue One = DAG.getConstant(1, VT);
if (Convert) {
SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
- MVT::i16, Flag);
+ MVT::i16, Flag);
if (Shift)
// FIXME: somewhere this is turned into a SRL, lower it MSP specific?
SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
}
}
+bool MSP430TargetLowering::isTruncateFree(const Type *Ty1,
+ const Type *Ty2) const {
+ if (!Ty1->isInteger() || !Ty2->isInteger())
+ return false;
+
+ return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
+}
+
+bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
+ if (!VT1.isInteger() || !VT2.isInteger())
+ return false;
+
+ return (VT1.getSizeInBits() > VT2.getSizeInBits());
+}
+
+bool MSP430TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && Ty1->isInteger(8) && Ty2->isInteger(16);
+}
+
+bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
+}
+
//===----------------------------------------------------------------------===//
// Other Lowering Code
//===----------------------------------------------------------------------===//
// BB:
// cmp 0, N
// je RemBB
- BuildMI(BB, dl, TII.get(MSP430::CMP8ir))
- .addImm(0).addReg(ShiftAmtSrcReg);
+ BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
+ .addReg(ShiftAmtSrcReg).addImm(0);
BuildMI(BB, dl, TII.get(MSP430::JCC))
.addMBB(RemBB)
.addImm(MSP430CC::COND_E);
.addReg(SrcReg).addMBB(BB)
.addReg(ShiftReg2).addMBB(LoopBB);
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
return RemBB;
}