Re: [PATCH v7 18/18] target/riscv: actual functions to realize crs 128-bit insns

2022-01-05 Thread Alistair Francis
On Tue, Dec 14, 2021 at 3:01 AM Frédéric Pétrot
 wrote:
>
> The csrs are accessed through function pointers: we add 128-bit read
> operations in the table for three csrs (writes fallback to the
> 64-bit version as the upper 64-bit information is handled elsewhere):
> - misa, as mxl is needed for proper operation,
> - mstatus and sstatus, to return sd
> In addition, we also add read and write accesses to the machine and
> supervisor scratch registers.
>
> Signed-off-by: Frédéric Pétrot 
> Co-authored-by: Fabien Portas 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h  |   7 ++
>  target/riscv/cpu_bits.h |   3 +
>  target/riscv/csr.c  | 195 +---
>  3 files changed, 175 insertions(+), 30 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 00e5081598..3e770e3d03 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -486,12 +486,19 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int 
> csrno,
>  Int128 *ret_value,
>  Int128 new_value, Int128 write_mask);
>
> +typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
> +   Int128 *ret_value);
> +typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int 
> csrno,
> + Int128 new_value);
> +
>  typedef struct {
>  const char *name;
>  riscv_csr_predicate_fn predicate;
>  riscv_csr_read_fn read;
>  riscv_csr_write_fn write;
>  riscv_csr_op_fn op;
> +riscv_csr_read128_fn read128;
> +riscv_csr_write128_fn write128;
>  } riscv_csr_operations;
>
>  /* CSR function table constants */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 9913fa9f77..390ba0a52f 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -392,6 +392,7 @@
>
>  #define MSTATUS32_SD0x8000
>  #define MSTATUS64_SD0x8000ULL
> +#define MSTATUSH128_SD  0x8000ULL
>
>  #define MISA32_MXL  0xC000
>  #define MISA64_MXL  0xC000ULL
> @@ -413,6 +414,8 @@ typedef enum {
>  #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
>  #define SSTATUS_MXR 0x0008
>
> +#define SSTATUS64_UXL   0x0003ULL
> +
>  #define SSTATUS32_SD0x8000
>  #define SSTATUS64_SD0x8000ULL
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index dca9e19a64..404aa2f31d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -453,7 +453,7 @@ static const target_ulong vs_delegable_excps = 
> 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_SUM | SSTATUS_MXR | (target_ulong)SSTATUS64_UXL;
>  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;
> @@ -498,6 +498,8 @@ static uint64_t add_status_sd(RISCVMXL xl, uint64_t 
> status)
>  return status | MSTATUS32_SD;
>  case MXL_RV64:
>  return status | MSTATUS64_SD;
> +case MXL_RV128:
> +return MSTATUSH128_SD;
>  default:
>  g_assert_not_reached();
>  }
> @@ -547,10 +549,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
> int csrno,
>
>  mstatus = (mstatus & ~mask) | (val & mask);
>
> -if (riscv_cpu_mxl(env) == MXL_RV64) {
> +RISCVMXL xl = riscv_cpu_mxl(env);
> +if (xl > MXL_RV32) {
>  /* SXL and UXL fields are for now read only */
> -mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
> -mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
> +mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
> +mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>  }
>  env->mstatus = mstatus;
>
> @@ -579,6 +582,20 @@ static RISCVException write_mstatush(CPURISCVState *env, 
> int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
> +Int128 *val)
> +{
> +*val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, 
> env->mstatus));
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
> + Int128 *val)
> +{
> +*val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
> +return RISCV_EXCP_NONE;
> +}
> +
>  static RISCVException read_misa(CPURISCVState *env, int csrno,
>  target_ulong *val)
>  {

[PATCH v7 18/18] target/riscv: actual functions to realize crs 128-bit insns

2021-12-13 Thread Frédéric Pétrot
The csrs are accessed through function pointers: we add 128-bit read
operations in the table for three csrs (writes fallback to the
64-bit version as the upper 64-bit information is handled elsewhere):
- misa, as mxl is needed for proper operation,
- mstatus and sstatus, to return sd
In addition, we also add read and write accesses to the machine and
supervisor scratch registers.

Signed-off-by: Frédéric Pétrot 
Co-authored-by: Fabien Portas 
---
 target/riscv/cpu.h  |   7 ++
 target/riscv/cpu_bits.h |   3 +
 target/riscv/csr.c  | 195 +---
 3 files changed, 175 insertions(+), 30 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 00e5081598..3e770e3d03 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -486,12 +486,19 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int 
csrno,
 Int128 *ret_value,
 Int128 new_value, Int128 write_mask);
 
+typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
+   Int128 *ret_value);
+typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno,
+ Int128 new_value);
+
 typedef struct {
 const char *name;
 riscv_csr_predicate_fn predicate;
 riscv_csr_read_fn read;
 riscv_csr_write_fn write;
 riscv_csr_op_fn op;
+riscv_csr_read128_fn read128;
+riscv_csr_write128_fn write128;
 } riscv_csr_operations;
 
 /* CSR function table constants */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 9913fa9f77..390ba0a52f 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -392,6 +392,7 @@
 
 #define MSTATUS32_SD0x8000
 #define MSTATUS64_SD0x8000ULL
+#define MSTATUSH128_SD  0x8000ULL
 
 #define MISA32_MXL  0xC000
 #define MISA64_MXL  0xC000ULL
@@ -413,6 +414,8 @@ typedef enum {
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
 #define SSTATUS_MXR 0x0008
 
+#define SSTATUS64_UXL   0x0003ULL
+
 #define SSTATUS32_SD0x8000
 #define SSTATUS64_SD0x8000ULL
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index dca9e19a64..404aa2f31d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -453,7 +453,7 @@ static const target_ulong vs_delegable_excps = 
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_SUM | SSTATUS_MXR | (target_ulong)SSTATUS64_UXL;
 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;
@@ -498,6 +498,8 @@ static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
 return status | MSTATUS32_SD;
 case MXL_RV64:
 return status | MSTATUS64_SD;
+case MXL_RV128:
+return MSTATUSH128_SD;
 default:
 g_assert_not_reached();
 }
@@ -547,10 +549,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 
 mstatus = (mstatus & ~mask) | (val & mask);
 
-if (riscv_cpu_mxl(env) == MXL_RV64) {
+RISCVMXL xl = riscv_cpu_mxl(env);
+if (xl > MXL_RV32) {
 /* SXL and UXL fields are for now read only */
-mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
-mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
+mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
+mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
 }
 env->mstatus = mstatus;
 
@@ -579,6 +582,20 @@ static RISCVException write_mstatush(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
+Int128 *val)
+{
+*val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, 
env->mstatus));
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
+ Int128 *val)
+{
+*val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_misa(CPURISCVState *env, int csrno,
 target_ulong *val)
 {
@@ -736,6 +753,21 @@ static RISCVException write_mcounteren(CPURISCVState *env, 
int csrno,
 }
 
 /* Machine Trap Handling */
+static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
+ Int128 *val)
+{
+*val = int128_make128(env->mscratch, env->mscratchh);
+return