mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
[arm-fast-isel] Add support for shl, lshr, and ashr.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161230 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8b52c855b3
commit
2946549a28
@ -167,6 +167,7 @@ class ARMFastISel : public FastISel {
|
||||
bool SelectRet(const Instruction *I);
|
||||
bool SelectTrunc(const Instruction *I);
|
||||
bool SelectIntExt(const Instruction *I);
|
||||
bool SelectShift(const Instruction *I, ARM_AM::ShiftOpc ShiftTy);
|
||||
|
||||
// Utility routines.
|
||||
private:
|
||||
@ -2613,6 +2614,61 @@ bool ARMFastISel::SelectIntExt(const Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARMFastISel::SelectShift(const Instruction *I,
|
||||
ARM_AM::ShiftOpc ShiftTy) {
|
||||
// We handle thumb2 mode by target independent selector
|
||||
// or SelectionDAG ISel.
|
||||
if (isThumb2)
|
||||
return false;
|
||||
|
||||
// Only handle i32 now.
|
||||
EVT DestVT = TLI.getValueType(I->getType(), true);
|
||||
if (DestVT != MVT::i32)
|
||||
return false;
|
||||
|
||||
unsigned Opc = ARM::MOVsr;
|
||||
unsigned ShiftImm;
|
||||
Value *Src2Value = I->getOperand(1);
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Src2Value)) {
|
||||
ShiftImm = CI->getZExtValue();
|
||||
|
||||
// Fall back to selection DAG isel if the shift amount
|
||||
// is zero or greater than the width of the value type.
|
||||
if (ShiftImm == 0 || ShiftImm >=32)
|
||||
return false;
|
||||
|
||||
Opc = ARM::MOVsi;
|
||||
}
|
||||
|
||||
Value *Src1Value = I->getOperand(0);
|
||||
unsigned Reg1 = getRegForValue(Src1Value);
|
||||
if (Reg1 == 0) return false;
|
||||
|
||||
unsigned Reg2;
|
||||
if (Opc == ARM::MOVsr) {
|
||||
Reg2 = getRegForValue(Src2Value);
|
||||
if (Reg2 == 0) return false;
|
||||
}
|
||||
|
||||
unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
|
||||
if(ResultReg == 0) return false;
|
||||
|
||||
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Opc), ResultReg)
|
||||
.addReg(Reg1);
|
||||
|
||||
if (Opc == ARM::MOVsi)
|
||||
MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, ShiftImm));
|
||||
else if (Opc == ARM::MOVsr) {
|
||||
MIB.addReg(Reg2);
|
||||
MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, 0));
|
||||
}
|
||||
|
||||
AddOptionalDefs(MIB);
|
||||
UpdateValueMap(I, ResultReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: SoftFP support.
|
||||
bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
|
||||
|
||||
@ -2673,6 +2729,12 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
|
||||
case Instruction::ZExt:
|
||||
case Instruction::SExt:
|
||||
return SelectIntExt(I);
|
||||
case Instruction::Shl:
|
||||
return SelectShift(I, ARM_AM::lsl);
|
||||
case Instruction::LShr:
|
||||
return SelectShift(I, ARM_AM::lsr);
|
||||
case Instruction::AShr:
|
||||
return SelectShift(I, ARM_AM::asr);
|
||||
default: break;
|
||||
}
|
||||
return false;
|
||||
|
50
test/CodeGen/ARM/fast-isel-shifter.ll
Normal file
50
test/CodeGen/ARM/fast-isel-shifter.ll
Normal file
@ -0,0 +1,50 @@
|
||||
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
|
||||
|
||||
define i32 @shl() nounwind ssp {
|
||||
entry:
|
||||
; ARM: shl
|
||||
; ARM: lsl r0, r0, #2
|
||||
%shl = shl i32 -1, 2
|
||||
ret i32 %shl
|
||||
}
|
||||
|
||||
define i32 @shl_reg(i32 %src1, i32 %src2) nounwind ssp {
|
||||
entry:
|
||||
; ARM: shl_reg
|
||||
; ARM: lsl r0, r0, r1
|
||||
%shl = shl i32 %src1, %src2
|
||||
ret i32 %shl
|
||||
}
|
||||
|
||||
define i32 @lshr() nounwind ssp {
|
||||
entry:
|
||||
; ARM: lshr
|
||||
; ARM: lsr r0, r0, #2
|
||||
%lshr = lshr i32 -1, 2
|
||||
ret i32 %lshr
|
||||
}
|
||||
|
||||
define i32 @lshr_reg(i32 %src1, i32 %src2) nounwind ssp {
|
||||
entry:
|
||||
; ARM: lshr_reg
|
||||
; ARM: lsr r0, r0, r1
|
||||
%lshr = lshr i32 %src1, %src2
|
||||
ret i32 %lshr
|
||||
}
|
||||
|
||||
define i32 @ashr() nounwind ssp {
|
||||
entry:
|
||||
; ARM: ashr
|
||||
; ARM: asr r0, r0, #2
|
||||
%ashr = ashr i32 -1, 2
|
||||
ret i32 %ashr
|
||||
}
|
||||
|
||||
define i32 @ashr_reg(i32 %src1, i32 %src2) nounwind ssp {
|
||||
entry:
|
||||
; ARM: ashr_reg
|
||||
; ARM: asr r0, r0, r1
|
||||
%ashr = ashr i32 %src1, %src2
|
||||
ret i32 %ashr
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user