Skip to content

Commit ca092dd

Browse files
committed
8389223: RISC-V: Implement CRC32C intrinsic using Zbc extension
1 parent 44ef318 commit ca092dd

10 files changed

Lines changed: 316 additions & 5 deletions

src/hotspot/cpu/riscv/assembler_riscv.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,6 +2713,9 @@ enum Nf {
27132713
INSN(maxu, 0b0110011, 0b111, 0b0000101);
27142714
INSN(min, 0b0110011, 0b100, 0b0000101);
27152715
INSN(minu, 0b0110011, 0b101, 0b0000101);
2716+
INSN(clmul, 0b0110011, 0b001, 0b0000101);
2717+
INSN(clmulh, 0b0110011, 0b011, 0b0000101);
2718+
INSN(clmulr, 0b0110011, 0b010, 0b0000101);
27162719

27172720
#undef INSN
27182721

src/hotspot/cpu/riscv/globals_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
119119
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
120120
product(bool, UseZvbb, false, DIAGNOSTIC, "Use Zvbb instructions") \
121121
product(bool, UseZvbc, false, DIAGNOSTIC, "Use Zvbc instructions") \
122+
product(bool, UseZbc, false, EXPERIMENTAL, "Use Zbc instructions") \
122123
product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \
123124
product(bool, UseZvfhmin, false, DIAGNOSTIC, "Use Zvfhmin instructions") \
124125
product(bool, UseZvkg, false, DIAGNOSTIC, "Use Zvkg instructions") \

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,6 +2731,185 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len,
27312731
andn(crc, tmp5, crc);
27322732
}
27332733

2734+
// Advance buf to the next 8-byte boundary, folding each byte into crc via the
2735+
// byte lookup table. tmp1 holds the alignment count, tmp2 the loaded byte.
2736+
void MacroAssembler::kernel_crc32c_clmul_align(Register crc, Register buf, Register len,
2737+
Register table, Register tmp1, Register tmp2) {
2738+
assert_different_registers(crc, buf, len, table, tmp1, tmp2);
2739+
Label L_adjust, L_loop, L_done;
2740+
2741+
// bytes to next 8-byte boundary: (-buf) & 7 = 8 - (buf & 7)
2742+
neg(tmp1, buf);
2743+
andi(tmp1, tmp1, 7);
2744+
2745+
// tmp1 = min(tmp1, len)
2746+
bleu(tmp1, len, L_adjust);
2747+
mv(tmp1, len);
2748+
bind(L_adjust);
2749+
subw(len, len, tmp1);
2750+
beqz(tmp1, L_done);
2751+
2752+
bind(L_loop);
2753+
lbu(tmp2, Address(buf, 0));
2754+
addi(buf, buf, 1);
2755+
update_byte_crc32(crc, tmp2, table);
2756+
addi(tmp1, tmp1, -1);
2757+
bnez(tmp1, L_loop);
2758+
bind(L_done);
2759+
}
2760+
2761+
// Fold 128 bits of input into the 128-bit accumulator (accum_hi:accum_lo).
2762+
// With the next 16 input bytes as (data_hi:data_lo) and * = carry-less mul:
2763+
// accum_lo' = (accum_lo*k1)[63:0] XOR (accum_hi*k2)[63:0] XOR data_lo
2764+
// accum_hi' = (accum_lo*k1)[127:64] XOR (accum_hi*k2)[127:64] XOR data_hi
2765+
void MacroAssembler::kernel_crc32c_clmul_fold_128(Register accum_lo, Register accum_hi,
2766+
Register k1, Register k2, Register buf, Register tmp1, Register tmp2) {
2767+
assert_different_registers(accum_lo, accum_hi, k1, k2, buf, tmp1, tmp2);
2768+
2769+
clmul(tmp1, accum_lo, k1);
2770+
clmulh(tmp2, accum_lo, k1);
2771+
2772+
clmul(accum_lo, accum_hi, k2);
2773+
clmulh(accum_hi, accum_hi, k2);
2774+
2775+
xorr(accum_lo, accum_lo, tmp1);
2776+
ld(tmp1, Address(buf, 0)); // tmp1 = data_lo
2777+
xorr(accum_lo, accum_lo, tmp1);
2778+
2779+
xorr(accum_hi, accum_hi, tmp2);
2780+
ld(tmp1, Address(buf, 8)); // tmp1 = data_hi
2781+
xorr(accum_hi, accum_hi, tmp1);
2782+
}
2783+
2784+
// Reduce the 128-bit accumulator (accum_hi:accum_lo) to 64 bits using the
2785+
// ISA-L two-constant method. With rk1 at OFF_REDUCE_HI and rk2 at OFF_REDUCE_LO:
2786+
// x = accum_lo
2787+
// y0 = accum_hi XOR clmul(x, rk1)[63:0]
2788+
// y1 = clmulh(x, rk1)[95:64]
2789+
// accum_lo' = clmul(y0[31:0], rk2)[63:0] XOR (y1 : y0[63:32])
2790+
void MacroAssembler::kernel_crc32c_clmul_reduce_128_to_64(Register accum_lo, Register accum_hi,
2791+
Register clmul_table, Register k, Register tmp1, Register tmp2) {
2792+
assert_different_registers(accum_lo, accum_hi, clmul_table, k, tmp1, tmp2);
2793+
2794+
const int OFF_REDUCE_LO = 16;
2795+
const int OFF_REDUCE_HI = 24;
2796+
2797+
ld(k, Address(clmul_table, OFF_REDUCE_HI));
2798+
clmul(tmp1, accum_lo, k); // tmp1 = clmul(x, rk1)[63:0]
2799+
clmulh(tmp2, accum_lo, k); // tmp2 = clmulh(x, rk1) = clmul(x, rk1)[127:64]
2800+
2801+
xorr(accum_hi, accum_hi, tmp1); // y0 = accum_hi XOR clmul(x, rk1)[63:0]
2802+
2803+
zext(tmp1, accum_hi, 32); // tmp1 = y0[31:0]
2804+
srli(accum_hi, accum_hi, 32); // accum_hi = y0[63:32]
2805+
2806+
ld(k, Address(clmul_table, OFF_REDUCE_LO));
2807+
clmul(accum_lo, tmp1, k); // accum_lo' = clmul(y0[31:0], rk2)[63:0]
2808+
2809+
slli(tmp2, tmp2, 32); // tmp2 = clmul(x, rk1)[95:64] << 32 = y1 : 0
2810+
xorr(tmp2, tmp2, accum_hi); // tmp2 = y1 : y0[63:32]
2811+
xorr(accum_lo, accum_lo, tmp2); // accum_lo' XOR= (y1 : y0[63:32])
2812+
}
2813+
2814+
// Reduce the 64-bit accumulator accum_lo to a residue mod P (the 33-bit
2815+
// CRC32C polynomial) using Barrett reduction, with mu = floor(x^64/P) at
2816+
// OFF_BARRETT_MU and poly = P at OFF_BARRETT_POLY:
2817+
// q = (accum_lo[31:0] * mu)[31:0] // quotient estimate
2818+
// accum_lo XOR= (q * poly)[63:0] // subtract q*P
2819+
// The high 32 bits of accum_lo then hold the final CRC.
2820+
void MacroAssembler::kernel_crc32c_clmul_barrett_64_to_32(Register accum_lo, Register clmul_table,
2821+
Register k, Register tmp) {
2822+
assert_different_registers(accum_lo, clmul_table, k, tmp);
2823+
2824+
const int OFF_BARRETT_MU = 32;
2825+
const int OFF_BARRETT_POLY = 40;
2826+
2827+
zext(tmp, accum_lo, 32); // tmp = accum_lo[31:0]
2828+
2829+
ld(k, Address(clmul_table, OFF_BARRETT_MU));
2830+
clmul(tmp, tmp, k);
2831+
zext(tmp, tmp, 32); // tmp = q = (accum_lo[31:0] * mu)[31:0]
2832+
2833+
ld(k, Address(clmul_table, OFF_BARRETT_POLY));
2834+
clmul(tmp, tmp, k);
2835+
2836+
xorr(accum_lo, accum_lo, tmp);
2837+
}
2838+
2839+
void MacroAssembler::kernel_crc32c_clmul_fold(Register crc, Register buf, Register len,
2840+
Register byte_table, Register clmul_table,
2841+
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6) {
2842+
assert_different_registers(crc, buf, len, byte_table, clmul_table, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);
2843+
Label L_fold_loop, L_tail, L_tail_loop, L_exit;
2844+
2845+
const int FOLD_THRESHOLD = 64; // fold only for inputs >= 4 FOLD_STEPs
2846+
const int FOLD_STEP = 16;
2847+
const int OFF_FOLD_K1 = 0;
2848+
const int OFF_FOLD_K2 = 8;
2849+
2850+
mv(tmp4, FOLD_THRESHOLD);
2851+
blt(len, tmp4, L_tail);
2852+
2853+
kernel_crc32c_clmul_align(crc, buf, len, byte_table, tmp4, tmp5);
2854+
beqz(len, L_exit);
2855+
2856+
// fold_end = buf + len - (len mod 16); len = tail
2857+
const Register fold_end = tmp6;
2858+
add(fold_end, buf, len);
2859+
andi(len, len, FOLD_STEP - 1);
2860+
sub(fold_end, fold_end, len);
2861+
2862+
// accum = (buf[0:8] XOR crc) : buf[8:16]
2863+
const Register accum_lo = crc;
2864+
const Register accum_hi = tmp1;
2865+
ld(tmp4, Address(buf, 0));
2866+
xorr(accum_lo, tmp4, crc);
2867+
ld(accum_hi, Address(buf, 8));
2868+
addi(buf, buf, FOLD_STEP);
2869+
2870+
ld(tmp2, Address(clmul_table, OFF_FOLD_K1));
2871+
ld(tmp3, Address(clmul_table, OFF_FOLD_K2));
2872+
2873+
bind(L_fold_loop);
2874+
kernel_crc32c_clmul_fold_128(accum_lo, accum_hi, tmp2, tmp3, buf, tmp4, tmp5);
2875+
addi(buf, buf, 16);
2876+
blt(buf, fold_end, L_fold_loop);
2877+
2878+
// reduce 128->64 (ISA-L) then 64->32 (Barrett); tmp2 = k; tmp4..tmp5 reused as scratch
2879+
kernel_crc32c_clmul_reduce_128_to_64(accum_lo, accum_hi, clmul_table, tmp2, tmp4, tmp5);
2880+
kernel_crc32c_clmul_barrett_64_to_32(accum_lo, clmul_table, tmp2, tmp4);
2881+
srli(crc, accum_lo, 32);
2882+
2883+
bind(L_tail);
2884+
add(tmp5, buf, len); // tmp5 = tail_end
2885+
bind(L_tail_loop);
2886+
bgeu(buf, tmp5, L_exit);
2887+
lbu(tmp4, Address(buf, 0));
2888+
addi(buf, buf, 1);
2889+
update_byte_crc32(crc, tmp4, byte_table);
2890+
j(L_tail_loop);
2891+
2892+
bind(L_exit);
2893+
}
2894+
2895+
void MacroAssembler::kernel_crc32c(Register crc, Register buf, Register len,
2896+
Register byte_table, Register clmul_table,
2897+
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6) {
2898+
assert_different_registers(crc, buf, len, byte_table, clmul_table, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);
2899+
assert(UseZbc, "CRC32C intrinsic requires Zbc");
2900+
2901+
zext(crc, crc, 32);
2902+
2903+
// _crc32c_table is followed by the clmul constants
2904+
const int64_t single_table_size = 256;
2905+
const ExternalAddress table_addr = StubRoutines::crc32c_table_addr();
2906+
la(byte_table, table_addr);
2907+
add(clmul_table, byte_table, 1 * single_table_size * sizeof(juint), tmp4);
2908+
2909+
kernel_crc32c_clmul_fold(crc, buf, len, byte_table, clmul_table,
2910+
tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);
2911+
}
2912+
27342913
#ifdef COMPILER2
27352914
// Push vector registers in the bitset supplied.
27362915
// Return the number of words pushed

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,23 @@ class MacroAssembler: public Assembler {
13671367
bool upper);
13681368
void update_byte_crc32(Register crc, Register val, Register table);
13691369

