Statistics
| Branch: | Revision:

root / target-m68k / translate.c @ 0402f767

History | View | Annotate | Download (69.8 kB)

1
/*
2
 *  m68k translation
3
 * 
4
 *  Copyright (c) 2005-2007 CodeSourcery
5
 *  Written by Paul Brook
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
#include <stdarg.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <inttypes.h>
26

    
27
#include "config.h"
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31
#include "m68k-qreg.h"
32

    
33
//#define DEBUG_DISPATCH 1
34

    
35
static inline void qemu_assert(int cond, const char *msg)
36
{
37
    if (!cond) {
38
        fprintf (stderr, "badness: %s\n", msg);
39
        abort();
40
    }
41
}
42

    
43
/* internal defines */
44
typedef struct DisasContext {
45
    target_ulong pc;
46
    int is_jmp;
47
    int cc_op;
48
    int user;
49
    uint32_t fpcr;
50
    struct TranslationBlock *tb;
51
    int singlestep_enabled;
52
} DisasContext;
53

    
54
#define DISAS_JUMP_NEXT 4
55

    
56
#if defined(CONFIG_USER_ONLY)
57
#define IS_USER(s) 1
58
#else
59
#define IS_USER(s) s->user
60
#endif
61

    
62
/* XXX: move that elsewhere */
63
/* ??? Fix exceptions.  */
64
static void *gen_throws_exception;
65
#define gen_last_qop NULL
66

    
67
static uint16_t *gen_opc_ptr;
68
static uint32_t *gen_opparam_ptr;
69
extern FILE *logfile;
70
extern int loglevel;
71

    
72
enum {
73
#define DEF(s, n, copy_size) INDEX_op_ ## s,
74
#include "opc.h"
75
#undef DEF
76
    NB_OPS,
77
};
78

    
79
#include "gen-op.h"
80

    
81
#if defined(CONFIG_USER_ONLY)
82
#define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
83
#define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
84
#else
85
#define gen_st(s, name, addr, val) do { \
86
    if (IS_USER(s)) \
87
        gen_op_st##name##_user(addr, val); \
88
    else \
89
        gen_op_st##name##_kernel(addr, val); \
90
    } while (0)
91
#define gen_ld(s, name, val, addr) do { \
92
    if (IS_USER(s)) \
93
        gen_op_ld##name##_user(val, addr); \
94
    else \
95
        gen_op_ld##name##_kernel(val, addr); \
96
    } while (0)
97
#endif
98

    
99
#include "op-hacks.h"
100

    
101
#define OS_BYTE 0
102
#define OS_WORD 1
103
#define OS_LONG 2
104
#define OS_SINGLE 4
105
#define OS_DOUBLE 5
106

    
107
#define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
108
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
109
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
110

    
111
typedef void (*disas_proc)(DisasContext *, uint16_t);
112

    
113
#ifdef DEBUG_DISPATCH
114
#define DISAS_INSN(name) \
115
  static void real_disas_##name (DisasContext *s, uint16_t insn); \
116
  static void disas_##name (DisasContext *s, uint16_t insn) { \
117
    if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
118
    real_disas_##name(s, insn); } \
119
  static void real_disas_##name (DisasContext *s, uint16_t insn)
120
#else
121
#define DISAS_INSN(name) \
122
  static void disas_##name (DisasContext *s, uint16_t insn)
123
#endif
124

    
125
/* Generate a load from the specified address.  Narrow values are
126
   sign extended to full register width.  */
127
static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
128
{
129
    int tmp;
130
    switch(opsize) {
131
    case OS_BYTE:
132
        tmp = gen_new_qreg(QMODE_I32);
133
        if (sign)
134
            gen_ld(s, 8s32, tmp, addr);
135
        else
136
            gen_ld(s, 8u32, tmp, addr);
137
        break;
138
    case OS_WORD:
139
        tmp = gen_new_qreg(QMODE_I32);
140
        if (sign)
141
            gen_ld(s, 16s32, tmp, addr);
142
        else
143
            gen_ld(s, 16u32, tmp, addr);
144
        break;
145
    case OS_LONG:
146
        tmp = gen_new_qreg(QMODE_I32);
147
        gen_ld(s, 32, tmp, addr);
148
        break;
149
    case OS_SINGLE:
150
        tmp = gen_new_qreg(QMODE_F32);
151
        gen_ld(s, f32, tmp, addr);
152
        break;
153
    case OS_DOUBLE:
154
        tmp  = gen_new_qreg(QMODE_F64);
155
        gen_ld(s, f64, tmp, addr);
156
        break;
157
    default:
158
        qemu_assert(0, "bad load size");
159
    }
160
    gen_throws_exception = gen_last_qop;
161
    return tmp;
162
}
163

    
164
/* Generate a store.  */
165
static inline void gen_store(DisasContext *s, int opsize, int addr, int val)
166
{
167
    switch(opsize) {
168
    case OS_BYTE:
169
        gen_st(s, 8, addr, val);
170
        break;
171
    case OS_WORD:
172
        gen_st(s, 16, addr, val);
173
        break;
174
    case OS_LONG:
175
        gen_st(s, 32, addr, val);
176
        break;
177
    case OS_SINGLE:
178
        gen_st(s, f32, addr, val);
179
        break;
180
    case OS_DOUBLE:
181
        gen_st(s, f64, addr, val);
182
        break;
183
    default:
184
        qemu_assert(0, "bad store size");
185
    }
186
    gen_throws_exception = gen_last_qop;
187
}
188

    
189
/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
190
   otherwise generate a store.  */
191
static int gen_ldst(DisasContext *s, int opsize, int addr, int val)
192
{
193
    if (val > 0) {
194
        gen_store(s, opsize, addr, val);
195
        return 0;
196
    } else {
197
        return gen_load(s, opsize, addr, val != 0);
198
    }
199
}
200

    
201
/* Handle a base + index + displacement effective addresss.  A base of
202
   -1 means pc-relative.  */
203
static int gen_lea_indexed(DisasContext *s, int opsize, int base)
204
{
205
    int scale;
206
    uint32_t offset;
207
    uint16_t ext;
208
    int add;
209
    int tmp;
210

    
211
    offset = s->pc;
212
    ext = lduw_code(s->pc);
213
    s->pc += 2;
214
    tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
215
    /* ??? Check W/L bit.  */
216
    scale = (ext >> 9) & 3;
217
    if (scale == 0) {
218
        add = tmp;
219
    } else {
220
        add = gen_new_qreg(QMODE_I32);
221
        gen_op_shl32(add, tmp, gen_im32(scale));
222
    }
223
    tmp = gen_new_qreg(QMODE_I32);
224
    if (base != -1) {
225
        gen_op_add32(tmp, base, gen_im32((int8_t)ext));
226
        gen_op_add32(tmp, tmp, add);
227
    } else {
228
        gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
229
    }
230
    return tmp;
231
}
232

    
233
/* Read a 32-bit immediate constant.  */
234
static inline uint32_t read_im32(DisasContext *s)
235
{
236
    uint32_t im;
237
    im = ((uint32_t)lduw_code(s->pc)) << 16;
238
    s->pc += 2;
239
    im |= lduw_code(s->pc);
240
    s->pc += 2;
241
    return im;
242
}
243

    
244

    
245
/* Update the CPU env CC_OP state.  */
246
static inline void gen_flush_cc_op(DisasContext *s)
247
{
248
    if (s->cc_op != CC_OP_DYNAMIC)
249
        gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
250
}
251

    
252
/* Evaluate all the CC flags.  */
253
static inline void gen_flush_flags(DisasContext *s)
254
{
255
    if (s->cc_op == CC_OP_FLAGS)
256
        return;
257
    gen_op_flush_flags(s->cc_op);
258
    s->cc_op = CC_OP_FLAGS;
259
}
260

    
261
static inline int opsize_bytes(int opsize)
262
{
263
    switch (opsize) {
264
    case OS_BYTE: return 1;
265
    case OS_WORD: return 2;
266
    case OS_LONG: return 4;
267
    case OS_SINGLE: return 4;
268
    case OS_DOUBLE: return 8;
269
    default:
270
        qemu_assert(0, "bad operand size");
271
    }
272
}
273

    
274
/* Assign value to a register.  If the width is less than the register width
275
   only the low part of the register is set.  */
276
static void gen_partset_reg(int opsize, int reg, int val)
277
{
278
    int tmp;
279
    switch (opsize) {
280
    case OS_BYTE:
281
        gen_op_and32(reg, reg, gen_im32(0xffffff00));
282
        tmp = gen_new_qreg(QMODE_I32);
283
        gen_op_and32(tmp, val, gen_im32(0xff));
284
        gen_op_or32(reg, reg, tmp);
285
        break;
286
    case OS_WORD:
287
        gen_op_and32(reg, reg, gen_im32(0xffff0000));
288
        tmp = gen_new_qreg(QMODE_I32);
289
        gen_op_and32(tmp, val, gen_im32(0xffff));
290
        gen_op_or32(reg, reg, tmp);
291
        break;
292
    case OS_LONG:
293
        gen_op_mov32(reg, val);
294
        break;
295
    case OS_SINGLE:
296
        gen_op_pack_32_f32(reg, val);
297
        break;
298
    default:
299
        qemu_assert(0, "Bad operand size");
300
        break;
301
    }
302
}
303

    
304
/* Sign or zero extend a value.  */
305
static inline int gen_extend(int val, int opsize, int sign)
306
{
307
    int tmp;
308

    
309
    switch (opsize) {
310
    case OS_BYTE:
311
        tmp = gen_new_qreg(QMODE_I32);
312
        if (sign)
313
            gen_op_ext8s32(tmp, val);
314
        else
315
            gen_op_ext8u32(tmp, val);
316
        break;
317
    case OS_WORD:
318
        tmp = gen_new_qreg(QMODE_I32);
319
        if (sign)
320
            gen_op_ext16s32(tmp, val);
321
        else
322
            gen_op_ext16u32(tmp, val);
323
        break;
324
    case OS_LONG:
325
        tmp = val;
326
        break;
327
    case OS_SINGLE:
328
        tmp = gen_new_qreg(QMODE_F32);
329
        gen_op_pack_f32_32(tmp, val);
330
        break;
331
    default:
332
        qemu_assert(0, "Bad operand size");
333
    }
334
    return tmp;
335
}
336

    
337
/* Generate code for an "effective address".  Does not adjust the base
338
   register for autoincrememnt addressing modes.  */
339
static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
340
{
341
    int reg;
342
    int tmp;
343
    uint16_t ext;
344
    uint32_t offset;
345

    
346
    reg = insn & 7;
347
    switch ((insn >> 3) & 7) {
348
    case 0: /* Data register direct.  */
349
    case 1: /* Address register direct.  */
350
        /* ??? generate bad addressing mode fault.  */
351
        qemu_assert(0, "invalid addressing mode");
352
    case 2: /* Indirect register */
353
    case 3: /* Indirect postincrement.  */
354
        reg += QREG_A0;
355
        return reg;
356
    case 4: /* Indirect predecrememnt.  */
357
        reg += QREG_A0;
358
        tmp = gen_new_qreg(QMODE_I32);
359
        gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
360
        return tmp;
361
    case 5: /* Indirect displacement.  */
362
        reg += QREG_A0;
363
        tmp = gen_new_qreg(QMODE_I32);
364
        ext = lduw_code(s->pc);
365
        s->pc += 2;
366
        gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
367
        return tmp;
368
    case 6: /* Indirect index + displacement.  */
369
        reg += QREG_A0;
370
        return gen_lea_indexed(s, opsize, reg);
371
    case 7: /* Other */
372
        switch (reg) {
373
        case 0: /* Absolute short.  */
374
            offset = ldsw_code(s->pc);
375
            s->pc += 2;
376
            return gen_im32(offset);
377
        case 1: /* Absolute long.  */
378
            offset = read_im32(s);
379
            return gen_im32(offset);
380
        case 2: /* pc displacement  */
381
            tmp = gen_new_qreg(QMODE_I32);
382
            offset = s->pc;
383
            offset += ldsw_code(s->pc);
384
            s->pc += 2;
385
            return gen_im32(offset);
386
        case 3: /* pc index+displacement.  */
387
            return gen_lea_indexed(s, opsize, -1);
388
        case 4: /* Immediate.  */
389
        default:
390
            /* ??? generate bad addressing mode fault.  */
391
            qemu_assert(0, "invalid addressing mode");
392
        }
393
    }
394
    /* Should never happen.  */
395
    return -1;
396
}
397

    
398
/* Helper function for gen_ea. Reuse the computed address between the
399
   for read/write operands.  */
