diff options
| author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-11-07 17:15:25 +0000 |
|---|---|---|
| committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-11-07 17:15:25 +0000 |
| commit | cf84ab5043d1a1f5d14b0cfe327a2d2823bcc810 (patch) | |
| tree | c245a2987cef5af0ee4f071e8f253772ffd527dd /llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | |
| parent | d3c8319f48876fc886e3ede5d189b7e4f931a255 (diff) | |
| download | bcm5719-llvm-cf84ab5043d1a1f5d14b0cfe327a2d2823bcc810.tar.gz bcm5719-llvm-cf84ab5043d1a1f5d14b0cfe327a2d2823bcc810.zip | |
First try of the post-inc operands handling... Not fully worked, though :(
llvm-svn: 86386
Diffstat (limited to 'llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index b45690b57a2..ac01bf81c34 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/llvm/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 |

