2143
2426
gen_jmp_tb(s, 1, addr + offset);
2429
DISAS_INSN(frestore)
2431
/* TODO: Implement frestore. */
2432
qemu_assert(0, "FRESTORE not implemented");
2437
/* TODO: Implement fsave. */
2438
qemu_assert(0, "FSAVE not implemented");
2441
static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
2443
int tmp = gen_new_qreg(QMODE_I32);
2444
if (s->env->macsr & MACSR_FI) {
2446
gen_op_and32(tmp, val, gen_im32(0xffff0000));
2448
gen_op_shl32(tmp, val, gen_im32(16));
2449
} else if (s->env->macsr & MACSR_SU) {
2451
gen_op_sar32(tmp, val, gen_im32(16));
2453
gen_op_ext16s32(tmp, val);
2456
gen_op_shr32(tmp, val, gen_im32(16));
2458
gen_op_ext16u32(tmp, val);
2474
int saved_flags = -1;
2476
ext = lduw_code(s->pc);
2479
acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
2480
dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
2481
if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
2482
disas_undef(s, insn);
2486
/* MAC with load. */
2487
tmp = gen_lea(s, insn, OS_LONG);
2488
addr = gen_new_qreg(QMODE_I32);
2489
gen_op_and32(addr, tmp, QREG_MAC_MASK);
2490
/* Load the value now to ensure correct exception behavior.
2491
Perform writeback after reading the MAC inputs. */
2492
loadval = gen_load(s, OS_LONG, addr, 0);
2495
rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2496
ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2498
loadval = addr = -1;
2499
rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2500
ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2503
gen_op_mac_clear_flags();
2505
if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2506
/* Skip the multiply if we know we will ignore it. */
2507
l1 = gen_new_label();
2508
tmp = gen_new_qreg(QMODE_I32);
2509
gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
2510
gen_op_jmp_nz32(tmp, l1);
2513
if ((ext & 0x0800) == 0) {
2515
rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
2516
ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2518
if (s->env->macsr & MACSR_FI) {
2519
gen_op_macmulf(rx, ry);
2521
if (s->env->macsr & MACSR_SU)
2522
gen_op_macmuls(rx, ry);
2524
gen_op_macmulu(rx, ry);
2525
switch ((ext >> 9) & 3) {
2536
/* Save the overflow flag from the multiply. */
2537
saved_flags = gen_new_qreg(QMODE_I32);
2538
gen_op_mov32(saved_flags, QREG_MACSR);
2541
if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2542
/* Skip the accumulate if the value is already saturated. */
2543
l1 = gen_new_label();
2544
tmp = gen_new_qreg(QMODE_I32);
2545
gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2546
gen_op_jmp_nz32(tmp, l1);
2554
if (s->env->macsr & MACSR_FI)
2555
gen_op_macsatf(acc);
2556
else if (s->env->macsr & MACSR_SU)
2557
gen_op_macsats(acc);
2559
gen_op_macsatu(acc);
2565
/* Dual accumulate variant. */
2566
acc = (ext >> 2) & 3;
2567
/* Restore the overflow flag from the multiplier. */
2568
gen_op_mov32(QREG_MACSR, saved_flags);
2569
if ((s->env->macsr & MACSR_OMC) != 0) {
2570
/* Skip the accumulate if the value is already saturated. */
2571
l1 = gen_new_label();
2572
tmp = gen_new_qreg(QMODE_I32);
2573
gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2574
gen_op_jmp_nz32(tmp, l1);
2580
if (s->env->macsr & MACSR_FI)
2581
gen_op_macsatf(acc);
2582
else if (s->env->macsr & MACSR_SU)
2583
gen_op_macsats(acc);
2585
gen_op_macsatu(acc);
2589
gen_op_mac_set_flags(acc);
2593
rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2594
gen_op_mov32(rw, loadval);
2595
/* FIXME: Should address writeback happen with the masked or
2597
switch ((insn >> 3) & 7) {
2598
case 3: /* Post-increment. */
2599
gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
2601
case 4: /* Pre-decrement. */
2602
gen_op_mov32(AREG(insn, 0), addr);
2607
DISAS_INSN(from_mac)
2612
rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2613
acc = (insn >> 9) & 3;
2614
if (s->env->macsr & MACSR_FI) {
2615
gen_op_get_macf(rx, acc);
2616
} else if ((s->env->macsr & MACSR_OMC) == 0) {
2617
gen_op_get_maci(rx, acc);
2618
} else if (s->env->macsr & MACSR_SU) {
2619
gen_op_get_macs(rx, acc);
2621
gen_op_get_macu(rx, acc);
2624
gen_op_clear_mac(acc);
2627
DISAS_INSN(move_mac)
2632
dest = (insn >> 9) & 3;
2633
gen_op_move_mac(dest, src);
2634
gen_op_mac_clear_flags();
2635
gen_op_mac_set_flags(dest);
2638
DISAS_INSN(from_macsr)
2642
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2643
gen_op_mov32(reg, QREG_MACSR);
2646
DISAS_INSN(from_mask)
2649
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2650
gen_op_mov32(reg, QREG_MAC_MASK);
2653
DISAS_INSN(from_mext)
2657
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2658
acc = (insn & 0x400) ? 2 : 0;
2659
if (s->env->macsr & MACSR_FI)
2660
gen_op_get_mac_extf(reg, acc);
2662
gen_op_get_mac_exti(reg, acc);
2665
DISAS_INSN(macsr_to_ccr)
2667
gen_op_mov32(QREG_CC_X, gen_im32(0));
2668
gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
2669
s->cc_op = CC_OP_FLAGS;
2676
acc = (insn >>9) & 3;
2677
SRC_EA(val, OS_LONG, 0, NULL);
2678
if (s->env->macsr & MACSR_FI) {
2679
gen_op_set_macf(val, acc);
2680
} else if (s->env->macsr & MACSR_SU) {
2681
gen_op_set_macs(val, acc);
2683
gen_op_set_macu(val, acc);
2685
gen_op_mac_clear_flags();
2686
gen_op_mac_set_flags(acc);
2689
DISAS_INSN(to_macsr)
2692
SRC_EA(val, OS_LONG, 0, NULL);
2693
gen_op_set_macsr(val);
2700
SRC_EA(val, OS_LONG, 0, NULL);
2701
gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
2708
SRC_EA(val, OS_LONG, 0, NULL);
2709
acc = (insn & 0x400) ? 2 : 0;
2710
if (s->env->macsr & MACSR_FI)
2711
gen_op_set_mac_extf(val, acc);
2712
else if (s->env->macsr & MACSR_SU)
2713
gen_op_set_mac_exts(val, acc);
2715
gen_op_set_mac_extu(val, acc);
2146
2718
static disas_proc opcode_table[65536];
2169
2745
from = opcode & ~(i - 1);
2171
for (i = from; i < to; i++)
2747
for (i = from; i < to; i++) {
2173
2748
if ((i & mask) == opcode)
2174
2749
opcode_table[i] = proc;
2178
2753
/* Register m68k opcode handlers. Order is important.
2179
2754
Later insn override earlier ones. */
2181
register_m68k_insns (m68k_def_t *def)
2755
void register_m68k_insns (CPUM68KState *env)
2185
iflags = def->insns;
2186
#define INSN(name, opcode, mask, isa) \
2187
if (iflags & M68K_INSN_##isa) \
2188
register_opcode(disas_##name, 0x##opcode, 0x##mask)
2189
INSN(undef, 0000, 0000, CF_A);
2190
INSN(arith_im, 0080, fff8, CF_A);
2191
INSN(bitrev, 00c0, fff8, CF_C);
2192
INSN(bitop_reg, 0100, f1c0, CF_A);
2193
INSN(bitop_reg, 0140, f1c0, CF_A);
2194
INSN(bitop_reg, 0180, f1c0, CF_A);
2195
INSN(bitop_reg, 01c0, f1c0, CF_A);
2196
INSN(arith_im, 0280, fff8, CF_A);
2197
INSN(byterev, 02c0, fff8, CF_A);
2198
INSN(arith_im, 0480, fff8, CF_A);
2199
INSN(ff1, 04c0, fff8, CF_C);
2200
INSN(arith_im, 0680, fff8, CF_A);
2201
INSN(bitop_im, 0800, ffc0, CF_A);
2202
INSN(bitop_im, 0840, ffc0, CF_A);
2203
INSN(bitop_im, 0880, ffc0, CF_A);
2204
INSN(bitop_im, 08c0, ffc0, CF_A);
2205
INSN(arith_im, 0a80, fff8, CF_A);
2206
INSN(arith_im, 0c00, ff38, CF_A);
2207
INSN(move, 1000, f000, CF_A);
2208
INSN(move, 2000, f000, CF_A);
2209
INSN(move, 3000, f000, CF_A);
2210
INSN(strldsr, 40e7, ffff, CF_A);
2211
INSN(negx, 4080, fff8, CF_A);
2212
INSN(move_from_sr, 40c0, fff8, CF_A);
2213
INSN(lea, 41c0, f1c0, CF_A);
2214
INSN(clr, 4200, ff00, CF_A);
2215
INSN(undef, 42c0, ffc0, CF_A);
2216
INSN(move_from_ccr, 42c0, fff8, CF_A);
2217
INSN(neg, 4480, fff8, CF_A);
2218
INSN(move_to_ccr, 44c0, ffc0, CF_A);
2219
INSN(not, 4680, fff8, CF_A);
2220
INSN(move_to_sr, 46c0, ffc0, CF_A);
2221
INSN(pea, 4840, ffc0, CF_A);
2222
INSN(swap, 4840, fff8, CF_A);
2223
INSN(movem, 48c0, fbc0, CF_A);
2224
INSN(ext, 4880, fff8, CF_A);
2225
INSN(ext, 48c0, fff8, CF_A);
2226
INSN(ext, 49c0, fff8, CF_A);
2227
INSN(tst, 4a00, ff00, CF_A);
2228
INSN(tas, 4ac0, ffc0, CF_B);
2229
INSN(halt, 4ac8, ffff, CF_A);
2230
INSN(pulse, 4acc, ffff, CF_A);
2231
INSN(illegal, 4afc, ffff, CF_A);
2232
INSN(mull, 4c00, ffc0, CF_A);
2233
INSN(divl, 4c40, ffc0, CF_A);
2234
INSN(sats, 4c80, fff8, CF_B);
2235
INSN(trap, 4e40, fff0, CF_A);
2236
INSN(link, 4e50, fff8, CF_A);
2237
INSN(unlk, 4e58, fff8, CF_A);
2238
INSN(move_to_usp, 4e60, fff8, CF_B);
2239
INSN(move_from_usp, 4e68, fff8, CF_B);
2240
INSN(nop, 4e71, ffff, CF_A);
2241
INSN(stop, 4e72, ffff, CF_A);
2242
INSN(rte, 4e73, ffff, CF_A);
2243
INSN(rts, 4e75, ffff, CF_A);
2244
INSN(movec, 4e7b, ffff, CF_A);
2245
INSN(jump, 4e80, ffc0, CF_A);
2246
INSN(jump, 4ec0, ffc0, CF_A);
2247
INSN(addsubq, 5180, f1c0, CF_A);
2248
INSN(scc, 50c0, f0f8, CF_A);
2249
INSN(addsubq, 5080, f1c0, CF_A);
2250
INSN(tpf, 51f8, fff8, CF_A);
2251
INSN(branch, 6000, f000, CF_A);
2252
INSN(moveq, 7000, f100, CF_A);
2253
INSN(mvzs, 7100, f100, CF_B);
2254
INSN(or, 8000, f000, CF_A);
2255
INSN(divw, 80c0, f0c0, CF_A);
2256
INSN(addsub, 9000, f000, CF_A);
2257
INSN(subx, 9180, f1f8, CF_A);
2258
INSN(suba, 91c0, f1c0, CF_A);
2259
INSN(undef_mac, a000, f000, CF_A);
2260
INSN(mov3q, a140, f1c0, CF_B);
2261
INSN(cmp, b000, f1c0, CF_B); /* cmp.b */
2262
INSN(cmp, b040, f1c0, CF_B); /* cmp.w */
2263
INSN(cmpa, b0c0, f1c0, CF_B); /* cmpa.w */
2264
INSN(cmp, b080, f1c0, CF_A);
2265
INSN(cmpa, b1c0, f1c0, CF_A);
2266
INSN(eor, b180, f1c0, CF_A);
2267
INSN(and, c000, f000, CF_A);
2268
INSN(mulw, c0c0, f0c0, CF_A);
2269
INSN(addsub, d000, f000, CF_A);
2270
INSN(addx, d180, f1f8, CF_A);
2271
INSN(adda, d1c0, f1c0, CF_A);
2272
INSN(shift_im, e080, f0f0, CF_A);
2273
INSN(shift_reg, e0a0, f0f0, CF_A);
2274
INSN(undef_fpu, f000, f000, CF_A);
2757
#define INSN(name, opcode, mask, feature) do { \
2758
if (m68k_feature(env, M68K_FEATURE_##feature)) \
2759
register_opcode(disas_##name, 0x##opcode, 0x##mask); \
2761
INSN(undef, 0000, 0000, CF_ISA_A);
2762
INSN(arith_im, 0080, fff8, CF_ISA_A);
2763
INSN(bitrev, 00c0, fff8, CF_ISA_APLUSC);
2764
INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2765
INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2766
INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2767
INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2768
INSN(arith_im, 0280, fff8, CF_ISA_A);
2769
INSN(byterev, 02c0, fff8, CF_ISA_APLUSC);
2770
INSN(arith_im, 0480, fff8, CF_ISA_A);
2771
INSN(ff1, 04c0, fff8, CF_ISA_APLUSC);
2772
INSN(arith_im, 0680, fff8, CF_ISA_A);
2773
INSN(bitop_im, 0800, ffc0, CF_ISA_A);
2774
INSN(bitop_im, 0840, ffc0, CF_ISA_A);
2775
INSN(bitop_im, 0880, ffc0, CF_ISA_A);
2776
INSN(bitop_im, 08c0, ffc0, CF_ISA_A);
2777
INSN(arith_im, 0a80, fff8, CF_ISA_A);
2778
INSN(arith_im, 0c00, ff38, CF_ISA_A);
2779
INSN(move, 1000, f000, CF_ISA_A);
2780
INSN(move, 2000, f000, CF_ISA_A);
2781
INSN(move, 3000, f000, CF_ISA_A);
2782
INSN(strldsr, 40e7, ffff, CF_ISA_APLUSC);
2783
INSN(negx, 4080, fff8, CF_ISA_A);
2784
INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2785
INSN(lea, 41c0, f1c0, CF_ISA_A);
2786
INSN(clr, 4200, ff00, CF_ISA_A);
2787
INSN(undef, 42c0, ffc0, CF_ISA_A);
2788
INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2789
INSN(neg, 4480, fff8, CF_ISA_A);
2790
INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2791
INSN(not, 4680, fff8, CF_ISA_A);
2792
INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2793
INSN(pea, 4840, ffc0, CF_ISA_A);
2794
INSN(swap, 4840, fff8, CF_ISA_A);
2795
INSN(movem, 48c0, fbc0, CF_ISA_A);
2796
INSN(ext, 4880, fff8, CF_ISA_A);
2797
INSN(ext, 48c0, fff8, CF_ISA_A);
2798
INSN(ext, 49c0, fff8, CF_ISA_A);
2799
INSN(tst, 4a00, ff00, CF_ISA_A);
2800
INSN(tas, 4ac0, ffc0, CF_ISA_B);
2801
INSN(halt, 4ac8, ffff, CF_ISA_A);
2802
INSN(pulse, 4acc, ffff, CF_ISA_A);
2803
INSN(illegal, 4afc, ffff, CF_ISA_A);
2804
INSN(mull, 4c00, ffc0, CF_ISA_A);
2805
INSN(divl, 4c40, ffc0, CF_ISA_A);
2806
INSN(sats, 4c80, fff8, CF_ISA_B);
2807
INSN(trap, 4e40, fff0, CF_ISA_A);
2808
INSN(link, 4e50, fff8, CF_ISA_A);
2809
INSN(unlk, 4e58, fff8, CF_ISA_A);
2810
INSN(move_to_usp, 4e60, fff8, USP);
2811
INSN(move_from_usp, 4e68, fff8, USP);
2812
INSN(nop, 4e71, ffff, CF_ISA_A);
2813
INSN(stop, 4e72, ffff, CF_ISA_A);
2814
INSN(rte, 4e73, ffff, CF_ISA_A);
2815
INSN(rts, 4e75, ffff, CF_ISA_A);
2816
INSN(movec, 4e7b, ffff, CF_ISA_A);
2817
INSN(jump, 4e80, ffc0, CF_ISA_A);
2818
INSN(jump, 4ec0, ffc0, CF_ISA_A);
2819
INSN(addsubq, 5180, f1c0, CF_ISA_A);
2820
INSN(scc, 50c0, f0f8, CF_ISA_A);
2821
INSN(addsubq, 5080, f1c0, CF_ISA_A);
2822
INSN(tpf, 51f8, fff8, CF_ISA_A);
2824
/* Branch instructions. */
2825
INSN(branch, 6000, f000, CF_ISA_A);
2826
/* Disable long branch instructions, then add back the ones we want. */
2827
INSN(undef, 60ff, f0ff, CF_ISA_A); /* All long branches. */
2828
INSN(branch, 60ff, f0ff, CF_ISA_B);
2829
INSN(undef, 60ff, ffff, CF_ISA_B); /* bra.l */
2830
INSN(branch, 60ff, ffff, BRAL);
2832
INSN(moveq, 7000, f100, CF_ISA_A);
2833
INSN(mvzs, 7100, f100, CF_ISA_B);
2834
INSN(or, 8000, f000, CF_ISA_A);
2835
INSN(divw, 80c0, f0c0, CF_ISA_A);
2836
INSN(addsub, 9000, f000, CF_ISA_A);
2837
INSN(subx, 9180, f1f8, CF_ISA_A);
2838
INSN(suba, 91c0, f1c0, CF_ISA_A);
2840
INSN(undef_mac, a000, f000, CF_ISA_A);
2841
INSN(mac, a000, f100, CF_EMAC);
2842
INSN(from_mac, a180, f9b0, CF_EMAC);
2843
INSN(move_mac, a110, f9fc, CF_EMAC);
2844
INSN(from_macsr,a980, f9f0, CF_EMAC);
2845
INSN(from_mask, ad80, fff0, CF_EMAC);
2846
INSN(from_mext, ab80, fbf0, CF_EMAC);
2847
INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
2848
INSN(to_mac, a100, f9c0, CF_EMAC);
2849
INSN(to_macsr, a900, ffc0, CF_EMAC);
2850
INSN(to_mext, ab00, fbc0, CF_EMAC);
2851
INSN(to_mask, ad00, ffc0, CF_EMAC);
2853
INSN(mov3q, a140, f1c0, CF_ISA_B);
2854
INSN(cmp, b000, f1c0, CF_ISA_B); /* cmp.b */
2855
INSN(cmp, b040, f1c0, CF_ISA_B); /* cmp.w */
2856
INSN(cmpa, b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2857
INSN(cmp, b080, f1c0, CF_ISA_A);
2858
INSN(cmpa, b1c0, f1c0, CF_ISA_A);
2859
INSN(eor, b180, f1c0, CF_ISA_A);
2860
INSN(and, c000, f000, CF_ISA_A);
2861
INSN(mulw, c0c0, f0c0, CF_ISA_A);
2862
INSN(addsub, d000, f000, CF_ISA_A);
2863
INSN(addx, d180, f1f8, CF_ISA_A);
2864
INSN(adda, d1c0, f1c0, CF_ISA_A);
2865
INSN(shift_im, e080, f0f0, CF_ISA_A);
2866
INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2867
INSN(undef_fpu, f000, f000, CF_ISA_A);
2275
2868
INSN(fpu, f200, ffc0, CF_FPU);
2276
2869
INSN(fbcc, f280, ffc0, CF_FPU);
2277
INSN(intouch, f340, ffc0, CF_A);
2278
INSN(cpushl, f428, ff38, CF_A);
2279
INSN(wddata, fb00, ff00, CF_A);
2280
INSN(wdebug, fbc0, ffc0, CF_A);
2870
INSN(frestore, f340, ffc0, CF_FPU);
2871
INSN(fsave, f340, ffc0, CF_FPU);
2872
INSN(intouch, f340, ffc0, CF_ISA_A);
2873
INSN(cpushl, f428, ff38, CF_ISA_A);
2874
INSN(wddata, fb00, ff00, CF_ISA_A);
2875
INSN(wdebug, fbc0, ffc0, CF_ISA_A);