mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 22:04:55 +00:00
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:
parent
6534f83ae8
commit
06ac0820a6
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)),
|
||||
|
Loading…
Reference in New Issue
Block a user