Statistics
| Branch: | Revision:

root / target-m68k / translate.c @ 820e00f2

History | View | Annotate | Download (66.4 kB)

1
/*
2
 *  m68k translation
3
 * 
4
 *  Copyright (c) 2005-2006 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
static inline void qemu_assert(int cond, const char *msg)
34
{
35
    if (!cond) {
36
        fprintf (stderr, "badness: %s\n", msg);
37
        abort();
38
    }
39
}
40

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

    
51
#define DISAS_JUMP_NEXT 4
52

    
53
/* XXX: move that elsewhere */
54
/* ??? Fix exceptions.  */
55
static void *gen_throws_exception;
56
#define gen_last_qop NULL
57

    
58
static uint16_t *gen_opc_ptr;
59
static uint32_t *gen_opparam_ptr;
60
extern FILE *logfile;
61
extern int loglevel;
62

    
63
enum {
64
#define DEF(s, n, copy_size) INDEX_op_ ## s,
65
#include "opc.h"
66
#undef DEF
67
    NB_OPS,
68
};
69

    
70
#include "gen-op.h"
71
#include "op-hacks.h"
72

    
73
#define OS_BYTE 0
74
#define OS_WORD 1
75
#define OS_LONG 2
76
#define OS_SINGLE 4
77
#define OS_DOUBLE 5
78

    
79
#define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
80
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
81
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
82

    
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
typedef void (*disas_proc)(DisasContext *, uint16_t);
103

    
104
#define DISAS_INSN(name) \
105
  static void disas_##name (DisasContext *s, uint16_t insn)
106

    
107
/* Generate a load from the specified address.  Narrow values are
108
   sign extended to full register width.  */
109
static inline int gen_load(int opsize, int addr, int sign)
110
{
111
    int tmp;
112
    switch(opsize) {
113
    case OS_BYTE:
114
        tmp = gen_new_qreg(QMODE_I32);
115
        if (sign)
116
            gen_op_ld8s32(tmp, addr);
117
        else
118
            gen_op_ld8u32(tmp, addr);
119
        break;
120
    case OS_WORD:
121
        tmp = gen_new_qreg(QMODE_I32);
122
        if (sign)
123
            gen_op_ld16s32(tmp, addr);
124
        else
125
            gen_op_ld16u32(tmp, addr);
126
        break;
127
    case OS_LONG:
128
        tmp = gen_new_qreg(QMODE_I32);
129
        gen_op_ld32(tmp, addr);
130
        break;
131
    case OS_SINGLE:
132
        tmp = gen_new_qreg(QMODE_F32);
133
        gen_op_ldf32(tmp, addr);
134
        break;
135
    case OS_DOUBLE:
136
        tmp  = gen_new_qreg(QMODE_F64);
137
        gen_op_ldf64(tmp, addr);
138
        break;
139
    default:
140
        qemu_assert(0, "bad load size");
141
    }
142
    gen_throws_exception = gen_last_qop;
143
    return tmp;
144
}
145

    
146
/* Generate a store.  */
147
static inline void gen_store(int opsize, int addr, int val)
148
{
149
    switch(opsize) {
150
    case OS_BYTE:
151
        gen_op_st8(addr, val);
152
        break;
153
    case OS_WORD:
154
        gen_op_st16(addr, val);
155
        break;
156
    case OS_LONG:
157
        gen_op_st32(addr, val);
158
        break;
159
    case OS_SINGLE:
160
        gen_op_stf32(addr, val);
161
        break;
162
    case OS_DOUBLE:
163
        gen_op_stf64(addr, val);
164
        break;
165
    default:
166
        qemu_assert(0, "bad store size");
167
    }
168
    gen_throws_exception = gen_last_qop;
169
}
170

    
171
/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
172
   otherwise generate a store.  */
173
static int gen_ldst(int opsize, int addr, int val)
174
{
175
    if (val > 0) {
176
        gen_store(opsize, addr, val);
177
        return 0;
178
    } else {
179
        return gen_load(opsize, addr, val != 0);
180
    }
181
}
182

    
183
/* Handle a base + index + displacement effective addresss.  A base of
184
   -1 means pc-relative.  */
185
static int gen_lea_indexed(DisasContext *s, int opsize, int base)
186
{
187
    int scale;
188
    uint32_t offset;
189
    uint16_t ext;
190
    int add;
191
    int tmp;
192

    
193
    offset = s->pc;
194
    ext = lduw(s->pc);
195
    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) {
200
        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

    
226

    
227
/* Update the CPU env CC_OP state.  */
228
static inline void gen_flush_cc_op(DisasContext *s)
229
{
230
    if (s->cc_op != CC_OP_DYNAMIC)
231
        gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
232
}
233

    
234
/* Evaluate all the CC flags.  */
235
static inline void gen_flush_flags(DisasContext *s)
236
{
237
    if (s->cc_op == CC_OP_FLAGS)
238
        return;
239
    gen_op_flush_flags(s->cc_op);
240
    s->cc_op = CC_OP_FLAGS;
241
}
242

    
243
static inline int opsize_bytes(int opsize)
244
{
245
    switch (opsize) {
246
    case OS_BYTE: return 1;
247
    case OS_WORD: return 2;
248
    case OS_LONG: return 4;
249
    case OS_SINGLE: return 4;
250
    case OS_DOUBLE: return 8;
251
    default:
252
        qemu_assert(0, "bad operand size");
253
    }
254
}
255

    
256
/* Assign value to a register.  If the width is less than the register width
257
   only the low part of the register is set.  */
258
static void gen_partset_reg(int opsize, int reg, int val)
259
{
260
    int tmp;
261
    switch (opsize) {
262
    case OS_BYTE:
263
        gen_op_and32(reg, reg, gen_im32(0xffffff00));
264
        tmp = gen_new_qreg(QMODE_I32);
265
        gen_op_and32(tmp, val, gen_im32(0xff));
266
        gen_op_or32(reg, reg, tmp);
267
        break;
268
    case OS_WORD:
269
        gen_op_and32(reg, reg, gen_im32(0xffff0000));
270
        tmp = gen_new_qreg(QMODE_I32);
271
        gen_op_and32(tmp, val, gen_im32(0xffff));
272
        gen_op_or32(reg, reg, tmp);
273
        break;
274
    case OS_LONG:
275
        gen_op_mov32(reg, val);
276
        break;
277
    case OS_SINGLE:
278
        gen_op_pack_32_f32(reg, val);
279
        break;
280
    default:
281
        qemu_assert(0, "Bad operand size");
282
        break;
283
    }
284
}
285

    
286
/* Sign or zero extend a value.  */
287
static inline int gen_extend(int val, int opsize, int sign)
288
{
289
    int tmp;
290

    
291
    switch (opsize) {
292
    case OS_BYTE:
293
        tmp = gen_new_qreg(QMODE_I32);
294
        if (sign)
295
            gen_op_ext8s32(tmp, val);
296
        else
297
            gen_op_ext8u32(tmp, val);
298
        break;
299
    case OS_WORD:
300
        tmp = gen_new_qreg(QMODE_I32);
301
        if (sign)
302
            gen_op_ext16s32(tmp, val);
303
        else
304
            gen_op_ext16u32(tmp, val);
305
        break;
306
    case OS_LONG:
307
        tmp = val;
308
        break;
309
    case OS_SINGLE:
310
        tmp = gen_new_qreg(QMODE_F32);
311
        gen_op_pack_f32_32(tmp, val);
312
        break;
313
    default:
314
        qemu_assert(0, "Bad operand size");
315
    }
316
    return tmp;
317
}
318

    
319
/* Generate code for an "effective address".  Does not adjust the base
320
   register for autoincrememnt addressing modes.  */
321
static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
322
{
323
    int reg;
324
    int tmp;
325
    uint16_t ext;
326
    uint32_t offset;
327

    
328
    reg = insn & 7;
329
    switch ((insn >> 3) & 7) {
330
    case 0: /* Data register direct.  */
331
    case 1: /* Address register direct.  */
332
        /* ??? generate bad addressing mode fault.  */
333
        qemu_assert(0, "invalid addressing mode");
334
    case 2: /* Indirect register */
335
    case 3: /* Indirect postincrement.  */
336
        reg += QREG_A0;
337
        return reg;
338
    case 4: /* Indirect predecrememnt.  */
339
        reg += QREG_A0;
340
        tmp = gen_new_qreg(QMODE_I32);
341
        gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
342
        return tmp;
343
    case 5: /* Indirect displacement.  */
344
        reg += QREG_A0;
345
        tmp = gen_new_qreg(QMODE_I32);
346
        ext = lduw(s->pc);
347
        s->pc += 2;
348
        gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
349
        return tmp;
350
    case 6: /* Indirect index + displacement.  */
351
        reg += QREG_A0;
352
        return gen_lea_indexed(s, opsize, reg);
353
    case 7: /* Other */
354
        switch (reg) {
355
        case 0: /* Absolute short.  */
356
            offset = ldsw(s->pc);
357
            s->pc += 2;
358
            return gen_im32(offset);
359
        case 1: /* Absolute long.  */
360
            offset = read_im32(s);
361
            return gen_im32(offset);
362
        case 2: /* pc displacement  */
363
            tmp = gen_new_qreg(QMODE_I32);
364
            offset = s->pc;
365
            offset += ldsw(s->pc);
366
            s->pc += 2;
367
            return gen_im32(offset);
368
        case 3: /* pc index+displacement.  */
369
            return gen_lea_indexed(s, opsize, -1);
370
        case 4: /* Immediate.  */
371
        default:
372
            /* ??? generate bad addressing mode fault.  */
373
            qemu_assert(0, "invalid addressing mode");
374
        }
375
    }
376
    /* Should never happen.  */
377
    return -1;
378
}
379

    
380
/* Helper function for gen_ea. Reuse the computed address between the
381
   for read/write operands.  */
382
static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
383
                              int val, int *addrp)
384
{
385
    int tmp;
386

    
387
    if (addrp && val > 0) {
388
        tmp = *addrp;
389
    } else {
390
        tmp = gen_lea(s, insn, opsize);
391
        if (addrp)
392
            *addrp = tmp;
393
    }
394
    return gen_ldst(opsize, tmp, val);
395
}
396

    
397
/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
398
   a write otherwise it is a read (0 == sign extend, -1 == zero extend).
