~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to target-m68k/translate.c

Tags: upstream-0.9.0+20070816
ImportĀ upstreamĀ versionĀ 0.9.0+20070816

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  m68k translation
3
3
 * 
4
 
 *  Copyright (c) 2005-2006 CodeSourcery
 
4
 *  Copyright (c) 2005-2007 CodeSourcery
5
5
 *  Written by Paul Brook
6
6
 *
7
7
 * This library is free software; you can redistribute it and/or
30
30
#include "disas.h"
31
31
#include "m68k-qreg.h"
32
32
 
 
33
//#define DEBUG_DISPATCH 1
 
34
 
33
35
static inline void qemu_assert(int cond, const char *msg)
34
36
{
35
37
    if (!cond) {
40
42
 
41
43
/* internal defines */
42
44
typedef struct DisasContext {
 
45
    CPUM68KState *env;
 
46
    target_ulong insn_pc; /* Start of the current instruction.  */
43
47
    target_ulong pc;
44
48
    int is_jmp;
45
49
    int cc_op;
 
50
    int user;
46
51
    uint32_t fpcr;
47
52
    struct TranslationBlock *tb;
48
53
    int singlestep_enabled;
 
54
    int is_mem;
49
55
} DisasContext;
50
56
 
51
57
#define DISAS_JUMP_NEXT 4
52
58
 
 
59
#if defined(CONFIG_USER_ONLY)
 
60
#define IS_USER(s) 1
 
61
#else
 
62
#define IS_USER(s) s->user
 
63
#endif
 
64
 
53
65
/* XXX: move that elsewhere */
54
66
/* ??? Fix exceptions.  */
55
67
static void *gen_throws_exception;
68
80
};
69
81
 
70
82
#include "gen-op.h"
 
83
 
 
84
#if defined(CONFIG_USER_ONLY)
 
85
#define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
 
86
#define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
 
87
#else
 
88
#define gen_st(s, name, addr, val) do { \
 
89
    if (IS_USER(s)) \
 
90
        gen_op_st##name##_user(addr, val); \
 
91
    else \
 
92
        gen_op_st##name##_kernel(addr, val); \
 
93
    } while (0)
 
94
#define gen_ld(s, name, val, addr) do { \
 
95
    if (IS_USER(s)) \
 
96
        gen_op_ld##name##_user(val, addr); \
 
97
    else \
 
98
        gen_op_ld##name##_kernel(val, addr); \
 
99
    } while (0)
 
100
#endif
 
101
 
71
102
#include "op-hacks.h"
72
103
 
73
104
#define OS_BYTE 0
80
111
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
81
112
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
82
113
 
83
 
#define M68K_INSN_CF_A    (1 << 0)
84
 
#define M68K_INSN_CF_B    (1 << 1)
85
 
#define M68K_INSN_CF_C    (1 << 2)
86
 
#define M68K_INSN_CF_MAC  (1 << 3)
87
 
#define M68K_INSN_CF_EMAC (1 << 4)
88
 
#define M68K_INSN_CF_FPU  (1 << 5)
89
 
 
90
 
struct m68k_def_t {
91
 
    const char * name;
92
 
    uint32_t insns;
93
 
};
94
 
 
95
 
static m68k_def_t m68k_cpu_defs[] = {
96
 
    {"m5206", M68K_INSN_CF_A},
97
 
    {"cfv4e", M68K_INSN_CF_A | M68K_INSN_CF_B | M68K_INSN_CF_C
98
 
            | M68K_INSN_CF_MAC | M68K_INSN_CF_EMAC | M68K_INSN_CF_FPU},
99
 
    {NULL, 0}, 
100
 
};
101
 
 
102
114
typedef void (*disas_proc)(DisasContext *, uint16_t);
103
115
 
 
116
#ifdef DEBUG_DISPATCH
 
117
#define DISAS_INSN(name) \
 
118
  static void real_disas_##name (DisasContext *s, uint16_t insn); \
 
119
  static void disas_##name (DisasContext *s, uint16_t insn) { \
 
120
    if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
 
121
    real_disas_##name(s, insn); } \
 
122
  static void real_disas_##name (DisasContext *s, uint16_t insn)
 
123
#else
104
124
#define DISAS_INSN(name) \
105
125
  static void disas_##name (DisasContext *s, uint16_t insn)
 
126
#endif
106
127
 
107
128
/* Generate a load from the specified address.  Narrow values are
108
129
   sign extended to full register width.  */
109
 
static inline int gen_load(int opsize, int addr, int sign)
 
