61 uint32_t value;
62 struct {
63 uint32_t sse3 : 1,
64 : 2,
65 monitor : 1,
66 : 1,
67 vmx : 1,
68 : 1,
69 est : 1,
70 : 1,
71 ssse3 : 1,
72 cid : 1,
73 : 2,
74 cmpxchg16: 1,
75 : 4,
76 dca : 1,
77 sse4_1 : 1,
78 sse4_2 : 1,
79 : 2,
80 popcnt : 1,
81 : 8;
82 } bits;
83 };
84
85 union StdCpuid1Edx {
86 uint32_t value;
87 struct {
88 uint32_t : 4,
89 tsc : 1,
90 : 3,
91 cmpxchg8 : 1,
92 : 6,
93 cmov : 1,
94 : 3,
95 clflush : 1,
96 : 3,
97 mmx : 1,
98 fxsr : 1,
99 sse : 1,
100 sse2 : 1,
101 : 1,
159 };
160
161 union ExtCpuid5Ex {
162 uint32_t value;
163 struct {
164 uint32_t L1_line_size : 8,
165 L1_tag_lines : 8,
166 L1_assoc : 8,
167 L1_size : 8;
168 } bits;
169 };
170
171 union ExtCpuid8Ecx {
172 uint32_t value;
173 struct {
174 uint32_t cores_per_cpu : 8,
175 : 24;
176 } bits;
177 };
178
179 protected:
180 static int _cpu;
181 static int _model;
182 static int _stepping;
183 static int _cpuFeatures; // features returned by the "cpuid" instruction
184 // 0 if this instruction is not available
185 static const char* _features_str;
186
187 enum {
188 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
189 CPU_CMOV = (1 << 1),
190 CPU_FXSR = (1 << 2),
191 CPU_HT = (1 << 3),
192 CPU_MMX = (1 << 4),
193 CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
194 // may not necessarily support other 3dnow instructions
195 CPU_SSE = (1 << 6),
196 CPU_SSE2 = (1 << 7),
197 CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
198 CPU_SSSE3 = (1 << 9),
199 CPU_SSE4A = (1 << 10),
200 CPU_SSE4_1 = (1 << 11),
201 CPU_SSE4_2 = (1 << 12),
202 CPU_POPCNT = (1 << 13),
203 CPU_LZCNT = (1 << 14)
204 } cpuFeatureFlags;
205
206 // cpuid information block. All info derived from executing cpuid with
207 // various function numbers is stored here. Intel and AMD info is
208 // merged in this block: accessor methods disentangle it.
209 //
210 // The info block is laid out in subblocks of 4 dwords corresponding to
211 // eax, ebx, ecx and edx, whether or not they contain anything useful.
212 struct CpuidInfo {
213 // cpuid function 0
214 uint32_t std_max_function;
215 uint32_t std_vendor_name_0;
216 uint32_t std_vendor_name_1;
217 uint32_t std_vendor_name_2;
218
219 // cpuid function 1
220 StdCpuid1Eax std_cpuid1_eax;
221 StdCpuid1Ebx std_cpuid1_ebx;
222 StdCpuid1Ecx std_cpuid1_ecx;
223 StdCpuid1Edx std_cpuid1_edx;
224
225 // cpuid function 4 (deterministic cache parameters)
226 DcpCpuid4Eax dcp_cpuid4_eax;
227 DcpCpuid4Ebx dcp_cpuid4_ebx;
228 uint32_t dcp_cpuid4_ecx; // unused currently
229 uint32_t dcp_cpuid4_edx; // unused currently
230
231 // cpuid function 0xB (processor topology)
232 // ecx = 0
233 uint32_t tpl_cpuidB0_eax;
234 TplCpuidBEbx tpl_cpuidB0_ebx;
235 uint32_t tpl_cpuidB0_ecx; // unused currently
236 uint32_t tpl_cpuidB0_edx; // unused currently
237
238 // ecx = 1
239 uint32_t tpl_cpuidB1_eax;
240 TplCpuidBEbx tpl_cpuidB1_ebx;
241 uint32_t tpl_cpuidB1_ecx; // unused currently
242 uint32_t tpl_cpuidB1_edx; // unused currently
243
244 // ecx = 2
245 uint32_t tpl_cpuidB2_eax;
246 TplCpuidBEbx tpl_cpuidB2_ebx;
247 uint32_t tpl_cpuidB2_ecx; // unused currently
248 uint32_t tpl_cpuidB2_edx; // unused currently
249
250 // cpuid function 0x80000000 // example, unused
258 uint32_t ext_cpuid1_ebx; // reserved
259 ExtCpuid1Ecx ext_cpuid1_ecx;
260 ExtCpuid1Edx ext_cpuid1_edx;
261
262 // cpuid functions 0x80000002 thru 0x80000004: example, unused
263 uint32_t proc_name_0, proc_name_1, proc_name_2, proc_name_3;
264 uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
265 uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
266
267 // cpuid function 0x80000005 //AMD L1, Intel reserved
268 uint32_t ext_cpuid5_eax; // unused currently
269 uint32_t ext_cpuid5_ebx; // reserved
270 ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD)
271 ExtCpuid5Ex ext_cpuid5_edx; // L1 instruction cache info (AMD)
272
273 // cpuid function 0x80000008
274 uint32_t ext_cpuid8_eax; // unused currently
275 uint32_t ext_cpuid8_ebx; // reserved
276 ExtCpuid8Ecx ext_cpuid8_ecx;
277 uint32_t ext_cpuid8_edx; // reserved
278 };
279
280 // The actual cpuid info block
281 static CpuidInfo _cpuid_info;
282
283 // Extractors and predicates
284 static uint32_t extended_cpu_family() {
285 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.family;
286 result += _cpuid_info.std_cpuid1_eax.bits.ext_family;
287 return result;
288 }
289 static uint32_t extended_cpu_model() {
290 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.model;
291 result |= _cpuid_info.std_cpuid1_eax.bits.ext_model << 4;
292 return result;
293 }
294 static uint32_t cpu_stepping() {
295 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.stepping;
296 return result;
297 }
311 // HT flag is set for multi-core processors also.
312 if (threads_per_core() > 1)
313 result |= CPU_HT;
314 if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || (is_amd() &&
315 _cpuid_info.ext_cpuid1_edx.bits.mmx != 0))
316 result |= CPU_MMX;
317 if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
318 result |= CPU_SSE;
319 if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
320 result |= CPU_SSE2;
321 if (_cpuid_info.std_cpuid1_ecx.bits.sse3 != 0)
322 result |= CPU_SSE3;
323 if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
324 result |= CPU_SSSE3;
325 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
326 result |= CPU_SSE4_1;
327 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
328 result |= CPU_SSE4_2;
329 if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
330 result |= CPU_POPCNT;
331
332 // AMD features.
333 if (is_amd()) {
334 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
335 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
336 result |= CPU_3DNOW_PREFETCH;
337 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
338 result |= CPU_LZCNT;
339 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
340 result |= CPU_SSE4A;
341 }
342
343 return result;
344 }
345
346 static void get_processor_features();
347
348 public:
349 // Offsets for cpuid asm stub
350 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
351 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
352 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
353 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); }
354 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); }
355 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); }
356 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); }
357 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); }
358 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); }
359
360 // Initialization
361 static void initialize();
362
363 // Asserts
364 static void assert_is_initialized() {
365 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized");
366 }
367
368 //
369 // Processor family:
370 // 3 - 386
371 // 4 - 486
372 // 5 - Pentium
373 // 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon,
374 // Pentium M, Core Solo, Core Duo, Core2 Duo
375 // family 6 model: 9, 13, 14, 15
376 // 0x0f - Pentium 4, Opteron
377 //
378 // Note: The cpu family should be used to select between
430 result = 32; // 32 bytes by default on x86 and other x64
431 return result;
432 }
433
434 //
435 // Feature identification
436 //
437 static bool supports_cpuid() { return _cpuFeatures != 0; }
438 static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
439 static bool supports_cmov() { return (_cpuFeatures & CPU_CMOV) != 0; }
440 static bool supports_fxsr() { return (_cpuFeatures & CPU_FXSR) != 0; }
441 static bool supports_ht() { return (_cpuFeatures & CPU_HT) != 0; }
442 static bool supports_mmx() { return (_cpuFeatures & CPU_MMX) != 0; }
443 static bool supports_sse() { return (_cpuFeatures & CPU_SSE) != 0; }
444 static bool supports_sse2() { return (_cpuFeatures & CPU_SSE2) != 0; }
445 static bool supports_sse3() { return (_cpuFeatures & CPU_SSE3) != 0; }
446 static bool supports_ssse3() { return (_cpuFeatures & CPU_SSSE3)!= 0; }
447 static bool supports_sse4_1() { return (_cpuFeatures & CPU_SSE4_1) != 0; }
448 static bool supports_sse4_2() { return (_cpuFeatures & CPU_SSE4_2) != 0; }
449 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; }
450 //
451 // AMD features
452 //
453 static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; }
454 static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
455 static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; }
456 static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; }
457
458 // Intel Core and newer cpus have fast IDIV instruction (excluding Atom).
459 static bool has_fast_idiv() { return is_intel() && cpu_family() == 6 &&
460 supports_sse3() && _model != 0x1C; }
461
462 static bool supports_compare_and_exchange() { return true; }
463
464 static const char* cpu_features() { return _features_str; }
465
466 static intx allocate_prefetch_distance() {
467 // This method should be called before allocate_prefetch_style().
468 //
469 // Hardware prefetching (distance/size in bytes):
|
61 uint32_t value;
62 struct {
63 uint32_t sse3 : 1,
64 : 2,
65 monitor : 1,
66 : 1,
67 vmx : 1,
68 : 1,
69 est : 1,
70 : 1,
71 ssse3 : 1,
72 cid : 1,
73 : 2,
74 cmpxchg16: 1,
75 : 4,
76 dca : 1,
77 sse4_1 : 1,
78 sse4_2 : 1,
79 : 2,
80 popcnt : 1,
81 : 3,
82 osxsave : 1,
83 avx : 1,
84 : 3;
85 } bits;
86 };
87
88 union StdCpuid1Edx {
89 uint32_t value;
90 struct {
91 uint32_t : 4,
92 tsc : 1,
93 : 3,
94 cmpxchg8 : 1,
95 : 6,
96 cmov : 1,
97 : 3,
98 clflush : 1,
99 : 3,
100 mmx : 1,
101 fxsr : 1,
102 sse : 1,
103 sse2 : 1,
104 : 1,
162 };
163
164 union ExtCpuid5Ex {
165 uint32_t value;
166 struct {
167 uint32_t L1_line_size : 8,
168 L1_tag_lines : 8,
169 L1_assoc : 8,
170 L1_size : 8;
171 } bits;
172 };
173
174 union ExtCpuid8Ecx {
175 uint32_t value;
176 struct {
177 uint32_t cores_per_cpu : 8,
178 : 24;
179 } bits;
180 };
181
182 union SefCpuid7Eax {
183 uint32_t value;
184 };
185
186 union SefCpuid7Ebx {
187 uint32_t value;
188 struct {
189 uint32_t fsgsbase : 1,
190 : 2,
191 bmi1 : 1,
192 : 1,
193 avx2 : 1,
194 : 2,
195 bmi2 : 1,
196 : 23;
197 } bits;
198 };
199
200 union XemXcr0Eax {
201 uint32_t value;
202 struct {
203 uint32_t x87 : 1,
204 sse : 1,
205 ymm : 1,
206 : 29;
207 } bits;
208 };
209
210 protected:
211 static int _cpu;
212 static int _model;
213 static int _stepping;
214 static int _cpuFeatures; // features returned by the "cpuid" instruction
215 // 0 if this instruction is not available
216 static const char* _features_str;
217
218 enum {
219 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
220 CPU_CMOV = (1 << 1),
221 CPU_FXSR = (1 << 2),
222 CPU_HT = (1 << 3),
223 CPU_MMX = (1 << 4),
224 CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
225 // may not necessarily support other 3dnow instructions
226 CPU_SSE = (1 << 6),
227 CPU_SSE2 = (1 << 7),
228 CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
229 CPU_SSSE3 = (1 << 9),
230 CPU_SSE4A = (1 << 10),
231 CPU_SSE4_1 = (1 << 11),
232 CPU_SSE4_2 = (1 << 12),
233 CPU_POPCNT = (1 << 13),
234 CPU_LZCNT = (1 << 14),
235 CPU_AVX = (1 << 15),
236 CPU_AVX2 = (1 << 16)
237 } cpuFeatureFlags;
238
239 // cpuid information block. All info derived from executing cpuid with
240 // various function numbers is stored here. Intel and AMD info is
241 // merged in this block: accessor methods disentangle it.
242 //
243 // The info block is laid out in subblocks of 4 dwords corresponding to
244 // eax, ebx, ecx and edx, whether or not they contain anything useful.
245 struct CpuidInfo {
246 // cpuid function 0
247 uint32_t std_max_function;
248 uint32_t std_vendor_name_0;
249 uint32_t std_vendor_name_1;
250 uint32_t std_vendor_name_2;
251
252 // cpuid function 1
253 StdCpuid1Eax std_cpuid1_eax;
254 StdCpuid1Ebx std_cpuid1_ebx;
255 StdCpuid1Ecx std_cpuid1_ecx;
256 StdCpuid1Edx std_cpuid1_edx;
257
258 // cpuid function 4 (deterministic cache parameters)
259 DcpCpuid4Eax dcp_cpuid4_eax;
260 DcpCpuid4Ebx dcp_cpuid4_ebx;
261 uint32_t dcp_cpuid4_ecx; // unused currently
262 uint32_t dcp_cpuid4_edx; // unused currently
263
264 // cpuid function 7 (structured extended features)
265 SefCpuid7Eax sef_cpuid7_eax;
266 SefCpuid7Ebx sef_cpuid7_ebx;
267 uint32_t sef_cpuid7_ecx; // unused currently
268 uint32_t sef_cpuid7_edx; // unused currently
269
270 // cpuid function 0xB (processor topology)
271 // ecx = 0
272 uint32_t tpl_cpuidB0_eax;
273 TplCpuidBEbx tpl_cpuidB0_ebx;
274 uint32_t tpl_cpuidB0_ecx; // unused currently
275 uint32_t tpl_cpuidB0_edx; // unused currently
276
277 // ecx = 1
278 uint32_t tpl_cpuidB1_eax;
279 TplCpuidBEbx tpl_cpuidB1_ebx;
280 uint32_t tpl_cpuidB1_ecx; // unused currently
281 uint32_t tpl_cpuidB1_edx; // unused currently
282
283 // ecx = 2
284 uint32_t tpl_cpuidB2_eax;
285 TplCpuidBEbx tpl_cpuidB2_ebx;
286 uint32_t tpl_cpuidB2_ecx; // unused currently
287 uint32_t tpl_cpuidB2_edx; // unused currently
288
289 // cpuid function 0x80000000 // example, unused
297 uint32_t ext_cpuid1_ebx; // reserved
298 ExtCpuid1Ecx ext_cpuid1_ecx;
299 ExtCpuid1Edx ext_cpuid1_edx;
300
301 // cpuid functions 0x80000002 thru 0x80000004: example, unused
302 uint32_t proc_name_0, proc_name_1, proc_name_2, proc_name_3;
303 uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
304 uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
305
306 // cpuid function 0x80000005 //AMD L1, Intel reserved
307 uint32_t ext_cpuid5_eax; // unused currently
308 uint32_t ext_cpuid5_ebx; // reserved
309 ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD)
310 ExtCpuid5Ex ext_cpuid5_edx; // L1 instruction cache info (AMD)
311
312 // cpuid function 0x80000008
313 uint32_t ext_cpuid8_eax; // unused currently
314 uint32_t ext_cpuid8_ebx; // reserved
315 ExtCpuid8Ecx ext_cpuid8_ecx;
316 uint32_t ext_cpuid8_edx; // reserved
317
318 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register)
319 XemXcr0Eax xem_xcr0_eax;
320 uint32_t xem_xcr0_edx; // reserved
321 };
322
323 // The actual cpuid info block
324 static CpuidInfo _cpuid_info;
325
326 // Extractors and predicates
327 static uint32_t extended_cpu_family() {
328 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.family;
329 result += _cpuid_info.std_cpuid1_eax.bits.ext_family;
330 return result;
331 }
332 static uint32_t extended_cpu_model() {
333 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.model;
334 result |= _cpuid_info.std_cpuid1_eax.bits.ext_model << 4;
335 return result;
336 }
337 static uint32_t cpu_stepping() {
338 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.stepping;
339 return result;
340 }
354 // HT flag is set for multi-core processors also.
355 if (threads_per_core() > 1)
356 result |= CPU_HT;
357 if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || (is_amd() &&
358 _cpuid_info.ext_cpuid1_edx.bits.mmx != 0))
359 result |= CPU_MMX;
360 if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
361 result |= CPU_SSE;
362 if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
363 result |= CPU_SSE2;
364 if (_cpuid_info.std_cpuid1_ecx.bits.sse3 != 0)
365 result |= CPU_SSE3;
366 if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
367 result |= CPU_SSSE3;
368 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
369 result |= CPU_SSE4_1;
370 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
371 result |= CPU_SSE4_2;
372 if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
373 result |= CPU_POPCNT;
374 if (_cpuid_info.std_cpuid1_ecx.bits.avx != 0 &&
375 _cpuid_info.std_cpuid1_ecx.bits.osxsave != 0 &&
376 _cpuid_info.xem_xcr0_eax.bits.sse != 0 &&
377 _cpuid_info.xem_xcr0_eax.bits.ymm != 0) {
378 result |= CPU_AVX;
379 if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0)
380 result |= CPU_AVX2;
381 }
382
383 // AMD features.
384 if (is_amd()) {
385 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
386 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
387 result |= CPU_3DNOW_PREFETCH;
388 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
389 result |= CPU_LZCNT;
390 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
391 result |= CPU_SSE4A;
392 }
393
394 return result;
395 }
396
397 static void get_processor_features();
398
399 public:
400 // Offsets for cpuid asm stub
401 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
402 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
403 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
404 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); }
405 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); }
406 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); }
407 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); }
408 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); }
409 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); }
410 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); }
411 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); }
412
413 // Initialization
414 static void initialize();
415
416 // Asserts
417 static void assert_is_initialized() {
418 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized");
419 }
420
421 //
422 // Processor family:
423 // 3 - 386
424 // 4 - 486
425 // 5 - Pentium
426 // 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon,
427 // Pentium M, Core Solo, Core Duo, Core2 Duo
428 // family 6 model: 9, 13, 14, 15
429 // 0x0f - Pentium 4, Opteron
430 //
431 // Note: The cpu family should be used to select between
483 result = 32; // 32 bytes by default on x86 and other x64
484 return result;
485 }
486
487 //
488 // Feature identification
489 //
490 static bool supports_cpuid() { return _cpuFeatures != 0; }
491 static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
492 static bool supports_cmov() { return (_cpuFeatures & CPU_CMOV) != 0; }
493 static bool supports_fxsr() { return (_cpuFeatures & CPU_FXSR) != 0; }
494 static bool supports_ht() { return (_cpuFeatures & CPU_HT) != 0; }
495 static bool supports_mmx() { return (_cpuFeatures & CPU_MMX) != 0; }
496 static bool supports_sse() { return (_cpuFeatures & CPU_SSE) != 0; }
497 static bool supports_sse2() { return (_cpuFeatures & CPU_SSE2) != 0; }
498 static bool supports_sse3() { return (_cpuFeatures & CPU_SSE3) != 0; }
499 static bool supports_ssse3() { return (_cpuFeatures & CPU_SSSE3)!= 0; }
500 static bool supports_sse4_1() { return (_cpuFeatures & CPU_SSE4_1) != 0; }
501 static bool supports_sse4_2() { return (_cpuFeatures & CPU_SSE4_2) != 0; }
502 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; }
503 static bool supports_avx() { return (_cpuFeatures & CPU_AVX) != 0; }
504 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; }
505 //
506 // AMD features
507 //
508 static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; }
509 static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
510 static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; }
511 static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; }
512
513 // Intel Core and newer cpus have fast IDIV instruction (excluding Atom).
514 static bool has_fast_idiv() { return is_intel() && cpu_family() == 6 &&
515 supports_sse3() && _model != 0x1C; }
516
517 static bool supports_compare_and_exchange() { return true; }
518
519 static const char* cpu_features() { return _features_str; }
520
521 static intx allocate_prefetch_distance() {
522 // This method should be called before allocate_prefetch_style().
523 //
524 // Hardware prefetching (distance/size in bytes):
|