@@ -35,12 +35,6 @@ typedef abi_ulong tb_page_addr_t;
typedef ram_addr_t tb_page_addr_t;
#endif
-/* is_jmp field values */
-#define DISAS_NEXT 0 /* next instruction can be analyzed */
-#define DISAS_JUMP 1 /* only pc was modified dynamically */
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
-
#include "qemu/log.h"
void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
new file mode 100644
@@ -0,0 +1,38 @@
+/*
+ * Generic intermediate code generation.
+ *
+ * Copyright (C) 2016-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * 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_TARGET: Start of target-specific conditions.
+ *
+ * What instruction to disassemble next.
+ */
+typedef enum DisasJumpType {
+ DISAS_NEXT,
+ DISAS_TOO_MANY,
+ 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 */
@@ -1,6 +1,9 @@
#ifndef TARGET_ARM_TRANSLATE_H
#define TARGET_ARM_TRANSLATE_H
+#include "exec/translator.h"
+
+
/* internal defines */
typedef struct DisasContext {
target_ulong pc;
@@ -119,30 +122,33 @@ static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
s->insn_start_idx = 0;
}
-/* 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 */
+#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
/* 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 4
-#define DISAS_SWI 5
+#define DISAS_WFI DISAS_TARGET_3
+#define DISAS_SWI DISAS_TARGET_4
/* For instructions which unconditionally cause an exception we can skip
* emitting unreachable code at the end of the TB in the A64 decoder
*/
-#define DISAS_EXC 6
+#define DISAS_EXC DISAS_TARGET_5
/* WFE */
-#define DISAS_WFE 7
-#define DISAS_HVC 8
-#define DISAS_SMC 9
-#define DISAS_YIELD 10
+#define DISAS_WFE DISAS_TARGET_6
+#define DISAS_HVC DISAS_TARGET_7
+#define DISAS_SMC DISAS_TARGET_8
+#define DISAS_YIELD DISAS_TARGET_9
/* 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_10
/* For instructions which want an immediate exit to the main loop,
* as opposed to attempting to use lookup_and_goto_ptr.
*/
-#define DISAS_EXIT 12
+#define DISAS_EXIT DISAS_TARGET_11
#ifdef TARGET_AARCH64
void a64_translate_init(void);
@@ -31,6 +31,7 @@
#include "exec/helper-proto.h"
#include "mmu.h"
#include "exec/cpu_ldst.h"
+#include "exec/translator.h"
#include "crisv32-decode.h"
#include "exec/helper-gen.h"
@@ -50,7 +51,11 @@
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
#define BUG_ON(x) ({if (x) BUG();})
-#define DISAS_SWI 5
+/* 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_SWI DISAS_TARGET_3
/* Used by the decoder. */
#define EXTRACT_FIELD(src, start, end) \
@@ -24,6 +24,7 @@
#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"
@@ -71,6 +72,9 @@
//#define MACRO_TEST 1
+/* is_jmp field values */
+#define DISAS_TB_JUMP DISAS_TARGET_0 /* only pc was modified statically */
+
/* global register indexes */
static TCGv_env cpu_env;
static TCGv cpu_A0;
@@ -22,6 +22,7 @@
#include "disas/disas.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
+#include "exec/translator.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
@@ -47,6 +48,11 @@
#define MEM_INDEX 0
+/* 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 */
+
static TCGv_env cpu_env;
static TCGv cpu_R[32];
static TCGv cpu_pc;
@@ -25,6 +25,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"
@@ -173,7 +174,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
@@ -27,6 +27,7 @@
#include "microblaze-decode.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-gen.h"
+#include "exec/translator.h"
#include "trace-tcg.h"
#include "exec/log.h"
@@ -46,6 +47,11 @@
#define EXTRACT_FIELD(src, start, end) \
(((src) >> start) & ((1 << (end - start + 1)) - 1))
+/* 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 */
+
static TCGv env_debug;
static TCGv_env cpu_env;
static TCGv cpu_R[32];
@@ -29,6 +29,12 @@
#include "exec/helper-gen.h"
#include "exec/log.h"
#include "exec/cpu_ldst.h"
+#include "exec/translator.h"
+
+/* 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 INSTRUCTION_FLG(func, flags) { (func), (flags) }
#define INSTRUCTION(func) \
@@ -27,6 +27,7 @@
#include "qemu/log.h"
#include "qemu/bitops.h"
#include "exec/cpu_ldst.h"
+#include "exec/translator.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
@@ -37,6 +38,11 @@
#define LOG_DIS(str, ...) \
qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->pc, ## __VA_ARGS__)
+/* 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 */
+
typedef struct DisasContext {
TranslationBlock *tb;
target_ulong pc;
@@ -76,7 +76,8 @@ typedef struct {
} u;
} DisasCompare;
-#define DISAS_EXCP 4
+/* is_jmp field values */
+#define DISAS_EXCP DISAS_TARGET_0
#ifdef DEBUG_INLINE_BRANCHES
static uint64_t inline_branch_hit[CC_OP_MAX];
@@ -16,6 +16,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"
@@ -45,9 +46,13 @@ typedef struct DisasContext {
#define IS_USER(s) 1
#endif
+/* 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 */
/* These instructions trap after executing, so defer them until after the
conditional executions state has been updated. */
-#define DISAS_SYSCALL 5
+#define DISAS_SYSCALL DISAS_TARGET_3
static TCGv_env cpu_env;
static TCGv_i32 cpu_R[32];
@@ -38,6 +38,7 @@
#include "sysemu/sysemu.h"
#include "exec/cpu_ldst.h"
#include "exec/semihost.h"
+#include "exec/translator.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
@@ -46,6 +47,9 @@
#include "exec/log.h"
+/* is_jmp field values */
+#define DISAS_UPDATE DISAS_TARGET_0 /* cpu state was modified dynamically */
+
typedef struct DisasContext {
const XtensaConfig *config;
TranslationBlock *tb;
Used later. An enum makes expected values explicit and bounds the value space of switches. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- include/exec/exec-all.h | 6 ------ include/exec/translator.h | 38 ++++++++++++++++++++++++++++++++++++++ target/arm/translate.h | 26 ++++++++++++++++---------- target/cris/translate.c | 7 ++++++- target/i386/translate.c | 4 ++++ target/lm32/translate.c | 6 ++++++ target/m68k/translate.c | 7 ++++++- target/microblaze/translate.c | 6 ++++++ target/nios2/translate.c | 6 ++++++ target/openrisc/translate.c | 6 ++++++ target/s390x/translate.c | 3 ++- target/unicore32/translate.c | 7 ++++++- target/xtensa/translate.c | 4 ++++ 13 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 include/exec/translator.h