diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index f2a9bf41..358fdfd2 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -35,36 +35,6 @@ typedef abi_ulong tb_page_addr_t; typedef ram_addr_t tb_page_addr_t; #endif -/* DisasContext is_jmp field values - * - * is_jmp starts as DISAS_NEXT. The translator will keep processing - * instructions until an exit condition is reached. If we reach the - * exit condition and is_jmp is still DISAS_NEXT (because of some - * other condition) we simply "jump" to the next address. - * The remaining exit cases are: - * - * DISAS_JUMP - Only the PC was modified dynamically (e.g computed) - * DISAS_TB_JUMP - Only the PC was modified statically (e.g. branch) - * - * In these cases as long as the PC is updated we can chain to the - * next TB either by exiting the loop or looking up the next TB via - * the loookup helper. - * - * DISAS_UPDATE - CPU State was modified dynamically - * - * This covers any other CPU state which necessities us exiting the - * TCG code to the main run-loop. Typically this includes anything - * that might change the interrupt state. - * - * Individual translators may define additional exit cases to deal - * with per-target special conditions. - */ -#define DISAS_NEXT 0 /* next instruction can be analyzed */ -#define DISAS_JUMP 1 /* only pc was modified dynamically */ -#define DISAS_TB_JUMP 2 /* only pc was modified statically */ -#define DISAS_UPDATE 3 /* cpu state was modified dynamically */ -#define DISAS_NORETURN 4 /* the tb has already been exited */ - #include "qemu/log.h" void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb); diff --git a/qemu/include/exec/translator.h b/qemu/include/exec/translator.h new file mode 100644 index 00000000..b51b8f8a --- /dev/null +++ b/qemu/include/exec/translator.h @@ -0,0 +1,40 @@ +/* + * Generic intermediate code generation. + * + * Copyright (C) 2016-2017 LluĂ­s Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef EXEC__TRANSLATOR_H +#define EXEC__TRANSLATOR_H + +/** + * DisasJumpType: + * @DISAS_NEXT: Next instruction in program order. + * @DISAS_TOO_MANY: Too many instructions translated. + * @DISAS_NORETURN: Following code is dead. + * @DISAS_TARGET_*: Start of target-specific conditions. + * + * What instruction to disassemble next. + */ +typedef enum DisasJumpType { + DISAS_NEXT, + DISAS_TOO_MANY, + DISAS_NORETURN, + DISAS_TARGET_0, + DISAS_TARGET_1, + DISAS_TARGET_2, + DISAS_TARGET_3, + DISAS_TARGET_4, + DISAS_TARGET_5, + DISAS_TARGET_6, + DISAS_TARGET_7, + DISAS_TARGET_8, + DISAS_TARGET_9, + DISAS_TARGET_10, + DISAS_TARGET_11, +} DisasJumpType; + +#endif /* EXEC__TRANSLATOR_H */ diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 597cc468..ff666e66 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -4283,7 +4283,7 @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest) gen_set_pc_im(s, dest); gen_goto_ptr(s); } - s->is_jmp = DISAS_TB_JUMP; + s->is_jmp = DISAS_NORETURN; } static inline void gen_jmp(DisasContext *s, uint32_t dest) @@ -4295,7 +4295,6 @@ static inline void gen_jmp(DisasContext *s, uint32_t dest) gen_bx_im(s, dest); } else { gen_goto_tb(s, 0, dest); - s->is_jmp = DISAS_TB_JUMP; } } diff --git a/qemu/target/arm/translate.h b/qemu/target/arm/translate.h index f09c0c8c..b376fa85 100644 --- a/qemu/target/arm/translate.h +++ b/qemu/target/arm/translate.h @@ -1,6 +1,8 @@ #ifndef TARGET_ARM_TRANSLATE_H #define TARGET_ARM_TRANSLATE_H +#include "exec/translator.h" + /* internal defines */ typedef struct DisasContext { target_ulong pc; @@ -119,28 +121,31 @@ static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) } /* target-specific extra values for is_jmp */ +/* is_jmp field values */ +#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */ +#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */ /* These instructions trap after executing, so the A32/T32 decoder must * defer them until after the conditional execution state has been updated. * WFI also needs special handling when single-stepping. */ -#define DISAS_WFI 5 -#define DISAS_SWI 6 +#define DISAS_WFI DISAS_TARGET_2 +#define DISAS_SWI DISAS_TARGET_3 /* WFE */ -#define DISAS_WFE 7 -#define DISAS_HVC 8 -#define DISAS_SMC 9 -#define DISAS_YIELD 10 +#define DISAS_WFE DISAS_TARGET_4 +#define DISAS_HVC DISAS_TARGET_5 +#define DISAS_SMC DISAS_TARGET_6 +#define DISAS_YIELD DISAS_TARGET_7 /* M profile branch which might be an exception return (and so needs * custom end-of-TB code) */ -#define DISAS_BX_EXCRET 11 +#define DISAS_BX_EXCRET DISAS_TARGET_8 /* For instructions which want an immediate exit to the main loop, * as opposed to attempting to use lookup_and_goto_ptr. Unlike * DISAS_UPDATE this doesn't write the PC on exiting the translation * loop so you need to ensure something (gen_a64_set_pc_im or runtime * helper) has done so before we reach return from cpu_tb_exec. */ -#define DISAS_EXIT 12 +#define DISAS_EXIT DISAS_TARGET_9 #ifdef TARGET_AARCH64 void a64_translate_init(struct uc_struct *uc); diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 5b9a1911..202caa30 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -25,13 +25,13 @@ #include "exec/exec-all.h" #include "tcg-op.h" #include "exec/cpu_ldst.h" +#include "exec/translator.h" + #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "uc_priv.h" -#define DISAS_TOO_MANY 5 - #define PREFIX_REPZ 0x01 #define PREFIX_REPNZ 0x02 #define PREFIX_LOCK 0x04 @@ -5045,7 +5045,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_update_cc_op(s); gen_jmp_im(s, pc_start - s->cs_base); gen_helper_hlt(tcg_ctx, cpu_env, tcg_const_i32(tcg_ctx, s->pc - pc_start)); - s->is_jmp = DISAS_TB_JUMP; + s->is_jmp = DISAS_NORETURN; return s->pc; } @@ -9245,7 +9245,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) gen_tb_start(tcg_ctx); gen_jmp_im(dc, tb->pc - tb->cs_base); gen_helper_hlt(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 0)); - dc->is_jmp = DISAS_TB_JUMP; + dc->is_jmp = DISAS_NORETURN; goto done_generating; } diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index 193d345b..f74a4c59 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -24,6 +24,7 @@ #include "tcg-op.h" #include "qemu/log.h" #include "exec/cpu_ldst.h" +#include "exec/translator.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" @@ -158,7 +159,11 @@ static void do_writebacks(DisasContext *s) } } -#define DISAS_JUMP_NEXT 4 +/* is_jmp field values */ +#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */ +#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */ +#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */ +#define DISAS_JUMP_NEXT DISAS_TARGET_3 #if defined(CONFIG_USER_ONLY) #define IS_USER(s) 1