1//===-- AVRISelDAGToDAG.cpp - A dag to dag inst selector for AVR ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines an instruction selector for the AVR target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "AVR.h"
14#include "AVRTargetMachine.h"
15#include "MCTargetDesc/AVRMCTargetDesc.h"
16
17#include "llvm/CodeGen/MachineRegisterInfo.h"
18#include "llvm/CodeGen/SelectionDAGISel.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/raw_ostream.h"
21
22#define DEBUG_TYPE "avr-isel"
23#define PASS_NAME "AVR DAG->DAG Instruction Selection"
24
25using namespace llvm;
26
27namespace {
28
29/// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
30class AVRDAGToDAGISel : public SelectionDAGISel {
31public:
32  static char ID;
33
34  AVRDAGToDAGISel() = delete;
35
36  AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOptLevel OptLevel)
37      : SelectionDAGISel(ID, TM, OptLevel), Subtarget(nullptr) {}
38
39  bool runOnMachineFunction(MachineFunction &MF) override;
40
41  bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp);
42
43  bool selectIndexedLoad(SDNode *N);
44  unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT, int Bank);
45
46  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
47                                    InlineAsm::ConstraintCode ConstraintCode,
48                                    std::vector<SDValue> &OutOps) override;
49
50// Include the pieces autogenerated from the target description.
51#include "AVRGenDAGISel.inc"
52
53private:
54  void Select(SDNode *N) override;
55  bool trySelect(SDNode *N);
56
57  template <unsigned NodeType> bool select(SDNode *N);
58  bool selectMultiplication(SDNode *N);
59
60  const AVRSubtarget *Subtarget;
61};
62
63} // namespace
64
65char AVRDAGToDAGISel::ID = 0;
66
67INITIALIZE_PASS(AVRDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false)
68
69bool AVRDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
70  Subtarget = &MF.getSubtarget<AVRSubtarget>();
71  return SelectionDAGISel::runOnMachineFunction(MF);
72}
73
74bool AVRDAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
75                                 SDValue &Disp) {
76  SDLoc dl(Op);
77  auto DL = CurDAG->getDataLayout();
78  MVT PtrVT = getTargetLowering()->getPointerTy(DL);
79
80  // if the address is a frame index get the TargetFrameIndex.
81  if (const FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
82    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), PtrVT);
83    Disp = CurDAG->getTargetConstant(0, dl, MVT::i8);
84
85    return true;
86  }
87
88  // Match simple Reg + uimm6 operands.
89  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
90      !CurDAG->isBaseWithConstantOffset(N)) {
91    return false;
92  }
93
94  if (const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
95    int RHSC = (int)RHS->getZExtValue();
96
97    // Convert negative offsets into positives ones.
98    if (N.getOpcode() == ISD::SUB) {
99      RHSC = -RHSC;
100    }
101
102    // <#Frame index + const>
103    // Allow folding offsets bigger than 63 so the frame pointer can be used
104    // directly instead of copying it around by adjusting and restoring it for
105    // each access.
106    if (N.getOperand(0).getOpcode() == ISD::FrameIndex) {
107      int FI = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
108
109      Base = CurDAG->getTargetFrameIndex(FI, PtrVT);
110      Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i16);
111
112      return true;
113    }
114
115    // The value type of the memory instruction determines what is the maximum
116    // offset allowed.
117    MVT VT = cast<MemSDNode>(Op)->getMemoryVT().getSimpleVT();
118
119    // We only accept offsets that fit in 6 bits (unsigned).
120    if (isUInt<6>(RHSC) && (VT == MVT::i8 || VT == MVT::i16)) {
121      Base = N.getOperand(0);
122      Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i8);
123
124      return true;
125    }
126  }
127
128  return false;
129}
130
131bool AVRDAGToDAGISel::selectIndexedLoad(SDNode *N) {
132  const LoadSDNode *LD = cast<LoadSDNode>(N);
133  ISD::MemIndexedMode AM = LD->getAddressingMode();
134  MVT VT = LD->getMemoryVT().getSimpleVT();
135  auto PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout());
136
137  // We only care if this load uses a POSTINC or PREDEC mode.
138  if ((LD->getExtensionType() != ISD::NON_EXTLOAD) ||
139      (AM != ISD::POST_INC && AM != ISD::PRE_DEC)) {
140
141    return false;
142  }
143
144  unsigned Opcode = 0;
145  bool isPre = (AM == ISD::PRE_DEC);
146  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
147
148  switch (VT.SimpleTy) {
149  case MVT::i8: {
150    if ((!isPre && Offs != 1) || (isPre && Offs != -1)) {
151      return false;
152    }
153
154    Opcode = (isPre) ? AVR::LDRdPtrPd : AVR::LDRdPtrPi;
155    break;
156  }
157  case MVT::i16: {
158    if ((!isPre && Offs != 2) || (isPre && Offs != -2)) {
159      return false;
160    }
161
162    Opcode = (isPre) ? AVR::LDWRdPtrPd : AVR::LDWRdPtrPi;
163    break;
164  }
165  default:
166    return false;
167  }
168
169  SDNode *ResNode =
170      CurDAG->getMachineNode(Opcode, SDLoc(N), VT, PtrVT, MVT::Other,
171                             LD->getBasePtr(), LD->getChain());
172  ReplaceUses(N, ResNode);
173  CurDAG->RemoveDeadNode(N);
174
175  return true;
176}
177
178unsigned AVRDAGToDAGISel::selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT,
179                                                   int Bank) {
180  // Progmem indexed loads only work in POSTINC mode.
181  if (LD->getExtensionType() != ISD::NON_EXTLOAD ||
182      LD->getAddressingMode() != ISD::POST_INC)
183    return 0;
184
185  // Feature ELPM is needed for loading from extended program memory.
186  assert((Bank == 0 || Subtarget->hasELPM()) &&
187         "cannot load from extended program memory on this mcu");
188
189  unsigned Opcode = 0;
190  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
191
192  if (VT.SimpleTy == MVT::i8 && Offs == 1 && Bank == 0)
193    Opcode = AVR::LPMRdZPi;
194
195  // TODO: Implements the expansion of the following pseudo instructions.
196  // LPMWRdZPi:  type == MVT::i16, offset == 2, Bank == 0.
197  // ELPMBRdZPi: type == MVT::i8,  offset == 1, Bank >  0.
198  // ELPMWRdZPi: type == MVT::i16, offset == 2, Bank >  0.
199
200  return Opcode;
201}
202
203bool AVRDAGToDAGISel::SelectInlineAsmMemoryOperand(
204    const SDValue &Op, InlineAsm::ConstraintCode ConstraintCode,
205    std::vector<SDValue> &OutOps) {
206  assert((ConstraintCode == InlineAsm::ConstraintCode::m ||
207          ConstraintCode == InlineAsm::ConstraintCode::Q) &&
208         "Unexpected asm memory constraint");
209
210  MachineRegisterInfo &RI = MF->getRegInfo();
211  const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
212  const TargetLowering &TL = *STI.getTargetLowering();
213  SDLoc dl(Op);
214  auto DL = CurDAG->getDataLayout();
215
216  const RegisterSDNode *RegNode = dyn_cast<RegisterSDNode>(Op);
217
218  // If address operand is of PTRDISPREGS class, all is OK, then.
219  if (RegNode &&
220      RI.getRegClass(RegNode->getReg()) == &AVR::PTRDISPREGSRegClass) {
221    OutOps.push_back(Op);
222    return false;
223  }
224
225  if (Op->getOpcode() == ISD::FrameIndex) {
226    SDValue Base, Disp;
227
228    if (SelectAddr(Op.getNode(), Op, Base, Disp)) {
229      OutOps.push_back(Base);
230      OutOps.push_back(Disp);
231
232      return false;
233    }
234
235    return true;
236  }
237
238  // If Op is add 'register, immediate' and
239  // register is either virtual register or register of PTRDISPREGSRegClass
240  if (Op->getOpcode() == ISD::ADD || Op->getOpcode() == ISD::SUB) {
241    SDValue CopyFromRegOp = Op->getOperand(0);
242    SDValue ImmOp = Op->getOperand(1);
243    ConstantSDNode *ImmNode = dyn_cast<ConstantSDNode>(ImmOp);
244
245    unsigned Reg;
246    bool CanHandleRegImmOpt = ImmNode && ImmNode->getAPIntValue().ult(64);
247
248    if (CopyFromRegOp->getOpcode() == ISD::CopyFromReg) {
249      RegisterSDNode *RegNode =
250          cast<RegisterSDNode>(CopyFromRegOp->getOperand(1));
251      Reg = RegNode->getReg();
252      CanHandleRegImmOpt &= (Register::isVirtualRegister(Reg) ||
253                             AVR::PTRDISPREGSRegClass.contains(Reg));
254    } else {
255      CanHandleRegImmOpt = false;
256    }
257
258    // If we detect proper case - correct virtual register class
259    // if needed and go to another inlineasm operand.
260    if (CanHandleRegImmOpt) {
261      SDValue Base, Disp;
262
263      if (RI.getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) {
264        SDLoc dl(CopyFromRegOp);
265
266        Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
267
268        SDValue CopyToReg =
269            CurDAG->getCopyToReg(CopyFromRegOp, dl, VReg, CopyFromRegOp);
270
271        SDValue NewCopyFromRegOp =
272            CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
273
274        Base = NewCopyFromRegOp;
275      } else {
276        Base = CopyFromRegOp;
277      }
278
279      if (ImmNode->getValueType(0) != MVT::i8) {
280        Disp = CurDAG->getTargetConstant(ImmNode->getZExtValue(), dl, MVT::i8);
281      } else {
282        Disp = ImmOp;
283      }
284
285      OutOps.push_back(Base);
286      OutOps.push_back(Disp);
287
288      return false;
289    }
290  }
291
292  // More generic case.
293  // Create chain that puts Op into pointer register
294  // and return that register.
295  Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
296
297  SDValue CopyToReg = CurDAG->getCopyToReg(Op, dl, VReg, Op);
298  SDValue CopyFromReg =
299      CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
300
301  OutOps.push_back(CopyFromReg);
302
303  return false;
304}
305
306template <> bool AVRDAGToDAGISel::select<ISD::FrameIndex>(SDNode *N) {
307  auto DL = CurDAG->getDataLayout();
308
309  // Convert the frameindex into a temp instruction that will hold the
310  // effective address of the final stack slot.
311  int FI = cast<FrameIndexSDNode>(N)->getIndex();
312  SDValue TFI =
313      CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy(DL));
314
315  CurDAG->SelectNodeTo(N, AVR::FRMIDX, getTargetLowering()->getPointerTy(DL),
316                       TFI, CurDAG->getTargetConstant(0, SDLoc(N), MVT::i16));
317  return true;
318}
319
320template <> bool AVRDAGToDAGISel::select<ISD::STORE>(SDNode *N) {
321  // Use the STD{W}SPQRr pseudo instruction when passing arguments through
322  // the stack on function calls for further expansion during the PEI phase.
323  const StoreSDNode *ST = cast<StoreSDNode>(N);
324  SDValue BasePtr = ST->getBasePtr();
325
326  // Early exit when the base pointer is a frame index node or a constant.
327  if (isa<FrameIndexSDNode>(BasePtr) || isa<ConstantSDNode>(BasePtr) ||
328      BasePtr.isUndef()) {
329    return false;
330  }
331
332  const RegisterSDNode *RN = dyn_cast<RegisterSDNode>(BasePtr.getOperand(0));
333  // Only stores where SP is the base pointer are valid.
334  if (!RN || (RN->getReg() != AVR::SP)) {
335    return false;
336  }
337
338  int CST = (int)BasePtr.getConstantOperandVal(1);
339  SDValue Chain = ST->getChain();
340  EVT VT = ST->getValue().getValueType();
341  SDLoc DL(N);
342  SDValue Offset = CurDAG->getTargetConstant(CST, DL, MVT::i16);
343  SDValue Ops[] = {BasePtr.getOperand(0), Offset, ST->getValue(), Chain};
344  unsigned Opc = (VT == MVT::i16) ? AVR::STDWSPQRr : AVR::STDSPQRr;
345
346  SDNode *ResNode = CurDAG->getMachineNode(Opc, DL, MVT::Other, Ops);
347
348  // Transfer memory operands.
349  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {ST->getMemOperand()});
350
351  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
352  CurDAG->RemoveDeadNode(N);
353
354  return true;
355}
356
357template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
358  const LoadSDNode *LD = cast<LoadSDNode>(N);
359  if (!AVR::isProgramMemoryAccess(LD)) {
360    // Check if the opcode can be converted into an indexed load.
361    return selectIndexedLoad(N);
362  }
363
364  if (!Subtarget->hasLPM())
365    report_fatal_error("cannot load from program memory on this mcu");
366
367  int ProgMemBank = AVR::getProgramMemoryBank(LD);
368  if (ProgMemBank < 0 || ProgMemBank > 5)
369    report_fatal_error("unexpected program memory bank");
370  if (ProgMemBank > 0 && !Subtarget->hasELPM())
371    report_fatal_error("unexpected program memory bank");
372
373  // This is a flash memory load, move the pointer into R31R30 and emit
374  // the lpm instruction.
375  MVT VT = LD->getMemoryVT().getSimpleVT();
376  SDValue Chain = LD->getChain();
377  SDValue Ptr = LD->getBasePtr();
378  SDNode *ResNode;
379  SDLoc DL(N);
380
381  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr, SDValue());
382  Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30, MVT::i16,
383                               Chain.getValue(1));
384
385  // Check if the opcode can be converted into an indexed load.
386  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT, ProgMemBank)) {
387    // It is legal to fold the load into an indexed load.
388    if (ProgMemBank == 0) {
389      ResNode =
390          CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr);
391    } else {
392      // Do not combine the LDI instruction into the ELPM pseudo instruction,
393      // since it may be reused by other ELPM pseudo instructions.
394      SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
395      auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
396      ResNode = CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other,
397                                       Ptr, SDValue(NP, 0));
398    }
399  } else {
400    // Selecting an indexed load is not legal, fallback to a normal load.
401    switch (VT.SimpleTy) {
402    case MVT::i8:
403      if (ProgMemBank == 0) {
404        unsigned Opc = Subtarget->hasLPMX() ? AVR::LPMRdZ : AVR::LPMBRdZ;
405        ResNode =
406            CurDAG->getMachineNode(Opc, DL, MVT::i8, MVT::Other, Ptr);
407      } else {
408        // Do not combine the LDI instruction into the ELPM pseudo instruction,
409        // since it may be reused by other ELPM pseudo instructions.
410        SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
411        auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
412        ResNode = CurDAG->getMachineNode(AVR::ELPMBRdZ, DL, MVT::i8, MVT::Other,
413                                         Ptr, SDValue(NP, 0));
414      }
415      break;
416    case MVT::i16:
417      if (ProgMemBank == 0) {
418        ResNode =
419            CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16, MVT::Other, Ptr);
420      } else {
421        // Do not combine the LDI instruction into the ELPM pseudo instruction,
422        // since LDI requires the destination register in range R16~R31.
423        SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
424        auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
425        ResNode = CurDAG->getMachineNode(AVR::ELPMWRdZ, DL, MVT::i16,
426                                         MVT::Other, Ptr, SDValue(NP, 0));
427      }
428      break;
429    default:
430      llvm_unreachable("Unsupported VT!");
431    }
432  }
433
434  // Transfer memory operands.
435  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {LD->getMemOperand()});
436
437  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
438  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
439  CurDAG->RemoveDeadNode(N);
440
441  return true;
442}
443
444template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
445  SDValue InGlue;
446  SDValue Chain = N->getOperand(0);
447  SDValue Callee = N->getOperand(1);
448  unsigned LastOpNum = N->getNumOperands() - 1;
449
450  // Direct calls are autogenerated.
451  unsigned Op = Callee.getOpcode();
452  if (Op == ISD::TargetGlobalAddress || Op == ISD::TargetExternalSymbol) {
453    return false;
454  }
455
456  // Skip the incoming flag if present
457  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
458    --LastOpNum;
459  }
460
461  SDLoc DL(N);
462  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InGlue);
463  SmallVector<SDValue, 8> Ops;
464  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
465
466  // Map all operands into the new node.
467  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
468    Ops.push_back(N->getOperand(i));
469  }
470
471  Ops.push_back(Chain);
472  Ops.push_back(Chain.getValue(1));
473
474  SDNode *ResNode = CurDAG->getMachineNode(
475      Subtarget->hasEIJMPCALL() ? AVR::EICALL : AVR::ICALL, DL, MVT::Other,
476      MVT::Glue, Ops);
477
478  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
479  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
480  CurDAG->RemoveDeadNode(N);
481
482  return true;
483}
484
485template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
486  SDValue Chain = N->getOperand(0);
487  SDValue JmpAddr = N->getOperand(1);
488
489  SDLoc DL(N);
490  // Move the destination address of the indirect branch into R31R30.
491  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
492  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
493
494  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
495  CurDAG->RemoveDeadNode(N);
496
497  return true;
498}
499
500bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
501  SDLoc DL(N);
502  MVT Type = N->getSimpleValueType(0);
503
504  assert(Type == MVT::i8 && "unexpected value type");
505
506  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
507  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
508
509  SDValue Lhs = N->getOperand(0);
510  SDValue Rhs = N->getOperand(1);
511  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
512  SDValue InChain = CurDAG->getEntryNode();
513  SDValue InGlue = SDValue(Mul, 0);
514
515  // Copy the low half of the result, if it is needed.
516  if (N->hasAnyUseOfValue(0)) {
517    SDValue CopyFromLo =
518        CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
519
520    ReplaceUses(SDValue(N, 0), CopyFromLo);
521
522    InChain = CopyFromLo.getValue(1);
523    InGlue = CopyFromLo.getValue(2);
524  }
525
526  // Copy the high half of the result, if it is needed.
527  if (N->hasAnyUseOfValue(1)) {
528    SDValue CopyFromHi =
529        CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
530
531    ReplaceUses(SDValue(N, 1), CopyFromHi);
532
533    InChain = CopyFromHi.getValue(1);
534    InGlue = CopyFromHi.getValue(2);
535  }
536
537  CurDAG->RemoveDeadNode(N);
538
539  // We need to clear R1. This is currently done (dirtily)
540  // using a custom inserter.
541
542  return true;
543}
544
545void AVRDAGToDAGISel::Select(SDNode *N) {
546  // If we have a custom node, we already have selected!
547  if (N->isMachineOpcode()) {
548    LLVM_DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
549    N->setNodeId(-1);
550    return;
551  }
552
553  // See if subclasses can handle this node.
554  if (trySelect(N))
555    return;
556
557  // Select the default instruction
558  SelectCode(N);
559}
560
561bool AVRDAGToDAGISel::trySelect(SDNode *N) {
562  unsigned Opcode = N->getOpcode();
563  SDLoc DL(N);
564
565  switch (Opcode) {
566  // Nodes we fully handle.
567  case ISD::FrameIndex:
568    return select<ISD::FrameIndex>(N);
569  case ISD::BRIND:
570    return select<ISD::BRIND>(N);
571  case ISD::UMUL_LOHI:
572  case ISD::SMUL_LOHI:
573    return selectMultiplication(N);
574
575  // Nodes we handle partially. Other cases are autogenerated
576  case ISD::STORE:
577    return select<ISD::STORE>(N);
578  case ISD::LOAD:
579    return select<ISD::LOAD>(N);
580  case AVRISD::CALL:
581    return select<AVRISD::CALL>(N);
582  default:
583    return false;
584  }
585}
586
587FunctionPass *llvm::createAVRISelDag(AVRTargetMachine &TM,
588                                     CodeGenOptLevel OptLevel) {
589  return new AVRDAGToDAGISel(TM, OptLevel);
590}
591