aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMFastISel.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-09 16:55:43 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-11 13:47:37 -0800
commitb770d0e0636a4b5ad61b1ca661caee67576c05fc (patch)
treec486ce032d41f97313c50629bd5b879f53e6ccbf /lib/Target/ARM/ARMFastISel.cpp
parentb835840cf112a6178506d834b58aa625f59a8994 (diff)
parent1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410 (diff)
Merge commit '1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410'
deplib features commented out due to removal upstream; will add back as a localmod Conflicts: include/llvm/ADT/Triple.h include/llvm/MC/MCAssembler.h include/llvm/Target/TargetFrameLowering.h lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h lib/CodeGen/BranchFolding.cpp lib/LLVMBuild.txt lib/Linker/LinkArchives.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/Makefile lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMFrameLowering.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMSubtarget.h lib/Target/ARM/ARMTargetObjectFile.cpp lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/Mips/MipsInstrInfo.td lib/Target/X86/X86CodeEmitter.cpp lib/Target/X86/X86Subtarget.h lib/VMCore/Module.cpp test/MC/MachO/ARM/nop-armv4-padding.s tools/Makefile tools/llc/llc.cpp tools/lto/LTOModule.cpp tools/lto/lto.cpp
Diffstat (limited to 'lib/Target/ARM/ARMFastISel.cpp')
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp77
1 files changed, 49 insertions, 28 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp
index 033540ae7d..9cacf1b000 100644
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -16,31 +16,31 @@
#include "ARM.h"
#include "ARMBaseInstrInfo.h"
#include "ARMCallingConv.h"
-#include "ARMTargetMachine.h"
-#include "ARMSubtarget.h"
#include "ARMConstantPoolValue.h"
+#include "ARMSubtarget.h"
+#include "ARMTargetMachine.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/CallingConv.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Module.h"
-#include "llvm/Operator.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/DataLayout.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Operator.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
@@ -186,7 +186,8 @@ class ARMFastISel : public FastISel {
bool ARMComputeAddress(const Value *Obj, Address &Addr);
void ARMSimplifyAddress(Address &Addr, EVT VT, bool useAM3);
bool ARMIsMemCpySmall(uint64_t Len);
- bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len);
+ bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
+ unsigned Alignment);
unsigned ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT, bool isZExt);
unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
unsigned ARMMaterializeInt(const Constant *C, EVT VT);
@@ -563,7 +564,9 @@ unsigned ARMFastISel::ARMMaterializeInt(const Constant *C, EVT VT) {
const ConstantInt *CI = cast<ConstantInt>(C);
if (Subtarget->hasV6T2Ops() && isUInt<16>(CI->getZExtValue())) {
unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16;
- unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32));
+ const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass :
+ &ARM::GPRRegClass;
+ unsigned ImmReg = createResultReg(RC);
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(Opc), ImmReg)
.addImm(CI->getZExtValue()));
@@ -1670,7 +1673,6 @@ bool ARMFastISel::SelectSelect(const Instruction *I) {
// Things need to be register sized for register moves.
if (VT != MVT::i32) return false;
- const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
unsigned CondReg = getRegForValue(I->getOperand(0));
if (CondReg == 0) return false;
@@ -1703,14 +1705,16 @@ bool ARMFastISel::SelectSelect(const Instruction *I) {
.addReg(CondReg).addImm(0));
unsigned MovCCOpc;
+ const TargetRegisterClass *RC;
if (!UseImm) {
+ RC = isThumb2 ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
} else {
- if (!isNegativeImm) {
+ RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
+ if (!isNegativeImm)
MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
- } else {
+ else
MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi;
- }
}
unsigned ResultReg = createResultReg(RC);
if (!UseImm)
@@ -2285,6 +2289,9 @@ bool ARMFastISel::SelectCall(const Instruction *I,
// Can't handle inline asm.
if (isa<InlineAsm>(Callee)) return false;
+ // Allow SelectionDAG isel to handle tail calls.
+ if (CI->isTailCall()) return false;
+
// Check the calling convention.
ImmutableCallSite CS(CI);
CallingConv::ID CC = CS.getCallingConv();
@@ -2424,21 +2431,30 @@ bool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) {
}
bool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src,
- uint64_t Len) {
+ uint64_t Len, unsigned Alignment) {
// Make sure we don't bloat code by inlining very large memcpy's.
if (!ARMIsMemCpySmall(Len))
return false;
- // We don't care about alignment here since we just emit integer accesses.
while (Len) {
MVT VT;
- if (Len >= 4)
- VT = MVT::i32;
- else if (Len >= 2)
- VT = MVT::i16;
- else {
- assert(Len == 1);
- VT = MVT::i8;
+ if (!Alignment || Alignment >= 4) {
+ if (Len >= 4)
+ VT = MVT::i32;
+ else if (Len >= 2)
+ VT = MVT::i16;
+ else {
+ assert (Len == 1 && "Expected a length of 1!");
+ VT = MVT::i8;
+ }
+ } else {
+ // Bound based on alignment.
+ if (Len >= 2 && Alignment == 2)
+ VT = MVT::i16;
+ else {
+ assert (Alignment == 1 && "Expected an alignment of 1!");
+ VT = MVT::i8;
+ }
}
bool RV;
@@ -2517,7 +2533,8 @@ bool ARMFastISel::SelectIntrinsicCall(const IntrinsicInst &I) {
if (!ARMComputeAddress(MTI.getRawDest(), Dest) ||
!ARMComputeAddress(MTI.getRawSource(), Src))
return false;
- if (ARMTryEmitSmallMemCpy(Dest, Src, Len))
+ unsigned Alignment = MTI.getAlignment();
+ if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))
return true;
}
}
@@ -2582,11 +2599,13 @@ unsigned ARMFastISel::ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT,
unsigned Opc;
bool isBoolZext = false;
+ const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::i32);
if (!SrcVT.isSimple()) return 0;
switch (SrcVT.getSimpleVT().SimpleTy) {
default: return 0;
case MVT::i16:
if (!Subtarget->hasV6Ops()) return 0;
+ RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
if (isZExt)
Opc = isThumb2 ? ARM::t2UXTH : ARM::UXTH;
else
@@ -2594,6 +2613,7 @@ unsigned ARMFastISel::ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT,
break;
case MVT::i8:
if (!Subtarget->hasV6Ops()) return 0;
+ RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
if (isZExt)
Opc = isThumb2 ? ARM::t2UXTB : ARM::UXTB;
else
@@ -2601,6 +2621,7 @@ unsigned ARMFastISel::ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT,
break;
case MVT::i1:
if (isZExt) {
+ RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
isBoolZext = true;
break;
@@ -2608,7 +2629,7 @@ unsigned ARMFastISel::ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT,
return 0;
}
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
+ unsigned ResultReg = createResultReg(RC);
MachineInstrBuilder MIB;
MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg)
.addReg(SrcReg);