130
static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
110
131
{
111
132
    int tmp;
 
133
    s->is_mem = 1;
112
134
    switch(opsize) {
113
135
    case OS_BYTE:
114
136
        tmp = gen_new_qreg(QMODE_I32);
115
137
        if (sign)
116
 
            gen_op_ld8s32(tmp, addr);
 
138
            gen_ld(s, 8s32, tmp, addr);
117
139
        else
118
 
            gen_op_ld8u32(tmp, addr);
 
140
            gen_ld(s, 8u32, tmp, addr);
119
141
        break;
120
142
    case OS_WORD:
121
143
        tmp = gen_new_qreg(QMODE_I32);
122
144
        if (sign)
123
 
            gen_op_ld16s32(tmp, addr);
 
145
            gen_ld(s, 16s32, tmp, addr);
124
146
        else
125
 
            gen_op_ld16u32(tmp, addr);
 
147
            gen_ld(s, 16u32, tmp, addr);
126
148
        break;
127
149
    case OS_LONG:
128
150
        tmp = gen_new_qreg(QMODE_I32);
129
 
        gen_op_ld32(tmp, addr);
 
151
        gen_ld(s, 32, tmp, addr);
130
152
        break;
131
153
    case OS_SINGLE:
132
154
        tmp = gen_new_qreg(QMODE_F32);
133
 
        gen_op_ldf32(tmp, addr);
 
155
        gen_ld(s, f32, tmp, addr);
134
156
        break;
135
157
    case OS_DOUBLE:
136
158
        tmp  = gen_new_qreg(QMODE_F64);
137
 
        gen_op_ldf64(tmp, addr);
 
159
        gen_ld(s, f64, tmp, addr);
138
160
        break;
139
161
    default:
140
162
        qemu_assert(0, "bad load size");
144
166
}
145
167
 
146
168
/* Generate a store.  */
147
 
static inline void gen_store(int opsize, int addr, int val)
 
169
static inline void gen_store(DisasContext *s, int opsize, int addr, int val)
148
170
{
 
171
    s->is_mem = 1;
149
172
    switch(opsize) {
150
173
    case OS_BYTE:
151
 
        gen_op_st8(addr, val);
 
174
        gen_st(s, 8, addr, val);
152
175
        break;
153
176
    case OS_WORD:
154
 
        gen_op_st16(addr, val);
 
177
        gen_st(s, 16, addr, val);
155
178
        break;
156
179
    case OS_LONG:
157
 
        gen_op_st32(addr, val);
 
180
        gen_st(s, 32, addr, val);
158
181
        break;
159
182
    case OS_SINGLE:
160
 
        gen_op_stf32(addr, val);
 
183
        gen_st(s, f32, addr, val);
161
184
        break;
162
185
    case OS_DOUBLE:
163
 
        gen_op_stf64(addr, val);
 
186
        gen_st(s, f64, addr, val);
164
187
        break;
165
188
    default:
166
189
        qemu_assert(0, "bad store size");
170
193
 
171
194
/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
172
195
   otherwise generate a store.  */
173
 
static int gen_ldst(int opsize, int addr, int val)
 
196
static int gen_ldst(DisasContext *s, int opsize, int addr, int val)
174
197
{
175
198
    if (val > 0) {
176
 
        gen_store(opsize, addr, val);
 
199
        gen_store(s, opsize, addr, val);
177
200
        return 0;
178
201
    } else {
179
 
        return gen_load(opsize, addr, val != 0);
180
 
    }
 
202
        return gen_load(s, opsize, addr, val != 0);
 
203
    }
 
204
}
 
205
 
 
206
/* Read a 32-bit immediate constant.  */
 
207
static inline uint32_t read_im32(DisasContext *s)
 
208
{
 
209
    uint32_t im;
 
210
    im = ((uint32_t)lduw_code(s->pc)) << 16;
 
211
    s->pc += 2;
 
212
    im |= lduw_code(s->pc);
 
213
    s->pc += 2;
 
214
    return im;
 
215
}
 
216
 
 
217
/* Calculate and address index.  */
 
218
static int gen_addr_index(uint16_t ext, int tmp)
 
219
{
 
220
    int add;
 
221
    int scale;
 
222
 
 
223
    add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
 
224
    if ((ext & 0x800) == 0) {
 
225
        gen_op_ext16s32(tmp, add);
 
226
        add = tmp;
 
227
    }
 
228
    scale = (ext >> 9) & 3;
 
229
    if (scale != 0) {
 
230
        gen_op_shl32(tmp, add, gen_im32(scale));
 
231
        add = tmp;
 
232
    }
 
233
    return add;
181
234
}
182
235
 
183
236
/* Handle a base + index + displacement effective addresss.  A base of
184
237
   -1 means pc-relative.  */
185
238
static int gen_lea_indexed(DisasContext *s, int opsize, int base)
186
239
{
187
 
    int scale;
188
240
    uint32_t offset;
189
241
    uint16_t ext;
190
242
    int add;
191
243
    int tmp;
 
244
    uint32_t bd, od;
192
245
 
193
246
    offset = s->pc;
194
 
    ext = lduw(s->pc);
 
247
    ext = lduw_code(s->pc);
195
248
    s->pc += 2;
196
 
    tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
197
 
    /* ??? Check W/L bit.  */
198
 
    scale = (ext >> 9) & 3;
199
 
    if (scale == 0) {
 
249
 
 
250
    if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
 
251
        return -1;
 
252
 
 
253
    if (ext & 0x100) {
 
254
        /* full extension word format */
 
255
        if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
 
256
            return -1;
 
257
 
 
258
        if ((ext & 0x30) > 0x10) {
 
259
            /* base displacement */
 
260
            if ((ext & 0x30) == 0x20) {
 
261
                bd = (int16_t)lduw_code(s->pc);
 
262
                s->pc += 2;
 
263
            } else {
 
264
                bd = read_im32(s);
 
265
            }
 
266
        } else {
 
267
            bd = 0;
 
268
        }
 
269
        tmp = gen_new_qreg(QMODE_I32);
 
270
        if ((ext & 0x44) == 0) {
 
271
            /* pre-index */
 
272
            add = gen_addr_index(ext, tmp);
 
273
        } else {
 
274
            add = QREG_NULL;
 
275
        }
 
276
        if ((ext & 0x80) == 0) {
 
277
            /* base not suppressed */
 
278
            if (base == -1) {
 
279
                base = gen_im32(offset + bd);
 
280
                bd = 0;
 
281
            }
 
282
            if (add) {
 
283
                gen_op_add32(tmp, add, base);
 
284
                add = tmp;
 
285
            } else {
 
286
                add = base;
 
287
            }
 
288
        }
 
289
        if (add) {
 
290
            if (bd != 0) {
 
291
                gen_op_add32(tmp, add, gen_im32(bd));
 
292
                add = tmp;
 
293
            }
 
294
        } else {
 
295
            add = gen_im32(bd);
 
296
        }
 
297
        if ((ext & 3) != 0) {
 
298
            /* memory indirect */
 
299
            base = gen_load(s, OS_LONG, add, 0);
 
300
            if ((ext & 0x44) == 4) {
 
301
                add = gen_addr_index(ext, tmp);
 
302
                gen_op_add32(tmp, add, base);
 
303
                add = tmp;
 
304
            } else {
 
305
                add = base;
 
306
            }
 
307
            if ((ext & 3) > 1) {
 
308
                /* outer displacement */
 
309
                if ((ext & 3) == 2) {
 
310
                    od = (int16_t)lduw_code(s->pc);
 
311
                    s->pc += 2;
 
312
                } else {
 
313
                    od = read_im32(s);
 
314
                }
 
315
            } else {
 
316
                od = 0;
 
317
            }
 
318
            if (od != 0) {
 
319
                gen_op_add32(tmp, add, gen_im32(od));
 
320
                add = tmp;
 
321
            }
 
322
        }
 
323
    } else {
 
324
        /* brief extension word format */
 
325
        tmp = gen_new_qreg(QMODE_I32);
 
326
        add = gen_addr_index(ext, tmp);
 
327
        if (base != -1) {
 
328
            gen_op_add32(tmp, add, base);
 
329
            if ((int8_t)ext)
 
330
                gen_op_add32(tmp, tmp, gen_im32((int8_t)ext));
 
331
        } else {
 
332
            gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
 
333
        }
200
334
        add = tmp;
201
 
    } else {
202
 
        add = gen_new_qreg(QMODE_I32);
203
 
        gen_op_shl32(add, tmp, gen_im32(scale));
204
 
    }
205
 
    tmp = gen_new_qreg(QMODE_I32);
206
 
    if (base != -1) {
207
 
        gen_op_add32(tmp, base, gen_im32((int8_t)ext));
208
 
        gen_op_add32(tmp, tmp, add);
209
 
    } else {
210
 
        gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
211
 
    }
212
 
    return tmp;
213
 
}
214
 
 
215
 
/* Read a 32-bit immediate constant.  */
216
 
static inline uint32_t read_im32(DisasContext *s)
217
 
{
218
 
    uint32_t im;
219
 
    im = ((uint32_t)lduw(s->pc)) << 16;
220
 
    s->pc += 2;
221
 
    im |= lduw(s->pc);
222
 
    s->pc += 2;
223
 
    return im;
224
 
}
225
 
 
 
335
    }
 
336
    return add;
 
337
}
226
338
 
227
339
/* Update the CPU env CC_OP state.  */
228
340
static inline void gen_flush_cc_op(DisasContext *s)
236
348
{
237
349
    if (s->cc_op == CC_OP_FLAGS)
238
350
        return;
239
 
    gen_op_flush_flags(s->cc_op);
 
351
    gen_flush_cc_op(s);
 
352
    gen_op_flush_flags();
240
353
    s->cc_op = CC_OP_FLAGS;
241
354
}
242
355
 
329
442
    switch ((insn >> 3) & 7) {
330
443
    case 0: /* Data register direct.  */
331
444
    case 1: /* Address register direct.  */
332
 
        /* ??? generate bad addressing mode fault.  */
333
 
        qemu_assert(0, "invalid addressing mode");
 
445
        return -1;
334
446
    case 2: /* Indirect register */
335
447
    case 3: /* Indirect postincrement.  */
336
448
        reg += QREG_A0;
343
455
    case 5: /* Indirect displacement.  */
344
456
        reg += QREG_A0;
345
457
        tmp = gen_new_qreg(QMODE_I32);
346
 
        ext = lduw(s->pc);
 
458
        ext = lduw_code(s->pc);
347
459
        s->pc += 2;
348
460
        gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
349
461
        return tmp;
353
465
    case 7: /* Other */
354
466
        switch (reg) {
355
467
        case 0: /* Absolute short.  */
356
 
            offset = ldsw(s->pc);
 
468
            offset = ldsw_code(s->pc);
357
469
            s->pc += 2;
358
470
            return gen_im32(offset);
359
471
        case 1: /* Absolute long.  */
362
474
        case 2: /* pc displacement  */
363
475
            tmp = gen_new_qreg(QMODE_I32);
364
476
            offset = s->pc;
365
 
            offset += ldsw(s->pc);
 
477
            offset += ldsw_code(s->pc);
366
478
            s->pc += 2;
367
479
            return gen_im32(offset);
368
480
        case 3: /* pc index+displacement.  */
369
481
            return gen_lea_indexed(s, opsize, -1);
370
482
        case 4: /* Immediate.  */
371
483
        default:
372
 
            /* ??? generate bad addressing mode fault.  */
373
 
            qemu_assert(0, "invalid addressing mode");
 
484
            return -1;
374
485
        }
375
486
    }
376
487
    /* Should never happen.  */
388
499
        tmp = *addrp;
389
500
    } else {
390
501
        tmp = gen_lea(s, insn, opsize);
 
502
        if (tmp == -1)
 
503
            return -1;
391
504
        if (addrp)
392
505
            *addrp = tmp;
393
506
    }