399
   ADDRP is non-null for readwrite operands.  */
400
static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
401
                  int *addrp)
402
{
403
    int reg;
404
    int result;
405
    uint32_t offset;
406

    
407
    reg = insn & 7;
408
    switch ((insn >> 3) & 7) {
409
    case 0: /* Data register direct.  */
410
        reg += QREG_D0;
411
        if (val > 0) {
412
            gen_partset_reg(opsize, reg, val);
413
            return 0;
414
        } else {
415
            return gen_extend(reg, opsize, val);
416
        }
417
    case 1: /* Address register direct.  */
418
        reg += QREG_A0;
419
        if (val > 0) {
420
            gen_op_mov32(reg, val);
421
            return 0;
422
        } else {
423
            return gen_extend(reg, opsize, val);
424
        }
425
    case 2: /* Indirect register */
426
        reg += QREG_A0;
427
        return gen_ldst(opsize, reg, val);
428
    case 3: /* Indirect postincrement.  */
429
        reg += QREG_A0;
430
        result = gen_ldst(opsize, reg, val);
431
        /* ??? This is not exception safe.  The instruction may still
432
           fault after this point.  */
433
        if (val > 0 || !addrp)
434
            gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
435
        return result;
436
    case 4: /* Indirect predecrememnt.  */
437
        {
438
            int tmp;
439
            if (addrp && val > 0) {
440
                tmp = *addrp;
441
            } else {
442
                tmp = gen_lea(s, insn, opsize);
443
                if (addrp)
444
                    *addrp = tmp;
445
            }
446
            result = gen_ldst(opsize, tmp, val);
447
            /* ??? This is not exception safe.  The instruction may still
448
               fault after this point.  */
449
            if (val > 0 || !addrp) {
450
                reg += QREG_A0;
451
                gen_op_mov32(reg, tmp);
452
            }
453
        }
454
        return result;
455
    case 5: /* Indirect displacement.  */
456
    case 6: /* Indirect index + displacement.  */
457
        return gen_ea_once(s, insn, opsize, val, addrp);
458
    case 7: /* Other */
459
        switch (reg) {
460
        case 0: /* Absolute short.  */
461
        case 1: /* Absolute long.  */
462
        case 2: /* pc displacement  */
463
        case 3: /* pc index+displacement.  */
464
            return gen_ea_once(s, insn, opsize, val, addrp);
465
        case 4: /* Immediate.  */
466
            /* Sign extend values for consistency.  */
467
            switch (opsize) {
468
            case OS_BYTE:
469
                if (val)
470
                    offset = ldsb(s->pc + 1);
471
                else
472
                    offset = ldub(s->pc + 1);
473
                s->pc += 2;
474
                break;
475
            case OS_WORD:
476
                if (val)
477
                    offset = ldsw(s->pc);
478
                else
479
                    offset = lduw(s->pc);
480
                s->pc += 2;
481
                break;
482
            case OS_LONG:
483
                offset = read_im32(s);
484
                break;
485
            default:
486
                qemu_assert(0, "Bad immediate operand");
487
            }
488
            return gen_im32(offset);
489
        default:
490
            qemu_assert(0, "invalid addressing mode");
491
        }
492
    }
493
    /* Should never happen.  */
494
    return -1;
495
}
496

    
497
static void gen_logic_cc(DisasContext *s, int val)
498
{
499
    gen_op_logic_cc(val);
500
    s->cc_op = CC_OP_LOGIC;
501
}
502

    
503
static void gen_jmpcc(DisasContext *s, int cond, int l1)
504
{
505
    int tmp;
506

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

    
610
DISAS_INSN(scc)
611
{
612
    int l1;
613
    int cond;
614
    int reg;
615

    
616
    l1 = gen_new_label();
617
    cond = (insn >> 8) & 0xf;
618
    reg = DREG(insn, 0);
619
    gen_op_and32(reg, reg, gen_im32(0xffffff00));
620
    gen_jmpcc(s, cond ^ 1, l1);
621
    gen_op_or32(reg, reg, gen_im32(0xff));
622
    gen_set_label(l1);
623
}
624

    
625
/* Generate a jump to to the address in qreg DEST.  */
626
static void gen_jmp(DisasContext *s, int dest)
627
{
628
    gen_flush_cc_op(s);
629
    gen_op_mov32(QREG_PC, dest);
630
    s->is_jmp = DISAS_JUMP;
631
}
632

    
633
static void gen_exception(DisasContext *s, uint32_t where, int nr)
634
{
635
    gen_flush_cc_op(s);
636
    gen_jmp(s, gen_im32(where));
637
    gen_op_raise_exception(nr);
638
}
639

    
640
/* Generate a jump to an immediate address.  */
641
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
642
{
643
    TranslationBlock *tb;
644

    
645
    tb = s->tb;
646
    if (__builtin_expect (s->singlestep_enabled, 0)) {
647
        gen_exception(s, dest, EXCP_DEBUG);
648
    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
649
               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
650
        gen_op_goto_tb(0, n, (long)tb);
651
        gen_op_mov32(QREG_PC, gen_im32(dest));
652
        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
653
        gen_op_exit_tb();
654
    } else {
655
        gen_jmp(s, gen_im32(dest));
656
        gen_op_mov32(QREG_T0, gen_im32(0));
657
        gen_op_exit_tb();
658
    }
659
    s->is_jmp = DISAS_TB_JUMP;
660
}
661

    
662
DISAS_INSN(undef_mac)
663
{
664
    gen_exception(s, s->pc - 2, EXCP_LINEA);
665
}
666

    
667
DISAS_INSN(undef_fpu)
668
{
669
    gen_exception(s, s->pc - 2, EXCP_LINEF);
670
}
671

    
672
DISAS_INSN(undef)
673
{
674
    gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
675
    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
676
              insn, s->pc - 2);
677
}
678

    
679
DISAS_INSN(mulw)
680
{
681
    int reg;
682
    int tmp;
683
    int src;
684
    int sign;
685

    
686
    sign = (insn & 0x100) != 0;
687
    reg = DREG(insn, 9);
688
    tmp = gen_new_qreg(QMODE_I32);
689
    if (sign)
690
        gen_op_ext16s32(tmp, reg);
691
    else
692
        gen_op_ext16u32(tmp, reg);
693
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
694
    gen_op_mul32(tmp, tmp, src);
695
    gen_op_mov32(reg, tmp);
696
    /* Unlike m68k, coldfire always clears the overflow bit.  */
697
    gen_logic_cc(s, tmp);
698
}
699

    
700
DISAS_INSN(divw)
701
{
702
    int reg;
703
    int tmp;
704
    int src;
705
    int sign;
706

    
707
    sign = (insn & 0x100) != 0;
708
    reg = DREG(insn, 9);
709
    if (sign) {
710
        gen_op_ext16s32(QREG_DIV1, reg);
711
    } else {
712
        gen_op_ext16u32(QREG_DIV1, reg);
713
    }
714
    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
715
    gen_op_mov32(QREG_DIV2, src);
716
    if (sign) {
717
        gen_op_divs(1);
718
    } else {
719
        gen_op_divu(1);
720
    }
721

    
722
    tmp = gen_new_qreg(QMODE_I32);
723
    src = gen_new_qreg(QMODE_I32);
724
    gen_op_ext16u32(tmp, QREG_DIV1);
725
    gen_op_shl32(src, QREG_DIV2, gen_im32(16));
726
    gen_op_or32(reg, tmp, src);
727
    gen_op_flags_set();
728
    s->cc_op = CC_OP_FLAGS;
729
}
730

    
731
DISAS_INSN(divl)
732
{
733
    int num;
734
    int den;
735
    int reg;
736
    uint16_t ext;
737

    
738
    ext = lduw(s->pc);
739
    s->pc += 2;
740
    if (ext & 0x87f8) {
741
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
742
        return;
743
    }
744
    num = DREG(ext, 12);
745
    reg = DREG(ext, 0);
746
    gen_op_mov32(QREG_DIV1, num);
747
    den = gen_ea(s, insn, OS_LONG, 0, NULL);
748
    gen_op_mov32(QREG_DIV2, den);
749
    if (ext & 0x0800) {
750
        gen_op_divs(2);
751
    } else {
752
        gen_op_divu(2);
753
    }
754
    if (num == reg) {
755
        /* div */
756
        gen_op_mov32 (reg, QREG_DIV1);
757
    } else {
758
        /* rem */
759
        gen_op_mov32 (reg, QREG_DIV2);
760
    }
761
    gen_op_flags_set();
762
    s->cc_op = CC_OP_FLAGS;
763
}
764

    
765
DISAS_INSN(addsub)
766
{
767
    int reg;
768
    int dest;
769
    int src;
770
    int tmp;
771
    int addr;
772
    int add;
773

    
774
    add = (insn & 0x4000) != 0;
775
    reg = DREG(insn, 9);
776
    dest = gen_new_qreg(QMODE_I32);
777
    if (insn & 0x100) {
778
        tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
779
        src = reg;
780
    } else {
781
        tmp = reg;
782
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
783
    }
784
    if (add) {
785
        gen_op_add32(dest, tmp, src);
786
        gen_op_update_xflag_lt(dest, src);
787
        s->cc_op = CC_OP_ADD;
788
    } else {
789
        gen_op_update_xflag_lt(tmp, src);
790
        gen_op_sub32(dest, tmp, src);
791
        s->cc_op = CC_OP_SUB;
792
    }
793
    gen_op_update_cc_add(dest, src);
794
    if (insn & 0x100) {
795
        gen_ea(s, insn, OS_LONG, dest, &addr);
796
    } else {
797
        gen_op_mov32(reg, dest);
798
    }
799
}
800

    
801

    
802
/* Reverse the order of the bits in REG.  */
803
DISAS_INSN(bitrev)
804
{
805
    int val;
806
    int tmp1;
807
    int tmp2;
808
    int reg;
809

    
810
    val = gen_new_qreg(QMODE_I32);
811
    tmp1 = gen_new_qreg(QMODE_I32);
812
    tmp2 = gen_new_qreg(QMODE_I32);
813
    reg = DREG(insn, 0);
814
    gen_op_mov32(val, reg);
815
    /* Reverse bits within each nibble.  */
816
    gen_op_shl32(tmp1, val, gen_im32(3));
817
    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
818
    gen_op_shl32(tmp2, val, gen_im32(1));
819
    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
820
    gen_op_or32(tmp1, tmp1, tmp2);
821
    gen_op_shr32(tmp2, val, gen_im32(1));
822
    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
823
    gen_op_or32(tmp1, tmp1, tmp2);
824
    gen_op_shr32(tmp2, val, gen_im32(3));
825
    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
826
    gen_op_or32(tmp1, tmp1, tmp2);
827
    /* Reverse nibbles withing bytes.  */
828
    gen_op_shl32(val, tmp1, gen_im32(4));
829
    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
830
    gen_op_shr32(tmp2, tmp1, gen_im32(4));
831
    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
832
    gen_op_or32(val, val, tmp2);
833
    /* Reverse bytes.  */
834
    gen_op_bswap32(reg, val);
835
    gen_op_mov32(reg, val);
836
}
837

    
838
DISAS_INSN(bitop_reg)
839
{
840
    int opsize;
841
    int op;
842
    int src1;
843
    int src2;
844
    int tmp;
845
    int addr;
846
    int dest;
847

    
848
    if ((insn & 0x38) != 0)
849
        opsize = OS_BYTE;
850
    else
851
        opsize = OS_LONG;
852
    op = (insn >> 6) & 3;
853
    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
854
    src2 = DREG(insn, 9);
855
    dest = gen_new_qreg(QMODE_I32);
856

    
857
    gen_flush_flags(s);
858
    tmp = gen_new_qreg(QMODE_I32);
859
    if (opsize == OS_BYTE)
860
        gen_op_and32(tmp, src2, gen_im32(7));
861
    else
862
        gen_op_and32(tmp, src2, gen_im32(31));
863
    src2 = tmp;
864
    tmp = gen_new_qreg(QMODE_I32);
865
    gen_op_shl32(tmp, gen_im32(1), src2);
866

    
867
    gen_op_btest(src1, tmp);
868
    switch (op) {
869
    case 1: /* bchg */
870
        gen_op_xor32(dest, src1, tmp);
871
        break;
872
    case 2: /* bclr */
873
        gen_op_not32(tmp, tmp);
874
        gen_op_and32(dest, src1, tmp);
875
        break;
876
    case 3: /* bset */
877
        gen_op_or32(dest, src1, tmp);
878
        break;
879
    default: /* btst */
880
        break;
881
    }
882
    if (op)
883
        gen_ea(s, insn, opsize, dest, &addr);
884
}
885

    
886
DISAS_INSN(sats)
887
{
888
    int reg;
889
    int tmp;
890
    int l1;
891

    
892
    reg = DREG(insn, 0);
893
    tmp = gen_new_qreg(QMODE_I32);
894
    gen_flush_flags(s);
895
    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
896
    l1 = gen_new_label();
897
    gen_op_jmp_z32(tmp, l1);
898
    tmp = gen_new_qreg(QMODE_I32);
899
    gen_op_shr32(tmp, reg, gen_im32(31));
900
    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
901
    gen_op_mov32(reg, tmp);
902
    gen_set_label(l1);
903
    gen_logic_cc(s, tmp);
904
}
905

    
906
static void gen_push(int val)
907
{
908
    int tmp;
909

    
910
    tmp = gen_new_qreg(QMODE_I32);
911
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
912
    gen_store(OS_LONG, tmp, val);
913
    gen_op_mov32(QREG_SP, tmp);
914
}
915

    
916
DISAS_INSN(movem)
917
{
918
    int addr;
919
    int i;
920
    uint16_t mask;
921
    int reg;
922
    int tmp;
923
    int is_load;
924

    
925
    mask = lduw(s->pc);
926
    s->pc += 2;
927
    tmp = gen_lea(s, insn, OS_LONG);
928
    addr = gen_new_qreg(QMODE_I32);
929
    gen_op_mov32(addr, tmp);
930
    is_load = ((insn & 0x0400) != 0);
931
    for (i = 0; i < 16; i++, mask >>= 1) {
932
        if (mask & 1) {
933
            if (i < 8)
934
                reg = DREG(i, 0);
935
            else
936
                reg = AREG(i, 0);
937
            if (is_load) {
938
                tmp = gen_load(OS_LONG, addr, 0);
939
                gen_op_mov32(reg, tmp);
940
            } else {
941
                gen_store(OS_LONG, addr, reg);
942
            }
943
            if (mask != 1)
944
                gen_op_add32(addr, addr, gen_im32(4));
945
        }
946
    }
947
}
948

    
949
DISAS_INSN(bitop_im)
950
{
951
    int opsize;
952
    int op;
953
    int src1;
954
    uint32_t mask;
955
    int bitnum;
956
    int tmp;
957
    int addr;
958
    int dest;
959

    
960
    if ((insn & 0x38) != 0)
961
        opsize = OS_BYTE;
962
    else
963
        opsize = OS_LONG;
964
    op = (insn >> 6) & 3;
965

    
966
    bitnum = lduw(s->pc);
967
    s->pc += 2;
968
    if (bitnum & 0xff00) {
969
        disas_undef(s, insn);
970
        return;
971
    }
972

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

    
975
    gen_flush_flags(s);
976
    tmp = gen_new_qreg(QMODE_I32);
977
    if (opsize == OS_BYTE)
978
        bitnum &= 7;
979
    else
980
        bitnum &= 31;
981
    mask = 1 << bitnum;
982

    
983
    gen_op_btest(src1, gen_im32(mask));
984
    if (op)
985
        dest = gen_new_qreg(QMODE_I32);
986
    else
987
        dest = -1;
988

    
989
    switch (op) {
990
    case 1: /* bchg */
991
        gen_op_xor32(dest, src1, gen_im32(mask));
992
        break;
993
    case 2: /* bclr */
994
        gen_op_and32(dest, src1, gen_im32(~mask));
995
        break;
996
    case 3: /* bset */
997
        gen_op_or32(dest, src1, gen_im32(mask));
998
        break;
999
    default: /* btst */
1000
        break;
1001
    }
1002
    if (op)
1003
        gen_ea(s, insn, opsize, dest, &addr);
1004
}
1005

    
1006
DISAS_INSN(arith_im)
1007
{
1008
    int op;
1009
    int src1;
1010
    int dest;
1011
    int src2;
1012
    int addr;
1013

    
1014
    op = (insn >> 9) & 7;
1015
    src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
1016
    src2 = gen_im32(read_im32(s));
1017
    dest = gen_new_qreg(QMODE_I32);
1018
    switch (op) {
1019
    case 0: /* ori */
1020
        gen_op_or32(dest, src1, src2);
1021
        gen_logic_cc(s, dest);
1022
        break;
1023
    case 1: /* andi */
1024
        gen_op_and32(dest, src1, src2);
1025
        gen_logic_cc(s, dest);
1026
        break;
1027
    case 2: /* subi */
1028
        gen_op_mov32(dest, src1);
1029
        gen_op_update_xflag_lt(dest, src2);
1030
        gen_op_sub32(dest, dest, src2);
1031
        gen_op_update_cc_add(dest, src2);
1032
        s->cc_op = CC_OP_SUB;
1033
        break;
1034
    case 3: /* addi */
1035
        gen_op_mov32(dest, src1);
1036
        gen_op_add32(dest, dest, src2);
1037
        gen_op_update_cc_add(dest, src2);
1038
        gen_op_update_xflag_lt(dest, src2);
1039
        s->cc_op = CC_OP_ADD;
1040
        break;
1041
    case 5: /* eori */
1042
        gen_op_xor32(dest, src1, src2);
1043
        gen_logic_cc(s, dest);
1044
        break;
1045
    case 6: /* cmpi */
1046
        gen_op_mov32(dest, src1);
1047
        gen_op_sub32(dest, dest, src2);
1048
        gen_op_update_cc_add(dest, src2);
1049
        s->cc_op = CC_OP_SUB;
1050
        break;
1051
    default:
1052
        abort();
1053
    }
1054
    if (op != 6) {
1055
        gen_ea(s, insn, OS_LONG, dest, &addr);
1056
    }
1057
}
1058

    
1059
DISAS_INSN(byterev)
1060
{
1061
    int reg;
1062

    
1063
    reg = DREG(insn, 0);
1064
    gen_op_bswap32(reg, reg);
1065
}
1066

    
1067
DISAS_INSN(move)
1068
{
1069
    int src;
1070
    int dest;
1071
    int op;
1072
    int opsize;
1073

    
1074
    switch (insn >> 12) {
1075
    case 1: /* move.b */
1076
        opsize = OS_BYTE;
1077
        break;
1078
    case 2: /* move.l */
1079
        opsize = OS_LONG;
1080
        break;
1081
    case 3: /* move.w */
1082
        opsize = OS_WORD;
1083
        break;
1084
    default:
1085
        abort();
1086
    }
1087
    src = gen_ea(s, insn, opsize, -1, NULL);
1088
    op = (insn >> 6) & 7;
1089
    if (op == 1) {
1090
        /* movea */
1091
        /* The value will already have been sign extended.  */
1092
        dest = AREG(insn, 9);
1093
        gen_op_mov32(dest, src);
1094
    } else {
1095
        /* normal move */
1096
        uint16_t dest_ea;
1097
        dest_ea = ((insn >> 9) & 7) | (op << 3);
1098
        gen_ea(s, dest_ea, opsize, src, NULL);
1099
        /* This will be correct because loads sign extend.  */
1100
        gen_logic_cc(s, src);
1101
    }
1102
}
1103

    
1104
DISAS_INSN(negx)
1105
{
1106
    int reg;
1107
    int dest;
1108
    int tmp;
1109

    
1110
    gen_flush_flags(s);
1111
    reg = DREG(insn, 0);
1112
    dest = gen_new_qreg(QMODE_I32);
1113
    gen_op_mov32 (dest, gen_im32(0));
1114
    gen_op_subx_cc(dest, reg);
1115
    /* !Z is sticky.  */
1116
    tmp = gen_new_qreg(QMODE_I32);
1117
    gen_op_mov32 (tmp, QREG_CC_DEST);
1118
    gen_op_update_cc_add(dest, reg);
1119
    gen_op_mov32(reg, dest);
1120
    s->cc_op = CC_OP_DYNAMIC;
1121
    gen_flush_flags(s);
1122
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1123
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1124
    s->cc_op = CC_OP_FLAGS;
1125
}
1126

    
1127
DISAS_INSN(lea)
1128
{
1129
    int reg;
1130
    int tmp;
1131

    
1132
    reg = AREG(insn, 9);
1133
    tmp = gen_lea(s, insn, OS_LONG);
1134
    gen_op_mov32(reg, tmp);
1135
}
1136

    
1137
DISAS_INSN(clr)
1138
{
1139
    int opsize;
1140

    
1141
    switch ((insn >> 6) & 3) {
1142
    case 0: /* clr.b */
1143
        opsize = OS_BYTE;
1144
        break;
1145
    case 1: /* clr.w */
1146
        opsize = OS_WORD;
1147
        break;
1148
    case 2: /* clr.l */
1149
        opsize = OS_LONG;
1150
        break;
1151
    default:
1152
        abort();
1153
    }
1154
    gen_ea (s, insn, opsize, gen_im32(0), NULL);
1155
    gen_logic_cc(s, gen_im32(0));
1156
}
1157

    
1158
DISAS_INSN(move_from_ccr)
1159
{
1160
    int reg;
1161
    int dest;
1162

    
1163
    gen_flush_flags(s);
1164
    dest = gen_new_qreg(QMODE_I32);
1165
    gen_op_get_xflag(dest);
1166
    gen_op_shl32(dest, dest, gen_im32(4));
1167
    gen_op_or32(dest, dest, QREG_CC_DEST);
1168
    reg = DREG(insn, 0);
1169
    gen_partset_reg(OS_WORD, reg, dest);
1170
}
1171

    
1172
DISAS_INSN(neg)
1173
{
1174
    int reg;
1175
    int src1;
1176

    
1177
    reg = DREG(insn, 0);
1178
    src1 = gen_new_qreg(QMODE_I32);
1179
    gen_op_mov32(src1, reg);
1180
    gen_op_neg32(reg, src1);
1181
    s->cc_op = CC_OP_SUB;
1182
    gen_op_update_cc_add(reg, src1);
1183
    gen_op_update_xflag_lt(gen_im32(0), src1);
1184
    s->cc_op = CC_OP_SUB;
1185
}
1186

    
1187
DISAS_INSN(move_to_ccr)
1188
{
1189
    int src1;
1190
    int reg;
1191

    
1192
    s->cc_op = CC_OP_FLAGS;
1193
    if ((insn & 0x38) == 0)
1194
      {
1195
        src1 = gen_new_qreg(QMODE_I32);
1196
        reg = DREG(insn, 0);
1197
        gen_op_and32(src1, reg, gen_im32(0xf));
1198
        gen_op_logic_cc(src1);
1199
        gen_op_shr32(src1, reg, gen_im32(4));
1200
        gen_op_and32(src1, src1, gen_im32(1));
1201
        gen_op_update_xflag_tst(src1);
1202
      }
1203
    else if ((insn & 0x3f) != 0x3c)
1204
      {
1205
        uint8_t val;
1206
        val = ldsb(s->pc);
1207
        s->pc += 2;
1208
        gen_op_logic_cc(gen_im32(val & 0xf));
1209
        gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1210
      }
1211
    else
1212
        disas_undef(s, insn);
1213
}
1214

    
1215
DISAS_INSN(not)
1216
{
1217
    int reg;
1218

    
1219
    reg = DREG(insn, 0);
1220
    gen_op_not32(reg, reg);
1221
    gen_logic_cc(s, reg);
1222
}
1223

    
1224
DISAS_INSN(swap)
1225
{
1226
    int dest;
1227
    int src1;
1228
    int src2;
1229
    int reg;
1230

    
1231
    dest = gen_new_qreg(QMODE_I32);
1232
    src1 = gen_new_qreg(QMODE_I32);
1233
    src2 = gen_new_qreg(QMODE_I32);
1234
    reg = DREG(insn, 0);
1235
    gen_op_shl32(src1, reg, gen_im32(16));
1236
    gen_op_shr32(src2, reg, gen_im32(16));
1237
    gen_op_or32(dest, src1, src2);
1238
    gen_op_mov32(reg, dest);
1239
    gen_logic_cc(s, dest);
1240
}
1241

    
1242
DISAS_INSN(pea)
1243
{
1244
    int tmp;
1245

    
1246
    tmp = gen_lea(s, insn, OS_LONG);
1247
    gen_push(tmp);
1248
}
1249

    
1250
DISAS_INSN(ext)
1251
{
1252
    int reg;
1253
    int op;
1254
    int tmp;
1255

    
1256
    reg = DREG(insn, 0);
1257
    op = (insn >> 6) & 7;
1258
    tmp = gen_new_qreg(QMODE_I32);
1259
    if (op == 3)
1260
        gen_op_ext16s32(tmp, reg);
1261
    else
1262
        gen_op_ext8s32(tmp, reg);
1263
    if (op == 2)
1264
        gen_partset_reg(OS_WORD, reg, tmp);
1265
    else
1266
      gen_op_mov32(reg, tmp);
1267
    gen_logic_cc(s, tmp);
1268
}
1269

    
1270
DISAS_INSN(tst)
1271
{
1272
    int opsize;
1273
    int tmp;
1274

    
1275
    switch ((insn >> 6) & 3) {
1276
    case 0: /* tst.b */
1277
        opsize = OS_BYTE;
1278
        break;
1279
    case 1: /* tst.w */
1280
        opsize = OS_WORD;
1281
        break;
1282
    case 2: /* tst.l */
1283
        opsize = OS_LONG;
1284
        break;
1285
    default:
1286
        abort();
1287
    }
1288
    tmp = gen_ea(s, insn, opsize, -1, NULL);
1289
    gen_logic_cc(s, tmp);
1290
}
1291

    
1292
DISAS_INSN(pulse)
1293
{
1294
  /* Implemented as a NOP.  */
1295
}
1296

    
1297
DISAS_INSN(illegal)
1298
{
1299
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1300
}
1301

    
1302
/* ??? This should be atomic.  */
1303
DISAS_INSN(tas)
1304
{
1305
    int dest;
1306
    int src1;
1307
    int addr;
1308

    
1309
    dest = gen_new_qreg(QMODE_I32);
1310
    src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
1311
    gen_logic_cc(s, src1);
1312
    gen_op_or32(dest, src1, gen_im32(0x80));
1313
    gen_ea(s, insn, OS_BYTE, dest, &addr);
1314
}
1315

    
1316
DISAS_INSN(mull)
1317
{
1318
    uint16_t ext;
1319
    int reg;
1320
    int src1;
1321
    int dest;
1322

    
1323
    /* The upper 32 bits of the product are discarded, so
1324
       muls.l and mulu.l are functionally equivalent.  */
1325
    ext = lduw(s->pc);
1326
    s->pc += 2;
1327
    if (ext & 0x87ff) {
1328
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1329
        return;
1330
    }
1331
    reg = DREG(ext, 12);
1332
    src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
1333
    dest = gen_new_qreg(QMODE_I32);
1334
    gen_op_mul32(dest, src1, reg);
1335
    gen_op_mov32(reg, dest);
1336
    /* Unlike m68k, coldfire always clears the overflow bit.  */
1337
    gen_logic_cc(s, dest);
1338
}
1339

    
1340
DISAS_INSN(link)
1341
{
1342
    int16_t offset;
1343
    int reg;
1344
    int tmp;
1345

    
1346
    offset = ldsw(s->pc);
1347
    s->pc += 2;
1348
    reg = AREG(insn, 0);
1349
    tmp = gen_new_qreg(QMODE_I32);
1350
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1351
    gen_store(OS_LONG, tmp, reg);
1352
    if (reg != QREG_SP)
1353
        gen_op_mov32(reg, tmp);
1354
    gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1355
}
1356

    
1357
DISAS_INSN(unlk)
1358
{
1359
    int src;
1360
    int reg;
1361
    int tmp;
1362

    
1363
    src = gen_new_qreg(QMODE_I32);
1364
    reg = AREG(insn, 0);
1365
    gen_op_mov32(src, reg);
1366
    tmp = gen_load(OS_LONG, src, 0);
1367
    gen_op_mov32(reg, tmp);
1368
    gen_op_add32(QREG_SP, src, gen_im32(4));
1369
}
1370

    
1371
DISAS_INSN(nop)
1372
{
1373
}
1374

    
1375
DISAS_INSN(rts)
1376
{
1377
    int tmp;
1378

    
1379
    tmp = gen_load(OS_LONG, QREG_SP, 0);
1380
    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1381
    gen_jmp(s, tmp);
1382
}
1383

    
1384
DISAS_INSN(jump)
1385
{
1386
    int tmp;
1387

    
1388
    /* Load the target address first to ensure correct exception
1389
       behavior.  */
1390
    tmp = gen_lea(s, insn, OS_LONG);
1391
    if ((insn & 0x40) == 0) {
1392
        /* jsr */
1393
        gen_push(gen_im32(s->pc));
1394
    }
1395
    gen_jmp(s, tmp);
1396
}
1397

    
1398
DISAS_INSN(addsubq)
1399
{
1400
    int src1;
1401
    int src2;
1402
    int dest;
1403
    int val;
1404
    int addr;
1405

    
1406
    src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
1407
    val = (insn >> 9) & 7;
1408
    if (val == 0)
1409
        val = 8;
1410
    src2 = gen_im32(val);
1411
    dest = gen_new_qreg(QMODE_I32);
1412
    gen_op_mov32(dest, src1);
1413
    if ((insn & 0x38) == 0x08) {
1414
        /* Don't update condition codes if the destination is an
1415
           address register.  */
1416
        if (insn & 0x0100) {
1417
            gen_op_sub32(dest, dest, src2);
1418
        } else {
1419
            gen_op_add32(dest, dest, src2);
1420
        }
1421
    } else {
1422
        if (insn & 0x0100) {
1423
            gen_op_update_xflag_lt(dest, src2);
1424
            gen_op_sub32(dest, dest, src2);
1425
            s->cc_op = CC_OP_SUB;
1426
        } else {
1427
            gen_op_add32(dest, dest, src2);
1428
            gen_op_update_xflag_lt(dest, src2);
1429
            s->cc_op = CC_OP_ADD;
1430
        }
1431
        gen_op_update_cc_add(dest, src2);
1432
    }
1433
    gen_ea(s, insn, OS_LONG, dest, &addr);
1434
}
1435

    
1436
DISAS_INSN(tpf)
1437
{
1438
    switch (insn & 7) {
1439
    case 2: /* One extension word.  */
1440
        s->pc += 2;
1441
        break;
1442
    case 3: /* Two extension words.  */
1443
        s->pc += 4;
1444
        break;
1445
    case 4: /* No extension words.  */
1446
        break;
1447
    default:
1448
        disas_undef(s, insn);
1449
    }
1450
}
1451

    
1452
DISAS_INSN(branch)
1453
{
1454
    int32_t offset;
1455
    uint32_t base;
1456
    int op;
1457
    int l1;
1458
    
1459
    base = s->pc;
1460
    op = (insn >> 8) & 0xf;
1461
    offset = (int8_t)insn;
1462
    if (offset == 0) {
1463
        offset = ldsw(s->pc);
1464
        s->pc += 2;
1465
    } else if (offset == -1) {
1466
        offset = read_im32(s);
1467
    }
1468
    if (op == 1) {
1469
        /* bsr */
1470
        gen_push(gen_im32(s->pc));
1471
    }
1472
    gen_flush_cc_op(s);
1473
    if (op > 1) {
1474
        /* Bcc */
1475
        l1 = gen_new_label();
1476
        gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1477
        gen_jmp_tb(s, 1, base + offset);
1478
        gen_set_label(l1);
1479
        gen_jmp_tb(s, 0, s->pc);
1480
    } else {
1481
        /* Unconditional branch.  */
1482
        gen_jmp_tb(s, 0, base + offset);
1483
    }
1484
}
1485

    
1486
DISAS_INSN(moveq)
1487
{
1488
    int tmp;
1489

    
1490
    tmp = gen_im32((int8_t)insn);
1491
    gen_op_mov32(DREG(insn, 9), tmp);
1492
    gen_logic_cc(s, tmp);
1493
}
1494

    
1495
DISAS_INSN(mvzs)
1496
{
1497
    int opsize;
1498
    int src;
1499
    int reg;
1500

    
1501
    if (insn & 0x40)
1502
        opsize = OS_WORD;
1503
    else
1504
        opsize = OS_BYTE;
1505
    src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
1506
    reg = DREG(insn, 9);
1507
    gen_op_mov32(reg, src);
1508
    gen_logic_cc(s, src);
1509
}
1510

    
1511
DISAS_INSN(or)
1512
{
1513
    int reg;
1514
    int dest;
1515
    int src;
1516
    int addr;
1517

    
1518
    reg = DREG(insn, 9);
1519
    dest = gen_new_qreg(QMODE_I32);
1520
    if (insn & 0x100) {
1521
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
1522
        gen_op_or32(dest, src, reg);
1523
        gen_ea(s, insn, OS_LONG, dest, &addr);
1524
    } else {
1525
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
1526
        gen_op_or32(dest, src, reg);
1527
        gen_op_mov32(reg, dest);
1528
    }
1529
    gen_logic_cc(s, dest);
1530
}
1531

    
1532
DISAS_INSN(suba)
1533
{
1534
    int src;
1535
    int reg;
1536

    
1537
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
1538
    reg = AREG(insn, 9);
1539
    gen_op_sub32(reg, reg, src);
1540
}
1541

    
1542
DISAS_INSN(subx)
1543
{
1544
    int reg;
1545
    int src;
1546
    int dest;
1547
    int tmp;
1548

    
1549
    gen_flush_flags(s);
1550
    reg = DREG(insn, 9);
1551
    src = DREG(insn, 0);
1552
    dest = gen_new_qreg(QMODE_I32);
1553
    gen_op_mov32 (dest, reg);
1554
    gen_op_subx_cc(dest, src);
1555
    /* !Z is sticky.  */
1556
    tmp = gen_new_qreg(QMODE_I32);
1557
    gen_op_mov32 (tmp, QREG_CC_DEST);
1558
    gen_op_update_cc_add(dest, src);
1559
    gen_op_mov32(reg, dest);
1560
    s->cc_op = CC_OP_DYNAMIC;
1561
    gen_flush_flags(s);
1562
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1563
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1564
    s->cc_op = CC_OP_FLAGS;
1565
}
1566

    
1567
DISAS_INSN(mov3q)
1568
{
1569
    int src;
1570
    int val;
1571

    
1572
    val = (insn >> 9) & 7;
1573
    if (val == 0)
1574
        val = -1;
1575
    src = gen_im32(val);
1576
    gen_logic_cc(s, src);
1577
    gen_ea(s, insn, OS_LONG, src, NULL);
1578
}
1579

    
1580
DISAS_INSN(cmp)
1581
{
1582
    int op;
1583
    int src;
1584
    int reg;
1585
    int dest;
1586
    int opsize;
1587

    
1588
    op = (insn >> 6) & 3;
1589
    switch (op) {
1590
    case 0: /* cmp.b */
1591
        opsize = OS_BYTE;
1592
        s->cc_op = CC_OP_CMPB;
1593
        break;
1594
    case 1: /* cmp.w */
1595
        opsize = OS_WORD;
1596
        s->cc_op = CC_OP_CMPW;
1597
        break;
1598
    case 2: /* cmp.l */
1599
        opsize = OS_LONG;
1600
        s->cc_op = CC_OP_SUB;
1601
        break;
1602
    default:
1603
        abort();
1604
    }
1605
    src = gen_ea(s, insn, opsize, -1, NULL);
1606
    reg = DREG(insn, 9);
1607
    dest = gen_new_qreg(QMODE_I32);
1608
    gen_op_sub32(dest, reg, src);
1609
    gen_op_update_cc_add(dest, src);
1610
}
1611

    
1612
DISAS_INSN(cmpa)
1613
{
1614
    int opsize;
1615
    int src;
1616
    int reg;
1617
    int dest;
1618

    
1619
    if (insn & 0x100) {
1620
        opsize = OS_LONG;
1621
    } else {
1622
        opsize = OS_WORD;
1623
    }
1624
    src = gen_ea(s, insn, opsize, -1, NULL);
1625
    reg = AREG(insn, 9);
1626
    dest = gen_new_qreg(QMODE_I32);
1627
    gen_op_sub32(dest, reg, src);
1628
    gen_op_update_cc_add(dest, src);
1629
    s->cc_op = CC_OP_SUB;
1630
}
1631

    
1632
DISAS_INSN(eor)
1633
{
1634
    int src;
1635
    int reg;
1636
    int dest;
1637
    int addr;
1638

    
1639
    src = gen_ea(s, insn, OS_LONG, 0, &addr);
1640
    reg = DREG(insn, 9);
1641
    dest = gen_new_qreg(QMODE_I32);
1642
    gen_op_xor32(dest, src, reg);
1643
    gen_logic_cc(s, dest);
1644
    gen_ea(s, insn, OS_LONG, dest, &addr);
1645
}
1646

    
1647
DISAS_INSN(and)
1648
{
1649
    int src;
1650
    int reg;
1651
    int dest;
1652
    int addr;
1653

    
1654
    reg = DREG(insn, 9);
1655
    dest = gen_new_qreg(QMODE_I32);
1656
    if (insn & 0x100) {
1657
        src = gen_ea(s, insn, OS_LONG, 0, &addr);
1658
        gen_op_and32(dest, src, reg);
1659
        gen_ea(s, insn, OS_LONG, dest, &addr);
1660
    } else {
1661
        src = gen_ea(s, insn, OS_LONG, 0, NULL);
1662
        gen_op_and32(dest, src, reg);
1663
        gen_op_mov32(reg, dest);
1664
    }
1665
    gen_logic_cc(s, dest);
1666
}
1667

    
1668
DISAS_INSN(adda)
1669
{
1670
    int src;
1671
    int reg;
1672

    
1673
    src = gen_ea(s, insn, OS_LONG, 0, NULL);
1674
    reg = AREG(insn, 9);
1675
    gen_op_add32(reg, reg, src);
1676
}
1677

    
1678
DISAS_INSN(addx)
1679
{
1680
    int reg;
1681
    int src;
1682
    int dest;
1683
    int tmp;
1684

    
1685
    gen_flush_flags(s);
1686
    reg = DREG(insn, 9);
1687
    src = DREG(insn, 0);
1688
    dest = gen_new_qreg(QMODE_I32);
1689
    gen_op_mov32 (dest, reg);
1690
    gen_op_addx_cc(dest, src);
1691
    /* !Z is sticky.  */
1692
    tmp = gen_new_qreg(QMODE_I32);
1693
    gen_op_mov32 (tmp, QREG_CC_DEST);
1694
    gen_op_update_cc_add(dest, src);
1695
    gen_op_mov32(reg, dest);
1696
    s->cc_op = CC_OP_DYNAMIC;
1697
    gen_flush_flags(s);
1698
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1699
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1700
    s->cc_op = CC_OP_FLAGS;
1701
}
1702

    
1703
DISAS_INSN(shift_im)
1704
{
1705
    int reg;
1706
    int tmp;
1707

    
1708
    reg = DREG(insn, 0);
1709
    tmp = (insn >> 9) & 7;
1710
    if (tmp == 0)
1711
      tmp = 8;
1712
    if (insn & 0x100) {
1713
        gen_op_shl_im_cc(reg, tmp);
1714
        s->cc_op = CC_OP_SHL;
1715
    } else {
1716
        if (insn & 8) {
1717
            gen_op_shr_im_cc(reg, tmp);
1718
            s->cc_op = CC_OP_SHR;
1719
        } else {
1720
            gen_op_sar_im_cc(reg, tmp);
1721
            s->cc_op = CC_OP_SAR;
1722
        }
1723
    }
1724
}
1725

    
1726
DISAS_INSN(shift_reg)
1727
{
1728
    int reg;
1729
    int src;
1730
    int tmp;
1731

    
1732
    reg = DREG(insn, 0);
1733
    src = DREG(insn, 9);
1734
    tmp = gen_new_qreg(QMODE_I32);
1735
    gen_op_and32(tmp, src, gen_im32(63));
1736
    if (insn & 0x100) {
1737
        gen_op_shl_cc(reg, tmp);
1738
        s->cc_op = CC_OP_SHL;
1739
    } else {
1740
        if (insn & 8) {
1741
            gen_op_shr_cc(reg, tmp);
1742
            s->cc_op = CC_OP_SHR;
1743
        } else {
1744
            gen_op_sar_cc(reg, tmp);
1745
            s->cc_op = CC_OP_SAR;
1746
        }
1747
    }
1748
}
1749

    
1750
DISAS_INSN(ff1)
1751
{
1752
    cpu_abort(NULL, "Unimplemented insn: ff1");
1753
}
1754

    
1755
DISAS_INSN(strldsr)
1756
{
1757
    uint16_t ext;
1758
    uint32_t addr;
1759

    
1760
    addr = s->pc - 2;
1761
    ext = lduw(s->pc);
1762
    s->pc += 2;
1763
    if (ext != 0x46FC)
1764
        gen_exception(s, addr, EXCP_UNSUPPORTED);
1765
    else
1766
        gen_exception(s, addr, EXCP_PRIVILEGE);
1767
}
1768

    
1769
DISAS_INSN(move_from_sr)
1770
{
1771
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1772
}
1773

    
1774
DISAS_INSN(move_to_sr)
1775
{
1776
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1777
}
1778

    
1779
DISAS_INSN(move_from_usp)
1780
{
1781
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1782
}
1783

    
1784
DISAS_INSN(move_to_usp)
1785
{
1786
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1787
}
1788

    
1789
DISAS_INSN(halt)
1790
{
1791
    gen_exception(s, s->pc, EXCP_HLT);
1792
}
1793

    
1794
DISAS_INSN(stop)
1795
{
1796
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1797
}
1798

    
1799
DISAS_INSN(rte)
1800
{
1801
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1802
}
1803

    
1804
DISAS_INSN(movec)
1805
{
1806
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1807
}
1808

    
1809
DISAS_INSN(intouch)
1810
{
1811
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1812
}
1813

    
1814
DISAS_INSN(cpushl)
1815
{
1816
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1817
}
1818

    
1819
DISAS_INSN(wddata)
1820
{
1821
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1822
}
1823

    
1824
DISAS_INSN(wdebug)
1825
{
1826
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1827
}
1828

    
1829
DISAS_INSN(trap)
1830
{
1831
    gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
1832
}
1833

    
1834
/* ??? FP exceptions are not implemented.  Most exceptions are deferred until
1835
   immediately before the next FP instruction is executed.  */
