aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-11-07 17:15:25 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-11-07 17:15:25 +0000
commit06ac0820a6cefa6896000054d8e4906326c0cce6 (patch)
tree1eff001505153a8027814a64d425a15d895338fc
parent6534f83ae8c39284ae51fbf478ce0c37d0c892a2 (diff)
downloadexternal_llvm-06ac0820a6cefa6896000054d8e4906326c0cce6.zip
external_llvm-06ac0820a6cefa6896000054d8e4906326c0cce6.tar.gz
external_llvm-06ac0820a6cefa6896000054d8e4906326c0cce6.tar.bz2
First try of the post-inc operands handling... Not fully worked, though :(
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86386 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp87
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp2
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td9
3 files changed, 87 insertions, 11 deletions
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index b45690b..ac01bf8 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -43,6 +43,9 @@ ViewRMWDAGs("view-msp430-rmw-dags", cl::Hidden,
static const bool ViewRMWDAGs = false;
#endif
+static cl::opt<bool>
+EnablePostIncOps("enable-msp430-post-inc-ops", cl::Hidden);
+
STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
@@ -148,6 +151,9 @@ namespace {
void PreprocessForRMW();
SDNode *Select(SDValue Op);
SDNode *SelectIndexedLoad(SDValue Op);
+ SDNode *SelectIndexedBinOp(SDValue Op, SDValue N1, SDValue N2,
+ unsigned Opc8, unsigned Opc16);
+
bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
#ifndef NDEBUG
@@ -598,39 +604,85 @@ void MSP430DAGToDAGISel::PreprocessForRMW() {
}
-SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+static bool isValidIndexedLoad(const LoadSDNode *LD) {
ISD::MemIndexedMode AM = LD->getAddressingMode();
if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
- return NULL;
+ return false;
EVT VT = LD->getMemoryVT();
- unsigned Opcode = 0;
switch (VT.getSimpleVT().SimpleTy) {
case MVT::i8:
// Sanity check
if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
- return NULL;
+ return false;
- Opcode = MSP430::MOV8rm_POST;
break;
case MVT::i16:
// Sanity check
if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
- return NULL;
+ return false;
+
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
+ LoadSDNode *LD = cast<LoadSDNode>(Op);
+ if (!isValidIndexedLoad(LD))
+ return NULL;
+
+ MVT VT = LD->getMemoryVT().getSimpleVT();
+
+ unsigned Opcode = 0;
+ switch (VT.SimpleTy) {
+ case MVT::i8:
+ Opcode = MSP430::MOV8rm_POST;
+ break;
+ case MVT::i16:
Opcode = MSP430::MOV16rm_POST;
break;
default:
return NULL;
}
- return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(),
- VT.getSimpleVT().SimpleTy, MVT::i16, MVT::Other,
- LD->getBasePtr(), LD->getChain());
+ return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(),
+ VT, MVT::i16, MVT::Other,
+ LD->getBasePtr(), LD->getChain());
}
+SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op,
+ SDValue N1, SDValue N2,
+ unsigned Opc8, unsigned Opc16) {
+ if (N1.getOpcode() == ISD::LOAD &&
+ N1.hasOneUse() &&
+ IsLegalAndProfitableToFold(N1.getNode(), Op.getNode(), Op.getNode())) {
+ LoadSDNode *LD = cast<LoadSDNode>(N1);
+ if (!isValidIndexedLoad(LD))
+ return NULL;
+
+ MVT VT = LD->getMemoryVT().getSimpleVT();
+ unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
+ MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
+ MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
+ SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
+ SDNode *ResNode =
+ CurDAG->SelectNodeTo(Op.getNode(), Opc,
+ VT, MVT::i16, MVT::Other,
+ Ops0, 3);
+ cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
+ ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 3));
+ return ResNode;
+ }
+
+ return NULL;
+}
+
+
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void MSP430DAGToDAGISel::InstructionSelect() {
@@ -693,6 +745,21 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
return ResNode;
// Other cases are autogenerated.
break;
+ case ISD::ADD:
+ if (EnablePostIncOps) {
+ if (SDNode *ResNode =
+ SelectIndexedBinOp(Op,
+ Op.getOperand(0), Op.getOperand(1),
+ MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
+ return ResNode;
+ else if (SDNode *ResNode =
+ SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
+ return ResNode;
+ }
+
+ // Other cases are autogenerated.
+ break;
}
// Select the default instruction
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 47a9777..326ea9a 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -62,7 +62,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
setBooleanContents(ZeroOrOneBooleanContent);
setSchedulingPreference(SchedulingForLatency);
- // We have post-incremented loads / stores
+ // We have post-incremented loads / stores.
setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 6d7b87c..33e468d 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -287,6 +287,15 @@ def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
[(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
(implicit SRW)]>;
+let mayLoad = 1, hasExtraDefRegAllocReq = 1,
+Constraints = "$base = $base_wb, $src1 = $dst" in {
+def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
+ "add.b\t{@$base+, $dst}", []>;
+def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
+ "add.w\t{@$base+, $dst}", []>;
+}
+
+
def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
"add.b\t{$src2, $dst}",
[(set GR8:$dst, (add GR8:$src1, imm:$src2)),