All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yifei Jiang <jiangyifei@huawei.com>
To: <qemu-devel@nongnu.org>, <qemu-riscv@nongnu.org>
Cc: zhang.zhanghailiang@huawei.com, sagark@eecs.berkeley.edu,
	kbastian@mail.uni-paderborn.de, victor.zhangxiaofeng@huawei.com,
	richard.henderson@linaro.org, Yifei Jiang <jiangyifei@huawei.com>,
	Alistair.Francis@wdc.com, yinyipeng1@huawei.com,
	palmer@dabbelt.com, wu.wubin@huawei.com, dengkai1@huawei.com
Subject: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
Date: Fri, 23 Oct 2020 17:12:20 +0800	[thread overview]
Message-ID: <20201023091225.224-2-jiangyifei@huawei.com> (raw)
In-Reply-To: <20201023091225.224-1-jiangyifei@huawei.com>

mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
This patch expands mstatus and vsstatus to uint64_t instead of
target_ulong so that it can be saved as one unit and reduce some
ifdefs in the code.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/cpu.c        |  8 +++--
 target/riscv/cpu.h        | 16 ++-------
 target/riscv/cpu_bits.h   | 16 ++++-----
 target/riscv/cpu_helper.c | 72 ++++++++++++++++-----------------------
 target/riscv/csr.c        | 28 ++++++++-------
 target/riscv/op_helper.c  | 49 +++++++++++++-------------
 6 files changed, 82 insertions(+), 107 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0bbfd7f457..dd05a220c7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -216,13 +216,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
 #ifndef CONFIG_USER_ONLY
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
 #ifdef TARGET_RISCV32
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
+                 (target_ulong)(env->mstatus >> 32));
 #endif
     if (riscv_has_ext(env, RVH)) {
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
-        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
+        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
+                     (target_ulong)env->vsstatus);
     }
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip     ", env->mip);
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie     ", env->mie);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de275782e6..57050f2268 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -140,14 +140,10 @@ struct CPURISCVState {
     target_ulong resetvec;
 
     target_ulong mhartid;
-    target_ulong mstatus;
+    uint64_t mstatus;
 
     target_ulong mip;
 
-#ifdef TARGET_RISCV32
-    target_ulong mstatush;
-#endif
-
     uint32_t miclaim;
 
     target_ulong mie;
@@ -179,16 +175,13 @@ struct CPURISCVState {
     uint64_t htimedelta;
 
     /* Virtual CSRs */
-    target_ulong vsstatus;
+    uint64_t vsstatus;
     target_ulong vstvec;
     target_ulong vsscratch;
     target_ulong vsepc;
     target_ulong vscause;
     target_ulong vstval;
     target_ulong vsatp;
-#ifdef TARGET_RISCV32
-    target_ulong vsstatush;
-#endif
 
     target_ulong mtval2;
     target_ulong mtinst;
@@ -200,10 +193,7 @@ struct CPURISCVState {
     target_ulong scause_hs;
     target_ulong stval_hs;
     target_ulong satp_hs;
-    target_ulong mstatus_hs;
-#ifdef TARGET_RISCV32
-    target_ulong mstatush_hs;
-#endif
+    uint64_t mstatus_hs;
 
     target_ulong scounteren;
     target_ulong mcounteren;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index bd36062877..62ca6b6f89 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -5,9 +5,14 @@
 
 #define get_field(reg, mask) (((reg) & \
                  (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
+#define get_field64(reg, mask) (((reg) & \
+                   (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
 #define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
                  (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
                  (target_ulong)(mask)))
+#define set_field64(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
+                   (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
+                   (uint64_t)(mask)))
 
 /* Floating point round mode */
 #define FSR_RD_SHIFT        5
@@ -381,19 +386,10 @@
 #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
 #define MSTATUS_TW          0x20000000 /* since: priv-1.10 */
 #define MSTATUS_TSR         0x40000000 /* since: priv-1.10 */
-#if defined(TARGET_RISCV64)
 #define MSTATUS_GVA         0x4000000000ULL
 #define MSTATUS_MPV         0x8000000000ULL
-#elif defined(TARGET_RISCV32)
-#define MSTATUS_GVA         0x00000040
-#define MSTATUS_MPV         0x00000080
-#endif
 
-#ifdef TARGET_RISCV32
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatush, MSTATUS_MPV)
-#else
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatus, MSTATUS_MPV)
-#endif
+#define MSTATUS_MPV_ISSET(env)  get_field64(env->mstatus, MSTATUS_MPV)
 
 #define MSTATUS64_UXL       0x0000000300000000ULL
 #define MSTATUS64_SXL       0x0000000C00000000ULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 904899054d..0430cbe4e3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -39,9 +39,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
     target_ulong irqs;
 
