Message ID | 20221118123728.49319-8-liweiwei@iscas.ac.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | support subsets of code size reduction extension | expand |
On 11/18/22 04:37, Weiwei Li wrote: > Add encode, trans* functions and helper functions support for Zcmt > instrutions > Add support for jvt csr > > Signed-off-by: Weiwei Li<liweiwei@iscas.ac.cn> > Signed-off-by: Junqiang Wang<wangjunqiang@iscas.ac.cn> > --- > target/riscv/cpu.h | 4 ++ > target/riscv/cpu_bits.h | 7 +++ > target/riscv/csr.c | 38 +++++++++++++++- > target/riscv/helper.h | 3 ++ > target/riscv/insn16.decode | 7 ++- > target/riscv/insn_trans/trans_rvzce.c.inc | 28 +++++++++++- > target/riscv/machine.c | 19 ++++++++ > target/riscv/meson.build | 3 +- > target/riscv/zce_helper.c | 55 +++++++++++++++++++++++ > 9 files changed, 159 insertions(+), 5 deletions(-) > create mode 100644 target/riscv/zce_helper.c Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
On Fri, Nov 18, 2022 at 10:46 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote: > > Add encode, trans* functions and helper functions support for Zcmt > instrutions > Add support for jvt csr > > Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> > Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > target/riscv/cpu.h | 4 ++ > target/riscv/cpu_bits.h | 7 +++ > target/riscv/csr.c | 38 +++++++++++++++- > target/riscv/helper.h | 3 ++ > target/riscv/insn16.decode | 7 ++- > target/riscv/insn_trans/trans_rvzce.c.inc | 28 +++++++++++- > target/riscv/machine.c | 19 ++++++++ > target/riscv/meson.build | 3 +- > target/riscv/zce_helper.c | 55 +++++++++++++++++++++++ > 9 files changed, 159 insertions(+), 5 deletions(-) > create mode 100644 target/riscv/zce_helper.c > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 6e915b6937..7bcedc7467 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -181,6 +181,8 @@ struct CPUArchState { > > uint32_t features; > > + target_ulong jvt; > + > #ifdef CONFIG_USER_ONLY > uint32_t elf_flags; > #endif > @@ -600,6 +602,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, > target_ulong new_val, > target_ulong write_mask), > void *rmw_fn_arg); > + > +RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit); > #endif > void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv); > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h > index 8b0d7e20ea..ce347e5575 100644 > --- a/target/riscv/cpu_bits.h > +++ b/target/riscv/cpu_bits.h > @@ -319,6 +319,7 @@ > #define SMSTATEEN_MAX_COUNT 4 > #define SMSTATEEN0_CS (1ULL << 0) > #define SMSTATEEN0_FCSR (1ULL << 1) > +#define SMSTATEEN0_JVT (1ULL << 2) > #define SMSTATEEN0_HSCONTXT (1ULL << 57) > #define SMSTATEEN0_IMSIC (1ULL << 58) > #define SMSTATEEN0_AIA (1ULL << 59) > @@ -523,6 +524,9 @@ > /* Crypto Extension */ > #define CSR_SEED 0x015 > > +/* Zcmt Extension */ > +#define CSR_JVT 0x017 > + > /* mstatus CSR bits */ > #define MSTATUS_UIE 0x00000001 > #define MSTATUS_SIE 0x00000002 > @@ -894,4 +898,7 @@ typedef enum RISCVException { > #define MHPMEVENT_IDX_MASK 0xFFFFF > #define MHPMEVENT_SSCOF_RESVD 16 > > +/* JVT CSR bits */ > +#define JVT_MODE 0x3F > +#define JVT_BASE (~0x3F) > #endif > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 8b25f885ec..5115dc882d 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops) > > /* Predicates */ > #if !defined(CONFIG_USER_ONLY) > -static RISCVException smstateen_acc_ok(CPURISCVState *env, int index, > - uint64_t bit) > +RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit) > { > bool virt = riscv_cpu_virt_enabled(env); > CPUState *cs = env_cpu(env); > @@ -167,6 +166,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno) > return ctr(env, csrno); > } > > +static RISCVException zcmt(CPURISCVState *env, int csrno) > +{ > + RISCVCPU *cpu = env_archcpu(env); > + > + if (!cpu->cfg.ext_zcmt) { > + return RISCV_EXCP_ILLEGAL_INST; > + } > + > +#if !defined(CONFIG_USER_ONLY) > + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT); > + if (ret != RISCV_EXCP_NONE) { > + return ret; > + } > +#endif > + > + return RISCV_EXCP_NONE; > +} > + > #if !defined(CONFIG_USER_ONLY) > static RISCVException mctr(CPURISCVState *env, int csrno) > { > @@ -3987,6 +4004,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno, > return ret; > } > > +static RISCVException read_jvt(CPURISCVState *env, int csrno, > + target_ulong *val) > +{ > + *val = env->jvt; > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_jvt(CPURISCVState *env, int csrno, > + target_ulong val) > +{ > + env->jvt = val; > + return RISCV_EXCP_NONE; > +} > + > /* Control and Status Register function table */ > riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > /* User Floating-Point CSRs */ > @@ -4024,6 +4055,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > /* Crypto Extension */ > [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed }, > > + /* Zcmt Extension */ > + [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt}, > + > #if !defined(CONFIG_USER_ONLY) > /* Machine Timers and Counters */ > [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, > diff --git a/target/riscv/helper.h b/target/riscv/helper.h > index 227c7122ef..d979f0bfc4 100644 > --- a/target/riscv/helper.h > +++ b/target/riscv/helper.h > @@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl) > > DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) > DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) > + > +/* Zce helper */ > +DEF_HELPER_FLAGS_2(cm_jalt, TCG_CALL_NO_WG, tl, env, i32) > diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode > index 4654c23052..c359c574ab 100644 > --- a/target/riscv/insn16.decode > +++ b/target/riscv/insn16.decode > @@ -49,6 +49,7 @@ > %zcb_h_uimm 5:1 !function=ex_shift_1 > %zcmp_spimm 2:2 !function=ex_shift_4 > %zcmp_rlist 4:4 > +%zcmt_index 2:8 > > # Argument sets imported from insn32.decode: > &empty !extern > @@ -63,6 +64,7 @@ > &r2_s rs1 rs2 !extern > > &zcmp zcmp_rlist zcmp_spimm > +&zcmt zcmt_index > > # Formats 16: > @cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd > @@ -106,6 +108,7 @@ > @zcb_sh ... . .. ... .. ... .. &s imm=%zcb_h_uimm rs1=%rs1_3 rs2=%rs2_3 > @zcmp ... ... ........ .. &zcmp %zcmp_rlist %zcmp_spimm > @cm_mv ... ... ... .. ... .. &r2_s rs2=%sreg2 rs1=%sreg1 > +@zcmt_jt ... ... ........ .. &zcmt %zcmt_index > > # *** RV32/64C Standard Extension (Quadrant 0) *** > { > @@ -186,7 +189,7 @@ slli 000 . ..... ..... 10 @c_shift2 > sq 101 ... ... .. ... 10 @c_sqsp > c_fsd 101 ...... ..... 10 @c_sdsp > > - # *** RV64 and RV32 Zcmp Extension *** > + # *** RV64 and RV32 Zcmp/Zcmt Extension *** > [ > cm_push 101 11000 .... .. 10 @zcmp > cm_pop 101 11010 .... .. 10 @zcmp > @@ -194,6 +197,8 @@ slli 000 . ..... ..... 10 @c_shift2 > cm_popretz 101 11100 .... .. 10 @zcmp > cm_mva01s 101 011 ... 11 ... 10 @cm_mv > cm_mvsa01 101 011 ... 01 ... 10 @cm_mv > + > + cm_jalt 101 000 ........ 10 @zcmt_jt > ] > } > sw 110 . ..... ..... 10 @c_swsp > diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc > index f647b6ed15..43cbd822c5 100644 > --- a/target/riscv/insn_trans/trans_rvzce.c.inc > +++ b/target/riscv/insn_trans/trans_rvzce.c.inc > @@ -1,5 +1,5 @@ > /* > - * RISC-V translation routines for the Zc[b,mp] Standard Extension. > + * RISC-V translation routines for the Zc[b,mp,mt] Standard Extension. > * > * Copyright (c) 2021-2022 PLCT Lab > * > @@ -26,6 +26,11 @@ > return false; \ > } while (0) > > +#define REQUIRE_ZCMT(ctx) do { \ > + if (!ctx->cfg_ptr->ext_zcmt) \ > + return false; \ > +} while (0) > + > static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a) > { > REQUIRE_ZCB(ctx); > @@ -285,3 +290,24 @@ static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a) > > return true; > } > + > +static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a) > +{ > + REQUIRE_ZCMT(ctx); > + > + /* > + * Update pc to current for the non-unwinding exception > + * that might come from cpu_ld*_code() in the helper. > + */ > + tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); > + gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->zcmt_index)); > + > + /* c.jt vs c.jalt depends on the index. */ > + if (a->zcmt_index >= 32) { > + gen_set_gpri(ctx, xRA, ctx->pc_succ_insn); > + } > + > + tcg_gen_lookup_and_goto_ptr(); > + ctx->base.is_jmp = DISAS_NORETURN; > + return true; > +} > diff --git a/target/riscv/machine.c b/target/riscv/machine.c > index 65a8549ec2..ee3a2deab6 100644 > --- a/target/riscv/machine.c > +++ b/target/riscv/machine.c > @@ -331,6 +331,24 @@ static const VMStateDescription vmstate_pmu_ctr_state = { > } > }; > > +static bool jvt_needed(void *opaque) > +{ > + RISCVCPU *cpu = opaque; > + > + return cpu->cfg.ext_zcmt; > +} > + > +static const VMStateDescription vmstate_jvt = { > + .name = "cpu/jvt", > + .version_id = 1, > + .minimum_version_id = 1, > + .needed = jvt_needed, > + .fields = (VMStateField[]) { > + VMSTATE_UINTTL(env.jvt, RISCVCPU), > + VMSTATE_END_OF_LIST() > + } > +}; > + > const VMStateDescription vmstate_riscv_cpu = { > .name = "cpu", > .version_id = 5, > @@ -400,6 +418,7 @@ const VMStateDescription vmstate_riscv_cpu = { > &vmstate_envcfg, > &vmstate_debug, > &vmstate_smstateen, > + &vmstate_jvt, > NULL > } > }; > diff --git a/target/riscv/meson.build b/target/riscv/meson.build > index ba25164d74..4bf9c9e632 100644 > --- a/target/riscv/meson.build > +++ b/target/riscv/meson.build > @@ -18,7 +18,8 @@ riscv_ss.add(files( > 'bitmanip_helper.c', > 'translate.c', > 'm128_helper.c', > - 'crypto_helper.c' > + 'crypto_helper.c', > + 'zce_helper.c' > )) > riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) > > diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c > new file mode 100644 > index 0000000000..9cec8c19d6 > --- /dev/null > +++ b/target/riscv/zce_helper.c > @@ -0,0 +1,55 @@ > +/* > + * RISC-V Zc* extension Helpers for QEMU. > + * > + * Copyright (c) 2021-2022 PLCT Lab > + * > + * 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/>. > + */ > + > +#include "qemu/osdep.h" > +#include "cpu.h" > +#include "exec/exec-all.h" > +#include "exec/helper-proto.h" > +#include "exec/cpu_ldst.h" > + > +target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index) > +{ > + > +#if !defined(CONFIG_USER_ONLY) > + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT); > + if (ret != RISCV_EXCP_NONE) { > + riscv_raise_exception(env, ret, 0); > + } > +#endif > + > + target_ulong target; > + target_ulong val = env->jvt; > + int xlen = riscv_cpu_xlen(env); > + uint8_t mode = get_field(val, JVT_MODE); > + target_ulong base = get_field(val, JVT_BASE); > + target_ulong t0; > + > + if (mode != 0) { > + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, 0); > + } > + > + if (xlen == 32) { > + t0 = base + (index << 2); > + target = cpu_ldl_code(env, t0); > + } else { > + t0 = base + (index << 3); > + target = cpu_ldq_code(env, t0); > + } > + > + return target & ~0x1; > +} > -- > 2.25.1 > >
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6e915b6937..7bcedc7467 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -181,6 +181,8 @@ struct CPUArchState { uint32_t features; + target_ulong jvt; + #ifdef CONFIG_USER_ONLY uint32_t elf_flags; #endif @@ -600,6 +602,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, target_ulong new_val, target_ulong write_mask), void *rmw_fn_arg); + +RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit); #endif void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 8b0d7e20ea..ce347e5575 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -319,6 +319,7 @@ #define SMSTATEEN_MAX_COUNT 4 #define SMSTATEEN0_CS (1ULL << 0) #define SMSTATEEN0_FCSR (1ULL << 1) +#define SMSTATEEN0_JVT (1ULL << 2) #define SMSTATEEN0_HSCONTXT (1ULL << 57) #define SMSTATEEN0_IMSIC (1ULL << 58) #define SMSTATEEN0_AIA (1ULL << 59) @@ -523,6 +524,9 @@ /* Crypto Extension */ #define CSR_SEED 0x015 +/* Zcmt Extension */ +#define CSR_JVT 0x017 + /* mstatus CSR bits */ #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 @@ -894,4 +898,7 @@ typedef enum RISCVException { #define MHPMEVENT_IDX_MASK 0xFFFFF #define MHPMEVENT_SSCOF_RESVD 16 +/* JVT CSR bits */ +#define JVT_MODE 0x3F +#define JVT_BASE (~0x3F) #endif diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 8b25f885ec..5115dc882d 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops) /* Predicates */ #if !defined(CONFIG_USER_ONLY) -static RISCVException smstateen_acc_ok(CPURISCVState *env, int index, - uint64_t bit) +RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit) { bool virt = riscv_cpu_virt_enabled(env); CPUState *cs = env_cpu(env); @@ -167,6 +166,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno) return ctr(env, csrno); } +static RISCVException zcmt(CPURISCVState *env, int csrno) +{ + RISCVCPU *cpu = env_archcpu(env); + + if (!cpu->cfg.ext_zcmt) { + return RISCV_EXCP_ILLEGAL_INST; + } + +#if !defined(CONFIG_USER_ONLY) + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT); + if (ret != RISCV_EXCP_NONE) { + return ret; + } +#endif + + return RISCV_EXCP_NONE; +} + #if !defined(CONFIG_USER_ONLY) static RISCVException mctr(CPURISCVState *env, int csrno) { @@ -3987,6 +4004,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno, return ret; } +static RISCVException read_jvt(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = env->jvt; + return RISCV_EXCP_NONE; +} + +static RISCVException write_jvt(CPURISCVState *env, int csrno, + target_ulong val) +{ + env->jvt = val; + return RISCV_EXCP_NONE; +} + /* Control and Status Register function table */ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* User Floating-Point CSRs */ @@ -4024,6 +4055,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Crypto Extension */ [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed }, + /* Zcmt Extension */ + [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt}, + #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 227c7122ef..d979f0bfc4 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) + +/* Zce helper */ +DEF_HELPER_FLAGS_2(cm_jalt, TCG_CALL_NO_WG, tl, env, i32) diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 4654c23052..c359c574ab 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -49,6 +49,7 @@ %zcb_h_uimm 5:1 !function=ex_shift_1 %zcmp_spimm 2:2 !function=ex_shift_4 %zcmp_rlist 4:4 +%zcmt_index 2:8 # Argument sets imported from insn32.decode: &empty !extern @@ -63,6 +64,7 @@ &r2_s rs1 rs2 !extern &zcmp zcmp_rlist zcmp_spimm +&zcmt zcmt_index # Formats 16: @cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd @@ -106,6 +108,7 @@ @zcb_sh ... . .. ... .. ... .. &s imm=%zcb_h_uimm rs1=%rs1_3 rs2=%rs2_3 @zcmp ... ... ........ .. &zcmp %zcmp_rlist %zcmp_spimm @cm_mv ... ... ... .. ... .. &r2_s rs2=%sreg2 rs1=%sreg1 +@zcmt_jt ... ... ........ .. &zcmt %zcmt_index # *** RV32/64C Standard Extension (Quadrant 0) *** { @@ -186,7 +189,7 @@ slli 000 . ..... ..... 10 @c_shift2 sq 101 ... ... .. ... 10 @c_sqsp c_fsd 101 ...... ..... 10 @c_sdsp - # *** RV64 and RV32 Zcmp Extension *** + # *** RV64 and RV32 Zcmp/Zcmt Extension *** [ cm_push 101 11000 .... .. 10 @zcmp cm_pop 101 11010 .... .. 10 @zcmp @@ -194,6 +197,8 @@ slli 000 . ..... ..... 10 @c_shift2 cm_popretz 101 11100 .... .. 10 @zcmp cm_mva01s 101 011 ... 11 ... 10 @cm_mv cm_mvsa01 101 011 ... 01 ... 10 @cm_mv + + cm_jalt 101 000 ........ 10 @zcmt_jt ] } sw 110 . ..... ..... 10 @c_swsp diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index f647b6ed15..43cbd822c5 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -1,5 +1,5 @@ /* - * RISC-V translation routines for the Zc[b,mp] Standard Extension. + * RISC-V translation routines for the Zc[b,mp,mt] Standard Extension. * * Copyright (c) 2021-2022 PLCT Lab * @@ -26,6 +26,11 @@ return false; \ } while (0) +#define REQUIRE_ZCMT(ctx) do { \ + if (!ctx->cfg_ptr->ext_zcmt) \ + return false; \ +} while (0) + static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a) { REQUIRE_ZCB(ctx); @@ -285,3 +290,24 @@ static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a) return true; } + +static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a) +{ + REQUIRE_ZCMT(ctx); + + /* + * Update pc to current for the non-unwinding exception + * that might come from cpu_ld*_code() in the helper. + */ + tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); + gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->zcmt_index)); + + /* c.jt vs c.jalt depends on the index. */ + if (a->zcmt_index >= 32) { + gen_set_gpri(ctx, xRA, ctx->pc_succ_insn); + } + + tcg_gen_lookup_and_goto_ptr(); + ctx->base.is_jmp = DISAS_NORETURN; + return true; +} diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 65a8549ec2..ee3a2deab6 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -331,6 +331,24 @@ static const VMStateDescription vmstate_pmu_ctr_state = { } }; +static bool jvt_needed(void *opaque) +{ + RISCVCPU *cpu = opaque; + + return cpu->cfg.ext_zcmt; +} + +static const VMStateDescription vmstate_jvt = { + .name = "cpu/jvt", + .version_id = 1, + .minimum_version_id = 1, + .needed = jvt_needed, + .fields = (VMStateField[]) { + VMSTATE_UINTTL(env.jvt, RISCVCPU), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_riscv_cpu = { .name = "cpu", .version_id = 5, @@ -400,6 +418,7 @@ const VMStateDescription vmstate_riscv_cpu = { &vmstate_envcfg, &vmstate_debug, &vmstate_smstateen, + &vmstate_jvt, NULL } }; diff --git a/target/riscv/meson.build b/target/riscv/meson.build index ba25164d74..4bf9c9e632 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -18,7 +18,8 @@ riscv_ss.add(files( 'bitmanip_helper.c', 'translate.c', 'm128_helper.c', - 'crypto_helper.c' + 'crypto_helper.c', + 'zce_helper.c' )) riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c new file mode 100644 index 0000000000..9cec8c19d6 --- /dev/null +++ b/target/riscv/zce_helper.c @@ -0,0 +1,55 @@ +/* + * RISC-V Zc* extension Helpers for QEMU. + * + * Copyright (c) 2021-2022 PLCT Lab + * + * 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/>. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" + +target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index) +{ + +#if !defined(CONFIG_USER_ONLY) + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT); + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, 0); + } +#endif + + target_ulong target; + target_ulong val = env->jvt; + int xlen = riscv_cpu_xlen(env); + uint8_t mode = get_field(val, JVT_MODE); + target_ulong base = get_field(val, JVT_BASE); + target_ulong t0; + + if (mode != 0) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, 0); + } + + if (xlen == 32) { + t0 = base + (index << 2); + target = cpu_ldl_code(env, t0); + } else { + t0 = base + (index << 3); + target = cpu_ldq_code(env, t0); + } + + return target & ~0x1; +}