aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:03:33 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:03:33 +0000
commit184a31c91df5eee886ae00fc4626343205d55345 (patch)
treea198c72bc297c98a766060cf72f986f980821c8b
parentee6380b4e9156e3af36be608838dc1af466a6886 (diff)
downloadexternal_llvm-184a31c91df5eee886ae00fc4626343205d55345.zip
external_llvm-184a31c91df5eee886ae00fc4626343205d55345.tar.gz
external_llvm-184a31c91df5eee886ae00fc4626343205d55345.tar.bz2
Add dummy lowering for shifts
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70715 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp31
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h6
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td15
3 files changed, 49 insertions, 3 deletions
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 8427fc7..9817202 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -49,6 +49,12 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
// Division is expensive
setIntDivIsCheap(false);
+ // Even if we have only 1 bit shift here, we can perform
+ // shifts of the whole bitwidth 1 bit per step.
+ setShiftAmountType(MVT::i8);
+
+ setOperationAction(ISD::SRA, MVT::i16, Custom);
+
setOperationAction(ISD::RET, MVT::Other, Custom);
}
@@ -56,6 +62,7 @@ SDValue MSP430TargetLowering::
LowerOperation(SDValue Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
+ case ISD::SRA: return LowerShifts(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
default:
assert(0 && "unimplemented operand");
@@ -210,10 +217,34 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain);
}
+SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
+ SelectionDAG &DAG) {
+ assert(Op.getOpcode() == ISD::SRA && "Only SRA is currently supported.");
+ SDNode* N = Op.getNode();
+ MVT VT = Op.getValueType();
+ DebugLoc dl = N->getDebugLoc();
+
+ // We currently only lower SRA of constant argument.
+ if (!isa<ConstantSDNode>(N->getOperand(1)))
+ return SDValue();
+
+ uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
+
+ // Expand the stuff into sequence of shifts.
+ // FIXME: for some shift amounts this might be done better!
+ // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
+ SDValue Victim = N->getOperand(0);
+ while (ShiftAmount--)
+ Victim = DAG.getNode(MSP430ISD::RRA, dl, VT, Victim);
+
+ return Victim;
+}
+
const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return NULL;
case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
+ case MSP430ISD::RRA: return "MSP430ISD::RRA";
}
}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index 4ee7a9c..e68b3ff 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -25,7 +25,10 @@ namespace llvm {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
/// Return with a flag operand. Operand 0 is the chain operand.
- RET_FLAG
+ RET_FLAG,
+
+ /// Y = RRA X, rotate right arithmetically
+ RRA
};
}
@@ -46,6 +49,7 @@ namespace llvm {
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerShifts(SDValue Op, SelectionDAG &DAG);
private:
const MSP430Subtarget &Subtarget;
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index f99b07a..8c7ed8f 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -26,9 +26,11 @@ class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
//===----------------------------------------------------------------------===//
// MSP430 Specific Node Definitions.
//===----------------------------------------------------------------------===//
-def retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
+def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInFlag]>;
+def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
+
//===----------------------------------------------------------------------===//
// Pseudo Instructions
//===----------------------------------------------------------------------===//
@@ -41,7 +43,7 @@ def NOP : Pseudo<(outs), (ins), "nop", []>;
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1 in {
- def RETI : Pseudo<(outs), (ins), "ret", [(retflag)]>;
+ def RETI : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
}
//===----------------------------------------------------------------------===//
@@ -73,4 +75,13 @@ def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
[(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
(implicit SR)]>;
}
+
+// FIXME: Provide proper encoding!
+let isTwoAddress = 1 in {
+def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
+ "rra.w\t$dst",
+ [(set GR16:$dst, (MSP430rra GR16:$src)),
+ (implicit SR)]>;
}
+
+} // Defs = [SR]