aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-05-12 17:31:52 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-05-12 17:31:52 +0100
commit3e9f48bcdabe57f8f90cf19f01bbbf3c86937267 (patch)
tree5e0459fff6a822c59bb4fb8ea4b25bfd3be59b3c /target
parent31589644ba069ba06c5d0d8c6f01908ec1f79105 (diff)
parentc30a0757f094c107e491820e3d35224eb68859c7 (diff)
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210511' into staging
A large collection of RISC-V fixes, improvements and features - Clenaup some left over v1.9 code - Documentation improvements - Support for the shakti_c machine - Internal cleanup of the CSR accesses - Updates to the OpenTitan platform - Support for the virtio-vga - Fix for the saturate subtract in vector extensions - Experimental support for the ePMP spec - A range of other internal code cleanups and bug fixes # gpg: Signature made Tue 11 May 2021 11:17:10 BST # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full] # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair/tags/pull-riscv-to-apply-20210511: (42 commits) target/riscv: Fix the RV64H decode comment target/riscv: Consolidate RV32/64 16-bit instructions target/riscv: Consolidate RV32/64 32-bit instructions target/riscv: Remove an unused CASE_OP_32_64 macro target/riscv: Remove the unused HSTATUS_WPRI macro target/riscv: Remove the hardcoded SATP_MODE macro target/riscv: Remove the hardcoded MSTATUS_SD macro target/riscv: Remove the hardcoded HGATP_MODE macro target/riscv: Remove the hardcoded SSTATUS_SD macro target/riscv: Remove the hardcoded RVXLEN macro target/riscv: fix a typo with interrupt names fpu/softfloat: set invalid excp flag for RISC-V muladd instructions hw/riscv: Fix OT IBEX reset vector target/riscv: fix exception index on instruction access fault target/riscv: fix vrgather macro index variable type bug target/riscv: Add ePMP support for the Ibex CPU target/riscv/pmp: Remove outdated comment target/riscv: Add a config option for ePMP target/riscv: Implementation of enhanced PMP (ePMP) target/riscv: Add ePMP CSR access functions ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/cpu.c26
-rw-r--r--target/riscv/cpu.h42
-rw-r--r--target/riscv/cpu_bits.h114
-rw-r--r--target/riscv/cpu_helper.c88
-rw-r--r--target/riscv/csr.c824
-rw-r--r--target/riscv/fpu_helper.c16
-rw-r--r--target/riscv/gdbstub.c8
-rw-r--r--target/riscv/helper.h18
-rw-r--r--target/riscv/insn16-32.decode28
-rw-r--r--target/riscv/insn16-64.decode36
-rw-r--r--target/riscv/insn16.decode30
-rw-r--r--target/riscv/insn32-64.decode88
-rw-r--r--target/riscv/insn32.decode67
-rw-r--r--target/riscv/insn_trans/trans_rva.c.inc14
-rw-r--r--target/riscv/insn_trans/trans_rvd.c.inc17
-rw-r--r--target/riscv/insn_trans/trans_rvf.c.inc6
-rw-r--r--target/riscv/insn_trans/trans_rvh.c.inc8
-rw-r--r--target/riscv/insn_trans/trans_rvi.c.inc22
-rw-r--r--target/riscv/insn_trans/trans_rvm.c.inc12
-rw-r--r--target/riscv/insn_trans/trans_rvv.c.inc39
-rw-r--r--target/riscv/machine.c8
-rw-r--r--target/riscv/meson.build13
-rw-r--r--target/riscv/monitor.c22
-rw-r--r--target/riscv/op_helper.c18
-rw-r--r--target/riscv/pmp.c218
-rw-r--r--target/riscv/pmp.h14
-rw-r--r--target/riscv/trace-events3
-rw-r--r--target/riscv/translate.c38
-rw-r--r--target/riscv/vector_helper.c18
29 files changed, 1096 insertions, 759 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d6ed80f6b..3191fd0082 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -88,8 +88,8 @@ const char * const riscv_intr_names[] = {
"vs_timer",
"m_timer",
"u_external",
+ "s_external",
"vs_external",
- "h_external",
"m_external",
"reserved",
"reserved",
@@ -137,7 +137,7 @@ static void set_feature(CPURISCVState *env, int feature)
env->features |= (1ULL << feature);
}
-static void set_resetvec(CPURISCVState *env, int resetvec)
+static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
{
#ifndef CONFIG_USER_ONLY
env->resetvec = resetvec;
@@ -147,7 +147,11 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
static void riscv_any_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
- set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
+#if defined(TARGET_RISCV32)
+ set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
+#elif defined(TARGET_RISCV64)
+ set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
+#endif
set_priv_version(env, PRIV_VERSION_1_11_0);
}
@@ -202,6 +206,7 @@ static void rv32_ibex_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
+ qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
}
static void rv32_imafcu_nommu_cpu_init(Object *obj)
@@ -282,7 +287,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
}
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->sbadaddr);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
if (riscv_has_ext(env, RVH)) {
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
@@ -358,7 +363,7 @@ static void riscv_cpu_reset(DeviceState *dev)
env->pc = env->resetvec;
env->two_stage_lookup = false;
#endif
- cs->exception_index = EXCP_NONE;
+ cs->exception_index = RISCV_EXCP_NONE;
env->load_res = -1;
set_default_nan_mode(1, &env->fp_status);
}
@@ -412,6 +417,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
if (cpu->cfg.pmp) {
set_feature(env, RISCV_FEATURE_PMP);
+
+ /*
+ * Enhanced PMP should only be available
+ * on harts with PMP support
+ */
+ if (cpu->cfg.epmp) {
+ set_feature(env, RISCV_FEATURE_EPMP);
+ }
}
set_resetvec(env, cpu->cfg.resetvec);
@@ -554,6 +567,8 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
+
DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
DEFINE_PROP_END_OF_LIST(),
};
@@ -708,6 +723,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
#endif
};
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0a33d387ba..7e879fb9ca 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -38,6 +38,7 @@
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
+#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
#define TYPE_RISCV_CPU_SIFIVE_E34 RISCV_CPU_TYPE_NAME("sifive-e34")
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
@@ -53,12 +54,6 @@
#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
-#if defined(TARGET_RISCV32)
-#define RVXLEN RV32
-#elif defined(TARGET_RISCV64)
-#define RVXLEN RV64
-#endif
-
#define RV(x) ((target_ulong)1 << (x - 'A'))
#define RVI RV('I')
@@ -80,6 +75,7 @@
enum {
RISCV_FEATURE_MMU,
RISCV_FEATURE_PMP,
+ RISCV_FEATURE_EPMP,
RISCV_FEATURE_MISA
};
@@ -163,10 +159,8 @@ struct CPURISCVState {
target_ulong mie;
target_ulong mideleg;
- target_ulong sptbr; /* until: priv-1.9.1 */
target_ulong satp; /* since: priv-1.10.0 */
- target_ulong sbadaddr;
- target_ulong mbadaddr;
+ target_ulong stval;
target_ulong medeleg;
target_ulong stvec;
@@ -230,6 +224,7 @@ struct CPURISCVState {
/* physical memory protection */
pmp_table_t pmp_state;
+ target_ulong mseccfg;
/* machine specific rdtime callback */
uint64_t (*rdtime_fn)(uint32_t);
@@ -303,6 +298,7 @@ struct RISCVCPU {
uint16_t elen;
bool mmu;
bool pmp;
+ bool epmp;
uint64_t resetvec;
} cfg;
};
@@ -455,10 +451,13 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
*pflags = flags;
}
-int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask);
-int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask);
+RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask);
+RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value,
+ target_ulong write_mask);
static inline void riscv_csr_write(CPURISCVState *env, int csrno,
target_ulong val)
@@ -473,13 +472,16 @@ static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
return val;
}
-typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno);
-typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
- target_ulong *ret_value);
-typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
- target_ulong new_value);
-typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
- target_ulong *ret_value, target_ulong new_value, target_ulong write_mask);
+typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
+ int csrno);
+typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
+ target_ulong *ret_value);
+typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
+ target_ulong new_value);
+typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value,
+ target_ulong write_mask);
typedef struct {
const char *name;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599207..52640e6856 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -153,12 +153,6 @@
/* 32-bit only */
#define CSR_MSTATUSH 0x310
-/* Legacy Counter Setup (priv v1.9.1) */
-/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
-#define CSR_MUCOUNTEREN 0x320
-#define CSR_MSCOUNTEREN 0x321
-#define CSR_MHCOUNTEREN 0x322
-
/* Machine Trap Handling */
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
@@ -166,9 +160,6 @@
#define CSR_MTVAL 0x343
#define CSR_MIP 0x344
-/* Legacy Machine Trap Handling (priv v1.9.1) */
-#define CSR_MBADADDR 0x343
-
/* Supervisor Trap Setup */
#define CSR_SSTATUS 0x100
#define CSR_SEDELEG 0x102
@@ -184,9 +175,6 @@
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
-/* Legacy Supervisor Trap Handling (priv v1.9.1) */
-#define CSR_SBADADDR 0x143
-
/* Supervisor Protection and Translation */
#define CSR_SPTBR 0x180
#define CSR_SATP 0x180
@@ -207,17 +195,6 @@
#define CSR_HTIMEDELTA 0x605
#define CSR_HTIMEDELTAH 0x615
-#if defined(TARGET_RISCV32)
-#define HGATP_MODE SATP32_MODE
-#define HGATP_VMID SATP32_ASID
-#define HGATP_PPN SATP32_PPN
-#endif
-#if defined(TARGET_RISCV64)
-#define HGATP_MODE SATP64_MODE
-#define HGATP_VMID SATP64_ASID
-#define HGATP_PPN SATP64_PPN
-#endif
-
/* Virtual CSRs */
#define CSR_VSSTATUS 0x200
#define CSR_VSIE 0x204
@@ -232,6 +209,9 @@
#define CSR_MTINST 0x34a
#define CSR_MTVAL2 0x34b
+/* Enhanced Physical Memory Protection (ePMP) */
+#define CSR_MSECCFG 0x390
+#define CSR_MSECCFGH 0x391
/* Physical Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
@@ -354,14 +334,6 @@
#define CSR_MHPMCOUNTER30H 0xb9e
#define CSR_MHPMCOUNTER31H 0xb9f
-/* Legacy Machine Protection and Translation (priv v1.9.1) */
-#define CSR_MBASE 0x380
-#define CSR_MBOUND 0x381
-#define CSR_MIBASE 0x382
-#define CSR_MIBOUND 0x383
-#define CSR_MDBASE 0x384
-#define CSR_MDBOUND 0x385
-
/* mstatus CSR bits */
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
@@ -375,10 +347,8 @@
#define MSTATUS_FS 0x00006000
#define MSTATUS_XS 0x00018000
#define MSTATUS_MPRV 0x00020000
-#define MSTATUS_PUM 0x00040000 /* until: priv-1.9.1 */
#define MSTATUS_SUM 0x00040000 /* since: priv-1.10 */
#define MSTATUS_MXR 0x00080000
-#define MSTATUS_VM 0x1F000000 /* until: priv-1.9.1 */
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
@@ -398,16 +368,6 @@
#define MXL_RV64 2
#define MXL_RV128 3
-#if defined(TARGET_RISCV32)
-#define MSTATUS_SD MSTATUS32_SD
-#define MISA_MXL MISA32_MXL
-#define MXL_VAL MXL_RV32
-#elif defined(TARGET_RISCV64)
-#define MSTATUS_SD MSTATUS64_SD
-#define MISA_MXL MISA64_MXL
-#define MXL_VAL MXL_RV64
-#endif
-
/* sstatus CSR bits */
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
@@ -416,19 +376,12 @@
#define SSTATUS_SPP 0x00000100
#define SSTATUS_FS 0x00006000
#define SSTATUS_XS 0x00018000
-#define SSTATUS_PUM 0x00040000 /* until: priv-1.9.1 */
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
#define SSTATUS_MXR 0x00080000
#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000ULL
-#if defined(TARGET_RISCV32)
-#define SSTATUS_SD SSTATUS32_SD
-#elif defined(TARGET_RISCV64)
-#define SSTATUS_SD SSTATUS64_SD
-#endif
-
/* hstatus CSR bits */
#define HSTATUS_VSBE 0x00000020
#define HSTATUS_GVA 0x00000040
@@ -443,12 +396,6 @@
#define HSTATUS32_WPRI 0xFF8FF87E
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
-#if defined(TARGET_RISCV32)
-#define HSTATUS_WPRI HSTATUS32_WPRI
-#elif defined(TARGET_RISCV64)
-#define HSTATUS_WPRI HSTATUS64_WPRI
-#endif
-
#define HCOUNTEREN_CY (1 << 0)
#define HCOUNTEREN_TM (1 << 1)
#define HCOUNTEREN_IR (1 << 2)
@@ -479,17 +426,6 @@
#define SATP64_ASID 0x0FFFF00000000000ULL
#define SATP64_PPN 0x00000FFFFFFFFFFFULL
-#if defined(TARGET_RISCV32)
-#define SATP_MODE SATP32_MODE
-#define SATP_ASID SATP32_ASID
-#define SATP_PPN SATP32_PPN
-#endif
-#if defined(TARGET_RISCV64)
-#define SATP_MODE SATP64_MODE
-#define SATP_ASID SATP64_ASID
-#define SATP_PPN SATP64_PPN
-#endif
-
/* VM modes (mstatus.vm) privileged ISA 1.9.1 */
#define VM_1_09_MBARE 0
#define VM_1_09_MBB 1
@@ -527,27 +463,29 @@
#define DEFAULT_RSTVEC 0x1000
/* Exception causes */
-#define EXCP_NONE -1 /* sentinel value */
-#define RISCV_EXCP_INST_ADDR_MIS 0x0
-#define RISCV_EXCP_INST_ACCESS_FAULT 0x1
-#define RISCV_EXCP_ILLEGAL_INST 0x2
-#define RISCV_EXCP_BREAKPOINT 0x3
-#define RISCV_EXCP_LOAD_ADDR_MIS 0x4
-#define RISCV_EXCP_LOAD_ACCESS_FAULT 0x5
-#define RISCV_EXCP_STORE_AMO_ADDR_MIS 0x6
-#define RISCV_EXCP_STORE_AMO_ACCESS_FAULT 0x7
-#define RISCV_EXCP_U_ECALL 0x8
-#define RISCV_EXCP_S_ECALL 0x9
-#define RISCV_EXCP_VS_ECALL 0xa
-#define RISCV_EXCP_M_ECALL 0xb
-#define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
-#define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
-#define RISCV_EXCP_STORE_PAGE_FAULT 0xf /* since: priv-1.10.0 */
-#define RISCV_EXCP_SEMIHOST 0x10
-#define RISCV_EXCP_INST_GUEST_PAGE_FAULT 0x14
-#define RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT 0x15
-#define RISCV_EXCP_VIRT_INSTRUCTION_FAULT 0x16
-#define RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT 0x17
+typedef enum RISCVException {
+ RISCV_EXCP_NONE = -1, /* sentinel value */
+ RISCV_EXCP_INST_ADDR_MIS = 0x0,
+ RISCV_EXCP_INST_ACCESS_FAULT = 0x1,
+ RISCV_EXCP_ILLEGAL_INST = 0x2,
+ RISCV_EXCP_BREAKPOINT = 0x3,
+ RISCV_EXCP_LOAD_ADDR_MIS = 0x4,
+ RISCV_EXCP_LOAD_ACCESS_FAULT = 0x5,
+ RISCV_EXCP_STORE_AMO_ADDR_MIS = 0x6,
+ RISCV_EXCP_STORE_AMO_ACCESS_FAULT = 0x7,
+ RISCV_EXCP_U_ECALL = 0x8,
+ RISCV_EXCP_S_ECALL = 0x9,
+ RISCV_EXCP_VS_ECALL = 0xa,
+ RISCV_EXCP_M_ECALL = 0xb,
+ RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
+ RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
+ RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
+ RISCV_EXCP_SEMIHOST = 0x10,
+ RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
+ RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
+ RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
+ RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
+} RISCVException;
#define RISCV_EXCP_INT_FLAG 0x80000000
#define RISCV_EXCP_INT_MASK 0x7fffffff
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 21c54ef561..968cb8046f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -72,7 +72,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
if (irqs) {
return ctz64(irqs); /* since non-zero */
} else {
- return EXCP_NONE; /* indicates no pending interrupt */
+ return RISCV_EXCP_NONE; /* indicates no pending interrupt */
}
}
#endif
@@ -136,8 +136,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
env->vscause = env->scause;
env->scause = env->scause_hs;
- env->vstval = env->sbadaddr;
- env->sbadaddr = env->stval_hs;
+ env->vstval = env->stval;
+ env->stval = env->stval_hs;
env->vsatp = env->satp;
env->satp = env->satp_hs;
@@ -159,8 +159,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
env->scause_hs = env->scause;
env->scause = env->vscause;
- env->stval_hs = env->sbadaddr;
- env->sbadaddr = env->vstval;
+ env->stval_hs = env->stval;
+ env->stval = env->vstval;
env->satp_hs = env->satp;
env->satp = env->vsatp;
@@ -342,12 +342,14 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
* @first_stage: Are we in first stage translation?
* Second stage is used for hypervisor guest translation
* @two_stage: Are we going to perform two stage translation
+ * @is_debug: Is this access from a debugger or the monitor?
*/
static int get_physical_address(CPURISCVState *env, hwaddr *physical,
int *prot, target_ulong addr,
target_ulong *fault_pte_addr,
int access_type, int mmu_idx,
- bool first_stage, bool two_stage)
+ bool first_stage, bool two_stage,
+ bool is_debug)
{
/* NOTE: the env->pc value visible here will not be
* correct, but the value visible to the exception handler
@@ -403,20 +405,35 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
if (first_stage == true) {
if (use_background) {
- base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->vsatp, SATP_MODE);
+ if (riscv_cpu_is_32bit(env)) {
+ base = (hwaddr)get_field(env->vsatp, SATP32_PPN) << PGSHIFT;
+ vm = get_field(env->vsatp, SATP32_MODE);
+ } else {
+ base = (hwaddr)get_field(env->vsatp, SATP64_PPN) << PGSHIFT;
+ vm = get_field(env->vsatp, SATP64_MODE);
+ }
} else {
- base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->satp, SATP_MODE);
+ if (riscv_cpu_is_32bit(env)) {
+ base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP32_MODE);
+ } else {
+ base = (hwaddr)get_field(env->satp, SATP64_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP64_MODE);
+ }
}
widened = 0;
} else {
- base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
- vm = get_field(env->hgatp, HGATP_MODE);
+ if (riscv_cpu_is_32bit(env)) {
+ base = (hwaddr)get_field(env->hgatp, SATP32_PPN) << PGSHIFT;
+ vm = get_field(env->hgatp, SATP32_MODE);
+ } else {
+ base = (hwaddr)get_field(env->hgatp, SATP64_PPN) << PGSHIFT;
+ vm = get_field(env->hgatp, SATP64_MODE);
+ }
widened = 2;
}
/* status.SUM will be ignored if execute on background */
- sum = get_field(env->mstatus, MSTATUS_SUM) || use_background;
+ sum = get_field(env->mstatus, MSTATUS_SUM) || use_background || is_debug;
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -475,7 +492,8 @@ restart:
/* Do the second stage translation on the base PTE address. */
int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
base, NULL, MMU_DATA_LOAD,
- mmu_idx, false, true);
+ mmu_idx, false, true,
+ is_debug);
if (vbase_ret != TRANSLATE_SUCCESS) {
if (fault_pte_addr) {
@@ -615,16 +633,23 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
bool first_stage, bool two_stage)
{
CPUState *cs = env_cpu(env);
- int page_fault_exceptions;
+ int page_fault_exceptions, vm;
+ uint64_t stap_mode;
+
+ if (riscv_cpu_is_32bit(env)) {
+ stap_mode = SATP32_MODE;
+ } else {
+ stap_mode = SATP64_MODE;
+ }
+
if (first_stage) {
- page_fault_exceptions =
- get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
- !pmp_violation;
+ vm = get_field(env->satp, stap_mode);
} else {
- page_fault_exceptions =
- get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE &&
- !pmp_violation;
+ vm = get_field(env->hgatp, stap_mode);
}
+
+ page_fault_exceptions = vm != VM_1_10_MBARE && !pmp_violation;
+
switch (access_type) {
case MMU_INST_FETCH:
if (riscv_cpu_virt_enabled(env) && !first_stage) {
@@ -666,13 +691,13 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
int mmu_idx = cpu_mmu_index(&cpu->env, false);
if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx,
- true, riscv_cpu_virt_enabled(env))) {
+ true, riscv_cpu_virt_enabled(env), true)) {
return -1;
}
if (riscv_cpu_virt_enabled(env)) {
if (get_physical_address(env, &phys_addr, &prot, phys_addr, NULL,
- 0, mmu_idx, false, true)) {
+ 0, mmu_idx, false, true, true)) {
return -1;
}
}
@@ -691,8 +716,10 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
if (access_type == MMU_DATA_STORE) {
cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
- } else {
+ } else if (access_type == MMU_DATA_LOAD) {
cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
+ } else {
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
}
env->badaddr = addr;
@@ -768,7 +795,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
/* Two stage lookup */
ret = get_physical_address(env, &pa, &prot, address,
&env->guest_phys_fault_addr, access_type,
- mmu_idx, true, true);
+ mmu_idx, true, true, false);
/*
* A G-stage exception may be triggered during two state lookup.
@@ -790,7 +817,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
im_address = pa;
ret = get_physical_address(env, &pa, &prot2, im_address, NULL,
- access_type, mmu_idx, false, true);
+ access_type, mmu_idx, false, true,
+ false);
qemu_log_mask(CPU_LOG_MMU,
"%s 2nd-stage address=%" VADDR_PRIx " ret %d physical "
@@ -825,7 +853,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
} else {
/* Single stage lookup */
ret = get_physical_address(env, &pa, &prot, address, NULL,
- access_type, mmu_idx, true, false);
+ access_type, mmu_idx, true, false, false);
qemu_log_mask(CPU_LOG_MMU,
"%s address=%" VADDR_PRIx " ret %d physical "
@@ -1023,7 +1051,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->mstatus = s;
env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
env->sepc = env->pc;
- env->sbadaddr = tval;
+ env->stval = tval;
env->htval = htval;
env->pc = (env->stvec >> 2 << 2) +
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
@@ -1054,7 +1082,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->mstatus = s;
env->mcause = cause | ~(((target_ulong)-1) >> async);
env->mepc = env->pc;
- env->mbadaddr = tval;
+ env->mtval = tval;
env->mtval2 = mtval2;
env->pc = (env->mtvec >> 2 << 2) +
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
@@ -1069,5 +1097,5 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->two_stage_lookup = false;
#endif
- cs->exception_index = EXCP_NONE; /* mark handled to qemu */
+ cs->exception_index = RISCV_EXCP_NONE; /* mark handled to qemu */
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d2585395bf..fe5628fea6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -35,29 +35,29 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
}
/* Predicates */
-static int fs(CPURISCVState *env, int csrno)
+static RISCVException fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
/* loose check condition for fcsr in vector extension */
if ((csrno == CSR_FCSR) && (env->misa & RVV)) {
- return 0;
+ return RISCV_EXCP_NONE;
}
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int vs(CPURISCVState *env, int csrno)
+static RISCVException vs(CPURISCVState *env, int csrno)
{
if (env->misa & RVV) {
- return 0;
+ return RISCV_EXCP_NONE;
}
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
-static int ctr(CPURISCVState *env, int csrno)
+static RISCVException ctr(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
CPUState *cs = env_cpu(env);
@@ -65,7 +65,7 @@ static int ctr(CPURISCVState *env, int csrno)
if (!cpu->cfg.ext_counters) {
/* The Counters extensions is not enabled */
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
if (riscv_cpu_virt_enabled(env)) {
@@ -73,25 +73,25 @@ static int ctr(CPURISCVState *env, int csrno)
case CSR_CYCLE:
if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
get_field(env->mcounteren, HCOUNTEREN_CY)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIME:
if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
get_field(env->mcounteren, HCOUNTEREN_TM)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRET:
if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
get_field(env->mcounteren, HCOUNTEREN_IR)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
}
@@ -100,148 +100,174 @@ static int ctr(CPURISCVState *env, int csrno)
case CSR_CYCLEH:
if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
get_field(env->mcounteren, HCOUNTEREN_CY)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIMEH:
if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
get_field(env->mcounteren, HCOUNTEREN_TM)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRETH:
if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
get_field(env->mcounteren, HCOUNTEREN_IR)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
}
}
}
#endif
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int ctr32(CPURISCVState *env, int csrno)
+static RISCVException ctr32(CPURISCVState *env, int csrno)
{
if (!riscv_cpu_is_32bit(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
return ctr(env, csrno);
}
#if !defined(CONFIG_USER_ONLY)
-static int any(CPURISCVState *env, int csrno)
+static RISCVException any(CPURISCVState *env, int csrno)
{
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int any32(CPURISCVState *env, int csrno)
+static RISCVException any32(CPURISCVState *env, int csrno)
{
if (!riscv_cpu_is_32bit(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
return any(env, csrno);
}
-static int smode(CPURISCVState *env, int csrno)
+static RISCVException smode(CPURISCVState *env, int csrno)
{
- return -!riscv_has_ext(env, RVS);
+ if (riscv_has_ext(env, RVS)) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
}
-static int hmode(CPURISCVState *env, int csrno)
+static RISCVException hmode(CPURISCVState *env, int csrno)
{
if (riscv_has_ext(env, RVS) &&
riscv_has_ext(env, RVH)) {
/* Hypervisor extension is supported */
if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
env->priv == PRV_M) {
- return 0;
+ return RISCV_EXCP_NONE;
} else {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
}
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
-static int hmode32(CPURISCVState *env, int csrno)
+static RISCVException hmode32(CPURISCVState *env, int csrno)
{
if (!riscv_cpu_is_32bit(env)) {
- return 0;
+ if (riscv_cpu_virt_enabled(env)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ } else {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
}
return hmode(env, csrno);
}
-static int pmp(CPURISCVState *env, int csrno)
+static RISCVException pmp(CPURISCVState *env, int csrno)
+{
+ if (riscv_feature(env, RISCV_FEATURE_PMP)) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
+}
+
+static RISCVException epmp(CPURISCVState *env, int csrno)
{
- return -!riscv_feature(env, RISCV_FEATURE_PMP);
+ if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
/* User Floating-Point CSRs */
-static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_fflags(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
*val = riscv_cpu_get_fflags(env);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_fflags(CPURISCVState *env, int csrno,
+ target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
env->mstatus |= MSTATUS_FS;
#endif
riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_frm(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
*val = env->frm;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_frm(CPURISCVState *env, int csrno,
+ target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
env->mstatus |= MSTATUS_FS;
#endif
env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_fcsr(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
*val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
@@ -250,14 +276,15 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
*val |= (env->vxrm << FSR_VXRM_SHIFT)
| (env->vxsat << FSR_VXSAT_SHIFT);
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_fcsr(CPURISCVState *env, int csrno,
+ target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
env->mstatus |= MSTATUS_FS;
#endif
@@ -267,59 +294,68 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT;
}
riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vtype(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vtype(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vtype;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vl(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vl(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vl;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vxrm(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vxrm(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vxrm;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vxrm(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vxrm(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vxrm = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vxsat(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vxsat(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vxsat;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vxsat(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vxsat(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vxsat = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vstart(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vstart(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vstart;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vstart(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vstart(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vstart = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* User Timers and Counters */
-static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_instret(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (icount_enabled()) {
@@ -330,10 +366,11 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
#else
*val = cpu_get_host_ticks();
#endif
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_instreth(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (icount_enabled()) {
@@ -344,46 +381,50 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
#else
*val = cpu_get_host_ticks() >> 32;
#endif
- return 0;
+ return RISCV_EXCP_NONE;
}
#if defined(CONFIG_USER_ONLY)
-static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_time(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = cpu_get_host_ticks();
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_timeh(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = cpu_get_host_ticks() >> 32;
- return 0;
+ return RISCV_EXCP_NONE;
}
#else /* CONFIG_USER_ONLY */
-static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_time(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
*val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_timeh(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
*val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Machine constants */
@@ -418,7 +459,7 @@ static const target_ulong delegable_excps =
(1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT));
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
- SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
+ SSTATUS_SUM | SSTATUS_MXR;
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
static const target_ulong hip_writable_mask = MIP_VSSIP;
static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
@@ -437,22 +478,26 @@ static const char valid_vm_1_10_64[16] = {
};
/* Machine Information Registers */
-static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_zero(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
- return *val = 0;
+ *val = 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mhartid(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mhartid;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Machine Trap Setup */
-static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mstatus(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mstatus;
- return 0;
+ return RISCV_EXCP_NONE;
}
static int validate_vm(CPURISCVState *env, target_ulong vm)
@@ -464,7 +509,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
}
}
-static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mstatus(CPURISCVState *env, int csrno,
+ target_ulong val)
{
uint64_t mstatus = env->mstatus;
uint64_t mask = 0;
@@ -492,19 +538,25 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
((mstatus & MSTATUS_XS) == MSTATUS_XS);
- mstatus = set_field(mstatus, MSTATUS_SD, dirty);
+ if (riscv_cpu_is_32bit(env)) {
+ mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
+ } else {
+ mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
+ }
env->mstatus = mstatus;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mstatush(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mstatus >> 32;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mstatush(CPURISCVState *env, int csrno,
+ target_ulong val)
{
uint64_t valh = (uint64_t)val << 32;
uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
@@ -515,26 +567,28 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
env->mstatus = (env->mstatus & ~mask) | (valh & mask);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_misa(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->misa;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_misa(CPURISCVState *env, int csrno,
+ target_ulong val)
{
if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
/* drop write to misa */
- return 0;
+ return RISCV_EXCP_NONE;
}
/* 'I' or 'E' must be present */
if (!(val & (RVI | RVE))) {
/* It is not, drop write to misa */
- return 0;
+ return RISCV_EXCP_NONE;
}
/* 'E' excludes all other extensions */
@@ -542,7 +596,7 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
/* when we support 'E' we can do "val = RVE;" however
* for now we just drop writes if 'E' is present.
*/
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Mask extensions that are not supported by this hart */
@@ -564,7 +618,11 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
}
/* misa.MXL writes are not supported by QEMU */
- val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
+ if (riscv_cpu_is_32bit(env)) {
+ val = (env->misa & MISA32_MXL) | (val & ~MISA32_MXL);
+ } else {
+ val = (env->misa & MISA64_MXL) | (val & ~MISA64_MXL);
+ }
/* flush translation cache */
if (val != env->misa) {
@@ -573,55 +631,63 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
env->misa = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_medeleg(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->medeleg;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_medeleg(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_medeleg(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->medeleg = (env->medeleg & ~delegable_excps) | (val & delegable_excps);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mideleg(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mideleg(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mideleg;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mideleg(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mideleg(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints);
if (riscv_has_ext(env, RVH)) {
env->mideleg |= VS_MODE_INTERRUPTS;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mie(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mie(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mie;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mie(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mie(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mie = (env->mie & ~all_ints) | (val & all_ints);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mtvec(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mtvec;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mtvec(CPURISCVState *env, int csrno,
+ target_ulong val)
{
/* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
if ((val & 3) < 2) {
@@ -629,92 +695,83 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
} else {
qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
}
- return 0;
-}
-
-static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
-{
- *val = env->mcounteren;
- return 0;
-}
-
-static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
-{
- env->mcounteren = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
-static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
- return -RISCV_EXCP_ILLEGAL_INST;
- }
*val = env->mcounteren;
- return 0;
+ return RISCV_EXCP_NONE;
}
-/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
-static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
+ target_ulong val)
{
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
- return -RISCV_EXCP_ILLEGAL_INST;
- }
env->mcounteren = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Machine Trap Handling */
-static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mscratch(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mscratch;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mscratch(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mscratch(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mscratch = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mepc(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mepc(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mepc;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mepc(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mepc(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mepc = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mcause(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mcause(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mcause;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mcause(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mcause(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mcause = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mtval(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
- *val = env->mbadaddr;
- return 0;
+ *val = env->mtval;
+ return RISCV_EXCP_NONE;
}
-static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mtval(CPURISCVState *env, int csrno,
+ target_ulong val)
{
- env->mbadaddr = val;
- return 0;
+ env->mtval = val;
+ return RISCV_EXCP_NONE;
}
-static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+static RISCVException rmw_mip(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
RISCVCPU *cpu = env_archcpu(env);
/* Allow software control of delegable interrupts not claimed by hardware */
@@ -731,42 +788,54 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
*ret_value = old_mip;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Supervisor Trap Setup */
-static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_sstatus(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
target_ulong mask = (sstatus_v1_10_mask);
+
+ if (riscv_cpu_is_32bit(env)) {
+ mask |= SSTATUS32_SD;
+ } else {
+ mask |= SSTATUS64_SD;
+ }
+
*val = env->mstatus & mask;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_sstatus(CPURISCVState *env, int csrno,
+ target_ulong val)
{
target_ulong mask = (sstatus_v1_10_mask);
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
return write_mstatus(env, CSR_MSTATUS, newval);
}
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vsie(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
/* Shift the VS bits to their S bit location in vsie */
*val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_sie(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
if (riscv_cpu_virt_enabled(env)) {
read_vsie(env, CSR_VSIE, val);
} else {
*val = env->mie & env->mideleg;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vsie(CPURISCVState *env, int csrno,
+ target_ulong val)
{
/* Shift the S bits to their VS bit location in mie */
target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
@@ -784,16 +853,18 @@ static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
write_mie(env, CSR_MIE, newval);
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_stvec(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->stvec;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_stvec(CPURISCVState *env, int csrno,
+ target_ulong val)
{
/* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
if ((val & 3) < 2) {
@@ -801,72 +872,83 @@ static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
} else {
qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_scounteren(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->scounteren;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_scounteren(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->scounteren = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Supervisor Trap Handling */
-static int read_sscratch(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_sscratch(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->sscratch;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_sscratch(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_sscratch(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->sscratch = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_sepc(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_sepc(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->sepc;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_sepc(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_sepc(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->sepc = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_scause(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_scause(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->scause;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_scause(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_scause(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->scause = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_stval(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
- *val = env->sbadaddr;
- return 0;
+ *val = env->stval;
+ return RISCV_EXCP_NONE;
}
-static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_stval(CPURISCVState *env, int csrno,
+ target_ulong val)
{
- env->sbadaddr = val;
- return 0;
+ env->stval = val;
+ return RISCV_EXCP_NONE;
}
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
/* Shift the S bits to their VS bit location in mip */
int ret = rmw_mip(env, 0, ret_value, new_value << 1,
@@ -877,8 +959,9 @@ static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
return ret;
}
-static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+static RISCVException rmw_sip(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
int ret;
@@ -894,44 +977,58 @@ static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
}
/* Supervisor Protection and Translation */
-static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_satp(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
*val = 0;
- return 0;
+ return RISCV_EXCP_NONE;
}
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
} else {
*val = env->satp;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_satp(CPURISCVState *env, int csrno,
+ target_ulong val)
{
+ int vm, mask, asid;
+
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
- return 0;
+ return RISCV_EXCP_NONE;
+ }
+
+ if (riscv_cpu_is_32bit(env)) {
+ vm = validate_vm(env, get_field(val, SATP32_MODE));
+ mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
+ asid = (val ^ env->satp) & SATP32_ASID;
+ } else {
+ vm = validate_vm(env, get_field(val, SATP64_MODE));
+ mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
+ asid = (val ^ env->satp) & SATP64_ASID;
}
- if (validate_vm(env, get_field(val, SATP_MODE)) &&
- ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
- {
+
+ if (vm && mask) {
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
} else {
- if ((val ^ env->satp) & SATP_ASID) {
+ if (asid) {
tlb_flush(env_cpu(env));
}
env->satp = val;
}
}
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Hypervisor Extensions */
-static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hstatus(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->hstatus;
if (!riscv_cpu_is_32bit(env)) {
@@ -940,10 +1037,11 @@ static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
}
/* We only support little endian */
*val = set_field(*val, HSTATUS_VSBE, 0);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hstatus(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->hstatus = val;
if (!riscv_cpu_is_32bit(env) && get_field(val, HSTATUS_VSXL) != 2) {
@@ -952,35 +1050,40 @@ static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
if (get_field(val, HSTATUS_VSBE) != 0) {
qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_hedeleg(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->hedeleg;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hedeleg(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->hedeleg = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_hideleg(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hideleg(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->hideleg;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hideleg(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->hideleg = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
int ret = rmw_mip(env, 0, ret_value, new_value,
write_mask & hvip_writable_mask);
@@ -990,8 +1093,9 @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
return ret;
}
-static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+static RISCVException rmw_hip(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
int ret = rmw_mip(env, 0, ret_value, new_value,
write_mask & hip_writable_mask);
@@ -1001,103 +1105,119 @@ static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value,
return ret;
}
-static int read_hie(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hie(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mie & VS_MODE_INTERRUPTS;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hie(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hie(CPURISCVState *env, int csrno,
+ target_ulong val)
{
target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | (val & VS_MODE_INTERRUPTS);
return write_mie(env, CSR_MIE, newval);
}
-static int read_hcounteren(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->hcounteren;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hcounteren(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->hcounteren = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_hgeie(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hgeie(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hgeie(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hgeie(CPURISCVState *env, int csrno,
+ target_ulong val)
{
qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_htval(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_htval(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->htval;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_htval(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_htval(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->htval = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_htinst(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_htinst(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->htinst;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_htinst(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_htinst(CPURISCVState *env, int csrno,
+ target_ulong val)
{
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_hgeip(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hgeip(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hgeip(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hgeip(CPURISCVState *env, int csrno,
+ target_ulong val)
{
qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hgatp(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->hgatp;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_hgatp(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->hgatp = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
*val = env->htimedelta;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
+ target_ulong val)
{
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
if (riscv_cpu_is_32bit(env)) {
@@ -1105,162 +1225,199 @@ static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
} else {
env->htimedelta = val;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
*val = env->htimedelta >> 32;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
+ target_ulong val)
{
if (!env->rdtime_fn) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Virtual CSR Registers */
-static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vsstatus;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
+ target_ulong val)
{
uint64_t mask = (target_ulong)-1;
env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
- return 0;
+ return RISCV_EXCP_NONE;
}
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = env->vstvec;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vstvec(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vstvec(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vstvec = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vsscratch(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vsscratch;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vsscratch(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vsscratch = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vsepc(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vsepc(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vsepc;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vsepc(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vsepc(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vsepc = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vscause(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vscause(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vscause;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vscause(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vscause(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vscause = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vstval(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vstval(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vstval;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vstval(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vstval(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vstval = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_vsatp(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vsatp(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->vsatp;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_vsatp(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vsatp(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->vsatp = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mtval2(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mtval2(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mtval2;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mtval2(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mtval2(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mtval2 = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_mtinst(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mtinst(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = env->mtinst;
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_mtinst(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mtinst(CPURISCVState *env, int csrno,
+ target_ulong val)
{
env->mtinst = val;
- return 0;
+ return RISCV_EXCP_NONE;
}
/* Physical Memory Protection */
-static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = mseccfg_csr_read(env);
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ mseccfg_csr_write(env, val);
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_pmpcfg(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
+ target_ulong val)
{
pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int read_pmpaddr(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
+ target_ulong *val)
{
*val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
- return 0;
+ return RISCV_EXCP_NONE;
}
-static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
+ target_ulong val)
{
pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
- return 0;
+ return RISCV_EXCP_NONE;
}
#endif
@@ -1274,10 +1431,11 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
* csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
*/
-int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
{
- int ret;
+ RISCVException ret;
target_ulong old_value;
RISCVCPU *cpu = env_archcpu(env);
@@ -1299,21 +1457,21 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
if ((write_mask && read_only) ||
(!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
#endif
/* ensure the CSR extension is enabled. */
if (!cpu->cfg.ext_icsr) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
/* check predicate */
if (!csr_ops[csrno].predicate) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
ret = csr_ops[csrno].predicate(env, csrno);
- if (ret < 0) {
+ if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -1324,12 +1482,11 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
/* if no accessor exists then return failure */
if (!csr_ops[csrno].read) {
- return -RISCV_EXCP_ILLEGAL_INST;
+ return RISCV_EXCP_ILLEGAL_INST;
}
-
/* read old value */
ret = csr_ops[csrno].read(env, csrno, &old_value);
- if (ret < 0) {
+ if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -1338,7 +1495,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
new_value = (old_value & ~write_mask) | (new_value & write_mask);
if (csr_ops[csrno].write) {
ret = csr_ops[csrno].write(env, csrno, new_value);
- if (ret < 0) {
+ if (ret != RISCV_EXCP_NONE) {
return ret;
}
}
@@ -1349,17 +1506,19 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
*ret_value = old_value;
}
- return 0;
+ return RISCV_EXCP_NONE;
}
/*
* Debugger support. If not in user mode, set env->debugger before the
* riscv_csrrw call and clear it after the call.
*/
-int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
+ target_ulong *ret_value,
+ target_ulong new_value,
+ target_ulong write_mask)
{
- int ret;
+ RISCVException ret;
#if !defined(CONFIG_USER_ONLY)
env->debugger = true;
#endif
@@ -1419,13 +1578,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
- [CSR_MSCOUNTEREN] = { "msounteren", any, read_mscounteren, write_mscounteren },
-
/* Machine Trap Handling */
[CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch },
[CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
[CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
- [CSR_MBADADDR] = { "mbadaddr", any, read_mbadaddr, write_mbadaddr },
+ [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
[CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
/* Supervisor Trap Setup */
@@ -1438,7 +1595,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch },
[CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
[CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
- [CSR_SBADADDR] = { "sbadaddr", smode, read_sbadaddr, write_sbadaddr },
+ [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
[CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
/* Supervisor Protection and Translation */
@@ -1473,6 +1630,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst },
/* Physical Memory Protection */
+ [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg },
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 7c4ab92ecb..8700516a14 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -223,13 +223,13 @@ target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
return (int32_t)float32_to_uint32(frs1, &env->fp_status);
}
-uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
+target_ulong helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
{
float32 frs1 = check_nanbox_s(rs1);
return float32_to_int64(frs1, &env->fp_status);
}
-uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
+target_ulong helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
{
float32 frs1 = check_nanbox_s(rs1);
return float32_to_uint64(frs1, &env->fp_status);
@@ -245,12 +245,12 @@ uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
return nanbox_s(uint32_to_float32((uint32_t)rs1, &env->fp_status));
}
-uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1)
+uint64_t helper_fcvt_s_l(CPURISCVState *env, target_ulong rs1)
{
return nanbox_s(int64_to_float32(rs1, &env->fp_status));
}
-uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)
+uint64_t helper_fcvt_s_lu(CPURISCVState *env, target_ulong rs1)
{
return nanbox_s(uint64_to_float32(rs1, &env->fp_status));
}
@@ -332,12 +332,12 @@ target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
return (int32_t)float64_to_uint32(frs1, &env->fp_status);
}
-uint64_t helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
+target_ulong helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
{
return float64_to_int64(frs1, &env->fp_status);
}
-uint64_t helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
+target_ulong helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
{
return float64_to_uint64(frs1, &env->fp_status);
}
@@ -352,12 +352,12 @@ uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
return uint32_to_float64((uint32_t)rs1, &env->fp_status);
}
-uint64_t helper_fcvt_d_l(CPURISCVState *env, uint64_t rs1)
+uint64_t helper_fcvt_d_l(CPURISCVState *env, target_ulong rs1)
{
return int64_to_float64(rs1, &env->fp_status);
}
-uint64_t helper_fcvt_d_lu(CPURISCVState *env, uint64_t rs1)
+uint64_t helper_fcvt_d_lu(CPURISCVState *env, target_ulong rs1)
{
return uint64_to_float64(rs1, &env->fp_status);
}
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 5f96b7ea2a..ca78682cf4 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -71,7 +71,7 @@ static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
*/
result = riscv_csrrw_debug(env, n - 32, &val,
0, 0);
- if (result == 0) {
+ if (result == RISCV_EXCP_NONE) {
return gdb_get_regl(buf, val);
}
}
@@ -94,7 +94,7 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
*/
result = riscv_csrrw_debug(env, n - 32, NULL,
val, -1);
- if (result == 0) {
+ if (result == RISCV_EXCP_NONE) {
return sizeof(target_ulong);
}
}
@@ -108,7 +108,7 @@ static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
int result;
result = riscv_csrrw_debug(env, n, &val, 0, 0);
- if (result == 0) {
+ if (result == RISCV_EXCP_NONE) {
return gdb_get_regl(buf, val);
}
}
@@ -122,7 +122,7 @@ static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
int result;
result = riscv_csrrw_debug(env, n, NULL, val, -1);
- if (result == 0) {
+ if (result == RISCV_EXCP_NONE) {
return sizeof(target_ulong);
}
}
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e3f3f41e89..c7267593c3 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -27,12 +27,12 @@ DEF_HELPER_FLAGS_3(flt_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_3(feq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_2(fcvt_w_s, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_wu_s, TCG_CALL_NO_RWG, tl, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, i64, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_s_w, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_2(fcvt_s_wu, TCG_CALL_NO_RWG, i64, env, tl)
-DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_1(fclass_s, TCG_CALL_NO_RWG_SE, tl, i64)
/* Floating Point - Double Precision */
@@ -50,12 +50,12 @@ DEF_HELPER_FLAGS_3(flt_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_3(feq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_2(fcvt_w_d, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_wu_d, TCG_CALL_NO_RWG, tl, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, i64, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_d_w, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_2(fcvt_d_wu, TCG_CALL_NO_RWG, i64, env, tl)
-DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
/* Special functions */
@@ -241,7 +241,6 @@ DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
-#ifdef TARGET_RISCV64
DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamoaddw_v_d, void, ptr, ptr, tl, ptr, env, i32)
@@ -260,7 +259,6 @@ DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-#endif
DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamoaddw_v_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vamoxorw_v_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn16-32.decode b/target/riscv/insn16-32.decode
deleted file mode 100644
index 0819b17028..0000000000
--- a/target/riscv/insn16-32.decode
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# RISC-V translation routines for the RVXI Base Integer Instruction Set.
-#
-# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
-# Bastian Koppelmann, kbastian@mail.uni-paderborn.de
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms and conditions of the GNU General Public License,
-# version 2 or later, as published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program. If not, see <http://www.gnu.org/licenses/>.
-
-# *** RV32C Standard Extension (Quadrant 0) ***
-flw 011 ... ... .. ... 00 @cl_w
-fsw 111 ... ... .. ... 00 @cs_w
-
-# *** RV32C Standard Extension (Quadrant 1) ***
-jal 001 ........... 01 @cj rd=1 # C.JAL
-
-# *** RV32C Standard Extension (Quadrant 2) ***
-flw 011 . ..... ..... 10 @c_lwsp
-fsw 111 . ..... ..... 10 @c_swsp
diff --git a/target/riscv/insn16-64.decode b/target/riscv/insn16-64.decode
deleted file mode 100644
index 672e1e916f..0000000000
--- a/target/riscv/insn16-64.decode
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# RISC-V translation routines for the RVXI Base Integer Instruction Set.
-#
-# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
-# Bastian Koppelmann, kbastian@mail.uni-paderborn.de
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms and conditions of the GNU General Public License,
-# version 2 or later, as published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program. If not, see <http://www.gnu.org/licenses/>.
-
-# *** RV64C Standard Extension (Quadrant 0) ***
-ld 011 ... ... .. ... 00 @cl_d
-sd 111 ... ... .. ... 00 @cs_d
-
-# *** RV64C Standard Extension (Quadrant 1) ***
-{
- illegal 001 - 00000 ----- 01 # c.addiw, RES rd=0
- addiw 001 . ..... ..... 01 @ci
-}
-subw 100 1 11 ... 00 ... 01 @cs_2
-addw 100 1 11 ... 01 ... 01 @cs_2
-
-# *** RV64C Standard Extension (Quadrant 2) ***
-{
- illegal 011 - 00000 ----- 10 # c.ldsp, RES rd=0
- ld 011 . ..... ..... 10 @c_ldsp
-}
-sd 111 . ..... ..... 10 @c_sdsp
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 1cb93876fe..2e9212663c 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -92,6 +92,16 @@ lw 010 ... ... .. ... 00 @cl_w
fsd 101 ... ... .. ... 00 @cs_d
sw 110 ... ... .. ... 00 @cs_w
+# *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
+{
+ ld 011 ... ... .. ... 00 @cl_d
+ flw 011 ... ... .. ... 00 @cl_w
+}
+{
+ sd 111 ... ... .. ... 00 @cs_d
+ fsw 111 ... ... .. ... 00 @cs_w
+}
+
# *** RV32/64C Standard Extension (Quadrant 1) ***
addi 000 . ..... ..... 01 @ci
addi 010 . ..... ..... 01 @c_li
@@ -111,6 +121,15 @@ jal 101 ........... 01 @cj rd=0 # C.J
beq 110 ... ... ..... 01 @cb_z
bne 111 ... ... ..... 01 @cb_z
+# *** RV64C and RV32C specific Standard Extension (Quadrant 1) ***
+{
+ c64_illegal 001 - 00000 ----- 01 # c.addiw, RES rd=0
+ addiw 001 . ..... ..... 01 @ci
+ jal 001 ........... 01 @cj rd=1 # C.JAL
+}
+subw 100 1 11 ... 00 ... 01 @cs_2
+addw 100 1 11 ... 01 ... 01 @cs_2
+
# *** RV32/64C Standard Extension (Quadrant 2) ***
slli 000 . ..... ..... 10 @c_shift2
fld 001 . ..... ..... 10 @c_ldsp
@@ -130,3 +149,14 @@ fld 001 . ..... ..... 10 @c_ldsp
}
fsd 101 ...... ..... 10 @c_sdsp
sw 110 . ..... ..... 10 @c_swsp
+
+# *** RV32C and RV64C specific Standard Extension (Quadrant 2) ***
+{
+ c64_illegal 011 - 00000 ----- 10 # c.ldsp, RES rd=0
+ ld 011 . ..... ..... 10 @c_ldsp
+ flw 011 . ..... ..... 10 @c_lwsp
+}
+{
+ sd 111 . ..... ..... 10 @c_sdsp
+ fsw 111 . ..... ..... 10 @c_swsp
+}
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
deleted file mode 100644
index 8157dee8b7..0000000000
--- a/target/riscv/insn32-64.decode
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# RISC-V translation routines for the RV Instruction Set.
-#
-# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
-# Bastian Koppelmann, kbastian@mail.uni-paderborn.de
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms and conditions of the GNU General Public License,
-# version 2 or later, as published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program. If not, see <http://www.gnu.org/licenses/>.
-
-# This is concatenated with insn32.decode for risc64 targets.
-# Most of the fields and formats are there.
-
-%sh5 20:5
-
-@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
-
-# *** RV64I Base Instruction Set (in addition to RV32I) ***
-lwu ............ ..... 110 ..... 0000011 @i
-ld ............ ..... 011 ..... 0000011 @i
-sd ....... ..... ..... 011 ..... 0100011 @s
-addiw ............ ..... 000 ..... 0011011 @i
-slliw 0000000 ..... ..... 001 ..... 0011011 @sh5
-srliw 0000000 ..... ..... 101 ..... 0011011 @sh5
-sraiw 0100000 ..... ..... 101 ..... 0011011 @sh5
-addw 0000000 ..... ..... 000 ..... 0111011 @r
-subw 0100000 ..... ..... 000 ..... 0111011 @r
-sllw 0000000 ..... ..... 001 ..... 0111011 @r
-srlw 0000000 ..... ..... 101 ..... 0111011 @r
-sraw 0100000 ..... ..... 101 ..... 0111011 @r
-
-# *** RV64M Standard Extension (in addition to RV32M) ***
-mulw 0000001 ..... ..... 000 ..... 0111011 @r
-divw 0000001 ..... ..... 100 ..... 0111011 @r
-divuw 0000001 ..... ..... 101 ..... 0111011 @r
-remw 0000001 ..... ..... 110 ..... 0111011 @r
-remuw 0000001 ..... ..... 111 ..... 0111011 @r
-
-# *** RV64A Standard Extension (in addition to RV32A) ***
-lr_d 00010 . . 00000 ..... 011 ..... 0101111 @atom_ld
-sc_d 00011 . . ..... ..... 011 ..... 0101111 @atom_st
-amoswap_d 00001 . . ..... ..... 011 ..... 0101111 @atom_st
-amoadd_d 00000 . . ..... ..... 011 ..... 0101111 @atom_st
-amoxor_d 00100 . . ..... ..... 011 ..... 0101111 @atom_st
-amoand_d 01100 . . ..... ..... 011 ..... 0101111 @atom_st
-amoor_d 01000 . . ..... ..... 011 ..... 0101111 @atom_st
-amomin_d 10000 . . ..... ..... 011 ..... 0101111 @atom_st
-amomax_d 10100 . . ..... ..... 011 ..... 0101111 @atom_st
-amominu_d 11000 . . ..... ..... 011 ..... 0101111 @atom_st
-amomaxu_d 11100 . . ..... ..... 011 ..... 0101111 @atom_st
-
-#*** Vector AMO operations (in addition to Zvamo) ***
-vamoswapd_v 00001 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamoaddd_v 00000 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamoxord_v 00100 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamoandd_v 01100 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamoord_v 01000 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamomind_v 10000 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamomaxd_v 10100 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamominud_v 11000 . . ..... ..... 111 ..... 0101111 @r_wdvm
-vamomaxud_v 11100 . . ..... ..... 111 ..... 0101111 @r_wdvm
-
-# *** RV64F Standard Extension (in addition to RV32F) ***
-fcvt_l_s 1100000 00010 ..... ... ..... 1010011 @r2_rm
-fcvt_lu_s 1100000 00011 ..... ... ..... 1010011 @r2_rm
-fcvt_s_l 1101000 00010 ..... ... ..... 1010011 @r2_rm
-fcvt_s_lu 1101000 00011 ..... ... ..... 1010011 @r2_rm
-
-# *** RV64D Standard Extension (in addition to RV32D) ***
-fcvt_l_d 1100001 00010 ..... ... ..... 1010011 @r2_rm
-fcvt_lu_d 1100001 00011 ..... ... ..... 1010011 @r2_rm
-fmv_x_d 1110001 00000 ..... 000 ..... 1010011 @r2
-fcvt_d_l 1101001 00010 ..... ... ..... 1010011 @r2_rm
-fcvt_d_lu 1101001 00011 ..... ... ..... 1010011 @r2_rm
-fmv_d_x 1111001 00000 ..... 000 ..... 1010011 @r2
-
-# *** RV32H Base Instruction Set ***
-hlv_wu 0110100 00001 ..... 100 ..... 1110011 @r2
-hlv_d 0110110 00000 ..... 100 ..... 1110011 @r2
-hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 84080dd18c..8901ba1e1b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,7 @@
%rs2 20:5
%rs1 15:5
%rd 7:5
+%sh5 20:5
%sh10 20:10
%csr 20:12
@@ -86,6 +87,8 @@
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
+# Formats 64:
+@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
# *** Privileged Instructions ***
ecall 000000000000 00000 000 00000 1110011
@@ -144,6 +147,20 @@ csrrwi ............ ..... 101 ..... 1110011 @csr
csrrsi ............ ..... 110 ..... 1110011 @csr
csrrci ............ ..... 111 ..... 1110011 @csr
+# *** RV64I Base Instruction Set (in addition to RV32I) ***
+lwu ............ ..... 110 ..... 0000011 @i
+ld ............ ..... 011 ..... 0000011 @i
+sd ....... ..... ..... 011 ..... 0100011 @s
+addiw ............ ..... 000 ..... 0011011 @i
+slliw 0000000 ..... ..... 001 ..... 0011011 @sh5
+srliw 0000000 ..... ..... 101 ..... 0011011 @sh5
+sraiw 0100000 ..... ..... 101 ..... 0011011 @sh5
+addw 0000000 ..... ..... 000 ..... 0111011 @r
+subw 0100000 ..... ..... 000 ..... 0111011 @r
+sllw 0000000 ..... ..... 001 ..... 0111011 @r
+srlw 0000000 ..... ..... 101 ..... 0111011 @r
+sraw 0100000 ..... ..... 101 ..... 0111011 @r
+
# *** RV32M Standard Extension ***
mul 0000001 ..... ..... 000 ..... 0110011 @r
mulh 0000001 ..... ..... 001 ..... 0110011 @r
@@ -154,6 +171,13 @@ divu 0000001 ..... ..... 101 ..... 0110011 @r
rem 0000001 ..... ..... 110 ..... 0110011 @r
remu 0000001 ..... ..... 111 ..... 0110011 @r
+# *** RV64M Standard Extension (in addition to RV32M) ***
+mulw 0000001 ..... ..... 000 ..... 0111011 @r
+divw 0000001 ..... ..... 100 ..... 0111011 @r
+divuw 0000001 ..... ..... 101 ..... 0111011 @r
+remw 0000001 ..... ..... 110 ..... 0111011 @r
+remuw 0000001 ..... ..... 111 ..... 0111011 @r
+
# *** RV32A Standard Extension ***
lr_w 00010 . . 00000 ..... 010 ..... 0101111 @atom_ld
sc_w 00011 . . ..... ..... 010 ..... 0101111 @atom_st
@@ -167,6 +191,19 @@ amomax_w 10100 . . ..... ..... 010 ..... 0101111 @atom_st
amominu_w 11000 . . ..... ..... 010 ..... 0101111 @atom_st
amomaxu_w 11100 . . ..... ..... 010 ..... 0101111 @atom_st
+# *** RV64A Standard Extension (in addition to RV32A) ***
+lr_d 00010 . . 00000 ..... 011 ..... 0101111 @atom_ld
+sc_d 00011 . . ..... ..... 011 ..... 0101111 @atom_st
+amoswap_d 00001 . . ..... ..... 011 ..... 0101111 @atom_st
+amoadd_d 00000 . . ..... ..... 011 ..... 0101111 @atom_st
+amoxor_d 00100 . . ..... ..... 011 ..... 0101111 @atom_st
+amoand_d 01100 . . ..... ..... 011 ..... 0101111 @atom_st
+amoor_d 01000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomin_d 10000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomax_d 10100 . . ..... ..... 011 ..... 0101111 @atom_st
+amominu_d 11000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomaxu_d 11100 . . ..... ..... 011 ..... 0101111 @atom_st
+
# *** RV32F Standard Extension ***
flw ............ ..... 010 ..... 0000111 @i
fsw ....... ..... ..... 010 ..... 0100111 @s
@@ -195,6 +232,12 @@ fcvt_s_w 1101000 00000 ..... ... ..... 1010011 @r2_rm
fcvt_s_wu 1101000 00001 ..... ... ..... 1010011 @r2_rm
fmv_w_x 1111000 00000 ..... 000 ..... 1010011 @r2
+# *** RV64F Standard Extension (in addition to RV32F) ***
+fcvt_l_s 1100000 00010 ..... ... ..... 1010011 @r2_rm
+fcvt_lu_s 1100000 00011 ..... ... ..... 1010011 @r2_rm
+fcvt_s_l 1101000 00010 ..... ... ..... 1010011 @r2_rm
+fcvt_s_lu 1101000 00011 ..... ... ..... 1010011 @r2_rm
+
# *** RV32D Standard Extension ***
fld ............ ..... 011 ..... 0000111 @i
fsd ....... ..... ..... 011 ..... 0100111 @s
@@ -223,6 +266,14 @@ fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm
fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
+# *** RV64D Standard Extension (in addition to RV32D) ***
+fcvt_l_d 1100001 00010 ..... ... ..... 1010011 @r2_rm
+fcvt_lu_d 1100001 00011 ..... ... ..... 1010011 @r2_rm
+fmv_x_d 1110001 00000 ..... 000 ..... 1010011 @r2
+fcvt_d_l 1101001 00010 ..... ... ..... 1010011 @r2_rm
+fcvt_d_lu 1101001 00011 ..... ... ..... 1010011 @r2_rm
+fmv_d_x 1111001 00000 ..... 000 ..... 1010011 @r2
+
# *** RV32H Base Instruction Set ***
hlv_b 0110000 00000 ..... 100 ..... 1110011 @r2
hlv_bu 0110000 00001 ..... 100 ..... 1110011 @r2
@@ -237,7 +288,10 @@ hsv_w 0110101 ..... ..... 100 00000 1110011 @r2_s
hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
-# *** RV32V Extension ***
+# *** RV64H Base Instruction Set ***
+hlv_wu 0110100 00001 ..... 100 ..... 1110011 @r2
+hlv_d 0110110 00000 ..... 100 ..... 1110011 @r2
+hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s
# *** Vector loads and stores are encoded within LOADFP/STORE-FP ***
vlb_v ... 100 . 00000 ..... 000 ..... 0000111 @r2_nfvm
@@ -592,3 +646,14 @@ vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r
vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
+
+#*** Vector AMO operations (in addition to Zvamo) ***
+vamoswapd_v 00001 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamoaddd_v 00000 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamoxord_v 00100 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamoandd_v 01100 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamoord_v 01000 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamomind_v 10000 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamomaxd_v 10100 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamominud_v 11000 . . ..... ..... 111 ..... 0101111 @r_wdvm
+vamomaxud_v 11100 . . ..... ..... 111 ..... 0101111 @r_wdvm
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index be8a9f06dd..ab2ec4f0a5 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -165,60 +165,68 @@ static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
}
-#ifdef TARGET_RISCV64
-
static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
}
static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
}
static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEQ));
}
static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
{
+ REQUIRE_64BIT(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEQ));
}
-#endif
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 4f832637fa..7e45538ae0 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -358,10 +358,9 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
return true;
}
-#ifdef TARGET_RISCV64
-
static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
@@ -375,6 +374,7 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
@@ -388,15 +388,21 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
+#ifdef TARGET_RISCV64
gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
return true;
+#else
+ qemu_build_not_reached();
+#endif
}
static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
@@ -412,6 +418,7 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
@@ -427,9 +434,11 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
+#ifdef TARGET_RISCV64
TCGv t0 = tcg_temp_new();
gen_get_gpr(t0, a->rs1);
@@ -437,5 +446,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
tcg_temp_free(t0);
mark_fs_dirty(ctx);
return true;
-}
+#else
+ qemu_build_not_reached();
#endif
+}
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 3dfec8211d..db1c0c9974 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -415,9 +415,9 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
return true;
}
-#ifdef TARGET_RISCV64
static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
@@ -431,6 +431,7 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
@@ -444,6 +445,7 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
@@ -460,6 +462,7 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
@@ -473,4 +476,3 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
tcg_temp_free(t0);
return true;
}
-#endif
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
index ce7ed5affb..6b5edf82b7 100644
--- a/target/riscv/insn_trans/trans_rvh.c.inc
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
@@ -203,10 +203,11 @@ static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
#endif
}
-#ifdef TARGET_RISCV64
static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
+
#ifndef CONFIG_USER_ONLY
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
@@ -228,7 +229,9 @@ static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
+
#ifndef CONFIG_USER_ONLY
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
@@ -250,7 +253,9 @@ static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
+
#ifndef CONFIG_USER_ONLY
TCGv t0 = tcg_temp_new();
TCGv dat = tcg_temp_new();
@@ -269,7 +274,6 @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
return false;
#endif
}
-#endif
static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
{
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index d04ca0394c..bd93f634cf 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -24,6 +24,12 @@ static bool trans_illegal(DisasContext *ctx, arg_empty *a)
return true;
}
+static bool trans_c64_illegal(DisasContext *ctx, arg_empty *a)
+{
+ REQUIRE_64BIT(ctx);
+ return trans_illegal(ctx, a);
+}
+
static bool trans_lui(DisasContext *ctx, arg_lui *a)
{
if (a->rd != 0) {
@@ -204,22 +210,23 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
return gen_store(ctx, a, MO_TESL);
}
-#ifdef TARGET_RISCV64
static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
{
+ REQUIRE_64BIT(ctx);
return gen_load(ctx, a, MO_TEUL);
}
static bool trans_ld(DisasContext *ctx, arg_ld *a)
{
+ REQUIRE_64BIT(ctx);
return gen_load(ctx, a, MO_TEQ);
}
static bool trans_sd(DisasContext *ctx, arg_sd *a)
{
+ REQUIRE_64BIT(ctx);
return gen_store(ctx, a, MO_TEQ);
}
-#endif
static bool trans_addi(DisasContext *ctx, arg_addi *a)
{
@@ -361,14 +368,15 @@ static bool trans_and(DisasContext *ctx, arg_and *a)
return gen_arith(ctx, a, &tcg_gen_and_tl);
}
-#ifdef TARGET_RISCV64
static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
{
+ REQUIRE_64BIT(ctx);
return gen_arith_imm_tl(ctx, a, &gen_addw);
}
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv source1;
source1 = tcg_temp_new();
gen_get_gpr(source1, a->rs1);
@@ -383,6 +391,7 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv t = tcg_temp_new();
gen_get_gpr(t, a->rs1);
tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
@@ -395,6 +404,7 @@ static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv t = tcg_temp_new();
gen_get_gpr(t, a->rs1);
tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
@@ -405,16 +415,19 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
static bool trans_addw(DisasContext *ctx, arg_addw *a)
{
+ REQUIRE_64BIT(ctx);
return gen_arith(ctx, a, &gen_addw);
}
static bool trans_subw(DisasContext *ctx, arg_subw *a)
{
+ REQUIRE_64BIT(ctx);
return gen_arith(ctx, a, &gen_subw);
}
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv source1 = tcg_temp_new();
TCGv source2 = tcg_temp_new();
@@ -433,6 +446,7 @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv source1 = tcg_temp_new();
TCGv source2 = tcg_temp_new();
@@ -453,6 +467,7 @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
{
+ REQUIRE_64BIT(ctx);
TCGv source1 = tcg_temp_new();
TCGv source2 = tcg_temp_new();
@@ -473,7 +488,6 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
return true;
}
-#endif
static bool trans_fence(DisasContext *ctx, arg_fence *a)
{
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
index 47cd6edc72..10ecc456fc 100644
--- a/target/riscv/insn_trans/trans_rvm.c.inc
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
@@ -87,34 +87,42 @@ static bool trans_remu(DisasContext *ctx, arg_remu *a)
return gen_arith(ctx, a, &gen_remu);
}
-#ifdef TARGET_RISCV64
static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
+
return gen_arith(ctx, a, &gen_mulw);
}
static bool trans_divw(DisasContext *ctx, arg_divw *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
+
return gen_arith_div_w(ctx, a, &gen_div);
}
static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
+
return gen_arith_div_uw(ctx, a, &gen_divu);
}
static bool trans_remw(DisasContext *ctx, arg_remw *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
+
return gen_arith_div_w(ctx, a, &gen_rem);
}
static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
{
+ REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
+
return gen_arith_div_uw(ctx, a, &gen_remu);
}
-#endif
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 887c6b8883..47914a3b69 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -705,7 +705,6 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
gen_helper_vamominuw_v_w,
gen_helper_vamomaxuw_v_w
};
-#ifdef TARGET_RISCV64
static gen_helper_amo *const fnsd[18] = {
gen_helper_vamoswapw_v_d,
gen_helper_vamoaddw_v_d,
@@ -726,7 +725,6 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
gen_helper_vamominud_v_d,
gen_helper_vamomaxud_v_d
};
-#endif
if (tb_cflags(s->base.tb) & CF_PARALLEL) {
gen_helper_exit_atomic(cpu_env);
@@ -734,12 +732,12 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
return true;
} else {
if (s->sew == 3) {
-#ifdef TARGET_RISCV64
- fn = fnsd[seq];
-#else
- /* Check done in amo_check(). */
- g_assert_not_reached();
-#endif
+ if (!is_32bit(s)) {
+ fn = fnsd[seq];
+ } else {
+ /* Check done in amo_check(). */
+ g_assert_not_reached();
+ }
} else {
assert(seq < ARRAY_SIZE(fnsw));
fn = fnsw[seq];
@@ -769,6 +767,11 @@ static bool amo_check(DisasContext *s, arg_rwdvm* a)
((1 << s->sew) >= 4));
}
+static bool amo_check64(DisasContext *s, arg_rwdvm* a)
+{
+ return !is_32bit(s) && amo_check(s, a);
+}
+
GEN_VEXT_TRANS(vamoswapw_v, 0, rwdvm, amo_op, amo_check)
GEN_VEXT_TRANS(vamoaddw_v, 1, rwdvm, amo_op, amo_check)
GEN_VEXT_TRANS(vamoxorw_v, 2, rwdvm, amo_op, amo_check)
@@ -778,17 +781,15 @@ GEN_VEXT_TRANS(vamominw_v, 5, rwdvm, amo_op, amo_check)
GEN_VEXT_TRANS(vamomaxw_v, 6, rwdvm, amo_op, amo_check)
GEN_VEXT_TRANS(vamominuw_v, 7, rwdvm, amo_op, amo_check)
GEN_VEXT_TRANS(vamomaxuw_v, 8, rwdvm, amo_op, amo_check)
-#ifdef TARGET_RISCV64
-GEN_VEXT_TRANS(vamoswapd_v, 9, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamoaddd_v, 10, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamoxord_v, 11, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamoandd_v, 12, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamoord_v, 13, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamomind_v, 14, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamomaxd_v, 15, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamominud_v, 16, rwdvm, amo_op, amo_check)
-GEN_VEXT_TRANS(vamomaxud_v, 17, rwdvm, amo_op, amo_check)
-#endif
+GEN_VEXT_TRANS(vamoswapd_v, 9, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamoaddd_v, 10, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamoxord_v, 11, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamoandd_v, 12, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamoord_v, 13, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamomind_v, 14, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamomaxd_v, 15, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamominud_v, 16, rwdvm, amo_op, amo_check64)
+GEN_VEXT_TRANS(vamomaxud_v, 17, rwdvm, amo_op, amo_check64)
/*
*** Vector Integer Arithmetic Instructions
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 44d4015bd6..16a08302da 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -140,8 +140,8 @@ static const VMStateDescription vmstate_hyper = {
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
@@ -165,10 +165,8 @@ const VMStateDescription vmstate_riscv_cpu = {
VMSTATE_UINT32(env.miclaim, RISCVCPU),
VMSTATE_UINTTL(env.mie, RISCVCPU),
VMSTATE_UINTTL(env.mideleg, RISCVCPU),
- VMSTATE_UINTTL(env.sptbr, RISCVCPU),
VMSTATE_UINTTL(env.satp, RISCVCPU),
- VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
- VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
+ VMSTATE_UINTTL(env.stval, RISCVCPU),
VMSTATE_UINTTL(env.medeleg, RISCVCPU),
VMSTATE_UINTTL(env.stvec, RISCVCPU),
VMSTATE_UINTTL(env.sepc, RISCVCPU),
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 88ab850682..af6c3416b7 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -1,18 +1,13 @@
# FIXME extra_args should accept files()
dir = meson.current_source_dir()
-gen32 = [
- decodetree.process('insn16.decode', extra_args: [dir / 'insn16-32.decode', '--static-decode=decode_insn16', '--insnwidth=16']),
- decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
-]
-gen64 = [
- decodetree.process('insn16.decode', extra_args: [dir / 'insn16-64.decode', '--static-decode=decode_insn16', '--insnwidth=16']),
- decodetree.process('insn32.decode', extra_args: [dir / 'insn32-64.decode', '--static-decode=decode_insn32']),
+gen = [
+ decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
+ decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
]
riscv_ss = ss.source_set()
-riscv_ss.add(when: 'TARGET_RISCV32', if_true: gen32)
-riscv_ss.add(when: 'TARGET_RISCV64', if_true: gen64)
+riscv_ss.add(gen)
riscv_ss.add(files(
'cpu.c',
'cpu_helper.c',
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index e51188f919..f7e6ea72b3 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -150,9 +150,14 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
target_ulong last_size;
int last_attr;
- base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
+ if (riscv_cpu_is_32bit(env)) {
+ base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP32_MODE);
+ } else {
+ base = (hwaddr)get_field(env->satp, SATP64_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP64_MODE);
+ }
- vm = get_field(env->satp, SATP_MODE);
switch (vm) {
case VM_1_10_SV32:
levels = 2;
@@ -215,9 +220,16 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
return;
}
- if (!(env->satp & SATP_MODE)) {
- monitor_printf(mon, "No translation or protection\n");
- return;
+ if (riscv_cpu_is_32bit(env)) {
+ if (!(env->satp & SATP32_MODE)) {
+ monitor_printf(mon, "No translation or protection\n");
+ return;
+ }
+ } else {
+ if (!(env->satp & SATP64_MODE)) {
+ monitor_printf(mon, "No translation or protection\n");
+ return;
+ }
}
mem_info_svxx(mon, env);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index f0bbd73ca5..170b494227 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -41,10 +41,10 @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
target_ulong csr)
{
target_ulong val = 0;
- int ret = riscv_csrrw(env, csr, &val, src, -1);
+ RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
- if (ret < 0) {
- riscv_raise_exception(env, -ret, GETPC());
+ if (ret != RISCV_EXCP_NONE) {
+ riscv_raise_exception(env, ret, GETPC());
}
return val;
}
@@ -53,10 +53,10 @@ target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
target_ulong csr, target_ulong rs1_pass)
{
target_ulong val = 0;
- int ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
+ RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
- if (ret < 0) {
- riscv_raise_exception(env, -ret, GETPC());
+ if (ret != RISCV_EXCP_NONE) {
+ riscv_raise_exception(env, ret, GETPC());
}
return val;
}
@@ -65,10 +65,10 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
target_ulong csr, target_ulong rs1_pass)
{
target_ulong val = 0;
- int ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
+ RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
- if (ret < 0) {
- riscv_raise_exception(env, -ret, GETPC());
+ if (ret != RISCV_EXCP_NONE) {
+ riscv_raise_exception(env, ret, GETPC());
}
return val;
}
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index cff020122a..78203291de 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -19,10 +19,6 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * PMP (Physical Memory Protection) is as-of-yet unused and needs testing.
- */
-
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
@@ -59,16 +55,6 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
return 0;
}
- /* In TOR mode, need to check the lock bit of the next pmp
- * (if there is a next)
- */
- const uint8_t a_field =
- pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
- if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
- (PMP_AMATCH_TOR == a_field)) {
- return 1;
- }
-
return 0;
}
@@ -100,11 +86,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
{
if (pmp_index < MAX_RISCV_PMPS) {
- if (!pmp_is_locked(env, pmp_index)) {
- env->pmp_state.pmp[pmp_index].cfg_reg = val;
- pmp_update_rule(env, pmp_index);
+ bool locked = true;
+
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ /* mseccfg.RLB is set */
+ if (MSECCFG_RLB_ISSET(env)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is not set */
+ if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is set */
+ if (MSECCFG_MML_ISSET(env)) {
+ /* not adding execute bit */
+ if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
+ locked = false;
+ }
+ /* shared region and not adding X bit */
+ if ((val & PMP_LOCK) != PMP_LOCK &&
+ (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
+ locked = false;
+ }
+ }
} else {
+ if (!pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+ }
+
+ if (locked) {
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
+ } else {
+ env->pmp_state.pmp[pmp_index].cfg_reg = val;
+ pmp_update_rule(env, pmp_index);
}
} else {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -227,6 +244,32 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
{
bool ret;
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (MSECCFG_MMWP_ISSET(env)) {
+ /*
+ * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
+ * so we default to deny all, even for M-mode.
+ */
+ *allowed_privs = 0;
+ return false;
+ } else if (MSECCFG_MML_ISSET(env)) {
+ /*
+ * The Machine Mode Lockdown (mseccfg.MML) bit is set
+ * so we can only execute code in M-mode with an applicable
+ * rule. Other modes are disabled.
+ */
+ if (mode == PRV_M && !(privs & PMP_EXEC)) {
+ ret = true;
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ } else {
+ ret = false;
+ *allowed_privs = 0;
+ }
+
+ return ret;
+ }
+ }
+
if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
/*
* Privileged spec v1.10 states if HW doesn't implement any PMP entry
@@ -304,13 +347,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
/*
- * If the PMP entry is not off and the address is in range, do the priv
- * check
+ * Convert the PMP permissions to match the truth table in the
+ * ePMP spec.
*/
+ const uint8_t epmp_operation =
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
+ (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
+
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
- *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
- if ((mode != PRV_M) || pmp_is_locked(env, i)) {
- *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ /*
+ * If the PMP entry is not off and the address is in range,
+ * do the priv check
+ */
+ if (!MSECCFG_MML_ISSET(env)) {
+ /*
+ * If mseccfg.MML Bit is not set, do pmp priv check
+ * This will always apply to regular PMP.
+ */
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ if ((mode != PRV_M) || pmp_is_locked(env, i)) {
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ }
+ } else {
+ /*
+ * If mseccfg.MML Bit set, do the enhanced pmp priv check
+ */
+ if (mode == PRV_M) {
+ switch (epmp_operation) {
+ case 0:
+ case 1:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ *allowed_privs = 0;
+ break;
+ case 2:
+ case 3:
+ case 14:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 9:
+ case 10:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 11:
+ case 13:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 12:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ }
+ } else {
+ switch (epmp_operation) {
+ case 0:
+ case 8:
+ case 9:
+ case 12:
+ case 13:
+ case 14:
+ *allowed_privs = 0;
+ break;
+ case 1:
+ case 10:
+ case 11:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 2:
+ case 4:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ case 3:
+ case 6:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 5:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 7:
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ break;
+ }
+ }
}
ret = ((privs & *allowed_privs) == privs);
@@ -380,7 +504,23 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val)
{
trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
+
if (addr_index < MAX_RISCV_PMPS) {
+ /*
+ * In TOR mode, need to check the lock bit of the next pmp
+ * (if there is a next).
+ */
+ if (addr_index + 1 < MAX_RISCV_PMPS) {
+ uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
+
+ if (pmp_cfg & PMP_LOCK &&
+ PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ignoring pmpaddr write - pmpcfg + 1 locked\n");
+ return;
+ }
+ }
+
if (!pmp_is_locked(env, addr_index)) {
env->pmp_state.pmp[addr_index].addr_reg = val;
pmp_update_rule(env, addr_index);
@@ -414,6 +554,40 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
}
/*
+ * Handle a write to a mseccfg CSR
+ */
+void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
+{
+ int i;
+
+ trace_mseccfg_csr_write(env->mhartid, val);
+
+ /* RLB cannot be enabled if it's already 0 and if any regions are locked */
+ if (!MSECCFG_RLB_ISSET(env)) {
+ for (i = 0; i < MAX_RISCV_PMPS; i++) {
+ if (pmp_is_locked(env, i)) {
+ val &= ~MSECCFG_RLB;
+ break;
+ }
+ }
+ }
+
+ /* Sticky bits */
+ val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+
+ env->mseccfg = val;
+}
+
+/*
+ * Handle a read from a mseccfg CSR
+ */
+target_ulong mseccfg_csr_read(CPURISCVState *env)
+{
+ trace_mseccfg_csr_read(env->mhartid, env->mseccfg);
+ return env->mseccfg;
+}
+
+/*
* Calculate the TLB size if the start address or the end address of
* PMP entry is presented in thie TLB page.
*/
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index b82a30f0d5..a9a0b363a7 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -36,6 +36,12 @@ typedef enum {
PMP_AMATCH_NAPOT /* Naturally aligned power-of-two region */
} pmp_am_t;
+typedef enum {
+ MSECCFG_MML = 1 << 0,
+ MSECCFG_MMWP = 1 << 1,
+ MSECCFG_RLB = 1 << 2
+} mseccfg_field_t;
+
typedef struct {
target_ulong addr_reg;
uint8_t cfg_reg;
@@ -55,6 +61,10 @@ typedef struct {
void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
target_ulong val);
target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index);
+
+void mseccfg_csr_write(CPURISCVState *env, target_ulong val);
+target_ulong mseccfg_csr_read(CPURISCVState *env);
+
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
@@ -68,4 +78,8 @@ void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
+#define MSECCFG_MML_ISSET(env) get_field(env->mseccfg, MSECCFG_MML)
+#define MSECCFG_MMWP_ISSET(env) get_field(env->mseccfg, MSECCFG_MMWP)
+#define MSECCFG_RLB_ISSET(env) get_field(env->mseccfg, MSECCFG_RLB)
+
#endif
diff --git a/target/riscv/trace-events b/target/riscv/trace-events
index b7e371ee97..49ec4d3b7d 100644
--- a/target/riscv/trace-events
+++ b/target/riscv/trace-events
@@ -6,3 +6,6 @@ pmpcfg_csr_read(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart %" PRI
pmpcfg_csr_write(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart %" PRIu64 ": write reg%" PRIu32", val: 0x%" PRIx64
pmpaddr_csr_read(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %" PRIu64 ": read addr%" PRIu32", val: 0x%" PRIx64
pmpaddr_csr_write(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %" PRIu64 ": write addr%" PRIu32", val: 0x%" PRIx64
+
+mseccfg_csr_read(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": read mseccfg, val: 0x%" PRIx64
+mseccfg_csr_write(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": write mseccfg, val: 0x%" PRIx64
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2f9f5ccc62..e945352bca 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -67,17 +67,22 @@ typedef struct DisasContext {
CPUState *cs;
} DisasContext;
-#ifdef TARGET_RISCV64
-#define CASE_OP_32_64(X) case X: case glue(X, W)
-#else
-#define CASE_OP_32_64(X) case X
-#endif
-
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
{
return ctx->misa & ext;
}
+#ifdef TARGET_RISCV32
+# define is_32bit(ctx) true
+#elif defined(CONFIG_USER_ONLY)
+# define is_32bit(ctx) false
+#else
+static inline bool is_32bit(DisasContext *ctx)
+{
+ return (ctx->misa & RV32) == RV32;
+}
+#endif
+
/*
* RISC-V requires NaN-boxing of narrower width floating point values.
* This applies when a 32-bit value is assigned to a 64-bit FP register.
@@ -116,7 +121,7 @@ static void generate_exception(DisasContext *ctx, int excp)
ctx->base.is_jmp = DISAS_NORETURN;
}
-static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
+static void generate_exception_mtval(DisasContext *ctx, int excp)
{
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
@@ -160,7 +165,7 @@ static void gen_exception_illegal(DisasContext *ctx)
static void gen_exception_inst_addr_mis(DisasContext *ctx)
{
- generate_exception_mbadaddr(ctx, RISCV_EXCP_INST_ADDR_MIS);
+ generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
}
static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
@@ -369,6 +374,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
static void mark_fs_dirty(DisasContext *ctx)
{
TCGv tmp;
+ target_ulong sd;
+
if (ctx->mstatus_fs == MSTATUS_FS) {
return;
}
@@ -376,13 +383,15 @@ static void mark_fs_dirty(DisasContext *ctx)
ctx->mstatus_fs = MSTATUS_FS;
tmp = tcg_temp_new();
+ sd = is_32bit(ctx) ? MSTATUS32_SD : MSTATUS64_SD;
+
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
if (ctx->virt_enabled) {
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
}
tcg_temp_free(tmp);
@@ -426,6 +435,12 @@ EX_SH(12)
} \
} while (0)
+#define REQUIRE_64BIT(ctx) do { \
+ if (is_32bit(ctx)) { \
+ return false; \
+ } \
+} while (0)
+
static int ex_rvc_register(DisasContext *ctx, int reg)
{
return 8 + reg;
@@ -473,7 +488,6 @@ static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
return true;
}
-#ifdef TARGET_RISCV64
static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2)
{
tcg_gen_add_tl(ret, arg1, arg2);
@@ -534,8 +548,6 @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
return true;
}
-#endif
-
static bool gen_arith(DisasContext *ctx, arg_r *a,
void(*func)(TCGv, TCGv, TCGv))
{
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a156573d28..12c31aa4b4 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -751,7 +751,6 @@ GEN_VEXT_AMO_NOATOMIC_OP(vamominw_v_w, 32, 32, H4, DO_MIN, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamomaxw_v_w, 32, 32, H4, DO_MAX, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamominuw_v_w, 32, 32, H4, DO_MINU, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamomaxuw_v_w, 32, 32, H4, DO_MAXU, l)
-#ifdef TARGET_RISCV64
GEN_VEXT_AMO_NOATOMIC_OP(vamoswapw_v_d, 64, 32, H8, DO_SWAP, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamoswapd_v_d, 64, 64, H8, DO_SWAP, q)
GEN_VEXT_AMO_NOATOMIC_OP(vamoaddw_v_d, 64, 32, H8, DO_ADD, l)
@@ -770,7 +769,6 @@ GEN_VEXT_AMO_NOATOMIC_OP(vamominuw_v_d, 64, 32, H8, DO_MINU, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamominud_v_d, 64, 64, H8, DO_MINU, q)
GEN_VEXT_AMO_NOATOMIC_OP(vamomaxuw_v_d, 64, 32, H8, DO_MAXU, l)
GEN_VEXT_AMO_NOATOMIC_OP(vamomaxud_v_d, 64, 64, H8, DO_MAXU, q)
-#endif
static inline void
vext_amo_noatomic(void *vs3, void *v0, target_ulong base,
@@ -814,7 +812,6 @@ void HELPER(NAME)(void *vs3, void *v0, target_ulong base, \
GETPC()); \
}
-#ifdef TARGET_RISCV64
GEN_VEXT_AMO(vamoswapw_v_d, int32_t, int64_t, idx_d, clearq)
GEN_VEXT_AMO(vamoswapd_v_d, int64_t, int64_t, idx_d, clearq)
GEN_VEXT_AMO(vamoaddw_v_d, int32_t, int64_t, idx_d, clearq)
@@ -833,7 +830,6 @@ GEN_VEXT_AMO(vamominuw_v_d, uint32_t, uint64_t, idx_d, clearq)
GEN_VEXT_AMO(vamominud_v_d, uint64_t, uint64_t, idx_d, clearq)
GEN_VEXT_AMO(vamomaxuw_v_d, uint32_t, uint64_t, idx_d, clearq)
GEN_VEXT_AMO(vamomaxud_v_d, uint64_t, uint64_t, idx_d, clearq)
-#endif
GEN_VEXT_AMO(vamoswapw_v_w, int32_t, int32_t, idx_w, clearl)
GEN_VEXT_AMO(vamoaddw_v_w, int32_t, int32_t, idx_w, clearl)
GEN_VEXT_AMO(vamoxorw_v_w, int32_t, int32_t, idx_w, clearl)
@@ -2451,7 +2447,7 @@ static inline int8_t ssub8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
{
int8_t res = a - b;
if ((res ^ a) & (a ^ b) & INT8_MIN) {
- res = a > 0 ? INT8_MAX : INT8_MIN;
+ res = a >= 0 ? INT8_MAX : INT8_MIN;
env->vxsat = 0x1;
}
return res;
@@ -2461,7 +2457,7 @@ static inline int16_t ssub16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
{
int16_t res = a - b;
if ((res ^ a) & (a ^ b) & INT16_MIN) {
- res = a > 0 ? INT16_MAX : INT16_MIN;
+ res = a >= 0 ? INT16_MAX : INT16_MIN;
env->vxsat = 0x1;
}
return res;
@@ -2471,7 +2467,7 @@ static inline int32_t ssub32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
{
int32_t res = a - b;
if ((res ^ a) & (a ^ b) & INT32_MIN) {
- res = a > 0 ? INT32_MAX : INT32_MIN;
+ res = a >= 0 ? INT32_MAX : INT32_MIN;
env->vxsat = 0x1;
}
return res;
@@ -2481,7 +2477,7 @@ static inline int64_t ssub64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
{
int64_t res = a - b;
if ((res ^ a) & (a ^ b) & INT64_MIN) {
- res = a > 0 ? INT64_MAX : INT64_MIN;
+ res = a >= 0 ? INT64_MAX : INT64_MIN;
env->vxsat = 0x1;
}
return res;
@@ -4796,7 +4792,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
- uint32_t index, i; \
+ uint64_t index; \
+ uint32_t i; \
\
for (i = 0; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \
@@ -4826,7 +4823,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
- uint32_t index = s1, i; \
+ uint64_t index = s1; \
+ uint32_t i; \
\
for (i = 0; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \