20#include "llvm/Config/llvm-config.h"
28#define DEBUG_TYPE "msp430-isel"
29#define PASS_NAME "MSP430 DAG->DAG Pattern Instruction Selection"
32 struct MSP430ISelAddressMode {
47 const char *ES =
nullptr;
51 MSP430ISelAddressMode() =
default;
53 bool hasSymbolicDisplacement()
const {
54 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr || JT != -1;
57#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
59 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
60 if (
BaseType == RegBase &&
Base.Reg.getNode() !=
nullptr) {
61 errs() <<
"Base.Reg ";
62 Base.Reg.getNode()->dump();
63 }
else if (
BaseType == FrameIndexBase) {
64 errs() <<
" Base.FrameIndex " <<
Base.FrameIndex <<
'\n';
66 errs() <<
" Disp " << Disp <<
'\n';
73 errs() <<
" Align" << Alignment.
value() <<
'\n';
78 errs() <<
" JT" << JT <<
" Align" << Alignment.
value() <<
'\n';
90 MSP430DAGToDAGISel() =
delete;
93 : SelectionDAGISel(
TM, OptLevel) {}
96 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
97 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
98 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
100 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
102 std::vector<SDValue> &OutOps)
override;
105 #include "MSP430GenDAGISel.inc"
108 void Select(SDNode *
N)
override;
110 bool tryIndexedLoad(SDNode *
Op);
120 MSP430DAGToDAGISelLegacy(MSP430TargetMachine &TM,
CodeGenOptLevel OptLevel)
121 : SelectionDAGISelLegacy(
122 ID, std::make_unique<MSP430DAGToDAGISel>(
TM, OptLevel)) {}
126char MSP430DAGToDAGISelLegacy::ID;
135 return new MSP430DAGToDAGISelLegacy(TM, OptLevel);
141bool MSP430DAGToDAGISel::MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM) {
144 if (AM.hasSymbolicDisplacement())
150 AM.GV =
G->getGlobal();
151 AM.Disp +=
G->getOffset();
154 AM.CP =
CP->getConstVal();
155 AM.Alignment =
CP->getAlign();
156 AM.Disp +=
CP->getOffset();
159 AM.ES = S->getSymbol();
162 AM.JT = J->getIndex();
173bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
175 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
181 AM.BaseType = MSP430ISelAddressMode::RegBase;
186bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
189 switch (
N.getOpcode()) {
197 case MSP430ISD::Wrapper:
198 if (!MatchWrapper(
N, AM))
203 if (AM.BaseType == MSP430ISelAddressMode::RegBase
204 && AM.Base.Reg.getNode() ==
nullptr) {
205 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
212 MSP430ISelAddressMode Backup = AM;
213 if (!MatchAddress(
N.getNode()->getOperand(0), AM) &&
214 !MatchAddress(
N.getNode()->getOperand(1), AM))
217 if (!MatchAddress(
N.getNode()->getOperand(1), AM) &&
218 !MatchAddress(
N.getNode()->getOperand(0), AM))
228 MSP430ISelAddressMode Backup = AM;
229 uint64_t
Offset = CN->getSExtValue();
231 if (!MatchAddress(
N.getOperand(0), AM) &&
235 CurDAG->MaskedValueIsZero(
N.getOperand(0), CN->getAPIntValue())) {
244 return MatchAddressBase(
N, AM);
250bool MSP430DAGToDAGISel::SelectAddr(
SDValue N,
252 MSP430ISelAddressMode AM;
254 if (MatchAddress(
N, AM))
257 if (AM.BaseType == MSP430ISelAddressMode::RegBase)
258 if (!AM.Base.Reg.getNode())
259 AM.Base.Reg = CurDAG->getRegister(MSP430::SR, MVT::i16);
261 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
262 ? CurDAG->getTargetFrameIndex(
268 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(
N),
272 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, AM.Alignment, AM.Disp,
275 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0);
276 else if (AM.JT != -1)
277 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0);
278 else if (AM.BlockAddr)
279 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
282 Disp = CurDAG->getSignedTargetConstant(AM.Disp, SDLoc(
N), MVT::i16);
287bool MSP430DAGToDAGISel::SelectInlineAsmMemoryOperand(
289 std::vector<SDValue> &OutOps) {
291 switch (ConstraintID) {
292 default:
return true;
293 case InlineAsm::ConstraintCode::m:
294 if (!SelectAddr(
Op, Op0, Op1))
299 OutOps.push_back(Op0);
300 OutOps.push_back(Op1);
309 EVT VT = LD->getMemoryVT();
313 if (LD->getOffset()->getAsZExtVal() != 1)
318 if (LD->getOffset()->getAsZExtVal() != 2)
329bool MSP430DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
334 MVT VT =
LD->getMemoryVT().getSimpleVT();
339 Opcode = MSP430::MOV8rp;
342 Opcode = MSP430::MOV16rp;
349 CurDAG->getMachineNode(Opcode, SDLoc(
N), VT, MVT::i16, MVT::Other,
350 LD->getBasePtr(),
LD->getChain()));
355 unsigned Opc8,
unsigned Opc16) {
358 IsLegalToFold(N1,
Op,
Op, OptLevel)) {
363 MVT VT =
LD->getMemoryVT().getSimpleVT();
364 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
366 SDValue Ops0[] = { N2,
LD->getBasePtr(),
LD->getChain() };
368 CurDAG->SelectNodeTo(
Op,
Opc, VT, MVT::i16, MVT::Other, Ops0);
381void MSP430DAGToDAGISel::Select(SDNode *Node) {
385 if (
Node->isMachineOpcode()) {
392 switch (
Node->getOpcode()) {
397 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
398 if (
Node->hasOneUse()) {
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))
414 if (tryIndexedBinOp(Node,
Node->getOperand(0),
Node->getOperand(1),
415 MSP430::ADD8rp, MSP430::ADD16rp))
417 else if (tryIndexedBinOp(Node,
Node->getOperand(1),
Node->getOperand(0),
418 MSP430::ADD8rp, MSP430::ADD16rp))
424 if (tryIndexedBinOp(Node,
Node->getOperand(0),
Node->getOperand(1),
425 MSP430::SUB8rp, MSP430::SUB16rp))
431 if (tryIndexedBinOp(Node,
Node->getOperand(0),
Node->getOperand(1),
432 MSP430::AND8rp, MSP430::AND16rp))
434 else if (tryIndexedBinOp(Node,
Node->getOperand(1),
Node->getOperand(0),
435 MSP430::AND8rp, MSP430::AND16rp))
441 if (tryIndexedBinOp(Node,
Node->getOperand(0),
Node->getOperand(1),
442 MSP430::BIS8rp, MSP430::BIS16rp))
444 else if (tryIndexedBinOp(Node,
Node->getOperand(1),
Node->getOperand(0),
445 MSP430::BIS8rp, MSP430::BIS16rp))
451 if (tryIndexedBinOp(Node,
Node->getOperand(0),
Node->getOperand(1),
452 MSP430::XOR8rp, MSP430::XOR16rp))
454 else if (tryIndexedBinOp(Node,
Node->getOperand(1),
Node->getOperand(0),
455 MSP430::XOR8rp, MSP430::XOR16rp))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
The address of a basic block.
This is an important base class in LLVM.
FunctionPass class - This class is used to implement most global optimizations.
This class is used to represent ISD::LOAD nodes.
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...
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
@ ADD
Simple integer binary arithmetic operators.
@ AND
Bitwise operators - logical and, logical or, logical xor.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
CodeGenOptLevel
Code generation optimization level.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
FunctionPass * createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOptLevel OptLevel)
createMSP430ISelDag - This pass converts a legalized DAG into a MSP430-specific DAG,...
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.