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