From d2c94ae49e546e68b591e838cdfc2fd016d928d9 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sun, 3 May 2009 13:03:33 +0000 Subject: [PATCH] Add dummy lowering for shifts git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70715 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430ISelLowering.cpp | 31 ++++++++++++++++++++++++ lib/Target/MSP430/MSP430ISelLowering.h | 6 ++++- lib/Target/MSP430/MSP430InstrInfo.td | 15 ++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 8427fc7cce9..98172029b35 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(N->getOperand(1))) + return SDValue(); + + uint64_t ShiftAmount = cast(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 4ee7a9c8cc4..e68b3ffe9f5 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 f99b07a31ed..8c7ed8ff874 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -26,9 +26,11 @@ class SDTCisI16 : SDTCisVT; //===----------------------------------------------------------------------===// // 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]