mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
target/riscv: Add itrigger support when icount is not enabled
When icount is not enabled, there is no API in QEMU that can get the guest instruction number. Translate the guest code in a way that each TB only has one instruction. After executing the instruction, decrease the count by 1 until it reaches 0 where the itrigger fires. Note that only when priviledge matches the itrigger configuration, the count will decrease. Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20221013062946.7530-2-zhiwei_liu@linux.alibaba.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
fb3f3730e4
commit
2c9d747121
9 changed files with 131 additions and 11 deletions
|
@ -78,7 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
|
|||
if (has_ext(ctx, RVS)) {
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_sret(cpu_pc, cpu_env);
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
exit_tb(ctx); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -94,7 +94,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_mret(cpu_pc, cpu_env);
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
exit_tb(ctx); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
#else
|
||||
|
|
|
@ -66,7 +66,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
|
|||
}
|
||||
|
||||
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
lookup_and_goto_ptr(ctx);
|
||||
|
||||
if (misaligned) {
|
||||
gen_set_label(misaligned);
|
||||
|
@ -803,7 +803,7 @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
|
|||
* end the TB and return to main loop
|
||||
*/
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
exit_tb(ctx);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
return true;
|
||||
|
@ -827,7 +827,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
|||
* however we need to end the translation block
|
||||
*/
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
exit_tb(ctx);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
@ -838,7 +838,7 @@ static bool do_csr_post(DisasContext *ctx)
|
|||
decode_save_opc(ctx);
|
||||
/* We may have changed important cpu state -- exit to main loop. */
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
exit_tb(ctx);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
|
|||
mark_vs_dirty(s);
|
||||
|
||||
gen_set_pc_imm(s, s->pc_succ_insn);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
lookup_and_goto_ptr(s);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
if (rd == 0 && rs1 == 0) {
|
||||
|
@ -222,7 +222,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
|
|||
gen_set_gpr(s, rd, dst);
|
||||
mark_vs_dirty(s);
|
||||
gen_set_pc_imm(s, s->pc_succ_insn);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
lookup_and_goto_ptr(s);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue