[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 02/14] tcg: Define actual structures for TCGv_*
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [RFC 02/14] tcg: Define actual structures for TCGv_* |
Date: |
Wed, 16 Nov 2016 20:51:38 +0100 |
Pointers that devolve to TCGTemp may tidy things up eventually.
At present, we still store indicies in TCGArg.
Signed-off-by: Richard Henderson <address@hidden>
---
tcg/tcg.c | 84 +++++++----------------
tcg/tcg.h | 230 +++++++++++++++++++++++++++++++-------------------------------
2 files changed, 138 insertions(+), 176 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 057c1ea..7118bce 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -449,13 +449,6 @@ void tcg_func_start(TCGContext *s)
s->be = tcg_malloc(sizeof(TCGBackendData));
}
-static inline int temp_idx(TCGContext *s, TCGTemp *ts)
-{
- ptrdiff_t n = ts - s->temps;
- tcg_debug_assert(n >= 0 && n < s->nb_temps);
- return n;
-}
-
static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
{
int n = s->nb_temps++;
@@ -470,8 +463,8 @@ static inline TCGTemp *tcg_global_alloc(TCGContext *s)
return tcg_temp_alloc(s);
}
-static int tcg_global_reg_new_internal(TCGContext *s, TCGType type,
- TCGReg reg, const char *name)
+static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
+ TCGReg reg, const char *name)
{
TCGTemp *ts;
@@ -487,44 +480,42 @@ static int tcg_global_reg_new_internal(TCGContext *s,
TCGType type,
ts->name = name;
tcg_regset_set_reg(s->reserved_regs, reg);
- return temp_idx(s, ts);
+ return ts;
}
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size)
{
- int idx;
s->frame_start = start;
s->frame_end = start + size;
- idx = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg, "_frame");
- s->frame_temp = &s->temps[idx];
+ s->frame_temp = tcg_global_reg_new_internal(s, TCG_TYPE_PTR, reg,
"_frame");
}
TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name)
{
TCGContext *s = &tcg_ctx;
- int idx;
+ TCGTemp *t;
if (tcg_regset_test_reg(s->reserved_regs, reg)) {
tcg_abort();
}
- idx = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name);
- return MAKE_TCGV_I32(idx);
+ t = tcg_global_reg_new_internal(s, TCG_TYPE_I32, reg, name);
+ return (TCGv_i32)t;
}
TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name)
{
TCGContext *s = &tcg_ctx;
- int idx;
+ TCGTemp *t;
if (tcg_regset_test_reg(s->reserved_regs, reg)) {
tcg_abort();
}
- idx = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name);
- return MAKE_TCGV_I64(idx);
+ t = tcg_global_reg_new_internal(s, TCG_TYPE_I64, reg, name);
+ return (TCGv_i64)t;
}
-int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
- intptr_t offset, const char *name)
+TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
+ intptr_t offset, const char *name)
{
TCGContext *s = &tcg_ctx;
TCGTemp *base_ts = &s->temps[GET_TCGV_PTR(base)];
@@ -576,10 +567,10 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr
base,
ts->mem_offset = offset;
ts->name = name;
}
- return temp_idx(s, ts);
+ return ts;
}
-static int tcg_temp_new_internal(TCGType type, int temp_local)
+TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
@@ -616,36 +607,18 @@ static int tcg_temp_new_internal(TCGType type, int
temp_local)
ts->temp_allocated = 1;
ts->temp_local = temp_local;
}
- idx = temp_idx(s, ts);
}
#if defined(CONFIG_DEBUG_TCG)
s->temps_in_use++;
#endif
- return idx;
-}
-
-TCGv_i32 tcg_temp_new_internal_i32(int temp_local)
-{
- int idx;
-
- idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
- return MAKE_TCGV_I32(idx);
+ return ts;
}
-TCGv_i64 tcg_temp_new_internal_i64(int temp_local)
-{
- int idx;
-
- idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
- return MAKE_TCGV_I64(idx);
-}
-
-static void tcg_temp_free_internal(int idx)
+void tcg_temp_free_internal(TCGTemp *ts)
{
TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int k;
+ int k, idx = temp_idx(ts);
#if defined(CONFIG_DEBUG_TCG)
s->temps_in_use--;
@@ -655,7 +628,6 @@ static void tcg_temp_free_internal(int idx)
#endif
tcg_debug_assert(idx >= s->nb_globals && idx < s->nb_temps);
- ts = &s->temps[idx];
tcg_debug_assert(ts->temp_allocated != 0);
ts->temp_allocated = 0;
@@ -663,16 +635,6 @@ static void tcg_temp_free_internal(int idx)
set_bit(idx, s->free_temps[k].l);
}
-void tcg_temp_free_i32(TCGv_i32 arg)
-{
- tcg_temp_free_internal(GET_TCGV_I32(arg));
-}
-
-void tcg_temp_free_i64(TCGv_i64 arg)
-{
- tcg_temp_free_internal(GET_TCGV_I64(arg));
-}
-
TCGv_i32 tcg_const_i32(int32_t val)
{
TCGv_i32 t0;
@@ -942,7 +904,7 @@ static void tcg_reg_alloc_start(TCGContext *s)
static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
TCGTemp *ts)
{
- int idx = temp_idx(s, ts);
+ int idx = temp_idx(ts);
if (idx < s->nb_globals) {
pstrcpy(buf, buf_size, ts->name);
@@ -1674,7 +1636,7 @@ static bool liveness_pass_2(TCGContext *s, uint8_t
*temp_state)
TCGTemp *dts = tcg_temp_alloc(s);
dts->type = its->type;
dts->base_type = its->base_type;
- dir_temps[i] = temp_idx(s, dts);
+ dir_temps[i] = temp_idx(dts);
}
}
@@ -1728,7 +1690,7 @@ static bool liveness_pass_2(TCGContext *s, uint8_t
*temp_state)
TCGArg *largs = &s->gen_opparam_buf[lop->args];
largs[0] = dir;
- largs[1] = temp_idx(s, its->mem_base);
+ largs[1] = temp_idx(its->mem_base);
largs[2] = its->mem_offset;
/* Loaded, but synced with memory. */
@@ -1800,7 +1762,7 @@ static bool liveness_pass_2(TCGContext *s, uint8_t
*temp_state)
TCGArg *sargs = &s->gen_opparam_buf[sop->args];
sargs[0] = dir;
- sargs[1] = temp_idx(s, its->mem_base);
+ sargs[1] = temp_idx(its->mem_base);
sargs[2] = its->mem_offset;
temp_state[arg] = TS_MEM;
@@ -1921,7 +1883,7 @@ static void temp_free_or_dead(TCGContext *s, TCGTemp *ts,
int free_or_dead)
}
ts->val_type = (free_or_dead < 0
|| ts->temp_local
- || temp_idx(s, ts) < s->nb_globals
+ || temp_idx(ts) < s->nb_globals
? TEMP_VAL_MEM : TEMP_VAL_DEAD);
}
@@ -1943,7 +1905,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts,
}
if (!ts->mem_coherent) {
if (!ts->mem_allocated) {
- temp_allocate_frame(s, temp_idx(s, ts));
+ temp_allocate_frame(s, temp_idx(ts));
}
switch (ts->val_type) {
case TEMP_VAL_CONST:
diff --git a/tcg/tcg.h b/tcg/tcg.h
index b2cdaff..5a65204 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -384,41 +384,52 @@ static inline unsigned get_alignment_bits(TCGMemOp memop)
typedef tcg_target_ulong TCGArg;
-/* Define type and accessor macros for TCG variables.
-
- TCG variables are the inputs and outputs of TCG ops, as described
- in tcg/README. Target CPU front-end code uses these types to deal
- with TCG variables as it emits TCG code via the tcg_gen_* functions.
- They come in several flavours:
- * TCGv_i32 : 32 bit integer type
- * TCGv_i64 : 64 bit integer type
- * TCGv_ptr : a host pointer type
- * TCGv : an integer type the same size as target_ulong
- (an alias for either TCGv_i32 or TCGv_i64)
- The compiler's type checking will complain if you mix them
- up and pass the wrong sized TCGv to a function.
-
- Users of tcg_gen_* don't need to know about any of the internal
- details of these, and should treat them as opaque types.
- You won't be able to look inside them in a debugger either.
-
- Internal implementation details follow:
-
- Note that there is no definition of the structs TCGv_i32_d etc anywhere.
- This is deliberate, because the values we store in variables of type
- TCGv_i32 are not really pointers-to-structures. They're just small
- integers, but keeping them in pointer types like this means that the
- compiler will complain if you accidentally pass a TCGv_i32 to a
- function which takes a TCGv_i64, and so on. Only the internals of
- TCG need to care about the actual contents of the types, and they always
- box and unbox via the MAKE_TCGV_* and GET_TCGV_* functions.
- Converting to and from intptr_t rather than int reduces the number
- of sign-extension instructions that get implied on 64-bit hosts. */
-
-typedef struct TCGv_i32_d *TCGv_i32;
-typedef struct TCGv_i64_d *TCGv_i64;
-typedef struct TCGv_ptr_d *TCGv_ptr;
+typedef enum TCGTempVal {
+ TEMP_VAL_DEAD,
+ TEMP_VAL_REG,
+ TEMP_VAL_MEM,
+ TEMP_VAL_CONST,
+} TCGTempVal;
+
+typedef struct TCGTemp {
+ TCGReg reg:8;
+ TCGTempVal val_type:8;
+ TCGType base_type:8;
+ TCGType type:8;
+ unsigned int fixed_reg:1;
+ unsigned int indirect_reg:1;
+ unsigned int indirect_base:1;
+ unsigned int mem_coherent:1;
+ unsigned int mem_allocated:1;
+ unsigned int temp_local:1; /* If true, the temp is saved across
+ basic blocks. Otherwise, it is not
+ preserved across basic blocks. */
+ unsigned int temp_allocated:1; /* never used for code gen */
+
+ tcg_target_long val;
+ struct TCGTemp *mem_base;
+ intptr_t mem_offset;
+ const char *name;
+} TCGTemp;
+
+typedef struct TCGv_i32_d {
+ TCGTemp impl;
+} *TCGv_i32;
+
+typedef struct TCGv_i64_d {
+#if TCG_TARGET_REG_BITS == 32
+ struct TCGv_i32_d lo, hi;
+#else
+ TCGTemp impl;
+#endif
+} *TCGv_i64;
+
+typedef struct TCGv_ptr_d {
+ TCGTemp impl;
+} *TCGv_ptr;
+
typedef TCGv_ptr TCGv_env;
+
#if TARGET_LONG_BITS == 32
#define TCGv TCGv_i32
#elif TARGET_LONG_BITS == 64
@@ -427,49 +438,19 @@ typedef TCGv_ptr TCGv_env;
#error Unhandled TARGET_LONG_BITS value
#endif
-static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i)
-{
- return (TCGv_i32)i;
-}
-
-static inline TCGv_i64 QEMU_ARTIFICIAL MAKE_TCGV_I64(intptr_t i)
-{
- return (TCGv_i64)i;
-}
-
-static inline TCGv_ptr QEMU_ARTIFICIAL MAKE_TCGV_PTR(intptr_t i)
-{
- return (TCGv_ptr)i;
-}
-
-static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I32(TCGv_i32 t)
-{
- return (intptr_t)t;
-}
-
-static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I64(TCGv_i64 t)
-{
- return (intptr_t)t;
-}
-
-static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t)
-{
- return (intptr_t)t;
-}
-
#if TCG_TARGET_REG_BITS == 32
-#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
-#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
+#define TCGV_LOW(t) (&(t)->lo)
+#define TCGV_HIGH(t) (&(t)->hi)
#endif
-#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
-#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
-#define TCGV_EQUAL_PTR(a, b) (GET_TCGV_PTR(a) == GET_TCGV_PTR(b))
+#define TCGV_EQUAL_I32(a, b) ((a) == (b))
+#define TCGV_EQUAL_I64(a, b) ((a) == (b))
+#define TCGV_EQUAL_PTR(a, b) ((a) == (b))
/* Dummy definition to avoid compiler warnings. */
-#define TCGV_UNUSED_I32(x) x = NULL
-#define TCGV_UNUSED_I64(x) x = NULL
-#define TCGV_UNUSED_PTR(x) x = NULL
+#define TCGV_UNUSED_I32(x) ((x) = NULL)
+#define TCGV_UNUSED_I64(x) ((x) = NULL)
+#define TCGV_UNUSED_PTR(x) ((x) = NULL)
#define TCGV_IS_UNUSED_I32(x) ((x) == NULL)
#define TCGV_IS_UNUSED_I64(x) ((x) == NULL)
@@ -575,34 +556,6 @@ static inline TCGCond tcg_high_cond(TCGCond c)
}
}
-typedef enum TCGTempVal {
- TEMP_VAL_DEAD,
- TEMP_VAL_REG,
- TEMP_VAL_MEM,
- TEMP_VAL_CONST,
-} TCGTempVal;
-
-typedef struct TCGTemp {
- TCGReg reg:8;
- TCGTempVal val_type:8;
- TCGType base_type:8;
- TCGType type:8;
- unsigned int fixed_reg:1;
- unsigned int indirect_reg:1;
- unsigned int indirect_base:1;
- unsigned int mem_coherent:1;
- unsigned int mem_allocated:1;
- unsigned int temp_local:1; /* If true, the temp is saved across
- basic blocks. Otherwise, it is not
- preserved across basic blocks. */
- unsigned int temp_allocated:1; /* never used for code gen */
-
- tcg_target_long val;
- struct TCGTemp *mem_base;
- intptr_t mem_offset;
- const char *name;
-} TCGTemp;
-
typedef struct TCGContext TCGContext;
typedef struct TCGTempSet {
@@ -736,6 +689,43 @@ struct TCGContext {
extern TCGContext tcg_ctx;
extern bool parallel_cpus;
+static inline uintptr_t temp_idx(TCGTemp *ts)
+{
+ ptrdiff_t n = ts - tcg_ctx.temps;
+ tcg_debug_assert(n >= 0 && n < tcg_ctx.nb_temps);
+ return n;
+}
+
+static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(uintptr_t i)
+{
+ return (TCGv_i32)&tcg_ctx.temps[i];
+}
+
+static inline TCGv_i64 QEMU_ARTIFICIAL MAKE_TCGV_I64(uintptr_t i)
+{
+ return (TCGv_i64)&tcg_ctx.temps[i];
+}
+
+static inline TCGv_ptr QEMU_ARTIFICIAL MAKE_TCGV_PTR(uintptr_t i)
+{
+ return (TCGv_ptr)&tcg_ctx.temps[i];
+}
+
+static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_I32(TCGv_i32 t)
+{
+ return temp_idx((TCGTemp *)t);
+}
+
+static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_I64(TCGv_i64 t)
+{
+ return temp_idx((TCGTemp *)t);
+}
+
+static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t)
+{
+ return temp_idx((TCGTemp *)t);
+}
+
static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
{
int op_argi = tcg_ctx.gen_op_buf[op_idx].args;
@@ -788,49 +778,59 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
-int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
+TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char
*);
+TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local);
+void tcg_temp_free_internal(TCGTemp *ts);
TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
-TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
-TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
-
-void tcg_temp_free_i32(TCGv_i32 arg);
-void tcg_temp_free_i64(TCGv_i64 arg);
-
static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
const char *name)
{
- int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
- return MAKE_TCGV_I32(idx);
+ TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
+ return (TCGv_i32)t;
}
static inline TCGv_i32 tcg_temp_new_i32(void)
{
- return tcg_temp_new_internal_i32(0);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, false);
+ return (TCGv_i32)t;
}
static inline TCGv_i32 tcg_temp_local_new_i32(void)
{
- return tcg_temp_new_internal_i32(1);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, true);
+ return (TCGv_i32)t;
}
static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
const char *name)
{
- int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
- return MAKE_TCGV_I64(idx);
+ TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
+ return (TCGv_i64)t;
}
static inline TCGv_i64 tcg_temp_new_i64(void)
{
- return tcg_temp_new_internal_i64(0);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, false);
+ return (TCGv_i64)t;
}
static inline TCGv_i64 tcg_temp_local_new_i64(void)
{
- return tcg_temp_new_internal_i64(1);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, true);
+ return (TCGv_i64)t;
+}
+
+static inline void tcg_temp_free_i32(TCGv_i32 arg)
+{
+ tcg_temp_free_internal((TCGTemp *)arg);
+}
+
+static inline void tcg_temp_free_i64(TCGv_i64 arg)
+{
+ tcg_temp_free_internal((TCGTemp *)arg);
}
#if defined(CONFIG_DEBUG_TCG)
--
2.7.4
- [Qemu-devel] [RFC 00/14] tcg: Use TCGTemp pointers instead of indices, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 01/14] tcg: Use NULL for TCGV_UNUSED_*, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 04/14] tcg: Add temp_global bit to TCGTemp, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 02/14] tcg: Define actual structures for TCGv_*,
Richard Henderson <=
- [Qemu-devel] [RFC 05/14] tcg: Avoid loops against variable bounds, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 03/14] tcg: Use per-temp state data in liveness, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 06/14] tcg: More use of arg_temp, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 07/14] tcg: Change temp_allocate_frame arg to TCGTemp, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 08/14] tcg: Remove unused TCG_CALL_DUMMY_TCGV, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 09/14] tcg: More use of arg_index, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 10/14] tcg: Map TCG_CALL_DUMMY_ARG to NULL, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 13/14] tcg: Use temp number 0 again, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 11/14] tcg: Introduce temp_info for the optimize pass, Richard Henderson, 2016/11/16
- [Qemu-devel] [RFC 12/14] tcg: Store pointers to temporaries directly in TCGArg, Richard Henderson, 2016/11/16