hotspot/src/cpu/x86/vm/vm_version_x86.cpp
changeset 46440 61025eecb743
parent 43936 093cd5bea2e2
child 46458 3c12af929e7d
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Sat May 06 00:05:32 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Fri May 05 19:28:54 2017 -0700
@@ -436,14 +436,14 @@
     __ movl(rax, 0x10000);
     __ andl(rax, Address(rsi, 4));
     __ cmpl(rax, 0x10000);
-    __ jccb(Assembler::notEqual, legacy_save_restore);
+    __ jcc(Assembler::notEqual, legacy_save_restore);
     // check _cpuid_info.xem_xcr0_eax.bits.opmask
     // check _cpuid_info.xem_xcr0_eax.bits.zmm512
     // check _cpuid_info.xem_xcr0_eax.bits.zmm32
     __ movl(rax, 0xE0);
     __ andl(rax, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); // xcr0 bits sse | ymm
     __ cmpl(rax, 0xE0);
-    __ jccb(Assembler::notEqual, legacy_save_restore);
+    __ jcc(Assembler::notEqual, legacy_save_restore);
 
     // If UseAVX is unitialized or is set by the user to include EVEX
     if (use_evex) {
@@ -469,11 +469,12 @@
       __ evmovdqul(xmm7, Address(rsp, 0), Assembler::AVX_512bit);
       __ addptr(rsp, 64);
 #endif // _WINDOWS
+      generate_vzeroupper(wrapup);
       VM_Version::clean_cpuFeatures();
       UseAVX = saved_useavx;
       UseSSE = saved_usesse;
       __ jmp(wrapup);
-    }
+   }
 
     __ bind(legacy_save_restore);
     // AVX check
@@ -498,6 +499,7 @@
     __ vmovdqu(xmm7, Address(rsp, 0));
     __ addptr(rsp, 32);
 #endif // _WINDOWS
+    generate_vzeroupper(wrapup);
     VM_Version::clean_cpuFeatures();
     UseAVX = saved_useavx;
     UseSSE = saved_usesse;
@@ -513,6 +515,21 @@
 
     return start;
   };
+  void generate_vzeroupper(Label& L_wrapup) {
+#   define __ _masm->
+    __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset())));
+    __ cmpl(Address(rsi, 4), 0x756e6547);  // 'uneG'
+    __ jcc(Assembler::notEqual, L_wrapup);
+    __ movl(rcx, 0x0FFF0FF0);
+    __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())));
+    __ andl(rcx, Address(rsi, 0));
+    __ cmpl(rcx, 0x00050670);              // If it is Xeon Phi 3200/5200/7200
+    __ jcc(Assembler::equal, L_wrapup);
+    __ cmpl(rcx, 0x00080650);              // If it is Future Xeon Phi
+    __ jcc(Assembler::equal, L_wrapup);
+    __ vzeroupper();
+#   undef __
+  }
 };
 
 void VM_Version::get_processor_features() {
@@ -619,8 +636,10 @@
   if (UseAVX < 2)
     _features &= ~CPU_AVX2;
 
-  if (UseAVX < 1)
+  if (UseAVX < 1) {
     _features &= ~CPU_AVX;
+    _features &= ~CPU_VZEROUPPER;
+  }
 
   if (!UseAES && !FLAG_IS_DEFAULT(UseAES))
     _features &= ~CPU_AES;
@@ -630,6 +649,14 @@
     _features &= ~CPU_HT;
   }
 
+  if( is_intel() ) { // Intel cpus specific settings
+    if ((cpu_family() == 0x06) &&
+        ((extended_cpu_model() == 0x57) ||   // Xeon Phi 3200/5200/7200
+        (extended_cpu_model() == 0x85))) {  // Future Xeon Phi
+      _features &= ~CPU_VZEROUPPER;
+    }
+  }
+
   char buf[256];
   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%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                cores_per_cpu(), threads_per_core(),
@@ -918,16 +945,36 @@
       warning("MaxVectorSize must be a power of 2");
       FLAG_SET_DEFAULT(MaxVectorSize, 64);
     }
-    if (MaxVectorSize > 64) {
-      FLAG_SET_DEFAULT(MaxVectorSize, 64);
-    }
-    if (MaxVectorSize > 16 && (UseAVX == 0 || !os_supports_avx_vectors())) {
-      // 32 bytes vectors (in YMM) are only supported with AVX+
-      FLAG_SET_DEFAULT(MaxVectorSize, 16);
-    }
     if (UseSSE < 2) {
       // Vectors (in XMM) are only supported with SSE2+
-      FLAG_SET_DEFAULT(MaxVectorSize, 0);
+      if (MaxVectorSize > 0) {
+        if (!FLAG_IS_DEFAULT(MaxVectorSize))
+          warning("MaxVectorSize must be 0");
+        FLAG_SET_DEFAULT(MaxVectorSize, 0);
+      }
+    }
+    else if (UseAVX == 0 || !os_supports_avx_vectors()) {
+      // 32 bytes vectors (in YMM) are only supported with AVX+
+      if (MaxVectorSize > 16) {
+        if (!FLAG_IS_DEFAULT(MaxVectorSize))
+          warning("MaxVectorSize must be <= 16");
+        FLAG_SET_DEFAULT(MaxVectorSize, 16);
+      }
+    }
+    else if (UseAVX == 1 || UseAVX == 2) {
+      // 64 bytes vectors (in ZMM) are only supported with AVX 3
+      if (MaxVectorSize > 32) {
+        if (!FLAG_IS_DEFAULT(MaxVectorSize))
+          warning("MaxVectorSize must be <= 32");
+        FLAG_SET_DEFAULT(MaxVectorSize, 32);
+      }
+    }
+    else if (UseAVX > 2 ) {
+      if (MaxVectorSize > 64) {
+        if (!FLAG_IS_DEFAULT(MaxVectorSize))
+          warning("MaxVectorSize must be <= 64");
+        FLAG_SET_DEFAULT(MaxVectorSize, 64);
+      }
     }
 #if defined(COMPILER2) && defined(ASSERT)
     if (supports_avx() && PrintMiscellaneous && Verbose && TraceNewVectors) {