1836
DISAS_INSN(fpu)
1837
{
1838
    uint16_t ext;
1839
    int opmode;
1840
    int src;
1841
    int dest;
1842
    int res;
1843
    int round;
1844
    int opsize;
1845

    
1846
    ext = lduw(s->pc);
1847
    s->pc += 2;
1848
    opmode = ext & 0x7f;
1849
    switch ((ext >> 13) & 7) {
1850
    case 0: case 2:
1851
        break;
1852
    case 1:
1853
        goto undef;
1854
    case 3: /* fmove out */
1855
        src = FREG(ext, 7);
1856
        /* fmove */
1857
        /* ??? TODO: Proper behavior on overflow.  */
1858
        switch ((ext >> 10) & 7) {
1859
        case 0:
1860
            opsize = OS_LONG;
1861
            res = gen_new_qreg(QMODE_I32);
1862
            gen_op_f64_to_i32(res, src);
1863
            break;
1864
        case 1:
1865
            opsize = OS_SINGLE;
1866
            res = gen_new_qreg(QMODE_F32);
1867
            gen_op_f64_to_f32(res, src);
1868
            break;
1869
        case 4:
1870
            opsize = OS_WORD;
1871
            res = gen_new_qreg(QMODE_I32);
1872
            gen_op_f64_to_i32(res, src);
1873
            break;
1874
        case 5:
1875
            opsize = OS_DOUBLE;
1876
            res = src;
1877
            break;
1878
        case 6:
1879
            opsize = OS_BYTE;
1880
            res = gen_new_qreg(QMODE_I32);
1881
            gen_op_f64_to_i32(res, src);
1882
            break;
1883
        default:
1884
            goto undef;
1885
        }
1886
        gen_ea(s, insn, opsize, res, NULL);
1887
        return;
1888
    case 4: /* fmove to control register.  */
1889
        switch ((ext >> 10) & 7) {
1890
        case 4: /* FPCR */
1891
            /* Not implemented.  Ignore writes.  */
1892
            break;
1893
        case 1: /* FPIAR */
1894
        case 2: /* FPSR */
1895
        default:
1896
            cpu_abort(NULL, "Unimplemented: fmove to control %d",
1897
                      (ext >> 10) & 7);
1898
        }
1899
        break;
1900
    case 5: /* fmove from control register.  */
1901
        switch ((ext >> 10) & 7) {
1902
        case 4: /* FPCR */
1903
            /* Not implemented.  Always return zero.  */
1904
            res = gen_im32(0);
1905
            break;
1906
        case 1: /* FPIAR */
1907
        case 2: /* FPSR */
1908
        default:
1909
            cpu_abort(NULL, "Unimplemented: fmove from control %d",
1910
                      (ext >> 10) & 7);
1911
            goto undef;
1912
        }
1913
        gen_ea(s, insn, OS_LONG, res, NULL);
1914
        break;
1915
    case 6: /* fmovem */ 
1916
    case 7:
1917
        {
1918
        int addr;
1919
        uint16_t mask;
1920
        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
1921
            goto undef;
1922
        src = gen_lea(s, insn, OS_LONG);
1923
        addr = gen_new_qreg(QMODE_I32);
1924
        gen_op_mov32(addr, src);
1925
        mask = 0x80;
1926
        dest = QREG_F0;
1927
        while (mask) {
1928
            if (ext & mask) {
1929
                if (ext & (1 << 13)) {
1930
                    /* store */
1931
                    gen_op_stf64(addr, dest);
1932
                } else {
1933
                    /* load */
1934
                    gen_op_ldf64(dest, addr);
1935
                }
1936
                if (ext & (mask - 1))
1937
                    gen_op_add32(addr, addr, gen_im32(8));
1938
            }
1939
            mask >>= 1;
1940
            dest++;
1941
        }
1942
        }
1943
        return;
1944
    }
1945
    if (ext & (1 << 14)) {
1946
        int tmp;
1947

    
1948
        /* Source effective address.  */
1949
        switch ((ext >> 10) & 7) {
1950
        case 0: opsize = OS_LONG; break;
1951
        case 1: opsize = OS_SINGLE; break;
1952
        case 4: opsize = OS_WORD; break;
1953
        case 5: opsize = OS_DOUBLE; break;
1954
        case 6: opsize = OS_BYTE; break;
1955
        default:
1956
            goto undef;
1957
        }
1958
        tmp = gen_ea(s, insn, opsize, -1, NULL);
1959
        if (opsize == OS_DOUBLE) {
1960
            src = tmp;
1961
        } else {
1962
            src = gen_new_qreg(QMODE_F64);
1963
            switch (opsize) {
1964
            case OS_LONG:
1965
            case OS_WORD:
1966
            case OS_BYTE:
1967
                gen_op_i32_to_f64(src, tmp);
1968
                break;
1969
            case OS_SINGLE:
1970
                gen_op_f32_to_f64(src, tmp);
1971
                break;
1972
            }
1973
        }
1974
    } else {
1975
        /* Source register.  */
1976
        src = FREG(ext, 10);
1977
    }
1978
    dest = FREG(ext, 7);
1979
    res = gen_new_qreg(QMODE_F64);
1980
    if (opmode != 0x3a)
1981
        gen_op_movf64(res, dest);
1982
    round = 1;
1983
    switch (opmode) {
1984
    case 0: case 0x40: case 0x44: /* fmove */
1985
        gen_op_movf64(res, src);
1986
        break;
1987
    case 1: /* fint */
1988
        gen_op_iround_f64(res, src);
1989
        round = 0;
1990
        break;
1991
    case 3: /* fintrz */
1992
        gen_op_itrunc_f64(res, src);
1993
        round = 0;
1994
        break;
1995
    case 4: case 0x41: case 0x45: /* fsqrt */
1996
        gen_op_sqrtf64(res, src);
1997
        break;
1998
    case 0x18: case 0x58: case 0x5c: /* fabs */
1999
        gen_op_absf64(res, src);
2000
        break;
2001
    case 0x1a: case 0x5a: case 0x5e: /* fneg */
2002
        gen_op_chsf64(res, src);
2003
        break;
2004
    case 0x20: case 0x60: case 0x64: /* fdiv */
2005
        gen_op_divf64(res, res, src);
2006
        break;
2007
    case 0x22: case 0x62: case 0x66: /* fadd */
2008
        gen_op_addf64(res, res, src);
2009
        break;
2010
    case 0x23: case 0x63: case 0x67: /* fmul */
2011
        gen_op_mulf64(res, res, src);
2012
        break;
2013
    case 0x28: case 0x68: case 0x6c: /* fsub */
2014
        gen_op_subf64(res, res, src);
2015
        break;
2016
    case 0x38: /* fcmp */
2017
        gen_op_sub_cmpf64(res, res, src);
2018
        dest = 0;
2019
        round = 0;
2020
        break;
2021
    case 0x3a: /* ftst */
2022
        gen_op_movf64(res, src);
2023
        dest = 0;
2024
        round = 0;
2025
        break;
2026
    default:
2027
        goto undef;
2028
    }
2029
    if (round) {
2030
        if (opmode & 0x40) {
2031
            if ((opmode & 0x4) != 0)
2032
                round = 0;
2033
        } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2034
            round = 0;
2035
        }
2036
    }
