Index: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -950,10 +950,20 @@ 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); + if ((Opc == ISD::SRA || Opc == ISD::SRL) && ShiftAmount >= 8) { + // foo >> (8 + N) => sxt(swpb(foo)) >> N + assert(VT == MVT::i16 && "Can not shift i8 by 8 and more"); + Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim); + if (Opc == ISD::SRA) + Victim = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Victim, + DAG.getValueType(MVT::i8)); + else + Victim = DAG.getZeroExtendInReg(Victim, dl, MVT::i8); + ShiftAmount -= 8; + } + if (Opc == ISD::SRL && ShiftAmount) { // Emit a special goodness here: // srl A, 1 => clrc; rrc A Index: llvm/trunk/test/CodeGen/MSP430/shifts.ll =================================================================== --- llvm/trunk/test/CodeGen/MSP430/shifts.ll +++ llvm/trunk/test/CodeGen/MSP430/shifts.ll @@ -5,6 +5,7 @@ define zeroext i8 @lshr8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone { entry: ; CHECK-LABEL: lshr8: +; CHECK: clrc ; CHECK: rrc.b %shr = lshr i8 %a, %cnt ret i8 %shr @@ -29,6 +30,7 @@ define zeroext i16 @lshr16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone { entry: ; CHECK-LABEL: lshr16: +; CHECK: clrc ; CHECK: rrc %shr = lshr i16 %a, %cnt ret i16 %shr @@ -49,3 +51,26 @@ %shl = shl i16 %a, %cnt ret i16 %shl } + +define i16 @ashr10_i16(i16 %a) #0 { +entry: +; CHECK-LABEL: ashr10_i16: +; CHECK: swpb r12 +; CHECK-NEXT: sxt r12 +; CHECK-NEXT: rra r12 +; CHECK-NEXT: rra r12 + %shr = ashr i16 %a, 10 + ret i16 %shr +} + +define i16 @lshr10_i16(i16 %a) #0 { +entry: +; CHECK-LABEL: lshr10_i16: +; CHECK: swpb r12 +; CHECK-NEXT: mov.b r12, r12 +; CHECK-NEXT: clrc +; CHECK-NEXT: rrc r12 +; CHECK-NEXT: rra r12 + %shr = lshr i16 %a, 10 + ret i16 %shr +}