[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/8] tcg: Define tcg_itype for code pointers
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 4/8] tcg: Define tcg_itype for code pointers |
Date: |
Fri, 28 Mar 2014 17:27:10 -0700 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH 0/8] tcg: tidy the type of code_ptr, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 1/8] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 2/8] tcg: Avoid stores to unaligned addresses, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 3/8] tcg: Avoid undefined behaviour patching code at unaligned addresses, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 4/8] tcg: Define tcg_itype for code pointers,
Richard Henderson <=
- [Qemu-devel] [PATCH 5/8] tcg-ppc64: Define TCG_TARGET_ITYPE_SIZE, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 6/8] tcg-ppc: Define TCG_TARGET_ITYPE_SIZE, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 7/8] tcg-aarch64: Define TCG_TARGET_ITYPE_SIZE, Richard Henderson, 2014/03/28
- [Qemu-devel] [PATCH 8/8] tcg-sparc: Define TCG_TARGET_ITYPE_SIZE, Richard Henderson, 2014/03/28
- Re: [Qemu-devel] [PATCH 0/8] tcg: tidy the type of code_ptr, Peter Maydell, 2014/03/29