int done_mac;
int writeback_mask;
TCGv writeback[8];
+#define MAX_TO_RELEASE 8
+ int release_count;
+ TCGv release[MAX_TO_RELEASE];
} DisasContext;
+static void init_release_array(DisasContext *s)
+{
+#ifdef CONFIG_DEBUG_TCG
+ memset(s->release, 0, sizeof(s->release));
+#endif
+ s->release_count = 0;
+}
+
+static void do_release(DisasContext *s)
+{
+ int i;
+ for (i = 0; i < s->release_count; i++) {
+ tcg_temp_free(s->release[i]);
+ }
+ init_release_array(s);
+}
+
+static TCGv mark_to_release(DisasContext *s, TCGv tmp)
+{
+ g_assert(s->release_count < MAX_TO_RELEASE);
+ return s->release[s->release_count++] = tmp;
+}
+
static TCGv get_areg(DisasContext *s, unsigned regno)
{
if (s->writeback_mask & (1 << regno)) {
gen_store(s, opsize, addr, val, index);
return store_dummy;
} else {
- return gen_load(s, opsize, addr, what == EA_LOADS, index);
+ return mark_to_release(s, gen_load(s, opsize, addr,
+ what == EA_LOADS, index));
}
}
} else {
bd = 0;
}
- tmp = tcg_temp_new();
+ tmp = mark_to_release(s, tcg_temp_new());
if ((ext & 0x44) == 0) {
/* pre-index */
add = gen_addr_index(s, ext, tmp);
if ((ext & 0x80) == 0) {
/* base not suppressed */
if (IS_NULL_QREG(base)) {
- base = tcg_const_i32(offset + bd);
+ base = mark_to_release(s, tcg_const_i32(offset + bd));
bd = 0;
}
if (!IS_NULL_QREG(add)) {
add = tmp;
}
} else {
- add = tcg_const_i32(bd);
+ add = mark_to_release(s, tcg_const_i32(bd));
}
if ((ext & 3) != 0) {
/* memory indirect */
- base = gen_load(s, OS_LONG, add, 0, IS_USER(s));
+ base = mark_to_release(s, gen_load(s, OS_LONG, add, 0, IS_USER(s)));
if ((ext & 0x44) == 4) {
add = gen_addr_index(s, ext, tmp);
tcg_gen_add_i32(tmp, add, base);
}
} else {
/* brief extension word format */
- tmp = tcg_temp_new();
+ tmp = mark_to_release(s, tcg_temp_new());
add = gen_addr_index(s, ext, tmp);
if (!IS_NULL_QREG(base)) {
tcg_gen_add_i32(tmp, add, base);
if (opsize == OS_LONG) {
tmp = val;
} else {
- tmp = tcg_temp_new();
+ tmp = mark_to_release(s, tcg_temp_new());
gen_ext(tmp, val, opsize, sign);
}
return NULL_QREG;
}
reg = get_areg(s, reg0);
- tmp = tcg_temp_new();
+ tmp = mark_to_release(s, tcg_temp_new());
if (reg0 == 7 && opsize == OS_BYTE &&
m68k_feature(s->env, M68K_FEATURE_M68000)) {
tcg_gen_subi_i32(tmp, reg, 2);
return tmp;
case 5: /* Indirect displacement. */
reg = get_areg(s, reg0);
- tmp = tcg_temp_new();
+ tmp = mark_to_release(s, tcg_temp_new());
ext = read_im16(env, s);
tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
return tmp;
switch (reg0) {
case 0: /* Absolute short. */
offset = (int16_t)read_im16(env, s);
- return tcg_const_i32(offset);
+ return mark_to_release(s, tcg_const_i32(offset));
case 1: /* Absolute long. */
offset = read_im32(env, s);
- return tcg_const_i32(offset);
+ return mark_to_release(s, tcg_const_i32(offset));
case 2: /* pc displacement */
offset = s->pc;
offset += (int16_t)read_im16(env, s);
- return tcg_const_i32(offset);
+ return mark_to_release(s, tcg_const_i32(offset));
case 3: /* pc index+displacement. */
return gen_lea_indexed(env, s, NULL_QREG);
case 4: /* Immediate. */
default:
g_assert_not_reached();
}
- return tcg_const_i32(offset);
+ return mark_to_release(s, tcg_const_i32(offset));
default:
return NULL_QREG;
}
uint16_t insn = read_im16(env, s);
opcode_table[insn](env, s, insn);
do_writebacks(s);
+ do_release(s);
}
/* generate intermediate code for basic block 'tb'. */
max_insns = TCG_MAX_INSNS;
}
+ init_release_array(dc);
+
gen_tb_start(tb);
do {
pc_offset = dc->pc - pc_start;