400
static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
401
                              int val, int *addrp)
402
{
403
    int tmp;
404

    
405
    if (addrp && val > 0) {
406
        tmp = *addrp;
407
    } else {
408
        tmp = gen_lea(s, insn, opsize);
409
        if (addrp)
410
            *addrp = tmp;
411
    }
412
    return gen_ldst(s, opsize, tmp, val);
413
}
414

    
415
/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
416
   a write otherwise it is a read (0 == sign extend, -1 == zero extend).
417
   ADDRP is non-null for readwrite operands.  */
418
static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
419
                  int *addrp)
420
{
421
    int reg;
422
    int result;
423
    uint32_t offset;
424

    
425
    reg = insn & 7;
426
    switch ((insn >> 3) & 7) {
427
    case 0: /* Data register direct.  */
428
        reg += QREG_D0;
429
        if (val > 0) {
430
            gen_partset_reg(opsize, reg, val);
431
            return 0;
432
        } else {
433
            return gen_extend(reg, opsize, val);
434
        }
435
    case 1: /* Address register direct.  */
436
        reg += QREG_A0;
437
        if (val > 0) {
438
            gen_op_mov32(reg, val);
439
            return 0;
440
        } else {
441
            return gen_extend(reg, opsize, val);
442
        }
443
    case 2: /* Indirect register */
444
        reg += QREG_A0;
445
        return gen_ldst(s, opsize, reg, val);
446
    case 3: /* Indirect postincrement.  */
447
        reg += QREG_A0;
448
        result = gen_ldst(s, opsize, reg, val);
449
        /* ??? This is not exception safe.  The instruction may still
450
           fault after this point.  */
451
        if (val > 0 || !addrp)
452
            gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
453
        return result;
454
    case 4: /* Indirect predecrememnt.  */
455
        {
456
            int tmp;
457
            if (addrp && val > 0) {
458
                tmp = *addrp;
459
            } else {
460
                tmp = gen_lea(s, insn, opsize);
461
                if (addrp)
462
                    *addrp = tmp;
463
            }
464
            result = gen_ldst(s, opsize, tmp, val);
465
            /* ??? This is not exception safe.  The instruction may still
466
               fault after this point.  */
467
            if (val > 0 || !addrp) {
468
                reg += QREG_A0;
469
                gen_op_mov32(reg, tmp);
470
            }
471
        }
472
        return result;
473
    case 5: /* Indirect displacement.  */
474
    case 6: /* Indirect index + displacement.  */
475
        return gen_ea_once(s, insn, opsize, val, addrp);
476
    case 7: /* Other */
477
        switch (reg) {
478
        case 0: /* Absolute short.  */
479
        case 1: /* Absolute long.  */
480
        case 2: /* pc displacement  */
481
        case 3: /* pc index+displacement.  */
482
            return gen_ea_once(s, insn, opsize, val, addrp);
483
        case 4: /* Immediate.  */
484
            /* Sign extend values for consistency.  */
485
            switch (opsize) {
486
            case OS_BYTE:
487
                if (val)
488
                    offset = ldsb_code(s->pc + 1);
489
                else
490
                    offset = ldub_code(s->pc + 1);
491
                s->pc += 2;
492
                break;
493
            case OS_WORD:
494
                if (val)
495
                    offset = ldsw_code(s->pc);
496
                else
497
                    offset = lduw_code(s->pc);
498
                s->pc += 2;
499
                break;
500
            case OS_LONG:
501
                offset = read_im32(s);
502
                break;
503
            default:
504
                qemu_assert(0, "Bad immediate operand");
505
            }
506
            return gen_im32(offset);
507
        default:
508
            qemu_assert(0, "invalid addressing mode");
509
        }
510
    }
511
    /* Should never happen.  */
512
    return -1;
513
}
514

    
515
static void gen_logic_cc(DisasContext *s, int val)
516
{
517
    gen_op_logic_cc(val);
518
    s->cc_op = CC_OP_LOGIC;
519
}
520

    
521
static void gen_jmpcc(DisasContext *s, int cond, int l1)
522
{
523
    int tmp;
524

    
525
    gen_flush_flags(s);
526
    switch (cond) {
527
    case 0: /* T */
528
        gen_op_jmp(l1);
529
        break;
530
    case 1: /* F */
531
        break;
532
    case 2: /* HI (!C && !Z) */
533
        tmp = gen_new_qreg(QMODE_I32);
534
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
535
        gen_op_jmp_z32(tmp, l1);
536
        break;
537
    case 3: /* LS (C || Z) */
538
        tmp = gen_new_qreg(QMODE_I32);
539
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
540
        gen_op_jmp_nz32(tmp, l1);
541
        break;
542
    case 4: /* CC (!C) */
543
        tmp = gen_new_qreg(QMODE_I32);
544
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
545
        gen_op_jmp_z32(tmp, l1);
546
        break;
547
    case 5: /* CS (C) */
548
        tmp = gen_new_qreg(QMODE_I32);
549
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
550
        gen_op_jmp_nz32(tmp, l1);
551
        break;
552
    case 6: /* NE (!Z) */
553
        tmp = gen_new_qreg(QMODE_I32);
554
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
555
        gen_op_jmp_z32(tmp, l1);
556
        break;
557
    case 7: /* EQ (Z) */
558
        tmp = gen_new_qreg(QMODE_I32);
559
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
560
        gen_op_jmp_nz32(tmp, l1);
561
        break;
562
    case 8: /* VC (!V) */
563
        tmp = gen_new_qreg(QMODE_I32);
564
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
565
        gen_op_jmp_z32(tmp, l1);
566
        break;
567
    case 9: /* VS (V) */
568
        tmp = gen_new_qreg(QMODE_I32);
569
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
570
        gen_op_jmp_nz32(tmp, l1);
571
        break;
572
    case 10: /* PL (!N) */
573
        tmp = gen_new_qreg(QMODE_I32);
574
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
575
        gen_op_jmp_z32(tmp, l1);
576
        break;
577
    case 11: /* MI (N) */
578
        tmp = gen_new_qreg(QMODE_I32);
579
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
580
        gen_op_jmp_nz32(tmp, l1);
581
        break;
582
    case 12: /* GE (!(N ^ V)) */
583
        tmp = gen_new_qreg(QMODE_I32);
584
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
585
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
586
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
587
        gen_op_jmp_z32(tmp, l1);
588
        break;
589
    case 13: /* LT (N ^ V) */
590
        tmp = gen_new_qreg(QMODE_I32);
591
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
592
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
593
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
594
        gen_op_jmp_nz32(tmp, l1);
595
        break;
596
    case 14: /* GT (!(Z || (N ^ V))) */
597
        {
598
            int l2;
599
            l2 = gen_new_label();
600
            tmp = gen_new_qreg(QMODE_I32);
601
            gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
602
            gen_op_jmp_nz32(tmp, l2);
603
            tmp = gen_new_qreg(QMODE_I32);
604
            gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
605
            gen_op_xor32(tmp, tmp, QREG_CC_DEST);
606
            gen_op_and32(tmp, tmp, gen_im32(CCF_V));
607
            gen_op_jmp_nz32(tmp, l2);
608
            gen_op_jmp(l1);
609
            gen_set_label(l2);
610
        }
611
        break;
612
    case 15: /* LE (Z || (N ^ V)) */
613
        tmp = gen_new_qreg(QMODE_I32);
614
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
615
        gen_op_jmp_nz32(tmp, l1);
616
        tmp = gen_new_qreg(QMODE_I32);
617
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
618
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
619
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
620
        gen_op_jmp_nz32(tmp, l1);
621
        break;
622
    default:
623
        /* Should ever happen.  */
624
        abort();
625
    }
626
}
627

    
628
DISAS_INSN(scc)
629
{
630
    int l1;
631
    int cond;
632
    int reg;
633

    
634
    l1 = gen_new_label();
635
    cond = (insn >> 8) & 0xf;
636
    reg = DREG(insn, 0);
637
    gen_op_and32(reg, reg, gen_im32(0xffffff00));
638
    gen_jmpcc(s, cond ^ 1, l1);
639
    gen_op_or32(reg, reg, gen_im32(0xff));
640
    gen_set_label(l1);
641
}
642

    
643
/* Force a TB lookup after an instruction that changes the CPU state.  */
644
static void gen_lookup_tb(DisasContext *s)
645
{
646
    gen_flush_cc_op(s);
647
    gen_op_mov32(QREG_PC, gen_im32(s->pc));
648
    s->is_jmp = DISAS_UPDATE;
649
}
650

    
651
/* Generate a jump to to the address in qreg DEST.  */
652
static void gen_jmp(DisasContext *s, int dest)
653
{
654
    gen_flush_cc_op(s);
655
    gen_op_mov32(QREG_PC, dest);
656
    s->is_jmp = DISAS_JUMP;
657
}
658

    
659
static void gen_exception(DisasContext *s, uint32_t where, int nr)
660
{
661
    gen_flush_cc_op(s);
662
    gen_jmp(s, gen_im32(where));
663
    gen_op_raise_exception(nr);
664
}
665

    
666
/* Generate a jump to an immediate address.  */
667
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
668
{
669
    TranslationBlock *tb;
670

    
671
    tb = s->tb;
672
    if (__builtin_expect (s->singlestep_enabled, 0)) {
673
        gen_exception(s, dest, EXCP_DEBUG);
674
    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
675
               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
676
        gen_op_goto_tb(0, n, (long)tb);
677
        gen_op_mov32(QREG_PC, gen_im32(dest));
678
        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
679
        gen_op_exit_tb();
680
    } else {
681
        gen_jmp(s, gen_im32(dest));
682
        gen_op_mov32(QREG_T0, gen_im32(0));
683
        gen_op_exit_tb();
684
    }
685
    s->is_jmp = DISAS_TB_JUMP;
686
}
687

    
688
DISAS_INSN(undef_mac)
689
{
690
    gen_exception(s, s->pc - 2, EXCP_LINEA);
691
}
692

    
693
DISAS_INSN(undef_fpu)
694
{
695
    gen_exception(s, s->pc - 2, EXCP_LINEF);
696
}
697

    
698
DISAS_INSN(undef)
699
{
700
    gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
701
    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
702
              insn, s->pc - 2);
