Merge patch series "target/riscv: Some updates to float point related extensions"
RISC-V defines a handful of extensions related to floating point, along
with various relationships between these and other extensions. This
patch set adds support for the Zvfh, Zvhfmin, and Zve64d extensions;
along with a handful of fixes and cleanups related to the other
floating-point extension relationships.
* b4-shazam-merge
target/riscv: Expose properties for Zv* extensions
target/riscv: Simplify check for EEW = 64 in trans_rvv.c.inc
target/riscv: Fix check for vector load/store instructions when EEW=64
target/riscv: Add support for Zvfh/zvfhmin extensions
target/riscv: Remove rebundunt check for zve32f and zve64f
target/riscv: Replace check for F/D to Zve32f/Zve64d in trans_rvv.c.inc
target/riscv: Simplify check for Zve32f and Zve64f
target/riscv: Indent fixes in cpu.c
target/riscv: Add propertie check for Zvfh{min} extensions
target/riscv: Fix relationship between V, Zve*, F and D
target/riscv: Add cfg properties for Zv* extensions
target/riscv: Simplify the check for Zfhmin and Zhinxmin
target/riscv: Fix the relationship between Zhinxmin and Zhinx
target/riscv: Fix the relationship between Zfhmin and Zfh
Message-ID: <20230215020539.4788-1-liweiwei@iscas.ac.cn>
[Palmer: commit text]
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 86c4adc..49f2c15 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -232,20 +232,21 @@
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
+ RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
+
cpu_phandle = (*phandle)++;
cpu_name = g_strdup_printf("/cpus/cpu@%d",
s->soc[socket].hartid_base + cpu);
qemu_fdt_add_subnode(ms->fdt, cpu_name);
- if (riscv_feature(&s->soc[socket].harts[cpu].env,
- RISCV_FEATURE_MMU)) {
+ if (cpu_ptr->cfg.mmu) {
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
(is_32_bit) ? "riscv,sv32" : "riscv,sv48");
} else {
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
"riscv,none");
}
- name = riscv_isa_string(&s->soc[socket].harts[cpu]);
+ name = riscv_isa_string(cpu_ptr);
qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
g_free(name);
qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b7f212c..9e726d1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -640,7 +640,7 @@
set_default_nan_mode(1, &env->fp_status);
#ifndef CONFIG_USER_ONLY
- if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+ if (cpu->cfg.debug) {
riscv_trigger_init(env);
}
@@ -958,24 +958,13 @@
}
}
- if (cpu->cfg.mmu) {
- riscv_set_feature(env, RISCV_FEATURE_MMU);
- }
-
- if (cpu->cfg.pmp) {
- riscv_set_feature(env, RISCV_FEATURE_PMP);
-
+ if (cpu->cfg.epmp && !cpu->cfg.pmp) {
/*
* Enhanced PMP should only be available
* on harts with PMP support
*/
- if (cpu->cfg.epmp) {
- riscv_set_feature(env, RISCV_FEATURE_EPMP);
- }
- }
-
- if (cpu->cfg.debug) {
- riscv_set_feature(env, RISCV_FEATURE_DEBUG);
+ error_setg(errp, "Invalid configuration: EPMP requires PMP support");
+ return;
}
@@ -1253,6 +1242,12 @@
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
+
+ /*
+ * write_misa() is marked as experimental for now so mark
+ * it with -x and default to 'false'.
+ */
+ DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7f5264e..d8e47b8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -81,17 +81,6 @@
#define RVH RV('H')
#define RVJ RV('J')
-/* S extension denotes that Supervisor mode exists, however it is possible
- to have a core that support S mode but does not have an MMU and there
- is currently no bit in misa to indicate whether an MMU exists or not
- so a cpu features bitfield is required, likewise for optional PMP support */
-enum {
- RISCV_FEATURE_MMU,
- RISCV_FEATURE_PMP,
- RISCV_FEATURE_EPMP,
- RISCV_FEATURE_MISA,
- RISCV_FEATURE_DEBUG
-};
/* Privileged specification version */
enum {
@@ -186,8 +175,6 @@
/* 128-bit helpers upper part return value */
target_ulong retxh;
- uint32_t features;
-
#ifdef CONFIG_USER_ONLY
uint32_t elf_flags;
#endif
@@ -501,6 +488,7 @@
bool pmp;
bool epmp;
bool debug;
+ bool misa_w;
bool short_isa_string;
};
@@ -538,16 +526,6 @@
return (env->misa_ext & ext) != 0;
}
-static inline bool riscv_feature(CPURISCVState *env, int feature)
-{
- return env->features & (1ULL << feature);
-}
-
-static inline void riscv_set_feature(CPURISCVState *env, int feature)
-{
- env->features |= (1ULL << feature);
-}
-
#include "cpu_user.h"
extern const char * const riscv_int_regnames[];
@@ -657,6 +635,11 @@
#endif
#define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
+static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
+{
+ return &env_archcpu(env)->cfg;
+}
+
#if defined(TARGET_RISCV32)
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
#else
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index a24a9fd..16667a3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -105,7 +105,7 @@
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
}
- if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
+ if (cpu->cfg.debug && !icount_enabled()) {
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
}
#endif
@@ -706,7 +706,7 @@
pmp_priv_t pmp_priv;
int pmp_index = -1;
- if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
+ if (!riscv_cpu_cfg(env)->pmp) {
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
@@ -796,7 +796,7 @@
mode = PRV_U;
}
- if (mode == PRV_M || !riscv_feature(env, RISCV_FEATURE_MMU)) {
+ if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
*physical = addr;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5b757c8..a1ecf62 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -418,7 +418,7 @@
static RISCVException pmp(CPURISCVState *env, int csrno)
{
- if (riscv_feature(env, RISCV_FEATURE_PMP)) {
+ if (riscv_cpu_cfg(env)->pmp) {
return RISCV_EXCP_NONE;
}
@@ -427,7 +427,7 @@
static RISCVException epmp(CPURISCVState *env, int csrno)
{
- if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (env->priv == PRV_M && riscv_cpu_cfg(env)->epmp) {
return RISCV_EXCP_NONE;
}
@@ -436,7 +436,7 @@
static RISCVException debug(CPURISCVState *env, int csrno)
{
- if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+ if (riscv_cpu_cfg(env)->debug) {
return RISCV_EXCP_NONE;
}
@@ -1328,7 +1328,7 @@
static RISCVException write_misa(CPURISCVState *env, int csrno,
target_ulong val)
{
- if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
+ if (!riscv_cpu_cfg(env)->misa_w) {
/* drop write to misa */
return RISCV_EXCP_NONE;
}
@@ -1355,9 +1355,6 @@
/* Mask extensions that are not supported by this hart */
val &= env->misa_ext_mask;
- /* Mask extensions that are not supported by QEMU */
- val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
-
/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
if ((val & RVD) && !(val & RVF)) {
val &= ~RVD;
@@ -2623,7 +2620,7 @@
static RISCVException read_satp(CPURISCVState *env, int csrno,
target_ulong *val)
{
- if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
+ if (!riscv_cpu_cfg(env)->mmu) {
*val = 0;
return RISCV_EXCP_NONE;
}
@@ -2642,7 +2639,7 @@
{
target_ulong vm, mask;
- if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
+ if (!riscv_cpu_cfg(env)->mmu) {
return RISCV_EXCP_NONE;
}
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index c6ce318..9c45593 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -27,9 +27,8 @@
static bool pmp_needed(void *opaque)
{
RISCVCPU *cpu = opaque;
- CPURISCVState *env = &cpu->env;
- return riscv_feature(env, RISCV_FEATURE_PMP);
+ return cpu->cfg.pmp;
}
static int pmp_post_load(void *opaque, int version_id)
@@ -226,9 +225,8 @@
static bool debug_needed(void *opaque)
{
RISCVCPU *cpu = opaque;
- CPURISCVState *env = &cpu->env;
- return riscv_feature(env, RISCV_FEATURE_DEBUG);
+ return cpu->cfg.debug;
}
static int debug_post_load(void *opaque, int version_id)
@@ -333,8 +331,8 @@
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
- .version_id = 6,
- .minimum_version_id = 6,
+ .version_id = 7,
+ .minimum_version_id = 7,
.post_load = riscv_cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
@@ -353,7 +351,6 @@
VMSTATE_UINT32(env.misa_ext, RISCVCPU),
VMSTATE_UINT32(env.misa_mxl_max, RISCVCPU),
VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
- VMSTATE_UINT32(env.features, RISCVCPU),
VMSTATE_UINTTL(env.priv, RISCVCPU),
VMSTATE_UINTTL(env.virt, RISCVCPU),
VMSTATE_UINT64(env.resetvec, RISCVCPU),
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 236f93b..f36ddfa 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -218,7 +218,7 @@
return;
}
- if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
+ if (!riscv_cpu_cfg(env)->mmu) {
monitor_printf(mon, "S-mode MMU unavailable\n");
return;
}
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 48f918b..9c0b91c 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -195,7 +195,7 @@
uint64_t mstatus = env->mstatus;
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
+ if (riscv_cpu_cfg(env)->pmp &&
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
}
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 4bc4113..a08cd95 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -88,7 +88,7 @@
if (pmp_index < MAX_RISCV_PMPS) {
bool locked = true;
- if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (riscv_cpu_cfg(env)->epmp) {
/* mseccfg.RLB is set */
if (MSECCFG_RLB_ISSET(env)) {
locked = false;
@@ -239,7 +239,7 @@
{
bool ret;
- if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (riscv_cpu_cfg(env)->epmp) {
if (MSECCFG_MMWP_ISSET(env)) {
/*
* The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
@@ -265,7 +265,7 @@
}
}
- if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
+ if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) {
/*
* Privileged spec v1.10 states if HW doesn't implement any PMP entry
* or no PMP entry matches an M-Mode access, the access succeeds.
@@ -315,7 +315,7 @@
}
if (size == 0) {
- if (riscv_feature(env, RISCV_FEATURE_MMU)) {
+ if (riscv_cpu_cfg(env)->mmu) {
/*
* If size is unknown (0), assume that all bytes
* from addr to the end of the page will be accessed.