1b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===-- XCoreISelDAGToDAG.cpp - A dag to dag inst selector for XCore ------===// 2b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 3b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// The LLVM Compiler Infrastructure 4b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 5b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file is distributed under the University of Illinois Open Source 6b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// License. See LICENSE.TXT for details. 7b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 8b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 9b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 10b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file defines an instruction selector for the XCore target. 11b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 12b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 13b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 14b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCore.h" 15b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreTargetMachine.h" 16b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/DerivedTypes.h" 17b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Function.h" 18b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Intrinsics.h" 19b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CallingConv.h" 20b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Constants.h" 219adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/LLVMContext.h" 22b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineFrameInfo.h" 23b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineFunction.h" 24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineInstrBuilder.h" 25b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineRegisterInfo.h" 26b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/SelectionDAG.h" 27b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/SelectionDAGISel.h" 28b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Target/TargetLowering.h" 29b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/Compiler.h" 30b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/Debug.h" 31dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 32dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 33b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm; 34b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 35b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// XCoreDAGToDAGISel - XCore specific code to select XCore machine 36b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// instructions for SelectionDAG operations. 37b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 38b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace { 39b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne class XCoreDAGToDAGISel : public SelectionDAGISel { 40d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const XCoreTargetLowering &Lowering; 41b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne const XCoreSubtarget &Subtarget; 42b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 43b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne public: 44b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne XCoreDAGToDAGISel(XCoreTargetMachine &TM) 4579ce276083ced01256a0eb7d80731e4948ca6e87Dan Gohman : SelectionDAGISel(TM), 46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Lowering(*TM.getTargetLowering()), 47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Subtarget(*TM.getSubtargetImpl()) { } 48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 49eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *Select(SDNode *N); 50bb057453db627a8614091af7eff2de971644255aRichard Osborne SDNode *SelectBRIND(SDNode *N); 51bb057453db627a8614091af7eff2de971644255aRichard Osborne 52b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// getI32Imm - Return a target constant with the specified value, of type 53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// i32. 54b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne inline SDValue getI32Imm(unsigned Imm) { 55825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return CurDAG->getTargetConstant(Imm, MVT::i32); 56b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 57b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 587853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen inline bool immMskBitp(SDNode *inN) const { 597853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen ConstantSDNode *N = cast<ConstantSDNode>(inN); 607853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen uint32_t value = (uint32_t)N->getZExtValue(); 617853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen if (!isMask_32(value)) { 627853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen return false; 637853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen } 647853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen int msksize = 32 - CountLeadingZeros_32(value); 657853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen return (msksize >= 1 && msksize <= 8) || 667853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen msksize == 16 || msksize == 24 || msksize == 32; 677853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen } 687853cd0beaf219630d326358908eb8e1c2baf8dbJakob Stoklund Olesen 69b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Complex Pattern Selectors. 7052a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset); 7152a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset); 7252a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset); 73b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 74b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne virtual const char *getPassName() const { 75b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return "XCore DAG->DAG Pattern Instruction Selection"; 76b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 77b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 78b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Include the pieces autogenerated from the target description. 79b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne #include "XCoreGenDAGISel.inc" 80b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne }; 81b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} // end anonymous namespace 82b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 83b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// createXCoreISelDag - This pass converts a legalized DAG into a 84b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// XCore-specific DAG, ready for instruction scheduling. 85b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 86b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneFunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) { 87b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return new XCoreDAGToDAGISel(TM); 88b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 9052a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattnerbool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, 9152a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner SDValue &Offset) { 92b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne FrameIndexSDNode *FIN = 0; 93f943b1586f9964c88ae6431c09887e7c7917e449Richard Osborne if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) { 94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(0, MVT::i32); 96b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 97b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 98b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Addr.getOpcode() == ISD::ADD) { 99b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne ConstantSDNode *CN = 0; 100b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) 101b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 102cfb1ae87c676b9d2f4b7c86506c99ab314300ec0Richard Osborne && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) { 103cfb1ae87c676b9d2f4b7c86506c99ab314300ec0Richard Osborne // Constant positive word offset from frame index 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 106b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 107b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 108b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 109b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 110b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 111b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 11252a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattnerbool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base, 11352a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner SDValue &Offset) { 114b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) { 115b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Base = Addr.getOperand(0); 116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(0, MVT::i32); 117b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 118b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 119b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Addr.getOpcode() == ISD::ADD) { 120b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne ConstantSDNode *CN = 0; 121b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if ((Addr.getOperand(0).getOpcode() == XCoreISD::DPRelativeWrapper) 122b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 123b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && (CN->getSExtValue() % 4 == 0)) { 124b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Constant word offset from a object in the data region 125b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Base = Addr.getOperand(0).getOperand(0); 126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 127b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 128b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 129b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 130b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 131b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 132b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 13352a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattnerbool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base, 13452a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner SDValue &Offset) { 135b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { 136b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Base = Addr.getOperand(0); 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(0, MVT::i32); 138b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 139b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 140b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Addr.getOpcode() == ISD::ADD) { 141b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne ConstantSDNode *CN = 0; 142b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper) 143b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 144b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && (CN->getSExtValue() % 4 == 0)) { 145b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Constant word offset from a object in the data region 146b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Base = Addr.getOperand(0).getOperand(0); 147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 148b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 149b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 150b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 151b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 152b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 153b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 154eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *XCoreDAGToDAGISel::Select(SDNode *N) { 155f90b2a7742ddeddc448586cc050818a664419e74Dale Johannesen DebugLoc dl = N->getDebugLoc(); 156bb057453db627a8614091af7eff2de971644255aRichard Osborne switch (N->getOpcode()) { 157bb057453db627a8614091af7eff2de971644255aRichard Osborne default: break; 158bb057453db627a8614091af7eff2de971644255aRichard Osborne case ISD::Constant: { 159bb057453db627a8614091af7eff2de971644255aRichard Osborne uint64_t Val = cast<ConstantSDNode>(N)->getZExtValue(); 160bb057453db627a8614091af7eff2de971644255aRichard Osborne if (immMskBitp(N)) { 161bb057453db627a8614091af7eff2de971644255aRichard Osborne // Transformation function: get the size of a mask 162bb057453db627a8614091af7eff2de971644255aRichard Osborne // Look for the first non-zero bit 163bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); 164bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, 165bb057453db627a8614091af7eff2de971644255aRichard Osborne MVT::i32, MskSize); 16659f727e57e1f84519ae71b96010a702acd66d360Richard Osborne } 167bb057453db627a8614091af7eff2de971644255aRichard Osborne else if (!isUInt<16>(Val)) { 168bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue CPIdx = 169bb057453db627a8614091af7eff2de971644255aRichard Osborne CurDAG->getTargetConstantPool(ConstantInt::get( 170bb057453db627a8614091af7eff2de971644255aRichard Osborne Type::getInt32Ty(*CurDAG->getContext()), Val), 171bb057453db627a8614091af7eff2de971644255aRichard Osborne TLI.getPointerTy()); 172a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne SDNode *node = CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, 173a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne MVT::Other, CPIdx, 174a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne CurDAG->getEntryNode()); 175a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 176a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne MemOp[0] = MF->getMachineMemOperand( 177a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne MachinePointerInfo::getConstantPool(), MachineMemOperand::MOLoad, 4, 4); 178a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne cast<MachineSDNode>(node)->setMemRefs(MemOp, MemOp + 1); 179a1d16b53e847a97846ad5df293ae1cfc3091a092Richard Osborne return node; 180b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 181bb057453db627a8614091af7eff2de971644255aRichard Osborne break; 182bb057453db627a8614091af7eff2de971644255aRichard Osborne } 183bb057453db627a8614091af7eff2de971644255aRichard Osborne case XCoreISD::LADD: { 184bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 185bb057453db627a8614091af7eff2de971644255aRichard Osborne N->getOperand(2) }; 186bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, 187bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops, 3); 188bb057453db627a8614091af7eff2de971644255aRichard Osborne } 189bb057453db627a8614091af7eff2de971644255aRichard Osborne case XCoreISD::LSUB: { 190bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 191bb057453db627a8614091af7eff2de971644255aRichard Osborne N->getOperand(2) }; 192bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, 193bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops, 3); 194bb057453db627a8614091af7eff2de971644255aRichard Osborne } 195bb057453db627a8614091af7eff2de971644255aRichard Osborne case XCoreISD::MACCU: { 196bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 197bb057453db627a8614091af7eff2de971644255aRichard Osborne N->getOperand(2), N->getOperand(3) }; 198bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32, 199bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops, 4); 200bb057453db627a8614091af7eff2de971644255aRichard Osborne } 201bb057453db627a8614091af7eff2de971644255aRichard Osborne case XCoreISD::MACCS: { 202bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 203bb057453db627a8614091af7eff2de971644255aRichard Osborne N->getOperand(2), N->getOperand(3) }; 204bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, 205bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops, 4); 206bb057453db627a8614091af7eff2de971644255aRichard Osborne } 207bb057453db627a8614091af7eff2de971644255aRichard Osborne case XCoreISD::LMUL: { 208bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 209bb057453db627a8614091af7eff2de971644255aRichard Osborne N->getOperand(2), N->getOperand(3) }; 210bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, 211bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops, 4); 212bb057453db627a8614091af7eff2de971644255aRichard Osborne } 2139497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne case ISD::INTRINSIC_WO_CHAIN: { 2149497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 2159497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne switch (IntNo) { 2169497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne case Intrinsic::xcore_crc8: 2179497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne SDValue Ops[] = { N->getOperand(1), N->getOperand(2), N->getOperand(3) }; 2189497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne return CurDAG->getMachineNode(XCore::CRC8_l4r, dl, MVT::i32, MVT::i32, 2199497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne Ops, 3); 2209497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne } 2219497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne break; 2229497466190a46ba06bf856302b1c81f1c4b5c951Richard Osborne } 223bb057453db627a8614091af7eff2de971644255aRichard Osborne case ISD::BRIND: 224bb057453db627a8614091af7eff2de971644255aRichard Osborne if (SDNode *ResNode = SelectBRIND(N)) 225bb057453db627a8614091af7eff2de971644255aRichard Osborne return ResNode; 226bb057453db627a8614091af7eff2de971644255aRichard Osborne break; 227bb057453db627a8614091af7eff2de971644255aRichard Osborne // Other cases are autogenerated. 228b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 229eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectCode(N); 230b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 231bb057453db627a8614091af7eff2de971644255aRichard Osborne 232bb057453db627a8614091af7eff2de971644255aRichard Osborne/// Given a chain return a new chain where any appearance of Old is replaced 233bb057453db627a8614091af7eff2de971644255aRichard Osborne/// by New. There must be at most one instruction between Old and Chain and 234bb057453db627a8614091af7eff2de971644255aRichard Osborne/// this instruction must be a TokenFactor. Returns an empty SDValue if 235bb057453db627a8614091af7eff2de971644255aRichard Osborne/// these conditions don't hold. 236bb057453db627a8614091af7eff2de971644255aRichard Osbornestatic SDValue 237bb057453db627a8614091af7eff2de971644255aRichard OsbornereplaceInChain(SelectionDAG *CurDAG, SDValue Chain, SDValue Old, SDValue New) 238bb057453db627a8614091af7eff2de971644255aRichard Osborne{ 239bb057453db627a8614091af7eff2de971644255aRichard Osborne if (Chain == Old) 240bb057453db627a8614091af7eff2de971644255aRichard Osborne return New; 241bb057453db627a8614091af7eff2de971644255aRichard Osborne if (Chain->getOpcode() != ISD::TokenFactor) 242bb057453db627a8614091af7eff2de971644255aRichard Osborne return SDValue(); 243bb057453db627a8614091af7eff2de971644255aRichard Osborne SmallVector<SDValue, 8> Ops; 244bb057453db627a8614091af7eff2de971644255aRichard Osborne bool found = false; 245bb057453db627a8614091af7eff2de971644255aRichard Osborne for (unsigned i = 0, e = Chain->getNumOperands(); i != e; ++i) { 246bb057453db627a8614091af7eff2de971644255aRichard Osborne if (Chain->getOperand(i) == Old) { 247bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops.push_back(New); 248bb057453db627a8614091af7eff2de971644255aRichard Osborne found = true; 249bb057453db627a8614091af7eff2de971644255aRichard Osborne } else { 250bb057453db627a8614091af7eff2de971644255aRichard Osborne Ops.push_back(Chain->getOperand(i)); 251bb057453db627a8614091af7eff2de971644255aRichard Osborne } 252bb057453db627a8614091af7eff2de971644255aRichard Osborne } 253bb057453db627a8614091af7eff2de971644255aRichard Osborne if (!found) 254bb057453db627a8614091af7eff2de971644255aRichard Osborne return SDValue(); 255bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->getNode(ISD::TokenFactor, Chain->getDebugLoc(), MVT::Other, 256bb057453db627a8614091af7eff2de971644255aRichard Osborne &Ops[0], Ops.size()); 257bb057453db627a8614091af7eff2de971644255aRichard Osborne} 258bb057453db627a8614091af7eff2de971644255aRichard Osborne 259bb057453db627a8614091af7eff2de971644255aRichard OsborneSDNode *XCoreDAGToDAGISel::SelectBRIND(SDNode *N) { 260bb057453db627a8614091af7eff2de971644255aRichard Osborne DebugLoc dl = N->getDebugLoc(); 261bb057453db627a8614091af7eff2de971644255aRichard Osborne // (brind (int_xcore_checkevent (addr))) 262bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Chain = N->getOperand(0); 263bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Addr = N->getOperand(1); 264bb057453db627a8614091af7eff2de971644255aRichard Osborne if (Addr->getOpcode() != ISD::INTRINSIC_W_CHAIN) 265bb057453db627a8614091af7eff2de971644255aRichard Osborne return 0; 266bb057453db627a8614091af7eff2de971644255aRichard Osborne unsigned IntNo = cast<ConstantSDNode>(Addr->getOperand(1))->getZExtValue(); 267bb057453db627a8614091af7eff2de971644255aRichard Osborne if (IntNo != Intrinsic::xcore_checkevent) 268bb057453db627a8614091af7eff2de971644255aRichard Osborne return 0; 269bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue nextAddr = Addr->getOperand(2); 270bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue CheckEventChainOut(Addr.getNode(), 1); 271bb057453db627a8614091af7eff2de971644255aRichard Osborne if (!CheckEventChainOut.use_empty()) { 272bb057453db627a8614091af7eff2de971644255aRichard Osborne // If the chain out of the checkevent intrinsic is an operand of the 273bb057453db627a8614091af7eff2de971644255aRichard Osborne // indirect branch or used in a TokenFactor which is the operand of the 274bb057453db627a8614091af7eff2de971644255aRichard Osborne // indirect branch then build a new chain which uses the chain coming into 275bb057453db627a8614091af7eff2de971644255aRichard Osborne // the checkevent intrinsic instead. 276bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue CheckEventChainIn = Addr->getOperand(0); 277bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut, 278bb057453db627a8614091af7eff2de971644255aRichard Osborne CheckEventChainIn); 279bb057453db627a8614091af7eff2de971644255aRichard Osborne if (!NewChain.getNode()) 280bb057453db627a8614091af7eff2de971644255aRichard Osborne return 0; 281bb057453db627a8614091af7eff2de971644255aRichard Osborne Chain = NewChain; 282bb057453db627a8614091af7eff2de971644255aRichard Osborne } 283bb057453db627a8614091af7eff2de971644255aRichard Osborne // Enable events on the thread using setsr 1 and then disable them immediately 284bb057453db627a8614091af7eff2de971644255aRichard Osborne // after with clrsr 1. If any resources owned by the thread are ready an event 285bb057453db627a8614091af7eff2de971644255aRichard Osborne // will be taken. If no resource is ready we branch to the address which was 286bb057453db627a8614091af7eff2de971644255aRichard Osborne // the operand to the checkevent intrinsic. 287bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue constOne = getI32Imm(1); 288bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue Glue = 289bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue, 290bb057453db627a8614091af7eff2de971644255aRichard Osborne constOne, Chain), 0); 291bb057453db627a8614091af7eff2de971644255aRichard Osborne Glue = 292bb057453db627a8614091af7eff2de971644255aRichard Osborne SDValue(CurDAG->getMachineNode(XCore::CLRSR_branch_u6, dl, MVT::Glue, 293bb057453db627a8614091af7eff2de971644255aRichard Osborne constOne, Glue), 0); 294bb057453db627a8614091af7eff2de971644255aRichard Osborne if (nextAddr->getOpcode() == XCoreISD::PCRelativeWrapper && 295bb057453db627a8614091af7eff2de971644255aRichard Osborne nextAddr->getOperand(0)->getOpcode() == ISD::TargetBlockAddress) { 296bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->SelectNodeTo(N, XCore::BRFU_lu6, MVT::Other, 297bb057453db627a8614091af7eff2de971644255aRichard Osborne nextAddr->getOperand(0), Glue); 298bb057453db627a8614091af7eff2de971644255aRichard Osborne } 299bb057453db627a8614091af7eff2de971644255aRichard Osborne return CurDAG->SelectNodeTo(N, XCore::BAU_1r, MVT::Other, nextAddr, Glue); 300bb057453db627a8614091af7eff2de971644255aRichard Osborne} 301