aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg-op.c24
-rw-r--r--tcg/tcg-op.h17
-rw-r--r--tcg/tcg.h7
3 files changed, 39 insertions, 9 deletions
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 6a91465..daa416a 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -2574,10 +2574,30 @@ void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
/* QEMU specific operations. */
+void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx)
+{
+ uintptr_t val = (uintptr_t)tb + idx;
+
+ if (tb == NULL) {
+ tcg_debug_assert(idx == 0);
+ } else if (idx <= TB_EXIT_IDXMAX) {
+#ifdef CONFIG_DEBUG_TCG
+ /* This is an exit following a goto_tb. Verify that we have
+ seen this numbered exit before, via tcg_gen_goto_tb. */
+ tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
+#endif
+ } else {
+ /* This is an exit via the exitreq label. */
+ tcg_debug_assert(idx == TB_EXIT_REQUESTED);
+ }
+
+ tcg_gen_op1i(INDEX_op_exit_tb, val);
+}
+
void tcg_gen_goto_tb(unsigned idx)
{
/* We only support two chained exits. */
- tcg_debug_assert(idx <= 1);
+ tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
#ifdef CONFIG_DEBUG_TCG
/* Verify that we havn't seen this numbered exit before. */
tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
@@ -2594,7 +2614,7 @@ void tcg_gen_lookup_and_goto_ptr(void)
tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
tcg_temp_free_ptr(ptr);
} else {
- tcg_gen_exit_tb(0);
+ tcg_gen_exit_tb(NULL, 0);
}
}
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 04eb3e9..7513c1e 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -782,10 +782,19 @@ static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
# error "Unhandled number of operands to insn_start"
#endif
-static inline void tcg_gen_exit_tb(uintptr_t val)
-{
- tcg_gen_op1i(INDEX_op_exit_tb, val);
-}
+/**
+ * tcg_gen_exit_tb() - output exit_tb TCG operation
+ * @tb: The TranslationBlock from which we are exiting
+ * @idx: Direct jump slot index, or exit request
+ *
+ * See tcg/README for more info about this TCG operation.
+ * See also tcg.h and the block comment above TB_EXIT_MASK.
+ *
+ * For a normal exit from the TB, back to the main loop, @tb should
+ * be NULL and @idx should be 0. Otherwise, @tb should be valid and
+ * @idx should be one of the TB_EXIT_ values.
+ */
+void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx);
/**
* tcg_gen_goto_tb() - output goto_tb TCG operation
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 08f8bbf..509f4d6 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1239,9 +1239,10 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
* 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_MASK 3
+#define TB_EXIT_IDX0 0
+#define TB_EXIT_IDX1 1
+#define TB_EXIT_IDXMAX 1
#define TB_EXIT_REQUESTED 3
#ifdef HAVE_TCG_QEMU_TB_EXEC