diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index b657c1f108ddf..03bb0b9ff85b1 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -2713,6 +2713,9 @@ enum Nf { INSN(maxu, 0b0110011, 0b111, 0b0000101); INSN(min, 0b0110011, 0b100, 0b0000101); INSN(minu, 0b0110011, 0b101, 0b0000101); + INSN(clmul, 0b0110011, 0b001, 0b0000101); + INSN(clmulh, 0b0110011, 0b011, 0b0000101); + INSN(clmulr, 0b0110011, 0b010, 0b0000101); #undef INSN diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index bc312bfc52cf3..d72502e356e8a 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -119,6 +119,7 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \ product(bool, UseZvbb, false, DIAGNOSTIC, "Use Zvbb instructions") \ product(bool, UseZvbc, false, DIAGNOSTIC, "Use Zvbc instructions") \ + product(bool, UseZbc, false, EXPERIMENTAL, "Use Zbc instructions") \ product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \ product(bool, UseZvfhmin, false, DIAGNOSTIC, "Use Zvfhmin instructions") \ product(bool, UseZvkg, false, DIAGNOSTIC, "Use Zvkg instructions") \ diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 7a339d83d252a..456199b256ebc 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -2731,6 +2731,185 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, andn(crc, tmp5, crc); } +// Advance buf to the next 8-byte boundary, folding each byte into crc via the +// byte lookup table. tmp1 holds the alignment count, tmp2 the loaded byte. +void MacroAssembler::kernel_crc32c_clmul_align(Register crc, Register buf, Register len, + Register table, Register tmp1, Register tmp2) { + assert_different_registers(crc, buf, len, table, tmp1, tmp2); + Label L_adjust, L_loop, L_done; + + // bytes to next 8-byte boundary: (-buf) & 7 = 8 - (buf & 7) + neg(tmp1, buf); + andi(tmp1, tmp1, 7); + + // tmp1 = min(tmp1, len) + bleu(tmp1, len, L_adjust); + mv(tmp1, len); + bind(L_adjust); + subw(len, len, tmp1); + beqz(tmp1, L_done); + + bind(L_loop); + lbu(tmp2, Address(buf, 0)); + addi(buf, buf, 1); + update_byte_crc32(crc, tmp2, table); + addi(tmp1, tmp1, -1); + bnez(tmp1, L_loop); + bind(L_done); +} + +// Fold 128 bits of input into the 128-bit accumulator (accum_hi:accum_lo). +// With the next 16 input bytes as (data_hi:data_lo) and * = carry-less mul: +// accum_lo' = (accum_lo*k1)[63:0] XOR (accum_hi*k2)[63:0] XOR data_lo +// accum_hi' = (accum_lo*k1)[127:64] XOR (accum_hi*k2)[127:64] XOR data_hi +void MacroAssembler::kernel_crc32c_clmul_fold_128(Register accum_lo, Register accum_hi, + Register k1, Register k2, Register buf, Register tmp1, Register tmp2) { + assert_different_registers(accum_lo, accum_hi, k1, k2, buf, tmp1, tmp2); + + clmul(tmp1, accum_lo, k1); + clmulh(tmp2, accum_lo, k1); + + clmul(accum_lo, accum_hi, k2); + clmulh(accum_hi, accum_hi, k2); + + xorr(accum_lo, accum_lo, tmp1); + ld(tmp1, Address(buf, 0)); // tmp1 = data_lo + xorr(accum_lo, accum_lo, tmp1); + + xorr(accum_hi, accum_hi, tmp2); + ld(tmp1, Address(buf, 8)); // tmp1 = data_hi + xorr(accum_hi, accum_hi, tmp1); +} + +// Reduce the 128-bit accumulator (accum_hi:accum_lo) to 64 bits using the +// ISA-L two-constant method. With rk1 at OFF_REDUCE_HI and rk2 at OFF_REDUCE_LO: +// x = accum_lo +// y0 = accum_hi XOR clmul(x, rk1)[63:0] +// y1 = clmulh(x, rk1)[95:64] +// accum_lo' = clmul(y0[31:0], rk2)[63:0] XOR (y1 : y0[63:32]) +void MacroAssembler::kernel_crc32c_clmul_reduce_128_to_64(Register accum_lo, Register accum_hi, + Register clmul_table, Register k, Register tmp1, Register tmp2) { + assert_different_registers(accum_lo, accum_hi, clmul_table, k, tmp1, tmp2); + + const int OFF_REDUCE_LO = 16; + const int OFF_REDUCE_HI = 24; + + ld(k, Address(clmul_table, OFF_REDUCE_HI)); + clmul(tmp1, accum_lo, k); // tmp1 = clmul(x, rk1)[63:0] + clmulh(tmp2, accum_lo, k); // tmp2 = clmulh(x, rk1) = clmul(x, rk1)[127:64] + + xorr(accum_hi, accum_hi, tmp1); // y0 = accum_hi XOR clmul(x, rk1)[63:0] + + zext(tmp1, accum_hi, 32); // tmp1 = y0[31:0] + srli(accum_hi, accum_hi, 32); // accum_hi = y0[63:32] + + ld(k, Address(clmul_table, OFF_REDUCE_LO)); + clmul(accum_lo, tmp1, k); // accum_lo' = clmul(y0[31:0], rk2)[63:0] + + slli(tmp2, tmp2, 32); // tmp2 = clmul(x, rk1)[95:64] << 32 = y1 : 0 + xorr(tmp2, tmp2, accum_hi); // tmp2 = y1 : y0[63:32] + xorr(accum_lo, accum_lo, tmp2); // accum_lo' XOR= (y1 : y0[63:32]) +} + +// Reduce the 64-bit accumulator accum_lo to a residue mod P (the 33-bit +// CRC32C polynomial) using Barrett reduction, with mu = floor(x^64/P) at +// OFF_BARRETT_MU and poly = P at OFF_BARRETT_POLY: +// q = (accum_lo[31:0] * mu)[31:0] // quotient estimate +// accum_lo XOR= (q * poly)[63:0] // subtract q*P +// The high 32 bits of accum_lo then hold the final CRC. +void MacroAssembler::kernel_crc32c_clmul_barrett_64_to_32(Register accum_lo, Register clmul_table, + Register k, Register tmp) { + assert_different_registers(accum_lo, clmul_table, k, tmp); + + const int OFF_BARRETT_MU = 32; + const int OFF_BARRETT_POLY = 40; + + zext(tmp, accum_lo, 32); // tmp = accum_lo[31:0] + + ld(k, Address(clmul_table, OFF_BARRETT_MU)); + clmul(tmp, tmp, k); + zext(tmp, tmp, 32); // tmp = q = (accum_lo[31:0] * mu)[31:0] + + ld(k, Address(clmul_table, OFF_BARRETT_POLY)); + clmul(tmp, tmp, k); + + xorr(accum_lo, accum_lo, tmp); +} + +void MacroAssembler::kernel_crc32c_clmul_fold(Register crc, Register buf, Register len, + Register byte_table, Register clmul_table, + Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6) { + assert_different_registers(crc, buf, len, byte_table, clmul_table, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6); + Label L_fold_loop, L_tail, L_tail_loop, L_exit; + + const int FOLD_THRESHOLD = 64; // fold only for inputs >= 4 FOLD_STEPs + const int FOLD_STEP = 16; + const int OFF_FOLD_K1 = 0; + const int OFF_FOLD_K2 = 8; + + mv(tmp4, FOLD_THRESHOLD); + blt(len, tmp4, L_tail); + + kernel_crc32c_clmul_align(crc, buf, len, byte_table, tmp4, tmp5); + beqz(len, L_exit); + + // fold_end = buf + len - (len mod 16); len = tail + const Register fold_end = tmp6; + add(fold_end, buf, len); + andi(len, len, FOLD_STEP - 1); + sub(fold_end, fold_end, len); + + // accum = (buf[0:8] XOR crc) : buf[8:16] + const Register accum_lo = crc; + const Register accum_hi = tmp1; + ld(tmp4, Address(buf, 0)); + xorr(accum_lo, tmp4, crc); + ld(accum_hi, Address(buf, 8)); + addi(buf, buf, FOLD_STEP); + + ld(tmp2, Address(clmul_table, OFF_FOLD_K1)); + ld(tmp3, Address(clmul_table, OFF_FOLD_K2)); + + bind(L_fold_loop); + kernel_crc32c_clmul_fold_128(accum_lo, accum_hi, tmp2, tmp3, buf, tmp4, tmp5); + addi(buf, buf, 16); + blt(buf, fold_end, L_fold_loop); + + // reduce 128->64 (ISA-L) then 64->32 (Barrett); tmp2 = k; tmp4..tmp5 reused as scratch + kernel_crc32c_clmul_reduce_128_to_64(accum_lo, accum_hi, clmul_table, tmp2, tmp4, tmp5); + kernel_crc32c_clmul_barrett_64_to_32(accum_lo, clmul_table, tmp2, tmp4); + srli(crc, accum_lo, 32); + + bind(L_tail); + add(tmp5, buf, len); // tmp5 = tail_end + bind(L_tail_loop); + bgeu(buf, tmp5, L_exit); + lbu(tmp4, Address(buf, 0)); + addi(buf, buf, 1); + update_byte_crc32(crc, tmp4, byte_table); + j(L_tail_loop); + + bind(L_exit); +} + +void MacroAssembler::kernel_crc32c(Register crc, Register buf, Register len, + Register byte_table, Register clmul_table, + Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6) { + assert_different_registers(crc, buf, len, byte_table, clmul_table, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6); + assert(UseZbc, "CRC32C intrinsic requires Zbc"); + + zext(crc, crc, 32); + + // _crc32c_table is followed by the clmul constants + const int64_t single_table_size = 256; + const ExternalAddress table_addr = StubRoutines::crc32c_table_addr(); + la(byte_table, table_addr); + add(clmul_table, byte_table, 1 * single_table_size * sizeof(juint), tmp4); + + kernel_crc32c_clmul_fold(crc, buf, len, byte_table, clmul_table, + tmp1, tmp2, tmp3, tmp4, tmp5, tmp6); +} + #ifdef COMPILER2 // Push vector registers in the bitset supplied. // Return the number of words pushed diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index f28e828fb650d..be2bf4d9dde33 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1367,6 +1367,23 @@ class MacroAssembler: public Assembler { bool upper); void update_byte_crc32(Register crc, Register val, Register table); + // CRC32C code for java.util.zip.CRC32C::updateBytes() intrinsic, + // accelerated with Zbc carry-less multiplication (clmul/clmulh). + void kernel_crc32c(Register crc, Register buf, Register len, + Register byte_table, Register clmul_table, + Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6); + void kernel_crc32c_clmul_fold(Register crc, Register buf, Register len, + Register byte_table, Register clmul_table, + Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6); + void kernel_crc32c_clmul_align(Register crc, Register buf, Register len, + Register table, Register tmp1, Register tmp2); + void kernel_crc32c_clmul_fold_128(Register accum_lo, Register accum_hi, + Register k1, Register k2, Register buf, Register tmp1, Register tmp2); + void kernel_crc32c_clmul_reduce_128_to_64(Register accum_lo, Register accum_hi, + Register clmul_table, Register k, Register tmp1, Register tmp2); + void kernel_crc32c_clmul_barrett_64_to_32(Register accum_lo, Register clmul_table, + Register k, Register tmp); + #ifdef COMPILER2 void vector_update_crc32(Register crc, Register buf, Register len, Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 11ce5695b4d2d..ff9c234816168 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -7262,6 +7262,33 @@ static const int64_t right_3_bits = right_n_bits(3); return start; } + address generate_updateBytesCRC32C(){ + assert(UseCRC32CIntrinsics, "what are we doing here?"); + + __ align(CodeEntryAlignment); + StubId stub_id = StubId::stubgen_updateBytesCRC32C_id; + StubCodeMark mark(this, stub_id); + + address start = __ pc(); + + const Register crc = c_rarg0; // crc + const Register buf = c_rarg1; // source java byte array address + const Register len = c_rarg2; // length + + BLOCK_COMMENT("Entry:"); + __ enter(); // required for proper stackwalking of RuntimeStub frame + + // c_rarg3/c_rarg4 are reused as the two table base pointers; the rest are scratch. + __ kernel_crc32c(crc, buf, len, + c_rarg3, c_rarg4, // byte_table, clmul_table + c_rarg5, c_rarg6, c_rarg7, // accum_hi, k1, k2 + t2, t3, t4); // scratch1, scratch2, fold_end + + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(); + + return start; + } // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { StubId stub_id = StubId::stubgen_upcall_stub_exception_handler_id; @@ -7333,6 +7360,10 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); } + if (UseCRC32CIntrinsics) { + StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(); + } + if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_float16ToFloat) && vmIntrinsics::is_intrinsic_available(vmIntrinsics::_floatToFloat16)) { StubRoutines::_hf2f = generate_float16ToFloat(); diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp index b7f69eff9fa31..d2bfa72da368e 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp @@ -58,7 +58,7 @@ bool StubRoutines::riscv::_completed = false; */ address StubRoutines::crc_table_addr() { return (address)StubRoutines::riscv::_crc_table; } -address StubRoutines::crc32c_table_addr() { ShouldNotCallThis(); return nullptr; } +address StubRoutines::crc32c_table_addr() { return (address)StubRoutines::riscv::_crc32c_table; } ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc_table[] = { @@ -506,6 +506,69 @@ ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc_table[] = 0xccaa009eUL, 0x00000000UL, }; +ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc32c_table[] ={ + 0x00000000UL, 0xF26B8303UL, 0xE13B70F7UL, 0x1350F3F4UL, 0xC79A971FUL, + 0x35F1141CUL, 0x26A1E7E8UL, 0xD4CA64EBUL, 0x8AD958CFUL, 0x78B2DBCCUL, + 0x6BE22838UL, 0x9989AB3BUL, 0x4D43CFD0UL, 0xBF284CD3UL, 0xAC78BF27UL, + 0x5E133C24UL, 0x105EC76FUL, 0xE235446CUL, 0xF165B798UL, 0x030E349BUL, + 0xD7C45070UL, 0x25AFD373UL, 0x36FF2087UL, 0xC494A384UL, 0x9A879FA0UL, + 0x68EC1CA3UL, 0x7BBCEF57UL, 0x89D76C54UL, 0x5D1D08BFUL, 0xAF768BBCUL, + 0xBC267848UL, 0x4E4DFB4BUL, 0x20BD8EDEUL, 0xD2D60DDDUL, 0xC186FE29UL, + 0x33ED7D2AUL, 0xE72719C1UL, 0x154C9AC2UL, 0x061C6936UL, 0xF477EA35UL, + 0xAA64D611UL, 0x580F5512UL, 0x4B5FA6E6UL, 0xB93425E5UL, 0x6DFE410EUL, + 0x9F95C20DUL, 0x8CC531F9UL, 0x7EAEB2FAUL, 0x30E349B1UL, 0xC288CAB2UL, + 0xD1D83946UL, 0x23B3BA45UL, 0xF779DEAEUL, 0x05125DADUL, 0x1642AE59UL, + 0xE4292D5AUL, 0xBA3A117EUL, 0x4851927DUL, 0x5B016189UL, 0xA96AE28AUL, + 0x7DA08661UL, 0x8FCB0562UL, 0x9C9BF696UL, 0x6EF07595UL, 0x417B1DBCUL, + 0xB3109EBFUL, 0xA0406D4BUL, 0x522BEE48UL, 0x86E18AA3UL, 0x748A09A0UL, + 0x67DAFA54UL, 0x95B17957UL, 0xCBA24573UL, 0x39C9C670UL, 0x2A993584UL, + 0xD8F2B687UL, 0x0C38D26CUL, 0xFE53516FUL, 0xED03A29BUL, 0x1F682198UL, + 0x5125DAD3UL, 0xA34E59D0UL, 0xB01EAA24UL, 0x42752927UL, 0x96BF4DCCUL, + 0x64D4CECFUL, 0x77843D3BUL, 0x85EFBE38UL, 0xDBFC821CUL, 0x2997011FUL, + 0x3AC7F2EBUL, 0xC8AC71E8UL, 0x1C661503UL, 0xEE0D9600UL, 0xFD5D65F4UL, + 0x0F36E6F7UL, 0x61C69362UL, 0x93AD1061UL, 0x80FDE395UL, 0x72966096UL, + 0xA65C047DUL, 0x5437877EUL, 0x4767748AUL, 0xB50CF789UL, 0xEB1FCBADUL, + 0x197448AEUL, 0x0A24BB5AUL, 0xF84F3859UL, 0x2C855CB2UL, 0xDEEEDFB1UL, + 0xCDBE2C45UL, 0x3FD5AF46UL, 0x7198540DUL, 0x83F3D70EUL, 0x90A324FAUL, + 0x62C8A7F9UL, 0xB602C312UL, 0x44694011UL, 0x5739B3E5UL, 0xA55230E6UL, + 0xFB410CC2UL, 0x092A8FC1UL, 0x1A7A7C35UL, 0xE811FF36UL, 0x3CDB9BDDUL, + 0xCEB018DEUL, 0xDDE0EB2AUL, 0x2F8B6829UL, 0x82F63B78UL, 0x709DB87BUL, + 0x63CD4B8FUL, 0x91A6C88CUL, 0x456CAC67UL, 0xB7072F64UL, 0xA457DC90UL, + 0x563C5F93UL, 0x082F63B7UL, 0xFA44E0B4UL, 0xE9141340UL, 0x1B7F9043UL, + 0xCFB5F4A8UL, 0x3DDE77ABUL, 0x2E8E845FUL, 0xDCE5075CUL, 0x92A8FC17UL, + 0x60C37F14UL, 0x73938CE0UL, 0x81F80FE3UL, 0x55326B08UL, 0xA759E80BUL, + 0xB4091BFFUL, 0x466298FCUL, 0x1871A4D8UL, 0xEA1A27DBUL, 0xF94AD42FUL, + 0x0B21572CUL, 0xDFEB33C7UL, 0x2D80B0C4UL, 0x3ED04330UL, 0xCCBBC033UL, + 0xA24BB5A6UL, 0x502036A5UL, 0x4370C551UL, 0xB11B4652UL, 0x65D122B9UL, + 0x97BAA1BAUL, 0x84EA524EUL, 0x7681D14DUL, 0x2892ED69UL, 0xDAF96E6AUL, + 0xC9A99D9EUL, 0x3BC21E9DUL, 0xEF087A76UL, 0x1D63F975UL, 0x0E330A81UL, + 0xFC588982UL, 0xB21572C9UL, 0x407EF1CAUL, 0x532E023EUL, 0xA145813DUL, + 0x758FE5D6UL, 0x87E466D5UL, 0x94B49521UL, 0x66DF1622UL, 0x38CC2A06UL, + 0xCAA7A905UL, 0xD9F75AF1UL, 0x2B9CD9F2UL, 0xFF56BD19UL, 0x0D3D3E1AUL, + 0x1E6DCDEEUL, 0xEC064EEDUL, 0xC38D26C4UL, 0x31E6A5C7UL, 0x22B65633UL, + 0xD0DDD530UL, 0x0417B1DBUL, 0xF67C32D8UL, 0xE52CC12CUL, 0x1747422FUL, + 0x49547E0BUL, 0xBB3FFD08UL, 0xA86F0EFCUL, 0x5A048DFFUL, 0x8ECEE914UL, + 0x7CA56A17UL, 0x6FF599E3UL, 0x9D9E1AE0UL, 0xD3D3E1ABUL, 0x21B862A8UL, + 0x32E8915CUL, 0xC083125FUL, 0x144976B4UL, 0xE622F5B7UL, 0xF5720643UL, + 0x07198540UL, 0x590AB964UL, 0xAB613A67UL, 0xB831C993UL, 0x4A5A4A90UL, + 0x9E902E7BUL, 0x6CFBAD78UL, 0x7FAB5E8CUL, 0x8DC0DD8FUL, 0xE330A81AUL, + 0x115B2B19UL, 0x020BD8EDUL, 0xF0605BEEUL, 0x24AA3F05UL, 0xD6C1BC06UL, + 0xC5914FF2UL, 0x37FACCF1UL, 0x69E9F0D5UL, 0x9B8273D6UL, 0x88D28022UL, + 0x7AB90321UL, 0xAE7367CAUL, 0x5C18E4C9UL, 0x4F48173DUL, 0xBD23943EUL, + 0xF36E6F75UL, 0x0105EC76UL, 0x12551F82UL, 0xE03E9C81UL, 0x34F4F86AUL, + 0xC69F7B69UL, 0xD5CF889DUL, 0x27A40B9EUL, 0x79B737BAUL, 0x8BDCB4B9UL, + 0x988C474DUL, 0x6AE7C44EUL, 0xBE2DA0A5UL, 0x4C4623A6UL, 0x5F16D052UL, + 0xAD7D5351UL, + + // CRC32C constants for carry-less multiplication implementation + 0xF20C0DFEUL, 0x00000000UL, + 0x493C7D27UL, 0x00000000UL, + 0xDD45AAB8UL, 0x00000000UL, + 0x493C7D27UL, 0x00000000UL, + 0xDEA713F1UL, 0x00000000UL, + 0x05EC76F1UL, 0x00000001UL, +}; + #if INCLUDE_CDS // nothing to do for riscv void StubRoutines::init_AOTAddressTable() { diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp index b230c2657ded5..48db99f35c4d4 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp @@ -99,6 +99,7 @@ class riscv { private: static juint _crc_table[]; + static juint _crc32c_table[]; }; #endif // CPU_RISCV_STUBROUTINES_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 3a6415d52bd39..06c9f99d30d73 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -214,9 +214,15 @@ void VM_Version::common_initialize() { FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); } - if (UseCRC32CIntrinsics) { - warning("CRC32C intrinsics are not available on this CPU."); - FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); + if (UseZbc) { + if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) { + FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true); + } + } else { + if (UseCRC32CIntrinsics) { + warning("CRC32C intrinsic are not available on this CPU."); + FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); + } } } @@ -495,6 +501,12 @@ bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) { return false; } break; + case vmIntrinsics::_updateBytesCRC32C: + case vmIntrinsics::_updateDirectByteBufferCRC32C: + if (!UseCRC32CIntrinsics) { + return false; + } + break; default: break; } diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index ab048719ad244..38de795ebd113 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -248,7 +248,7 @@ class VM_Version : public Abstract_VM_Version { /* Zbb Basic bit-manipulation */ \ decl(Zbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \ /* Zbc Carry-less multiplication */ \ - decl(Zbc , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(Zbc , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbc)) \ /* Bitmanip instructions for Cryptography */ \ decl(Zbkb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \ /* Zbs Single-bit instructions */ \ @@ -434,6 +434,7 @@ class VM_Version : public Abstract_VM_Version { RV_ENABLE_EXTENSION(UseRVV) \ RV_ENABLE_EXTENSION(UseZba) \ RV_ENABLE_EXTENSION(UseZbb) \ + RV_ENABLE_EXTENSION(UseZbc) \ RV_ENABLE_EXTENSION(UseZbs) \ RV_ENABLE_EXTENSION(UseZcb) \ RV_ENABLE_EXTENSION(UseZfa) \ diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index 24c65bd21e041..94db4e27b8799 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -207,6 +207,9 @@ void RiscvHwprobe::add_features_from_query_result() { if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBB)) { VM_Version::ext_Zbb.enable_feature(); } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBC)) { + VM_Version::ext_Zbc.enable_feature(); + } #ifndef PRODUCT if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBKB)) { VM_Version::ext_Zbkb.enable_feature();