2037
    if (round) {
2038
        int tmp;
2039

    
2040
        tmp = gen_new_qreg(QMODE_F32);
2041
        gen_op_f64_to_f32(tmp, res);
2042
        gen_op_f32_to_f64(res, tmp);
2043
    } 
2044
    gen_op_fp_result(res);
2045
    if (dest) {
2046
        gen_op_movf64(dest, res);
2047
    }
2048
    return;
2049
undef:
2050
    s->pc -= 2;
2051
    disas_undef_fpu(s, insn);
2052
}
2053

    
2054
DISAS_INSN(fbcc)
2055
{
2056
    uint32_t offset;
2057
    uint32_t addr;
2058
    int flag;
2059
    int zero;
2060
    int l1;
2061

    
2062
    addr = s->pc;
2063
    offset = ldsw(s->pc);
2064
    s->pc += 2;
2065
    if (insn & (1 << 6)) {
2066
        offset = (offset << 16) | lduw(s->pc);
2067
        s->pc += 2;
2068
    }
2069

    
2070
    l1 = gen_new_label();
2071
    /* TODO: Raise BSUN exception.  */
2072
    flag = gen_new_qreg(QMODE_I32);
2073
    zero = gen_new_qreg(QMODE_F64);
2074
    gen_op_zerof64(zero);
2075
    gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2076
    /* Jump to l1 if condition is true.  */
2077
    switch (insn & 0xf) {
2078
    case 0: /* f */
2079
        break;
2080
    case 1: /* eq (=0) */
2081
        gen_op_jmp_z32(flag, l1);
2082
        break;
2083
    case 2: /* ogt (=1) */
2084
        gen_op_sub32(flag, flag, gen_im32(1));
2085
        gen_op_jmp_z32(flag, l1);
2086
        break;
2087
    case 3: /* oge (=0 or =1) */
2088
        gen_op_jmp_z32(flag, l1);
2089
        gen_op_sub32(flag, flag, gen_im32(1));
2090
        gen_op_jmp_z32(flag, l1);
2091
        break;
2092
    case 4: /* olt (=-1) */
2093
        gen_op_jmp_s32(flag, l1);
2094
        break;
2095
    case 5: /* ole (=-1 or =0) */
2096
        gen_op_jmp_s32(flag, l1);
2097
        gen_op_jmp_z32(flag, l1);
2098
        break;
2099
    case 6: /* ogl (=-1 or =1) */
2100
        gen_op_jmp_s32(flag, l1);
2101
        gen_op_sub32(flag, flag, gen_im32(1));
2102
        gen_op_jmp_z32(flag, l1);
2103
        break;
2104
    case 7: /* or (=2) */
2105
        gen_op_sub32(flag, flag, gen_im32(2));
2106
        gen_op_jmp_z32(flag, l1);
2107
        break;
2108
    case 8: /* un (<2) */
2109
        gen_op_sub32(flag, flag, gen_im32(2));
2110
        gen_op_jmp_s32(flag, l1);
2111
        break;
2112
    case 9: /* ueq (=0 or =2) */
2113
        gen_op_jmp_z32(flag, l1);
2114
        gen_op_sub32(flag, flag, gen_im32(2));
2115
        gen_op_jmp_z32(flag, l1);
2116
        break;
2117
    case 10: /* ugt (>0) */
2118
        /* ??? Add jmp_gtu.  */
2119
        gen_op_sub32(flag, flag, gen_im32(1));
2120
        gen_op_jmp_ns32(flag, l1);
2121
        break;
2122
    case 11: /* uge (>=0) */
2123
        gen_op_jmp_ns32(flag, l1);
2124
        break;
2125
    case 12: /* ult (=-1 or =2) */
2126
        gen_op_jmp_s32(flag, l1);
2127
        gen_op_sub32(flag, flag, gen_im32(2));
2128
        gen_op_jmp_z32(flag, l1);
2129
        break;
2130
    case 13: /* ule (!=1) */
2131
        gen_op_sub32(flag, flag, gen_im32(1));
2132
        gen_op_jmp_nz32(flag, l1);
2133
        break;
2134
    case 14: /* ne (!=0) */
2135
        gen_op_jmp_nz32(flag, l1);
2136
        break;
2137
    case 15: /* t */
2138
        gen_op_mov32(flag, gen_im32(1));
2139
        break;
2140
    }
2141
    gen_jmp_tb(s, 0, s->pc);
2142
    gen_set_label(l1);
2143
    gen_jmp_tb(s, 1, addr + offset);
2144
}
2145

    
2146
static disas_proc opcode_table[65536];
2147

    
2148
static void
2149
register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2150
{
2151
  int i;
2152
  int from;
2153
  int to;
2154

    
2155
  /* Sanity check.  All set bits must be included in the mask.  */
2156
  if (opcode & ~mask)
2157
      abort();
2158
  /* This could probably be cleverer.  For now just optimize the case where
2159
     the top bits are known.  */
2160
  /* Find the first zero bit in the mask.  */
2161
  i = 0x8000;
2162
  while ((i & mask) != 0)
2163
      i >>= 1;
2164
  /* Iterate over all combinations of this and lower bits.  */
2165
  if (i == 0)
2166
      i = 1;
2167
  else
2168
      i <<= 1;
2169
  from = opcode & ~(i - 1);
2170
  to = from + i;
2171
  for (i = from; i < to; i++)
2172
    {
2173
      if ((i & mask) == opcode)
2174
          opcode_table[i] = proc;
2175
    }
2176
}
2177

    
2178
/* Register m68k opcode handlers.  Order is important.
2179
   Later insn override earlier ones.  */
