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
This commit is contained in:
Anton Korobeynikov 2009-11-07 17:15:25 +00:00
parent 6534f83ae8
commit 06ac0820a6
3 changed files with 87 additions and 11 deletions

View File

@ -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

View File

@ -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);

View File

@ -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)),