Index: src/arm/assembler-arm.cc |
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
index 78ffe25390592406cf51c78f21f5ab466b2c99fb..90ca15a8849c287a971fddb5127a7f12f28b9847 100644 |
--- a/src/arm/assembler-arm.cc |
+++ b/src/arm/assembler-arm.cc |
@@ -46,84 +46,116 @@ |
namespace v8 { |
namespace internal { |
-// Get the CPU features enabled by the build. For cross compilation the |
-// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS |
-// can be defined to enable ARMv7 and VFPv3 instructions when building the |
-// snapshot. |
-static unsigned CpuFeaturesImpliedByCompiler() { |
- unsigned answer = 0; |
-#ifdef CAN_USE_ARMV8_INSTRUCTIONS |
- if (FLAG_enable_armv8) { |
- answer |= 1u << ARMv8; |
- // ARMv8 always features VFP and NEON. |
- answer |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; |
- answer |= 1u << SUDIV; |
+static const unsigned kArmv6 = 0u; |
+static const unsigned kArmv7 = kArmv6 | (1u << ARMv7); |
+static const unsigned kArmv7WithSudiv = kArmv7 | (1u << ARMv7_SUDIV); |
+static const unsigned kArmv8 = kArmv7WithSudiv | (1u << ARMv8); |
+ |
+static unsigned CpuFeaturesFromCommandLine() { |
+ if (strcmp(FLAG_arm_arch, "armv8") == 0) { |
+ return kArmv8; |
+ } else if (strcmp(FLAG_arm_arch, "armv7+sudiv") == 0) { |
+ return kArmv7WithSudiv; |
+ } else if (strcmp(FLAG_arm_arch, "armv7") == 0) { |
+ return kArmv7; |
+ } else if (strcmp(FLAG_arm_arch, "armv6") == 0) { |
+ return kArmv6; |
} |
-#endif // CAN_USE_ARMV8_INSTRUCTIONS |
-#ifdef CAN_USE_ARMV7_INSTRUCTIONS |
- if (FLAG_enable_armv7) answer |= 1u << ARMv7; |
-#endif // CAN_USE_ARMV7_INSTRUCTIONS |
-#ifdef CAN_USE_VFP3_INSTRUCTIONS |
- if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7; |
-#endif // CAN_USE_VFP3_INSTRUCTIONS |
-#ifdef CAN_USE_VFP32DREGS |
- if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS; |
-#endif // CAN_USE_VFP32DREGS |
-#ifdef CAN_USE_NEON |
- if (FLAG_enable_neon) answer |= 1u << NEON; |
-#endif // CAN_USE_VFP32DREGS |
- return answer; |
+ fprintf(stderr, "Warning: unrecognised value for --arm-arch ('%s').\n", |
Michael Achenbach
2016/08/12 10:16:37
I suggest we raise an error here since the flag is
|
+ FLAG_arm_arch); |
+ fprintf(stderr, |
+ "Supported values are: armv8\n" |
+ " armv7+sudiv\n" |
+ " armv7\n" |
+ " armv6\n" |
+ "Falling back to armv6.\n"); |
+ return kArmv6; |
+} |
+ |
+// Get the CPU features enabled by the build. |
+// For cross compilation the preprocessor symbols such as |
+// CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS can be used to |
+// enable ARMv7 and VFPv3 instructions when building the snapshot. However, |
+// these flags should be consistent with a supported ARM configuration: |
+// "armv6": ARMv6 + VFPv2 |
+// "armv7": ARMv7 + VFPv3-D32 + NEON |
+// "armv7+sudiv": ARMv7 + VFPv4-D32 + NEON + SUDIV |
+// "armv8": ARMv8 (+ all of the above) |
+static constexpr unsigned CpuFeaturesFromCompiler() { |
+ // TODO(jbramley): Once the build flags are simplified, these tests should |
+ // also be simplified. |
+ |
+ // Find compiler-implied features. |
+#if defined(CAN_USE_ARMV8_INSTRUCTIONS) && \ |
+ defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ |
+ defined(CAN_USE_SUDIV) && \ |
+ defined(CAN_USE_NEON) && \ |
+ defined(CAN_USE_VFP3_INSTRUCTIONS) |
+ return kArmv8; |
+#elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ |
+ defined(CAN_USE_SUDIV) && \ |
+ defined(CAN_USE_NEON) && \ |
+ defined(CAN_USE_VFP3_INSTRUCTIONS) |
+ return kArmv7WithSudiv; |
+#elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ |
+ defined(CAN_USE_NEON) && \ |
+ defined(CAN_USE_VFP3_INSTRUCTIONS) |
+ return kArmv7; |
+#else |
Michael Achenbach
2016/08/12 10:16:37
Same comment as flag-definitions.h - maybe raise e
|
+ return kArmv6; |
+#endif |
} |
void CpuFeatures::ProbeImpl(bool cross_compile) { |
- supported_ |= CpuFeaturesImpliedByCompiler(); |
dcache_line_size_ = 64; |
+ unsigned command_line = CpuFeaturesFromCommandLine(); |
// Only use statically determined features for cross compile (snapshot). |
- if (cross_compile) return; |
+ if (cross_compile) { |
+ supported_ |= command_line & CpuFeaturesFromCompiler(); |
+ return; |
+ } |
#ifndef __arm__ |
// For the simulator build, use whatever the flags specify. |
- if (FLAG_enable_armv8) { |
- supported_ |= 1u << ARMv8; |
- // ARMv8 always features VFP and NEON. |
- supported_ |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; |
- supported_ |= 1u << SUDIV; |
- if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
- } |
- if (FLAG_enable_armv7) { |
- supported_ |= 1u << ARMv7; |
- if (FLAG_enable_vfp3) supported_ |= 1u << VFP3; |
- if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS; |
- if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV; |
- if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
- if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS; |
+ supported_ |= command_line; |
+ |
+ if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7)) { |
+ supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
} |
#else // __arm__ |
// Probe for additional features at runtime. |
base::CPU cpu; |
- if (FLAG_enable_vfp3 && cpu.has_vfp3()) { |
- // This implementation also sets the VFP flags if runtime |
- // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI |
- // 0406B, page A1-6. |
- supported_ |= 1u << VFP3 | 1u << ARMv7; |
+ // Runtime detection is slightly fuzzy, and some inferences are necessary. |
+ unsigned runtime = kArmv6; |
+ // NEON and VFPv3 imply at least ARMv7-A. |
+ if (cpu.has_neon() && cpu.has_vfp3_d32()) { |
+ DCHECK(cpu.has_vfp3()); |
+ runtime |= kArmv7; |
+ if (cpu.has_idiva()) { |
+ runtime |= kArmv7WithSudiv; |
Michael Achenbach
2016/08/12 10:16:37
Maybe nest the armv8 case within cpu.has_idiva()?
|
+ } |
+ if (cpu.architecture() >= 8) { |
+ runtime |= kArmv8; |
+ } |
} |
- if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON; |
- if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV; |
+ // Use the best of the features found by CPU detection and those inferred from |
+ // the build system. In both cases, restrict available features using the |
+ // command-line. Note that the command-line flags are very permissive (kArmv8) |
+ // by default. |
+ supported_ |= command_line & CpuFeaturesFromCompiler(); |
+ supported_ |= command_line & runtime; |
- if (cpu.architecture() >= 7) { |
- if (FLAG_enable_armv7) supported_ |= 1u << ARMv7; |
- if (FLAG_enable_armv8 && cpu.architecture() >= 8) { |
- supported_ |= 1u << ARMv8; |
- } |
- // Use movw/movt for QUALCOMM ARMv7 cores. |
- if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) { |
- supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
- } |
+ // Additional tuning options. |
+ |
+ // Prefer to use movw/movt for QUALCOMM ARMv7 cores. |
+ if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7) && |
+ (cpu.implementer() == base::CPU::QUALCOMM)) { |
+ supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
} |
// ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. |
@@ -132,11 +164,11 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
cpu.part() == base::CPU::ARM_CORTEX_A9)) { |
dcache_line_size_ = 32; |
} |
- |
- if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS; |
#endif |
- DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7)); |
+ DCHECK_IMPLIES(IsSupported(ARMv7_SUDIV), IsSupported(ARMv7)); |
+ DCHECK_IMPLIES(IsSupported(ARMv8), IsSupported(ARMv7_SUDIV)); |
+ DCHECK_IMPLIES(IsSupported(MOVW_MOVT_IMMEDIATE_LOADS), IsSupported(ARMv7)); |
} |
@@ -209,7 +241,7 @@ void CpuFeatures::PrintFeatures() { |
#else |
bool eabi_hardfloat = false; |
#endif |
- printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); |
+ printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); |
} |