21#include "llvm/Config/llvm-config.h"
32#define DEBUG_TYPE "msp430-isel"
33#define PASS_NAME "MSP430 DAG->DAG Pattern Instruction Selection"
36 struct MSP430ISelAddressMode {
51 const char *ES =
nullptr;
55 MSP430ISelAddressMode() =
default;
57 bool hasSymbolicDisplacement()
const {
58 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr || JT != -1;
61#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
63 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
64 if (
BaseType == RegBase &&
Base.Reg.getNode() !=
nullptr) {
65 errs() <<
"Base.Reg ";
66 Base.Reg.getNode()->dump();
67 }
else if (
BaseType == FrameIndexBase) {
68 errs() <<
" Base.FrameIndex " <<
Base.FrameIndex <<
'\n';
70 errs() <<
" Disp " << Disp <<
'\n';
77 errs() <<
" Align" << Alignment.
value() <<
'\n';
82 errs() <<
" JT" << JT <<
" Align" << Alignment.
value() <<
'\n';
94 MSP430DAGToDAGISel() =
delete;
100 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
101 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
102 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
106 std::vector<SDValue> &OutOps)
override;
109 #include "MSP430GenDAGISel.inc"
126 ID,
std::make_unique<MSP430DAGToDAGISel>(
TM, OptLevel)) {}
130char MSP430DAGToDAGISelLegacy::ID;
139 return new MSP430DAGToDAGISelLegacy(TM, OptLevel);
145bool MSP430DAGToDAGISel::MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM) {
148 if (AM.hasSymbolicDisplacement())
154 AM.GV =
G->getGlobal();
155 AM.Disp +=
G->getOffset();
158 AM.CP =
CP->getConstVal();
159 AM.Alignment =
CP->getAlign();
160 AM.Disp +=
CP->getOffset();
163 AM.ES = S->getSymbol();
166 AM.JT = J->getIndex();
169 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
177bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
179 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
185 AM.BaseType = MSP430ISelAddressMode::RegBase;
190bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
193 switch (
N.getOpcode()) {
196 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
202 if (!MatchWrapper(
N, AM))
207 if (AM.BaseType == MSP430ISelAddressMode::RegBase
208 && AM.Base.Reg.getNode() ==
nullptr) {
209 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
210 AM.Base.FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
216 MSP430ISelAddressMode Backup = AM;
217 if (!MatchAddress(
N.getNode()->getOperand(0), AM) &&
218 !MatchAddress(
N.getNode()->getOperand(1), AM))
221 if (!MatchAddress(
N.getNode()->getOperand(1), AM) &&
222 !MatchAddress(
N.getNode()->getOperand(0), AM))
232 MSP430ISelAddressMode Backup = AM;
235 if (!MatchAddress(
N.getOperand(0), AM) &&
239 CurDAG->MaskedValueIsZero(
N.getOperand(0), CN->getAPIntValue())) {
248 return MatchAddressBase(
N, AM);
254bool MSP430DAGToDAGISel::SelectAddr(
SDValue N,
256 MSP430ISelAddressMode AM;
258 if (MatchAddress(
N, AM))
261 if (AM.BaseType == MSP430ISelAddressMode::RegBase)
262 if (!AM.Base.Reg.getNode())
263 AM.Base.Reg = CurDAG->getRegister(MSP430::SR, MVT::i16);
265 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
266 ? CurDAG->getTargetFrameIndex(
272 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(
N),
276 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, AM.Alignment, AM.Disp,
279 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0);
280 else if (AM.JT != -1)
281 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0);
282 else if (AM.BlockAddr)
283 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
286 Disp = CurDAG->getTargetConstant(AM.Disp,
SDLoc(
N), MVT::i16);
291bool MSP430DAGToDAGISel::SelectInlineAsmMemoryOperand(
293 std::vector<SDValue> &OutOps) {
295 switch (ConstraintID) {
296 default:
return true;
297 case InlineAsm::ConstraintCode::m:
298 if (!SelectAddr(
Op, Op0, Op1))
303 OutOps.push_back(Op0);
304 OutOps.push_back(Op1);
313 EVT VT = LD->getMemoryVT();
317 if (LD->getOffset()->getAsZExtVal() != 1)
322 if (LD->getOffset()->getAsZExtVal() != 2)
333bool MSP430DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
338 MVT VT =
LD->getMemoryVT().getSimpleVT();
343 Opcode = MSP430::MOV8rp;
346 Opcode = MSP430::MOV16rp;
353 CurDAG->getMachineNode(Opcode,
SDLoc(
N), VT, MVT::i16, MVT::Other,
354 LD->getBasePtr(),
LD->getChain()));
359 unsigned Opc8,
unsigned Opc16) {
362 IsLegalToFold(N1,
Op,
Op, OptLevel)) {
367 MVT VT =
LD->getMemoryVT().getSimpleVT();
368 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
370 SDValue Ops0[] = { N2,
LD->getBasePtr(),
LD->getChain() };
372 CurDAG->SelectNodeTo(
Op, Opc, VT, MVT::i16, MVT::Other, Ops0);
373 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {
MemRef});
385void MSP430DAGToDAGISel::Select(
SDNode *
Node) {
389 if (
Node->isMachineOpcode()) {
396 switch (
Node->getOpcode()) {
400 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
401 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
402 if (
Node->hasOneUse()) {
403 CurDAG->SelectNodeTo(
Node, MSP430::ADDframe, MVT::i16, TFI,
404 CurDAG->getTargetConstant(0, dl, MVT::i16));
407 ReplaceNode(
Node, CurDAG->getMachineNode(
408 MSP430::ADDframe, dl, MVT::i16, TFI,
409 CurDAG->getTargetConstant(0, dl, MVT::i16)));
413 if (tryIndexedLoad(
Node))
418 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
419 MSP430::ADD8rp, MSP430::ADD16rp))
421 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
422 MSP430::ADD8rp, MSP430::ADD16rp))
428 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
429 MSP430::SUB8rp, MSP430::SUB16rp))
435 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
436 MSP430::AND8rp, MSP430::AND16rp))
438 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
439 MSP430::AND8rp, MSP430::AND16rp))
445 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
446 MSP430::BIS8rp, MSP430::BIS16rp))
448 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
449 MSP430::BIS8rp, MSP430::BIS16rp))
455 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
456 MSP430::XOR8rp, MSP430::XOR16rp))
458 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
459 MSP430::XOR8rp, MSP430::XOR16rp))
amdgpu AMDGPU Register Bank Select
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isValidIndexedLoad(const LoadSDNode *LD)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DEMANGLE_DUMP_METHOD void dump() const
The address of a basic block.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
This class is used to represent ISD::LOAD nodes.
A description of a memory reference used in the backend.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
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.
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
void dump() const
Support for debugging, callable in GDB: V->dump()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ AND
Bitwise operators - logical and, logical or, logical xor.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
@ Wrapper
Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
CodeGenOptLevel
Code generation optimization level.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel)
createMSP430ISelDag - This pass converts a legalized DAG into a MSP430-specific DAG,...
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.