< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Print this page

        

@@ -4386,10 +4386,63 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
     return start;
 }
 
+// Polynomial x^128+x^127+x^126+x^121+1
+address ghash_polynomial_addr() {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "_ghash_poly_addr");
+    address start = __ pc();
+    __ emit_data64(0x0000000000000001, relocInfo::none);
+    __ emit_data64(0xc200000000000000, relocInfo::none);
+    return start;
+}
+
+address ghash_shufflemask_addr() {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "_ghash_shuffmask_addr");
+    address start = __ pc();
+    __ emit_data64(0x0f0f0f0f0f0f0f0f, relocInfo::none);
+    __ emit_data64(0x0f0f0f0f0f0f0f0f, relocInfo::none);
+    return start;
+}
+
+// Ghash single and multi block operations using AVX instructions
+address generate_avx_ghash_processBlocks() {
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
+    address start = __ pc();
+
+    // arguments
+    const Register state = c_rarg0;
+    const Register htbl = c_rarg1;
+    const Register data = c_rarg2;
+    const Register blocks = c_rarg3;
+    __ enter();
+   // Save state before entering routine
+    __ push(r12);
+    __ push(r13);
+    __ push(r14);
+    __ push(r15);
+    __ push(rbx);
+    __ push(rbp);
+
+    __ avx_ghash(state, htbl, data, blocks);
+
+    __ pop(rbp);
+    __ pop(rbx);
+    __ pop(r15);
+    __ pop(r14);
+    __ pop(r13);
+    __ pop(r12);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+    return start;
+}
+
   // byte swap x86 long
   address generate_ghash_long_swap_mask() {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask");
     address start = __ pc();

@@ -5886,12 +5939,18 @@
 
     // Generate GHASH intrinsics code
     if (UseGHASHIntrinsics) {
       StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
       StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask();
+      if (VM_Version::supports_avx()) {
+          StubRoutines::x86::_ghash_shuffmask_addr = ghash_shufflemask_addr();
+          StubRoutines::x86::_ghash_poly_addr = ghash_polynomial_addr();
+          StubRoutines::_ghash_processBlocks = generate_avx_ghash_processBlocks();
+      } else {
       StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
     }
+    }
 
     if (UseBASE64Intrinsics) {
       StubRoutines::x86::_and_mask = base64_and_mask_addr();
       StubRoutines::x86::_bswap_mask = base64_bswap_mask_addr();
       StubRoutines::x86::_base64_charset = base64_charset_addr();
< prev index next >