xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
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 
25 using namespace llvm;
26 
27 namespace {
28 
29 /// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
30 class AVRDAGToDAGISel : public SelectionDAGISel {
31 public:
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 
53 private:
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 
65 char AVRDAGToDAGISel::ID = 0;
66 
67 INITIALIZE_PASS(AVRDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false)
68 
69 bool AVRDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
70   Subtarget = &MF.getSubtarget<AVRSubtarget>();
71   return SelectionDAGISel::runOnMachineFunction(MF);
72 }
73 
74 bool 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 
131 bool 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 
178 unsigned 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 
203 bool 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 
306 template <> 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 
320 template <> 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 
357 template <> 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 
444 template <> 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 
485 template <> 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 
500 bool 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 
545 void 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 
561 bool 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 
587 FunctionPass *llvm::createAVRISelDag(AVRTargetMachine &TM,
588                                      CodeGenOptLevel OptLevel) {
589   return new AVRDAGToDAGISel(TM, OptLevel);
590 }
591