To be defined by the tcg backend based on the elemental unit of the ISA. During the transition, allow TCG_TARGET_ITYPE_SIZE to be undefined, which allows us to default tcg_itype to the current uint8_t.
Signed-off-by: Richard Henderson <r...@twiddle.net> --- include/exec/exec-all.h | 2 +- tcg/i386/tcg-target.h | 1 + tcg/tcg-be-ldst.h | 4 +-- tcg/tcg.c | 89 +++++++++++++++++++++++++++++++++---------------- tcg/tcg.h | 37 +++++++++++++++----- translate-all.c | 6 ++-- 6 files changed, 95 insertions(+), 44 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 1c49a21..0766e24 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -145,7 +145,7 @@ struct TranslationBlock { #define CF_COUNT_MASK 0x7fff #define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */ - uint8_t *tc_ptr; /* pointer to the translated code */ + void *tc_ptr; /* pointer to the translated code */ /* next matching tb for physical address. */ struct TranslationBlock *phys_hash_next; /* first and second physical page containing code. The lower bit diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index bdf2222..c6d13d2 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -25,6 +25,7 @@ #define TCG_TARGET_I386 1 #undef TCG_TARGET_WORDS_BIGENDIAN +#define TCG_TARGET_ITYPE_SIZE 1 #ifdef __x86_64__ # define TCG_TARGET_REG_BITS 64 diff --git a/tcg/tcg-be-ldst.h b/tcg/tcg-be-ldst.h index 284db0c..94a4472 100644 --- a/tcg/tcg-be-ldst.h +++ b/tcg/tcg-be-ldst.h @@ -31,8 +31,8 @@ typedef struct TCGLabelQemuLdst { TCGReg datalo_reg; /* reg index for low word to be loaded or stored */ TCGReg datahi_reg; /* reg index for high word to be loaded or stored */ int mem_index; /* soft MMU memory index */ - uint8_t *raddr; /* gen code addr of the next IR of qemu_ld/st IR */ - uint8_t *label_ptr[2]; /* label pointers to be updated */ + tcg_itype *raddr; /* gen code addr of the next IR of qemu_ld/st IR */ + tcg_itype *label_ptr[2]; /* label pointers to be updated */ } TCGLabelQemuLdst; typedef struct TCGBackendData { diff --git a/tcg/tcg.c b/tcg/tcg.c index 727112d..8500859 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -65,7 +65,7 @@ /* Forward declarations for functions declared in tcg-target.c and used here. */ static void tcg_target_init(TCGContext *s); static void tcg_target_qemu_prologue(TCGContext *s); -static void patch_reloc(uint8_t *code_ptr, int type, +static void patch_reloc(tcg_itype *code_ptr, int type, intptr_t value, intptr_t addend); /* The CIE and FDE header definitions will be common to all hosts. */ @@ -117,55 +117,85 @@ const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); static TCGRegSet tcg_target_available_regs[2]; static TCGRegSet tcg_target_call_clobber_regs; +#if TCG_TARGET_ITYPE_SIZE == 1 static inline void tcg_out8(TCGContext *s, uint8_t v) { *s->code_ptr++ = v; } -static inline void tcg_out16(TCGContext *s, uint16_t v) +static inline void tcg_patch8(tcg_itype *p, uint8_t v) { - uint8_t *p = s->code_ptr; - memcpy(p, &v, sizeof(v)); - s->code_ptr = p + 2; + *p = v; } +#endif -static inline void tcg_out32(TCGContext *s, uint32_t v) +#if TCG_TARGET_ITYPE_SIZE <= 2 +static inline void tcg_out16(TCGContext *s, uint16_t v) { - uint8_t *p = s->code_ptr; - memcpy(p, &v, sizeof(v)); - s->code_ptr = p + 4; + if (TCG_TARGET_ITYPE_SIZE == 2) { + *s->code_ptr++ = v; + } else { + tcg_itype *p = s->code_ptr; + memcpy(p, &v, sizeof(v)); + s->code_ptr = p + (2 / TCG_TARGET_ITYPE_SIZE); + } } -static inline void tcg_out64(TCGContext *s, uint64_t v) +static inline void tcg_patch16(tcg_itype *p, uint16_t v) { - uint8_t *p = s->code_ptr; - memcpy(p, &v, sizeof(v)); - s->code_ptr = p + 8; + if (TCG_TARGET_ITYPE_SIZE == 2) { + *p = v; + } else { + memcpy(p, &v, sizeof(v)); + } } +#endif -static inline void tcg_patch8(uint8_t *p, uint8_t v) +#if TCG_TARGET_ITYPE_SIZE <= 4 +static inline void tcg_out32(TCGContext *s, uint32_t v) { - memcpy(p, &v, sizeof(v)); + if (TCG_TARGET_ITYPE_SIZE == 4) { + *s->code_ptr++ = v; + } else { + tcg_itype *p = s->code_ptr; + memcpy(p, &v, sizeof(v)); + s->code_ptr = p + (4 / TCG_TARGET_ITYPE_SIZE); + } } -static inline void tcg_patch16(uint8_t *p, uint16_t v) +static inline void tcg_patch32(tcg_itype *p, uint32_t v) { - memcpy(p, &v, sizeof(v)); + if (TCG_TARGET_ITYPE_SIZE) { + *p = v; + } else { + memcpy(p, &v, sizeof(v)); + } } +#endif -static inline void tcg_patch32(uint8_t *p, uint32_t v) +static inline void tcg_out64(TCGContext *s, uint64_t v) { - memcpy(p, &v, sizeof(v)); + if (TCG_TARGET_ITYPE_SIZE == 8) { + *s->code_ptr++ = v; + } else { + tcg_itype *p = s->code_ptr; + memcpy(p, &v, sizeof(v)); + s->code_ptr = p + (8 / TCG_TARGET_ITYPE_SIZE); + } } -static inline void tcg_patch64(uint8_t *p, uint64_t v) +static inline void tcg_patch64(tcg_itype *p, uint64_t v) { - memcpy(p, &v, sizeof(v)); + if (TCG_TARGET_ITYPE_SIZE == 8) { + *p = v; + } else { + memcpy(p, &v, sizeof(v)); + } } /* label relocation processing */ -static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, +static void tcg_out_reloc(TCGContext *s, tcg_itype *code_ptr, int type, int label_index, intptr_t addend) { TCGLabel *l; @@ -188,7 +218,7 @@ static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, } } -static void tcg_out_label(TCGContext *s, int label_index, void *ptr) +static void tcg_out_label(TCGContext *s, int label_index, tcg_itype *ptr) { TCGLabel *l; TCGRelocation *r; @@ -359,7 +389,7 @@ void tcg_prologue_init(TCGContext *s) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { - size_t size = s->code_ptr - s->code_buf; + size_t size = (uintptr_t)s->code_ptr - (uintptr_t)s->code_buf; qemu_log("PROLOGUE: [size=%zu]\n", size); log_disas(s->code_buf, size); qemu_log("\n"); @@ -2472,7 +2502,7 @@ static void dump_op_count(void) #endif -static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, +static inline int tcg_gen_code_common(TCGContext *s, tcg_itype *gen_code_buf, long search_pc) { TCGOpcode opc; @@ -2587,7 +2617,8 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, } args += def->nb_args; next: - if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) { + if (search_pc >= 0 + && search_pc < (intptr_t)s->code_ptr - (intptr_t)gen_code_buf) { return op_index; } op_index++; @@ -2601,7 +2632,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, return -1; } -int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) +int tcg_gen_code(TCGContext *s, tcg_itype *gen_code_buf) { #ifdef CONFIG_PROFILER { @@ -2622,14 +2653,14 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) /* flush instruction cache */ flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr); - return s->code_ptr - gen_code_buf; + return (uintptr_t)s->code_ptr - (uintptr_t)gen_code_buf; } /* Return the index of the micro operation such as the pc after is < offset bytes from the start of the TB. The contents of gen_code_buf must not be changed, though writing the same values is ok. Return -1 if not found. */ -int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset) +int tcg_gen_code_search_pc(TCGContext *s, tcg_itype *gen_code_buf, long offset) { return tcg_gen_code_common(s, gen_code_buf, offset); } diff --git a/tcg/tcg.h b/tcg/tcg.h index f7efcb4..1aa0800 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -139,10 +139,26 @@ typedef enum TCGOpcode { #define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b) #define tcg_regset_not(d, a) (d) = ~(a) +#ifndef TCG_TARGET_ITYPE_SIZE +#define TCG_TARGET_ITYPE_SIZE 1 +#endif +#if TCG_TARGET_ITYPE_SIZE == 1 +typedef uint8_t tcg_itype; +#elif TCG_TARGET_ITYPE_SIZE == 2 +typedef uint16_t tcg_itype; +#elif TCG_TARGET_ITYPE_SIZE == 4 +typedef uint32_t tcg_itype; +#elif TCG_TARGET_ITYPE_SIZE == 8 +typedef uint64_t tcg_itype; +#else +# error +#endif + + typedef struct TCGRelocation { struct TCGRelocation *next; int type; - uint8_t *ptr; + tcg_itype *ptr; intptr_t addend; } TCGRelocation; @@ -457,7 +473,7 @@ struct TCGContext { int nb_temps; /* goto_tb support */ - uint8_t *code_buf; + tcg_itype *code_buf; uintptr_t *tb_next; uint16_t *tb_next_offset; uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ @@ -478,7 +494,7 @@ struct TCGContext { intptr_t frame_end; int frame_reg; - uint8_t *code_ptr; + tcg_itype *code_ptr; TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ TCGTempSet free_temps[TCG_TYPE_COUNT * 2]; @@ -517,14 +533,17 @@ struct TCGContext { uint16_t gen_opc_icount[OPC_BUF_SIZE]; uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; - /* Code generation */ + /* Code generation. Note that we specifically do not use tcg_itype + here, because there's too much arithmetic throughout that relies + on addition and subtraction working on bytes. Rely on the GCC + extension that allows arithmetic on void*. */ int code_gen_max_blocks; - uint8_t *code_gen_prologue; - uint8_t *code_gen_buffer; + void *code_gen_prologue; + void *code_gen_buffer; size_t code_gen_buffer_size; /* threshold to flush the translated code buffer */ size_t code_gen_buffer_max_size; - uint8_t *code_gen_ptr; + void *code_gen_ptr; TBContext tb_ctx; @@ -559,8 +578,8 @@ void tcg_context_init(TCGContext *s); void tcg_prologue_init(TCGContext *s); void tcg_func_start(TCGContext *s); -int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf); -int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset); +int tcg_gen_code(TCGContext *s, tcg_itype *gen_code_buf); +int tcg_gen_code_search_pc(TCGContext *s, tcg_itype *gen_code_buf, long offset); void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size); diff --git a/translate-all.c b/translate-all.c index f243c10..377d97c 100644 --- a/translate-all.c +++ b/translate-all.c @@ -143,7 +143,7 @@ void cpu_gen_init(void) int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr) { TCGContext *s = &tcg_ctx; - uint8_t *gen_code_buf; + tcg_itype *gen_code_buf; int gen_code_size; #ifdef CONFIG_PROFILER int64_t ti; @@ -235,7 +235,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, s->tb_jmp_offset = NULL; s->tb_next = tb->tb_next; #endif - j = tcg_gen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr); + j = tcg_gen_code_search_pc(s, (tcg_itype *)tc_ptr, searched_pc - tc_ptr); if (j < 0) return -1; /* now find start of instruction before */ @@ -944,7 +944,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, { CPUArchState *env = cpu->env_ptr; TranslationBlock *tb; - uint8_t *tc_ptr; + tcg_itype *tc_ptr; tb_page_addr_t phys_pc, phys_page2; target_ulong virt_page2; int code_gen_size; -- 1.9.0