[PATCH v2 7/7] lib: sbi: ISA extension emulation (Zvbb).

Vivian Wang wangruikang at iscas.ac.cn
Mon Nov 17 04:35:14 PST 2025


Hi Benedikt,

Thank you for your patch. We have found it very useful.

Han Gao (cc'd) has been testing this on the SG2044. We have some minor
suggestions and a bug report regarding patch 7. Please see below.

On 11/15/25 04:38, Benedikt Freisen wrote:
> [...]
>
> diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
> index 07cfaa6..0da775c 100644
> --- a/lib/sbi/objects.mk
> +++ b/lib/sbi/objects.mk
> @@ -83,6 +83,7 @@ libsbi-objs-y += sbi_illegal_atomic.o
>  libsbi-objs-y += sbi_illegal_insn.o
>  libsbi-objs-y += sbi_insn_emu.o
>  libsbi-objs-y += sbi_insn_emu_fp.o
> +libsbi-objs-y += sbi_insn_emu_v.o

libsbi-objs-$(CONFIG_EMU_ZVBB) += sbi_insn_emu_v.o

> [...]
> diff --git a/lib/sbi/sbi_insn_emu_v.c b/lib/sbi/sbi_insn_emu_v.c
> new file mode 100644
> index 0000000..517791e
> --- /dev/null
> +++ b/lib/sbi/sbi_insn_emu_v.c
> @@ -0,0 +1,1146 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2025 Benedikt Freisen.
> + *
> + * Authors:
> + *   Benedikt Freisen <b.freisen at gmx.net>
> + */
> +
> +#if __riscv_xlen == 64 && CONFIG_EMU_ZVBB

The Makefile change above should make this CONFIG_EMU_ZVBB check
unnecessary.

I'm not sure about how to do the XLEN check. I think this should be an
#if ... #error as well, like below, but ideally this should be exposed
in Kconfig so we can use a Kconfig dependency. It's currently not
though, and I'm not sure how to fix it.

> [...]
> +
> +#ifndef OPENSBI_CC_SUPPORT_VECTOR
> +#error "Zvbb emulation requires a toolchain that supports the V extension!"
> +#endif

Similarly I think ideally this is handled in Kconfig... But it's fine as is.

> [...]
>
> +static inline u64 op_rev8(u64 op1, u64 op2)
> +{
> +	u64 result;
> +	asm volatile(".option push\n\t"
> +		     ".option arch, +zbb\n\t"
> +		     "rev8 %0, %2\n\t"
> +		     "srl %0, %0, %1\n\t"
> +		     ".option pop\n\t"
> +		     : "=r"(result)

Should be an "early-clobber" operand [1]:

    "=&r"(result)

result is used in the second instruction, so we need to prevent the
compiler from allocating result and op2 in the same register.

We've managed to run into this in practice, with GCC allocating the
registers like this:

   4d9b2: 6b875793      rev8    a5, a4
   4d9b6: 00f7d7b3      srl     a5, a5, a5

This breaks Zvbb emulation for various instructions.

(Theoretically we can try to allocate registers better, since result and
op1 can overlap, but we're not really in a shortage of registers here so
it's likely fine.)

Two more instances below:

> +		     : "r"(op1), "r"(op2));
> +	return result;
> +}
> +
> +static inline u64 op_brev(u64 op1, u64 op2)
> +{
> +	return op_rev8(op1, op_brev8(op2));
> +}
> +
> +static inline u64 op_clz(u64 op1, u64 op2)
> +{
> +	u64 result;
> +	asm volatile(".option push\n\t"
> +		     ".option arch, +zbb\n\t"
> +		     "clz %0, %2\n\t"
> +		     "sub %0, %0, %1\n\t"
> +		     ".option pop\n\t"
> +		     : "=r"(result)

(Same problem)

> +		     : "r"(op1), "r"(op2));
> +	return result;
> +}
> +
> +static inline u64 op_ctz(u64 op1, u64 op2)
> +{
> +	u64 result;
> +	asm volatile(".option push\n\t"
> +		     ".option arch, +zbb\n\t"
> +		     "ctz %0, %2\n\t"
> +		     "minu %0, %0, %1\n\t"
> +		     ".option pop\n\t"
> +		     : "=r"(result)

(Same problem)

> +		     : "r"(op1), "r"(op2));
> +	return result;
> +}
> +
> +static inline u64 op_cpop(u64 op)
> +{
> +	u64 result;
> +	asm volatile(".option push\n\t"
> +		     ".option arch, +zbb\n\t"
> +		     "cpop %0, %1\n\t"
> +		     ".option pop\n\t"
> +		     : "=r"(result)
> +		     : "r"(op));
This one is fine though, since it's just one instruction.
> +	return result;
> +}
> +

Thanks,
Vivian "dramforever" Wang

[1]: https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Modifiers.html#index-_0026-in-constraint




More information about the opensbi mailing list