aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:16:17 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:16:17 +0000
commite699d0f549151a2cca993c21407aea4a6eff7d3f (patch)
treee7b9f1cbbb2adfb2a5cd566adcef0f0913250933
parente375a7c768f003b6f89a7e2e5a0e8c97a9a34868 (diff)
Handle logical shift right (at least I hope so :) )
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70758 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp17
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h8
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td12
3 files changed, 33 insertions, 4 deletions
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 4ad74db725..9301bff7e3 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -69,6 +69,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
setOperationAction(ISD::SRA, MVT::i16, Custom);
setOperationAction(ISD::SHL, MVT::i16, Custom);
+ setOperationAction(ISD::SRL, MVT::i16, Custom);
setOperationAction(ISD::RET, MVT::Other, Custom);
setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);
@@ -94,6 +95,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
case ISD::SHL: // FALLTHROUGH
+ case ISD::SRL:
case ISD::SRA: return LowerShifts(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
case ISD::CALL: return LowerCALL(Op, DAG);
@@ -430,8 +432,6 @@ MSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
SelectionDAG &DAG) {
unsigned Opc = Op.getOpcode();
- assert((Opc == ISD::SRA || ISD::SHL) &&
- "Only SRA and SHL are currently supported.");
SDNode* N = Op.getNode();
MVT VT = Op.getValueType();
DebugLoc dl = N->getDebugLoc();
@@ -446,6 +446,15 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
// FIXME: for some shift amounts this might be done better!
// E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
SDValue Victim = N->getOperand(0);
+
+ if (Opc == ISD::SRL && ShiftAmount) {
+ // Emit a special goodness here:
+ // srl A, 1 => clrc; rrc A
+ SDValue clrc = DAG.getNode(MSP430ISD::CLRC, dl, MVT::Other);
+ Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim, clrc);
+ ShiftAmount -= 1;
+ }
+
while (ShiftAmount--)
Victim = DAG.getNode((Opc == ISD::SRA ? MSP430ISD::RRA : MSP430ISD::RLA),
dl, VT, Victim);
@@ -586,13 +595,15 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
default: return NULL;
case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
case MSP430ISD::RRA: return "MSP430ISD::RRA";
- case MSP430ISD::RLA: return "MSP430ISD::RRA";
+ case MSP430ISD::RLA: return "MSP430ISD::RLA";
+ case MSP430ISD::RRC: return "MSP430ISD::RRC";
case MSP430ISD::CALL: return "MSP430ISD::CALL";
case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
case MSP430ISD::BRCOND: return "MSP430ISD::BRCOND";
case MSP430ISD::CMP: return "MSP430ISD::CMP";
case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
case MSP430ISD::SELECT: return "MSP430ISD::SELECT";
+ case MSP430ISD::CLRC: return "MSP430ISD::CLRC";
}
}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index 064cb67c24..2903903c26 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -30,6 +30,9 @@ namespace llvm {
/// Y = R{R,L}A X, rotate right (left) arithmetically
RRA, RLA,
+ /// Y = RRC X, rotate right via carry
+ RRC,
+
/// CALL/TAILCALL - These operations represent an abstract call
/// instruction, which includes a bunch of information.
CALL,
@@ -53,7 +56,10 @@ namespace llvm {
/// SELECT. Operand 0 and operand 1 are selection variable, operand 3 is
/// condition code and operand 4 is flag operand.
- SELECT
+ SELECT,
+
+ /// CLRC - Clear carry bit
+ CLRC
};
}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 2c838e31a2..2a7e927e99 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -33,6 +33,7 @@ def SDT_MSP430BrCond : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>,
SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
def SDT_MSP430Select : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
SDTCisVT<3, i8>, SDTCisVT<4, i16>]>;
+def SDT_MSP430Clrc : SDTypeProfile<0, 0, []>;
//===----------------------------------------------------------------------===//
// MSP430 Specific Node Definitions.
@@ -42,6 +43,7 @@ def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
+def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, [SDNPInFlag]>;
def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
[SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
@@ -56,6 +58,7 @@ def MSP430setcc : SDNode<"MSP430ISD::SETCC", SDT_MSP430SetCC>;
def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp>;
def MSP430brcond : SDNode<"MSP430ISD::BRCOND", SDT_MSP430BrCond, [SDNPHasChain]>;
def MSP430select : SDNode<"MSP430ISD::SELECT", SDT_MSP430Select>;
+def MSP430clrc : SDNode<"MSP430ISD::CLRC", SDT_MSP430Clrc, [SDNPOutFlag]>;
//===----------------------------------------------------------------------===//
// MSP430 Operand Definitions.
@@ -597,6 +600,11 @@ def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
[(set GR16:$dst, (MSP430rla GR16:$src)),
(implicit SRW)]>;
+def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
+ "rrc.w\t$dst",
+ [(set GR16:$dst, (MSP430rrc GR16:$src)),
+ (implicit SRW)]>;
+
def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
"sxt\t$dst",
[(set GR16:$dst, (sext_inreg GR16:$src, i8)),
@@ -662,6 +670,10 @@ def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
} // isTwoAddress = 1
+let Defs = [SRW] in
+def CLRC : Pseudo<(outs), (ins),
+ "clrc", [(MSP430clrc)]>;
+
// Integer comparisons
let Defs = [SRW] in {
def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),