-    target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
-    target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
-    target_ulong hs_mstatus_sie = get_field(env->mstatus_hs, MSTATUS_SIE);
+    target_ulong mstatus_mie = get_field64(env->mstatus, MSTATUS_MIE);
+    target_ulong mstatus_sie = get_field64(env->mstatus, MSTATUS_SIE);
+    target_ulong hs_mstatus_sie = get_field64(env->mstatus_hs, MSTATUS_SIE);
 
     target_ulong pending = env->mip & env->mie &
                                ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
@@ -110,14 +110,20 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
-    target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
-                                MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
+    uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
+                            MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
     bool current_virt = riscv_cpu_virt_enabled(env);
 
     g_assert(riscv_has_ext(env, RVH));
 
 #if defined(TARGET_RISCV64)
     mstatus_mask |= MSTATUS64_UXL;
+#elif defined(TARGET_RISCV32)
+    /*
+     * The upper 32 bits of env->mstatus is mstatush
+     * register in RISCV32. We need to backup it.
+     */
+    mstatus_mask |= (~0ULL << 32);
 #endif
 
     if (current_virt) {
@@ -126,11 +132,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->mstatus_hs;
 
-#if defined(TARGET_RISCV32)
-        env->vsstatush = env->mstatush;
-        env->mstatush |= env->mstatush_hs;
-#endif
-
         env->vstvec = env->stvec;
         env->stvec = env->stvec_hs;
 
@@ -154,11 +155,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->vsstatus;
 
-#if defined(TARGET_RISCV32)
-        env->mstatush_hs = env->mstatush;
-        env->mstatush |= env->vsstatush;
-#endif
-
         env->stvec_hs = env->stvec;
         env->stvec = env->vstvec;
 
@@ -347,8 +343,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     }
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
@@ -370,9 +366,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
 
     if (first_stage == true) {
-        mxr = get_field(env->mstatus, MSTATUS_MXR);
+        mxr = get_field64(env->mstatus, MSTATUS_MXR);
     } else {
-        mxr = get_field(env->vsstatus, MSTATUS_MXR);
+        mxr = get_field64(env->vsstatus, MSTATUS_MXR);
     }
 
     if (first_stage == true) {
@@ -389,7 +385,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
         vm = get_field(env->hgatp, HGATP_MODE);
         widened = 2;
     }
-    sum = get_field(env->mstatus, MSTATUS_SUM);
+    sum = get_field64(env->mstatus, MSTATUS_SUM);
     switch (vm) {
     case VM_1_10_SV32:
       levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -712,14 +708,14 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                   __func__, address, access_type, mmu_idx);
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, true);
     }
@@ -780,7 +776,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     /* We did the two stage lookup based on MPRV, unset the lookup */
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, false);
     }
@@ -844,7 +840,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
-    target_ulong s;
+    uint64_t s;
 
     /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
      * so we mask off the MSB and separate into trap type and cause.
@@ -932,7 +928,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
                 /* Trap into HS mode, from virt */
                 riscv_cpu_swap_hypervisor_regs(env);
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
-                                         get_field(env->mstatus, SSTATUS_SPP));
+                                         get_field64(env->mstatus, SSTATUS_SPP));
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
                                          riscv_cpu_virt_enabled(env));
 