2180
static void
2181
register_m68k_insns (m68k_def_t *def)
2182
{
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);
2275
    INSN(fpu,       f200, ffc0, CF_FPU);
2276
    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);
2281
#undef INSN
2282
}
2283

    
2284
/* ??? Some of this implementation is not exception safe.  We should always
2285
   write back the result to memory before setting the condition codes.  */
2286
static void disas_m68k_insn(CPUState * env, DisasContext *s)
2287
{
2288
    uint16_t insn;
2289

    
2290
    insn = lduw(s->pc);
2291
    s->pc += 2;
2292

    
2293
    opcode_table[insn](s, insn);
2294
}
2295

    
2296
#if 0
2297
/* Save the result of a floating point operation.  */
2298
static void expand_op_fp_result(qOP *qop)
2299
{
2300
    gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2301
}
2302

2303
/* Dummy op to indicate that the flags have been set.  */
2304
static void expand_op_flags_set(qOP *qop)
2305
{
2306
}
2307

2308
/* Convert the confition codes into CC_OP_FLAGS format.  */
2309
static void expand_op_flush_flags(qOP *qop)
2310
{
2311
    int cc_opreg;
2312

2313
    if (qop->args[0] == CC_OP_DYNAMIC)
2314
        cc_opreg = QREG_CC_OP;
2315
    else
2316
        cc_opreg = gen_im32(qop->args[0]);
2317
    gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2318
}
2319

