forked from OSchip/llvm-project
Add the __ARM_ARCH_EXT_IDIV__ predefine. It is set to 1 if we have hardware divide in the mode that we are compiling in (depending on the target features), not defined if we don't. Should be compatible with the GCC conterpart. Also adding a -hwdiv option to overide the default behavior.
llvm-svn: 193074
This commit is contained in:
parent
6652921d5a
commit
f9671dd09d
|
@ -1047,6 +1047,17 @@ are listed below.
|
|||
efficient model can be used. The TLS model can be overridden per
|
||||
variable using the ``tls_model`` attribute.
|
||||
|
||||
.. option:: -mhwdiv=[values]
|
||||
|
||||
Select the ARM modes (arm or thumb) that support hardware division
|
||||
instructions.
|
||||
|
||||
Valid values are: ``arm``, ``thumb`` and ``arm,thumb``.
|
||||
This option is used to indicate which mode (arm or thumb) supports
|
||||
hardware division instructions. This only applies to the ARM
|
||||
architecture.
|
||||
|
||||
|
||||
Controlling Size of Debug Information
|
||||
-------------------------------------
|
||||
|
||||
|
|
|
@ -950,6 +950,7 @@ def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group<cl
|
|||
def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>;
|
||||
def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>;
|
||||
def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
|
||||
def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>;
|
||||
def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>;
|
||||
def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
|
||||
def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
|
||||
|
@ -1279,6 +1280,7 @@ def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option
|
|||
// Double dash options, which are usually an alias for one of the previous
|
||||
// options.
|
||||
|
||||
def _mhwdiv_EQ : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
|
||||
def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>;
|
||||
def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
|
||||
def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
|
||||
|
|
|
@ -3599,6 +3599,12 @@ class ARMTargetInfo : public TargetInfo {
|
|||
NeonFPU = (1 << 3)
|
||||
};
|
||||
|
||||
// Possible HWDiv features.
|
||||
enum HWDivMode {
|
||||
HWDivThumb = (1 << 0),
|
||||
HWDivARM = (1 << 1)
|
||||
};
|
||||
|
||||
static bool FPUModeIsVFP(FPUMode Mode) {
|
||||
return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU);
|
||||
}
|
||||
|
@ -3618,6 +3624,7 @@ class ARMTargetInfo : public TargetInfo {
|
|||
|
||||
unsigned IsAAPCS : 1;
|
||||
unsigned IsThumb : 1;
|
||||
unsigned HWDiv : 2;
|
||||
|
||||
// Initialized via features.
|
||||
unsigned SoftFloat : 1;
|
||||
|
@ -3770,6 +3777,7 @@ public:
|
|||
DiagnosticsEngine &Diags) {
|
||||
FPU = 0;
|
||||
SoftFloat = SoftFloatABI = false;
|
||||
HWDiv = 0;
|
||||
for (unsigned i = 0, e = Features.size(); i != e; ++i) {
|
||||
if (Features[i] == "+soft-float")
|
||||
SoftFloat = true;
|
||||
|
@ -3783,6 +3791,10 @@ public:
|
|||
FPU |= VFP4FPU;
|
||||
else if (Features[i] == "+neon")
|
||||
FPU |= NeonFPU;
|
||||
else if (Features[i] == "+hwdiv")
|
||||
HWDiv |= HWDivThumb;
|
||||
else if (Features[i] == "+hwdiv-arm")
|
||||
HWDiv |= HWDivARM;
|
||||
}
|
||||
|
||||
if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
|
||||
|
@ -3812,6 +3824,8 @@ public:
|
|||
.Case("softfloat", SoftFloat)
|
||||
.Case("thumb", IsThumb)
|
||||
.Case("neon", (FPU & NeonFPU) && !SoftFloat)
|
||||
.Case("hwdiv", HWDiv & HWDivThumb)
|
||||
.Case("hwdiv-arm", HWDiv & HWDivARM)
|
||||
.Default(false);
|
||||
}
|
||||
// FIXME: Should we actually have some table instead of these switches?
|
||||
|
@ -3905,6 +3919,8 @@ public:
|
|||
if (CPUArch == "6T2" || IsARMv7)
|
||||
Builder.defineMacro("__thumb2__");
|
||||
}
|
||||
if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
|
||||
Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
|
||||
|
||||
// Note, this is always on in gcc, even though it doesn't make sense.
|
||||
Builder.defineMacro("__APCS_32__");
|
||||
|
|
|
@ -596,6 +596,27 @@ static void getAArch64FPUFeatures(const Driver &D, const Arg *A,
|
|||
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
|
||||
}
|
||||
|
||||
// Handle -mhwdiv=.
|
||||
static void getARMHWDivFeatures(const Driver &D, const Arg *A,
|
||||
const ArgList &Args,
|
||||
std::vector<const char *> &Features) {
|
||||
StringRef HWDiv = A->getValue();
|
||||
if (HWDiv == "arm") {
|
||||
Features.push_back("+hwdiv-arm");
|
||||
Features.push_back("-hwdiv");
|
||||
} else if (HWDiv == "thumb") {
|
||||
Features.push_back("-hwdiv-arm");
|
||||
Features.push_back("+hwdiv");
|
||||
} else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") {
|
||||
Features.push_back("+hwdiv-arm");
|
||||
Features.push_back("+hwdiv");
|
||||
} else if (HWDiv == "none") {
|
||||
Features.push_back("-hwdiv-arm");
|
||||
Features.push_back("-hwdiv");
|
||||
} else
|
||||
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
|
||||
}
|
||||
|
||||
// Handle -mfpu=.
|
||||
//
|
||||
// FIXME: Centralize feature selection, defaulting shouldn't be also in the
|
||||
|
@ -740,6 +761,8 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
|
|||
// Honor -mfpu=.
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
|
||||
getARMFPUFeatures(D, A, Args, Features);
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
|
||||
getARMHWDivFeatures(D, A, Args, Features);
|
||||
|
||||
// Setting -msoft-float effectively disables NEON because of the GCC
|
||||
// implementation, although the same isn't true of VFP or VFP3.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// Test that different values of -mhwdiv pick correct ARM hwdiv target-feature(s).
|
||||
|
||||
// RUN: %clang -### -target arm %s -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-DEFAULT %s
|
||||
// CHECK-DEFAULT-NOT: "-target-feature" "+hwdiv"
|
||||
// CHECK-DEFAULT-NOT: "-target-feature" "+hwdiv-arm"
|
||||
|
||||
// RUN: %clang -### -target arm %s -mhwdiv=arm -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-ARM %s
|
||||
// CHECK-ARM: "-target-feature" "+hwdiv-arm"
|
||||
// CHECK-ARM: "-target-feature" "-hwdiv"
|
||||
|
||||
// RUN: %clang -### -target arm %s -mhwdiv=thumb -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-THUMB %s
|
||||
// CHECK-THUMB: "-target-feature" "-hwdiv-arm"
|
||||
// CHECK-THUMB: "-target-feature" "+hwdiv"
|
||||
|
||||
// RUN: %clang -### -target arm %s -mhwdiv=arm,thumb -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-ARM-THUMB %s
|
||||
// CHECK-ARM-THUMB: "-target-feature" "+hwdiv-arm"
|
||||
// CHECK-ARM-THUMB: "-target-feature" "+hwdiv"
|
||||
|
||||
// RUN: %clang -### -target arm %s -mhwdiv=thumb,arm -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-THUMB-ARM %s
|
||||
// CHECK-THUMB-ARM: "-target-feature" "+hwdiv-arm"
|
||||
// CHECK-THUMB-ARM: "-target-feature" "+hwdiv"
|
||||
|
||||
// RUN: %clang -### -target arm %s -mhwdiv=none -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-NONE %s
|
||||
// CHECK-NONE: "-target-feature" "-hwdiv-arm"
|
||||
// CHECK-NONE: "-target-feature" "-hwdiv"
|
||||
|
||||
// Also check the alternative syntax.
|
||||
|
||||
// RUN: %clang -### -target arm %s --mhwdiv arm -o %t.o 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-ALT %s
|
||||
// CHECK-ALT: "-target-feature" "+hwdiv-arm"
|
||||
// CHECK-ALT: "-target-feature" "-hwdiv"
|
||||
|
|
@ -512,6 +512,26 @@
|
|||
// ARMEABIHARDFP:#define __arm 1
|
||||
// ARMEABIHARDFP:#define __arm__ 1
|
||||
|
||||
// Check that -mhwdiv works properly for targets which don't have the hwdiv feature enabled by default.
|
||||
|
||||
// RUN: %clang -target arm -mhwdiv=arm -x c -E -dM %s -o - | FileCheck --check-prefix=ARMHWDIV-ARM %s
|
||||
// ARMHWDIV-ARM:#define __ARM_ARCH_EXT_IDIV__ 1
|
||||
|
||||
// RUN: %clang -target arm -mthumb -mhwdiv=thumb -x c -E -dM %s -o - | FileCheck --check-prefix=THUMBHWDIV-THUMB %s
|
||||
// THUMBHWDIV-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1
|
||||
|
||||
// RUN: %clang -target arm -x c -E -dM %s -o - | FileCheck --check-prefix=ARM-FALSE %s
|
||||
// ARM-FALSE-NOT:#define __ARM_ARCH_EXT_IDIV__
|
||||
|
||||
// RUN: %clang -target arm -mthumb -x c -E -dM %s -o - | FileCheck --check-prefix=THUMB-FALSE %s
|
||||
// THUMB-FALSE-NOT:#define __ARM_ARCH_EXT_IDIV__
|
||||
|
||||
// RUN: %clang -target arm -mhwdiv=thumb -x c -E -dM %s -o - | FileCheck --check-prefix=THUMBHWDIV-ARM-FALSE %s
|
||||
// THUMBHWDIV-ARM-FALSE-NOT:#define __ARM_ARCH_EXT_IDIV__
|
||||
|
||||
// RUN: %clang -target arm -mthumb -mhwdiv=arm -x c -E -dM %s -o - | FileCheck --check-prefix=ARMHWDIV-THUMB-FALSE %s
|
||||
// ARMHWDIV-THUMB-FALSE-NOT:#define __ARM_ARCH_EXT_IDIV__
|
||||
|
||||
//
|
||||
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -check-prefix I386 %s
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue