From: Chao Liu <chao.liu@processmission.com>
To: Max Chou <max.chou@sifive.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <Alistair.Francis@wdc.com>,
Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>,
Weiwei Li <liwei1518@gmail.com>,
Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Subject: Re: [PATCH v4 6/6] tests/tcg/riscv64: Add tests for SiFive int8 matmul extensions
Date: Sun, 27 Sep 2026 20:11:41 +0800 [thread overview]
Message-ID: <arkH39PkZWjekd-z@MacBook-Pro-4.local> (raw)
In-Reply-To: <20260927082534.3228237-7-max.chou@sifive.com>
On Sun, Sep 27, 2026 at 04:25:34PM +0800, Max Chou wrote:
> Add a test that exercises all SiFive int8 matrix-multiply instructions
> from the Xsfvqmaccqoq and Xsfvqmaccdod extensions.
>
> For each tile shape the test covers the four signedness variants
> (sf.vqmaccu / sf.vqmacc / sf.vqmaccus / sf.vqmaccsu) and the
> reserved-encoding path: with vl set to a value that is not a multiple
> of the tile size the helper raises an illegal-instruction exception.
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Acked-by: Alistair Francis <alistair.francis@wdc.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Chao Liu <chao.liu@processmission.com>
Thanks,
Chao
> ---
> MAINTAINERS | 1 +
> tests/tcg/riscv64/system/meson.build | 7 +
> tests/tcg/riscv64/test-xsfvqmacc.S | 260 +++++++++++++++++++++++++++
> 3 files changed, 268 insertions(+)
> create mode 100644 tests/tcg/riscv64/test-xsfvqmacc.S
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index be1c505ac20..9bf7f46fc24 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -407,6 +407,7 @@ F: target/riscv/xsf.decode
> F: target/riscv/tcg/insn_trans/trans_xsf.c.inc
> F: target/riscv/tcg/xsf_helper.c
> F: disas/riscv-xsf*
> +F: tests/tcg/riscv64/test-xsfvqmacc.S
>
> RENESAS RX CPUs
> R: Yoshinori Sato <yoshinori.sato@nifty.com>
> diff --git a/tests/tcg/riscv64/system/meson.build b/tests/tcg/riscv64/system/meson.build
> index 2aca68e0782..7f861212366 100644
> --- a/tests/tcg/riscv64/system/meson.build
> +++ b/tests/tcg/riscv64/system/meson.build
> @@ -62,6 +62,13 @@ tests += {
> }
> }
>
> +tests += {
> + 'test-xsfvqmacc.S': {
> + 'cflags': cflags,
> + 'qemu_args': ['-cpu', 'rv64,v=true,vlen=256,xsfvqmaccdod=true,xsfvqmaccqoq=true', qemu_args],
> + }
> +}
> +
> if 'qemu-system-riscv64' in emulators
> tcg_tests += {
> 'riscv64-softmmu': {
> diff --git a/tests/tcg/riscv64/test-xsfvqmacc.S b/tests/tcg/riscv64/test-xsfvqmacc.S
> new file mode 100644
> index 00000000000..a116712e502
> --- /dev/null
> +++ b/tests/tcg/riscv64/test-xsfvqmacc.S
> @@ -0,0 +1,260 @@
> +/*
> + * Test the SiFive Xsfvqmaccqoq/Xsfvqmaccdod custom int8 matrix-multiply
> + * extensions.
> + *
> + * The eight instructions widen 8-bit integer inputs to 32 bits and perform
> + * a matrix-multiply-accumulate into a vector of int32 accumulators:
> + *
> + * C[j] += A * B[j]
> + *
> + * Xsfvqmaccqoq (4x8x4): A is 4x8, B[j] is 8x4, C[j] is 4x4 int32. One matrix
> + * operation is performed per 32 elements of vl (TILE_SIZE = 32).
> + * Xsfvqmaccdod (2x8x2): A is 2x8, B[j] is 8x2, C[j] is 2x2 int32. One matrix
> + * operation is performed per 16 elements of vl (TILE_SIZE = 16).
> + *
> + * The input tiles below contain bytes >= 0x80 so that each signedness
> + * variant produces a distinct result; the expected int32 tiles were computed
> + * with an independent reference model of the specification. The accumulators
> + * are cleared before every operation, so the expected value is the pure
> + * matrix product.
> + *
> + * Test exits via semihosting with status 0 on success, or the 1-based index
> + * of the first failing operation.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> + .option arch, +v
> + .option norvc
> +
> + .text
> +
> +/*
> + * Run one 4x8x4 operation: load the 32-byte A and B tiles, clear the 4x4
> + * int32 accumulator (vd = v4:v5, EMUL = 2), execute the op, then compare the
> + * 16 int32 results against the expected tile.
> + */
> +.macro RUN_QOQ id, word, exp
> + li a2, 32
> + vsetvli t0, a2, e8, m1, ta, ma
> + la t1, a_qoq
> + vle8.v v1, (t1)
> + la t1, b_qoq
> + vle8.v v2, (t1)
> + vsetvli t0, x0, e32, m2, ta, ma
> + vmv.v.i v4, 0
> + li a2, 32
> + vsetvli t0, a2, e8, m1, ta, ma
> + .word \word
> + vsetvli t0, x0, e32, m2, ta, ma
> + la t1, result
> + vse32.v v4, (t1)
> + la a0, result
> + la a1, \exp
> + li a2, 16
> + li t6, \id
> + call check_words
> +.endm
> +
> +/*
> + * Run one 2x8x2 operation: load the 16-byte A and B tiles, clear the 2x2
> + * int32 accumulator (vd = v4, EMUL = 1), execute the op, then compare the
> + * 4 int32 results against the expected tile.
> + */
> +.macro RUN_DOD id, word, exp
> + li a2, 16
> + vsetvli t0, a2, e8, m1, ta, ma
> + la t1, a_dod
> + vle8.v v1, (t1)
> + la t1, b_dod
> + vle8.v v2, (t1)
> + vsetvli t0, x0, e32, m1, ta, ma
> + vmv.v.i v4, 0
> + li a2, 16
> + vsetvli t0, a2, e8, m1, ta, ma
> + .word \word
> + vsetvli t0, x0, e32, m1, ta, ma
> + la t1, result
> + vse32.v v4, (t1)
> + la a0, result
> + la a1, \exp
> + li a2, 4
> + li t6, \id
> + call check_words
> +.endm
> +
> + .global _start
> +_start:
> + /* Enable the vector unit (mstatus.VS = Initial). */
> + li t0, 1 << 9
> + csrs mstatus, t0
> +
> + /* Route synchronous traps to trap_handler (mtvec direct mode). */
> + la t0, trap_handler
> + csrw mtvec, t0
> +
> + RUN_QOQ 1, 0xF220A25B, exp_qoq_u /* sf.vqmaccu.4x8x4 */
> + RUN_QOQ 2, 0xF620A25B, exp_qoq_s /* sf.vqmacc.4x8x4 */
> + RUN_QOQ 3, 0xFA20A25B, exp_qoq_us /* sf.vqmaccus.4x8x4 */
> + RUN_QOQ 4, 0xFE20A25B, exp_qoq_su /* sf.vqmaccsu.4x8x4 */
> + RUN_DOD 5, 0xB220A25B, exp_dod_u /* sf.vqmaccu.2x8x2 */
> + RUN_DOD 6, 0xB620A25B, exp_dod_s /* sf.vqmacc.2x8x2 */
> + RUN_DOD 7, 0xBA20A25B, exp_dod_us /* sf.vqmaccus.2x8x2 */
> + RUN_DOD 8, 0xBE20A25B, exp_dod_su /* sf.vqmaccsu.2x8x2 */
> +
> + /*
> + * Illegal-instruction reporting test (op 9).
> + *
> + * When vl is not a multiple of the tile size the instruction is
> + * reserved and the helper raises an illegal-instruction exception at
> + * runtime.
> + */
> + la t1, trap_mtval
> + sd zero, 0(t1)
> + la t1, trap_mcause
> + sd zero, 0(t1)
> + /* vl = 16 is not a multiple of the 4x8x4 tile size (32 elements). */
> + li a2, 16
> + vsetvli t0, a2, e8, m1, ta, ma
> + .word 0xF220A25B /* sf.vqmaccu.4x8x4, traps */
> + /* The handler skips the faulting insn, so control resumes here. */
> + li a0, 9 /* fail code for this check */
> + la t1, trap_mcause
> + ld t2, 0(t1)
> + li t3, 2 /* RISCV_EXCP_ILLEGAL_INST */
> + bne t2, t3, _exit
> + la t1, trap_mtval
> + ld t2, 0(t1)
> + li t3, 0xF220A25B
> + bne t2, t3, _exit
> +
> + li a0, 0
> + j _exit
> +
> +/*
> + * Machine-mode trap handler: record mcause and mtval, then advance mepc
> + * past the 4-byte faulting instruction and return.
> + */
> + .balign 4
> +trap_handler:
> + csrr t4, mcause
> + la t5, trap_mcause
> + sd t4, 0(t5)
> + csrr t4, mtval
> + la t5, trap_mtval
> + sd t4, 0(t5)
> + csrr t4, mepc
> + addi t4, t4, 4
> + csrw mepc, t4
> + mret
> +
> +/*
> + * check_words(a0 = result, a1 = expected, a2 = word count).
> + * Returns to the caller if every word matches; otherwise exits with the
> + * operation index held in t6.
> + */
> +check_words:
> +1: beqz a2, 2f
> + lw t2, 0(a0)
> + lw t3, 0(a1)
> + bne t2, t3, 3f
> + addi a0, a0, 4
> + addi a1, a1, 4
> + addi a2, a2, -1
> + j 1b
> +2: ret
> +3: mv a0, t6
> + j _exit
> +
> +/* Exit through the semihosting SYS_EXIT_EXTENDED call with a0 as the code. */
> +_exit:
> + la a1, semiargs
> + li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
> + sd t0, 0(a1)
> + sd a0, 8(a1)
> + li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
> + .balign 16
> + slli zero, zero, 0x1f
> + ebreak
> + srai zero, zero, 0x7
> + j .
> +
> + .data
> + .balign 8
> +semiargs:
> + .space 16
> +result:
> + .space 64
> +trap_mcause:
> + .space 8
> +trap_mtval:
> + .space 8
> +
> +/*
> + * A (4x8, row-major) in bytes [0, 32) of vs1.
> + */
> +a_qoq:
> + .byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x80
> + .byte 0xFF, 0x01, 0x00, 0x02, 0x7F, 0x03, 0x04, 0x05
> + .byte 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x08
> + .byte 0x00, 0x00, 0x81, 0x00, 0x00, 0x02, 0x00, 0x03
> +/*
> + * B (8x4, row-major) in bytes [0, 32) of vs2.
> + */
> +b_qoq:
> + .byte 0x01, 0x02, 0x03, 0x04
> + .byte 0x05, 0x06, 0x07, 0x08
> + .byte 0x80, 0x7F, 0xFF, 0x01
> + .byte 0x00, 0x10, 0x20, 0x30
> + .byte 0x02, 0x02, 0x02, 0x02
> + .byte 0xFE, 0x01, 0x00, 0x7F
> + .byte 0x03, 0x00, 0x81, 0x04
> + .byte 0x40, 0x50, 0x60, 0x70
> +/*
> + * A (2x8, row-major) in bytes [0, 16) of vs1.
> + */
> +a_dod:
> + .byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x80
> + .byte 0xFF, 0x7F, 0x00, 0x02, 0x81, 0x03, 0x04, 0x05
> +/*
> + * B (8x2, row-major) in bytes [0, 16) of vs2.
> + */
> +b_dod:
> + .byte 0x01, 0x02
> + .byte 0x80, 0x7F
> + .byte 0x03, 0xFF
> + .byte 0x00, 0x10
> + .byte 0x02, 0xFE
> + .byte 0x7F, 0x01
> + .byte 0x81, 0x04
> + .byte 0x40, 0x50
> +
> + .balign 4
> +exp_qoq_u:
> + .word 0x0000279e, 0x000029db, 0x0000371f, 0x00003bf7
> + .word 0x00000648, 0x000004b5, 0x00000826, 0x0000091f
> + .word 0x00007be0, 0x00002030, 0x000074f0, 0x000042f0
> + .word 0x0000433c, 0x000040f1, 0x0000819f, 0x000002cf
> +exp_qoq_s:
> + .word 0xffffde9e, 0xffffd9db, 0xffffcd1f, 0xffffcbf7
> + .word 0x00000248, 0x000002b5, 0x00000126, 0x0000051f
> + .word 0xffffebe0, 0x00002030, 0xffffd4f0, 0x000042f0
> + .word 0x0000403c, 0xffffc1f1, 0x0000019f, 0x000001cf
> +exp_qoq_us:
> + .word 0x00001e9e, 0x000029db, 0x00002d1f, 0x00003bf7
> + .word 0x00000348, 0x000004b5, 0x00000426, 0x0000091f
> + .word 0xffffebe0, 0x00002030, 0xffffd4f0, 0x000042f0
> + .word 0xffffc03c, 0x000040f1, 0x0000009f, 0x000002cf
> +exp_qoq_su:
> + .word 0xffffe79e, 0xffffd9db, 0xffffd71f, 0xffffcbf7
> + .word 0x00000548, 0x000002b5, 0x00000526, 0x0000051f
> + .word 0x00007be0, 0x00002030, 0x000074f0, 0x000042f0
> + .word 0xffffc33c, 0xffffc1f1, 0xffff829f, 0x000001cf
> +exp_dod_u:
> + .word 0x00002795, 0x00003155, 0x00004642, 0x0000c2c0
> +exp_dod_s:
> + .word 0xffffde95, 0xffffd955, 0xffffc042, 0x000041c0
> +exp_dod_us:
> + .word 0x00001e95, 0x00002955, 0xffffc342, 0x000041c0
> +exp_dod_su:
> + .word 0xffffe795, 0xffffe155, 0x00004342, 0xffffc2c0
> --
> 2.43.0
>
next prev parent reply other threads:[~2026-09-27 12:12 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 8:25 [PATCH v4 0/6] target/riscv: Add SiFive Xsfvqmaccdod/Xsfvqmaccqoq int8 matmul extensions Max Chou
2026-09-27 8:25 ` [PATCH v4 1/6] target/riscv: Add cfg property for SiFive " Max Chou
2026-09-27 11:58 ` Chao Liu
2026-09-27 8:25 ` [PATCH v4 2/6] target/riscv/cpu: List one implied-ext rule per line Max Chou
2026-09-27 11:59 ` Chao Liu
2026-09-27 8:25 ` [PATCH v4 3/6] target/riscv/cpu: Add SiFive custom int8 matmul extension implied rules Max Chou
2026-09-27 12:00 ` Chao Liu
2026-09-27 8:25 ` [PATCH v4 4/6] target/riscv: rvv: Add SiFive custom int8 matmul instructions Max Chou
2026-09-27 12:01 ` Chao Liu
2026-09-27 8:25 ` [PATCH v4 5/6] disas/riscv: Add disassembler support for Xsfvqmaccdod/Xsfvqmaccqoq Max Chou
2026-09-27 12:02 ` Chao Liu
2026-09-27 8:25 ` [PATCH v4 6/6] tests/tcg/riscv64: Add tests for SiFive int8 matmul extensions Max Chou
2026-09-27 12:11 ` Chao Liu [this message]
2026-10-01 5:05 ` [PATCH v4 0/6] target/riscv: Add SiFive Xsfvqmaccdod/Xsfvqmaccqoq " Alistair Francis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=arkH39PkZWjekd-z@MacBook-Pro-4.local \
--to=chao.liu@processmission.com \
--cc=Alistair.Francis@wdc.com \
--cc=daniel.barboza@oss.qualcomm.com \
--cc=liwei1518@gmail.com \
--cc=max.chou@sifive.com \
--cc=palmer@dabbelt.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.