1370+
// CRC32C code for java.util.zip.CRC32C::updateBytes() intrinsic,
1371+
// accelerated with Zbc carry-less multiplication (clmul/clmulh).
1372+
void kernel_crc32c(Register crc, Register buf, Register len,
1373+
Register byte_table, Register clmul_table,
1374+
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6);
1375+
void kernel_crc32c_clmul_fold(Register crc, Register buf, Register len,
1376+
Register byte_table, Register clmul_table,
1377+
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6);
1378+
void kernel_crc32c_clmul_align(Register crc, Register buf, Register len,
1379+
Register table, Register tmp1, Register tmp2);
1380+
void kernel_crc32c_clmul_fold_128(Register accum_lo, Register accum_hi,
1381+
Register k1, Register k2, Register buf, Register tmp1, Register tmp2);
1382+
void kernel_crc32c_clmul_reduce_128_to_64(Register accum_lo, Register accum_hi,
1383+
Register clmul_table, Register k, Register tmp1, Register tmp2);
1384+
void kernel_crc32c_clmul_barrett_64_to_32(Register accum_lo, Register clmul_table,
1385+
Register k, Register tmp);
1386+
13701387
#ifdef COMPILER2
13711388
void vector_update_crc32(Register crc, Register buf, Register len,
13721389
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,

src/hotspot/cpu/riscv/stubGenerator_riscv.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7262,6 +7262,33 @@ static const int64_t right_3_bits = right_n_bits(3);
72627262
return start;
72637263
}
72647264

