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); | ... | ... |