From 6534f83ae8c39284ae51fbf478ce0c37d0c892a2 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 7 Nov 2009 17:15:06 +0000 Subject: Add some dummy support for post-incremented loads git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86385 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 40 ++++++++++++++++++++++++++ lib/Target/MSP430/MSP430ISelLowering.cpp | 48 +++++++++++++++++++++++++++++--- lib/Target/MSP430/MSP430ISelLowering.h | 6 ++++ lib/Target/MSP430/MSP430InstrInfo.td | 7 +++++ test/CodeGen/MSP430/postinc.ll | 25 +++++++++++++++++ 5 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/MSP430/postinc.ll diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index 37a6107..b45690b 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -147,6 +147,7 @@ namespace { DenseMap RMWStores; void PreprocessForRMW(); SDNode *Select(SDValue Op); + SDNode *SelectIndexedLoad(SDValue Op); bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp); #ifndef NDEBUG @@ -596,6 +597,40 @@ void MSP430DAGToDAGISel::PreprocessForRMW() { } } + +SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) { + LoadSDNode *LD = cast(Op); + ISD::MemIndexedMode AM = LD->getAddressingMode(); + if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) + return NULL; + + EVT VT = LD->getMemoryVT(); + + unsigned Opcode = 0; + switch (VT.getSimpleVT().SimpleTy) { + case MVT::i8: + // Sanity check + if (cast(LD->getOffset())->getZExtValue() != 1) + return NULL; + + Opcode = MSP430::MOV8rm_POST; + break; + case MVT::i16: + // Sanity check + if (cast(LD->getOffset())->getZExtValue() != 2) + return NULL; + + 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()); +} + /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. void MSP430DAGToDAGISel::InstructionSelect() { @@ -653,6 +688,11 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, TFI, CurDAG->getTargetConstant(0, MVT::i16)); } + case ISD::LOAD: + if (SDNode *ResNode = SelectIndexedLoad(Op)) + 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 09be40c..47a9777 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -62,10 +62,14 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setBooleanContents(ZeroOrOneBooleanContent); setSchedulingPreference(SchedulingForLatency); - setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); + // We have post-incremented loads / stores + setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); + setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); + + setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); + setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); + setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); + setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); // We don't have any truncstores @@ -670,6 +674,42 @@ SDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, DAG.getValueType(Val.getValueType())); } +/// getPostIndexedAddressParts - returns true by value, base pointer and +/// offset pointer and addressing mode by reference if this node can be +/// combined with a load / store to form a post-indexed load / store. +bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, + SDValue &Base, + SDValue &Offset, + ISD::MemIndexedMode &AM, + SelectionDAG &DAG) const { + + LoadSDNode *LD = cast(N); + if (LD->getExtensionType() != ISD::NON_EXTLOAD) + return false; + + EVT VT = LD->getMemoryVT(); + if (VT != MVT::i8 && VT != MVT::i16) + return false; + + if (Op->getOpcode() != ISD::ADD) + return false; + + if (ConstantSDNode *RHS = dyn_cast(Op->getOperand(1))) { + uint64_t RHSC = RHS->getZExtValue(); + if ((VT == MVT::i16 && RHSC != 2) || + (VT == MVT::i8 && RHSC != 1)) + return false; + + Base = Op->getOperand(0); + Offset = DAG.getConstant(RHSC, VT); + AM = ISD::POST_INC; + return true; + } + + return false; +} + + const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return NULL; diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index fdbc384..d413ccb 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -136,6 +136,12 @@ namespace llvm { const SmallVectorImpl &Outs, DebugLoc dl, SelectionDAG &DAG); + virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, + SDValue &Base, + SDValue &Offset, + ISD::MemIndexedMode &AM, + SelectionDAG &DAG) const; + const MSP430Subtarget &Subtarget; const MSP430TargetMachine &TM; }; diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index 2b50669..6d7b87c 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -215,6 +215,13 @@ def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src), "mov.b\t{$src, $dst}", [(set GR16:$dst, (zextloadi16i8 addr:$src))]>; +let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in { +def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base), + "mov.b\t{@$base+, $dst}", []>; +def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base), + "mov.w\t{@$base+, $dst}", []>; +} + // Any instruction that defines a 8-bit result leaves the high half of the // register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may // be copying from a truncate, but any other 8-bit operation will zero-extend diff --git a/test/CodeGen/MSP430/postinc.ll b/test/CodeGen/MSP430/postinc.ll new file mode 100644 index 0000000..424b4f7 --- /dev/null +++ b/test/CodeGen/MSP430/postinc.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8" +target triple = "msp430" + +define zeroext i16 @add(i16* nocapture %a, i16 zeroext %n) nounwind readonly { +entry: + %cmp8 = icmp eq i16 %n, 0 ; [#uses=1] + br i1 %cmp8, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; [#uses=2] + %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] +; CHECK: add: +; CHECK: mov.w @r15+, r11 + %tmp4 = load i16* %arrayidx ; [#uses=1] + %add = add i16 %tmp4, %sum.09 ; [#uses=2] + %inc = add i16 %i.010, 1 ; [#uses=2] + %exitcond = icmp eq i16 %inc, %n ; [#uses=1] + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + ret i16 %sum.0.lcssa +} -- cgit v1.1