Re: [PATCH v7 18/18] target/riscv: actual functions to realize crs 128-bit insns
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
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