2320
/* Set CC_DEST after a logical or direct flag setting operation.  */
2321
static void expand_op_logic_cc(qOP *qop)
2322
{
2323
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2324
}
2325

2326
/* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2327
static void expand_op_update_cc_add(qOP *qop)
2328
{
2329
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2330
    gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2331
}
2332

2333
/* Update the X flag.  */
2334
static void expand_op_update_xflag(qOP *qop)
2335
{
2336
    int arg0;
2337
    int arg1;
2338

2339
    arg0 = qop->args[0];
2340
    arg1 = qop->args[1];
2341
    if (arg1 == QREG_NULL) {
2342
        /* CC_X = arg0.  */
2343
        gen_op_mov32(QREG_CC_X, arg0);
2344
    } else {
2345
        /* CC_X = arg0 < (unsigned)arg1.  */
2346
        gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2347
    }
2348
}
2349

2350
/* Set arg0 to the contents of the X flag.  */
2351
static void expand_op_get_xflag(qOP *qop)
2352
{
2353
    gen_op_mov32(qop->args[0], QREG_CC_X);
2354
}
2355

2356
/* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2357
   already know the shift is within range.  */
2358
static inline void expand_shift_im(qOP *qop, int right, int arith)
2359
{
2360
    int val;
2361
    int reg;
2362
    int tmp;
2363
    int im;
2364

2365
    reg = qop->args[0];
2366
    im = qop->args[1];
2367
    tmp = gen_im32(im);
2368
    val = gen_new_qreg(QMODE_I32);
2369
    gen_op_mov32(val, reg);
2370
    gen_op_mov32(QREG_CC_DEST, val);
2371
    gen_op_mov32(QREG_CC_SRC, tmp);
2372
    if (right) {
2373
        if (arith) {
2374
            gen_op_sar32(reg, val, tmp);
2375
        } else {
2376
            gen_op_shr32(reg, val, tmp);
2377
        }
2378
        if (im == 1)
2379
            tmp = QREG_NULL;
2380
        else
2381
            tmp = gen_im32(im - 1);
2382
    } else {
2383
        gen_op_shl32(reg, val, tmp);
2384
        tmp = gen_im32(32 - im);
2385
    }
2386
    if (tmp != QREG_NULL)
2387
        gen_op_shr32(val, val, tmp);
2388
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2389
}
2390

