LLVM  14.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);
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  MVT VT) {
170  ISD::MemIndexedMode AM = LD->getAddressingMode();
171 
172  // Progmem indexed loads only work in POSTINC mode.
173  if (LD->getExtensionType() != ISD::NON_EXTLOAD || AM != ISD::POST_INC) {
174  return 0;
175  }
176 
177  unsigned Opcode = 0;
178  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
179 
180  switch (VT.SimpleTy) {
181  case MVT::i8: {
182  if (Offs != 1) {
183  return 0;
184  }
185  Opcode = AVR::LPMRdZPi;
186  break;
187  }
188  case MVT::i16: {
189  if (Offs != 2) {
190  return 0;
191  }
192  Opcode = AVR::LPMWRdZPi;
193  break;
194  }
195  default:
196  return 0;
197  }
198 
199  return Opcode;
200 }
201 
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 
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(
279  ImmNode->getAPIntValue().getZExtValue(), dl, MVT::i8);
280  } else {
281  Disp = ImmOp;
282  }
283 
284  OutOps.push_back(Base);
285  OutOps.push_back(Disp);
286 
287  return false;
288  }
289  }
290 
291  // More generic case.
292  // Create chain that puts Op into pointer register
293  // and return that register.
294  Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
295 
296  SDValue CopyToReg = CurDAG->getCopyToReg(Op, dl, VReg, Op);
298  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
299 
300  OutOps.push_back(CopyFromReg);
301 
302  return false;
303 }
304 
305 template <> bool AVRDAGToDAGISel::select<ISD::FrameIndex>(SDNode *N) {
306  auto DL = CurDAG->getDataLayout();
307 
308  // Convert the frameindex into a temp instruction that will hold the
309  // effective address of the final stack slot.
310  int FI = cast<FrameIndexSDNode>(N)->getIndex();
311  SDValue TFI =
312  CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy(DL));
313 
314  CurDAG->SelectNodeTo(N, AVR::FRMIDX, getTargetLowering()->getPointerTy(DL),
315  TFI, CurDAG->getTargetConstant(0, SDLoc(N), MVT::i16));
316  return true;
317 }
318 
319 template <> bool AVRDAGToDAGISel::select<ISD::STORE>(SDNode *N) {
320  // Use the STD{W}SPQRr pseudo instruction when passing arguments through
321  // the stack on function calls for further expansion during the PEI phase.
322  const StoreSDNode *ST = cast<StoreSDNode>(N);
323  SDValue BasePtr = ST->getBasePtr();
324 
325  // Early exit when the base pointer is a frame index node or a constant.
326  if (isa<FrameIndexSDNode>(BasePtr) || isa<ConstantSDNode>(BasePtr) ||
327  BasePtr.isUndef()) {
328  return false;
329  }
330 
331  const RegisterSDNode *RN = dyn_cast<RegisterSDNode>(BasePtr.getOperand(0));
332  // Only stores where SP is the base pointer are valid.
333  if (!RN || (RN->getReg() != AVR::SP)) {
334  return false;
335  }
336 
337  int CST = (int)cast<ConstantSDNode>(BasePtr.getOperand(1))->getZExtValue();
338  SDValue Chain = ST->getChain();
339  EVT VT = ST->getValue().getValueType();
340  SDLoc DL(N);
341  SDValue Offset = CurDAG->getTargetConstant(CST, DL, MVT::i16);
342  SDValue Ops[] = {BasePtr.getOperand(0), Offset, ST->getValue(), Chain};
343  unsigned Opc = (VT == MVT::i16) ? AVR::STDWSPQRr : AVR::STDSPQRr;
344 
345  SDNode *ResNode = CurDAG->getMachineNode(Opc, DL, MVT::Other, Ops);
346 
347  // Transfer memory operands.
348  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {ST->getMemOperand()});
349 
350  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
351  CurDAG->RemoveDeadNode(N);
352 
353  return true;
354 }
355 
356 template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
357  const LoadSDNode *LD = cast<LoadSDNode>(N);
359  // Check if the opcode can be converted into an indexed load.
360  return selectIndexedLoad(N);
361  }
362 
363  assert(Subtarget->hasLPM() && "cannot load from program memory on this mcu");
364 
365  // This is a flash memory load, move the pointer into R31R30 and emit
366  // the lpm instruction.
367  MVT VT = LD->getMemoryVT().getSimpleVT();
368  SDValue Chain = LD->getChain();
369  SDValue Ptr = LD->getBasePtr();
370  SDNode *ResNode;
371  SDLoc DL(N);
372 
373  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr, SDValue());
374  Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30, MVT::i16,
375  Chain.getValue(1));
376 
377  SDValue RegZ = CurDAG->getRegister(AVR::R31R30, MVT::i16);
378 
379  // Check if the opcode can be converted into an indexed load.
380  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT)) {
381  // It is legal to fold the load into an indexed load.
382  ResNode =
383  CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr, RegZ);
384  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
385  } else {
386  // Selecting an indexed load is not legal, fallback to a normal load.
387  switch (VT.SimpleTy) {
388  case MVT::i8:
389  ResNode = CurDAG->getMachineNode(AVR::LPMRdZ, DL, MVT::i8, MVT::Other,
390  Ptr, RegZ);
391  break;
392  case MVT::i16:
393  ResNode = CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16, MVT::Other,
394  Ptr, RegZ);
395  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
396  break;
397  default:
398  llvm_unreachable("Unsupported VT!");
399  }
400  }
401 
402  // Transfer memory operands.
403  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {LD->getMemOperand()});
404 
405  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
406  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
407  CurDAG->RemoveDeadNode(N);
408 
409  return true;
410 }
411 
412 template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
413  SDValue InFlag;
414  SDValue Chain = N->getOperand(0);
415  SDValue Callee = N->getOperand(1);
416  unsigned LastOpNum = N->getNumOperands() - 1;
417 
418  // Direct calls are autogenerated.
419  unsigned Op = Callee.getOpcode();
421  return false;
422  }
423 
424  // Skip the incoming flag if present
425  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
426  --LastOpNum;
427  }
428 
429  SDLoc DL(N);
430  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
432  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
433 
434  // Map all operands into the new node.
435  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
436  Ops.push_back(N->getOperand(i));
437  }
438 
439  Ops.push_back(Chain);
440  Ops.push_back(Chain.getValue(1));
441 
442  SDNode *ResNode =
443  CurDAG->getMachineNode(AVR::ICALL, DL, MVT::Other, MVT::Glue, Ops);
444 
445  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
446  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
447  CurDAG->RemoveDeadNode(N);
448 
449  return true;
450 }
451 
452 template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
453  SDValue Chain = N->getOperand(0);
454  SDValue JmpAddr = N->getOperand(1);
455 
456  SDLoc DL(N);
457  // Move the destination address of the indirect branch into R31R30.
458  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
459  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
460 
461  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
462  CurDAG->RemoveDeadNode(N);
463 
464  return true;
465 }
466 
467 bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
468  SDLoc DL(N);
469  MVT Type = N->getSimpleValueType(0);
470 
471  assert(Type == MVT::i8 && "unexpected value type");
472 
473  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
474  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
475 
476  SDValue Lhs = N->getOperand(0);
477  SDValue Rhs = N->getOperand(1);
478  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
479  SDValue InChain = CurDAG->getEntryNode();
480  SDValue InGlue = SDValue(Mul, 0);
481 
482  // Copy the low half of the result, if it is needed.
483  if (N->hasAnyUseOfValue(0)) {
484  SDValue CopyFromLo =
485  CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
486 
487  ReplaceUses(SDValue(N, 0), CopyFromLo);
488 
489  InChain = CopyFromLo.getValue(1);
490  InGlue = CopyFromLo.getValue(2);
491  }
492 
493  // Copy the high half of the result, if it is needed.
494  if (N->hasAnyUseOfValue(1)) {
495  SDValue CopyFromHi =
496  CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
497 
498  ReplaceUses(SDValue(N, 1), CopyFromHi);
499 
500  InChain = CopyFromHi.getValue(1);
501  InGlue = CopyFromHi.getValue(2);
502  }
503 
505 
506  // We need to clear R1. This is currently done (dirtily)
507  // using a custom inserter.
508 
509  return true;
510 }
511 
512 void AVRDAGToDAGISel::Select(SDNode *N) {
513  // If we have a custom node, we already have selected!
514  if (N->isMachineOpcode()) {
515  LLVM_DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
516  N->setNodeId(-1);
517  return;
518  }
519 
520  // See if subclasses can handle this node.
521  if (trySelect(N))
522  return;
523 
524  // Select the default instruction
525  SelectCode(N);
526 }
527 
528 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
529  unsigned Opcode = N->getOpcode();
530  SDLoc DL(N);
531 
532  switch (Opcode) {
533  // Nodes we fully handle.
534  case ISD::FrameIndex:
535  return select<ISD::FrameIndex>(N);
536  case ISD::BRIND:
537  return select<ISD::BRIND>(N);
538  case ISD::UMUL_LOHI:
539  case ISD::SMUL_LOHI:
540  return selectMultiplication(N);
541 
542  // Nodes we handle partially. Other cases are autogenerated
543  case ISD::STORE:
544  return select<ISD::STORE>(N);
545  case ISD::LOAD:
546  return select<ISD::LOAD>(N);
547  case AVRISD::CALL:
548  return select<AVRISD::CALL>(N);
549  default:
550  return false;
551  }
552 }
553 
555  CodeGenOpt::Level OptLevel) {
556  return new AVRDAGToDAGISel(TM, OptLevel);
557 }
558 
559 } // end of namespace llvm
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:240
i
i
Definition: README.txt:29
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1556
llvm::RegisterSDNode
Definition: SelectionDAGNodes.h:2098
llvm::SelectionDAGISel::getTargetLowering
const TargetLowering * getTargetLowering() const
Definition: SelectionDAGISel.h:67
llvm::ISD::MemIndexedMode
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1310
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::SelectionDAGISel::TM
TargetMachine & TM
Definition: SelectionDAGISel.h:41
llvm::SDNode::getValueType
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Definition: SelectionDAGNodes.h:966
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1086
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:158
llvm::ConstantSDNode::getAPIntValue
const APInt & getAPIntValue() const
Definition: SelectionDAGNodes.h:1570
llvm::ISD::NON_EXTLOAD
@ NON_EXTLOAD
Definition: ISDOpcodes.h:1341
llvm::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:735
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::ISD::PRE_DEC
@ PRE_DEC
Definition: ISDOpcodes.h:1310
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:1168
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:455
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition: SelectionDAGNodes.h:2281
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:262
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:4364
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:247
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
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:942
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:629
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
llvm::SelectionDAG::getTargetFrameIndex
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:688
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:35
llvm::AVRSubtarget
A specific AVR target MCU.
Definition: AVRSubtarget.h:31
llvm::SelectionDAGISel::OptLevel
CodeGenOpt::Level OptLevel
Definition: SelectionDAGISel.h:51
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:3189
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition: MachineValueType.h:321
llvm::RegisterSDNode::getReg
Register getReg() const
Definition: SelectionDAGNodes.h:2107
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::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1453
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1744
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:634
llvm::ISD::POST_INC
@ POST_INC
Definition: ISDOpcodes.h:1310
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::SelectionDAG::RemoveDeadNode
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
Definition: SelectionDAG.cpp:906
llvm::AVRDAGToDAGISel::selectIndexedProgMemLoad
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
Definition: AVRISelDAGToDAG.cpp:168
llvm::InlineAsm::Constraint_Q
@ Constraint_Q
Definition: InlineAsm.h:251
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:921
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:761
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition: SelectionDAGNodes.h:904
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:202
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:2309
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:172
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:44
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:47
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:9011
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:31
llvm::MachineFunction
Definition: MachineFunction.h:230
SelectionDAGISel.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
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:554
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:1037
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:206
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::SelectionDAGISel::MF
MachineFunction * MF
Definition: SelectionDAGISel.h:45
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
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:516
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:440
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:206
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:138
AVR.h
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:922
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
llvm::SelectionDAGISel
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Definition: SelectionDAGISel.h:39
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:637
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:45
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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:415
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:346
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::AVR::isProgramMemoryAccess
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:49