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';
96 MSP430DAGToDAGISel() =
delete;
102 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
103 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
104 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
107 std::vector<SDValue> &OutOps)
override;
110 #include "MSP430GenDAGISel.inc"
115 bool tryIndexedLoad(
SDNode *Op);
123char MSP430DAGToDAGISel::ID;
131 CodeGenOpt::Level OptLevel) {
132 return new MSP430DAGToDAGISel(
TM, OptLevel);
139bool 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.Alignment =
CP->getAlign();
154 AM.Disp +=
CP->getOffset();
157 AM.ES = S->getSymbol();
160 AM.JT = J->getIndex();
163 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
171bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
173 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
179 AM.BaseType = MSP430ISelAddressMode::RegBase;
184bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
187 switch (
N.getOpcode()) {
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;
211 if (!MatchAddress(
N.getNode()->getOperand(0), AM) &&
212 !MatchAddress(
N.getNode()->getOperand(1), AM))
215 if (!MatchAddress(
N.getNode()->getOperand(1), AM) &&
216 !MatchAddress(
N.getNode()->getOperand(0), AM))
226 MSP430ISelAddressMode Backup = AM;
229 if (!MatchAddress(
N.getOperand(0), AM) &&
233 CurDAG->MaskedValueIsZero(
N.getOperand(0), CN->getAPIntValue())) {
242 return MatchAddressBase(
N, AM);
248bool 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(
266 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(
N),
270 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, AM.Alignment, AM.Disp,
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);
285bool MSP430DAGToDAGISel::
286SelectInlineAsmMemoryOperand(
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);
307 EVT VT = LD->getMemoryVT();
311 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
316 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
327bool MSP430DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
332 MVT VT =
LD->getMemoryVT().getSimpleVT();
337 Opcode = MSP430::MOV8rp;
340 Opcode = MSP430::MOV16rp;
347 CurDAG->getMachineNode(Opcode,
SDLoc(
N), VT, MVT::i16, MVT::Other,
348 LD->getBasePtr(),
LD->getChain()));
353 unsigned Opc8,
unsigned Opc16) {
356 IsLegalToFold(N1, Op, Op, OptLevel)) {
361 MVT VT =
LD->getMemoryVT().getSimpleVT();
362 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
364 SDValue Ops0[] = { N2,
LD->getBasePtr(),
LD->getChain() };
366 CurDAG->SelectNodeTo(Op, Opc, VT, MVT::i16, MVT::Other, Ops0);
367 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {
MemRef});
379void MSP430DAGToDAGISel::Select(
SDNode *
Node) {
383 if (
Node->isMachineOpcode()) {
390 switch (
Node->getOpcode()) {
394 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
395 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
396 if (
Node->hasOneUse()) {
397 CurDAG->SelectNodeTo(
Node, MSP430::ADDframe, MVT::i16, TFI,
398 CurDAG->getTargetConstant(0, dl, MVT::i16));
401 ReplaceNode(
Node, CurDAG->getMachineNode(
402 MSP430::ADDframe, dl, MVT::i16, TFI,
403 CurDAG->getTargetConstant(0, dl, MVT::i16)));
407 if (tryIndexedLoad(
Node))
412 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
413 MSP430::ADD8rp, MSP430::ADD16rp))
415 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
416 MSP430::ADD8rp, MSP430::ADD16rp))
422 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
423 MSP430::SUB8rp, MSP430::SUB16rp))
429 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
430 MSP430::AND8rp, MSP430::AND16rp))
432 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
433 MSP430::AND8rp, MSP430::AND16rp))
439 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
440 MSP430::BIS8rp, MSP430::BIS16rp))
442 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
443 MSP430::BIS8rp, MSP430::BIS16rp))
449 if (tryIndexedBinOp(
Node,
Node->getOperand(0),
Node->getOperand(1),
450 MSP430::XOR8rp, MSP430::XOR16rp))
452 else if (tryIndexedBinOp(
Node,
Node->getOperand(1),
Node->getOperand(0),
453 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)
const char LLVMTargetMachineRef TM
#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.
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, unsigned 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.
Level
Code generation optimization level.
@ 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)
FunctionPass * createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
createMSP430ISelDag - This pass converts a legalized DAG into a MSP430-specific DAG,...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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.