All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Chou <max.chou@sifive.com>
To: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
	 Palmer Dabbelt <palmer@dabbelt.com>,
	Alistair Francis <Alistair.Francis@wdc.com>,
	 Weiwei Li <liwei1518@gmail.com>,
	Liu Zhiwei <zhiwei_liu@linux.alibaba.com>,
	 Chao Liu <chao.liu@processmission.com>,
	Frank Chang <frank.chang@sifive.com>
Subject: Re: [PATCH 3/5] target/riscv: rvv: Add SiFive custom int8 matmul instructions
Date: Fri, 7 Aug 2026 16:50:02 +0800	[thread overview]
Message-ID: <anWYFy7730o4auCV@sifive.com> (raw)
In-Reply-To: <537a0ac1-8970-4ffc-934d-293d44f159c0@oss.qualcomm.com>

On 2026-08-06 18:13, Daniel Henrique Barboza wrote:
> 
> 
> On 7/21/2026 9:20 AM, Max Chou wrote:
> > From: Frank Chang <frank.chang@sifive.com>
> > 
> > Add the 8 SiFive custom int8 matrix-multiply vector instructions:
> > sf.vqmacc{u,,us,su}.4x8x4 and sf.vqmacc{u,,us,su}.2x8x2. Each name
> > suffix encodes the signedness of vs1/vs2.
> > The 4x8x4 forms multiply-accumulate a 4x8 by 8x4 int8 tile into a
> > 4x4 int32 result; the 2x8x2 forms use a 2x8 by 8x2 tile producing a
> > 2x2 int32 result. Both Xsfvqmaccqoq/Xsfvqmaccdod extensions are
> > gated on vlenb >= 32, sew == 8 and vm == 1, per the SiFive Int8
> > Matrix Multiplication Extensions Specification.
> > 
> > Signed-off-by: Frank Chang <frank.chang@sifive.com>
> > Signed-off-by: Max Chou <max.chou@sifive.com>
> > ---
> 
> One thing that caught my attention is adding what is, at least for now,
> a vendor specific helper in vector_helper.c which is a common code
> helper.  Existing vendor extensions in QEMU doesn't do that, at least
> from what I can see.
> 
> All this said, I have a suspicion that the code for this extension will
> be re-used in zvldot/zvbdot, so keeping this helper in vector_helper.c
> is ok to me.
> 
> 

Hi Daniel,

I believe we can move the vendor helper to the new helper file at v2.
Additionally, we can extract the common part into vector_helper.c or
vector_internal.h for related ISA extensions in the future.

In fact, I’m preparing the upstream patchset for Zvdota/Zvbdota
extensions and will send it after a release tag is added to the
riscv-isa-manual repository.

Thanks,
rnax

> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> 
> 
> >   MAINTAINERS                                 |  7 ++
> >   target/riscv/cpu_cfg.h                      |  5 ++
> >   target/riscv/helper.h                       | 10 +++
> >   target/riscv/meson.build                    |  1 +
> >   target/riscv/tcg/insn_trans/trans_xsf.c.inc | 98 +++++++++++++++++++++
> >   target/riscv/tcg/translate.c                |  3 +
> >   target/riscv/tcg/vector_helper.c            | 74 ++++++++++++++++
> >   target/riscv/xsf.decode                     | 30 +++++++
> >   8 files changed, 228 insertions(+)
> >   create mode 100644 target/riscv/tcg/insn_trans/trans_xsf.c.inc
> >   create mode 100644 target/riscv/xsf.decode
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 97dcc78ded..94cd63eeba 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -389,6 +389,13 @@ F: target/riscv/XVentanaCondOps.decode
> >   F: target/riscv/insn_trans/trans_xventanacondops.c.inc
> >   F: disas/riscv-xventana*
> > +RISC-V SiFive (Xsf*) extensions
> > +M: Max Chou <max.chou@sifive.com>
> > +L: qemu-riscv@nongnu.org
> > +S: Supported
> > +F: target/riscv/xsf.decode
> > +F: target/riscv/tcg/insn_trans/trans_xsf.c.inc
> > +
> >   RENESAS RX CPUs
> >   R: Yoshinori Sato <yoshinori.sato@nifty.com>
> >   S: Orphan
> > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > index 211d0708ba..d6db1cfb7c 100644
> > --- a/target/riscv/cpu_cfg.h
> > +++ b/target/riscv/cpu_cfg.h
> > @@ -51,6 +51,11 @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
> >              cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
> >   }
> > +static inline bool has_xsf_p(const RISCVCPUConfig *cfg)
> > +{
> > +    return cfg->ext_xsfvqmaccdod || cfg->ext_xsfvqmaccqoq;
> > +}
> > +
> >   #define MATERIALISE_EXT_PREDICATE(ext) \
> >       static inline bool has_ ## ext ## _p(const RISCVCPUConfig *cfg) \
> >       { \
> > diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> > index 542b7c264f..4234f46271 100644
> > --- a/target/riscv/helper.h
> > +++ b/target/riscv/helper.h
> > @@ -1358,3 +1358,13 @@ DEF_HELPER_1(ssamoswap_disabled, void, env)
> >   /* Zalrsc SC write probe */
> >   DEF_HELPER_FLAGS_3(sc_probe_write, TCG_CALL_NO_WG, void, env, tl, tl)
> > +
> > +/* SiFive Custom int8 Matrix-Multiply */
> > +DEF_HELPER_5(sf_vqmaccu_4x8x4, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmacc_4x8x4, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmaccus_4x8x4, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmaccsu_4x8x4, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmaccu_2x8x2, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmacc_2x8x2, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmaccus_2x8x2, void, ptr, ptr, ptr, env, i32)
> > +DEF_HELPER_5(sf_vqmaccsu_2x8x2, void, ptr, ptr, ptr, env, i32)
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index 42d0f6d538..c06526adb2 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -6,6 +6,7 @@ gen = [
> >     decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
> >     decodetree.process('xmips.decode', extra_args: '--static-decode=decode_xmips'),
> >     decodetree.process('xlrbr.decode', extra_args: '--static-decode=decode_xlrbr'),
> > +  decodetree.process('xsf.decode', extra_args: '--static-decode=decode_xsf'),
> >   ]
> >   riscv_ss = ss.source_set()
> > diff --git a/target/riscv/tcg/insn_trans/trans_xsf.c.inc b/target/riscv/tcg/insn_trans/trans_xsf.c.inc
> > new file mode 100644
> > index 0000000000..1677352689
> > --- /dev/null
> > +++ b/target/riscv/tcg/insn_trans/trans_xsf.c.inc
> > @@ -0,0 +1,98 @@
> > +/*
> > + * RISC-V translation routines for the SiFive vendor extensions (xsf*)
> > + *
> > + * Copyright (c) 2023 SiFive, Inc.
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +
> > +/*
> > + * SiFive Xsfvqmaccdod/Xsfvqmaccqoq custom int8 matrix-multiply extensions
> > + */
> > +static bool sf_int8_matmul_check(DisasContext *s, arg_rmrr *a)
> > +{
> > +    return require_rvv(s) &&
> > +           vext_check_isa_ill(s) &&
> > +           s->vstart_eq_zero &&
> > +           (s->cfg_ptr->vlenb >= 32) &&
> > +           (s->sew == MO_8) &&
> > +           (a->vm == 1);
> > +}
> > +
> > +static bool sf_int8_matmul_4x8x4_check(DisasContext *s, arg_rmrr *a)
> > +{
> > +    /*
> > +     * vd  has EMUL=2*LMUL
> > +     * vs2 has EMUL=LMUL
> > +     * vs1 has EMUL=1
> > +     * vd must not overlap vs1
> > +     */
> > +    return sf_int8_matmul_check(s, a) &&
> > +           (s->cfg_ptr->ext_xsfvqmaccqoq) &&
> > +           (s->lmul <= 2) &&
> > +           require_align(a->rd, s->lmul + 1) &&
> > +           require_align(a->rs2, s->lmul) &&
> > +           require_align(a->rs1, 0) &&
> > +           require_noover(a->rd, s->lmul + 1, a->rs2, s->lmul) &&
> > +           !is_overlapped(a->rd, 1 << MAX(s->lmul + 1, 0), a->rs1, 1);
> > +}
> > +
> > +static bool sf_int8_matmul_2x8x2_check(DisasContext *s, arg_rmrr *a)
> > +{
> > +    /*
> > +     * vd  has EMUL=LMUL
> > +     * vs2 has EMUL=LMUL
> > +     * vs1 has EMUL=1
> > +     * vd must not overlap vs1
> > +     */
> > +    return sf_int8_matmul_check(s, a) &&
> > +           (s->cfg_ptr->ext_xsfvqmaccdod) &&
> > +           require_align(a->rd, s->lmul) &&
> > +           require_align(a->rs2, s->lmul) &&
> > +           require_align(a->rs1, 0) &&
> > +           !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs1, 1);
> > +}
> > +
> > +static bool sf_int8_matmul_op(DisasContext *s, arg_rmrr *a, uint8_t seq)
> > +{
> > +    static gen_helper_gvec_3_ptr * const fns[8] = {
> > +        gen_helper_sf_vqmaccu_4x8x4, gen_helper_sf_vqmacc_4x8x4,
> > +        gen_helper_sf_vqmaccus_4x8x4, gen_helper_sf_vqmaccsu_4x8x4,
> > +        gen_helper_sf_vqmaccu_2x8x2, gen_helper_sf_vqmacc_2x8x2,
> > +        gen_helper_sf_vqmaccus_2x8x2, gen_helper_sf_vqmaccsu_2x8x2,
> > +    };
> > +
> > +    /*
> > +     * The helper raises an illegal-instruction exception when vl is not a
> > +     * multiple of the tile size; save the opcode so mtval/stval report the
> > +     * faulting instruction if that exception is thrown.
> > +     */
> > +    decode_save_opc(s, 0);
> > +
> > +    tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
> > +                       vreg_ofs(s, a->rs2), tcg_env,
> > +                       s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, 0, fns[seq]);
> > +
> > +    finalize_rvv_inst(s);
> > +
> > +    return true;
> > +}
> > +
> > +#define GEN_SF_INT8_MATMUL_TRANS(NAME, CHECK, SEQ)       \
> > +static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
> > +{                                                        \
> > +    if (CHECK(s, a)) {                                   \
> > +        return sf_int8_matmul_op(s, a, SEQ);             \
> > +    }                                                    \
> > +    return false;                                        \
> > +}
> > +
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccu_4x8x4,  sf_int8_matmul_4x8x4_check, 0)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmacc_4x8x4,   sf_int8_matmul_4x8x4_check, 1)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccus_4x8x4, sf_int8_matmul_4x8x4_check, 2)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccsu_4x8x4, sf_int8_matmul_4x8x4_check, 3)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccu_2x8x2,  sf_int8_matmul_2x8x2_check, 4)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmacc_2x8x2,   sf_int8_matmul_2x8x2_check, 5)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccus_2x8x2, sf_int8_matmul_2x8x2_check, 6)
> > +GEN_SF_INT8_MATMUL_TRANS(sf_vqmaccsu_2x8x2, sf_int8_matmul_2x8x2_check, 7)
> > diff --git a/target/riscv/tcg/translate.c b/target/riscv/tcg/translate.c
> > index 9684dbe752..41e3dd2fe2 100644
> > --- a/target/riscv/tcg/translate.c
> > +++ b/target/riscv/tcg/translate.c
> > @@ -1216,10 +1216,12 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
> >   #include "decode-xthead.c.inc"
> >   #include "decode-xmips.c.inc"
> >   #include "decode-xlrbr.c.inc"
> > +#include "decode-xsf.c.inc"
> >   #include "insn_trans/trans_xthead.c.inc"
> >   #include "insn_trans/trans_xventanacondops.c.inc"
> >   #include "insn_trans/trans_xmips.c.inc"
> >   #include "insn_trans/trans_xlrbr.c.inc"
> > +#include "insn_trans/trans_xsf.c.inc"
> >   /* Include the auto-generated decoder for 16 bit insn */
> >   #include "decode-insn16.c.inc"
> > @@ -1240,6 +1242,7 @@ const RISCVDecoder decoder_table[] = {
> >       { has_xthead_p, decode_xthead},
> >       { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
> >       { has_xlrbr_p, decode_xlrbr},
> > +    { has_xsf_p, decode_xsf },
> >   };
> >   const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
> > diff --git a/target/riscv/tcg/vector_helper.c b/target/riscv/tcg/vector_helper.c
> > index e321ca2616..a9b5d861dc 100644
> > --- a/target/riscv/tcg/vector_helper.c
> > +++ b/target/riscv/tcg/vector_helper.c
> > @@ -5871,3 +5871,77 @@ GEN_VEXT_INT_EXT(vsext_vf2_d, int64_t, int32_t, H8, H4)
> >   GEN_VEXT_INT_EXT(vsext_vf4_w, int32_t, int8_t,  H4, H1)
> >   GEN_VEXT_INT_EXT(vsext_vf4_d, int64_t, int16_t, H8, H2)
> >   GEN_VEXT_INT_EXT(vsext_vf8_d, int64_t, int8_t,  H8, H1)
> > +
> > +/* SiFive Custom int8 Matrix-Multiply */
> > +#define SF_QOP_SUU_B int32_t, uint8_t, uint8_t, int32_t, int32_t
> > +#define SF_QOP_SUS_B int32_t, uint8_t, int8_t, int32_t, int32_t
> > +#define SF_QOP_SSU_B int32_t, int8_t, uint8_t, int32_t, int32_t
> > +#define SF_QOP_SSS_B int32_t, int8_t, int8_t, int32_t, int32_t
> > +
> > +/*
> > + * vd may overlap vs2, we need to allocate an additional vd array
> > + * to save temporary results of vd and write them back at the end.
> > + */
> > +#define GEN_VEXT_SF_INT8_MATMUL(NAME, TD, T1, T2, TX1, TX2,           \
> > +                                HD, HS1, HS2, ROWS, COLS, TILE_SIZE)  \
> > +void HELPER(NAME)(void *vd, void *vs1, void *vs2,                     \
> > +                  CPURISCVState *env, uint32_t desc)                  \
> > +{                                                                     \
> > +    int it, il, in, im, ivd, ivs1, ivs2;                              \
> > +    TD *vds;                                                          \
> > +                                                                      \
> > +    if (env->vl % TILE_SIZE) {                                        \
> > +        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); \
> > +        return;                                                       \
> > +    }                                                                 \
> > +                                                                      \
> > +    VSTART_CHECK_EARLY_EXIT(env, env->vl);                            \
> > +                                                                      \
> > +    vds = g_malloc0(sizeof(TD) *                                      \
> > +                    ROWS * ROWS * (env->vl / TILE_SIZE));             \
> > +                                                                      \
> > +    for (it = 0; it < (env->vl / TILE_SIZE); it++) {                  \
> > +        for (il = 0; il < ROWS; il++) {                               \
> > +            for (in = 0; in < ROWS; in++) {                           \
> > +                ivd = ROWS * ROWS * it + ROWS * il + in;              \
> > +                vds[ivd] = *((TD *)vd + HD(ivd));                     \
> > +                for (im = 0; im < COLS; im++) {                       \
> > +                    ivs1 = il * COLS + im;                            \
> > +                    ivs2 = TILE_SIZE * it + im * ROWS + in;           \
> > +                    T1 s1 = *((T1 *)vs1 + HS1(ivs1));                 \
> > +                    T2 s2 = *((T2 *)vs2 + HS2(ivs2));                 \
> > +                    vds[ivd] += (TX1)s1 * (TX2)s2;                    \
> > +                }                                                     \
> > +            }                                                         \
> > +        }                                                             \
> > +    }                                                                 \
> > +                                                                      \
> > +    for (it = 0; it < (env->vl / TILE_SIZE); it++) {                  \
> > +        for (il = 0; il < ROWS; il++) {                               \
> > +            for (in = 0; in < ROWS; in++) {                           \
> > +                ivd = ROWS * ROWS * it + ROWS * il + in;              \
> > +                *((TD *)vd + HD(ivd)) = vds[ivd];                     \
> > +            }                                                         \
> > +        }                                                             \
> > +    }                                                                 \
> > +                                                                      \
> > +    env->vstart = 0;                                                  \
> > +    g_free(vds);                                                      \
> > +}
> > +
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccu_4x8x4,  SF_QOP_SUU_B,
> > +        H4, H1, H1, 4, 8, 32)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmacc_4x8x4,   SF_QOP_SSS_B,
> > +        H4, H1, H1, 4, 8, 32)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccus_4x8x4, SF_QOP_SUS_B,
> > +        H4, H1, H1, 4, 8, 32)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccsu_4x8x4, SF_QOP_SSU_B,
> > +        H4, H1, H1, 4, 8, 32)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccu_2x8x2,  SF_QOP_SUU_B,
> > +        H4, H1, H1, 2, 8, 16)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmacc_2x8x2,   SF_QOP_SSS_B,
> > +        H4, H1, H1, 2, 8, 16)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccus_2x8x2, SF_QOP_SUS_B,
> > +        H4, H1, H1, 2, 8, 16)
> > +RVVCALL(GEN_VEXT_SF_INT8_MATMUL, sf_vqmaccsu_2x8x2, SF_QOP_SSU_B,
> > +        H4, H1, H1, 2, 8, 16)
> > diff --git a/target/riscv/xsf.decode b/target/riscv/xsf.decode
> > new file mode 100644
> > index 0000000000..bb585046ab
> > --- /dev/null
> > +++ b/target/riscv/xsf.decode
> > @@ -0,0 +1,30 @@
> > +#
> > +# RISC-V translation routines for the SiFive vendor extensions
> > +#
> > +# Copyright (c) 2023 SiFive, Inc.
> > +#
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +
> > +# Fields:
> > +%rs2       20:5
> > +%rs1       15:5
> > +%rd        7:5
> > +%vm        25:1
> > +
> > +# Argument sets:
> > +&rmrr      vm rd rs1 rs2                           !extern
> > +
> > +# Formats:
> > +@r_vm_1    ......  . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
> > +
> > +# *** Xsfvqmaccqoq: SiFive custom int8 matrix-multiply (4x8x4 tile) ***
> > +sf_vqmaccu_4x8x4    111100 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmacc_4x8x4     111101 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmaccus_4x8x4   111110 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmaccsu_4x8x4   111111 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +
> > +# *** Xsfvqmaccdod: SiFive custom int8 matrix-multiply (2x8x2 tile) ***
> > +sf_vqmaccu_2x8x2    101100 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmacc_2x8x2     101101 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmaccus_2x8x2   101110 1 ..... ..... 010 ..... 1011011 @r_vm_1
> > +sf_vqmaccsu_2x8x2   101111 1 ..... ..... 010 ..... 1011011 @r_vm_1
> 


  reply	other threads:[~2026-08-07  8:50 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 12:20 [PATCH 0/5] target/riscv: Add SiFive Xsfvqmaccdod/Xsfvqmaccqoq int8 matmul extensions Max Chou
2026-07-21 12:20 ` [PATCH 1/5] target/riscv: Add cfg property for SiFive " Max Chou
2026-08-06 21:04   ` Daniel Henrique Barboza
2026-07-21 12:20 ` [PATCH 2/5] target/riscv: Add SiFive custom int8 matmul extension implied rules Max Chou
2026-08-06 21:07   ` Daniel Henrique Barboza
2026-08-07  8:32     ` Max Chou
2026-07-21 12:20 ` [PATCH 3/5] target/riscv: rvv: Add SiFive custom int8 matmul instructions Max Chou
2026-08-06 21:13   ` Daniel Henrique Barboza
2026-08-07  8:50     ` Max Chou [this message]
2026-07-21 12:20 ` [PATCH 4/5] disas/riscv: Add disassembler support for Xsfvqmaccdod/Xsfvqmaccqoq Max Chou
2026-08-06 21:15   ` Daniel Henrique Barboza
2026-07-21 12:20 ` [PATCH 5/5] tests/tcg/riscv64: Add tests for SiFive int8 matmul extensions Max Chou
2026-08-06 21:15   ` Daniel Henrique Barboza

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=anWYFy7730o4auCV@sifive.com \
    --to=max.chou@sifive.com \
    --cc=Alistair.Francis@wdc.com \
    --cc=chao.liu@processmission.com \
    --cc=daniel.barboza@oss.qualcomm.com \
    --cc=frank.chang@sifive.com \
    --cc=liwei1518@gmail.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.