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) {
314 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
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;
361 template <>
bool AVRDAGToDAGISel::select<ISD::LOAD>(
SDNode *
N) {
368 assert(Subtarget->
hasLPM() &&
"cannot load from program memory on this mcu");
392 switch (VT.SimpleTy) {
417 template <>
bool AVRDAGToDAGISel::select<AVRISD::CALL>(
SDNode *
N) {
421 unsigned LastOpNum =
N->getNumOperands() - 1;
430 if (
N->getOperand(LastOpNum).getValueType() ==
MVT::Glue) {
440 for (
unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
457 template <>
bool AVRDAGToDAGISel::select<ISD::BRIND>(
SDNode *
N) {
472 bool AVRDAGToDAGISel::selectMultiplication(
llvm::SDNode *
N) {
479 unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
517 void AVRDAGToDAGISel::Select(
SDNode *N) {
533 bool AVRDAGToDAGISel::trySelect(
SDNode *N) {
548 default:
return false;
SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOffset() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
bool selectIndexedLoad(SDNode *N)
This class represents lattice values for constants.
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const SDValue & getValue() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
const SDValue & getChain() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode...
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
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 AVRTargetLowering * getTargetLowering() const override
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
const DataLayout & getDataLayout() const
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.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
amdgpu Simplify well known AMD library false Value * Callee
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
CodeGenOpt::Level OptLevel
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...
The instances of the Type class are immutable: once they are created, they are never changed...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
const SDValue & getOperand(unsigned Num) const
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
const APInt & getAPIntValue() 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).
AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void dump() const
Dump this node, for debugging.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
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)
EVT getMemoryVT() const
Return the type of the in-memory value.
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.
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)
unsigned getOpcode() const
SDValue getValue(unsigned R) const
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
const TargetLowering * getTargetLowering() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getRegister(unsigned Reg, EVT VT)
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
StringRef - Represent a constant reference to a string, i.e.
const SDValue & getOperand(unsigned i) const
void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand *> NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
This class is used to represent ISD::LOAD nodes.