23 #define DEBUG_TYPE "avr-isel"
34 return "AVR DAG->DAG Instruction Selection";
45 std::vector<SDValue> &OutOps)
override;
48 #include "AVRGenDAGISel.inc"
51 void Select(
SDNode *
N)
override;
54 template <
unsigned NodeType>
bool select(
SDNode *
N);
55 bool selectMultiplication(
SDNode *
N);
86 int RHSC = (int)RHS->getZExtValue();
98 int FI = cast<FrameIndexSDNode>(N.
getOperand(0))->getIndex();
108 MVT VT = cast<MemSDNode>(
Op)->getMemoryVT().getSimpleVT();
137 int Offs = cast<ConstantSDNode>(LD->
getOffset())->getSExtValue();
141 if ((!isPre && Offs != 1) || (isPre && Offs != -1)) {
145 Opcode = (isPre) ? AVR::LDRdPtrPd : AVR::LDRdPtrPi;
149 if ((!isPre && Offs != 2) || (isPre && Offs != -2)) {
153 Opcode = (isPre) ? AVR::LDWRdPtrPd : AVR::LDWRdPtrPi;
179 int Offs = cast<ConstantSDNode>(LD->
getOffset())->getSExtValue();
186 Opcode = AVR::LPMRdZPi;
193 Opcode = AVR::LPMWRdZPi;
204 unsigned ConstraintCode,
205 std::vector<SDValue> &OutOps) {
208 "Unexpected asm memory constraint");
221 OutOps.push_back(Op);
229 OutOps.push_back(Base);
230 OutOps.push_back(Disp);
246 bool CanHandleRegImmOpt =
true;
248 CanHandleRegImmOpt &= ImmNode != 0;
253 cast<RegisterSDNode>(CopyFromRegOp->
getOperand(1));
256 AVR::PTRDISPREGSRegClass.contains(Reg));
258 CanHandleRegImmOpt =
false;
263 if (CanHandleRegImmOpt) {
266 if (RI.
getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) {
267 SDLoc dl(CopyFromRegOp);
277 Base = NewCopyFromRegOp;
279 Base = CopyFromRegOp;
288 OutOps.push_back(Base);
289 OutOps.push_back(Disp);
304 OutOps.push_back(CopyFromReg);
309 template <>
bool AVRDAGToDAGISel::select<ISD::FrameIndex>(
SDNode *
N) {
310 auto DL = CurDAG->getDataLayout();
314 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
316 CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy(DL));
318 CurDAG->SelectNodeTo(
N, AVR::FRMIDX,
319 getTargetLowering()->getPointerTy(DL), TFI,
324 template <>
bool AVRDAGToDAGISel::select<ISD::STORE>(
SDNode *
N) {
331 if (isa<FrameIndexSDNode>(BasePtr) || isa<ConstantSDNode>(BasePtr) ||
338 if (!RN || (RN->
getReg() != AVR::SP)) {
342 int CST = (int)cast<ConstantSDNode>(BasePtr.getOperand(1))->getZExtValue();
348 unsigned Opc = (VT ==
MVT::i16) ? AVR::STDWSPQRr : AVR::STDSPQRr;
355 cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
358 CurDAG->RemoveDeadNode(
N);
363 template <>
bool AVRDAGToDAGISel::select<ISD::LOAD>(
SDNode *
N) {
367 return selectIndexedLoad(
N);
370 assert(Subtarget->hasLPM() &&
"cannot load from program memory on this mcu");
380 Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr,
SDValue());
381 Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30,
MVT::i16,
387 if (
unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT)) {
394 switch (VT.SimpleTy) {
400 ResNode = CurDAG->getMachineNode(AVR::LPMWRdZ, DL,
MVT::i16,
412 cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
416 CurDAG->RemoveDeadNode(
N);
421 template <>
bool AVRDAGToDAGISel::select<AVRISD::CALL>(
SDNode *
N) {
425 unsigned LastOpNum =
N->getNumOperands() - 1;
434 if (
N->getOperand(LastOpNum).getValueType() ==
MVT::Glue) {
439 Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
444 for (
unsigned i = 2, e = LastOpNum + 1;
i != e; ++
i) {
456 CurDAG->RemoveDeadNode(
N);
461 template <>
bool AVRDAGToDAGISel::select<ISD::BRIND>(
SDNode *
N) {
467 Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
471 CurDAG->RemoveDeadNode(
N);
476 bool AVRDAGToDAGISel::selectMultiplication(
llvm::SDNode *
N) {
483 unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
489 SDValue InGlue = SDValue(Mul, 0);
498 InChain = CopyFromLo.getValue(1);
499 InGlue = CopyFromLo.getValue(2);
509 InChain = CopyFromHi.getValue(1);
510 InGlue = CopyFromHi.getValue(2);
521 void AVRDAGToDAGISel::Select(SDNode *N) {
526 if (N->isMachineOpcode()) {
540 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
541 unsigned Opcode = N->getOpcode();
555 default:
return false;
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint64_t getZExtValue() const
Get zero extended value.
bool selectIndexedLoad(SDNode *N)
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
const SDValue & getOperand(unsigned Num) const
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode...
const SDValue & getBasePtr() const
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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), MachineInstr opcode, and operands.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
const TargetLowering * getTargetLowering() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
const AVRTargetLowering * getTargetLowering() const override
Reg
All possible values of the reg field in the ModR/M byte.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
A generic AVR implementation.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
SDValue getTargetFrameIndex(int FI, EVT VT)
Simple integer binary arithmetic operators.
const SDValue & getBasePtr() const
const APInt & getAPIntValue() const
EVT getMemoryVT() const
Return the type of the in-memory value.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
const DataLayout & getDataLayout() const
This class is used to represent ISD::STORE nodes.
SDNode * getNode() const
get the SDNode which holds the desired result
CodeGenOpt::Level OptLevel
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp)
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
const SDValue & getValue() const
EVT - Extended Value Type.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getOffset() const
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
A specific AVR target MCU.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
EVT getValueType() const
Return the ValueType of the referenced return value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
StringRef - Represent a constant reference to a string, i.e.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
This class is used to represent ISD::LOAD nodes.