13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef CPU_AARCH64_VM_VERSION_AARCH64_HPP
27 #define CPU_AARCH64_VM_VERSION_AARCH64_HPP
28
29 #include "spin_wait_aarch64.hpp"
30 #include "runtime/abstract_vm_version.hpp"
31 #include "utilities/sizes.hpp"
32
33 class VM_Version : public Abstract_VM_Version {
34 friend class VMStructs;
35 friend class JVMCIVMStructs;
36
37 protected:
38 static int _cpu;
39 static int _model;
40 static int _model2;
41 static int _variant;
42 static int _revision;
43 static int _stepping;
44
45 static int _zva_length;
46 static int _dcache_line_size;
47 static int _icache_line_size;
48 static int _initial_sve_vector_length;
49 static int _max_supported_sve_vector_length;
50 static bool _rop_protection;
51 static uintptr_t _pac_mask;
52
53 static SpinWait _spin_wait;
54
55 // Read additional info using OS-specific interfaces
56 static void get_os_cpu_info();
57
58 // Sets the SVE length and returns a new actual value or negative on error.
59 // If the len is larger than the system largest supported SVE vector length,
60 // the function sets the largest supported value.
61 static int set_and_get_current_sve_vector_length(int len);
62 static int get_current_sve_vector_length();
63
64 public:
65 // Initialization
66 static void initialize();
67 static void check_virtualizations();
68
69 static void print_platform_virtualization_info(outputStream*);
70
71 // Asserts
72 static void assert_is_initialized() {
73 }
74
75 static bool expensive_load(int ld_size, int scale) {
76 if (cpu_family() == CPU_ARM) {
77 // Half-word load with index shift by 1 (aka scale is 2) has
78 // extra cycle latency, e.g. ldrsh w0, [x1,w2,sxtw #1].
79 if (ld_size == 2 && scale == 2) {
80 return true;
81 }
82 }
83 return false;
121 decl(EVTSTRM, evtstrm, 2) \
122 decl(AES, aes, 3) \
123 decl(PMULL, pmull, 4) \
124 decl(SHA1, sha1, 5) \
125 decl(SHA2, sha256, 6) \
126 decl(CRC32, crc32, 7) \
127 decl(LSE, lse, 8) \
128 decl(FPHP, fphp, 9) \
129 decl(ASIMDHP, asimdhp, 10) \
130 decl(DCPOP, dcpop, 16) \
131 decl(SHA3, sha3, 17) \
132 decl(SHA512, sha512, 21) \
133 decl(SVE, sve, 22) \
134 decl(PACA, paca, 30) \
135 /* flags above must follow Linux HWCAP */ \
136 decl(SVEBITPERM, svebitperm, 27) \
137 decl(SVE2, sve2, 28) \
138 decl(A53MAC, a53mac, 31)
139
140 enum Feature_Flag {
141 #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
142 CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
143 #undef DECLARE_CPU_FEATURE_FLAG
144 };
145
146 // Feature identification
147 #define CPU_FEATURE_DETECTION(id, name, bit) \
148 static bool supports_##name() { return (_features & CPU_##id) != 0; };
149 CPU_FEATURE_FLAGS(CPU_FEATURE_DETECTION)
150 #undef CPU_FEATURE_DETECTION
151
152 static int cpu_family() { return _cpu; }
153 static int cpu_model() { return _model; }
154 static int cpu_model2() { return _model2; }
155 static int cpu_variant() { return _variant; }
156 static int cpu_revision() { return _revision; }
157
158 static bool model_is(int cpu_model) {
159 return _model == cpu_model || _model2 == cpu_model;
160 }
161
162 static bool is_zva_enabled() { return 0 <= _zva_length; }
163 static int zva_length() {
164 assert(is_zva_enabled(), "ZVA not available");
165 return _zva_length;
166 }
167
168 static int icache_line_size() { return _icache_line_size; }
169 static int dcache_line_size() { return _dcache_line_size; }
170 static int get_initial_sve_vector_length() { return _initial_sve_vector_length; };
171 static int get_max_supported_sve_vector_length() { return _max_supported_sve_vector_length; };
182 static const SpinWait& spin_wait_desc() { return _spin_wait; }
183
184 static bool supports_on_spin_wait() { return _spin_wait.inst() != SpinWait::NONE; }
185
186 static bool supports_float16() { return true; }
187
188 #ifdef __APPLE__
189 // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64)
190 static bool is_cpu_emulated();
191 #endif
192
193 static void initialize_cpu_information(void);
194
195 static bool use_rop_protection() { return _rop_protection; }
196
197 // For common 64/128-bit unpredicated vector operations, we may prefer
198 // emitting NEON instructions rather than the corresponding SVE instructions.
199 static bool use_neon_for_vector(int vector_length_in_bytes) {
200 return vector_length_in_bytes <= 16;
201 }
202 };
203
204 #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
|
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef CPU_AARCH64_VM_VERSION_AARCH64_HPP
27 #define CPU_AARCH64_VM_VERSION_AARCH64_HPP
28
29 #include "spin_wait_aarch64.hpp"
30 #include "runtime/abstract_vm_version.hpp"
31 #include "utilities/sizes.hpp"
32
33 class stringStream;
34
35 #define BIT_MASK(flag) (1ULL<<(flag))
36
37 class VM_Version : public Abstract_VM_Version {
38 friend class VMStructs;
39 friend class JVMCIVMStructs;
40
41 protected:
42 static int _cpu;
43 static int _model;
44 static int _model2;
45 static int _variant;
46 static int _revision;
47 static int _stepping;
48
49 static int _zva_length;
50 static int _dcache_line_size;
51 static int _icache_line_size;
52 static int _initial_sve_vector_length;
53 static int _max_supported_sve_vector_length;
54 static bool _rop_protection;
55 static uintptr_t _pac_mask;
56
57 static SpinWait _spin_wait;
58
59 // Read additional info using OS-specific interfaces
60 static void get_os_cpu_info();
61
62 // Sets the SVE length and returns a new actual value or negative on error.
63 // If the len is larger than the system largest supported SVE vector length,
64 // the function sets the largest supported value.
65 static int set_and_get_current_sve_vector_length(int len);
66 static int get_current_sve_vector_length();
67
68 static void insert_features_names(uint64_t features, stringStream& ss);
69
70 public:
71 // Initialization
72 static void initialize();
73 static void check_virtualizations();
74
75 static void print_platform_virtualization_info(outputStream*);
76
77 // Asserts
78 static void assert_is_initialized() {
79 }
80
81 static bool expensive_load(int ld_size, int scale) {
82 if (cpu_family() == CPU_ARM) {
83 // Half-word load with index shift by 1 (aka scale is 2) has
84 // extra cycle latency, e.g. ldrsh w0, [x1,w2,sxtw #1].
85 if (ld_size == 2 && scale == 2) {
86 return true;
87 }
88 }
89 return false;
127 decl(EVTSTRM, evtstrm, 2) \
128 decl(AES, aes, 3) \
129 decl(PMULL, pmull, 4) \
130 decl(SHA1, sha1, 5) \
131 decl(SHA2, sha256, 6) \
132 decl(CRC32, crc32, 7) \
133 decl(LSE, lse, 8) \
134 decl(FPHP, fphp, 9) \
135 decl(ASIMDHP, asimdhp, 10) \
136 decl(DCPOP, dcpop, 16) \
137 decl(SHA3, sha3, 17) \
138 decl(SHA512, sha512, 21) \
139 decl(SVE, sve, 22) \
140 decl(PACA, paca, 30) \
141 /* flags above must follow Linux HWCAP */ \
142 decl(SVEBITPERM, svebitperm, 27) \
143 decl(SVE2, sve2, 28) \
144 decl(A53MAC, a53mac, 31)
145
146 enum Feature_Flag {
147 #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = bit,
148 CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
149 #undef DECLARE_CPU_FEATURE_FLAG
150 MAX_CPU_FEATURES
151 };
152
153 STATIC_ASSERT(sizeof(_features) * BitsPerByte >= MAX_CPU_FEATURES);
154
155 static const char* _features_names[MAX_CPU_FEATURES];
156
157 // Feature identification
158 #define CPU_FEATURE_DETECTION(id, name, bit) \
159 static bool supports_##name() { return supports_feature(CPU_##id); }
160 CPU_FEATURE_FLAGS(CPU_FEATURE_DETECTION)
161 #undef CPU_FEATURE_DETECTION
162
163 static void set_feature(Feature_Flag flag) {
164 _features |= BIT_MASK(flag);
165 }
166 static void clear_feature(Feature_Flag flag) {
167 _features &= (~BIT_MASK(flag));
168 }
169 static bool supports_feature(Feature_Flag flag) {
170 return (_features & BIT_MASK(flag)) != 0;
171 }
172 static bool supports_feature(uint64_t features, Feature_Flag flag) {
173 return (features & BIT_MASK(flag)) != 0;
174 }
175
176 static int cpu_family() { return _cpu; }
177 static int cpu_model() { return _model; }
178 static int cpu_model2() { return _model2; }
179 static int cpu_variant() { return _variant; }
180 static int cpu_revision() { return _revision; }
181
182 static bool model_is(int cpu_model) {
183 return _model == cpu_model || _model2 == cpu_model;
184 }
185
186 static bool is_zva_enabled() { return 0 <= _zva_length; }
187 static int zva_length() {
188 assert(is_zva_enabled(), "ZVA not available");
189 return _zva_length;
190 }
191
192 static int icache_line_size() { return _icache_line_size; }
193 static int dcache_line_size() { return _dcache_line_size; }
194 static int get_initial_sve_vector_length() { return _initial_sve_vector_length; };
195 static int get_max_supported_sve_vector_length() { return _max_supported_sve_vector_length; };
206 static const SpinWait& spin_wait_desc() { return _spin_wait; }
207
208 static bool supports_on_spin_wait() { return _spin_wait.inst() != SpinWait::NONE; }
209
210 static bool supports_float16() { return true; }
211
212 #ifdef __APPLE__
213 // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64)
214 static bool is_cpu_emulated();
215 #endif
216
217 static void initialize_cpu_information(void);
218
219 static bool use_rop_protection() { return _rop_protection; }
220
221 // For common 64/128-bit unpredicated vector operations, we may prefer
222 // emitting NEON instructions rather than the corresponding SVE instructions.
223 static bool use_neon_for_vector(int vector_length_in_bytes) {
224 return vector_length_in_bytes <= 16;
225 }
226
227 static void get_cpu_features_name(void* features_buffer, stringStream& ss);
228 static void get_missing_features_name(void* features_buffer, stringStream& ss);
229
230 // Returns number of bytes required to store cpu features representation
231 static int cpu_features_size();
232
233 // Stores cpu features representation in the provided buffer. This representation is arch dependent.
234 // Size of the buffer must be same as returned by cpu_features_size()
235 static void store_cpu_features(void* buf);
236
237 static bool supports_features(void* features_to_test);
238 };
239
240 #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
|