@@ -952,9 +948,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
-        s = set_field(s, MSTATUS_SPP, env->priv);
-        s = set_field(s, MSTATUS_SIE, 0);
+        s = set_field64(s, MSTATUS_SPIE, get_field64(s, MSTATUS_SIE));
+        s = set_field64(s, MSTATUS_SPP, env->priv);
+        s = set_field64(s, MSTATUS_SIE, 0);
         env->mstatus = s;
         env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
         env->sepc = env->pc;
@@ -969,19 +965,11 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             if (riscv_cpu_virt_enabled(env)) {
                 riscv_cpu_swap_hypervisor_regs(env);
             }
-#ifdef TARGET_RISCV32
-            env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
+            env->mstatus = set_field64(env->mstatus, MSTATUS_MPV,
                                        riscv_cpu_virt_enabled(env));
             if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
-            }
-#else
-            env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
-                                      riscv_cpu_virt_enabled(env));
-            if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
+                env->mstatus = set_field64(env->mstatus, MSTATUS_GVA, 1);
             }
-#endif
 
             mtval2 = env->guest_phys_fault_addr;
 
@@ -991,9 +979,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
-        s = set_field(s, MSTATUS_MPP, env->priv);
-        s = set_field(s, MSTATUS_MIE, 0);
+        s = set_field64(s, MSTATUS_MPIE, get_field64(s, MSTATUS_MIE));
+        s = set_field64(s, MSTATUS_MPP, env->priv);
+        s = set_field64(s, MSTATUS_MIE, 0);
         env->mstatus = s;
         env->mcause = cause | ~(((target_ulong)-1) >> async);
         env->mepc = env->pc;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index aaef6c6f20..d4b6371719 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -446,8 +446,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
 
 static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    target_ulong mstatus = env->mstatus;
-    target_ulong mask = 0;
+    uint64_t mstatus = env->mstatus;
+    uint64_t mask = 0;
     int dirty;
 
     /* flush tlb on mstatus fields that affect VM */
@@ -471,7 +471,7 @@ 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);
+    mstatus = set_field64(mstatus, MSTATUS_SD, dirty);
     env->mstatus = mstatus;
 
     return 0;
@@ -480,19 +480,20 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 #ifdef TARGET_RISCV32
 static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
 {
-    *val = env->mstatush;
+    *val = env->mstatus >> 32;
     return 0;
 }
 
 static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
 {
-    if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
+    uint64_t valh = (uint64_t)val << 32;
+    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
+
+    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
         tlb_flush(env_cpu(env));
     }
 
-    val &= MSTATUS_MPV | MSTATUS_GVA;
-
-    env->mstatush = val;
+    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
 
     return 0;
 }
@@ -718,14 +719,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
 static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    *val = env->mstatus & mask;
+    *val = (target_ulong)env->mstatus & mask;
     return 0;
 }
 
 static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
+    target_ulong newval = ((target_ulong)env->mstatus & ~mask) | (val & mask);
     return write_mstatus(env, CSR_MSTATUS, newval);
 }
 
@@ -861,7 +862,7 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
         return 0;
     }
 
