Pointers that devolve to TCGTemp may tidy things up eventually. At present, we still store indicies in TCGArg.
Signed-off-by: Richard Henderson <[email protected]> --- 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