7265+
address generate_updateBytesCRC32C(){
7266+
assert(UseCRC32CIntrinsics, "what are we doing here?");
7267+
7268+
__ align(CodeEntryAlignment);
7269+
StubId stub_id = StubId::stubgen_updateBytesCRC32C_id;
7270+
StubCodeMark mark(this, stub_id);
7271+
7272+
address start = __ pc();
7273+
7274+
const Register crc = c_rarg0; // crc
7275+
const Register buf = c_rarg1; // source java byte array address
7276+
const Register len = c_rarg2; // length
7277+
7278+
BLOCK_COMMENT("Entry:");
7279+
__ enter(); // required for proper stackwalking of RuntimeStub frame
7280+
7281+
// c_rarg3/c_rarg4 are reused as the two table base pointers; the rest are scratch.
7282+
__ kernel_crc32c(crc, buf, len,
7283+
c_rarg3, c_rarg4, // byte_table, clmul_table
7284+
c_rarg5, c_rarg6, c_rarg7, // accum_hi, k1, k2
7285+
t2, t3, t4); // scratch1, scratch2, fold_end
7286+
7287+
__ leave(); // required for proper stackwalking of RuntimeStub frame
7288+
__ ret();
7289+
7290+
return start;
7291+
}
72657292
// exception handler for upcall stubs
72667293
address generate_upcall_stub_exception_handler() {
72677294
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);
73337360
StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
73347361
}
73357362

