forked from OSchip/llvm-project
Factor out ARM indexed load matching code.
llvm-svn: 74681
This commit is contained in:
parent
bbf38f8f3b
commit
d9c55368e7
|
@ -111,11 +111,13 @@ public:
|
|||
#include "ARMGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||
/// inline asm expressions.
|
||||
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
|
||||
char ConstraintCode,
|
||||
std::vector<SDValue> &OutOps);
|
||||
SDNode *SelectARMIndexedLoad(SDValue Op);
|
||||
|
||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||
/// inline asm expressions.
|
||||
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
|
||||
char ConstraintCode,
|
||||
std::vector<SDValue> &OutOps);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -713,6 +715,53 @@ static inline SDValue getAL(SelectionDAG *CurDAG) {
|
|||
return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
|
||||
}
|
||||
|
||||
SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(Op);
|
||||
ISD::MemIndexedMode AM = LD->getAddressingMode();
|
||||
if (AM == ISD::UNINDEXED)
|
||||
return NULL;
|
||||
|
||||
MVT LoadedVT = LD->getMemoryVT();
|
||||
SDValue Offset, AMOpc;
|
||||
bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
|
||||
unsigned Opcode = 0;
|
||||
bool Match = false;
|
||||
if (LoadedVT == MVT::i32 &&
|
||||
SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
|
||||
Match = true;
|
||||
} else if (LoadedVT == MVT::i16 &&
|
||||
SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
|
||||
? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
|
||||
: (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
|
||||
} else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
|
||||
if (LD->getExtensionType() == ISD::SEXTLOAD) {
|
||||
if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
|
||||
}
|
||||
} else {
|
||||
if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Match) {
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue Base = LD->getBasePtr();
|
||||
SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
|
||||
CurDAG->getRegister(0, MVT::i32), Chain };
|
||||
return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32,
|
||||
MVT::Other, Ops, 6);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
||||
SDNode *N = Op.getNode();
|
||||
|
@ -843,47 +892,9 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
|||
return CurDAG->getTargetNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
|
||||
}
|
||||
case ISD::LOAD: {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(Op);
|
||||
ISD::MemIndexedMode AM = LD->getAddressingMode();
|
||||
MVT LoadedVT = LD->getMemoryVT();
|
||||
if (AM != ISD::UNINDEXED) {
|
||||
SDValue Offset, AMOpc;
|
||||
bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
|
||||
unsigned Opcode = 0;
|
||||
bool Match = false;
|
||||
if (LoadedVT == MVT::i32 &&
|
||||
SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
|
||||
Match = true;
|
||||
} else if (LoadedVT == MVT::i16 &&
|
||||
SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
|
||||
? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
|
||||
: (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
|
||||
} else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
|
||||
if (LD->getExtensionType() == ISD::SEXTLOAD) {
|
||||
if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
|
||||
}
|
||||
} else {
|
||||
if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
|
||||
Match = true;
|
||||
Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Match) {
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue Base = LD->getBasePtr();
|
||||
SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
|
||||
CurDAG->getRegister(0, MVT::i32), Chain };
|
||||
return CurDAG->getTargetNode(Opcode, dl, MVT::i32, MVT::i32,
|
||||
MVT::Other, Ops, 6);
|
||||
}
|
||||
}
|
||||
SDNode *ResNode = SelectARMIndexedLoad(Op);
|
||||
if (ResNode)
|
||||
return ResNode;
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue