Mon, 11 Apr 2011 15:30:31 -0700
7035713: 3DNow Prefetch Instruction Support
Summary: The upcoming processors from AMD are the first that support 3dnow prefetch without supporting the 3dnow instruction set.
Reviewed-by: kvn
Contributed-by: tom.deneau@amd.com
1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Sat Apr 09 22:55:25 2011 -0700 1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Mon Apr 11 15:30:31 2011 -0700 1.3 @@ -2317,7 +2317,7 @@ 1.4 } 1.5 1.6 void Assembler::prefetchr(Address src) { 1.7 - NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); 1.8 + NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support")); 1.9 InstructionMark im(this); 1.10 prefetch_prefix(src); 1.11 emit_byte(0x0D); 1.12 @@ -2349,7 +2349,7 @@ 1.13 } 1.14 1.15 void Assembler::prefetchw(Address src) { 1.16 - NOT_LP64(assert(VM_Version::supports_3dnow(), "must support")); 1.17 + NOT_LP64(assert(VM_Version::supports_3dnow_prefetch(), "must support")); 1.18 InstructionMark im(this); 1.19 prefetch_prefix(src); 1.20 emit_byte(0x0D);
2.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Sat Apr 09 22:55:25 2011 -0700 2.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Apr 11 15:30:31 2011 -0700 2.3 @@ -1401,7 +1401,7 @@ 2.4 default: 2.5 ShouldNotReachHere(); break; 2.6 } 2.7 - } else if (VM_Version::supports_3dnow()) { 2.8 + } else if (VM_Version::supports_3dnow_prefetch()) { 2.9 __ prefetchr(from_addr); 2.10 } 2.11 } 2.12 @@ -1424,7 +1424,7 @@ 2.13 default: 2.14 ShouldNotReachHere(); break; 2.15 } 2.16 - } else if (VM_Version::supports_3dnow()) { 2.17 + } else if (VM_Version::supports_3dnow_prefetch()) { 2.18 __ prefetchw(from_addr); 2.19 } 2.20 }
3.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp Sat Apr 09 22:55:25 2011 -0700 3.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Mon Apr 11 15:30:31 2011 -0700 3.3 @@ -348,7 +348,7 @@ 3.4 } 3.5 3.6 char buf[256]; 3.7 - jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 3.8 + jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 3.9 cores_per_cpu(), threads_per_core(), 3.10 cpu_family(), _model, _stepping, 3.11 (supports_cmov() ? ", cmov" : ""), 3.12 @@ -363,8 +363,7 @@ 3.13 (supports_sse4_2() ? ", sse4.2" : ""), 3.14 (supports_popcnt() ? ", popcnt" : ""), 3.15 (supports_mmx_ext() ? ", mmxext" : ""), 3.16 - (supports_3dnow() ? ", 3dnow" : ""), 3.17 - (supports_3dnow2() ? ", 3dnowext" : ""), 3.18 + (supports_3dnow_prefetch() ? ", 3dnowpref" : ""), 3.19 (supports_lzcnt() ? ", lzcnt": ""), 3.20 (supports_sse4a() ? ", sse4a": ""), 3.21 (supports_ht() ? ", ht": "")); 3.22 @@ -522,13 +521,13 @@ 3.23 // set valid Prefetch instruction 3.24 if( ReadPrefetchInstr < 0 ) ReadPrefetchInstr = 0; 3.25 if( ReadPrefetchInstr > 3 ) ReadPrefetchInstr = 3; 3.26 - if( ReadPrefetchInstr == 3 && !supports_3dnow() ) ReadPrefetchInstr = 0; 3.27 - if( !supports_sse() && supports_3dnow() ) ReadPrefetchInstr = 3; 3.28 + if( ReadPrefetchInstr == 3 && !supports_3dnow_prefetch() ) ReadPrefetchInstr = 0; 3.29 + if( !supports_sse() && supports_3dnow_prefetch() ) ReadPrefetchInstr = 3; 3.30 3.31 if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0; 3.32 if( AllocatePrefetchInstr > 3 ) AllocatePrefetchInstr = 3; 3.33 - if( AllocatePrefetchInstr == 3 && !supports_3dnow() ) AllocatePrefetchInstr=0; 3.34 - if( !supports_sse() && supports_3dnow() ) AllocatePrefetchInstr = 3; 3.35 + if( AllocatePrefetchInstr == 3 && !supports_3dnow_prefetch() ) AllocatePrefetchInstr=0; 3.36 + if( !supports_sse() && supports_3dnow_prefetch() ) AllocatePrefetchInstr = 3; 3.37 3.38 // Allocation prefetch settings 3.39 intx cache_line_size = L1_data_cache_line_size(); 3.40 @@ -576,10 +575,10 @@ 3.41 logical_processors_per_package()); 3.42 tty->print_cr("UseSSE=%d",UseSSE); 3.43 tty->print("Allocation: "); 3.44 - if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow()) { 3.45 + if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) { 3.46 tty->print_cr("no prefetching"); 3.47 } else { 3.48 - if (UseSSE == 0 && supports_3dnow()) { 3.49 + if (UseSSE == 0 && supports_3dnow_prefetch()) { 3.50 tty->print("PREFETCHW"); 3.51 } else if (UseSSE >= 1) { 3.52 if (AllocatePrefetchInstr == 0) {
4.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp Sat Apr 09 22:55:25 2011 -0700 4.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Mon Apr 11 15:30:31 2011 -0700 4.3 @@ -188,7 +188,8 @@ 4.4 CPU_FXSR = (1 << 2), 4.5 CPU_HT = (1 << 3), 4.6 CPU_MMX = (1 << 4), 4.7 - CPU_3DNOW = (1 << 5), // 3DNow comes from cpuid 0x80000001 (EDX) 4.8 + CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions 4.9 + // may not necessarily support other 3dnow instructions 4.10 CPU_SSE = (1 << 6), 4.11 CPU_SSE2 = (1 << 7), 4.12 CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX) 4.13 @@ -328,8 +329,9 @@ 4.14 4.15 // AMD features. 4.16 if (is_amd()) { 4.17 - if (_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) 4.18 - result |= CPU_3DNOW; 4.19 + if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || 4.20 + (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) 4.21 + result |= CPU_3DNOW_PREFETCH; 4.22 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) 4.23 result |= CPU_LZCNT; 4.24 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0) 4.25 @@ -446,9 +448,8 @@ 4.26 // 4.27 // AMD features 4.28 // 4.29 - static bool supports_3dnow() { return (_cpuFeatures & CPU_3DNOW) != 0; } 4.30 + static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; } 4.31 static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; } 4.32 - static bool supports_3dnow2() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; } 4.33 static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; } 4.34 static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; } 4.35
5.1 --- a/src/cpu/x86/vm/x86_32.ad Sat Apr 09 22:55:25 2011 -0700 5.2 +++ b/src/cpu/x86/vm/x86_32.ad Mon Apr 11 15:30:31 2011 -0700 5.3 @@ -3423,7 +3423,7 @@ 5.4 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 5.5 5.6 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 5.7 - if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { 5.8 + if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.9 // prefetchw [eax + Offset(_owner)-2] 5.10 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 5.11 } 5.12 @@ -3467,7 +3467,7 @@ 5.13 masm.movptr(boxReg, tmpReg) ; 5.14 5.15 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 5.16 - if ((EmitSync & 2048) && VM_Version::supports_3dnow() && os::is_MP()) { 5.17 + if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.18 // prefetchw [eax + Offset(_owner)-2] 5.19 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 5.20 } 5.21 @@ -3614,7 +3614,7 @@ 5.22 // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html. 5.23 5.24 masm.get_thread (boxReg) ; 5.25 - if ((EmitSync & 4096) && VM_Version::supports_3dnow() && os::is_MP()) { 5.26 + if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.27 // prefetchw [ebx + Offset(_owner)-2] 5.28 masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); 5.29 } 5.30 @@ -7333,7 +7333,7 @@ 5.31 // Must be safe to execute with invalid address (cannot fault). 5.32 5.33 instruct prefetchr0( memory mem ) %{ 5.34 - predicate(UseSSE==0 && !VM_Version::supports_3dnow()); 5.35 + predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 5.36 match(PrefetchRead mem); 5.37 ins_cost(0); 5.38 size(0); 5.39 @@ -7343,7 +7343,7 @@ 5.40 %} 5.41 5.42 instruct prefetchr( memory mem ) %{ 5.43 - predicate(UseSSE==0 && VM_Version::supports_3dnow() || ReadPrefetchInstr==3); 5.44 + predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3); 5.45 match(PrefetchRead mem); 5.46 ins_cost(100); 5.47 5.48 @@ -7387,7 +7387,7 @@ 5.49 %} 5.50 5.51 instruct prefetchw0( memory mem ) %{ 5.52 - predicate(UseSSE==0 && !VM_Version::supports_3dnow()); 5.53 + predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 5.54 match(PrefetchWrite mem); 5.55 ins_cost(0); 5.56 size(0); 5.57 @@ -7397,7 +7397,7 @@ 5.58 %} 5.59 5.60 instruct prefetchw( memory mem ) %{ 5.61 - predicate(UseSSE==0 && VM_Version::supports_3dnow() || AllocatePrefetchInstr==3); 5.62 + predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || AllocatePrefetchInstr==3); 5.63 match( PrefetchWrite mem ); 5.64 ins_cost(100); 5.65