-/// Emit nodes that will be selected as "test Op0,Op0", or something
-/// equivalent.
-SDValue X86TargetLowering::EmitTest(SDValue Op, SelectionDAG &DAG) {
- DebugLoc dl = Op.getDebugLoc();
-
- if (Op.getResNo() == 0) {
- unsigned Opcode = 0;
- switch (Op.getNode()->getOpcode()) {
- case ISD::ADD:
- // Due to an isel shortcoming, be conservative if this add is likely to
- // be selected as part of a load-modify-store instruction. When the root
- // node in a match is a store, isel doesn't know how to remap non-chain
- // non-flag uses of other nodes in the match, such as the ADD in this
- // case. This leads to the ADD being left around and reselected, with
- // the result being two adds in the output.
- for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
- UE = Op.getNode()->use_end(); UI != UE; ++UI)
- if (UI->getOpcode() == ISD::STORE)
- goto default_case;
- // An add of one will be selected as an INC.
- if (ConstantSDNode *C =
- dyn_cast<ConstantSDNode>(Op.getNode()->getOperand(1)))
- if (C->getAPIntValue() == 1) {
- Opcode = X86ISD::INC;
- break;
- }
- // Otherwise use a regular EFLAGS-setting add.
- Opcode = X86ISD::ADD;
- break;
- case ISD::SUB:
- // Due to the ISEL shortcoming noted above, be conservative if this sub is
- // likely to be selected as part of a load-modify-store instruction.
- for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
- UE = Op.getNode()->use_end(); UI != UE; ++UI)
- if (UI->getOpcode() == ISD::STORE)
- goto default_case;
- // A subtract of one will be selected as a DEC.
- if (ConstantSDNode *C =
- dyn_cast<ConstantSDNode>(Op.getNode()->getOperand(1)))
- if (C->getAPIntValue() == 1) {
- Opcode = X86ISD::DEC;
- break;
- }
- // Otherwise use a regular EFLAGS-setting sub.
- Opcode = X86ISD::SUB;
- break;
- case X86ISD::ADD:
- case X86ISD::SUB:
- case X86ISD::INC:
- case X86ISD::DEC:
- return SDValue(Op.getNode(), 1);
- default:
- default_case:
- break;
- }
- if (Opcode != 0) {
- const MVT *VTs = DAG.getNodeValueTypes(Op.getValueType(), MVT::i32);
- SmallVector<SDValue, 4> Ops;
- for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i)
- Ops.push_back(Op.getOperand(i));
- SDValue New = DAG.getNode(Opcode, dl, VTs, 2, &Ops[0], Ops.size());
- DAG.ReplaceAllUsesWith(Op, New);
- return SDValue(New.getNode(), 1);
- }
- }
-
- return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
- DAG.getConstant(0, Op.getValueType()));
-}
-
-/// Emit nodes that will be selected as "cmp Op0,Op1", or something
-/// equivalent.
-SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, SelectionDAG &DAG) {
- if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op1))
- if (C->getAPIntValue() == 0)
- return EmitTest(Op0, DAG);
-
- DebugLoc dl = Op0.getDebugLoc();
- return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1);
-}
-