< prev index next >

src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp

Print this page

        

@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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.

@@ -1953,11 +1953,11 @@
     __ z_la(data, 3+1*wordSize, argP);  // byte value (stack address).
                                         // Being passed as an int, the single byte is at offset +3.
     __ z_llgf(crc, 2 * wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
 
     StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
-    __ kernel_crc32_singleByte(crc, data, dataLen, table, Z_R1);
+    __ kernel_crc32_singleByte(crc, data, dataLen, table, Z_R1, true);
 
     // Restore caller sp for c2i case.
     __ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
 
     __ z_br(Z_R14);

@@ -2030,11 +2030,11 @@
 
     StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
 
     __ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
     __ z_stmg(t0, t3, 1*8, Z_SP);        // Spill regs 10..13 to make them available as work registers.
-    __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3);
+    __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, true);
     __ z_lmg(t0, t3, 1*8, Z_SP);         // Spill regs 10..13 back from stack.
 
     // Restore caller sp for c2i case.
     __ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
 

@@ -2049,12 +2049,77 @@
   }
 
   return NULL;
 }
 
-// Not supported
+
+// Method entry for static native methods:
+//   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int len)
+//   int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int len)
 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+
+  if (UseCRC32CIntrinsics) {
+    uint64_t entry_off = __ offset();
+
+    // We don't generate local frame and don't align stack because
+    // we call stub code and there is no safepoint on this path.
+
+    // Load parameters.
+    // Z_esp is callers operand stack pointer, i.e. it points to the parameters.
+    const Register argP    = Z_esp;
+    const Register crc     = Z_ARG1;  // crc value
+    const Register data    = Z_ARG2;  // address of java byte array
+    const Register dataLen = Z_ARG3;  // source data len
+    const Register table   = Z_ARG4;  // address of crc32 table
+    const Register t0      = Z_R10;   // work reg for kernel* emitters
+    const Register t1      = Z_R11;   // work reg for kernel* emitters
+    const Register t2      = Z_R12;   // work reg for kernel* emitters
+    const Register t3      = Z_R13;   // work reg for kernel* emitters
+
+    // Arguments are reversed on java expression stack.
+    // Calculate address of start element.
+    if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateByteBuffer direct".
+      // crc     @ (SP + 5W) (32bit)
+      // buf     @ (SP + 3W) (64bit ptr to long array)
+      // off     @ (SP + 2W) (32bit)
+      // dataLen @ (SP + 1W) (32bit)
+      // data = buf + off
+      BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
+      __ z_llgf(crc,    5*wordSize, argP);  // current crc state
+      __ z_lg(data,     3*wordSize, argP);  // start of byte buffer
+      __ z_agf(data,    2*wordSize, argP);  // Add byte buffer offset.
+      __ z_lgf(dataLen, 1*wordSize, argP);  // #bytes to process
+    } else {                                                                // Used for "updateBytes update".
+      // crc     @ (SP + 4W) (32bit)
+      // buf     @ (SP + 3W) (64bit ptr to byte array)
+      // off     @ (SP + 2W) (32bit)
+      // dataLen @ (SP + 1W) (32bit)
+      // data = buf + off + base_offset
+      BLOCK_COMMENT("CRC32C_updateBytes {");
+      __ z_llgf(crc,    4*wordSize, argP);  // current crc state
+      __ z_lg(data,     3*wordSize, argP);  // start of byte buffer
+      __ z_agf(data,    2*wordSize, argP);  // Add byte buffer offset.
+      __ z_lgf(dataLen, 1*wordSize, argP);  // #bytes to process
+      __ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
+    }
+
+    StubRoutines::zarch::generate_load_crc32c_table_addr(_masm, table);
+
+    __ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
+    __ z_stmg(t0, t3, 1*8, Z_SP);        // Spill regs 10..13 to make them available as work registers.
+    __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, false);
+    __ z_lmg(t0, t3, 1*8, Z_SP);         // Spill regs 10..13 back from stack.
+
+    // Restore caller sp for c2i case.
+    __ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
+
+    __ z_br(Z_R14);
+
+    BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
+    return __ addr_at(entry_off);
+  }
+
   return NULL;
 }
 
 void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
   // Quick & dirty stack overflow checking: bang the stack & handle trap.
< prev index next >