* [PULL 00/51] riscv-to-apply queue
@ 2026-04-29 4:47 alistair23
2026-04-29 4:47 ` [PULL 01/51] hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI alistair23
` (51 more replies)
0 siblings, 52 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Alistair Francis
From: Alistair Francis <alistair.francis@wdc.com>
The following changes since commit 759c456b1d22fe4083c8b384da27d3f56fd53f82:
Merge tag 'linux-user-next-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2026-04-27 12:57:33 -0400)
are available in the Git repository at:
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20260429-1
for you to fetch changes up to 4d82676cfc6e14099d0e529445a5ee520752ebe5:
target/riscv: rvv: Handle mask/source overlap of vector reduction instructions (2026-04-29 14:25:06 +1000)
----------------------------------------------------------------
RISC-V PR for 11.1.
* Use standard EN_PRI bit for PRI IOMMU
* Add draft RISC-V Zbr ext as xbr0p93
* Forbid to use legacy native endianness API
* Fix irq_overflow_left residual value bug in IOMMU
* Add IPSR.PMIP RW1C support to IOMMU
* Use kvm timer frequency when kvm enabled
* Fix stale ptshift and base on page walk restart
* Fix heap OOB in ACLINT MTIMER multi-socket
* Reject RISC-V HTIF invalid signature ranges
* Fix RV32 henvcfg/stateen CSR handling
* Add Zvfbfa extension support
* Allow fractional LMUL on vector SHA instructions
* Add Tenstorrent mvendorid
* Warn if a ELF format file is loaded as a binary
* Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer
* Mask xepc[0] only when Zc* extension is enabled
* Generate access fault if sc comparison fails
* Don't OR mip.SEIP when mvien is one
* Use ELEN for Fractional LMUL check
* Fix Zjpm implementation
* Handle mask/source overlap of vector reduction instructions
----------------------------------------------------------------
Alistair Francis (3):
target/riscv: Generate access fault if sc comparison fails
target/riscv: Don't OR mip.SEIP when mvien is one
target/riscv: Use ELEN for Fractional LMUL check
Anton Blanchard (2):
target/riscv: rvv: Allow fractional LMUL on vector SHA instructions
target/riscv: rvv: Handle mask/source overlap of vector reduction instructions
Bruno Sa (2):
target/riscv: preserve RV32 henvcfgh on henvcfg writes
target/riscv: fix RV32 stateen CSR handling
Djordje Todorovic (1):
target/riscv: Use MO_LE for instruction fetch
Emmanuel Blot (3):
util: export CRC32[C] lookup tables
target/riscv: add draft RISC-V Zbr ext as xbr0p93
disas: diassemble RISC-V xlrbr (crc32) instructions
Frank Chang (7):
target/riscv: Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer
target/riscv: Mask xepc[0] only when Zc* extension is enabled
target/riscv: Add a helper to return the current effective priv mode
target/riscv: Fix pointer masking PMM field selection logic
target/riscv: Fix pointer masking for virtual-machine load/store insns
target/riscv: Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm()
target/riscv: Fix pointer masking translation mode check bug
Frédéric Pétrot (2):
target/riscv: Make LQ and SQ use 128-bit ld/st
target/riscv: Remove MTTCG check for x-rv128 CPU model
Jay Chang (3):
hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI
hw/riscv/riscv-iommu-hpm: Fix irq_overflow_left residual value bug
hw/riscv/riscv-iommu: Add IPSR.PMIP RW1C support
Joel Stanley (1):
target/riscv: tt-ascalon: Add Tenstorrent mvendorid
Max Chou (9):
target/riscv: Add cfg properties for Zvfbfa extensions
target/riscv: Add the Zvfbfa extension implied rule
target/riscv: rvv: Add new VTYPE CSR field - altfmt
target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR
target/riscv: Use the tb->cs_base as the extend tb flags
target/riscv: Introduce altfmt into DisasContext
target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
target/riscv: rvv: Support Zvfbfa vector bf16 operations
target/riscv: Expose Zvfbfa extension as a cpu property
Munkhbaatar Enkhbaatar (1):
riscv_htif: reject invalid signature ranges (end <= begin)
Nicholas Piggin (1):
hw/riscv/boot: Warn if a ELF format file is loaded as a binary
Philippe Mathieu-Daudé (12):
target/riscv: Use explicit little-endian LD/ST API
target/riscv: Explode MO_TExx -> MO_TE | MO_xx (again)
target/riscv: Conceal MO_ALIGN|MO_TE within load_acquire / store_release
target/riscv: Factor tiny ldn() helper in gdbstub
target/riscv: Simplify riscv_cpu_gdb_write_register()
target/riscv: Expose mo_endian_env()
target/riscv: Have gdbstub consider CPU endianness
target/riscv: Replace MO_TE by mo_endian (MIPS extension)
target/riscv: Replace MO_TE by mo_endian (Zilsd extension)
target/riscv: Replace MO_TE by mo_endian (Zalasr extension)
target/riscv: Replace MO_TE -> MO_LE
configs/targets: Forbid RISC-V to use legacy native endianness APIs
Sebastián Alba Vives (2):
target/riscv: fix stale ptshift and base on page walk restart
hw/intc: fix heap OOB in ACLINT MTIMER multi-socket
Yicong Yang (1):
hw/riscv/virt-acpi-build.c: Use kvm timer frequency when kvm enabled
Yong-Xuan Wang (1):
target/riscv: fix address masking
MAINTAINERS | 5 +-
configs/targets/riscv32-linux-user.mak | 1 +
configs/targets/riscv32-softmmu.mak | 1 +
configs/targets/riscv64-bsd-user.mak | 1 +
configs/targets/riscv64-linux-user.mak | 1 +
configs/targets/riscv64-softmmu.mak | 1 +
disas/riscv-xlrbr.h | 19 +
hw/riscv/riscv-iommu-bits.h | 1 +
include/exec/translation-block.h | 1 +
include/qemu/crc32.h | 14 +
include/qemu/crc32c.h | 1 +
target/riscv/cpu.h | 48 +-
target/riscv/cpu_cfg.h | 1 +
target/riscv/cpu_vendorid.h | 2 +
target/riscv/helper.h | 65 ++
target/riscv/internals.h | 33 +-
target/riscv/cpu_cfg_fields.h.inc | 2 +
target/riscv/xlrbr.decode | 30 +
disas/riscv-xlrbr.c | 79 +++
disas/riscv.c | 2 +
hw/char/riscv_htif.c | 6 +
hw/intc/riscv_aclint.c | 10 +-
hw/riscv/boot.c | 23 +-
hw/riscv/riscv-iommu-hpm.c | 1 +
hw/riscv/riscv-iommu.c | 11 +-
hw/riscv/virt-acpi-build.c | 7 +-
target/riscv/bitmanip_helper.c | 20 +
target/riscv/cpu.c | 110 +--
target/riscv/cpu_helper.c | 119 +++-
target/riscv/csr.c | 135 +++-
target/riscv/gdbstub.c | 42 +-
target/riscv/op_helper.c | 28 +-
target/riscv/tcg/tcg-cpu.c | 29 +-
target/riscv/translate.c | 24 +-
target/riscv/vector_helper.c | 398 ++++++++++-
util/crc32.c | 81 +++
util/crc32c.c | 4 +-
target/riscv/insn_trans/trans_rva.c.inc | 6 +
target/riscv/insn_trans/trans_rvi.c.inc | 32 +-
target/riscv/insn_trans/trans_rvv.c.inc | 990 +++++++++++++++++----------
target/riscv/insn_trans/trans_rvvk.c.inc | 3 +-
target/riscv/insn_trans/trans_rvzalasr.c.inc | 18 +-
target/riscv/insn_trans/trans_xlrbr.c.inc | 45 ++
target/riscv/insn_trans/trans_xmips.c.inc | 24 +-
target/riscv/insn_trans/trans_zilsd.c.inc | 4 +-
disas/meson.build | 3 +-
target/riscv/meson.build | 1 +
tests/tcg/riscv64/Makefile.softmmu-target | 5 +
tests/tcg/riscv64/test-crc32.S | 64 ++
util/meson.build | 1 +
50 files changed, 1922 insertions(+), 630 deletions(-)
create mode 100644 disas/riscv-xlrbr.h
create mode 100644 include/qemu/crc32.h
create mode 100644 target/riscv/xlrbr.decode
create mode 100644 disas/riscv-xlrbr.c
create mode 100644 util/crc32.c
create mode 100644 target/riscv/insn_trans/trans_xlrbr.c.inc
create mode 100644 tests/tcg/riscv64/test-crc32.S
^ permalink raw reply [flat|nested] 54+ messages in thread
* [PULL 01/51] hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 02/51] util: export CRC32[C] lookup tables alistair23
` (50 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Jay Chang, Frank Chang, Nutty Liu, Alistair Francis
From: Jay Chang <jay.chang@sifive.com>
Replace the temporary custom extension bit (TC[32]) with the
standard EN_PRI bit defined in RISC-V IOMMU specification.
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260325014856.58948-1-jay.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/riscv-iommu.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index c3c9ed6469..8476405d0e 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -1572,11 +1572,8 @@ static int riscv_iommu_translate(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
riscv_iommu_hpm_incr_ctr(s, ctx, RISCV_IOMMU_HPMEVENT_URQ);
iot_cache = g_hash_table_ref(s->iot_cache);
- /*
- * TC[32] is reserved for custom extensions, used here to temporarily
- * enable automatic page-request generation for ATS queries.
- */
- enable_pri = (iotlb->perm == IOMMU_NONE) && (ctx->tc & BIT_ULL(32));
+ enable_pri = (iotlb->perm == IOMMU_NONE) &&
+ (ctx->tc & RISCV_IOMMU_DC_TC_EN_PRI);
enable_pid = (ctx->tc & RISCV_IOMMU_DC_TC_PDTV);
/* Check for ATS request. */
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 02/51] util: export CRC32[C] lookup tables
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
2026-04-29 4:47 ` [PULL 01/51] hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 03/51] target/riscv: add draft RISC-V Zbr ext as xbr0p93 alistair23
` (49 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Emmanuel Blot, James Wainwright, Alistair Francis
From: Emmanuel Blot <eblot@rivosinc.com>
These are needed for the xlrbr CRC32 instructions which pre-XOR the data
into the CRC state before the instruction is executed, making the zlib
crc32 and QEMU crc32c implementations inappropriate.
https://github.com/riscv/riscv-bitmanip/releases/download/v0.93/bitmanip-0.93.pdf
Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260320134254.217123-2-james.wainwright@lowrisc.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/qemu/crc32.h | 14 ++++++++
include/qemu/crc32c.h | 1 +
util/crc32.c | 81 +++++++++++++++++++++++++++++++++++++++++++
util/crc32c.c | 4 +--
util/meson.build | 1 +
5 files changed, 99 insertions(+), 2 deletions(-)
create mode 100644 include/qemu/crc32.h
create mode 100644 util/crc32.c
diff --git a/include/qemu/crc32.h b/include/qemu/crc32.h
new file mode 100644
index 0000000000..9824a8cb5d
--- /dev/null
+++ b/include/qemu/crc32.h
@@ -0,0 +1,14 @@
+/*
+ * CRC32 Checksum
+ *
+ * Copyright (c) 2026 QEMU contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_CRC32_H
+#define QEMU_CRC32_H
+
+extern const uint32_t crc32_table[256];
+
+#endif
diff --git a/include/qemu/crc32c.h b/include/qemu/crc32c.h
index 88b4d2b3b3..3d5ba189ef 100644
--- a/include/qemu/crc32c.h
+++ b/include/qemu/crc32c.h
@@ -28,6 +28,7 @@
#ifndef QEMU_CRC32C_H
#define QEMU_CRC32C_H
+extern const uint32_t crc32c_table[256];
uint32_t crc32c(uint32_t crc, const uint8_t *data, unsigned int length);
uint32_t iov_crc32c(uint32_t crc, const struct iovec *iov, size_t iov_cnt);
diff --git a/util/crc32.c b/util/crc32.c
new file mode 100644
index 0000000000..a0f91ff09c
--- /dev/null
+++ b/util/crc32.c
@@ -0,0 +1,81 @@
+/*
+ * Constants for computing CRC32 checksums
+ *
+ * Copyright (c) 2026 QEMU contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/crc32.h"
+
+/*
+ * CRC-32 table (reversed; polynomial 0xEDB88320).
+ */
+
+const uint32_t crc32_table[256] = {
+ 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau,
+ 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u,
+ 0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u,
+ 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u,
+ 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu,
+ 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u,
+ 0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu,
+ 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u,
+ 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u,
+ 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu,
+ 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u,
+ 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u,
+ 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u,
+ 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu,
+ 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u,
+ 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du,
+ 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au,
+ 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u,
+ 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u,
+ 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u,
+ 0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu,
+ 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u,
+ 0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu,
+ 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u,
+ 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u,
+ 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu,
+ 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u,
+ 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u,
+ 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u,
+ 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu,
+ 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u,
+ 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu,
+ 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au,
+ 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u,
+ 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u,
+ 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u,
+ 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu,
+ 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u,
+ 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu,
+ 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u,
+ 0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u,
+ 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu,
+ 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u,
+ 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u,
+ 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u,
+ 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu,
+ 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u,
+ 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du,
+ 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au,
+ 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u,
+ 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u,
+ 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u,
+ 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu,
+ 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u,
+ 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu,
+ 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u,
+ 0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u,
+ 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu,
+ 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u,
+ 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u,
+ 0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u,
+ 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu,
+ 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u,
+ 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du
+};
diff --git a/util/crc32c.c b/util/crc32c.c
index ea7f345de8..f40597f80d 100644
--- a/util/crc32c.c
+++ b/util/crc32c.c
@@ -1,7 +1,7 @@
/*
* Castagnoli CRC32C Checksum Algorithm
*
- * Polynomial: 0x11EDC6F41
+ * Polynomial: 0x1EDC6F41
*
* Castagnoli93: Guy Castagnoli and Stefan Braeuer and Martin Herrman
* "Optimization of Cyclic Redundancy-Check Codes with 24
@@ -37,7 +37,7 @@
* reflect output bytes = true
*/
-static const uint32_t crc32c_table[256] = {
+const uint32_t crc32c_table[256] = {
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
diff --git a/util/meson.build b/util/meson.build
index 8bed0267c0..e29cbd948a 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -45,6 +45,7 @@ util_ss.add(files('id.c'))
util_ss.add(files('qemu-config.c', 'notify.c'))
util_ss.add(files('qemu-option.c', 'qemu-progress.c'))
util_ss.add(files('keyval.c'))
+util_ss.add(files('crc32.c'))
util_ss.add(files('crc32c.c'))
util_ss.add(files('uuid.c'))
util_ss.add(files('getauxval.c'))
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 03/51] target/riscv: add draft RISC-V Zbr ext as xbr0p93
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
2026-04-29 4:47 ` [PULL 01/51] hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI alistair23
2026-04-29 4:47 ` [PULL 02/51] util: export CRC32[C] lookup tables alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 04/51] disas: diassemble RISC-V xlrbr (crc32) instructions alistair23
` (48 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Emmanuel Blot, James Wainwright, Alistair Francis
From: Emmanuel Blot <eblot@rivosinc.com>
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>
---
MAINTAINERS | 3 ++
target/riscv/cpu_cfg.h | 1 +
target/riscv/helper.h | 2 +
target/riscv/cpu_cfg_fields.h.inc | 1 +
target/riscv/xlrbr.decode | 30 +++++++++++
target/riscv/bitmanip_helper.c | 20 +++++++
target/riscv/cpu.c | 4 +-
target/riscv/translate.c | 3 ++
target/riscv/insn_trans/trans_xlrbr.c.inc | 45 ++++++++++++++++
target/riscv/meson.build | 1 +
tests/tcg/riscv64/Makefile.softmmu-target | 5 ++
tests/tcg/riscv64/test-crc32.S | 64 +++++++++++++++++++++++
12 files changed, 178 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/xlrbr.decode
create mode 100644 target/riscv/insn_trans/trans_xlrbr.c.inc
create mode 100644 tests/tcg/riscv64/test-crc32.S
diff --git a/MAINTAINERS b/MAINTAINERS
index 49f9bce818..f7e835cf55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1729,6 +1729,9 @@ F: hw/riscv/opentitan.c
F: hw/*/ibex_*.c
F: include/hw/riscv/opentitan.h
F: include/hw/*/ibex_*.h
+F: target/riscv/insn_trans/trans_xthead.c.inc
+F: target/riscv/xlrbr.decode
+F: tests/tcg/riscv64/test-crc32.S
Microchip PolarFire SoC Icicle Kit
L: qemu-riscv@nongnu.org
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index cd1cba797c..211d0708ba 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -69,5 +69,6 @@ MATERIALISE_EXT_PREDICATE(xtheadmemidx)
MATERIALISE_EXT_PREDICATE(xtheadmempair)
MATERIALISE_EXT_PREDICATE(xtheadsync)
MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
+MATERIALISE_EXT_PREDICATE(xlrbr);
#endif
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b785456ee0..7722c590bd 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -84,6 +84,8 @@ DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(xperm8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl)
/* Floating Point - Half Precision */
DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index cd1a5ec56b..d4b7c880d4 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -154,6 +154,7 @@ BOOL_FIELD(ext_XVentanaCondOps)
BOOL_FIELD(ext_xmipscbop)
BOOL_FIELD(ext_xmipscmov)
BOOL_FIELD(ext_xmipslsp)
+BOOL_FIELD(ext_xlrbr)
BOOL_FIELD(mmu)
BOOL_FIELD(pmp)
diff --git a/target/riscv/xlrbr.decode b/target/riscv/xlrbr.decode
new file mode 100644
index 0000000000..893ce6ec71
--- /dev/null
+++ b/target/riscv/xlrbr.decode
@@ -0,0 +1,30 @@
+#
+# Translation routines for the instructions of the xlrbr ISA extension
+# (matching the draft encodings in the standard reserved encoding space for the
+# unratified Zbr CRC32 bitmanip extension version 0.93).
+#
+# Copyright (c) 2026 Rivos Inc.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Fields:
+%rs1 15:5
+%rd 7:5
+
+# Argument sets:
+&r2 rd rs1 !extern
+
+# Formats 32:
+@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
+
+# *** RV32 xlrbr extension ***
+crc32_b 0110000 10000 ..... 001 ..... 0010011 @r2
+crc32_h 0110000 10001 ..... 001 ..... 0010011 @r2
+crc32_w 0110000 10010 ..... 001 ..... 0010011 @r2
+crc32c_b 0110000 11000 ..... 001 ..... 0010011 @r2
+crc32c_h 0110000 11001 ..... 001 ..... 0010011 @r2
+crc32c_w 0110000 11010 ..... 001 ..... 0010011 @r2
+
+# *** RV64 xlrbr extension (in addition to RV32) ***
+crc32_d 0110000 10011 ..... 001 ..... 0010011 @r2
+crc32c_d 0110000 11011 ..... 001 ..... 0010011 @r2
diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
index e9c8d7f778..1156a87dd3 100644
--- a/target/riscv/bitmanip_helper.c
+++ b/target/riscv/bitmanip_helper.c
@@ -23,6 +23,8 @@
#include "exec/target_long.h"
#include "exec/helper-proto.h"
#include "tcg/tcg.h"
+#include "qemu/crc32.h"
+#include "qemu/crc32c.h"
target_ulong HELPER(clmul)(target_ulong rs1, target_ulong rs2)
{
@@ -129,3 +131,21 @@ target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2)
{
return do_xperm(rs1, rs2, 3);
}
+
+target_ulong HELPER(crc32)(target_ulong rs1, target_ulong sz)
+{
+ for (target_ulong i = 0; i < sz; i++) {
+ rs1 = crc32_table[rs1 & 0xFF] ^ (rs1 >> 8);
+ }
+
+ return rs1;
+}
+
+target_ulong HELPER(crc32c)(target_ulong rs1, target_ulong sz)
+{
+ for (target_ulong i = 0; i < sz; i++) {
+ rs1 = crc32c_table[rs1 & 0xFF] ^ (rs1 >> 8);
+ }
+
+ return rs1;
+}
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8ac935ac06..03a1bb075a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1373,6 +1373,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
MULTI_EXT_CFG_BOOL("xmipslsp", ext_xmipslsp, false),
+ MULTI_EXT_CFG_BOOL("xlrbr", ext_xlrbr, false),
{ },
};
@@ -3059,7 +3060,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.ext_zba = true,
.cfg.ext_zbb = true,
.cfg.ext_zbc = true,
- .cfg.ext_zbs = true
+ .cfg.ext_zbs = true,
+ .cfg.ext_xlrbr = true
),
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f42e53df88..711080f3fd 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1213,9 +1213,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_rvbf16.c.inc"
#include "decode-xthead.c.inc"
#include "decode-xmips.c.inc"
+#include "decode-xlrbr.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 the auto-generated decoder for 16 bit insn */
#include "decode-insn16.c.inc"
@@ -1235,6 +1237,7 @@ const RISCVDecoder decoder_table[] = {
{ has_xmips_p, decode_xmips},
{ has_xthead_p, decode_xthead},
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps},
+ { has_xlrbr_p, decode_xlrbr},
};
const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
diff --git a/target/riscv/insn_trans/trans_xlrbr.c.inc b/target/riscv/insn_trans/trans_xlrbr.c.inc
new file mode 100644
index 0000000000..01da2b6ce1
--- /dev/null
+++ b/target/riscv/insn_trans/trans_xlrbr.c.inc
@@ -0,0 +1,45 @@
+/*
+ * RISC-V translation routines for xlrbr matching the unratified Zbr CRC32
+ * bitmanip extension v0.93.
+ *
+ * Copyright (c) 2026 Rivos Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#define REQUIRE_XLRBR(ctx) do { \
+ if (!ctx->cfg_ptr->ext_xlrbr) { \
+ return false; \
+ } \
+} while (0)
+
+static bool gen_crc(DisasContext *ctx, arg_r2 *a,
+ void (*func)(TCGv, TCGv, TCGv), TCGv tsz)
+{
+ REQUIRE_XLRBR(ctx);
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+
+ func(dest, src1, tsz);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ return true;
+}
+
+#define TRANS_CRC32(NAME, SIZE) \
+ static bool trans_crc32_##NAME(DisasContext *ctx, arg_r2 *a) \
+ { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
+ return gen_crc(ctx, a, gen_helper_crc32, tcg_constant_tl(SIZE)); }
+#define TRANS_CRC32C(NAME, SIZE) \
+ static bool trans_crc32c_##NAME(DisasContext *ctx, arg_r2 *a) \
+ { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
+ return gen_crc(ctx, a, gen_helper_crc32c, tcg_constant_tl(SIZE)); }
+
+TRANS_CRC32(b, 1);
+TRANS_CRC32(h, 2);
+TRANS_CRC32(w, 4);
+TRANS_CRC32(d, 8);
+TRANS_CRC32C(b, 1);
+TRANS_CRC32C(h, 2);
+TRANS_CRC32C(w, 4);
+TRANS_CRC32C(d, 8);
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 3842c7c1a8..79f36abd63 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -5,6 +5,7 @@ gen = [
decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
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'),
]
riscv_ss = ss.source_set()
diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
index eb1ce6504a..82be8a2c91 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -36,5 +36,10 @@ run-plugin-interruptedmemory: interruptedmemory
$(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
$(QEMU_OPTS)$<)
+EXTRA_RUNS += run-test-crc32
+comma:= ,
+run-test-crc32: test-crc32
+ $(call run-test, $<, $(QEMU) -cpu rv64$(comma)xlrbr=true $(QEMU_OPTS)$<)
+
# We don't currently support the multiarch system tests
undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/test-crc32.S b/tests/tcg/riscv64/test-crc32.S
new file mode 100644
index 0000000000..70d70b16a9
--- /dev/null
+++ b/tests/tcg/riscv64/test-crc32.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2026 lowRISC CIC
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#define crc32(op, rd, rs1) .insn r 19, 1, 48, rd, rs1, x##op
+
+#define crc32_b(rd, rs1) crc32(16, rd, rs1)
+#define crc32_h(rd, rs1) crc32(17, rd, rs1)
+#define crc32_w(rd, rs1) crc32(18, rd, rs1)
+#define crc32_d(rd, rs1) crc32(19, rd, rs1)
+#define crc32c_b(rd, rs1) crc32(24, rd, rs1)
+#define crc32c_h(rd, rs1) crc32(25, rd, rs1)
+#define crc32c_w(rd, rs1) crc32(26, rd, rs1)
+#define crc32c_d(rd, rs1) crc32(27, rd, rs1)
+
+ .option norvc
+
+ .text
+ .globl _start
+_start:
+ lla t0, trap
+ csrw mtvec, t0
+
+ li t0, 0x34e24a2cd65650d4
+
+ crc32_b (t0, t0)
+ crc32_h (t0, t0)
+ crc32_w (t0, t0)
+ crc32_d (t0, t0)
+ crc32c_b (t0, t0)
+ crc32c_h (t0, t0)
+ crc32c_w (t0, t0)
+ crc32c_d (t0, t0)
+
+ li t1, 0x68167e78
+
+ li a0, 0
+ beq t0, t1, _exit
+fail:
+ li a0, 1
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 # ADP_Stopped_ApplicationExit
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED
+
+ # Semihosting call sequence
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+ .data
+ .balign 16
+semiargs:
+ .space 16
+
+trap:
+ csrr t0, mepc
+ addi t0, t0, 4
+ mret
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 04/51] disas: diassemble RISC-V xlrbr (crc32) instructions
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (2 preceding siblings ...)
2026-04-29 4:47 ` [PULL 03/51] target/riscv: add draft RISC-V Zbr ext as xbr0p93 alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 05/51] target/riscv: Use explicit little-endian LD/ST API alistair23
` (47 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Emmanuel Blot, James Wainwright, Alistair Francis
From: Emmanuel Blot <eblot@rivosinc.com>
Placed in a separate file as a vendor extension.
Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260320134254.217123-4-james.wainwright@lowrisc.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
MAINTAINERS | 2 +-
disas/riscv-xlrbr.h | 19 +++++++++++
disas/riscv-xlrbr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++
disas/riscv.c | 2 ++
disas/meson.build | 3 +-
5 files changed, 103 insertions(+), 2 deletions(-)
create mode 100644 disas/riscv-xlrbr.h
create mode 100644 disas/riscv-xlrbr.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f7e835cf55..e41f0eb92c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4135,7 +4135,7 @@ R: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
L: qemu-riscv@nongnu.org
S: Maintained
F: tcg/riscv64/
-F: disas/riscv.[ch]
+F: disas/riscv*.[ch]
S390 TCG target
M: Richard Henderson <richard.henderson@linaro.org>
diff --git a/disas/riscv-xlrbr.h b/disas/riscv-xlrbr.h
new file mode 100644
index 0000000000..939a69ea6d
--- /dev/null
+++ b/disas/riscv-xlrbr.h
@@ -0,0 +1,19 @@
+/*
+ * QEMU RISC-V Disassembler for xlrbr matching the unratified Zbr CRC32
+ * bitmanip extension v0.93.
+ *
+ * Copyright (c) 2023 Rivos Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DISAS_RISCV_XLRBR_H
+#define DISAS_RISCV_XLRBR_H
+
+#include "disas/riscv.h"
+
+extern const rv_opcode_data rv_xlrbr_opcode_data[];
+
+void decode_xlrbr(rv_decode *, rv_isa);
+
+#endif /* DISAS_RISCV_XLRBR_H */
diff --git a/disas/riscv-xlrbr.c b/disas/riscv-xlrbr.c
new file mode 100644
index 0000000000..57cb434523
--- /dev/null
+++ b/disas/riscv-xlrbr.c
@@ -0,0 +1,79 @@
+/*
+ * QEMU RISC-V Disassembler for xlrbr matching the unratified Zbr CRC32
+ * bitmanip extension v0.93.
+ *
+ * Copyright (c) 2023 Rivos Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "disas/riscv.h"
+#include "disas/riscv-xlrbr.h"
+
+typedef enum {
+ /* 0 is reserved for rv_op_illegal. */
+ rv_op_crc32_b = 1,
+ rv_op_crc32_h = 2,
+ rv_op_crc32_w = 3,
+ rv_op_crc32_d = 4,
+ rv_op_crc32c_b = 5,
+ rv_op_crc32c_h = 6,
+ rv_op_crc32c_w = 7,
+ rv_op_crc32c_d = 8,
+} rv_xlrbr_op;
+
+const rv_opcode_data rv_xlrbr_opcode_data[] = {
+ { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
+ { "crc32.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32c.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32c.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32c.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+ { "crc32c.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+};
+
+void decode_xlrbr(rv_decode *dec, rv_isa isa)
+{
+ rv_inst inst = dec->inst;
+ rv_opcode op = rv_op_illegal;
+
+ switch ((inst >> 0) & 0b1111111) {
+ case 0b0010011:
+ switch ((inst >> 12) & 0b111) {
+ case 0b001:
+ switch ((inst >> 20 & 0b111111111111)) {
+ case 0b011000010000:
+ op = rv_op_crc32_b;
+ break;
+ case 0b011000010001:
+ op = rv_op_crc32_h;
+ break;
+ case 0b011000010010:
+ op = rv_op_crc32_w;
+ break;
+ case 0b011000010011:
+ op = rv_op_crc32_d;
+ break;
+ case 0b011000011000:
+ op = rv_op_crc32c_b;
+ break;
+ case 0b011000011001:
+ op = rv_op_crc32c_h;
+ break;
+ case 0b011000011010:
+ op = rv_op_crc32c_w;
+ break;
+ case 0b011000011011:
+ op = rv_op_crc32c_d;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ dec->op = op;
+}
diff --git a/disas/riscv.c b/disas/riscv.c
index 6f2667482d..d416a4d6b3 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -26,6 +26,7 @@
/* Vendor extensions */
#include "disas/riscv-xthead.h"
#include "disas/riscv-xventana.h"
+#include "disas/riscv-xlrbr.h"
typedef enum {
/* 0 is reserved for rv_op_illegal. */
@@ -5434,6 +5435,7 @@ static GString *disasm_inst(rv_isa isa, uint64_t pc, rv_inst inst,
{ has_xtheadmempair_p, xthead_opcode_data, decode_xtheadmempair },
{ has_xtheadsync_p, xthead_opcode_data, decode_xtheadsync },
{ has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
+ { has_xlrbr_p, rv_xlrbr_opcode_data, decode_xlrbr },
};
for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
diff --git a/disas/meson.build b/disas/meson.build
index bbfa119783..42977a1f74 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -7,7 +7,8 @@ common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
'riscv.c',
'riscv-xthead.c',
- 'riscv-xventana.c'
+ 'riscv-xventana.c',
+ 'riscv-xlrbr.c'
))
common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 05/51] target/riscv: Use explicit little-endian LD/ST API
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (3 preceding siblings ...)
2026-04-29 4:47 ` [PULL 04/51] disas: diassemble RISC-V xlrbr (crc32) instructions alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 06/51] target/riscv: Make LQ and SQ use 128-bit ld/st alistair23
` (46 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
We only build our RISC-V targets as little-endian, therefore
the LD/ST API expands to its little-endian variant. Directly
use the latter.
Mechanical change running:
$ for a in uw w l q; do \
sed -i -e "s/ld${a}_p(/ld${a}_le_p(/" \
$(git grep -wlE '(ld|st)u?[wlq]_p' target/riscv);
done
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-3-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index dd6c861a90..c28832e0e3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1365,9 +1365,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
}
if (riscv_cpu_mxl(env) == MXL_RV32) {
- pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
+ pte = address_space_ldl_le(cs->as, pte_addr, attrs, &res);
} else {
- pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
+ pte = address_space_ldq_le(cs->as, pte_addr, attrs, &res);
}
if (res != MEMTX_OK) {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 06/51] target/riscv: Make LQ and SQ use 128-bit ld/st
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (4 preceding siblings ...)
2026-04-29 4:47 ` [PULL 05/51] target/riscv: Use explicit little-endian LD/ST API alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 07/51] target/riscv: Remove MTTCG check for x-rv128 CPU model alistair23
` (45 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frédéric Pétrot,
Philippe Mathieu-Daudé, Richard Henderson, Alistair Francis
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
The lq and sq helpers for the experimental rv128 architecture
currently use direct memory accesses.
Replace these direct accesses with the standard
tcg_gen_qemu_{ld,st}_i128 TCG helpers that handle endianness
issues.
Reported-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
Message-ID: <20260101181442.2489496-2-frederic.petrot@univ-grenoble-alpes.fr>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-4-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvi.c.inc | 32 ++++++++++++++++++-------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 54b9b4f241..2c82ae41a7 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -377,6 +377,9 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
TCGv destl = dest_gpr(ctx, a->rd);
TCGv desth = dest_gprh(ctx, a->rd);
TCGv addrl = tcg_temp_new();
+ TCGv_i128 t16 = tcg_temp_new_i128();
+ TCGv_i64 tl = tcg_temp_new_i64();
+ TCGv_i64 th = tcg_temp_new_i64();
tcg_gen_addi_tl(addrl, src1l, a->imm);
@@ -388,10 +391,14 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
tcg_gen_movi_tl(desth, 0);
}
} else {
- /* assume little-endian memory access for now */
- tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ);
- tcg_gen_addi_tl(addrl, addrl, 8);
- tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ);
+ tcg_gen_qemu_ld_i128(t16, addrl, ctx->mem_idx, memop);
+ if (mo_endian(ctx) == MO_LE) {
+ tcg_gen_extr_i128_i64(tl, th, t16);
+ } else {
+ tcg_gen_extr_i128_i64(th, tl, t16);
+ }
+ tcg_gen_trunc_i64_tl(destl, tl);
+ tcg_gen_trunc_i64_tl(desth, th);
}
gen_set_gpr128(ctx, a->rd, destl, desth);
@@ -488,16 +495,25 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE);
TCGv src2h = get_gprh(ctx, a->rs2);
TCGv addrl = tcg_temp_new();
+ TCGv_i128 t16 = tcg_temp_new_i128();
+ TCGv_i64 tl = tcg_temp_new_i64();
+ TCGv_i64 th = tcg_temp_new_i64();
tcg_gen_addi_tl(addrl, src1l, a->imm);
if ((memop & MO_SIZE) <= MO_64) {
tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop);
} else {
- /* little-endian memory access assumed for now */
- tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ);
- tcg_gen_addi_tl(addrl, addrl, 8);
- tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ);
+
+ tcg_gen_ext_tl_i64(tl, src2l);
+ tcg_gen_ext_tl_i64(th, src2h);
+
+ if (mo_endian(ctx) == MO_LE) {
+ tcg_gen_concat_i64_i128(t16, tl, th);
+ } else {
+ tcg_gen_concat_i64_i128(t16, th, tl);
+ }
+ tcg_gen_qemu_st_i128(t16, addrl, ctx->mem_idx, memop);
}
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 07/51] target/riscv: Remove MTTCG check for x-rv128 CPU model
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (5 preceding siblings ...)
2026-04-29 4:47 ` [PULL 06/51] target/riscv: Make LQ and SQ use 128-bit ld/st alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 08/51] target/riscv: Explode MO_TExx -> MO_TE | MO_xx (again) alistair23
` (44 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frédéric Pétrot,
Philippe Mathieu-Daudé, Alistair Francis
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
We had to check that mttcg was not used when executing QEMU with
-cpu x-rv128 as a single 128-bit access was done as two distinct
64-bit accesses.
Now that we use the 128-bit ld/st that access the data atomically,
this check is no longer necessary.
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
Message-ID: <20260101181442.2489496-3-frederic.petrot@univ-grenoble-alpes.fr>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-5-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/tcg/tcg-cpu.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 988b2d905f..3407191c22 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1305,16 +1305,6 @@ static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp)
}
#ifndef CONFIG_USER_ONLY
- RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
-
- if (mcc->def->misa_mxl_max >= MXL_RV128 && qemu_tcg_mttcg_enabled()) {
- /* Missing 128-bit aligned atomics */
- error_setg(errp,
- "128-bit RISC-V currently does not work with Multi "
- "Threaded TCG. Please use: -accel tcg,thread=single");
- return false;
- }
-
CPURISCVState *env = &cpu->env;
tcg_cflags_set(CPU(cs), CF_PCREL);
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 08/51] target/riscv: Explode MO_TExx -> MO_TE | MO_xx (again)
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (6 preceding siblings ...)
2026-04-29 4:47 ` [PULL 07/51] target/riscv: Remove MTTCG check for x-rv128 CPU model alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 09/51] target/riscv: Conceal MO_ALIGN|MO_TE within load_acquire / store_release alistair23
` (43 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Following commit 73ae67fd4e6, extract the implicit MO_TE
definition in order to replace it.
Mechanical change using:
$ for n in UW UL UQ UO SW SL SQ; do \
sed -i -e "s/MO_TE$n/MO_TE | MO_$n/" \
$(git grep -l MO_TE$n target/riscv); \
done
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-6-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvzalasr.c.inc | 12 ++++++------
target/riscv/insn_trans/trans_xmips.c.inc | 16 ++++++++--------
target/riscv/insn_trans/trans_zilsd.c.inc | 4 ++--
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvzalasr.c.inc b/target/riscv/insn_trans/trans_rvzalasr.c.inc
index bf86805cef..525f01ca34 100644
--- a/target/riscv/insn_trans/trans_rvzalasr.c.inc
+++ b/target/riscv/insn_trans/trans_rvzalasr.c.inc
@@ -49,20 +49,20 @@ static bool trans_lb_aqrl(DisasContext *ctx, arg_lb_aqrl *a)
static bool trans_lh_aqrl(DisasContext *ctx, arg_lh_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TESW));
+ return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_SW));
}
static bool trans_lw_aqrl(DisasContext *ctx, arg_lw_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TESL));
+ return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_SL));
}
static bool trans_ld_aqrl(DisasContext *ctx, arg_ld_aqrl *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TEUQ));
+ return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_UQ));
}
static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
@@ -96,18 +96,18 @@ static bool trans_sb_aqrl(DisasContext *ctx, arg_sb_aqrl *a)
static bool trans_sh_aqrl(DisasContext *ctx, arg_sh_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TESW));
+ return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_SW));
}
static bool trans_sw_aqrl(DisasContext *ctx, arg_sw_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TESL));
+ return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_SL));
}
static bool trans_sd_aqrl(DisasContext *ctx, arg_sd_aqrl *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TEUQ));
+ return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_UQ));
}
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc b/target/riscv/insn_trans/trans_xmips.c.inc
index 9a72f3392f..37572563ae 100644
--- a/target/riscv/insn_trans/trans_xmips.c.inc
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -56,11 +56,11 @@ static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_y);
- tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESQ);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TE | MO_SQ);
gen_set_gpr(ctx, a->rd, dest0);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESQ);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TE | MO_SQ);
gen_set_gpr(ctx, a->rs3, dest1);
return true;
@@ -77,11 +77,11 @@ static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_x);
- tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESL);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TE | MO_SL);
gen_set_gpr(ctx, a->rd, dest0);
tcg_gen_addi_tl(addr, addr, 4);
- tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESL);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TE | MO_SL);
gen_set_gpr(ctx, a->rs3, dest1);
return true;
@@ -99,10 +99,10 @@ static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_w);
- tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TEUQ);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TE | MO_UQ);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TEUQ);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TE | MO_UQ);
return true;
}
@@ -118,10 +118,10 @@ static bool trans_swp(DisasContext *ctx, arg_swp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_v);
- tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TESL);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TE | MO_SL);
tcg_gen_addi_tl(addr, addr, 4);
- tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TESL);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TE | MO_SL);
return true;
}
diff --git a/target/riscv/insn_trans/trans_zilsd.c.inc b/target/riscv/insn_trans/trans_zilsd.c.inc
index 369c33004b..445406cf01 100644
--- a/target/riscv/insn_trans/trans_zilsd.c.inc
+++ b/target/riscv/insn_trans/trans_zilsd.c.inc
@@ -30,7 +30,7 @@ static bool gen_load_i64(DisasContext *ctx, arg_ld *a)
TCGv addr = get_address(ctx, a->rs1, a->imm);
TCGv_i64 tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_TESQ);
+ tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_TE | MO_SQ);
if (a->rd == 0) {
return true;
@@ -85,7 +85,7 @@ static bool gen_store_i64(DisasContext *ctx, arg_sd *a)
} else {
tcg_gen_concat_tl_i64(tmp, data_low, data_high);
}
- tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_TESQ);
+ tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_TE | MO_SQ);
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 09/51] target/riscv: Conceal MO_ALIGN|MO_TE within load_acquire / store_release
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (7 preceding siblings ...)
2026-04-29 4:47 ` [PULL 08/51] target/riscv: Explode MO_TExx -> MO_TE | MO_xx (again) alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 10/51] target/riscv: Factor tiny ldn() helper in gdbstub alistair23
` (42 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
All callers of gen_load_acquire() and gen_store_release() set both
the MO_ALIGN|MO_TE flags. Set them once in each callee.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-7-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvzalasr.c.inc | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvzalasr.c.inc b/target/riscv/insn_trans/trans_rvzalasr.c.inc
index 525f01ca34..2b1f73f650 100644
--- a/target/riscv/insn_trans/trans_rvzalasr.c.inc
+++ b/target/riscv/insn_trans/trans_rvzalasr.c.inc
@@ -29,6 +29,7 @@ static bool gen_load_acquire(DisasContext *ctx, arg_lb_aqrl *a, MemOp memop)
return false;
}
+ memop |= MO_ALIGN | MO_TE;
memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
@@ -43,26 +44,26 @@ static bool gen_load_acquire(DisasContext *ctx, arg_lb_aqrl *a, MemOp memop)
static bool trans_lb_aqrl(DisasContext *ctx, arg_lb_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_SB));
+ return gen_load_acquire(ctx, a, MO_SB);
}
static bool trans_lh_aqrl(DisasContext *ctx, arg_lh_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_SW));
+ return gen_load_acquire(ctx, a, MO_SW);
}
static bool trans_lw_aqrl(DisasContext *ctx, arg_lw_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_SL));
+ return gen_load_acquire(ctx, a, MO_SL);
}
static bool trans_ld_aqrl(DisasContext *ctx, arg_ld_aqrl *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZALASR(ctx);
- return gen_load_acquire(ctx, a, (MO_ALIGN | MO_TE | MO_UQ));
+ return gen_load_acquire(ctx, a, MO_UQ);
}
static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
@@ -78,6 +79,7 @@ static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
return false;
}
+ memop |= MO_ALIGN | MO_TE;
memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
/* Add a memory barrier implied by RL (mandatory) and AQ (optional) */
@@ -90,24 +92,24 @@ static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
static bool trans_sb_aqrl(DisasContext *ctx, arg_sb_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_SB));
+ return gen_store_release(ctx, a, MO_SB);
}
static bool trans_sh_aqrl(DisasContext *ctx, arg_sh_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_SW));
+ return gen_store_release(ctx, a, MO_SW);
}
static bool trans_sw_aqrl(DisasContext *ctx, arg_sw_aqrl *a)
{
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_SL));
+ return gen_store_release(ctx, a, MO_SL);
}
static bool trans_sd_aqrl(DisasContext *ctx, arg_sd_aqrl *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZALASR(ctx);
- return gen_store_release(ctx, a, (MO_ALIGN | MO_TE | MO_UQ));
+ return gen_store_release(ctx, a, MO_UQ);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 10/51] target/riscv: Factor tiny ldn() helper in gdbstub
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (8 preceding siblings ...)
2026-04-29 4:47 ` [PULL 09/51] target/riscv: Conceal MO_ALIGN|MO_TE within load_acquire / store_release alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 11/51] target/riscv: Simplify riscv_cpu_gdb_write_register() alistair23
` (41 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
In preparation of having this helper handle CPU runtime
endianness changes, factor the ldn() helper out.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-8-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/gdbstub.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 6a5b7a82fd..be42566bcc 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -47,6 +47,11 @@ static const struct TypeSize vec_lanes[] = {
{ "uint8", "bytes", 8, 'b' },
};
+static uint64_t ldn(CPURISCVState *env, uint8_t *mem_buf, size_t regsz)
+{
+ return ldn_p(mem_buf, regsz);
+}
+
int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
@@ -84,15 +89,15 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
switch (mcc->def->misa_mxl_max) {
case MXL_RV32:
- tmp = (int32_t)ldl_p(mem_buf);
+ tmp = (int32_t)ldn(env, mem_buf, 4);
length = 4;
break;
case MXL_RV64:
case MXL_RV128:
if (env->xl < MXL_RV64) {
- tmp = (int32_t)ldq_p(mem_buf);
+ tmp = (int32_t)ldn(env, mem_buf, 8);
} else {
- tmp = ldq_p(mem_buf);
+ tmp = ldn(env, mem_buf, 8);
}
length = 8;
break;
@@ -130,7 +135,7 @@ static int riscv_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n)
CPURISCVState *env = &cpu->env;
if (n < 32) {
- env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
+ env->fpr[n] = ldn(env, mem_buf, 8); /* always 64-bit */
return sizeof(uint64_t);
}
return 0;
@@ -162,7 +167,7 @@ static int riscv_gdb_set_vector(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 32) {
int i;
for (i = 0; i < vlenb; i += 8) {
- env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
+ env->vreg[(n * vlenb + i) / 8] = ldn(env, mem_buf + i, 8);
}
return vlenb;
}
@@ -194,7 +199,7 @@ static int riscv_gdb_set_csr(CPUState *cs, uint8_t *mem_buf, int n)
const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
if (n < CSR_TABLE_SIZE) {
- uint64_t val = ldn_p(mem_buf, regsz);
+ uint64_t val = ldn(env, mem_buf, regsz);
int result;
result = riscv_csrrw_debug(env, n, NULL, val, -1);
@@ -230,8 +235,7 @@ static int riscv_gdb_set_virtual(CPUState *cs, uint8_t *mem_buf, int n)
const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
#ifndef CONFIG_USER_ONLY
CPURISCVState *env = &cpu->env;
-
- target_ulong new_priv = ldn_p(mem_buf, regsz) & 0x3;
+ uint64_t new_priv = ldn(env, mem_buf, regsz) & 0x3;
bool new_virt = 0;
if (new_priv == PRV_RESERVED) {
@@ -239,7 +243,7 @@ static int riscv_gdb_set_virtual(CPUState *cs, uint8_t *mem_buf, int n)
}
if (new_priv != PRV_M) {
- new_virt = (ldn_p(mem_buf, regsz) & BIT(2)) >> 2;
+ new_virt = (ldn(env, mem_buf, regsz) & BIT(2)) >> 2;
}
if (riscv_has_ext(env, RVH) && new_virt != env->virt_enabled) {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 11/51] target/riscv: Simplify riscv_cpu_gdb_write_register()
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (9 preceding siblings ...)
2026-04-29 4:47 ` [PULL 10/51] target/riscv: Factor tiny ldn() helper in gdbstub alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 12/51] target/riscv: Expose mo_endian_env() alistair23
` (40 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Use a single ldn() call, sign-extend once.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-9-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/gdbstub.c | 25 ++++++-------------------
1 file changed, 6 insertions(+), 19 deletions(-)
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index be42566bcc..a5c1263878 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -84,33 +84,20 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
- int length = 0;
- uint64_t tmp;
+ const size_t regsize = mcc->def->misa_mxl_max == MXL_RV32 ? 4 : 8;
+ uint64_t tmp = ldn(env, mem_buf, regsize);
- switch (mcc->def->misa_mxl_max) {
- case MXL_RV32:
- tmp = (int32_t)ldn(env, mem_buf, 4);
- length = 4;
- break;
- case MXL_RV64:
- case MXL_RV128:
- if (env->xl < MXL_RV64) {
- tmp = (int32_t)ldn(env, mem_buf, 8);
- } else {
- tmp = ldn(env, mem_buf, 8);
- }
- length = 8;
- break;
- default:
- g_assert_not_reached();
+ if (env->xl < MXL_RV64) {
+ tmp = (int32_t)tmp;
}
+
if (n > 0 && n < 32) {
env->gpr[n] = tmp;
} else if (n == 32) {
env->pc = tmp;
}
- return length;
+ return regsize;
}
static int riscv_gdb_get_fpu(CPUState *cs, GByteArray *buf, int n)
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 12/51] target/riscv: Expose mo_endian_env()
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (10 preceding siblings ...)
2026-04-29 4:47 ` [PULL 11/51] target/riscv: Simplify riscv_cpu_gdb_write_register() alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 13/51] target/riscv: Have gdbstub consider CPU endianness alistair23
` (39 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Move mo_endian_env() definition to "internals.h" for re-use.
Do not restrict to system emulation only because this will
also be used by user emulation code.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-10-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/internals.h | 12 ++++++++++++
target/riscv/op_helper.c | 14 --------------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 35b923c4bf..860c47732b 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -62,6 +62,18 @@ static inline bool mmuidx_2stage(int mmu_idx)
return mmu_idx & MMU_2STAGE_BIT;
}
+static inline MemOp mo_endian_env(CPURISCVState *env)
+{
+ /*
+ * A couple of bits in MSTATUS set the endianness:
+ * - MSTATUS_UBE (User-mode),
+ * - MSTATUS_SBE (Supervisor-mode),
+ * - MSTATUS_MBE (Machine-mode)
+ * but we don't implement that yet.
+ */
+ return MO_TE;
+}
+
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 6ccc127c30..dde40a5549 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -28,20 +28,6 @@
#include "exec/tlb-flags.h"
#include "trace.h"
-#ifndef CONFIG_USER_ONLY
-static inline MemOp mo_endian_env(CPURISCVState *env)
-{
- /*
- * A couple of bits in MSTATUS set the endianness:
- * - MSTATUS_UBE (User-mode),
- * - MSTATUS_SBE (Supervisor-mode),
- * - MSTATUS_MBE (Machine-mode)
- * but we don't implement that yet.
- */
- return MO_TE;
-}
-#endif
-
/* Exceptions processing helpers */
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
RISCVException exception,
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 13/51] target/riscv: Have gdbstub consider CPU endianness
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (11 preceding siblings ...)
2026-04-29 4:47 ` [PULL 12/51] target/riscv: Expose mo_endian_env() alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 14/51] target/riscv: Replace MO_TE by mo_endian (MIPS extension) alistair23
` (38 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Consider CPU endianness when accessing registers.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-11-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/gdbstub.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index a5c1263878..2c6ccd4761 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -20,6 +20,7 @@
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "cpu.h"
+#include "internals.h"
struct TypeSize {
const char *gdb_type;
@@ -49,7 +50,7 @@ static const struct TypeSize vec_lanes[] = {
static uint64_t ldn(CPURISCVState *env, uint8_t *mem_buf, size_t regsz)
{
- return ldn_p(mem_buf, regsz);
+ return (mo_endian_env(env) == MO_LE ? ldn_le_p : ldn_be_p)(mem_buf, regsz);
}
int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 14/51] target/riscv: Replace MO_TE by mo_endian (MIPS extension)
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (12 preceding siblings ...)
2026-04-29 4:47 ` [PULL 13/51] target/riscv: Have gdbstub consider CPU endianness alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 15/51] target/riscv: Replace MO_TE by mo_endian (Zilsd extension) alistair23
` (37 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Replace compile-time MO_TE evaluation by runtime mo_endian()
one, which expand target endianness from DisasContext.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-12-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_xmips.c.inc | 24 +++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc b/target/riscv/insn_trans/trans_xmips.c.inc
index 37572563ae..c1a30156d3 100644
--- a/target/riscv/insn_trans/trans_xmips.c.inc
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -47,6 +47,8 @@ static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
/* Load Doubleword Pair. */
static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
{
+ MemOp memop = MO_SQ | mo_endian(ctx);
+
REQUIRE_XMIPSLSP(ctx);
REQUIRE_64_OR_128BIT(ctx);
@@ -56,11 +58,11 @@ static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_y);
- tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TE | MO_SQ);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, memop);
gen_set_gpr(ctx, a->rd, dest0);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TE | MO_SQ);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, memop);
gen_set_gpr(ctx, a->rs3, dest1);
return true;
@@ -69,6 +71,8 @@ static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
/* Load Word Pair. */
static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
{
+ MemOp memop = MO_SL | mo_endian(ctx);
+
REQUIRE_XMIPSLSP(ctx);
TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -77,11 +81,11 @@ static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_x);
- tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TE | MO_SL);
+ tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, memop);
gen_set_gpr(ctx, a->rd, dest0);
tcg_gen_addi_tl(addr, addr, 4);
- tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TE | MO_SL);
+ tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, memop);
gen_set_gpr(ctx, a->rs3, dest1);
return true;
@@ -90,6 +94,8 @@ static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
/* Store Doubleword Pair. */
static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
{
+ MemOp memop = MO_UQ | mo_endian(ctx);
+
REQUIRE_XMIPSLSP(ctx);
REQUIRE_64_OR_128BIT(ctx);
@@ -99,10 +105,10 @@ static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_w);
- tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TE | MO_UQ);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, memop);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TE | MO_UQ);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, memop);
return true;
}
@@ -110,6 +116,8 @@ static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
/* Store Word Pair. */
static bool trans_swp(DisasContext *ctx, arg_swp *a)
{
+ MemOp memop = MO_SL | mo_endian(ctx);
+
REQUIRE_XMIPSLSP(ctx);
TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -118,10 +126,10 @@ static bool trans_swp(DisasContext *ctx, arg_swp *a)
TCGv addr = tcg_temp_new();
tcg_gen_addi_tl(addr, src, a->imm_v);
- tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TE | MO_SL);
+ tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, memop);
tcg_gen_addi_tl(addr, addr, 4);
- tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TE | MO_SL);
+ tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, memop);
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 15/51] target/riscv: Replace MO_TE by mo_endian (Zilsd extension)
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (13 preceding siblings ...)
2026-04-29 4:47 ` [PULL 14/51] target/riscv: Replace MO_TE by mo_endian (MIPS extension) alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 16/51] target/riscv: Replace MO_TE by mo_endian (Zalasr extension) alistair23
` (36 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Replace compile-time MO_TE evaluation by runtime mo_endian()
one, which expand target endianness from DisasContext.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-13-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_zilsd.c.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/riscv/insn_trans/trans_zilsd.c.inc b/target/riscv/insn_trans/trans_zilsd.c.inc
index 445406cf01..f50c52f22c 100644
--- a/target/riscv/insn_trans/trans_zilsd.c.inc
+++ b/target/riscv/insn_trans/trans_zilsd.c.inc
@@ -30,7 +30,7 @@ static bool gen_load_i64(DisasContext *ctx, arg_ld *a)
TCGv addr = get_address(ctx, a->rs1, a->imm);
TCGv_i64 tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_TE | MO_SQ);
+ tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_SQ | mo_endian(ctx));
if (a->rd == 0) {
return true;
@@ -85,7 +85,7 @@ static bool gen_store_i64(DisasContext *ctx, arg_sd *a)
} else {
tcg_gen_concat_tl_i64(tmp, data_low, data_high);
}
- tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_TE | MO_SQ);
+ tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_SQ | mo_endian(ctx));
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 16/51] target/riscv: Replace MO_TE by mo_endian (Zalasr extension)
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (14 preceding siblings ...)
2026-04-29 4:47 ` [PULL 15/51] target/riscv: Replace MO_TE by mo_endian (Zilsd extension) alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 17/51] target/riscv: Replace MO_TE -> MO_LE alistair23
` (35 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Replace compile-time MO_TE evaluation by runtime mo_endian()
one, which expand target endianness from DisasContext.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-14-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvzalasr.c.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvzalasr.c.inc b/target/riscv/insn_trans/trans_rvzalasr.c.inc
index 2b1f73f650..0f307affec 100644
--- a/target/riscv/insn_trans/trans_rvzalasr.c.inc
+++ b/target/riscv/insn_trans/trans_rvzalasr.c.inc
@@ -29,7 +29,7 @@ static bool gen_load_acquire(DisasContext *ctx, arg_lb_aqrl *a, MemOp memop)
return false;
}
- memop |= MO_ALIGN | MO_TE;
+ memop |= MO_ALIGN | mo_endian(ctx);
memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
@@ -79,7 +79,7 @@ static bool gen_store_release(DisasContext *ctx, arg_sb_aqrl *a, MemOp memop)
return false;
}
- memop |= MO_ALIGN | MO_TE;
+ memop |= MO_ALIGN | mo_endian(ctx);
memop |= (ctx->cfg_ptr->ext_zama16b) ? MO_ATOM_WITHIN16 : 0;
/* Add a memory barrier implied by RL (mandatory) and AQ (optional) */
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 17/51] target/riscv: Replace MO_TE -> MO_LE
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (15 preceding siblings ...)
2026-04-29 4:47 ` [PULL 16/51] target/riscv: Replace MO_TE by mo_endian (Zalasr extension) alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 18/51] target/riscv: Use MO_LE for instruction fetch alistair23
` (34 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
We only build the RISC-V target using little endianness order,
therefore the MO_TE definitions expand to the little endian
one. Use the latter which is more explicit.
Mechanical change running:
$ sed -i -e s/MO_TE/MO_LE/ \
$(git grep -wl MO_TE target/riscv/)
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-15-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/internals.h | 2 +-
target/riscv/translate.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 860c47732b..460346dd6d 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -71,7 +71,7 @@ static inline MemOp mo_endian_env(CPURISCVState *env)
* - MSTATUS_MBE (Machine-mode)
* but we don't implement that yet.
*/
- return MO_TE;
+ return MO_LE;
}
/* share data between vector helpers and decode code */
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 711080f3fd..1a25c517a2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -135,7 +135,7 @@ static inline MemOp mo_endian(DisasContext *ctx)
* - MSTATUS_MBE (Machine-mode)
* but we don't implement that yet.
*/
- return MO_TE;
+ return MO_LE;
}
#ifdef TARGET_RISCV32
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 18/51] target/riscv: Use MO_LE for instruction fetch
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (16 preceding siblings ...)
2026-04-29 4:47 ` [PULL 17/51] target/riscv: Replace MO_TE -> MO_LE alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 19/51] configs/targets: Forbid RISC-V to use legacy native endianness APIs alistair23
` (33 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Djordje Todorovic, Alistair Francis,
Philippe Mathieu-Daudé
From: Djordje Todorovic <Djordje.Todorovic@htecgroup.com>
RISC-V instructions are always little-endian regardless of the data
endianness mode configured via mstatus SBE/MBE/UBE bits.
Currently, instruction fetches in decode_opc() and the page boundary
check use mo_endian(ctx), which returns MO_TE. This happens to work
today because RISC-V targets are little-endian only, but is
semantically incorrect and will break once mo_endian() is updated to
respect runtime data endianness for big-endian support.
Use MO_LE explicitly for all instruction fetch paths. Data memory
operations (AMOs, loads/stores via mxl_memop) continue to use
mo_endian(ctx) as they should respect the configured data endianness.
Not-Signed-off-by: Djordje Todorovic <Djordje.Todorovic@htecgroup.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260311115910.564481-3-djordje.todorovic@htecgroup.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20260318103122.97244-16-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1a25c517a2..f6b915a7fb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1258,7 +1258,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
* additional page fault.
*/
opcode = translator_ldl_end(env, &ctx->base, ctx->base.pc_next,
- mo_endian(ctx));
+ MO_LE);
} else {
/*
* For unaligned pc, instruction preload may trigger additional
@@ -1266,7 +1266,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
*/
opcode = (uint32_t) translator_lduw_end(env, &ctx->base,
ctx->base.pc_next,
- mo_endian(ctx));
+ MO_LE);
}
ctx->ol = ctx->xl;
@@ -1288,7 +1288,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
opcode = deposit32(opcode, 16, 16,
translator_lduw_end(env, &ctx->base,
ctx->base.pc_next + 2,
- mo_endian(ctx)));
+ MO_LE));
}
ctx->opcode = opcode;
@@ -1404,7 +1404,7 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
if (page_ofs > TARGET_PAGE_SIZE - MAX_INSN_LEN) {
uint16_t next_insn =
translator_lduw_end(env, &ctx->base, ctx->base.pc_next,
- mo_endian(ctx));
+ MO_LE);
int len = insn_len(next_insn);
if (!translator_is_same_page(&ctx->base, ctx->base.pc_next + len - 1)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 19/51] configs/targets: Forbid RISC-V to use legacy native endianness APIs
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (17 preceding siblings ...)
2026-04-29 4:47 ` [PULL 18/51] target/riscv: Use MO_LE for instruction fetch alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 20/51] hw/riscv/riscv-iommu-hpm: Fix irq_overflow_left residual value bug alistair23
` (32 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis
From: Philippe Mathieu-Daudé <philmd@linaro.org>
All RISC-V related binaries are buildable without a single
use of the legacy "native endian" API. Set the transitional
TARGET_USE_LEGACY_NATIVE_ENDIAN_API definition to forbid
further uses of the legacy API.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260318103122.97244-17-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
configs/targets/riscv32-linux-user.mak | 1 +
configs/targets/riscv32-softmmu.mak | 1 +
configs/targets/riscv64-bsd-user.mak | 1 +
configs/targets/riscv64-linux-user.mak | 1 +
configs/targets/riscv64-softmmu.mak | 1 +
5 files changed, 5 insertions(+)
diff --git a/configs/targets/riscv32-linux-user.mak b/configs/targets/riscv32-linux-user.mak
index f069ab9a0f..d88fdf5e1b 100644
--- a/configs/targets/riscv32-linux-user.mak
+++ b/configs/targets/riscv32-linux-user.mak
@@ -8,3 +8,4 @@ TARGET_SYSTBL_ABI=32
TARGET_SYSTBL_ABI=common,32,riscv,memfd_secret
TARGET_SYSTBL=syscall.tbl
TARGET_LONG_BITS=32
+TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv32-softmmu.mak b/configs/targets/riscv32-softmmu.mak
index 26080599be..5d5016d008 100644
--- a/configs/targets/riscv32-softmmu.mak
+++ b/configs/targets/riscv32-softmmu.mak
@@ -5,3 +5,4 @@ TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml ri
TARGET_NEED_FDT=y
TARGET_LONG_BITS=32
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
+TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv64-bsd-user.mak b/configs/targets/riscv64-bsd-user.mak
index bc85d9ed04..5b4e138099 100644
--- a/configs/targets/riscv64-bsd-user.mak
+++ b/configs/targets/riscv64-bsd-user.mak
@@ -3,3 +3,4 @@ TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml
TARGET_LONG_BITS=64
+TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv64-linux-user.mak b/configs/targets/riscv64-linux-user.mak
index bca0864512..35621520c5 100644
--- a/configs/targets/riscv64-linux-user.mak
+++ b/configs/targets/riscv64-linux-user.mak
@@ -8,3 +8,4 @@ TARGET_SYSTBL_ABI=64
TARGET_SYSTBL_ABI=common,64,riscv,rlimit,memfd_secret
TARGET_SYSTBL=syscall.tbl
TARGET_LONG_BITS=64
+TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv64-softmmu.mak b/configs/targets/riscv64-softmmu.mak
index 5059c55048..a10dc03c04 100644
--- a/configs/targets/riscv64-softmmu.mak
+++ b/configs/targets/riscv64-softmmu.mak
@@ -6,3 +6,4 @@ TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml ri
TARGET_NEED_FDT=y
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
+TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 20/51] hw/riscv/riscv-iommu-hpm: Fix irq_overflow_left residual value bug
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (18 preceding siblings ...)
2026-04-29 4:47 ` [PULL 19/51] configs/targets: Forbid RISC-V to use legacy native endianness APIs alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 21/51] hw/riscv/riscv-iommu: Add IPSR.PMIP RW1C support alistair23
` (31 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Jay Chang, Frank Chang, Alistair Francis
From: Jay Chang <jay.chang@sifive.com>
Reset irq_overflow_left to 0 before setting up a new timer. Without
this fix, a stale irq_overflow_left value from a previous timer setup
could cause incorrect timer behavior.
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260325050011.66722-2-jay.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/riscv-iommu-hpm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/riscv/riscv-iommu-hpm.c b/hw/riscv/riscv-iommu-hpm.c
index c5034bff79..e8d284ac8b 100644
--- a/hw/riscv/riscv-iommu-hpm.c
+++ b/hw/riscv/riscv-iommu-hpm.c
@@ -228,6 +228,7 @@ static void hpm_setup_timer(RISCVIOMMUState *s, uint64_t value)
}
overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + overflow_ns;
+ s->irq_overflow_left = 0;
if (overflow_at > INT64_MAX) {
s->irq_overflow_left = overflow_at - INT64_MAX;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 21/51] hw/riscv/riscv-iommu: Add IPSR.PMIP RW1C support
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (19 preceding siblings ...)
2026-04-29 4:47 ` [PULL 20/51] hw/riscv/riscv-iommu-hpm: Fix irq_overflow_left residual value bug alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 22/51] hw/riscv/virt-acpi-build.c: Use kvm timer frequency when kvm enabled alistair23
` (30 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Jay Chang, Frank Chang, Nutty Liu, Alistair Francis
From: Jay Chang <jay.chang@sifive.com>
Add proper RW1C (Read/Write 1 to Clear) support for the IPSR.PMIP
(Performance Monitor Interrupt Pending) bit, which was missing from
the IPSR register implementation.
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260325050011.66722-3-jay.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/riscv-iommu-bits.h | 1 +
hw/riscv/riscv-iommu.c | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
index 47fe01bee5..a938fd3eb4 100644
--- a/hw/riscv/riscv-iommu-bits.h
+++ b/hw/riscv/riscv-iommu-bits.h
@@ -189,6 +189,7 @@ enum riscv_iommu_ddtp_modes {
#define RISCV_IOMMU_REG_IPSR 0x0054
#define RISCV_IOMMU_IPSR_CIP BIT(0)
#define RISCV_IOMMU_IPSR_FIP BIT(1)
+#define RISCV_IOMMU_IPSR_PMIP BIT(2)
#define RISCV_IOMMU_IPSR_PIP BIT(3)
enum {
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 8476405d0e..7ba3240552 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -2150,6 +2150,10 @@ static void riscv_iommu_update_ipsr(RISCVIOMMUState *s, uint64_t data)
ipsr_clr |= RISCV_IOMMU_IPSR_FIP;
}
+ if (!(data & RISCV_IOMMU_IPSR_PMIP)) {
+ ipsr_clr |= RISCV_IOMMU_IPSR_PMIP;
+ }
+
if (data & RISCV_IOMMU_IPSR_PIP) {
pqcsr = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_PQCSR);
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 22/51] hw/riscv/virt-acpi-build.c: Use kvm timer frequency when kvm enabled
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (20 preceding siblings ...)
2026-04-29 4:47 ` [PULL 21/51] hw/riscv/riscv-iommu: Add IPSR.PMIP RW1C support alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 23/51] target/riscv: fix stale ptshift and base on page walk restart alistair23
` (29 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Yicong Yang, Andrew Jones, Alistair Francis
From: Yicong Yang <yang.yicong@picoheart.com>
The timer frequency is decided by the host(kvm) rather than a fixed
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ on kvm accelerated VM. So build
RCHT with KVM provided timer frequency if KVM is enabled, just like
how we build the timer node on DT based VM.
Fixes: ebfd39289370 ("hw/riscv/virt: virt-acpi-build.c: Add RHCT Table")
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
Reviewed-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
Message-ID: <20260325081314.57089-1-yang.yicong@picoheart.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/virt-acpi-build.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index f1406cb683..fd6ca5dbc4 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -35,9 +35,11 @@
#include "hw/riscv/virt.h"
#include "hw/riscv/numa.h"
#include "hw/virtio/virtio-acpi.h"
+#include "kvm/kvm_riscv.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "system/kvm.h"
#include "system/reset.h"
#define ACPI_BUILD_TABLE_SIZE 0x20000
@@ -296,7 +298,10 @@ static void build_rhct(GArray *table_data,
/* Time Base Frequency */
build_append_int_noprefix(table_data,
- RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, 8);
+ kvm_enabled() ?
+ kvm_riscv_get_timebase_frequency(&s->soc->harts[0]) :
+ RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ,
+ 8);
/* ISA + N hart info */
num_rhct_nodes = 1 + ms->smp.cpus;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 23/51] target/riscv: fix stale ptshift and base on page walk restart
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (21 preceding siblings ...)
2026-04-29 4:47 ` [PULL 22/51] hw/riscv/virt-acpi-build.c: Use kvm timer frequency when kvm enabled alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 24/51] hw/intc: fix heap OOB in ACLINT MTIMER multi-socket alistair23
` (28 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Sebastián Alba Vives, Alistair Francis
From: Sebastián Alba Vives <sebasjosue84@gmail.com>
When the atomic compare-and-swap for updating A/D bits in the page
table entry fails due to a concurrent PTE modification by another
vCPU, get_physical_address() jumps to the 'restart' label to re-walk
the page table from the root.
However, neither 'ptshift' nor 'base' are re-initialized before the
restart. After the walk completes, ptshift has been decremented to
its final value and base has been overwritten with an inner PTE PPN.
On goto restart, the for loop resets i=0 but ptshift and base remain
stale, causing the restarted walk to compute incorrect PTE addresses.
In an SMP guest with MTTCG and Svadu active, this can result in
incorrect physical address mappings or guest crashes.
Fix by saving the root base address and re-initializing both ptshift
and base on each restart.
Fixes: 0c3e702aca ("RISC-V CPU Helpers")
Signed-off-by: Sebastián Alba Vives <sebasjosue84@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260401053853.10473-1-sebasjosue84@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_helper.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c28832e0e3..659150c646 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1316,12 +1316,15 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
adue = adue && (env->henvcfg & HENVCFG_ADUE);
}
- int ptshift = (levels - 1) * ptidxbits;
+ int ptshift;
target_ulong pte;
hwaddr pte_addr;
+ const hwaddr base_root = base;
int i;
restart:
+ ptshift = (levels - 1) * ptidxbits;
+ base = base_root;
for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
target_ulong idx;
if (i == 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 24/51] hw/intc: fix heap OOB in ACLINT MTIMER multi-socket
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (22 preceding siblings ...)
2026-04-29 4:47 ` [PULL 23/51] target/riscv: fix stale ptshift and base on page walk restart alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin) alistair23
` (27 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Sebastián Alba Vives, qemu-security,
Alistair Francis
From: Sebastián Alba Vives <sebasjosue84@gmail.com>
The MMIO read/write handlers index timecmp[] with the absolute hartid
(hartid_base + offset) but the array is allocated with num_harts
elements. In multi-socket configurations with hartid_base > 0 this
causes heap OOB access in the QEMU process.
Fix by using the relative offset for array indexing.
Cc: qemu-security@nongnu.org
Signed-off-by: Sebastián Alba Vives <sebasjosue84@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260401053853.10473-2-sebasjosue84@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/intc/riscv_aclint.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index 9c1491bd04..e27e5fb394 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -131,6 +131,7 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
size_t hartid = mtimer->hartid_base +
((addr - mtimer->timecmp_base) >> 3);
+ size_t hartid_offset = hartid - mtimer->hartid_base;
CPUState *cpu = cpu_by_arch_id(hartid);
CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
if (!env) {
@@ -138,11 +139,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
"aclint-mtimer: invalid hartid: %zu", hartid);
} else if ((addr & 0x7) == 0) {
/* timecmp_lo for RV32/RV64 or timecmp for RV64 */
- uint64_t timecmp = mtimer->timecmp[hartid];
+ uint64_t timecmp = mtimer->timecmp[hartid_offset];
return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
} else if ((addr & 0x7) == 4) {
/* timecmp_hi */
- uint64_t timecmp = mtimer->timecmp[hartid];
+ uint64_t timecmp = mtimer->timecmp[hartid_offset];
return (timecmp >> 32) & 0xFFFFFFFF;
} else {
qemu_log_mask(LOG_UNIMP,
@@ -174,6 +175,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
size_t hartid = mtimer->hartid_base +
((addr - mtimer->timecmp_base) >> 3);
+ size_t hartid_offset = hartid - mtimer->hartid_base;
CPUState *cpu = cpu_by_arch_id(hartid);
CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
if (!env) {
@@ -182,7 +184,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
} else if ((addr & 0x7) == 0) {
if (size == 4) {
/* timecmp_lo for RV32/RV64 */
- uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32;
+ uint64_t timecmp_hi = mtimer->timecmp[hartid_offset] >> 32;
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
timecmp_hi << 32 | (value & 0xFFFFFFFF));
} else {
@@ -193,7 +195,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
} else if ((addr & 0x7) == 4) {
if (size == 4) {
/* timecmp_hi for RV32/RV64 */
- uint64_t timecmp_lo = mtimer->timecmp[hartid];
+ uint64_t timecmp_lo = mtimer->timecmp[hartid_offset];
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
value << 32 | (timecmp_lo & 0xFFFFFFFF));
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin)
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (23 preceding siblings ...)
2026-04-29 4:47 ` [PULL 24/51] hw/intc: fix heap OOB in ACLINT MTIMER multi-socket alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-30 18:14 ` Michael Tokarev
2026-04-29 4:47 ` [PULL 26/51] target/riscv: preserve RV32 henvcfgh on henvcfg writes alistair23
` (26 subsequent siblings)
51 siblings, 1 reply; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Munkhbaatar Enkhbaatar, Alistair Francis, Tao Tang,
Philippe Mathieu-Daudé
From: Munkhbaatar Enkhbaatar <munkhuu0825@gmail.com>
Prevents huge allocations and crashes caused by malformed HTIF signature
addresses.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3205
Signed-off-by: Munkhbaatar Enkhbaatar <munkhuu0825@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20251209085349.61510-1-munkhuu0825@gmail.com>
[ Squashed with following commit to fix build failures
hw/char/riscv_htif: Fix format specifier for uint64_t
Message-ID: <20260415134826.1742308-1-chao.liu.zevorn@gmail.com>
Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
]
Tested-by: Tao Tang <tangtao1634@phytium.com.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/char/riscv_htif.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
index e9efab16e9..a53d2ace02 100644
--- a/hw/char/riscv_htif.c
+++ b/hw/char/riscv_htif.c
@@ -171,6 +171,12 @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
* begin/end_signature symbols exist.
*/
if (sig_file && begin_sig_addr && end_sig_addr) {
+ if (end_sig_addr <= begin_sig_addr) {
+ error_report("Invalid HTIF signature range:"
+ " begin=0x%" PRIx64 " end=0x%" PRIx64,
+ begin_sig_addr, end_sig_addr);
+ return;
+ }
uint64_t sig_len = end_sig_addr - begin_sig_addr;
char *sig_data = g_malloc(sig_len);
dma_memory_read(&address_space_memory, begin_sig_addr,
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 26/51] target/riscv: preserve RV32 henvcfgh on henvcfg writes
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (24 preceding siblings ...)
2026-04-29 4:47 ` [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin) alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 27/51] target/riscv: Add cfg properties for Zvfbfa extensions alistair23
` (25 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Bruno Sa, Alistair Francis
From: Bruno Sa <bruno.vilaca.sa@gmail.com>
On RV32, STCE/ADUE/PBMTE/DTE are implemented in henvcfgh. A write to
henvcfg should therefore only update the low 32 bits of env->henvcfg.
The current write_henvcfg() path overwrites env->henvcfg with the
low-half value and clears any bits previously written via henvcfgh.
Preserve the upper 32 bits on RV32 henvcfg writes and keep the existing
RV64 behaviour unchanged.
Signed-off-by: Bruno Sa <bruno.vilaca.sa@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260409155344.2849233-2-bruno.vilaca.sa@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a75281539b..cfd076b368 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3353,7 +3353,15 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
}
}
- env->henvcfg = val & mask;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ /*
+ * RV32 stores STCE/ADUE/PBMTE/DTE in henvcfgh, so a low-half henvcfg
+ * write must not clobber the upper 32 bits.
+ */
+ env->henvcfg = (env->henvcfg & ~0xFFFFFFFFULL) | (val & mask);
+ } else {
+ env->henvcfg = val & mask;
+ }
if ((env->henvcfg & HENVCFG_DTE) == 0) {
env->vsstatus &= ~MSTATUS_SDT;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 27/51] target/riscv: Add cfg properties for Zvfbfa extensions
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (25 preceding siblings ...)
2026-04-29 4:47 ` [PULL 26/51] target/riscv: preserve RV32 henvcfgh on henvcfg writes alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 28/51] target/riscv: Add the Zvfbfa extension implied rule alistair23
` (24 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Daniel Henrique Barboza, Nutty Liu,
Alistair Francis
From: Max Chou <max.chou@sifive.com>
The Zvfbfa extension adds more complete BF16 vector compute support
and requires the Zve32f and Zfbfmin extensions.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-2-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg_fields.h.inc | 1 +
target/riscv/cpu.c | 1 +
target/riscv/tcg/tcg-cpu.c | 8 ++++++++
3 files changed, 10 insertions(+)
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index d4b7c880d4..734fa079f2 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -100,6 +100,7 @@ BOOL_FIELD(ext_zvks)
BOOL_FIELD(ext_zvksc)
BOOL_FIELD(ext_zvksg)
BOOL_FIELD(ext_zmmul)
+BOOL_FIELD(ext_zvfbfa)
BOOL_FIELD(ext_zvfbfmin)
BOOL_FIELD(ext_zvfbfwma)
BOOL_FIELD(ext_zvfh)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 03a1bb075a..7c652dea78 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -189,6 +189,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
+ ISA_EXT_DATA_ENTRY(zvfbfa, PRIV_VERSION_1_13_0, ext_zvfbfa),
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 3407191c22..c4f7da7193 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -720,6 +720,14 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
return;
}
+ if (cpu->cfg.ext_zvfbfa) {
+ if (!cpu->cfg.ext_zve32f || !cpu->cfg.ext_zfbfmin) {
+ error_setg(errp, "Zvfbfa extension requires Zve32f extension "
+ "and Zfbfmin extension");
+ return;
+ }
+ }
+
if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 28/51] target/riscv: Add the Zvfbfa extension implied rule
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (26 preceding siblings ...)
2026-04-29 4:47 ` [PULL 27/51] target/riscv: Add cfg properties for Zvfbfa extensions alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 29/51] target/riscv: rvv: Add new VTYPE CSR field - altfmt alistair23
` (23 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Daniel Henrique Barboza, Nutty Liu,
Alistair Francis
From: Max Chou <max.chou@sifive.com>
According to the Zvfbfa isa spec:
The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-3-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c652dea78..bbab96385b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2622,6 +2622,15 @@ static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = {
},
};
+static RISCVCPUImpliedExtsRule ZVFBFA_IMPLIED = {
+ .ext = CPU_CFG_OFFSET(ext_zvfbfa),
+ .implied_multi_exts = {
+ CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zfbfmin),
+
+ RISCV_IMPLIED_EXTS_RULE_END
+ },
+};
+
RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
&RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
&RVM_IMPLIED, &RVV_IMPLIED, NULL
@@ -2635,8 +2644,8 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
&ZHINX_IMPLIED, &ZHINXMIN_IMPLIED, &ZICNTR_IMPLIED,
&ZIHPM_IMPLIED, &ZK_IMPLIED, &ZKN_IMPLIED,
&ZKS_IMPLIED, &ZVBB_IMPLIED, &ZVE32F_IMPLIED,
- &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED,
- &ZVE64X_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
+ &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED, &ZVE64X_IMPLIED,
+ &ZVFBFA_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
&ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
&ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
&ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 29/51] target/riscv: rvv: Add new VTYPE CSR field - altfmt
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (27 preceding siblings ...)
2026-04-29 4:47 ` [PULL 28/51] target/riscv: Add the Zvfbfa extension implied rule alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 30/51] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR alistair23
` (22 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Daniel Henrique Barboza, Nutty Liu,
Alistair Francis
From: Max Chou <max.chou@sifive.com>
According to the Zvfbfa ISA spec v0.1, the vtype CSR adds a new field:
altfmt for BF16 support.
This update changes the layout of the vtype CSR fields.
- Removed VEDIV field (bits 8-9) since EDIV extension is not planned to
be part of the base V extension
- Added ALTFMT field at bit 8
- Changed RESERVED field to start from bit 9 instead of bit 10
When Zvfbfa is disabled, bits 8+ are treated as reserved (preserving
existing behavior for altfmt bit). When Zvfbfa is enabled, only bits 9+
are reserved.
Reference:
- https://github.com/riscvarchive/riscv-v-spec/blob/master/ediv.adoc
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-4-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 4 ++--
target/riscv/vector_helper.c | 39 +++++++++++++++++++++++++++++++-----
2 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 35d1f6362c..962cc45073 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -191,8 +191,8 @@ FIELD(VTYPE, VLMUL, 0, 3)
FIELD(VTYPE, VSEW, 3, 3)
FIELD(VTYPE, VTA, 6, 1)
FIELD(VTYPE, VMA, 7, 1)
-FIELD(VTYPE, VEDIV, 8, 2)
-FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
+FIELD(VTYPE, ALTFMT, 8, 1)
+FIELD(VTYPE, RESERVED, 9, sizeof(target_ulong) * 8 - 10)
typedef struct PMUCTRState {
/* Current value of a counter */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 83dd26314d..63ca6fe16b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -33,6 +33,22 @@
#include "vector_internals.h"
#include <math.h>
+static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
+{
+ int xlen = riscv_cpu_xlen(env);
+ target_ulong reserved = 0;
+
+ if (riscv_cpu_cfg(env)->ext_zvfbfa) {
+ reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
+ xlen - 1 - R_VTYPE_RESERVED_SHIFT);
+ } else {
+ reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_ALTFMT_SHIFT,
+ xlen - 1 - R_VTYPE_ALTFMT_SHIFT);
+ }
+
+ return reserved;
+}
+
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
target_ulong s2, target_ulong x0)
{
@@ -41,12 +57,10 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
uint16_t sew = 8 << vsew;
- uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
+ uint8_t altfmt = FIELD_EX64(s2, VTYPE, ALTFMT);
+ bool ill_altfmt = true;
int xlen = riscv_cpu_xlen(env);
bool vill = (s2 >> (xlen - 1)) & 0x1;
- target_ulong reserved = s2 &
- MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
- xlen - 1 - R_VTYPE_RESERVED_SHIFT);
uint16_t vlen = cpu->cfg.vlenb << 3;
int8_t lmul;
@@ -63,7 +77,22 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
}
}
- if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+ switch (vsew) {
+ case MO_8:
+ ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
+ break;
+ case MO_16:
+ ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
+ break;
+ default:
+ break;
+ }
+
+ if (altfmt && ill_altfmt) {
+ vill = true;
+ }
+
+ if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
/* only set vill bit. */
env->vill = 1;
env->vtype = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 30/51] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (28 preceding siblings ...)
2026-04-29 4:47 ` [PULL 29/51] target/riscv: rvv: Add new VTYPE CSR field - altfmt alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 31/51] target/riscv: Use the tb->cs_base as the extend tb flags alistair23
` (21 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis, Nutty Liu
From: Max Chou <max.chou@sifive.com>
Replace the same vill reset flow by reset_ill_vtype function.
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-5-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/vector_helper.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 63ca6fe16b..1e0cce5ae5 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -49,6 +49,15 @@ static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
return reserved;
}
+static inline void reset_ill_vtype(CPURISCVState *env)
+{
+ /* only set vill bit. */
+ env->vill = 1;
+ env->vtype = 0;
+ env->vl = 0;
+ env->vstart = 0;
+}
+
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
target_ulong s2, target_ulong x0)
{
@@ -93,11 +102,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
}
if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
- /* only set vill bit. */
- env->vill = 1;
- env->vtype = 0;
- env->vl = 0;
- env->vstart = 0;
+ reset_ill_vtype(env);
return 0;
}
@@ -113,11 +118,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
}
if (cpu->cfg.rvv_vsetvl_x0_vill && x0 && (env->vl != vl)) {
- /* only set vill bit. */
- env->vill = 1;
- env->vtype = 0;
- env->vl = 0;
- env->vstart = 0;
+ reset_ill_vtype(env);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 31/51] target/riscv: Use the tb->cs_base as the extend tb flags
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (29 preceding siblings ...)
2026-04-29 4:47 ` [PULL 30/51] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 32/51] target/riscv: Introduce altfmt into DisasContext alistair23
` (20 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
We have more than 32-bits worth of state per TB, so use the
tb->cs_base, which is otherwise unused for RISC-V, as the extend flag.
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-6-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/exec/translation-block.h | 1 +
target/riscv/cpu.h | 3 +++
target/riscv/tcg/tcg-cpu.c | 7 ++++++-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
index 4f83d5bec9..40cc699031 100644
--- a/include/exec/translation-block.h
+++ b/include/exec/translation-block.h
@@ -65,6 +65,7 @@ struct TranslationBlock {
* arm: an extension of tb->flags,
* s390x: instruction data for EXECUTE,
* sparc: the next pc of the instruction queue (for delay slots).
+ * riscv: an extension of tb->flags,
*/
uint64_t cs_base;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 962cc45073..4c0676ed53 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -703,6 +703,9 @@ FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1)
FIELD(TB_FLAGS, PM_PMM, 29, 2)
FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1)
+FIELD(EXT_TB_FLAGS, MISA_EXT, 0, 32)
+FIELD(EXT_TB_FLAGS, ALTFMT, 32, 1)
+
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
#else
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index c4f7da7193..f3f7808895 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -104,6 +104,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
RISCVCPU *cpu = env_archcpu(env);
RISCVExtStatus fs, vs;
uint32_t flags = 0;
+ uint64_t ext_flags = 0;
bool pm_signext = riscv_cpu_virt_mem_enabled(env);
if (cpu->cfg.ext_zve32x) {
@@ -118,6 +119,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
/* lmul encoded as in DisasContext::lmul */
int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
+ uint8_t altfmt = FIELD_EX64(env->vtype, VTYPE, ALTFMT);
uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
uint32_t maxsz = vlmax << vsew;
@@ -133,6 +135,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
flags = FIELD_DP32(flags, TB_FLAGS, VMA,
FIELD_EX64(env->vtype, VTYPE, VMA));
flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0);
+ ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, ALTFMT, altfmt);
} else {
flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
}
@@ -189,10 +192,12 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env));
flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext);
+ ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, MISA_EXT, env->misa_ext);
+
return (TCGTBCPUState){
.pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
.flags = flags,
- .cs_base = env->misa_ext,
+ .cs_base = ext_flags,
};
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 32/51] target/riscv: Introduce altfmt into DisasContext
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (30 preceding siblings ...)
2026-04-29 4:47 ` [PULL 31/51] target/riscv: Use the tb->cs_base as the extend tb flags alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 33/51] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension alistair23
` (19 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-7-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f6b915a7fb..f8ccf34438 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -101,6 +101,7 @@ typedef struct DisasContext {
bool cfg_vta_all_1s;
bool vstart_eq_zero;
bool vl_eq_vlmax;
+ bool altfmt;
CPUState *cs;
TCGv zero;
/* actual address width */
@@ -1310,6 +1311,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
RISCVCPU *cpu = RISCV_CPU(cs);
uint32_t tb_flags = ctx->base.tb->flags;
+ uint64_t ext_tb_flags = ctx->base.tb->cs_base;
ctx->pc_save = ctx->base.pc_first;
ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
@@ -1329,6 +1331,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
+ ctx->altfmt = FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, ALTFMT);
ctx->misa_mxl_max = mcc->def->misa_mxl_max;
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 33/51] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (31 preceding siblings ...)
2026-04-29 4:47 ` [PULL 32/51] target/riscv: Introduce altfmt into DisasContext alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 34/51] target/riscv: rvv: Support Zvfbfa vector bf16 operations alistair23
` (18 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
According to the Zvfbfa ISA spec (v0.1), improperly NaN-boxed
f-register operands must substitute the BF16 canonical NaN instead of
the FP16 canonical NaN for some vector floating-point instructions.
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-8-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 8 ++++++++
target/riscv/insn_trans/trans_rvv.c.inc | 18 +++++++++---------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f8ccf34438..1e4f340256 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -214,6 +214,14 @@ static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
}
+static void gen_check_nanbox_h_bf16(TCGv_i64 out, TCGv_i64 in)
+{
+ TCGv_i64 t_max = tcg_constant_i64(0xffffffffffff0000ull);
+ TCGv_i64 t_nan = tcg_constant_i64(0xffffffffffff7fc0ull);
+
+ tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
+}
+
static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
{
TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 4df9a40b44..03ae85796a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2319,17 +2319,17 @@ GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx)
*/
static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
{
- switch (s->sew) {
- case 1:
- gen_check_nanbox_h(out, in);
- break;
- case 2:
+ if (s->sew == MO_16) {
+ if (s->altfmt) {
+ gen_check_nanbox_h_bf16(out, in);
+ } else {
+ gen_check_nanbox_h(out, in);
+ }
+ } else if (s->sew == MO_32) {
gen_check_nanbox_s(out, in);
- break;
- case 3:
+ } else if (s->sew == MO_64) {
tcg_gen_mov_i64(out, in);
- break;
- default:
+ } else {
g_assert_not_reached();
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 34/51] target/riscv: rvv: Support Zvfbfa vector bf16 operations
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (32 preceding siblings ...)
2026-04-29 4:47 ` [PULL 33/51] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 35/51] target/riscv: Expose Zvfbfa extension as a cpu property alistair23
` (17 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
According to the Zvfbfa ISA spec v0.1, the following vector floating
point instructions have different behaviors depend on the ALTFMT and
VSEW fields of VTYPE CSR.
When altfmt=1 and SEW=8, all vector floating-point instructions become
reserved, except for the following, which are redefined to use the
BF16 format for any operand that would otherwise have used the FP16
format:
- vfwcvt.f.x[u].v, vfncvt.x[u].f.w, vfncvt.rtz.x[u].f.w
When altfmt=1 and SEW=16, all vector floating-point instructions become
reserved, except for the following, which are redefined to use the
BF16 format for any operand that would otherwise have used the FP16
format:
- vfadd.v[vf], vfsub.v[vf], vfmin.v[vf], vfmax.v[vf], vmfeq.v[vf],
vmfle.v[vf], vmflt.v[vf], vmfne.v[vf], vmfgt.vf, vmfge.vf,
vfmul.v[vf], vfrsub.vf, vfmadd.v[vf], vfnmadd.v[vf], vfmsub.v[vf],
vfnmsub.v[vf], vfmacc.v[vf], vfnmacc.v[vf], vfmsac.v[vf],
vfnmsac.v[vf], vfwadd.v[vf], vfwsub.v[vf], vfwadd.w[vf],
vfwsub.w[vf], vfwmul.v[vf], vfwmacc.v[vf], vfwnmacc.v[vf],
vfwmsac.v[vf], vfwnmsac.v[vf], vfwcvt.f.f.v, vfncvt.f.f.w,
vfncvt.rod.f.f.w, vfrsqrt7.v, vfrec7.v, vfclass.v
The following instructions marked with * have the same semantics
regardless of altfmt.
*- vfmv.f.s,
vfwmaccbf16.v[vf] (only if Zvfbfwma is implemented)
vfwcvtbf16.f.f.v (only if Zvfbfmin is implemented)
vfncvtbf16.f.f.w (only if Zvfbfmin is implemented)
The following instructions marked with ** differ only in that
improperly NaN-boxed f-register operands must substitute the BF16
canonical NaN instead of the FP16 canonical NaN.
**- vfsgnj.v[vf], vfsgnjn.v[vf], vfsgnjx.v[vf], vfslide1up.vf,
vfslide1down.vf, vfmv.v.f, vfmerge.vfm, vfmv.s.f
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-9-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/helper.h | 60 ++
target/riscv/internals.h | 1 +
target/riscv/vector_helper.c | 329 ++++++++
target/riscv/insn_trans/trans_rvv.c.inc | 970 +++++++++++++++---------
4 files changed, 989 insertions(+), 371 deletions(-)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 7722c590bd..54d2331966 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -768,45 +768,60 @@ DEF_HELPER_6(vnclip_wx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vnclip_wx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vnclip_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vfadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfrsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwadd_wv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwsub_wv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwadd_wf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwadd_wf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwsub_wf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmul_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmul_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmul_vf_d, void, ptr, ptr, i64, ptr, env, i32)
@@ -817,74 +832,98 @@ DEF_HELPER_6(vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwmul_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwmul_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwnmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwnmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfwmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwnmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwnmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
@@ -892,23 +931,29 @@ DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrsqrt7_v_h_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrec7_v_h_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrec7_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrec7_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfrec7_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmin_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmax_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmax_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmax_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vfmax_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmin_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmin_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmin_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmin_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmax_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmax_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmax_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfmax_vf_d, void, ptr, ptr, i64, ptr, env, i32)
@@ -932,37 +977,48 @@ DEF_HELPER_6(vfsgnjx_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfsgnjx_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfsgnjx_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfeq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfeq_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfeq_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfne_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfne_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfne_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfne_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmflt_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmflt_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmflt_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmflt_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfle_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfle_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfle_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vmfle_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfeq_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfeq_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfeq_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfne_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfne_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfne_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfne_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmflt_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmflt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmflt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmflt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfle_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfle_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfle_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfle_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfgt_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfgt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfgt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfge_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_5(vfclass_v_h_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
@@ -989,18 +1045,22 @@ DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_b_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_b_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_xu_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_b_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_xu_f_w_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_xu_f_w_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_x_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_b_bf16, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_x_f_w_h, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_x_f_w_w, void, ptr, ptr, ptr, env, i32)
DEF_HELPER_5(vfncvt_f_xu_w_h, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 460346dd6d..b001cbc080 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -84,6 +84,7 @@ FIELD(VDATA, NF, 7, 4)
FIELD(VDATA, WD, 7, 1)
/* float point classify helpers */
+target_ulong fclass_h_bf16(uint64_t frs1);
target_ulong fclass_h(uint64_t frs1);
target_ulong fclass_s(uint64_t frs1);
target_ulong fclass_d(uint64_t frs1);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 1e0cce5ae5..538168efc9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3168,9 +3168,11 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
total_elems * ESZ); \
}
+RVVCALL(OPFVV2, vfadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_add)
RVVCALL(OPFVV2, vfadd_vv_h, OP_UUU_H, H2, H2, H2, float16_add)
RVVCALL(OPFVV2, vfadd_vv_w, OP_UUU_W, H4, H4, H4, float32_add)
RVVCALL(OPFVV2, vfadd_vv_d, OP_UUU_D, H8, H8, H8, float64_add)
+GEN_VEXT_VV_ENV(vfadd_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfadd_vv_h, 2)
GEN_VEXT_VV_ENV(vfadd_vv_w, 4)
GEN_VEXT_VV_ENV(vfadd_vv_d, 8)
@@ -3213,26 +3215,37 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \
total_elems * ESZ); \
}
+RVVCALL(OPFVF2, vfadd_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_add)
RVVCALL(OPFVF2, vfadd_vf_h, OP_UUU_H, H2, H2, float16_add)
RVVCALL(OPFVF2, vfadd_vf_w, OP_UUU_W, H4, H4, float32_add)
RVVCALL(OPFVF2, vfadd_vf_d, OP_UUU_D, H8, H8, float64_add)
+GEN_VEXT_VF(vfadd_vf_h_bf16, 2)
GEN_VEXT_VF(vfadd_vf_h, 2)
GEN_VEXT_VF(vfadd_vf_w, 4)
GEN_VEXT_VF(vfadd_vf_d, 8)
+RVVCALL(OPFVV2, vfsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_sub)
RVVCALL(OPFVV2, vfsub_vv_h, OP_UUU_H, H2, H2, H2, float16_sub)
RVVCALL(OPFVV2, vfsub_vv_w, OP_UUU_W, H4, H4, H4, float32_sub)
RVVCALL(OPFVV2, vfsub_vv_d, OP_UUU_D, H8, H8, H8, float64_sub)
+GEN_VEXT_VV_ENV(vfsub_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfsub_vv_h, 2)
GEN_VEXT_VV_ENV(vfsub_vv_w, 4)
GEN_VEXT_VV_ENV(vfsub_vv_d, 8)
+RVVCALL(OPFVF2, vfsub_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_sub)
RVVCALL(OPFVF2, vfsub_vf_h, OP_UUU_H, H2, H2, float16_sub)
RVVCALL(OPFVF2, vfsub_vf_w, OP_UUU_W, H4, H4, float32_sub)
RVVCALL(OPFVF2, vfsub_vf_d, OP_UUU_D, H8, H8, float64_sub)
+GEN_VEXT_VF(vfsub_vf_h_bf16, 2)
GEN_VEXT_VF(vfsub_vf_h, 2)
GEN_VEXT_VF(vfsub_vf_w, 4)
GEN_VEXT_VF(vfsub_vf_d, 8)
+static uint16_t bfloat16_rsub(uint16_t a, uint16_t b, float_status * s)
+{
+ return bfloat16_sub(b, a, s);
+}
+
static uint16_t float16_rsub(uint16_t a, uint16_t b, float_status *s)
{
return float16_sub(b, a, s);
@@ -3248,14 +3261,22 @@ static uint64_t float64_rsub(uint64_t a, uint64_t b, float_status *s)
return float64_sub(b, a, s);
}
+RVVCALL(OPFVF2, vfrsub_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_rsub)
RVVCALL(OPFVF2, vfrsub_vf_h, OP_UUU_H, H2, H2, float16_rsub)
RVVCALL(OPFVF2, vfrsub_vf_w, OP_UUU_W, H4, H4, float32_rsub)
RVVCALL(OPFVF2, vfrsub_vf_d, OP_UUU_D, H8, H8, float64_rsub)
+GEN_VEXT_VF(vfrsub_vf_h_bf16, 2)
GEN_VEXT_VF(vfrsub_vf_h, 2)
GEN_VEXT_VF(vfrsub_vf_w, 4)
GEN_VEXT_VF(vfrsub_vf_d, 8)
/* Vector Widening Floating-Point Add/Subtract Instructions */
+static uint32_t vfwadd16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ return float32_add(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), s);
+}
+
static uint32_t vfwadd16(uint16_t a, uint16_t b, float_status *s)
{
return float32_add(float16_to_float32(a, true, s),
@@ -3269,15 +3290,25 @@ static uint64_t vfwadd32(uint32_t a, uint32_t b, float_status *s)
}
+RVVCALL(OPFVV2, vfwadd_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwadd16_bf16)
RVVCALL(OPFVV2, vfwadd_vv_h, WOP_UUU_H, H4, H2, H2, vfwadd16)
RVVCALL(OPFVV2, vfwadd_vv_w, WOP_UUU_W, H8, H4, H4, vfwadd32)
+GEN_VEXT_VV_ENV(vfwadd_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwadd_vv_h, 4)
GEN_VEXT_VV_ENV(vfwadd_vv_w, 8)
+RVVCALL(OPFVF2, vfwadd_vf_h_bf16, WOP_UUU_H, H4, H2, vfwadd16_bf16)
RVVCALL(OPFVF2, vfwadd_vf_h, WOP_UUU_H, H4, H2, vfwadd16)
RVVCALL(OPFVF2, vfwadd_vf_w, WOP_UUU_W, H8, H4, vfwadd32)
+GEN_VEXT_VF(vfwadd_vf_h_bf16, 4)
GEN_VEXT_VF(vfwadd_vf_h, 4)
GEN_VEXT_VF(vfwadd_vf_w, 8)
+static uint32_t vfwsub16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ return float32_sub(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), s);
+}
+
static uint32_t vfwsub16(uint16_t a, uint16_t b, float_status *s)
{
return float32_sub(float16_to_float32(a, true, s),
@@ -3291,15 +3322,24 @@ static uint64_t vfwsub32(uint32_t a, uint32_t b, float_status *s)
}
+RVVCALL(OPFVV2, vfwsub_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwsub16_bf16)
RVVCALL(OPFVV2, vfwsub_vv_h, WOP_UUU_H, H4, H2, H2, vfwsub16)
RVVCALL(OPFVV2, vfwsub_vv_w, WOP_UUU_W, H8, H4, H4, vfwsub32)
+GEN_VEXT_VV_ENV(vfwsub_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwsub_vv_h, 4)
GEN_VEXT_VV_ENV(vfwsub_vv_w, 8)
+RVVCALL(OPFVF2, vfwsub_vf_h_bf16, WOP_UUU_H, H4, H2, vfwsub16_bf16)
RVVCALL(OPFVF2, vfwsub_vf_h, WOP_UUU_H, H4, H2, vfwsub16)
RVVCALL(OPFVF2, vfwsub_vf_w, WOP_UUU_W, H8, H4, vfwsub32)
+GEN_VEXT_VF(vfwsub_vf_h_bf16, 4)
GEN_VEXT_VF(vfwsub_vf_h, 4)
GEN_VEXT_VF(vfwsub_vf_w, 8)
+static uint32_t vfwaddw16_bf16(uint32_t a, uint16_t b, float_status *s)
+{
+ return float32_add(a, bfloat16_to_float32(b, s), s);
+}
+
static uint32_t vfwaddw16(uint32_t a, uint16_t b, float_status *s)
{
return float32_add(a, float16_to_float32(b, true, s), s);
@@ -3310,15 +3350,24 @@ static uint64_t vfwaddw32(uint64_t a, uint32_t b, float_status *s)
return float64_add(a, float32_to_float64(b, s), s);
}
+RVVCALL(OPFVV2, vfwadd_wv_h_bf16, WOP_WUUU_H, H4, H2, H2, vfwaddw16_bf16)
RVVCALL(OPFVV2, vfwadd_wv_h, WOP_WUUU_H, H4, H2, H2, vfwaddw16)
RVVCALL(OPFVV2, vfwadd_wv_w, WOP_WUUU_W, H8, H4, H4, vfwaddw32)
+GEN_VEXT_VV_ENV(vfwadd_wv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwadd_wv_h, 4)
GEN_VEXT_VV_ENV(vfwadd_wv_w, 8)
+RVVCALL(OPFVF2, vfwadd_wf_h_bf16, WOP_WUUU_H, H4, H2, vfwaddw16_bf16)
RVVCALL(OPFVF2, vfwadd_wf_h, WOP_WUUU_H, H4, H2, vfwaddw16)
RVVCALL(OPFVF2, vfwadd_wf_w, WOP_WUUU_W, H8, H4, vfwaddw32)
+GEN_VEXT_VF(vfwadd_wf_h_bf16, 4)
GEN_VEXT_VF(vfwadd_wf_h, 4)
GEN_VEXT_VF(vfwadd_wf_w, 8)
+static uint32_t vfwsubw16_bf16(uint32_t a, uint16_t b, float_status *s)
+{
+ return float32_sub(a, bfloat16_to_float32(b, s), s);
+}
+
static uint32_t vfwsubw16(uint32_t a, uint16_t b, float_status *s)
{
return float32_sub(a, float16_to_float32(b, true, s), s);
@@ -3329,25 +3378,33 @@ static uint64_t vfwsubw32(uint64_t a, uint32_t b, float_status *s)
return float64_sub(a, float32_to_float64(b, s), s);
}
+RVVCALL(OPFVV2, vfwsub_wv_h_bf16, WOP_WUUU_H, H4, H2, H2, vfwsubw16_bf16)
RVVCALL(OPFVV2, vfwsub_wv_h, WOP_WUUU_H, H4, H2, H2, vfwsubw16)
RVVCALL(OPFVV2, vfwsub_wv_w, WOP_WUUU_W, H8, H4, H4, vfwsubw32)
+GEN_VEXT_VV_ENV(vfwsub_wv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwsub_wv_h, 4)
GEN_VEXT_VV_ENV(vfwsub_wv_w, 8)
+RVVCALL(OPFVF2, vfwsub_wf_h_bf16, WOP_WUUU_H, H4, H2, vfwsubw16_bf16)
RVVCALL(OPFVF2, vfwsub_wf_h, WOP_WUUU_H, H4, H2, vfwsubw16)
RVVCALL(OPFVF2, vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32)
+GEN_VEXT_VF(vfwsub_wf_h_bf16, 4)
GEN_VEXT_VF(vfwsub_wf_h, 4)
GEN_VEXT_VF(vfwsub_wf_w, 8)
/* Vector Single-Width Floating-Point Multiply/Divide Instructions */
+RVVCALL(OPFVV2, vfmul_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_mul)
RVVCALL(OPFVV2, vfmul_vv_h, OP_UUU_H, H2, H2, H2, float16_mul)
RVVCALL(OPFVV2, vfmul_vv_w, OP_UUU_W, H4, H4, H4, float32_mul)
RVVCALL(OPFVV2, vfmul_vv_d, OP_UUU_D, H8, H8, H8, float64_mul)
+GEN_VEXT_VV_ENV(vfmul_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmul_vv_h, 2)
GEN_VEXT_VV_ENV(vfmul_vv_w, 4)
GEN_VEXT_VV_ENV(vfmul_vv_d, 8)
+RVVCALL(OPFVF2, vfmul_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_mul)
RVVCALL(OPFVF2, vfmul_vf_h, OP_UUU_H, H2, H2, float16_mul)
RVVCALL(OPFVF2, vfmul_vf_w, OP_UUU_W, H4, H4, float32_mul)
RVVCALL(OPFVF2, vfmul_vf_d, OP_UUU_D, H8, H8, float64_mul)
+GEN_VEXT_VF(vfmul_vf_h_bf16, 2)
GEN_VEXT_VF(vfmul_vf_h, 2)
GEN_VEXT_VF(vfmul_vf_w, 4)
GEN_VEXT_VF(vfmul_vf_d, 8)
@@ -3388,6 +3445,12 @@ GEN_VEXT_VF(vfrdiv_vf_w, 4)
GEN_VEXT_VF(vfrdiv_vf_d, 8)
/* Vector Widening Floating-Point Multiply */
+static uint32_t vfwmul16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ return float32_mul(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), s);
+}
+
static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s)
{
return float32_mul(float16_to_float32(a, true, s),
@@ -3400,12 +3463,17 @@ static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s)
float32_to_float64(b, s), s);
}
+
+RVVCALL(OPFVV2, vfwmul_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwmul16_bf16)
RVVCALL(OPFVV2, vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16)
RVVCALL(OPFVV2, vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32)
+GEN_VEXT_VV_ENV(vfwmul_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwmul_vv_h, 4)
GEN_VEXT_VV_ENV(vfwmul_vv_w, 8)
+RVVCALL(OPFVF2, vfwmul_vf_h_bf16, WOP_UUU_H, H4, H2, vfwmul16_bf16)
RVVCALL(OPFVF2, vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16)
RVVCALL(OPFVF2, vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32)
+GEN_VEXT_VF(vfwmul_vf_h_bf16, 4)
GEN_VEXT_VF(vfwmul_vf_h, 4)
GEN_VEXT_VF(vfwmul_vf_w, 8)
@@ -3420,6 +3488,12 @@ static void do_##NAME(void *vd, void *vs1, void *vs2, int i, \
*((TD *)vd + HD(i)) = OP(s2, s1, d, &env->fp_status); \
}
+static uint16_t fmacc16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(a, b, d, 0, s);
+}
+
static uint16_t fmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(a, b, d, 0, s);
@@ -3435,9 +3509,11 @@ static uint64_t fmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(a, b, d, 0, s);
}
+RVVCALL(OPFVV3, vfmacc_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmacc16_bf16)
RVVCALL(OPFVV3, vfmacc_vv_h, OP_UUU_H, H2, H2, H2, fmacc16)
RVVCALL(OPFVV3, vfmacc_vv_w, OP_UUU_W, H4, H4, H4, fmacc32)
RVVCALL(OPFVV3, vfmacc_vv_d, OP_UUU_D, H8, H8, H8, fmacc64)
+GEN_VEXT_VV_ENV(vfmacc_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmacc_vv_h, 2)
GEN_VEXT_VV_ENV(vfmacc_vv_w, 4)
GEN_VEXT_VV_ENV(vfmacc_vv_d, 8)
@@ -3451,13 +3527,22 @@ static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \
*((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, d, &env->fp_status);\
}
+RVVCALL(OPFVF3, vfmacc_vf_h_bf16, OP_UUU_H, H2, H2, fmacc16_bf16)
RVVCALL(OPFVF3, vfmacc_vf_h, OP_UUU_H, H2, H2, fmacc16)
RVVCALL(OPFVF3, vfmacc_vf_w, OP_UUU_W, H4, H4, fmacc32)
RVVCALL(OPFVF3, vfmacc_vf_d, OP_UUU_D, H8, H8, fmacc64)
+GEN_VEXT_VF(vfmacc_vf_h_bf16, 2)
GEN_VEXT_VF(vfmacc_vf_h, 2)
GEN_VEXT_VF(vfmacc_vf_w, 4)
GEN_VEXT_VF(vfmacc_vf_d, 8)
+static uint16_t fnmacc16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(a, b, d, float_muladd_negate_c |
+ float_muladd_negate_product, s);
+}
+
static uint16_t fnmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(a, b, d, float_muladd_negate_c |
@@ -3476,19 +3561,29 @@ static uint64_t fnmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfnmacc_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmacc16_bf16)
RVVCALL(OPFVV3, vfnmacc_vv_h, OP_UUU_H, H2, H2, H2, fnmacc16)
RVVCALL(OPFVV3, vfnmacc_vv_w, OP_UUU_W, H4, H4, H4, fnmacc32)
RVVCALL(OPFVV3, vfnmacc_vv_d, OP_UUU_D, H8, H8, H8, fnmacc64)
+GEN_VEXT_VV_ENV(vfnmacc_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfnmacc_vv_h, 2)
GEN_VEXT_VV_ENV(vfnmacc_vv_w, 4)
GEN_VEXT_VV_ENV(vfnmacc_vv_d, 8)
+RVVCALL(OPFVF3, vfnmacc_vf_h_bf16, OP_UUU_H, H2, H2, fnmacc16_bf16)
RVVCALL(OPFVF3, vfnmacc_vf_h, OP_UUU_H, H2, H2, fnmacc16)
RVVCALL(OPFVF3, vfnmacc_vf_w, OP_UUU_W, H4, H4, fnmacc32)
RVVCALL(OPFVF3, vfnmacc_vf_d, OP_UUU_D, H8, H8, fnmacc64)
+GEN_VEXT_VF(vfnmacc_vf_h_bf16, 2)
GEN_VEXT_VF(vfnmacc_vf_h, 2)
GEN_VEXT_VF(vfnmacc_vf_w, 4)
GEN_VEXT_VF(vfnmacc_vf_d, 8)
+static uint16_t fmsac16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(a, b, d, float_muladd_negate_c, s);
+}
+
static uint16_t fmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(a, b, d, float_muladd_negate_c, s);
@@ -3504,19 +3599,29 @@ static uint64_t fmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(a, b, d, float_muladd_negate_c, s);
}
+RVVCALL(OPFVV3, vfmsac_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmsac16_bf16)
RVVCALL(OPFVV3, vfmsac_vv_h, OP_UUU_H, H2, H2, H2, fmsac16)
RVVCALL(OPFVV3, vfmsac_vv_w, OP_UUU_W, H4, H4, H4, fmsac32)
RVVCALL(OPFVV3, vfmsac_vv_d, OP_UUU_D, H8, H8, H8, fmsac64)
+GEN_VEXT_VV_ENV(vfmsac_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmsac_vv_h, 2)
GEN_VEXT_VV_ENV(vfmsac_vv_w, 4)
GEN_VEXT_VV_ENV(vfmsac_vv_d, 8)
+RVVCALL(OPFVF3, vfmsac_vf_h_bf16, OP_UUU_H, H2, H2, fmsac16_bf16)
RVVCALL(OPFVF3, vfmsac_vf_h, OP_UUU_H, H2, H2, fmsac16)
RVVCALL(OPFVF3, vfmsac_vf_w, OP_UUU_W, H4, H4, fmsac32)
RVVCALL(OPFVF3, vfmsac_vf_d, OP_UUU_D, H8, H8, fmsac64)
+GEN_VEXT_VF(vfmsac_vf_h_bf16, 2)
GEN_VEXT_VF(vfmsac_vf_h, 2)
GEN_VEXT_VF(vfmsac_vf_w, 4)
GEN_VEXT_VF(vfmsac_vf_d, 8)
+static uint16_t fnmsac16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(a, b, d, float_muladd_negate_product, s);
+}
+
static uint16_t fnmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(a, b, d, float_muladd_negate_product, s);
@@ -3532,19 +3637,29 @@ static uint64_t fnmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(a, b, d, float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfnmsac_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmsac16_bf16)
RVVCALL(OPFVV3, vfnmsac_vv_h, OP_UUU_H, H2, H2, H2, fnmsac16)
RVVCALL(OPFVV3, vfnmsac_vv_w, OP_UUU_W, H4, H4, H4, fnmsac32)
RVVCALL(OPFVV3, vfnmsac_vv_d, OP_UUU_D, H8, H8, H8, fnmsac64)
+GEN_VEXT_VV_ENV(vfnmsac_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfnmsac_vv_h, 2)
GEN_VEXT_VV_ENV(vfnmsac_vv_w, 4)
GEN_VEXT_VV_ENV(vfnmsac_vv_d, 8)
+RVVCALL(OPFVF3, vfnmsac_vf_h_bf16, OP_UUU_H, H2, H2, fnmsac16_bf16)
RVVCALL(OPFVF3, vfnmsac_vf_h, OP_UUU_H, H2, H2, fnmsac16)
RVVCALL(OPFVF3, vfnmsac_vf_w, OP_UUU_W, H4, H4, fnmsac32)
RVVCALL(OPFVF3, vfnmsac_vf_d, OP_UUU_D, H8, H8, fnmsac64)
+GEN_VEXT_VF(vfnmsac_vf_h_bf16, 2)
GEN_VEXT_VF(vfnmsac_vf_h, 2)
GEN_VEXT_VF(vfnmsac_vf_w, 4)
GEN_VEXT_VF(vfnmsac_vf_d, 8)
+static uint16_t fmadd16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(d, b, a, 0, s);
+}
+
static uint16_t fmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(d, b, a, 0, s);
@@ -3560,19 +3675,30 @@ static uint64_t fmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(d, b, a, 0, s);
}
+RVVCALL(OPFVV3, vfmadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmadd16_bf16)
RVVCALL(OPFVV3, vfmadd_vv_h, OP_UUU_H, H2, H2, H2, fmadd16)
RVVCALL(OPFVV3, vfmadd_vv_w, OP_UUU_W, H4, H4, H4, fmadd32)
RVVCALL(OPFVV3, vfmadd_vv_d, OP_UUU_D, H8, H8, H8, fmadd64)
+GEN_VEXT_VV_ENV(vfmadd_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmadd_vv_h, 2)
GEN_VEXT_VV_ENV(vfmadd_vv_w, 4)
GEN_VEXT_VV_ENV(vfmadd_vv_d, 8)
+RVVCALL(OPFVF3, vfmadd_vf_h_bf16, OP_UUU_H, H2, H2, fmadd16_bf16)
RVVCALL(OPFVF3, vfmadd_vf_h, OP_UUU_H, H2, H2, fmadd16)
RVVCALL(OPFVF3, vfmadd_vf_w, OP_UUU_W, H4, H4, fmadd32)
RVVCALL(OPFVF3, vfmadd_vf_d, OP_UUU_D, H8, H8, fmadd64)
+GEN_VEXT_VF(vfmadd_vf_h_bf16, 2)
GEN_VEXT_VF(vfmadd_vf_h, 2)
GEN_VEXT_VF(vfmadd_vf_w, 4)
GEN_VEXT_VF(vfmadd_vf_d, 8)
+static uint16_t fnmadd16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(d, b, a, float_muladd_negate_c |
+ float_muladd_negate_product, s);
+}
+
static uint16_t fnmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(d, b, a, float_muladd_negate_c |
@@ -3591,19 +3717,29 @@ static uint64_t fnmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfnmadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmadd16_bf16)
RVVCALL(OPFVV3, vfnmadd_vv_h, OP_UUU_H, H2, H2, H2, fnmadd16)
RVVCALL(OPFVV3, vfnmadd_vv_w, OP_UUU_W, H4, H4, H4, fnmadd32)
RVVCALL(OPFVV3, vfnmadd_vv_d, OP_UUU_D, H8, H8, H8, fnmadd64)
+GEN_VEXT_VV_ENV(vfnmadd_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfnmadd_vv_h, 2)
GEN_VEXT_VV_ENV(vfnmadd_vv_w, 4)
GEN_VEXT_VV_ENV(vfnmadd_vv_d, 8)
+RVVCALL(OPFVF3, vfnmadd_vf_h_bf16, OP_UUU_H, H2, H2, fnmadd16_bf16)
RVVCALL(OPFVF3, vfnmadd_vf_h, OP_UUU_H, H2, H2, fnmadd16)
RVVCALL(OPFVF3, vfnmadd_vf_w, OP_UUU_W, H4, H4, fnmadd32)
RVVCALL(OPFVF3, vfnmadd_vf_d, OP_UUU_D, H8, H8, fnmadd64)
+GEN_VEXT_VF(vfnmadd_vf_h_bf16, 2)
GEN_VEXT_VF(vfnmadd_vf_h, 2)
GEN_VEXT_VF(vfnmadd_vf_w, 4)
GEN_VEXT_VF(vfnmadd_vf_d, 8)
+static uint16_t fmsub16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(d, b, a, float_muladd_negate_c, s);
+}
+
static uint16_t fmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(d, b, a, float_muladd_negate_c, s);
@@ -3619,19 +3755,29 @@ static uint64_t fmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(d, b, a, float_muladd_negate_c, s);
}
+RVVCALL(OPFVV3, vfmsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmsub16_bf16)
RVVCALL(OPFVV3, vfmsub_vv_h, OP_UUU_H, H2, H2, H2, fmsub16)
RVVCALL(OPFVV3, vfmsub_vv_w, OP_UUU_W, H4, H4, H4, fmsub32)
RVVCALL(OPFVV3, vfmsub_vv_d, OP_UUU_D, H8, H8, H8, fmsub64)
+GEN_VEXT_VV_ENV(vfmsub_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmsub_vv_h, 2)
GEN_VEXT_VV_ENV(vfmsub_vv_w, 4)
GEN_VEXT_VV_ENV(vfmsub_vv_d, 8)
+RVVCALL(OPFVF3, vfmsub_vf_h_bf16, OP_UUU_H, H2, H2, fmsub16_bf16)
RVVCALL(OPFVF3, vfmsub_vf_h, OP_UUU_H, H2, H2, fmsub16)
RVVCALL(OPFVF3, vfmsub_vf_w, OP_UUU_W, H4, H4, fmsub32)
RVVCALL(OPFVF3, vfmsub_vf_d, OP_UUU_D, H8, H8, fmsub64)
+GEN_VEXT_VF(vfmsub_vf_h_bf16, 2)
GEN_VEXT_VF(vfmsub_vf_h, 2)
GEN_VEXT_VF(vfmsub_vf_w, 4)
GEN_VEXT_VF(vfmsub_vf_d, 8)
+static uint16_t fnmsub16_bf16(uint16_t a, uint16_t b, uint16_t d,
+ float_status *s)
+{
+ return bfloat16_muladd(d, b, a, float_muladd_negate_product, s);
+}
+
static uint16_t fnmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
{
return float16_muladd(d, b, a, float_muladd_negate_product, s);
@@ -3647,15 +3793,19 @@ static uint64_t fnmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
return float64_muladd(d, b, a, float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfnmsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmsub16_bf16)
RVVCALL(OPFVV3, vfnmsub_vv_h, OP_UUU_H, H2, H2, H2, fnmsub16)
RVVCALL(OPFVV3, vfnmsub_vv_w, OP_UUU_W, H4, H4, H4, fnmsub32)
RVVCALL(OPFVV3, vfnmsub_vv_d, OP_UUU_D, H8, H8, H8, fnmsub64)
+GEN_VEXT_VV_ENV(vfnmsub_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfnmsub_vv_h, 2)
GEN_VEXT_VV_ENV(vfnmsub_vv_w, 4)
GEN_VEXT_VV_ENV(vfnmsub_vv_d, 8)
+RVVCALL(OPFVF3, vfnmsub_vf_h_bf16, OP_UUU_H, H2, H2, fnmsub16_bf16)
RVVCALL(OPFVF3, vfnmsub_vf_h, OP_UUU_H, H2, H2, fnmsub16)
RVVCALL(OPFVF3, vfnmsub_vf_w, OP_UUU_W, H4, H4, fnmsub32)
RVVCALL(OPFVF3, vfnmsub_vf_d, OP_UUU_D, H8, H8, fnmsub64)
+GEN_VEXT_VF(vfnmsub_vf_h_bf16, 2)
GEN_VEXT_VF(vfnmsub_vf_h, 2)
GEN_VEXT_VF(vfnmsub_vf_w, 4)
GEN_VEXT_VF(vfnmsub_vf_d, 8)
@@ -3693,6 +3843,15 @@ GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16)
GEN_VEXT_VF(vfwmaccbf16_vf, 4)
+static uint32_t fwnmacc16_bf16(uint16_t a, uint16_t b, uint32_t d,
+ float_status *s)
+{
+ return float32_muladd(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), d,
+ float_muladd_negate_c | float_muladd_negate_product,
+ s);
+}
+
static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
{
return float32_muladd(float16_to_float32(a, true, s),
@@ -3708,15 +3867,27 @@ static uint64_t fwnmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfwnmacc_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwnmacc16_bf16)
RVVCALL(OPFVV3, vfwnmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwnmacc16)
RVVCALL(OPFVV3, vfwnmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwnmacc32)
+GEN_VEXT_VV_ENV(vfwnmacc_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwnmacc_vv_h, 4)
GEN_VEXT_VV_ENV(vfwnmacc_vv_w, 8)
+RVVCALL(OPFVF3, vfwnmacc_vf_h_bf16, WOP_UUU_H, H4, H2, fwnmacc16_bf16)
RVVCALL(OPFVF3, vfwnmacc_vf_h, WOP_UUU_H, H4, H2, fwnmacc16)
RVVCALL(OPFVF3, vfwnmacc_vf_w, WOP_UUU_W, H8, H4, fwnmacc32)
+GEN_VEXT_VF(vfwnmacc_vf_h_bf16, 4)
GEN_VEXT_VF(vfwnmacc_vf_h, 4)
GEN_VEXT_VF(vfwnmacc_vf_w, 8)
+static uint32_t fwmsac16_bf16(uint16_t a, uint16_t b, uint32_t d,
+ float_status *s)
+{
+ return float32_muladd(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), d,
+ float_muladd_negate_c, s);
+}
+
static uint32_t fwmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
{
return float32_muladd(float16_to_float32(a, true, s),
@@ -3731,15 +3902,27 @@ static uint64_t fwmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
float_muladd_negate_c, s);
}
+RVVCALL(OPFVV3, vfwmsac_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwmsac16_bf16)
RVVCALL(OPFVV3, vfwmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwmsac16)
RVVCALL(OPFVV3, vfwmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwmsac32)
+GEN_VEXT_VV_ENV(vfwmsac_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwmsac_vv_h, 4)
GEN_VEXT_VV_ENV(vfwmsac_vv_w, 8)
+RVVCALL(OPFVF3, vfwmsac_vf_h_bf16, WOP_UUU_H, H4, H2, fwmsac16_bf16)
RVVCALL(OPFVF3, vfwmsac_vf_h, WOP_UUU_H, H4, H2, fwmsac16)
RVVCALL(OPFVF3, vfwmsac_vf_w, WOP_UUU_W, H8, H4, fwmsac32)
+GEN_VEXT_VF(vfwmsac_vf_h_bf16, 4)
GEN_VEXT_VF(vfwmsac_vf_h, 4)
GEN_VEXT_VF(vfwmsac_vf_w, 8)
+static uint32_t fwnmsac16_bf16(uint16_t a, uint16_t b, uint32_t d,
+ float_status *s)
+{
+ return float32_muladd(bfloat16_to_float32(a, s),
+ bfloat16_to_float32(b, s), d,
+ float_muladd_negate_product, s);
+}
+
static uint32_t fwnmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
{
return float32_muladd(float16_to_float32(a, true, s),
@@ -3754,12 +3937,16 @@ static uint64_t fwnmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
float_muladd_negate_product, s);
}
+RVVCALL(OPFVV3, vfwnmsac_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwnmsac16_bf16)
RVVCALL(OPFVV3, vfwnmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwnmsac16)
RVVCALL(OPFVV3, vfwnmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwnmsac32)
+GEN_VEXT_VV_ENV(vfwnmsac_vv_h_bf16, 4)
GEN_VEXT_VV_ENV(vfwnmsac_vv_h, 4)
GEN_VEXT_VV_ENV(vfwnmsac_vv_w, 8)
+RVVCALL(OPFVF3, vfwnmsac_vf_h_bf16, WOP_UUU_H, H4, H2, fwnmsac16_bf16)
RVVCALL(OPFVF3, vfwnmsac_vf_h, WOP_UUU_H, H4, H2, fwnmsac16)
RVVCALL(OPFVF3, vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32)
+GEN_VEXT_VF(vfwnmsac_vf_h_bf16, 4)
GEN_VEXT_VF(vfwnmsac_vf_h, 4)
GEN_VEXT_VF(vfwnmsac_vf_w, 8)
@@ -3865,6 +4052,46 @@ static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size)
return val;
}
+static bfloat16 frsqrt7_h_bf16(bfloat16 f, float_status *s)
+{
+ int exp_size = 8, frac_size = 7;
+ bool sign = bfloat16_is_neg(f);
+
+ /*
+ * frsqrt7(sNaN) = canonical NaN
+ * frsqrt7(-inf) = canonical NaN
+ * frsqrt7(-normal) = canonical NaN
+ * frsqrt7(-subnormal) = canonical NaN
+ */
+ if (bfloat16_is_signaling_nan(f, s) ||
+ (bfloat16_is_infinity(f) && sign) ||
+ (bfloat16_is_normal(f) && sign) ||
+ (bfloat16_is_zero_or_denormal(f) && !bfloat16_is_zero(f) && sign)) {
+ s->float_exception_flags |= float_flag_invalid;
+ return bfloat16_default_nan(s);
+ }
+
+ /* frsqrt7(qNaN) = canonical NaN */
+ if (bfloat16_is_quiet_nan(f, s)) {
+ return bfloat16_default_nan(s);
+ }
+
+ /* frsqrt7(+-0) = +-inf */
+ if (bfloat16_is_zero(f)) {
+ s->float_exception_flags |= float_flag_divbyzero;
+ return bfloat16_set_sign(bfloat16_infinity, sign);
+ }
+
+ /* frsqrt7(+inf) = +0 */
+ if (bfloat16_is_infinity(f) && !sign) {
+ return bfloat16_set_sign(bfloat16_zero, sign);
+ }
+
+ /* +normal, +subnormal */
+ uint64_t val = frsqrt7(f, exp_size, frac_size);
+ return make_float16(val);
+}
+
static float16 frsqrt7_h(float16 f, float_status *s)
{
int exp_size = 5, frac_size = 10;
@@ -3985,9 +4212,11 @@ static float64 frsqrt7_d(float64 f, float_status *s)
return make_float64(val);
}
+RVVCALL(OPFVV1, vfrsqrt7_v_h_bf16, OP_UU_H, H2, H2, frsqrt7_h_bf16)
RVVCALL(OPFVV1, vfrsqrt7_v_h, OP_UU_H, H2, H2, frsqrt7_h)
RVVCALL(OPFVV1, vfrsqrt7_v_w, OP_UU_W, H4, H4, frsqrt7_s)
RVVCALL(OPFVV1, vfrsqrt7_v_d, OP_UU_D, H8, H8, frsqrt7_d)
+GEN_VEXT_V_ENV(vfrsqrt7_v_h_bf16, 2)
GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2)
GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4)
GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8)
@@ -4080,6 +4309,38 @@ static uint64_t frec7(uint64_t f, int exp_size, int frac_size,
return val;
}
+static bfloat16 frec7_h_bf16(bfloat16 f, float_status *s)
+{
+ int exp_size = 8, frac_size = 7;
+ bool sign = bfloat16_is_neg(f);
+
+ /* frec7(+-inf) = +-0 */
+ if (bfloat16_is_infinity(f)) {
+ return bfloat16_set_sign(bfloat16_zero, sign);
+ }
+
+ /* frec7(+-0) = +-inf */
+ if (bfloat16_is_zero(f)) {
+ s->float_exception_flags |= float_flag_divbyzero;
+ return bfloat16_set_sign(bfloat16_infinity, sign);
+ }
+
+ /* frec7(sNaN) = canonical NaN */
+ if (bfloat16_is_signaling_nan(f, s)) {
+ s->float_exception_flags |= float_flag_invalid;
+ return bfloat16_default_nan(s);
+ }
+
+ /* frec7(qNaN) = canonical NaN */
+ if (bfloat16_is_quiet_nan(f, s)) {
+ return bfloat16_default_nan(s);
+ }
+
+ /* +-normal, +-subnormal */
+ uint64_t val = frec7(f, exp_size, frac_size, s);
+ return make_float16(val);
+}
+
static float16 frec7_h(float16 f, float_status *s)
{
int exp_size = 5, frac_size = 10;
@@ -4176,36 +4437,46 @@ static float64 frec7_d(float64 f, float_status *s)
return make_float64(val);
}
+RVVCALL(OPFVV1, vfrec7_v_h_bf16, OP_UU_H, H2, H2, frec7_h_bf16)
RVVCALL(OPFVV1, vfrec7_v_h, OP_UU_H, H2, H2, frec7_h)
RVVCALL(OPFVV1, vfrec7_v_w, OP_UU_W, H4, H4, frec7_s)
RVVCALL(OPFVV1, vfrec7_v_d, OP_UU_D, H8, H8, frec7_d)
+GEN_VEXT_V_ENV(vfrec7_v_h_bf16, 2)
GEN_VEXT_V_ENV(vfrec7_v_h, 2)
GEN_VEXT_V_ENV(vfrec7_v_w, 4)
GEN_VEXT_V_ENV(vfrec7_v_d, 8)
/* Vector Floating-Point MIN/MAX Instructions */
+RVVCALL(OPFVV2, vfmin_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_minimum_number)
RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number)
RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number)
RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minimum_number)
+GEN_VEXT_VV_ENV(vfmin_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmin_vv_h, 2)
GEN_VEXT_VV_ENV(vfmin_vv_w, 4)
GEN_VEXT_VV_ENV(vfmin_vv_d, 8)
+RVVCALL(OPFVF2, vfmin_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_minimum_number)
RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minimum_number)
RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minimum_number)
RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minimum_number)
+GEN_VEXT_VF(vfmin_vf_h_bf16, 2)
GEN_VEXT_VF(vfmin_vf_h, 2)
GEN_VEXT_VF(vfmin_vf_w, 4)
GEN_VEXT_VF(vfmin_vf_d, 8)
+RVVCALL(OPFVV2, vfmax_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_maximum_number)
RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maximum_number)
RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maximum_number)
RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maximum_number)
+GEN_VEXT_VV_ENV(vfmax_vv_h_bf16, 2)
GEN_VEXT_VV_ENV(vfmax_vv_h, 2)
GEN_VEXT_VV_ENV(vfmax_vv_w, 4)
GEN_VEXT_VV_ENV(vfmax_vv_d, 8)
+RVVCALL(OPFVF2, vfmax_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_maximum_number)
RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maximum_number)
RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maximum_number)
RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maximum_number)
+GEN_VEXT_VF(vfmax_vf_h_bf16, 2)
GEN_VEXT_VF(vfmax_vf_h, 2)
GEN_VEXT_VF(vfmax_vf_w, 4)
GEN_VEXT_VF(vfmax_vf_d, 8)
@@ -4334,6 +4605,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
} \
}
+GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h_bf16, uint16_t, H2, bfloat16_eq_quiet)
GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet)
GEN_VEXT_CMP_VV_ENV(vmfeq_vv_w, uint32_t, H4, float32_eq_quiet)
GEN_VEXT_CMP_VV_ENV(vmfeq_vv_d, uint64_t, H8, float64_eq_quiet)
@@ -4375,10 +4647,17 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
} \
}
+GEN_VEXT_CMP_VF(vmfeq_vf_h_bf16, uint16_t, H2, bfloat16_eq_quiet)
GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet)
GEN_VEXT_CMP_VF(vmfeq_vf_w, uint32_t, H4, float32_eq_quiet)
GEN_VEXT_CMP_VF(vmfeq_vf_d, uint64_t, H8, float64_eq_quiet)
+static bool vmfne16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ FloatRelation compare = bfloat16_compare_quiet(a, b, s);
+ return compare != float_relation_equal;
+}
+
static bool vmfne16(uint16_t a, uint16_t b, float_status *s)
{
FloatRelation compare = float16_compare_quiet(a, b, s);
@@ -4397,27 +4676,39 @@ static bool vmfne64(uint64_t a, uint64_t b, float_status *s)
return compare != float_relation_equal;
}
+GEN_VEXT_CMP_VV_ENV(vmfne_vv_h_bf16, uint16_t, H2, vmfne16_bf16)
GEN_VEXT_CMP_VV_ENV(vmfne_vv_h, uint16_t, H2, vmfne16)
GEN_VEXT_CMP_VV_ENV(vmfne_vv_w, uint32_t, H4, vmfne32)
GEN_VEXT_CMP_VV_ENV(vmfne_vv_d, uint64_t, H8, vmfne64)
+GEN_VEXT_CMP_VF(vmfne_vf_h_bf16, uint16_t, H2, vmfne16_bf16)
GEN_VEXT_CMP_VF(vmfne_vf_h, uint16_t, H2, vmfne16)
GEN_VEXT_CMP_VF(vmfne_vf_w, uint32_t, H4, vmfne32)
GEN_VEXT_CMP_VF(vmfne_vf_d, uint64_t, H8, vmfne64)
+GEN_VEXT_CMP_VV_ENV(vmflt_vv_h_bf16, uint16_t, H2, bfloat16_lt)
GEN_VEXT_CMP_VV_ENV(vmflt_vv_h, uint16_t, H2, float16_lt)
GEN_VEXT_CMP_VV_ENV(vmflt_vv_w, uint32_t, H4, float32_lt)
GEN_VEXT_CMP_VV_ENV(vmflt_vv_d, uint64_t, H8, float64_lt)
+GEN_VEXT_CMP_VF(vmflt_vf_h_bf16, uint16_t, H2, bfloat16_lt)
GEN_VEXT_CMP_VF(vmflt_vf_h, uint16_t, H2, float16_lt)
GEN_VEXT_CMP_VF(vmflt_vf_w, uint32_t, H4, float32_lt)
GEN_VEXT_CMP_VF(vmflt_vf_d, uint64_t, H8, float64_lt)
+GEN_VEXT_CMP_VV_ENV(vmfle_vv_h_bf16, uint16_t, H2, bfloat16_le)
GEN_VEXT_CMP_VV_ENV(vmfle_vv_h, uint16_t, H2, float16_le)
GEN_VEXT_CMP_VV_ENV(vmfle_vv_w, uint32_t, H4, float32_le)
GEN_VEXT_CMP_VV_ENV(vmfle_vv_d, uint64_t, H8, float64_le)
+GEN_VEXT_CMP_VF(vmfle_vf_h_bf16, uint16_t, H2, bfloat16_le)
GEN_VEXT_CMP_VF(vmfle_vf_h, uint16_t, H2, float16_le)
GEN_VEXT_CMP_VF(vmfle_vf_w, uint32_t, H4, float32_le)
GEN_VEXT_CMP_VF(vmfle_vf_d, uint64_t, H8, float64_le)
+static bool vmfgt16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ FloatRelation compare = bfloat16_compare(a, b, s);
+ return compare == float_relation_greater;
+}
+
static bool vmfgt16(uint16_t a, uint16_t b, float_status *s)
{
FloatRelation compare = float16_compare(a, b, s);
@@ -4436,10 +4727,18 @@ static bool vmfgt64(uint64_t a, uint64_t b, float_status *s)
return compare == float_relation_greater;
}
+GEN_VEXT_CMP_VF(vmfgt_vf_h_bf16, uint16_t, H2, vmfgt16_bf16)
GEN_VEXT_CMP_VF(vmfgt_vf_h, uint16_t, H2, vmfgt16)
GEN_VEXT_CMP_VF(vmfgt_vf_w, uint32_t, H4, vmfgt32)
GEN_VEXT_CMP_VF(vmfgt_vf_d, uint64_t, H8, vmfgt64)
+static bool vmfge16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+ FloatRelation compare = bfloat16_compare(a, b, s);
+ return compare == float_relation_greater ||
+ compare == float_relation_equal;
+}
+
static bool vmfge16(uint16_t a, uint16_t b, float_status *s)
{
FloatRelation compare = float16_compare(a, b, s);
@@ -4461,11 +4760,31 @@ static bool vmfge64(uint64_t a, uint64_t b, float_status *s)
compare == float_relation_equal;
}
+GEN_VEXT_CMP_VF(vmfge_vf_h_bf16, uint16_t, H2, vmfge16_bf16)
GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16)
GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
/* Vector Floating-Point Classify Instruction */
+target_ulong fclass_h_bf16(uint64_t frs1)
+{
+ bfloat16 f = frs1;
+ bool sign = bfloat16_is_neg(f);
+
+ if (bfloat16_is_infinity(f)) {
+ return sign ? 1 << 0 : 1 << 7;
+ } else if (bfloat16_is_zero(f)) {
+ return sign ? 1 << 3 : 1 << 4;
+ } else if (bfloat16_is_zero_or_denormal(f)) {
+ return sign ? 1 << 2 : 1 << 5;
+ } else if (bfloat16_is_any_nan(f)) {
+ float_status s = { }; /* for snan_bit_is_one */
+ return bfloat16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+ } else {
+ return sign ? 1 << 1 : 1 << 6;
+ }
+}
+
target_ulong fclass_h(uint64_t frs1)
{
float16 f = frs1;
@@ -4523,9 +4842,11 @@ target_ulong fclass_d(uint64_t frs1)
}
}
+RVVCALL(OPIVV1, vfclass_v_h_bf16, OP_UU_H, H2, H2, fclass_h_bf16)
RVVCALL(OPIVV1, vfclass_v_h, OP_UU_H, H2, H2, fclass_h)
RVVCALL(OPIVV1, vfclass_v_w, OP_UU_W, H4, H4, fclass_s)
RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
+GEN_VEXT_V(vfclass_v_h_bf16, 2)
GEN_VEXT_V(vfclass_v_h, 2)
GEN_VEXT_V(vfclass_v_w, 4)
GEN_VEXT_V(vfclass_v_d, 8)
@@ -4616,17 +4937,21 @@ GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 8)
* vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float.
*/
RVVCALL(OPFVV1, vfwcvt_f_xu_v_b, WOP_UU_B, H2, H1, uint8_to_float16)
+RVVCALL(OPFVV1, vfwcvt_f_xu_v_b_bf16, WOP_UU_B, H2, H1, uint8_to_bfloat16)
RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32)
RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64)
GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b, 2)
+GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b_bf16, 2)
GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 4)
GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 8)
/* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */
RVVCALL(OPFVV1, vfwcvt_f_x_v_b, WOP_UU_B, H2, H1, int8_to_float16)
+RVVCALL(OPFVV1, vfwcvt_f_x_v_b_bf16, WOP_UU_B, H2, H1, int8_to_bfloat16)
RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32)
RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64)
GEN_VEXT_V_ENV(vfwcvt_f_x_v_b, 2)
+GEN_VEXT_V_ENV(vfwcvt_f_x_v_b_bf16, 2)
GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 4)
GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 8)
@@ -4653,17 +4978,21 @@ GEN_VEXT_V_ENV(vfwcvtbf16_f_f_v, 4)
#define NOP_UU_W uint32_t, uint64_t, uint64_t
/* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
RVVCALL(OPFVV1, vfncvt_xu_f_w_b, NOP_UU_B, H1, H2, float16_to_uint8)
+RVVCALL(OPFVV1, vfncvt_xu_f_w_b_bf16, NOP_UU_B, H1, H2, bfloat16_to_uint8)
RVVCALL(OPFVV1, vfncvt_xu_f_w_h, NOP_UU_H, H2, H4, float32_to_uint16)
RVVCALL(OPFVV1, vfncvt_xu_f_w_w, NOP_UU_W, H4, H8, float64_to_uint32)
GEN_VEXT_V_ENV(vfncvt_xu_f_w_b, 1)
+GEN_VEXT_V_ENV(vfncvt_xu_f_w_b_bf16, 1)
GEN_VEXT_V_ENV(vfncvt_xu_f_w_h, 2)
GEN_VEXT_V_ENV(vfncvt_xu_f_w_w, 4)
/* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */
RVVCALL(OPFVV1, vfncvt_x_f_w_b, NOP_UU_B, H1, H2, float16_to_int8)
+RVVCALL(OPFVV1, vfncvt_x_f_w_b_bf16, NOP_UU_B, H1, H2, bfloat16_to_int8)
RVVCALL(OPFVV1, vfncvt_x_f_w_h, NOP_UU_H, H2, H4, float32_to_int16)
RVVCALL(OPFVV1, vfncvt_x_f_w_w, NOP_UU_W, H4, H8, float64_to_int32)
GEN_VEXT_V_ENV(vfncvt_x_f_w_b, 1)
+GEN_VEXT_V_ENV(vfncvt_x_f_w_b_bf16, 1)
GEN_VEXT_V_ENV(vfncvt_x_f_w_h, 2)
GEN_VEXT_V_ENV(vfncvt_x_f_w_w, 4)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 03ae85796a..5b72926b3c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -40,6 +40,9 @@ static bool require_rvf(DisasContext *s)
switch (s->sew) {
case MO_16:
+ if (s->altfmt) {
+ return s->cfg_ptr->ext_zvfbfa;
+ }
return s->cfg_ptr->ext_zvfh;
case MO_32:
return s->cfg_ptr->ext_zve32f;
@@ -58,6 +61,9 @@ static bool require_rvfmin(DisasContext *s)
switch (s->sew) {
case MO_16:
+ if (s->altfmt) {
+ return s->cfg_ptr->ext_zvfbfa;
+ }
return s->cfg_ptr->ext_zvfhmin;
case MO_32:
return s->cfg_ptr->ext_zve32f;
@@ -74,6 +80,9 @@ static bool require_scale_rvf(DisasContext *s)
switch (s->sew) {
case MO_8:
+ if (s->altfmt) {
+ return s->cfg_ptr->ext_zvfbfa;
+ }
return s->cfg_ptr->ext_zvfh;
case MO_16:
return s->cfg_ptr->ext_zve32f;
@@ -2334,25 +2343,39 @@ static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
}
}
+/*
+ * Check altfmt & sew combinations when Zvfbfa extension is enabled.
+ */
+static bool vext_check_altfmt(DisasContext *s, int8_t valid_vsew)
+{
+ if (s->cfg_ptr->ext_zvfbfa) {
+ if (s->altfmt && (valid_vsew == -1 || s->sew != valid_vsew)) {
+ return false;
+ }
+ }
+ return true;
+}
+
/* Vector Single-Width Floating-Point Add/Subtract Instructions */
/*
* If the current SEW does not correspond to a supported IEEE floating-point
* type, an illegal instruction exception is raised.
*/
-static bool opfvv_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_check(DisasContext *s, arg_rmrr *a, int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+ vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
/* OPFVV without GVEC IR */
#define GEN_OPFVV_TRANS(NAME, CHECK) \
static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
{ \
- if (CHECK(s, a)) { \
+ if (CHECK(s, a, -1)) { \
uint32_t data = 0; \
static gen_helper_gvec_4_ptr * const fns[3] = { \
gen_helper_##NAME##_h, \
@@ -2378,8 +2401,41 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
} \
return false; \
}
-GEN_OPFVV_TRANS(vfadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsub_vv, opfvv_check)
+
+#define GEN_OPFVV_BFA_TRANS(NAME, CHECK, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_4_ptr * const fns[3] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ gen_helper_##NAME##_d \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs1), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1])); \
+ tcg_gen_movi_tl(cpu_vstart, 0); \
+ finalize_rvv_inst(s); \
+ \
+ return true; \
+ } \
+ return false; \
+}
+
+GEN_OPFVV_BFA_TRANS(vfadd_vv, opfvv_check, vfadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfsub_vv, opfvv_check, vfsub_vv_h_bf16)
typedef void gen_helper_opfvf(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_ptr,
TCGv_env, TCGv_i32);
@@ -2415,244 +2471,316 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
* If the current SEW does not correspond to a supported IEEE floating-point
* type, an illegal instruction exception is raised
*/
-static bool opfvf_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_check(DisasContext *s, arg_rmrr *a, int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_ss(s, a->rd, a->rs2, a->vm);
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
/* OPFVF without GVEC IR */
-#define GEN_OPFVF_TRANS(NAME, CHECK) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{ \
- if (CHECK(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_opfvf *const fns[3] = { \
- gen_helper_##NAME##_h, \
- gen_helper_##NAME##_w, \
- gen_helper_##NAME##_d, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \
- s->cfg_vta_all_1s); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
- fns[s->sew - 1], s); \
- } \
- return false; \
-}
-
-GEN_OPFVF_TRANS(vfadd_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfsub_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
+#define GEN_OPFVF_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, -1)) { \
+ uint32_t data = 0; \
+ static gen_helper_opfvf *const fns[3] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ gen_helper_##NAME##_d, \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \
+ s->cfg_vta_all_1s); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
+ fns[s->sew - 1], s); \
+ } \
+ return false; \
+}
+
+#define GEN_OPFVF_BFA_TRANS(NAME, CHECK, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_opfvf *const fns[3] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ gen_helper_##NAME##_d, \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \
+ s->cfg_vta_all_1s); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1]), \
+ s); \
+ } \
+ return false; \
+}
+
+GEN_OPFVF_BFA_TRANS(vfadd_vf, opfvf_check, vfadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfsub_vf, opfvf_check, vfsub_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfrsub_vf, opfvf_check, vfrsub_vf_h_bf16)
/* Vector Widening Floating-Point Add/Subtract Instructions */
-static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
+ vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool opfvv_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
- return require_rvv(s) &&
- require_rvf(s) &&
- require_scale_rvf(s) &&
- vext_check_isa_ill(s) &&
- vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+ return opfvv_widen_check(s, a, valid_bfa_vsew) &&
vext_check_input_eew(s, a->rd, s->sew + 1, a->rs1, s->sew, a->vm) &&
vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
}
/* OPFVV with WIDEN */
-#define GEN_OPFVV_WIDEN_TRANS(NAME, CHECK) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{ \
- if (CHECK(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_4_ptr * const fns[2] = { \
- gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew - 1]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
-}
-
-GEN_OPFVV_WIDEN_TRANS(vfwadd_vv, opfvv_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
-
-static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
+#define GEN_OPFVV_WIDEN_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, -1)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_4_ptr * const fns[2] = { \
+ gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs1), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ fns[s->sew - 1]); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
+}
+
+#define GEN_OPFVV_WIDEN_BFA_TRANS(NAME, CHECK, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_4_ptr * const fns[2] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs1), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
+}
+
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwadd_vv, opfvv_widen_check, vfwadd_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwsub_vv, opfvv_widen_check, vfwsub_vv_h_bf16)
+
+static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_ds(s, a->rd, a->rs2, a->vm);
+ vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool opfvf_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
- return require_rvv(s) &&
- require_rvf(s) &&
- require_scale_rvf(s) &&
- vext_check_isa_ill(s) &&
- vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+ return opfvf_widen_check(s, a, valid_bfa_vsew) &&
vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
}
/* OPFVF with WIDEN */
-#define GEN_OPFVF_WIDEN_TRANS(NAME, CHECK) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{ \
- if (CHECK(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_opfvf *const fns[2] = { \
- gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
- fns[s->sew - 1], s); \
- } \
- return false; \
-}
-
-GEN_OPFVF_WIDEN_TRANS(vfwadd_vf, opfvf_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwsub_vf, opfvf_widen_check)
-
-static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
+#define GEN_OPFVF_WIDEN_BFA_TRANS(NAME, CHECK, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_opfvf *const fns[2] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1]), \
+ s); \
+ } \
+ return false; \
+}
+
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwadd_vf, opfvf_widen_check, vfwadd_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwsub_vf, opfvf_widen_check, vfwsub_vf_h_bf16)
+
+static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
+ vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
/* WIDEN OPFVV with WIDEN */
-#define GEN_OPFWV_WIDEN_TRANS(NAME) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{ \
- if (opfwv_widen_check(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_4_ptr * const fns[2] = { \
- gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew - 1]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
+#define GEN_OPFWV_WIDEN_BFA_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (opfwv_widen_check(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_4_ptr * const fns[2] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs1), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##NAME##_h_bf16 : \
+ fns[s->sew - 1])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
}
-GEN_OPFWV_WIDEN_TRANS(vfwadd_wv)
-GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
+GEN_OPFWV_WIDEN_BFA_TRANS(vfwadd_wv)
+GEN_OPFWV_WIDEN_BFA_TRANS(vfwsub_wv)
-static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_dd(s, a->rd, a->rs2, a->vm);
+ vext_check_dd(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
/* WIDEN OPFVF with WIDEN */
-#define GEN_OPFWF_WIDEN_TRANS(NAME) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{ \
- if (opfwf_widen_check(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_opfvf *const fns[2] = { \
- gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
- fns[s->sew - 1], s); \
- } \
- return false; \
-}
-
-GEN_OPFWF_WIDEN_TRANS(vfwadd_wf)
-GEN_OPFWF_WIDEN_TRANS(vfwsub_wf)
+#define GEN_OPFWF_WIDEN_BFA_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (opfwf_widen_check(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_opfvf *const fns[2] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
+ (s->altfmt ? gen_helper_##NAME##_h_bf16 : \
+ fns[s->sew - 1]), \
+ s); \
+ } \
+ return false; \
+}
+
+GEN_OPFWF_WIDEN_BFA_TRANS(vfwadd_wf)
+GEN_OPFWF_WIDEN_BFA_TRANS(vfwsub_wf)
/* Vector Single-Width Floating-Point Multiply/Divide Instructions */
-GEN_OPFVV_TRANS(vfmul_vv, opfvv_check)
+GEN_OPFVV_BFA_TRANS(vfmul_vv, opfvv_check, vfmul_vv_h_bf16)
GEN_OPFVV_TRANS(vfdiv_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmul_vf, opfvf_check)
+GEN_OPFVF_BFA_TRANS(vfmul_vf, opfvf_check, vfmul_vf_h_bf16)
GEN_OPFVF_TRANS(vfdiv_vf, opfvf_check)
GEN_OPFVF_TRANS(vfrdiv_vf, opfvf_check)
/* Vector Widening Floating-Point Multiply */
-GEN_OPFVV_WIDEN_TRANS(vfwmul_vv, opfvv_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmul_vf, opfvf_widen_check)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmul_vv, opfvv_widen_check, vfwmul_vv_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmul_vf, opfvf_widen_check, vfwmul_vf_h_bf16)
/* Vector Single-Width Floating-Point Fused Multiply-Add Instructions */
-GEN_OPFVV_TRANS(vfmacc_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmacc_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmsac_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmsac_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmsub_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmsub_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmacc_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmacc_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmsac_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmsac_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmadd_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmadd_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmsub_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmsub_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfmacc_vv, opfvv_check, vfmacc_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmacc_vv, opfvv_check, vfnmacc_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmsac_vv, opfvv_check, vfmsac_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmsac_vv, opfvv_check, vfnmsac_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmadd_vv, opfvv_check, vfmadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmadd_vv, opfvv_check, vfnmadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmsub_vv, opfvv_check, vfmsub_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmsub_vv, opfvv_check, vfnmsub_vv_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmacc_vf, opfvf_check, vfmacc_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmacc_vf, opfvf_check, vfnmacc_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmsac_vf, opfvf_check, vfmsac_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmsac_vf, opfvf_check, vfnmsac_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmadd_vf, opfvf_check, vfmadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmadd_vf, opfvf_check, vfnmadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmsub_vf, opfvf_check, vfmsub_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmsub_vf, opfvf_check, vfnmsub_vf_h_bf16)
/* Vector Widening Floating-Point Fused Multiply-Add Instructions */
-GEN_OPFVV_WIDEN_TRANS(vfwmacc_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwnmacc_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwmsac_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwnmsac_vv, opfvv_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmacc_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwnmacc_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmsac_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmacc_vv, opfvv_overwrite_widen_check,
+ vfwmaccbf16_vv)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwnmacc_vv, opfvv_overwrite_widen_check,
+ vfwnmacc_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmsac_vv, opfvv_overwrite_widen_check,
+ vfwmsac_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwnmsac_vv, opfvv_overwrite_widen_check,
+ vfwnmsac_vv_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmacc_vf, opfvf_overwrite_widen_check,
+ vfwmaccbf16_vf)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwnmacc_vf, opfvf_overwrite_widen_check,
+ vfwnmacc_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmsac_vf, opfvf_overwrite_widen_check,
+ vfwmsac_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check,
+ vfwnmsac_vf_h_bf16)
/* Vector Floating-Point Square-Root Instruction */
@@ -2660,21 +2788,23 @@ GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check)
* If the current SEW does not correspond to a supported IEEE floating-point
* type, an illegal instruction exception is raised
*/
-static bool opfv_check(DisasContext *s, arg_rmr *a)
+static bool opfv_check(DisasContext *s, arg_rmr *a, int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
/* OPFV instructions ignore vs1 check */
- vext_check_ss(s, a->rd, a->rs2, a->vm);
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
static bool do_opfv(DisasContext *s, arg_rmr *a,
gen_helper_gvec_3_ptr *fn,
- bool (*checkfn)(DisasContext *, arg_rmr *),
- int rm)
+ bool (*checkfn)(DisasContext *, arg_rmr *, int8_t),
+ int rm,
+ int8_t valid_bfa_vsew)
{
- if (checkfn(s, a)) {
+ if (checkfn(s, a, valid_bfa_vsew)) {
uint32_t data = 0;
gen_set_rm_chkfrm(s, rm);
@@ -2692,76 +2822,95 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
return false;
}
-#define GEN_OPFV_TRANS(NAME, CHECK, FRM) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- static gen_helper_gvec_3_ptr * const fns[3] = { \
- gen_helper_##NAME##_h, \
- gen_helper_##NAME##_w, \
- gen_helper_##NAME##_d \
- }; \
- return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM); \
+#define GEN_OPFV_TRANS(NAME, CHECK, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ gen_helper_##NAME##_d \
+ }; \
+ return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM, -1); \
+}
+
+#define GEN_OPFV_BFA_TRANS(NAME, CHECK, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, \
+ gen_helper_##NAME##_d \
+ }; \
+ return do_opfv(s, a, \
+ (s->altfmt ? gen_helper_##NAME##_h_bf16 : \
+ fns[s->sew - 1]), \
+ CHECK, FRM, MO_16); \
}
GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
-GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
-GEN_OPFV_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN)
/* Vector Floating-Point MIN/MAX Instructions */
-GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmax_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmin_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmax_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfmin_vv, opfvv_check, vfmin_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmax_vv, opfvv_check, vfmax_vv_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmin_vf, opfvf_check, vfmin_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmax_vf, opfvf_check, vfmax_vf_h_bf16)
/* Vector Floating-Point Sign-Injection Instructions */
-GEN_OPFVV_TRANS(vfsgnj_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsgnjn_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsgnjx_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfsgnj_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfsgnjn_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfsgnjx_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfsgnj_vv, opfvv_check, vfsgnj_vv_h)
+GEN_OPFVV_BFA_TRANS(vfsgnjn_vv, opfvv_check, vfsgnjn_vv_h)
+GEN_OPFVV_BFA_TRANS(vfsgnjx_vv, opfvv_check, vfsgnjx_vv_h)
+GEN_OPFVF_BFA_TRANS(vfsgnj_vf, opfvf_check, vfsgnj_vf_h)
+GEN_OPFVF_BFA_TRANS(vfsgnjn_vf, opfvf_check, vfsgnjn_vf_h)
+GEN_OPFVF_BFA_TRANS(vfsgnjx_vf, opfvf_check, vfsgnjx_vf_h)
/* Vector Floating-Point Compare Instructions */
-static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_mss(s, a->rd, a->rs1, a->rs2);
+ vext_check_mss(s, a->rd, a->rs1, a->rs2) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmfne_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmflt_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmfle_vv, opfvv_cmp_check)
+GEN_OPFVV_BFA_TRANS(vmfeq_vv, opfvv_cmp_check, vmfeq_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmfne_vv, opfvv_cmp_check, vmfne_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmflt_vv, opfvv_cmp_check, vmflt_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmfle_vv, opfvv_cmp_check, vmfle_vv_h_bf16)
-static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
- vext_check_ms(s, a->rd, a->rs2);
+ vext_check_ms(s, a->rd, a->rs2) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-GEN_OPFVF_TRANS(vmfeq_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfne_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmflt_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
+GEN_OPFVF_BFA_TRANS(vmfeq_vf, opfvf_cmp_check, vmfeq_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfne_vf, opfvf_cmp_check, vmfne_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmflt_vf, opfvf_cmp_check, vmflt_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfle_vf, opfvf_cmp_check, vmfle_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfgt_vf, opfvf_cmp_check, vmfgt_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfge_vf, opfvf_cmp_check, vmfge_vf_h_bf16)
/* Vector Floating-Point Classify Instruction */
-GEN_OPFV_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
/* Vector Floating-Point Merge Instruction */
-GEN_OPFVF_TRANS(vfmerge_vfm, opfvf_check)
+GEN_OPFVF_BFA_TRANS(vfmerge_vfm, opfvf_check, vfmerge_vfm_h)
static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
{
if (require_rvv(s) &&
require_rvf(s) &&
vext_check_isa_ill(s) &&
- require_align(a->rd, s->lmul)) {
+ require_align(a->rd, s->lmul) &&
+ vext_check_altfmt(s, MO_16)) {
gen_set_rm(s, RISCV_FRM_DYN);
TCGv_i64 t1;
@@ -2782,7 +2931,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
static gen_helper_vmv_vx * const fns[3] = {
gen_helper_vmv_v_x_h,
gen_helper_vmv_v_x_w,
- gen_helper_vmv_v_x_d,
+ gen_helper_vmv_v_x_d
};
t1 = tcg_temp_new_i64();
@@ -2803,15 +2952,15 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
}
/* Single-Width Floating-Point/Integer Type-Convert Instructions */
-#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- static gen_helper_gvec_3_ptr * const fns[3] = { \
- gen_helper_##HELPER##_h, \
- gen_helper_##HELPER##_w, \
- gen_helper_##HELPER##_d \
- }; \
- return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM); \
+#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w, \
+ gen_helper_##HELPER##_d \
+ }; \
+ return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM, -1); \
}
GEN_OPFV_CVT_TRANS(vfcvt_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_DYN)
@@ -2835,95 +2984,129 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
vext_check_ds(s, a->rd, a->rs2, a->vm);
}
-static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opxfv_widen_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return opfv_widen_check(s, a) &&
- require_rvf(s);
+ require_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opffv_widen_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return opfv_widen_check(s, a) &&
require_rvfmin(s) &&
- require_scale_rvfmin(s);
-}
-
-#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- if (CHECK(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_3_ptr * const fns[2] = { \
- gen_helper_##HELPER##_h, \
- gen_helper_##HELPER##_w, \
- }; \
- gen_set_rm_chkfrm(s, FRM); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew - 1]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
+ require_scale_rvfmin(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
+}
+
+#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (CHECK(s, a, -1)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[2] = { \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w, \
+ }; \
+ gen_set_rm_chkfrm(s, FRM); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ fns[s->sew - 1]); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
+}
+
+#define GEN_OPFV_WIDEN_BFA_TRANS(NAME, CHECK, HELPER, FRM, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[2] = { \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w, \
+ }; \
+ gen_set_rm_chkfrm(s, FRM); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
}
GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
RISCV_FRM_DYN)
GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
RISCV_FRM_DYN)
-GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v,
- RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_BFA_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v,
+ RISCV_FRM_DYN, vfwcvtbf16_f_f_v)
/* Reuse the helper functions from vfwcvt.xu.f.v and vfwcvt.x.f.v */
GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
RISCV_FRM_RTZ)
GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
RISCV_FRM_RTZ)
-static bool opfxv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opfxv_widen_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
/* OPFV widening instructions ignore vs1 check */
- vext_check_ds(s, a->rd, a->rs2, a->vm);
+ vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-#define GEN_OPFXV_WIDEN_TRANS(NAME) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- if (opfxv_widen_check(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_3_ptr * const fns[3] = { \
- gen_helper_##NAME##_b, \
- gen_helper_##NAME##_h, \
- gen_helper_##NAME##_w, \
- }; \
- gen_set_rm(s, RISCV_FRM_DYN); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
+#define GEN_OPFXV_WIDEN_BFA_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (opfxv_widen_check(s, a, MO_8)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
+ gen_helper_##NAME##_b, \
+ gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w \
+ }; \
+ gen_set_rm(s, RISCV_FRM_DYN); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##NAME##_b_bf16 : \
+ fns[s->sew])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
}
-GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_xu_v)
-GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_x_v)
+GEN_OPFXV_WIDEN_BFA_TRANS(vfwcvt_f_xu_v)
+GEN_OPFXV_WIDEN_BFA_TRANS(vfwcvt_f_x_v)
/* Narrowing Floating-Point/Integer Type-Convert Instructions */
@@ -2939,104 +3122,140 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
vext_check_sd(s, a->rd, a->rs2, a->vm);
}
-static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return opfv_narrow_check(s, a) &&
require_rvf(s) &&
- (s->sew != MO_64);
+ (s->sew != MO_64) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opffv_narrow_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return opfv_narrow_check(s, a) &&
require_rvfmin(s) &&
- require_scale_rvfmin(s);
+ require_scale_rvfmin(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return opfv_narrow_check(s, a) &&
require_rvf(s) &&
- require_scale_rvf(s);
-}
-
-#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- if (CHECK(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_3_ptr * const fns[2] = { \
- gen_helper_##HELPER##_h, \
- gen_helper_##HELPER##_w, \
- }; \
- gen_set_rm_chkfrm(s, FRM); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew - 1]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
+ require_scale_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
+}
+
+#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (CHECK(s, a, -1)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[2] = { \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w, \
+ }; \
+ gen_set_rm_chkfrm(s, FRM); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ fns[s->sew - 1]); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
+}
+
+#define GEN_OPFV_NARROW_BFA_TRANS(NAME, CHECK, HELPER, FRM, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (CHECK(s, a, MO_16)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[2] = { \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w, \
+ }; \
+ gen_set_rm_chkfrm(s, FRM); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##BFA_HELPER : \
+ fns[s->sew - 1])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
}
GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, opfxv_narrow_check, vfncvt_f_xu_w,
RISCV_FRM_DYN)
GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, opfxv_narrow_check, vfncvt_f_x_w,
RISCV_FRM_DYN)
-GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
- RISCV_FRM_DYN)
+GEN_OPFV_NARROW_BFA_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
+ RISCV_FRM_DYN, vfncvtbf16_f_f_w)
/* Reuse the helper function from vfncvt.f.f.w */
-GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_rod_narrow_check, vfncvt_f_f_w,
- RISCV_FRM_ROD)
+GEN_OPFV_NARROW_BFA_TRANS(vfncvt_rod_f_f_w, opffv_rod_narrow_check,
+ vfncvt_f_f_w, RISCV_FRM_ROD, vfncvtbf16_f_f_w)
-static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a,
+ int8_t valid_bfa_vsew)
{
return require_rvv(s) &&
require_scale_rvf(s) &&
vext_check_isa_ill(s) &&
/* OPFV narrowing instructions ignore vs1 check */
- vext_check_sd(s, a->rd, a->rs2, a->vm);
+ vext_check_sd(s, a->rd, a->rs2, a->vm) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-#define GEN_OPXFV_NARROW_TRANS(NAME, HELPER, FRM) \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
-{ \
- if (opxfv_narrow_check(s, a)) { \
- uint32_t data = 0; \
- static gen_helper_gvec_3_ptr * const fns[3] = { \
- gen_helper_##HELPER##_b, \
- gen_helper_##HELPER##_h, \
- gen_helper_##HELPER##_w, \
- }; \
- gen_set_rm_chkfrm(s, FRM); \
- \
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
- tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), tcg_env, \
- s->cfg_ptr->vlenb, \
- s->cfg_ptr->vlenb, data, \
- fns[s->sew]); \
- finalize_rvv_inst(s); \
- return true; \
- } \
- return false; \
+#define GEN_OPXFV_NARROW_BFA_TRANS(NAME, HELPER, FRM) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (opxfv_narrow_check(s, a, MO_8)) { \
+ uint32_t data = 0; \
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
+ gen_helper_##HELPER##_b, \
+ gen_helper_##HELPER##_h, \
+ gen_helper_##HELPER##_w \
+ }; \
+ gen_set_rm_chkfrm(s, FRM); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+ vreg_ofs(s, a->rs2), tcg_env, \
+ s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data, \
+ (s->altfmt ? gen_helper_##HELPER##_b_bf16 : \
+ fns[s->sew])); \
+ finalize_rvv_inst(s); \
+ return true; \
+ } \
+ return false; \
}
-GEN_OPXFV_NARROW_TRANS(vfncvt_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_DYN)
-GEN_OPXFV_NARROW_TRANS(vfncvt_x_f_w, vfncvt_x_f_w, RISCV_FRM_DYN)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_DYN)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_x_f_w, vfncvt_x_f_w, RISCV_FRM_DYN)
/* Reuse the helper functions from vfncvt.xu.f.w and vfncvt.x.f.w */
-GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_RTZ)
-GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_x_f_w, vfncvt_x_f_w, RISCV_FRM_RTZ)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_rtz_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_RTZ)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_rtz_x_f_w, vfncvt_x_f_w, RISCV_FRM_RTZ)
/*
*** Vector Reduction Operations
@@ -3069,10 +3288,12 @@ GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check)
GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check)
/* Vector Single-Width Floating-Point Reduction Instructions */
-static bool freduction_check(DisasContext *s, arg_rmrr *a)
+static bool freduction_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return reduction_check(s, a) &&
- require_rvf(s);
+ require_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
GEN_OPFVV_TRANS(vfredusum_vs, freduction_check)
@@ -3081,11 +3302,13 @@ GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
/* Vector Widening Floating-Point Reduction Instructions */
-static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
+static bool freduction_widen_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return reduction_widen_check(s, a) &&
require_rvf(s) &&
- require_scale_rvf(s);
+ require_scale_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
@@ -3500,7 +3723,8 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
{
if (require_rvv(s) &&
require_rvf(s) &&
- vext_check_isa_ill(s)) {
+ vext_check_isa_ill(s) &&
+ vext_check_altfmt(s, MO_16)) {
gen_set_rm(s, RISCV_FRM_DYN);
/* The instructions ignore LMUL and vector register group. */
@@ -3594,20 +3818,24 @@ GEN_OPIVX_VSLIDE1_TRANS(vslide1up_vx, slideup_check)
GEN_OPIVX_VSLIDE1_TRANS(vslide1down_vx, slidedown_check)
/* Vector Floating-Point Slide Instructions */
-static bool fslideup_check(DisasContext *s, arg_rmrr *a)
+static bool fslideup_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return slideup_check(s, a) &&
- require_rvf(s);
+ require_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
+static bool fslidedown_check(DisasContext *s, arg_rmrr *a,
+ int8_t valid_bfa_vsew)
{
return slidedown_check(s, a) &&
- require_rvf(s);
+ require_rvf(s) &&
+ vext_check_altfmt(s, valid_bfa_vsew);
}
-GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check)
-GEN_OPFVF_TRANS(vfslide1down_vf, fslidedown_check)
+GEN_OPFVF_BFA_TRANS(vfslide1up_vf, fslideup_check, vfslide1up_vf_h)
+GEN_OPFVF_BFA_TRANS(vfslide1down_vf, fslidedown_check, vfslide1down_vf_h)
/* Vector Register Gather Instruction */
static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 35/51] target/riscv: Expose Zvfbfa extension as a cpu property
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (33 preceding siblings ...)
2026-04-29 4:47 ` [PULL 34/51] target/riscv: rvv: Support Zvfbfa vector bf16 operations alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 36/51] target/riscv: rvv: Allow fractional LMUL on vector SHA instructions alistair23
` (16 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260402125234.1371897-10-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index bbab96385b..38286b6b40 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1266,6 +1266,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
+ MULTI_EXT_CFG_BOOL("zvfbfa", ext_zvfbfa, false),
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 36/51] target/riscv: rvv: Allow fractional LMUL on vector SHA instructions
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (34 preceding siblings ...)
2026-04-29 4:47 ` [PULL 35/51] target/riscv: Expose Zvfbfa extension as a cpu property alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 37/51] target/riscv: tt-ascalon: Add Tenstorrent mvendorid alistair23
` (15 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Anton Blanchard, Alistair Francis
From: Anton Blanchard <antonb@tenstorrent.com>
Vector SHA instructions incorrectly raise an illegal instruction exception
when LMUL < 1. The ISA only states that LMUL*VLEN >= EGW:
For element-group instructions, LMUL*VLEN must always be at least as
large as EGW, otherwise an illegal-instruction exception is raised, even
if vl=0.
There is already a check for this:
MAXSZ(s) >= egw_bytes
so just remove the check for a fractional LMUL.
Signed-off-by: Anton Blanchard <antonb@tenstorrent.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Message-ID: <20260104233724.192886-1-antonb@tenstorrent.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvvk.c.inc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
index 27bf3f0b68..32255d3aa0 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -426,8 +426,7 @@ static bool vsha_check(DisasContext *s, arg_rmrr *a)
vsha_check_sew(s) &&
MAXSZ(s) >= egw_bytes &&
!is_overlapped(a->rd, mult, a->rs1, mult) &&
- !is_overlapped(a->rd, mult, a->rs2, mult) &&
- s->lmul >= 0;
+ !is_overlapped(a->rd, mult, a->rs2, mult);
}
GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 37/51] target/riscv: tt-ascalon: Add Tenstorrent mvendorid
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (35 preceding siblings ...)
2026-04-29 4:47 ` [PULL 36/51] target/riscv: rvv: Allow fractional LMUL on vector SHA instructions alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 38/51] hw/riscv/boot: Warn if a ELF format file is loaded as a binary alistair23
` (14 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Joel Stanley, Michael Ellerman, Alistair Francis
From: Joel Stanley <joel@jms.id.au>
JEP106 has two vendor IDs for Tenstorrent. We will use Bank 16, company 33:
((16 - 1) << 7) | 33 = 0x7a1
As JEP106 requires registration to download, the number can confirmed by
looking at the OpenOCD sources[1].
Alternatively, referring to the JEDEC document the hex IDs are listed with the
parity (MSB) bit added. Company 33 has hex 0xa1:
((16 - 1) << 7) | (0xa1 & ~0x80) = 0x7a1
Add it to the Ascalon CPU definition as the mvendorid CSR.
[1] https://github.com/openocd-org/openocd/blob/1ebff3ab33c77e3f8fb4e1ddda262b606b572af1/src/helper/jep106.inc#L1935
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Michael Ellerman <mpe@oss.tenstorrent.com>
Message-ID: <20260114020516.982305-1-joel@jms.id.au>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_vendorid.h | 2 ++
target/riscv/cpu.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
index f1ffc66542..751a13aace 100644
--- a/target/riscv/cpu_vendorid.h
+++ b/target/riscv/cpu_vendorid.h
@@ -8,4 +8,6 @@
#define VEYRON_V1_MIMPID 0x111
#define VEYRON_V1_MVENDORID 0x61f
+#define TENSTORRENT_VENDOR_ID 0x7a1
+
#endif /* TARGET_RISCV_CPU_VENDORID_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 38286b6b40..72c6f4f0f1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3207,6 +3207,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
.cfg.ext_svnapot = true,
.cfg.ext_svpbmt = true,
+ .cfg.mvendorid = TENSTORRENT_VENDOR_ID,
+
.cfg.max_satp_mode = VM_1_10_SV57,
),
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 38/51] hw/riscv/boot: Warn if a ELF format file is loaded as a binary
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (36 preceding siblings ...)
2026-04-29 4:47 ` [PULL 37/51] target/riscv: tt-ascalon: Add Tenstorrent mvendorid alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 39/51] target/riscv: fix RV32 stateen CSR handling alistair23
` (13 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Nicholas Piggin, Joel Stanley, Alistair Francis
From: Nicholas Piggin <npiggin@gmail.com>
It is possible that an ELF file can not be loaded, in that
case the loader falls back to loading the file as a binary
blob. Print a warning in this case because it is likely that
it is not intended.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260415064838.652297-4-joel@jms.id.au>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/boot.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index e5490beda0..9086793b7a 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -163,13 +163,27 @@ hwaddr riscv_load_firmware(const char *firmware_filename,
g_assert(firmware_filename != NULL);
- if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
- &firmware_entry, NULL, &firmware_end, NULL,
- 0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
+ firmware_size = load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
+ &firmware_entry, NULL, &firmware_end,
+ NULL, 0, EM_RISCV, 1, 0, NULL, false,
+ sym_cb);
+ if (firmware_size > 0) {
*firmware_load_addr = firmware_entry;
return firmware_end;
}
+ if (firmware_size != ELF_LOAD_NOT_ELF) {
+ /*
+ * If the user specified an ELF format firmware that could not be
+ * loaded as an ELF, it's possible that loading it as a binary is
+ * not what was intended.
+ */
+ warn_report("could not load ELF format firmware '%s' (%s). "
+ "Attempting to load as binary.",
+ firmware_filename,
+ load_elf_strerror(firmware_size));
+ }
+
firmware_size = load_image_targphys_as(firmware_filename,
*firmware_load_addr,
current_machine->ram_size, NULL,
@@ -179,7 +193,8 @@ hwaddr riscv_load_firmware(const char *firmware_filename,
return *firmware_load_addr + firmware_size;
}
- error_report("could not load firmware '%s'", firmware_filename);
+ error_report("could not load firmware '%s': %s", firmware_filename,
+ load_elf_strerror(firmware_size));
exit(1);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 39/51] target/riscv: fix RV32 stateen CSR handling
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (37 preceding siblings ...)
2026-04-29 4:47 ` [PULL 38/51] hw/riscv/boot: Warn if a ELF format file is loaded as a binary alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 40/51] target/riscv: Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer alistair23
` (12 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Bruno Sa, Alistair Francis
From: Bruno Sa <bruno.vilaca.sa@gmail.com>
The RV32 stateen CSRs are split between the low-half CSR and the
corresponding xH CSR, but the current implementation still handles some
upper-half bits through the low-half write paths and also accepts the
xH CSRs on RV64.
Fix this by:
- rejecting mstateen*h and hstateen*h accesses on RV64
- keeping the RV64-only writable bits in the low-half write paths
- handling the RV32 upper-half writable bits in write_mstateen0h() and
write_hstateen0h()
- dropping unsupported writable bits from write_sstateen0()
Signed-off-by: Bruno Sa <bruno.vilaca.sa@gmail.com>
Message-ID: <20260410110928.1014170-1-bruno.vilaca.sa@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 117 ++++++++++++++++++++++++++++++++-------------
1 file changed, 83 insertions(+), 34 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index cfd076b368..80727aa81e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -502,6 +502,15 @@ static RISCVException mstateen(CPURISCVState *env, int csrno)
return any(env, csrno);
}
+static RISCVException mstateen_32(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return mstateen(env, csrno);
+}
+
static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
{
if (!riscv_cpu_cfg(env)->ext_smstateen) {
@@ -533,6 +542,10 @@ static RISCVException hstateen(CPURISCVState *env, int csrno)
static RISCVException hstateenh(CPURISCVState *env, int csrno)
{
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
}
@@ -3447,25 +3460,29 @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
wr_mask |= SMSTATEEN0_FCSR;
}
- if (env->priv_ver >= PRIV_VERSION_1_13_0) {
- wr_mask |= SMSTATEEN0_P1P13;
- }
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
+ if (env->priv_ver >= PRIV_VERSION_1_13_0) {
+ wr_mask |= SMSTATEEN0_P1P13;
+ }
- if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
- wr_mask |= SMSTATEEN0_SVSLCT;
- }
+ if (riscv_cpu_cfg(env)->ext_smaia ||
+ riscv_cpu_cfg(env)->ext_smcsrind) {
+ wr_mask |= SMSTATEEN0_SVSLCT;
+ }
- /*
- * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
- * implemented. However, that information is with MachineState and we can't
- * figure that out in csr.c. Just enable if Smaia is available.
- */
- if (riscv_cpu_cfg(env)->ext_smaia) {
- wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
- }
+ /*
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid
+ * only if IMSIC is implemented. However, that information is
+ * with MachineState and we can't figure that out in csr.c.
+ * Just enable if Smaia is available.
+ */
+ if (riscv_cpu_cfg(env)->ext_smaia) {
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
+ }
- if (riscv_cpu_cfg(env)->ext_ssctr) {
- wr_mask |= SMSTATEEN0_CTR;
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
}
return write_mstateen(env, csrno, wr_mask, new_val);
@@ -3507,6 +3524,20 @@ static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
wr_mask |= SMSTATEEN0_P1P13;
}
+ if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
+ wr_mask |= SMSTATEEN0_SVSLCT;
+ }
+
+ /*
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if
+ * IMSIC is implemented. However, that information is with
+ * MachineState and we can't figure that out in csr.c. Just enable
+ * if Smaia is available.
+ */
+ if (riscv_cpu_cfg(env)->ext_smaia) {
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
+ }
+
if (riscv_cpu_cfg(env)->ext_ssctr) {
wr_mask |= SMSTATEEN0_CTR;
}
@@ -3552,21 +3583,25 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
wr_mask |= SMSTATEEN0_FCSR;
}
- if (riscv_cpu_cfg(env)->ext_ssaia || riscv_cpu_cfg(env)->ext_sscsrind) {
- wr_mask |= SMSTATEEN0_SVSLCT;
- }
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
+ if (riscv_cpu_cfg(env)->ext_ssaia ||
+ riscv_cpu_cfg(env)->ext_sscsrind) {
+ wr_mask |= SMSTATEEN0_SVSLCT;
+ }
- /*
- * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
- * implemented. However, that information is with MachineState and we can't
- * figure that out in csr.c. Just enable if Ssaia is available.
- */
- if (riscv_cpu_cfg(env)->ext_ssaia) {
- wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
- }
+ /*
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid
+ * only if IMSIC is implemented. However, that information is
+ * with MachineState and we can't figure that out in csr.c.
+ * Just enable if Ssaia is available.
+ */
+ if (riscv_cpu_cfg(env)->ext_ssaia) {
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
+ }
- if (riscv_cpu_cfg(env)->ext_ssctr) {
- wr_mask |= SMSTATEEN0_CTR;
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
}
return write_hstateen(env, csrno, wr_mask, new_val);
@@ -3608,6 +3643,20 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (riscv_cpu_cfg(env)->ext_ssaia || riscv_cpu_cfg(env)->ext_sscsrind) {
+ wr_mask |= SMSTATEEN0_SVSLCT;
+ }
+
+ /*
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if
+ * IMSIC is implemented. However, that information is with
+ * MachineState and we can't figure that out in csr.c. Just enable
+ * if Ssaia is available.
+ */
+ if (riscv_cpu_cfg(env)->ext_ssaia) {
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
+ }
+
if (riscv_cpu_cfg(env)->ext_ssctr) {
wr_mask |= SMSTATEEN0_CTR;
}
@@ -3657,7 +3706,7 @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
target_ulong new_val, uintptr_t ra)
{
- uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ uint64_t wr_mask = 0;
if (!riscv_has_ext(env, RVF)) {
wr_mask |= SMSTATEEN0_FCSR;
@@ -5937,25 +5986,25 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
/* Smstateen extension CSRs */
[CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
+ [CSR_MSTATEEN0H] = { "mstateen0h", mstateen_32, read_mstateenh,
write_mstateen0h,
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
write_mstateen_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
+ [CSR_MSTATEEN1H] = { "mstateen1h", mstateen_32, read_mstateenh,
write_mstateenh_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
write_mstateen_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
+ [CSR_MSTATEEN2H] = { "mstateen2h", mstateen_32, read_mstateenh,
write_mstateenh_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
write_mstateen_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
+ [CSR_MSTATEEN3H] = { "mstateen3h", mstateen_32, read_mstateenh,
write_mstateenh_1_3,
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 40/51] target/riscv: Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (38 preceding siblings ...)
2026-04-29 4:47 ` [PULL 39/51] target/riscv: fix RV32 stateen CSR handling alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 41/51] target/riscv: Mask xepc[0] only when Zc* extension is enabled alistair23
` (11 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Max Chou, Nutty Liu,
Philippe Mathieu-Daudé, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
Use designated initializers to initialize riscv_excp_names[] and
riscv_intr_names[] so that we don't have to explicitly add "reserved"
items. Also, add the missing trap names: sw_check, hw_error,
virt_illegal_instruction, semihost, s_guest_external, and
counter_overflow.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421071107.2848439-1-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 89 +++++++++++++++++++++++-----------------------
1 file changed, 45 insertions(+), 44 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 72c6f4f0f1..ce15a17c37 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -328,60 +328,61 @@ const char * const riscv_rvv_regnames[] = {
};
static const char * const riscv_excp_names[] = {
- "misaligned_fetch",
- "fault_fetch",
- "illegal_instruction",
- "breakpoint",
- "misaligned_load",
- "fault_load",
- "misaligned_store",
- "fault_store",
- "user_ecall",
- "supervisor_ecall",
- "hypervisor_ecall",
- "machine_ecall",
- "exec_page_fault",
- "load_page_fault",
- "reserved",
- "store_page_fault",
- "double_trap",
- "reserved",
- "reserved",
- "reserved",
- "guest_exec_page_fault",
- "guest_load_page_fault",
- "reserved",
- "guest_store_page_fault",
+ [RISCV_EXCP_INST_ADDR_MIS] = "misaligned_fetch",
+ [RISCV_EXCP_INST_ACCESS_FAULT] = "fault_fetch",
+ [RISCV_EXCP_ILLEGAL_INST] = "illegal_instruction",
+ [RISCV_EXCP_BREAKPOINT] = "breakpoint",
+ [RISCV_EXCP_LOAD_ADDR_MIS] = "misaligned_load",
+ [RISCV_EXCP_LOAD_ACCESS_FAULT] = "fault_load",
+ [RISCV_EXCP_STORE_AMO_ADDR_MIS] = "misaligned_store",
+ [RISCV_EXCP_STORE_AMO_ACCESS_FAULT] = "fault_store",
+ [RISCV_EXCP_U_ECALL] = "user_ecall",
+ [RISCV_EXCP_S_ECALL] = "supervisor_ecall",
+ [RISCV_EXCP_VS_ECALL] = "hypervisor_ecall",
+ [RISCV_EXCP_M_ECALL] = "machine_ecall",
+ [RISCV_EXCP_INST_PAGE_FAULT] = "exec_page_fault",
+ [RISCV_EXCP_LOAD_PAGE_FAULT] = "load_page_fault",
+ [RISCV_EXCP_STORE_PAGE_FAULT] = "store_page_fault",
+ [RISCV_EXCP_DOUBLE_TRAP] = "double_trap",
+ [RISCV_EXCP_SW_CHECK] = "sw_check",
+ [RISCV_EXCP_HW_ERR] = "hw_error",
+ [RISCV_EXCP_INST_GUEST_PAGE_FAULT] = "guest_exec_page_fault",
+ [RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT] = "guest_load_page_fault",
+ [RISCV_EXCP_VIRT_INSTRUCTION_FAULT] = "virt_illegal_instruction",
+ [RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT] = "guest_store_page_fault",
+ [RISCV_EXCP_SEMIHOST] = "semihost",
};
static const char * const riscv_intr_names[] = {
- "u_software",
- "s_software",
- "vs_software",
- "m_software",
- "u_timer",
- "s_timer",
- "vs_timer",
- "m_timer",
- "u_external",
- "s_external",
- "vs_external",
- "m_external",
- "reserved",
- "reserved",
- "reserved",
- "reserved"
+ [IRQ_U_SOFT] = "u_software",
+ [IRQ_S_SOFT] = "s_software",
+ [IRQ_VS_SOFT] = "vs_software",
+ [IRQ_M_SOFT] = "m_software",
+ [IRQ_U_TIMER] = "u_timer",
+ [IRQ_S_TIMER] = "s_timer",
+ [IRQ_VS_TIMER] = "vs_timer",
+ [IRQ_M_TIMER] = "m_timer",
+ [IRQ_U_EXT] = "u_external",
+ [IRQ_S_EXT] = "s_external",
+ [IRQ_VS_EXT] = "vs_external",
+ [IRQ_M_EXT] = "m_external",
+ [IRQ_S_GEXT] = "s_guest_external",
+ [IRQ_PMU_OVF] = "counter_overflow",
};
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
{
if (async) {
- return (cause < ARRAY_SIZE(riscv_intr_names)) ?
- riscv_intr_names[cause] : "(unknown)";
+ if ((cause < ARRAY_SIZE(riscv_intr_names)) && riscv_intr_names[cause]) {
+ return riscv_intr_names[cause];
+ }
} else {
- return (cause < ARRAY_SIZE(riscv_excp_names)) ?
- riscv_excp_names[cause] : "(unknown)";
+ if ((cause < ARRAY_SIZE(riscv_excp_names)) && riscv_excp_names[cause]) {
+ return riscv_excp_names[cause];
+ }
}
+
+ return "(unknown)";
}
void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext)
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 41/51] target/riscv: Mask xepc[0] only when Zc* extension is enabled
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (39 preceding siblings ...)
2026-04-29 4:47 ` [PULL 40/51] target/riscv: Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 42/51] target/riscv: Generate access fault if sc comparison fails alistair23
` (10 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
IALIGN is 16 when the CPU supports the Zc* extension. Only xepc[0]
should be masked when the Zc* extension is enabled.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421074940.2916287-1-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/internals.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b001cbc080..ab8dea45c9 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -173,9 +173,15 @@ static inline float16 check_nanbox_bf16(CPURISCVState *env, uint64_t f)
static inline target_ulong get_xepc_mask(CPURISCVState *env)
{
- /* When IALIGN=32, both low bits must be zero.
- * When IALIGN=16 (has C extension), only bit 0 must be zero. */
- if (riscv_has_ext(env, RVC)) {
+ RISCVCPU *cpu = env_archcpu(env);
+
+ /*
+ * When IALIGN=32, both low bits must be zero.
+ * When IALIGN=16 (has C or Zc* extensions), only bit 0 must be zero.
+ */
+ if (riscv_has_ext(env, RVC) || cpu->cfg.ext_zca ||
+ cpu->cfg.ext_zcb || cpu->cfg.ext_zcd || cpu->cfg.ext_zce ||
+ cpu->cfg.ext_zcf || cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) {
return ~(target_ulong)1;
} else {
return ~(target_ulong)3;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 42/51] target/riscv: Generate access fault if sc comparison fails
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (40 preceding siblings ...)
2026-04-29 4:47 ` [PULL 41/51] target/riscv: Mask xepc[0] only when Zc* extension is enabled alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 43/51] target/riscv: Don't OR mip.SEIP when mvien is one alistair23
` (9 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Alistair Francis, qemu-stable
From: Alistair Francis <alistair.francis@wdc.com>
The RISC-V spec states:
"For the purposes of memory protection, a failed SC.W may be treated
like a store."
So if the comparison in sc.w fails we should still check for alignment
and do a probe access to check permissions.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3323
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3136
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260415233740.3027321-2-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/helper.h | 3 +++
target/riscv/op_helper.c | 14 ++++++++++++++
target/riscv/insn_trans/trans_rva.c.inc | 6 ++++++
3 files changed, 23 insertions(+)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 54d2331966..36cdacfb0e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1351,3 +1351,6 @@ DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_1(ssamoswap_disabled, void, env)
#endif
+
+/* Zalrsc SC write probe */
+DEF_HELPER_FLAGS_3(sc_probe_write, TCG_CALL_NO_WG, void, env, tl, tl)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index dde40a5549..81873014cb 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -267,6 +267,20 @@ void helper_cbo_inval(CPURISCVState *env, target_ulong address)
/* We don't emulate the cache-hierarchy, so we're done. */
}
+void helper_sc_probe_write(CPURISCVState *env, target_ulong addr,
+ target_ulong size)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = riscv_env_mmu_index(env, false);
+
+ if (addr & (size - 1)) {
+ env->badaddr = addr;
+ riscv_raise_exception(env, RISCV_EXCP_STORE_AMO_ADDR_MIS, ra);
+ }
+
+ probe_write(env, addr, size, mmu_idx, ra);
+}
+
#ifndef CONFIG_USER_ONLY
target_ulong helper_sret(CPURISCVState *env)
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index a7a3278d24..62c0fe673d 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -90,6 +90,12 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
*/
TCGBar bar_strl = (ctx->ztso || a->rl) ? TCG_BAR_STRL : 0;
tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + bar_strl);
+ /*
+ * "For the purposes of memory protection, a failed SC.W may be treated
+ * like a store." so let's check the write access permissions
+ */
+ gen_helper_sc_probe_write(tcg_env, src1,
+ tcg_constant_tl(memop_size(mop)));
gen_set_gpr(ctx, a->rd, tcg_constant_tl(1));
gen_set_label(l2);
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 43/51] target/riscv: Don't OR mip.SEIP when mvien is one
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (41 preceding siblings ...)
2026-04-29 4:47 ` [PULL 42/51] target/riscv: Generate access fault if sc comparison fails alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 44/51] target/riscv: Use ELEN for Fractional LMUL check alistair23
` (8 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Alistair Francis, qemu-stable, Nutty Liu
From: Alistair Francis <alistair.francis@wdc.com>
The RISC-V spec states that
"""
But when bit 9 of mvien is one, bit SEIP in mip is read-only and does
not include the value of bit 9 of mvip. Rather, the value of mip.SEIP
is simply the supervisor external interrupt signal from the hart’s
external interrupt controller (APLIC or IMSIC).
"""
As such let's mark the mip.SEIP in rmw_mip64().
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2828
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Message-ID: <20260415233740.3027321-4-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 80727aa81e..da366cf562 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3728,6 +3728,14 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
uint64_t old_mip, mask = wr_mask & delegable_ints;
uint32_t gin;
+ /*
+ * When mvien[9]=1, mip.SEIP is read-only and reflects only
+ * the external interrupt signal from the interrupt controller.
+ */
+ if (env->mvien & MIP_SEIP) {
+ mask &= ~MIP_SEIP;
+ }
+
if (mask & MIP_SEIP) {
env->software_seip = new_val & MIP_SEIP;
new_val |= env->external_seip * MIP_SEIP;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 44/51] target/riscv: Use ELEN for Fractional LMUL check
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (42 preceding siblings ...)
2026-04-29 4:47 ` [PULL 43/51] target/riscv: Don't OR mip.SEIP when mvien is one alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 45/51] target/riscv: fix address masking alistair23
` (7 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Alistair Francis, qemu-stable, Max Chou
From: Alistair Francis <alistair.francis@wdc.com>
The RISC-V spec states that
"""
For a given supported fractional LMUL setting, implementations
must support SEW settings between SEWMIN and LMUL * ELEN, inclusive.
"""
We were previously checking VLEN, instead of ELEN, so let's update to
check ELEN instead of VLEN for fractional scaling.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3196
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Max Chou <max.chou@sifive.com>
Message-ID: <20260415233740.3027321-5-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/vector_helper.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 538168efc9..5a3554dd71 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -70,18 +70,17 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
bool ill_altfmt = true;
int xlen = riscv_cpu_xlen(env);
bool vill = (s2 >> (xlen - 1)) & 0x1;
- uint16_t vlen = cpu->cfg.vlenb << 3;
int8_t lmul;
if (vlmul & 4) {
/*
* Fractional LMUL, check:
*
- * VLEN * LMUL >= SEW
- * VLEN >> (8 - lmul) >= sew
- * (vlenb << 3) >> (8 - lmul) >= sew
+ * ELEN * LMUL >= SEW
+ * ELEN >> (8 - vlmul) >= sew
*/
- if (vlmul == 4 || (vlen >> (8 - vlmul)) < sew) {
+ if (vlmul == 4 ||
+ (cpu->cfg.elen >> (8 - vlmul)) < sew) {
vill = true;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 45/51] target/riscv: fix address masking
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (43 preceding siblings ...)
2026-04-29 4:47 ` [PULL 44/51] target/riscv: Use ELEN for Fractional LMUL check alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 46/51] target/riscv: Add a helper to return the current effective priv mode alistair23
` (6 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Yong-Xuan Wang, Daniel Henrique Barboza,
Alistair Francis
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
The pmlen should get the corresponding value before shifting address.
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-2-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/internals.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index ab8dea45c9..d090db2641 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -222,8 +222,8 @@ static inline target_ulong adjust_addr_body(CPURISCVState *env,
if (!is_virt_addr) {
signext = riscv_cpu_virt_mem_enabled(env);
}
- addr = addr << pmlen;
pmlen = riscv_pm_get_pmlen(pmm);
+ addr = addr << pmlen;
/* sign/zero extend masked address by N-1 bit */
if (signext) {
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 46/51] target/riscv: Add a helper to return the current effective priv mode
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (44 preceding siblings ...)
2026-04-29 4:47 ` [PULL 45/51] target/riscv: fix address masking alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 47/51] target/riscv: Fix pointer masking PMM field selection logic alistair23
` (5 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
This helper returns the current effective privilege mode.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-3-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 37 +++++++++++++++++++++++++++++++++++++
target/riscv/cpu_helper.c | 15 +++++----------
2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4c0676ed53..672f0dab0f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -806,6 +806,43 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
}
#endif
+/*
+ * Returns the current effective privilege mode.
+ *
+ * @env: CPURISCVState
+ * @priv: The returned effective privilege mode.
+ * @virt: The returned effective virtualization mode.
+ *
+ * Returns true if the effective privilege mode is modified.
+ */
+static inline QEMU_ALWAYS_INLINE
+bool riscv_cpu_eff_priv(CPURISCVState *env, int *priv, bool *virt)
+{
+ int mode = env->priv;
+ bool virt_enabled = false;
+ bool mode_modified = false;
+
+#ifndef CONFIG_USER_ONLY
+ if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+ mode = get_field(env->mstatus, MSTATUS_MPP);
+ virt_enabled = get_field(env->mstatus, MSTATUS_MPV) && (mode != PRV_M);
+ mode_modified = true;
+ } else {
+ virt_enabled = env->virt_enabled;
+ }
+#endif
+
+ if (priv) {
+ *priv = mode;
+ }
+
+ if (virt) {
+ *virt = virt_enabled;
+ }
+
+ return mode_modified;
+}
+
static inline bool riscv_cpu_allow_16bit_insn(const RISCVCPUConfig *cfg,
target_long priv_ver,
uint32_t misa_ext)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 659150c646..513bad21af 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -45,19 +45,14 @@ int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
#else
bool virt = env->virt_enabled;
int mode = env->priv;
+ bool mode_modified = false;
/* All priv -> mmu_idx mapping are here */
if (!ifetch) {
- uint64_t status = env->mstatus;
-
- if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) {
- mode = get_field(env->mstatus, MSTATUS_MPP);
- virt = get_field(env->mstatus, MSTATUS_MPV) &&
- (mode != PRV_M);
- if (virt) {
- status = env->vsstatus;
- }
- }
+ mode_modified = riscv_cpu_eff_priv(env, &mode, &virt);
+ uint64_t status = (mode_modified && virt) ? env->vsstatus :
+ env->mstatus;
+
if (mode == PRV_S && get_field(status, MSTATUS_SUM)) {
mode = MMUIdx_S_SUM;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 47/51] target/riscv: Fix pointer masking PMM field selection logic
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (45 preceding siblings ...)
2026-04-29 4:47 ` [PULL 46/51] target/riscv: Add a helper to return the current effective priv mode alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 48/51] target/riscv: Fix pointer masking for virtual-machine load/store insns alistair23
` (4 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Daniel Henrique Barboza,
Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
mstatus.MPV only records the previous virtualization state, and does not
affect pointer masking according to the Zjpm specification.
This patch rewrites riscv_pm_get_pmm() to follow the architectural
definition of Smmpm, Smnpm, and Ssnpm.
The resulting PMM selection logic for each mode is summarized below:
* mstatus.MXR = 1: pointer masking disabled
* Smmpm + Smnpm + Ssnpm:
M-mode: mseccfg.PMM
S-mode: menvcfg.PMM
U-mode: senvcfg.PMM
VS-mode: henvcfg.PMM
VU-mode: senvcfg.PMM
* Smmpm + Smnpm (RVS implemented):
M-mode: mseccfg.PMM
S-mode: menvcfg.PMM
U/VS/VU: disabled (Ssnpm not present)
* Smmpm + Smnpm (RVS not implemented):
M-mode: mseccfg.PMM
U-mode: menvcfg.PMM
S/VS/VU: disabled (no S-mode)
* Smmpm only:
M-mode: mseccfg.PMM
Other existing modes: pointer masking disabled
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-4-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_helper.c | 51 +++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 513bad21af..bab4153e53 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -131,13 +131,47 @@ bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt)
#endif
}
+/*
+ * Returns the effective PMM field.
+ *
+ * @env: CPURISCVState
+ *
+ * The PMM field selection logic for each effective privilege mode
+ * is as follows:
+ *
+ * - mstatus.MXR = 1: disabled
+ *
+ * - Smmpm + Smnpm + Ssnpm:
+ * M-mode: mseccfg.PMM
+ * S-mode: menvcfg.PMM
+ * U-mode: senvcfg.PMM
+ * VS-mode: henvcfg.PMM
+ * VU-mode: senvcfg.PMM
+ *
+ * - Smmpm + Smnpm (RVS implemented):
+ * M-mode: mseccfg.PMM
+ * S-mode: menvcfg.PMM
+ * U/VS/VU: disabled (Ssnpm not present)
+ *
+ * - Smmpm + Smnpm (RVS not implemented):
+ * M-mode: mseccfg.PMM
+ * U-mode: menvcfg.PMM
+ * S/VS/VU: disabled (no S-mode)
+ *
+ * - Smmpm only:
+ * M-mode: mseccfg.PMM
+ * Other existing modes: disabled
+ */
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
- int priv_mode = cpu_address_mode(env);
+ int priv_mode;
+ bool virt;
+
+ riscv_cpu_eff_priv(env, &priv_mode, &virt);
- if (get_field(env->mstatus, MSTATUS_MPRV) &&
- get_field(env->mstatus, MSTATUS_MXR)) {
+ if ((priv_mode != PRV_M && get_field(env->mstatus, MSTATUS_MXR)) ||
+ (virt && get_field(env->vsstatus, MSTATUS_MXR))) {
return PMM_FIELD_DISABLED;
}
@@ -149,12 +183,14 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
}
break;
case PRV_S:
- if (riscv_cpu_cfg(env)->ext_smnpm) {
- if (get_field(env->mstatus, MSTATUS_MPV)) {
- return get_field(env->henvcfg, HENVCFG_PMM);
- } else {
+ if (!virt) {
+ if (riscv_cpu_cfg(env)->ext_smnpm) {
return get_field(env->menvcfg, MENVCFG_PMM);
}
+ } else {
+ if (riscv_cpu_cfg(env)->ext_ssnpm) {
+ return get_field(env->henvcfg, HENVCFG_PMM);
+ }
}
break;
case PRV_U:
@@ -171,6 +207,7 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
default:
g_assert_not_reached();
}
+
return PMM_FIELD_DISABLED;
#else
return PMM_FIELD_DISABLED;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 48/51] target/riscv: Fix pointer masking for virtual-machine load/store insns
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (46 preceding siblings ...)
2026-04-29 4:47 ` [PULL 47/51] target/riscv: Fix pointer masking PMM field selection logic alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 49/51] target/riscv: Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm() alistair23
` (3 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
The effective privilege of explicit memory accesses made by
virtual-machine load/store instructions (HLV.* and HSV.*) is controlled
by hstatus.SPVP. mstatus.MPRV does not affect these virtual-machine
load/store instructions.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-5-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_helper.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index bab4153e53..2b3fea81d5 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -217,16 +217,23 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
- int priv_mode = cpu_address_mode(env);
+ int priv_mode;
+
+ if (!riscv_cpu_cfg(env)->ext_ssnpm ||
+ get_field(env->mstatus, MSTATUS_MXR) ||
+ get_field(env->vsstatus, MSTATUS_MXR)) {
+ return PMM_FIELD_DISABLED;
+ }
+
+ priv_mode = get_field(env->hstatus, HSTATUS_SPVP);
- if (priv_mode == PRV_U) {
- return get_field(env->hstatus, HSTATUS_HUPMM);
+ if (priv_mode == PRV_S) {
+ /* Effective privilege mode: VS */
+ return get_field(env->henvcfg, HENVCFG_PMM);
} else {
- if (get_field(env->hstatus, HSTATUS_SPVP)) {
- return get_field(env->henvcfg, HENVCFG_PMM);
- } else {
- return get_field(env->senvcfg, SENVCFG_PMM);
- }
+ /* Effective privilege mode: VU */
+ return (env->priv == PRV_U) ? get_field(env->hstatus, HSTATUS_HUPMM) :
+ get_field(env->senvcfg, SENVCFG_PMM);
}
#else
return PMM_FIELD_DISABLED;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 49/51] target/riscv: Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm()
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (47 preceding siblings ...)
2026-04-29 4:47 ` [PULL 48/51] target/riscv: Fix pointer masking for virtual-machine load/store insns alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 50/51] target/riscv: Fix pointer masking translation mode check bug alistair23
` (2 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Daniel Henrique Barboza,
Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm() to better
reflect its actual usage. This function is used when checking the PMM
field for virtual-machine load/store instructions (HLV.* and HSV.*),
rather than for VS/VU modes.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-6-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 2 +-
target/riscv/internals.h | 2 +-
target/riscv/cpu_helper.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 672f0dab0f..138183e017 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -890,7 +890,7 @@ bool riscv_cpu_is_32bit(RISCVCPU *cpu);
bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
-RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env);
+RISCVPmPmm riscv_pm_get_vm_ldst_pmm(CPURISCVState *env);
uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm);
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index d090db2641..7eb6edbe90 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -209,7 +209,7 @@ static inline target_ulong adjust_addr_body(CPURISCVState *env,
/* get pmm field depending on whether addr is */
if (is_virt_addr) {
- pmm = riscv_pm_get_virt_pmm(env);
+ pmm = riscv_pm_get_vm_ldst_pmm(env);
} else {
pmm = riscv_pm_get_pmm(env);
}
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2b3fea81d5..ef1ff7cb0b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -214,7 +214,7 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
#endif
}
-RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env)
+RISCVPmPmm riscv_pm_get_vm_ldst_pmm(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
int priv_mode;
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 50/51] target/riscv: Fix pointer masking translation mode check bug
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (48 preceding siblings ...)
2026-04-29 4:47 ` [PULL 49/51] target/riscv: Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm() alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 4:47 ` [PULL 51/51] target/riscv: rvv: Handle mask/source overlap of vector reduction instructions alistair23
2026-04-29 16:23 ` [PULL 00/51] riscv-to-apply queue Stefan Hajnoczi
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Frank Chang, Radim Krčmář,
Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
When running with virtualization in VS/VU mode, or when executing the
virtual-machine load/store instructions (HLV.* and HSV.*), the type of
address that determines which pointer masking rules apply should be
checked against vsatp rather than satp.
As a result, sign extension also applies to the virtual-machine
load/store instructions.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260421093715.2995067-7-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 2 +-
target/riscv/internals.h | 4 +---
target/riscv/cpu_helper.c | 19 +++++++++++++++----
target/riscv/tcg/tcg-cpu.c | 4 ++--
4 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 138183e017..81c41e3429 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -888,7 +888,7 @@ static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
-bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env, bool is_vm_ldst);
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
RISCVPmPmm riscv_pm_get_vm_ldst_pmm(CPURISCVState *env);
uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm);
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 7eb6edbe90..bac6c8032a 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -219,9 +219,7 @@ static inline target_ulong adjust_addr_body(CPURISCVState *env,
return addr;
}
- if (!is_virt_addr) {
- signext = riscv_cpu_virt_mem_enabled(env);
- }
+ signext = riscv_cpu_virt_mem_enabled(env, is_virt_addr);
pmlen = riscv_pm_get_pmlen(pmm);
addr = addr << pmlen;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ef1ff7cb0b..39c3486ae0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -240,16 +240,27 @@ RISCVPmPmm riscv_pm_get_vm_ldst_pmm(CPURISCVState *env)
#endif
}
-bool riscv_cpu_virt_mem_enabled(CPURISCVState *env)
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env, bool is_vm_ldst)
{
#ifndef CONFIG_USER_ONLY
int satp_mode = 0;
- int priv_mode = cpu_address_mode(env);
+ uint64_t satp;
+ int priv_mode;
+ bool virt = false;
+
+ if (!is_vm_ldst) {
+ riscv_cpu_eff_priv(env, &priv_mode, &virt);
+ } else {
+ priv_mode = get_field(env->hstatus, HSTATUS_SPVP);
+ virt = true;
+ }
+
+ satp = virt ? env->vsatp : env->satp;
if (riscv_cpu_mxl(env) == MXL_RV32) {
- satp_mode = get_field(env->satp, SATP32_MODE);
+ satp_mode = get_field(satp, SATP32_MODE);
} else {
- satp_mode = get_field(env->satp, SATP64_MODE);
+ satp_mode = get_field(satp, SATP64_MODE);
}
return ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M));
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index f3f7808895..02c98cc2db 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -105,7 +105,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
RISCVExtStatus fs, vs;
uint32_t flags = 0;
uint64_t ext_flags = 0;
- bool pm_signext = riscv_cpu_virt_mem_enabled(env);
+ bool pm_signext = riscv_cpu_virt_mem_enabled(env, false);
if (cpu->cfg.ext_zve32x) {
/*
@@ -260,7 +260,7 @@ static vaddr riscv_pointer_wrap(CPUState *cs, int mmu_idx,
return result;
}
- pm_signext = riscv_cpu_virt_mem_enabled(env);
+ pm_signext = riscv_cpu_virt_mem_enabled(env, false);
if (pm_signext) {
return sextract64(result, 0, 64 - pm_len);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PULL 51/51] target/riscv: rvv: Handle mask/source overlap of vector reduction instructions
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (49 preceding siblings ...)
2026-04-29 4:47 ` [PULL 50/51] target/riscv: Fix pointer masking translation mode check bug alistair23
@ 2026-04-29 4:47 ` alistair23
2026-04-29 16:23 ` [PULL 00/51] riscv-to-apply queue Stefan Hajnoczi
51 siblings, 0 replies; 54+ messages in thread
From: alistair23 @ 2026-04-29 4:47 UTC (permalink / raw)
To: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel
Cc: alistair23, Anton Blanchard, Alistair Francis
From: Anton Blanchard <antonb@tenstorrent.com>
Masked vector reduction instructions must not use v0 as a source register.
Check rs1 and rs2 against the mask register when vm=0.
Signed-off-by: Anton Blanchard <antonb@tenstorrent.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Message-ID: <20260417120626.77415-1-antonb@tenstorrent.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvv.c.inc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 5b72926b3c..e65356eb7c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3265,6 +3265,8 @@ static bool reduction_check(DisasContext *s, arg_rmrr *a)
{
return require_rvv(s) &&
vext_check_isa_ill(s) &&
+ require_vm(a->vm, a->rs1) &&
+ require_vm(a->vm, a->rs2) &&
vext_check_reduction(s, a->rs2);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PULL 00/51] riscv-to-apply queue
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
` (50 preceding siblings ...)
2026-04-29 4:47 ` [PULL 51/51] target/riscv: rvv: Handle mask/source overlap of vector reduction instructions alistair23
@ 2026-04-29 16:23 ` Stefan Hajnoczi
51 siblings, 0 replies; 54+ messages in thread
From: Stefan Hajnoczi @ 2026-04-29 16:23 UTC (permalink / raw)
To: alistair23
Cc: palmer, liwei1518, daniel.barboza, zhiwei_liu, chao.liu.zevorn,
qemu-riscv, qemu-devel, alistair23, Alistair Francis
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin)
2026-04-29 4:47 ` [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin) alistair23
@ 2026-04-30 18:14 ` Michael Tokarev
0 siblings, 0 replies; 54+ messages in thread
From: Michael Tokarev @ 2026-04-30 18:14 UTC (permalink / raw)
To: alistair23, palmer, liwei1518, daniel.barboza, zhiwei_liu,
chao.liu.zevorn, qemu-riscv, qemu-devel
Cc: Munkhbaatar Enkhbaatar, Alistair Francis, Tao Tang,
Philippe Mathieu-Daudé, qemu-stable
On 29.04.2026 07:47, alistair23@gmail.com wrote:
> From: Munkhbaatar Enkhbaatar <munkhuu0825@gmail.com>
>
> Prevents huge allocations and crashes caused by malformed HTIF signature
> addresses.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3205
> Signed-off-by: Munkhbaatar Enkhbaatar <munkhuu0825@gmail.com>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Message-ID: <20251209085349.61510-1-munkhuu0825@gmail.com>
> [ Squashed with following commit to fix build failures
> hw/char/riscv_htif: Fix format specifier for uint64_t
>
> Message-ID: <20260415134826.1742308-1-chao.liu.zevorn@gmail.com>
> Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
> ]
> Tested-by: Tao Tang <tangtao1634@phytium.com.cn>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> hw/char/riscv_htif.c | 6 ++++++
> 1 file changed, 6 insertions(+)
This change, it looks like, should be part of stable qemu series.
I'm picking it up, please let me know if I shouldn't.
Thanks,
/mjt
^ permalink raw reply [flat|nested] 54+ messages in thread
end of thread, other threads:[~2026-04-30 18:15 UTC | newest]
Thread overview: 54+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-29 4:47 [PULL 00/51] riscv-to-apply queue alistair23
2026-04-29 4:47 ` [PULL 01/51] hw/riscv/riscv-iommu: Use standard EN_PRI bit for PRI alistair23
2026-04-29 4:47 ` [PULL 02/51] util: export CRC32[C] lookup tables alistair23
2026-04-29 4:47 ` [PULL 03/51] target/riscv: add draft RISC-V Zbr ext as xbr0p93 alistair23
2026-04-29 4:47 ` [PULL 04/51] disas: diassemble RISC-V xlrbr (crc32) instructions alistair23
2026-04-29 4:47 ` [PULL 05/51] target/riscv: Use explicit little-endian LD/ST API alistair23
2026-04-29 4:47 ` [PULL 06/51] target/riscv: Make LQ and SQ use 128-bit ld/st alistair23
2026-04-29 4:47 ` [PULL 07/51] target/riscv: Remove MTTCG check for x-rv128 CPU model alistair23
2026-04-29 4:47 ` [PULL 08/51] target/riscv: Explode MO_TExx -> MO_TE | MO_xx (again) alistair23
2026-04-29 4:47 ` [PULL 09/51] target/riscv: Conceal MO_ALIGN|MO_TE within load_acquire / store_release alistair23
2026-04-29 4:47 ` [PULL 10/51] target/riscv: Factor tiny ldn() helper in gdbstub alistair23
2026-04-29 4:47 ` [PULL 11/51] target/riscv: Simplify riscv_cpu_gdb_write_register() alistair23
2026-04-29 4:47 ` [PULL 12/51] target/riscv: Expose mo_endian_env() alistair23
2026-04-29 4:47 ` [PULL 13/51] target/riscv: Have gdbstub consider CPU endianness alistair23
2026-04-29 4:47 ` [PULL 14/51] target/riscv: Replace MO_TE by mo_endian (MIPS extension) alistair23
2026-04-29 4:47 ` [PULL 15/51] target/riscv: Replace MO_TE by mo_endian (Zilsd extension) alistair23
2026-04-29 4:47 ` [PULL 16/51] target/riscv: Replace MO_TE by mo_endian (Zalasr extension) alistair23
2026-04-29 4:47 ` [PULL 17/51] target/riscv: Replace MO_TE -> MO_LE alistair23
2026-04-29 4:47 ` [PULL 18/51] target/riscv: Use MO_LE for instruction fetch alistair23
2026-04-29 4:47 ` [PULL 19/51] configs/targets: Forbid RISC-V to use legacy native endianness APIs alistair23
2026-04-29 4:47 ` [PULL 20/51] hw/riscv/riscv-iommu-hpm: Fix irq_overflow_left residual value bug alistair23
2026-04-29 4:47 ` [PULL 21/51] hw/riscv/riscv-iommu: Add IPSR.PMIP RW1C support alistair23
2026-04-29 4:47 ` [PULL 22/51] hw/riscv/virt-acpi-build.c: Use kvm timer frequency when kvm enabled alistair23
2026-04-29 4:47 ` [PULL 23/51] target/riscv: fix stale ptshift and base on page walk restart alistair23
2026-04-29 4:47 ` [PULL 24/51] hw/intc: fix heap OOB in ACLINT MTIMER multi-socket alistair23
2026-04-29 4:47 ` [PULL 25/51] riscv_htif: reject invalid signature ranges (end <= begin) alistair23
2026-04-30 18:14 ` Michael Tokarev
2026-04-29 4:47 ` [PULL 26/51] target/riscv: preserve RV32 henvcfgh on henvcfg writes alistair23
2026-04-29 4:47 ` [PULL 27/51] target/riscv: Add cfg properties for Zvfbfa extensions alistair23
2026-04-29 4:47 ` [PULL 28/51] target/riscv: Add the Zvfbfa extension implied rule alistair23
2026-04-29 4:47 ` [PULL 29/51] target/riscv: rvv: Add new VTYPE CSR field - altfmt alistair23
2026-04-29 4:47 ` [PULL 30/51] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR alistair23
2026-04-29 4:47 ` [PULL 31/51] target/riscv: Use the tb->cs_base as the extend tb flags alistair23
2026-04-29 4:47 ` [PULL 32/51] target/riscv: Introduce altfmt into DisasContext alistair23
2026-04-29 4:47 ` [PULL 33/51] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension alistair23
2026-04-29 4:47 ` [PULL 34/51] target/riscv: rvv: Support Zvfbfa vector bf16 operations alistair23
2026-04-29 4:47 ` [PULL 35/51] target/riscv: Expose Zvfbfa extension as a cpu property alistair23
2026-04-29 4:47 ` [PULL 36/51] target/riscv: rvv: Allow fractional LMUL on vector SHA instructions alistair23
2026-04-29 4:47 ` [PULL 37/51] target/riscv: tt-ascalon: Add Tenstorrent mvendorid alistair23
2026-04-29 4:47 ` [PULL 38/51] hw/riscv/boot: Warn if a ELF format file is loaded as a binary alistair23
2026-04-29 4:47 ` [PULL 39/51] target/riscv: fix RV32 stateen CSR handling alistair23
2026-04-29 4:47 ` [PULL 40/51] target/riscv: Initialize riscv_excp_names[] and riscv_intr_names[] using designated initializer alistair23
2026-04-29 4:47 ` [PULL 41/51] target/riscv: Mask xepc[0] only when Zc* extension is enabled alistair23
2026-04-29 4:47 ` [PULL 42/51] target/riscv: Generate access fault if sc comparison fails alistair23
2026-04-29 4:47 ` [PULL 43/51] target/riscv: Don't OR mip.SEIP when mvien is one alistair23
2026-04-29 4:47 ` [PULL 44/51] target/riscv: Use ELEN for Fractional LMUL check alistair23
2026-04-29 4:47 ` [PULL 45/51] target/riscv: fix address masking alistair23
2026-04-29 4:47 ` [PULL 46/51] target/riscv: Add a helper to return the current effective priv mode alistair23
2026-04-29 4:47 ` [PULL 47/51] target/riscv: Fix pointer masking PMM field selection logic alistair23
2026-04-29 4:47 ` [PULL 48/51] target/riscv: Fix pointer masking for virtual-machine load/store insns alistair23
2026-04-29 4:47 ` [PULL 49/51] target/riscv: Rename riscv_pm_get_virt_pmm() to riscv_pm_get_vm_ldst_pmm() alistair23
2026-04-29 4:47 ` [PULL 50/51] target/riscv: Fix pointer masking translation mode check bug alistair23
2026-04-29 4:47 ` [PULL 51/51] target/riscv: rvv: Handle mask/source overlap of vector reduction instructions alistair23
2026-04-29 16:23 ` [PULL 00/51] riscv-to-apply queue Stefan Hajnoczi
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.