703
}
704

    
705
DISAS_INSN(mulw)
706
{
707
    int reg;
708
    int tmp;
709
    int src;
710
    int sign;
711

    
712
    sign = (insn & 0x100) != 0;
713
    reg = DREG(insn, 9);
714
    tmp = gen_new_qreg(QMODE_I32);
715
    if (sign)
716
        gen_op_ext16s32(tmp, reg);
717
    else
718
        gen_op_ext16u32(tmp, reg);
719
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
720
    gen_op_mul32(tmp, tmp, src);
721
    gen_op_mov32(reg, tmp);
722
    /* Unlike m68k, coldfire always clears the overflow bit.  */
723
    gen_logic_cc(s, tmp);
724
}
725

    
726
DISAS_INSN(divw)
727
{
728
    int reg;
729
    int tmp;
730
    int src;
731
    int sign;
732

    
733
    sign = (insn & 0x100) != 0;
734
    reg = DREG(insn, 9);
735
    if (sign) {
736
        gen_op_ext16s32(QREG_DIV1, reg);
737
    } else {
738
        gen_op_ext16u32(QREG_DIV1, reg);
739
    }
740
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
741
    gen_op_mov32(QREG_DIV2, src);
742
    if (sign) {
743
        gen_op_divs(1);
744
    } else {
745
        gen_op_divu(1);
746
    }
747

    
748
    tmp = gen_new_qreg(QMODE_I32);
749
    src = gen_new_qreg(QMODE_I32);
750
    gen_op_ext16u32(tmp, QREG_DIV1);
751
    gen_op_shl32(src, QREG_DIV2, gen_im32(16));
752
    gen_op_or32(reg, tmp, src);
753
    gen_op_flags_set();
754
    s->cc_op = CC_OP_FLAGS;
755
}
756

    
757
DISAS_INSN(divl)
758
{
759
    int num;
760
    int den;
761
    int reg;
762
    uint16_t ext;
763

    
764
    ext = lduw_code(s->pc);
765
    s->pc += 2;
766
    if (ext & 0x87f8) {
767
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
768
        return;
769
    }
770
    num = DREG(ext, 12);
771
    reg = DREG(ext, 0);
772
    gen_op_mov32(QREG_DIV1, num);
773
    den = gen_ea(s, insn, OS_LONG, 0, NULL);
774
    gen_op_mov32(QREG_DIV2, den);
775
    if (ext & 0x0800) {
776
        gen_op_divs(2);
777
    } else {
778
        gen_op_divu(2);
779
    }
780
    if (num == reg) {
781
        /* div */
782
        gen_op_mov32 (reg, QREG_DIV1);
783
    } else {
784
        /* rem */
785
        gen_op_mov32 (reg, QREG_DIV2);
786
    }
787
    gen_op_flags_set();
788
    s->cc_op = CC_OP_FLAGS;
789
}
790

    
791
DISAS_INSN(addsub)
792
{
793
    int reg;
794
    int dest;
795
    int src;
796
    int tmp;
797
    int addr;
798
    int add;
799

    
800
    add = (insn & 0x4000) != 0;
801
    reg = DREG(insn, 9);
802
    dest = gen_new_qreg(QMODE_I32);
803
    if (insn & 0x100) {
804
        tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
805
        src = reg;
806
    } else {
807
        tmp = reg;
808
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
809
    }
810
    if (add) {
811
        gen_op_add32(dest, tmp, src);
812
        gen_op_update_xflag_lt(dest, src);
813
        s->cc_op = CC_OP_ADD;
814
    } else {
815
        gen_op_update_xflag_lt(tmp, src);
816
        gen_op_sub32(dest, tmp, src);
817
        s->cc_op = CC_OP_SUB;
818
    }
819
    gen_op_update_cc_add(dest, src);
820
    if (insn & 0x100) {
821
        gen_ea(s, insn, OS_LONG, dest, &addr);
822
    } else {
823
        gen_op_mov32(reg, dest);
824
    }
825
}
826

    
827

    
828
/* Reverse the order of the bits in REG.  */
829
DISAS_INSN(bitrev)
830
{
831
    int val;
832
    int tmp1;
833
    int tmp2;
834
    int reg;
835

    
836
    val = gen_new_qreg(QMODE_I32);
837
    tmp1 = gen_new_qreg(QMODE_I32);
838
    tmp2 = gen_new_qreg(QMODE_I32);
839
    reg = DREG(insn, 0);
840
    gen_op_mov32(val, reg);
841
    /* Reverse bits within each nibble.  */
842
    gen_op_shl32(tmp1, val, gen_im32(3));
843
    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
844
    gen_op_shl32(tmp2, val, gen_im32(1));
845
    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
846
    gen_op_or32(tmp1, tmp1, tmp2);
847
    gen_op_shr32(tmp2, val, gen_im32(1));
848
    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
849
    gen_op_or32(tmp1, tmp1, tmp2);
850
    gen_op_shr32(tmp2, val, gen_im32(3));
851
    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
852
    gen_op_or32(tmp1, tmp1, tmp2);
853
    /* Reverse nibbles withing bytes.  */
854
    gen_op_shl32(val, tmp1, gen_im32(4));
855
    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
856
    gen_op_shr32(tmp2, tmp1, gen_im32(4));
857
    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
858
    gen_op_or32(val, val, tmp2);
859
    /* Reverse bytes.  */
860
    gen_op_bswap32(reg, val);
861
    gen_op_mov32(reg, val);
862
}
863

    
864
DISAS_INSN(bitop_reg)
865
{
866
    int opsize;
867
    int op;
868
    int src1;
869
    int src2;
870
    int tmp;
871
    int addr;
872
    int dest;
873

    
874
    if ((insn & 0x38) != 0)
875
        opsize = OS_BYTE;
876
    else
877
        opsize = OS_LONG;
878
    op = (insn >> 6) & 3;
879
    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
880
    src2 = DREG(insn, 9);
881
    dest = gen_new_qreg(QMODE_I32);
882

    
883
    gen_flush_flags(s);
884
    tmp = gen_new_qreg(QMODE_I32);
885
    if (opsize == OS_BYTE)
886
        gen_op_and32(tmp, src2, gen_im32(7));
887
    else
888
        gen_op_and32(tmp, src2, gen_im32(31));
889
    src2 = tmp;
890
    tmp = gen_new_qreg(QMODE_I32);
891
    gen_op_shl32(tmp, gen_im32(1), src2);
892

    
893
    gen_op_btest(src1, tmp);
894
    switch (op) {
895
    case 1: /* bchg */
896
        gen_op_xor32(dest, src1, tmp);
897
        break;
898
    case 2: /* bclr */
899
        gen_op_not32(tmp, tmp);
900
        gen_op_and32(dest, src1, tmp);
901
        break;
902
    case 3: /* bset */
903
        gen_op_or32(dest, src1, tmp);
904
        break;
905
    default: /* btst */
906
        break;
907
    }
908
    if (op)
909
        gen_ea(s, insn, opsize, dest, &addr);
910
}
911

    
912
DISAS_INSN(sats)
913
{
914
    int reg;
915
    int tmp;
916
    int l1;
917

    
918
    reg = DREG(insn, 0);
919
    tmp = gen_new_qreg(QMODE_I32);
920
    gen_flush_flags(s);
921
    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
922
    l1 = gen_new_label();
923
    gen_op_jmp_z32(tmp, l1);
924
    tmp = gen_new_qreg(QMODE_I32);
925
    gen_op_shr32(tmp, reg, gen_im32(31));
926
    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
927
    gen_op_mov32(reg, tmp);
928
    gen_set_label(l1);
929
    gen_logic_cc(s, tmp);
930
}
931

    
932
static void gen_push(DisasContext *s, int val)
933
{
934
    int tmp;
935

    
936
    tmp = gen_new_qreg(QMODE_I32);
937
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
938
    gen_store(s, OS_LONG, tmp, val);
939
    gen_op_mov32(QREG_SP, tmp);
940
}
941

    
942
DISAS_INSN(movem)
943
{
944
    int addr;
945
    int i;
946
    uint16_t mask;
947
    int reg;
948
    int tmp;
949
    int is_load;
950

    
951
    mask = lduw_code(s->pc);
952
    s->pc += 2;
953
    tmp = gen_lea(s, insn, OS_LONG);
954
    addr = gen_new_qreg(QMODE_I32);
955
    gen_op_mov32(addr, tmp);
956
    is_load = ((insn & 0x0400) != 0);
957
    for (i = 0; i < 16; i++, mask >>= 1) {
958
        if (mask & 1) {
959
            if (i < 8)
960
                reg = DREG(i, 0);
961
            else
962
                reg = AREG(i, 0);
963
            if (is_load) {
964
                tmp = gen_load(s, OS_LONG, addr, 0);
965
                gen_op_mov32(reg, tmp);
966
            } else {
967
                gen_store(s, OS_LONG, addr, reg);
968
            }
969
            if (mask != 1)
970
                gen_op_add32(addr, addr, gen_im32(4));
971
        }
972
    }
973
}
974

    
975
DISAS_INSN(bitop_im)
976
{
977
    int opsize;
978
    int op;
979
    int src1;
980
    uint32_t mask;
981
    int bitnum;
982
    int tmp;
983
    int addr;
984
    int dest;
985

    
986
    if ((insn & 0x38) != 0)
987
        opsize = OS_BYTE;
988
    else
989
        opsize = OS_LONG;
990
    op = (insn >> 6) & 3;
991

    
992
    bitnum = lduw_code(s->pc);
993
    s->pc += 2;
994
    if (bitnum & 0xff00) {
995
        disas_undef(s, insn);
996
        return;
997
    }
998

    
999
    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
1000

    
1001
    gen_flush_flags(s);
1002
    tmp = gen_new_qreg(QMODE_I32);
1003
    if (opsize == OS_BYTE)
1004
        bitnum &= 7;
1005
    else
1006
        bitnum &= 31;
1007
    mask = 1 << bitnum;
1008

    
1009
    gen_op_btest(src1, gen_im32(mask));
1010
    if (op)
1011
        dest = gen_new_qreg(QMODE_I32);
1012
    else
1013
        dest = -1;
1014

    
1015
    switch (op) {
1016
    case 1: /* bchg */
1017
        gen_op_xor32(dest, src1, gen_im32(mask));
1018
        break;
1019
    case 2: /* bclr */
1020
        gen_op_and32(dest, src1, gen_im32(~mask));
1021
        break;
1022
    case 3: /* bset */
1023
        gen_op_or32(dest, src1, gen_im32(mask));
1024
        break;
1025
    default: /* btst */
1026
        break;
1027
    }
1028
    if (op)
1029
        gen_ea(s, insn, opsize, dest, &addr);
1030
}
1031

    
1032
DISAS_INSN(arith_im)
1033
{
1034
    int op;
1035
    int src1;
1036
    int dest;
1037
    int src2;
1038
    int addr;
1039

    
1040
    op = (insn >> 9) & 7;
1041
    src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
1042
    src2 = gen_im32(read_im32(s));
1043
    dest = gen_new_qreg(QMODE_I32);
1044
    switch (op) {
1045
    case 0: /* ori */
1046
        gen_op_or32(dest, src1, src2);
1047
        gen_logic_cc(s, dest);
1048
        break;
1049
    case 1: /* andi */
1050
        gen_op_and32(dest, src1, src2);
1051
        gen_logic_cc(s, dest);
1052
        break;
1053
    case 2: /* subi */
1054
        gen_op_mov32(dest, src1);
1055
        gen_op_update_xflag_lt(dest, src2);
1056
        gen_op_sub32(dest, dest, src2);
1057
        gen_op_update_cc_add(dest, src2);
1058
        s->cc_op = CC_OP_SUB;
1059
        break;
1060
    case 3: /* addi */
1061
        gen_op_mov32(dest, src1);
1062
        gen_op_add32(dest, dest, src2);
1063
        gen_op_update_cc_add(dest, src2);
1064
        gen_op_update_xflag_lt(dest, src2);
1065
        s->cc_op = CC_OP_ADD;
1066
        break;
1067
    case 5: /* eori */
1068
        gen_op_xor32(dest, src1, src2);
1069
        gen_logic_cc(s, dest);
1070
        break;
1071
    case 6: /* cmpi */
1072
        gen_op_mov32(dest, src1);
1073
        gen_op_sub32(dest, dest, src2);
1074
        gen_op_update_cc_add(dest, src2);
1075
        s->cc_op = CC_OP_SUB;
1076
        break;
1077
    default:
1078
        abort();
1079
    }
1080
    if (op != 6) {
1081
        gen_ea(s, insn, OS_LONG, dest, &addr);
1082
    }
1083
}
1084

    
1085
DISAS_INSN(byterev)
1086
{
1087
    int reg;
1088

    
1089
    reg = DREG(insn, 0);
1090
    gen_op_bswap32(reg, reg);
1091
}
1092

    
1093
DISAS_INSN(move)
1094
{
1095
    int src;
1096
    int dest;
1097
    int op;
1098
    int opsize;
1099

    
1100
    switch (insn >> 12) {
1101
    case 1: /* move.b */
1102
        opsize = OS_BYTE;
1103
        break;
1104
    case 2: /* move.l */
1105
        opsize = OS_LONG;
1106
        break;
1107
    case 3: /* move.w */
1108
        opsize = OS_WORD;
1109
        break;
1110
    default:
1111
        abort();
1112
    }
1113
    src = gen_ea(s, insn, opsize, -1, NULL);
1114
    op = (insn >> 6) & 7;
1115
    if (op == 1) {
1116
        /* movea */
1117
        /* The value will already have been sign extended.  */
1118
        dest = AREG(insn, 9);
1119
        gen_op_mov32(dest, src);
1120
    } else {
1121
        /* normal move */
1122
        uint16_t dest_ea;
1123
        dest_ea = ((insn >> 9) & 7) | (op << 3);
1124
        gen_ea(s, dest_ea, opsize, src, NULL);
1125
        /* This will be correct because loads sign extend.  */
1126
        gen_logic_cc(s, src);
1127
    }
1128
}
1129

    
1130
DISAS_INSN(negx)
1131
{
1132
    int reg;
1133
    int dest;
1134
    int tmp;
1135

    
1136
    gen_flush_flags(s);
1137
    reg = DREG(insn, 0);
1138
    dest = gen_new_qreg(QMODE_I32);
1139
    gen_op_mov32 (dest, gen_im32(0));
1140
    gen_op_subx_cc(dest, reg);
1141
    /* !Z is sticky.  */
1142
    tmp = gen_new_qreg(QMODE_I32);
1143
    gen_op_mov32 (tmp, QREG_CC_DEST);
1144
    gen_op_update_cc_add(dest, reg);
1145
    gen_op_mov32(reg, dest);
1146
    s->cc_op = CC_OP_DYNAMIC;
1147
    gen_flush_flags(s);
1148
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1149
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1150
    s->cc_op = CC_OP_FLAGS;
1151
}
1152

    
1153
DISAS_INSN(lea)
1154
{
1155
    int reg;
1156
    int tmp;
1157

    
1158
    reg = AREG(insn, 9);
1159
    tmp = gen_lea(s, insn, OS_LONG);
1160
    gen_op_mov32(reg, tmp);
1161
}
1162

    
1163
DISAS_INSN(clr)
1164
{
1165
    int opsize;
1166

    
1167
    switch ((insn >> 6) & 3) {
1168
    case 0: /* clr.b */
1169
        opsize = OS_BYTE;
1170
        break;
1171
    case 1: /* clr.w */
1172
        opsize = OS_WORD;
1173
        break;
1174
    case 2: /* clr.l */
1175
        opsize = OS_LONG;
1176
        break;
1177
    default:
1178
        abort();
1179
    }
1180
    gen_ea (s, insn, opsize, gen_im32(0), NULL);
1181
    gen_logic_cc(s, gen_im32(0));
1182
}
1183

    
1184
static int gen_get_ccr(DisasContext *s)
1185
{
1186
    int dest;
1187

    
1188
    gen_flush_flags(s);
1189
    dest = gen_new_qreg(QMODE_I32);
1190
    gen_op_get_xflag(dest);
1191
    gen_op_shl32(dest, dest, gen_im32(4));
1192
    gen_op_or32(dest, dest, QREG_CC_DEST);
1193
    return dest;
1194
}
1195

    
1196
DISAS_INSN(move_from_ccr)
1197
{
1198
    int reg;
1199
    int ccr;
1200

    
1201
    ccr = gen_get_ccr(s);
1202
    reg = DREG(insn, 0);
1203
    gen_partset_reg(OS_WORD, reg, ccr);
1204
}
1205

    
1206
DISAS_INSN(neg)
1207
{
1208
    int reg;
1209
    int src1;
1210

    
1211
    reg = DREG(insn, 0);
1212
    src1 = gen_new_qreg(QMODE_I32);
1213
    gen_op_mov32(src1, reg);
1214
    gen_op_neg32(reg, src1);
1215
    s->cc_op = CC_OP_SUB;
1216
    gen_op_update_cc_add(reg, src1);
1217
    gen_op_update_xflag_lt(gen_im32(0), src1);
1218
    s->cc_op = CC_OP_SUB;
1219
}
1220

    
1221
static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1222
{
1223
    gen_op_logic_cc(gen_im32(val & 0xf));
1224
    gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1225
    if (!ccr_only) {
1226
        gen_op_mov32(QREG_SR, gen_im32(val & 0xff00));
1227
    }
1228
}
1229

    
1230
static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1231
{
1232
    int src1;
1233
    int reg;
1234

    
1235
    s->cc_op = CC_OP_FLAGS;
1236
    if ((insn & 0x38) == 0)
1237
      {
1238
        src1 = gen_new_qreg(QMODE_I32);
1239
        reg = DREG(insn, 0);
1240
        gen_op_and32(src1, reg, gen_im32(0xf));
1241
        gen_op_logic_cc(src1);
1242
        gen_op_shr32(src1, reg, gen_im32(4));
1243
        gen_op_and32(src1, src1, gen_im32(1));
1244
        gen_op_update_xflag_tst(src1);
1245
        if (!ccr_only) {
1246
            gen_op_and32(QREG_SR, reg, gen_im32(0xff00));
1247
        }
1248
      }
1249
    else if ((insn & 0x3f) == 0x3c)
1250
      {
1251
        uint16_t val;
1252
        val = lduw_code(s->pc);
1253
        s->pc += 2;
1254
        gen_set_sr_im(s, val, ccr_only);
1255
      }
1256
    else
1257
        disas_undef(s, insn);
1258
}
1259

    
1260
DISAS_INSN(move_to_ccr)
1261
{
1262
    gen_set_sr(s, insn, 1);
1263
}
1264

    
1265
DISAS_INSN(not)
1266
{
1267
    int reg;
1268

    
1269
    reg = DREG(insn, 0);
1270
    gen_op_not32(reg, reg);
1271
    gen_logic_cc(s, reg);
1272
}
1273

    
1274
DISAS_INSN(swap)
1275
{
1276
    int dest;
1277
    int src1;
1278
    int src2;
1279
    int reg;
1280

    
1281
    dest = gen_new_qreg(QMODE_I32);
1282
    src1 = gen_new_qreg(QMODE_I32);
1283
    src2 = gen_new_qreg(QMODE_I32);
1284
    reg = DREG(insn, 0);
1285
    gen_op_shl32(src1, reg, gen_im32(16));
1286
    gen_op_shr32(src2, reg, gen_im32(16));
1287
    gen_op_or32(dest, src1, src2);
1288
    gen_op_mov32(reg, dest);
1289
    gen_logic_cc(s, dest);
1290
}
1291

    
1292
DISAS_INSN(pea)
1293
{
1294
    int tmp;
1295

    
1296
    tmp = gen_lea(s, insn, OS_LONG);
1297
    gen_push(s, tmp);
1298
}
1299

    
1300
DISAS_INSN(ext)
1301
{
1302
    int reg;
1303
    int op;
1304
    int tmp;
1305

    
1306
    reg = DREG(insn, 0);
1307
    op = (insn >> 6) & 7;
1308
    tmp = gen_new_qreg(QMODE_I32);
1309
    if (op == 3)
1310
        gen_op_ext16s32(tmp, reg);
1311
    else
1312
        gen_op_ext8s32(tmp, reg);
1313
    if (op == 2)
1314
        gen_partset_reg(OS_WORD, reg, tmp);
1315
    else
1316
      gen_op_mov32(reg, tmp);
1317
    gen_logic_cc(s, tmp);
1318
}
1319

    
1320
DISAS_INSN(tst)
1321
{
1322
    int opsize;
1323
    int tmp;
1324

    
1325
    switch ((insn >> 6) & 3) {
1326
    case 0: /* tst.b */
1327
        opsize = OS_BYTE;
1328
        break;
1329
    case 1: /* tst.w */
1330
        opsize = OS_WORD;
1331
        break;
1332
    case 2: /* tst.l */
1333
        opsize = OS_LONG;
1334
        break;
1335
    default:
1336
        abort();
1337
    }
1338
    tmp = gen_ea(s, insn, opsize, -1, NULL);
1339
    gen_logic_cc(s, tmp);
1340
}
1341

    
1342
DISAS_INSN(pulse)
1343
{
1344
  /* Implemented as a NOP.  */
1345
}
1346

    
1347
DISAS_INSN(illegal)
1348
{
1349
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1350
}
1351

    
1352
/* ??? This should be atomic.  */
1353
DISAS_INSN(tas)
1354
{
1355
    int dest;
1356
    int src1;
1357
    int addr;
1358

    
1359
    dest = gen_new_qreg(QMODE_I32);
1360
    src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
1361
    gen_logic_cc(s, src1);
1362
    gen_op_or32(dest, src1, gen_im32(0x80));
1363
    gen_ea(s, insn, OS_BYTE, dest, &addr);
1364
}
1365

    
1366
DISAS_INSN(mull)
1367
{
1368
    uint16_t ext;
1369
    int reg;
1370
    int src1;
1371
    int dest;
1372

    
1373
    /* The upper 32 bits of the product are discarded, so
1374
       muls.l and mulu.l are functionally equivalent.  */
1375
    ext = lduw_code(s->pc);
1376
    s->pc += 2;
1377
    if (ext & 0x87ff) {
1378
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1379
        return;
1380
    }
1381
    reg = DREG(ext, 12);
1382
    src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
1383
    dest = gen_new_qreg(QMODE_I32);
1384
    gen_op_mul32(dest, src1, reg);
1385
    gen_op_mov32(reg, dest);
1386
    /* Unlike m68k, coldfire always clears the overflow bit.  */
1387
    gen_logic_cc(s, dest);
1388
}
1389

    
1390
DISAS_INSN(link)
1391
{
1392
    int16_t offset;
1393
    int reg;
1394
    int tmp;
1395

    
1396
    offset = ldsw_code(s->pc);
1397
    s->pc += 2;
1398
    reg = AREG(insn, 0);
1399
    tmp = gen_new_qreg(QMODE_I32);
1400
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1401
    gen_store(s, OS_LONG, tmp, reg);
1402
    if (reg != QREG_SP)
1403
        gen_op_mov32(reg, tmp);
1404
    gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1405
}
1406

    
1407
DISAS_INSN(unlk)
1408
{
1409
    int src;
1410
    int reg;
1411
    int tmp;
1412

    
1413
    src = gen_new_qreg(QMODE_I32);
1414
    reg = AREG(insn, 0);
1415
    gen_op_mov32(src, reg);
1416
    tmp = gen_load(s, OS_LONG, src, 0);
1417
    gen_op_mov32(reg, tmp);
1418
    gen_op_add32(QREG_SP, src, gen_im32(4));
1419
}
1420

    
1421
DISAS_INSN(nop)
1422
{
1423
}
1424

    
1425
DISAS_INSN(rts)
1426
{
1427
    int tmp;
1428

    
1429
    tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1430
    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1431
    gen_jmp(s, tmp);
1432
}
1433

    
1434
DISAS_INSN(jump)
1435
{
1436
    int tmp;
1437

    
1438
    /* Load the target address first to ensure correct exception
1439
       behavior.  */
1440
    tmp = gen_lea(s, insn, OS_LONG);
1441
    if ((insn & 0x40) == 0) {
1442
        /* jsr */
1443
        gen_push(s, gen_im32(s->pc));
1444
    }
1445
    gen_jmp(s, tmp);
1446
}
1447

    
1448
DISAS_INSN(addsubq)
1449
{
1450
    int src1;
1451
    int src2;
1452
    int dest;
1453
    int val;
1454
    int addr;
1455

    
1456
    src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
1457
    val = (insn >> 9) & 7;
1458
    if (val == 0)
1459
        val = 8;
1460
    src2 = gen_im32(val);
1461
    dest = gen_new_qreg(QMODE_I32);
1462
    gen_op_mov32(dest, src1);
1463
    if ((insn & 0x38) == 0x08) {
1464
        /* Don't update condition codes if the destination is an
1465
           address register.  */
1466
        if (insn & 0x0100) {
1467
            gen_op_sub32(dest, dest, src2);
1468
        } else {
1469
            gen_op_add32(dest, dest, src2);
1470
        }
1471
    } else {
1472
        if (insn & 0x0100) {
1473
            gen_op_update_xflag_lt(dest, src2);
1474
            gen_op_sub32(dest, dest, src2);
1475
            s->cc_op = CC_OP_SUB;
1476
        } else {
1477
            gen_op_add32(dest, dest, src2);
1478
            gen_op_update_xflag_lt(dest, src2);
1479
            s->cc_op = CC_OP_ADD;
1480
        }
1481
        gen_op_update_cc_add(dest, src2);
1482
    }
1483
    gen_ea(s, insn, OS_LONG, dest, &addr);
1484
}
1485

    
1486
DISAS_INSN(tpf)
1487
{
1488
    switch (insn & 7) {
1489
    case 2: /* One extension word.  */
1490
        s->pc += 2;
1491
        break;
1492
    case 3: /* Two extension words.  */
1493
        s->pc += 4;
1494
        break;
1495
    case 4: /* No extension words.  */
1496
        break;
1497
    default:
1498
        disas_undef(s, insn);
1499
    }
1500
}
1501

    
1502
DISAS_INSN(branch)
1503
{
1504
    int32_t offset;
1505
    uint32_t base;
1506
    int op;
1507
    int l1;
1508
    
1509
    base = s->pc;
1510
    op = (insn >> 8) & 0xf;
1511
    offset = (int8_t)insn;
1512
    if (offset == 0) {
1513
        offset = ldsw_code(s->pc);
1514
        s->pc += 2;
1515
    } else if (offset == -1) {
1516
        offset = read_im32(s);
1517
    }
1518
    if (op == 1) {
1519
        /* bsr */
1520
        gen_push(s, gen_im32(s->pc));
1521
    }
1522
    gen_flush_cc_op(s);
1523
    if (op > 1) {
1524
        /* Bcc */
1525
        l1 = gen_new_label();
1526
        gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1527
        gen_jmp_tb(s, 1, base + offset);
1528
        gen_set_label(l1);
1529
        gen_jmp_tb(s, 0, s->pc);
1530
    } else {
1531
        /* Unconditional branch.  */
1532
        gen_jmp_tb(s, 0, base + offset);
1533
    }
1534
}
1535

    
1536
DISAS_INSN(moveq)
1537
{
1538
    int tmp;
1539

    
1540
    tmp = gen_im32((int8_t)insn);
1541
    gen_op_mov32(DREG(insn, 9), tmp);
1542
    gen_logic_cc(s, tmp);
1543
}
1544

    
1545
DISAS_INSN(mvzs)
1546
{
1547
    int opsize;
1548
    int src;
1549
    int reg;
1550

    
1551
    if (insn & 0x40)
1552
        opsize = OS_WORD;
1553
    else
1554
        opsize = OS_BYTE;
1555
    src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
1556
    reg = DREG(insn, 9);
1557
    gen_op_mov32(reg, src);
1558
    gen_logic_cc(s, src);
1559
}
1560

    
1561
DISAS_INSN(or)
1562
{
1563
    int reg;
1564
    int dest;
1565
    int src;
1566
    int addr;
1567

    
1568
    reg = DREG(insn, 9);
1569
    dest = gen_new_qreg(QMODE_I32);
1570
    if (insn & 0x100) {
1571
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
1572
        gen_op_or32(dest, src, reg);
1573
        gen_ea(s, insn, OS_LONG, dest, &addr);
1574
    } else {
1575
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
1576
        gen_op_or32(dest, src, reg);
1577
        gen_op_mov32(reg, dest);
1578
    }
1579
    gen_logic_cc(s, dest);
1580
}
1581

    
1582
DISAS_INSN(suba)
1583
{
1584
    int src;
1585
    int reg;
1586

    
1587
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
1588
    reg = AREG(insn, 9);
1589
    gen_op_sub32(reg, reg, src);
1590
}
1591

    
1592
DISAS_INSN(subx)
1593
{
1594
    int reg;
1595
    int src;
1596
    int dest;
1597
    int tmp;
1598

    
1599
    gen_flush_flags(s);
1600
    reg = DREG(insn, 9);
1601
    src = DREG(insn, 0);
1602
    dest = gen_new_qreg(QMODE_I32);
1603
    gen_op_mov32 (dest, reg);
1604
    gen_op_subx_cc(dest, src);
1605
    /* !Z is sticky.  */
1606
    tmp = gen_new_qreg(QMODE_I32);
1607
    gen_op_mov32 (tmp, QREG_CC_DEST);
1608
    gen_op_update_cc_add(dest, src);
1609
    gen_op_mov32(reg, dest);
1610
    s->cc_op = CC_OP_DYNAMIC;
1611
    gen_flush_flags(s);
1612
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1613
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1614
    s->cc_op = CC_OP_FLAGS;
1615
}
1616

    
1617
DISAS_INSN(mov3q)
1618
{
1619
    int src;
1620
    int val;
1621

    
1622
    val = (insn >> 9) & 7;
1623
    if (val == 0)
1624
        val = -1;
1625
    src = gen_im32(val);
1626
    gen_logic_cc(s, src);
1627
    gen_ea(s, insn, OS_LONG, src, NULL);
1628
}
1629

    
1630
DISAS_INSN(cmp)
1631
{
1632
    int op;
1633
    int src;
1634
    int reg;
1635
    int dest;
1636
    int opsize;
1637

    
1638
    op = (insn >> 6) & 3;
1639
    switch (op) {
1640
    case 0: /* cmp.b */
1641
        opsize = OS_BYTE;
1642
        s->cc_op = CC_OP_CMPB;
1643
        break;
1644
    case 1: /* cmp.w */
1645
        opsize = OS_WORD;
1646
        s->cc_op = CC_OP_CMPW;
1647
        break;
1648
    case 2: /* cmp.l */
1649
        opsize = OS_LONG;
1650
        s->cc_op = CC_OP_SUB;
1651
        break;
1652
    default:
1653
        abort();
1654
    }
1655
    src = gen_ea(s, insn, opsize, -1, NULL);
1656
    reg = DREG(insn, 9);
1657
    dest = gen_new_qreg(QMODE_I32);
1658
    gen_op_sub32(dest, reg, src);
1659
    gen_op_update_cc_add(dest, src);
1660
}
1661

    
1662
DISAS_INSN(cmpa)
1663
{
1664
    int opsize;
1665
    int src;
1666
    int reg;
1667
    int dest;
1668

    
1669
    if (insn & 0x100) {
1670
        opsize = OS_LONG;
1671
    } else {
1672
        opsize = OS_WORD;
1673
    }
1674
    src = gen_ea(s, insn, opsize, -1, NULL);
1675
    reg = AREG(insn, 9);
1676
    dest = gen_new_qreg(QMODE_I32);
1677
    gen_op_sub32(dest, reg, src);
1678
    gen_op_update_cc_add(dest, src);
1679
    s->cc_op = CC_OP_SUB;
1680
}
1681

    
1682
DISAS_INSN(eor)
1683
{
1684
    int src;
1685
    int reg;
1686
    int dest;
1687
    int addr;
1688

    
1689
    src = gen_ea(s, insn, OS_LONG, 0, &addr);
1690
    reg = DREG(insn, 9);
1691
    dest = gen_new_qreg(QMODE_I32);
1692
    gen_op_xor32(dest, src, reg);
1693
    gen_logic_cc(s, dest);
1694
    gen_ea(s, insn, OS_LONG, dest, &addr);
1695
}
1696

    
1697
DISAS_INSN(and)
1698
{
1699
    int src;
1700
    int reg;
1701
    int dest;
1702
    int addr;
1703

    
1704
    reg = DREG(insn, 9);
1705
    dest = gen_new_qreg(QMODE_I32);
1706
    if (insn & 0x100) {
1707
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
1708
        gen_op_and32(dest, src, reg);
1709
        gen_ea(s, insn, OS_LONG, dest, &addr);
1710
    } else {
1711
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
1712
        gen_op_and32(dest, src, reg);
1713
        gen_op_mov32(reg, dest);
1714
    }
1715
    gen_logic_cc(s, dest);
1716
}
1717

    
1718
DISAS_INSN(adda)
1719
{
1720
    int src;
1721
    int reg;
1722

    
1723
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
1724
    reg = AREG(insn, 9);
1725
    gen_op_add32(reg, reg, src);
1726
}
1727

    
1728
DISAS_INSN(addx)
1729
{
1730
    int reg;
1731
    int src;
1732
    int dest;
1733
    int tmp;
1734

    
1735
    gen_flush_flags(s);
1736
    reg = DREG(insn, 9);
1737
    src = DREG(insn, 0);
1738
    dest = gen_new_qreg(QMODE_I32);
1739
    gen_op_mov32 (dest, reg);
1740
    gen_op_addx_cc(dest, src);
1741
    /* !Z is sticky.  */
1742
    tmp = gen_new_qreg(QMODE_I32);
1743
    gen_op_mov32 (tmp, QREG_CC_DEST);
1744
    gen_op_update_cc_add(dest, src);
1745
    gen_op_mov32(reg, dest);
1746
    s->cc_op = CC_OP_DYNAMIC;
1747
    gen_flush_flags(s);
1748
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1749
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1750
    s->cc_op = CC_OP_FLAGS;
1751
}
1752

    
1753
DISAS_INSN(shift_im)
1754
{
1755
    int reg;
1756
    int tmp;
1757

    
1758
    reg = DREG(insn, 0);
1759
    tmp = (insn >> 9) & 7;
1760
    if (tmp == 0)
1761
      tmp = 8;
1762
    if (insn & 0x100) {
1763
        gen_op_shl_im_cc(reg, tmp);
1764
        s->cc_op = CC_OP_SHL;
1765
    } else {
1766
        if (insn & 8) {
1767
            gen_op_shr_im_cc(reg, tmp);
1768
            s->cc_op = CC_OP_SHR;
1769
        } else {
1770
            gen_op_sar_im_cc(reg, tmp);
1771
            s->cc_op = CC_OP_SAR;
1772
        }
1773
    }
1774
}
1775

    
1776
DISAS_INSN(shift_reg)
1777
{
1778
    int reg;
1779
    int src;
1780
    int tmp;
1781

    
1782
    reg = DREG(insn, 0);
1783
    src = DREG(insn, 9);
1784
    tmp = gen_new_qreg(QMODE_I32);
1785
    gen_op_and32(tmp, src, gen_im32(63));
1786
    if (insn & 0x100) {
1787
        gen_op_shl_cc(reg, tmp);
1788
        s->cc_op = CC_OP_SHL;
1789
    } else {
1790
        if (insn & 8) {
1791
            gen_op_shr_cc(reg, tmp);
1792
            s->cc_op = CC_OP_SHR;
1793
        } else {
1794
            gen_op_sar_cc(reg, tmp);
1795
            s->cc_op = CC_OP_SAR;
1796
        }
1797
    }
1798
}
1799

    
1800
DISAS_INSN(ff1)
1801
{
1802
    cpu_abort(NULL, "Unimplemented insn: ff1");
1803
}
1804

    
1805
static int gen_get_sr(DisasContext *s)
1806
{
1807
    int ccr;
1808
    int sr;
1809

    
1810
    ccr = gen_get_ccr(s);
1811
    sr = gen_new_qreg(QMODE_I32);
1812
    gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
1813
    gen_op_or32(sr, sr, ccr);
1814
    return sr;
1815
}
1816

    
1817
DISAS_INSN(strldsr)
1818
{
1819
    uint16_t ext;
1820
    uint32_t addr;
1821

    
1822
    addr = s->pc - 2;
1823
    ext = lduw_code(s->pc);
1824
    s->pc += 2;
1825
    if (ext != 0x46FC) {
1826
        gen_exception(s, addr, EXCP_UNSUPPORTED);
1827
        return;
1828
    }
1829
    ext = lduw_code(s->pc);
1830
    s->pc += 2;
1831
    if (IS_USER(s) || (ext & SR_S) == 0) {
1832
        gen_exception(s, addr, EXCP_PRIVILEGE);
1833
        return;
1834
    }
1835
    gen_push(s, gen_get_sr(s));
1836
    gen_set_sr_im(s, ext, 0);
1837
}
1838

    
1839
DISAS_INSN(move_from_sr)
1840
{
1841
    int reg;
1842
    int sr;
1843

    
1844
    if (IS_USER(s)) {
1845
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1846
        return;
1847
    }
1848
    sr = gen_get_sr(s);
1849
    reg = DREG(insn, 0);
1850
    gen_partset_reg(OS_WORD, reg, sr);
1851
}
1852

    
1853
DISAS_INSN(move_to_sr)
1854
{
1855
    if (IS_USER(s)) {
1856
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1857
        return;
1858
    }
1859
    gen_set_sr(s, insn, 0);
1860
    gen_lookup_tb(s);
1861
}
1862

    
1863
DISAS_INSN(move_from_usp)
1864
{
1865
    if (IS_USER(s)) {
1866
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1867
        return;
1868
    }
1869
    /* TODO: Implement USP.  */
1870
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1871
}
1872

    
1873
DISAS_INSN(move_to_usp)
1874
{
1875
    if (IS_USER(s)) {
1876
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1877
        return;
1878
    }
1879
    /* TODO: Implement USP.  */
1880
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1881
}
1882

    
1883
DISAS_INSN(halt)
1884
{
1885
    gen_jmp(s, gen_im32(s->pc));
1886
    gen_op_halt();
1887
}
1888

    
1889
DISAS_INSN(stop)
1890
{
1891
    uint16_t ext;
1892

    
1893
    if (IS_USER(s)) {
1894
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1895
        return;
1896
    }
1897

    
1898
    ext = lduw_code(s->pc);
1899
    s->pc += 2;
1900

    
1901
    gen_set_sr_im(s, ext, 0);
1902
    gen_jmp(s, gen_im32(s->pc));
1903
    gen_op_stop();
1904
}
1905

    
1906
DISAS_INSN(rte)
1907
{
1908
    if (IS_USER(s)) {
1909
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1910
        return;
1911
    }
1912
    gen_exception(s, s->pc - 2, EXCP_RTE);
1913
}
1914

    
1915
DISAS_INSN(movec)
1916
{
1917
    uint16_t ext;
1918
    int reg;
1919

    
1920
    if (IS_USER(s)) {
1921
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1922
        return;
1923
    }
1924

    
1925
    ext = lduw_code(s->pc);
1926
    s->pc += 2;
1927

    
1928
    if (ext & 0x8000) {
1929
        reg = AREG(ext, 12);
1930
    } else {
1931
        reg = DREG(ext, 12);
1932
    }
1933
    gen_op_movec(gen_im32(ext & 0xfff), reg);
1934
    gen_lookup_tb(s);
1935
}
1936

    
1937
DISAS_INSN(intouch)
1938
{
1939
    if (IS_USER(s)) {
1940
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1941
        return;
1942
    }
1943
    /* ICache fetch.  Implement as no-op.  */
1944
}
1945

    
1946
DISAS_INSN(cpushl)
1947
{
1948
    if (IS_USER(s)) {
1949
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1950
        return;
1951
    }
1952
    /* Cache push/invalidate.  Implement as no-op.  */
1953
}
1954

    
1955
DISAS_INSN(wddata)
1956
{
1957
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1958
}
1959

    
1960
DISAS_INSN(wdebug)
1961
{
1962
    if (IS_USER(s)) {
1963
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1964
        return;
1965
    }
1966
    /* TODO: Implement wdebug.  */
1967
    qemu_assert(0, "WDEBUG not implemented");
1968
}
1969

    
1970
DISAS_INSN(trap)
1971
{
1972
    gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
1973
}
1974

    
1975
/* ??? FP exceptions are not implemented.  Most exceptions are deferred until
1976
   immediately before the next FP instruction is executed.  */