-    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+    if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
         return -RISCV_EXCP_ILLEGAL_INST;
     } else {
         *val = env->satp;
@@ -878,7 +879,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
     if (validate_vm(env, get_field(val, SATP_MODE)) &&
         ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
     {
-        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+        if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
             return -RISCV_EXCP_ILLEGAL_INST;
         } else {
             if((val ^ env->satp) & SATP_ASID) {
@@ -1105,7 +1106,8 @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
 
 static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    env->vsstatus = val;
+    uint64_t mask = (target_ulong)-1;
+    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
     return 0;
 }
 
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 9b9ada45a9..18cdffc738 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -79,7 +79,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
-    target_ulong prev_priv, prev_virt, mstatus;
+    uint64_t mstatus;
+    target_ulong prev_priv, prev_virt;
 
     if (!(env->priv >= PRV_S)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
@@ -90,7 +91,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
+    if (get_field64(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
@@ -105,14 +106,14 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         /* We support Hypervisor extensions and virtulisation is disabled */
         target_ulong hstatus = env->hstatus;
 
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
         prev_virt = get_field(hstatus, HSTATUS_SPV);
 
         hstatus = set_field(hstatus, HSTATUS_SPV, 0);
-        mstatus = set_field(mstatus, MSTATUS_SPP, 0);
-        mstatus = set_field(mstatus, SSTATUS_SIE,
-                            get_field(mstatus, SSTATUS_SPIE));
-        mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, 0);
+        mstatus = set_field64(mstatus, SSTATUS_SIE,
+                              get_field64(mstatus, SSTATUS_SPIE));
+        mstatus = set_field64(mstatus, SSTATUS_SPIE, 1);
 
         env->mstatus = mstatus;
         env->hstatus = hstatus;
@@ -123,12 +124,12 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 
         riscv_cpu_set_virt_enabled(env, prev_virt);
     } else {
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
 
-        mstatus = set_field(mstatus, MSTATUS_SIE,
-                            get_field(mstatus, MSTATUS_SPIE));
-        mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
-        mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+        mstatus = set_field64(mstatus, MSTATUS_SIE,
+                              get_field64(mstatus, MSTATUS_SPIE));
+        mstatus = set_field64(mstatus, MSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, PRV_U);
         env->mstatus = mstatus;
     }
 
@@ -148,18 +149,14 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    target_ulong mstatus = env->mstatus;
-    target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+    uint64_t mstatus = env->mstatus;
+    target_ulong prev_priv = get_field64(mstatus, MSTATUS_MPP);
     target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
-    mstatus = set_field(mstatus, MSTATUS_MIE,
-                        get_field(mstatus, MSTATUS_MPIE));
-    mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
-    mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
-#ifdef TARGET_RISCV32
-    env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
-#else
-    mstatus = set_field(mstatus, MSTATUS_MPV, 0);
-#endif
+    mstatus = set_field64(mstatus, MSTATUS_MIE,
+                          get_field64(mstatus, MSTATUS_MPIE));
+    mstatus = set_field64(mstatus, MSTATUS_MPIE, 1);
+    mstatus = set_field64(mstatus, MSTATUS_MPP, PRV_U);
+    mstatus = set_field64(mstatus, MSTATUS_MPV, 0);
     env->mstatus = mstatus;
     riscv_cpu_set_mode(env, prev_priv);
 
@@ -179,7 +176,7 @@ void helper_wfi(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
 
     if ((env->priv == PRV_S &&
-        get_field(env->mstatus, MSTATUS_TW)) ||
+        get_field64(env->mstatus, MSTATUS_TW)) ||
         riscv_cpu_virt_enabled(env)) {
         riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
     } else {
@@ -194,7 +191,7 @@ void helper_tlb_flush(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
     if (!(env->priv >= PRV_S) ||
         (env->priv == PRV_S &&
-         get_field(env->mstatus, MSTATUS_TVM))) {
+         get_field64(env->mstatus, MSTATUS_TVM))) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
                get_field(env->hstatus, HSTATUS_VTVM)) {
@@ -224,7 +221,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
 void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 {
     if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
-        get_field(env->mstatus, MSTATUS_TVM)) {
+        get_field64(env->mstatus, MSTATUS_TVM)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
-- 
2.19.1



WARNING: multiple messages have this Message-ID (diff)
From: Yifei Jiang <jiangyifei@huawei.com>
To: <qemu-devel@nongnu.org>, <qemu-riscv@nongnu.org>
Cc: <palmer@dabbelt.com>, <Alistair.Francis@wdc.com>,
	<sagark@eecs.berkeley.edu>, <kbastian@mail.uni-paderborn.de>,
	<richard.henderson@linaro.org>, <victor.zhangxiaofeng@huawei.com>,
	<wu.wubin@huawei.com>, <zhang.zhanghailiang@huawei.com>,
	<dengkai1@huawei.com>, <yinyipeng1@huawei.com>,
	Yifei Jiang <jiangyifei@huawei.com>
Subject: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
Date: Fri, 23 Oct 2020 17:12:20 +0800	[thread overview]
Message-ID: <20201023091225.224-2-jiangyifei@huawei.com> (raw)
In-Reply-To: <20201023091225.224-1-jiangyifei@huawei.com>

mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
This patch expands mstatus and vsstatus to uint64_t instead of
target_ulong so that it can be saved as one unit and reduce some
ifdefs in the code.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/cpu.c        |  8 +++--
 target/riscv/cpu.h        | 16 ++-------
 target/riscv/cpu_bits.h   | 16 ++++-----
 target/riscv/cpu_helper.c | 72 ++++++++++++++++-----------------------
 target/riscv/csr.c        | 28 ++++++++-------
 target/riscv/op_helper.c  | 49 +++++++++++++-------------
 6 files changed, 82 insertions(+), 107 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0bbfd7f457..dd05a220c7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -216,13 +216,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
 #ifndef CONFIG_USER_ONLY
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
 #ifdef TARGET_RISCV32
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
+                 (target_ulong)(env->mstatus >> 32));
 #endif
     if (riscv_has_ext(env, RVH)) {
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
-        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
+        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
+                     (target_ulong)env->vsstatus);
     }
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip     ", env->mip);
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie     ", env->mie);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de275782e6..57050f2268 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -140,14 +140,10 @@ struct CPURISCVState {
     target_ulong resetvec;
 
     target_ulong mhartid;
-    target_ulong mstatus;
+    uint64_t mstatus;
 
     target_ulong mip;
 
-#ifdef TARGET_RISCV32
-    target_ulong mstatush;
-#endif
-
     uint32_t miclaim;
 
     target_ulong mie;
@@ -179,16 +175,13 @@ struct CPURISCVState {
     uint64_t htimedelta;
 
     /* Virtual CSRs */
-    target_ulong vsstatus;
+    uint64_t vsstatus;
     target_ulong vstvec;
     target_ulong vsscratch;
     target_ulong vsepc;
     target_ulong vscause;
     target_ulong vstval;
     target_ulong vsatp;
-#ifdef TARGET_RISCV32
-    target_ulong vsstatush;
-#endif
 
     target_ulong mtval2;
     target_ulong mtinst;
@@ -200,10 +193,7 @@ struct CPURISCVState {
     target_ulong scause_hs;
     target_ulong stval_hs;
     target_ulong satp_hs;
-    target_ulong mstatus_hs;
-#ifdef TARGET_RISCV32
-    target_ulong mstatush_hs;
-#endif
+    uint64_t mstatus_hs;
 
     target_ulong scounteren;
     target_ulong mcounteren;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index bd36062877..62ca6b6f89 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -5,9 +5,14 @@
 
 #define get_field(reg, mask) (((reg) & \
                  (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
+#define get_field64(reg, mask) (((reg) & \
+                   (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
 #define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
                  (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
                  (target_ulong)(mask)))
+#define set_field64(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
+                   (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
+                   (uint64_t)(mask)))
 
 /* Floating point round mode */
 #define FSR_RD_SHIFT        5
@@ -381,19 +386,10 @@
 #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
 #define MSTATUS_TW          0x20000000 /* since: priv-1.10 */
 #define MSTATUS_TSR         0x40000000 /* since: priv-1.10 */
-#if defined(TARGET_RISCV64)
 #define MSTATUS_GVA         0x4000000000ULL
 #define MSTATUS_MPV         0x8000000000ULL
-#elif defined(TARGET_RISCV32)
-#define MSTATUS_GVA         0x00000040
-#define MSTATUS_MPV         0x00000080
-#endif
 
-#ifdef TARGET_RISCV32
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatush, MSTATUS_MPV)
-#else
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatus, MSTATUS_MPV)
-#endif
+#define MSTATUS_MPV_ISSET(env)  get_field64(env->mstatus, MSTATUS_MPV)
 
 #define MSTATUS64_UXL       0x0000000300000000ULL
 #define MSTATUS64_SXL       0x0000000C00000000ULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 904899054d..0430cbe4e3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -39,9 +39,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
     target_ulong irqs;
 
-    target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
-    target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
-    target_ulong hs_mstatus_sie = get_field(env->mstatus_hs, MSTATUS_SIE);
+    target_ulong mstatus_mie = get_field64(env->mstatus, MSTATUS_MIE);
+    target_ulong mstatus_sie = get_field64(env->mstatus, MSTATUS_SIE);
+    target_ulong hs_mstatus_sie = get_field64(env->mstatus_hs, MSTATUS_SIE);
 
     target_ulong pending = env->mip & env->mie &
                                ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
@@ -110,14 +110,20 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
-    target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
-                                MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
+    uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
+                            MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
     bool current_virt = riscv_cpu_virt_enabled(env);
 
     g_assert(riscv_has_ext(env, RVH));
 
 #if defined(TARGET_RISCV64)
     mstatus_mask |= MSTATUS64_UXL;
+#elif defined(TARGET_RISCV32)
+    /*
+     * The upper 32 bits of env->mstatus is mstatush
+     * register in RISCV32. We need to backup it.
+     */
+    mstatus_mask |= (~0ULL << 32);
 #endif
 
     if (current_virt) {
@@ -126,11 +132,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->mstatus_hs;
 
-#if defined(TARGET_RISCV32)
-        env->vsstatush = env->mstatush;
-        env->mstatush |= env->mstatush_hs;
-#endif
-
         env->vstvec = env->stvec;
         env->stvec = env->stvec_hs;
 
@@ -154,11 +155,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->vsstatus;
 
-#if defined(TARGET_RISCV32)
-        env->mstatush_hs = env->mstatush;
-        env->mstatush |= env->vsstatush;
-#endif
-
         env->stvec_hs = env->stvec;
         env->stvec = env->vstvec;
 
@@ -347,8 +343,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     }
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
@@ -370,9 +366,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
 
     if (first_stage == true) {
-        mxr = get_field(env->mstatus, MSTATUS_MXR);
+        mxr = get_field64(env->mstatus, MSTATUS_MXR);
     } else {
-        mxr = get_field(env->vsstatus, MSTATUS_MXR);
+        mxr = get_field64(env->vsstatus, MSTATUS_MXR);
     }
 
     if (first_stage == true) {
@@ -389,7 +385,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
         vm = get_field(env->hgatp, HGATP_MODE);
         widened = 2;
     }
-    sum = get_field(env->mstatus, MSTATUS_SUM);
+    sum = get_field64(env->mstatus, MSTATUS_SUM);
     switch (vm) {
     case VM_1_10_SV32:
       levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -712,14 +708,14 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                   __func__, address, access_type, mmu_idx);
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, true);
     }
@@ -780,7 +776,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     /* We did the two stage lookup based on MPRV, unset the lookup */
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, false);
     }
