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,14 +184,20 @@ void m68k_switch_sp(CPUM68KState *env); | ||
| 184 | 184 | ||
| 185 | void do_m68k_semihosting(CPUM68KState *env, int nr); | 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 | enum m68k_features { | 191 | enum m68k_features { |
| 188 | M68K_FEATURE_CF_ISA_A, | 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 | M68K_FEATURE_CF_FPU, | 196 | M68K_FEATURE_CF_FPU, |
| 192 | M68K_FEATURE_CF_MAC, | 197 | M68K_FEATURE_CF_MAC, |
| 193 | M68K_FEATURE_CF_EMAC, | 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 | M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ | 201 | M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ |
| 196 | M68K_FEATURE_WORD_INDEX /* word sized address index registers. */ | 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,13 +68,15 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) | ||
| 68 | break; | 68 | break; |
| 69 | case M68K_CPUID_M5208: | 69 | case M68K_CPUID_M5208: |
| 70 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); | 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 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); | 73 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 72 | m68k_set_feature(env, M68K_FEATURE_USP); | 74 | m68k_set_feature(env, M68K_FEATURE_USP); |
| 73 | break; | 75 | break; |
| 74 | case M68K_CPUID_CFV4E: | 76 | case M68K_CPUID_CFV4E: |
| 75 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); | 77 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); |
| 76 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); | 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 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); | 80 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); |
| 79 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); | 81 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 80 | m68k_set_feature(env, M68K_FEATURE_USP); | 82 | m68k_set_feature(env, M68K_FEATURE_USP); |
| @@ -82,13 +84,16 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) | @@ -82,13 +84,16 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) | ||
| 82 | case M68K_CPUID_ANY: | 84 | case M68K_CPUID_ANY: |
| 83 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); | 85 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); |
| 84 | m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); | 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 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); | 89 | m68k_set_feature(env, M68K_FEATURE_CF_FPU); |
| 87 | /* MAC and EMAC are mututally exclusive, so pick EMAC. | 90 | /* MAC and EMAC are mututally exclusive, so pick EMAC. |
| 88 | It's mostly backwards compatible. */ | 91 | It's mostly backwards compatible. */ |
| 89 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); | 92 | m68k_set_feature(env, M68K_FEATURE_CF_EMAC); |
| 93 | + m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B); | ||
| 90 | m68k_set_feature(env, M68K_FEATURE_USP); | 94 | m68k_set_feature(env, M68K_FEATURE_USP); |
| 91 | m68k_set_feature(env, M68K_FEATURE_EXT_FULL); | 95 | m68k_set_feature(env, M68K_FEATURE_EXT_FULL); |
| 96 | + m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); | ||
| 92 | break; | 97 | break; |
| 93 | } | 98 | } |
| 94 | 99 |
target-m68k/translate.c
| @@ -2473,6 +2473,10 @@ DISAS_INSN(mac) | @@ -2473,6 +2473,10 @@ DISAS_INSN(mac) | ||
| 2473 | 2473 | ||
| 2474 | acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); | 2474 | acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); |
| 2475 | dual = ((insn & 0x30) != 0 && (ext & 3) != 0); | 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 | if (insn & 0x30) { | 2480 | if (insn & 0x30) { |
| 2477 | /* MAC with load. */ | 2481 | /* MAC with load. */ |
| 2478 | tmp = gen_lea(s, insn, OS_LONG); | 2482 | tmp = gen_lea(s, insn, OS_LONG); |
| @@ -2745,20 +2749,21 @@ register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask) | @@ -2745,20 +2749,21 @@ register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask) | ||
| 2745 | Later insn override earlier ones. */ | 2749 | Later insn override earlier ones. */ |
| 2746 | void register_m68k_insns (CPUM68KState *env) | 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 | if (m68k_feature(env, M68K_FEATURE_##feature)) \ | 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 | INSN(undef, 0000, 0000, CF_ISA_A); | 2756 | INSN(undef, 0000, 0000, CF_ISA_A); |
| 2752 | INSN(arith_im, 0080, fff8, CF_ISA_A); | 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 | INSN(bitop_reg, 0100, f1c0, CF_ISA_A); | 2759 | INSN(bitop_reg, 0100, f1c0, CF_ISA_A); |
| 2755 | INSN(bitop_reg, 0140, f1c0, CF_ISA_A); | 2760 | INSN(bitop_reg, 0140, f1c0, CF_ISA_A); |
| 2756 | INSN(bitop_reg, 0180, f1c0, CF_ISA_A); | 2761 | INSN(bitop_reg, 0180, f1c0, CF_ISA_A); |
| 2757 | INSN(bitop_reg, 01c0, f1c0, CF_ISA_A); | 2762 | INSN(bitop_reg, 01c0, f1c0, CF_ISA_A); |
| 2758 | INSN(arith_im, 0280, fff8, CF_ISA_A); | 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 | INSN(arith_im, 0480, fff8, CF_ISA_A); | 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 | INSN(arith_im, 0680, fff8, CF_ISA_A); | 2767 | INSN(arith_im, 0680, fff8, CF_ISA_A); |
| 2763 | INSN(bitop_im, 0800, ffc0, CF_ISA_A); | 2768 | INSN(bitop_im, 0800, ffc0, CF_ISA_A); |
| 2764 | INSN(bitop_im, 0840, ffc0, CF_ISA_A); | 2769 | INSN(bitop_im, 0840, ffc0, CF_ISA_A); |
| @@ -2769,7 +2774,7 @@ void register_m68k_insns (CPUM68KState *env) | @@ -2769,7 +2774,7 @@ void register_m68k_insns (CPUM68KState *env) | ||
| 2769 | INSN(move, 1000, f000, CF_ISA_A); | 2774 | INSN(move, 1000, f000, CF_ISA_A); |
| 2770 | INSN(move, 2000, f000, CF_ISA_A); | 2775 | INSN(move, 2000, f000, CF_ISA_A); |
| 2771 | INSN(move, 3000, f000, CF_ISA_A); | 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 | INSN(negx, 4080, fff8, CF_ISA_A); | 2778 | INSN(negx, 4080, fff8, CF_ISA_A); |
| 2774 | INSN(move_from_sr, 40c0, fff8, CF_ISA_A); | 2779 | INSN(move_from_sr, 40c0, fff8, CF_ISA_A); |
| 2775 | INSN(lea, 41c0, f1c0, CF_ISA_A); | 2780 | INSN(lea, 41c0, f1c0, CF_ISA_A); |
| @@ -2810,7 +2815,15 @@ void register_m68k_insns (CPUM68KState *env) | @@ -2810,7 +2815,15 @@ void register_m68k_insns (CPUM68KState *env) | ||
| 2810 | INSN(scc, 50c0, f0f8, CF_ISA_A); | 2815 | INSN(scc, 50c0, f0f8, CF_ISA_A); |
| 2811 | INSN(addsubq, 5080, f1c0, CF_ISA_A); | 2816 | INSN(addsubq, 5080, f1c0, CF_ISA_A); |
| 2812 | INSN(tpf, 51f8, fff8, CF_ISA_A); | 2817 | INSN(tpf, 51f8, fff8, CF_ISA_A); |
| 2818 | + | ||
| 2819 | + /* Branch instructions. */ | ||
| 2813 | INSN(branch, 6000, f000, CF_ISA_A); | 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 | INSN(moveq, 7000, f100, CF_ISA_A); | 2827 | INSN(moveq, 7000, f100, CF_ISA_A); |
| 2815 | INSN(mvzs, 7100, f100, CF_ISA_B); | 2828 | INSN(mvzs, 7100, f100, CF_ISA_B); |
| 2816 | INSN(or, 8000, f000, CF_ISA_A); | 2829 | INSN(or, 8000, f000, CF_ISA_A); |