mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 03:29:40 +00:00
Add some dummy support for post-incremented loads
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86385 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8983da729a
commit
6534f83ae8
@ -147,6 +147,7 @@ namespace {
|
||||
DenseMap<SDNode*, SDNode*> RMWStores;
|
||||
void PreprocessForRMW();
|
||||
SDNode *Select(SDValue Op);
|
||||
SDNode *SelectIndexedLoad(SDValue Op);
|
||||
bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -596,6 +597,40 @@ void MSP430DAGToDAGISel::PreprocessForRMW() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(Op);
|
||||
ISD::MemIndexedMode AM = LD->getAddressingMode();
|
||||
if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
|
||||
Opcode = MSP430::MOV8rm_POST;
|
||||
break;
|
||||
case MVT::i16:
|
||||
// Sanity check
|
||||
if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
|
||||
return NULL;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/// InstructionSelect - This callback is invoked by
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
void MSP430DAGToDAGISel::InstructionSelect() {
|
||||
@ -653,6 +688,11 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
|
||||
return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
|
||||
TFI, CurDAG->getTargetConstant(0, MVT::i16));
|
||||
}
|
||||
case ISD::LOAD:
|
||||
if (SDNode *ResNode = SelectIndexedLoad(Op))
|
||||
return ResNode;
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
|
||||
// Select the default instruction
|
||||
|
@ -62,10 +62,14 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
|
||||
setBooleanContents(ZeroOrOneBooleanContent);
|
||||
setSchedulingPreference(SchedulingForLatency);
|
||||
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
|
||||
// We have post-incremented loads / stores
|
||||
setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
|
||||
setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
|
||||
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
|
||||
|
||||
// We don't have any truncstores
|
||||
@ -670,6 +674,42 @@ SDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
|
||||
DAG.getValueType(Val.getValueType()));
|
||||
}
|
||||
|
||||
/// getPostIndexedAddressParts - returns true by value, base pointer and
|
||||
/// offset pointer and addressing mode by reference if this node can be
|
||||
/// combined with a load / store to form a post-indexed load / store.
|
||||
bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||
SDValue &Base,
|
||||
SDValue &Offset,
|
||||
ISD::MemIndexedMode &AM,
|
||||
SelectionDAG &DAG) const {
|
||||
|
||||
LoadSDNode *LD = cast<LoadSDNode>(N);
|
||||
if (LD->getExtensionType() != ISD::NON_EXTLOAD)
|
||||
return false;
|
||||
|
||||
EVT VT = LD->getMemoryVT();
|
||||
if (VT != MVT::i8 && VT != MVT::i16)
|
||||
return false;
|
||||
|
||||
if (Op->getOpcode() != ISD::ADD)
|
||||
return false;
|
||||
|
||||
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
|
||||
uint64_t RHSC = RHS->getZExtValue();
|
||||
if ((VT == MVT::i16 && RHSC != 2) ||
|
||||
(VT == MVT::i8 && RHSC != 1))
|
||||
return false;
|
||||
|
||||
Base = Op->getOperand(0);
|
||||
Offset = DAG.getConstant(RHSC, VT);
|
||||
AM = ISD::POST_INC;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
default: return NULL;
|
||||
|
@ -136,6 +136,12 @@ namespace llvm {
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
DebugLoc dl, SelectionDAG &DAG);
|
||||
|
||||
virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||
SDValue &Base,
|
||||
SDValue &Offset,
|
||||
ISD::MemIndexedMode &AM,
|
||||
SelectionDAG &DAG) const;
|
||||
|
||||
const MSP430Subtarget &Subtarget;
|
||||
const MSP430TargetMachine &TM;
|
||||
};
|
||||
|
@ -215,6 +215,13 @@ def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
|
||||
"mov.b\t{$src, $dst}",
|
||||
[(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
|
||||
|
||||
let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
|
||||
def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
|
||||
"mov.b\t{@$base+, $dst}", []>;
|
||||
def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
|
||||
"mov.w\t{@$base+, $dst}", []>;
|
||||
}
|
||||
|
||||
// Any instruction that defines a 8-bit result leaves the high half of the
|
||||
// register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
|
||||
// be copying from a truncate, but any other 8-bit operation will zero-extend
|
||||
|
25
test/CodeGen/MSP430/postinc.ll
Normal file
25
test/CodeGen/MSP430/postinc.ll
Normal file
@ -0,0 +1,25 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"
|
||||
target triple = "msp430"
|
||||
|
||||
define zeroext i16 @add(i16* nocapture %a, i16 zeroext %n) nounwind readonly {
|
||||
entry:
|
||||
%cmp8 = icmp eq i16 %n, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp8, label %for.end, label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; <i16> [#uses=2]
|
||||
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||
%arrayidx = getelementptr i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||
; CHECK: add:
|
||||
; CHECK: mov.w @r15+, r11
|
||||
%tmp4 = load i16* %arrayidx ; <i16> [#uses=1]
|
||||
%add = add i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||
%inc = add i16 %i.010, 1 ; <i16> [#uses=2]
|
||||
%exitcond = icmp eq i16 %inc, %n ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
%sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||
ret i16 %sum.0.lcssa
|
||||
}
|
Loading…
Reference in New Issue
Block a user