@samitouri / QOSamiQemu / commits / 32bbab666e

target/riscv: add draft RISC-V Zbr ext as xbr0p93

This extension was not ratified with the Zb[abcs] bitmanip extensions. This is the latest draft version (0.93) as implemented by the Ibex core. These instructions are in the reserved encoding space but have not been ratified and could conflict with future ratified instructions. For this reason they are added as a vendor extension to support Ibex's impl. Signed-off-by: James Wainwright <james.wainwright@lowrisc.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260320134254.217123-3-james.wainwright@lowrisc.org> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Emmanuel Blot committed Mar 20, 2026 at 13:42 UTC 32bbab666e08856c1a6660c3743a4493170a9afd
12 files changed +178 -1
MAINTAINERS
+3
@@ -1729,6 +1729,9 @@ F: hw/riscv/opentitan.c
1729 F: hw/*/ibex_*.c
1730 F: include/hw/riscv/opentitan.h
1731 F: include/hw/*/ibex_*.h
1732 +F: target/riscv/insn_trans/trans_xthead.c.inc
1733 +F: target/riscv/xlrbr.decode
1734 +F: tests/tcg/riscv64/test-crc32.S
1735
1736 Microchip PolarFire SoC Icicle Kit
1737 L: qemu-riscv@nongnu.org
target/riscv/bitmanip_helper.c
+20
@@ -23,6 +23,8 @@
23 #include "exec/target_long.h"
24 #include "exec/helper-proto.h"
25 #include "tcg/tcg.h"
26 +#include "qemu/crc32.h"
27 +#include "qemu/crc32c.h"
28
29 target_ulong HELPER(clmul)(target_ulong rs1, target_ulong rs2)
30 {
@@ -129,3 +131,21 @@ target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2)
131 {
132 return do_xperm(rs1, rs2, 3);
133 }
134 +
135 +target_ulong HELPER(crc32)(target_ulong rs1, target_ulong sz)
136 +{
137 + for (target_ulong i = 0; i < sz; i++) {
138 + rs1 = crc32_table[rs1 & 0xFF] ^ (rs1 >> 8);
139 + }
140 +
141 + return rs1;
142 +}
143 +
144 +target_ulong HELPER(crc32c)(target_ulong rs1, target_ulong sz)
145 +{
146 + for (target_ulong i = 0; i < sz; i++) {
147 + rs1 = crc32c_table[rs1 & 0xFF] ^ (rs1 >> 8);
148 + }
149 +
150 + return rs1;
151 +}
target/riscv/cpu.c
+3 -1
@@ -1373,6 +1373,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
1373 MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
1374 MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
1375 MULTI_EXT_CFG_BOOL("xmipslsp", ext_xmipslsp, false),
1376 + MULTI_EXT_CFG_BOOL("xlrbr", ext_xlrbr, false),
1377
1378 { },
1379 };
@@ -3059,7 +3060,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
3060 .cfg.ext_zba = true,
3061 .cfg.ext_zbb = true,
3062 .cfg.ext_zbc = true,
3062 - .cfg.ext_zbs = true
3063 + .cfg.ext_zbs = true,
3064 + .cfg.ext_xlrbr = true
3065 ),
3066
3067 DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,
target/riscv/cpu_cfg.h
+1
@@ -69,5 +69,6 @@ MATERIALISE_EXT_PREDICATE(xtheadmemidx)
69 MATERIALISE_EXT_PREDICATE(xtheadmempair)
70 MATERIALISE_EXT_PREDICATE(xtheadsync)
71 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
72 +MATERIALISE_EXT_PREDICATE(xlrbr);
73
74 #endif
target/riscv/cpu_cfg_fields.h.inc
+1
@@ -154,6 +154,7 @@ BOOL_FIELD(ext_XVentanaCondOps)
154 BOOL_FIELD(ext_xmipscbop)
155 BOOL_FIELD(ext_xmipscmov)
156 BOOL_FIELD(ext_xmipslsp)
157 +BOOL_FIELD(ext_xlrbr)
158
159 BOOL_FIELD(mmu)
160 BOOL_FIELD(pmp)
target/riscv/helper.h
+2
@@ -84,6 +84,8 @@ DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl)
84 DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl)
85 DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl)
86 DEF_HELPER_FLAGS_2(xperm8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
87 +DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl)
88 +DEF_HELPER_FLAGS_2(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl)
89
90 /* Floating Point - Half Precision */
91 DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
target/riscv/insn_trans/trans_xlrbr.c.inc new
+45
@@ -0,0 +1,45 @@
1 +/*
2 + * RISC-V translation routines for xlrbr matching the unratified Zbr CRC32
3 + * bitmanip extension v0.93.
4 + *
5 + * Copyright (c) 2026 Rivos Inc.
6 + *
7 + * SPDX-License-Identifier: GPL-2.0-or-later
8 + */
9 +
10 +#define REQUIRE_XLRBR(ctx) do { \
11 + if (!ctx->cfg_ptr->ext_xlrbr) { \
12 + return false; \
13 + } \
14 +} while (0)
15 +
16 +static bool gen_crc(DisasContext *ctx, arg_r2 *a,
17 + void (*func)(TCGv, TCGv, TCGv), TCGv tsz)
18 +{
19 + REQUIRE_XLRBR(ctx);
20 + TCGv dest = dest_gpr(ctx, a->rd);
21 + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
22 +
23 + func(dest, src1, tsz);
24 + gen_set_gpr(ctx, a->rd, dest);
25 +
26 + return true;
27 +}
28 +
29 +#define TRANS_CRC32(NAME, SIZE) \
30 + static bool trans_crc32_##NAME(DisasContext *ctx, arg_r2 *a) \
31 + { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
32 + return gen_crc(ctx, a, gen_helper_crc32, tcg_constant_tl(SIZE)); }
33 +#define TRANS_CRC32C(NAME, SIZE) \
34 + static bool trans_crc32c_##NAME(DisasContext *ctx, arg_r2 *a) \
35 + { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
36 + return gen_crc(ctx, a, gen_helper_crc32c, tcg_constant_tl(SIZE)); }
37 +
38 +TRANS_CRC32(b, 1);
39 +TRANS_CRC32(h, 2);
40 +TRANS_CRC32(w, 4);
41 +TRANS_CRC32(d, 8);
42 +TRANS_CRC32C(b, 1);
43 +TRANS_CRC32C(h, 2);
44 +TRANS_CRC32C(w, 4);
45 +TRANS_CRC32C(d, 8);
target/riscv/meson.build
+1
@@ -5,6 +5,7 @@ gen = [
5 decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
6 decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
7 decodetree.process('xmips.decode', extra_args: '--static-decode=decode_xmips'),
8 + decodetree.process('xlrbr.decode', extra_args: '--static-decode=decode_xlrbr'),
9 ]
10
11 riscv_ss = ss.source_set()
target/riscv/translate.c
+3
@@ -1213,9 +1213,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
1213 #include "insn_trans/trans_rvbf16.c.inc"
1214 #include "decode-xthead.c.inc"
1215 #include "decode-xmips.c.inc"
1216 +#include "decode-xlrbr.c.inc"
1217 #include "insn_trans/trans_xthead.c.inc"
1218 #include "insn_trans/trans_xventanacondops.c.inc"
1219 #include "insn_trans/trans_xmips.c.inc"
1220 +#include "insn_trans/trans_xlrbr.c.inc"
1221
1222 /* Include the auto-generated decoder for 16 bit insn */
1223 #include "decode-insn16.c.inc"
@@ -1235,6 +1237,7 @@ const RISCVDecoder decoder_table[] = {
1237 { has_xmips_p, decode_xmips},
1238 { has_xthead_p, decode_xthead},
1239 { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
1240 + { has_xlrbr_p, decode_xlrbr},
1241 };
1242
1243 const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
target/riscv/xlrbr.decode new
+30
@@ -0,0 +1,30 @@
1 +#
2 +# Translation routines for the instructions of the xlrbr ISA extension
3 +# (matching the draft encodings in the standard reserved encoding space for the
4 +# unratified Zbr CRC32 bitmanip extension version 0.93).
5 +#
6 +# Copyright (c) 2026 Rivos Inc.
7 +#
8 +# SPDX-License-Identifier: GPL-2.0-or-later
9 +
10 +# Fields:
11 +%rs1 15:5
12 +%rd 7:5
13 +
14 +# Argument sets:
15 +&r2 rd rs1 !extern
16 +
17 +# Formats 32:
18 +@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
19 +
20 +# *** RV32 xlrbr extension ***
21 +crc32_b 0110000 10000 ..... 001 ..... 0010011 @r2
22 +crc32_h 0110000 10001 ..... 001 ..... 0010011 @r2
23 +crc32_w 0110000 10010 ..... 001 ..... 0010011 @r2
24 +crc32c_b 0110000 11000 ..... 001 ..... 0010011 @r2
25 +crc32c_h 0110000 11001 ..... 001 ..... 0010011 @r2
26 +crc32c_w 0110000 11010 ..... 001 ..... 0010011 @r2
27 +
28 +# *** RV64 xlrbr extension (in addition to RV32) ***
29 +crc32_d 0110000 10011 ..... 001 ..... 0010011 @r2
30 +crc32c_d 0110000 11011 ..... 001 ..... 0010011 @r2
tests/tcg/riscv64/Makefile.softmmu-target
+5
@@ -36,5 +36,10 @@ run-plugin-interruptedmemory: interruptedmemory
36 $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
37 $(QEMU_OPTS)$<)
38
39 +EXTRA_RUNS += run-test-crc32
40 +comma:= ,
41 +run-test-crc32: test-crc32
42 + $(call run-test, $<, $(QEMU) -cpu rv64$(comma)xlrbr=true $(QEMU_OPTS)$<)
43 +
44 # We don't currently support the multiarch system tests
45 undefine MULTIARCH_TESTS
tests/tcg/riscv64/test-crc32.S new
+64
@@ -0,0 +1,64 @@
1 +/*
2 + * Copyright (c) 2026 lowRISC CIC
3 + * SPDX-License-Identifier: GPL-2.0-or-later
4 + */
5 +
6 +#define crc32(op, rd, rs1) .insn r 19, 1, 48, rd, rs1, x##op
7 +
8 +#define crc32_b(rd, rs1) crc32(16, rd, rs1)
9 +#define crc32_h(rd, rs1) crc32(17, rd, rs1)
10 +#define crc32_w(rd, rs1) crc32(18, rd, rs1)
11 +#define crc32_d(rd, rs1) crc32(19, rd, rs1)
12 +#define crc32c_b(rd, rs1) crc32(24, rd, rs1)
13 +#define crc32c_h(rd, rs1) crc32(25, rd, rs1)
14 +#define crc32c_w(rd, rs1) crc32(26, rd, rs1)
15 +#define crc32c_d(rd, rs1) crc32(27, rd, rs1)
16 +
17 + .option norvc
18 +
19 + .text
20 + .globl _start
21 +_start:
22 + lla t0, trap
23 + csrw mtvec, t0
24 +
25 + li t0, 0x34e24a2cd65650d4
26 +
27 + crc32_b (t0, t0)
28 + crc32_h (t0, t0)
29 + crc32_w (t0, t0)
30 + crc32_d (t0, t0)
31 + crc32c_b (t0, t0)
32 + crc32c_h (t0, t0)
33 + crc32c_w (t0, t0)
34 + crc32c_d (t0, t0)
35 +
36 + li t1, 0x68167e78
37 +
38 + li a0, 0
39 + beq t0, t1, _exit
40 +fail:
41 + li a0, 1
42 +_exit:
43 + lla a1, semiargs
44 + li t0, 0x20026 # ADP_Stopped_ApplicationExit
45 + sd t0, 0(a1)
46 + sd a0, 8(a1)
47 + li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED
48 +
49 + # Semihosting call sequence
50 + .balign 16
51 + slli zero, zero, 0x1f
52 + ebreak
53 + srai zero, zero, 0x7
54 + j .
55 +
56 + .data
57 + .balign 16
58 +semiargs:
59 + .space 16
60 +
61 +trap:
62 + csrr t0, mepc
63 + addi t0, t0, 4
64 + mret