* [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants
@ 2008-05-23 17:33 Fabrice Bellard
2008-05-23 18:03 ` Paul Brook
2008-05-30 18:59 ` Blue Swirl
0 siblings, 2 replies; 4+ messages in thread
From: Fabrice Bellard @ 2008-05-23 17:33 UTC (permalink / raw)
To: qemu-devel
Revision: 4544
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4544
Author: bellard
Date: 2008-05-23 17:33:39 +0000 (Fri, 23 May 2008)
Log Message:
-----------
added tcg_temp_free() and improved the handling of constants
Modified Paths:
--------------
trunk/tcg/tcg-op.h
trunk/tcg/tcg.c
trunk/tcg/tcg.h
Modified: trunk/tcg/tcg-op.h
===================================================================
--- trunk/tcg/tcg-op.h 2008-05-23 16:06:43 UTC (rev 4543)
+++ trunk/tcg/tcg-op.h 2008-05-23 17:33:39 UTC (rev 4544)
@@ -178,88 +178,115 @@
static inline void tcg_gen_helper_0_0(void *func)
{
+ TCGv t0;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
0, NULL, 0, NULL);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_0_1(void *func, TCGv arg)
{
+ TCGv t0;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
0, NULL, 1, &arg);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
{
TCGv args[2];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
0, NULL, 2, args);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_0_3(void *func,
TCGv arg1, TCGv arg2, TCGv arg3)
{
TCGv args[3];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
0, NULL, 3, args);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
TCGv arg3, TCGv arg4)
{
TCGv args[4];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
0, NULL, 4, args);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_1_0(void *func, TCGv ret)
{
+ TCGv t0;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
1, &ret, 0, NULL);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
{
+ TCGv t0;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
1, &ret, 1, &arg1);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_1_2(void *func, TCGv ret,
TCGv arg1, TCGv arg2)
{
TCGv args[2];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
1, &ret, 2, args);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_1_3(void *func, TCGv ret,
TCGv arg1, TCGv arg2, TCGv arg3)
{
TCGv args[3];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
1, &ret, 3, args);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
@@ -267,13 +294,16 @@
TCGv arg4)
{
TCGv args[4];
+ TCGv t0;
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
+ t0 = tcg_const_ptr((tcg_target_long)func);
tcg_gen_call(&tcg_ctx,
- tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ t0, TCG_HELPER_CALL_FLAGS,
1, &ret, 4, args);
+ tcg_temp_free(t0);
}
/* 32 bit ops */
@@ -329,7 +359,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_add_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_add_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -344,7 +376,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_sub_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_sub_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -361,7 +395,9 @@
} else if (arg2 == 0xffffffff) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_and_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_and_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -378,7 +414,9 @@
} else if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_or_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_or_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -393,7 +431,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_xor_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_xor_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -407,7 +447,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_shl_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_shl_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -421,7 +463,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_shr_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_shr_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -435,7 +479,9 @@
if (arg2 == 0) {
tcg_gen_mov_i32(ret, arg1);
} else {
- tcg_gen_sar_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_sar_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -452,7 +498,9 @@
static inline void tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2)
{
- tcg_gen_mul_i32(ret, arg1, tcg_const_i32(arg2));
+ TCGv t0 = tcg_const_i32(arg2);
+ tcg_gen_mul_i32(ret, arg1, t0);
+ tcg_temp_free(t0);
}
#ifdef TCG_TARGET_HAS_div_i32
@@ -482,6 +530,7 @@
t0 = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_sari_i32(t0, arg1, 31);
tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
@@ -490,6 +539,7 @@
t0 = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_sari_i32(t0, arg1, 31);
tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
@@ -498,6 +548,7 @@
t0 = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_movi_i32(t0, 0);
tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
@@ -506,6 +557,7 @@
t0 = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_movi_i32(t0, 0);
tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
#endif
@@ -608,7 +660,9 @@
static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_add_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_add_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -619,7 +673,9 @@
static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_sub_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_sub_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -713,11 +769,15 @@
tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
tcg_gen_mov_i64(ret, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_mul_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_mul_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -824,7 +884,9 @@
static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_add_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_add_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -834,7 +896,9 @@
static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_sub_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_sub_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -844,7 +908,9 @@
static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_and_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_and_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -854,7 +920,9 @@
static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_or_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_or_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -864,7 +932,9 @@
static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_xor_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_xor_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -877,7 +947,9 @@
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- tcg_gen_shl_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_shl_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -891,7 +963,9 @@
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- tcg_gen_shr_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_shr_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -905,7 +979,9 @@
if (arg2 == 0) {
tcg_gen_mov_i64(ret, arg1);
} else {
- tcg_gen_sar_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_sar_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
}
@@ -922,7 +998,9 @@
static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
{
- tcg_gen_mul_i64(ret, arg1, tcg_const_i64(arg2));
+ TCGv t0 = tcg_const_i64(arg2);
+ tcg_gen_mul_i64(ret, arg1, t0);
+ tcg_temp_free(t0);
}
#ifdef TCG_TARGET_HAS_div_i64
@@ -952,6 +1030,7 @@
t0 = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_sari_i64(t0, arg1, 63);
tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -960,6 +1039,7 @@
t0 = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_sari_i64(t0, arg1, 63);
tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -968,6 +1048,7 @@
t0 = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_movi_i64(t0, 0);
tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
@@ -976,6 +1057,7 @@
t0 = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_movi_i64(t0, 0);
tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
+ tcg_temp_free(t0);
}
#endif
@@ -1030,6 +1112,8 @@
tcg_gen_andi_i32(t1, arg, 0x000000ff);
tcg_gen_shli_i32(t1, t1, 8);
tcg_gen_or_i32(ret, t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
#endif
}
@@ -1054,6 +1138,8 @@
tcg_gen_shri_i32(t1, arg, 24);
tcg_gen_or_i32(ret, t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
#endif
}
@@ -1121,6 +1207,8 @@
tcg_gen_bswap_i32(t1, TCGV_HIGH(arg));
tcg_gen_mov_i32(ret, t1);
tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
#else
@@ -1227,6 +1315,8 @@
tcg_gen_shri_i64(t1, arg, 56);
tcg_gen_or_i64(ret, t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
#endif
}
@@ -1237,7 +1327,9 @@
#ifdef TCG_TARGET_HAS_neg_i32
tcg_gen_op2(INDEX_op_neg_i32, ret, arg);
#else
- tcg_gen_sub_i32(ret, tcg_const_i32(0), arg);
+ TCGv t0 = tcg_const_i32(0);
+ tcg_gen_sub_i32(ret, t0, arg);
+ tcg_temp_free(t0);
#endif
}
@@ -1246,18 +1338,20 @@
#ifdef TCG_TARGET_HAS_neg_i64
tcg_gen_op2(INDEX_op_neg_i64, ret, arg);
#else
- tcg_gen_sub_i64(ret, tcg_const_i64(0), arg);
+ TCGv t0 = tcg_const_i64(0);
+ tcg_gen_sub_i64(ret, t0, arg);
+ tcg_temp_free(t0);
#endif
}
static inline void tcg_gen_not_i32(TCGv ret, TCGv arg)
{
- tcg_gen_xor_i32(ret, arg, tcg_const_i32(-1));
+ tcg_gen_xori_i32(ret, arg, -1);
}
static inline void tcg_gen_not_i64(TCGv ret, TCGv arg)
{
- tcg_gen_xor_i64(ret, arg, tcg_const_i64(-1));
+ tcg_gen_xori_i64(ret, arg, -1);
}
static inline void tcg_gen_discard_i32(TCGv arg)
Modified: trunk/tcg/tcg.c
===================================================================
--- trunk/tcg/tcg.c 2008-05-23 16:06:43 UTC (rev 4543)
+++ trunk/tcg/tcg.c 2008-05-23 17:33:39 UTC (rev 4544)
@@ -266,8 +266,11 @@
void tcg_func_start(TCGContext *s)
{
+ int i;
tcg_pool_reset(s);
s->nb_temps = s->nb_globals;
+ for(i = 0; i < TCG_TYPE_COUNT; i++)
+ s->first_free_temp[i] = -1;
s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
s->nb_labels = 0;
s->current_frame_offset = s->frame_start;
@@ -301,7 +304,6 @@
ts->type = type;
ts->fixed_reg = 1;
ts->reg = reg;
- ts->val_type = TEMP_VAL_REG;
ts->name = name;
s->nb_globals++;
tcg_regset_set_reg(s->reserved_regs, reg);
@@ -327,7 +329,6 @@
ts->type = TCG_TYPE_I32;
ts->fixed_reg = 1;
ts->reg = reg1;
- ts->val_type = TEMP_VAL_REG;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_0");
ts->name = strdup(buf);
@@ -337,7 +338,6 @@
ts->type = TCG_TYPE_I32;
ts->fixed_reg = 1;
ts->reg = reg2;
- ts->val_type = TEMP_VAL_REG;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_1");
ts->name = strdup(buf);
@@ -370,7 +370,6 @@
#else
ts->mem_offset = offset;
#endif
- ts->val_type = TEMP_VAL_MEM;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_0");
ts->name = strdup(buf);
@@ -386,7 +385,6 @@
#else
ts->mem_offset = offset + 4;
#endif
- ts->val_type = TEMP_VAL_MEM;
pstrcpy(buf, sizeof(buf), name);
pstrcat(buf, sizeof(buf), "_1");
ts->name = strdup(buf);
@@ -403,7 +401,6 @@
ts->mem_allocated = 1;
ts->mem_reg = reg;
ts->mem_offset = offset;
- ts->val_type = TEMP_VAL_MEM;
ts->name = name;
s->nb_globals++;
}
@@ -416,90 +413,75 @@
TCGTemp *ts;
int idx;
- idx = s->nb_temps;
+ idx = s->first_free_temp[type];
+ if (idx != -1) {
+ /* There is already an available temp with the
+ right type */
+ ts = &s->temps[idx];
+ s->first_free_temp[type] = ts->next_free_temp;
+ ts->temp_allocated = 1;
+ } else {
+ idx = s->nb_temps;
#if TCG_TARGET_REG_BITS == 32
- if (type == TCG_TYPE_I64) {
- tcg_temp_alloc(s, s->nb_temps + 1);
- ts = &s->temps[s->nb_temps];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 0;
- ts->val_type = TEMP_VAL_DEAD;
- ts->mem_allocated = 0;
- ts->name = NULL;
- ts++;
- ts->base_type = TCG_TYPE_I32;
- ts->type = TCG_TYPE_I32;
- ts->val_type = TEMP_VAL_DEAD;
- ts->fixed_reg = 0;
- ts->mem_allocated = 0;
- ts->name = NULL;
- s->nb_temps += 2;
- } else
+ if (type == TCG_TYPE_I64) {
+ tcg_temp_alloc(s, s->nb_temps + 1);
+ ts = &s->temps[s->nb_temps];
+ ts->base_type = type;
+ ts->type = TCG_TYPE_I32;
+ ts->temp_allocated = 1;
+ ts->name = NULL;
+ ts++;
+ ts->base_type = TCG_TYPE_I32;
+ ts->type = TCG_TYPE_I32;
+ ts->temp_allocated = 1;
+ ts->name = NULL;
+ s->nb_temps += 2;
+ } else
#endif
- {
- tcg_temp_alloc(s, s->nb_temps + 1);
- ts = &s->temps[s->nb_temps];
- ts->base_type = type;
- ts->type = type;
- ts->fixed_reg = 0;
- ts->val_type = TEMP_VAL_DEAD;
- ts->mem_allocated = 0;
- ts->name = NULL;
- s->nb_temps++;
+ {
+ tcg_temp_alloc(s, s->nb_temps + 1);
+ ts = &s->temps[s->nb_temps];
+ ts->base_type = type;
+ ts->type = type;
+ ts->temp_allocated = 1;
+ ts->name = NULL;
+ s->nb_temps++;
+ }
}
return MAKE_TCGV(idx);
}
-TCGv tcg_const_i32(int32_t val)
+void tcg_temp_free(TCGv arg)
{
TCGContext *s = &tcg_ctx;
TCGTemp *ts;
- int idx;
+ int idx = GET_TCGV(arg);
+ TCGType type;
- idx = s->nb_temps;
- tcg_temp_alloc(s, idx + 1);
+ assert(idx >= s->nb_globals && idx < s->nb_temps);
ts = &s->temps[idx];
- ts->base_type = ts->type = TCG_TYPE_I32;
- ts->val_type = TEMP_VAL_CONST;
- ts->name = NULL;
- ts->val = val;
- s->nb_temps++;
- return MAKE_TCGV(idx);
+ assert(ts->temp_allocated != 0);
+ ts->temp_allocated = 0;
+ type = ts->base_type;
+ ts->next_free_temp = s->first_free_temp[type];
+ s->first_free_temp[type] = idx;
}
+
+TCGv tcg_const_i32(int32_t val)
+{
+ TCGv t0;
+ t0 = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(t0, val);
+ return t0;
+}
+
TCGv tcg_const_i64(int64_t val)
{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx;
-
- idx = s->nb_temps;
-#if TCG_TARGET_REG_BITS == 32
- tcg_temp_alloc(s, idx + 2);
- ts = &s->temps[idx];
- ts->base_type = TCG_TYPE_I64;
- ts->type = TCG_TYPE_I32;
- ts->val_type = TEMP_VAL_CONST;
- ts->name = NULL;
- ts->val = val;
- ts++;
- ts->base_type = TCG_TYPE_I32;
- ts->type = TCG_TYPE_I32;
- ts->val_type = TEMP_VAL_CONST;
- ts->name = NULL;
- ts->val = val >> 32;
- s->nb_temps += 2;
-#else
- tcg_temp_alloc(s, idx + 1);
- ts = &s->temps[idx];
- ts->base_type = ts->type = TCG_TYPE_I64;
- ts->val_type = TEMP_VAL_CONST;
- ts->name = NULL;
- ts->val = val;
- s->nb_temps++;
-#endif
- return MAKE_TCGV(idx);
+ TCGv t0;
+ t0 = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_movi_i64(t0, val);
+ return t0;
}
void tcg_register_helper(void *func, const char *name)
@@ -663,6 +645,8 @@
tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
tcg_gen_mov_i32(ret, t1);
}
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
}
#endif
@@ -679,6 +663,12 @@
ts->val_type = TEMP_VAL_MEM;
}
}
+ for(i = s->nb_globals; i < s->nb_temps; i++) {
+ ts = &s->temps[i];
+ ts->val_type = TEMP_VAL_DEAD;
+ ts->mem_allocated = 0;
+ ts->fixed_reg = 0;
+ }
for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
s->reg_to_temp[i] = -1;
}
@@ -693,11 +683,7 @@
if (idx < s->nb_globals) {
pstrcpy(buf, buf_size, ts->name);
} else {
- if (ts->val_type == TEMP_VAL_CONST) {
- snprintf(buf, buf_size, "$0x%" TCG_PRIlx , ts->val);
- } else {
- snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
- }
+ snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
}
return buf;
}
@@ -707,37 +693,49 @@
return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg));
}
-/* find helper definition (XXX: inefficient) */
-static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
+static int helper_cmp(const void *p1, const void *p2)
{
- int i;
- for(i = 0; i < s->nb_helpers; i++) {
- if (s->helpers[i].func == val)
- return &s->helpers[i];
- }
- return NULL;
+ const TCGHelperInfo *th1 = p1;
+ const TCGHelperInfo *th2 = p2;
+ if (th1->func < th2->func)
+ return -1;
+ else if (th1->func == th2->func)
+ return 0;
+ else
+ return 1;
}
-static const char *tcg_get_helper_str_idx(TCGContext *s, char *buf, int buf_size,
- int idx)
+/* find helper definition (Note: A hash table would be better) */
+static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
{
- TCGTemp *ts;
+ int m, m_min, m_max;
TCGHelperInfo *th;
+ tcg_target_ulong v;
- ts = &s->temps[idx];
- if (ts->val_type == TEMP_VAL_CONST) {
- /* find helper name (XXX: inefficient) */
- th = tcg_find_helper(s, ts->val);
- if (th) {
- pstrcpy(buf, buf_size, "$");
- pstrcat(buf, buf_size, th->name);
- return buf;
+ if (unlikely(!s->helpers_sorted)) {
+ qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
+ helper_cmp);
+ s->helpers_sorted = 1;
+ }
+
+ /* binary search */
+ m_min = 0;
+ m_max = s->nb_helpers - 1;
+ while (m_min <= m_max) {
+ m = (m_min + m_max) >> 1;
+ th = &s->helpers[m];
+ v = th->func;
+ if (v == val)
+ return th;
+ else if (val < v) {
+ m_max = m - 1;
+ } else {
+ m_min = m + 1;
}
}
- return tcg_get_arg_str_idx(s, buf, buf_size, idx);
+ return NULL;
}
-
void tcg_dump_ops(TCGContext *s, FILE *outfile)
{
const uint16_t *opc_ptr;
@@ -780,7 +778,7 @@
/* function name */
fprintf(outfile, "%s",
- tcg_get_helper_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
+ tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
/* flags */
fprintf(outfile, ",$0x%" TCG_PRIlx,
args[nb_oargs + nb_iargs]);
@@ -800,6 +798,29 @@
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
}
}
+ } else if (c == INDEX_op_movi_i32
+#if TCG_TARGET_REG_BITS == 64
+ || c == INDEX_op_movi_i64
+#endif
+ ) {
+ tcg_target_ulong val;
+ TCGHelperInfo *th;
+
+ nb_oargs = def->nb_oargs;
+ nb_iargs = def->nb_iargs;
+ nb_cargs = def->nb_cargs;
+ fprintf(outfile, " %s %s,$", def->name,
+ tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
+ val = args[1];
+ th = tcg_find_helper(s, val);
+ if (th) {
+ fprintf(outfile, th->name);
+ } else {
+ if (c == INDEX_op_movi_i32)
+ fprintf(outfile, "0x%x", (uint32_t)val);
+ else
+ fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
+ }
} else {
fprintf(outfile, " %s ", def->name);
if (c == INDEX_op_nopn) {
@@ -1281,11 +1302,6 @@
dump_regs(s);
tcg_abort();
}
- if (ts->val_type == TEMP_VAL_CONST && k < s->nb_globals) {
- printf("constant forbidden in global %s\n",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
- goto fail;
- }
}
}
#endif
@@ -1351,47 +1367,80 @@
}
/* save globals to their cannonical location and assume they can be
- modified be the following code. */
-static void save_globals(TCGContext *s)
+ modified be the following code. 'allocated_regs' is used in case a
+ temporary registers needs to be allocated to store a constant. */
+static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
{
TCGTemp *ts;
- int i;
+ int i, reg;
for(i = 0; i < s->nb_globals; i++) {
ts = &s->temps[i];
if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG) {
+ switch(ts->val_type) {
+ case TEMP_VAL_REG:
tcg_reg_free(s, ts->reg);
- } else if (ts->val_type == TEMP_VAL_DEAD) {
+ break;
+ case TEMP_VAL_DEAD:
ts->val_type = TEMP_VAL_MEM;
+ break;
+ case TEMP_VAL_CONST:
+ reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
+ allocated_regs);
+ tcg_out_movi(s, ts->type, reg, ts->val);
+ tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
+ ts->val_type = TEMP_VAL_MEM;
+ break;
+ case TEMP_VAL_MEM:
+ break;
+ default:
+ tcg_abort();
}
}
}
}
/* at the end of a basic block, we assume all temporaries are dead and
- all globals are stored at their canonical location */
-/* XXX: optimize by handling constants in another array ? */
-void tcg_reg_alloc_bb_end(TCGContext *s)
+ all globals are stored at their canonical location. */
+static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
{
TCGTemp *ts;
int i;
- save_globals(s);
-
for(i = s->nb_globals; i < s->nb_temps; i++) {
ts = &s->temps[i];
- if (ts->val_type != TEMP_VAL_CONST) {
- if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = -1;
- }
- ts->val_type = TEMP_VAL_DEAD;
+ if (ts->val_type == TEMP_VAL_REG) {
+ s->reg_to_temp[ts->reg] = -1;
}
+ ts->val_type = TEMP_VAL_DEAD;
}
+
+ save_globals(s, allocated_regs);
}
#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
+static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
+{
+ TCGTemp *ots;
+ tcg_target_ulong val;
+
+ ots = &s->temps[args[0]];
+ val = args[1];
+
+ if (ots->fixed_reg) {
+ /* for fixed registers, we do not do any constant
+ propagation */
+ tcg_out_movi(s, ots->type, ots->reg, val);
+ } else {
+ /* The movi is not explicitely generated here */
+ if (ots->val_type == TEMP_VAL_REG)
+ s->reg_to_temp[ots->reg] = -1;
+ ots->val_type = TEMP_VAL_CONST;
+ ots->val = val;
+ }
+}
+
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
const TCGArg *args,
unsigned int dead_iargs)
@@ -1404,6 +1453,7 @@
ts = &s->temps[args[1]];
arg_ct = &def->args_ct[0];
+ /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
if (ts->val_type == TEMP_VAL_REG) {
if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
/* the mov can be suppressed */
@@ -1430,12 +1480,17 @@
}
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
} else if (ts->val_type == TEMP_VAL_CONST) {
- if (ots->val_type == TEMP_VAL_REG) {
+ if (ots->fixed_reg) {
reg = ots->reg;
+ tcg_out_movi(s, ots->type, reg, ts->val);
} else {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
+ /* propagate constant */
+ if (ots->val_type == TEMP_VAL_REG)
+ s->reg_to_temp[ots->reg] = -1;
+ ots->val_type = TEMP_VAL_CONST;
+ ots->val = ts->val;
+ return;
}
- tcg_out_movi(s, ots->type, reg, ts->val);
} else {
tcg_abort();
}
@@ -1487,10 +1542,13 @@
new_args[i] = ts->val;
goto iarg_end;
} else {
- /* need to move to a register*/
+ /* need to move to a register */
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_movi(s, ts->type, reg, ts->val);
- goto iarg_end1;
+ ts->val_type = TEMP_VAL_REG;
+ ts->reg = reg;
+ ts->mem_coherent = 0;
+ s->reg_to_temp[reg] = arg;
}
}
assert(ts->val_type == TEMP_VAL_REG);
@@ -1518,78 +1576,78 @@
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_mov(s, reg, ts->reg);
}
- iarg_end1:
new_args[i] = reg;
const_args[i] = 0;
tcg_regset_set_reg(allocated_regs, reg);
iarg_end: ;
}
- /* mark dead temporaries and free the associated registers */
- for(i = 0; i < nb_iargs; i++) {
- arg = args[nb_oargs + i];
- if (IS_DEAD_IARG(i)) {
- ts = &s->temps[arg];
- if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_DEAD;
+ if (def->flags & TCG_OPF_BB_END) {
+ tcg_reg_alloc_bb_end(s, allocated_regs);
+ } else {
+ /* mark dead temporaries and free the associated registers */
+ for(i = 0; i < nb_iargs; i++) {
+ arg = args[nb_oargs + i];
+ if (IS_DEAD_IARG(i)) {
+ ts = &s->temps[arg];
+ if (!ts->fixed_reg) {
+ if (ts->val_type == TEMP_VAL_REG)
+ s->reg_to_temp[ts->reg] = -1;
+ ts->val_type = TEMP_VAL_DEAD;
+ }
}
}
- }
-
- if (def->flags & TCG_OPF_CALL_CLOBBER) {
- /* XXX: permit generic clobber register list ? */
- for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
- if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
- tcg_reg_free(s, reg);
+
+ if (def->flags & TCG_OPF_CALL_CLOBBER) {
+ /* XXX: permit generic clobber register list ? */
+ for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
+ if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
+ tcg_reg_free(s, reg);
+ }
}
+ /* XXX: for load/store we could do that only for the slow path
+ (i.e. when a memory callback is called) */
+
+ /* store globals and free associated registers (we assume the insn
+ can modify any global. */
+ save_globals(s, allocated_regs);
}
- /* XXX: for load/store we could do that only for the slow path
- (i.e. when a memory callback is called) */
-
- /* store globals and free associated registers (we assume the insn
- can modify any global. */
- save_globals(s);
- }
-
- /* satisfy the output constraints */
- tcg_regset_set(allocated_regs, s->reserved_regs);
- for(k = 0; k < nb_oargs; k++) {
- i = def->sorted_args[k];
- arg = args[i];
- arg_ct = &def->args_ct[i];
- ts = &s->temps[arg];
- if (arg_ct->ct & TCG_CT_ALIAS) {
- reg = new_args[arg_ct->alias_index];
- } else {
- /* if fixed register, we try to use it */
- reg = ts->reg;
- if (ts->fixed_reg &&
- tcg_regset_test_reg(arg_ct->u.regs, reg)) {
- goto oarg_end;
+
+ /* satisfy the output constraints */
+ tcg_regset_set(allocated_regs, s->reserved_regs);
+ for(k = 0; k < nb_oargs; k++) {
+ i = def->sorted_args[k];
+ arg = args[i];
+ arg_ct = &def->args_ct[i];
+ ts = &s->temps[arg];
+ if (arg_ct->ct & TCG_CT_ALIAS) {
+ reg = new_args[arg_ct->alias_index];
+ } else {
+ /* if fixed register, we try to use it */
+ reg = ts->reg;
+ if (ts->fixed_reg &&
+ tcg_regset_test_reg(arg_ct->u.regs, reg)) {
+ goto oarg_end;
+ }
+ reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
}
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
+ tcg_regset_set_reg(allocated_regs, reg);
+ /* if a fixed register is used, then a move will be done afterwards */
+ if (!ts->fixed_reg) {
+ if (ts->val_type == TEMP_VAL_REG)
+ s->reg_to_temp[ts->reg] = -1;
+ ts->val_type = TEMP_VAL_REG;
+ ts->reg = reg;
+ /* temp value is modified, so the value kept in memory is
+ potentially not the same */
+ ts->mem_coherent = 0;
+ s->reg_to_temp[reg] = arg;
+ }
+ oarg_end:
+ new_args[i] = reg;
}
- tcg_regset_set_reg(allocated_regs, reg);
- /* if a fixed register is used, then a move will be done afterwards */
- if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- /* temp value is modified, so the value kept in memory is
- potentially not the same */
- ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
- }
- oarg_end:
- new_args[i] = reg;
}
- if (def->flags & TCG_OPF_BB_END)
- tcg_reg_alloc_bb_end(s);
-
/* emit instruction */
tcg_out_op(s, opc, new_args, const_args);
@@ -1708,6 +1766,7 @@
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
func_arg = reg;
+ tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_REG) {
reg = ts->reg;
if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
@@ -1715,6 +1774,7 @@
tcg_out_mov(s, reg, ts->reg);
}
func_arg = reg;
+ tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_CONST) {
if (tcg_target_const_match(func_addr, arg_ct)) {
const_func_arg = 1;
@@ -1723,17 +1783,19 @@
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_movi(s, ts->type, reg, func_addr);
func_arg = reg;
+ tcg_regset_set_reg(allocated_regs, reg);
}
} else {
tcg_abort();
}
+
/* mark dead temporaries and free the associated registers */
for(i = 0; i < nb_iargs; i++) {
arg = args[nb_oargs + i];
if (IS_DEAD_IARG(i)) {
ts = &s->temps[arg];
- if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
+ if (!ts->fixed_reg) {
if (ts->val_type == TEMP_VAL_REG)
s->reg_to_temp[ts->reg] = -1;
ts->val_type = TEMP_VAL_DEAD;
@@ -1750,7 +1812,7 @@
/* store globals and free associated registers (we assume the call
can modify any global. */
- save_globals(s);
+ save_globals(s, allocated_regs);
tcg_out_op(s, opc, &func_arg, &const_func_arg);
@@ -1763,7 +1825,7 @@
arg = args[i];
ts = &s->temps[arg];
reg = tcg_target_call_oarg_regs[i];
- tcg_reg_free(s, reg);
+ assert(s->reg_to_temp[reg] == -1);
if (ts->fixed_reg) {
if (ts->reg != reg) {
tcg_out_mov(s, ts->reg, reg);
@@ -1863,6 +1925,12 @@
dead_iargs = s->op_dead_iargs[op_index];
tcg_reg_alloc_mov(s, def, args, dead_iargs);
break;
+ case INDEX_op_movi_i32:
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_movi_i64:
+#endif
+ tcg_reg_alloc_movi(s, args);
+ break;
case INDEX_op_debug_insn_start:
/* debug instruction */
break;
@@ -1879,7 +1947,7 @@
TCGTemp *ts;
ts = &s->temps[args[0]];
/* mark the temporary as dead */
- if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
+ if (!ts->fixed_reg) {
if (ts->val_type == TEMP_VAL_REG)
s->reg_to_temp[ts->reg] = -1;
ts->val_type = TEMP_VAL_DEAD;
@@ -1900,7 +1968,7 @@
/* must never happen here */
tcg_abort();
case INDEX_op_set_label:
- tcg_reg_alloc_bb_end(s);
+ tcg_reg_alloc_bb_end(s, s->reserved_regs);
tcg_out_label(s, args[0], (long)s->code_ptr);
break;
case INDEX_op_call:
@@ -1916,7 +1984,7 @@
#ifdef CONFIG_PROFILER
s->old_op_count++;
#endif
- tcg_reg_alloc_bb_end(s);
+ tcg_reg_alloc_bb_end(s, s->reserved_regs);
if (search_pc >= 0) {
s->code_ptr += def->copy_size;
args += def->nb_args;
Modified: trunk/tcg/tcg.h
===================================================================
--- trunk/tcg/tcg.h 2008-05-23 16:06:43 UTC (rev 4543)
+++ trunk/tcg/tcg.h 2008-05-23 17:33:39 UTC (rev 4544)
@@ -98,6 +98,7 @@
#define TCG_TYPE_I32 0
#define TCG_TYPE_I64 1
+#define TCG_TYPE_COUNT 2 /* number of different types */
#if TCG_TARGET_REG_BITS == 32
#define TCG_TYPE_PTR TCG_TYPE_I32
@@ -188,6 +189,9 @@
unsigned int fixed_reg:1;
unsigned int mem_coherent:1;
unsigned int mem_allocated:1;
+ unsigned int temp_allocated:1; /* never used for code gen */
+ /* index of next free temp of same base type, -1 if end */
+ int next_free_temp;
const char *name;
} TCGTemp;
@@ -208,6 +212,8 @@
TCGTemp *temps; /* globals first, temps after */
int nb_globals;
int nb_temps;
+ int first_free_temp[TCG_TYPE_COUNT]; /* index of free temps, -1 if none */
+
/* constant indexes (end of temp array) */
int const_start;
int const_end;
@@ -236,6 +242,7 @@
TCGHelperInfo *helpers;
int nb_helpers;
int allocated_helpers;
+ int helpers_sorted;
#ifdef CONFIG_PROFILER
/* profiling info */
@@ -299,6 +306,7 @@
TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
const char *name);
TCGv tcg_temp_new(TCGType type);
+void tcg_temp_free(TCGv arg);
char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
void tcg_dump_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
@@ -381,9 +389,6 @@
void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
int label_index, long addend);
-void tcg_reg_alloc_start(TCGContext *s);
-void tcg_reg_alloc_bb_end(TCGContext *s);
-void tcg_liveness_analysis(TCGContext *s);
const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
unsigned int dead_iargs);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants
2008-05-23 17:33 [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants Fabrice Bellard
@ 2008-05-23 18:03 ` Paul Brook
2008-05-23 18:27 ` Fabrice Bellard
2008-05-30 18:59 ` Blue Swirl
1 sibling, 1 reply; 4+ messages in thread
From: Paul Brook @ 2008-05-23 18:03 UTC (permalink / raw)
To: qemu-devel
> added tcg_temp_free() and improved the handling of constants
Should the return value of tcg_const_i32 et. al. be considered immutable, or
is it ok to use it as a temporary?
e.g.:
static TCGv do_frob(TCGv base, int addend)
{
TCGv tmp = tcg_const_i32(addend);
tcg_gen_helper_frob(tmp, tmp, base)
return tmp;
}
or should this be written as:
static TCGv do_frob(TCGv base, int addend)
{
TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_movi_i32(tmp, addend);
tcg_gen_helper_frob(tmp, tmp, base)
return tmp;
}
Currently it's fairly hard to enforce this restriction automatically, but we
need to decide whether it's a feature or a bug.
Paul
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants
2008-05-23 18:03 ` Paul Brook
@ 2008-05-23 18:27 ` Fabrice Bellard
0 siblings, 0 replies; 4+ messages in thread
From: Fabrice Bellard @ 2008-05-23 18:27 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook
I will update the TCG documentation soon to explain it and other
modifications I am about to do.
In short, tcg_const() is now exactly equivalent to a temporary, hence it
should be freed. Freeing temporaries is useful to reduce translation
time and memory usage. However it has little consequences on the quality
of the generated code.
Fabrice.
Paul Brook wrote:
>> added tcg_temp_free() and improved the handling of constants
>
> Should the return value of tcg_const_i32 et. al. be considered immutable, or
> is it ok to use it as a temporary?
>
> e.g.:
>
> static TCGv do_frob(TCGv base, int addend)
> {
> TCGv tmp = tcg_const_i32(addend);
> tcg_gen_helper_frob(tmp, tmp, base)
> return tmp;
> }
>
> or should this be written as:
>
> static TCGv do_frob(TCGv base, int addend)
> {
> TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
> tcg_gen_movi_i32(tmp, addend);
> tcg_gen_helper_frob(tmp, tmp, base)
> return tmp;
> }
>
> Currently it's fairly hard to enforce this restriction automatically, but we
> need to decide whether it's a feature or a bug.
>
> Paul
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants
2008-05-23 17:33 [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants Fabrice Bellard
2008-05-23 18:03 ` Paul Brook
@ 2008-05-30 18:59 ` Blue Swirl
1 sibling, 0 replies; 4+ messages in thread
From: Blue Swirl @ 2008-05-30 18:59 UTC (permalink / raw)
To: qemu-devel
On 5/23/08, Fabrice Bellard <fabrice@bellard.org> wrote:
> Revision: 4544
> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4544
> Author: bellard
> Date: 2008-05-23 17:33:39 +0000 (Fri, 23 May 2008)
>
> Log Message:
> -----------
> added tcg_temp_free() and improved the handling of constants
>
> Modified Paths:
> --------------
> trunk/tcg/tcg-op.h
> trunk/tcg/tcg.c
> trunk/tcg/tcg.h
This commit broke sparc64-linux-user on i386 host.
The error can be reproduced for example:
./obj-i386/sparc64-linux-user/qemu-sparc64 -L ../sparc64 ../sash -h
/src/qemu/tcg/tcg.c:1700: tcg fatal error
While the expected output is:
Stand-alone shell (version 3.7)
Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-05-30 18:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-23 17:33 [Qemu-devel] [4544] added tcg_temp_free() and improved the handling of constants Fabrice Bellard
2008-05-23 18:03 ` Paul Brook
2008-05-23 18:27 ` Fabrice Bellard
2008-05-30 18:59 ` Blue Swirl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).