Commit d315c8886b72b6ff8abfd43471449ac59da1f35a
1 parent
20dcee94
Improve ColdFire CPU selection.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2925 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
35 additions
and
11 deletions
target-m68k/cpu.h
| ... | ... | @@ -184,14 +184,20 @@ void m68k_switch_sp(CPUM68KState *env); |
| 184 | 184 | |
| 185 | 185 | void do_m68k_semihosting(CPUM68KState *env, int nr); |
| 186 | 186 | |
| 187 | +/* There are 4 ColdFire core ISA revisions: A, A+, B and C. | |
| 188 | + Each feature covers the subset of instructions common to the | |
| 189 | + ISA revisions mentioned. */ | |
| 190 | + | |
| 187 | 191 | enum m68k_features { |
| 188 | 192 | M68K_FEATURE_CF_ISA_A, |
| 189 | - M68K_FEATURE_CF_ISA_B, | |
| 190 | - M68K_FEATURE_CF_ISA_C, | |
| 193 | + M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */ | |
| 194 | + M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */ | |
| 195 | + M68K_FEATURE_BRAL, /* Long unconditional branch. (ISA A+ or B). */ | |
| 191 | 196 | M68K_FEATURE_CF_FPU, |
| 192 | 197 | M68K_FEATURE_CF_MAC, |
| 193 | 198 | M68K_FEATURE_CF_EMAC, |
| 194 | - M68K_FEATURE_USP, | |
| 199 | + M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate). */ | |
| 200 | + M68K_FEATURE_USP, /* User Stack Pointer. (ISA A+, B or C). */ | |
| 195 | 201 | M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ |
| 196 | 202 | M68K_FEATURE_WORD_INDEX /* word sized address index registers. */ |
| 197 | 203 | }; | ... | ... |
target-m68k/helper.c
| ... | ... | @@ -68,13 +68,15 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) |
| 68 | 68 | break; |
| 69 | 69 | case M68K_CPUID_M5208: |
| 70 | 70 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); |
| 71 | + m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); | |
| 72 | + m68k_set_feature(env, M68K_FEATURE_BRAL); | |
| 71 | 73 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 72 | 74 | m68k_set_feature(env, M68K_FEATURE_USP); |
| 73 | 75 | break; |
| 74 | 76 | case M68K_CPUID_CFV4E: |
| 75 | 77 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); |
| 76 | 78 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); |
| 77 | - m68k_set_feature(env, M68K_FEATURE_CF_ISA_C); | |
| 79 | + m68k_set_feature(env, M68K_FEATURE_BRAL); | |
| 78 | 80 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); |
| 79 | 81 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 80 | 82 | m68k_set_feature(env, M68K_FEATURE_USP); |
| ... | ... | @@ -82,13 +84,16 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) |
| 82 | 84 | case M68K_CPUID_ANY: |
| 83 | 85 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); |
| 84 | 86 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); |
| 85 | - m68k_set_feature(env, M68K_FEATURE_CF_ISA_C); | |
| 87 | + m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); | |
| 88 | + m68k_set_feature(env, M68K_FEATURE_BRAL); | |
| 86 | 89 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); |
| 87 | 90 | /* MAC and EMAC are mututally exclusive, so pick EMAC. |
| 88 | 91 | It's mostly backwards compatible. */ |
| 89 | 92 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 93 | + m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B); | |
| 90 | 94 | m68k_set_feature(env, M68K_FEATURE_USP); |
| 91 | 95 | m68k_set_feature(env, M68K_FEATURE_EXT_FULL); |
| 96 | + m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); | |
| 92 | 97 | break; |
| 93 | 98 | } |
| 94 | 99 | ... | ... |
target-m68k/translate.c
| ... | ... | @@ -2473,6 +2473,10 @@ DISAS_INSN(mac) |
| 2473 | 2473 | |
| 2474 | 2474 | acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); |
| 2475 | 2475 | dual = ((insn & 0x30) != 0 && (ext & 3) != 0); |
| 2476 | + if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) { | |
| 2477 | + disas_undef(s, insn); | |
| 2478 | + return; | |
| 2479 | + } | |
| 2476 | 2480 | if (insn & 0x30) { |
| 2477 | 2481 | /* MAC with load. */ |
| 2478 | 2482 | tmp = gen_lea(s, insn, OS_LONG); |
| ... | ... | @@ -2745,20 +2749,21 @@ register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask) |
| 2745 | 2749 | Later insn override earlier ones. */ |
| 2746 | 2750 | void register_m68k_insns (CPUM68KState *env) |
| 2747 | 2751 | { |
| 2748 | -#define INSN(name, opcode, mask, feature) \ | |
| 2752 | +#define INSN(name, opcode, mask, feature) do { \ | |
| 2749 | 2753 | if (m68k_feature(env, M68K_FEATURE_##feature)) \ |
| 2750 | - register_opcode(disas_##name, 0x##opcode, 0x##mask) | |
| 2754 | + register_opcode(disas_##name, 0x##opcode, 0x##mask); \ | |
| 2755 | + } while(0) | |
| 2751 | 2756 | INSN(undef, 0000, 0000, CF_ISA_A); |
| 2752 | 2757 | INSN(arith_im, 0080, fff8, CF_ISA_A); |
| 2753 | - INSN(bitrev, 00c0, fff8, CF_ISA_C); | |
| 2758 | + INSN(bitrev, 00c0, fff8, CF_ISA_APLUSC); | |
| 2754 | 2759 | INSN(bitop_reg, 0100, f1c0, CF_ISA_A); |
| 2755 | 2760 | INSN(bitop_reg, 0140, f1c0, CF_ISA_A); |
| 2756 | 2761 | INSN(bitop_reg, 0180, f1c0, CF_ISA_A); |
| 2757 | 2762 | INSN(bitop_reg, 01c0, f1c0, CF_ISA_A); |
| 2758 | 2763 | INSN(arith_im, 0280, fff8, CF_ISA_A); |
| 2759 | - INSN(byterev, 02c0, fff8, CF_ISA_A); | |
| 2764 | + INSN(byterev, 02c0, fff8, CF_ISA_APLUSC); | |
| 2760 | 2765 | INSN(arith_im, 0480, fff8, CF_ISA_A); |
| 2761 | - INSN(ff1, 04c0, fff8, CF_ISA_C); | |
| 2766 | + INSN(ff1, 04c0, fff8, CF_ISA_APLUSC); | |
| 2762 | 2767 | INSN(arith_im, 0680, fff8, CF_ISA_A); |
| 2763 | 2768 | INSN(bitop_im, 0800, ffc0, CF_ISA_A); |
| 2764 | 2769 | INSN(bitop_im, 0840, ffc0, CF_ISA_A); |
| ... | ... | @@ -2769,7 +2774,7 @@ void register_m68k_insns (CPUM68KState *env) |
| 2769 | 2774 | INSN(move, 1000, f000, CF_ISA_A); |
| 2770 | 2775 | INSN(move, 2000, f000, CF_ISA_A); |
| 2771 | 2776 | INSN(move, 3000, f000, CF_ISA_A); |
| 2772 | - INSN(strldsr, 40e7, ffff, CF_ISA_A); | |
| 2777 | + INSN(strldsr, 40e7, ffff, CF_ISA_APLUSC); | |
| 2773 | 2778 | INSN(negx, 4080, fff8, CF_ISA_A); |
| 2774 | 2779 | INSN(move_from_sr, 40c0, fff8, CF_ISA_A); |
| 2775 | 2780 | INSN(lea, 41c0, f1c0, CF_ISA_A); |
| ... | ... | @@ -2810,7 +2815,15 @@ void register_m68k_insns (CPUM68KState *env) |
| 2810 | 2815 | INSN(scc, 50c0, f0f8, CF_ISA_A); |
| 2811 | 2816 | INSN(addsubq, 5080, f1c0, CF_ISA_A); |
| 2812 | 2817 | INSN(tpf, 51f8, fff8, CF_ISA_A); |
| 2818 | + | |
| 2819 | + /* Branch instructions. */ | |
| 2813 | 2820 | INSN(branch, 6000, f000, CF_ISA_A); |
| 2821 | + /* Disable long branch instructions, then add back the ones we want. */ | |
| 2822 | + INSN(undef, 60ff, f0ff, CF_ISA_A); /* All long branches. */ | |
| 2823 | + INSN(branch, 60ff, f0ff, CF_ISA_B); | |
| 2824 | + INSN(undef, 60ff, ffff, CF_ISA_B); /* bra.l */ | |
| 2825 | + INSN(branch, 60ff, ffff, BRAL); | |
| 2826 | + | |
| 2814 | 2827 | INSN(moveq, 7000, f100, CF_ISA_A); |
| 2815 | 2828 | INSN(mvzs, 7100, f100, CF_ISA_B); |
| 2816 | 2829 | INSN(or, 8000, f000, CF_ISA_A); | ... | ... |