394
 
    return gen_ldst(opsize, tmp, val);
 
507
    return gen_ldst(s, opsize, tmp, val);
395
508
}
396
509
 
397
510
/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
424
537
        }
425
538
    case 2: /* Indirect register */
426
539
        reg += QREG_A0;
427
 
        return gen_ldst(opsize, reg, val);
 
540
        return gen_ldst(s, opsize, reg, val);
428
541
    case 3: /* Indirect postincrement.  */
429
542
        reg += QREG_A0;
430
 
        result = gen_ldst(opsize, reg, val);
 
543
        result = gen_ldst(s, opsize, reg, val);
431
544
        /* ??? This is not exception safe.  The instruction may still
432
545
           fault after this point.  */
433
546
        if (val > 0 || !addrp)
440
553
                tmp = *addrp;
441
554
            } else {
442
555
                tmp = gen_lea(s, insn, opsize);
 
556
                if (tmp == -1)
 
557
                    return -1;
443
558
                if (addrp)
444
559
                    *addrp = tmp;
445
560
            }
446
 
            result = gen_ldst(opsize, tmp, val);
 
561
            result = gen_ldst(s, opsize, tmp, val);
447
562
            /* ??? This is not exception safe.  The instruction may still
448
563
               fault after this point.  */
449
564
            if (val > 0 || !addrp) {
467
582
            switch (opsize) {
468
583
            case OS_BYTE:
469
584
                if (val)
470
 
                    offset = ldsb(s->pc + 1);
 
585
                    offset = ldsb_code(s->pc + 1);
471
586
                else
472
 
                    offset = ldub(s->pc + 1);
 
587
                    offset = ldub_code(s->pc + 1);
473
588
                s->pc += 2;
474
589
                break;
475
590
            case OS_WORD:
476
591
                if (val)
477
 
                    offset = ldsw(s->pc);
 
592
                    offset = ldsw_code(s->pc);
478
593
                else
479
 
                    offset = lduw(s->pc);
 
594
                    offset = lduw_code(s->pc);
480
595
                s->pc += 2;
481
596
                break;
482
597
            case OS_LONG:
487
602
            }
488
603
            return gen_im32(offset);
489
604
        default:
490
 
            qemu_assert(0, "invalid addressing mode");
 
605
            return -1;
491
606
        }
492
607
    }
493
608
    /* Should never happen.  */
622
737
    gen_set_label(l1);
623
738
}
624
739
 
 
740
/* Force a TB lookup after an instruction that changes the CPU state.  */
 
741
static void gen_lookup_tb(DisasContext *s)
 
742
{
 
743
    gen_flush_cc_op(s);
 
744
    gen_op_mov32(QREG_PC, gen_im32(s->pc));
 
745
    s->is_jmp = DISAS_UPDATE;
 
746
}
 
747
 
625
748
/* Generate a jump to to the address in qreg DEST.  */
626
749
static void gen_jmp(DisasContext *s, int dest)
627
750
{
637
760
    gen_op_raise_exception(nr);
638
761
}
639
762
 
 
763
static inline void gen_addr_fault(DisasContext *s)
 
764
{
 
765
    gen_exception(s, s->insn_pc, EXCP_ADDRESS);
 
766
}
 
767
 
 
768
#define SRC_EA(result, opsize, val, addrp) do { \
 
769
    result = gen_ea(s, insn, opsize, val, addrp); \
 
770
    if (result == -1) { \
 
771
        gen_addr_fault(s); \
 
772
        return; \
 
773
    } \
 
774
    } while (0)
 
775
 
 
776
#define DEST_EA(insn, opsize, val, addrp) do { \
 
777
    int ea_result = gen_ea(s, insn, opsize, val, addrp); \
 
778
    if (ea_result == -1) { \
 
779
        gen_addr_fault(s); \
 
780
        return; \
 
781
    } \
 
782
    } while (0)
 
783
 
640
784
/* Generate a jump to an immediate address.  */
641
785
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
642
786
{
690
834
        gen_op_ext16s32(tmp, reg);
691
835
    else
692
836
        gen_op_ext16u32(tmp, reg);
693
 
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
 
837
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
694
838
    gen_op_mul32(tmp, tmp, src);
695
839
    gen_op_mov32(reg, tmp);
696
840
    /* Unlike m68k, coldfire always clears the overflow bit.  */
711
855
    } else {
712
856
        gen_op_ext16u32(QREG_DIV1, reg);
713
857
    }
714
 
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
 
858
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
715
859
    gen_op_mov32(QREG_DIV2, src);
716
860
    if (sign) {
717
861
        gen_op_divs(1);
735
879
    int reg;
736
880
    uint16_t ext;
737
881
 
738
 
    ext = lduw(s->pc);
 
882
    ext = lduw_code(s->pc);
739
883
    s->pc += 2;
740
884
    if (ext & 0x87f8) {
741
885
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
744
888
    num = DREG(ext, 12);
745
889
    reg = DREG(ext, 0);
746
890
    gen_op_mov32(QREG_DIV1, num);
747
 
    den = gen_ea(s, insn, OS_LONG, 0, NULL);
 
891
    SRC_EA(den, OS_LONG, 0, NULL);
748
892
    gen_op_mov32(QREG_DIV2, den);
749
893
    if (ext & 0x0800) {
750
894
        gen_op_divs(2);
775
919
    reg = DREG(insn, 9);
776
920
    dest = gen_new_qreg(QMODE_I32);
777
921
    if (insn & 0x100) {
778
 
        tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
 
922
        SRC_EA(tmp, OS_LONG, 0, &addr);
779
923
        src = reg;
780
924
    } else {
781
925
        tmp = reg;
782
 
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
 
926
        SRC_EA(src, OS_LONG, 0, NULL);
783
927
    }
784
928
    if (add) {
785
929
        gen_op_add32(dest, tmp, src);
792
936
    }
793
937
    gen_op_update_cc_add(dest, src);
794
938
    if (insn & 0x100) {
795
 
        gen_ea(s, insn, OS_LONG, dest, &addr);
 
939
        DEST_EA(insn, OS_LONG, dest, &addr);
796
940
    } else {
797
941
        gen_op_mov32(reg, dest);
798
942
    }
850
994
    else
851
995
        opsize = OS_LONG;
852
996
    op = (insn >> 6) & 3;
853
 
    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
 
997
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
854
998
    src2 = DREG(insn, 9);
855
999
    dest = gen_new_qreg(QMODE_I32);
856
1000
 
880
1024
        break;
881
1025
    }
882
1026
    if (op)
883
 
        gen_ea(s, insn, opsize, dest, &addr);
 
1027
        DEST_EA(insn, opsize, dest, &addr);
884
1028
}
885
1029
 
886
1030
DISAS_INSN(sats)
903
1047
    gen_logic_cc(s, tmp);
904
1048
}
905
1049
 
906
 
static void gen_push(int val)
 
1050
static void gen_push(DisasContext *s, int val)
907
1051
{
908
1052
    int tmp;
909
1053
 
910
1054
    tmp = gen_new_qreg(QMODE_I32);
911
1055
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
912
 
    gen_store(OS_LONG, tmp, val);
 
1056
    gen_store(s, OS_LONG, tmp, val);
913
1057
    gen_op_mov32(QREG_SP, tmp);
914
1058
}
915
1059
 
922
1066
    int tmp;
923
1067
    int is_load;
924
1068
 
925
 
    mask = lduw(s->pc);
 
1069
    mask = lduw_code(s->pc);
926
1070
    s->pc += 2;
