target/arm: [tcg] Port to tb_start

Incrementally paves the way towards using the generic instruction translation
loop.

Backports commit b14768544fd715a3f1742c10fc36ae81c703cbc1 from qemu
This commit is contained in:
Lluís Vilanova 2018-03-04 19:22:16 -05:00 committed by Lioncash
parent 529c6c17f1
commit b3878f117e
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -12102,6 +12102,50 @@ static int arm_tr_init_disas_context(DisasContextBase *dcbase,
return max_insns;
}
static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
TCGContext *tcg_ctx = cpu->uc->tcg_ctx;
/* A note on handling of the condexec (IT) bits:
*
* We want to avoid the overhead of having to write the updated condexec
* bits back to the CPUARMState for every instruction in an IT block. So:
* (1) if the condexec bits are not already zero then we write
* zero back into the CPUARMState now. This avoids complications trying
* to do it at the end of the block. (For example if we don't do this
* it's hard to identify whether we can safely skip writing condexec
* at the end of the TB, which we definitely want to do for the case
* where a TB doesn't do anything with the IT state at all.)
* (2) if we are going to leave the TB then we call gen_set_condexec()
* which will write the correct value into CPUARMState if zero is wrong.
* This is done both for leaving the TB at the end, and for leaving
* it because of an exception we know will happen, which is done in
* gen_exception_insn(). The latter is necessary because we need to
* leave the TB with the PC/IT state just prior to execution of the
* instruction which caused the exception.
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
* then the CPUARMState will be wrong and we need to reset it.
* This is handled in the same way as restoration of the
* PC in these situations; we save the value of the condexec bits
* for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
* then uses this to restore them after an exception.
*
* Note that there are no instructions which can read the condexec
* bits, and none which can write non-static values to them, so
* we don't need to care about whether CPUARMState is correct in the
* middle of a TB.
*/
/* Reset the conditional execution bits immediately. This avoids
complications trying to do it at the end of the block. */
if (dc->condexec_mask || dc->condexec_cond) {
TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
tcg_gen_movi_i32(tcg_ctx, tmp, 0);
store_cpu_field(tcg_ctx, tmp, condexec_bits);
}
}
/* generate intermediate code for basic block 'tb'. */
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
{
@ -12163,45 +12207,8 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
}
gen_tb_start(tcg_ctx, tb);
arm_tr_tb_start(&dc->base, cs);
/* A note on handling of the condexec (IT) bits:
*
* We want to avoid the overhead of having to write the updated condexec
* bits back to the CPUARMState for every instruction in an IT block. So:
* (1) if the condexec bits are not already zero then we write
* zero back into the CPUARMState now. This avoids complications trying
* to do it at the end of the block. (For example if we don't do this
* it's hard to identify whether we can safely skip writing condexec
* at the end of the TB, which we definitely want to do for the case
* where a TB doesn't do anything with the IT state at all.)
* (2) if we are going to leave the TB then we call gen_set_condexec()
* which will write the correct value into CPUARMState if zero is wrong.
* This is done both for leaving the TB at the end, and for leaving
* it because of an exception we know will happen, which is done in
* gen_exception_insn(). The latter is necessary because we need to
* leave the TB with the PC/IT state just prior to execution of the
* instruction which caused the exception.
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
* then the CPUARMState will be wrong and we need to reset it.
* This is handled in the same way as restoration of the
* PC in these situations; we save the value of the condexec bits
* for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
* then uses this to restore them after an exception.
*
* Note that there are no instructions which can read the condexec
* bits, and none which can write non-static values to them, so
* we don't need to care about whether CPUARMState is correct in the
* middle of a TB.
*/
/* Reset the conditional execution bits immediately. This avoids
complications trying to do it at the end of the block. */
if (dc->condexec_mask || dc->condexec_cond)
{
TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
tcg_gen_movi_i32(tcg_ctx, tmp, 0);
store_cpu_field(tcg_ctx, tmp, condexec_bits);
}
do {
dc->base.num_insns++;
dc->insn_start_idx = tcg_op_buf_count(tcg_ctx);