Skip to content

Commit b6efb21

Browse files
rivos-eblotjwnrt
authored andcommitted
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>
1 parent 6d89325 commit b6efb21

11 files changed

Lines changed: 197 additions & 1 deletion

File tree

target/riscv/bitmanip_helper.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "exec/target_long.h"
2424
#include "exec/helper-proto.h"
2525
#include "tcg/tcg.h"
26+
#include "qemu/crc32.h"
27+
#include "qemu/crc32c.h"
2628

2729
target_ulong HELPER(clmul)(target_ulong rs1, target_ulong rs2)
2830
{
@@ -129,3 +131,21 @@ target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2)
129131
{
130132
return do_xperm(rs1, rs2, 3);
131133
}
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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
13701370
MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
13711371
MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
13721372
MULTI_EXT_CFG_BOOL("xmipslsp", ext_xmipslsp, false),
1373+
MULTI_EXT_CFG_BOOL("xbr0p93", ext_xbr0p93, false),
13731374

13741375
{ },
13751376
};
@@ -3056,7 +3057,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
30563057
.cfg.ext_zba = true,
30573058
.cfg.ext_zbb = true,
30583059
.cfg.ext_zbc = true,
3059-
.cfg.ext_zbs = true
3060+
.cfg.ext_zbs = true,
3061+
.cfg.ext_xbr0p93 = true
30603062
),
30613063

30623064
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,

target/riscv/cpu_cfg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,6 @@ MATERIALISE_EXT_PREDICATE(xtheadmemidx)
6969
MATERIALISE_EXT_PREDICATE(xtheadmempair)
7070
MATERIALISE_EXT_PREDICATE(xtheadsync)
7171
MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
72+
MATERIALISE_EXT_PREDICATE(xbr0p93);
7273

7374
#endif

target/riscv/cpu_cfg_fields.h.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ BOOL_FIELD(ext_XVentanaCondOps)
153153
BOOL_FIELD(ext_xmipscbop)
154154
BOOL_FIELD(ext_xmipscmov)
155155
BOOL_FIELD(ext_xmipslsp)
156+
BOOL_FIELD(ext_xbr0p93)
156157

157158
BOOL_FIELD(mmu)
158159
BOOL_FIELD(pmp)

target/riscv/helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl)
8484
DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl)
8585
DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl)
8686
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)
8789

8890
/* Floating Point - Half Precision */
8991
DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* RISC-V translation routines for xbr0p93 matching the unratified Zbr CRC32
3+
* bitmanip extension v0.93.
4+
*
5+
* Copyright (c) 2026 Rivos Inc.
6+
*
7+
* This program is free software; you can redistribute it and/or modify it
8+
* under the terms and conditions of the GNU General Public License,
9+
* version 2 or later, as published by the Free Software Foundation.
10+
*
11+
* This program is distributed in the hope it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+
* more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with
17+
* this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#define REQUIRE_XBR0P93(ctx) do { \
21+
if (!ctx->cfg_ptr->ext_xbr0p93) { \
22+
return false; \
23+
} \
24+
} while (0)
25+
26+
static bool gen_crc(DisasContext *ctx, arg_r2 *a,
27+
void (*func)(TCGv, TCGv, TCGv), TCGv tsz)
28+
{
29+
REQUIRE_XBR0P93(ctx);
30+
TCGv dest = dest_gpr(ctx, a->rd);
31+
TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
32+
33+
func(dest, src1, tsz);
34+
gen_set_gpr(ctx, a->rd, dest);
35+
36+
return true;
37+
}
38+
39+
#define TRANS_CRC32(NAME, SIZE) \
40+
static bool trans_crc32_##NAME(DisasContext *ctx, arg_r2 *a) \
41+
{ if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
42+
return gen_crc(ctx, a, gen_helper_crc32, tcg_constant_tl(SIZE)); }
43+
#define TRANS_CRC32C(NAME, SIZE) \
44+
static bool trans_crc32c_##NAME(DisasContext *ctx, arg_r2 *a) \
45+
{ if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
46+
return gen_crc(ctx, a, gen_helper_crc32c, tcg_constant_tl(SIZE)); }
47+
48+
TRANS_CRC32(b, 1);
49+
TRANS_CRC32(h, 2);
50+
TRANS_CRC32(w, 4);
51+
TRANS_CRC32(d, 8);
52+
TRANS_CRC32C(b, 1);
53+
TRANS_CRC32C(h, 2);
54+
TRANS_CRC32C(w, 4);
55+
TRANS_CRC32C(d, 8);

