--- old/src/cpu/s390/vm/macroAssembler_s390.cpp 2017-03-02 17:12:10.927901000 +0100 +++ new/src/cpu/s390/vm/macroAssembler_s390.cpp 2017-03-02 17:12:10.810871000 +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 @@ -5884,8 +5884,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; @@ -5895,20 +5894,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); } @@ -5925,6 +5916,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); @@ -5943,17 +5935,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); } @@ -5966,7 +5953,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; @@ -5981,7 +5969,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 { @@ -5996,7 +5986,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 @@ -6004,21 +5994,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_brct(ctr, L_mainLoop); // Iterate. - z_lrvr(crc, crc); // Revert byte order back to original. + 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); + update_byteLoop_crc32(crc, buf, len, table, data); - not_(crc, noreg, false); // 1s complement of crc + if (invertCRC) { + not_(crc, noreg, false); // 1s complement of crc + } } /** @@ -6030,7 +6022,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; @@ -6044,7 +6037,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); @@ -6056,13 +6051,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); + update_byteLoop_crc32(crc, buf, len, table, data); - not_(crc, noreg, false); // 1s complement of crc + if (invertCRC) { + not_(crc, noreg, false); // 1s complement of crc + } } /** @@ -6072,22 +6070,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); + 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) { +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 + } } //