@@ -167,6 +167,7 @@ class ARMFastISel : public FastISel {
167
167
bool SelectRet (const Instruction *I);
168
168
bool SelectTrunc (const Instruction *I);
169
169
bool SelectIntExt (const Instruction *I);
170
+ bool SelectShift (const Instruction *I, ARM_AM::ShiftOpc ShiftTy);
170
171
171
172
// Utility routines.
172
173
private:
@@ -2613,6 +2614,61 @@ bool ARMFastISel::SelectIntExt(const Instruction *I) {
2613
2614
return true ;
2614
2615
}
2615
2616
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
+
2616
2672
// TODO: SoftFP support.
2617
2673
bool ARMFastISel::TargetSelectInstruction (const Instruction *I) {
2618
2674
@@ -2673,6 +2729,12 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
2673
2729
case Instruction::ZExt:
2674
2730
case Instruction::SExt:
2675
2731
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);
2676
2738
default : break ;
2677
2739
}
2678
2740
return false ;
0 commit comments