1977
DISAS_INSN(fpu)
1978
{
1979
    uint16_t ext;
1980
    int opmode;
1981
    int src;
1982
    int dest;
1983
    int res;
1984
    int round;
1985
    int opsize;
1986

    
1987
    ext = lduw_code(s->pc);
1988
    s->pc += 2;
1989
    opmode = ext & 0x7f;
1990
    switch ((ext >> 13) & 7) {
1991
    case 0: case 2:
1992
        break;
1993
    case 1:
1994
        goto undef;
1995
    case 3: /* fmove out */
1996
        src = FREG(ext, 7);
1997
        /* fmove */
1998
        /* ??? TODO: Proper behavior on overflow.  */
1999
        switch ((ext >> 10) & 7) {
2000
        case 0:
2001
            opsize = OS_LONG;
2002
            res = gen_new_qreg(QMODE_I32);
2003
            gen_op_f64_to_i32(res, src);
2004
            break;
2005
        case 1:
2006
            opsize = OS_SINGLE;
2007
            res = gen_new_qreg(QMODE_F32);
2008
            gen_op_f64_to_f32(res, src);
2009
            break;
2010
        case 4:
2011
            opsize = OS_WORD;
2012
            res = gen_new_qreg(QMODE_I32);
2013
            gen_op_f64_to_i32(res, src);
2014
            break;
2015
        case 5:
2016
            opsize = OS_DOUBLE;
2017
            res = src;
2018
            break;
2019
        case 6:
2020
            opsize = OS_BYTE;
2021
            res = gen_new_qreg(QMODE_I32);
2022
            gen_op_f64_to_i32(res, src);
2023
            break;
2024
        default:
2025
            goto undef;
2026
        }
2027
        gen_ea(s, insn, opsize, res, NULL);
2028
        return;
2029
    case 4: /* fmove to control register.  */
2030
        switch ((ext >> 10) & 7) {
2031
        case 4: /* FPCR */
2032
            /* Not implemented.  Ignore writes.  */
2033
            break;
2034
        case 1: /* FPIAR */
2035
        case 2: /* FPSR */
2036
        default:
2037
            cpu_abort(NULL, "Unimplemented: fmove to control %d",
2038
                      (ext >> 10) & 7);
2039
        }
2040
        break;
2041
    case 5: /* fmove from control register.  */
2042
        switch ((ext >> 10) & 7) {
2043
        case 4: /* FPCR */
2044
            /* Not implemented.  Always return zero.  */
2045
            res = gen_im32(0);
2046
            break;
2047
        case 1: /* FPIAR */
2048
        case 2: /* FPSR */
2049
        default:
2050
            cpu_abort(NULL, "Unimplemented: fmove from control %d",
2051
                      (ext >> 10) & 7);
2052
            goto undef;
2053
        }
2054
        gen_ea(s, insn, OS_LONG, res, NULL);
2055
        break;
2056
    case 6: /* fmovem */ 
2057
    case 7:
2058
        {
2059
        int addr;
2060
        uint16_t mask;
2061
        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2062
            goto undef;
2063
        src = gen_lea(s, insn, OS_LONG);
2064
        addr = gen_new_qreg(QMODE_I32);
2065
        gen_op_mov32(addr, src);
2066
        mask = 0x80;
2067
        dest = QREG_F0;
2068
        while (mask) {
2069
            if (ext & mask) {
2070
                if (ext & (1 << 13)) {
2071
                    /* store */
2072
                    gen_st(s, f64, addr, dest);
2073
                } else {
2074
                    /* load */
2075
                    gen_ld(s, f64, dest, addr);
2076
                }
2077
                if (ext & (mask - 1))
2078
                    gen_op_add32(addr, addr, gen_im32(8));
2079
            }
2080
            mask >>= 1;
2081
            dest++;
2082
        }
2083
        }
2084
        return;
2085
    }
2086
    if (ext & (1 << 14)) {
2087
        int tmp;
2088

    
2089
        /* Source effective address.  */
2090
        switch ((ext >> 10) & 7) {
2091
        case 0: opsize = OS_LONG; break;
2092
        case 1: opsize = OS_SINGLE; break;
2093
        case 4: opsize = OS_WORD; break;
2094
        case 5: opsize = OS_DOUBLE; break;
2095
        case 6: opsize = OS_BYTE; break;
2096
        default:
2097
            goto undef;
2098
        }
2099
        tmp = gen_ea(s, insn, opsize, -1, NULL);
2100
        if (opsize == OS_DOUBLE) {
2101
            src = tmp;
2102
        } else {
2103
            src = gen_new_qreg(QMODE_F64);
2104
            switch (opsize) {
2105
            case OS_LONG:
2106
            case OS_WORD:
2107
            case OS_BYTE:
2108
                gen_op_i32_to_f64(src, tmp);
2109
                break;
2110
            case OS_SINGLE:
2111
                gen_op_f32_to_f64(src, tmp);
2112
                break;
2113
            }
2114
        }
2115
    } else {
2116
        /* Source register.  */
2117
        src = FREG(ext, 10);
2118
    }
2119
    dest = FREG(ext, 7);
2120
    res = gen_new_qreg(QMODE_F64);
2121
    if (opmode != 0x3a)
2122
        gen_op_movf64(res, dest);
2123
    round = 1;
2124
    switch (opmode) {
2125
    case 0: case 0x40: case 0x44: /* fmove */
2126
        gen_op_movf64(res, src);
2127
        break;
2128
    case 1: /* fint */
2129
        gen_op_iround_f64(res, src);
2130
        round = 0;
2131
        break;
2132
    case 3: /* fintrz */
2133
        gen_op_itrunc_f64(res, src);
2134
        round = 0;
2135
        break;
2136
    case 4: case 0x41: case 0x45: /* fsqrt */
2137
        gen_op_sqrtf64(res, src);
2138
        break;
2139
    case 0x18: case 0x58: case 0x5c: /* fabs */
2140
        gen_op_absf64(res, src);
2141
        break;
2142
    case 0x1a: case 0x5a: case 0x5e: /* fneg */
2143
        gen_op_chsf64(res, src);
2144
        break;
2145
    case 0x20: case 0x60: case 0x64: /* fdiv */
2146
        gen_op_divf64(res, res, src);
2147
        break;
2148
    case 0x22: case 0x62: case 0x66: /* fadd */
2149
        gen_op_addf64(res, res, src);
2150
        break;
2151
    case 0x23: case 0x63: case 0x67: /* fmul */
2152
        gen_op_mulf64(res, res, src);
2153
        break;
2154
    case 0x28: case 0x68: case 0x6c: /* fsub */
2155
        gen_op_subf64(res, res, src);
2156
        break;
2157
    case 0x38: /* fcmp */
2158
        gen_op_sub_cmpf64(res, res, src);
2159
        dest = 0;
2160
        round = 0;
2161
        break;
2162
    case 0x3a: /* ftst */
2163
        gen_op_movf64(res, src);
2164
        dest = 0;
2165
        round = 0;
2166
        break;
2167
    default:
2168
        goto undef;
2169
    }
2170
    if (round) {
2171
        if (opmode & 0x40) {
2172
            if ((opmode & 0x4) != 0)
2173
                round = 0;
2174
        } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2175
            round = 0;
2176
        }
2177
    }
