Skip to content

Commit 4705da9

Browse files
committed
[arm-fast-isel] Add support for shl, lshr, and ashr.
llvm-svn: 161230
1 parent edac6ee commit 4705da9

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

llvm/lib/Target/ARM/ARMFastISel.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class ARMFastISel : public FastISel {
167167
bool SelectRet(const Instruction *I);
168168
bool SelectTrunc(const Instruction *I);
169169
bool SelectIntExt(const Instruction *I);
170+
bool SelectShift(const Instruction *I, ARM_AM::ShiftOpc ShiftTy);
170171

171172
// Utility routines.
172173
private:
@@ -2613,6 +2614,61 @@ bool ARMFastISel::SelectIntExt(const Instruction *I) {
26132614
return true;
26142615
}
26152616

2617+
bool ARMFastISel::SelectShift(const Instruction *I,
2618+
ARM_AM::ShiftOpc ShiftTy) {
2619+
// We handle thumb2 mode by target independent selector
2620+
// or SelectionDAG ISel.
2621+
if (isThumb2)
2622+
return false;
2623+
2624+
// Only handle i32 now.
2625+
EVT DestVT = TLI.getValueType(I->getType(), true);
2626+
if (DestVT != MVT::i32)
2627+
return false;
2628+
2629+
unsigned Opc = ARM::MOVsr;
2630+
unsigned ShiftImm;
2631+
Value *Src2Value = I->getOperand(1);
2632+
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Src2Value)) {
2633+
ShiftImm = CI->getZExtValue();
2634+
2635+
// Fall back to selection DAG isel if the shift amount
2636+
// is zero or greater than the width of the value type.
2637+
if (ShiftImm == 0 || ShiftImm >=32)
2638+
return false;
2639+
2640+
Opc = ARM::MOVsi;
2641+
}
2642+
2643+
Value *Src1Value = I->getOperand(0);
2644+
unsigned Reg1 = getRegForValue(Src1Value);
2645+
if (Reg1 == 0) return false;
2646+
2647+
unsigned Reg2;
2648+
if (Opc == ARM::MOVsr) {
2649+
Reg2 = getRegForValue(Src2Value);
2650+
if (Reg2 == 0) return false;
2651+
}
2652+
2653+
unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
2654+
if(ResultReg == 0) return false;
2655+
2656+
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2657+
TII.get(Opc), ResultReg)
2658+
.addReg(Reg1);
2659+
2660+
if (Opc == ARM::MOVsi)
2661+
MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, ShiftImm));
2662+
else if (Opc == ARM::MOVsr) {
2663+
MIB.addReg(Reg2);
2664+
MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, 0));
2665+
}
2666+
2667+
AddOptionalDefs(MIB);
2668+
UpdateValueMap(I, ResultReg);
2669+
return true;
2670+
}
2671+
26162672
// TODO: SoftFP support.
26172673
bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
26182674

@@ -2673,6 +2729,12 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
26732729
case Instruction::ZExt:
26742730
case Instruction::SExt:
26752731
return SelectIntExt(I);
2732+
case Instruction::Shl:
2733+
return SelectShift(I, ARM_AM::lsl);
2734+
case Instruction::LShr:
2735+
return SelectShift(I, ARM_AM::lsr);
2736+
case Instruction::AShr:
2737+
return SelectShift(I, ARM_AM::asr);
26762738
default: break;
26772739
}
26782740
return false;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
2+
3+
define i32 @shl() nounwind ssp {
4+
entry:
5+
; ARM: shl
6+
; ARM: lsl r0, r0, #2
7+
%shl = shl i32 -1, 2
8+
ret i32 %shl
9+
}
10+
11+
define i32 @shl_reg(i32 %src1, i32 %src2) nounwind ssp {
12+
entry:
13+
; ARM: shl_reg
14+
; ARM: lsl r0, r0, r1
15+
%shl = shl i32 %src1, %src2
16+
ret i32 %shl
17+
}
18+
19+
define i32 @lshr() nounwind ssp {
20+
entry:
21+
; ARM: lshr
22+
; ARM: lsr r0, r0, #2
23+
%lshr = lshr i32 -1, 2
24+
ret i32 %lshr
25+
}
26+
27+
define i32 @lshr_reg(i32 %src1, i32 %src2) nounwind ssp {
28+
entry:
29+
; ARM: lshr_reg
30+
; ARM: lsr r0, r0, r1
31+
%lshr = lshr i32 %src1, %src2
32+
ret i32 %lshr
33+
}
34+
35+
define i32 @ashr() nounwind ssp {
36+
entry:
37+
; ARM: ashr
38+
; ARM: asr r0, r0, #2
39+
%ashr = ashr i32 -1, 2
40+
ret i32 %ashr
41+
}
42+
43+
define i32 @ashr_reg(i32 %src1, i32 %src2) nounwind ssp {
44+
entry:
45+
; ARM: ashr_reg
46+
; ARM: asr r0, r0, r1
47+
%ashr = ashr i32 %src1, %src2
48+
ret i32 %ashr
49+
}
50+

0 commit comments

Comments
 (0)