LLVM 17.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, 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
52private:
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
64char AVRDAGToDAGISel::ID = 0;
65
66INITIALIZE_PASS(AVRDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false)
67
68bool AVRDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
69 Subtarget = &MF.getSubtarget<AVRSubtarget>();
71}
72
73bool 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
130bool 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
177unsigned 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
202bool 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
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);
297 CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
298
299 OutOps.push_back(CopyFromReg);
300
301 return false;
302}
303
304template <> 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
318template <> 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
355template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
356 const LoadSDNode *LD = cast<LoadSDNode>(N);
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
442template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
443 SDValue InFlag;
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();
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, InFlag);
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
483template <> 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
498bool 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
543void 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
559bool 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:
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
586 CodeGenOpt::Level OptLevel) {
587 return new AVRDAGToDAGISel(TM, OptLevel);
588}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
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
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
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 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...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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:75
int getProgramMemoryBank(MemSDNode const *N)
Definition: AVR.h:86
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Level
Code generation optimization level.
Definition: CodeGen.h:57
@ 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:978
@ FrameIndex
Definition: ISDOpcodes.h:80
@ TargetExternalSymbol
Definition: ISDOpcodes.h:169
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:999
@ 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:1396
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:406
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
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