All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr
@ 2014-04-01 20:53 Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps Richard Henderson
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Here's a second revision, attempting to take Peter's review on board.

In particular, inlines to hide some of the pointer differencing issues.
I also chose a different name for the type: tcg_insn_unit as suggested
by Jay Foad.


r~


Peter Maydell (3):
  exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps
  tcg: Avoid stores to unaligned addresses
  tcg: Avoid undefined behaviour patching code at unaligned addresses

Richard Henderson (6):
  tcg: Introduce byte pointer arithmetic helpers
  tcg: Define tcg_insn_unit for code pointers
  tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE
  tcg-ppc64: Define TCG_TARGET_INSN_UNIT_SIZE
  tcg-ppc: Define TCG_TARGET_INSN_UNIT_SIZE
  tcg-sparc: Define TCG_TARGET_INSN_UNIT_SIZE

 include/exec/exec-all.h |   4 +-
 tcg/i386/tcg-target.c   |  60 +++++++--------
 tcg/i386/tcg-target.h   |   1 +
 tcg/ppc/tcg-target.c    | 194 +++++++++++++++++++++++-------------------------
 tcg/ppc/tcg-target.h    |   1 +
 tcg/ppc64/tcg-target.c  | 163 ++++++++++++++++++++--------------------
 tcg/ppc64/tcg-target.h  |   1 +
 tcg/sparc/tcg-target.c  | 138 ++++++++++++++++------------------
 tcg/sparc/tcg-target.h  |   2 +-
 tcg/tcg-be-ldst.h       |   4 +-
 tcg/tcg.c               | 108 +++++++++++++++++++--------
 tcg/tcg.h               |  84 ++++++++++++++++++---
 translate-all.c         |  13 ++--
 13 files changed, 432 insertions(+), 341 deletions(-)

-- 
1.9.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 2/9] tcg: Avoid stores to unaligned addresses Richard Henderson
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

From: Peter Maydell <peter.maydell@linaro.org>

The code which patches x86 jump instructions assumes it can do an
unaligned write of a uint32_t. This is actually safe on x86, but it's
still undefined behaviour. We have infrastructure for doing efficient
unaligned accesses which doesn't engage in undefined behaviour, so
use it.

This is technically fractionally less efficient, at least with gcc 4.6;
instead of one instruction:
 7b2:   89 3e                   mov    %edi,(%rsi)
we get an extra spurious store to the stack slot:
 7b2:   89 7c 24 64             mov    %edi,0x64(%rsp)
 7b6:   89 3e                   mov    %edi,(%rsi)

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/exec/exec-all.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index f9ac332..1c49a21 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -229,7 +229,7 @@ void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
 static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
-    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
+    stl_p((void*)jmp_addr, addr - (jmp_addr + 4));
     /* no need to flush icache explicitly */
 }
 #elif defined(__aarch64__)
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 2/9] tcg: Avoid stores to unaligned addresses
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 3/9] tcg: Avoid undefined behaviour patching code at " Richard Henderson
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

From: Peter Maydell <peter.maydell@linaro.org>

Avoid stores to unaligned addresses in TCG code generation, by using the
usual memcpy() approach. (Using bswap.h would drag a lot of QEMU baggage
into TCG, so it's simpler just to do direct memcpy() here.)

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/tcg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index f1e0763..60f06c5 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -125,21 +125,21 @@ static inline void tcg_out8(TCGContext *s, uint8_t v)
 static inline void tcg_out16(TCGContext *s, uint16_t v)
 {
     uint8_t *p = s->code_ptr;
-    *(uint16_t *)p = v;
+    memcpy(p, &v, sizeof(v));
     s->code_ptr = p + 2;
 }
 
 static inline void tcg_out32(TCGContext *s, uint32_t v)
 {
     uint8_t *p = s->code_ptr;
-    *(uint32_t *)p = v;
+    memcpy(p, &v, sizeof(v));
     s->code_ptr = p + 4;
 }
 
 static inline void tcg_out64(TCGContext *s, uint64_t v)
 {
     uint8_t *p = s->code_ptr;
-    *(uint64_t *)p = v;
+    memcpy(p, &v, sizeof(v));
     s->code_ptr = p + 8;
 }
 
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 3/9] tcg: Avoid undefined behaviour patching code at unaligned addresses
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 2/9] tcg: Avoid stores to unaligned addresses Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 4/9] tcg: Introduce byte pointer arithmetic helpers Richard Henderson
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

From: Peter Maydell <peter.maydell@linaro.org>

To avoid C undefined behaviour when patching generated code,
provide wrappers tcg_patch8/16/32/64 which use the usual memcpy
trick, and use them in the i386 backend.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/i386/tcg-target.c | 12 ++++++------
 tcg/tcg.c             | 20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index f832282..a0f9dff 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -151,14 +151,14 @@ static void patch_reloc(uint8_t *code_ptr, int type,
         if (value != (int32_t)value) {
             tcg_abort();
         }
-        *(uint32_t *)code_ptr = value;
+        tcg_patch32(code_ptr, value);
         break;
     case R_386_PC8:
         value -= (uintptr_t)code_ptr;
         if (value != (int8_t)value) {
             tcg_abort();
         }
-        *(uint8_t *)code_ptr = value;
+        tcg_patch8(code_ptr, value);
         break;
     default:
         tcg_abort();
@@ -1276,9 +1276,9 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     uint8_t **label_ptr = &l->label_ptr[0];
 
     /* resolve label address */
-    *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
+    tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
+        tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
     }
 
     if (TCG_TARGET_REG_BITS == 32) {
@@ -1360,9 +1360,9 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     TCGReg retaddr;
 
     /* resolve label address */
-    *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
+    tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
+        tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
     }
 
     if (TCG_TARGET_REG_BITS == 32) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 60f06c5..727112d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -143,6 +143,26 @@ static inline void tcg_out64(TCGContext *s, uint64_t v)
     s->code_ptr = p + 8;
 }
 
+static inline void tcg_patch8(uint8_t *p, uint8_t v)
+{
+    memcpy(p, &v, sizeof(v));
+}
+
+static inline void tcg_patch16(uint8_t *p, uint16_t v)
+{
+    memcpy(p, &v, sizeof(v));
+}
+
+static inline void tcg_patch32(uint8_t *p, uint32_t v)
+{
+    memcpy(p, &v, sizeof(v));
+}
+
+static inline void tcg_patch64(uint8_t *p, uint64_t v)
+{
+    memcpy(p, &v, sizeof(v));
+}
+
 /* label relocation processing */
 
 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 4/9] tcg: Introduce byte pointer arithmetic helpers
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (2 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 3/9] tcg: Avoid undefined behaviour patching code at " Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 5/9] tcg: Define tcg_insn_unit for code pointers Richard Henderson
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/tcg.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index f7efcb4..8df1641 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -717,6 +717,51 @@ TCGv_i32 tcg_const_local_i32(int32_t val);
 TCGv_i64 tcg_const_local_i64(int64_t val);
 
 /**
+ * tcg_ptr_byte_diff
+ * @a, @b: addresses to be differenced
+ *
+ * There are many places within the TCG backends where we need a byte
+ * difference between two pointers.  While this can be accomplished
+ * with local casting, it's easy to get wrong -- especially if one is
+ * concerned with the signedness of the result.
+ *
+ * This version relies on GCC's void pointer arithmetic to get the
+ * correct result.
+ */
+
+static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
+{
+    return a - b;
+}
+
+/**
+ * tcg_pcrel_diff
+ * @s: the tcg context
+ * @target: address of the target
+ *
+ * Produce a pc-relative difference, from the current code_ptr
+ * to the destination address.
+ */
+
+static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
+{
+    return tcg_ptr_byte_diff(target, s->code_ptr);
+}
+
+/**
+ * tcg_current_code_size
+ * @s: the tcg context
+ *
+ * Compute the current code size within the translation block.
+ * This is used to fill in qemu's data structures for goto_tb.
+ */
+
+static inline size_t tcg_current_code_size(TCGContext *s)
+{
+    return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
+}
+
+/**
  * tcg_qemu_tb_exec:
  * @env: CPUArchState * for the CPU
  * @tb_ptr: address of generated code for the TB to execute
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 5/9] tcg: Define tcg_insn_unit for code pointers
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (3 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 4/9] tcg: Introduce byte pointer arithmetic helpers Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 6/9] tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE Richard Henderson
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

To be defined by the tcg backend based on the elemental unit of the ISA.
During the transition, allow TCG_TARGET_INSN_UNIT_SIZE to be undefined,
which allows us to default tcg_insn_unit to the current uint8_t.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/exec/exec-all.h |   2 +-
 tcg/tcg-be-ldst.h       |   4 +-
 tcg/tcg.c               | 110 ++++++++++++++++++++++++++++++------------------
 tcg/tcg.h               |  39 +++++++++++++----
 translate-all.c         |  13 +++---
 5 files changed, 109 insertions(+), 59 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/tcg-be-ldst.h b/tcg/tcg-be-ldst.h
index 284db0c..86190ca 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_insn_unit *raddr;   /* gen code addr of the next IR of qemu_ld/st IR */
+    tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */
 } TCGLabelQemuLdst;
 
 typedef struct TCGBackendData {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 727112d..529b207 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_insn_unit *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_INSN_UNIT_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_insn_unit *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_INSN_UNIT_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_INSN_UNIT_SIZE == 2) {
+        *s->code_ptr++ = v;
+    } else {
+        tcg_insn_unit *p = s->code_ptr;
+        memcpy(p, &v, sizeof(v));
+        s->code_ptr = p + (2 / TCG_TARGET_INSN_UNIT_SIZE);
+    }
 }
 
