@@ -67,7 +67,7 @@ typedef struct DisasContext {
to any system register, which includes CSR_FRM, so we do not have
to reset this known value. */
int frm;
- bool w;
+ RISCVMXL ol;
bool virt_enabled;
bool ext_ifencei;
bool hlsx;
@@ -104,13 +104,18 @@ static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
return 16 << get_xl(ctx);
}
-/* The word size for this operation. */
-static inline int oper_len(DisasContext *ctx)
+/* The operation length, as opposed to the xlen. */
+#ifdef TARGET_RISCV32
+#define get_ol(ctx) MXL_RV32
+#else
+#define get_ol(ctx) ((ctx)->ol)
+#endif
+
+static inline int get_olen(DisasContext *ctx)
{
- return ctx->w ? 32 : TARGET_LONG_BITS;
+ return 16 << get_ol(ctx);
}
-
/*
* 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.
@@ -197,24 +202,34 @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
return ctx->zero;
}
- switch (ctx->w ? ext : EXT_NONE) {
- case EXT_NONE:
- return cpu_gpr[reg_num];
- case EXT_SIGN:
- t = temp_new(ctx);
- tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
- return t;
- case EXT_ZERO:
- t = temp_new(ctx);
- tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
- return t;
+ switch (get_ol(ctx)) {
+ case MXL_RV32:
+ switch (ext) {
+ case EXT_NONE:
+ break;
+ case EXT_SIGN:
+ t = temp_new(ctx);
+ tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
+ return t;
+ case EXT_ZERO:
+ t = temp_new(ctx);
+ tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
+ return t;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+ case MXL_RV64:
+ break;
+ default:
+ g_assert_not_reached();
}
- g_assert_not_reached();
+ return cpu_gpr[reg_num];
}
static TCGv dest_gpr(DisasContext *ctx, int reg_num)
{
- if (reg_num == 0 || ctx->w) {
+ if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) {
return temp_new(ctx);
}
return cpu_gpr[reg_num];
@@ -223,10 +238,15 @@ static TCGv dest_gpr(DisasContext *ctx, int reg_num)
static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
{
if (reg_num != 0) {
- if (ctx->w) {
+ switch (get_ol(ctx)) {
+ case MXL_RV32:
tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
- } else {
+ break;
+ case MXL_RV64:
tcg_gen_mov_tl(cpu_gpr[reg_num], t);
+ break;
+ default:
+ g_assert_not_reached();
}
}
}
@@ -387,7 +407,7 @@ static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
void (*func)(TCGv, TCGv, target_long))
{
TCGv dest, src1;
- int max_len = oper_len(ctx);
+ int max_len = get_olen(ctx);
if (a->shamt >= max_len) {
return false;
@@ -406,7 +426,7 @@ static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
void (*func)(TCGv, TCGv, TCGv))
{
TCGv dest, src1, src2;
- int max_len = oper_len(ctx);
+ int max_len = get_olen(ctx);
if (a->shamt >= max_len) {
return false;
@@ -430,7 +450,7 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
TCGv ext2 = tcg_temp_new();
- tcg_gen_andi_tl(ext2, src2, oper_len(ctx) - 1);
+ tcg_gen_andi_tl(ext2, src2, get_olen(ctx) - 1);
func(dest, src1, ext2);
gen_set_gpr(ctx, a->rd, dest);
@@ -530,7 +550,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
ctx->cs = cs;
- ctx->w = false;
ctx->ntemp = 0;
memset(ctx->temp, 0, sizeof(ctx->temp));
@@ -554,9 +573,9 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
CPURISCVState *env = cpu->env_ptr;
uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
+ ctx->ol = ctx->xl;
decode_opc(env, ctx, opcode16);
ctx->base.pc_next = ctx->pc_succ_insn;
- ctx->w = false;
for (int i = ctx->ntemp - 1; i >= 0; --i) {
tcg_temp_free(ctx->temp[i]);
@@ -344,7 +344,7 @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZBB(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
}
@@ -370,7 +370,7 @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZBB(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift(ctx, a, EXT_NONE, gen_rorw);
}
@@ -378,7 +378,7 @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZBB(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_rorw);
}
@@ -404,7 +404,7 @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_ZBB(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift(ctx, a, EXT_NONE, gen_rolw);
}
@@ -331,14 +331,14 @@ static bool trans_and(DisasContext *ctx, arg_and *a)
static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl);
}
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
}
@@ -350,7 +350,7 @@ static void gen_srliw(TCGv dst, TCGv src, target_long shamt)
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw);
}
@@ -362,42 +362,42 @@ static void gen_sraiw(TCGv dst, TCGv src, target_long shamt)
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw);
}
static bool trans_addw(DisasContext *ctx, arg_addw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl);
}
static bool trans_subw(DisasContext *ctx, arg_subw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl);
}
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl);
}
static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl);
}
static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
{
REQUIRE_64BIT(ctx);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl);
}
@@ -214,7 +214,7 @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl);
}
@@ -222,7 +222,7 @@ static bool trans_divw(DisasContext *ctx, arg_divw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_SIGN, gen_div);
}
@@ -230,7 +230,7 @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_ZERO, gen_divu);
}
@@ -238,7 +238,7 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_SIGN, gen_rem);
}
@@ -246,6 +246,6 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVM);
- ctx->w = true;
+ ctx->ol = MXL_RV32;
return gen_arith(ctx, a, EXT_ZERO, gen_remu);
}