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;
66 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
67 if (BaseType == RegBase && Base.Reg.getNode() !=
nullptr) {
68 errs() <<
"Base.Reg ";
69 Base.Reg.getNode()->dump();
70 }
else if (BaseType == FrameIndexBase) {
71 errs() <<
" Base.FrameIndex " << Base.FrameIndex <<
'\n';
73 errs() <<
" Disp " << Disp <<
'\n';
99 const char *getPassName()
const override {
100 return "MSP430 DAG->DAG Pattern Instruction Selection";
103 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
104 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
105 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
107 bool SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
108 std::vector<SDValue> &OutOps)
override;
111 #include "MSP430GenDAGISel.inc"
117 unsigned Opc8,
unsigned Opc16);
128 return new MSP430DAGToDAGISel(TM, OptLevel);
135 bool MSP430DAGToDAGISel::MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM) {
138 if (AM.hasSymbolicDisplacement())
144 AM.GV =
G->getGlobal();
145 AM.Disp +=
G->getOffset();
148 AM.CP =
CP->getConstVal();
149 AM.Align =
CP->getAlignment();
150 AM.Disp +=
CP->getOffset();
153 AM.ES = S->getSymbol();
156 AM.JT = J->getIndex();
159 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
167 bool MSP430DAGToDAGISel::MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM) {
169 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
175 AM.BaseType = MSP430ISelAddressMode::RegBase;
180 bool MSP430DAGToDAGISel::MatchAddress(
SDValue N, MSP430ISelAddressMode &AM) {
181 DEBUG(
errs() <<
"MatchAddress: "; AM.dump());
186 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
192 if (!MatchWrapper(N, AM))
197 if (AM.BaseType == MSP430ISelAddressMode::RegBase
198 && AM.Base.Reg.getNode() ==
nullptr) {
199 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
200 AM.Base.FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
206 MSP430ISelAddressMode Backup = AM;
222 MSP430ISelAddressMode Backup = AM;
223 uint64_t Offset = CN->getSExtValue();
229 CurDAG->MaskedValueIsZero(N.
getOperand(0), CN->getAPIntValue())) {
238 return MatchAddressBase(N, AM);
244 bool MSP430DAGToDAGISel::SelectAddr(
SDValue N,
246 MSP430ISelAddressMode AM;
248 if (MatchAddress(N, AM))
252 if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
253 if (!AM.Base.Reg.getNode())
254 AM.Base.Reg = CurDAG->getRegister(0, VT);
257 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
258 ? CurDAG->getTargetFrameIndex(
260 getTargetLowering()->getPointerTy(CurDAG->getDataLayout()))
264 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(N),
268 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i16,
269 AM.Align, AM.Disp, 0);
271 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i16, 0);
272 else if (AM.JT != -1)
273 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i16, 0);
274 else if (AM.BlockAddr)
275 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, 0,
278 Disp = CurDAG->getTargetConstant(AM.Disp,
SDLoc(N),
MVT::i16);
283 bool MSP430DAGToDAGISel::
284 SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
285 std::vector<SDValue> &OutOps) {
287 switch (ConstraintID) {
288 default:
return true;
290 if (!SelectAddr(Op, Op0, Op1))
295 OutOps.push_back(Op0);
296 OutOps.push_back(Op1);
310 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 1)
316 if (cast<ConstantSDNode>(LD->
getOffset())->getZExtValue() != 2)
327 SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(
SDNode *N) {
337 Opcode = MSP430::MOV8rm_POST;
340 Opcode = MSP430::MOV16rm_POST;
346 return CurDAG->getMachineNode(Opcode,
SDLoc(N),
351 SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(
SDNode *Op,
353 unsigned Opc8,
unsigned Opc16) {
356 IsLegalToFold(N1, Op, Op, OptLevel)) {
362 unsigned Opc = (VT ==
MVT::i16 ? Opc16 : Opc8);
364 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
368 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
402 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
405 return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri,
MVT::i16, TFI,
406 CurDAG->getTargetConstant(0, dl,
MVT::i16));
407 return CurDAG->getMachineNode(MSP430::ADD16ri, dl,
MVT::i16, TFI,
408 CurDAG->getTargetConstant(0, dl,
MVT::i16));
411 if (
SDNode *ResNode = SelectIndexedLoad(Node))
417 SelectIndexedBinOp(Node,
419 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
421 else if (
SDNode *ResNode =
423 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
430 SelectIndexedBinOp(Node,
432 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
439 SelectIndexedBinOp(Node,
441 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
443 else if (
SDNode *ResNode =
445 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
452 SelectIndexedBinOp(Node,
454 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
456 else if (
SDNode *ResNode =
458 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
465 SelectIndexedBinOp(Node,
467 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
469 else if (
SDNode *ResNode =
471 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
479 SDNode *ResNode = SelectCode(Node);
482 if (ResNode ==
nullptr || ResNode == Node)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void dump() const
Dump this node, for debugging.
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.
BlockAddress - The address of a basic block.
MachineMemOperand - 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
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...
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
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.
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.