diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-23 17:33:39 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-23 17:33:39 +0000 |
commit | e8996ee012e957cf8456d41ee6a7bbaf1f9b888b (patch) | |
tree | e5adc099e59c63196813379f76102faa33d8a39b | |
parent | d7e4036e317f75884513252acbf7eece54fc2ff5 (diff) |
added tcg_temp_free() and improved the handling of constants
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4544 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | tcg/tcg-op.h | 164 | ||||
-rw-r--r-- | tcg/tcg.c | 450 | ||||
-rw-r--r-- | tcg/tcg.h | 11 |
3 files changed, 396 insertions, 229 deletions
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index b92b7bd162..469e444d5c 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -178,88 +178,115 @@ static inline void tcg_gen_movi_i32(TCGv ret, int32_t arg) 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 @@ static inline void tcg_gen_helper_1_4(void *func, TCGv ret, 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 @@ static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2) 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 @@ static inline void tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2) 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 @@ static inline void tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2) } 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 @@ static inline void tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2) } 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 @@ static inline void tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2) 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 @@ static inline void tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2) 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 @@ static inline void tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2) 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 @@ static inline void tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2) 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_mul_i32(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2) 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_add_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_add_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_and_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_or_i64(TCGv ret, TCGv arg1, TCGv arg2) 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_xor_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2) 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 @@ static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2) 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 @@ static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2) 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_mul_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2) 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 @@ static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg) 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 @@ static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg) 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 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) 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 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) 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 @@ static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg) #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 @@ static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg) #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) @@ -266,8 +266,11 @@ void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func) 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 @@ TCGv tcg_global_reg_new(TCGType type, int reg, const char *name) 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 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, 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 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, 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 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, #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 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, #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 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, 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 @@ TCGv tcg_temp_new(TCGType type) 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_i64(int64_t val) + +TCGv tcg_const_i32(int32_t val) { - TCGContext *s = &tcg_ctx; - TCGTemp *ts; - int idx; + TCGv t0; + t0 = tcg_temp_new(TCG_TYPE_I32); + tcg_gen_movi_i32(t0, val); + return t0; +} - 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 tcg_const_i64(int64_t val) +{ + 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 @@ void tcg_gen_shifti_i64(TCGv ret, TCGv arg1, 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 @@ void tcg_reg_alloc_start(TCGContext *s) 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 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, 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 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg) 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 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) /* 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 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) 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 @@ static void check_regs(TCGContext *s) 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 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) } /* 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 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, 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 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, } 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 @@ static void tcg_reg_alloc_op(TCGContext *s, 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 @@ static void tcg_reg_alloc_op(TCGContext *s, 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; + 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; } - 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 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 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 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 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 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 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 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, /* 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 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 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 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, 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 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, 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 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, /* 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 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #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; @@ -98,6 +98,7 @@ typedef int TCGType; #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 @@ typedef struct TCGTemp { 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 @@ struct TCGContext { 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 @@ struct TCGContext { TCGHelperInfo *helpers; int nb_helpers; int allocated_helpers; + int helpers_sorted; #ifdef CONFIG_PROFILER /* profiling info */ @@ -299,6 +306,7 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, 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 @@ TCGv tcg_const_i64(int64_t val); 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); |