@@ -1808,6 +1808,16 @@ static inline void tcg_gen_discard_i64(TCGv_i64 arg)
#endif
}
+static inline void tcg_gen_discard_v128(TCGv_v128 arg)
+{
+ tcg_gen_op1_v128(INDEX_op_discard, arg);
+}
+
+static inline void tcg_gen_sync_temp_v128(TCGv_v128 arg)
+{
+ tcg_gen_op1_v128(INDEX_op_sync_temp, arg);
+}
+
static inline void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
if (TCG_TARGET_HAS_andc_i32) {
@@ -37,6 +37,7 @@ DEF(nop3, 0, 0, 3, TCG_OPF_NOT_PRESENT)
DEF(nopn, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT)
+DEF(sync_temp, 0, 1, 0, TCG_OPF_NOT_PRESENT)
DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
/* variable number of parameters */
@@ -1553,6 +1553,11 @@ static void tcg_liveness_analysis(TCGContext *s)
dead_temps[args[0]] = 1;
mem_temps[args[0]] = 0;
break;
+ case INDEX_op_sync_temp:
+ args--;
+ dead_temps[args[0]] = 1;
+ mem_temps[args[0]] = 1;
+ break;
case INDEX_op_end:
break;
@@ -2527,6 +2532,13 @@ static inline int tcg_gen_code_common(TCGContext *s,
case INDEX_op_discard:
temp_dead(s, args[0]);
break;
+ case INDEX_op_sync_temp:
+ /* We use it only for globals currently. */
+ assert(args[0] < s->nb_globals);
+ if (s->temps[args[0]].val_type == TEMP_VAL_REG) {
+ tcg_reg_free(s, s->temps[args[0]].reg);
+ }
+ break;
case INDEX_op_set_label:
tcg_reg_alloc_bb_end(s, s->reserved_regs);
tcg_out_label(s, args[0], s->code_ptr);
Currently every field of CPUArchState can be accessed from the TCG-generated code as a memory location or as a global but not both. In order to be able to mix these two approaches we need to restore consistency between value of global (possibly kept on register) and value in corresponding memory location. Introduce sync_temp TCGOpcode which instructs register allocator to save value of a global into its memory location. Signed-off-by: Kirill Batuzov <batuzovk@ispras.ru> --- tcg/tcg-op.h | 10 ++++++++++ tcg/tcg-opc.h | 1 + tcg/tcg.c | 12 ++++++++++++ 3 files changed, 23 insertions(+)