-static inline void tcg_out64(TCGContext *s, uint64_t v)
+static inline void tcg_patch16(tcg_insn_unit *p, uint16_t v)
 {
-    uint8_t *p = s->code_ptr;
-    memcpy(p, &v, sizeof(v));
-    s->code_ptr = p + 8;
+    if (TCG_TARGET_INSN_UNIT_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_INSN_UNIT_SIZE <= 4
+static inline void tcg_out32(TCGContext *s, uint32_t v)
 {
-    memcpy(p, &v, sizeof(v));
+    if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
+        *s->code_ptr++ = v;
+    } else {
+        tcg_insn_unit *p = s->code_ptr;
+        memcpy(p, &v, sizeof(v));
+        s->code_ptr = p + (4 / TCG_TARGET_INSN_UNIT_SIZE);
+    }
 }
 
-static inline void tcg_patch16(uint8_t *p, uint16_t v)
+static inline void tcg_patch32(tcg_insn_unit *p, uint32_t v)
 {
-    memcpy(p, &v, sizeof(v));
+    if (TCG_TARGET_INSN_UNIT_SIZE == 4) {
+        *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_INSN_UNIT_SIZE == 8) {
+        *s->code_ptr++ = v;
+    } else {
+        tcg_insn_unit *p = s->code_ptr;
+        memcpy(p, &v, sizeof(v));
+        s->code_ptr = p + (8 / TCG_TARGET_INSN_UNIT_SIZE);
+    }
 }
 
-static inline void tcg_patch64(uint8_t *p, uint64_t v)
+static inline void tcg_patch64(tcg_insn_unit *p, uint64_t v)
 {
-    memcpy(p, &v, sizeof(v));
+    if (TCG_TARGET_INSN_UNIT_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_insn_unit *code_ptr, int type,
                           int label_index, intptr_t addend)
 {
     TCGLabel *l;
@@ -188,23 +218,20 @@ 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_insn_unit *ptr)
 {
-    TCGLabel *l;
-    TCGRelocation *r;
+    TCGLabel *l = &s->labels[label_index];
     intptr_t value = (intptr_t)ptr;
+    TCGRelocation *r;
 
-    l = &s->labels[label_index];
-    if (l->has_value) {
-        tcg_abort();
-    }
-    r = l->u.first_reloc;
-    while (r != NULL) {
+    assert(!l->has_value);
+
+    for (r = l->u.first_reloc; r != NULL; r = r->next) {
         patch_reloc(r->ptr, r->type, value, r->addend);
-        r = r->next;
     }
+
     l->has_value = 1;
-    l->u.value = value;
+    l->u.value_ptr = ptr;
 }
 
 int gen_new_label(void)
@@ -359,7 +386,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 = tcg_current_code_size(s);
         qemu_log("PROLOGUE: [size=%zu]\n", size);
         log_disas(s->code_buf, size);
         qemu_log("\n");
@@ -2472,7 +2499,8 @@ 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_insn_unit *gen_code_buf,
                                       long search_pc)
 {
     TCGOpcode opc;
@@ -2587,7 +2615,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 +2630,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_insn_unit *gen_code_buf)
 {
 #ifdef CONFIG_PROFILER
     {
@@ -2620,16 +2649,17 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
     tcg_gen_code_common(s, gen_code_buf, -1);
 
     /* flush instruction cache */
-    flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr);
+    flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
 
-    return s->code_ptr -  gen_code_buf;
+    return tcg_current_code_size(s);
 }
 
 /* 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_insn_unit *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 8df1641..d751c91 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_INSN_UNIT_SIZE
+#define TCG_TARGET_INSN_UNIT_SIZE 1
+#endif
+#if TCG_TARGET_INSN_UNIT_SIZE == 1
+typedef uint8_t tcg_insn_unit;
+#elif TCG_TARGET_INSN_UNIT_SIZE == 2
+typedef uint16_t tcg_insn_unit;
+#elif TCG_TARGET_INSN_UNIT_SIZE == 4
+typedef uint32_t tcg_insn_unit;
+#elif TCG_TARGET_INSN_UNIT_SIZE == 8
+typedef uint64_t tcg_insn_unit;
+#else
+# error
+#endif
+
+
 typedef struct TCGRelocation {
     struct TCGRelocation *next;
     int type;
-    uint8_t *ptr;
+    tcg_insn_unit *ptr;
     intptr_t addend;
 } TCGRelocation; 
 
@@ -150,6 +166,7 @@ typedef struct TCGLabel {
     int has_value;
     union {
         uintptr_t value;
+        tcg_insn_unit *value_ptr;
         TCGRelocation *first_reloc;
     } u;
 } TCGLabel;
@@ -457,7 +474,7 @@ struct TCGContext {
     int nb_temps;
 
     /* goto_tb support */
-    uint8_t *code_buf;
+    tcg_insn_unit *code_buf;
     uintptr_t *tb_next;
     uint16_t *tb_next_offset;
     uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
@@ -478,7 +495,7 @@ struct TCGContext {
     intptr_t frame_end;
     int frame_reg;
 
-    uint8_t *code_ptr;
+    tcg_insn_unit *code_ptr;
     TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
     TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
 
@@ -517,14 +534,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_insn_unit
+       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 +579,9 @@ 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_insn_unit *gen_code_buf);
+int tcg_gen_code_search_pc(TCGContext *s, tcg_insn_unit *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..68a93c9 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_insn_unit *gen_code_buf;
     int gen_code_size;
 #ifdef CONFIG_PROFILER
     int64_t ti;
@@ -186,8 +186,8 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr
 
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
-        qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);
-        log_disas(tb->tc_ptr, *gen_code_size_ptr);
+        qemu_log("OUT: [size=%d]\n", gen_code_size);
+        log_disas(tb->tc_ptr, gen_code_size);
         qemu_log("\n");
         qemu_log_flush();
     }
@@ -235,7 +235,8 @@ 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_insn_unit *)tc_ptr,
+                               searched_pc - tc_ptr);
     if (j < 0)
         return -1;
     /* now find start of instruction before */
@@ -944,7 +945,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 {
     CPUArchState *env = cpu->env_ptr;
     TranslationBlock *tb;
-    uint8_t *tc_ptr;
     tb_page_addr_t phys_pc, phys_page2;
     target_ulong virt_page2;
     int code_gen_size;
@@ -959,8 +959,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
         /* Don't forget to invalidate previous TB info.  */
         tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
     }
-    tc_ptr = tcg_ctx.code_gen_ptr;
-    tb->tc_ptr = tc_ptr;
+    tb->tc_ptr = tcg_ctx.code_gen_ptr;
     tb->cs_base = cs_base;
     tb->flags = flags;
     tb->cflags = cflags;
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 6/9] tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (4 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 5/9] tcg: Define tcg_insn_unit for code pointers Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: " Richard Henderson
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

And use tcg pointer differencing functions as appropriate.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/i386/tcg-target.c | 48 ++++++++++++++++++++++++------------------------
 tcg/i386/tcg-target.h |  1 +
 2 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index a0f9dff..19b5d2c 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -139,9 +139,9 @@ static bool have_bmi2;
 # define have_bmi2 0
 #endif
 
-static uint8_t *tb_ret_addr;
+static tcg_insn_unit *tb_ret_addr;
 
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
     value += addend;
