23 #include "llvm/Config/llvm-config.h" 34 #define DEBUG_TYPE "msp430-isel" 37 struct MSP430ISelAddressMode {
56 MSP430ISelAddressMode()
57 :
BaseType(RegBase), Disp(0), GV(
nullptr),
CP(
nullptr),
58 BlockAddr(
nullptr), ES(
nullptr),
JT(-1),
Align(0) {
61 bool hasSymbolicDisplacement()
const {
62 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr || JT != -1;
65 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 67 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
68 if (BaseType == RegBase &&
Base.Reg.getNode() !=
nullptr) {
69 errs() <<
"Base.Reg ";
70 Base.Reg.getNode()->dump();
71 }
else if (BaseType == FrameIndexBase) {
72 errs() <<
" Base.FrameIndex " <<
Base.FrameIndex <<
'\n';
74 errs() <<
" Disp " << Disp <<
'\n';
81 errs() <<
" Align" << Align <<
'\n';
86 errs() <<
" JT" << JT <<
" Align" << Align <<
'\n';
103 return "MSP430 DAG->DAG Pattern Instruction Selection";
106 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
107 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
108 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
110 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
111 std::vector<SDValue> &OutOps)
override;
114 #include "MSP430GenDAGISel.inc" 119 bool tryIndexedLoad(
SDNode *Op);
132 return new MSP430DAGToDAGISel(TM, OptLevel);
139 bool MSP430DAGToDAGISel::MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM) {
142 if (AM.hasSymbolicDisplacement())
148 AM.GV =
G->getGlobal();
149 AM.Disp +=
G->getOffset();
152 AM.CP =
CP->getConstVal();
153 AM.Align =
CP->getAlignment();
154 AM.Disp +=
CP->getOffset();
157 AM.ES = S->getSymbol();
160 AM.JT = J->getIndex();
163 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
171 bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
173 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
179 AM.BaseType = MSP430ISelAddressMode::RegBase;
184 bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
190 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
196 if (!MatchWrapper(N, AM))
201 if (AM.BaseType == MSP430ISelAddressMode::RegBase
202 && AM.Base.Reg.getNode() ==
nullptr) {
203 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
204 AM.Base.FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
210 MSP430ISelAddressMode Backup = AM;
226 MSP430ISelAddressMode Backup = AM;
227 uint64_t
Offset = CN->getSExtValue();
233 CurDAG->MaskedValueIsZero(N.
getOperand(0), CN->getAPIntValue())) {
242 return MatchAddressBase(N, AM);
248 bool MSP430DAGToDAGISel::SelectAddr(
SDValue N,
250 MSP430ISelAddressMode AM;
252 if (MatchAddress(N, AM))
255 if (AM.BaseType == MSP430ISelAddressMode::RegBase)
256 if (!AM.Base.Reg.getNode())
257 AM.Base.Reg = CurDAG->getRegister(MSP430::SR,
MVT::i16);
259 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
260 ? CurDAG->getTargetFrameIndex(
262 getTargetLowering()->getPointerTy(CurDAG->getDataLayout()))
266 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(N),
270 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i16,
271 AM.Align, AM.Disp, 0);
273 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i16, 0);
274 else if (AM.JT != -1)
275 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i16, 0);
276 else if (AM.BlockAddr)
277 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, 0,
280 Disp = CurDAG->getTargetConstant(AM.Disp,
SDLoc(N),
MVT::i16);
285 bool MSP430DAGToDAGISel::
286 SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
287 std::vector<SDValue> &OutOps) {
289 switch (ConstraintID) {
290 default:
return true;
292 if (!SelectAddr(Op, Op0, Op1))
297 OutOps.push_back(Op0);
298 OutOps.push_back(Op1);
312 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 1)
318 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 2)
329 bool MSP430DAGToDAGISel::tryIndexedLoad(
SDNode *N) {
339 Opcode = MSP430::MOV8rp;
342 Opcode = MSP430::MOV16rp;
355 unsigned Opc8,
unsigned Opc16) {
358 IsLegalToFold(N1, Op, Op, OptLevel)) {
364 unsigned Opc = (VT ==
MVT::i16 ? Opc16 : Opc8);
369 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemRef});
396 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
399 CurDAG->SelectNodeTo(Node, MSP430::ADDframe,
MVT::i16, TFI,
400 CurDAG->getTargetConstant(0, dl,
MVT::i16));
403 ReplaceNode(Node, CurDAG->getMachineNode(
404 MSP430::ADDframe, dl,
MVT::i16, TFI,
405 CurDAG->getTargetConstant(0, dl,
MVT::i16)));
409 if (tryIndexedLoad(Node))
415 MSP430::ADD8rp, MSP430::ADD16rp))
418 MSP430::ADD8rp, MSP430::ADD16rp))
425 MSP430::SUB8rp, MSP430::SUB16rp))
432 MSP430::AND8rp, MSP430::AND16rp))
435 MSP430::AND8rp, MSP430::AND16rp))
442 MSP430::BIS8rp, MSP430::BIS16rp))
445 MSP430::BIS8rp, MSP430::BIS16rp))
452 MSP430::XOR8rp, MSP430::XOR16rp))
455 MSP430::XOR8rp, MSP430::XOR16rp))
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
const SDValue & getOffset() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents lattice values for constants.
const SDValue & getBasePtr() const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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.
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
FunctionPass * createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
createMSP430ISelDag - This pass converts a legalized DAG into a MSP430-specific DAG, ready for instruction scheduling.
void dump() const
Support for debugging, callable in GDB: V->dump()
The address of a basic block.
bool hasOneUse() const
Return true if there is exactly one use of this node.
A description of a memory reference used in the backend.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Simple integer binary arithmetic operators.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
This is an important base class in LLVM.
const SDValue & getOperand(unsigned Num) const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
FunctionPass class - This class is used to implement most global optimizations.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
void dump() const
Dump this node, for debugging.
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...
EVT getMemoryVT() const
Return the type of the in-memory value.
Bitwise operators - logical and, logical or, logical xor.
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
unsigned getOpcode() const
static bool isValidIndexedLoad(const LoadSDNode *LD)
Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
const SDValue & getOperand(unsigned i) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
This file describes how to lower LLVM code to machine code.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
This class is used to represent ISD::LOAD nodes.