2391
static void expand_op_shl_im_cc(qOP *qop)
2392
{
2393
    expand_shift_im(qop, 0, 0);
2394
}
2395

2396
static void expand_op_shr_im_cc(qOP *qop)
2397
{
2398
    expand_shift_im(qop, 1, 0);
2399
}
2400

2401
static void expand_op_sar_im_cc(qOP *qop)
2402
{
2403
    expand_shift_im(qop, 1, 1);
2404
}
2405

2406
/* Expand a shift by register.  */
2407
/* ??? This gives incorrect answers for shifts by 0 or >= 32 */
2408
static inline void expand_shift_reg(qOP *qop, int right, int arith)
2409
{
2410
    int val;
2411
    int reg;
2412
    int shift;
2413
    int tmp;
2414

2415
    reg = qop->args[0];
2416
    shift = qop->args[1];
2417
    val = gen_new_qreg(QMODE_I32);
2418
    gen_op_mov32(val, reg);
2419
    gen_op_mov32(QREG_CC_DEST, val);
2420
    gen_op_mov32(QREG_CC_SRC, shift);
2421
    tmp = gen_new_qreg(QMODE_I32);
2422
    if (right) {
2423
        if (arith) {
2424
            gen_op_sar32(reg, val, shift);
2425
        } else {
2426
            gen_op_shr32(reg, val, shift);
2427
        }
2428
        gen_op_sub32(tmp, shift, gen_im32(1));
2429
    } else {
2430
        gen_op_shl32(reg, val, shift);
2431
        gen_op_sub32(tmp, gen_im32(31), shift);
2432
    }
2433
    gen_op_shl32(val, val, tmp);
2434
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2435
}
2436

2437
static void expand_op_shl_cc(qOP *qop)
2438
{
2439
    expand_shift_reg(qop, 0, 0);
2440
}
2441

2442
static void expand_op_shr_cc(qOP *qop)
2443
{
2444
    expand_shift_reg(qop, 1, 0);
2445
}
2446

2447
static void expand_op_sar_cc(qOP *qop)
2448
{
2449
    expand_shift_reg(qop, 1, 1);
2450
}
2451

