diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-01-08 21:39:44 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-01-08 21:39:44 +0000 |
commit | 232e5537e476c463f5e6e2e9ae31f6e2da9ebfe9 (patch) | |
tree | fe9fc4a6bf46d1d2a6fce3287b7e92f2f37f5665 /target/m68k/translate.c | |
parent | 4bd797af6f5bc9f7114030695716d199dceafa6e (diff) | |
parent | cc5230267678c26b7f96157086f45fd8a347eb21 (diff) |
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' into staging
# gpg: Signature made Thu 04 Jan 2018 16:37:32 GMT
# gpg: using RSA key 0xF30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>"
# gpg: aka "Laurent Vivier <laurent@vivier.eu>"
# gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>"
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C
* remotes/vivier/tags/m68k-for-2.12-pull-request:
target/m68k: fix m68k_cpu_dump_state()
target/m68k: add the Interrupt Stack Pointer
target/m68k: add andi/ori/eori to SR/CCR
target/m68k: add 680x0 "move to SR" instruction
target/m68k: move CCR/SR functions
target/m68k: implement fsave/frestore
target/m68k: add reset
target/m68k: add cpush/cinv
target/m68k: softmmu cleanup
target/m68k: add move16
target/m68k: add chk and chk2
target/m68k: manage 680x0 stack frames
target/m68k: add CPU_LOG_INT trace
target/m68k: use insn_pc to generate instruction fault address
linux-user, m68k: correctly manage SR in context
target/m68k: fix gen_get_ccr()
target-m68k: sync CC_OP before gen_jmp_tb()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/m68k/translate.c')
-rw-r--r-- | target/m68k/translate.c | 497 |
1 files changed, 396 insertions, 101 deletions
diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 09226eba81..f0e86a73d4 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -270,7 +270,6 @@ static void gen_raise_exception(int nr) static void gen_exception(DisasContext *s, uint32_t where, int nr) { - update_cc_op(s); gen_jmp_im(s, where); gen_raise_exception(nr); } @@ -1510,12 +1509,12 @@ DISAS_INSN(dbcc) DISAS_INSN(undef_mac) { - gen_exception(s, s->pc - 2, EXCP_LINEA); + gen_exception(s, s->insn_pc, EXCP_LINEA); } DISAS_INSN(undef_fpu) { - gen_exception(s, s->pc - 2, EXCP_LINEF); + gen_exception(s, s->insn_pc, EXCP_LINEF); } DISAS_INSN(undef) @@ -1524,8 +1523,8 @@ DISAS_INSN(undef) for the 680x0 series, as well as those that are implemented but actually illegal for CPU32 or pre-68020. */ qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x", - insn, s->pc - 2); - gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED); + insn, s->insn_pc); + gen_exception(s, s->insn_pc, EXCP_UNSUPPORTED); } DISAS_INSN(mulw) @@ -2132,6 +2131,68 @@ DISAS_INSN(bitop_im) } } +static TCGv gen_get_ccr(DisasContext *s) +{ + TCGv dest; + + update_cc_op(s); + dest = tcg_temp_new(); + gen_helper_get_ccr(dest, cpu_env); + return dest; +} + +static TCGv gen_get_sr(DisasContext *s) +{ + TCGv ccr; + TCGv sr; + + ccr = gen_get_ccr(s); + sr = tcg_temp_new(); + tcg_gen_andi_i32(sr, QREG_SR, 0xffe0); + tcg_gen_or_i32(sr, sr, ccr); + return sr; +} + +static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) +{ + if (ccr_only) { + tcg_gen_movi_i32(QREG_CC_C, val & CCF_C ? 1 : 0); + tcg_gen_movi_i32(QREG_CC_V, val & CCF_V ? -1 : 0); + tcg_gen_movi_i32(QREG_CC_Z, val & CCF_Z ? 0 : 1); + 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 { + 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(DisasContext *s, TCGv val, int ccr_only) +{ + 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 { + TCGv src; + SRC_EA(env, src, OS_WORD, 0, NULL); + gen_set_sr(s, src, ccr_only); + } +} + DISAS_INSN(arith_im) { int op; @@ -2140,6 +2201,7 @@ DISAS_INSN(arith_im) TCGv dest; TCGv addr; int opsize; + bool with_SR = ((insn & 0x3f) == 0x3c); op = (insn >> 9) & 7; opsize = insn_opsize(insn); @@ -2156,32 +2218,73 @@ DISAS_INSN(arith_im) default: abort(); } - SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : &addr); + + if (with_SR) { + /* SR/CCR can only be used with andi/eori/ori */ + if (op == 2 || op == 3 || op == 6) { + disas_undef(env, s, insn); + return; + } + switch (opsize) { + case OS_BYTE: + src1 = gen_get_ccr(s); + break; + case OS_WORD: + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + src1 = gen_get_sr(s); + break; + case OS_LONG: + disas_undef(env, s, insn); + return; + } + } else { + SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : &addr); + } dest = tcg_temp_new(); switch (op) { case 0: /* ori */ tcg_gen_or_i32(dest, src1, im); - gen_logic_cc(s, dest, opsize); + if (with_SR) { + gen_set_sr(s, dest, opsize == OS_BYTE); + } else { + DEST_EA(env, insn, opsize, dest, &addr); + gen_logic_cc(s, dest, opsize); + } break; case 1: /* andi */ tcg_gen_and_i32(dest, src1, im); - gen_logic_cc(s, dest, opsize); + if (with_SR) { + gen_set_sr(s, dest, opsize == OS_BYTE); + } else { + DEST_EA(env, insn, opsize, dest, &addr); + gen_logic_cc(s, dest, opsize); + } break; case 2: /* subi */ tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, src1, im); tcg_gen_sub_i32(dest, src1, im); gen_update_cc_add(dest, im, opsize); set_cc_op(s, CC_OP_SUBB + opsize); + DEST_EA(env, insn, opsize, dest, &addr); break; case 3: /* addi */ tcg_gen_add_i32(dest, src1, im); gen_update_cc_add(dest, im, opsize); tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, im); set_cc_op(s, CC_OP_ADDB + opsize); + DEST_EA(env, insn, opsize, dest, &addr); break; case 5: /* eori */ tcg_gen_xor_i32(dest, src1, im); - gen_logic_cc(s, dest, opsize); + if (with_SR) { + gen_set_sr(s, dest, opsize == OS_BYTE); + } else { + DEST_EA(env, insn, opsize, dest, &addr); + gen_logic_cc(s, dest, opsize); + } break; case 6: /* cmpi */ gen_update_cc_cmp(s, src1, im, opsize); @@ -2190,9 +2293,6 @@ DISAS_INSN(arith_im) abort(); } tcg_temp_free(im); - if (op != 6) { - DEST_EA(env, insn, opsize, dest, &addr); - } tcg_temp_free(dest); } @@ -2475,17 +2575,6 @@ DISAS_INSN(clr) tcg_temp_free(zero); } -static TCGv gen_get_ccr(DisasContext *s) -{ - TCGv dest; - - gen_flush_flags(s); - update_cc_op(s); - dest = tcg_temp_new(); - gen_helper_get_ccr(dest, cpu_env); - return dest; -} - DISAS_INSN(move_from_ccr) { TCGv ccr; @@ -2512,43 +2601,9 @@ DISAS_INSN(neg) tcg_temp_free(dest); } -static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) -{ - if (ccr_only) { - tcg_gen_movi_i32(QREG_CC_C, val & CCF_C ? 1 : 0); - tcg_gen_movi_i32(QREG_CC_V, val & CCF_V ? -1 : 0); - tcg_gen_movi_i32(QREG_CC_Z, val & CCF_Z ? 0 : 1); - 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)); - } - set_cc_op(s, CC_OP_FLAGS); -} - -static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn, - 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) { - uint16_t val; - val = read_im16(env, s); - gen_set_sr_im(s, val, ccr_only); - } else { - disas_undef(env, s, insn); - } -} - - DISAS_INSN(move_to_ccr) { - gen_set_sr(env, s, insn, 1); + gen_move_to_sr(env, s, insn, true); } DISAS_INSN(not) @@ -2585,7 +2640,7 @@ DISAS_INSN(swap) DISAS_INSN(bkpt) { - gen_exception(s, s->pc - 2, EXCP_DEBUG); + gen_exception(s, s->insn_pc, EXCP_DEBUG); } DISAS_INSN(pea) @@ -2638,7 +2693,7 @@ DISAS_INSN(pulse) DISAS_INSN(illegal) { - gen_exception(s, s->pc - 2, EXCP_ILLEGAL); + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); } /* ??? This should be atomic. */ @@ -2668,7 +2723,7 @@ DISAS_INSN(mull) if (ext & 0x400) { if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { - gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + gen_exception(s, s->insn_pc, EXCP_UNSUPPORTED); return; } @@ -2764,6 +2819,18 @@ DISAS_INSN(unlk) tcg_temp_free(src); } +#if defined(CONFIG_SOFTMMU) +DISAS_INSN(reset) +{ + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + + gen_helper_reset(cpu_env); +} +#endif + DISAS_INSN(nop) { } @@ -2897,6 +2964,7 @@ DISAS_INSN(branch) gen_jmp_tb(s, 0, s->pc); } else { /* Unconditional branch. */ + update_cc_op(s); gen_jmp_tb(s, 0, base + offset); } } @@ -4204,16 +4272,148 @@ DISAS_INSN(ff1) gen_helper_ff1(reg, reg); } -static TCGv gen_get_sr(DisasContext *s) +DISAS_INSN(chk) { - TCGv ccr; - TCGv sr; + TCGv src, reg; + int opsize; - ccr = gen_get_ccr(s); - sr = tcg_temp_new(); - tcg_gen_andi_i32(sr, QREG_SR, 0xffe0); - tcg_gen_or_i32(sr, sr, ccr); - return sr; + switch ((insn >> 7) & 3) { + case 3: + opsize = OS_WORD; + break; + case 2: + if (m68k_feature(env, M68K_FEATURE_CHK2)) { + opsize = OS_LONG; + break; + } + /* fallthru */ + default: + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); + return; + } + SRC_EA(env, src, opsize, 1, NULL); + reg = gen_extend(DREG(insn, 9), opsize, 1); + + gen_flush_flags(s); + gen_helper_chk(cpu_env, reg, src); +} + +DISAS_INSN(chk2) +{ + uint16_t ext; + TCGv addr1, addr2, bound1, bound2, reg; + int opsize; + + switch ((insn >> 9) & 3) { + case 0: + opsize = OS_BYTE; + break; + case 1: + opsize = OS_WORD; + break; + case 2: + opsize = OS_LONG; + break; + default: + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); + return; + } + + ext = read_im16(env, s); + if ((ext & 0x0800) == 0) { + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); + return; + } + + addr1 = gen_lea(env, s, insn, OS_UNSIZED); + addr2 = tcg_temp_new(); + tcg_gen_addi_i32(addr2, addr1, opsize_bytes(opsize)); + + bound1 = gen_load(s, opsize, addr1, 1); + tcg_temp_free(addr1); + bound2 = gen_load(s, opsize, addr2, 1); + tcg_temp_free(addr2); + + reg = tcg_temp_new(); + if (ext & 0x8000) { + tcg_gen_mov_i32(reg, AREG(ext, 12)); + } else { + gen_ext(reg, DREG(ext, 12), opsize, 1); + } + + gen_flush_flags(s); + gen_helper_chk2(cpu_env, reg, bound1, bound2); + tcg_temp_free(reg); +} + +static void m68k_copy_line(TCGv dst, TCGv src, int index) +{ + TCGv addr; + TCGv_i64 t0, t1; + + addr = tcg_temp_new(); + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + tcg_gen_andi_i32(addr, src, ~15); + tcg_gen_qemu_ld64(t0, addr, index); + tcg_gen_addi_i32(addr, addr, 8); + tcg_gen_qemu_ld64(t1, addr, index); + + tcg_gen_andi_i32(addr, dst, ~15); + tcg_gen_qemu_st64(t0, addr, index); + tcg_gen_addi_i32(addr, addr, 8); + tcg_gen_qemu_st64(t1, addr, index); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + tcg_temp_free(addr); +} + +DISAS_INSN(move16_reg) +{ + int index = IS_USER(s); + TCGv tmp; + uint16_t ext; + + ext = read_im16(env, s); + if ((ext & (1 << 15)) == 0) { + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); + } + + m68k_copy_line(AREG(ext, 12), AREG(insn, 0), index); + + /* Ax can be Ay, so save Ay before incrementing Ax */ + tmp = tcg_temp_new(); + tcg_gen_mov_i32(tmp, AREG(ext, 12)); + tcg_gen_addi_i32(AREG(insn, 0), AREG(insn, 0), 16); + tcg_gen_addi_i32(AREG(ext, 12), tmp, 16); + tcg_temp_free(tmp); +} + +DISAS_INSN(move16_mem) +{ + int index = IS_USER(s); + TCGv reg, addr; + + reg = AREG(insn, 0); + addr = tcg_const_i32(read_im32(env, s)); + + if ((insn >> 3) & 1) { + /* MOVE16 (xxx).L, (Ay) */ + m68k_copy_line(reg, addr, index); + } else { + /* MOVE16 (Ay), (xxx).L */ + m68k_copy_line(addr, reg, index); + } + + tcg_temp_free(addr); + + if (((insn >> 3) & 2) == 0) { + /* (Ay)+ */ + tcg_gen_addi_i32(reg, reg, 16); + } } DISAS_INSN(strldsr) @@ -4241,27 +4441,28 @@ DISAS_INSN(move_from_sr) TCGv sr; if (IS_USER(s) && !m68k_feature(env, M68K_FEATURE_M68000)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } sr = gen_get_sr(s); DEST_EA(env, insn, OS_WORD, sr, NULL); } +#if defined(CONFIG_SOFTMMU) DISAS_INSN(move_to_sr) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + 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); } DISAS_INSN(move_from_usp) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } tcg_gen_ld_i32(AREG(insn, 0), cpu_env, @@ -4271,7 +4472,7 @@ DISAS_INSN(move_from_usp) DISAS_INSN(move_to_usp) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } tcg_gen_st_i32(AREG(insn, 0), cpu_env, @@ -4280,6 +4481,11 @@ DISAS_INSN(move_to_usp) DISAS_INSN(halt) { + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + gen_exception(s, s->pc, EXCP_HALT_INSN); } @@ -4288,7 +4494,7 @@ DISAS_INSN(stop) uint16_t ext; if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } @@ -4302,19 +4508,19 @@ DISAS_INSN(stop) DISAS_INSN(rte) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } - gen_exception(s, s->pc - 2, EXCP_RTE); + gen_exception(s, s->insn_pc, EXCP_RTE); } -DISAS_INSN(movec) +DISAS_INSN(cf_movec) { uint16_t ext; TCGv reg; if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } @@ -4325,14 +4531,39 @@ DISAS_INSN(movec) } else { reg = DREG(ext, 12); } - gen_helper_movec(cpu_env, tcg_const_i32(ext & 0xfff), reg); + gen_helper_cf_movec_to(cpu_env, tcg_const_i32(ext & 0xfff), reg); + gen_lookup_tb(s); +} + +DISAS_INSN(m68k_movec) +{ + uint16_t ext; + TCGv reg; + + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + + ext = read_im16(env, s); + + if (ext & 0x8000) { + reg = AREG(ext, 12); + } else { + reg = DREG(ext, 12); + } + if (insn & 1) { + gen_helper_m68k_movec_to(cpu_env, tcg_const_i32(ext & 0xfff), reg); + } else { + gen_helper_m68k_movec_from(reg, cpu_env, tcg_const_i32(ext & 0xfff)); + } gen_lookup_tb(s); } DISAS_INSN(intouch) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } /* ICache fetch. Implement as no-op. */ @@ -4341,15 +4572,33 @@ DISAS_INSN(intouch) DISAS_INSN(cpushl) { if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } /* Cache push/invalidate. Implement as no-op. */ } +DISAS_INSN(cpush) +{ + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + /* Cache push/invalidate. Implement as no-op. */ +} + +DISAS_INSN(cinv) +{ + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + /* Invalidate cache line. Implement as no-op. */ +} + DISAS_INSN(wddata) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); } DISAS_INSN(wdebug) @@ -4357,16 +4606,17 @@ DISAS_INSN(wdebug) M68kCPU *cpu = m68k_env_get_cpu(env); if (IS_USER(s)) { - gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); return; } /* TODO: Implement wdebug. */ cpu_abort(CPU(cpu), "WDEBUG not implemented"); } +#endif DISAS_INSN(trap) { - gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf)); + gen_exception(s, s->insn_pc, EXCP_TRAP0 + (insn & 0xf)); } static void gen_load_fcr(DisasContext *s, TCGv res, int reg) @@ -4875,6 +5125,7 @@ static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1) DisasCompare c; gen_fcc_cond(&c, s, cond); + update_cc_op(s); tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1); free_cond(&c); } @@ -4919,21 +5170,40 @@ DISAS_INSN(fscc) tcg_temp_free(tmp); } +#if defined(CONFIG_SOFTMMU) DISAS_INSN(frestore) { - M68kCPU *cpu = m68k_env_get_cpu(env); + TCGv addr; - /* TODO: Implement frestore. */ - cpu_abort(CPU(cpu), "FRESTORE not implemented"); + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } + if (m68k_feature(s->env, M68K_FEATURE_M68040)) { + SRC_EA(env, addr, OS_LONG, 0, NULL); + /* FIXME: check the state frame */ + } else { + disas_undef(env, s, insn); + } } DISAS_INSN(fsave) { - M68kCPU *cpu = m68k_env_get_cpu(env); + if (IS_USER(s)) { + gen_exception(s, s->insn_pc, EXCP_PRIVILEGE); + return; + } - /* TODO: Implement fsave. */ - cpu_abort(CPU(cpu), "FSAVE not implemented"); + if (m68k_feature(s->env, M68K_FEATURE_M68040)) { + /* always write IDLE */ + TCGv idle = tcg_const_i32(0x41000000); + DEST_EA(env, insn, OS_LONG, idle, NULL); + tcg_temp_free(idle); + } else { + disas_undef(env, s, insn); + } } +#endif static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper) { @@ -5306,7 +5576,7 @@ void register_m68k_insns (CPUM68KState *env) BASE(undef, 0000, 0000); INSN(arith_im, 0080, fff8, CF_ISA_A); INSN(arith_im, 0000, ff00, M68000); - INSN(undef, 00c0, ffc0, M68000); + INSN(chk2, 00c0, f9c0, CHK2); INSN(bitrev, 00c0, fff8, CF_ISA_APLUSC); BASE(bitop_reg, 0100, f1c0); BASE(bitop_reg, 0140, f1c0); @@ -5339,6 +5609,7 @@ void register_m68k_insns (CPUM68KState *env) BASE(move, 1000, f000); BASE(move, 2000, f000); BASE(move, 3000, f000); + INSN(chk, 4000, f040, M68000); INSN(strldsr, 40e7, ffff, CF_ISA_APLUSC); INSN(negx, 4080, fff8, CF_ISA_A); INSN(negx, 4000, ff00, M68000); @@ -5356,8 +5627,9 @@ 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); - INSN(move_to_sr, 46c0, ffc0, CF_ISA_A); +#if defined(CONFIG_SOFTMMU) + BASE(move_to_sr, 46c0, ffc0); +#endif INSN(nbcd, 4800, ffc0, M68000); INSN(linkl, 4808, fff8, M68000); BASE(pea, 4840, ffc0); @@ -5372,7 +5644,9 @@ void register_m68k_insns (CPUM68KState *env) BASE(tst, 4a00, ff00); INSN(tas, 4ac0, ffc0, CF_ISA_B); INSN(tas, 4ac0, ffc0, M68000); +#if defined(CONFIG_SOFTMMU) INSN(halt, 4ac8, ffff, CF_ISA_A); +#endif INSN(pulse, 4acc, ffff, CF_ISA_A); BASE(illegal, 4afc, ffff); INSN(mull, 4c00, ffc0, CF_ISA_A); @@ -5383,14 +5657,18 @@ void register_m68k_insns (CPUM68KState *env) BASE(trap, 4e40, fff0); BASE(link, 4e50, fff8); BASE(unlk, 4e58, fff8); +#if defined(CONFIG_SOFTMMU) INSN(move_to_usp, 4e60, fff8, USP); INSN(move_from_usp, 4e68, fff8, USP); - BASE(nop, 4e71, ffff); + INSN(reset, 4e70, ffff, M68000); BASE(stop, 4e72, ffff); BASE(rte, 4e73, ffff); + INSN(cf_movec, 4e7b, ffff, CF_ISA_A); + INSN(m68k_movec, 4e7a, fffe, M68000); +#endif + BASE(nop, 4e71, ffff); INSN(rtd, 4e74, ffff, RTD); BASE(rts, 4e75, ffff); - INSN(movec, 4e7b, ffff, CF_ISA_A); BASE(jump, 4e80, ffc0); BASE(jump, 4ec0, ffc0); INSN(addsubq, 5000, f080, M68000); @@ -5494,17 +5772,23 @@ void register_m68k_insns (CPUM68KState *env) BASE(undef_fpu, f000, f000); INSN(fpu, f200, ffc0, CF_FPU); INSN(fbcc, f280, ffc0, CF_FPU); - INSN(frestore, f340, ffc0, CF_FPU); - INSN(fsave, f300, ffc0, CF_FPU); INSN(fpu, f200, ffc0, FPU); INSN(fscc, f240, ffc0, FPU); INSN(fbcc, f280, ff80, FPU); +#if defined(CONFIG_SOFTMMU) + INSN(frestore, f340, ffc0, CF_FPU); + INSN(fsave, f300, ffc0, CF_FPU); INSN(frestore, f340, ffc0, FPU); INSN(fsave, f300, ffc0, FPU); INSN(intouch, f340, ffc0, CF_ISA_A); INSN(cpushl, f428, ff38, CF_ISA_A); + INSN(cpush, f420, ff20, M68040); + INSN(cinv, f400, ff20, M68040); INSN(wddata, fb00, ff00, CF_ISA_A); INSN(wdebug, fbc0, ffc0, CF_ISA_A); +#endif + INSN(move16_mem, f600, ffe0, M68040); + INSN(move16_reg, f620, fff8, M68040); #undef INSN } @@ -5652,9 +5936,12 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, } cpu_fprintf (f, "PC = %08x ", env->pc); sr = env->sr | cpu_m68k_get_ccr(env); - cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-', - (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-', - (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-'); + cpu_fprintf(f, "SR = %04x T:%x I:%x %c%c %c%c%c%c%c\n", + sr, (sr & SR_T) >> SR_T_SHIFT, (sr & SR_I) >> SR_I_SHIFT, + (sr & SR_S) ? 'S' : 'U', (sr & SR_M) ? '%' : 'I', + (sr & CCF_X) ? 'X' : '-', (sr & CCF_N) ? 'N' : '-', + (sr & CCF_Z) ? 'Z' : '-', (sr & CCF_V) ? 'V' : '-', + (sr & CCF_C) ? 'C' : '-'); cpu_fprintf(f, "FPSR = %08x %c%c%c%c ", env->fpsr, (env->fpsr & FPSR_CC_A) ? 'A' : '-', (env->fpsr & FPSR_CC_I) ? 'I' : '-', @@ -5687,6 +5974,14 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "RP "); break; } + cpu_fprintf(f, "\n"); +#ifdef CONFIG_SOFTMMU + cpu_fprintf(f, "%sA7(MSP) = %08x %sA7(USP) = %08x %sA7(ISP) = %08x\n", + env->current_sp == M68K_SSP ? "->" : " ", env->sp[M68K_SSP], + env->current_sp == M68K_USP ? "->" : " ", env->sp[M68K_USP], + env->current_sp == M68K_ISP ? "->" : " ", env->sp[M68K_ISP]); + cpu_fprintf(f, "VBR = 0x%08x\n", env->vbr); +#endif } void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, |