927
1071
    tmp = gen_lea(s, insn, OS_LONG);
 
1072
    if (tmp == -1) {
 
1073
        gen_addr_fault(s);
 
1074
        return;
 
1075
    }
928
1076
    addr = gen_new_qreg(QMODE_I32);
929
1077
    gen_op_mov32(addr, tmp);
930
1078
    is_load = ((insn & 0x0400) != 0);
935
1083
            else
936
1084
                reg = AREG(i, 0);
937
1085
            if (is_load) {
938
 
                tmp = gen_load(OS_LONG, addr, 0);
 
1086
                tmp = gen_load(s, OS_LONG, addr, 0);
939
1087
                gen_op_mov32(reg, tmp);
940
1088
            } else {
941
 
                gen_store(OS_LONG, addr, reg);
 
1089
                gen_store(s, OS_LONG, addr, reg);
942
1090
            }
943
1091
            if (mask != 1)
944
1092
                gen_op_add32(addr, addr, gen_im32(4));
963
1111
        opsize = OS_LONG;
964
1112
    op = (insn >> 6) & 3;
965
1113
 
966
 
    bitnum = lduw(s->pc);
 
1114
    bitnum = lduw_code(s->pc);
967
1115
    s->pc += 2;
968
1116
    if (bitnum & 0xff00) {
969
1117
        disas_undef(s, insn);
970
1118
        return;
971
1119
    }
972
1120
 
973
 
    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
 
1121
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
974
1122
 
975
1123
    gen_flush_flags(s);
976
1124
    tmp = gen_new_qreg(QMODE_I32);
1000
1148
        break;
1001
1149
    }
1002
1150
    if (op)
1003
 
        gen_ea(s, insn, opsize, dest, &addr);
 
1151
        DEST_EA(insn, opsize, dest, &addr);
1004
1152
}
1005
1153
 
1006
1154
DISAS_INSN(arith_im)
1012
1160
    int addr;
1013
1161
 
1014
1162
    op = (insn >> 9) & 7;
1015
 
    src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
 
1163
    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1016
1164
    src2 = gen_im32(read_im32(s));
1017
1165
    dest = gen_new_qreg(QMODE_I32);
1018
1166
    switch (op) {
1052
1200
        abort();
1053
1201
    }
1054
1202
    if (op != 6) {
1055
 
        gen_ea(s, insn, OS_LONG, dest, &addr);
 
1203
        DEST_EA(insn, OS_LONG, dest, &addr);
1056
1204
    }
1057
1205
}
1058
1206
 
1084
1232
    default:
1085
1233
        abort();
1086
1234
    }
1087
 
    src = gen_ea(s, insn, opsize, -1, NULL);
 
1235
    SRC_EA(src, opsize, -1, NULL);
1088
1236
    op = (insn >> 6) & 7;
1089
1237
    if (op == 1) {
1090
1238
        /* movea */
1095
1243
        /* normal move */
1096
1244
        uint16_t dest_ea;
1097
1245
        dest_ea = ((insn >> 9) & 7) | (op << 3);
1098
 
        gen_ea(s, dest_ea, opsize, src, NULL);
 
1246
        DEST_EA(dest_ea, opsize, src, NULL);
1099
1247
        /* This will be correct because loads sign extend.  */
1100
1248
        gen_logic_cc(s, src);
1101
1249
    }
1131
1279
 
1132
1280
    reg = AREG(insn, 9);
1133
1281
    tmp = gen_lea(s, insn, OS_LONG);
 
1282
    if (tmp == -1) {
 
1283
        gen_addr_fault(s);
 
1284
        return;
 
1285
    }
1134
1286
    gen_op_mov32(reg, tmp);
1135
1287
}
1136
1288
 
1151
1303
    default:
1152
1304
        abort();
1153
1305
    }
1154
 
    gen_ea (s, insn, opsize, gen_im32(0), NULL);
 
1306
    DEST_EA(insn, opsize, gen_im32(0), NULL);
1155
1307
    gen_logic_cc(s, gen_im32(0));
1156
1308
}
1157
1309
 
1158
 
DISAS_INSN(move_from_ccr)
 
1310
static int gen_get_ccr(DisasContext *s)
1159
1311
{
1160
 
    int reg;
1161
1312
    int dest;
1162
1313
 
1163
1314
    gen_flush_flags(s);
1165
1316
    gen_op_get_xflag(dest);
1166
1317
    gen_op_shl32(dest, dest, gen_im32(4));
1167
1318
    gen_op_or32(dest, dest, QREG_CC_DEST);
 
1319
    return dest;
 
1320
}
 
1321
 
 
1322
DISAS_INSN(move_from_ccr)
 
1323
{
 
1324
    int reg;
 
1325
    int ccr;
 
1326
 
 
1327
    ccr = gen_get_ccr(s);
1168
1328
    reg = DREG(insn, 0);
1169
 
    gen_partset_reg(OS_WORD, reg, dest);
 
1329
    gen_partset_reg(OS_WORD, reg, ccr);
1170
1330
}
1171
1331
 
1172
1332
DISAS_INSN(neg)
1184
1344
    s->cc_op = CC_OP_SUB;
1185
1345
}
1186
1346
 
1187
 
DISAS_INSN(move_to_ccr)
 
1347
static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
 
1348
{
 
1349
    gen_op_logic_cc(gen_im32(val & 0xf));
 
1350
    gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
 
1351
    if (!ccr_only) {
 
1352
        gen_op_set_sr(gen_im32(val & 0xff00));
 
1353
    }
 
1354
}
 
1355
 
 
1356
static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1188
1357
{
1189
1358
    int src1;
1190
1359
    int reg;
1199
1368
        gen_op_shr32(src1, reg, gen_im32(4));
1200
1369
        gen_op_and32(src1, src1, gen_im32(1));
1201
1370
        gen_op_update_xflag_tst(src1);
 
1371
        if (!ccr_only) {
 
1372
            gen_op_set_sr(reg);
 
1373
        }
1202
1374
      }
1203
 
    else if ((insn & 0x3f) != 0x3c)
 
1375
    else if ((insn & 0x3f) == 0x3c)
1204
1376
      {
1205
 
        uint8_t val;
1206
 
        val = ldsb(s->pc);
 
1377
        uint16_t val;
 
1378
        val = lduw_code(s->pc);
1207
1379
        s->pc += 2;
1208
 
        gen_op_logic_cc(gen_im32(val & 0xf));
1209
 
        gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
 
1380
        gen_set_sr_im(s, val, ccr_only);
1210
1381
      }
1211
1382
    else
1212
1383
        disas_undef(s, insn);
1213
1384
}
1214
1385
 
 
1386
DISAS_INSN(move_to_ccr)
 
1387
{
 
1388
    gen_set_sr(s, insn, 1);
 
1389
}
 
1390
 
1215
1391
DISAS_INSN(not)
1216
1392
{
1217
1393
    int reg;
1244
1420
    int tmp;
1245
1421
 
1246
1422
    tmp = gen_lea(s, insn, OS_LONG);
1247
 
    gen_push(tmp);
 
1423
    if (tmp == -1) {
 
1424
        gen_addr_fault(s);
 
1425
        return;
 
1426
    }
 
1427
    gen_push(s, tmp);
1248
1428
}
1249
1429
 
1250
1430
DISAS_INSN(ext)
1285
1465
    default:
1286
1466
        abort();
1287
1467
    }
1288
 
    tmp = gen_ea(s, insn, opsize, -1, NULL);
 
1468
    SRC_EA(tmp, opsize, -1, NULL);
1289
1469
    gen_logic_cc(s, tmp);
1290
1470
}
1291
1471
 
1307
1487
    int addr;
1308
1488
 
1309
1489
    dest = gen_new_qreg(QMODE_I32);
1310
 
    src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
 
1490
    SRC_EA(src1, OS_BYTE, -1, &addr);
1311
1491
    gen_logic_cc(s, src1);
1312
1492
    gen_op_or32(dest, src1, gen_im32(0x80));
