--- old/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2018-11-20 18:13:26.063536300 -0800 +++ new/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2018-11-20 18:13:25.374467400 -0800 @@ -4388,6 +4388,59 @@ 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); @@ -5886,9 +5939,15 @@ // 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(); - StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + 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) {