2452
/* Set the Z flag to (arg0 & arg1) == 0.  */
2453
static void expand_op_btest(qOP *qop)
2454
{
2455
    int tmp;
2456
    int l1;
2457

2458
    l1 = gen_new_label();
2459
    tmp = gen_new_qreg(QMODE_I32);
2460
    gen_op_and32(tmp, qop->args[0], qop->args[1]);
2461
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
2462
    gen_op_jmp_nz32(tmp, l1);
2463
    gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
2464
    gen_op_label(l1);
2465
}
2466

2467
/* arg0 += arg1 + CC_X */
2468
static void expand_op_addx_cc(qOP *qop)
2469
{
2470
    int arg0 = qop->args[0];
2471
    int arg1 = qop->args[1];
2472
    int l1, l2;
2473
    
2474
    gen_op_add32 (arg0, arg0, arg1);
2475
    l1 = gen_new_label();
2476
    l2 = gen_new_label();
2477
    gen_op_jmp_z32(QREG_CC_X, l1);
2478
    gen_op_add32(arg0, arg0, gen_im32(1));
2479
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
2480
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2481
    gen_op_jmp(l2);
2482
    gen_set_label(l1);
2483
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
2484
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2485
    gen_set_label(l2);
2486
}
2487

2488
/* arg0 -= arg1 + CC_X */
2489
static void expand_op_subx_cc(qOP *qop)
2490
{
2491
    int arg0 = qop->args[0];
2492
    int arg1 = qop->args[1];
2493
    int l1, l2;
2494

2495
    l1 = gen_new_label();
2496
    l2 = gen_new_label();
2497
    gen_op_jmp_z32(QREG_CC_X, l1);
2498
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2499
    gen_op_sub32(arg0, arg0, gen_im32(1));
2500
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
2501
    gen_op_jmp(l2);
2502
    gen_set_label(l1);
2503
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2504
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
2505
    gen_set_label(l2);
2506
    gen_op_sub32 (arg0, arg0, arg1);
2507
}
2508

2509
/* Expand target specific ops to generic qops.  */
2510
static void expand_target_qops(void)
2511
{
2512
    qOP *qop;
2513
    qOP *next;
2514
    int c;
2515

2516
    /* Copy the list of qops, expanding target specific ops as we go.  */
2517
    qop = gen_first_qop;
2518
    gen_first_qop = NULL;
2519
    gen_last_qop = NULL;
2520
    for (; qop; qop = next) {
2521
        c = qop->opcode;
2522
        next = qop->next;
2523
        if (c < FIRST_TARGET_OP) {
2524
            qop->prev = gen_last_qop;
2525
            qop->next = NULL;
2526
            if (gen_last_qop)
2527
                gen_last_qop->next = qop;
2528
            else
2529
                gen_first_qop = qop;
2530
            gen_last_qop = qop;
2531
            continue;
2532
        }
2533
        switch (c) {
2534
#define DEF(name, nargs, barrier) \
2535
        case INDEX_op_##name: \
2536
            expand_op_##name(qop); \
2537
            break;
2538
#include "qop-target.def"
2539
#undef DEF
2540
        default:
2541
            cpu_abort(NULL, "Unexpanded target qop");
2542
        }
2543
    }
2544
}
2545

2546
/* ??? Implement this.  */
2547
static void
2548
optimize_flags(void)
2549
{
2550
}
2551
#endif
2552

    
2553
/* generate intermediate code for basic block 'tb'.  */
2554
static inline int
2555
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2556
                               int search_pc)
2557
{
2558
    DisasContext dc1, *dc = &dc1;
2559
    uint16_t *gen_opc_end;
2560
    int j, lj;
2561
    target_ulong pc_start;
2562
    int pc_offset;
2563
    int last_cc_op;
2564

    
2565
    /* generate intermediate code */
2566
    pc_start = tb->pc;
2567
       
2568
    dc->tb = tb;
2569

    
2570
    gen_opc_ptr = gen_opc_buf;
2571
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2572
    gen_opparam_ptr = gen_opparam_buf;
2573

    
2574
    dc->is_jmp = DISAS_NEXT;
2575
    dc->pc = pc_start;
2576
    dc->cc_op = CC_OP_DYNAMIC;
2577
    dc->singlestep_enabled = env->singlestep_enabled;
2578
    dc->fpcr = env->fpcr;
2579
    nb_gen_labels = 0;
2580
    lj = -1;
2581
    do {
2582
        free_qreg = 0;
2583
        pc_offset = dc->pc - pc_start;
2584
        gen_throws_exception = NULL;
2585
        if (env->nb_breakpoints > 0) {
2586
            for(j = 0; j < env->nb_breakpoints; j++) {
2587
                if (env->breakpoints[j] == dc->pc) {
2588
                    gen_exception(dc, dc->pc, EXCP_DEBUG);
2589
                    dc->is_jmp = DISAS_JUMP;
2590
                    break;
2591
                }
2592
            }
2593
            if (dc->is_jmp)
2594
                break;
2595
        }
2596
        if (search_pc) {
2597
            j = gen_opc_ptr - gen_opc_buf;
2598
            if (lj < j) {
2599
                lj++;
2600
                while (lj < j)
2601
                    gen_opc_instr_start[lj++] = 0;
2602
            }
2603
            gen_opc_pc[lj] = dc->pc;
2604
            gen_opc_instr_start[lj] = 1;
2605
        }
2606
        last_cc_op = dc->cc_op;
2607
        disas_m68k_insn(env, dc);
2608
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
2609
             !env->singlestep_enabled &&
2610
             (pc_offset) < (TARGET_PAGE_SIZE - 32));
2611

    
2612
    if (__builtin_expect(env->singlestep_enabled, 0)) {
2613
        /* Make sure the pc is updated, and raise a debug exception.  */
2614
        if (!dc->is_jmp) {
2615
            gen_flush_cc_op(dc);
2616
            gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
2617
        }
2618
        gen_op_raise_exception(EXCP_DEBUG);
2619
    } else {
2620
        switch(dc->is_jmp) {
2621
        case DISAS_NEXT:
2622
            gen_flush_cc_op(dc);
2623
            gen_jmp_tb(dc, 0, dc->pc);
2624
            break;
2625
        default:
2626
        case DISAS_JUMP:
2627
        case DISAS_UPDATE:
2628
            gen_flush_cc_op(dc);
2629
            /* indicate that the hash table must be used to find the next TB */
2630
            gen_op_mov32(QREG_T0, gen_im32(0));
2631
            gen_op_exit_tb();
2632
            break;
2633
        case DISAS_TB_JUMP:
2634
            /* nothing more to generate */
2635
            break;
2636
        }
2637
    }
2638
    *gen_opc_ptr = INDEX_op_end;
2639

    
2640
#ifdef DEBUG_DISAS
2641
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2642
        fprintf(logfile, "----------------\n");
2643
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2644
        target_disas(logfile, pc_start, dc->pc - pc_start, 0);
2645
        fprintf(logfile, "\n");
2646
        if (loglevel & (CPU_LOG_TB_OP)) {
2647
            fprintf(logfile, "OP:\n");
2648
            dump_ops(gen_opc_buf, gen_opparam_buf);
2649
            fprintf(logfile, "\n");
2650
        }
2651
    }
2652
#endif
2653
    if (search_pc) {
2654
        j = gen_opc_ptr - gen_opc_buf;
2655
        lj++;
2656
        while (lj <= j)
2657
            gen_opc_instr_start[lj++] = 0;
2658
        tb->size = 0;
2659
    } else {
2660
        tb->size = dc->pc - pc_start;
2661
    }
2662

    
2663
    //optimize_flags();
2664
    //expand_target_qops();
2665
    return 0;
2666
}
2667

    
2668
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2669
{
2670
    return gen_intermediate_code_internal(env, tb, 0);
2671
}
2672

    
2673
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2674
{
2675
    return gen_intermediate_code_internal(env, tb, 1);
2676
}
2677

    
2678
CPUM68KState *cpu_m68k_init(void)
2679
{
2680
    CPUM68KState *env;
2681

    
2682
    env = malloc(sizeof(CPUM68KState));
2683
    if (!env)
2684
        return NULL;
2685
    cpu_exec_init(env);
2686

    
2687
    memset(env, 0, sizeof(CPUM68KState));
2688
    /* ??? FP regs should be initialized to NaN.  */
2689
    cpu_single_env = env;
2690
    env->cc_op = CC_OP_FLAGS;
2691
    return env;
2692
}
2693

    
2694
void cpu_m68k_close(CPUM68KState *env)
2695
{
2696
    free(env);
2697
}
2698

    
2699
m68k_def_t *m68k_find_by_name(const char *name)
2700
{
2701
    m68k_def_t *def;
2702

    
2703
    def = m68k_cpu_defs;
2704
    while (def->name)
2705
      {
2706
        if (strcmp(def->name, name) == 0)
2707
            return def;
2708
        def++;
2709
      }
2710
    return NULL;
2711
}
2712

    
2713
void cpu_m68k_register(CPUM68KState *env, m68k_def_t *def)
2714
{
2715
    register_m68k_insns(def);
2716
}
2717

    
2718
void cpu_dump_state(CPUState *env, FILE *f, 
2719
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2720
                    int flags)
2721
{
2722
    int i;
2723
    uint16_t sr;
2724
    CPU_DoubleU u;
2725
    for (i = 0; i < 8; i++)
2726
      {
2727
        u.d = env->fregs[i];
2728
        cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
2729
                     i, env->dregs[i], i, env->aregs[i],
2730
                     i, u.l.upper, u.l.lower, u.d);
2731
      }
2732
    cpu_fprintf (f, "PC = %08x   ", env->pc);
2733
    sr = env->sr;
2734
    cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
2735
                 (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
2736
                 (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
2737
    cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
2738
}
2739

    
2740
/* ??? */
2741
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2742
{
2743
    return addr;
2744
}
2745

    
2746
#if defined(CONFIG_USER_ONLY) 
2747

    
2748
int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
2749
                               int is_user, int is_softmmu)
2750
{
2751
    env->exception_index = EXCP_ACCESS;
2752
    env->mmu.ar = address;
2753
    return 1;
2754
}
2755

    
2756
#else
2757

    
2758
#error not implemented
2759

    
2760
#endif