33 #define DEBUG_TYPE "msp430-isel"
36 struct MSP430ISelAddressMode {
55 MSP430ISelAddressMode()
56 : BaseType(RegBase), Disp(0), GV(
nullptr),
CP(
nullptr),
57 BlockAddr(
nullptr), ES(
nullptr),
JT(-1), Align(0) {
60 bool hasSymbolicDisplacement()
const {
61 return GV !=
nullptr ||
CP !=
nullptr || ES !=
nullptr ||
JT != -1;
65 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
66 if (BaseType == RegBase && Base.Reg.getNode() !=
nullptr) {
67 errs() <<
"Base.Reg ";
68 Base.Reg.getNode()->dump();
69 }
else if (BaseType == FrameIndexBase) {
70 errs() <<
" Base.FrameIndex " << Base.FrameIndex <<
'\n';
72 errs() <<
" Disp " << Disp <<
'\n';
79 errs() <<
" Align" << Align <<
'\n';
84 errs() <<
" JT" <<
JT <<
" Align" << Align <<
'\n';
99 return "MSP430 DAG->DAG Pattern Instruction Selection";
102 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
103 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
104 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
106 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
107 std::vector<SDValue> &OutOps)
override;
110 #include "MSP430GenDAGISel.inc"
127 return new MSP430DAGToDAGISel(TM, OptLevel);
134 bool MSP430DAGToDAGISel::MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM) {
137 if (AM.hasSymbolicDisplacement())
143 AM.GV =
G->getGlobal();
144 AM.Disp +=
G->getOffset();
147 AM.CP =
CP->getConstVal();
148 AM.Align =
CP->getAlignment();
149 AM.Disp +=
CP->getOffset();
152 AM.ES = S->getSymbol();
155 AM.JT = J->getIndex();
158 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
166 bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
168 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
174 AM.BaseType = MSP430ISelAddressMode::RegBase;
179 bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
180 DEBUG(
errs() <<
"MatchAddress: "; AM.dump());
185 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
191 if (!MatchWrapper(N, AM))
196 if (AM.BaseType == MSP430ISelAddressMode::RegBase
197 && AM.Base.Reg.getNode() ==
nullptr) {
198 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
199 AM.Base.FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
205 MSP430ISelAddressMode Backup = AM;
221 MSP430ISelAddressMode Backup = AM;
222 uint64_t
Offset = CN->getSExtValue();
228 CurDAG->MaskedValueIsZero(N.
getOperand(0), CN->getAPIntValue())) {
237 return MatchAddressBase(N, AM);
243 bool MSP430DAGToDAGISel::SelectAddr(
SDValue N,
245 MSP430ISelAddressMode AM;
247 if (MatchAddress(N, AM))
251 if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
252 if (!AM.Base.Reg.getNode())
253 AM.Base.Reg = CurDAG->getRegister(0, VT);
256 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
257 ? CurDAG->getTargetFrameIndex(
259 getTargetLowering()->getPointerTy(CurDAG->getDataLayout()))
263 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(N),
267 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i16,
268 AM.Align, AM.Disp, 0);
270 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i16, 0);
271 else if (AM.JT != -1)
272 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i16, 0);
273 else if (AM.BlockAddr)
274 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, 0,
277 Disp = CurDAG->getTargetConstant(AM.Disp,
SDLoc(N),
MVT::i16);
282 bool MSP430DAGToDAGISel::
283 SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
284 std::vector<SDValue> &OutOps) {
286 switch (ConstraintID) {
287 default:
return true;
289 if (!SelectAddr(Op, Op0, Op1))
294 OutOps.push_back(Op0);
295 OutOps.push_back(Op1);
309 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 1)
315 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 2)
326 bool MSP430DAGToDAGISel::tryIndexedLoad(
SDNode *N) {
336 Opcode = MSP430::MOV8rm_POST;
339 Opcode = MSP430::MOV16rm_POST;
352 unsigned Opc8,
unsigned Opc16) {
355 IsLegalToFold(N1, Op, Op, OptLevel)) {
361 unsigned Opc = (VT ==
MVT::i16 ? Opc16 : Opc8);
363 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
367 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
401 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
404 CurDAG->SelectNodeTo(Node, MSP430::ADD16ri,
MVT::i16, TFI,
405 CurDAG->getTargetConstant(0, dl,
MVT::i16));
408 ReplaceNode(Node, CurDAG->getMachineNode(
410 CurDAG->getTargetConstant(0, dl,
MVT::i16)));
414 if (tryIndexedLoad(Node))
420 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
423 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
430 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
437 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
440 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
447 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
450 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
457 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
460 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
const SDValue & getOperand(unsigned Num) const
void setNodeId(int Id)
Set unique node id.
const SDValue & getBasePtr() const
FunctionPass * createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
createMSP430ISelDag - This pass converts a legalized DAG into a MSP430-specific DAG, ready for instruction scheduling.
The address of a basic block.
A description of a memory reference used in the backend.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Reg
All possible values of the reg field in the ModR/M byte.
Simple integer binary arithmetic operators.
EVT getMemoryVT() const
Return the type of the in-memory value.
SDNode * getNode() const
get the SDNode which holds the desired result
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
EVT - Extended Value Type.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
const SDValue & getOffset() const
void dump() const
Dump this node, for debugging.
const SDValue & getChain() const
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...
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
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...
static bool isValidIndexedLoad(const LoadSDNode *LD)
Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
EVT getValueType() const
Return the ValueType of the referenced return value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
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.