hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp
changeset 46315 a796c32af782
parent 46289 1904e7ec236e
child 46327 91576389a517
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Tue Mar 07 22:58:16 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Wed Mar 08 14:55:32 2017 +0100
@@ -1,6 +1,6 @@
 /*
- * 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
@@ -5910,8 +5910,7 @@
  * @param len   register containing number of bytes
  * @param table register pointing to CRC table
  */
-void MacroAssembler::update_byteLoop_crc32(Register crc, Register buf, Register len, Register table,
-                                           Register data, bool invertCRC) {
+void MacroAssembler::update_byteLoop_crc32(Register crc, Register buf, Register len, Register table, Register data) {
   assert_different_registers(crc, buf, len, table, data);
 
   Label L_mainLoop, L_done;
@@ -5921,20 +5920,12 @@
   z_ltr(len, len);
   z_brnh(L_done);
 
-  if (invertCRC) {
-    not_(crc, noreg, false); // ~c
-  }
-
   bind(L_mainLoop);
     z_llgc(data, Address(buf, (intptr_t)0));// Current byte of input buffer (zero extended). Avoids garbage in upper half of register.
     add2reg(buf, mainLoop_stepping);        // Advance buffer position.
     update_byte_crc32(crc, data, table);
     z_brct(len, L_mainLoop);                // Iterate.
 
-  if (invertCRC) {
-    not_(crc, noreg, false); // ~c
-  }
-
   bind(L_done);
 }
 
@@ -5951,6 +5942,7 @@
   //         c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
   //             crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
   // #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+  // Pre-calculate (constant) column offsets, use columns 4..7 for big-endian.
   const int ix0 = 4*(4*CRC32_COLUMN_SIZE);
   const int ix1 = 5*(4*CRC32_COLUMN_SIZE);
   const int ix2 = 6*(4*CRC32_COLUMN_SIZE);
@@ -5969,17 +5961,12 @@
   rotate_then_insert(t1, t0, 56-2, 63-2, 2-16, true);  // ((c >> 16) & 0xff) << 2
   rotate_then_insert(t0, t0, 56-2, 63-2, 2-24, true);  // ((c >> 24) & 0xff) << 2
 
-  // Load pre-calculated table values.
-  // Use columns 4..7 for big-endian.
-  z_ly(t3, Address(table, t3, (intptr_t)ix0));
+  // XOR indexed table values to calculate updated crc.
   z_ly(t2, Address(table, t2, (intptr_t)ix1));
-  z_ly(t1, Address(table, t1, (intptr_t)ix2));
   z_ly(t0, Address(table, t0, (intptr_t)ix3));
-
-  // Calculate new crc from table values.
-  z_xr(t2, t3);
-  z_xr(t0, t1);
-  z_xr(t0, t2);  // Now crc contains the final checksum value.
+  z_xy(t2, Address(table, t3, (intptr_t)ix0));
+  z_xy(t0, Address(table, t1, (intptr_t)ix2));
+  z_xr(t0, t2);           // Now t0 contains the updated CRC value.
   lgr_if_needed(crc, t0);
 }
 
