Changes in directory llvm/lib/Target/X86:
X86ISelDAGToDAG.cpp updated: 1.22 -> 1.23 --- Log message: ISEL code for MULHU, MULHS, and UNDEF. --- Diffs of the changes: (+82 -7) X86ISelDAGToDAG.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 82 insertions(+), 7 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.22 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.23 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.22 Thu Jan 5 19:06:31 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Jan 6 14:36:21 2006 @@ -100,6 +100,8 @@ SDOperand &Index, SDOperand &Disp); bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, SDOperand &Index, SDOperand &Disp); + bool TryFoldLoad(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp); inline void getAddressOperands(X86ISelAddressMode &AM, SDOperand &Base, SDOperand &Scale, SDOperand &Index, @@ -294,8 +296,16 @@ return false; } -static bool isRegister0(SDOperand Op) -{ +bool X86DAGToDAGISel::TryFoldLoad(SDOperand N, SDOperand &Base, + SDOperand &Scale, SDOperand &Index, + SDOperand &Disp) { + if (N.getOpcode() == ISD::LOAD && N.hasOneUse() && + CodeGenMap.count(N.getValue(1))) + return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp); + return false; +} + +static bool isRegister0(SDOperand Op) { if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) return (R->getReg() == 0); return false; @@ -354,14 +364,67 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) { SDNode *Node = N.Val; MVT::ValueType NVT = Node->getValueType(0); - unsigned Opc; + unsigned Opc, MOpc; + unsigned Opcode = Node->getOpcode(); - if (Node->getOpcode() >= ISD::BUILTIN_OP_END && - Node->getOpcode() < X86ISD::FIRST_NUMBER) + if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) return N; // Already selected. - switch (Node->getOpcode()) { + switch (Opcode) { default: break; + case ISD::MULHU: + case ISD::MULHS: { + if (Opcode == ISD::MULHU) + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::MUL8r; MOpc = X86::MUL8m; break; + case MVT::i16: Opc = X86::MUL16r; MOpc = X86::MUL16m; break; + case MVT::i32: Opc = X86::MUL32r; MOpc = X86::MUL32m; break; + } + else + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::IMUL8r; MOpc = X86::IMUL8m; break; + case MVT::i16: Opc = X86::IMUL16r; MOpc = X86::IMUL16m; break; + case MVT::i32: Opc = X86::IMUL32r; MOpc = X86::IMUL32m; break; + } + + unsigned LoReg, HiReg; + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: LoReg = X86::AL; HiReg = X86::AH; break; + case MVT::i16: LoReg = X86::AX; HiReg = X86::DX; break; + case MVT::i32: LoReg = X86::EAX; HiReg = X86::EDX; break; + } + + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + + bool foldedLoad = false; + SDOperand Tmp0, Tmp1, Tmp2, Tmp3; + foldedLoad = TryFoldLoad(N1, Tmp0, Tmp1, Tmp2, Tmp3); + SDOperand Chain = foldedLoad ? Select(N1.getOperand(0)) + : CurDAG->getEntryNode(); + + SDOperand InFlag; + Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT), + Select(N0), InFlag); + InFlag = Chain.getValue(1); + + if (foldedLoad) { + Chain = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1, + Tmp2, Tmp3, Chain, InFlag); + InFlag = Chain.getValue(1); + } else { + InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, Select(N1), InFlag); + } + + SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag); + CodeGenMap[N.getValue(0)] = Result; + CodeGenMap[N.getValue(1)] = Result.getValue(1); + CodeGenMap[N.getValue(2)] = Result.getValue(2); + return Result.getValue(N.ResNo); + } case ISD::TRUNCATE: { unsigned Reg; @@ -387,9 +450,21 @@ Result = CurDAG->getCopyFromReg(Chain, Reg, VT, InFlag); - return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); + if (N.Val->hasOneUse()) + return CurDAG->SelectNodeTo(N.Val, Opc, VT, Result); + else + return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); break; } + + case ISD::UNDEF: { + Opc = (NVT == MVT::f64) ? (X86Vector >= SSE2 ? X86::FLD0SD : X86::FpLD0) + : X86::IMPLICIT_DEF; + if (N.Val->hasOneUse()) + return CurDAG->SelectNodeTo(N.Val, Opc, NVT); + else + return CodeGenMap[N] = CurDAG->getTargetNode(Opc, NVT); + } } return SelectCode(N); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits