From e699d0f549151a2cca993c21407aea4a6eff7d3f Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sun, 3 May 2009 13:16:17 +0000 Subject: [PATCH] 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 --- lib/Target/MSP430/MSP430ISelLowering.cpp | 17 ++++++++++++++--- lib/Target/MSP430/MSP430ISelLowering.h | 8 +++++++- lib/Target/MSP430/MSP430InstrInfo.td | 12 ++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 4ad74db725b..9301bff7e3f 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 064cb67c247..2903903c263 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 2c838e31a21..2a7e927e99f 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), -- 2.34.1