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 |