LLVM  16.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 
24 namespace llvm {
25 
26 /// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
28 public:
30  : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {}
31 
32  StringRef getPassName() const override {
33  return "AVR DAG->DAG Instruction Selection";
34  }
35 
36  bool runOnMachineFunction(MachineFunction &MF) override;
37 
38  bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp);
39 
40  bool selectIndexedLoad(SDNode *N);
41  unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT, int Bank);
42 
43  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
44  std::vector<SDValue> &OutOps) override;
45 
46 // Include the pieces autogenerated from the target description.
47 #include "AVRGenDAGISel.inc"
48 
49 private:
50  void Select(SDNode *N) override;
51  bool trySelect(SDNode *N);
52 
53  template <unsigned NodeType> bool select(SDNode *N);
54  bool selectMultiplication(SDNode *N);
55 
56  const AVRSubtarget *Subtarget;
57 };
58 
60  Subtarget = &MF.getSubtarget<AVRSubtarget>();
62 }
63 
65  SDValue &Disp) {
66  SDLoc dl(Op);
67  auto DL = CurDAG->getDataLayout();
69 
70  // if the address is a frame index get the TargetFrameIndex.
71  if (const FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
72  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), PtrVT);
73  Disp = CurDAG->getTargetConstant(0, dl, MVT::i8);
74 
75  return true;
76  }
77 
78  // Match simple Reg + uimm6 operands.
79  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
81  return false;
82  }
83 
84  if (const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
85  int RHSC = (int)RHS->getZExtValue();
86 
87  // Convert negative offsets into positives ones.
88  if (N.getOpcode() == ISD::SUB) {
89  RHSC = -RHSC;
90  }
91 
92  // <#Frame index + const>
93  // Allow folding offsets bigger than 63 so the frame pointer can be used
94  // directly instead of copying it around by adjusting and restoring it for
95  // each access.
96  if (N.getOperand(0).getOpcode() == ISD::FrameIndex) {
97  int FI = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
98 
99  Base = CurDAG->getTargetFrameIndex(FI, PtrVT);
100  Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i16);
101 
102  return true;
103  }
104 
105  // The value type of the memory instruction determines what is the maximum
106  // offset allowed.
107  MVT VT = cast<MemSDNode>(Op)->getMemoryVT().getSimpleVT();
108 
109  // We only accept offsets that fit in 6 bits (unsigned).
110  if (isUInt<6>(RHSC) && (VT == MVT::i8 || VT == MVT::i16)) {
111  Base = N.getOperand(0);
112  Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i8);
113 
114  return true;
115  }
116  }
117 
118  return false;
119 }
120 
122  const LoadSDNode *LD = cast<LoadSDNode>(N);
123  ISD::MemIndexedMode AM = LD->getAddressingMode();
124  MVT VT = LD->getMemoryVT().getSimpleVT();
126 
127  // We only care if this load uses a POSTINC or PREDEC mode.
128  if ((LD->getExtensionType() != ISD::NON_EXTLOAD) ||
129  (AM != ISD::POST_INC && AM != ISD::PRE_DEC)) {
130 
131  return false;
132  }
133 
134  unsigned Opcode = 0;
135  bool isPre = (AM == ISD::PRE_DEC);
136  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
137 
138  switch (VT.SimpleTy) {
139  case MVT::i8: {
140  if ((!isPre && Offs != 1) || (isPre && Offs != -1)) {
141  return false;
142  }
143 
144  Opcode = (isPre) ? AVR::LDRdPtrPd : AVR::LDRdPtrPi;
145  break;
146  }
147  case MVT::i16: {
148  if ((!isPre && Offs != 2) || (isPre && Offs != -2)) {
149  return false;
150  }
151 
152  Opcode = (isPre) ? AVR::LDWRdPtrPd : AVR::LDWRdPtrPi;
153  break;
154  }
155  default:
156  return false;
157  }
158 
159  SDNode *ResNode =
160  CurDAG->getMachineNode(Opcode, SDLoc(N), VT, PtrVT, MVT::Other,
161  LD->getBasePtr(), LD->getChain());
162  ReplaceUses(N, ResNode);
164 
165  return true;
166 }
167 
169  int Bank) {
170  // Progmem indexed loads only work in POSTINC mode.
171  if (LD->getExtensionType() != ISD::NON_EXTLOAD ||
172  LD->getAddressingMode() != ISD::POST_INC)
173  return 0;
174 
175  // Feature ELPM is needed for loading from extended program memory.
176  assert((Bank == 0 || Subtarget->hasELPM()) &&
177  "cannot load from extended program memory on this mcu");
178 
179  unsigned Opcode = 0;
180  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
181 
182  switch (VT.SimpleTy) {
183  case MVT::i8:
184  if (Offs == 1)
185  Opcode = Bank > 0 ? AVR::ELPMBRdZPi : AVR::LPMRdZPi;
186  break;
187  case MVT::i16:
188  if (Offs == 2)
189  Opcode = Bank > 0 ? AVR::ELPMWRdZPi : AVR::LPMWRdZPi;
190  break;
191  default:
192  break;
193  }
194 
195  return Opcode;
196 }
197 
199  const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) {
200  assert((ConstraintCode == InlineAsm::Constraint_m ||
201  ConstraintCode == InlineAsm::Constraint_Q) &&
202  "Unexpected asm memory constraint");
203 
205  const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
206  const TargetLowering &TL = *STI.getTargetLowering();
207  SDLoc dl(Op);
208  auto DL = CurDAG->getDataLayout();
209 
210  const RegisterSDNode *RegNode = dyn_cast<RegisterSDNode>(Op);
211 
212  // If address operand is of PTRDISPREGS class, all is OK, then.
213  if (RegNode &&
214  RI.getRegClass(RegNode->getReg()) == &AVR::PTRDISPREGSRegClass) {
215  OutOps.push_back(Op);
216  return false;
217  }
218 
219  if (Op->getOpcode() == ISD::FrameIndex) {
220  SDValue Base, Disp;
221 
222  if (SelectAddr(Op.getNode(), Op, Base, Disp)) {
223  OutOps.push_back(Base);
224  OutOps.push_back(Disp);
225 
226  return false;
227  }
228 
229  return true;
230  }
231 
232  // If Op is add 'register, immediate' and
233  // register is either virtual register or register of PTRDISPREGSRegClass
234  if (Op->getOpcode() == ISD::ADD || Op->getOpcode() == ISD::SUB) {
235  SDValue CopyFromRegOp = Op->getOperand(0);
236  SDValue ImmOp = Op->getOperand(1);
237  ConstantSDNode *ImmNode = dyn_cast<ConstantSDNode>(ImmOp);
238 
239  unsigned Reg;
240  bool CanHandleRegImmOpt = ImmNode && ImmNode->getAPIntValue().ult(64);
241 
242  if (CopyFromRegOp->getOpcode() == ISD::CopyFromReg) {
243  RegisterSDNode *RegNode =
244  cast<RegisterSDNode>(CopyFromRegOp->getOperand(1));
245  Reg = RegNode->getReg();
246  CanHandleRegImmOpt &= (Register::isVirtualRegister(Reg) ||
247  AVR::PTRDISPREGSRegClass.contains(Reg));
248  } else {
249  CanHandleRegImmOpt = false;
250  }
251 
252  // If we detect proper case - correct virtual register class
253  // if needed and go to another inlineasm operand.
254  if (CanHandleRegImmOpt) {
255  SDValue Base, Disp;
256 
257  if (RI.getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) {
258  SDLoc dl(CopyFromRegOp);
259 
260  Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
261 
263  CurDAG->getCopyToReg(CopyFromRegOp, dl, VReg, CopyFromRegOp);
264 
265  SDValue NewCopyFromRegOp =
266  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
267 
268  Base = NewCopyFromRegOp;
269  } else {
270  Base = CopyFromRegOp;
271  }
272 
273  if (ImmNode->getValueType(0) != MVT::i8) {
274  Disp = CurDAG->getTargetConstant(
275  ImmNode->getAPIntValue().getZExtValue(), dl, MVT::i8);
276  } else {
277  Disp = ImmOp;
278  }
279 
280  OutOps.push_back(Base);
281  OutOps.push_back(Disp);
282 
283  return false;
284  }
285  }
286 
287  // More generic case.
288  // Create chain that puts Op into pointer register
289  // and return that register.
290  Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
291 
292  SDValue CopyToReg = CurDAG->getCopyToReg(Op, dl, VReg, Op);
294  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
295 
296  OutOps.push_back(CopyFromReg);
297 
298  return false;
299 }
300 
301 template <> bool AVRDAGToDAGISel::select<ISD::FrameIndex>(SDNode *N) {
302  auto DL = CurDAG->getDataLayout();
303 
304  // Convert the frameindex into a temp instruction that will hold the
305  // effective address of the final stack slot.
306  int FI = cast<FrameIndexSDNode>(N)->getIndex();
307  SDValue TFI =
308  CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy(DL));
309 
310  CurDAG->SelectNodeTo(N, AVR::FRMIDX, getTargetLowering()->getPointerTy(DL),
311  TFI, CurDAG->getTargetConstant(0, SDLoc(N), MVT::i16));
312  return true;
313 }
314 
315 template <> bool AVRDAGToDAGISel::select<ISD::STORE>(SDNode *N) {
316  // Use the STD{W}SPQRr pseudo instruction when passing arguments through
317  // the stack on function calls for further expansion during the PEI phase.
318  const StoreSDNode *ST = cast<StoreSDNode>(N);
319  SDValue BasePtr = ST->getBasePtr();
320 
321  // Early exit when the base pointer is a frame index node or a constant.
322  if (isa<FrameIndexSDNode>(BasePtr) || isa<ConstantSDNode>(BasePtr) ||
323  BasePtr.isUndef()) {
324  return false;
325  }
326 
327  const RegisterSDNode *RN = dyn_cast<RegisterSDNode>(BasePtr.getOperand(0));
328  // Only stores where SP is the base pointer are valid.
329  if (!RN || (RN->getReg() != AVR::SP)) {
330  return false;
331  }
332 
333  int CST = (int)cast<ConstantSDNode>(BasePtr.getOperand(1))->getZExtValue();
334  SDValue Chain = ST->getChain();
335  EVT VT = ST->getValue().getValueType();
336  SDLoc DL(N);
337  SDValue Offset = CurDAG->getTargetConstant(CST, DL, MVT::i16);
338  SDValue Ops[] = {BasePtr.getOperand(0), Offset, ST->getValue(), Chain};
339  unsigned Opc = (VT == MVT::i16) ? AVR::STDWSPQRr : AVR::STDSPQRr;
340 
341  SDNode *ResNode = CurDAG->getMachineNode(Opc, DL, MVT::Other, Ops);
342 
343  // Transfer memory operands.
344  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {ST->getMemOperand()});
345 
346  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
347  CurDAG->RemoveDeadNode(N);
348 
349  return true;
350 }
351 
352 template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
353  const LoadSDNode *LD = cast<LoadSDNode>(N);
355  // Check if the opcode can be converted into an indexed load.
356  return selectIndexedLoad(N);
357  }
358 
359  if (!Subtarget->hasLPM())
360  report_fatal_error("cannot load from program memory on this mcu");
361 
362  int ProgMemBank = AVR::getProgramMemoryBank(LD);
363  if (ProgMemBank < 0 || ProgMemBank > 5)
364  report_fatal_error("unexpected program memory bank");
365 
366  // This is a flash memory load, move the pointer into R31R30 and emit
367  // the lpm instruction.
368  MVT VT = LD->getMemoryVT().getSimpleVT();
369  SDValue Chain = LD->getChain();
370  SDValue Ptr = LD->getBasePtr();
371  SDNode *ResNode;
372  SDLoc DL(N);
373 
374  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr, SDValue());
375  Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30, MVT::i16,
376  Chain.getValue(1));
377 
378  // Check if the opcode can be converted into an indexed load.
379  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT, ProgMemBank)) {
380  // It is legal to fold the load into an indexed load.
381  if (ProgMemBank == 0) {
382  ResNode =
383  CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr);
384  } else {
385  // Do not combine the LDI instruction into the ELPM pseudo instruction,
386  // since it may be reused by other ELPM pseudo instructions.
387  SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
388  auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
389  ResNode = CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other,
390  Ptr, SDValue(NP, 0));
391  }
392  } else {
393  // Selecting an indexed load is not legal, fallback to a normal load.
394  switch (VT.SimpleTy) {
395  case MVT::i8:
396  if (ProgMemBank == 0) {
397  ResNode =
398  CurDAG->getMachineNode(AVR::LPMRdZ, DL, MVT::i8, MVT::Other, Ptr);
399  } else {
400  // Do not combine the LDI instruction into the ELPM pseudo instruction,
401  // since it may be reused by other ELPM pseudo instructions.
402  SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
403  auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
404  ResNode = CurDAG->getMachineNode(AVR::ELPMBRdZ, DL, MVT::i8, MVT::Other,
405  Ptr, SDValue(NP, 0));
406  }
407  break;
408  case MVT::i16:
409  if (ProgMemBank == 0) {
410  ResNode =
411  CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16, MVT::Other, Ptr);
412  } else {
413  // Do not combine the LDI instruction into the ELPM pseudo instruction,
414  // since LDI requires the destination register in range R16~R31.
415  SDValue NC = CurDAG->getTargetConstant(ProgMemBank, DL, MVT::i8);
416  auto *NP = CurDAG->getMachineNode(AVR::LDIRdK, DL, MVT::i8, NC);
417  ResNode = CurDAG->getMachineNode(AVR::ELPMWRdZ, DL, MVT::i16,
418  MVT::Other, Ptr, SDValue(NP, 0));
419  }
420  break;
421  default:
422  llvm_unreachable("Unsupported VT!");
423  }
424  }
425 
426  // Transfer memory operands.
427  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {LD->getMemOperand()});
428 
429  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
430  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
431  CurDAG->RemoveDeadNode(N);
432 
433  return true;
434 }
435 
436 template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
437  SDValue InFlag;
438  SDValue Chain = N->getOperand(0);
439  SDValue Callee = N->getOperand(1);
440  unsigned LastOpNum = N->getNumOperands() - 1;
441 
442  // Direct calls are autogenerated.
443  unsigned Op = Callee.getOpcode();
445  return false;
446  }
447 
448  // Skip the incoming flag if present
449  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
450  --LastOpNum;
451  }
452 
453  SDLoc DL(N);
454  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
456  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
457 
458  // Map all operands into the new node.
459  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
460  Ops.push_back(N->getOperand(i));
461  }
462 
463  Ops.push_back(Chain);
464  Ops.push_back(Chain.getValue(1));
465 
466  SDNode *ResNode =
467  CurDAG->getMachineNode(AVR::ICALL, DL, MVT::Other, MVT::Glue, Ops);
468 
469  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
470  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
471  CurDAG->RemoveDeadNode(N);
472 
473  return true;
474 }
475 
476 template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
477  SDValue Chain = N->getOperand(0);
478  SDValue JmpAddr = N->getOperand(1);
479 
480  SDLoc DL(N);
481  // Move the destination address of the indirect branch into R31R30.
482  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
483  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
484 
485  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
486  CurDAG->RemoveDeadNode(N);
487 
488  return true;
489 }
490 
491 bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
492  SDLoc DL(N);
493  MVT Type = N->getSimpleValueType(0);
494 
495  assert(Type == MVT::i8 && "unexpected value type");
496 
497  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
498  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
499 
500  SDValue Lhs = N->getOperand(0);
501  SDValue Rhs = N->getOperand(1);
502  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
503  SDValue InChain = CurDAG->getEntryNode();
504  SDValue InGlue = SDValue(Mul, 0);
505 
506  // Copy the low half of the result, if it is needed.
507  if (N->hasAnyUseOfValue(0)) {
508  SDValue CopyFromLo =
509  CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
510 
511  ReplaceUses(SDValue(N, 0), CopyFromLo);
512 
513  InChain = CopyFromLo.getValue(1);
514  InGlue = CopyFromLo.getValue(2);
515  }
516 
517  // Copy the high half of the result, if it is needed.
518  if (N->hasAnyUseOfValue(1)) {
519  SDValue CopyFromHi =
520  CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
521 
522  ReplaceUses(SDValue(N, 1), CopyFromHi);
523 
524  InChain = CopyFromHi.getValue(1);
525  InGlue = CopyFromHi.getValue(2);
526  }
527 
529 
530  // We need to clear R1. This is currently done (dirtily)
531  // using a custom inserter.
532 
533  return true;
534 }
535 
536 void AVRDAGToDAGISel::Select(SDNode *N) {
537  // If we have a custom node, we already have selected!
538  if (N->isMachineOpcode()) {
539  LLVM_DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
540  N->setNodeId(-1);
541  return;
542  }
543 
544  // See if subclasses can handle this node.
545  if (trySelect(N))
546  return;
547 
548  // Select the default instruction
549  SelectCode(N);
550 }
551 
552 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
553  unsigned Opcode = N->getOpcode();
554  SDLoc DL(N);
555 
556  switch (Opcode) {
557  // Nodes we fully handle.
558  case ISD::FrameIndex:
559  return select<ISD::FrameIndex>(N);
560  case ISD::BRIND:
561  return select<ISD::BRIND>(N);
562  case ISD::UMUL_LOHI:
563  case ISD::SMUL_LOHI:
564  return selectMultiplication(N);
565 
566  // Nodes we handle partially. Other cases are autogenerated
567  case ISD::STORE:
568  return select<ISD::STORE>(N);
569  case ISD::LOAD:
570  return select<ISD::LOAD>(N);
571  case AVRISD::CALL:
572  return select<AVRISD::CALL>(N);
573  default:
574  return false;
575  }
576 }
577 
579  CodeGenOpt::Level OptLevel) {
580  return new AVRDAGToDAGISel(TM, OptLevel);
581 }
582 
583 } // end of namespace llvm
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:240
i
i
Definition: README.txt:29
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1581
llvm::RegisterSDNode
Definition: SelectionDAGNodes.h:2160
llvm::SelectionDAGISel::getTargetLowering
const TargetLowering * getTargetLowering() const
Definition: SelectionDAGISel.h:71
llvm::ISD::MemIndexedMode
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1373
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::SelectionDAGISel::TM
TargetMachine & TM
Definition: SelectionDAGISel.h:43
llvm::SDNode::getValueType
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Definition: SelectionDAGNodes.h:985
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1105
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::ConstantSDNode::getAPIntValue
const APInt & getAPIntValue() const
Definition: SelectionDAGNodes.h:1595
llvm::ISD::NON_EXTLOAD
@ NON_EXTLOAD
Definition: ISDOpcodes.h:1404
llvm::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:767
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::ISD::PRE_DEC
@ PRE_DEC
Definition: ISDOpcodes.h:1373
llvm::ARM_MB::LD
@ LD
Definition: ARMBaseInfo.h:72
llvm::AVRTargetMachine
A generic AVR implementation.
Definition: AVRTargetMachine.h:28
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:463
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2343
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:273
llvm::AVRDAGToDAGISel::SelectAddr
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp)
Definition: AVRISelDAGToDAG.cpp:64
llvm::SelectionDAG::isBaseWithConstantOffset
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
Definition: SelectionDAG.cpp:4684
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
MachineRegisterInfo.h
llvm::AVRISD::CALL
@ CALL
Represents an abstract call instruction, which includes a bunch of information.
Definition: AVRISelLowering.h:34
llvm::ISD::BRIND
@ BRIND
BRIND - Indirect branch.
Definition: ISDOpcodes.h:987
llvm::AVRDAGToDAGISel::selectIndexedProgMemLoad
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT, int Bank)
Definition: AVRISelDAGToDAG.cpp:168
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:644
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
llvm::SelectionDAG::getTargetFrameIndex
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:720
llvm::ISD::CopyToReg
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:203
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
llvm::AVRSubtarget
A specific AVR target MCU.
Definition: AVRSubtarget.h:31
llvm::SelectionDAGISel::OptLevel
CodeGenOpt::Level OptLevel
Definition: SelectionDAGISel.h:54
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3486
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition: MachineValueType.h:332
llvm::RegisterSDNode::getReg
Register getReg() const
Definition: SelectionDAGNodes.h:2169
llvm::AVRSubtarget::getTargetLowering
const AVRTargetLowering * getTargetLowering() const override
Definition: AVRSubtarget.h:45
llvm::AVRDAGToDAGISel::AVRDAGToDAGISel
AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
Definition: AVRISelDAGToDAG.cpp:29
llvm::AVRDAGToDAGISel::getPassName
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
Definition: AVRISelDAGToDAG.cpp:32
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1486
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1784
llvm::ISD::TargetGlobalAddress
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:164
llvm::ISD::CopyFromReg
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:208
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:647
llvm::ISD::POST_INC
@ POST_INC
Definition: ISDOpcodes.h:1373
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:259
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::SelectionDAG::RemoveDeadNode
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
Definition: SelectionDAG.cpp:997
llvm::ISD::LOAD
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:966
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:53
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:793
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:920
llvm::AVRDAGToDAGISel::SelectInlineAsmMemoryOperand
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
Definition: AVRISelDAGToDAG.cpp:198
llvm::AVRDAGToDAGISel::selectIndexedLoad
bool selectIndexedLoad(SDNode *N)
Definition: AVRISelDAGToDAG.cpp:121
AVRTargetMachine.h
llvm::Register::isVirtualRegister
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
llvm::StoreSDNode
This class is used to represent ISD::STORE nodes.
Definition: SelectionDAGNodes.h:2371
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:179
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:46
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:49
AVRMCTargetDesc.h
llvm::SelectionDAG::getMachineNode
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
Definition: SelectionDAG.cpp:9791
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:31
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::AVRSubtarget::hasELPM
bool hasELPM() const
Definition: AVRSubtarget.h:73
SelectionDAGISel.h
Mul
BinaryOperator * Mul
Definition: X86PartialReduction.cpp:70
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::ISD::UMUL_LOHI
@ UMUL_LOHI
Definition: ISDOpcodes.h:251
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::createAVRISelDag
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
Definition: AVRISelDAGToDAG.cpp:578
llvm::ISD::SMUL_LOHI
@ 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
llvm::CodeGenOpt::Level
Level
Definition: CodeGen.h:52
llvm::APInt::ult
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition: APInt.h:1081
llvm::AVR::getProgramMemoryBank
int getProgramMemoryBank(MemSDNode const *N)
Definition: AVR.h:84
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:187
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::SelectionDAGISel::MF
MachineFunction * MF
Definition: SelectionDAGISel.h:47
NC
#define NC
Definition: regutils.h:42
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::ISD::TargetExternalSymbol
@ TargetExternalSymbol
Definition: ISDOpcodes.h:169
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:548
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:469
llvm::AVRDAGToDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: AVRISelDAGToDAG.cpp:59
llvm::SelectionDAGISel::ReplaceUses
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
Definition: SelectionDAGISel.h:210
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
AVR.h
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:967
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
isSigned
static bool isSigned(unsigned int Opcode)
Definition: ExpandLargeDivRem.cpp:52
llvm::SelectionDAGISel
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Definition: SelectionDAGISel.h:41
llvm::AVRDAGToDAGISel
Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
Definition: AVRISelDAGToDAG.cpp:27
N
#define N
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:669
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
RN
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s src2 rnd ← FPSCR RN
Definition: README_P9.txt:262
raw_ostream.h
llvm::SelectionDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: SelectionDAGISel.cpp:373
llvm::InlineAsm::Constraint_Q
@ Constraint_Q
Definition: InlineAsm.h:263
Debug.h
llvm::TargetLoweringBase::getPointerTy
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Definition: TargetLowering.h:356
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::AVR::isProgramMemoryAccess
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:73