Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #if V8_TARGET_ARCH_ARM | 39 #if V8_TARGET_ARCH_ARM |
| 40 | 40 |
| 41 #include "src/arm/assembler-arm-inl.h" | 41 #include "src/arm/assembler-arm-inl.h" |
| 42 #include "src/base/bits.h" | 42 #include "src/base/bits.h" |
| 43 #include "src/base/cpu.h" | 43 #include "src/base/cpu.h" |
| 44 #include "src/macro-assembler.h" | 44 #include "src/macro-assembler.h" |
| 45 | 45 |
| 46 namespace v8 { | 46 namespace v8 { |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 // Get the CPU features enabled by the build. For cross compilation the | 49 static const unsigned kArmv6 = 0u; |
| 50 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS | 50 static const unsigned kArmv7 = kArmv6 | (1u << ARMv7); |
| 51 // can be defined to enable ARMv7 and VFPv3 instructions when building the | 51 static const unsigned kArmv7WithSudiv = kArmv7 | (1u << ARMv7_SUDIV); |
| 52 // snapshot. | 52 static const unsigned kArmv8 = kArmv7WithSudiv | (1u << ARMv8); |
| 53 static unsigned CpuFeaturesImpliedByCompiler() { | 53 |
| 54 unsigned answer = 0; | 54 static unsigned CpuFeaturesFromCommandLine() { |
| 55 #ifdef CAN_USE_ARMV8_INSTRUCTIONS | 55 if (strcmp(FLAG_arm_arch, "armv8") == 0) { |
| 56 if (FLAG_enable_armv8) { | 56 return kArmv8; |
| 57 answer |= 1u << ARMv8; | 57 } else if (strcmp(FLAG_arm_arch, "armv7+sudiv") == 0) { |
| 58 // ARMv8 always features VFP and NEON. | 58 return kArmv7WithSudiv; |
| 59 answer |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; | 59 } else if (strcmp(FLAG_arm_arch, "armv7") == 0) { |
| 60 answer |= 1u << SUDIV; | 60 return kArmv7; |
| 61 } else if (strcmp(FLAG_arm_arch, "armv6") == 0) { | |
| 62 return kArmv6; | |
| 61 } | 63 } |
| 62 #endif // CAN_USE_ARMV8_INSTRUCTIONS | |
| 63 #ifdef CAN_USE_ARMV7_INSTRUCTIONS | |
| 64 if (FLAG_enable_armv7) answer |= 1u << ARMv7; | |
| 65 #endif // CAN_USE_ARMV7_INSTRUCTIONS | |
| 66 #ifdef CAN_USE_VFP3_INSTRUCTIONS | |
| 67 if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7; | |
| 68 #endif // CAN_USE_VFP3_INSTRUCTIONS | |
| 69 #ifdef CAN_USE_VFP32DREGS | |
| 70 if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS; | |
| 71 #endif // CAN_USE_VFP32DREGS | |
| 72 #ifdef CAN_USE_NEON | |
| 73 if (FLAG_enable_neon) answer |= 1u << NEON; | |
| 74 #endif // CAN_USE_VFP32DREGS | |
| 75 | 64 |
| 76 return answer; | 65 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
| |
| 66 FLAG_arm_arch); | |
| 67 fprintf(stderr, | |
| 68 "Supported values are: armv8\n" | |
| 69 " armv7+sudiv\n" | |
| 70 " armv7\n" | |
| 71 " armv6\n" | |
| 72 "Falling back to armv6.\n"); | |
| 73 return kArmv6; | |
| 74 } | |
| 75 | |
| 76 // Get the CPU features enabled by the build. | |
| 77 // For cross compilation the preprocessor symbols such as | |
| 78 // CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS can be used to | |
| 79 // enable ARMv7 and VFPv3 instructions when building the snapshot. However, | |
| 80 // these flags should be consistent with a supported ARM configuration: | |
| 81 // "armv6": ARMv6 + VFPv2 | |
| 82 // "armv7": ARMv7 + VFPv3-D32 + NEON | |
| 83 // "armv7+sudiv": ARMv7 + VFPv4-D32 + NEON + SUDIV | |
| 84 // "armv8": ARMv8 (+ all of the above) | |
| 85 static constexpr unsigned CpuFeaturesFromCompiler() { | |
| 86 // TODO(jbramley): Once the build flags are simplified, these tests should | |
| 87 // also be simplified. | |
| 88 | |
| 89 // Find compiler-implied features. | |
| 90 #if defined(CAN_USE_ARMV8_INSTRUCTIONS) && \ | |
| 91 defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ | |
| 92 defined(CAN_USE_SUDIV) && \ | |
| 93 defined(CAN_USE_NEON) && \ | |
| 94 defined(CAN_USE_VFP3_INSTRUCTIONS) | |
| 95 return kArmv8; | |
| 96 #elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ | |
| 97 defined(CAN_USE_SUDIV) && \ | |
| 98 defined(CAN_USE_NEON) && \ | |
| 99 defined(CAN_USE_VFP3_INSTRUCTIONS) | |
| 100 return kArmv7WithSudiv; | |
| 101 #elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && \ | |
| 102 defined(CAN_USE_NEON) && \ | |
| 103 defined(CAN_USE_VFP3_INSTRUCTIONS) | |
| 104 return kArmv7; | |
| 105 #else | |
|
Michael Achenbach
2016/08/12 10:16:37
Same comment as flag-definitions.h - maybe raise e
| |
| 106 return kArmv6; | |
| 107 #endif | |
| 77 } | 108 } |
| 78 | 109 |
| 79 | 110 |
| 80 void CpuFeatures::ProbeImpl(bool cross_compile) { | 111 void CpuFeatures::ProbeImpl(bool cross_compile) { |
| 81 supported_ |= CpuFeaturesImpliedByCompiler(); | |
| 82 dcache_line_size_ = 64; | 112 dcache_line_size_ = 64; |
| 83 | 113 |
| 114 unsigned command_line = CpuFeaturesFromCommandLine(); | |
| 84 // Only use statically determined features for cross compile (snapshot). | 115 // Only use statically determined features for cross compile (snapshot). |
| 85 if (cross_compile) return; | 116 if (cross_compile) { |
| 117 supported_ |= command_line & CpuFeaturesFromCompiler(); | |
| 118 return; | |
| 119 } | |
| 86 | 120 |
| 87 #ifndef __arm__ | 121 #ifndef __arm__ |
| 88 // For the simulator build, use whatever the flags specify. | 122 // For the simulator build, use whatever the flags specify. |
| 89 if (FLAG_enable_armv8) { | 123 supported_ |= command_line; |
| 90 supported_ |= 1u << ARMv8; | 124 |
| 91 // ARMv8 always features VFP and NEON. | 125 if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7)) { |
| 92 supported_ |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; | 126 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
| 93 supported_ |= 1u << SUDIV; | |
| 94 if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | |
| 95 } | |
| 96 if (FLAG_enable_armv7) { | |
| 97 supported_ |= 1u << ARMv7; | |
| 98 if (FLAG_enable_vfp3) supported_ |= 1u << VFP3; | |
| 99 if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS; | |
| 100 if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV; | |
| 101 if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | |
| 102 if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS; | |
| 103 } | 127 } |
| 104 | 128 |
| 105 #else // __arm__ | 129 #else // __arm__ |
| 106 // Probe for additional features at runtime. | 130 // Probe for additional features at runtime. |
| 107 base::CPU cpu; | 131 base::CPU cpu; |
| 108 if (FLAG_enable_vfp3 && cpu.has_vfp3()) { | 132 // Runtime detection is slightly fuzzy, and some inferences are necessary. |
| 109 // This implementation also sets the VFP flags if runtime | 133 unsigned runtime = kArmv6; |
| 110 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI | 134 // NEON and VFPv3 imply at least ARMv7-A. |
| 111 // 0406B, page A1-6. | 135 if (cpu.has_neon() && cpu.has_vfp3_d32()) { |
| 112 supported_ |= 1u << VFP3 | 1u << ARMv7; | 136 DCHECK(cpu.has_vfp3()); |
| 113 } | 137 runtime |= kArmv7; |
| 114 | 138 if (cpu.has_idiva()) { |
| 115 if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON; | 139 runtime |= kArmv7WithSudiv; |
|
Michael Achenbach
2016/08/12 10:16:37
Maybe nest the armv8 case within cpu.has_idiva()?
| |
| 116 if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV; | |
| 117 | |
| 118 if (cpu.architecture() >= 7) { | |
| 119 if (FLAG_enable_armv7) supported_ |= 1u << ARMv7; | |
| 120 if (FLAG_enable_armv8 && cpu.architecture() >= 8) { | |
| 121 supported_ |= 1u << ARMv8; | |
| 122 } | 140 } |
| 123 // Use movw/movt for QUALCOMM ARMv7 cores. | 141 if (cpu.architecture() >= 8) { |
| 124 if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) { | 142 runtime |= kArmv8; |
| 125 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | |
| 126 } | 143 } |
| 127 } | 144 } |
| 128 | 145 |
| 146 // Use the best of the features found by CPU detection and those inferred from | |
| 147 // the build system. In both cases, restrict available features using the | |
| 148 // command-line. Note that the command-line flags are very permissive (kArmv8) | |
| 149 // by default. | |
| 150 supported_ |= command_line & CpuFeaturesFromCompiler(); | |
| 151 supported_ |= command_line & runtime; | |
| 152 | |
| 153 // Additional tuning options. | |
| 154 | |
| 155 // Prefer to use movw/movt for QUALCOMM ARMv7 cores. | |
| 156 if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7) && | |
| 157 (cpu.implementer() == base::CPU::QUALCOMM)) { | |
| 158 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | |
| 159 } | |
| 160 | |
| 129 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. | 161 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. |
| 130 if (cpu.implementer() == base::CPU::ARM && | 162 if (cpu.implementer() == base::CPU::ARM && |
| 131 (cpu.part() == base::CPU::ARM_CORTEX_A5 || | 163 (cpu.part() == base::CPU::ARM_CORTEX_A5 || |
| 132 cpu.part() == base::CPU::ARM_CORTEX_A9)) { | 164 cpu.part() == base::CPU::ARM_CORTEX_A9)) { |
| 133 dcache_line_size_ = 32; | 165 dcache_line_size_ = 32; |
| 134 } | 166 } |
| 135 | |
| 136 if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS; | |
| 137 #endif | 167 #endif |
| 138 | 168 |
| 139 DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7)); | 169 DCHECK_IMPLIES(IsSupported(ARMv7_SUDIV), IsSupported(ARMv7)); |
| 170 DCHECK_IMPLIES(IsSupported(ARMv8), IsSupported(ARMv7_SUDIV)); | |
| 171 DCHECK_IMPLIES(IsSupported(MOVW_MOVT_IMMEDIATE_LOADS), IsSupported(ARMv7)); | |
| 140 } | 172 } |
| 141 | 173 |
| 142 | 174 |
| 143 void CpuFeatures::PrintTarget() { | 175 void CpuFeatures::PrintTarget() { |
| 144 const char* arm_arch = NULL; | 176 const char* arm_arch = NULL; |
| 145 const char* arm_target_type = ""; | 177 const char* arm_target_type = ""; |
| 146 const char* arm_no_probe = ""; | 178 const char* arm_no_probe = ""; |
| 147 const char* arm_fpu = ""; | 179 const char* arm_fpu = ""; |
| 148 const char* arm_thumb = ""; | 180 const char* arm_thumb = ""; |
| 149 const char* arm_float_abi = NULL; | 181 const char* arm_float_abi = NULL; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS), | 234 CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS), |
| 203 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), | 235 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), |
| 204 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); | 236 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); |
| 205 #ifdef __arm__ | 237 #ifdef __arm__ |
| 206 bool eabi_hardfloat = base::OS::ArmUsingHardFloat(); | 238 bool eabi_hardfloat = base::OS::ArmUsingHardFloat(); |
| 207 #elif USE_EABI_HARDFLOAT | 239 #elif USE_EABI_HARDFLOAT |
| 208 bool eabi_hardfloat = true; | 240 bool eabi_hardfloat = true; |
| 209 #else | 241 #else |
| 210 bool eabi_hardfloat = false; | 242 bool eabi_hardfloat = false; |
| 211 #endif | 243 #endif |
| 212 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); | 244 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); |
| 213 } | 245 } |
| 214 | 246 |
| 215 | 247 |
| 216 // ----------------------------------------------------------------------------- | 248 // ----------------------------------------------------------------------------- |
| 217 // Implementation of RelocInfo | 249 // Implementation of RelocInfo |
| 218 | 250 |
| 219 // static | 251 // static |
| 220 const int RelocInfo::kApplyMask = 0; | 252 const int RelocInfo::kApplyMask = 0; |
| 221 | 253 |
| 222 | 254 |
| (...skipping 4026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4249 DCHECK(is_uint12(offset)); | 4281 DCHECK(is_uint12(offset)); |
| 4250 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 4282 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
| 4251 } | 4283 } |
| 4252 } | 4284 } |
| 4253 | 4285 |
| 4254 | 4286 |
| 4255 } // namespace internal | 4287 } // namespace internal |
| 4256 } // namespace v8 | 4288 } // namespace v8 |
| 4257 | 4289 |
| 4258 #endif // V8_TARGET_ARCH_ARM | 4290 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |