Compute the target address before storing it into badaddr
when mis-aligned exception is triggered.
Use a target_pc temp to store the target address to avoid
the confusing operation that udpate target address into
cpu_pc before misalign check, then update it into badaddr
and restore cpu_pc to current pc if exception is triggered.
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
target/riscv/translate.c | 21 ++++++++++-----------
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 4ad54e8a49..cc72864d32 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
{
TCGLabel *misaligned = NULL;
+ TCGv target_pc = tcg_temp_new();
- tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
- tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+ tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
+ tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
+
+ if (get_xl(ctx) == MXL_RV32) {
+ tcg_gen_ext32s_tl(target_pc, target_pc);
+ }
- gen_set_pc(ctx, cpu_pc);
if (!has_ext(ctx, RVC)) {
TCGv t0 = tcg_temp_new();
misaligned = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+ tcg_gen_andi_tl(t0, target_pc, 0x2);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
}
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
+ tcg_gen_mov_tl(cpu_pc, target_pc);
lookup_and_goto_ptr(ctx);
if (misaligned) {
gen_set_label(misaligned);
- gen_exception_inst_addr_mis(ctx);
+ gen_exception_inst_addr_mis(ctx, target_pc);
}
ctx->base.is_jmp = DISAS_NORETURN;
@@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
TCGLabel *l = gen_new_label();
TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
+ target_ulong next_pc;
if (get_xl(ctx) == MXL_RV128) {
TCGv src1h = get_gprh(ctx, a->rs1);
@@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
gen_set_label(l); /* branch taken */
- if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+ next_pc = ctx->base.pc_next + a->imm;
+ if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
/* misaligned */
- gen_exception_inst_addr_mis(ctx);
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, next_pc);
+ gen_exception_inst_addr_mis(ctx, target_pc);
} else {
gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0ee8ee147d..d434fedb37 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
ctx->insn_start = NULL;
}
-static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
+ target_ulong dest)
{
if (get_xl(ctx) == MXL_RV32) {
dest = (int32_t)dest;
}
- tcg_gen_movi_tl(cpu_pc, dest);
+ tcg_gen_movi_tl(target, dest);
}
-static void gen_set_pc(DisasContext *ctx, TCGv dest)
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
{
- if (get_xl(ctx) == MXL_RV32) {
- tcg_gen_ext32s_tl(cpu_pc, dest);
- } else {
- tcg_gen_mov_tl(cpu_pc, dest);
- }
+ gen_pc_plus_diff(cpu_pc, ctx, dest);
}
static void generate_exception(DisasContext *ctx, int excp)
@@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
}
}
-static void gen_exception_inst_addr_mis(DisasContext *ctx)
+static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
{
- tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
+ tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
}
@@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
next_pc = ctx->base.pc_next + imm;
if (!has_ext(ctx, RVC)) {
if ((next_pc & 0x3) != 0) {
- gen_exception_inst_addr_mis(ctx);
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, next_pc);
+ gen_exception_inst_addr_mis(ctx, target_pc);
return;
}
}
--
2.25.1
On Tue, Apr 4, 2023 at 12:08 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> Compute the target address before storing it into badaddr
> when mis-aligned exception is triggered.
> Use a target_pc temp to store the target address to avoid
> the confusing operation that udpate target address into
> cpu_pc before misalign check, then update it into badaddr
> and restore cpu_pc to current pc if exception is triggered.
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
> target/riscv/translate.c | 21 ++++++++++-----------
> 2 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 4ad54e8a49..cc72864d32 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> {
> TCGLabel *misaligned = NULL;
> + TCGv target_pc = tcg_temp_new();
>
> - tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> - tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
> +
> + if (get_xl(ctx) == MXL_RV32) {
> + tcg_gen_ext32s_tl(target_pc, target_pc);
> + }
>
> - gen_set_pc(ctx, cpu_pc);
> if (!has_ext(ctx, RVC)) {
> TCGv t0 = tcg_temp_new();
>
> misaligned = gen_new_label();
> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
> + tcg_gen_andi_tl(t0, target_pc, 0x2);
> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> }
>
> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
> + tcg_gen_mov_tl(cpu_pc, target_pc);
> lookup_and_goto_ptr(ctx);
>
> if (misaligned) {
> gen_set_label(misaligned);
> - gen_exception_inst_addr_mis(ctx);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> }
> ctx->base.is_jmp = DISAS_NORETURN;
>
> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> TCGLabel *l = gen_new_label();
> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
> + target_ulong next_pc;
>
> if (get_xl(ctx) == MXL_RV128) {
> TCGv src1h = get_gprh(ctx, a->rs1);
> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>
> gen_set_label(l); /* branch taken */
>
> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> + next_pc = ctx->base.pc_next + a->imm;
> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
> /* misaligned */
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> } else {
> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
> }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 0ee8ee147d..d434fedb37 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
> ctx->insn_start = NULL;
> }
>
> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
> + target_ulong dest)
> {
> if (get_xl(ctx) == MXL_RV32) {
> dest = (int32_t)dest;
> }
> - tcg_gen_movi_tl(cpu_pc, dest);
> + tcg_gen_movi_tl(target, dest);
> }
>
> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> {
> - if (get_xl(ctx) == MXL_RV32) {
> - tcg_gen_ext32s_tl(cpu_pc, dest);
> - } else {
> - tcg_gen_mov_tl(cpu_pc, dest);
> - }
> + gen_pc_plus_diff(cpu_pc, ctx, dest);
> }
>
> static void generate_exception(DisasContext *ctx, int excp)
> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
> }
> }
>
> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
> {
> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
> }
>
> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> next_pc = ctx->base.pc_next + imm;
> if (!has_ext(ctx, RVC)) {
> if ((next_pc & 0x3) != 0) {
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> return;
> }
> }
> --
> 2.25.1
>
>
On 2023/4/4 10:06, Weiwei Li wrote:
> Compute the target address before storing it into badaddr
> when mis-aligned exception is triggered.
> Use a target_pc temp to store the target address to avoid
> the confusing operation that udpate target address into
> cpu_pc before misalign check, then update it into badaddr
> and restore cpu_pc to current pc if exception is triggered.
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
> target/riscv/translate.c | 21 ++++++++++-----------
> 2 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 4ad54e8a49..cc72864d32 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> {
> TCGLabel *misaligned = NULL;
> + TCGv target_pc = tcg_temp_new();
>
> - tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> - tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
> +
> + if (get_xl(ctx) == MXL_RV32) {
> + tcg_gen_ext32s_tl(target_pc, target_pc);
> + }
>
Delete this.
> - gen_set_pc(ctx, cpu_pc);
> if (!has_ext(ctx, RVC)) {
> TCGv t0 = tcg_temp_new();
>
> misaligned = gen_new_label();
> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
> + tcg_gen_andi_tl(t0, target_pc, 0x2);
> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> }
>
> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
> + tcg_gen_mov_tl(cpu_pc, target_pc);
And we can use the gen_set_pc instead.
I think the reason you want to delete gen_set_pc is to make the
gen_set_pc_imm the only API to change the cpu_pc.
This implicitly enhance the correctness, which may constrain the scalable.
Zhiwei
> lookup_and_goto_ptr(ctx);
>
> if (misaligned) {
> gen_set_label(misaligned);
> - gen_exception_inst_addr_mis(ctx);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> }
> ctx->base.is_jmp = DISAS_NORETURN;
>
> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> TCGLabel *l = gen_new_label();
> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
> + target_ulong next_pc;
>
> if (get_xl(ctx) == MXL_RV128) {
> TCGv src1h = get_gprh(ctx, a->rs1);
> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>
> gen_set_label(l); /* branch taken */
>
> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> + next_pc = ctx->base.pc_next + a->imm;
> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
> /* misaligned */
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> } else {
> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
> }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 0ee8ee147d..d434fedb37 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
> ctx->insn_start = NULL;
> }
>
> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
> + target_ulong dest)
> {
> if (get_xl(ctx) == MXL_RV32) {
> dest = (int32_t)dest;
> }
> - tcg_gen_movi_tl(cpu_pc, dest);
> + tcg_gen_movi_tl(target, dest);
> }
>
> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> {
> - if (get_xl(ctx) == MXL_RV32) {
> - tcg_gen_ext32s_tl(cpu_pc, dest);
> - } else {
> - tcg_gen_mov_tl(cpu_pc, dest);
> - }
> + gen_pc_plus_diff(cpu_pc, ctx, dest);
> }
>
> static void generate_exception(DisasContext *ctx, int excp)
> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
> }
> }
>
> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
> {
> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
> }
>
> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> next_pc = ctx->base.pc_next + imm;
> if (!has_ext(ctx, RVC)) {
> if ((next_pc & 0x3) != 0) {
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> return;
> }
> }
On 2023/4/4 11:06, LIU Zhiwei wrote:
>
> On 2023/4/4 10:06, Weiwei Li wrote:
>> Compute the target address before storing it into badaddr
>> when mis-aligned exception is triggered.
>> Use a target_pc temp to store the target address to avoid
>> the confusing operation that udpate target address into
>> cpu_pc before misalign check, then update it into badaddr
>> and restore cpu_pc to current pc if exception is triggered.
>>
>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
>> target/riscv/translate.c | 21 ++++++++++-----------
>> 2 files changed, 26 insertions(+), 18 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>> b/target/riscv/insn_trans/trans_rvi.c.inc
>> index 4ad54e8a49..cc72864d32 100644
>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
>> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>> {
>> TCGLabel *misaligned = NULL;
>> + TCGv target_pc = tcg_temp_new();
>> - tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
>> - tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
>> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
>> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>> +
>> + if (get_xl(ctx) == MXL_RV32) {
>> + tcg_gen_ext32s_tl(target_pc, target_pc);
>> + }
> Delete this.
The (signed-extended)target_pc should be used in both updating cpu_pc
and following gen_exception_inst_addr_mis().
So we cannot delete it and just resue the logic in gen_set_pc().
This is also why I use tcg_gen_mov_tl(cpu_pc, target_pc) directly in
following code.
Regards,
Weiwei Li
>> - gen_set_pc(ctx, cpu_pc);
>> if (!has_ext(ctx, RVC)) {
>> TCGv t0 = tcg_temp_new();
>> misaligned = gen_new_label();
>> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
>> + tcg_gen_andi_tl(t0, target_pc, 0x2);
>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>> }
>> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>> + tcg_gen_mov_tl(cpu_pc, target_pc);
>
> And we can use the gen_set_pc instead.
>
> I think the reason you want to delete gen_set_pc is to make the
> gen_set_pc_imm the only API to change the cpu_pc.
>
> This implicitly enhance the correctness, which may constrain the
> scalable.
>
> Zhiwei
>
>> lookup_and_goto_ptr(ctx);
>> if (misaligned) {
>> gen_set_label(misaligned);
>> - gen_exception_inst_addr_mis(ctx);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> }
>> ctx->base.is_jmp = DISAS_NORETURN;
>> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> TCGLabel *l = gen_new_label();
>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>> + target_ulong next_pc;
>> if (get_xl(ctx) == MXL_RV128) {
>> TCGv src1h = get_gprh(ctx, a->rs1);
>> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_set_label(l); /* branch taken */
>> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
>> + next_pc = ctx->base.pc_next + a->imm;
>> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>> /* misaligned */
>> - gen_exception_inst_addr_mis(ctx);
>> + TCGv target_pc = tcg_temp_new();
>> + gen_pc_plus_diff(target_pc, ctx, next_pc);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> } else {
>> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>> }
>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>> index 0ee8ee147d..d434fedb37 100644
>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
>> ctx->insn_start = NULL;
>> }
>> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>> + target_ulong dest)
>> {
>> if (get_xl(ctx) == MXL_RV32) {
>> dest = (int32_t)dest;
>> }
>> - tcg_gen_movi_tl(cpu_pc, dest);
>> + tcg_gen_movi_tl(target, dest);
>> }
>> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
>> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> {
>> - if (get_xl(ctx) == MXL_RV32) {
>> - tcg_gen_ext32s_tl(cpu_pc, dest);
>> - } else {
>> - tcg_gen_mov_tl(cpu_pc, dest);
>> - }
>> + gen_pc_plus_diff(cpu_pc, ctx, dest);
>> }
>> static void generate_exception(DisasContext *ctx, int excp)
>> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
>> }
>> }
>> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
>> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
>> {
>> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
>> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
>> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
>> }
>> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd,
>> target_ulong imm)
>> next_pc = ctx->base.pc_next + imm;
>> if (!has_ext(ctx, RVC)) {
>> if ((next_pc & 0x3) != 0) {
>> - gen_exception_inst_addr_mis(ctx);
>> + TCGv target_pc = tcg_temp_new();
>> + gen_pc_plus_diff(target_pc, ctx, next_pc);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> return;
>> }
>> }
© 2016 - 2026 Red Hat, Inc.