提交 3accab73 编写于 作者: P Peter Maydell 提交者: Michael Roth

tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses

Document tcg_qemu_tb_exec(). In particular, its return value is a
combination of a pointer to the next translation block and some
extra information in the low two bits. Provide some #defines for
the values passed in these bits to improve code clarity.
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: NRichard Henderson <rth@twiddle.net>
Signed-off-by: NBlue Swirl <blauwirbel@gmail.com>

(cherry picked from commit 0980011b)

Conflicts:
	tcg/tcg.h
Signed-off-by: NMichael Tokarev <mjt@tls.msk.ru>
Signed-off-by: NMichael Roth <mdroth@linux.vnet.ibm.com>
上级 60259539
......@@ -71,7 +71,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
env->current_tb = NULL;
if ((next_tb & 3) == 2) {
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
/* Restore PC. This may happen if async event occurs before
the TB starts executing. */
cpu_pc_from_tb(env, tb);
......@@ -583,7 +583,8 @@ int cpu_exec(CPUArchState *env)
spans two pages, we cannot safely do a direct
jump. */
if (next_tb != 0 && tb->page_addr[1] == -1) {
tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
next_tb & TB_EXIT_MASK, tb);
}
spin_unlock(&tb_lock);
......@@ -597,10 +598,10 @@ int cpu_exec(CPUArchState *env)
tc_ptr = tb->tc_ptr;
/* execute the generated code */
next_tb = tcg_qemu_tb_exec(env, tc_ptr);
if ((next_tb & 3) == 2) {
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
/* Instruction counter expired. */
int insns_left;
tb = (TranslationBlock *)(next_tb & ~3);
tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
/* Restore PC. */
cpu_pc_from_tb(env, tb);
insns_left = env->icount_decr.u32;
......
......@@ -32,7 +32,7 @@ static void gen_icount_end(TranslationBlock *tb, int num_insns)
if (use_icount) {
*icount_arg = num_insns;
gen_set_label(icount_label);
tcg_gen_exit_tb((tcg_target_long)tb + 2);
tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED);
}
}
......
......@@ -660,7 +660,49 @@ TCGv_i64 tcg_const_local_i64(int64_t val);
extern uint8_t *code_gen_prologue;
/* TCG targets may use a different definition of tcg_qemu_tb_exec. */
/**
* tcg_qemu_tb_exec:
* @env: CPUArchState * for the CPU
* @tb_ptr: address of generated code for the TB to execute
*
* Start executing code from a given translation block.
* Where translation blocks have been linked, execution
* may proceed from the given TB into successive ones.
* Control eventually returns only when some action is needed
* from the top-level loop: either control must pass to a TB
* which has not yet been directly linked, or an asynchronous
* event such as an interrupt needs handling.
*
* The return value is a pointer to the next TB to execute
* (if known; otherwise zero). This pointer is assumed to be
* 4-aligned, and the bottom two bits are used to return further
* information:
* 0, 1: the link between this TB and the next is via the specified
* TB index (0 or 1). That is, we left the TB via (the equivalent
* of) "goto_tb <index>". The main loop uses this to determine
* how to link the TB just executed to the next.
* 2: we are using instruction counting code generation, and we
* did not start executing this TB because the instruction counter
* would hit zero midway through it. In this case the next-TB pointer
* returned is the TB we were about to execute, and the caller must
* arrange to execute the remaining count of instructions.
*
* If the bottom two bits indicate an exit-via-index then the CPU
* state is correctly synchronised and ready for execution of the next
* TB (and in particular the guest PC is the address to execute next).
* Otherwise, we gave up on execution of this TB before it started, and
* the caller must fix up the CPU state by calling cpu_pc_from_tb()
* with the next-TB pointer we return.
*
* Note that TCG targets may use a different definition of tcg_qemu_tb_exec
* to this default (which just calls the prologue.code emitted by
* tcg_target_qemu_prologue()).
*/
#define TB_EXIT_MASK 3
#define TB_EXIT_IDX0 0
#define TB_EXIT_IDX1 1
#define TB_EXIT_ICOUNT_EXPIRED 2
#if !defined(tcg_qemu_tb_exec)
# define tcg_qemu_tb_exec(env, tb_ptr) \
((tcg_target_ulong (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册