--- 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
+ }
}
//