diff options
Diffstat (limited to 'target/m68k')
-rw-r--r-- | target/m68k/cpu.c | 1 | ||||
-rw-r--r-- | target/m68k/cpu.h | 68 | ||||
-rw-r--r-- | target/m68k/op_helper.c | 17 | ||||
-rw-r--r-- | target/m68k/translate.c | 20 |
4 files changed, 82 insertions, 24 deletions
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 37d2ed9dc7..a14874b4da 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -161,6 +161,7 @@ static void m68020_cpu_initfn(Object *obj) m68k_set_feature(env, M68K_FEATURE_CAS); m68k_set_feature(env, M68K_FEATURE_CHK2); m68k_set_feature(env, M68K_FEATURE_MSP); + m68k_set_feature(env, M68K_FEATURE_UNALIGNED_DATA); } /* diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 7c3feeaf8a..402c86c876 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -475,36 +475,60 @@ void do_m68k_semihosting(CPUM68KState *env, int nr); */ enum m68k_features { - M68K_FEATURE_M68000, /* Base m68k instruction set */ + /* Base m68k instruction set */ + M68K_FEATURE_M68000, M68K_FEATURE_M68010, M68K_FEATURE_M68020, M68K_FEATURE_M68030, M68K_FEATURE_M68040, M68K_FEATURE_M68060, - M68K_FEATURE_CF_ISA_A, /* Base Coldfire set Rev A. */ - M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */ - M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */ - M68K_FEATURE_BRAL, /* BRA with Long branch. (680[2346]0, ISA A+ or B). */ + /* Base Coldfire set Rev A. */ + M68K_FEATURE_CF_ISA_A, + /* (ISA B or C). */ + M68K_FEATURE_CF_ISA_B, + /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */ + M68K_FEATURE_CF_ISA_APLUSC, + /* BRA with Long branch. (680[2346]0, ISA A+ or B). */ + M68K_FEATURE_BRAL, M68K_FEATURE_CF_FPU, M68K_FEATURE_CF_MAC, M68K_FEATURE_CF_EMAC, - M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate). */ - M68K_FEATURE_USP, /* User Stack Pointer. (680[012346]0, ISA A+, B or C).*/ - M68K_FEATURE_MSP, /* Master Stack Pointer. (680[234]0) */ - M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ - M68K_FEATURE_WORD_INDEX, /* word sized address index registers. */ - M68K_FEATURE_SCALED_INDEX, /* scaled address index registers. */ - M68K_FEATURE_LONG_MULDIV, /* 32 bit mul/div. (680[2346]0, and CPU32) */ - M68K_FEATURE_QUAD_MULDIV, /* 64 bit mul/div. (680[2346]0, and CPU32) */ - M68K_FEATURE_BCCL, /* Bcc with Long branches. (680[2346]0, and CPU32) */ - M68K_FEATURE_BITFIELD, /* BFxxx Bit field insns. (680[2346]0) */ - M68K_FEATURE_FPU, /* fpu insn. (680[46]0) */ - M68K_FEATURE_CAS, /* CAS/CAS2[WL] insns. (680[2346]0) */ - M68K_FEATURE_BKPT, /* BKPT insn. (680[12346]0, and CPU32) */ - M68K_FEATURE_RTD, /* RTD insn. (680[12346]0, and CPU32) */ - M68K_FEATURE_CHK2, /* CHK2 insn. (680[2346]0, and CPU32) */ - M68K_FEATURE_MOVEP, /* MOVEP insn. (680[01234]0, and CPU32) */ - M68K_FEATURE_MOVEC, /* MOVEC insn. (from 68010) */ + /* Revision B EMAC (dual accumulate). */ + M68K_FEATURE_CF_EMAC_B, + /* User Stack Pointer. (680[012346]0, ISA A+, B or C). */ + M68K_FEATURE_USP, + /* Master Stack Pointer. (680[234]0) */ + M68K_FEATURE_MSP, + /* 68020+ full extension word. */ + M68K_FEATURE_EXT_FULL, + /* word sized address index registers. */ + M68K_FEATURE_WORD_INDEX, + /* scaled address index registers. */ + M68K_FEATURE_SCALED_INDEX, + /* 32 bit mul/div. (680[2346]0, and CPU32) */ + M68K_FEATURE_LONG_MULDIV, + /* 64 bit mul/div. (680[2346]0, and CPU32) */ + M68K_FEATURE_QUAD_MULDIV, + /* Bcc with Long branches. (680[2346]0, and CPU32) */ + M68K_FEATURE_BCCL, + /* BFxxx Bit field insns. (680[2346]0) */ + M68K_FEATURE_BITFIELD, + /* fpu insn. (680[46]0) */ + M68K_FEATURE_FPU, + /* CAS/CAS2[WL] insns. (680[2346]0) */ + M68K_FEATURE_CAS, + /* BKPT insn. (680[12346]0, and CPU32) */ + M68K_FEATURE_BKPT, + /* RTD insn. (680[12346]0, and CPU32) */ + M68K_FEATURE_RTD, + /* CHK2 insn. (680[2346]0, and CPU32) */ + M68K_FEATURE_CHK2, + /* MOVEP insn. (680[01234]0, and CPU32) */ + M68K_FEATURE_MOVEP, + /* MOVEC insn. (from 68010) */ + M68K_FEATURE_MOVEC, + /* Unaligned data accesses (680[2346]0) */ + M68K_FEATURE_UNALIGNED_DATA, }; static inline int m68k_feature(CPUM68KState *env, int feature) diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 9b0698f267..ae1ba4b437 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -348,7 +348,10 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw) cpu_m68k_set_sr(env, sr); sp = env->aregs[7]; - sp &= ~1; + if (!m68k_feature(env, M68K_FEATURE_UNALIGNED_DATA)) { + sp &= ~1; + } + if (cs->exception_index == EXCP_ACCESS) { if (env->mmu.fault) { cpu_abort(cs, "DOUBLE MMU FAULT\n"); @@ -468,7 +471,17 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; - env->mmu.ssw |= M68K_ATC_040; + + /* + * According to the MC68040 users manual the ATC bit of the SSW is + * used to distinguish between ATC faults and physical bus errors. + * In the case of a bus error e.g. during nubus read from an empty + * slot this bit should not be set + */ + if (response != MEMTX_DECODE_ERROR) { + env->mmu.ssw |= M68K_ATC_040; + } + /* FIXME: manage MMU table access error */ env->mmu.ssw &= ~M68K_TM_040; if (env->sr & SR_S) { /* SUPERVISOR */ diff --git a/target/m68k/translate.c b/target/m68k/translate.c index ac936ebe8f..200018ae6a 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -2969,6 +2969,25 @@ DISAS_INSN(rtd) gen_jmp(s, tmp); } +DISAS_INSN(rtr) +{ + TCGv tmp; + TCGv ccr; + TCGv sp; + + sp = tcg_temp_new(); + ccr = gen_load(s, OS_WORD, QREG_SP, 0, IS_USER(s)); + tcg_gen_addi_i32(sp, QREG_SP, 2); + tmp = gen_load(s, OS_LONG, sp, 0, IS_USER(s)); + tcg_gen_addi_i32(QREG_SP, sp, 4); + tcg_temp_free(sp); + + gen_set_sr(s, ccr, true); + tcg_temp_free(ccr); + + gen_jmp(s, tmp); +} + DISAS_INSN(rts) { TCGv tmp; @@ -6015,6 +6034,7 @@ void register_m68k_insns (CPUM68KState *env) BASE(nop, 4e71, ffff); INSN(rtd, 4e74, ffff, RTD); BASE(rts, 4e75, ffff); + INSN(rtr, 4e77, ffff, M68000); BASE(jump, 4e80, ffc0); BASE(jump, 4ec0, ffc0); INSN(addsubq, 5000, f080, M68000); |