2012-02-18 20:03:15 +08:00
|
|
|
//===-- ARMSubtarget.cpp - ARM Subtarget Information ----------------------===//
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2011-07-02 05:01:15 +08:00
|
|
|
// This file implements the ARM specific subclass of TargetSubtargetInfo.
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "ARMSubtarget.h"
|
2014-06-27 03:30:02 +08:00
|
|
|
#include "ARMFrameLowering.h"
|
|
|
|
#include "ARMISelLowering.h"
|
|
|
|
#include "ARMInstrInfo.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "ARMMachineFunctionInfo.h"
|
2014-06-27 03:30:02 +08:00
|
|
|
#include "ARMSelectionDAGInfo.h"
|
|
|
|
#include "ARMSubtarget.h"
|
2014-12-18 10:20:58 +08:00
|
|
|
#include "ARMTargetMachine.h"
|
2014-06-27 03:30:02 +08:00
|
|
|
#include "Thumb1FrameLowering.h"
|
|
|
|
#include "Thumb1InstrInfo.h"
|
|
|
|
#include "Thumb2InstrInfo.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2013-02-16 06:41:25 +08:00
|
|
|
#include "llvm/IR/Attributes.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
2014-01-07 19:48:04 +08:00
|
|
|
#include "llvm/IR/GlobalValue.h"
|
2009-06-23 05:01:46 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2013-03-22 02:47:47 +08:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2014-07-16 01:18:41 +08:00
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
2011-07-02 04:45:01 +08:00
|
|
|
|
2014-04-22 10:03:14 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 06:55:11 +08:00
|
|
|
#define DEBUG_TYPE "arm-subtarget"
|
|
|
|
|
2011-07-02 04:45:01 +08:00
|
|
|
#define GET_SUBTARGETINFO_TARGET_DESC
|
2011-07-08 09:53:10 +08:00
|
|
|
#define GET_SUBTARGETINFO_CTOR
|
2011-07-02 06:36:09 +08:00
|
|
|
#include "ARMGenSubtargetInfo.inc"
|
2011-07-02 04:45:01 +08:00
|
|
|
|
2012-09-30 05:43:49 +08:00
|
|
|
static cl::opt<bool>
|
|
|
|
UseFusedMulOps("arm-use-mulops",
|
|
|
|
cl::init(true), cl::Hidden);
|
|
|
|
|
2013-11-14 02:29:49 +08:00
|
|
|
enum ITMode {
|
|
|
|
DefaultIT,
|
|
|
|
RestrictedIT,
|
|
|
|
NoRestrictedIT
|
|
|
|
};
|
|
|
|
|
|
|
|
static cl::opt<ITMode>
|
|
|
|
IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT),
|
|
|
|
cl::ZeroOrMore,
|
|
|
|
cl::values(clEnumValN(DefaultIT, "arm-default-it",
|
|
|
|
"Generate IT block based on arch"),
|
|
|
|
clEnumValN(RestrictedIT, "arm-restrict-it",
|
|
|
|
"Disallow deprecated IT based on ARMv8"),
|
|
|
|
clEnumValN(NoRestrictedIT, "arm-no-restrict-it",
|
|
|
|
"Allow IT blocks based on ARMv7"),
|
|
|
|
clEnumValEnd));
|
|
|
|
|
2015-09-23 17:19:54 +08:00
|
|
|
/// ForceFastISel - Use the fast-isel, even for subtargets where it is not
|
|
|
|
/// currently supported (for testing only).
|
|
|
|
static cl::opt<bool>
|
|
|
|
ForceFastISel("arm-force-fast-isel",
|
|
|
|
cl::init(false), cl::Hidden);
|
|
|
|
|
2014-06-13 08:20:35 +08:00
|
|
|
/// initializeSubtargetDependencies - Initializes using a CPU and feature string
|
|
|
|
/// so that we can use initializer lists for subtarget initialization.
|
|
|
|
ARMSubtarget &ARMSubtarget::initializeSubtargetDependencies(StringRef CPU,
|
|
|
|
StringRef FS) {
|
2013-02-16 09:36:26 +08:00
|
|
|
initializeEnvironment();
|
2014-09-04 04:36:31 +08:00
|
|
|
initSubtargetFeatures(CPU, FS);
|
2014-06-13 08:20:35 +08:00
|
|
|
return *this;
|
2013-02-16 06:41:25 +08:00
|
|
|
}
|
|
|
|
|
2015-01-27 03:03:15 +08:00
|
|
|
ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU,
|
|
|
|
StringRef FS) {
|
|
|
|
ARMSubtarget &STI = initializeSubtargetDependencies(CPU, FS);
|
|
|
|
if (STI.isThumb1Only())
|
|
|
|
return (ARMFrameLowering *)new Thumb1FrameLowering(STI);
|
|
|
|
|
|
|
|
return new ARMFrameLowering(STI);
|
|
|
|
}
|
|
|
|
|
2015-06-10 20:11:26 +08:00
|
|
|
ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,
|
2015-01-27 03:03:15 +08:00
|
|
|
const std::string &FS,
|
|
|
|
const ARMBaseTargetMachine &TM, bool IsLittle)
|
2015-09-16 00:17:27 +08:00
|
|
|
: ARMGenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
|
2015-11-17 21:38:29 +08:00
|
|
|
ARMProcClass(None), ARMArch(ARMv4t), stackAlignment(4), CPUString(CPU),
|
2015-11-17 19:57:33 +08:00
|
|
|
IsLittle(IsLittle), TargetTriple(TT), Options(TM.Options), TM(TM),
|
2015-01-27 03:03:15 +08:00
|
|
|
FrameLowering(initializeFrameLowering(CPU, FS)),
|
|
|
|
// At this point initializeSubtargetDependencies has been called so
|
|
|
|
// we can query directly.
|
2014-06-27 03:30:02 +08:00
|
|
|
InstrInfo(isThumb1Only()
|
|
|
|
? (ARMBaseInstrInfo *)new Thumb1InstrInfo(*this)
|
|
|
|
: !isThumb()
|
|
|
|
? (ARMBaseInstrInfo *)new ARMInstrInfo(*this)
|
|
|
|
: (ARMBaseInstrInfo *)new Thumb2InstrInfo(*this)),
|
2015-01-29 08:19:39 +08:00
|
|
|
TLInfo(TM, *this) {}
|
2014-06-13 08:20:35 +08:00
|
|
|
|
2013-02-16 09:36:26 +08:00
|
|
|
void ARMSubtarget::initializeEnvironment() {
|
|
|
|
HasV4TOps = false;
|
|
|
|
HasV5TOps = false;
|
|
|
|
HasV5TEOps = false;
|
|
|
|
HasV6Ops = false;
|
2013-10-08 00:55:23 +08:00
|
|
|
HasV6MOps = false;
|
2015-03-17 19:55:28 +08:00
|
|
|
HasV6KOps = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasV6T2Ops = false;
|
|
|
|
HasV7Ops = false;
|
2013-06-27 00:58:26 +08:00
|
|
|
HasV8Ops = false;
|
2015-04-01 22:54:56 +08:00
|
|
|
HasV8_1aOps = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasVFPv2 = false;
|
|
|
|
HasVFPv3 = false;
|
|
|
|
HasVFPv4 = false;
|
2013-09-13 21:46:57 +08:00
|
|
|
HasFPARMv8 = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasNEON = false;
|
|
|
|
UseNEONForSinglePrecisionFP = false;
|
|
|
|
UseMulOps = UseFusedMulOps;
|
|
|
|
SlowFPVMLx = false;
|
|
|
|
HasVMLxForwarding = false;
|
|
|
|
SlowFPBrcc = false;
|
|
|
|
InThumbMode = false;
|
2015-05-12 09:26:05 +08:00
|
|
|
UseSoftFloat = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasThumb2 = false;
|
|
|
|
NoARM = false;
|
2015-07-21 09:42:02 +08:00
|
|
|
ReserveR9 = false;
|
2015-07-16 08:58:23 +08:00
|
|
|
NoMovt = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
SupportsTailCall = false;
|
|
|
|
HasFP16 = false;
|
|
|
|
HasD16 = false;
|
|
|
|
HasHardwareDivide = false;
|
|
|
|
HasHardwareDivideInARM = false;
|
|
|
|
HasT2ExtractPack = false;
|
|
|
|
HasDataBarrier = false;
|
|
|
|
Pref32BitThumb = false;
|
|
|
|
AvoidCPSRPartialUpdate = false;
|
|
|
|
AvoidMOVsShifterOperand = false;
|
|
|
|
HasRAS = false;
|
|
|
|
HasMPExtension = false;
|
2013-11-01 21:27:35 +08:00
|
|
|
HasVirtualization = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
FPOnlySP = false;
|
2013-05-24 03:11:14 +08:00
|
|
|
HasPerfMon = false;
|
2013-04-10 20:08:35 +08:00
|
|
|
HasTrustZone = false;
|
2013-09-19 19:59:01 +08:00
|
|
|
HasCrypto = false;
|
2013-10-30 00:54:52 +08:00
|
|
|
HasCRC = false;
|
2014-04-01 21:22:02 +08:00
|
|
|
HasZeroCycleZeroing = false;
|
2015-07-29 06:44:28 +08:00
|
|
|
StrictAlign = false;
|
2015-09-25 01:31:16 +08:00
|
|
|
HasDSP = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
UseNaClTrap = false;
|
2015-07-07 14:54:42 +08:00
|
|
|
GenLongCalls = false;
|
2013-03-22 02:47:47 +08:00
|
|
|
UnsafeFPMath = false;
|
2015-10-29 06:56:36 +08:00
|
|
|
UseSjLjEH = (isTargetDarwin() &&
|
|
|
|
TargetTriple.getSubArch() != Triple::ARMSubArch_v7k);
|
2013-02-16 09:36:26 +08:00
|
|
|
}
|
|
|
|
|
2014-09-04 04:36:31 +08:00
|
|
|
void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
|
2013-09-03 01:09:01 +08:00
|
|
|
if (CPUString.empty()) {
|
2015-10-29 06:46:43 +08:00
|
|
|
CPUString = "generic";
|
|
|
|
|
|
|
|
if (isTargetDarwin()) {
|
|
|
|
StringRef ArchName = TargetTriple.getArchName();
|
|
|
|
if (ArchName.endswith("v7s"))
|
|
|
|
// Default to the Swift CPU when targeting armv7s/thumbv7s.
|
|
|
|
CPUString = "swift";
|
|
|
|
else if (ArchName.endswith("v7k"))
|
|
|
|
// Default to the Cortex-a7 CPU when targeting armv7k/thumbv7k.
|
|
|
|
// ARMv7k does not use SjLj exception handling.
|
|
|
|
CPUString = "cortex-a7";
|
|
|
|
}
|
2013-09-03 01:09:01 +08:00
|
|
|
}
|
2009-03-08 12:02:49 +08:00
|
|
|
|
2011-06-30 10:12:44 +08:00
|
|
|
// Insert the architecture feature derived from the target triple into the
|
|
|
|
// feature string. This is important for setting features that are implied
|
|
|
|
// based on the architecture version.
|
2015-09-16 00:17:27 +08:00
|
|
|
std::string ArchFS = ARM_MC::ParseARMTriple(TargetTriple, CPUString);
|
2011-07-07 08:08:19 +08:00
|
|
|
if (!FS.empty()) {
|
|
|
|
if (!ArchFS.empty())
|
2015-03-30 23:42:36 +08:00
|
|
|
ArchFS = (Twine(ArchFS) + "," + FS).str();
|
2011-07-07 08:08:19 +08:00
|
|
|
else
|
|
|
|
ArchFS = FS;
|
|
|
|
}
|
2011-07-07 15:07:08 +08:00
|
|
|
ParseSubtargetFeatures(CPUString, ArchFS);
|
2011-07-07 08:08:19 +08:00
|
|
|
|
2013-12-13 19:16:00 +08:00
|
|
|
// FIXME: This used enable V6T2 support implicitly for Thumb2 mode.
|
|
|
|
// Assert this for now to make the change obvious.
|
|
|
|
assert(hasV6T2Ops() || !hasThumb2());
|
2010-11-10 06:50:47 +08:00
|
|
|
|
2012-08-08 10:44:16 +08:00
|
|
|
// Keep a pointer to static instruction cost data for the specified CPU.
|
|
|
|
SchedModel = getSchedModelForCPU(CPUString);
|
|
|
|
|
2011-07-02 04:45:01 +08:00
|
|
|
// Initialize scheduling itinerary for the specified CPU.
|
|
|
|
InstrItins = getInstrItineraryForCPU(CPUString);
|
|
|
|
|
2014-04-03 04:32:05 +08:00
|
|
|
// FIXME: this is invalid for WindowsCE
|
2014-12-18 10:08:45 +08:00
|
|
|
if (isTargetWindows())
|
2014-04-03 04:32:05 +08:00
|
|
|
NoARM = true;
|
|
|
|
|
2007-02-14 03:52:28 +08:00
|
|
|
if (isAAPCS_ABI())
|
|
|
|
stackAlignment = 8;
|
2015-10-29 06:46:43 +08:00
|
|
|
if (isTargetNaCl() || isAAPCS16_ABI())
|
Use 16 byte stack alignment for NaCl on ARM
NaCl's ARM ABI uses 16 byte stack alignment, so set that in
ARMSubtarget.cpp.
Using 16 byte alignment exposes an issue in code generation in which a
varargs function leaves a 4 byte gap between the values of r1-r3 saved
to the stack and the following arguments that were passed on the
stack. (Previously, this code only needed to support 4 byte and 8
byte alignment.)
With this issue, llc generated:
varargs_func:
sub sp, sp, #16
push {lr}
sub sp, sp, #12
add r0, sp, #16 // Should be 20
stm r0, {r1, r2, r3}
ldr r0, .LCPI0_0 // Address of va_list
add r1, sp, #16
str r1, [r0]
bl external_func
Fix the bug by checking for "Align > 4". Also simplify the code by
using OffsetToAlignment(), and update comments.
Differential Revision: http://llvm-reviews.chandlerc.com/D2677
llvm-svn: 201497
2014-02-17 02:59:48 +08:00
|
|
|
stackAlignment = 16;
|
2007-02-14 03:52:28 +08:00
|
|
|
|
2015-09-28 17:44:11 +08:00
|
|
|
// FIXME: Completely disable sibcall for Thumb1 since ThumbRegisterInfo::
|
|
|
|
// emitEpilogue is not ready for them. Thumb tail calls also use t2B, as
|
|
|
|
// the Thumb1 16-bit unconditional branch doesn't have sufficient relocation
|
|
|
|
// support in the assembler and linker to be used. This would need to be
|
|
|
|
// fixed to fully support tail calls in Thumb1.
|
|
|
|
//
|
|
|
|
// Doing this is tricky, since the LDM/POP instruction on Thumb doesn't take
|
|
|
|
// LR. This means if we need to reload LR, it takes an extra instructions,
|
|
|
|
// which outweighs the value of the tail call; but here we don't know yet
|
|
|
|
// whether LR is going to be used. Probably the right approach is to
|
|
|
|
// generate the tail call here and turn it back into CALL/RET in
|
|
|
|
// emitEpilogue if LR is used.
|
|
|
|
|
|
|
|
// Thumb1 PIC calls to external symbols use BX, so they can be tail calls,
|
|
|
|
// but we need to make sure there are enough registers; the only valid
|
|
|
|
// registers are the 4 used for parameters. We don't currently do this
|
|
|
|
// case.
|
|
|
|
|
|
|
|
SupportsTailCall = !isThumb1Only();
|
|
|
|
|
|
|
|
if (isTargetMachO() && isTargetIOS() && getTargetTriple().isOSVersionLT(5, 0))
|
|
|
|
SupportsTailCall = false;
|
2009-10-02 05:46:35 +08:00
|
|
|
|
2013-11-14 02:29:49 +08:00
|
|
|
switch (IT) {
|
|
|
|
case DefaultIT:
|
2015-04-14 23:32:58 +08:00
|
|
|
RestrictIT = hasV8Ops();
|
2013-11-14 02:29:49 +08:00
|
|
|
break;
|
|
|
|
case RestrictedIT:
|
|
|
|
RestrictIT = true;
|
|
|
|
break;
|
|
|
|
case NoRestrictedIT:
|
|
|
|
RestrictIT = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-03-22 02:47:47 +08:00
|
|
|
// NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
|
2015-05-26 18:47:10 +08:00
|
|
|
const FeatureBitset &Bits = getFeatureBits();
|
|
|
|
if ((Bits[ARM::ProcA5] || Bits[ARM::ProcA8]) && // Where this matters
|
2013-03-22 02:47:47 +08:00
|
|
|
(Options.UnsafeFPMath || isTargetDarwin()))
|
|
|
|
UseNEONForSinglePrecisionFP = true;
|
2007-01-19 15:51:42 +08:00
|
|
|
}
|
2009-08-29 07:18:09 +08:00
|
|
|
|
2014-12-18 10:20:58 +08:00
|
|
|
bool ARMSubtarget::isAPCS_ABI() const {
|
|
|
|
assert(TM.TargetABI != ARMBaseTargetMachine::ARM_ABI_UNKNOWN);
|
|
|
|
return TM.TargetABI == ARMBaseTargetMachine::ARM_ABI_APCS;
|
|
|
|
}
|
|
|
|
bool ARMSubtarget::isAAPCS_ABI() const {
|
|
|
|
assert(TM.TargetABI != ARMBaseTargetMachine::ARM_ABI_UNKNOWN);
|
2015-10-29 06:46:43 +08:00
|
|
|
return TM.TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS ||
|
|
|
|
TM.TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16;
|
2014-12-18 10:20:58 +08:00
|
|
|
}
|
2015-10-29 06:46:43 +08:00
|
|
|
bool ARMSubtarget::isAAPCS16_ABI() const {
|
|
|
|
assert(TM.TargetABI != ARMBaseTargetMachine::ARM_ABI_UNKNOWN);
|
|
|
|
return TM.TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16;
|
|
|
|
}
|
|
|
|
|
2014-12-18 10:20:58 +08:00
|
|
|
|
2009-08-29 07:18:09 +08:00
|
|
|
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
|
2009-09-03 15:04:02 +08:00
|
|
|
bool
|
2010-04-15 09:51:59 +08:00
|
|
|
ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
|
|
|
|
Reloc::Model RelocM) const {
|
2009-09-03 15:04:02 +08:00
|
|
|
if (RelocM == Reloc::Static)
|
2009-08-29 07:18:09 +08:00
|
|
|
return false;
|
2009-09-03 15:04:02 +08:00
|
|
|
|
2015-07-06 04:52:35 +08:00
|
|
|
bool isDef = GV->isStrongDefinitionForLinker();
|
2009-09-03 15:04:02 +08:00
|
|
|
|
2014-01-06 22:28:05 +08:00
|
|
|
if (!isTargetMachO()) {
|
2009-09-03 15:04:02 +08:00
|
|
|
// Extra load is needed for all externally visible.
|
|
|
|
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
} else {
|
2015-07-06 04:52:35 +08:00
|
|
|
// If this is a strong reference to a definition, it is definitely not
|
|
|
|
// through a stub.
|
|
|
|
if (isDef)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Unless we have a symbol with hidden visibility, we have to go through a
|
|
|
|
// normal $non_lazy_ptr stub because this symbol might be resolved late.
|
|
|
|
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
|
|
|
|
return true;
|
2009-09-03 15:04:02 +08:00
|
|
|
|
2015-07-06 04:52:35 +08:00
|
|
|
if (RelocM == Reloc::PIC_) {
|
2009-09-03 15:04:02 +08:00
|
|
|
// If symbol visibility is hidden, we have a stub for common symbol
|
|
|
|
// references and external declarations.
|
2015-07-06 04:52:35 +08:00
|
|
|
if (GV->isDeclarationForLinker() || GV->hasCommonLinkage())
|
2009-09-03 15:04:02 +08:00
|
|
|
// Hidden $non_lazy_ptr reference.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2009-08-29 07:18:09 +08:00
|
|
|
}
|
2009-11-10 08:48:55 +08:00
|
|
|
|
2010-09-29 05:57:50 +08:00
|
|
|
unsigned ARMSubtarget::getMispredictionPenalty() const {
|
2014-09-03 01:43:54 +08:00
|
|
|
return SchedModel.MispredictPenalty;
|
2010-09-29 05:57:50 +08:00
|
|
|
}
|
|
|
|
|
2013-11-03 14:14:38 +08:00
|
|
|
bool ARMSubtarget::hasSinCos() const {
|
2015-10-29 06:51:16 +08:00
|
|
|
return isTargetWatchOS() ||
|
|
|
|
(isTargetIOS() && !getTargetTriple().isOSVersionLT(7, 0));
|
2013-11-03 14:14:38 +08:00
|
|
|
}
|
|
|
|
|
2015-07-18 07:18:30 +08:00
|
|
|
bool ARMSubtarget::enableMachineScheduler() const {
|
|
|
|
// Enable the MachineScheduler before register allocation for out-of-order
|
|
|
|
// architectures where we do not use the PostRA scheduler anymore (for now
|
|
|
|
// restricted to swift).
|
|
|
|
return getSchedModel().isOutOfOrder() && isSwift();
|
|
|
|
}
|
|
|
|
|
2014-07-16 06:39:58 +08:00
|
|
|
// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
|
2015-06-13 11:42:16 +08:00
|
|
|
bool ARMSubtarget::enablePostRAScheduler() const {
|
2015-07-18 07:18:30 +08:00
|
|
|
// No need for PostRA scheduling on out of order CPUs (for now restricted to
|
|
|
|
// swift).
|
|
|
|
if (getSchedModel().isOutOfOrder() && isSwift())
|
|
|
|
return false;
|
2014-07-16 06:39:58 +08:00
|
|
|
return (!isThumb() || hasThumb2());
|
2014-06-04 15:06:27 +08:00
|
|
|
}
|
|
|
|
|
2014-08-22 05:50:01 +08:00
|
|
|
bool ARMSubtarget::enableAtomicExpand() const {
|
2014-06-20 05:03:04 +08:00
|
|
|
return hasAnyDataBarrier() && !isThumb1Only();
|
|
|
|
}
|
|
|
|
|
2015-08-04 01:20:10 +08:00
|
|
|
bool ARMSubtarget::useStride4VFPs(const MachineFunction &MF) const {
|
2015-10-29 06:56:36 +08:00
|
|
|
// For general targets, the prologue can grow when VFPs are allocated with
|
|
|
|
// stride 4 (more vpush instructions). But WatchOS uses a compact unwind
|
|
|
|
// format which it's more important to get right.
|
|
|
|
return isTargetWatchOS() || (isSwift() && !MF.getFunction()->optForMinSize());
|
2015-08-04 01:20:10 +08:00
|
|
|
}
|
|
|
|
|
2014-07-04 09:55:26 +08:00
|
|
|
bool ARMSubtarget::useMovt(const MachineFunction &MF) const {
|
|
|
|
// NOTE Windows on ARM needs to use mov.w/mov.t pairs to materialise 32-bit
|
|
|
|
// immediates as it is inherently position independent, and may be out of
|
|
|
|
// range otherwise.
|
2015-07-16 08:58:23 +08:00
|
|
|
return !NoMovt && hasV6T2Ops() &&
|
2015-08-04 23:49:57 +08:00
|
|
|
(isTargetWindows() || !MF.getFunction()->optForMinSize());
|
2014-07-04 09:55:26 +08:00
|
|
|
}
|
2015-05-23 09:14:08 +08:00
|
|
|
|
|
|
|
bool ARMSubtarget::useFastISel() const {
|
2015-09-23 17:19:54 +08:00
|
|
|
// Enable fast-isel for any target, for testing only.
|
|
|
|
if (ForceFastISel)
|
|
|
|
return true;
|
|
|
|
|
2015-09-19 04:08:18 +08:00
|
|
|
// Limit fast-isel to the targets that are or have been tested.
|
|
|
|
if (!hasV6Ops())
|
|
|
|
return false;
|
|
|
|
|
2015-05-23 09:14:08 +08:00
|
|
|
// Thumb2 support on iOS; ARM support on iOS, Linux and NaCl.
|
|
|
|
return TM.Options.EnableFastISel &&
|
|
|
|
((isTargetMachO() && !isThumb1Only()) ||
|
|
|
|
(isTargetLinux() && !isThumb()) || (isTargetNaCl() && !isThumb()));
|
|
|
|
}
|