LLVM  13.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 = CurDAG->getMachineNode(Opcode, SDLoc(N), VT,
160  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  unsigned ConstraintCode,
204  std::vector<SDValue> &OutOps) {
205  assert((ConstraintCode == InlineAsm::Constraint_m ||
206  ConstraintCode == InlineAsm::Constraint_Q) &&
207  "Unexpected asm memory constraint");
208 
210  const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
211  const TargetLowering &TL = *STI.getTargetLowering();
212  SDLoc dl(Op);
213  auto DL = CurDAG->getDataLayout();
214 
215  const RegisterSDNode *RegNode = dyn_cast<RegisterSDNode>(Op);
216 
217  // If address operand is of PTRDISPREGS class, all is OK, then.
218  if (RegNode &&
219  RI.getRegClass(RegNode->getReg()) == &AVR::PTRDISPREGSRegClass) {
220  OutOps.push_back(Op);
221  return false;
222  }
223 
224  if (Op->getOpcode() == ISD::FrameIndex) {
225  SDValue Base, Disp;
226 
227  if (SelectAddr(Op.getNode(), Op, Base, Disp)) {
228  OutOps.push_back(Base);
229  OutOps.push_back(Disp);
230 
231  return false;
232  }
233 
234  return true;
235  }
236 
237  // If Op is add 'register, immediate' and
238  // register is either virtual register or register of PTRDISPREGSRegClass
239  if (Op->getOpcode() == ISD::ADD || Op->getOpcode() == ISD::SUB) {
240  SDValue CopyFromRegOp = Op->getOperand(0);
241  SDValue ImmOp = Op->getOperand(1);
242  ConstantSDNode *ImmNode = dyn_cast<ConstantSDNode>(ImmOp);
243 
244  unsigned Reg;
245  bool CanHandleRegImmOpt = ImmNode && ImmNode->getAPIntValue().ult(64);
246 
247  if (CopyFromRegOp->getOpcode() == ISD::CopyFromReg) {
248  RegisterSDNode *RegNode =
249  cast<RegisterSDNode>(CopyFromRegOp->getOperand(1));
250  Reg = RegNode->getReg();
251  CanHandleRegImmOpt &= (Register::isVirtualRegister(Reg) ||
252  AVR::PTRDISPREGSRegClass.contains(Reg));
253  } else {
254  CanHandleRegImmOpt = false;
255  }
256 
257  // If we detect proper case - correct virtual register class
258  // if needed and go to another inlineasm operand.
259  if (CanHandleRegImmOpt) {
260  SDValue Base, Disp;
261 
262  if (RI.getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) {
263  SDLoc dl(CopyFromRegOp);
264 
265  Register VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
266 
268  CurDAG->getCopyToReg(CopyFromRegOp, dl, VReg, CopyFromRegOp);
269 
270  SDValue NewCopyFromRegOp =
271  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
272 
273  Base = NewCopyFromRegOp;
274  } else {
275  Base = CopyFromRegOp;
276  }
277 
278  if (ImmNode->getValueType(0) != MVT::i8) {
279  Disp = CurDAG->getTargetConstant(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,
315  getTargetLowering()->getPointerTy(DL), TFI,
316  CurDAG->getTargetConstant(0, SDLoc(N), MVT::i16));
317  return true;
318 }
319 
320 template <> 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)cast<ConstantSDNode>(BasePtr.getOperand(1))->getZExtValue();
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 
357 template <> 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  assert(Subtarget->hasLPM() && "cannot load from program memory on this mcu");
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  SDValue RegZ = CurDAG->getRegister(AVR::R31R30, MVT::i16);
379 
380  // Check if the opcode can be converted into an indexed load.
381  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT)) {
382  // It is legal to fold the load into an indexed load.
383  ResNode = CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr,
384  RegZ);
385  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
386  } else {
387  // Selecting an indexed load is not legal, fallback to a normal load.
388  switch (VT.SimpleTy) {
389  case MVT::i8:
390  ResNode = CurDAG->getMachineNode(AVR::LPMRdZ, DL, MVT::i8, MVT::Other,
391  Ptr, RegZ);
392  break;
393  case MVT::i16:
394  ResNode = CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16,
395  MVT::Other, Ptr, RegZ);
396  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
397  break;
398  default:
399  llvm_unreachable("Unsupported VT!");
400  }
401  }
402 
403  // Transfer memory operands.
404  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {LD->getMemOperand()});
405 
406  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
407  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
408  CurDAG->RemoveDeadNode(N);
409 
410  return true;
411 }
412 
413 template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
414  SDValue InFlag;
415  SDValue Chain = N->getOperand(0);
416  SDValue Callee = N->getOperand(1);
417  unsigned LastOpNum = N->getNumOperands() - 1;
418 
419  // Direct calls are autogenerated.
420  unsigned Op = Callee.getOpcode();
422  return false;
423  }
424 
425  // Skip the incoming flag if present
426  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
427  --LastOpNum;
428  }
429 
430  SDLoc DL(N);
431  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
433  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
434 
435  // Map all operands into the new node.
436  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
437  Ops.push_back(N->getOperand(i));
438  }
439 
440  Ops.push_back(Chain);
441  Ops.push_back(Chain.getValue(1));
442 
443  SDNode *ResNode =
444  CurDAG->getMachineNode(AVR::ICALL, DL, MVT::Other, MVT::Glue, Ops);
445 
446  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
447  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
448  CurDAG->RemoveDeadNode(N);
449 
450  return true;
451 }
452 
453 template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
454  SDValue Chain = N->getOperand(0);
455  SDValue JmpAddr = N->getOperand(1);
456 
457  SDLoc DL(N);
458  // Move the destination address of the indirect branch into R31R30.
459  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
460  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
461 
462  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
463  CurDAG->RemoveDeadNode(N);
464 
465  return true;
466 }
467 
468 bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
469  SDLoc DL(N);
470  MVT Type = N->getSimpleValueType(0);
471 
472  assert(Type == MVT::i8 && "unexpected value type");
473 
474  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
475  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
476 
477  SDValue Lhs = N->getOperand(0);
478  SDValue Rhs = N->getOperand(1);
479  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
480  SDValue InChain = CurDAG->getEntryNode();
481  SDValue InGlue = SDValue(Mul, 0);
482 
483  // Copy the low half of the result, if it is needed.
484  if (N->hasAnyUseOfValue(0)) {
485  SDValue CopyFromLo =
486  CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
487 
488  ReplaceUses(SDValue(N, 0), CopyFromLo);
489 
490  InChain = CopyFromLo.getValue(1);
491  InGlue = CopyFromLo.getValue(2);
492  }
493 
494  // Copy the high half of the result, if it is needed.
495  if (N->hasAnyUseOfValue(1)) {
496  SDValue CopyFromHi =
497  CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
498 
499  ReplaceUses(SDValue(N, 1), CopyFromHi);
500 
501  InChain = CopyFromHi.getValue(1);
502  InGlue = CopyFromHi.getValue(2);
503  }
504 
506 
507  // We need to clear R1. This is currently done (dirtily)
508  // using a custom inserter.
509 
510  return true;
511 }
512 
513 void AVRDAGToDAGISel::Select(SDNode *N) {
514  // If we have a custom node, we already have selected!
515  if (N->isMachineOpcode()) {
516  LLVM_DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
517  N->setNodeId(-1);
518  return;
519  }
520 
521  // See if subclasses can handle this node.
522  if (trySelect(N))
523  return;
524 
525  // Select the default instruction
526  SelectCode(N);
527 }
528 
529 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
530  unsigned Opcode = N->getOpcode();
531  SDLoc DL(N);
532 
533  switch (Opcode) {
534  // Nodes we fully handle.
535  case ISD::FrameIndex: return select<ISD::FrameIndex>(N);
536  case ISD::BRIND: return select<ISD::BRIND>(N);
537  case ISD::UMUL_LOHI:
538  case ISD::SMUL_LOHI: return selectMultiplication(N);
539 
540  // Nodes we handle partially. Other cases are autogenerated
541  case ISD::STORE: return select<ISD::STORE>(N);
542  case ISD::LOAD: return select<ISD::LOAD>(N);
543  case AVRISD::CALL: return select<AVRISD::CALL>(N);
544  default: return false;
545  }
546 }
547 
549  CodeGenOpt::Level OptLevel) {
550  return new AVRDAGToDAGISel(TM, OptLevel);
551 }
552 
553 } // end of namespace llvm
554 
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:233
i
i
Definition: README.txt:29
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1536
llvm::RegisterSDNode
Definition: SelectionDAGNodes.h:2072
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:1290
llvm
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:958
llvm::SystemZISD::TM
@ TM
Definition: SystemZISelLowering.h:65
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1078
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:1550
llvm::ISD::NON_EXTLOAD
@ NON_EXTLOAD
Definition: ISDOpcodes.h:1321
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::InlineAsm::Constraint_Q
@ Constraint_Q
Definition: InlineAsm.h:249
llvm::ISD::PRE_DEC
@ PRE_DEC
Definition: ISDOpcodes.h:1290
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:2255
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:249
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:4183
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
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:122
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:932
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition: SelectionDAGNodes.h:621
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:568
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:196
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:3143
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition: MachineValueType.h:304
llvm::RegisterSDNode::getReg
Register getReg() const
Definition: SelectionDAGNodes.h:2081
llvm::AVRSubtarget::getTargetLowering
const AVRTargetLowering * getTargetLowering() const override
Definition: AVRSubtarget.h:43
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:1631
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1718
llvm::ISD::TargetGlobalAddress
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:157
llvm::ISD::CopyFromReg
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:201
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:1290
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:558
llvm::SelectionDAG::RemoveDeadNode
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
Definition: SelectionDAG.cpp:855
llvm::AVRDAGToDAGISel::selectIndexedProgMemLoad
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
Definition: AVRISelDAGToDAG.cpp:168
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:911
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:896
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:2283
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition: SelectionDAGNodes.h:172
llvm::MVT::i8
@ i8
Definition: MachineValueType.h:41
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:39
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:8429
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:30
llvm::MachineFunction
Definition: MachineFunction.h:230
SelectionDAGISel.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
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:244
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::createAVRISelDag
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
Definition: AVRISelDAGToDAG.cpp:548
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:243
llvm::CodeGenOpt::Level
Level
Definition: CodeGen.h:52
llvm::APInt::ult
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition: APInt.h:1205
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:205
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:73
llvm::SelectionDAGISel::MF
MachineFunction * MF
Definition: SelectionDAGISel.h:45
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::ISD::TargetExternalSymbol
@ TargetExternalSymbol
Definition: ISDOpcodes.h:162
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
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:245
AVR.h
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:912
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:232
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
llvm::MVT::i16
@ i16
Definition: MachineValueType.h:42
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:411
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:343
llvm::AVR::isProgramMemoryAccess
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:47