< prev index next >

src/cpu/ppc/vm/stubGenerator_ppc.cpp

Print this page

        

@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, SAP SE. 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -3274,10 +3274,40 @@
     __ blr();  // Return to caller.
 
     return start;
   }
 
+
+  // Compute CRC32/CRC32C function.
+  void generate_CRC_updateBytes(const char* name, Register table, bool invertCRC) {
+
+      // arguments to kernel_crc32:
+      const Register crc     = R3_ARG1;  // Current checksum, preset by caller or result from previous call.
+      const Register data    = R4_ARG2;  // source byte array
+      const Register dataLen = R5_ARG3;  // #bytes to process
+
+      const Register t0      = R2;
+      const Register t1      = R7;
+      const Register t2      = R8;
+      const Register t3      = R9;
+      const Register tc0     = R10;
+      const Register tc1     = R11;
+      const Register tc2     = R12;
+
+      BLOCK_COMMENT("Stub body {");
+      assert_different_registers(crc, data, dataLen, table);
+
+      __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table, invertCRC);
+
+      BLOCK_COMMENT("return");
+      __ mr_if_needed(R3_RET, crc);      // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
+      __ blr();
+
+      BLOCK_COMMENT("} Stub body");
+  }
+
+
   /**
    * Arguments:
    *
    * Inputs:
    *   R3_ARG1    - int   crc

@@ -3294,18 +3324,18 @@
   address generate_CRC32_updateBytes(const char* name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();  // Remember stub start address (is rtn value).
 
+    const Register table   = R6;       // crc table address
+
+#ifdef VM_LITTLE_ENDIAN
     // arguments to kernel_crc32:
     const Register crc     = R3_ARG1;  // Current checksum, preset by caller or result from previous call.
     const Register data    = R4_ARG2;  // source byte array
     const Register dataLen = R5_ARG3;  // #bytes to process
 
-    const Register table   = R6;       // crc table address
-
-#ifdef VM_LITTLE_ENDIAN
     if (VM_Version::has_vpmsumb()) {
       const Register constants    = R2;  // constants address
       const Register bconstants   = R8;  // barret table address
 
       const Register t0      = R9;

@@ -3319,45 +3349,93 @@
 
       StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
       StubRoutines::ppc64::generate_load_crc_constants_addr(_masm, constants);
       StubRoutines::ppc64::generate_load_crc_barret_constants_addr(_masm, bconstants);
 
-      __ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4);
+      __ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4, true);
 
       BLOCK_COMMENT("return");
       __ mr_if_needed(R3_RET, crc);      // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
       __ blr();
 
       BLOCK_COMMENT("} Stub body");
     } else
 #endif
     {
-      const Register t0      = R2;
-      const Register t1      = R7;
-      const Register t2      = R8;
-      const Register t3      = R9;
-      const Register tc0     = R10;
-      const Register tc1     = R11;
-      const Register tc2     = R12;
+      StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
+      generate_CRC_updateBytes(name, table, true);
+    }
+
+    return start;
+  }
+
+
+  /**
+   * Arguments:
+   *
+   * Inputs:
+   *   R3_ARG1    - int   crc
+   *   R4_ARG2    - byte* buf
+   *   R5_ARG3    - int   length (of buffer)
+   *
+   * scratch:
+   *   R2, R6-R12
+   *
+   * Ouput:
+   *   R3_RET     - int   crc result
+   */
+  // Compute CRC32C function.
+  address generate_CRC32C_updateBytes(const char* name) {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    address start = __ function_entry();  // Remember stub start address (is rtn value).
+
+    const Register table   = R6;       // crc table address
+
+#if 0   // no vector support yet for CRC32C
+#ifdef VM_LITTLE_ENDIAN
+    // arguments to kernel_crc32:
+    const Register crc     = R3_ARG1;  // Current checksum, preset by caller or result from previous call.
+    const Register data    = R4_ARG2;  // source byte array
+    const Register dataLen = R5_ARG3;  // #bytes to process
+
+    if (VM_Version::has_vpmsumb()) {
+      const Register constants    = R2;  // constants address
+      const Register bconstants   = R8;  // barret table address
+
+      const Register t0      = R9;
+      const Register t1      = R10;
+      const Register t2      = R11;
+      const Register t3      = R12;
+      const Register t4      = R7;
 
       BLOCK_COMMENT("Stub body {");
       assert_different_registers(crc, data, dataLen, table);
 
-      StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
+      StubRoutines::ppc64::generate_load_crc32c_table_addr(_masm, table);
+      StubRoutines::ppc64::generate_load_crc32c_constants_addr(_masm, constants);
+      StubRoutines::ppc64::generate_load_crc32c_barret_constants_addr(_masm, bconstants);
 
-      __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
+      __ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4, false);
 
       BLOCK_COMMENT("return");
       __ mr_if_needed(R3_RET, crc);      // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
       __ blr();
 
       BLOCK_COMMENT("} Stub body");
+    } else
+#endif
+#endif
+    {
+      StubRoutines::ppc64::generate_load_crc32c_table_addr(_masm, table);
+      generate_CRC_updateBytes(name, table, false);
     }
 
     return start;
   }
 
+
   // Initialization
   void generate_initial() {
     // Generates all stubs and initializes the entry points
 
     // Entry points that exist in all platforms.

@@ -3381,10 +3459,16 @@
     // CRC32 Intrinsics.
     if (UseCRC32Intrinsics) {
       StubRoutines::_crc_table_adr    = (address)StubRoutines::ppc64::_crc_table;
       StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes("CRC32_updateBytes");
     }
+
+    // CRC32C Intrinsics.
+    if (UseCRC32CIntrinsics) {
+      StubRoutines::_crc32c_table_addr = (address)StubRoutines::ppc64::_crc32c_table;
+      StubRoutines::_updateBytesCRC32C = generate_CRC32C_updateBytes("CRC32C_updateBytes");
+    }
   }
 
   void generate_all() {
     // Generates all stubs and initializes the entry points
 
< prev index next >