|
|
|
@ -428,10 +428,23 @@ static inline void gen_flush_flags(DisasContext *s) |
|
|
|
s->cc_op = CC_OP_FLAGS; |
|
|
|
} |
|
|
|
|
|
|
|
static void gen_logic_cc(DisasContext *s, TCGv val) |
|
|
|
#define SET_CC_OP(opsize, op) do { \ |
|
|
|
switch (opsize) { \ |
|
|
|
case OS_BYTE: \ |
|
|
|
s->cc_op = CC_OP_##op##B; break; \ |
|
|
|
case OS_WORD: \ |
|
|
|
s->cc_op = CC_OP_##op##W; break; \ |
|
|
|
case OS_LONG: \ |
|
|
|
s->cc_op = CC_OP_##op; break; \ |
|
|
|
default: \ |
|
|
|
abort(); \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
static void gen_logic_cc(DisasContext *s, TCGv val, int opsize) |
|
|
|
{ |
|
|
|
tcg_gen_mov_i32(QREG_CC_DEST, val); |
|
|
|
s->cc_op = CC_OP_LOGIC; |
|
|
|
SET_CC_OP(opsize, LOGIC); |
|
|
|
} |
|
|
|
|
|
|
|
static void gen_update_cc_add(TCGv dest, TCGv src) |
|
|
|
@ -933,8 +946,7 @@ DISAS_INSN(mulw) |
|
|
|
SRC_EA(env, src, OS_WORD, sign, NULL); |
|
|
|
tcg_gen_mul_i32(tmp, tmp, src); |
|
|
|
tcg_gen_mov_i32(reg, tmp); |
|
|
|
/* Unlike m68k, coldfire always clears the overflow bit. */ |
|
|
|
gen_logic_cc(s, tmp); |
|
|
|
gen_logic_cc(s, tmp, OS_WORD); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(divw) |
|
|
|
@ -1103,7 +1115,7 @@ DISAS_INSN(sats) |
|
|
|
reg = DREG(insn, 0); |
|
|
|
gen_flush_flags(s); |
|
|
|
gen_helper_sats(reg, reg, QREG_CC_DEST); |
|
|
|
gen_logic_cc(s, reg); |
|
|
|
gen_logic_cc(s, reg, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
static void gen_push(DisasContext *s, TCGv val) |
|
|
|
@ -1228,11 +1240,11 @@ DISAS_INSN(arith_im) |
|
|
|
switch (op) { |
|
|
|
case 0: /* ori */ |
|
|
|
tcg_gen_ori_i32(dest, src1, im); |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
break; |
|
|
|
case 1: /* andi */ |
|
|
|
tcg_gen_andi_i32(dest, src1, im); |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
break; |
|
|
|
case 2: /* subi */ |
|
|
|
tcg_gen_mov_i32(dest, src1); |
|
|
|
@ -1250,7 +1262,7 @@ DISAS_INSN(arith_im) |
|
|
|
break; |
|
|
|
case 5: /* eori */ |
|
|
|
tcg_gen_xori_i32(dest, src1, im); |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
break; |
|
|
|
case 6: /* cmpi */ |
|
|
|
tcg_gen_mov_i32(dest, src1); |
|
|
|
@ -1307,7 +1319,7 @@ DISAS_INSN(move) |
|
|
|
dest_ea = ((insn >> 9) & 7) | (op << 3); |
|
|
|
DEST_EA(env, dest_ea, opsize, src, NULL); |
|
|
|
/* This will be correct because loads sign extend. */ |
|
|
|
gen_logic_cc(s, src); |
|
|
|
gen_logic_cc(s, src, opsize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1340,7 +1352,7 @@ DISAS_INSN(clr) |
|
|
|
|
|
|
|
opsize = insn_opsize(insn); |
|
|
|
DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL); |
|
|
|
gen_logic_cc(s, tcg_const_i32(0)); |
|
|
|
gen_logic_cc(s, tcg_const_i32(0), opsize); |
|
|
|
} |
|
|
|
|
|
|
|
static TCGv gen_get_ccr(DisasContext *s) |
|
|
|
@ -1427,7 +1439,7 @@ DISAS_INSN(not) |
|
|
|
|
|
|
|
reg = DREG(insn, 0); |
|
|
|
tcg_gen_not_i32(reg, reg); |
|
|
|
gen_logic_cc(s, reg); |
|
|
|
gen_logic_cc(s, reg, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(swap) |
|
|
|
@ -1442,7 +1454,7 @@ DISAS_INSN(swap) |
|
|
|
tcg_gen_shli_i32(src1, reg, 16); |
|
|
|
tcg_gen_shri_i32(src2, reg, 16); |
|
|
|
tcg_gen_or_i32(reg, src1, src2); |
|
|
|
gen_logic_cc(s, reg); |
|
|
|
gen_logic_cc(s, reg, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(pea) |
|
|
|
@ -1474,7 +1486,7 @@ DISAS_INSN(ext) |
|
|
|
gen_partset_reg(OS_WORD, reg, tmp); |
|
|
|
else |
|
|
|
tcg_gen_mov_i32(reg, tmp); |
|
|
|
gen_logic_cc(s, tmp); |
|
|
|
gen_logic_cc(s, tmp, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(tst) |
|
|
|
@ -1484,7 +1496,7 @@ DISAS_INSN(tst) |
|
|
|
|
|
|
|
opsize = insn_opsize(insn); |
|
|
|
SRC_EA(env, tmp, opsize, 1, NULL); |
|
|
|
gen_logic_cc(s, tmp); |
|
|
|
gen_logic_cc(s, tmp, opsize); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(pulse) |
|
|
|
@ -1506,7 +1518,7 @@ DISAS_INSN(tas) |
|
|
|
|
|
|
|
dest = tcg_temp_new(); |
|
|
|
SRC_EA(env, src1, OS_BYTE, 1, &addr); |
|
|
|
gen_logic_cc(s, src1); |
|
|
|
gen_logic_cc(s, src1, OS_BYTE); |
|
|
|
tcg_gen_ori_i32(dest, src1, 0x80); |
|
|
|
DEST_EA(env, insn, OS_BYTE, dest, &addr); |
|
|
|
} |
|
|
|
@ -1531,7 +1543,7 @@ DISAS_INSN(mull) |
|
|
|
tcg_gen_mul_i32(dest, src1, reg); |
|
|
|
tcg_gen_mov_i32(reg, dest); |
|
|
|
/* Unlike m68k, coldfire always clears the overflow bit. */ |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(link) |
|
|
|
@ -1689,7 +1701,7 @@ DISAS_INSN(moveq) |
|
|
|
|
|
|
|
val = (int8_t)insn; |
|
|
|
tcg_gen_movi_i32(DREG(insn, 9), val); |
|
|
|
gen_logic_cc(s, tcg_const_i32(val)); |
|
|
|
gen_logic_cc(s, tcg_const_i32(val), OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(mvzs) |
|
|
|
@ -1705,7 +1717,7 @@ DISAS_INSN(mvzs) |
|
|
|
SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL); |
|
|
|
reg = DREG(insn, 9); |
|
|
|
tcg_gen_mov_i32(reg, src); |
|
|
|
gen_logic_cc(s, src); |
|
|
|
gen_logic_cc(s, src, opsize); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(or) |
|
|
|
@ -1726,7 +1738,7 @@ DISAS_INSN(or) |
|
|
|
tcg_gen_or_i32(dest, src, reg); |
|
|
|
tcg_gen_mov_i32(reg, dest); |
|
|
|
} |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(suba) |
|
|
|
@ -1759,40 +1771,24 @@ DISAS_INSN(mov3q) |
|
|
|
if (val == 0) |
|
|
|
val = -1; |
|
|
|
src = tcg_const_i32(val); |
|
|
|
gen_logic_cc(s, src); |
|
|
|
gen_logic_cc(s, src, OS_LONG); |
|
|
|
DEST_EA(env, insn, OS_LONG, src, NULL); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(cmp) |
|
|
|
{ |
|
|
|
int op; |
|
|
|
TCGv src; |
|
|
|
TCGv reg; |
|
|
|
TCGv dest; |
|
|
|
int opsize; |
|
|
|
|
|
|
|
op = (insn >> 6) & 3; |
|
|
|
switch (op) { |
|
|
|
case 0: /* cmp.b */ |
|
|
|
opsize = OS_BYTE; |
|
|
|
s->cc_op = CC_OP_CMPB; |
|
|
|
break; |
|
|
|
case 1: /* cmp.w */ |
|
|
|
opsize = OS_WORD; |
|
|
|
s->cc_op = CC_OP_CMPW; |
|
|
|
break; |
|
|
|
case 2: /* cmp.l */ |
|
|
|
opsize = OS_LONG; |
|
|
|
s->cc_op = CC_OP_SUB; |
|
|
|
break; |
|
|
|
default: |
|
|
|
abort(); |
|
|
|
} |
|
|
|
SRC_EA(env, src, opsize, 1, NULL); |
|
|
|
opsize = insn_opsize(insn); |
|
|
|
SRC_EA(env, src, opsize, -1, NULL); |
|
|
|
reg = DREG(insn, 9); |
|
|
|
dest = tcg_temp_new(); |
|
|
|
tcg_gen_sub_i32(dest, reg, src); |
|
|
|
gen_update_cc_add(dest, src); |
|
|
|
SET_CC_OP(opsize, SUB); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(cmpa) |
|
|
|
@ -1812,7 +1808,7 @@ DISAS_INSN(cmpa) |
|
|
|
dest = tcg_temp_new(); |
|
|
|
tcg_gen_sub_i32(dest, reg, src); |
|
|
|
gen_update_cc_add(dest, src); |
|
|
|
s->cc_op = CC_OP_SUB; |
|
|
|
SET_CC_OP(OS_LONG, SUB); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(eor) |
|
|
|
@ -1826,7 +1822,7 @@ DISAS_INSN(eor) |
|
|
|
reg = DREG(insn, 9); |
|
|
|
dest = tcg_temp_new(); |
|
|
|
tcg_gen_xor_i32(dest, src, reg); |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
DEST_EA(env, insn, OS_LONG, dest, &addr); |
|
|
|
} |
|
|
|
|
|
|
|
@ -1848,7 +1844,7 @@ DISAS_INSN(and) |
|
|
|
tcg_gen_and_i32(dest, src, reg); |
|
|
|
tcg_gen_mov_i32(reg, dest); |
|
|
|
} |
|
|
|
gen_logic_cc(s, dest); |
|
|
|
gen_logic_cc(s, dest, OS_LONG); |
|
|
|
} |
|
|
|
|
|
|
|
DISAS_INSN(adda) |
|
|
|
@ -1923,7 +1919,7 @@ DISAS_INSN(ff1) |
|
|
|
{ |
|
|
|
TCGv reg; |
|
|
|
reg = DREG(insn, 0); |
|
|
|
gen_logic_cc(s, reg); |
|
|
|
gen_logic_cc(s, reg, OS_LONG); |
|
|
|
gen_helper_ff1(reg, reg); |
|
|
|
} |
|
|
|
|
|
|
|
|