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 <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20180104012913.30763-15-laurent@vivier.eu>
This commit is contained in:
Laurent Vivier 2018-01-04 02:29:10 +01:00
parent 01490ea8f5
commit b6a21d8d8f

View file

@ -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_N, val & CCF_N ? -1 : 0);
tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0); tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0);
} else { } 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); set_cc_op(s, CC_OP_FLAGS);
} }
static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn, static void gen_set_sr(DisasContext *s, TCGv val, int ccr_only)
int ccr_only)
{ {
if ((insn & 0x38) == 0) { if (ccr_only) {
if (ccr_only) { gen_helper_set_ccr(cpu_env, val);
gen_helper_set_ccr(cpu_env, DREG(insn, 0)); } else {
} else { gen_helper_set_sr(cpu_env, val);
gen_helper_set_sr(cpu_env, DREG(insn, 0)); }
} set_cc_op(s, CC_OP_FLAGS);
set_cc_op(s, CC_OP_FLAGS); }
} else if ((insn & 0x3f) == 0x3c) {
static void gen_move_to_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
bool ccr_only)
{
if ((insn & 0x3f) == 0x3c) {
uint16_t val; uint16_t val;
val = read_im16(env, s); val = read_im16(env, s);
gen_set_sr_im(s, val, ccr_only); gen_set_sr_im(s, val, ccr_only);
} else { } 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) DISAS_INSN(move_to_ccr)
{ {
gen_set_sr(env, s, insn, 1); gen_move_to_sr(env, s, insn, true);
} }
DISAS_INSN(not) DISAS_INSN(not)
@ -4409,7 +4416,7 @@ DISAS_INSN(move_to_sr)
gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); gen_exception(s, s->insn_pc, EXCP_PRIVILEGE);
return; return;
} }
gen_set_sr(env, s, insn, 0); gen_move_to_sr(env, s, insn, false);
gen_lookup_tb(s); gen_lookup_tb(s);
} }
@ -5556,9 +5563,8 @@ void register_m68k_insns (CPUM68KState *env)
BASE(move_to_ccr, 44c0, ffc0); BASE(move_to_ccr, 44c0, ffc0);
INSN(not, 4680, fff8, CF_ISA_A); INSN(not, 4680, fff8, CF_ISA_A);
INSN(not, 4600, ff00, M68000); INSN(not, 4600, ff00, M68000);
INSN(undef, 46c0, ffc0, M68000);
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
INSN(move_to_sr, 46c0, ffc0, CF_ISA_A); BASE(move_to_sr, 46c0, ffc0);
#endif #endif
INSN(nbcd, 4800, ffc0, M68000); INSN(nbcd, 4800, ffc0, M68000);
INSN(linkl, 4808, fff8, M68000); INSN(linkl, 4808, fff8, M68000);