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