@@ -844,7 +840,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
-    target_ulong s;
+    uint64_t s;
 
     /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
      * so we mask off the MSB and separate into trap type and cause.
@@ -932,7 +928,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
                 /* Trap into HS mode, from virt */
                 riscv_cpu_swap_hypervisor_regs(env);
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
-                                         get_field(env->mstatus, SSTATUS_SPP));
+                                         get_field64(env->mstatus, SSTATUS_SPP));
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
                                          riscv_cpu_virt_enabled(env));
 
@@ -952,9 +948,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
-        s = set_field(s, MSTATUS_SPP, env->priv);
-        s = set_field(s, MSTATUS_SIE, 0);
+        s = set_field64(s, MSTATUS_SPIE, get_field64(s, MSTATUS_SIE));
+        s = set_field64(s, MSTATUS_SPP, env->priv);
+        s = set_field64(s, MSTATUS_SIE, 0);
         env->mstatus = s;
         env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
         env->sepc = env->pc;
@@ -969,19 +965,11 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             if (riscv_cpu_virt_enabled(env)) {
                 riscv_cpu_swap_hypervisor_regs(env);
             }
-#ifdef TARGET_RISCV32
-            env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
+            env->mstatus = set_field64(env->mstatus, MSTATUS_MPV,
                                        riscv_cpu_virt_enabled(env));
             if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