7363+
if (UseCRC32CIntrinsics) {
7364+
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
7365+
}
7366+
73367367
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_float16ToFloat) &&
73377368
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_floatToFloat16)) {
73387369
StubRoutines::_hf2f = generate_float16ToFloat();

src/hotspot/cpu/riscv/stubRoutines_riscv.cpp

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ bool StubRoutines::riscv::_completed = false;
5858
*/
5959

6060
address StubRoutines::crc_table_addr() { return (address)StubRoutines::riscv::_crc_table; }
61-
address StubRoutines::crc32c_table_addr() { ShouldNotCallThis(); return nullptr; }
61+
address StubRoutines::crc32c_table_addr() { return (address)StubRoutines::riscv::_crc32c_table; }
6262

6363
ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc_table[] =
6464
{
@@ -506,6 +506,69 @@ ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc_table[] =
506506
0xccaa009eUL, 0x00000000UL,
507507
};
508508

509+
ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc32c_table[] ={
510+
0x00000000UL, 0xF26B8303UL, 0xE13B70F7UL, 0x1350F3F4UL, 0xC79A971FUL,
511+
0x35F1141CUL, 0x26A1E7E8UL, 0xD4CA64EBUL, 0x8AD958CFUL, 0x78B2DBCCUL,
512+
0x6BE22838UL, 0x9989AB3BUL, 0x4D43CFD0UL, 0xBF284CD3UL, 0xAC78BF27UL,
513+
0x5E133C24UL, 0x105EC76FUL, 0xE235446CUL, 0xF165B798UL, 0x030E349BUL,
514+
0xD7C45070UL, 0x25AFD373UL, 0x36FF2087UL, 0xC494A384UL, 0x9A879FA0UL,
515+
0x68EC1CA3UL, 0x7BBCEF57UL, 0x89D76C54UL, 0x5D1D08BFUL, 0xAF768BBCUL,
516+
0xBC267848UL, 0x4E4DFB4BUL, 0x20BD8EDEUL, 0xD2D60DDDUL, 0xC186FE29UL,
517+
0x33ED7D2AUL, 0xE72719C1UL, 0x154C9AC2UL, 0x061C6936UL, 0xF477EA35UL,
518+
0xAA64D611UL, 0x580F5512UL, 0x4B5FA6E6UL, 0xB93425E5UL, 0x6DFE410EUL,
519+
0x9F95C20DUL, 0x8CC531F9UL, 0x7EAEB2FAUL, 0x30E349B1UL, 0xC288CAB2UL,
520+
0xD1D83946UL, 0x23B3BA45UL, 0xF779DEAEUL, 0x05125DADUL, 0x1642AE59UL,
521+
0xE4292D5AUL, 0xBA3A117EUL, 0x4851927DUL, 0x5B016189UL, 0xA96AE28AUL,
522+
0x7DA08661UL, 0x8FCB0562UL, 0x9C9BF696UL, 0x6EF07595UL, 0x417B1DBCUL,
523+
0xB3109EBFUL, 0xA0406D4BUL, 0x522BEE48UL, 0x86E18AA3UL, 0x748A09A0UL,
524+
0x67DAFA54UL, 0x95B17957UL, 0xCBA24573UL, 0x39C9C670UL, 0x2A993584UL,
525+
0xD8F2B687UL, 0x0C38D26CUL, 0xFE53516FUL, 0xED03A29BUL, 0x1F682198UL,
526+
0x5125DAD3UL, 0xA34E59D0UL, 0xB01EAA24UL, 0x42752927UL, 0x96BF4DCCUL,
527+
0x64D4CECFUL, 0x77843D3BUL, 0x85EFBE38UL, 0xDBFC821CUL, 0x2997011FUL,
528+
0x3AC7F2EBUL, 0xC8AC71E8UL, 0x1C661503UL, 0xEE0D9600UL, 0xFD5D65F4UL,
529+
0x0F36E6F7UL, 0x61C69362UL, 0x93AD1061UL, 0x80FDE395UL, 0x72966096UL,
530+
0xA65C047DUL, 0x5437877EUL, 0x4767748AUL, 0xB50CF789UL, 0xEB1FCBADUL,
531+
0x197448AEUL, 0x0A24BB5AUL, 0xF84F3859UL, 0x2C855CB2UL, 0xDEEEDFB1UL,
532+
0xCDBE2C45UL, 0x3FD5AF46UL, 0x7198540DUL, 0x83F3D70EUL, 0x90A324FAUL,
533+
0x62C8A7F9UL, 0xB602C312UL, 0x44694011UL, 0x5739B3E5UL, 0xA55230E6UL,
534+
0xFB410CC2UL, 0x092A8FC1UL, 0x1A7A7C35UL, 0xE811FF36UL, 0x3CDB9BDDUL,
535+
0xCEB018DEUL, 0xDDE0EB2AUL, 0x2F8B6829UL, 0x82F63B78UL, 0x709DB87BUL,
536+
0x63CD4B8FUL, 0x91A6C88CUL, 0x456CAC67UL, 0xB7072F64UL, 0xA457DC90UL,
537+
0x563C5F93UL, 0x082F63B7UL, 0xFA44E0B4UL, 0xE9141340UL, 0x1B7F9043UL,
538+
0xCFB5F4A8UL, 0x3DDE77ABUL, 0x2E8E845FUL, 0xDCE5075CUL, 0x92A8FC17UL,
539+
0x60C37F14UL, 0x73938CE0UL, 0x81F80FE3UL, 0x55326B08UL, 0xA759E80BUL,
540+
0xB4091BFFUL, 0x466298FCUL, 0x1871A4D8UL, 0xEA1A27DBUL, 0xF94AD42FUL,
541+
0x0B21572CUL, 0xDFEB33C7UL, 0x2D80B0C4UL, 0x3ED04330UL, 0xCCBBC033UL,
542+
0xA24BB5A6UL, 0x502036A5UL, 0x4370C551UL, 0xB11B4652UL, 0x65D122B9UL,
543+
0x97BAA1BAUL, 0x84EA524EUL, 0x7681D14DUL, 0x2892ED69UL, 0xDAF96E6AUL,
544+
0xC9A99D9EUL, 0x3BC21E9DUL, 0xEF087A76UL, 0x1D63F975UL, 0x0E330A81UL,
545+
0xFC588982UL, 0xB21572C9UL, 0x407EF1CAUL, 0x532E023EUL, 0xA145813DUL,
546+
0x758FE5D6UL, 0x87E466D5UL, 0x94B49521UL, 0x66DF1622UL, 0x38CC2A06UL,
547+
0xCAA7A905UL, 0xD9F75AF1UL, 0x2B9CD9F2UL, 0xFF56BD19UL, 0x0D3D3E1AUL,
548+
0x1E6DCDEEUL, 0xEC064EEDUL, 0xC38D26C4UL, 0x31E6A5C7UL, 0x22B65633UL,
549+
0xD0DDD530UL, 0x0417B1DBUL, 0xF67C32D8UL, 0xE52CC12CUL, 0x1747422FUL,
550+
0x49547E0BUL, 0xBB3FFD08UL, 0xA86F0EFCUL, 0x5A048DFFUL, 0x8ECEE914UL,
551+
0x7CA56A17UL, 0x6FF599E3UL, 0x9D9E1AE0UL, 0xD3D3E1ABUL, 0x21B862A8UL,
552+
0x32E8915CUL, 0xC083125FUL, 0x144976B4UL, 0xE622F5B7UL, 0xF5720643UL,
553+
0x07198540UL, 0x590AB964UL, 0xAB613A67UL, 0xB831C993UL, 0x4A5A4A90UL,
554+
0x9E902E7BUL, 0x6CFBAD78UL, 0x7FAB5E8CUL, 0x8DC0DD8FUL, 0xE330A81AUL,
555+
0x115B2B19UL, 0x020BD8EDUL, 0xF0605BEEUL, 0x24AA3F05UL, 0xD6C1BC06UL,
556+
0xC5914FF2UL, 0x37FACCF1UL, 0x69E9F0D5UL, 0x9B8273D6UL, 0x88D28022UL,
557+
0x7AB90321UL, 0xAE7367CAUL, 0x5C18E4C9UL, 0x4F48173DUL, 0xBD23943EUL,
558+
0xF36E6F75UL, 0x0105EC76UL, 0x12551F82UL, 0xE03E9C81UL, 0x34F4F86AUL,
559+
0xC69F7B69UL, 0xD5CF889DUL, 0x27A40B9EUL, 0x79B737BAUL, 0x8BDCB4B9UL,
560+
0x988C474DUL, 0x6AE7C44EUL, 0xBE2DA0A5UL, 0x4C4623A6UL, 0x5F16D052UL,
561+
0xAD7D5351UL,
562+
563+
// CRC32C constants for carry-less multiplication implementation
564+
0xF20C0DFEUL, 0x00000000UL,
565+
0x493C7D27UL, 0x00000000UL,
566+
0xDD45AAB8UL, 0x00000000UL,
567+
0x493C7D27UL, 0x00000000UL,
568+
0xDEA713F1UL, 0x00000000UL,
569+
0x05EC76F1UL, 0x00000001UL,
570+
};
571+
509572
#if INCLUDE_CDS
510573
// nothing to do for riscv
511574
void StubRoutines::init_AOTAddressTable() {

src/hotspot/cpu/riscv/stubRoutines_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class riscv {
9999

100100
private:
101101
static juint _crc_table[];
102+
static juint _crc32c_table[];
102103
};
103104

104105
#endif // CPU_RISCV_STUBROUTINES_RISCV_HPP

src/hotspot/cpu/riscv/vm_version_riscv.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,15 @@ void VM_Version::common_initialize() {
214214
FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
215215
}
216216

217-
if (UseCRC32CIntrinsics) {
218-
warning("CRC32C intrinsics are not available on this CPU.");
219-
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
217+
if (UseZbc) {
218+
if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
219+
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
220+
}
221+
} else {
222+
if (UseCRC32CIntrinsics) {
223+
warning("CRC32C intrinsic are not available on this CPU.");
224+
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
225+
}
220226
}
221227
}
222228

@@ -495,6 +501,12 @@ bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
495501
return false;
496502
}
497503
break;
504+
case vmIntrinsics::_updateBytesCRC32C:
505+
case vmIntrinsics::_updateDirectByteBufferCRC32C:
506+
if (!UseCRC32CIntrinsics) {
507+
return false;
508+
}
509+
break;
498510
default:
499511
break;
500512
}

0 commit comments

Comments
 (0)