2178
    if (round) {
2179
        int tmp;
2180

    
2181
        tmp = gen_new_qreg(QMODE_F32);
2182
        gen_op_f64_to_f32(tmp, res);
2183
        gen_op_f32_to_f64(res, tmp);
2184
    } 
2185
    gen_op_fp_result(res);
2186
    if (dest) {
2187
        gen_op_movf64(dest, res);
2188
    }
2189
    return;
2190
undef:
2191
    s->pc -= 2;
2192
    disas_undef_fpu(s, insn);
2193
}
2194

    
2195
DISAS_INSN(fbcc)
2196
{
2197
    uint32_t offset;
2198
    uint32_t addr;
2199
    int flag;
2200
    int zero;
2201
    int l1;
2202

    
2203
    addr = s->pc;
2204
    offset = ldsw_code(s->pc);
2205
    s->pc += 2;
2206
    if (insn & (1 << 6)) {
2207
        offset = (offset << 16) | lduw_code(s->pc);
2208
        s->pc += 2;
2209
    }
2210

    
2211
    l1 = gen_new_label();
2212
    /* TODO: Raise BSUN exception.  */
2213
    flag = gen_new_qreg(QMODE_I32);
2214
    zero = gen_new_qreg(QMODE_F64);
2215
    gen_op_zerof64(zero);
2216
    gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2217
    /* Jump to l1 if condition is true.  */
2218
    switch (insn & 0xf) {
2219
    case 0: /* f */
2220
        break;
2221
    case 1: /* eq (=0) */
2222
        gen_op_jmp_z32(flag, l1);
2223
        break;
2224
    case 2: /* ogt (=1) */
2225
        gen_op_sub32(flag, flag, gen_im32(1));
2226
        gen_op_jmp_z32(flag, l1);
2227
        break;
2228
    case 3: /* oge (=0 or =1) */
2229
        gen_op_jmp_z32(flag, l1);
2230
        gen_op_sub32(flag, flag, gen_im32(1));
2231
        gen_op_jmp_z32(flag, l1);
2232
        break;
2233
    case 4: /* olt (=-1) */
2234
        gen_op_jmp_s32(flag, l1);
2235
        break;
2236
    case 5: /* ole (=-1 or =0) */
2237
        gen_op_jmp_s32(flag, l1);
2238
        gen_op_jmp_z32(flag, l1);
2239
        break;
2240
    case 6: /* ogl (=-1 or =1) */
2241
        gen_op_jmp_s32(flag, l1);
2242
        gen_op_sub32(flag, flag, gen_im32(1));
2243
        gen_op_jmp_z32(flag, l1);
2244
        break;
2245
    case 7: /* or (=2) */
2246
        gen_op_sub32(flag, flag, gen_im32(2));
2247
        gen_op_jmp_z32(flag, l1);
2248
        break;
2249
    case 8: /* un (<2) */
2250
        gen_op_sub32(flag, flag, gen_im32(2));
2251
        gen_op_jmp_s32(flag, l1);
2252
        break;
2253
    case 9: /* ueq (=0 or =2) */
2254
        gen_op_jmp_z32(flag, l1);
2255
        gen_op_sub32(flag, flag, gen_im32(2));
2256
        gen_op_jmp_z32(flag, l1);
2257
        break;
2258
    case 10: /* ugt (>0) */
2259
        /* ??? Add jmp_gtu.  */
2260
        gen_op_sub32(flag, flag, gen_im32(1));
2261
        gen_op_jmp_ns32(flag, l1);
2262
        break;
2263
    case 11: /* uge (>=0) */
2264
        gen_op_jmp_ns32(flag, l1);
2265
        break;
2266
    case 12: /* ult (=-1 or =2) */
2267
        gen_op_jmp_s32(flag, l1);
2268
        gen_op_sub32(flag, flag, gen_im32(2));
2269
        gen_op_jmp_z32(flag, l1);
2270
        break;
2271
    case 13: /* ule (!=1) */
2272
        gen_op_sub32(flag, flag, gen_im32(1));
2273
        gen_op_jmp_nz32(flag, l1);
2274
        break;
2275
    case 14: /* ne (!=0) */
2276
        gen_op_jmp_nz32(flag, l1);
2277
        break;
2278
    case 15: /* t */
2279
        gen_op_mov32(flag, gen_im32(1));
2280
        break;
2281
    }
2282
    gen_jmp_tb(s, 0, s->pc);
2283
    gen_set_label(l1);
2284
    gen_jmp_tb(s, 1, addr + offset);
2285
}
2286

    
2287
DISAS_INSN(frestore)
2288
{
2289
    /* TODO: Implement frestore.  */
2290
    qemu_assert(0, "FRESTORE not implemented");
2291
}
2292

    
2293
DISAS_INSN(fsave)
2294
{
2295
    /* TODO: Implement fsave.  */
2296
    qemu_assert(0, "FSAVE not implemented");
2297
}
2298

    
2299
static disas_proc opcode_table[65536];
2300

    
2301
static void
2302
register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2303
{
2304
  int i;
2305
  int from;
2306
  int to;
2307

    
2308
  /* Sanity check.  All set bits must be included in the mask.  */
2309
  if (opcode & ~mask)
2310
      abort();
2311
  /* This could probably be cleverer.  For now just optimize the case where
2312
     the top bits are known.  */
2313
  /* Find the first zero bit in the mask.  */
2314
  i = 0x8000;
2315
  while ((i & mask) != 0)
2316
      i >>= 1;
2317
  /* Iterate over all combinations of this and lower bits.  */
2318
  if (i == 0)
2319
      i = 1;
2320
  else
2321
      i <<= 1;
2322
  from = opcode & ~(i - 1);
2323
  to = from + i;
2324
  for (i = from; i < to; i++) {
2325
      if ((i & mask) == opcode)
2326
          opcode_table[i] = proc;
2327
  }
2328
}
2329

    
2330
/* Register m68k opcode handlers.  Order is important.
2331
   Later insn override earlier ones.  */
