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

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: cl format Created 4 years, 3 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') | no next file with comments »
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 unsigned result;
56 if (FLAG_enable_armv8) { 56 if (strcmp(FLAG_arm_arch, "armv8") == 0) {
57 answer |= 1u << ARMv8; 57 result = kArmv8;
58 // ARMv8 always features VFP and NEON. 58 } else if (strcmp(FLAG_arm_arch, "armv7+sudiv") == 0) {
59 answer |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; 59 result = kArmv7WithSudiv;
60 answer |= 1u << SUDIV; 60 } else if (strcmp(FLAG_arm_arch, "armv7") == 0) {
61 } 61 result = kArmv7;
62 #endif // CAN_USE_ARMV8_INSTRUCTIONS 62 } else if (strcmp(FLAG_arm_arch, "armv6") == 0) {
63 #ifdef CAN_USE_ARMV7_INSTRUCTIONS 63 result = kArmv6;
64 if (FLAG_enable_armv7) answer |= 1u << ARMv7; 64 } else {
65 #endif // CAN_USE_ARMV7_INSTRUCTIONS 65 fprintf(stderr, "Error: unrecognised value for --arm-arch ('%s').\n",
66 #ifdef CAN_USE_VFP3_INSTRUCTIONS 66 FLAG_arm_arch);
67 if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7; 67 fprintf(stderr,
68 #endif // CAN_USE_VFP3_INSTRUCTIONS 68 "Supported values are: armv8\n"
69 #ifdef CAN_USE_VFP32DREGS 69 " armv7+sudiv\n"
70 if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS; 70 " armv7\n"
71 #endif // CAN_USE_VFP32DREGS 71 " armv6\n");
72 #ifdef CAN_USE_NEON 72 CHECK(false);
73 if (FLAG_enable_neon) answer |= 1u << NEON; 73 }
74 #endif // CAN_USE_VFP32DREGS 74
75 75 // If any of the old (deprecated) flags are specified, print a warning, but
76 return answer; 76 // otherwise try to respect them for now.
77 // TODO(jbramley): When all the old bots have been updated, remove this.
78 if (FLAG_enable_armv7.has_value || FLAG_enable_vfp3.has_value ||
79 FLAG_enable_32dregs.has_value || FLAG_enable_neon.has_value ||
80 FLAG_enable_sudiv.has_value || FLAG_enable_armv8.has_value) {
81 // As an approximation of the old behaviour, set the default values from the
82 // arm_arch setting, then apply the flags over the top.
83 bool enable_armv7 = (result & (1u << ARMv7)) != 0;
84 bool enable_vfp3 = (result & (1u << ARMv7)) != 0;
85 bool enable_32dregs = (result & (1u << ARMv7)) != 0;
86 bool enable_neon = (result & (1u << ARMv7)) != 0;
87 bool enable_sudiv = (result & (1u << ARMv7_SUDIV)) != 0;
88 bool enable_armv8 = (result & (1u << ARMv8)) != 0;
89 if (FLAG_enable_armv7.has_value) {
90 fprintf(stderr,
91 "Warning: --enable_armv7 is deprecated. "
92 "Use --arm_arch instead.\n");
93 enable_armv7 = FLAG_enable_armv7.value;
94 }
95 if (FLAG_enable_vfp3.has_value) {
96 fprintf(stderr,
97 "Warning: --enable_vfp3 is deprecated. "
98 "Use --arm_arch instead.\n");
99 enable_vfp3 = FLAG_enable_vfp3.value;
100 }
101 if (FLAG_enable_32dregs.has_value) {
102 fprintf(stderr,
103 "Warning: --enable_32dregs is deprecated. "
104 "Use --arm_arch instead.\n");
105 enable_32dregs = FLAG_enable_32dregs.value;
106 }
107 if (FLAG_enable_neon.has_value) {
108 fprintf(stderr,
109 "Warning: --enable_neon is deprecated. "
110 "Use --arm_arch instead.\n");
111 enable_neon = FLAG_enable_neon.value;
112 }
113 if (FLAG_enable_sudiv.has_value) {
114 fprintf(stderr,
115 "Warning: --enable_sudiv is deprecated. "
116 "Use --arm_arch instead.\n");
117 enable_sudiv = FLAG_enable_sudiv.value;
118 }
119 if (FLAG_enable_armv8.has_value) {
120 fprintf(stderr,
121 "Warning: --enable_armv8 is deprecated. "
122 "Use --arm_arch instead.\n");
123 enable_armv8 = FLAG_enable_armv8.value;
124 }
125 // Emulate the old implications.
126 if (enable_armv8) {
127 enable_vfp3 = true;
128 enable_neon = true;
129 enable_32dregs = true;
130 enable_sudiv = true;
131 }
132 // Select the best available configuration.
133 if (enable_armv7 && enable_vfp3 && enable_32dregs && enable_neon) {
134 if (enable_sudiv) {
135 if (enable_armv8) {
136 result = kArmv8;
137 } else {
138 result = kArmv7WithSudiv;
139 }
140 } else {
141 result = kArmv7;
142 }
143 } else {
144 result = kArmv6;
145 }
146 }
147 return result;
77 } 148 }
78 149
150 // Get the CPU features enabled by the build.
151 // For cross compilation the preprocessor symbols such as
152 // CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS can be used to
153 // enable ARMv7 and VFPv3 instructions when building the snapshot. However,
154 // these flags should be consistent with a supported ARM configuration:
155 // "armv6": ARMv6 + VFPv2
156 // "armv7": ARMv7 + VFPv3-D32 + NEON
157 // "armv7+sudiv": ARMv7 + VFPv4-D32 + NEON + SUDIV
158 // "armv8": ARMv8 (+ all of the above)
159 static constexpr unsigned CpuFeaturesFromCompiler() {
160 // TODO(jbramley): Once the build flags are simplified, these tests should
161 // also be simplified.
162
163 // Check *architectural* implications.
164 #if defined(CAN_USE_ARMV8_INSTRUCTIONS) && !defined(CAN_USE_ARMV7_INSTRUCTIONS)
165 #error "CAN_USE_ARMV8_INSTRUCTIONS should imply CAN_USE_ARMV7_INSTRUCTIONS"
166 #endif
167 #if defined(CAN_USE_ARMV8_INSTRUCTIONS) && !defined(CAN_USE_SUDIV)
168 #error "CAN_USE_ARMV8_INSTRUCTIONS should imply CAN_USE_SUDIV"
169 #endif
170 #if defined(CAN_USE_ARMV7_INSTRUCTIONS) != defined(CAN_USE_VFP3_INSTRUCTIONS)
171 // V8 requires VFP, and all ARMv7 devices with VFP have VFPv3. Similarly,
172 // VFPv3 isn't available before ARMv7.
173 #error "CAN_USE_ARMV7_INSTRUCTIONS should match CAN_USE_VFP3_INSTRUCTIONS"
174 #endif
175 #if defined(CAN_USE_NEON) && !defined(CAN_USE_ARMV7_INSTRUCTIONS)
176 #error "CAN_USE_NEON should imply CAN_USE_ARMV7_INSTRUCTIONS"
177 #endif
178
179 // Find compiler-implied features.
180 #if defined(CAN_USE_ARMV8_INSTRUCTIONS) && \
181 defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(CAN_USE_SUDIV) && \
182 defined(CAN_USE_NEON) && defined(CAN_USE_VFP3_INSTRUCTIONS)
183 return kArmv8;
184 #elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(CAN_USE_SUDIV) && \
185 defined(CAN_USE_NEON) && defined(CAN_USE_VFP3_INSTRUCTIONS)
186 return kArmv7WithSudiv;
187 #elif defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(CAN_USE_NEON) && \
188 defined(CAN_USE_VFP3_INSTRUCTIONS)
189 return kArmv7;
190 #else
191 return kArmv6;
192 #endif
193 }
194
79 195
80 void CpuFeatures::ProbeImpl(bool cross_compile) { 196 void CpuFeatures::ProbeImpl(bool cross_compile) {
81 supported_ |= CpuFeaturesImpliedByCompiler();
82 dcache_line_size_ = 64; 197 dcache_line_size_ = 64;
83 198
199 unsigned command_line = CpuFeaturesFromCommandLine();
84 // Only use statically determined features for cross compile (snapshot). 200 // Only use statically determined features for cross compile (snapshot).
85 if (cross_compile) return; 201 if (cross_compile) {
202 supported_ |= command_line & CpuFeaturesFromCompiler();
203 return;
204 }
86 205
87 #ifndef __arm__ 206 #ifndef __arm__
88 // For the simulator build, use whatever the flags specify. 207 // For the simulator build, use whatever the flags specify.
89 if (FLAG_enable_armv8) { 208 supported_ |= command_line;
90 supported_ |= 1u << ARMv8; 209
91 // ARMv8 always features VFP and NEON. 210 if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7)) {
92 supported_ |= 1u << ARMv7 | 1u << VFP3 | 1u << NEON | 1u << VFP32DREGS; 211 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 } 212 }
104 213
105 #else // __arm__ 214 #else // __arm__
106 // Probe for additional features at runtime. 215 // Probe for additional features at runtime.
107 base::CPU cpu; 216 base::CPU cpu;
108 if (FLAG_enable_vfp3 && cpu.has_vfp3()) { 217 // Runtime detection is slightly fuzzy, and some inferences are necessary.
109 // This implementation also sets the VFP flags if runtime 218 unsigned runtime = kArmv6;
110 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI 219 // NEON and VFPv3 imply at least ARMv7-A.
111 // 0406B, page A1-6. 220 if (cpu.has_neon() && cpu.has_vfp3_d32()) {
112 supported_ |= 1u << VFP3 | 1u << ARMv7; 221 DCHECK(cpu.has_vfp3());
113 } 222 runtime |= kArmv7;
114 223 if (cpu.has_idiva()) {
115 if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON; 224 runtime |= kArmv7WithSudiv;
116 if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV; 225 if (cpu.architecture() >= 8) {
117 226 runtime |= kArmv8;
118 if (cpu.architecture() >= 7) { 227 }
119 if (FLAG_enable_armv7) supported_ |= 1u << ARMv7; 228 }
120 if (FLAG_enable_armv8 && cpu.architecture() >= 8) { 229 }
121 supported_ |= 1u << ARMv8; 230
122 } 231 // Use the best of the features found by CPU detection and those inferred from
123 // Use movw/movt for QUALCOMM ARMv7 cores. 232 // the build system. In both cases, restrict available features using the
124 if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) { 233 // command-line. Note that the command-line flags are very permissive (kArmv8)
125 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; 234 // by default.
126 } 235 supported_ |= command_line & CpuFeaturesFromCompiler();
236 supported_ |= command_line & runtime;
237
238 // Additional tuning options.
239
240 // Prefer to use movw/movt for QUALCOMM ARMv7 cores.
241 if (FLAG_enable_movw_movt && ((supported_ & kArmv7) == kArmv7) &&
242 (cpu.implementer() == base::CPU::QUALCOMM)) {
243 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS;
127 } 244 }
128 245
129 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. 246 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines.
130 if (cpu.implementer() == base::CPU::ARM && 247 if (cpu.implementer() == base::CPU::ARM &&
131 (cpu.part() == base::CPU::ARM_CORTEX_A5 || 248 (cpu.part() == base::CPU::ARM_CORTEX_A5 ||
132 cpu.part() == base::CPU::ARM_CORTEX_A9)) { 249 cpu.part() == base::CPU::ARM_CORTEX_A9)) {
133 dcache_line_size_ = 32; 250 dcache_line_size_ = 32;
134 } 251 }
135
136 if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
137 #endif 252 #endif
138 253
139 DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7)); 254 DCHECK_IMPLIES(IsSupported(ARMv7_SUDIV), IsSupported(ARMv7));
255 DCHECK_IMPLIES(IsSupported(ARMv8), IsSupported(ARMv7_SUDIV));
256 DCHECK_IMPLIES(IsSupported(MOVW_MOVT_IMMEDIATE_LOADS), IsSupported(ARMv7));
140 } 257 }
141 258
142 259
143 void CpuFeatures::PrintTarget() { 260 void CpuFeatures::PrintTarget() {
144 const char* arm_arch = NULL; 261 const char* arm_arch = NULL;
145 const char* arm_target_type = ""; 262 const char* arm_target_type = "";
146 const char* arm_no_probe = ""; 263 const char* arm_no_probe = "";
147 const char* arm_fpu = ""; 264 const char* arm_fpu = "";
148 const char* arm_thumb = ""; 265 const char* arm_thumb = "";
149 const char* arm_float_abi = NULL; 266 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), 319 CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS),
203 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), 320 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV),
204 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); 321 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
205 #ifdef __arm__ 322 #ifdef __arm__
206 bool eabi_hardfloat = base::OS::ArmUsingHardFloat(); 323 bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
207 #elif USE_EABI_HARDFLOAT 324 #elif USE_EABI_HARDFLOAT
208 bool eabi_hardfloat = true; 325 bool eabi_hardfloat = true;
209 #else 326 #else
210 bool eabi_hardfloat = false; 327 bool eabi_hardfloat = false;
211 #endif 328 #endif
212 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); 329 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat);
213 } 330 }
214 331
215 332
216 // ----------------------------------------------------------------------------- 333 // -----------------------------------------------------------------------------
217 // Implementation of RelocInfo 334 // Implementation of RelocInfo
218 335
219 // static 336 // static
220 const int RelocInfo::kApplyMask = 0; 337 const int RelocInfo::kApplyMask = 0;
221 338
222 339
(...skipping 4026 matching lines...) Expand 10 before | Expand all | Expand 10 after
4249 DCHECK(is_uint12(offset)); 4366 DCHECK(is_uint12(offset));
4250 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); 4367 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset));
4251 } 4368 }
4252 } 4369 }
4253 4370
4254 4371
4255 } // namespace internal 4372 } // namespace internal
4256 } // namespace v8 4373 } // namespace v8
4257 4374
4258 #endif // V8_TARGET_ARCH_ARM 4375 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/disasm-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698