int done_mac;
int writeback_mask;
TCGv writeback[8];
-#define MAX_TO_RELEASE 8
- int release_count;
- TCGv release[MAX_TO_RELEASE];
bool ss_active;
} 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 mark_to_release(s, gen_load(s, opsize, addr,
- what == EA_LOADS, index));
+ return gen_load(s, opsize, addr, what == EA_LOADS, index);
}
}
} else {
bd = 0;
}
- tmp = mark_to_release(s, tcg_temp_new());
+ tmp = 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 = mark_to_release(s, tcg_const_i32(offset + bd));
+ base = tcg_const_i32(offset + bd);
bd = 0;
}
if (!IS_NULL_QREG(add)) {
add = tmp;
}
} else {
- add = mark_to_release(s, tcg_const_i32(bd));
+ add = tcg_const_i32(bd);
}
if ((ext & 3) != 0) {
/* memory indirect */
- base = mark_to_release(s, gen_load(s, OS_LONG, add, 0, IS_USER(s)));
+ base = 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 = mark_to_release(s, tcg_temp_new());
+ tmp = 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 = mark_to_release(s, tcg_temp_new());
+ tmp = tcg_temp_new();
gen_ext(tmp, val, opsize, sign);
}
return NULL_QREG;
}
reg = get_areg(s, reg0);
- tmp = mark_to_release(s, tcg_temp_new());
+ tmp = tcg_temp_new();
if (reg0 == 7 && opsize == OS_BYTE &&
m68k_feature(s->env, M68K_FEATURE_M68K)) {
tcg_gen_subi_i32(tmp, reg, 2);
return tmp;
case 5: /* Indirect displacement. */
reg = get_areg(s, reg0);
- tmp = mark_to_release(s, tcg_temp_new());
+ tmp = 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 mark_to_release(s, tcg_const_i32(offset));
+ return tcg_const_i32(offset);
case 1: /* Absolute long. */
offset = read_im32(env, s);
- return mark_to_release(s, tcg_const_i32(offset));
+ return tcg_const_i32(offset);
case 2: /* pc displacement */
offset = s->pc;
offset += (int16_t)read_im16(env, s);
- return mark_to_release(s, tcg_const_i32(offset));
+ return 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 mark_to_release(s, tcg_const_i32(offset));
+ return tcg_const_i32(offset);
default:
return NULL_QREG;
}
typedef struct {
TCGCond tcond;
- bool g1;
- bool g2;
TCGv v1;
TCGv v2;
} DisasCompare;
/* The CC_OP_CMP form can handle most normal comparisons directly. */
if (op == CC_OP_CMPB || op == CC_OP_CMPW || op == CC_OP_CMPL) {
- c->g1 = c->g2 = 1;
c->v1 = QREG_CC_N;
c->v2 = QREG_CC_V;
switch (cond) {
goto done;
case 10: /* PL */
case 11: /* MI */
- c->g1 = c->g2 = 0;
c->v2 = tcg_const_i32(0);
c->v1 = tmp = tcg_temp_new();
tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V);
}
}
- c->g1 = 1;
- c->g2 = 0;
c->v2 = tcg_const_i32(0);
switch (cond) {
case 2: /* HI (!C && !Z) -> !(C || Z)*/
case 3: /* LS (C || Z) */
c->v1 = tmp = tcg_temp_new();
- c->g1 = 0;
tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
tcg_gen_or_i32(tmp, tmp, QREG_CC_C);
tcond = TCG_COND_NE;
case 12: /* GE (!(N ^ V)) */
case 13: /* LT (N ^ V) */
c->v1 = tmp = tcg_temp_new();
- c->g1 = 0;
tcg_gen_xor_i32(tmp, QREG_CC_N, QREG_CC_V);
tcond = TCG_COND_LT;
break;
case 14: /* GT (!(Z || (N ^ V))) */
case 15: /* LE (Z || (N ^ V)) */
c->v1 = tmp = tcg_temp_new();
- c->g1 = 0;
tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
tcg_gen_neg_i32(tmp, tmp);
tmp2 = tcg_temp_new();
c->tcond = tcond;
}
-static void free_cond(DisasCompare *c)
-{
- if (!c->g1) {
- tcg_temp_free(c->v1);
- }
- if (!c->g2) {
- tcg_temp_free(c->v2);
- }
-}
-
static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
{
DisasCompare c;
gen_cc_cond(&c, s, cond);
update_cc_op(s);
tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
- free_cond(&c);
}
/* Force a TB lookup after an instruction that changes the CPU state. */
tmp = tcg_temp_new();
tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
- free_cond(&c);
tcg_gen_neg_i32(tmp, tmp);
DEST_EA(env, insn, OS_BYTE, tmp, NULL);
s->base.is_jmp = DISAS_NEXT;
}
}
- free_cond(c);
}
DISAS_INSN(trapcc)
{
TCGv fpsr;
- c->g1 = 1;
c->v2 = tcg_const_i32(0);
- c->g2 = 0;
/* TODO: Raise BSUN exception. */
fpsr = tcg_temp_new();
gen_load_fcr(s, fpsr, M68K_FPSR);
case 1: /* EQual Z */
case 17: /* Signaling EQual Z */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
c->tcond = TCG_COND_NE;
break;
case 2: /* Ordered Greater Than !(A || Z || N) */
case 18: /* Greater Than !(A || Z || N) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr,
FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
c->tcond = TCG_COND_EQ;
case 3: /* Ordered Greater than or Equal Z || !(A || N) */
case 19: /* Greater than or Equal Z || !(A || N) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
case 4: /* Ordered Less Than !(!N || A || Z); */
case 20: /* Less Than !(!N || A || Z); */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
c->tcond = TCG_COND_EQ;
case 5: /* Ordered Less than or Equal Z || (N && !A) */
case 21: /* Less than or Equal Z || (N && !A) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
tcg_gen_andc_i32(c->v1, fpsr, c->v1);
case 6: /* Ordered Greater or Less than !(A || Z) */
case 22: /* Greater or Less than !(A || Z) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
c->tcond = TCG_COND_EQ;
break;
case 7: /* Ordered !A */
case 23: /* Greater, Less or Equal !A */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
c->tcond = TCG_COND_EQ;
break;
case 8: /* Unordered A */
case 24: /* Not Greater, Less or Equal A */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
c->tcond = TCG_COND_NE;
break;
case 9: /* Unordered or Equal A || Z */
case 25: /* Not Greater or Less then A || Z */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
c->tcond = TCG_COND_NE;
break;
case 10: /* Unordered or Greater Than A || !(N || Z)) */
case 26: /* Not Less or Equal A || !(N || Z)) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_A | FPSR_CC_N);
case 11: /* Unordered or Greater or Equal A || Z || !N */
case 27: /* Not Less Than A || Z || !N */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
c->tcond = TCG_COND_NE;
case 12: /* Unordered or Less Than A || (N && !Z) */
case 28: /* Not Greater than or Equal A || (N && !Z) */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
tcg_gen_andc_i32(c->v1, fpsr, c->v1);
case 13: /* Unordered or Less or Equal A || Z || N */
case 29: /* Not Greater Than A || Z || N */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
c->tcond = TCG_COND_NE;
break;
case 14: /* Not Equal !Z */
case 30: /* Signaling Not Equal !Z */
c->v1 = tcg_temp_new();
- c->g1 = 0;
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
c->tcond = TCG_COND_EQ;
break;
gen_fcc_cond(&c, s, cond);
update_cc_op(s);
tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
- free_cond(&c);
}
DISAS_INSN(fbcc)
tmp = tcg_temp_new();
tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
- free_cond(&c);
tcg_gen_neg_i32(tmp, tmp);
DEST_EA(env, insn, OS_BYTE, tmp, NULL);
dc->cc_op_synced = 1;
dc->done_mac = 0;
dc->writeback_mask = 0;
- init_release_array(dc);
dc->ss_active = (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS);
/* If architectural single step active, limit to 1 */
opcode_table[insn](env, dc, insn);
do_writebacks(dc);
- do_release(dc);
dc->pc_prev = dc->base.pc_next;
dc->base.pc_next = dc->pc;