@@ -5992,7 +5979,8 @@
  * uses Z_R10..Z_R13 as work register. Must be saved/restored by caller!
  */
 void MacroAssembler::kernel_crc32_2word(Register crc, Register buf, Register len, Register table,
-                                        Register t0,  Register t1,  Register t2,  Register t3) {
+                                        Register t0,  Register t1,  Register t2,  Register t3,
+                                        bool invertCRC) {
   assert_different_registers(crc, buf, len, table);
 
   Label L_mainLoop, L_tail;
@@ -6007,7 +5995,9 @@
   // The situation itself is detected and handled correctly by the conditional branches
   // following aghi(len, -stepping) and aghi(len, +stepping).
 
-  not_(crc, noreg, false);             // 1s complement of crc
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 
 #if 0
   {
@@ -6022,7 +6012,7 @@
     rotate_then_insert(ctr, ctr, 62, 63, 0, true); // TODO: should set cc
     z_sgfr(len, ctr);                  // Remaining len after alignment.
 
-    update_byteLoop_crc32(crc, buf, ctr, table, data, false);
+    update_byteLoop_crc32(crc, buf, ctr, table, data);
   }
 #endif
 
@@ -6030,21 +6020,23 @@
   z_srag(ctr, len, log_stepping);
   z_brnh(L_tail);
 
-  z_lrvr(crc, crc);             // Revert byte order because we are dealing with big-endian data.
+  z_lrvr(crc, crc);          // Revert byte order because we are dealing with big-endian data.
   rotate_then_insert(len, len, 64-log_stepping, 63, 0, true); // #bytes for tailLoop
 
   BIND(L_mainLoop);
     update_1word_crc32(crc, buf, table, 0, 0, crc, t1, t2, t3);
     update_1word_crc32(crc, buf, table, 4, mainLoop_stepping, crc, t1, t2, t3);
-    z_brct(ctr, L_mainLoop);    // Iterate.
-
-  z_lrvr(crc, crc);        // Revert byte order back to original.
+    z_brct(ctr, L_mainLoop); // Iterate.
+
+  z_lrvr(crc, crc);          // Revert byte order back to original.
 
   // Process last few (<8) bytes of buffer.
   BIND(L_tail);
-  update_byteLoop_crc32(crc, buf, len, table, data, false);
-
-  not_(crc, noreg, false); // 1s complement of crc
+  update_byteLoop_crc32(crc, buf, len, table, data);
+
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 }
 
 /**
@@ -6056,7 +6048,8 @@
  * uses Z_R10..Z_R13 as work register. Must be saved/restored by caller!
  */
 void MacroAssembler::kernel_crc32_1word(Register crc, Register buf, Register len, Register table,
-                                        Register t0,  Register t1,  Register t2,  Register t3) {
+                                        Register t0,  Register t1,  Register t2,  Register t3,
+                                        bool invertCRC) {
   assert_different_registers(crc, buf, len, table);
 
   Label L_mainLoop, L_tail;
@@ -6070,7 +6063,9 @@
   // The situation itself is detected and handled correctly by the conditional branches
   // following aghi(len, -stepping) and aghi(len, +stepping).
 
-  not_(crc, noreg, false); // 1s complement of crc
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 
   // Check for short (<4 bytes) buffer.
   z_srag(ctr, len, log_stepping);
@@ -6082,13 +6077,16 @@
   BIND(L_mainLoop);
     update_1word_crc32(crc, buf, table, 0, mainLoop_stepping, crc, t1, t2, t3);
     z_brct(ctr, L_mainLoop); // Iterate.
+
   z_lrvr(crc, crc);          // Revert byte order back to original.
 
   // Process last few (<8) bytes of buffer.
   BIND(L_tail);
-  update_byteLoop_crc32(crc, buf, len, table, data, false);
-
-  not_(crc, noreg, false); // 1s complement of crc
+  update_byteLoop_crc32(crc, buf, len, table, data);
+
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 }
 
 /**
@@ -6098,22 +6096,51 @@
  * @param table register pointing to CRC table
  */
 void MacroAssembler::kernel_crc32_1byte(Register crc, Register buf, Register len, Register table,
-                                        Register t0,  Register t1,  Register t2,  Register t3) {
+                                        Register t0,  Register t1,  Register t2,  Register t3,
+                                        bool invertCRC) {
   assert_different_registers(crc, buf, len, table);
   Register data = t0;
 
-  update_byteLoop_crc32(crc, buf, len, table, data, true);
-}
-
-void MacroAssembler::kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp) {
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
+
+  update_byteLoop_crc32(crc, buf, len, table, data);
+
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
+}
+
+void MacroAssembler::kernel_crc32_singleByte(Register crc, Register buf, Register len, Register table, Register tmp,
+                                             bool invertCRC) {
   assert_different_registers(crc, buf, len, table, tmp);
 
-  not_(crc, noreg, false); // ~c
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 
   z_llgc(tmp, Address(buf, (intptr_t)0));  // Current byte of input buffer (zero extended). Avoids garbage in upper half of register.
   update_byte_crc32(crc, tmp, table);
 
-  not_(crc, noreg, false); // ~c
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
+}
+
+void MacroAssembler::kernel_crc32_singleByteReg(Register crc, Register val, Register table,
+                                                bool invertCRC) {
+  assert_different_registers(crc, val, table);
+
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
+
+  update_byte_crc32(crc, val, table);
+
+  if (invertCRC) {
+    not_(crc, noreg, false);           // 1s complement of crc
+  }
 }
 
 //