From b6a21d8d8f69ac04fd6180e752a65d582c07e948 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 4 Jan 2018 02:29:10 +0100 Subject: [PATCH] target/m68k: add 680x0 "move to SR" instruction Some cleanup, and allows SR to be moved from any addressing mode. Previous code was wrong for coldfire: coldfire also allows to use addressing mode to set SR/CCR. It only supports Data register to get SR/CCR (move from) Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson Message-Id: <20180104012913.30763-15-laurent@vivier.eu> --- target/m68k/translate.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 1f867a4f7a..8f23cade04 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -2162,27 +2162,34 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0); tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0); } else { - gen_helper_set_sr(cpu_env, tcg_const_i32(val)); + TCGv sr = tcg_const_i32(val); + gen_helper_set_sr(cpu_env, sr); + tcg_temp_free(sr); } set_cc_op(s, CC_OP_FLAGS); } -static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn, - int ccr_only) +static void gen_set_sr(DisasContext *s, TCGv val, int ccr_only) { - if ((insn & 0x38) == 0) { - if (ccr_only) { - gen_helper_set_ccr(cpu_env, DREG(insn, 0)); - } else { - gen_helper_set_sr(cpu_env, DREG(insn, 0)); - } - set_cc_op(s, CC_OP_FLAGS); - } else if ((insn & 0x3f) == 0x3c) { + if (ccr_only) { + gen_helper_set_ccr(cpu_env, val); + } else { + gen_helper_set_sr(cpu_env, val); + } + set_cc_op(s, CC_OP_FLAGS); +} + +static void gen_move_to_sr(CPUM68KState *env, DisasContext *s, uint16_t insn, + bool ccr_only) +{ + if ((insn & 0x3f) == 0x3c) { uint16_t val; val = read_im16(env, s); gen_set_sr_im(s, val, ccr_only); } else { - disas_undef(env, s, insn); + TCGv src; + SRC_EA(env, src, OS_WORD, 0, NULL); + gen_set_sr(s, src, ccr_only); } } @@ -2557,7 +2564,7 @@ DISAS_INSN(neg) DISAS_INSN(move_to_ccr) { - gen_set_sr(env, s, insn, 1); + gen_move_to_sr(env, s, insn, true); } DISAS_INSN(not) @@ -4409,7 +4416,7 @@ DISAS_INSN(move_to_sr) gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } - gen_set_sr(env, s, insn, 0); + gen_move_to_sr(env, s, insn, false); gen_lookup_tb(s); } @@ -5556,9 +5563,8 @@ void register_m68k_insns (CPUM68KState *env) BASE(move_to_ccr, 44c0, ffc0); INSN(not, 4680, fff8, CF_ISA_A); INSN(not, 4600, ff00, M68000); - INSN(undef, 46c0, ffc0, M68000); #if defined(CONFIG_SOFTMMU) - INSN(move_to_sr, 46c0, ffc0, CF_ISA_A); + BASE(move_to_sr, 46c0, ffc0); #endif INSN(nbcd, 4800, ffc0, M68000); INSN(linkl, 4808, fff8, M68000); -- 2.11.0