qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]