@@ -859,7 +859,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
     TCGLabel *l = &s->labels[label_index];
 
     if (l->has_value) {
-        val = l->u.value - (intptr_t)s->code_ptr;
+        val = tcg_pcrel_diff(s, l->u.value_ptr);
         val1 = val - 2;
         if ((int8_t)val1 == val1) {
             if (opc == -1) {
@@ -1099,26 +1099,26 @@ static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
 }
 #endif
 
-static void tcg_out_branch(TCGContext *s, int call, uintptr_t dest)
+static void tcg_out_branch(TCGContext *s, int call, tcg_insn_unit *dest)
 {
-    intptr_t disp = dest - (intptr_t)s->code_ptr - 5;
+    intptr_t disp = tcg_pcrel_diff(s, dest) - 5;
 
     if (disp == (int32_t)disp) {
         tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
         tcg_out32(s, disp);
     } else {
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, (uintptr_t)dest);
         tcg_out_modrm(s, OPC_GRP5,
                       call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
     }
 }
 
-static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
+static inline void tcg_out_calli(TCGContext *s, tcg_insn_unit *dest)
 {
     tcg_out_branch(s, 1, dest);
 }
 
-static void tcg_out_jmp(TCGContext *s, uintptr_t dest)
+static void tcg_out_jmp(TCGContext *s, tcg_insn_unit *dest)
 {
     tcg_out_branch(s, 0, dest);
 }
@@ -1127,7 +1127,7 @@ static void tcg_out_jmp(TCGContext *s, uintptr_t dest)
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_ld_helpers[16] = {
+static void * const qemu_ld_helpers[16] = {
     [MO_UB]   = helper_ret_ldub_mmu,
     [MO_LEUW] = helper_le_lduw_mmu,
     [MO_LEUL] = helper_le_ldul_mmu,
@@ -1140,7 +1140,7 @@ static const void * const qemu_ld_helpers[16] = {
 /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
  *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_st_helpers[16] = {
+static void * const qemu_st_helpers[16] = {
     [MO_UB]   = helper_ret_stb_mmu,
     [MO_LEUW] = helper_le_stw_mmu,
     [MO_LEUL] = helper_le_stl_mmu,
@@ -1173,7 +1173,7 @@ static const void * const qemu_st_helpers[16] = {
 
 static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
                                     int mem_index, TCGMemOp s_bits,
-                                    uint8_t **label_ptr, int which)
+                                    tcg_insn_unit **label_ptr, int which)
 {
     const TCGReg r0 = TCG_REG_L0;
     const TCGReg r1 = TCG_REG_L1;
@@ -1247,8 +1247,8 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
 static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOp opc,
                                 TCGReg datalo, TCGReg datahi,
                                 TCGReg addrlo, TCGReg addrhi,
-                                int mem_index, uint8_t *raddr,
-                                uint8_t **label_ptr)
+                                int mem_index, tcg_insn_unit *raddr,
+                                tcg_insn_unit **label_ptr)
 {
     TCGLabelQemuLdst *label = new_ldst_label(s);
 
@@ -1273,7 +1273,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 {
     TCGMemOp opc = l->opc;
     TCGReg data_reg;
-    uint8_t **label_ptr = &l->label_ptr[0];
+    tcg_insn_unit **label_ptr = &l->label_ptr[0];
 
     /* resolve label address */
     tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
@@ -1308,7 +1308,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
                      (uintptr_t)l->raddr);
     }
 
-    tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[opc & ~MO_SIGN]);
+    tcg_out_calli(s, qemu_ld_helpers[opc & ~MO_SIGN]);
 
     data_reg = l->datalo_reg;
     switch (opc & MO_SSIZE) {
@@ -1346,7 +1346,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     }
 
     /* Jump to the code corresponding to next IR of qemu_st */
-    tcg_out_jmp(s, (uintptr_t)l->raddr);
+    tcg_out_jmp(s, l->raddr);
 }
 
 /*
@@ -1356,7 +1356,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 {
     TCGMemOp opc = l->opc;
     TCGMemOp s_bits = opc & MO_SIZE;
-    uint8_t **label_ptr = &l->label_ptr[0];
+    tcg_insn_unit **label_ptr = &l->label_ptr[0];
     TCGReg retaddr;
 
     /* resolve label address */
@@ -1413,7 +1413,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 
     /* "Tail call" to the helper, with the return address back inline.  */
     tcg_out_push(s, retaddr);
-    tcg_out_jmp(s, (uintptr_t)qemu_st_helpers[opc]);
+    tcg_out_jmp(s, qemu_st_helpers[opc]);
 }
 #elif defined(__x86_64__) && defined(__linux__)
 # include <asm/prctl.h>
@@ -1534,7 +1534,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
 #if defined(CONFIG_SOFTMMU)
     int mem_index;
     TCGMemOp s_bits;
-    uint8_t *label_ptr[2];
+    tcg_insn_unit *label_ptr[2];
 #endif
 
     datalo = *args++;
@@ -1665,7 +1665,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
 #if defined(CONFIG_SOFTMMU)
     int mem_index;
     TCGMemOp s_bits;
-    uint8_t *label_ptr[2];
+    tcg_insn_unit *label_ptr[2];
 #endif
 
     datalo = *args++;
@@ -1731,24 +1731,24 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
     switch(opc) {
     case INDEX_op_exit_tb:
         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
-        tcg_out_jmp(s, (uintptr_t)tb_ret_addr);
+        tcg_out_jmp(s, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
         if (s->tb_jmp_offset) {
             /* direct jump method */
             tcg_out8(s, OPC_JMP_long); /* jmp im */
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             tcg_out32(s, 0);
         } else {
             /* indirect jump method */
             tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
                                  (intptr_t)(s->tb_next + args[0]));
         }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_call:
         if (const_args[0]) {
-            tcg_out_calli(s, args[0]);
+            tcg_out_calli(s, (tcg_insn_unit *)(uintptr_t)args[0]);
         } else {
             /* call *reg */
             tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index bdf2222..c7520bc 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_INSN_UNIT_SIZE  1
 
 #ifdef __x86_64__
 # define TCG_TARGET_REG_BITS  64
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (5 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 6/9] tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 21:12   ` Peter Maydell
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 8/9] tcg-ppc: " Richard Henderson
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

And use tcg pointer differencing functions as appropriate.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ppc64/tcg-target.c | 163 ++++++++++++++++++++++++-------------------------
 tcg/ppc64/tcg-target.h |   1 +
 2 files changed, 80 insertions(+), 84 deletions(-)

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 06e440f..a199a96 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -31,7 +31,7 @@
 #define TCG_CT_CONST_ZERO 0x1000
 #define TCG_CT_CONST_MONE 0x2000
 
-static uint8_t *tb_ret_addr;
+static tcg_insn_unit *tb_ret_addr;
 
 #if TARGET_LONG_BITS == 32
 #define LD_ADDR LWZ
@@ -168,61 +168,53 @@ static inline bool in_range_b(tcg_target_long target)
     return target == sextract64(target, 0, 26);
 }
 
-static uint32_t reloc_pc24_val(void *pc, tcg_target_long target)
+static uint32_t reloc_pc24_val(void *pc, tcg_insn_unit *target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long)pc;
+    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
     assert(in_range_b(disp));
-
     return disp & 0x3fffffc;
 }
 
-static void reloc_pc24(void *pc, tcg_target_long target)
+static void reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
 {
-    *(uint32_t *)pc = (*(uint32_t *)pc & ~0x3fffffc)
-        | reloc_pc24_val(pc, target);
+    *pc = (*pc & ~0x3fffffc) | reloc_pc24_val(pc, target);
 }
 
-static uint16_t reloc_pc14_val(void *pc, tcg_target_long target)
+static uint16_t reloc_pc14_val(void *pc, tcg_insn_unit *target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long)pc;
-    if (disp != (int16_t) disp) {
-        tcg_abort();
-    }
-
+    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
+    assert(disp == (int16_t) disp);
     return disp & 0xfffc;
 }
 
-static void reloc_pc14(void *pc, tcg_target_long target)
+static void reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
 {
-    *(uint32_t *)pc = (*(uint32_t *)pc & ~0xfffc) | reloc_pc14_val(pc, target);
+    *pc = (*pc & ~0xfffc) | reloc_pc14_val(pc, target);
 }
 
 static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
 {
-    unsigned retrans = *(uint32_t *)s->code_ptr & 0x3fffffc;
+    unsigned retrans = *s->code_ptr & 0x3fffffc;
     tcg_out32(s, insn | retrans);
 }
 
 static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
 {
-    unsigned retrans = *(uint32_t *)s->code_ptr & 0xfffc;
+    unsigned retrans = *s->code_ptr & 0xfffc;
     tcg_out32(s, insn | retrans);
 }
 
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
-    value += addend;
+    /* Note that we always use 0 for addend in calls to tcg_out_reloc.  */
+    tcg_insn_unit *target = (tcg_insn_unit *)value;
     switch (type) {
     case R_PPC_REL14:
-        reloc_pc14(code_ptr, value);
+        reloc_pc14(code_ptr, target);
         break;
     case R_PPC_REL24:
-        reloc_pc24(code_ptr, value);
+        reloc_pc24(code_ptr, target);
         break;
     default:
         tcg_abort();
@@ -694,62 +686,66 @@ static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
     tcg_out_zori32(s, dst, src, c, XORI, XORIS);
 }
 
-static void tcg_out_b(TCGContext *s, int mask, tcg_target_long target)
+static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long)s->code_ptr;
+    ptrdiff_t disp = tcg_pcrel_diff(s, target);
     if (in_range_b(disp)) {
         tcg_out32(s, B | (disp & 0x3fffffc) | mask);
     } else {
-        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, (tcg_target_long)target);
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, (uintptr_t)target);
         tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
         tcg_out32(s, BCCTR | BO_ALWAYS | mask);
     }
 }
 
-static void tcg_out_call(TCGContext *s, tcg_target_long arg, int const_arg)
+static void tcg_out_calli(TCGContext *s, void *target)
 {
 #ifdef __APPLE__
-    if (const_arg) {
-        tcg_out_b(s, LK, arg);
-    } else {
-        tcg_out32(s, MTSPR | RS(arg) | LR);
-        tcg_out32(s, BCLR | BO_ALWAYS | LK);
-    }
+    tcg_out_b(s, LK, target);
 #else
-    TCGReg reg = arg;
-    int ofs = 0;
-
-    if (const_arg) {
-        /* Look through the descriptor.  If the branch is in range, and we
-           don't have to spend too much effort on building the toc.  */
-        intptr_t tgt = ((intptr_t *)arg)[0];
-        intptr_t toc = ((intptr_t *)arg)[1];
-        intptr_t diff = tgt - (intptr_t)s->code_ptr;
-
-        if (in_range_b(diff) && toc == (uint32_t)toc) {
-            tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, toc);
-            tcg_out_b(s, LK, tgt);
-            return;
-        }
-
+    /* Look through the descriptor.  If the branch is in range, and we
+       don't have to spend too much effort on building the toc.  */
+    void *tgt = ((void **)target)[0];
+    uintptr_t toc = ((uintptr_t *)target)[1];
+    intptr_t diff = tcg_pcrel_diff(s, tgt);
+
+    if (in_range_b(diff) && toc == (uint32_t)toc) {
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, toc);
+        tcg_out_b(s, LK, tgt);
+    } else {
         /* Fold the low bits of the constant into the addresses below.  */
-        ofs = (int16_t)arg;
+        intptr_t arg = (intptr_t)target;
+        int ofs = (int16_t)arg;
+
         if (ofs + 8 < 0x8000) {
             arg -= ofs;
         } else {
             ofs = 0;
         }
-        reg = TCG_REG_R2;
-        tcg_out_movi(s, TCG_TYPE_I64, reg, arg);
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, arg);
+        tcg_out32(s, LD | TAI(TCG_REG_R0, TCG_REG_R2, ofs));
+        tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
+        tcg_out32(s, LD | TAI(TCG_REG_R2, TCG_REG_R2, ofs + 8));
+        tcg_out32(s, BCCTR | BO_ALWAYS | LK);
     }
+#endif
+}
 
-    tcg_out32(s, LD | TAI(TCG_REG_R0, reg, ofs));
-    tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
-    tcg_out32(s, LD | TAI(TCG_REG_R2, reg, ofs + 8));
-    tcg_out32(s, BCCTR | BO_ALWAYS | LK);
+static void tcg_out_call(TCGContext *s, TCGArg arg, int const_arg)
+{
+    if (const_arg) {
+        tcg_out_calli(s, (void *)(uintptr_t)arg);
+    } else {
+#ifdef __APPLE__
+        tcg_out32(s, MTSPR | RS(arg) | LR);
+        tcg_out32(s, BCLR | BO_ALWAYS | LK);
+#else
+        tcg_out32(s, LD | TAI(TCG_REG_R0, arg, 0));
+        tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
+        tcg_out32(s, LD | TAI(TCG_REG_R2, arg, 8));
+        tcg_out32(s, BCCTR | BO_ALWAYS | LK);
 #endif
+    }
 }
 
 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
@@ -836,7 +832,7 @@ static const uint32_t qemu_exts_opc[4] = {
 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
  *                                 int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_ld_helpers[16] = {
+static void * const qemu_ld_helpers[16] = {
     [MO_UB]   = helper_ret_ldub_mmu,
     [MO_LEUW] = helper_le_lduw_mmu,
     [MO_LEUL] = helper_le_ldul_mmu,
@@ -849,7 +845,7 @@ static const void * const qemu_ld_helpers[16] = {
 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
  *                                 uintxx_t val, int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_st_helpers[16] = {
+static void * const qemu_st_helpers[16] = {
     [MO_UB]   = helper_ret_stb_mmu,
     [MO_LEUW] = helper_le_stw_mmu,
     [MO_LEUL] = helper_le_stl_mmu,
@@ -938,7 +934,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits, TCGReg addr_reg,
    helper code.  */
 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
                                 int data_reg, int addr_reg, int mem_index,
-                                uint8_t *raddr, uint8_t *label_ptr)
+                                tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
 {
     TCGLabelQemuLdst *label = new_ldst_label(s);
 
@@ -955,7 +951,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
 {
     TCGMemOp opc = lb->opc;
 
-    reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
+    reloc_pc14(lb->label_ptr[0], s->code_ptr);
 
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0);
 
@@ -966,7 +962,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, lb->mem_index);
     tcg_out32(s, MFSPR | RT(TCG_REG_R6) | LR);
 
-    tcg_out_call(s, (tcg_target_long)qemu_ld_helpers[opc & ~MO_SIGN], 1);
+    tcg_out_calli(s, qemu_ld_helpers[opc & ~MO_SIGN]);
 
     if (opc & MO_SIGN) {
         uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
@@ -975,7 +971,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
         tcg_out_mov(s, TCG_TYPE_I64, lb->datalo_reg, TCG_REG_R3);
     }
 
-    tcg_out_b(s, 0, (uintptr_t)lb->raddr);
+    tcg_out_b(s, 0, lb->raddr);
 }
 
 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
@@ -983,7 +979,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
     TCGMemOp opc = lb->opc;
     TCGMemOp s_bits = opc & MO_SIZE;
 
-    reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
+    reloc_pc14(lb->label_ptr[0], s->code_ptr);
 
     tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, TCG_AREG0);
 
@@ -996,9 +992,9 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R6, lb->mem_index);
     tcg_out32(s, MFSPR | RT(TCG_REG_R7) | LR);
 
-    tcg_out_call(s, (tcg_target_long)qemu_st_helpers[opc], 1);
+    tcg_out_calli(s, qemu_st_helpers[opc]);
 
-    tcg_out_b(s, 0, (uintptr_t)lb->raddr);
+    tcg_out_b(s, 0, lb->raddr);
 }
 #endif /* SOFTMMU */
 
@@ -1009,7 +1005,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
     uint32_t insn;
     TCGMemOp s_bits = opc & MO_SIZE;
 #ifdef CONFIG_SOFTMMU
-    void *label_ptr;
+    tcg_insn_unit *label_ptr;
 #endif
 
 #ifdef CONFIG_SOFTMMU
@@ -1055,7 +1051,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
     TCGReg rbase;
     uint32_t insn;
 #ifdef CONFIG_SOFTMMU
-    void *label_ptr;
+    tcg_insn_unit *label_ptr;
 #endif
 
 #ifdef CONFIG_SOFTMMU
@@ -1115,7 +1111,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 #ifndef __APPLE__
     /* First emit adhoc function descriptor */
     tcg_out64(s, (uint64_t)s->code_ptr + 24); /* entry point */
-    s->code_ptr += 16;          /* skip TOC and environment pointer */
+    tcg_out64(s, 0);                          /* toc */
+    tcg_out64(s, 0);                          /* environment pointer */
 #endif
 
     /* Prologue */
@@ -1407,7 +1404,7 @@ static void tcg_out_bc(TCGContext *s, int bc, int label_index)
     TCGLabel *l = &s->labels[label_index];
 
     if (l->has_value) {
-        tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value));
+        tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
     } else {
         tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
         tcg_out_bc_noaddr(s, bc);
@@ -1470,15 +1467,13 @@ static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
     }
 }
 
-void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr)
+void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
 {
     TCGContext s;
-    unsigned long patch_size;
 
-    s.code_ptr = (uint8_t *) jmp_addr;
-    tcg_out_b(&s, 0, addr);
-    patch_size = s.code_ptr - (uint8_t *) jmp_addr;
-    flush_icache_range(jmp_addr, jmp_addr + patch_size);
+    s.code_buf = s.code_ptr = (tcg_insn_unit *)jmp_addr;
+    tcg_out_b(&s, 0, (tcg_insn_unit *)addr);
+    flush_icache_range(jmp_addr, jmp_addr + tcg_current_code_size(&s));
 }
 
 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
@@ -1490,25 +1485,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     switch (opc) {
     case INDEX_op_exit_tb:
         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
-        tcg_out_b(s, 0, (tcg_target_long)tb_ret_addr);
+        tcg_out_b(s, 0, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
         if (s->tb_jmp_offset) {
             /* Direct jump method.  */
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            s->code_ptr += 28;
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
+            s->code_ptr += 7;
         } else {
             /* Indirect jump method.  */
             tcg_abort();
         }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         {
             TCGLabel *l = &s->labels[args[0]];
 
             if (l->has_value) {
-                tcg_out_b(s, 0, l->u.value);
+                tcg_out_b(s, 0, l->u.value_ptr);
             } else {
                 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
                 tcg_out_b_noaddr(s, B);
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 7ee50b6..0f6cadb 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -26,6 +26,7 @@
 
 #define TCG_TARGET_WORDS_BIGENDIAN
 #define TCG_TARGET_NB_REGS 32
+#define TCG_TARGET_INSN_UNIT_SIZE 4
 
 typedef enum {
     TCG_REG_R0 = 0,
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 8/9] tcg-ppc: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (6 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: " Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 9/9] tcg-sparc: " Richard Henderson
  2014-04-01 21:15 ` [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Peter Maydell
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

And use tcg pointer differencing functions as appropriate.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ppc/tcg-target.c | 194 ++++++++++++++++++++++++---------------------------
 tcg/ppc/tcg-target.h |   1 +
 2 files changed, 93 insertions(+), 102 deletions(-)

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index dc2c2df..7d5a9c6 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -24,7 +24,7 @@
 
 #include "tcg-be-ldst.h"
 
-static uint8_t *tb_ret_addr;
+static tcg_insn_unit *tb_ret_addr;
 
 #if defined _CALL_DARWIN || defined __APPLE__
 #define TCG_TARGET_CALL_DARWIN
@@ -171,50 +171,46 @@ static const int tcg_target_callee_save_regs[] = {
     TCG_REG_R31
 };
 
-static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
+static inline bool in_range_b(tcg_target_long target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if ((disp << 6) >> 6 != disp)
-        tcg_abort ();
+    return target == sextract32(target, 0, 26);
+}
 
+static uint32_t reloc_pc24_val(void *pc, tcg_insn_unit *target)
+{
+    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
+    assert(in_range_b(disp));
     return disp & 0x3fffffc;
 }
 
-static void reloc_pc24 (void *pc, tcg_target_long target)
+static void reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
 {
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
-        | reloc_pc24_val (pc, target);
+    *pc = (*pc & ~0x3fffffc) | reloc_pc24_val(pc, target);
 }
 
-static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
+static uint16_t reloc_pc14_val(void *pc, tcg_insn_unit *target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) pc;
-    if (disp != (int16_t) disp)
-        tcg_abort ();
-
+    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
+    assert(disp == (int16_t) disp);
     return disp & 0xfffc;
 }
 
-static void reloc_pc14 (void *pc, tcg_target_long target)
+static void reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
 {
-    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
-        | reloc_pc14_val (pc, target);
+    *pc = (*pc & ~0xfffc) | reloc_pc14_val(pc, target);
 }
 
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
-    value += addend;
+    /* Note that we always use 0 for addend in calls to tcg_out_reloc.  */
+    tcg_insn_unit *target = (tcg_insn_unit *)value;
     switch (type) {
     case R_PPC_REL14:
-        reloc_pc14 (code_ptr, value);
+        reloc_pc14(code_ptr, target);
         break;
     case R_PPC_REL24:
-        reloc_pc24 (code_ptr, value);
+        reloc_pc24(code_ptr, target);
         break;
     default:
         tcg_abort();
@@ -480,44 +476,37 @@ static void tcg_out_ldst (TCGContext *s, int ret, int addr,
     }
 }
 
-static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
+static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
 {
-    tcg_target_long disp;
-
-    disp = target - (tcg_target_long) s->code_ptr;
-    if ((disp << 6) >> 6 == disp)
-        tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
-    else {
-        tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
-        tcg_out32 (s, MTSPR | RS (0) | CTR);
-        tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
+    ptrdiff_t disp = tcg_pcrel_diff(s, target);
+    if (in_range_b(disp)) {
+        tcg_out32(s, B | (disp & 0x3fffffc) | mask);
+    } else {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
+        tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
+        tcg_out32(s, BCCTR | BO_ALWAYS | mask);
     }
 }
 
-static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg,
-                          int lk)
+static void tcg_out_callr(TCGContext *s, TCGReg reg, int lk)
 {
 #ifdef _CALL_AIX
-    int reg;
-
-    if (const_arg) {
-        reg = 2;
-        tcg_out_movi (s, TCG_TYPE_I32, reg, arg);
-    }
-    else reg = arg;
+    tcg_out32(s, LWZ | RT(TCG_REG_R0) | RA(reg));
+    tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
+    tcg_out32(s, LWZ | RT(TCG_REG_R2) | RA(reg) | 4);
+#else
+    tcg_out32(s, MTSPR | RS(reg) | CTR);
+#endif
+    tcg_out32(s, BCCTR | BO_ALWAYS | lk);
+}
 
-    tcg_out32 (s, LWZ | RT (0) | RA (reg));
-    tcg_out32 (s, MTSPR | RA (0) | CTR);
-    tcg_out32 (s, LWZ | RT (2) | RA (reg) | 4);
-    tcg_out32 (s, BCCTR | BO_ALWAYS | lk);
+static void tcg_out_calli(TCGContext *s, void *target, int lk)
+{
+#ifdef _CALL_AIX
+    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, (uintptr_t)target);
+    tcg_out_callr(s, TCG_REG_R2, lk);
 #else
-    if (const_arg) {
-        tcg_out_b (s, lk, arg);
-    }
-    else {
-        tcg_out32 (s, MTSPR | RS (arg) | LR);
-        tcg_out32 (s, BCLR | BO_ALWAYS | lk);
-    }
+    tcg_out_b(s, lk, target);
 #endif
 }
 
@@ -531,8 +520,8 @@ static void add_qemu_ldst_label (TCGContext *s,
                                  int addrlo_reg,
                                  int addrhi_reg,
                                  int mem_index,
-                                 uint8_t *raddr,
-                                 uint8_t *label_ptr)
+                                 tcg_insn_unit *raddr,
+                                 tcg_insn_unit *label_ptr)
 {
     TCGLabelQemuLdst *label = new_ldst_label(s);
 
@@ -550,7 +539,7 @@ static void add_qemu_ldst_label (TCGContext *s,
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_ld_helpers[16] = {
+static void * const qemu_ld_helpers[16] = {
     [MO_UB]   = helper_ret_ldub_mmu,
     [MO_LEUW] = helper_le_lduw_mmu,
     [MO_LEUL] = helper_le_ldul_mmu,
@@ -563,7 +552,7 @@ static const void * const qemu_ld_helpers[16] = {
 /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
  *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
  */
-static const void * const qemu_st_helpers[16] = {
+static void * const qemu_st_helpers[16] = {
     [MO_UB]   = helper_ret_stb_mmu,
     [MO_LEUW] = helper_le_stw_mmu,
     [MO_LEUL] = helper_le_stl_mmu,
@@ -573,8 +562,8 @@ static const void * const qemu_st_helpers[16] = {
     [MO_BEQ]  = helper_be_stq_mmu,
 };
 
-static void *ld_trampolines[16];
-static void *st_trampolines[16];
+static tcg_insn_unit *ld_trampolines[16];
+static tcg_insn_unit *st_trampolines[16];
 
 /* Perform the TLB load and compare.  Branches to the slow path, placing the
    address of the branch in *LABEL_PTR.  Loads the addend of the TLB into R0.
@@ -582,14 +571,15 @@ static void *st_trampolines[16];
 
 static void tcg_out_tlb_check(TCGContext *s, TCGReg r0, TCGReg r1, TCGReg r2,
                               TCGReg addrlo, TCGReg addrhi, TCGMemOp s_bits,
-                              int mem_index, int is_load, uint8_t **label_ptr)
+                              int mem_index, int is_load,
+                              tcg_insn_unit **label_ptr)
 {
     int cmp_off =
         (is_load
          ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
          : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
-    uint16_t retranst;
+    tcg_insn_unit retranst;
     TCGReg base = TCG_AREG0;
 
     /* Extract the page index, shifted into place for tlb index.  */
@@ -648,7 +638,7 @@ static void tcg_out_tlb_check(TCGContext *s, TCGReg r0, TCGReg r1, TCGReg r2,
        This address cannot be used for a tail call, but it's shorter
        than forming an address from scratch.  */
     *label_ptr = s->code_ptr;
-    retranst = ((uint16_t *) s->code_ptr)[1] & ~3;
+    retranst = *s->code_ptr & 0xfffc;
     tcg_out32(s, BC | BI(7, CR_EQ) | retranst | BO_COND_FALSE | LK);
 }
 #endif
@@ -659,7 +649,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
     TCGMemOp opc, bswap;
 #ifdef CONFIG_SOFTMMU
     int mem_index;
-    uint8_t *label_ptr;
+    tcg_insn_unit *label_ptr;
 #endif
 
     datalo = *args++;
@@ -731,7 +721,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
     TCGMemOp opc, bswap, s_bits;
 #ifdef CONFIG_SOFTMMU
     int mem_index;
-    uint8_t *label_ptr;
+    tcg_insn_unit *label_ptr;
 #endif
 
     datalo = *args++;
@@ -790,7 +780,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     TCGReg ir, datalo, datahi;
     TCGMemOp opc = l->opc;
 
-    reloc_pc14 (l->label_ptr[0], (uintptr_t)s->code_ptr);
+    reloc_pc14(l->label_ptr[0], s->code_ptr);
 
     ir = TCG_REG_R4;
     if (TARGET_LONG_BITS == 32) {
@@ -804,7 +794,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     }
     tcg_out_movi(s, TCG_TYPE_I32, ir++, l->mem_index);
     tcg_out32(s, MFSPR | RT(ir++) | LR);
-    tcg_out_b(s, LK, (uintptr_t)ld_trampolines[opc & ~MO_SIGN]);
+    tcg_out_b(s, LK, ld_trampolines[opc & ~MO_SIGN]);
 
     datalo = l->datalo_reg;
     switch (opc & MO_SSIZE) {
@@ -832,7 +822,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         }
         break;
     }
-    tcg_out_b (s, 0, (uintptr_t)l->raddr);
+    tcg_out_b(s, 0, l->raddr);
 }
 
 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
@@ -840,7 +830,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     TCGReg ir, datalo;
     TCGMemOp opc = l->opc;
 
-    reloc_pc14 (l->label_ptr[0], (tcg_target_long) s->code_ptr);
+    reloc_pc14(l->label_ptr[0], s->code_ptr);
 
     ir = TCG_REG_R4;
     if (TARGET_LONG_BITS == 32) {
@@ -878,16 +868,16 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 
     tcg_out_movi(s, TCG_TYPE_I32, ir++, l->mem_index);
     tcg_out32(s, MFSPR | RT(ir++) | LR);
-    tcg_out_b(s, LK, (uintptr_t)st_trampolines[opc]);
-    tcg_out_b(s, 0, (uintptr_t)l->raddr);
+    tcg_out_b(s, LK, st_trampolines[opc]);
+    tcg_out_b(s, 0, l->raddr);
 }
 #endif
 
 #ifdef CONFIG_SOFTMMU
-static void emit_ldst_trampoline (TCGContext *s, const void *ptr)
+static void emit_ldst_trampoline(TCGContext *s, void *ptr)
 {
-    tcg_out_mov (s, TCG_TYPE_I32, 3, TCG_AREG0);
-    tcg_out_call (s, (tcg_target_long) ptr, 1, 0);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0);
+    tcg_out_calli(s, ptr, 0);
 }
 #endif
 
@@ -909,12 +899,13 @@ static void tcg_target_qemu_prologue (TCGContext *s)
 
 #ifdef _CALL_AIX
     {
-        uint32_t addr;
+        uintptr_t addr;
 
         /* First emit adhoc function descriptor */
-        addr = (uint32_t) s->code_ptr + 12;
-        tcg_out32 (s, addr);        /* entry point */
-        s->code_ptr += 8;           /* skip TOC and environment pointer */
+        addr = (uintptr_t)s->code_ptr + 12;
+        tcg_out32(s, addr);        /* entry point */
+        tcg_out32(s, 0);           /* toc */
+        tcg_out32(s, 0);           /* environment pointer */
     }
 #endif
     tcg_out32 (s, MFSPR | RT (0) | LR);
@@ -1065,18 +1056,17 @@ static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
 
 }
 
-static void tcg_out_bc (TCGContext *s, int bc, int label_index)
+static void tcg_out_bc(TCGContext *s, int bc, int label_index)
 {
     TCGLabel *l = &s->labels[label_index];
 
-    if (l->has_value)
-        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
-    else {
-        uint16_t val = *(uint16_t *) &s->code_ptr[2];
-
+    if (l->has_value) {
+        tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
+    } else {
         /* Thanks to Andrzej Zaborowski */
-        tcg_out32 (s, bc | (val & 0xfffc));
-        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
+        tcg_insn_unit retrans = *s->code_ptr & 0xfffc;
+        tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
+        tcg_out32(s, bc | retrans);
     }
 }
 
@@ -1367,39 +1357,39 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
 {
     switch (opc) {
     case INDEX_op_exit_tb:
-        tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
-        tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
+        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
+        tcg_out_b(s, 0, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
         if (s->tb_jmp_offset) {
             /* direct jump method */
-
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-            s->code_ptr += 16;
-        }
-        else {
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
+            s->code_ptr += 4;
+        } else {
             tcg_abort ();
         }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         {
             TCGLabel *l = &s->labels[args[0]];
 
             if (l->has_value) {
-                tcg_out_b (s, 0, l->u.value);
-            }
-            else {
-                uint32_t val = *(uint32_t *) s->code_ptr;
-
+                tcg_out_b(s, 0, l->u.value_ptr);
+            } else {
                 /* Thanks to Andrzej Zaborowski */
-                tcg_out32 (s, B | (val & 0x3fffffc));
-                tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
+                tcg_insn_unit retrans = *s->code_ptr & 0x3fffffc;
+                tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
+                tcg_out32(s, B | retrans);
             }
         }
         break;
     case INDEX_op_call:
-        tcg_out_call (s, args[0], const_args[0], LK);
+        if (const_args[0]) {
+            tcg_out_calli(s, (void *)(uintptr_t)args[0], LK);
+        } else {
+            tcg_out_callr(s, args[0], LK);
+        }
         break;
     case INDEX_op_movi_i32:
         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index e3395e3..a3e53ff 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -26,6 +26,7 @@
 
 #define TCG_TARGET_WORDS_BIGENDIAN
 #define TCG_TARGET_NB_REGS 32
+#define TCG_TARGET_INSN_UNIT_SIZE 4
 
 typedef enum {
     TCG_REG_R0 = 0,
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 9/9] tcg-sparc: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (7 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 8/9] tcg-ppc: " Richard Henderson
@ 2014-04-01 20:53 ` Richard Henderson
  2014-04-01 21:15 ` [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Peter Maydell
  9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

And use tcg pointer differencing functions as appropriate.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/sparc/tcg-target.c | 138 ++++++++++++++++++++++---------------------------
 tcg/sparc/tcg-target.h |   2 +-
 2 files changed, 64 insertions(+), 76 deletions(-)

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 152335c..d4c97e1 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -253,37 +253,32 @@ static inline int check_fit_i32(uint32_t val, unsigned int bits)
     return ((val << (32 - bits)) >> (32 - bits)) == val;
 }
 
-static void patch_reloc(uint8_t *code_ptr, int type,
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
     uint32_t insn;
-    value += addend;
+
+    /* Note that we always use 0 for addend in calls to tcg_out_reloc.  */
+    value = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
+
     switch (type) {
-    case R_SPARC_32:
-        if (value != (uint32_t)value) {
-            tcg_abort();
-        }
-        *(uint32_t *)code_ptr = value;
-        break;
     case R_SPARC_WDISP16:
-        value -= (intptr_t)code_ptr;
         if (!check_fit_tl(value >> 2, 16)) {
             tcg_abort();
         }
-        insn = *(uint32_t *)code_ptr;
+        insn = *code_ptr;
         insn &= ~INSN_OFF16(-1);
         insn |= INSN_OFF16(value);
-        *(uint32_t *)code_ptr = insn;
+        *code_ptr = insn;
         break;
     case R_SPARC_WDISP19:
-        value -= (intptr_t)code_ptr;
         if (!check_fit_tl(value >> 2, 19)) {
             tcg_abort();
         }
-        insn = *(uint32_t *)code_ptr;
+        insn = *code_ptr;
         insn &= ~INSN_OFF19(-1);
         insn |= INSN_OFF19(value);
-        *(uint32_t *)code_ptr = insn;
+        *code_ptr = insn;
         break;
     default:
         tcg_abort();
@@ -544,10 +539,10 @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, int label)
     int off19;
 
     if (l->has_value) {
-        off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
+        off19 = INSN_OFF19(tcg_pcrel_diff(s, l->u.value_ptr));
     } else {
         /* Make sure to preserve destinations during retranslation.  */
-        off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
+        off19 = *s->code_ptr & INSN_OFF19(-1);
         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label, 0);
     }
     tcg_out_bpcc0(s, scond, flags, off19);
@@ -592,10 +587,10 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
         int off16;
 
         if (l->has_value) {
-            off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr);
+            off16 = INSN_OFF16(tcg_pcrel_diff(s, l->u.value_ptr));
         } else {
             /* Make sure to preserve destinations during retranslation.  */
-            off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1);
+            off16 = *s->code_ptr & INSN_OFF16(-1);
             tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0);
         }
         tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
@@ -794,62 +789,60 @@ static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
     tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
 }
 
-static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
+static inline void tcg_out_calli(TCGContext *s, void *dest)
 {
-    intptr_t disp = dest - (uintptr_t)s->code_ptr;
+    ptrdiff_t disp = tcg_pcrel_diff(s, dest);
 
     if (disp == (int32_t)disp) {
         tcg_out32(s, CALL | (uint32_t)disp >> 2);
     } else {
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, dest & ~0xfff);
-        tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, dest & 0xfff, JMPL);
+        uintptr_t desti = (uintptr_t)dest;
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, desti & ~0xfff);
+        tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, desti & 0xfff, JMPL);
     }
 }
 
 #ifdef CONFIG_SOFTMMU
-static uintptr_t qemu_ld_trampoline[16];
-static uintptr_t qemu_st_trampoline[16];
+static tcg_insn_unit *qemu_ld_trampoline[16];
+static tcg_insn_unit *qemu_st_trampoline[16];
 
 static void build_trampolines(TCGContext *s)
 {
-    static uintptr_t const qemu_ld_helpers[16] = {
-        [MO_UB]   = (uintptr_t)helper_ret_ldub_mmu,
-        [MO_SB]   = (uintptr_t)helper_ret_ldsb_mmu,
-        [MO_LEUW] = (uintptr_t)helper_le_lduw_mmu,
-        [MO_LESW] = (uintptr_t)helper_le_ldsw_mmu,
-        [MO_LEUL] = (uintptr_t)helper_le_ldul_mmu,
-        [MO_LEQ]  = (uintptr_t)helper_le_ldq_mmu,
-        [MO_BEUW] = (uintptr_t)helper_be_lduw_mmu,
-        [MO_BESW] = (uintptr_t)helper_be_ldsw_mmu,
-        [MO_BEUL] = (uintptr_t)helper_be_ldul_mmu,
-        [MO_BEQ]  = (uintptr_t)helper_be_ldq_mmu,
+    static void * const qemu_ld_helpers[16] = {
+        [MO_UB]   = helper_ret_ldub_mmu,
+        [MO_SB]   = helper_ret_ldsb_mmu,
+        [MO_LEUW] = helper_le_lduw_mmu,
+        [MO_LESW] = helper_le_ldsw_mmu,
+        [MO_LEUL] = helper_le_ldul_mmu,
+        [MO_LEQ]  = helper_le_ldq_mmu,
+        [MO_BEUW] = helper_be_lduw_mmu,
+        [MO_BESW] = helper_be_ldsw_mmu,
+        [MO_BEUL] = helper_be_ldul_mmu,
+        [MO_BEQ]  = helper_be_ldq_mmu,
     };
-    static uintptr_t const qemu_st_helpers[16] = {
-        [MO_UB]   = (uintptr_t)helper_ret_stb_mmu,
-        [MO_LEUW] = (uintptr_t)helper_le_stw_mmu,
-        [MO_LEUL] = (uintptr_t)helper_le_stl_mmu,
-        [MO_LEQ]  = (uintptr_t)helper_le_stq_mmu,
-        [MO_BEUW] = (uintptr_t)helper_be_stw_mmu,
-        [MO_BEUL] = (uintptr_t)helper_be_stl_mmu,
-        [MO_BEQ]  = (uintptr_t)helper_be_stq_mmu,
+    static void * const qemu_st_helpers[16] = {
+        [MO_UB]   = helper_ret_stb_mmu,
+        [MO_LEUW] = helper_le_stw_mmu,
+        [MO_LEUL] = helper_le_stl_mmu,
+        [MO_LEQ]  = helper_le_stq_mmu,
+        [MO_BEUW] = helper_be_stw_mmu,
+        [MO_BEUL] = helper_be_stl_mmu,
+        [MO_BEQ]  = helper_be_stq_mmu,
     };
 
     int i;
     TCGReg ra;
-    uintptr_t tramp;
 
     for (i = 0; i < 16; ++i) {
-        if (qemu_ld_helpers[i] == 0) {
+        if (qemu_ld_helpers[i] == NULL) {
             continue;
         }
 
         /* May as well align the trampoline.  */
-        tramp = (uintptr_t)s->code_ptr;
-        while (tramp & 15) {
+        while ((uintptr_t)s->code_ptr & 15) {
             tcg_out_nop(s);
-            tramp += 4;
         }
-        qemu_ld_trampoline[i] = tramp;
+        qemu_ld_trampoline[i] = s->code_ptr;
 
         /* Find the retaddr argument register.  */
         ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
@@ -864,17 +857,15 @@ static void build_trampolines(TCGContext *s)
     }
 
     for (i = 0; i < 16; ++i) {
-        if (qemu_st_helpers[i] == 0) {
+        if (qemu_st_helpers[i] == NULL) {
             continue;
         }
 
         /* May as well align the trampoline.  */
-        tramp = (uintptr_t)s->code_ptr;
-        while (tramp & 15) {
+        while ((uintptr_t)s->code_ptr & 15) {
             tcg_out_nop(s);
-            tramp += 4;
         }
-        qemu_st_trampoline[i] = tramp;
+        qemu_st_trampoline[i] = s->code_ptr;
 
         /* Find the retaddr argument.  For 32-bit, this may be past the
            last argument register, and need passing on the stack.  */
@@ -1044,9 +1035,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
     TCGMemOp memop, s_bits;
 #if defined(CONFIG_SOFTMMU)
     TCGReg addrz, param;
-    uintptr_t func;
+    void *func;
     int memi;
-    uint32_t *label_ptr[2];
+    tcg_insn_unit *label_ptr[2];
 #endif
 
     datalo = *args++;
@@ -1065,7 +1056,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
         int reg64;
 
         /* bne,pn %[xi]cc, label0 */
-        label_ptr[0] = (uint32_t *)s->code_ptr;
+        label_ptr[0] = s->code_ptr;
         tcg_out_bpcc0(s, COND_NE, BPCC_PN
                       | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
         tcg_out_nop(s);
@@ -1082,7 +1073,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
         }
 
         /* b,a,pt label1 */
-        label_ptr[1] = (uint32_t *)s->code_ptr;
+        label_ptr[1] = s->code_ptr;
         tcg_out_bpcc0(s, COND_A, BPCC_A | BPCC_PT, 0);
     } else {
         /* The fast path is exactly one insn.  Thus we can perform the
@@ -1091,7 +1082,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
 
         /* beq,a,pt %[xi]cc, label0 */
         label_ptr[0] = NULL;
-        label_ptr[1] = (uint32_t *)s->code_ptr;
+        label_ptr[1] = s->code_ptr;
         tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                       | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
         /* delay slot */
@@ -1101,8 +1092,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
     /* TLB Miss.  */
 
     if (label_ptr[0]) {
-        *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
-                                    (unsigned long)label_ptr[0]);
+        ptrdiff_t disp = tcg_ptr_byte_diff(s->code_ptr, label_ptr[0]);
+        *label_ptr[0] |= INSN_OFF19(disp);
     }
 
     param = TCG_REG_O1;
@@ -1118,7 +1109,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
     } else {
         func = qemu_ld_trampoline[memop];
     }
-    assert(func != 0);
+    assert(func != NULL);
     tcg_out_calli(s, func);
     /* delay slot */
     tcg_out_movi(s, TCG_TYPE_I32, param, memi);
@@ -1140,8 +1131,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
         break;
     }
 
-    *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
-                                (unsigned long)label_ptr[1]);
+    *label_ptr[1] |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr[1]));
 #else
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
         tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
@@ -1172,9 +1162,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
     TCGMemOp memop, s_bits;
 #if defined(CONFIG_SOFTMMU)
     TCGReg addrz, datafull, param;
-    uintptr_t func;
+    void *func;
     int memi;
-    uint32_t *label_ptr;
+    tcg_insn_unit *label_ptr;
 #endif
 
     datalo = *args++;
@@ -1201,7 +1191,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
     /* The fast path is exactly one insn.  Thus we can perform the entire
        TLB Hit in the (annulled) delay slot of the branch over TLB Miss.  */
     /* beq,a,pt %[xi]cc, label0 */
-    label_ptr = (uint32_t *)s->code_ptr;
+    label_ptr = s->code_ptr;
     tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                   | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
     /* delay slot */
@@ -1220,13 +1210,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
     tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
 
     func = qemu_st_trampoline[memop];
-    assert(func != 0);
+    assert(func != NULL);
     tcg_out_calli(s, func);
     /* delay slot */
     tcg_out_movi(s, TCG_TYPE_REG, param, memi);
 
-    *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
-                             (unsigned long)label_ptr);
+    *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
 #else
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
         tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
@@ -1259,21 +1248,20 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     case INDEX_op_goto_tb:
         if (s->tb_jmp_offset) {
             /* direct jump method */
-            uint32_t old_insn = *(uint32_t *)s->code_ptr;
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             /* Make sure to preserve links during retranslation.  */
-            tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
+            tcg_out32(s, CALL | (*s->code_ptr & ~INSN_OP(-1)));
         } else {
             /* indirect jump method */
             tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
         }
         tcg_out_nop(s);
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_call:
         if (const_args[0]) {
-            tcg_out_calli(s, args[0]);
+            tcg_out_calli(s, (void *)(uintptr_t)args[0]);
         } else {
             tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
         }
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 3abf1b4..da5a0ef 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -33,7 +33,7 @@
 #endif
 
 #define TCG_TARGET_WORDS_BIGENDIAN
-
+#define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_NB_REGS 32
 
 typedef enum {
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: " Richard Henderson
@ 2014-04-01 21:12   ` Peter Maydell
  2014-04-01 21:31     ` Richard Henderson
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2014-04-01 21:12 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On 1 April 2014 21:53, Richard Henderson <rth@twiddle.net> wrote:
> And use tcg pointer differencing functions as appropriate.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>

Few minor nits and queries below.

> ---
>  tcg/ppc64/tcg-target.c | 163 ++++++++++++++++++++++++-------------------------
>  tcg/ppc64/tcg-target.h |   1 +
>  2 files changed, 80 insertions(+), 84 deletions(-)
>
> diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
> index 06e440f..a199a96 100644
> --- a/tcg/ppc64/tcg-target.c
> +++ b/tcg/ppc64/tcg-target.c
> @@ -31,7 +31,7 @@
>  #define TCG_CT_CONST_ZERO 0x1000
>  #define TCG_CT_CONST_MONE 0x2000
>
> -static uint8_t *tb_ret_addr;
> +static tcg_insn_unit *tb_ret_addr;
>
>  #if TARGET_LONG_BITS == 32
>  #define LD_ADDR LWZ
> @@ -168,61 +168,53 @@ static inline bool in_range_b(tcg_target_long target)
>      return target == sextract64(target, 0, 26);
>  }
>
> -static uint32_t reloc_pc24_val(void *pc, tcg_target_long target)
> +static uint32_t reloc_pc24_val(void *pc, tcg_insn_unit *target)
>  {
> -    tcg_target_long disp;
> -
> -    disp = target - (tcg_target_long)pc;
> +    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
>      assert(in_range_b(disp));
> -
>      return disp & 0x3fffffc;
>  }
>
> -static void reloc_pc24(void *pc, tcg_target_long target)
> +static void reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
>  {
> -    *(uint32_t *)pc = (*(uint32_t *)pc & ~0x3fffffc)
> -        | reloc_pc24_val(pc, target);
> +    *pc = (*pc & ~0x3fffffc) | reloc_pc24_val(pc, target);
>  }
>
> -static uint16_t reloc_pc14_val(void *pc, tcg_target_long target)
> +static uint16_t reloc_pc14_val(void *pc, tcg_insn_unit *target)

Should be tcg_insn_unit *pc like the others I guess?

>  {
> -    tcg_target_long disp;
> -
> -    disp = target - (tcg_target_long)pc;
> -    if (disp != (int16_t) disp) {
> -        tcg_abort();
> -    }
> -
> +    ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
> +    assert(disp == (int16_t) disp);
>      return disp & 0xfffc;
>  }
>
> -static void reloc_pc14(void *pc, tcg_target_long target)
> +static void reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
>  {
> -    *(uint32_t *)pc = (*(uint32_t *)pc & ~0xfffc) | reloc_pc14_val(pc, target);
> +    *pc = (*pc & ~0xfffc) | reloc_pc14_val(pc, target);
>  }
>
>  static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
>  {
> -    unsigned retrans = *(uint32_t *)s->code_ptr & 0x3fffffc;
> +    unsigned retrans = *s->code_ptr & 0x3fffffc;
>      tcg_out32(s, insn | retrans);
>  }
>
>  static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
>  {
> -    unsigned retrans = *(uint32_t *)s->code_ptr & 0xfffc;
> +    unsigned retrans = *s->code_ptr & 0xfffc;
>      tcg_out32(s, insn | retrans);
>  }
>
> -static void patch_reloc(uint8_t *code_ptr, int type,
> +static void patch_reloc(tcg_insn_unit *code_ptr, int type,
>                          intptr_t value, intptr_t addend)
>  {
> -    value += addend;
> +    /* Note that we always use 0 for addend in calls to tcg_out_reloc.  */

Is this comment saying "assert(addend == 0)" ?

> +    tcg_insn_unit *target = (tcg_insn_unit *)value;
>      switch (type) {
>      case R_PPC_REL14:
> -        reloc_pc14(code_ptr, value);
> +        reloc_pc14(code_ptr, target);
>          break;
>      case R_PPC_REL24:
> -        reloc_pc24(code_ptr, value);
> +        reloc_pc24(code_ptr, target);
>          break;
>      default:
>          tcg_abort();

> @@ -836,7 +832,7 @@ static const uint32_t qemu_exts_opc[4] = {
>  /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
>   *                                 int mmu_idx, uintptr_t ra)
>   */
> -static const void * const qemu_ld_helpers[16] = {
> +static void * const qemu_ld_helpers[16] = {
>      [MO_UB]   = helper_ret_ldub_mmu,
>      [MO_LEUW] = helper_le_lduw_mmu,
>      [MO_LEUL] = helper_le_ldul_mmu,
> @@ -849,7 +845,7 @@ static const void * const qemu_ld_helpers[16] = {
>  /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
>   *                                 uintxx_t val, int mmu_idx, uintptr_t ra)
>   */
> -static const void * const qemu_st_helpers[16] = {
> +static void * const qemu_st_helpers[16] = {

Why do we lose the extra 'const' here?

> @@ -1115,7 +1111,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
>  #ifndef __APPLE__
>      /* First emit adhoc function descriptor */
>      tcg_out64(s, (uint64_t)s->code_ptr + 24); /* entry point */
> -    s->code_ptr += 16;          /* skip TOC and environment pointer */
> +    tcg_out64(s, 0);                          /* toc */
> +    tcg_out64(s, 0);                          /* environment pointer */

This is a behaviour change, right? Is it a bugfix or just a "doesn't
matter if we write zeros here or not" thing?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr
  2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
                   ` (8 preceding siblings ...)
  2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 9/9] tcg-sparc: " Richard Henderson
@ 2014-04-01 21:15 ` Peter Maydell
  9 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2014-04-01 21:15 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On 1 April 2014 21:53, Richard Henderson <rth@twiddle.net> wrote:
> Here's a second revision, attempting to take Peter's review on board.
>
> In particular, inlines to hide some of the pointer differencing issues.
> I also chose a different name for the type: tcg_insn_unit as suggested
> by Jay Foad.

I had a few nitpicks on the ppc patches but otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: Define TCG_TARGET_INSN_UNIT_SIZE
  2014-04-01 21:12   ` Peter Maydell
@ 2014-04-01 21:31     ` Richard Henderson
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2014-04-01 21:31 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 04/01/2014 02:12 PM, Peter Maydell wrote:
>> -static uint16_t reloc_pc14_val(void *pc, tcg_target_long target)
>> +static uint16_t reloc_pc14_val(void *pc, tcg_insn_unit *target)
> 
> Should be tcg_insn_unit *pc like the others I guess?

Yep.

>> -    value += addend;
>> +    /* Note that we always use 0 for addend in calls to tcg_out_reloc.  */
> 
> Is this comment saying "assert(addend == 0)" ?
> 
>> +    tcg_insn_unit *target = (tcg_insn_unit *)value;

Err.. sure.

I sort of had in mind to eventually change the type of "value" to
tcg_insn_unit* and eliminate "addend".  But that's an interface change that has
to happen all at once, and that'll be easier after this set of changes is
complete across all targets.

>> -static const void * const qemu_st_helpers[16] = {
>> +static void * const qemu_st_helpers[16] = {
> 
> Why do we lose the extra 'const' here?

We'd have to carry the const all the way through all of the relocation and
pointer differencing functions.  It didn't seem worth it.

>>  #ifndef __APPLE__
>>      /* First emit adhoc function descriptor */
>>      tcg_out64(s, (uint64_t)s->code_ptr + 24); /* entry point */
>> -    s->code_ptr += 16;          /* skip TOC and environment pointer */
>> +    tcg_out64(s, 0);                          /* toc */
>> +    tcg_out64(s, 0);                          /* environment pointer */
> 
> This is a behaviour change, right? Is it a bugfix or just a "doesn't
> matter if we write zeros here or not" thing?

The later.  It seemed better to just write zeros than do "+= 2".


r~

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-04-01 21:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-01 20:53 [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 1/9] exec-all.h: Use stl_p to avoid undefined behaviour patching x86 jumps Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 2/9] tcg: Avoid stores to unaligned addresses Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 3/9] tcg: Avoid undefined behaviour patching code at " Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 4/9] tcg: Introduce byte pointer arithmetic helpers Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 5/9] tcg: Define tcg_insn_unit for code pointers Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 6/9] tcg-i386: Define TCG_TARGET_INSN_UNIT_SIZE Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 7/9] tcg-ppc64: " Richard Henderson
2014-04-01 21:12   ` Peter Maydell
2014-04-01 21:31     ` Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 8/9] tcg-ppc: " Richard Henderson
2014-04-01 20:53 ` [Qemu-devel] [PATCH v2 9/9] tcg-sparc: " Richard Henderson
2014-04-01 21:15 ` [Qemu-devel] [PATCH v2 0/9] tcg: tidy the type of code_ptr Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.