target/riscv/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ gen = [
55
decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
66
decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
77
decodetree.process('xmips.decode', extra_args: '--static-decode=decode_xmips'),
8+
decodetree.process('xbr0p93.decode', extra_args: '--static-decode=decode_xbr0p93'),
89
]
910

1011
riscv_ss = ss.source_set()

target/riscv/translate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,9 +1213,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
12131213
#include "insn_trans/trans_rvbf16.c.inc"
12141214
#include "decode-xthead.c.inc"
12151215
#include "decode-xmips.c.inc"
1216+
#include "decode-xbr0p93.c.inc"
12161217
#include "insn_trans/trans_xthead.c.inc"
12171218
#include "insn_trans/trans_xventanacondops.c.inc"
12181219
#include "insn_trans/trans_xmips.c.inc"
1220+
#include "insn_trans/trans_xbr0p93.c.inc"
12191221

12201222
/* Include the auto-generated decoder for 16 bit insn */
12211223
#include "decode-insn16.c.inc"
@@ -1235,6 +1237,7 @@ const RISCVDecoder decoder_table[] = {
12351237
{ has_xmips_p, decode_xmips},
12361238
{ has_xthead_p, decode_xthead},
12371239
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps},
1240+
{ has_xbr0p93_p, decode_xbr0p93},
12381241
};
12391242

12401243
const size_t decoder_table_size = ARRAY_SIZE(decoder_table);

target/riscv/xbr0p93.decode

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#
2+
# Translation routines for the instructions of the xbr0p93 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+
# This program is free software; you can redistribute it and/or modify it
11+
# under the terms and conditions of the GNU General Public License,
12+
# version 2 or later, as published by the Free Software Foundation.
13+
#
14+
# This program is distributed in the hope it will be useful, but WITHOUT
15+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17+
# more details.
18+
#
19+
# You should have received a copy of the GNU General Public License along with
20+
# this program. If not, see <http://www.gnu.org/licenses/>.
21+
22+
# Fields:
23+
%rs1 15:5
24+
%rd 7:5
25+
26+
# Argument sets:
27+
&r2 rd rs1 !extern
28+
29+
# Formats 32:
30+
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
31+
32+
# *** RV32 xbr0p93 extension ***
33+
crc32_b 0110000 10000 ..... 001 ..... 0010011 @r2
34+
crc32_h 0110000 10001 ..... 001 ..... 0010011 @r2
35+
crc32_w 0110000 10010 ..... 001 ..... 0010011 @r2
36+
crc32c_b 0110000 11000 ..... 001 ..... 0010011 @r2
37+
crc32c_h 0110000 11001 ..... 001 ..... 0010011 @r2
38+
crc32c_w 0110000 11010 ..... 001 ..... 0010011 @r2
39+
40+
# *** RV64 xbr0p93 extension (in addition to RV32) ***
41+
crc32_d 0110000 10011 ..... 001 ..... 0010011 @r2
42+
crc32c_d 0110000 11011 ..... 001 ..... 0010011 @r2

tests/tcg/riscv64/Makefile.softmmu-target

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ run-plugin-interruptedmemory: interruptedmemory
3636
$(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
3737
$(QEMU_OPTS)$<)
3838

39+
EXTRA_RUNS += run-test-crc32
40+
comma:= ,
41+
run-test-crc32: test-crc32
42+
$(call run-test, $<, $(QEMU) -cpu rv64$(comma)xbr0p93=true $(QEMU_OPTS)$<)
43+
3944
# We don't currently support the multiarch system tests
4045
undefine MULTIARCH_TESTS

0 commit comments

Comments
 (0)