21 #include "llvm/Config/llvm-config.h"
32 #define DEBUG_TYPE "msp430-isel"
35 struct MSP430ISelAddressMode {
50 const char *ES =
nullptr;
54 MSP430ISelAddressMode() =
default;
56 bool hasSymbolicDisplacement()
const {
57 return GV !=
nullptr ||
CP !=
nullptr || ES !=
nullptr ||
JT != -1;
60 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
62 errs() <<
"MSP430ISelAddressMode " <<
this <<
'\n';
63 if (
BaseType == RegBase &&
Base.Reg.getNode() !=
nullptr) {
64 errs() <<
"Base.Reg ";
65 Base.Reg.getNode()->dump();
66 }
else if (
BaseType == FrameIndexBase) {
67 errs() <<
" Base.FrameIndex " <<
Base.FrameIndex <<
'\n';
69 errs() <<
" Disp " << Disp <<
'\n';
76 errs() <<
" Align" << Alignment.value() <<
'\n';
81 errs() <<
" JT" <<
JT <<
" Align" << Alignment.value() <<
'\n';
98 return "MSP430 DAG->DAG Pattern Instruction Selection";
101 bool MatchAddress(
SDValue N, MSP430ISelAddressMode &AM);
102 bool MatchWrapper(
SDValue N, MSP430ISelAddressMode &AM);
103 bool MatchAddressBase(
SDValue N, MSP430ISelAddressMode &AM);
105 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
106 std::vector<SDValue> &OutOps)
override;
109 #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.Alignment =
CP->getAlign();
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) {
182 switch (
N.getOpcode()) {
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;
206 if (!MatchAddress(
N.getNode()->getOperand(0), AM) &&
207 !MatchAddress(
N.getNode()->getOperand(1), AM))
210 if (!MatchAddress(
N.getNode()->getOperand(1), AM) &&
211 !MatchAddress(
N.getNode()->getOperand(0), AM))
221 MSP430ISelAddressMode Backup = AM;
224 if (!MatchAddress(
N.getOperand(0), AM) &&
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))
250 if (AM.BaseType == MSP430ISelAddressMode::RegBase)
251 if (!AM.Base.Reg.getNode())
252 AM.Base.Reg = CurDAG->getRegister(MSP430::SR,
MVT::i16);
254 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
255 ? CurDAG->getTargetFrameIndex(
261 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(
N),
265 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i16, AM.Alignment, AM.Disp,
268 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i16, 0);
269 else if (AM.JT != -1)
270 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i16, 0);
271 else if (AM.BlockAddr)
272 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, 0,
280 bool MSP430DAGToDAGISel::
281 SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
282 std::vector<SDValue> &OutOps) {
284 switch (ConstraintID) {
285 default:
return true;
287 if (!SelectAddr(
Op, Op0, Op1))
292 OutOps.push_back(Op0);
293 OutOps.push_back(Op1);
302 EVT VT =
LD->getMemoryVT();
306 if (cast<ConstantSDNode>(
LD->getOffset())->getZExtValue() != 1)
311 if (cast<ConstantSDNode>(
LD->getOffset())->getZExtValue() != 2)
322 bool MSP430DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
327 MVT VT =
LD->getMemoryVT().getSimpleVT();
332 Opcode = MSP430::MOV8rp;
335 Opcode = MSP430::MOV16rp;
343 LD->getBasePtr(),
LD->getChain()));
348 unsigned Opc8,
unsigned Opc16) {
351 IsLegalToFold(N1,
Op,
Op, OptLevel)) {
356 MVT VT =
LD->getMemoryVT().getSimpleVT();
357 unsigned Opc = (VT ==
MVT::i16 ? Opc16 : Opc8);
359 SDValue Ops0[] = { N2,
LD->getBasePtr(),
LD->getChain() };
362 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {
MemRef});
378 if (Node->isMachineOpcode()) {
385 switch (Node->getOpcode()) {
389 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
391 if (Node->hasOneUse()) {
392 CurDAG->SelectNodeTo(Node, MSP430::ADDframe,
MVT::i16, TFI,
393 CurDAG->getTargetConstant(0, dl,
MVT::i16));
396 ReplaceNode(Node, CurDAG->getMachineNode(
397 MSP430::ADDframe, dl,
MVT::i16, TFI,
398 CurDAG->getTargetConstant(0, dl,
MVT::i16)));
402 if (tryIndexedLoad(Node))
407 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
408 MSP430::ADD8rp, MSP430::ADD16rp))
410 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
411 MSP430::ADD8rp, MSP430::ADD16rp))
417 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
418 MSP430::SUB8rp, MSP430::SUB16rp))
424 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
425 MSP430::AND8rp, MSP430::AND16rp))
427 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
428 MSP430::AND8rp, MSP430::AND16rp))
434 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
435 MSP430::BIS8rp, MSP430::BIS16rp))
437 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
438 MSP430::BIS8rp, MSP430::BIS16rp))
444 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
445 MSP430::XOR8rp, MSP430::XOR16rp))
447 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
448 MSP430::XOR8rp, MSP430::XOR16rp))