mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 14:15:39 +00:00
target/arm: Introduce pc_curr
Add a new field to retain the address of the instruction currently being translated. The 32-bit uses are all within subroutines used by a32 and t32. This will become less obvious when t16 support is merged with a32+t32, and having a clear definition will help. Convert aarch64 as well for consistency. Note that there is one instance of a pre-assert fprintf that used the wrong value for the address of the current instruction. Backports commit 43722a6d4f0c92f7e7e1e291580039b0f9789df1 from qemu
This commit is contained in:
parent
1aa3c685a8
commit
0048f3e887
|
@ -1425,7 +1425,7 @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
|
||||||
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
|
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
|
uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4;
|
||||||
|
|
||||||
if (insn & (1U << 31)) {
|
if (insn & (1U << 31)) {
|
||||||
/* BL Branch with link */
|
/* BL Branch with link */
|
||||||
|
@ -1454,7 +1454,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
|
||||||
sf = extract32(insn, 31, 1);
|
sf = extract32(insn, 31, 1);
|
||||||
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
|
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
|
||||||
rt = extract32(insn, 0, 5);
|
rt = extract32(insn, 0, 5);
|
||||||
addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
|
addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
|
||||||
|
|
||||||
tcg_cmp = read_cpu_reg(s, rt, sf);
|
tcg_cmp = read_cpu_reg(s, rt, sf);
|
||||||
label_match = gen_new_label(tcg_ctx);
|
label_match = gen_new_label(tcg_ctx);
|
||||||
|
@ -1484,7 +1484,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
|
||||||
|
|
||||||
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
|
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
|
||||||
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
|
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
|
||||||
addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
|
addr = s->pc_curr + sextract32(insn, 5, 14) * 4;
|
||||||
rt = extract32(insn, 0, 5);
|
rt = extract32(insn, 0, 5);
|
||||||
|
|
||||||
tcg_cmp = tcg_temp_new_i64(tcg_ctx);
|
tcg_cmp = tcg_temp_new_i64(tcg_ctx);
|
||||||
|
@ -1516,7 +1516,7 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
|
||||||
unallocated_encoding(s);
|
unallocated_encoding(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
|
addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
|
||||||
cond = extract32(insn, 0, 4);
|
cond = extract32(insn, 0, 4);
|
||||||
|
|
||||||
reset_btype(s);
|
reset_btype(s);
|
||||||
|
@ -1903,7 +1903,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
|
||||||
TCGv_i32 tcg_syn, tcg_isread;
|
TCGv_i32 tcg_syn, tcg_isread;
|
||||||
uint32_t syndrome;
|
uint32_t syndrome;
|
||||||
|
|
||||||
gen_a64_set_pc_im(s, s->pc - 4);
|
gen_a64_set_pc_im(s, s->pc_curr);
|
||||||
tmpptr = tcg_const_ptr(tcg_ctx, ri);
|
tmpptr = tcg_const_ptr(tcg_ctx, ri);
|
||||||
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
|
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
|
||||||
tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
|
tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
|
||||||
|
@ -2072,7 +2072,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
||||||
/* The pre HVC helper handles cases when HVC gets trapped
|
/* The pre HVC helper handles cases when HVC gets trapped
|
||||||
* as an undefined insn by runtime configuration.
|
* as an undefined insn by runtime configuration.
|
||||||
*/
|
*/
|
||||||
gen_a64_set_pc_im(s, s->pc - 4);
|
gen_a64_set_pc_im(s, s->pc_curr);
|
||||||
gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
gen_ss_advance(s);
|
gen_ss_advance(s);
|
||||||
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
|
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
|
||||||
|
@ -2082,7 +2082,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
||||||
unallocated_encoding(s);
|
unallocated_encoding(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gen_a64_set_pc_im(s, s->pc - 4);
|
gen_a64_set_pc_im(s, s->pc_curr);
|
||||||
tmp = tcg_const_i32(tcg_ctx, syn_aa64_smc(imm16));
|
tmp = tcg_const_i32(tcg_ctx, syn_aa64_smc(imm16));
|
||||||
gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
|
gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
@ -2801,7 +2801,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
|
||||||
|
|
||||||
tcg_rt = cpu_reg(s, rt);
|
tcg_rt = cpu_reg(s, rt);
|
||||||
|
|
||||||
clean_addr = tcg_const_i64(tcg_ctx, (s->pc - 4) + imm);
|
clean_addr = tcg_const_i64(tcg_ctx, s->pc_curr + imm);
|
||||||
if (is_vector) {
|
if (is_vector) {
|
||||||
do_fp_ld(s, rt, clean_addr, size);
|
do_fp_ld(s, rt, clean_addr, size);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3788,7 +3788,7 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
|
||||||
offset = sextract64(insn, 5, 19);
|
offset = sextract64(insn, 5, 19);
|
||||||
offset = offset << 2 | extract32(insn, 29, 2);
|
offset = offset << 2 | extract32(insn, 29, 2);
|
||||||
rd = extract32(insn, 0, 5);
|
rd = extract32(insn, 0, 5);
|
||||||
base = s->pc - 4;
|
base = s->pc_curr;
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
/* ADRP (page based) */
|
/* ADRP (page based) */
|
||||||
|
@ -11828,7 +11828,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
|
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
|
||||||
__func__, insn, fpopcode, s->pc);
|
__func__, insn, fpopcode, s->pc_curr);
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14363,6 +14363,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->pc_curr = s->pc;
|
||||||
insn = arm_ldl_code(env, s->pc, s->sctlr_b);
|
insn = arm_ldl_code(env, s->pc, s->sctlr_b);
|
||||||
s->insn = insn;
|
s->insn = insn;
|
||||||
s->pc += 4;
|
s->pc += 4;
|
||||||
|
|
|
@ -25,7 +25,7 @@ void unallocated_encoding(DisasContext *s);
|
||||||
qemu_log_mask(LOG_UNIMP, \
|
qemu_log_mask(LOG_UNIMP, \
|
||||||
"%s:%d: unsupported instruction encoding 0x%08x " \
|
"%s:%d: unsupported instruction encoding 0x%08x " \
|
||||||
"at pc=%016" PRIx64 "\n", \
|
"at pc=%016" PRIx64 "\n", \
|
||||||
__FILE__, __LINE__, insn, s->pc - 4); \
|
__FILE__, __LINE__, insn, s->pc_curr); \
|
||||||
unallocated_encoding(s); \
|
unallocated_encoding(s); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -1269,7 +1269,7 @@ static inline void gen_hvc(DisasContext *s, int imm16)
|
||||||
* as an undefined insn by runtime configuration (ie before
|
* as an undefined insn by runtime configuration (ie before
|
||||||
* the insn really executes).
|
* the insn really executes).
|
||||||
*/
|
*/
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
|
gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
/* Otherwise we will treat this as a real exception which
|
/* Otherwise we will treat this as a real exception which
|
||||||
* happens after execution of the insn. (The distinction matters
|
* happens after execution of the insn. (The distinction matters
|
||||||
|
@ -1289,7 +1289,7 @@ static inline void gen_smc(DisasContext *s)
|
||||||
TCGv_i32 tmp;
|
TCGv_i32 tmp;
|
||||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
|
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
tmp = tcg_const_i32(tcg_ctx, syn_aa32_smc());
|
tmp = tcg_const_i32(tcg_ctx, syn_aa32_smc());
|
||||||
gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
|
gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
@ -3310,7 +3310,7 @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
|
||||||
|
|
||||||
/* Sync state because msr_banked() can raise exceptions */
|
/* Sync state because msr_banked() can raise exceptions */
|
||||||
gen_set_condexec(s);
|
gen_set_condexec(s);
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
tcg_reg = load_reg(s, rn);
|
tcg_reg = load_reg(s, rn);
|
||||||
tcg_tgtmode = tcg_const_i32(tcg_ctx, tgtmode);
|
tcg_tgtmode = tcg_const_i32(tcg_ctx, tgtmode);
|
||||||
tcg_regno = tcg_const_i32(tcg_ctx, regno);
|
tcg_regno = tcg_const_i32(tcg_ctx, regno);
|
||||||
|
@ -3333,7 +3333,7 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
|
||||||
|
|
||||||
/* Sync state because mrs_banked() can raise exceptions */
|
/* Sync state because mrs_banked() can raise exceptions */
|
||||||
gen_set_condexec(s);
|
gen_set_condexec(s);
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
tcg_reg = tcg_temp_new_i32(tcg_ctx);
|
tcg_reg = tcg_temp_new_i32(tcg_ctx);
|
||||||
tcg_tgtmode = tcg_const_i32(tcg_ctx, tgtmode);
|
tcg_tgtmode = tcg_const_i32(tcg_ctx, tgtmode);
|
||||||
tcg_regno = tcg_const_i32(tcg_ctx, regno);
|
tcg_regno = tcg_const_i32(tcg_ctx, regno);
|
||||||
|
@ -7364,7 +7364,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_set_condexec(s);
|
gen_set_condexec(s);
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
tmpptr = tcg_const_ptr(tcg_ctx, ri);
|
tmpptr = tcg_const_ptr(tcg_ctx, ri);
|
||||||
tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
|
tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
|
||||||
tcg_isread = tcg_const_i32(tcg_ctx, isread);
|
tcg_isread = tcg_const_i32(tcg_ctx, isread);
|
||||||
|
@ -7786,7 +7786,7 @@ static void gen_srs(DisasContext *s,
|
||||||
tmp = tcg_const_i32(tcg_ctx, mode);
|
tmp = tcg_const_i32(tcg_ctx, mode);
|
||||||
/* get_r13_banked() will raise an exception if called from System mode */
|
/* get_r13_banked() will raise an exception if called from System mode */
|
||||||
gen_set_condexec(s);
|
gen_set_condexec(s);
|
||||||
gen_set_pc_im(s, s->pc - 4);
|
gen_set_pc_im(s, s->pc_curr);
|
||||||
gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
|
gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
switch (amode) {
|
switch (amode) {
|
||||||
|
@ -12232,6 +12232,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc->pc_curr = dc->pc;
|
||||||
insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
|
insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
|
||||||
dc->insn = insn;
|
dc->insn = insn;
|
||||||
dc->pc += 4;
|
dc->pc += 4;
|
||||||
|
@ -12301,6 +12302,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc->pc_curr = dc->pc;
|
||||||
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
|
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
|
||||||
is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
|
is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
|
||||||
dc->pc += 2;
|
dc->pc += 2;
|
||||||
|
|
|
@ -10,6 +10,8 @@ typedef struct DisasContext {
|
||||||
const ARMISARegisters *isar;
|
const ARMISARegisters *isar;
|
||||||
|
|
||||||
target_ulong pc;
|
target_ulong pc;
|
||||||
|
/* The address of the current instruction being translated. */
|
||||||
|
target_ulong pc_curr;
|
||||||
target_ulong page_start;
|
target_ulong page_start;
|
||||||
uint32_t insn;
|
uint32_t insn;
|
||||||
/* Nonzero if this instruction has been conditionally skipped. */
|
/* Nonzero if this instruction has been conditionally skipped. */
|
||||||
|
|
Loading…
Reference in a new issue