LLVM 19.0.0git
AVRISelDAGToDAG.cpp
Go to the documentation of this file.
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"
16
19#include "llvm/Support/Debug.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
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>();
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
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);
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);
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();
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);
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:
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
588 CodeGenOptLevel OptLevel) {
589 return new AVRDAGToDAGISel(TM, OptLevel);
590}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
bool AVRDAGToDAGISel::select< ISD::LOAD >(SDNode *N)
#define PASS_NAME
#define DEBUG_TYPE
bool AVRDAGToDAGISel::select< ISD::FrameIndex >(SDNode *N)
bool AVRDAGToDAGISel::select< ISD::BRIND >(SDNode *N)
bool AVRDAGToDAGISel::select< AVRISD::CALL >(SDNode *N)
bool AVRDAGToDAGISel::select< ISD::STORE >(SDNode *N)
#define LLVM_DEBUG(X)
Definition: Debug.h:101
static bool isSigned(unsigned int Opcode)
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
BinaryOperator * Mul
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition: APInt.h:1089
A specific AVR target MCU.
Definition: AVRSubtarget.h:32
const AVRTargetLowering * getTargetLowering() const override
Definition: AVRSubtarget.h:46
A generic AVR implementation.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
This class is used to represent ISD::LOAD nodes.
Machine Value Type.
SimpleValueType SimpleTy
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getReg() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDValue getValue(unsigned R) const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
This class is used to represent ISD::STORE nodes.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CALL
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:74
int getProgramMemoryBank(MemSDNode const *N)
Definition: AVR.h:85
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1031
@ FrameIndex
Definition: ISDOpcodes.h:80
@ TargetExternalSymbol
Definition: ISDOpcodes.h:169
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:1052
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:208
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:164
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:203
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1472
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOptLevel OptLevel)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
#define N
#define NC
Definition: regutils.h:42
Extended Value Type.
Definition: ValueTypes.h:34