getI8Imm(ShlVal, dl));
return;
}
- case X86ISD::UMUL8:
- case X86ISD::SMUL8: {
- SDValue N0 = Node->getOperand(0);
- SDValue N1 = Node->getOperand(1);
-
- unsigned Opc = (Opcode == X86ISD::SMUL8 ? X86::IMUL8r : X86::MUL8r);
-
- SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::AL,
- N0, SDValue()).getValue(1);
-
- SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32);
- SDValue Ops[] = {N1, InFlag};
- SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
-
- ReplaceNode(Node, CNode);
- return;
- }
-
+ case X86ISD::SMUL:
+ // i16/i32/i64 are handled with isel patterns.
+ if (NVT != MVT::i8)
+ break;
+ LLVM_FALLTHROUGH;
case X86ISD::UMUL: {
SDValue N0 = Node->getOperand(0);
SDValue N1 = Node->getOperand(1);
unsigned LoReg, Opc;
switch (NVT.SimpleTy) {
default: llvm_unreachable("Unsupported VT!");
- // MVT::i8 is handled by X86ISD::UMUL8.
+ case MVT::i8:
+ LoReg = X86::AL;
+ Opc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
+ break;
case MVT::i16: LoReg = X86::AX; Opc = X86::MUL16r; break;
case MVT::i32: LoReg = X86::EAX; Opc = X86::MUL32r; break;
case MVT::i64: LoReg = X86::RAX; Opc = X86::MUL64r; break;
SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
N0, SDValue()).getValue(1);
- SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
+ // i16/i32/i64 use an instruction that produces a low and high result even
+ // though only the low result is used.
+ SDVTList VTs;
+ if (NVT == MVT::i8)
+ VTs = CurDAG->getVTList(NVT, MVT::i32);
+ else
+ VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
+
SDValue Ops[] = {N1, InFlag};
SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
-
- ReplaceNode(Node, CNode);
+ ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
+ CurDAG->RemoveDeadNode(Node);
return;
}
Cond = X86::COND_B;
break;
case ISD::SMULO:
- BaseOp = Op.getValueType() == MVT::i8 ? X86ISD::SMUL8 : X86ISD::SMUL;
+ BaseOp = X86ISD::SMUL;
Cond = X86::COND_O;
break;
- case ISD::UMULO: { // i64, i8 = umulo lhs, rhs --> i64, i64, i32 umul lhs,rhs
- if (Op.getValueType() == MVT::i8) {
- BaseOp = X86ISD::UMUL8;
- Cond = X86::COND_O;
- break;
- }
- SDVTList VTs = DAG.getVTList(Op.getValueType(), Op.getValueType(),
- MVT::i32);
- Value = DAG.getNode(X86ISD::UMUL, DL, VTs, LHS, RHS);
- Overflow = Value.getValue(2);
+ case ISD::UMULO:
+ BaseOp = X86ISD::UMUL;
Cond = X86::COND_O;
break;
}
- }
if (BaseOp) {
// Also sets EFLAGS.
return true;
if (Op.getResNo() == 1 &&
(Opc == X86ISD::ADD || Opc == X86ISD::SUB || Opc == X86ISD::ADC ||
- Opc == X86ISD::SBB || Opc == X86ISD::SMUL ||
+ Opc == X86ISD::SBB || Opc == X86ISD::SMUL || Opc == X86ISD::UMUL ||
Opc == X86ISD::INC || Opc == X86ISD::DEC || Opc == X86ISD::OR ||
Opc == X86ISD::XOR || Opc == X86ISD::AND))
return true;
- if (Op.getResNo() == 2 && Opc == X86ISD::UMUL)
- return true;
-
return false;
}
case X86ISD::SBB: return "X86ISD::SBB";
case X86ISD::SMUL: return "X86ISD::SMUL";
case X86ISD::UMUL: return "X86ISD::UMUL";
- case X86ISD::SMUL8: return "X86ISD::SMUL8";
- case X86ISD::UMUL8: return "X86ISD::UMUL8";
case X86ISD::INC: return "X86ISD::INC";
case X86ISD::DEC: return "X86ISD::DEC";
case X86ISD::OR: return "X86ISD::OR";
CMPM_RND,
// Arithmetic operations with FLAGS results.
- ADD, SUB, ADC, SBB, SMUL,
+ ADD, SUB, ADC, SBB, SMUL, UMUL,
INC, DEC, OR, XOR, AND,
// Bit field extract.
// Zero High Bits Starting with Specified Bit Position.
BZHI,
- // LOW, HI, FLAGS = umul LHS, RHS.
- UMUL,
-
- // 8-bit SMUL/UMUL - AX, FLAGS = smul8/umul8 AL, RHS.
- SMUL8, UMUL8,
-
// X86-specific multiply by immediate.
MUL_IMM,