1313
 
    gen_ea(s, insn, OS_BYTE, dest, &addr);
 
1493
    DEST_EA(insn, OS_BYTE, dest, &addr);
1314
1494
}
1315
1495
 
1316
1496
DISAS_INSN(mull)
1322
1502
 
1323
1503
    /* The upper 32 bits of the product are discarded, so
1324
1504
       muls.l and mulu.l are functionally equivalent.  */
1325
 
    ext = lduw(s->pc);
 
1505
    ext = lduw_code(s->pc);
1326
1506
    s->pc += 2;
1327
1507
    if (ext & 0x87ff) {
1328
1508
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1329
1509
        return;
1330
1510
    }
1331
1511
    reg = DREG(ext, 12);
1332
 
    src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
 
1512
    SRC_EA(src1, OS_LONG, 0, NULL);
1333
1513
    dest = gen_new_qreg(QMODE_I32);
1334
1514
    gen_op_mul32(dest, src1, reg);
1335
1515
    gen_op_mov32(reg, dest);
1343
1523
    int reg;
1344
1524
    int tmp;
1345
1525
 
1346
 
    offset = ldsw(s->pc);
 
1526
    offset = ldsw_code(s->pc);
1347
1527
    s->pc += 2;
1348
1528
    reg = AREG(insn, 0);
1349
1529
    tmp = gen_new_qreg(QMODE_I32);
1350
1530
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1351
 
    gen_store(OS_LONG, tmp, reg);
 
1531
    gen_store(s, OS_LONG, tmp, reg);
1352
1532
    if (reg != QREG_SP)
1353
1533
        gen_op_mov32(reg, tmp);
1354
1534
    gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1363
1543
    src = gen_new_qreg(QMODE_I32);
1364
1544
    reg = AREG(insn, 0);
1365
1545
    gen_op_mov32(src, reg);
1366
 
    tmp = gen_load(OS_LONG, src, 0);
 
1546
    tmp = gen_load(s, OS_LONG, src, 0);
1367
1547
    gen_op_mov32(reg, tmp);
1368
1548
    gen_op_add32(QREG_SP, src, gen_im32(4));
1369
1549
}
1376
1556
{
1377
1557
    int tmp;
1378
1558
 
1379
 
    tmp = gen_load(OS_LONG, QREG_SP, 0);
 
1559
    tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1380
1560
    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1381
1561
    gen_jmp(s, tmp);
1382
1562
}
1388
1568
    /* Load the target address first to ensure correct exception
1389
1569
       behavior.  */
1390
1570
    tmp = gen_lea(s, insn, OS_LONG);
 
1571
    if (tmp == -1) {
 
1572
        gen_addr_fault(s);
 
1573
        return;
 
1574
    }
1391
1575
    if ((insn & 0x40) == 0) {
1392
1576
        /* jsr */
1393
 
        gen_push(gen_im32(s->pc));
 
1577
        gen_push(s, gen_im32(s->pc));
1394
1578
    }
1395
1579
    gen_jmp(s, tmp);
1396
1580
}
1403
1587
    int val;
1404
1588
    int addr;
1405
1589
 
1406
 
    src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
 
1590
    SRC_EA(src1, OS_LONG, 0, &addr);
1407
1591
    val = (insn >> 9) & 7;
1408
1592
    if (val == 0)
1409
1593
        val = 8;
1430
1614
        }
1431
1615
        gen_op_update_cc_add(dest, src2);
1432
1616
    }
1433
 
    gen_ea(s, insn, OS_LONG, dest, &addr);
 
1617
    DEST_EA(insn, OS_LONG, dest, &addr);
1434
1618
}
1435
1619
 
1436
1620
DISAS_INSN(tpf)
1460
1644
    op = (insn >> 8) & 0xf;
1461
1645
    offset = (int8_t)insn;
1462
1646
    if (offset == 0) {
1463
 
        offset = ldsw(s->pc);
 
1647
        offset = ldsw_code(s->pc);
1464
1648
        s->pc += 2;
1465
1649
    } else if (offset == -1) {
1466
1650
        offset = read_im32(s);
1467
1651
    }
1468
1652
    if (op == 1) {
1469
1653
        /* bsr */
1470
 
        gen_push(gen_im32(s->pc));
 
1654
        gen_push(s, gen_im32(s->pc));
1471
1655
    }
1472
1656
    gen_flush_cc_op(s);
1473
1657
    if (op > 1) {
1502
1686
        opsize = OS_WORD;
1503
1687
    else
1504
1688
        opsize = OS_BYTE;
1505
 
    src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
 
1689
    SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
1506
1690
    reg = DREG(insn, 9);
1507
1691
    gen_op_mov32(reg, src);
1508
1692
    gen_logic_cc(s, src);
1518
1702
    reg = DREG(insn, 9);
1519
1703
    dest = gen_new_qreg(QMODE_I32);
1520
1704
    if (insn & 0x100) {
1521
 
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
 
1705
        SRC_EA(src, OS_LONG, 0, &addr);
1522
1706
        gen_op_or32(dest, src, reg);
1523
 
        gen_ea(s, insn, OS_LONG, dest, &addr);
 
1707
        DEST_EA(insn, OS_LONG, dest, &addr);
1524
1708
    } else {
1525
 
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
 
1709
        SRC_EA(src, OS_LONG, 0, NULL);
1526
1710
        gen_op_or32(dest, src, reg);
1527
1711
        gen_op_mov32(reg, dest);
1528
1712
    }
1534
1718
    int src;
1535
1719
    int reg;
1536
1720
 
1537
 
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
 
1721
    SRC_EA(src, OS_LONG, 0, NULL);
1538
1722
    reg = AREG(insn, 9);
1539
1723
    gen_op_sub32(reg, reg, src);
1540
1724
}
1574
1758
        val = -1;
1575
1759
    src = gen_im32(val);
1576
1760
    gen_logic_cc(s, src);
1577
 
    gen_ea(s, insn, OS_LONG, src, NULL);
 
1761
    DEST_EA(insn, OS_LONG, src, NULL);
1578
1762
}
1579
1763
 
1580
1764
DISAS_INSN(cmp)
1602
1786
    default:
1603
1787
        abort();
1604
1788
    }
1605
 
    src = gen_ea(s, insn, opsize, -1, NULL);
 
1789
    SRC_EA(src, opsize, -1, NULL);
1606
1790
    reg = DREG(insn, 9);
1607
1791
    dest = gen_new_qreg(QMODE_I32);
1608
1792
    gen_op_sub32(dest, reg, src);
1621
1805
    } else {
1622
1806
        opsize = OS_WORD;
1623
1807
    }
1624
 
    src = gen_ea(s, insn, opsize, -1, NULL);
 
1808
    SRC_EA(src, opsize, -1, NULL);
1625
1809
    reg = AREG(insn, 9);
1626
1810
    dest = gen_new_qreg(QMODE_I32);
1627
1811
    gen_op_sub32(dest, reg, src);
1636
1820
    int dest;
1637
1821
    int addr;
1638
1822
 
1639
 
    src = gen_ea(s, insn, OS_LONG, 0, &addr);
 
1823
    SRC_EA(src, OS_LONG, 0, &addr);
1640
1824
    reg = DREG(insn, 9);
1641
1825
    dest = gen_new_qreg(QMODE_I32);
1642
1826
    gen_op_xor32(dest, src, reg);
1643
1827
    gen_logic_cc(s, dest);
1644
 
    gen_ea(s, insn, OS_LONG, dest, &addr);
 
1828
    DEST_EA(insn, OS_LONG, dest, &addr);
1645
1829
}
1646
1830
 
1647
1831
DISAS_INSN(and)
1654
1838
    reg = DREG(insn, 9);
1655
1839
    dest = gen_new_qreg(QMODE_I32);
