diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 13:03:33 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-05-03 13:03:33 +0000 |
commit | 184a31c91df5eee886ae00fc4626343205d55345 (patch) | |
tree | a198c72bc297c98a766060cf72f986f980821c8b | |
parent | ee6380b4e9156e3af36be608838dc1af466a6886 (diff) | |
download | external_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.cpp | 31 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.h | 6 | ||||
-rw-r--r-- | 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 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] |