Add dummy lowering for shifts
authorAnton Korobeynikov <asl@math.spbu.ru>
Sun, 3 May 2009 13:03:33 +0000 (13:03 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sun, 3 May 2009 13:03:33 +0000 (13:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70715 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/MSP430/MSP430ISelLowering.cpp
lib/Target/MSP430/MSP430ISelLowering.h
lib/Target/MSP430/MSP430InstrInfo.td

index 8427fc7cce9489c5e2b55b2328d71f7e361b77b2..98172029b35210364ece376c51e32f428950eab9 100644 (file)
@@ -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";
   }
 }
 
index 4ee7a9c8cc4ea6f8676f5babbdc8b08063c9f890..e68b3ffe9f5c1f9378f64b0d72cf0cadc25e215a 100644 (file)
@@ -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;
index f99b07a31edffc3c3492c299a3c638545f3bc812..8c7ed8ff8743e6e8666c44f4fa735bb3e9d7d416 100644 (file)
@@ -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]