Loading target-m68k/cpu.h +3 −3 Original line number Diff line number Diff line Loading @@ -179,11 +179,11 @@ typedef enum { CC_OP_FLAGS, /* X in cc_x, C = X, N in cc_n, Z in cc_n, V via cc_n/cc_v. */ CC_OP_ADD, CC_OP_SUB, CC_OP_ADDB, CC_OP_ADDW, CC_OP_ADDL, CC_OP_SUBB, CC_OP_SUBW, CC_OP_SUBL, /* X in cc_x, {N,Z,C,V} via cc_n/cc_v. */ CC_OP_CMP, CC_OP_CMPB, CC_OP_CMPW, CC_OP_CMPL, /* X in cc_x, C = 0, V = 0, N in cc_n, Z in cc_n. */ CC_OP_LOGIC, Loading target-m68k/helper.c +17 −8 Original line number Diff line number Diff line Loading @@ -584,32 +584,41 @@ void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc) } } #define EXTSIGN(val, index) ( \ (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \ ) #define COMPUTE_CCR(op, x, n, z, v, c) { \ switch (op) { \ case CC_OP_FLAGS: \ /* Everything in place. */ \ break; \ case CC_OP_ADD: \ case CC_OP_ADDB: \ case CC_OP_ADDW: \ case CC_OP_ADDL: \ res = n; \ src2 = v; \ src1 = res - src2; \ src1 = EXTSIGN(res - src2, op - CC_OP_ADDB); \ c = x; \ z = n; \ v = (res ^ src1) & ~(src1 ^ src2); \ break; \ case CC_OP_SUB: \ case CC_OP_SUBB: \ case CC_OP_SUBW: \ case CC_OP_SUBL: \ res = n; \ src2 = v; \ src1 = res + src2; \ src1 = EXTSIGN(res + src2, op - CC_OP_SUBB); \ c = x; \ z = n; \ v = (res ^ src1) & (src1 ^ src2); \ break; \ case CC_OP_CMP: \ case CC_OP_CMPB: \ case CC_OP_CMPW: \ case CC_OP_CMPL: \ src1 = n; \ src2 = v; \ res = src1 - src2; \ res = EXTSIGN(src1 - src2, op - CC_OP_CMPB); \ n = res; \ z = res; \ c = src1 < src2; \ Loading @@ -630,16 +639,16 @@ uint32_t cpu_m68k_get_ccr(CPUM68KState *env) uint32_t res, src1, src2; x = env->cc_x; c = env->cc_c; n = env->cc_n; z = env->cc_z; v = env->cc_v; c = env->cc_c; COMPUTE_CCR(env->cc_op, x, n, z, v, c); n = n >> 31; v = v >> 31; z = (z == 0); v = v >> 31; return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C; } Loading target-m68k/translate.c +73 −58 Original line number Diff line number Diff line Loading @@ -178,9 +178,9 @@ typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn); static const uint8_t cc_op_live[CC_OP_NB] = { [CC_OP_FLAGS] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X, [CC_OP_ADD] = CCF_X | CCF_N | CCF_V, [CC_OP_SUB] = CCF_X | CCF_N | CCF_V, [CC_OP_CMP] = CCF_X | CCF_N | CCF_V, [CC_OP_ADDB ... CC_OP_ADDL] = CCF_X | CCF_N | CCF_V, [CC_OP_SUBB ... CC_OP_SUBL] = CCF_X | CCF_N | CCF_V, [CC_OP_CMPB ... CC_OP_CMPL] = CCF_X | CCF_N | CCF_V, [CC_OP_LOGIC] = CCF_X | CCF_N }; Loading Loading @@ -454,6 +454,33 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) return add; } /* Sign or zero extend a value. */ static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign) { switch (opsize) { case OS_BYTE: if (sign) { tcg_gen_ext8s_i32(res, val); } else { tcg_gen_ext8u_i32(res, val); } break; case OS_WORD: if (sign) { tcg_gen_ext16s_i32(res, val); } else { tcg_gen_ext16u_i32(res, val); } break; case OS_LONG: tcg_gen_mov_i32(res, val); break; default: g_assert_not_reached(); } } /* Evaluate all the CC flags. */ static void gen_flush_flags(DisasContext *s) Loading @@ -464,13 +491,16 @@ static void gen_flush_flags(DisasContext *s) case CC_OP_FLAGS: return; case CC_OP_ADD: case CC_OP_ADDB: case CC_OP_ADDW: case CC_OP_ADDL: tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); /* Compute signed overflow for addition. */ t0 = tcg_temp_new(); t1 = tcg_temp_new(); tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V); gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1); tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); tcg_temp_free(t0); Loading @@ -478,13 +508,16 @@ static void gen_flush_flags(DisasContext *s) tcg_temp_free(t1); break; case CC_OP_SUB: case CC_OP_SUBB: case CC_OP_SUBW: case CC_OP_SUBL: tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); /* Compute signed overflow for subtraction. */ t0 = tcg_temp_new(); t1 = tcg_temp_new(); tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V); gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1); tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); tcg_temp_free(t0); Loading @@ -492,9 +525,12 @@ static void gen_flush_flags(DisasContext *s) tcg_temp_free(t1); break; case CC_OP_CMP: case CC_OP_CMPB: case CC_OP_CMPW: case CC_OP_CMPL: tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V); tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V); gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1); /* Compute signed overflow for subtraction. */ t0 = tcg_temp_new(); tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N); Loading Loading @@ -526,34 +562,7 @@ static void gen_flush_flags(DisasContext *s) s->cc_op_synced = 1; } /* Sign or zero extend a value. */ static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign) { switch (opsize) { case OS_BYTE: if (sign) { tcg_gen_ext8s_i32(res, val); } else { tcg_gen_ext8u_i32(res, val); } break; case OS_WORD: if (sign) { tcg_gen_ext16s_i32(res, val); } else { tcg_gen_ext16u_i32(res, val); } break; case OS_LONG: tcg_gen_mov_i32(res, val); break; default: g_assert_not_reached(); } } static TCGv gen_extend(TCGv val, int opsize, int sign) static inline TCGv gen_extend(TCGv val, int opsize, int sign) { TCGv tmp; Loading @@ -573,9 +582,9 @@ static void gen_logic_cc(DisasContext *s, TCGv val, int opsize) set_cc_op(s, CC_OP_LOGIC); } static void gen_update_cc_add(TCGv dest, TCGv src) static void gen_update_cc_add(TCGv dest, TCGv src, int opsize) { tcg_gen_mov_i32(QREG_CC_N, dest); gen_ext(QREG_CC_N, dest, opsize, 1); tcg_gen_mov_i32(QREG_CC_V, src); } Loading Loading @@ -822,7 +831,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) CCOp op = s->cc_op; /* The CC_OP_CMP form can handle most normal comparisons directly. */ if (op == CC_OP_CMP) { 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; Loading @@ -845,6 +854,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) c->v2 = tcg_const_i32(0); c->v1 = tmp = tcg_temp_new(); tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V); gen_ext(tmp, tmp, op - CC_OP_CMPB, 1); /* fallthru */ case 12: /* GE */ case 13: /* LT */ Loading Loading @@ -888,7 +898,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 10: /* PL (!N) */ case 11: /* MI (N) */ /* Several cases represent N normally. */ if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL || op == CC_OP_LOGIC) { c->v1 = QREG_CC_N; tcond = TCG_COND_LT; goto done; Loading @@ -897,7 +909,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 6: /* NE (!Z) */ case 7: /* EQ (Z) */ /* Some cases fold Z into N. */ if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL || op == CC_OP_LOGIC) { tcond = TCG_COND_EQ; c->v1 = QREG_CC_N; goto done; Loading @@ -906,7 +920,8 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 4: /* CC (!C) */ case 5: /* CS (C) */ /* Some cases fold C into X. */ if (op == CC_OP_ADD || op == CC_OP_SUB) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL) { tcond = TCG_COND_NE; c->v1 = QREG_CC_X; goto done; Loading Loading @@ -1252,13 +1267,13 @@ DISAS_INSN(addsub) if (add) { tcg_gen_add_i32(dest, tmp, src); tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); } else { tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src); tcg_gen_sub_i32(dest, tmp, src); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } gen_update_cc_add(dest, src); gen_update_cc_add(dest, src, OS_LONG); if (insn & 0x100) { DEST_EA(env, insn, OS_LONG, dest, &addr); } else { Loading Loading @@ -1459,23 +1474,23 @@ DISAS_INSN(arith_im) tcg_gen_mov_i32(dest, src1); tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im); tcg_gen_subi_i32(dest, dest, im); gen_update_cc_add(dest, tcg_const_i32(im)); set_cc_op(s, CC_OP_SUB); gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG); set_cc_op(s, CC_OP_SUBL); break; case 3: /* addi */ tcg_gen_mov_i32(dest, src1); tcg_gen_addi_i32(dest, dest, im); gen_update_cc_add(dest, tcg_const_i32(im)); gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG); tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); break; case 5: /* eori */ tcg_gen_xori_i32(dest, src1, im); gen_logic_cc(s, dest, OS_LONG); break; case 6: /* cmpi */ gen_update_cc_add(src1, tcg_const_i32(im)); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(src1, tcg_const_i32(im), OS_LONG); set_cc_op(s, CC_OP_CMPL); break; default: abort(); Loading Loading @@ -1623,9 +1638,9 @@ DISAS_INSN(neg) src1 = tcg_temp_new(); tcg_gen_mov_i32(src1, reg); tcg_gen_neg_i32(reg, src1); gen_update_cc_add(reg, src1); gen_update_cc_add(reg, src1, OS_LONG); tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, src1, 0); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) Loading Loading @@ -1895,13 +1910,13 @@ DISAS_INSN(addsubq) if (insn & 0x0100) { tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2); tcg_gen_sub_i32(dest, dest, src2); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } else { tcg_gen_add_i32(dest, dest, src2); tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); } gen_update_cc_add(dest, src2); gen_update_cc_add(dest, src2, OS_LONG); } DEST_EA(env, insn, OS_LONG, dest, &addr); } Loading Loading @@ -2105,8 +2120,8 @@ DISAS_INSN(cmp) opsize = insn_opsize(insn); SRC_EA(env, src, opsize, -1, NULL); reg = DREG(insn, 9); gen_update_cc_add(reg, src); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(reg, src, OS_LONG); set_cc_op(s, CC_OP_CMPL); } DISAS_INSN(cmpa) Loading @@ -2122,8 +2137,8 @@ DISAS_INSN(cmpa) } SRC_EA(env, src, opsize, 1, NULL); reg = AREG(insn, 9); gen_update_cc_add(reg, src); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(reg, src, OS_LONG); set_cc_op(s, CC_OP_CMPL); } DISAS_INSN(eor) Loading Loading
target-m68k/cpu.h +3 −3 Original line number Diff line number Diff line Loading @@ -179,11 +179,11 @@ typedef enum { CC_OP_FLAGS, /* X in cc_x, C = X, N in cc_n, Z in cc_n, V via cc_n/cc_v. */ CC_OP_ADD, CC_OP_SUB, CC_OP_ADDB, CC_OP_ADDW, CC_OP_ADDL, CC_OP_SUBB, CC_OP_SUBW, CC_OP_SUBL, /* X in cc_x, {N,Z,C,V} via cc_n/cc_v. */ CC_OP_CMP, CC_OP_CMPB, CC_OP_CMPW, CC_OP_CMPL, /* X in cc_x, C = 0, V = 0, N in cc_n, Z in cc_n. */ CC_OP_LOGIC, Loading
target-m68k/helper.c +17 −8 Original line number Diff line number Diff line Loading @@ -584,32 +584,41 @@ void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc) } } #define EXTSIGN(val, index) ( \ (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \ ) #define COMPUTE_CCR(op, x, n, z, v, c) { \ switch (op) { \ case CC_OP_FLAGS: \ /* Everything in place. */ \ break; \ case CC_OP_ADD: \ case CC_OP_ADDB: \ case CC_OP_ADDW: \ case CC_OP_ADDL: \ res = n; \ src2 = v; \ src1 = res - src2; \ src1 = EXTSIGN(res - src2, op - CC_OP_ADDB); \ c = x; \ z = n; \ v = (res ^ src1) & ~(src1 ^ src2); \ break; \ case CC_OP_SUB: \ case CC_OP_SUBB: \ case CC_OP_SUBW: \ case CC_OP_SUBL: \ res = n; \ src2 = v; \ src1 = res + src2; \ src1 = EXTSIGN(res + src2, op - CC_OP_SUBB); \ c = x; \ z = n; \ v = (res ^ src1) & (src1 ^ src2); \ break; \ case CC_OP_CMP: \ case CC_OP_CMPB: \ case CC_OP_CMPW: \ case CC_OP_CMPL: \ src1 = n; \ src2 = v; \ res = src1 - src2; \ res = EXTSIGN(src1 - src2, op - CC_OP_CMPB); \ n = res; \ z = res; \ c = src1 < src2; \ Loading @@ -630,16 +639,16 @@ uint32_t cpu_m68k_get_ccr(CPUM68KState *env) uint32_t res, src1, src2; x = env->cc_x; c = env->cc_c; n = env->cc_n; z = env->cc_z; v = env->cc_v; c = env->cc_c; COMPUTE_CCR(env->cc_op, x, n, z, v, c); n = n >> 31; v = v >> 31; z = (z == 0); v = v >> 31; return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C; } Loading
target-m68k/translate.c +73 −58 Original line number Diff line number Diff line Loading @@ -178,9 +178,9 @@ typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn); static const uint8_t cc_op_live[CC_OP_NB] = { [CC_OP_FLAGS] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X, [CC_OP_ADD] = CCF_X | CCF_N | CCF_V, [CC_OP_SUB] = CCF_X | CCF_N | CCF_V, [CC_OP_CMP] = CCF_X | CCF_N | CCF_V, [CC_OP_ADDB ... CC_OP_ADDL] = CCF_X | CCF_N | CCF_V, [CC_OP_SUBB ... CC_OP_SUBL] = CCF_X | CCF_N | CCF_V, [CC_OP_CMPB ... CC_OP_CMPL] = CCF_X | CCF_N | CCF_V, [CC_OP_LOGIC] = CCF_X | CCF_N }; Loading Loading @@ -454,6 +454,33 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) return add; } /* Sign or zero extend a value. */ static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign) { switch (opsize) { case OS_BYTE: if (sign) { tcg_gen_ext8s_i32(res, val); } else { tcg_gen_ext8u_i32(res, val); } break; case OS_WORD: if (sign) { tcg_gen_ext16s_i32(res, val); } else { tcg_gen_ext16u_i32(res, val); } break; case OS_LONG: tcg_gen_mov_i32(res, val); break; default: g_assert_not_reached(); } } /* Evaluate all the CC flags. */ static void gen_flush_flags(DisasContext *s) Loading @@ -464,13 +491,16 @@ static void gen_flush_flags(DisasContext *s) case CC_OP_FLAGS: return; case CC_OP_ADD: case CC_OP_ADDB: case CC_OP_ADDW: case CC_OP_ADDL: tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); /* Compute signed overflow for addition. */ t0 = tcg_temp_new(); t1 = tcg_temp_new(); tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V); gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1); tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); tcg_temp_free(t0); Loading @@ -478,13 +508,16 @@ static void gen_flush_flags(DisasContext *s) tcg_temp_free(t1); break; case CC_OP_SUB: case CC_OP_SUBB: case CC_OP_SUBW: case CC_OP_SUBL: tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); /* Compute signed overflow for subtraction. */ t0 = tcg_temp_new(); t1 = tcg_temp_new(); tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V); gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1); tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); tcg_temp_free(t0); Loading @@ -492,9 +525,12 @@ static void gen_flush_flags(DisasContext *s) tcg_temp_free(t1); break; case CC_OP_CMP: case CC_OP_CMPB: case CC_OP_CMPW: case CC_OP_CMPL: tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V); tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V); gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1); /* Compute signed overflow for subtraction. */ t0 = tcg_temp_new(); tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N); Loading Loading @@ -526,34 +562,7 @@ static void gen_flush_flags(DisasContext *s) s->cc_op_synced = 1; } /* Sign or zero extend a value. */ static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign) { switch (opsize) { case OS_BYTE: if (sign) { tcg_gen_ext8s_i32(res, val); } else { tcg_gen_ext8u_i32(res, val); } break; case OS_WORD: if (sign) { tcg_gen_ext16s_i32(res, val); } else { tcg_gen_ext16u_i32(res, val); } break; case OS_LONG: tcg_gen_mov_i32(res, val); break; default: g_assert_not_reached(); } } static TCGv gen_extend(TCGv val, int opsize, int sign) static inline TCGv gen_extend(TCGv val, int opsize, int sign) { TCGv tmp; Loading @@ -573,9 +582,9 @@ static void gen_logic_cc(DisasContext *s, TCGv val, int opsize) set_cc_op(s, CC_OP_LOGIC); } static void gen_update_cc_add(TCGv dest, TCGv src) static void gen_update_cc_add(TCGv dest, TCGv src, int opsize) { tcg_gen_mov_i32(QREG_CC_N, dest); gen_ext(QREG_CC_N, dest, opsize, 1); tcg_gen_mov_i32(QREG_CC_V, src); } Loading Loading @@ -822,7 +831,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) CCOp op = s->cc_op; /* The CC_OP_CMP form can handle most normal comparisons directly. */ if (op == CC_OP_CMP) { 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; Loading @@ -845,6 +854,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) c->v2 = tcg_const_i32(0); c->v1 = tmp = tcg_temp_new(); tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V); gen_ext(tmp, tmp, op - CC_OP_CMPB, 1); /* fallthru */ case 12: /* GE */ case 13: /* LT */ Loading Loading @@ -888,7 +898,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 10: /* PL (!N) */ case 11: /* MI (N) */ /* Several cases represent N normally. */ if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL || op == CC_OP_LOGIC) { c->v1 = QREG_CC_N; tcond = TCG_COND_LT; goto done; Loading @@ -897,7 +909,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 6: /* NE (!Z) */ case 7: /* EQ (Z) */ /* Some cases fold Z into N. */ if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL || op == CC_OP_LOGIC) { tcond = TCG_COND_EQ; c->v1 = QREG_CC_N; goto done; Loading @@ -906,7 +920,8 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond) case 4: /* CC (!C) */ case 5: /* CS (C) */ /* Some cases fold C into X. */ if (op == CC_OP_ADD || op == CC_OP_SUB) { if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL || op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL) { tcond = TCG_COND_NE; c->v1 = QREG_CC_X; goto done; Loading Loading @@ -1252,13 +1267,13 @@ DISAS_INSN(addsub) if (add) { tcg_gen_add_i32(dest, tmp, src); tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); } else { tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src); tcg_gen_sub_i32(dest, tmp, src); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } gen_update_cc_add(dest, src); gen_update_cc_add(dest, src, OS_LONG); if (insn & 0x100) { DEST_EA(env, insn, OS_LONG, dest, &addr); } else { Loading Loading @@ -1459,23 +1474,23 @@ DISAS_INSN(arith_im) tcg_gen_mov_i32(dest, src1); tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im); tcg_gen_subi_i32(dest, dest, im); gen_update_cc_add(dest, tcg_const_i32(im)); set_cc_op(s, CC_OP_SUB); gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG); set_cc_op(s, CC_OP_SUBL); break; case 3: /* addi */ tcg_gen_mov_i32(dest, src1); tcg_gen_addi_i32(dest, dest, im); gen_update_cc_add(dest, tcg_const_i32(im)); gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG); tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); break; case 5: /* eori */ tcg_gen_xori_i32(dest, src1, im); gen_logic_cc(s, dest, OS_LONG); break; case 6: /* cmpi */ gen_update_cc_add(src1, tcg_const_i32(im)); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(src1, tcg_const_i32(im), OS_LONG); set_cc_op(s, CC_OP_CMPL); break; default: abort(); Loading Loading @@ -1623,9 +1638,9 @@ DISAS_INSN(neg) src1 = tcg_temp_new(); tcg_gen_mov_i32(src1, reg); tcg_gen_neg_i32(reg, src1); gen_update_cc_add(reg, src1); gen_update_cc_add(reg, src1, OS_LONG); tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, src1, 0); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) Loading Loading @@ -1895,13 +1910,13 @@ DISAS_INSN(addsubq) if (insn & 0x0100) { tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2); tcg_gen_sub_i32(dest, dest, src2); set_cc_op(s, CC_OP_SUB); set_cc_op(s, CC_OP_SUBL); } else { tcg_gen_add_i32(dest, dest, src2); tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2); set_cc_op(s, CC_OP_ADD); set_cc_op(s, CC_OP_ADDL); } gen_update_cc_add(dest, src2); gen_update_cc_add(dest, src2, OS_LONG); } DEST_EA(env, insn, OS_LONG, dest, &addr); } Loading Loading @@ -2105,8 +2120,8 @@ DISAS_INSN(cmp) opsize = insn_opsize(insn); SRC_EA(env, src, opsize, -1, NULL); reg = DREG(insn, 9); gen_update_cc_add(reg, src); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(reg, src, OS_LONG); set_cc_op(s, CC_OP_CMPL); } DISAS_INSN(cmpa) Loading @@ -2122,8 +2137,8 @@ DISAS_INSN(cmpa) } SRC_EA(env, src, opsize, 1, NULL); reg = AREG(insn, 9); gen_update_cc_add(reg, src); set_cc_op(s, CC_OP_CMP); gen_update_cc_add(reg, src, OS_LONG); set_cc_op(s, CC_OP_CMPL); } DISAS_INSN(eor) Loading