2332
void register_m68k_insns (CPUM68KState *env)
2333
{
2334
#define INSN(name, opcode, mask, feature) \
2335
    if (m68k_feature(env, M68K_FEATURE_##feature)) \
2336
        register_opcode(disas_##name, 0x##opcode, 0x##mask)
2337
    INSN(undef,     0000, 0000, CF_ISA_A);
2338
    INSN(arith_im,  0080, fff8, CF_ISA_A);
2339
    INSN(bitrev,    00c0, fff8, CF_ISA_C);
2340
    INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2341
    INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2342
    INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2343
    INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2344
    INSN(arith_im,  0280, fff8, CF_ISA_A);
2345
    INSN(byterev,   02c0, fff8, CF_ISA_A);
2346
    INSN(arith_im,  0480, fff8, CF_ISA_A);
2347
    INSN(ff1,       04c0, fff8, CF_ISA_C);
2348
    INSN(arith_im,  0680, fff8, CF_ISA_A);
2349
    INSN(bitop_im,  0800, ffc0, CF_ISA_A);
2350
    INSN(bitop_im,  0840, ffc0, CF_ISA_A);
2351
    INSN(bitop_im,  0880, ffc0, CF_ISA_A);
2352
    INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
2353
    INSN(arith_im,  0a80, fff8, CF_ISA_A);
2354
    INSN(arith_im,  0c00, ff38, CF_ISA_A);
2355
    INSN(move,      1000, f000, CF_ISA_A);
2356
    INSN(move,      2000, f000, CF_ISA_A);
2357
    INSN(move,      3000, f000, CF_ISA_A);
2358
    INSN(strldsr,   40e7, ffff, CF_ISA_A);
2359
    INSN(negx,      4080, fff8, CF_ISA_A);
2360
    INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2361
    INSN(lea,       41c0, f1c0, CF_ISA_A);
2362
    INSN(clr,       4200, ff00, CF_ISA_A);
2363
    INSN(undef,     42c0, ffc0, CF_ISA_A);
2364
    INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2365
    INSN(neg,       4480, fff8, CF_ISA_A);
2366
    INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2367
    INSN(not,       4680, fff8, CF_ISA_A);
2368
    INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2369
    INSN(pea,       4840, ffc0, CF_ISA_A);
2370
    INSN(swap,      4840, fff8, CF_ISA_A);
2371
    INSN(movem,     48c0, fbc0, CF_ISA_A);
2372
    INSN(ext,       4880, fff8, CF_ISA_A);
2373
    INSN(ext,       48c0, fff8, CF_ISA_A);
2374
    INSN(ext,       49c0, fff8, CF_ISA_A);
2375
    INSN(tst,       4a00, ff00, CF_ISA_A);
2376
    INSN(tas,       4ac0, ffc0, CF_ISA_B);
2377
    INSN(halt,      4ac8, ffff, CF_ISA_A);
2378
    INSN(pulse,     4acc, ffff, CF_ISA_A);
2379
    INSN(illegal,   4afc, ffff, CF_ISA_A);
2380
    INSN(mull,      4c00, ffc0, CF_ISA_A);
2381
    INSN(divl,      4c40, ffc0, CF_ISA_A);
2382
    INSN(sats,      4c80, fff8, CF_ISA_B);
2383
    INSN(trap,      4e40, fff0, CF_ISA_A);
2384
    INSN(link,      4e50, fff8, CF_ISA_A);
2385
    INSN(unlk,      4e58, fff8, CF_ISA_A);
2386
    INSN(move_to_usp, 4e60, fff8, CF_ISA_B);
2387
    INSN(move_from_usp, 4e68, fff8, CF_ISA_B);
2388
    INSN(nop,       4e71, ffff, CF_ISA_A);
2389
    INSN(stop,      4e72, ffff, CF_ISA_A);
2390
    INSN(rte,       4e73, ffff, CF_ISA_A);
2391
    INSN(rts,       4e75, ffff, CF_ISA_A);
2392
    INSN(movec,     4e7b, ffff, CF_ISA_A);
2393
    INSN(jump,      4e80, ffc0, CF_ISA_A);
2394
    INSN(jump,      4ec0, ffc0, CF_ISA_A);
2395
    INSN(addsubq,   5180, f1c0, CF_ISA_A);
2396
    INSN(scc,       50c0, f0f8, CF_ISA_A);
2397
    INSN(addsubq,   5080, f1c0, CF_ISA_A);
2398
    INSN(tpf,       51f8, fff8, CF_ISA_A);
2399
    INSN(branch,    6000, f000, CF_ISA_A);
2400
    INSN(moveq,     7000, f100, CF_ISA_A);
2401
    INSN(mvzs,      7100, f100, CF_ISA_B);
2402
    INSN(or,        8000, f000, CF_ISA_A);
2403
    INSN(divw,      80c0, f0c0, CF_ISA_A);
2404
    INSN(addsub,    9000, f000, CF_ISA_A);
2405
    INSN(subx,      9180, f1f8, CF_ISA_A);
2406
    INSN(suba,      91c0, f1c0, CF_ISA_A);
2407
    INSN(undef_mac, a000, f000, CF_ISA_A);
2408
    INSN(mov3q,     a140, f1c0, CF_ISA_B);
2409
    INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
2410
    INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
2411
    INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2412
    INSN(cmp,       b080, f1c0, CF_ISA_A);
2413
    INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
2414
    INSN(eor,       b180, f1c0, CF_ISA_A);
2415
    INSN(and,       c000, f000, CF_ISA_A);
2416
    INSN(mulw,      c0c0, f0c0, CF_ISA_A);
2417
    INSN(addsub,    d000, f000, CF_ISA_A);
2418
    INSN(addx,      d180, f1f8, CF_ISA_A);
2419
    INSN(adda,      d1c0, f1c0, CF_ISA_A);
2420
    INSN(shift_im,  e080, f0f0, CF_ISA_A);
2421
    INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2422
    INSN(undef_fpu, f000, f000, CF_ISA_A);
2423
    INSN(fpu,       f200, ffc0, CF_FPU);
2424
    INSN(fbcc,      f280, ffc0, CF_FPU);
2425
    INSN(frestore,  f340, ffc0, CF_FPU);
2426
    INSN(fsave,     f340, ffc0, CF_FPU);
2427
    INSN(intouch,   f340, ffc0, CF_ISA_A);
2428
    INSN(cpushl,    f428, ff38, CF_ISA_A);
2429
    INSN(wddata,    fb00, ff00, CF_ISA_A);
2430
    INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
2431
#undef INSN
2432
}
2433

    
2434
/* ??? Some of this implementation is not exception safe.  We should always
2435
   write back the result to memory before setting the condition codes.  */
2436
static void disas_m68k_insn(CPUState * env, DisasContext *s)
2437
{
2438
    uint16_t insn;
2439

    
2440
    insn = lduw_code(s->pc);
2441
    s->pc += 2;
2442

    
2443
    opcode_table[insn](s, insn);
2444
}
2445

    
2446
#if 0
2447
/* Save the result of a floating point operation.  */
2448
static void expand_op_fp_result(qOP *qop)
2449
{
2450
    gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2451
}
2452

2453
/* Dummy op to indicate that the flags have been set.  */
2454
static void expand_op_flags_set(qOP *qop)
2455
{
2456
}
2457

2458
/* Convert the confition codes into CC_OP_FLAGS format.  */
2459
static void expand_op_flush_flags(qOP *qop)
2460
{
2461
    int cc_opreg;
2462

2463
    if (qop->args[0] == CC_OP_DYNAMIC)
2464
        cc_opreg = QREG_CC_OP;
2465
    else
2466
        cc_opreg = gen_im32(qop->args[0]);
2467
    gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2468
}
2469

2470
/* Set CC_DEST after a logical or direct flag setting operation.  */
2471
static void expand_op_logic_cc(qOP *qop)
2472
{
2473
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2474
}
2475

2476
/* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2477
static void expand_op_update_cc_add(qOP *qop)
2478
{
2479
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2480
    gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2481
}
2482

2483
/* Update the X flag.  */
2484
static void expand_op_update_xflag(qOP *qop)
2485
{
2486
    int arg0;
2487
    int arg1;
2488

2489
    arg0 = qop->args[0];
2490
    arg1 = qop->args[1];
2491
    if (arg1 == QREG_NULL) {
2492
        /* CC_X = arg0.  */
2493
        gen_op_mov32(QREG_CC_X, arg0);
2494
    } else {
2495
        /* CC_X = arg0 < (unsigned)arg1.  */
2496
        gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2497
    }
2498
}
2499

2500
/* Set arg0 to the contents of the X flag.  */
2501
static void expand_op_get_xflag(qOP *qop)
2502
{
2503
    gen_op_mov32(qop->args[0], QREG_CC_X);
2504
}
2505

2506
/* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2507
   already know the shift is within range.  */
2508
static inline void expand_shift_im(qOP *qop, int right, int arith)
2509
{
2510
    int val;
2511
    int reg;
2512
    int tmp;
2513
    int im;
2514

2515
    reg = qop->args[0];
2516
    im = qop->args[1];
2517
    tmp = gen_im32(im);
2518
    val = gen_new_qreg(QMODE_I32);
2519
    gen_op_mov32(val, reg);
2520
    gen_op_mov32(QREG_CC_DEST, val);
2521
    gen_op_mov32(QREG_CC_SRC, tmp);
2522
    if (right) {
2523
        if (arith) {
2524
            gen_op_sar32(reg, val, tmp);
2525
        } else {
2526
            gen_op_shr32(reg, val, tmp);
2527
        }
2528
        if (im == 1)
2529
            tmp = QREG_NULL;
2530
        else
2531
            tmp = gen_im32(im - 1);
2532
    } else {
2533
        gen_op_shl32(reg, val, tmp);
2534
        tmp = gen_im32(32 - im);
2535
    }
2536
    if (tmp != QREG_NULL)
2537
        gen_op_shr32(val, val, tmp);
2538
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2539
}
2540

2541
static void expand_op_shl_im_cc(qOP *qop)
2542
{
2543
    expand_shift_im(qop, 0, 0);
2544
}
2545

2546
static void expand_op_shr_im_cc(qOP *qop)
2547
{
2548
    expand_shift_im(qop, 1, 0);
2549
}
2550

2551
static void expand_op_sar_im_cc(qOP *qop)
2552
{
2553
    expand_shift_im(qop, 1, 1);
2554
}
2555

2556
/* Expand a shift by register.  */
2557
/* ??? This gives incorrect answers for shifts by 0 or >= 32 */
2558
static inline void expand_shift_reg(qOP *qop, int right, int arith)
2559
{
2560
    int val;
2561
    int reg;
2562
    int shift;
2563
    int tmp;
2564

2565
    reg = qop->args[0];
2566
    shift = qop->args[1];
2567
    val = gen_new_qreg(QMODE_I32);
2568
    gen_op_mov32(val, reg);
2569
    gen_op_mov32(QREG_CC_DEST, val);
2570
    gen_op_mov32(QREG_CC_SRC, shift);
2571
    tmp = gen_new_qreg(QMODE_I32);
2572
    if (right) {
2573
        if (arith) {
2574
            gen_op_sar32(reg, val, shift);
2575
        } else {
2576
            gen_op_shr32(reg, val, shift);
2577
        }
2578
        gen_op_sub32(tmp, shift, gen_im32(1));
2579
    } else {
2580
        gen_op_shl32(reg, val, shift);
2581
        gen_op_sub32(tmp, gen_im32(31), shift);
2582
    }
2583
    gen_op_shl32(val, val, tmp);
2584
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2585
}
2586

2587
static void expand_op_shl_cc(qOP *qop)
2588
{
2589
    expand_shift_reg(qop, 0, 0);
2590
}
2591

2592
static void expand_op_shr_cc(qOP *qop)
2593
{
2594
    expand_shift_reg(qop, 1, 0);
2595
}
2596

2597
static void expand_op_sar_cc(qOP *qop)
2598
{
2599
    expand_shift_reg(qop, 1, 1);
2600
}
2601

2602
/* Set the Z flag to (arg0 & arg1) == 0.  */
2603
static void expand_op_btest(qOP *qop)
2604
{
2605
    int tmp;
2606
    int l1;
2607

2608
    l1 = gen_new_label();
2609
    tmp = gen_new_qreg(QMODE_I32);
2610
    gen_op_and32(tmp, qop->args[0], qop->args[1]);
2611
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
2612
    gen_op_jmp_nz32(tmp, l1);
2613
    gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
2614
    gen_op_label(l1);
2615
}
2616

2617
/* arg0 += arg1 + CC_X */
2618
static void expand_op_addx_cc(qOP *qop)
2619
{
2620
    int arg0 = qop->args[0];
2621
    int arg1 = qop->args[1];
2622
    int l1, l2;
2623
    
2624
    gen_op_add32 (arg0, arg0, arg1);
2625
    l1 = gen_new_label();
2626
    l2 = gen_new_label();
2627
    gen_op_jmp_z32(QREG_CC_X, l1);
2628
    gen_op_add32(arg0, arg0, gen_im32(1));
2629
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
2630
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2631
    gen_op_jmp(l2);
2632
    gen_set_label(l1);
2633
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
2634
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2635
    gen_set_label(l2);
2636
}
2637

2638
/* arg0 -= arg1 + CC_X */
2639
static void expand_op_subx_cc(qOP *qop)
2640
{
2641
    int arg0 = qop->args[0];
2642
    int arg1 = qop->args[1];
2643
    int l1, l2;
2644

2645
    l1 = gen_new_label();
2646
    l2 = gen_new_label();
2647
    gen_op_jmp_z32(QREG_CC_X, l1);
2648
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2649
    gen_op_sub32(arg0, arg0, gen_im32(1));
2650
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
2651
    gen_op_jmp(l2);
2652
    gen_set_label(l1);
2653
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2654
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
2655
    gen_set_label(l2);
2656
    gen_op_sub32 (arg0, arg0, arg1);
2657
}
2658

2659
/* Expand target specific ops to generic qops.  */
2660
static void expand_target_qops(void)
2661
{
2662
    qOP *qop;
2663
    qOP *next;
2664
    int c;
2665

2666
    /* Copy the list of qops, expanding target specific ops as we go.  */
2667
    qop = gen_first_qop;
2668
    gen_first_qop = NULL;
2669
    gen_last_qop = NULL;
2670
    for (; qop; qop = next) {
2671
        c = qop->opcode;
2672
        next = qop->next;
2673
        if (c < FIRST_TARGET_OP) {
2674
            qop->prev = gen_last_qop;
2675
            qop->next = NULL;
2676
            if (gen_last_qop)
2677
                gen_last_qop->next = qop;
2678
            else
2679
                gen_first_qop = qop;
2680
            gen_last_qop = qop;
2681
            continue;
2682
        }
2683
        switch (c) {
2684
#define DEF(name, nargs, barrier) \
2685
        case INDEX_op_##name: \
2686
            expand_op_##name(qop); \
2687
            break;
2688
#include "qop-target.def"
2689
#undef DEF
2690
        default:
2691
            cpu_abort(NULL, "Unexpanded target qop");
2692
        }
2693
    }
2694
}
2695

2696
/* ??? Implement this.  */
2697
static void
2698
optimize_flags(void)
2699
{
2700
}
2701
#endif
2702

    
2703
/* generate intermediate code for basic block 'tb'.  */
2704
static inline int
2705
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2706
                               int search_pc)
2707
{
2708
    DisasContext dc1, *dc = &dc1;
2709
    uint16_t *gen_opc_end;
2710
    int j, lj;
2711
    target_ulong pc_start;
2712
    int pc_offset;
2713
    int last_cc_op;
2714

    
2715
    /* generate intermediate code */
2716
    pc_start = tb->pc;
2717
       
2718
    dc->tb = tb;
2719

    
2720
    gen_opc_ptr = gen_opc_buf;
2721
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2722
    gen_opparam_ptr = gen_opparam_buf;
2723

    
2724
    dc->is_jmp = DISAS_NEXT;
2725
    dc->pc = pc_start;
2726
    dc->cc_op = CC_OP_DYNAMIC;
2727
    dc->singlestep_enabled = env->singlestep_enabled;
2728
    dc->fpcr = env->fpcr;
2729
    dc->user = (env->sr & SR_S) == 0;
2730
    nb_gen_labels = 0;
2731
    lj = -1;
2732
    do {
2733
        free_qreg = 0;
2734
        pc_offset = dc->pc - pc_start;
2735
        gen_throws_exception = NULL;
2736
        if (env->nb_breakpoints > 0) {
2737
            for(j = 0; j < env->nb_breakpoints; j++) {
2738
                if (env->breakpoints[j] == dc->pc) {
2739
                    gen_exception(dc, dc->pc, EXCP_DEBUG);
2740
                    dc->is_jmp = DISAS_JUMP;
2741
                    break;
2742
                }
2743
            }
2744
            if (dc->is_jmp)
2745
                break;
2746
        }
2747
        if (search_pc) {
2748
            j = gen_opc_ptr - gen_opc_buf;
2749
            if (lj < j) {
2750
                lj++;
2751
                while (lj < j)
2752
                    gen_opc_instr_start[lj++] = 0;
2753
            }
2754
            gen_opc_pc[lj] = dc->pc;
2755
            gen_opc_instr_start[lj] = 1;
2756
        }
2757
        last_cc_op = dc->cc_op;
2758
        disas_m68k_insn(env, dc);
2759
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
2760
             !env->singlestep_enabled &&
2761
             (pc_offset) < (TARGET_PAGE_SIZE - 32));
2762

    
2763
    if (__builtin_expect(env->singlestep_enabled, 0)) {
2764
        /* Make sure the pc is updated, and raise a debug exception.  */
2765
        if (!dc->is_jmp) {
2766
            gen_flush_cc_op(dc);
2767
            gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
2768
        }
2769
        gen_op_raise_exception(EXCP_DEBUG);
2770
    } else {
2771
        switch(dc->is_jmp) {
2772
        case DISAS_NEXT:
2773
            gen_flush_cc_op(dc);
2774
            gen_jmp_tb(dc, 0, dc->pc);
2775
            break;
2776
        default:
2777
        case DISAS_JUMP:
2778
        case DISAS_UPDATE:
2779
            gen_flush_cc_op(dc);
2780
            /* indicate that the hash table must be used to find the next TB */
2781
            gen_op_mov32(QREG_T0, gen_im32(0));
2782
            gen_op_exit_tb();
2783
            break;
2784
        case DISAS_TB_JUMP:
2785
            /* nothing more to generate */
2786
            break;
2787
        }
2788
    }
2789
    *gen_opc_ptr = INDEX_op_end;
2790

    
2791
#ifdef DEBUG_DISAS
2792
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2793
        fprintf(logfile, "----------------\n");
2794
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2795
        target_disas(logfile, pc_start, dc->pc - pc_start, 0);
2796
        fprintf(logfile, "\n");
2797
        if (loglevel & (CPU_LOG_TB_OP)) {
2798
            fprintf(logfile, "OP:\n");
2799
            dump_ops(gen_opc_buf, gen_opparam_buf);
2800
            fprintf(logfile, "\n");
2801
        }
2802
    }
2803
#endif
2804
    if (search_pc) {
2805
        j = gen_opc_ptr - gen_opc_buf;
2806
        lj++;
2807
        while (lj <= j)
2808
            gen_opc_instr_start[lj++] = 0;
2809
        tb->size = 0;
2810
    } else {
2811
        tb->size = dc->pc - pc_start;
2812
    }
2813

    
2814
    //optimize_flags();
2815
    //expand_target_qops();
2816
    return 0;
2817
}
2818

    
2819
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2820
{
2821
    return gen_intermediate_code_internal(env, tb, 0);
2822
}
2823

    
2824
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2825
{
2826
    return gen_intermediate_code_internal(env, tb, 1);
2827
}
2828

    
2829
void cpu_reset(CPUM68KState *env)
2830
{
2831
    memset(env, 0, offsetof(CPUM68KState, breakpoints));
2832
#if !defined (CONFIG_USER_ONLY)
2833
    env->sr = 0x2700;
2834
#endif
2835
    /* ??? FP regs should be initialized to NaN.  */
2836
    env->cc_op = CC_OP_FLAGS;
2837
    /* TODO: We should set PC from the interrupt vector.  */
2838
    env->pc = 0;
2839
    tlb_flush(env, 1);
2840
}
2841

    
2842
CPUM68KState *cpu_m68k_init(void)
2843
{
2844
    CPUM68KState *env;
2845

    
2846
    env = malloc(sizeof(CPUM68KState));
2847
    if (!env)
2848
        return NULL;
2849
    cpu_exec_init(env);
2850

    
2851
    cpu_reset(env);
2852
    return env;
2853
}
2854

    
2855
void cpu_m68k_close(CPUM68KState *env)
2856
{
2857
    free(env);
2858
}
2859

    
2860
void cpu_dump_state(CPUState *env, FILE *f, 
2861
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2862
                    int flags)
2863
{
2864
    int i;
2865
    uint16_t sr;
2866
    CPU_DoubleU u;
2867
    for (i = 0; i < 8; i++)
2868
      {
2869
        u.d = env->fregs[i];
2870
        cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
2871
                     i, env->dregs[i], i, env->aregs[i],
2872
                     i, u.l.upper, u.l.lower, u.d);
2873
      }
2874
    cpu_fprintf (f, "PC = %08x   ", env->pc);
2875
    sr = env->sr;
2876
    cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
2877
                 (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
2878
                 (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
2879
    cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
2880
}
2881