1656
1840
    if (insn & 0x100) {
1657
 
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
 
1841
        SRC_EA(src, OS_LONG, 0, &addr);
1658
1842
        gen_op_and32(dest, src, reg);
1659
 
        gen_ea(s, insn, OS_LONG, dest, &addr);
 
1843
        DEST_EA(insn, OS_LONG, dest, &addr);
1660
1844
    } else {
1661
 
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
 
1845
        SRC_EA(src, OS_LONG, 0, NULL);
1662
1846
        gen_op_and32(dest, src, reg);
1663
1847
        gen_op_mov32(reg, dest);
1664
1848
    }
1670
1854
    int src;
1671
1855
    int reg;
1672
1856
 
1673
 
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
 
1857
    SRC_EA(src, OS_LONG, 0, NULL);
1674
1858
    reg = AREG(insn, 9);
1675
1859
    gen_op_add32(reg, reg, src);
1676
1860
}
1749
1933
 
1750
1934
DISAS_INSN(ff1)
1751
1935
{
1752
 
    cpu_abort(NULL, "Unimplemented insn: ff1");
 
1936
    int reg;
 
1937
    reg = DREG(insn, 0);
 
1938
    gen_logic_cc(s, reg);
 
1939
    gen_op_ff1(reg, reg);
 
1940
}
 
1941
 
 
1942
static int gen_get_sr(DisasContext *s)
 
1943
{
 
1944
    int ccr;
 
1945
    int sr;
 
1946
 
 
1947
    ccr = gen_get_ccr(s);
 
1948
    sr = gen_new_qreg(QMODE_I32);
 
1949
    gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
 
1950
    gen_op_or32(sr, sr, ccr);
 
1951
    return sr;
1753
1952
}
1754
1953
 
1755
1954
DISAS_INSN(strldsr)
1758
1957
    uint32_t addr;
1759
1958
 
1760
1959
    addr = s->pc - 2;
1761
 
    ext = lduw(s->pc);
 
1960
    ext = lduw_code(s->pc);
1762
1961
    s->pc += 2;
1763
 
    if (ext != 0x46FC)
 
1962
    if (ext != 0x46FC) {
1764
1963
        gen_exception(s, addr, EXCP_UNSUPPORTED);
1765
 
    else
 
1964
        return;
 
1965
    }
 
1966
    ext = lduw_code(s->pc);
 
1967
    s->pc += 2;
 
1968
    if (IS_USER(s) || (ext & SR_S) == 0) {
1766
1969
        gen_exception(s, addr, EXCP_PRIVILEGE);
 
1970
        return;
 
1971
    }
 
1972
    gen_push(s, gen_get_sr(s));
 
1973
    gen_set_sr_im(s, ext, 0);
1767
1974
}
1768
1975
 
1769
1976
DISAS_INSN(move_from_sr)
1770
1977
{
1771
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
1978
    int reg;
 
1979
    int sr;
 
1980
 
 
1981
    if (IS_USER(s)) {
 
1982
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
1983
        return;
 
1984
    }
 
1985
    sr = gen_get_sr(s);
 
1986
    reg = DREG(insn, 0);
 
1987
    gen_partset_reg(OS_WORD, reg, sr);
1772
1988
}
1773
1989
 
1774
1990
DISAS_INSN(move_to_sr)
1775
1991
{
1776
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
1992
    if (IS_USER(s)) {
 
1993
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
1994
        return;
 
1995
    }
 
1996
    gen_set_sr(s, insn, 0);
 
1997
    gen_lookup_tb(s);
1777
1998
}
1778
1999
 
1779
2000
DISAS_INSN(move_from_usp)
1780
2001
{
1781
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2002
    if (IS_USER(s)) {
 
2003
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2004
        return;
 
2005
    }
 
2006
    /* TODO: Implement USP.  */
 
2007
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1782
2008
}
1783
2009
 
1784
2010
DISAS_INSN(move_to_usp)
1785
2011
{
1786
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2012
    if (IS_USER(s)) {
 
2013
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2014
        return;
 
2015
    }
 
2016
    /* TODO: Implement USP.  */
 
2017
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1787
2018
}
1788
2019
 
1789
2020
DISAS_INSN(halt)
1790
2021
{
1791
 
    gen_exception(s, s->pc, EXCP_HLT);
 
2022
    gen_jmp(s, gen_im32(s->pc));
 
2023
    gen_op_halt();
1792
2024
}
1793
2025
 
1794
2026
DISAS_INSN(stop)
1795
2027
{
1796
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2028
    uint16_t ext;
 
2029
 
 
2030
    if (IS_USER(s)) {
 
2031
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2032
        return;
 
2033
    }
 
2034
 
 
2035
    ext = lduw_code(s->pc);
 
2036
    s->pc += 2;
 
2037
 
 
2038
    gen_set_sr_im(s, ext, 0);
 
2039
    gen_jmp(s, gen_im32(s->pc));
 
2040
    gen_op_stop();
1797
2041
}
1798
2042
 
1799
2043
DISAS_INSN(rte)
1800
2044
{
1801
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2045
    if (IS_USER(s)) {
 
2046
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2047
        return;
 
2048
    }
 
2049
    gen_exception(s, s->pc - 2, EXCP_RTE);
1802
2050
}
1803
2051
 
1804
2052
DISAS_INSN(movec)
1805
2053
{
1806
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2054
    uint16_t ext;
 
2055
    int reg;
 
2056
 
 
2057
    if (IS_USER(s)) {
 
2058
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2059
        return;
 
2060
    }
 
2061
 
 
2062
    ext = lduw_code(s->pc);
 
2063
    s->pc += 2;
 
2064
 
 
2065
    if (ext & 0x8000) {
 
2066
        reg = AREG(ext, 12);
 
2067
    } else {
 
2068
        reg = DREG(ext, 12);
 
2069
    }
 
2070
    gen_op_movec(gen_im32(ext & 0xfff), reg);
 
2071
    gen_lookup_tb(s);
1807
2072
}
1808
2073
 
1809
2074
DISAS_INSN(intouch)
1810
2075
{
1811
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2076
    if (IS_USER(s)) {
 
2077
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2078
        return;
 
2079
    }
 
2080
    /* ICache fetch.  Implement as no-op.  */
1812
2081
}
1813
2082
 
1814
2083
DISAS_INSN(cpushl)
1815
2084
{
1816
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2085
    if (IS_USER(s)) {
 
2086
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2087
        return;
 
2088
    }
 
2089
    /* Cache push/invalidate.  Implement as no-op.  */
1817
2090
}
1818
2091
 
1819
2092
DISAS_INSN(wddata)
1823
2096
 
1824
2097
DISAS_INSN(wdebug)
1825
2098
{
1826
 
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2099
    if (IS_USER(s)) {
 
2100
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
 
2101
        return;
 
2102
    }
 
2103
    /* TODO: Implement wdebug.  */
 
2104
    qemu_assert(0, "WDEBUG not implemented");
1827
2105
}
1828
2106
 
1829
2107
DISAS_INSN(trap)
1843
2121
    int round;
1844
2122
    int opsize;
1845
2123
 
1846
 
    ext = lduw(s->pc);
 
2124
    ext = lduw_code(s->pc);
1847
2125
    s->pc += 2;
1848
2126
    opmode = ext & 0x7f;
1849
2127
    switch ((ext >> 13) & 7) {
1883
2161
        default:
1884
2162
            goto undef;
1885
2163
        }
1886
 
        gen_ea(s, insn, opsize, res, NULL);
 
2164
        DEST_EA(insn, opsize, res, NULL);
1887
2165
        return;
1888
2166
    case 4: /* fmove to control register.  */
1889
2167
        switch ((ext >> 10) & 7) {
1910
2188
                      (ext >> 10) & 7);
1911
2189
            goto undef;
1912
2190
        }
1913
 
        gen_ea(s, insn, OS_LONG, res, NULL);
 
2191
        DEST_EA(insn, OS_LONG, res, NULL);
1914
2192
        break;
1915
2193
    case 6: /* fmovem */ 
1916
2194
    case 7:
1920
2198
        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
1921
2199
            goto undef;
1922
2200
        src = gen_lea(s, insn, OS_LONG);
 