-            }
-#else
-            env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
-                                      riscv_cpu_virt_enabled(env));
-            if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
+                env->mstatus = set_field64(env->mstatus, MSTATUS_GVA, 1);
             }
-#endif
 
             mtval2 = env->guest_phys_fault_addr;
 
@@ -991,9 +979,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
-        s = set_field(s, MSTATUS_MPP, env->priv);
-        s = set_field(s, MSTATUS_MIE, 0);
+        s = set_field64(s, MSTATUS_MPIE, get_field64(s, MSTATUS_MIE));
+        s = set_field64(s, MSTATUS_MPP, env->priv);
+        s = set_field64(s, MSTATUS_MIE, 0);
         env->mstatus = s;
         env->mcause = cause | ~(((target_ulong)-1) >> async);
         env->mepc = env->pc;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index aaef6c6f20..d4b6371719 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -446,8 +446,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
 
 static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    target_ulong mstatus = env->mstatus;
-    target_ulong mask = 0;
+    uint64_t mstatus = env->mstatus;
+    uint64_t mask = 0;
     int dirty;
 
     /* flush tlb on mstatus fields that affect VM */
@@ -471,7 +471,7 @@ 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);
+    mstatus = set_field64(mstatus, MSTATUS_SD, dirty);
     env->mstatus = mstatus;
 
     return 0;
