Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: src/arm/assembler-arm.cc

Issue 2223433002: [arm] Simplify run-time CPU selection. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm/disasm-arm.cc » ('j') | src/flag-definitions.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/arm/disasm-arm.cc » ('j') | src/flag-definitions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698