2201
        if (src == -1) {
 
2202
            gen_addr_fault(s);
 
2203
            return;
 
2204
        }
1923
2205
        addr = gen_new_qreg(QMODE_I32);
1924
2206
        gen_op_mov32(addr, src);
1925
2207
        mask = 0x80;
1926
2208
        dest = QREG_F0;
1927
2209
        while (mask) {
1928
2210
            if (ext & mask) {
 
2211
                s->is_mem = 1;
1929
2212
                if (ext & (1 << 13)) {
1930
2213
                    /* store */
1931
 
                    gen_op_stf64(addr, dest);
 
2214
                    gen_st(s, f64, addr, dest);
1932
2215
                } else {
1933
2216
                    /* load */
1934
 
                    gen_op_ldf64(dest, addr);
 
2217
                    gen_ld(s, f64, dest, addr);
1935
2218
                }
1936
2219
                if (ext & (mask - 1))
1937
2220
                    gen_op_add32(addr, addr, gen_im32(8));
1955
2238
        default:
1956
2239
            goto undef;
1957
2240
        }
1958
 
        tmp = gen_ea(s, insn, opsize, -1, NULL);
 
2241
        SRC_EA(tmp, opsize, -1, NULL);
1959
2242
        if (opsize == OS_DOUBLE) {
1960
2243
            src = tmp;
1961
2244
        } else {
2060
2343
    int l1;
2061
2344
 
2062
2345
    addr = s->pc;
2063
 
    offset = ldsw(s->pc);
 
2346
    offset = ldsw_code(s->pc);
2064
2347
    s->pc += 2;
2065
2348
    if (insn & (1 << 6)) {
2066
 
        offset = (offset << 16) | lduw(s->pc);
 
2349
        offset = (offset << 16) | lduw_code(s->pc);
2067
2350
        s->pc += 2;
2068
2351
    }
2069
2352
 
2143
2426
    gen_jmp_tb(s, 1, addr + offset);
2144
2427
}
2145
2428
 
 
2429
DISAS_INSN(frestore)
 
2430
{
 
2431
    /* TODO: Implement frestore.  */
 
2432
    qemu_assert(0, "FRESTORE not implemented");
 
2433
}
 
2434
 
 
2435
DISAS_INSN(fsave)
 
2436
{
 
2437
    /* TODO: Implement fsave.  */
 
2438
    qemu_assert(0, "FSAVE not implemented");
 
2439
}
 
2440
 
 
2441
static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
 
2442
{
 
2443
    int tmp = gen_new_qreg(QMODE_I32);
 
2444
    if (s->env->macsr & MACSR_FI) {
 
2445
        if (upper)
 
2446
            gen_op_and32(tmp, val, gen_im32(0xffff0000));
 
2447
        else
 
2448
            gen_op_shl32(tmp, val, gen_im32(16));
 
2449
    } else if (s->env->macsr & MACSR_SU) {
 
2450
        if (upper)
 
2451
            gen_op_sar32(tmp, val, gen_im32(16));
 
2452
        else
 
2453
            gen_op_ext16s32(tmp, val);
 
2454
    } else {
 
2455
        if (upper)
 
2456
            gen_op_shr32(tmp, val, gen_im32(16));
 
2457
        else
 
2458
            gen_op_ext16u32(tmp, val);
 
2459
    }
 
2460
    return tmp;
 
2461
}
 
2462
 
 
2463
DISAS_INSN(mac)
 
2464
{
 
2465
    int rx;
 
2466
    int ry;
 
2467
    uint16_t ext;
 
2468
    int acc;
 
2469
    int l1;
 
2470
    int tmp;
 
2471
    int addr;
 
2472
    int loadval;
 
2473
    int dual;
 
2474
    int saved_flags = -1;
 
2475
 
 
2476
    ext = lduw_code(s->pc);
 
2477
    s->pc += 2;
 
2478
 
 
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);
 
2483
        return;
 
2484
    }
 
2485
    if (insn & 0x30) {
 
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);
 
2493
 
 
2494
        acc ^= 1;
 
2495
        rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
 
2496
        ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
 
2497
    } else {
 
2498
        loadval = addr = -1;
 
2499
        rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
 
2500
        ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
 
2501
    }
 
2502
 
 
2503
    gen_op_mac_clear_flags();
 
2504
    l1 = -1;
 
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);
 
2511
    }
 
2512
 
 
2513
    if ((ext & 0x0800) == 0) {
 
2514
        /* Word.  */
 
2515
        rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
 
2516
        ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
 
2517
    }
 
2518
    if (s->env->macsr & MACSR_FI) {
 
2519
        gen_op_macmulf(rx, ry);
 
2520
    } else {
 
2521
        if (s->env->macsr & MACSR_SU)
 
2522
            gen_op_macmuls(rx, ry);
 
2523
        else
 
2524
            gen_op_macmulu(rx, ry);
 
2525
        switch ((ext >> 9) & 3) {
 
2526
        case 1:
 
2527
            gen_op_macshl();
 
2528
            break;
 
2529
        case 3:
 
2530
            gen_op_macshr();
 
2531
            break;
 
2532
        }
 
2533
    }
 
2534
 
 
2535
    if (dual) {
 
2536
        /* Save the overflow flag from the multiply.  */
 
2537
        saved_flags = gen_new_qreg(QMODE_I32);
 
2538
        gen_op_mov32(saved_flags, QREG_MACSR);
 
2539
    }
 
2540
 
 
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);
 
2547
    }
 
2548
 
 
2549
    if (insn & 0x100)
 
2550
        gen_op_macsub(acc);
 
2551
    else
 
2552
        gen_op_macadd(acc);
 
2553
 
 
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);
 
2558
    else
 
2559
        gen_op_macsatu(acc);
 
2560
 
 
2561
    if (l1 != -1)
 
2562
        gen_set_label(l1);
 
2563
 
 
2564
    if (dual) {
 
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);
 
2575
        }
 
2576
        if (ext & 2)
 
2577
            gen_op_macsub(acc);
 
2578
        else
 
2579
            gen_op_macadd(acc);
 
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);
 
2584
        else
 
2585
            gen_op_macsatu(acc);
 
2586
        if (l1 != -1)
 
2587
            gen_set_label(l1);
 
2588
    }
 
2589
    gen_op_mac_set_flags(acc);
 
2590
 
 
2591
    if (insn & 0x30) {
 
2592
        int rw;
 
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
 
2596
           unmasked value?  */
 
2597
        switch ((insn >> 3) & 7) {
 
2598
        case 3: /* Post-increment.  */
 
2599
            gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
 
2600
            break;
 
2601
        case 4: /* Pre-decrement.  */
 
2602
            gen_op_mov32(AREG(insn, 0), addr);
 
2603
        }
 
2604
    }
 
2605
}
 
2606
 
 
2607
DISAS_INSN(from_mac)
 
2608
{
 
2609
    int rx;
 
2610
    int acc;
 
2611
 
 
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);
 
2620
    } else {
 
2621
        gen_op_get_macu(rx, acc);
 
2622
    }
 
2623
    if (insn & 0x40)
 
2624
        gen_op_clear_mac(acc);
 
2625
}
 
2626
 
 
2627
DISAS_INSN(move_mac)
 
2628
{
 
2629
    int src;
 
2630
    int dest;
 
2631
    src = insn & 3;
 
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);
 
2636
}
 
2637
 
 
2638
DISAS_INSN(from_macsr)
 
2639
{
 
2640
    int reg;
 
2641
 
 
2642
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
 
2643
    gen_op_mov32(reg, QREG_MACSR);
 
2644
}
 
2645
 
 
2646
DISAS_INSN(from_mask)
 
2647
{
 
2648
    int reg;
 
2649
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
 
2650
    gen_op_mov32(reg, QREG_MAC_MASK);
 
2651
}
 
2652
 
 
2653
DISAS_INSN(from_mext)
 
2654
{
 
2655
    int reg;
 
2656
    int acc;
 
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);
 
2661
    else
 