@@ -480,19 +480,20 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 #ifdef TARGET_RISCV32
 static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
 {
-    *val = env->mstatush;
+    *val = env->mstatus >> 32;
     return 0;
 }
 
 static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
 {
-    if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
+    uint64_t valh = (uint64_t)val << 32;
+    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
+
+    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
         tlb_flush(env_cpu(env));
     }
 
-    val &= MSTATUS_MPV | MSTATUS_GVA;
-
-    env->mstatush = val;
+    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
 
     return 0;
 }
@@ -718,14 +719,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
 static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    *val = env->mstatus & mask;
+    *val = (target_ulong)env->mstatus & mask;
     return 0;
 }
 
 static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
+    target_ulong newval = ((target_ulong)env->mstatus & ~mask) | (val & mask);
     return write_mstatus(env, CSR_MSTATUS, newval);
 }
 
@@ -861,7 +862,7 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
         return 0;
     }
 
-    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+    if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
         return -RISCV_EXCP_ILLEGAL_INST;
     } else {
         *val = env->satp;
@@ -878,7 +879,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
     if (validate_vm(env, get_field(val, SATP_MODE)) &&
         ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
     {
-        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+        if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
             return -RISCV_EXCP_ILLEGAL_INST;
         } else {
             if((val ^ env->satp) & SATP_ASID) {
@@ -1105,7 +1106,8 @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
 
 static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    env->vsstatus = val;
+    uint64_t mask = (target_ulong)-1;
+    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
     return 0;
 }
 
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 9b9ada45a9..18cdffc738 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -79,7 +79,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
-    target_ulong prev_priv, prev_virt, mstatus;
+    uint64_t mstatus;
+    target_ulong prev_priv, prev_virt;
 
     if (!(env->priv >= PRV_S)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
@@ -90,7 +91,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
+    if (get_field64(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
@@ -105,14 +106,14 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         /* We support Hypervisor extensions and virtulisation is disabled */
         target_ulong hstatus = env->hstatus;
 
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
         prev_virt = get_field(hstatus, HSTATUS_SPV);
 
         hstatus = set_field(hstatus, HSTATUS_SPV, 0);
-        mstatus = set_field(mstatus, MSTATUS_SPP, 0);
-        mstatus = set_field(mstatus, SSTATUS_SIE,
-                            get_field(mstatus, SSTATUS_SPIE));
-        mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, 0);
+        mstatus = set_field64(mstatus, SSTATUS_SIE,
+                              get_field64(mstatus, SSTATUS_SPIE));
+        mstatus = set_field64(mstatus, SSTATUS_SPIE, 1);
 
         env->mstatus = mstatus;
         env->hstatus = hstatus;
@@ -123,12 +124,12 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 
         riscv_cpu_set_virt_enabled(env, prev_virt);
     } else {
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
 
-        mstatus = set_field(mstatus, MSTATUS_SIE,
-                            get_field(mstatus, MSTATUS_SPIE));
-        mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
-        mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+        mstatus = set_field64(mstatus, MSTATUS_SIE,
+                              get_field64(mstatus, MSTATUS_SPIE));
+        mstatus = set_field64(mstatus, MSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, PRV_U);
         env->mstatus = mstatus;
     }
 
@@ -148,18 +149,14 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    target_ulong mstatus = env->mstatus;
-    target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+    uint64_t mstatus = env->mstatus;
+    target_ulong prev_priv = get_field64(mstatus, MSTATUS_MPP);
     target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
-    mstatus = set_field(mstatus, MSTATUS_MIE,
-                        get_field(mstatus, MSTATUS_MPIE));
-    mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
-    mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
-#ifdef TARGET_RISCV32
-    env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
-#else
-    mstatus = set_field(mstatus, MSTATUS_MPV, 0);
-#endif
+    mstatus = set_field64(mstatus, MSTATUS_MIE,
+                          get_field64(mstatus, MSTATUS_MPIE));
+    mstatus = set_field64(mstatus, MSTATUS_MPIE, 1);
+    mstatus = set_field64(mstatus, MSTATUS_MPP, PRV_U);
+    mstatus = set_field64(mstatus, MSTATUS_MPV, 0);
     env->mstatus = mstatus;
     riscv_cpu_set_mode(env, prev_priv);
 
@@ -179,7 +176,7 @@ void helper_wfi(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
 
     if ((env->priv == PRV_S &&
-        get_field(env->mstatus, MSTATUS_TW)) ||
+        get_field64(env->mstatus, MSTATUS_TW)) ||
         riscv_cpu_virt_enabled(env)) {
         riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
     } else {
@@ -194,7 +191,7 @@ void helper_tlb_flush(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
     if (!(env->priv >= PRV_S) ||
         (env->priv == PRV_S &&
-         get_field(env->mstatus, MSTATUS_TVM))) {
+         get_field64(env->mstatus, MSTATUS_TVM))) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
                get_field(env->hstatus, HSTATUS_VTVM)) {
@@ -224,7 +221,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
 void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 {
     if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
-        get_field(env->mstatus, MSTATUS_TVM)) {
+        get_field64(env->mstatus, MSTATUS_TVM)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
-- 
2.19.1



  reply	other threads:[~2020-10-23  9:17 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
2020-10-23  9:12 ` Yifei Jiang
2020-10-23  9:12 ` Yifei Jiang [this message]
2020-10-23  9:12   ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
2020-10-23  9:41   ` Jiangyifei
2020-10-23  9:41     ` Jiangyifei
2020-10-23 23:50   ` Alistair Francis
2020-10-23 23:50     ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
2020-10-23  9:12   ` Yifei Jiang
2020-10-23 23:52   ` Alistair Francis
2020-10-23 23:52     ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 3/6] target/riscv: Add PMP state description Yifei Jiang
2020-10-23  9:12   ` Yifei Jiang
2020-10-23 23:59   ` Alistair Francis
2020-10-23 23:59     ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 4/6] target/riscv: Add H extension " Yifei Jiang
2020-10-23  9:12   ` Yifei Jiang
2020-10-24  0:00   ` Alistair Francis
2020-10-24  0:00     ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 5/6] target/riscv: Add V " Yifei Jiang
2020-10-23  9:12   ` Yifei Jiang
2020-10-24  0:01   ` Alistair Francis
2020-10-24  0:01     ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
2020-10-23  9:12   ` Yifei Jiang
2020-10-24  0:02   ` Alistair Francis
2020-10-24  0:02     ` Alistair Francis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201023091225.224-2-jiangyifei@huawei.com \
    --to=jiangyifei@huawei.com \
    --cc=Alistair.Francis@wdc.com \
    --cc=dengkai1@huawei.com \
    --cc=kbastian@mail.uni-paderborn.de \
    --cc=palmer@dabbelt.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=sagark@eecs.berkeley.edu \
    --cc=victor.zhangxiaofeng@huawei.com \
    --cc=wu.wubin@huawei.com \
    --cc=yinyipeng1@huawei.com \
    --cc=zhang.zhanghailiang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.