diff src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 11080:b800986664f4

7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32 Summary: add intrinsics using new instruction to interpreter, C1, C2, for suitable x86; add test Reviewed-by: kvn, twisti
author drchase
date Tue, 02 Jul 2013 20:42:12 -0400
parents ef57c43512d6
children 980532a806a5
line wrap: on
line diff
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Jul 02 07:51:31 2013 +0200
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Jul 02 20:42:12 2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2713,6 +2713,59 @@
     return start;
   }
 
+  /**
+   *  Arguments:
+   *
+   * Inputs:
+   *   rsp(4)   - int crc
+   *   rsp(8)   - byte* buf
+   *   rsp(12)  - int length
+   *
+   * Ouput:
+   *       rax   - int crc result
+   */
+  address generate_updateBytesCRC32() {
+    assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions");
+
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32");
+
+    address start = __ pc();
+
+    const Register crc   = rdx;  // crc
+    const Register buf   = rsi;  // source java byte array address
+    const Register len   = rcx;  // length
+    const Register table = rdi;  // crc_table address (reuse register)
+    const Register tmp   = rbx;
+    assert_different_registers(crc, buf, len, table, tmp, rax);
+
+    BLOCK_COMMENT("Entry:");
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    __ push(rsi);
+    __ push(rdi);
+    __ push(rbx);
+
+    Address crc_arg(rbp, 8 + 0);
+    Address buf_arg(rbp, 8 + 4);
+    Address len_arg(rbp, 8 + 8);
+
+    // Load up:
+    __ movl(crc,   crc_arg);
+    __ movptr(buf, buf_arg);
+    __ movl(len,   len_arg);
+
+    __ kernel_crc32(crc, buf, len, table, tmp);
+
+    __ movl(rax, crc);
+    __ pop(rbx);
+    __ pop(rdi);
+    __ pop(rsi);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
 
  public:
   // Information about frame layout at time of blocking runtime call.
@@ -2887,6 +2940,12 @@
 
     // Build this early so it's available for the interpreter
     StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",           CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
+
+    if (UseCRC32Intrinsics) {
+      // set table address before stub generation which use it
+      StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
+      StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
+    }
   }