mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-15 05:25:55 +00:00
Factor out ARM indexed load matching code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74681 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9e529c3f78
commit
af4550f826
@ -111,11 +111,13 @@ public:
|
|||||||
#include "ARMGenDAGISel.inc"
|
#include "ARMGenDAGISel.inc"
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
SDNode *SelectARMIndexedLoad(SDValue Op);
|
||||||
/// inline asm expressions.
|
|
||||||
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
|
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||||
char ConstraintCode,
|
/// inline asm expressions.
|
||||||
std::vector<SDValue> &OutOps);
|
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);
|
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 *ARMDAGToDAGISel::Select(SDValue Op) {
|
||||||
SDNode *N = Op.getNode();
|
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);
|
return CurDAG->getTargetNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
|
||||||
}
|
}
|
||||||
case ISD::LOAD: {
|
case ISD::LOAD: {
|
||||||
LoadSDNode *LD = cast<LoadSDNode>(Op);
|
SDNode *ResNode = SelectARMIndexedLoad(Op);
|
||||||
ISD::MemIndexedMode AM = LD->getAddressingMode();
|
if (ResNode)
|
||||||
MVT LoadedVT = LD->getMemoryVT();
|
return ResNode;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user