2662
        gen_op_get_mac_exti(reg, acc);
 
2663
}
 
2664
 
 
2665
DISAS_INSN(macsr_to_ccr)
 
2666
{
 
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;
 
2670
}
 
2671
 
 
2672
DISAS_INSN(to_mac)
 
2673
{
 
2674
    int acc;
 
2675
    int val;
 
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);
 
2682
    } else {
 
2683
        gen_op_set_macu(val, acc);
 
2684
    }
 
2685
    gen_op_mac_clear_flags();
 
2686
    gen_op_mac_set_flags(acc);
 
2687
}
 
2688
 
 
2689
DISAS_INSN(to_macsr)
 
2690
{
 
2691
    int val;
 
2692
    SRC_EA(val, OS_LONG, 0, NULL);
 
2693
    gen_op_set_macsr(val);
 
2694
    gen_lookup_tb(s);
 
2695
}
 
2696
 
 
2697
DISAS_INSN(to_mask)
 
2698
{
 
2699
    int val;
 
2700
    SRC_EA(val, OS_LONG, 0, NULL);
 
2701
    gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
 
2702
}
 
2703
 
 
2704
DISAS_INSN(to_mext)
 
2705
{
 
2706
    int val;
 
2707
    int acc;
 
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);
 
2714
    else
 
2715
        gen_op_set_mac_extu(val, acc);
 
2716
}
 
2717
 
2146
2718
static disas_proc opcode_table[65536];
2147
2719
 
2148
2720
static void
2153
2725
  int to;
2154
2726
 
2155
2727
  /* Sanity check.  All set bits must be included in the mask.  */
2156
 
  if (opcode & ~mask)
 
2728
  if (opcode & ~mask) {
 
2729
      fprintf(stderr,
 
2730
              "qemu internal error: bogus opcode definition %04x/%04x\n",
 
2731
              opcode, mask);
2157
2732
      abort();
 
2733
  }
2158
2734
  /* This could probably be cleverer.  For now just optimize the case where
2159
2735
     the top bits are known.  */
2160
2736
  /* Find the first zero bit in the mask.  */
2168
2744
      i <<= 1;
2169
2745
  from = opcode & ~(i - 1);
2170
2746
  to = from + i;
2171
 
  for (i = from; i < to; i++)
2172
 
    {
 
2747
  for (i = from; i < to; i++) {
2173
2748
      if ((i & mask) == opcode)
2174
2749
          opcode_table[i] = proc;
2175
 
    }
 
2750
  }
2176
2751
}
2177
2752
 
2178
2753
/* Register m68k opcode handlers.  Order is important.
2179
2754
   Later insn override earlier ones.  */
2180
 
static void
2181
 
register_m68k_insns (m68k_def_t *def)
 
2755
void register_m68k_insns (CPUM68KState *env)
2182
2756
{
2183
 
    uint32_t iflags;
2184
 
 
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); \
 
2760
    } while(0)
 
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);
 
2823
 
 
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);
 
2831
 
 
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);
 
2839
 
 
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);
 
2852
 
 
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);
2281
2876
#undef INSN
2282
2877
}
2283
2878
 
2287
2882
{
2288
2883
    uint16_t insn;
2289
2884
 
2290
 
    insn = lduw(s->pc);
 
2885
    insn = lduw_code(s->pc);
2291
2886
    s->pc += 2;
2292
2887
 
2293
2888
    opcode_table[insn](s, insn);
2551
3146
#endif
2552
3147
 
2553
3148
/* generate intermediate code for basic block 'tb'.  */
2554
 
int gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2555
 
                                   int search_pc)
 
3149
static inline int
 
3150
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
3151
                               int search_pc)
2556
3152
{
2557
3153
    DisasContext dc1, *dc = &dc1;
2558
3154
    uint16_t *gen_opc_end;
2570
3166
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2571
3167
    gen_opparam_ptr = gen_opparam_buf;
2572
3168
 
 
3169
    dc->env = env;
2573
3170
    dc->is_jmp = DISAS_NEXT;
2574
3171
    dc->pc = pc_start;
2575
3172
    dc->cc_op = CC_OP_DYNAMIC;
2576
3173
    dc->singlestep_enabled = env->singlestep_enabled;
2577
3174
    dc->fpcr = env->fpcr;
 
3175
    dc->user = (env->sr & SR_S) == 0;
 
3176
    dc->is_mem = 0;
2578
3177
    nb_gen_labels = 0;
2579
3178
    lj = -1;
2580
3179
    do {
2603
3202
            gen_opc_instr_start[lj] = 1;
2604
3203
        }
2605
3204
        last_cc_op = dc->cc_op;
 
3205
        dc->insn_pc = dc->pc;
2606
3206
        disas_m68k_insn(env, dc);
 
3207
 
 
3208
        /* Terminate the TB on memory ops if watchpoints are present.  */
 
3209
        /* FIXME: This should be replacd by the deterministic execution
 
3210
         * IRQ raising bits.  */
 
3211
        if (dc->is_mem && env->nb_watchpoints)
 
3212
            break;
2607
3213
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
2608
3214
             !env->singlestep_enabled &&
2609
3215
             (pc_offset) < (TARGET_PAGE_SIZE - 32));
2674
3280
    return gen_intermediate_code_internal(env, tb, 1);
2675
3281
}
2676
3282
 
 
3283
void cpu_reset(CPUM68KState *env)
 
3284
{
 
3285
    memset(env, 0, offsetof(CPUM68KState, breakpoints));
 
3286
#if !defined (CONFIG_USER_ONLY)
 
3287
    env->sr = 0x2700;
 
3288
#endif
 
3289
    m68k_switch_sp(env);
 
3290
    /* ??? FP regs should be initialized to NaN.  */
 
3291
    env->cc_op = CC_OP_FLAGS;
 
3292
    /* TODO: We should set PC from the interrupt vector.  */
 
3293
    env->pc = 0;
 
3294
    tlb_flush(env, 1);
 
3295
}
 
3296
 
2677
3297
CPUM68KState *cpu_m68k_init(void)
2678
3298
{
2679
3299
    CPUM68KState *env;
2683
3303
        return NULL;
2684
3304
    cpu_exec_init(env);
2685
3305
 
2686
 
    memset(env, 0, sizeof(CPUM68KState));
2687
 
    /* ??? FP regs should be initialized to NaN.  */
2688
 
    cpu_single_env = env;
2689
 
    env->cc_op = CC_OP_FLAGS;
 
3306
    cpu_reset(env);
2690
3307
    return env;
2691
3308
}
2692
3309
 
2695
3312
    free(env);
2696
3313
}
2697
3314
 
2698
 
m68k_def_t *m68k_find_by_name(const char *name)
2699
 
{
2700
 
    m68k_def_t *def;
2701
 
 
2702
 
    def = m68k_cpu_defs;
2703
 
    while (def->name)
2704
 
      {
2705
 
        if (strcmp(def->name, name) == 0)
2706
 
            return def;
2707
 
        def++;
2708
 
      }
2709
 
    return NULL;
2710
 
}
2711
 
 
2712
 
void cpu_m68k_register(CPUM68KState *env, m68k_def_t *def)
2713
 
{
2714
 
    register_m68k_insns(def);
2715
 
}
2716
 
 
2717
3315
void cpu_dump_state(CPUState *env, FILE *f, 
2718
3316
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2719
3317
                    int flags)
2736
3334
    cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
2737
3335
}
2738
3336
 
2739
 
/* ??? */
2740
 
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2741
 
{
2742
 
    return addr;
2743
 
}
2744
 
 
2745
 
#if defined(CONFIG_USER_ONLY) 
2746
 
 
2747
 
int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
2748
 
                               int is_user, int is_softmmu)
2749
 
{
2750
 
    env->exception_index = EXCP_ACCESS;
2751
 
    env->mmu.ar = address;
2752
 
    return 1;
2753
 
}
2754
 
 
2755
 
#else
2756
 
 
2757
 
#error not implemented
2758
 
 
2759
 
#endif