Statistics
| Branch: | Revision:

root / target-m68k / translate.c @ d2856f1a

History | View | Annotate | Download (80 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 "tcg-op.h"
32
#include "m68k-qreg.h"
33

    
34
//#define DEBUG_DISPATCH 1
35

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

    
44
/* internal defines */
45
typedef struct DisasContext {
46
    CPUM68KState *env;
47
    target_ulong insn_pc; /* Start of the current instruction.  */
48
    target_ulong pc;
49
    int is_jmp;
50
    int cc_op;
51
    int user;
52
    uint32_t fpcr;
53
    struct TranslationBlock *tb;
54
    int singlestep_enabled;
55
    int is_mem;
56
} DisasContext;
57

    
58
#define DISAS_JUMP_NEXT 4
59

    
60
#if defined(CONFIG_USER_ONLY)
61
#define IS_USER(s) 1
62
#else
63
#define IS_USER(s) s->user
64
#endif
65

    
66
/* XXX: move that elsewhere */
67
/* ??? Fix exceptions.  */
68
static void *gen_throws_exception;
69
#define gen_last_qop NULL
70

    
71
extern FILE *logfile;
72
extern int loglevel;
73

    
74
#if defined(CONFIG_USER_ONLY)
75
#define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
76
#define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
77
#else
78
#define gen_st(s, name, addr, val) do { \
79
    if (IS_USER(s)) \
80
        gen_op_st##name##_user(addr, val); \
81
    else \
82
        gen_op_st##name##_kernel(addr, val); \
83
    } while (0)
84
#define gen_ld(s, name, val, addr) do { \
85
    if (IS_USER(s)) \
86
        gen_op_ld##name##_user(val, addr); \
87
    else \
88
        gen_op_ld##name##_kernel(val, addr); \
89
    } while (0)
90
#endif
91

    
92
#include "op-hacks.h"
93

    
94
#define OS_BYTE 0
95
#define OS_WORD 1
96
#define OS_LONG 2
97
#define OS_SINGLE 4
98
#define OS_DOUBLE 5
99

    
100
#define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
101
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
102
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
103

    
104
typedef void (*disas_proc)(DisasContext *, uint16_t);
105

    
106
#ifdef DEBUG_DISPATCH
107
#define DISAS_INSN(name) \
108
  static void real_disas_##name (DisasContext *s, uint16_t insn); \
109
  static void disas_##name (DisasContext *s, uint16_t insn) { \
110
    if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
111
    real_disas_##name(s, insn); } \
112
  static void real_disas_##name (DisasContext *s, uint16_t insn)
113
#else
114
#define DISAS_INSN(name) \
115
  static void disas_##name (DisasContext *s, uint16_t insn)
116
#endif
117

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

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

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

    
196
/* Read a 32-bit immediate constant.  */
197
static inline uint32_t read_im32(DisasContext *s)
198
{
199
    uint32_t im;
200
    im = ((uint32_t)lduw_code(s->pc)) << 16;
201
    s->pc += 2;
202
    im |= lduw_code(s->pc);
203
    s->pc += 2;
204
    return im;
205
}
206

    
207
/* Calculate and address index.  */
208
static int gen_addr_index(uint16_t ext, int tmp)
209
{
210
    int add;
211
    int scale;
212

    
213
    add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
214
    if ((ext & 0x800) == 0) {
215
        gen_op_ext16s32(tmp, add);
216
        add = tmp;
217
    }
218
    scale = (ext >> 9) & 3;
219
    if (scale != 0) {
220
        gen_op_shl32(tmp, add, gen_im32(scale));
221
        add = tmp;
222
    }
223
    return add;
224
}
225

    
226
/* Handle a base + index + displacement effective addresss.  A base of
227
   -1 means pc-relative.  */
228
static int gen_lea_indexed(DisasContext *s, int opsize, int base)
229
{
230
    uint32_t offset;
231
    uint16_t ext;
232
    int add;
233
    int tmp;
234
    uint32_t bd, od;
235

    
236
    offset = s->pc;
237
    ext = lduw_code(s->pc);
238
    s->pc += 2;
239

    
240
    if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
241
        return -1;
242

    
243
    if (ext & 0x100) {
244
        /* full extension word format */
245
        if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
246
            return -1;
247

    
248
        if ((ext & 0x30) > 0x10) {
249
            /* base displacement */
250
            if ((ext & 0x30) == 0x20) {
251
                bd = (int16_t)lduw_code(s->pc);
252
                s->pc += 2;
253
            } else {
254
                bd = read_im32(s);
255
            }
256
        } else {
257
            bd = 0;
258
        }
259
        tmp = gen_new_qreg(QMODE_I32);
260
        if ((ext & 0x44) == 0) {
261
            /* pre-index */
262
            add = gen_addr_index(ext, tmp);
263
        } else {
264
            add = QREG_NULL;
265
        }
266
        if ((ext & 0x80) == 0) {
267
            /* base not suppressed */
268
            if (base == -1) {
269
                base = gen_im32(offset + bd);
270
                bd = 0;
271
            }
272
            if (add) {
273
                gen_op_add32(tmp, add, base);
274
                add = tmp;
275
            } else {
276
                add = base;
277
            }
278
        }
279
        if (add) {
280
            if (bd != 0) {
281
                gen_op_add32(tmp, add, gen_im32(bd));
282
                add = tmp;
283
            }
284
        } else {
285
            add = gen_im32(bd);
286
        }
287
        if ((ext & 3) != 0) {
288
            /* memory indirect */
289
            base = gen_load(s, OS_LONG, add, 0);
290
            if ((ext & 0x44) == 4) {
291
                add = gen_addr_index(ext, tmp);
292
                gen_op_add32(tmp, add, base);
293
                add = tmp;
294
            } else {
295
                add = base;
296
            }
297
            if ((ext & 3) > 1) {
298
                /* outer displacement */
299
                if ((ext & 3) == 2) {
300
                    od = (int16_t)lduw_code(s->pc);
301
                    s->pc += 2;
302
                } else {
303
                    od = read_im32(s);
304
                }
305
            } else {
306
                od = 0;
307
            }
308
            if (od != 0) {
309
                gen_op_add32(tmp, add, gen_im32(od));
310
                add = tmp;
311
            }
312
        }
313
    } else {
314
        /* brief extension word format */
315
        tmp = gen_new_qreg(QMODE_I32);
316
        add = gen_addr_index(ext, tmp);
317
        if (base != -1) {
318
            gen_op_add32(tmp, add, base);
319
            if ((int8_t)ext)
320
                gen_op_add32(tmp, tmp, gen_im32((int8_t)ext));
321
        } else {
322
            gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
323
        }
324
        add = tmp;
325
    }
326
    return add;
327
}
328

    
329
/* Update the CPU env CC_OP state.  */
330
static inline void gen_flush_cc_op(DisasContext *s)
331
{
332
    if (s->cc_op != CC_OP_DYNAMIC)
333
        gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
334
}
335

    
336
/* Evaluate all the CC flags.  */
337
static inline void gen_flush_flags(DisasContext *s)
338
{
339
    if (s->cc_op == CC_OP_FLAGS)
340
        return;
341
    gen_flush_cc_op(s);
342
    gen_op_flush_flags();
343
    s->cc_op = CC_OP_FLAGS;
344
}
345

    
346
static inline int opsize_bytes(int opsize)
347
{
348
    switch (opsize) {
349
    case OS_BYTE: return 1;
350
    case OS_WORD: return 2;
351
    case OS_LONG: return 4;
352
    case OS_SINGLE: return 4;
353
    case OS_DOUBLE: return 8;
354
    default:
355
        qemu_assert(0, "bad operand size");
356
    }
357
}
358

    
359
/* Assign value to a register.  If the width is less than the register width
360
   only the low part of the register is set.  */
361
static void gen_partset_reg(int opsize, int reg, int val)
362
{
363
    int tmp;
364
    switch (opsize) {
365
    case OS_BYTE:
366
        gen_op_and32(reg, reg, gen_im32(0xffffff00));
367
        tmp = gen_new_qreg(QMODE_I32);
368
        gen_op_and32(tmp, val, gen_im32(0xff));
369
        gen_op_or32(reg, reg, tmp);
370
        break;
371
    case OS_WORD:
372
        gen_op_and32(reg, reg, gen_im32(0xffff0000));
373
        tmp = gen_new_qreg(QMODE_I32);
374
        gen_op_and32(tmp, val, gen_im32(0xffff));
375
        gen_op_or32(reg, reg, tmp);
376
        break;
377
    case OS_LONG:
378
        gen_op_mov32(reg, val);
379
        break;
380
    case OS_SINGLE:
381
        gen_op_pack_32_f32(reg, val);
382
        break;
383
    default:
384
        qemu_assert(0, "Bad operand size");
385
        break;
386
    }
387
}
388

    
389
/* Sign or zero extend a value.  */
390
static inline int gen_extend(int val, int opsize, int sign)
391
{
392
    int tmp;
393

    
394
    switch (opsize) {
395
    case OS_BYTE:
396
        tmp = gen_new_qreg(QMODE_I32);
397
        if (sign)
398
            gen_op_ext8s32(tmp, val);
399
        else
400
            gen_op_ext8u32(tmp, val);
401
        break;
402
    case OS_WORD:
403
        tmp = gen_new_qreg(QMODE_I32);
404
        if (sign)
405
            gen_op_ext16s32(tmp, val);
406
        else
407
            gen_op_ext16u32(tmp, val);
408
        break;
409
    case OS_LONG:
410
        tmp = val;
411
        break;
412
    case OS_SINGLE:
413
        tmp = gen_new_qreg(QMODE_F32);
414
        gen_op_pack_f32_32(tmp, val);
415
        break;
416
    default:
417
        qemu_assert(0, "Bad operand size");
418
    }
419
    return tmp;
420
}
421

    
422
/* Generate code for an "effective address".  Does not adjust the base
423
   register for autoincrememnt addressing modes.  */
424
static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
425
{
426
    int reg;
427
    int tmp;
428
    uint16_t ext;
429
    uint32_t offset;
430

    
431
    reg = insn & 7;
432
    switch ((insn >> 3) & 7) {
433
    case 0: /* Data register direct.  */
434
    case 1: /* Address register direct.  */
435
        return -1;
436
    case 2: /* Indirect register */
437
    case 3: /* Indirect postincrement.  */
438
        reg += QREG_A0;
439
        return reg;
440
    case 4: /* Indirect predecrememnt.  */
441
        reg += QREG_A0;
442
        tmp = gen_new_qreg(QMODE_I32);
443
        gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
444
        return tmp;
445
    case 5: /* Indirect displacement.  */
446
        reg += QREG_A0;
447
        tmp = gen_new_qreg(QMODE_I32);
448
        ext = lduw_code(s->pc);
449
        s->pc += 2;
450
        gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
451
        return tmp;
452
    case 6: /* Indirect index + displacement.  */
453
        reg += QREG_A0;
454
        return gen_lea_indexed(s, opsize, reg);
455
    case 7: /* Other */
456
        switch (reg) {
457
        case 0: /* Absolute short.  */
458
            offset = ldsw_code(s->pc);
459
            s->pc += 2;
460
            return gen_im32(offset);
461
        case 1: /* Absolute long.  */
462
            offset = read_im32(s);
463
            return gen_im32(offset);
464
        case 2: /* pc displacement  */
465
            tmp = gen_new_qreg(QMODE_I32);
466
            offset = s->pc;
467
            offset += ldsw_code(s->pc);
468
            s->pc += 2;
469
            return gen_im32(offset);
470
        case 3: /* pc index+displacement.  */
471
            return gen_lea_indexed(s, opsize, -1);
472
        case 4: /* Immediate.  */
473
        default:
474
            return -1;
475
        }
476
    }
477
    /* Should never happen.  */
478
    return -1;
479
}
480

    
481
/* Helper function for gen_ea. Reuse the computed address between the
482
   for read/write operands.  */
483
static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
484
                              int val, int *addrp)
485
{
486
    int tmp;
487

    
488
    if (addrp && val > 0) {
489
        tmp = *addrp;
490
    } else {
491
        tmp = gen_lea(s, insn, opsize);
492
        if (tmp == -1)
493
            return -1;
494
        if (addrp)
495
            *addrp = tmp;
496
    }
497
    return gen_ldst(s, opsize, tmp, val);
498
}
499

    
500
/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
501
   a write otherwise it is a read (0 == sign extend, -1 == zero extend).
502
   ADDRP is non-null for readwrite operands.  */
503
static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
504
                  int *addrp)
505
{
506
    int reg;
507
    int result;
508
    uint32_t offset;
509

    
510
    reg = insn & 7;
511
    switch ((insn >> 3) & 7) {
512
    case 0: /* Data register direct.  */
513
        reg += QREG_D0;
514
        if (val > 0) {
515
            gen_partset_reg(opsize, reg, val);
516
            return 0;
517
        } else {
518
            return gen_extend(reg, opsize, val);
519
        }
520
    case 1: /* Address register direct.  */
521
        reg += QREG_A0;
522
        if (val > 0) {
523
            gen_op_mov32(reg, val);
524
            return 0;
525
        } else {
526
            return gen_extend(reg, opsize, val);
527
        }
528
    case 2: /* Indirect register */
529
        reg += QREG_A0;
530
        return gen_ldst(s, opsize, reg, val);
531
    case 3: /* Indirect postincrement.  */
532
        reg += QREG_A0;
533
        result = gen_ldst(s, opsize, reg, val);
534
        /* ??? This is not exception safe.  The instruction may still
535
           fault after this point.  */
536
        if (val > 0 || !addrp)
537
            gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
538
        return result;
539
    case 4: /* Indirect predecrememnt.  */
540
        {
541
            int tmp;
542
            if (addrp && val > 0) {
543
                tmp = *addrp;
544
            } else {
545
                tmp = gen_lea(s, insn, opsize);
546
                if (tmp == -1)
547
                    return -1;
548
                if (addrp)
549
                    *addrp = tmp;
550
            }
551
            result = gen_ldst(s, opsize, tmp, val);
552
            /* ??? This is not exception safe.  The instruction may still
553
               fault after this point.  */
554
            if (val > 0 || !addrp) {
555
                reg += QREG_A0;
556
                gen_op_mov32(reg, tmp);
557
            }
558
        }
559
        return result;
560
    case 5: /* Indirect displacement.  */
561
    case 6: /* Indirect index + displacement.  */
562
        return gen_ea_once(s, insn, opsize, val, addrp);
563
    case 7: /* Other */
564
        switch (reg) {
565
        case 0: /* Absolute short.  */
566
        case 1: /* Absolute long.  */
567
        case 2: /* pc displacement  */
568
        case 3: /* pc index+displacement.  */
569
            return gen_ea_once(s, insn, opsize, val, addrp);
570
        case 4: /* Immediate.  */
571
            /* Sign extend values for consistency.  */
572
            switch (opsize) {
573
            case OS_BYTE:
574
                if (val)
575
                    offset = ldsb_code(s->pc + 1);
576
                else
577
                    offset = ldub_code(s->pc + 1);
578
                s->pc += 2;
579
                break;
580
            case OS_WORD:
581
                if (val)
582
                    offset = ldsw_code(s->pc);
583
                else
584
                    offset = lduw_code(s->pc);
585
                s->pc += 2;
586
                break;
587
            case OS_LONG:
588
                offset = read_im32(s);
589
                break;
590
            default:
591
                qemu_assert(0, "Bad immediate operand");
592
            }
593
            return gen_im32(offset);
594
        default:
595
            return -1;
596
        }
597
    }
598
    /* Should never happen.  */
599
    return -1;
600
}
601

    
602
static void gen_logic_cc(DisasContext *s, int val)
603
{
604
    gen_op_logic_cc(val);
605
    s->cc_op = CC_OP_LOGIC;
606
}
607

    
608
static void gen_jmpcc(DisasContext *s, int cond, int l1)
609
{
610
    int tmp;
611

    
612
    gen_flush_flags(s);
613
    switch (cond) {
614
    case 0: /* T */
615
        gen_op_jmp_im(l1);
616
        break;
617
    case 1: /* F */
618
        break;
619
    case 2: /* HI (!C && !Z) */
620
        tmp = gen_new_qreg(QMODE_I32);
621
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
622
        gen_op_jmp_z32(tmp, l1);
623
        break;
624
    case 3: /* LS (C || Z) */
625
        tmp = gen_new_qreg(QMODE_I32);
626
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
627
        gen_op_jmp_nz32(tmp, l1);
628
        break;
629
    case 4: /* CC (!C) */
630
        tmp = gen_new_qreg(QMODE_I32);
631
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
632
        gen_op_jmp_z32(tmp, l1);
633
        break;
634
    case 5: /* CS (C) */
635
        tmp = gen_new_qreg(QMODE_I32);
636
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
637
        gen_op_jmp_nz32(tmp, l1);
638
        break;
639
    case 6: /* NE (!Z) */
640
        tmp = gen_new_qreg(QMODE_I32);
641
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
642
        gen_op_jmp_z32(tmp, l1);
643
        break;
644
    case 7: /* EQ (Z) */
645
        tmp = gen_new_qreg(QMODE_I32);
646
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
647
        gen_op_jmp_nz32(tmp, l1);
648
        break;
649
    case 8: /* VC (!V) */
650
        tmp = gen_new_qreg(QMODE_I32);
651
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
652
        gen_op_jmp_z32(tmp, l1);
653
        break;
654
    case 9: /* VS (V) */
655
        tmp = gen_new_qreg(QMODE_I32);
656
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
657
        gen_op_jmp_nz32(tmp, l1);
658
        break;
659
    case 10: /* PL (!N) */
660
        tmp = gen_new_qreg(QMODE_I32);
661
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
662
        gen_op_jmp_z32(tmp, l1);
663
        break;
664
    case 11: /* MI (N) */
665
        tmp = gen_new_qreg(QMODE_I32);
666
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
667
        gen_op_jmp_nz32(tmp, l1);
668
        break;
669
    case 12: /* GE (!(N ^ V)) */
670
        tmp = gen_new_qreg(QMODE_I32);
671
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
672
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
673
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
674
        gen_op_jmp_z32(tmp, l1);
675
        break;
676
    case 13: /* LT (N ^ V) */
677
        tmp = gen_new_qreg(QMODE_I32);
678
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
679
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
680
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
681
        gen_op_jmp_nz32(tmp, l1);
682
        break;
683
    case 14: /* GT (!(Z || (N ^ V))) */
684
        {
685
            int l2;
686
            l2 = gen_new_label();
687
            tmp = gen_new_qreg(QMODE_I32);
688
            gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
689
            gen_op_jmp_nz32(tmp, l2);
690
            tmp = gen_new_qreg(QMODE_I32);
691
            gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
692
            gen_op_xor32(tmp, tmp, QREG_CC_DEST);
693
            gen_op_and32(tmp, tmp, gen_im32(CCF_V));
694
            gen_op_jmp_nz32(tmp, l2);
695
            gen_op_jmp_im(l1);
696
            gen_set_label(l2);
697
        }
698
        break;
699
    case 15: /* LE (Z || (N ^ V)) */
700
        tmp = gen_new_qreg(QMODE_I32);
701
        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
702
        gen_op_jmp_nz32(tmp, l1);
703
        tmp = gen_new_qreg(QMODE_I32);
704
        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
705
        gen_op_xor32(tmp, tmp, QREG_CC_DEST);
706
        gen_op_and32(tmp, tmp, gen_im32(CCF_V));
707
        gen_op_jmp_nz32(tmp, l1);
708
        break;
709
    default:
710
        /* Should ever happen.  */
711
        abort();
712
    }
713
}
714

    
715
DISAS_INSN(scc)
716
{
717
    int l1;
718
    int cond;
719
    int reg;
720

    
721
    l1 = gen_new_label();
722
    cond = (insn >> 8) & 0xf;
723
    reg = DREG(insn, 0);
724
    gen_op_and32(reg, reg, gen_im32(0xffffff00));
725
    gen_jmpcc(s, cond ^ 1, l1);
726
    gen_op_or32(reg, reg, gen_im32(0xff));
727
    gen_set_label(l1);
728
}
729

    
730
/* Force a TB lookup after an instruction that changes the CPU state.  */
731
static void gen_lookup_tb(DisasContext *s)
732
{
733
    gen_flush_cc_op(s);
734
    gen_op_mov32(QREG_PC, gen_im32(s->pc));
735
    s->is_jmp = DISAS_UPDATE;
736
}
737

    
738
/* Generate a jump to to the address in qreg DEST.  */
739
static void gen_jmp(DisasContext *s, int dest)
740
{
741
    gen_flush_cc_op(s);
742
    gen_op_mov32(QREG_PC, dest);
743
    s->is_jmp = DISAS_JUMP;
744
}
745

    
746
static void gen_exception(DisasContext *s, uint32_t where, int nr)
747
{
748
    gen_flush_cc_op(s);
749
    gen_jmp(s, gen_im32(where));
750
    gen_op_raise_exception(nr);
751
}
752

    
753
static inline void gen_addr_fault(DisasContext *s)
754
{
755
    gen_exception(s, s->insn_pc, EXCP_ADDRESS);
756
}
757

    
758
#define SRC_EA(result, opsize, val, addrp) do { \
759
    result = gen_ea(s, insn, opsize, val, addrp); \
760
    if (result == -1) { \
761
        gen_addr_fault(s); \
762
        return; \
763
    } \
764
    } while (0)
765

    
766
#define DEST_EA(insn, opsize, val, addrp) do { \
767
    int ea_result = gen_ea(s, insn, opsize, val, addrp); \
768
    if (ea_result == -1) { \
769
        gen_addr_fault(s); \
770
        return; \
771
    } \
772
    } while (0)
773

    
774
/* Generate a jump to an immediate address.  */
775
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
776
{
777
    TranslationBlock *tb;
778

    
779
    tb = s->tb;
780
    if (__builtin_expect (s->singlestep_enabled, 0)) {
781
        gen_exception(s, dest, EXCP_DEBUG);
782
    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
783
               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
784
        tcg_gen_goto_tb(n);
785
        gen_op_mov32(QREG_PC, gen_im32(dest));
786
        tcg_gen_exit_tb((long)tb + n);
787
    } else {
788
        gen_jmp(s, gen_im32(dest));
789
        tcg_gen_exit_tb(0);
790
    }
791
    s->is_jmp = DISAS_TB_JUMP;
792
}
793

    
794
DISAS_INSN(undef_mac)
795
{
796
    gen_exception(s, s->pc - 2, EXCP_LINEA);
797
}
798

    
799
DISAS_INSN(undef_fpu)
800
{
801
    gen_exception(s, s->pc - 2, EXCP_LINEF);
802
}
803

    
804
DISAS_INSN(undef)
805
{
806
    gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
807
    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
808
              insn, s->pc - 2);
809
}
810

    
811
DISAS_INSN(mulw)
812
{
813
    int reg;
814
    int tmp;
815
    int src;
816
    int sign;
817

    
818
    sign = (insn & 0x100) != 0;
819
    reg = DREG(insn, 9);
820
    tmp = gen_new_qreg(QMODE_I32);
821
    if (sign)
822
        gen_op_ext16s32(tmp, reg);
823
    else
824
        gen_op_ext16u32(tmp, reg);
825
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
826
    gen_op_mul32(tmp, tmp, src);
827
    gen_op_mov32(reg, tmp);
828
    /* Unlike m68k, coldfire always clears the overflow bit.  */
829
    gen_logic_cc(s, tmp);
830
}
831

    
832
DISAS_INSN(divw)
833
{
834
    int reg;
835
    int tmp;
836
    int src;
837
    int sign;
838

    
839
    sign = (insn & 0x100) != 0;
840
    reg = DREG(insn, 9);
841
    if (sign) {
842
        gen_op_ext16s32(QREG_DIV1, reg);
843
    } else {
844
        gen_op_ext16u32(QREG_DIV1, reg);
845
    }
846
    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
847
    gen_op_mov32(QREG_DIV2, src);
848
    if (sign) {
849
        gen_op_divs(1);
850
    } else {
851
        gen_op_divu(1);
852
    }
853

    
854
    tmp = gen_new_qreg(QMODE_I32);
855
    src = gen_new_qreg(QMODE_I32);
856
    gen_op_ext16u32(tmp, QREG_DIV1);
857
    gen_op_shl32(src, QREG_DIV2, gen_im32(16));
858
    gen_op_or32(reg, tmp, src);
859
    gen_op_flags_set();
860
    s->cc_op = CC_OP_FLAGS;
861
}
862

    
863
DISAS_INSN(divl)
864
{
865
    int num;
866
    int den;
867
    int reg;
868
    uint16_t ext;
869

    
870
    ext = lduw_code(s->pc);
871
    s->pc += 2;
872
    if (ext & 0x87f8) {
873
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
874
        return;
875
    }
876
    num = DREG(ext, 12);
877
    reg = DREG(ext, 0);
878
    gen_op_mov32(QREG_DIV1, num);
879
    SRC_EA(den, OS_LONG, 0, NULL);
880
    gen_op_mov32(QREG_DIV2, den);
881
    if (ext & 0x0800) {
882
        gen_op_divs(2);
883
    } else {
884
        gen_op_divu(2);
885
    }
886
    if (num == reg) {
887
        /* div */
888
        gen_op_mov32 (reg, QREG_DIV1);
889
    } else {
890
        /* rem */
891
        gen_op_mov32 (reg, QREG_DIV2);
892
    }
893
    gen_op_flags_set();
894
    s->cc_op = CC_OP_FLAGS;
895
}
896

    
897
DISAS_INSN(addsub)
898
{
899
    int reg;
900
    int dest;
901
    int src;
902
    int tmp;
903
    int addr;
904
    int add;
905

    
906
    add = (insn & 0x4000) != 0;
907
    reg = DREG(insn, 9);
908
    dest = gen_new_qreg(QMODE_I32);
909
    if (insn & 0x100) {
910
        SRC_EA(tmp, OS_LONG, 0, &addr);
911
        src = reg;
912
    } else {
913
        tmp = reg;
914
        SRC_EA(src, OS_LONG, 0, NULL);
915
    }
916
    if (add) {
917
        gen_op_add32(dest, tmp, src);
918
        gen_op_update_xflag_lt(dest, src);
919
        s->cc_op = CC_OP_ADD;
920
    } else {
921
        gen_op_update_xflag_lt(tmp, src);
922
        gen_op_sub32(dest, tmp, src);
923
        s->cc_op = CC_OP_SUB;
924
    }
925
    gen_op_update_cc_add(dest, src);
926
    if (insn & 0x100) {
927
        DEST_EA(insn, OS_LONG, dest, &addr);
928
    } else {
929
        gen_op_mov32(reg, dest);
930
    }
931
}
932

    
933

    
934
/* Reverse the order of the bits in REG.  */
935
DISAS_INSN(bitrev)
936
{
937
    int val;
938
    int tmp1;
939
    int tmp2;
940
    int reg;
941

    
942
    val = gen_new_qreg(QMODE_I32);
943
    tmp1 = gen_new_qreg(QMODE_I32);
944
    tmp2 = gen_new_qreg(QMODE_I32);
945
    reg = DREG(insn, 0);
946
    gen_op_mov32(val, reg);
947
    /* Reverse bits within each nibble.  */
948
    gen_op_shl32(tmp1, val, gen_im32(3));
949
    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
950
    gen_op_shl32(tmp2, val, gen_im32(1));
951
    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
952
    gen_op_or32(tmp1, tmp1, tmp2);
953
    gen_op_shr32(tmp2, val, gen_im32(1));
954
    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
955
    gen_op_or32(tmp1, tmp1, tmp2);
956
    gen_op_shr32(tmp2, val, gen_im32(3));
957
    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
958
    gen_op_or32(tmp1, tmp1, tmp2);
959
    /* Reverse nibbles withing bytes.  */
960
    gen_op_shl32(val, tmp1, gen_im32(4));
961
    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
962
    gen_op_shr32(tmp2, tmp1, gen_im32(4));
963
    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
964
    gen_op_or32(val, val, tmp2);
965
    /* Reverse bytes.  */
966
    gen_op_bswap32(reg, val);
967
    gen_op_mov32(reg, val);
968
}
969

    
970
DISAS_INSN(bitop_reg)
971
{
972
    int opsize;
973
    int op;
974
    int src1;
975
    int src2;
976
    int tmp;
977
    int addr;
978
    int dest;
979

    
980
    if ((insn & 0x38) != 0)
981
        opsize = OS_BYTE;
982
    else
983
        opsize = OS_LONG;
984
    op = (insn >> 6) & 3;
985
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
986
    src2 = DREG(insn, 9);
987
    dest = gen_new_qreg(QMODE_I32);
988

    
989
    gen_flush_flags(s);
990
    tmp = gen_new_qreg(QMODE_I32);
991
    if (opsize == OS_BYTE)
992
        gen_op_and32(tmp, src2, gen_im32(7));
993
    else
994
        gen_op_and32(tmp, src2, gen_im32(31));
995
    src2 = tmp;
996
    tmp = gen_new_qreg(QMODE_I32);
997
    gen_op_shl32(tmp, gen_im32(1), src2);
998

    
999
    gen_op_btest(src1, tmp);
1000
    switch (op) {
1001
    case 1: /* bchg */
1002
        gen_op_xor32(dest, src1, tmp);
1003
        break;
1004
    case 2: /* bclr */
1005
        gen_op_not32(tmp, tmp);
1006
        gen_op_and32(dest, src1, tmp);
1007
        break;
1008
    case 3: /* bset */
1009
        gen_op_or32(dest, src1, tmp);
1010
        break;
1011
    default: /* btst */
1012
        break;
1013
    }
1014
    if (op)
1015
        DEST_EA(insn, opsize, dest, &addr);
1016
}
1017

    
1018
DISAS_INSN(sats)
1019
{
1020
    int reg;
1021
    int tmp;
1022
    int l1;
1023

    
1024
    reg = DREG(insn, 0);
1025
    tmp = gen_new_qreg(QMODE_I32);
1026
    gen_flush_flags(s);
1027
    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
1028
    l1 = gen_new_label();
1029
    gen_op_jmp_z32(tmp, l1);
1030
    tmp = gen_new_qreg(QMODE_I32);
1031
    gen_op_shr32(tmp, reg, gen_im32(31));
1032
    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
1033
    gen_op_mov32(reg, tmp);
1034
    gen_set_label(l1);
1035
    gen_logic_cc(s, tmp);
1036
}
1037

    
1038
static void gen_push(DisasContext *s, int val)
1039
{
1040
    int tmp;
1041

    
1042
    tmp = gen_new_qreg(QMODE_I32);
1043
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1044
    gen_store(s, OS_LONG, tmp, val);
1045
    gen_op_mov32(QREG_SP, tmp);
1046
}
1047

    
1048
DISAS_INSN(movem)
1049
{
1050
    int addr;
1051
    int i;
1052
    uint16_t mask;
1053
    int reg;
1054
    int tmp;
1055
    int is_load;
1056

    
1057
    mask = lduw_code(s->pc);
1058
    s->pc += 2;
1059
    tmp = gen_lea(s, insn, OS_LONG);
1060
    if (tmp == -1) {
1061
        gen_addr_fault(s);
1062
        return;
1063
    }
1064
    addr = gen_new_qreg(QMODE_I32);
1065
    gen_op_mov32(addr, tmp);
1066
    is_load = ((insn & 0x0400) != 0);
1067
    for (i = 0; i < 16; i++, mask >>= 1) {
1068
        if (mask & 1) {
1069
            if (i < 8)
1070
                reg = DREG(i, 0);
1071
            else
1072
                reg = AREG(i, 0);
1073
            if (is_load) {
1074
                tmp = gen_load(s, OS_LONG, addr, 0);
1075
                gen_op_mov32(reg, tmp);
1076
            } else {
1077
                gen_store(s, OS_LONG, addr, reg);
1078
            }
1079
            if (mask != 1)
1080
                gen_op_add32(addr, addr, gen_im32(4));
1081
        }
1082
    }
1083
}
1084

    
1085
DISAS_INSN(bitop_im)
1086
{
1087
    int opsize;
1088
    int op;
1089
    int src1;
1090
    uint32_t mask;
1091
    int bitnum;
1092
    int tmp;
1093
    int addr;
1094
    int dest;
1095

    
1096
    if ((insn & 0x38) != 0)
1097
        opsize = OS_BYTE;
1098
    else
1099
        opsize = OS_LONG;
1100
    op = (insn >> 6) & 3;
1101

    
1102
    bitnum = lduw_code(s->pc);
1103
    s->pc += 2;
1104
    if (bitnum & 0xff00) {
1105
        disas_undef(s, insn);
1106
        return;
1107
    }
1108

    
1109
    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1110

    
1111
    gen_flush_flags(s);
1112
    tmp = gen_new_qreg(QMODE_I32);
1113
    if (opsize == OS_BYTE)
1114
        bitnum &= 7;
1115
    else
1116
        bitnum &= 31;
1117
    mask = 1 << bitnum;
1118

    
1119
    gen_op_btest(src1, gen_im32(mask));
1120
    if (op)
1121
        dest = gen_new_qreg(QMODE_I32);
1122
    else
1123
        dest = -1;
1124

    
1125
    switch (op) {
1126
    case 1: /* bchg */
1127
        gen_op_xor32(dest, src1, gen_im32(mask));
1128
        break;
1129
    case 2: /* bclr */
1130
        gen_op_and32(dest, src1, gen_im32(~mask));
1131
        break;
1132
    case 3: /* bset */
1133
        gen_op_or32(dest, src1, gen_im32(mask));
1134
        break;
1135
    default: /* btst */
1136
        break;
1137
    }
1138
    if (op)
1139
        DEST_EA(insn, opsize, dest, &addr);
1140
}
1141

    
1142
DISAS_INSN(arith_im)
1143
{
1144
    int op;
1145
    int src1;
1146
    int dest;
1147
    int src2;
1148
    int addr;
1149

    
1150
    op = (insn >> 9) & 7;
1151
    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1152
    src2 = gen_im32(read_im32(s));
1153
    dest = gen_new_qreg(QMODE_I32);
1154
    switch (op) {
1155
    case 0: /* ori */
1156
        gen_op_or32(dest, src1, src2);
1157
        gen_logic_cc(s, dest);
1158
        break;
1159
    case 1: /* andi */
1160
        gen_op_and32(dest, src1, src2);
1161
        gen_logic_cc(s, dest);
1162
        break;
1163
    case 2: /* subi */
1164
        gen_op_mov32(dest, src1);
1165
        gen_op_update_xflag_lt(dest, src2);
1166
        gen_op_sub32(dest, dest, src2);
1167
        gen_op_update_cc_add(dest, src2);
1168
        s->cc_op = CC_OP_SUB;
1169
        break;
1170
    case 3: /* addi */
1171
        gen_op_mov32(dest, src1);
1172
        gen_op_add32(dest, dest, src2);
1173
        gen_op_update_cc_add(dest, src2);
1174
        gen_op_update_xflag_lt(dest, src2);
1175
        s->cc_op = CC_OP_ADD;
1176
        break;
1177
    case 5: /* eori */
1178
        gen_op_xor32(dest, src1, src2);
1179
        gen_logic_cc(s, dest);
1180
        break;
1181
    case 6: /* cmpi */
1182
        gen_op_mov32(dest, src1);
1183
        gen_op_sub32(dest, dest, src2);
1184
        gen_op_update_cc_add(dest, src2);
1185
        s->cc_op = CC_OP_SUB;
1186
        break;
1187
    default:
1188
        abort();
1189
    }
1190
    if (op != 6) {
1191
        DEST_EA(insn, OS_LONG, dest, &addr);
1192
    }
1193
}
1194

    
1195
DISAS_INSN(byterev)
1196
{
1197
    int reg;
1198

    
1199
    reg = DREG(insn, 0);
1200
    gen_op_bswap32(reg, reg);
1201
}
1202

    
1203
DISAS_INSN(move)
1204
{
1205
    int src;
1206
    int dest;
1207
    int op;
1208
    int opsize;
1209

    
1210
    switch (insn >> 12) {
1211
    case 1: /* move.b */
1212
        opsize = OS_BYTE;
1213
        break;
1214
    case 2: /* move.l */
1215
        opsize = OS_LONG;
1216
        break;
1217
    case 3: /* move.w */
1218
        opsize = OS_WORD;
1219
        break;
1220
    default:
1221
        abort();
1222
    }
1223
    SRC_EA(src, opsize, -1, NULL);
1224
    op = (insn >> 6) & 7;
1225
    if (op == 1) {
1226
        /* movea */
1227
        /* The value will already have been sign extended.  */
1228
        dest = AREG(insn, 9);
1229
        gen_op_mov32(dest, src);
1230
    } else {
1231
        /* normal move */
1232
        uint16_t dest_ea;
1233
        dest_ea = ((insn >> 9) & 7) | (op << 3);
1234
        DEST_EA(dest_ea, opsize, src, NULL);
1235
        /* This will be correct because loads sign extend.  */
1236
        gen_logic_cc(s, src);
1237
    }
1238
}
1239

    
1240
DISAS_INSN(negx)
1241
{
1242
    int reg;
1243
    int dest;
1244
    int tmp;
1245

    
1246
    gen_flush_flags(s);
1247
    reg = DREG(insn, 0);
1248
    dest = gen_new_qreg(QMODE_I32);
1249
    gen_op_mov32 (dest, gen_im32(0));
1250
    gen_op_subx_cc(dest, reg);
1251
    /* !Z is sticky.  */
1252
    tmp = gen_new_qreg(QMODE_I32);
1253
    gen_op_mov32 (tmp, QREG_CC_DEST);
1254
    gen_op_update_cc_add(dest, reg);
1255
    gen_op_mov32(reg, dest);
1256
    s->cc_op = CC_OP_DYNAMIC;
1257
    gen_flush_flags(s);
1258
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1259
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1260
    s->cc_op = CC_OP_FLAGS;
1261
}
1262

    
1263
DISAS_INSN(lea)
1264
{
1265
    int reg;
1266
    int tmp;
1267

    
1268
    reg = AREG(insn, 9);
1269
    tmp = gen_lea(s, insn, OS_LONG);
1270
    if (tmp == -1) {
1271
        gen_addr_fault(s);
1272
        return;
1273
    }
1274
    gen_op_mov32(reg, tmp);
1275
}
1276

    
1277
DISAS_INSN(clr)
1278
{
1279
    int opsize;
1280

    
1281
    switch ((insn >> 6) & 3) {
1282
    case 0: /* clr.b */
1283
        opsize = OS_BYTE;
1284
        break;
1285
    case 1: /* clr.w */
1286
        opsize = OS_WORD;
1287
        break;
1288
    case 2: /* clr.l */
1289
        opsize = OS_LONG;
1290
        break;
1291
    default:
1292
        abort();
1293
    }
1294
    DEST_EA(insn, opsize, gen_im32(0), NULL);
1295
    gen_logic_cc(s, gen_im32(0));
1296
}
1297

    
1298
static int gen_get_ccr(DisasContext *s)
1299
{
1300
    int dest;
1301

    
1302
    gen_flush_flags(s);
1303
    dest = gen_new_qreg(QMODE_I32);
1304
    gen_op_get_xflag(dest);
1305
    gen_op_shl32(dest, dest, gen_im32(4));
1306
    gen_op_or32(dest, dest, QREG_CC_DEST);
1307
    return dest;
1308
}
1309

    
1310
DISAS_INSN(move_from_ccr)
1311
{
1312
    int reg;
1313
    int ccr;
1314

    
1315
    ccr = gen_get_ccr(s);
1316
    reg = DREG(insn, 0);
1317
    gen_partset_reg(OS_WORD, reg, ccr);
1318
}
1319

    
1320
DISAS_INSN(neg)
1321
{
1322
    int reg;
1323
    int src1;
1324

    
1325
    reg = DREG(insn, 0);
1326
    src1 = gen_new_qreg(QMODE_I32);
1327
    gen_op_mov32(src1, reg);
1328
    gen_op_neg32(reg, src1);
1329
    s->cc_op = CC_OP_SUB;
1330
    gen_op_update_cc_add(reg, src1);
1331
    gen_op_update_xflag_lt(gen_im32(0), src1);
1332
    s->cc_op = CC_OP_SUB;
1333
}
1334

    
1335
static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1336
{
1337
    gen_op_logic_cc(gen_im32(val & 0xf));
1338
    gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1339
    if (!ccr_only) {
1340
        gen_op_set_sr(gen_im32(val & 0xff00));
1341
    }
1342
}
1343

    
1344
static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1345
{
1346
    int src1;
1347
    int reg;
1348

    
1349
    s->cc_op = CC_OP_FLAGS;
1350
    if ((insn & 0x38) == 0)
1351
      {
1352
        src1 = gen_new_qreg(QMODE_I32);
1353
        reg = DREG(insn, 0);
1354
        gen_op_and32(src1, reg, gen_im32(0xf));
1355
        gen_op_logic_cc(src1);
1356
        gen_op_shr32(src1, reg, gen_im32(4));
1357
        gen_op_and32(src1, src1, gen_im32(1));
1358
        gen_op_update_xflag_tst(src1);
1359
        if (!ccr_only) {
1360
            gen_op_set_sr(reg);
1361
        }
1362
      }
1363
    else if ((insn & 0x3f) == 0x3c)
1364
      {
1365
        uint16_t val;
1366
        val = lduw_code(s->pc);
1367
        s->pc += 2;
1368
        gen_set_sr_im(s, val, ccr_only);
1369
      }
1370
    else
1371
        disas_undef(s, insn);
1372
}
1373

    
1374
DISAS_INSN(move_to_ccr)
1375
{
1376
    gen_set_sr(s, insn, 1);
1377
}
1378

    
1379
DISAS_INSN(not)
1380
{
1381
    int reg;
1382

    
1383
    reg = DREG(insn, 0);
1384
    gen_op_not32(reg, reg);
1385
    gen_logic_cc(s, reg);
1386
}
1387

    
1388
DISAS_INSN(swap)
1389
{
1390
    int dest;
1391
    int src1;
1392
    int src2;
1393
    int reg;
1394

    
1395
    dest = gen_new_qreg(QMODE_I32);
1396
    src1 = gen_new_qreg(QMODE_I32);
1397
    src2 = gen_new_qreg(QMODE_I32);
1398
    reg = DREG(insn, 0);
1399
    gen_op_shl32(src1, reg, gen_im32(16));
1400
    gen_op_shr32(src2, reg, gen_im32(16));
1401
    gen_op_or32(dest, src1, src2);
1402
    gen_op_mov32(reg, dest);
1403
    gen_logic_cc(s, dest);
1404
}
1405

    
1406
DISAS_INSN(pea)
1407
{
1408
    int tmp;
1409

    
1410
    tmp = gen_lea(s, insn, OS_LONG);
1411
    if (tmp == -1) {
1412
        gen_addr_fault(s);
1413
        return;
1414
    }
1415
    gen_push(s, tmp);
1416
}
1417

    
1418
DISAS_INSN(ext)
1419
{
1420
    int reg;
1421
    int op;
1422
    int tmp;
1423

    
1424
    reg = DREG(insn, 0);
1425
    op = (insn >> 6) & 7;
1426
    tmp = gen_new_qreg(QMODE_I32);
1427
    if (op == 3)
1428
        gen_op_ext16s32(tmp, reg);
1429
    else
1430
        gen_op_ext8s32(tmp, reg);
1431
    if (op == 2)
1432
        gen_partset_reg(OS_WORD, reg, tmp);
1433
    else
1434
      gen_op_mov32(reg, tmp);
1435
    gen_logic_cc(s, tmp);
1436
}
1437

    
1438
DISAS_INSN(tst)
1439
{
1440
    int opsize;
1441
    int tmp;
1442

    
1443
    switch ((insn >> 6) & 3) {
1444
    case 0: /* tst.b */
1445
        opsize = OS_BYTE;
1446
        break;
1447
    case 1: /* tst.w */
1448
        opsize = OS_WORD;
1449
        break;
1450
    case 2: /* tst.l */
1451
        opsize = OS_LONG;
1452
        break;
1453
    default:
1454
        abort();
1455
    }
1456
    SRC_EA(tmp, opsize, -1, NULL);
1457
    gen_logic_cc(s, tmp);
1458
}
1459

    
1460
DISAS_INSN(pulse)
1461
{
1462
  /* Implemented as a NOP.  */
1463
}
1464

    
1465
DISAS_INSN(illegal)
1466
{
1467
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1468
}
1469

    
1470
/* ??? This should be atomic.  */
1471
DISAS_INSN(tas)
1472
{
1473
    int dest;
1474
    int src1;
1475
    int addr;
1476

    
1477
    dest = gen_new_qreg(QMODE_I32);
1478
    SRC_EA(src1, OS_BYTE, -1, &addr);
1479
    gen_logic_cc(s, src1);
1480
    gen_op_or32(dest, src1, gen_im32(0x80));
1481
    DEST_EA(insn, OS_BYTE, dest, &addr);
1482
}
1483

    
1484
DISAS_INSN(mull)
1485
{
1486
    uint16_t ext;
1487
    int reg;
1488
    int src1;
1489
    int dest;
1490

    
1491
    /* The upper 32 bits of the product are discarded, so
1492
       muls.l and mulu.l are functionally equivalent.  */
1493
    ext = lduw_code(s->pc);
1494
    s->pc += 2;
1495
    if (ext & 0x87ff) {
1496
        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1497
        return;
1498
    }
1499
    reg = DREG(ext, 12);
1500
    SRC_EA(src1, OS_LONG, 0, NULL);
1501
    dest = gen_new_qreg(QMODE_I32);
1502
    gen_op_mul32(dest, src1, reg);
1503
    gen_op_mov32(reg, dest);
1504
    /* Unlike m68k, coldfire always clears the overflow bit.  */
1505
    gen_logic_cc(s, dest);
1506
}
1507

    
1508
DISAS_INSN(link)
1509
{
1510
    int16_t offset;
1511
    int reg;
1512
    int tmp;
1513

    
1514
    offset = ldsw_code(s->pc);
1515
    s->pc += 2;
1516
    reg = AREG(insn, 0);
1517
    tmp = gen_new_qreg(QMODE_I32);
1518
    gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1519
    gen_store(s, OS_LONG, tmp, reg);
1520
    if (reg != QREG_SP)
1521
        gen_op_mov32(reg, tmp);
1522
    gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1523
}
1524

    
1525
DISAS_INSN(unlk)
1526
{
1527
    int src;
1528
    int reg;
1529
    int tmp;
1530

    
1531
    src = gen_new_qreg(QMODE_I32);
1532
    reg = AREG(insn, 0);
1533
    gen_op_mov32(src, reg);
1534
    tmp = gen_load(s, OS_LONG, src, 0);
1535
    gen_op_mov32(reg, tmp);
1536
    gen_op_add32(QREG_SP, src, gen_im32(4));
1537
}
1538

    
1539
DISAS_INSN(nop)
1540
{
1541
}
1542

    
1543
DISAS_INSN(rts)
1544
{
1545
    int tmp;
1546

    
1547
    tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1548
    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1549
    gen_jmp(s, tmp);
1550
}
1551

    
1552
DISAS_INSN(jump)
1553
{
1554
    int tmp;
1555

    
1556
    /* Load the target address first to ensure correct exception
1557
       behavior.  */
1558
    tmp = gen_lea(s, insn, OS_LONG);
1559
    if (tmp == -1) {
1560
        gen_addr_fault(s);
1561
        return;
1562
    }
1563
    if ((insn & 0x40) == 0) {
1564
        /* jsr */
1565
        gen_push(s, gen_im32(s->pc));
1566
    }
1567
    gen_jmp(s, tmp);
1568
}
1569

    
1570
DISAS_INSN(addsubq)
1571
{
1572
    int src1;
1573
    int src2;
1574
    int dest;
1575
    int val;
1576
    int addr;
1577

    
1578
    SRC_EA(src1, OS_LONG, 0, &addr);
1579
    val = (insn >> 9) & 7;
1580
    if (val == 0)
1581
        val = 8;
1582
    src2 = gen_im32(val);
1583
    dest = gen_new_qreg(QMODE_I32);
1584
    gen_op_mov32(dest, src1);
1585
    if ((insn & 0x38) == 0x08) {
1586
        /* Don't update condition codes if the destination is an
1587
           address register.  */
1588
        if (insn & 0x0100) {
1589
            gen_op_sub32(dest, dest, src2);
1590
        } else {
1591
            gen_op_add32(dest, dest, src2);
1592
        }
1593
    } else {
1594
        if (insn & 0x0100) {
1595
            gen_op_update_xflag_lt(dest, src2);
1596
            gen_op_sub32(dest, dest, src2);
1597
            s->cc_op = CC_OP_SUB;
1598
        } else {
1599
            gen_op_add32(dest, dest, src2);
1600
            gen_op_update_xflag_lt(dest, src2);
1601
            s->cc_op = CC_OP_ADD;
1602
        }
1603
        gen_op_update_cc_add(dest, src2);
1604
    }
1605
    DEST_EA(insn, OS_LONG, dest, &addr);
1606
}
1607

    
1608
DISAS_INSN(tpf)
1609
{
1610
    switch (insn & 7) {
1611
    case 2: /* One extension word.  */
1612
        s->pc += 2;
1613
        break;
1614
    case 3: /* Two extension words.  */
1615
        s->pc += 4;
1616
        break;
1617
    case 4: /* No extension words.  */
1618
        break;
1619
    default:
1620
        disas_undef(s, insn);
1621
    }
1622
}
1623

    
1624
DISAS_INSN(branch)
1625
{
1626
    int32_t offset;
1627
    uint32_t base;
1628
    int op;
1629
    int l1;
1630

    
1631
    base = s->pc;
1632
    op = (insn >> 8) & 0xf;
1633
    offset = (int8_t)insn;
1634
    if (offset == 0) {
1635
        offset = ldsw_code(s->pc);
1636
        s->pc += 2;
1637
    } else if (offset == -1) {
1638
        offset = read_im32(s);
1639
    }
1640
    if (op == 1) {
1641
        /* bsr */
1642
        gen_push(s, gen_im32(s->pc));
1643
    }
1644
    gen_flush_cc_op(s);
1645
    if (op > 1) {
1646
        /* Bcc */
1647
        l1 = gen_new_label();
1648
        gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1649
        gen_jmp_tb(s, 1, base + offset);
1650
        gen_set_label(l1);
1651
        gen_jmp_tb(s, 0, s->pc);
1652
    } else {
1653
        /* Unconditional branch.  */
1654
        gen_jmp_tb(s, 0, base + offset);
1655
    }
1656
}
1657

    
1658
DISAS_INSN(moveq)
1659
{
1660
    int tmp;
1661

    
1662
    tmp = gen_im32((int8_t)insn);
1663
    gen_op_mov32(DREG(insn, 9), tmp);
1664
    gen_logic_cc(s, tmp);
1665
}
1666

    
1667
DISAS_INSN(mvzs)
1668
{
1669
    int opsize;
1670
    int src;
1671
    int reg;
1672

    
1673
    if (insn & 0x40)
1674
        opsize = OS_WORD;
1675
    else
1676
        opsize = OS_BYTE;
1677
    SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
1678
    reg = DREG(insn, 9);
1679
    gen_op_mov32(reg, src);
1680
    gen_logic_cc(s, src);
1681
}
1682

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

    
1690
    reg = DREG(insn, 9);
1691
    dest = gen_new_qreg(QMODE_I32);
1692
    if (insn & 0x100) {
1693
        SRC_EA(src, OS_LONG, 0, &addr);
1694
        gen_op_or32(dest, src, reg);
1695
        DEST_EA(insn, OS_LONG, dest, &addr);
1696
    } else {
1697
        SRC_EA(src, OS_LONG, 0, NULL);
1698
        gen_op_or32(dest, src, reg);
1699
        gen_op_mov32(reg, dest);
1700
    }
1701
    gen_logic_cc(s, dest);
1702
}
1703

    
1704
DISAS_INSN(suba)
1705
{
1706
    int src;
1707
    int reg;
1708

    
1709
    SRC_EA(src, OS_LONG, 0, NULL);
1710
    reg = AREG(insn, 9);
1711
    gen_op_sub32(reg, reg, src);
1712
}
1713

    
1714
DISAS_INSN(subx)
1715
{
1716
    int reg;
1717
    int src;
1718
    int dest;
1719
    int tmp;
1720

    
1721
    gen_flush_flags(s);
1722
    reg = DREG(insn, 9);
1723
    src = DREG(insn, 0);
1724
    dest = gen_new_qreg(QMODE_I32);
1725
    gen_op_mov32 (dest, reg);
1726
    gen_op_subx_cc(dest, src);
1727
    /* !Z is sticky.  */
1728
    tmp = gen_new_qreg(QMODE_I32);
1729
    gen_op_mov32 (tmp, QREG_CC_DEST);
1730
    gen_op_update_cc_add(dest, src);
1731
    gen_op_mov32(reg, dest);
1732
    s->cc_op = CC_OP_DYNAMIC;
1733
    gen_flush_flags(s);
1734
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1735
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1736
    s->cc_op = CC_OP_FLAGS;
1737
}
1738

    
1739
DISAS_INSN(mov3q)
1740
{
1741
    int src;
1742
    int val;
1743

    
1744
    val = (insn >> 9) & 7;
1745
    if (val == 0)
1746
        val = -1;
1747
    src = gen_im32(val);
1748
    gen_logic_cc(s, src);
1749
    DEST_EA(insn, OS_LONG, src, NULL);
1750
}
1751

    
1752
DISAS_INSN(cmp)
1753
{
1754
    int op;
1755
    int src;
1756
    int reg;
1757
    int dest;
1758
    int opsize;
1759

    
1760
    op = (insn >> 6) & 3;
1761
    switch (op) {
1762
    case 0: /* cmp.b */
1763
        opsize = OS_BYTE;
1764
        s->cc_op = CC_OP_CMPB;
1765
        break;
1766
    case 1: /* cmp.w */
1767
        opsize = OS_WORD;
1768
        s->cc_op = CC_OP_CMPW;
1769
        break;
1770
    case 2: /* cmp.l */
1771
        opsize = OS_LONG;
1772
        s->cc_op = CC_OP_SUB;
1773
        break;
1774
    default:
1775
        abort();
1776
    }
1777
    SRC_EA(src, opsize, -1, NULL);
1778
    reg = DREG(insn, 9);
1779
    dest = gen_new_qreg(QMODE_I32);
1780
    gen_op_sub32(dest, reg, src);
1781
    gen_op_update_cc_add(dest, src);
1782
}
1783

    
1784
DISAS_INSN(cmpa)
1785
{
1786
    int opsize;
1787
    int src;
1788
    int reg;
1789
    int dest;
1790

    
1791
    if (insn & 0x100) {
1792
        opsize = OS_LONG;
1793
    } else {
1794
        opsize = OS_WORD;
1795
    }
1796
    SRC_EA(src, opsize, -1, NULL);
1797
    reg = AREG(insn, 9);
1798
    dest = gen_new_qreg(QMODE_I32);
1799
    gen_op_sub32(dest, reg, src);
1800
    gen_op_update_cc_add(dest, src);
1801
    s->cc_op = CC_OP_SUB;
1802
}
1803

    
1804
DISAS_INSN(eor)
1805
{
1806
    int src;
1807
    int reg;
1808
    int dest;
1809
    int addr;
1810

    
1811
    SRC_EA(src, OS_LONG, 0, &addr);
1812
    reg = DREG(insn, 9);
1813
    dest = gen_new_qreg(QMODE_I32);
1814
    gen_op_xor32(dest, src, reg);
1815
    gen_logic_cc(s, dest);
1816
    DEST_EA(insn, OS_LONG, dest, &addr);
1817
}
1818

    
1819
DISAS_INSN(and)
1820
{
1821
    int src;
1822
    int reg;
1823
    int dest;
1824
    int addr;
1825

    
1826
    reg = DREG(insn, 9);
1827
    dest = gen_new_qreg(QMODE_I32);
1828
    if (insn & 0x100) {
1829
        SRC_EA(src, OS_LONG, 0, &addr);
1830
        gen_op_and32(dest, src, reg);
1831
        DEST_EA(insn, OS_LONG, dest, &addr);
1832
    } else {
1833
        SRC_EA(src, OS_LONG, 0, NULL);
1834
        gen_op_and32(dest, src, reg);
1835
        gen_op_mov32(reg, dest);
1836
    }
1837
    gen_logic_cc(s, dest);
1838
}
1839

    
1840
DISAS_INSN(adda)
1841
{
1842
    int src;
1843
    int reg;
1844

    
1845
    SRC_EA(src, OS_LONG, 0, NULL);
1846
    reg = AREG(insn, 9);
1847
    gen_op_add32(reg, reg, src);
1848
}
1849

    
1850
DISAS_INSN(addx)
1851
{
1852
    int reg;
1853
    int src;
1854
    int dest;
1855
    int tmp;
1856

    
1857
    gen_flush_flags(s);
1858
    reg = DREG(insn, 9);
1859
    src = DREG(insn, 0);
1860
    dest = gen_new_qreg(QMODE_I32);
1861
    gen_op_mov32 (dest, reg);
1862
    gen_op_addx_cc(dest, src);
1863
    /* !Z is sticky.  */
1864
    tmp = gen_new_qreg(QMODE_I32);
1865
    gen_op_mov32 (tmp, QREG_CC_DEST);
1866
    gen_op_update_cc_add(dest, src);
1867
    gen_op_mov32(reg, dest);
1868
    s->cc_op = CC_OP_DYNAMIC;
1869
    gen_flush_flags(s);
1870
    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1871
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1872
    s->cc_op = CC_OP_FLAGS;
1873
}
1874

    
1875
DISAS_INSN(shift_im)
1876
{
1877
    int reg;
1878
    int tmp;
1879

    
1880
    reg = DREG(insn, 0);
1881
    tmp = (insn >> 9) & 7;
1882
    if (tmp == 0)
1883
      tmp = 8;
1884
    if (insn & 0x100) {
1885
        gen_op_shl_im_cc(reg, tmp);
1886
        s->cc_op = CC_OP_SHL;
1887
    } else {
1888
        if (insn & 8) {
1889
            gen_op_shr_im_cc(reg, tmp);
1890
            s->cc_op = CC_OP_SHR;
1891
        } else {
1892
            gen_op_sar_im_cc(reg, tmp);
1893
            s->cc_op = CC_OP_SAR;
1894
        }
1895
    }
1896
}
1897

    
1898
DISAS_INSN(shift_reg)
1899
{
1900
    int reg;
1901
    int src;
1902
    int tmp;
1903

    
1904
    reg = DREG(insn, 0);
1905
    src = DREG(insn, 9);
1906
    tmp = gen_new_qreg(QMODE_I32);
1907
    gen_op_and32(tmp, src, gen_im32(63));
1908
    if (insn & 0x100) {
1909
        gen_op_shl_cc(reg, tmp);
1910
        s->cc_op = CC_OP_SHL;
1911
    } else {
1912
        if (insn & 8) {
1913
            gen_op_shr_cc(reg, tmp);
1914
            s->cc_op = CC_OP_SHR;
1915
        } else {
1916
            gen_op_sar_cc(reg, tmp);
1917
            s->cc_op = CC_OP_SAR;
1918
        }
1919
    }
1920
}
1921

    
1922
DISAS_INSN(ff1)
1923
{
1924
    int reg;
1925
    reg = DREG(insn, 0);
1926
    gen_logic_cc(s, reg);
1927
    gen_op_ff1(reg, reg);
1928
}
1929

    
1930
static int gen_get_sr(DisasContext *s)
1931
{
1932
    int ccr;
1933
    int sr;
1934

    
1935
    ccr = gen_get_ccr(s);
1936
    sr = gen_new_qreg(QMODE_I32);
1937
    gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
1938
    gen_op_or32(sr, sr, ccr);
1939
    return sr;
1940
}
1941

    
1942
DISAS_INSN(strldsr)
1943
{
1944
    uint16_t ext;
1945
    uint32_t addr;
1946

    
1947
    addr = s->pc - 2;
1948
    ext = lduw_code(s->pc);
1949
    s->pc += 2;
1950
    if (ext != 0x46FC) {
1951
        gen_exception(s, addr, EXCP_UNSUPPORTED);
1952
        return;
1953
    }
1954
    ext = lduw_code(s->pc);
1955
    s->pc += 2;
1956
    if (IS_USER(s) || (ext & SR_S) == 0) {
1957
        gen_exception(s, addr, EXCP_PRIVILEGE);
1958
        return;
1959
    }
1960
    gen_push(s, gen_get_sr(s));
1961
    gen_set_sr_im(s, ext, 0);
1962
}
1963

    
1964
DISAS_INSN(move_from_sr)
1965
{
1966
    int reg;
1967
    int sr;
1968

    
1969
    if (IS_USER(s)) {
1970
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1971
        return;
1972
    }
1973
    sr = gen_get_sr(s);
1974
    reg = DREG(insn, 0);
1975
    gen_partset_reg(OS_WORD, reg, sr);
1976
}
1977

    
1978
DISAS_INSN(move_to_sr)
1979
{
1980
    if (IS_USER(s)) {
1981
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1982
        return;
1983
    }
1984
    gen_set_sr(s, insn, 0);
1985
    gen_lookup_tb(s);
1986
}
1987

    
1988
DISAS_INSN(move_from_usp)
1989
{
1990
    if (IS_USER(s)) {
1991
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1992
        return;
1993
    }
1994
    /* TODO: Implement USP.  */
1995
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1996
}
1997

    
1998
DISAS_INSN(move_to_usp)
1999
{
2000
    if (IS_USER(s)) {
2001
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2002
        return;
2003
    }
2004
    /* TODO: Implement USP.  */
2005
    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
2006
}
2007

    
2008
DISAS_INSN(halt)
2009
{
2010
    gen_jmp(s, gen_im32(s->pc));
2011
    gen_op_halt();
2012
}
2013

    
2014
DISAS_INSN(stop)
2015
{
2016
    uint16_t ext;
2017

    
2018
    if (IS_USER(s)) {
2019
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2020
        return;
2021
    }
2022

    
2023
    ext = lduw_code(s->pc);
2024
    s->pc += 2;
2025

    
2026
    gen_set_sr_im(s, ext, 0);
2027
    gen_jmp(s, gen_im32(s->pc));
2028
    gen_op_stop();
2029
}
2030

    
2031
DISAS_INSN(rte)
2032
{
2033
    if (IS_USER(s)) {
2034
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2035
        return;
2036
    }
2037
    gen_exception(s, s->pc - 2, EXCP_RTE);
2038
}
2039

    
2040
DISAS_INSN(movec)
2041
{
2042
    uint16_t ext;
2043
    int reg;
2044

    
2045
    if (IS_USER(s)) {
2046
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2047
        return;
2048
    }
2049

    
2050
    ext = lduw_code(s->pc);
2051
    s->pc += 2;
2052

    
2053
    if (ext & 0x8000) {
2054
        reg = AREG(ext, 12);
2055
    } else {
2056
        reg = DREG(ext, 12);
2057
    }
2058
    gen_op_movec(gen_im32(ext & 0xfff), reg);
2059
    gen_lookup_tb(s);
2060
}
2061

    
2062
DISAS_INSN(intouch)
2063
{
2064
    if (IS_USER(s)) {
2065
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2066
        return;
2067
    }
2068
    /* ICache fetch.  Implement as no-op.  */
2069
}
2070

    
2071
DISAS_INSN(cpushl)
2072
{
2073
    if (IS_USER(s)) {
2074
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2075
        return;
2076
    }
2077
    /* Cache push/invalidate.  Implement as no-op.  */
2078
}
2079

    
2080
DISAS_INSN(wddata)
2081
{
2082
    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2083
}
2084

    
2085
DISAS_INSN(wdebug)
2086
{
2087
    if (IS_USER(s)) {
2088
        gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2089
        return;
2090
    }
2091
    /* TODO: Implement wdebug.  */
2092
    qemu_assert(0, "WDEBUG not implemented");
2093
}
2094

    
2095
DISAS_INSN(trap)
2096
{
2097
    gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
2098
}
2099

    
2100
/* ??? FP exceptions are not implemented.  Most exceptions are deferred until
2101
   immediately before the next FP instruction is executed.  */
2102
DISAS_INSN(fpu)
2103
{
2104
    uint16_t ext;
2105
    int opmode;
2106
    int src;
2107
    int dest;
2108
    int res;
2109
    int round;
2110
    int opsize;
2111

    
2112
    ext = lduw_code(s->pc);
2113
    s->pc += 2;
2114
    opmode = ext & 0x7f;
2115
    switch ((ext >> 13) & 7) {
2116
    case 0: case 2:
2117
        break;
2118
    case 1:
2119
        goto undef;
2120
    case 3: /* fmove out */
2121
        src = FREG(ext, 7);
2122
        /* fmove */
2123
        /* ??? TODO: Proper behavior on overflow.  */
2124
        switch ((ext >> 10) & 7) {
2125
        case 0:
2126
            opsize = OS_LONG;
2127
            res = gen_new_qreg(QMODE_I32);
2128
            gen_op_f64_to_i32(res, src);
2129
            break;
2130
        case 1:
2131
            opsize = OS_SINGLE;
2132
            res = gen_new_qreg(QMODE_F32);
2133
            gen_op_f64_to_f32(res, src);
2134
            break;
2135
        case 4:
2136
            opsize = OS_WORD;
2137
            res = gen_new_qreg(QMODE_I32);
2138
            gen_op_f64_to_i32(res, src);
2139
            break;
2140
        case 5:
2141
            opsize = OS_DOUBLE;
2142
            res = src;
2143
            break;
2144
        case 6:
2145
            opsize = OS_BYTE;
2146
            res = gen_new_qreg(QMODE_I32);
2147
            gen_op_f64_to_i32(res, src);
2148
            break;
2149
        default:
2150
            goto undef;
2151
        }
2152
        DEST_EA(insn, opsize, res, NULL);
2153
        return;
2154
    case 4: /* fmove to control register.  */
2155
        switch ((ext >> 10) & 7) {
2156
        case 4: /* FPCR */
2157
            /* Not implemented.  Ignore writes.  */
2158
            break;
2159
        case 1: /* FPIAR */
2160
        case 2: /* FPSR */
2161
        default:
2162
            cpu_abort(NULL, "Unimplemented: fmove to control %d",
2163
                      (ext >> 10) & 7);
2164
        }
2165
        break;
2166
    case 5: /* fmove from control register.  */
2167
        switch ((ext >> 10) & 7) {
2168
        case 4: /* FPCR */
2169
            /* Not implemented.  Always return zero.  */
2170
            res = gen_im32(0);
2171
            break;
2172
        case 1: /* FPIAR */
2173
        case 2: /* FPSR */
2174
        default:
2175
            cpu_abort(NULL, "Unimplemented: fmove from control %d",
2176
                      (ext >> 10) & 7);
2177
            goto undef;
2178
        }
2179
        DEST_EA(insn, OS_LONG, res, NULL);
2180
        break;
2181
    case 6: /* fmovem */
2182
    case 7:
2183
        {
2184
        int addr;
2185
        uint16_t mask;
2186
        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2187
            goto undef;
2188
        src = gen_lea(s, insn, OS_LONG);
2189
        if (src == -1) {
2190
            gen_addr_fault(s);
2191
            return;
2192
        }
2193
        addr = gen_new_qreg(QMODE_I32);
2194
        gen_op_mov32(addr, src);
2195
        mask = 0x80;
2196
        dest = QREG_F0;
2197
        while (mask) {
2198
            if (ext & mask) {
2199
                s->is_mem = 1;
2200
                if (ext & (1 << 13)) {
2201
                    /* store */
2202
                    gen_st(s, f64, addr, dest);
2203
                } else {
2204
                    /* load */
2205
                    gen_ld(s, f64, dest, addr);
2206
                }
2207
                if (ext & (mask - 1))
2208
                    gen_op_add32(addr, addr, gen_im32(8));
2209
            }
2210
            mask >>= 1;
2211
            dest++;
2212
        }
2213
        }
2214
        return;
2215
    }
2216
    if (ext & (1 << 14)) {
2217
        int tmp;
2218

    
2219
        /* Source effective address.  */
2220
        switch ((ext >> 10) & 7) {
2221
        case 0: opsize = OS_LONG; break;
2222
        case 1: opsize = OS_SINGLE; break;
2223
        case 4: opsize = OS_WORD; break;
2224
        case 5: opsize = OS_DOUBLE; break;
2225
        case 6: opsize = OS_BYTE; break;
2226
        default:
2227
            goto undef;
2228
        }
2229
        SRC_EA(tmp, opsize, -1, NULL);
2230
        if (opsize == OS_DOUBLE) {
2231
            src = tmp;
2232
        } else {
2233
            src = gen_new_qreg(QMODE_F64);
2234
            switch (opsize) {
2235
            case OS_LONG:
2236
            case OS_WORD:
2237
            case OS_BYTE:
2238
                gen_op_i32_to_f64(src, tmp);
2239
                break;
2240
            case OS_SINGLE:
2241
                gen_op_f32_to_f64(src, tmp);
2242
                break;
2243
            }
2244
        }
2245
    } else {
2246
        /* Source register.  */
2247
        src = FREG(ext, 10);
2248
    }
2249
    dest = FREG(ext, 7);
2250
    res = gen_new_qreg(QMODE_F64);
2251
    if (opmode != 0x3a)
2252
        gen_op_movf64(res, dest);
2253
    round = 1;
2254
    switch (opmode) {
2255
    case 0: case 0x40: case 0x44: /* fmove */
2256
        gen_op_movf64(res, src);
2257
        break;
2258
    case 1: /* fint */
2259
        gen_op_iround_f64(res, src);
2260
        round = 0;
2261
        break;
2262
    case 3: /* fintrz */
2263
        gen_op_itrunc_f64(res, src);
2264
        round = 0;
2265
        break;
2266
    case 4: case 0x41: case 0x45: /* fsqrt */
2267
        gen_op_sqrtf64(res, src);
2268
        break;
2269
    case 0x18: case 0x58: case 0x5c: /* fabs */
2270
        gen_op_absf64(res, src);
2271
        break;
2272
    case 0x1a: case 0x5a: case 0x5e: /* fneg */
2273
        gen_op_chsf64(res, src);
2274
        break;
2275
    case 0x20: case 0x60: case 0x64: /* fdiv */
2276
        gen_op_divf64(res, res, src);
2277
        break;
2278
    case 0x22: case 0x62: case 0x66: /* fadd */
2279
        gen_op_addf64(res, res, src);
2280
        break;
2281
    case 0x23: case 0x63: case 0x67: /* fmul */
2282
        gen_op_mulf64(res, res, src);
2283
        break;
2284
    case 0x28: case 0x68: case 0x6c: /* fsub */
2285
        gen_op_subf64(res, res, src);
2286
        break;
2287
    case 0x38: /* fcmp */
2288
        gen_op_sub_cmpf64(res, res, src);
2289
        dest = 0;
2290
        round = 0;
2291
        break;
2292
    case 0x3a: /* ftst */
2293
        gen_op_movf64(res, src);
2294
        dest = 0;
2295
        round = 0;
2296
        break;
2297
    default:
2298
        goto undef;
2299
    }
2300
    if (round) {
2301
        if (opmode & 0x40) {
2302
            if ((opmode & 0x4) != 0)
2303
                round = 0;
2304
        } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2305
            round = 0;
2306
        }
2307
    }
2308
    if (round) {
2309
        int tmp;
2310

    
2311
        tmp = gen_new_qreg(QMODE_F32);
2312
        gen_op_f64_to_f32(tmp, res);
2313
        gen_op_f32_to_f64(res, tmp);
2314
    }
2315
    gen_op_fp_result(res);
2316
    if (dest) {
2317
        gen_op_movf64(dest, res);
2318
    }
2319
    return;
2320
undef:
2321
    s->pc -= 2;
2322
    disas_undef_fpu(s, insn);
2323
}
2324

    
2325
DISAS_INSN(fbcc)
2326
{
2327
    uint32_t offset;
2328
    uint32_t addr;
2329
    int flag;
2330
    int zero;
2331
    int l1;
2332

    
2333
    addr = s->pc;
2334
    offset = ldsw_code(s->pc);
2335
    s->pc += 2;
2336
    if (insn & (1 << 6)) {
2337
        offset = (offset << 16) | lduw_code(s->pc);
2338
        s->pc += 2;
2339
    }
2340

    
2341
    l1 = gen_new_label();
2342
    /* TODO: Raise BSUN exception.  */
2343
    flag = gen_new_qreg(QMODE_I32);
2344
    zero = gen_new_qreg(QMODE_F64);
2345
    gen_op_zerof64(zero);
2346
    gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2347
    /* Jump to l1 if condition is true.  */
2348
    switch (insn & 0xf) {
2349
    case 0: /* f */
2350
        break;
2351
    case 1: /* eq (=0) */
2352
        gen_op_jmp_z32(flag, l1);
2353
        break;
2354
    case 2: /* ogt (=1) */
2355
        gen_op_sub32(flag, flag, gen_im32(1));
2356
        gen_op_jmp_z32(flag, l1);
2357
        break;
2358
    case 3: /* oge (=0 or =1) */
2359
        gen_op_jmp_z32(flag, l1);
2360
        gen_op_sub32(flag, flag, gen_im32(1));
2361
        gen_op_jmp_z32(flag, l1);
2362
        break;
2363
    case 4: /* olt (=-1) */
2364
        gen_op_jmp_s32(flag, l1);
2365
        break;
2366
    case 5: /* ole (=-1 or =0) */
2367
        gen_op_jmp_s32(flag, l1);
2368
        gen_op_jmp_z32(flag, l1);
2369
        break;
2370
    case 6: /* ogl (=-1 or =1) */
2371
        gen_op_jmp_s32(flag, l1);
2372
        gen_op_sub32(flag, flag, gen_im32(1));
2373
        gen_op_jmp_z32(flag, l1);
2374
        break;
2375
    case 7: /* or (=2) */
2376
        gen_op_sub32(flag, flag, gen_im32(2));
2377
        gen_op_jmp_z32(flag, l1);
2378
        break;
2379
    case 8: /* un (<2) */
2380
        gen_op_sub32(flag, flag, gen_im32(2));
2381
        gen_op_jmp_s32(flag, l1);
2382
        break;
2383
    case 9: /* ueq (=0 or =2) */
2384
        gen_op_jmp_z32(flag, l1);
2385
        gen_op_sub32(flag, flag, gen_im32(2));
2386
        gen_op_jmp_z32(flag, l1);
2387
        break;
2388
    case 10: /* ugt (>0) */
2389
        /* ??? Add jmp_gtu.  */
2390
        gen_op_sub32(flag, flag, gen_im32(1));
2391
        gen_op_jmp_ns32(flag, l1);
2392
        break;
2393
    case 11: /* uge (>=0) */
2394
        gen_op_jmp_ns32(flag, l1);
2395
        break;
2396
    case 12: /* ult (=-1 or =2) */
2397
        gen_op_jmp_s32(flag, l1);
2398
        gen_op_sub32(flag, flag, gen_im32(2));
2399
        gen_op_jmp_z32(flag, l1);
2400
        break;
2401
    case 13: /* ule (!=1) */
2402
        gen_op_sub32(flag, flag, gen_im32(1));
2403
        gen_op_jmp_nz32(flag, l1);
2404
        break;
2405
    case 14: /* ne (!=0) */
2406
        gen_op_jmp_nz32(flag, l1);
2407
        break;
2408
    case 15: /* t */
2409
        gen_op_mov32(flag, gen_im32(1));
2410
        break;
2411
    }
2412
    gen_jmp_tb(s, 0, s->pc);
2413
    gen_set_label(l1);
2414
    gen_jmp_tb(s, 1, addr + offset);
2415
}
2416

    
2417
DISAS_INSN(frestore)
2418
{
2419
    /* TODO: Implement frestore.  */
2420
    qemu_assert(0, "FRESTORE not implemented");
2421
}
2422

    
2423
DISAS_INSN(fsave)
2424
{
2425
    /* TODO: Implement fsave.  */
2426
    qemu_assert(0, "FSAVE not implemented");
2427
}
2428

    
2429
static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
2430
{
2431
    int tmp = gen_new_qreg(QMODE_I32);
2432
    if (s->env->macsr & MACSR_FI) {
2433
        if (upper)
2434
            gen_op_and32(tmp, val, gen_im32(0xffff0000));
2435
        else
2436
            gen_op_shl32(tmp, val, gen_im32(16));
2437
    } else if (s->env->macsr & MACSR_SU) {
2438
        if (upper)
2439
            gen_op_sar32(tmp, val, gen_im32(16));
2440
        else
2441
            gen_op_ext16s32(tmp, val);
2442
    } else {
2443
        if (upper)
2444
            gen_op_shr32(tmp, val, gen_im32(16));
2445
        else
2446
            gen_op_ext16u32(tmp, val);
2447
    }
2448
    return tmp;
2449
}
2450

    
2451
DISAS_INSN(mac)
2452
{
2453
    int rx;
2454
    int ry;
2455
    uint16_t ext;
2456
    int acc;
2457
    int l1;
2458
    int tmp;
2459
    int addr;
2460
    int loadval;
2461
    int dual;
2462
    int saved_flags = -1;
2463

    
2464
    ext = lduw_code(s->pc);
2465
    s->pc += 2;
2466

    
2467
    acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
2468
    dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
2469
    if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
2470
        disas_undef(s, insn);
2471
        return;
2472
    }
2473
    if (insn & 0x30) {
2474
        /* MAC with load.  */
2475
        tmp = gen_lea(s, insn, OS_LONG);
2476
        addr = gen_new_qreg(QMODE_I32);
2477
        gen_op_and32(addr, tmp, QREG_MAC_MASK);
2478
        /* Load the value now to ensure correct exception behavior.
2479
           Perform writeback after reading the MAC inputs.  */
2480
        loadval = gen_load(s, OS_LONG, addr, 0);
2481

    
2482
        acc ^= 1;
2483
        rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2484
        ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2485
    } else {
2486
        loadval = addr = -1;
2487
        rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2488
        ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2489
    }
2490

    
2491
    gen_op_mac_clear_flags();
2492
    l1 = -1;
2493
    if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2494
        /* Skip the multiply if we know we will ignore it.  */
2495
        l1 = gen_new_label();
2496
        tmp = gen_new_qreg(QMODE_I32);
2497
        gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
2498
        gen_op_jmp_nz32(tmp, l1);
2499
    }
2500

    
2501
    if ((ext & 0x0800) == 0) {
2502
        /* Word.  */
2503
        rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
2504
        ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2505
    }
2506
    if (s->env->macsr & MACSR_FI) {
2507
        gen_op_macmulf(rx, ry);
2508
    } else {
2509
        if (s->env->macsr & MACSR_SU)
2510
            gen_op_macmuls(rx, ry);
2511
        else
2512
            gen_op_macmulu(rx, ry);
2513
        switch ((ext >> 9) & 3) {
2514
        case 1:
2515
            gen_op_macshl();
2516
            break;
2517
        case 3:
2518
            gen_op_macshr();
2519
            break;
2520
        }
2521
    }
2522

    
2523
    if (dual) {
2524
        /* Save the overflow flag from the multiply.  */
2525
        saved_flags = gen_new_qreg(QMODE_I32);
2526
        gen_op_mov32(saved_flags, QREG_MACSR);
2527
    }
2528

    
2529
    if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2530
        /* Skip the accumulate if the value is already saturated.  */
2531
        l1 = gen_new_label();
2532
        tmp = gen_new_qreg(QMODE_I32);
2533
        gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2534
        gen_op_jmp_nz32(tmp, l1);
2535
    }
2536

    
2537
    if (insn & 0x100)
2538
        gen_op_macsub(acc);
2539
    else
2540
        gen_op_macadd(acc);
2541

    
2542
    if (s->env->macsr & MACSR_FI)
2543
        gen_op_macsatf(acc);
2544
    else if (s->env->macsr & MACSR_SU)
2545
        gen_op_macsats(acc);
2546
    else
2547
        gen_op_macsatu(acc);
2548

    
2549
    if (l1 != -1)
2550
        gen_set_label(l1);
2551

    
2552
    if (dual) {
2553
        /* Dual accumulate variant.  */
2554
        acc = (ext >> 2) & 3;
2555
        /* Restore the overflow flag from the multiplier.  */
2556
        gen_op_mov32(QREG_MACSR, saved_flags);
2557
        if ((s->env->macsr & MACSR_OMC) != 0) {
2558
            /* Skip the accumulate if the value is already saturated.  */
2559
            l1 = gen_new_label();
2560
            tmp = gen_new_qreg(QMODE_I32);
2561
            gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2562
            gen_op_jmp_nz32(tmp, l1);
2563
        }
2564
        if (ext & 2)
2565
            gen_op_macsub(acc);
2566
        else
2567
            gen_op_macadd(acc);
2568
        if (s->env->macsr & MACSR_FI)
2569
            gen_op_macsatf(acc);
2570
        else if (s->env->macsr & MACSR_SU)
2571
            gen_op_macsats(acc);
2572
        else
2573
            gen_op_macsatu(acc);
2574
        if (l1 != -1)
2575
            gen_set_label(l1);
2576
    }
2577
    gen_op_mac_set_flags(acc);
2578

    
2579
    if (insn & 0x30) {
2580
        int rw;
2581
        rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2582
        gen_op_mov32(rw, loadval);
2583
        /* FIXME: Should address writeback happen with the masked or
2584
           unmasked value?  */
2585
        switch ((insn >> 3) & 7) {
2586
        case 3: /* Post-increment.  */
2587
            gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
2588
            break;
2589
        case 4: /* Pre-decrement.  */
2590
            gen_op_mov32(AREG(insn, 0), addr);
2591
        }
2592
    }
2593
}
2594

    
2595
DISAS_INSN(from_mac)
2596
{
2597
    int rx;
2598
    int acc;
2599

    
2600
    rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2601
    acc = (insn >> 9) & 3;
2602
    if (s->env->macsr & MACSR_FI) {
2603
        gen_op_get_macf(rx, acc);
2604
    } else if ((s->env->macsr & MACSR_OMC) == 0) {
2605
        gen_op_get_maci(rx, acc);
2606
    } else if (s->env->macsr & MACSR_SU) {
2607
        gen_op_get_macs(rx, acc);
2608
    } else {
2609
        gen_op_get_macu(rx, acc);
2610
    }
2611
    if (insn & 0x40)
2612
        gen_op_clear_mac(acc);
2613
}
2614

    
2615
DISAS_INSN(move_mac)
2616
{
2617
    int src;
2618
    int dest;
2619
    src = insn & 3;
2620
    dest = (insn >> 9) & 3;
2621
    gen_op_move_mac(dest, src);
2622
    gen_op_mac_clear_flags();
2623
    gen_op_mac_set_flags(dest);
2624
}
2625

    
2626
DISAS_INSN(from_macsr)
2627
{
2628
    int reg;
2629

    
2630
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2631
    gen_op_mov32(reg, QREG_MACSR);
2632
}
2633

    
2634
DISAS_INSN(from_mask)
2635
{
2636
    int reg;
2637
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2638
    gen_op_mov32(reg, QREG_MAC_MASK);
2639
}
2640

    
2641
DISAS_INSN(from_mext)
2642
{
2643
    int reg;
2644
    int acc;
2645
    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2646
    acc = (insn & 0x400) ? 2 : 0;
2647
    if (s->env->macsr & MACSR_FI)
2648
        gen_op_get_mac_extf(reg, acc);
2649
    else
2650
        gen_op_get_mac_exti(reg, acc);
2651
}
2652

    
2653
DISAS_INSN(macsr_to_ccr)
2654
{
2655
    gen_op_mov32(QREG_CC_X, gen_im32(0));
2656
    gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
2657
    s->cc_op = CC_OP_FLAGS;
2658
}
2659

    
2660
DISAS_INSN(to_mac)
2661
{
2662
    int acc;
2663
    int val;
2664
    acc = (insn >>9) & 3;
2665
    SRC_EA(val, OS_LONG, 0, NULL);
2666
    if (s->env->macsr & MACSR_FI) {
2667
        gen_op_set_macf(val, acc);
2668
    } else if (s->env->macsr & MACSR_SU) {
2669
        gen_op_set_macs(val, acc);
2670
    } else {
2671
        gen_op_set_macu(val, acc);
2672
    }
2673
    gen_op_mac_clear_flags();
2674
    gen_op_mac_set_flags(acc);
2675
}
2676

    
2677
DISAS_INSN(to_macsr)
2678
{
2679
    int val;
2680
    SRC_EA(val, OS_LONG, 0, NULL);
2681
    gen_op_set_macsr(val);
2682
    gen_lookup_tb(s);
2683
}
2684

    
2685
DISAS_INSN(to_mask)
2686
{
2687
    int val;
2688
    SRC_EA(val, OS_LONG, 0, NULL);
2689
    gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
2690
}
2691

    
2692
DISAS_INSN(to_mext)
2693
{
2694
    int val;
2695
    int acc;
2696
    SRC_EA(val, OS_LONG, 0, NULL);
2697
    acc = (insn & 0x400) ? 2 : 0;
2698
    if (s->env->macsr & MACSR_FI)
2699
        gen_op_set_mac_extf(val, acc);
2700
    else if (s->env->macsr & MACSR_SU)
2701
        gen_op_set_mac_exts(val, acc);
2702
    else
2703
        gen_op_set_mac_extu(val, acc);
2704
}
2705

    
2706
static disas_proc opcode_table[65536];
2707

    
2708
static void
2709
register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2710
{
2711
  int i;
2712
  int from;
2713
  int to;
2714

    
2715
  /* Sanity check.  All set bits must be included in the mask.  */
2716
  if (opcode & ~mask) {
2717
      fprintf(stderr,
2718
              "qemu internal error: bogus opcode definition %04x/%04x\n",
2719
              opcode, mask);
2720
      abort();
2721
  }
2722
  /* This could probably be cleverer.  For now just optimize the case where
2723
     the top bits are known.  */
2724
  /* Find the first zero bit in the mask.  */
2725
  i = 0x8000;
2726
  while ((i & mask) != 0)
2727
      i >>= 1;
2728
  /* Iterate over all combinations of this and lower bits.  */
2729
  if (i == 0)
2730
      i = 1;
2731
  else
2732
      i <<= 1;
2733
  from = opcode & ~(i - 1);
2734
  to = from + i;
2735
  for (i = from; i < to; i++) {
2736
      if ((i & mask) == opcode)
2737
          opcode_table[i] = proc;
2738
  }
2739
}
2740

    
2741
/* Register m68k opcode handlers.  Order is important.
2742
   Later insn override earlier ones.  */
2743
void register_m68k_insns (CPUM68KState *env)
2744
{
2745
#define INSN(name, opcode, mask, feature) do { \
2746
    if (m68k_feature(env, M68K_FEATURE_##feature)) \
2747
        register_opcode(disas_##name, 0x##opcode, 0x##mask); \
2748
    } while(0)
2749
    INSN(undef,     0000, 0000, CF_ISA_A);
2750
    INSN(arith_im,  0080, fff8, CF_ISA_A);
2751
    INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
2752
    INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2753
    INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2754
    INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2755
    INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2756
    INSN(arith_im,  0280, fff8, CF_ISA_A);
2757
    INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
2758
    INSN(arith_im,  0480, fff8, CF_ISA_A);
2759
    INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
2760
    INSN(arith_im,  0680, fff8, CF_ISA_A);
2761
    INSN(bitop_im,  0800, ffc0, CF_ISA_A);
2762
    INSN(bitop_im,  0840, ffc0, CF_ISA_A);
2763
    INSN(bitop_im,  0880, ffc0, CF_ISA_A);
2764
    INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
2765
    INSN(arith_im,  0a80, fff8, CF_ISA_A);
2766
    INSN(arith_im,  0c00, ff38, CF_ISA_A);
2767
    INSN(move,      1000, f000, CF_ISA_A);
2768
    INSN(move,      2000, f000, CF_ISA_A);
2769
    INSN(move,      3000, f000, CF_ISA_A);
2770
    INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
2771
    INSN(negx,      4080, fff8, CF_ISA_A);
2772
    INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2773
    INSN(lea,       41c0, f1c0, CF_ISA_A);
2774
    INSN(clr,       4200, ff00, CF_ISA_A);
2775
    INSN(undef,     42c0, ffc0, CF_ISA_A);
2776
    INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2777
    INSN(neg,       4480, fff8, CF_ISA_A);
2778
    INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2779
    INSN(not,       4680, fff8, CF_ISA_A);
2780
    INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2781
    INSN(pea,       4840, ffc0, CF_ISA_A);
2782
    INSN(swap,      4840, fff8, CF_ISA_A);
2783
    INSN(movem,     48c0, fbc0, CF_ISA_A);
2784
    INSN(ext,       4880, fff8, CF_ISA_A);
2785
    INSN(ext,       48c0, fff8, CF_ISA_A);
2786
    INSN(ext,       49c0, fff8, CF_ISA_A);
2787
    INSN(tst,       4a00, ff00, CF_ISA_A);
2788
    INSN(tas,       4ac0, ffc0, CF_ISA_B);
2789
    INSN(halt,      4ac8, ffff, CF_ISA_A);
2790
    INSN(pulse,     4acc, ffff, CF_ISA_A);
2791
    INSN(illegal,   4afc, ffff, CF_ISA_A);
2792
    INSN(mull,      4c00, ffc0, CF_ISA_A);
2793
    INSN(divl,      4c40, ffc0, CF_ISA_A);
2794
    INSN(sats,      4c80, fff8, CF_ISA_B);
2795
    INSN(trap,      4e40, fff0, CF_ISA_A);
2796
    INSN(link,      4e50, fff8, CF_ISA_A);
2797
    INSN(unlk,      4e58, fff8, CF_ISA_A);
2798
    INSN(move_to_usp, 4e60, fff8, USP);
2799
    INSN(move_from_usp, 4e68, fff8, USP);
2800
    INSN(nop,       4e71, ffff, CF_ISA_A);
2801
    INSN(stop,      4e72, ffff, CF_ISA_A);
2802
    INSN(rte,       4e73, ffff, CF_ISA_A);
2803
    INSN(rts,       4e75, ffff, CF_ISA_A);
2804
    INSN(movec,     4e7b, ffff, CF_ISA_A);
2805
    INSN(jump,      4e80, ffc0, CF_ISA_A);
2806
    INSN(jump,      4ec0, ffc0, CF_ISA_A);
2807
    INSN(addsubq,   5180, f1c0, CF_ISA_A);
2808
    INSN(scc,       50c0, f0f8, CF_ISA_A);
2809
    INSN(addsubq,   5080, f1c0, CF_ISA_A);
2810
    INSN(tpf,       51f8, fff8, CF_ISA_A);
2811

    
2812
    /* Branch instructions.  */
2813
    INSN(branch,    6000, f000, CF_ISA_A);
2814
    /* Disable long branch instructions, then add back the ones we want.  */
2815
    INSN(undef,     60ff, f0ff, CF_ISA_A); /* All long branches.  */
2816
    INSN(branch,    60ff, f0ff, CF_ISA_B);
2817
    INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
2818
    INSN(branch,    60ff, ffff, BRAL);
2819

    
2820
    INSN(moveq,     7000, f100, CF_ISA_A);
2821
    INSN(mvzs,      7100, f100, CF_ISA_B);
2822
    INSN(or,        8000, f000, CF_ISA_A);
2823
    INSN(divw,      80c0, f0c0, CF_ISA_A);
2824
    INSN(addsub,    9000, f000, CF_ISA_A);
2825
    INSN(subx,      9180, f1f8, CF_ISA_A);
2826
    INSN(suba,      91c0, f1c0, CF_ISA_A);
2827

    
2828
    INSN(undef_mac, a000, f000, CF_ISA_A);
2829
    INSN(mac,       a000, f100, CF_EMAC);
2830
    INSN(from_mac,  a180, f9b0, CF_EMAC);
2831
    INSN(move_mac,  a110, f9fc, CF_EMAC);
2832
    INSN(from_macsr,a980, f9f0, CF_EMAC);
2833
    INSN(from_mask, ad80, fff0, CF_EMAC);
2834
    INSN(from_mext, ab80, fbf0, CF_EMAC);
2835
    INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
2836
    INSN(to_mac,    a100, f9c0, CF_EMAC);
2837
    INSN(to_macsr,  a900, ffc0, CF_EMAC);
2838
    INSN(to_mext,   ab00, fbc0, CF_EMAC);
2839
    INSN(to_mask,   ad00, ffc0, CF_EMAC);
2840

    
2841
    INSN(mov3q,     a140, f1c0, CF_ISA_B);
2842
    INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
2843
    INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
2844
    INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2845
    INSN(cmp,       b080, f1c0, CF_ISA_A);
2846
    INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
2847
    INSN(eor,       b180, f1c0, CF_ISA_A);
2848
    INSN(and,       c000, f000, CF_ISA_A);
2849
    INSN(mulw,      c0c0, f0c0, CF_ISA_A);
2850
    INSN(addsub,    d000, f000, CF_ISA_A);
2851
    INSN(addx,      d180, f1f8, CF_ISA_A);
2852
    INSN(adda,      d1c0, f1c0, CF_ISA_A);
2853
    INSN(shift_im,  e080, f0f0, CF_ISA_A);
2854
    INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2855
    INSN(undef_fpu, f000, f000, CF_ISA_A);
2856
    INSN(fpu,       f200, ffc0, CF_FPU);
2857
    INSN(fbcc,      f280, ffc0, CF_FPU);
2858
    INSN(frestore,  f340, ffc0, CF_FPU);
2859
    INSN(fsave,     f340, ffc0, CF_FPU);
2860
    INSN(intouch,   f340, ffc0, CF_ISA_A);
2861
    INSN(cpushl,    f428, ff38, CF_ISA_A);
2862
    INSN(wddata,    fb00, ff00, CF_ISA_A);
2863
    INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
2864
#undef INSN
2865
}
2866

    
2867
/* ??? Some of this implementation is not exception safe.  We should always
2868
   write back the result to memory before setting the condition codes.  */
2869
static void disas_m68k_insn(CPUState * env, DisasContext *s)
2870
{
2871
    uint16_t insn;
2872

    
2873
    insn = lduw_code(s->pc);
2874
    s->pc += 2;
2875

    
2876
    opcode_table[insn](s, insn);
2877
}
2878

    
2879
#if 0
2880
/* Save the result of a floating point operation.  */
2881
static void expand_op_fp_result(qOP *qop)
2882
{
2883
    gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2884
}
2885

2886
/* Dummy op to indicate that the flags have been set.  */
2887
static void expand_op_flags_set(qOP *qop)
2888
{
2889
}
2890

2891
/* Convert the confition codes into CC_OP_FLAGS format.  */
2892
static void expand_op_flush_flags(qOP *qop)
2893
{
2894
    int cc_opreg;
2895

2896
    if (qop->args[0] == CC_OP_DYNAMIC)
2897
        cc_opreg = QREG_CC_OP;
2898
    else
2899
        cc_opreg = gen_im32(qop->args[0]);
2900
    gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2901
}
2902

2903
/* Set CC_DEST after a logical or direct flag setting operation.  */
2904
static void expand_op_logic_cc(qOP *qop)
2905
{
2906
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2907
}
2908

2909
/* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2910
static void expand_op_update_cc_add(qOP *qop)
2911
{
2912
    gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2913
    gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2914
}
2915

2916
/* Update the X flag.  */
2917
static void expand_op_update_xflag(qOP *qop)
2918
{
2919
    int arg0;
2920
    int arg1;
2921

2922
    arg0 = qop->args[0];
2923
    arg1 = qop->args[1];
2924
    if (arg1 == QREG_NULL) {
2925
        /* CC_X = arg0.  */
2926
        gen_op_mov32(QREG_CC_X, arg0);
2927
    } else {
2928
        /* CC_X = arg0 < (unsigned)arg1.  */
2929
        gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2930
    }
2931
}
2932

2933
/* Set arg0 to the contents of the X flag.  */
2934
static void expand_op_get_xflag(qOP *qop)
2935
{
2936
    gen_op_mov32(qop->args[0], QREG_CC_X);
2937
}
2938

2939
/* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2940
   already know the shift is within range.  */
2941
static inline void expand_shift_im(qOP *qop, int right, int arith)
2942
{
2943
    int val;
2944
    int reg;
2945
    int tmp;
2946
    int im;
2947

2948
    reg = qop->args[0];
2949
    im = qop->args[1];
2950
    tmp = gen_im32(im);
2951
    val = gen_new_qreg(QMODE_I32);
2952
    gen_op_mov32(val, reg);
2953
    gen_op_mov32(QREG_CC_DEST, val);
2954
    gen_op_mov32(QREG_CC_SRC, tmp);
2955
    if (right) {
2956
        if (arith) {
2957
            gen_op_sar32(reg, val, tmp);
2958
        } else {
2959
            gen_op_shr32(reg, val, tmp);
2960
        }
2961
        if (im == 1)
2962
            tmp = QREG_NULL;
2963
        else
2964
            tmp = gen_im32(im - 1);
2965
    } else {
2966
        gen_op_shl32(reg, val, tmp);
2967
        tmp = gen_im32(32 - im);
2968
    }
2969
    if (tmp != QREG_NULL)
2970
        gen_op_shr32(val, val, tmp);
2971
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
2972
}
2973

2974
static void expand_op_shl_im_cc(qOP *qop)
2975
{
2976
    expand_shift_im(qop, 0, 0);
2977
}
2978

2979
static void expand_op_shr_im_cc(qOP *qop)
2980
{
2981
    expand_shift_im(qop, 1, 0);
2982
}
2983

2984
static void expand_op_sar_im_cc(qOP *qop)
2985
{
2986
    expand_shift_im(qop, 1, 1);
2987
}
2988

2989
/* Expand a shift by register.  */
2990
/* ??? This gives incorrect answers for shifts by 0 or >= 32 */
2991
static inline void expand_shift_reg(qOP *qop, int right, int arith)
2992
{
2993
    int val;
2994
    int reg;
2995
    int shift;
2996
    int tmp;
2997

2998
    reg = qop->args[0];
2999
    shift = qop->args[1];
3000
    val = gen_new_qreg(QMODE_I32);
3001
    gen_op_mov32(val, reg);
3002
    gen_op_mov32(QREG_CC_DEST, val);
3003
    gen_op_mov32(QREG_CC_SRC, shift);
3004
    tmp = gen_new_qreg(QMODE_I32);
3005
    if (right) {
3006
        if (arith) {
3007
            gen_op_sar32(reg, val, shift);
3008
        } else {
3009
            gen_op_shr32(reg, val, shift);
3010
        }
3011
        gen_op_sub32(tmp, shift, gen_im32(1));
3012
    } else {
3013
        gen_op_shl32(reg, val, shift);
3014
        gen_op_sub32(tmp, gen_im32(31), shift);
3015
    }
3016
    gen_op_shl32(val, val, tmp);
3017
    gen_op_and32(QREG_CC_X, val, gen_im32(1));
3018
}
3019

3020
static void expand_op_shl_cc(qOP *qop)
3021
{
3022
    expand_shift_reg(qop, 0, 0);
3023
}
3024

3025
static void expand_op_shr_cc(qOP *qop)
3026
{
3027
    expand_shift_reg(qop, 1, 0);
3028
}
3029

3030
static void expand_op_sar_cc(qOP *qop)
3031
{
3032
    expand_shift_reg(qop, 1, 1);
3033
}
3034

3035
/* Set the Z flag to (arg0 & arg1) == 0.  */
3036
static void expand_op_btest(qOP *qop)
3037
{
3038
    int tmp;
3039
    int l1;
3040

3041
    l1 = gen_new_label();
3042
    tmp = gen_new_qreg(QMODE_I32);
3043
    gen_op_and32(tmp, qop->args[0], qop->args[1]);
3044
    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
3045
    gen_op_jmp_nz32(tmp, l1);
3046
    gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
3047
    gen_op_label(l1);
3048
}
3049

3050
/* arg0 += arg1 + CC_X */
3051
static void expand_op_addx_cc(qOP *qop)
3052
{
3053
    int arg0 = qop->args[0];
3054
    int arg1 = qop->args[1];
3055
    int l1, l2;
3056

3057
    gen_op_add32 (arg0, arg0, arg1);
3058
    l1 = gen_new_label();
3059
    l2 = gen_new_label();
3060
    gen_op_jmp_z32(QREG_CC_X, l1);
3061
    gen_op_add32(arg0, arg0, gen_im32(1));
3062
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
3063
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3064
    gen_op_jmp_im(l2);
3065
    gen_set_label(l1);
3066
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
3067
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3068
    gen_set_label(l2);
3069
}
3070

3071
/* arg0 -= arg1 + CC_X */
3072
static void expand_op_subx_cc(qOP *qop)
3073
{
3074
    int arg0 = qop->args[0];
3075
    int arg1 = qop->args[1];
3076
    int l1, l2;
3077

3078
    l1 = gen_new_label();
3079
    l2 = gen_new_label();
3080
    gen_op_jmp_z32(QREG_CC_X, l1);
3081
    gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3082
    gen_op_sub32(arg0, arg0, gen_im32(1));
3083
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
3084
    gen_op_jmp_im(l2);
3085
    gen_set_label(l1);
3086
    gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3087
    gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
3088
    gen_set_label(l2);
3089
    gen_op_sub32 (arg0, arg0, arg1);
3090
}
3091

3092
/* Expand target specific ops to generic qops.  */
3093
static void expand_target_qops(void)
3094
{
3095
    qOP *qop;
3096
    qOP *next;
3097
    int c;
3098

3099
    /* Copy the list of qops, expanding target specific ops as we go.  */
3100
    qop = gen_first_qop;
3101
    gen_first_qop = NULL;
3102
    gen_last_qop = NULL;
3103
    for (; qop; qop = next) {
3104
        c = qop->opcode;
3105
        next = qop->next;
3106
        if (c < FIRST_TARGET_OP) {
3107
            qop->prev = gen_last_qop;
3108
            qop->next = NULL;
3109
            if (gen_last_qop)
3110
                gen_last_qop->next = qop;
3111
            else
3112
                gen_first_qop = qop;
3113
            gen_last_qop = qop;
3114
            continue;
3115
        }
3116
        switch (c) {
3117
#define DEF(name, nargs, barrier) \
3118
        case INDEX_op_##name: \
3119
            expand_op_##name(qop); \
3120
            break;
3121
#include "qop-target.def"
3122
#undef DEF
3123
        default:
3124
            cpu_abort(NULL, "Unexpanded target qop");
3125
        }
3126
    }
3127
}
3128

3129
/* ??? Implement this.  */
3130
static void
3131
optimize_flags(void)
3132
{
3133
}
3134
#endif
3135

    
3136
/* generate intermediate code for basic block 'tb'.  */
3137
static inline int
3138
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3139
                               int search_pc)
3140
{
3141
    DisasContext dc1, *dc = &dc1;
3142
    uint16_t *gen_opc_end;
3143
    int j, lj;
3144
    target_ulong pc_start;
3145
    int pc_offset;
3146
    int last_cc_op;
3147

    
3148
    /* generate intermediate code */
3149
    pc_start = tb->pc;
3150

    
3151
    dc->tb = tb;
3152

    
3153
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3154

    
3155
    dc->env = env;
3156
    dc->is_jmp = DISAS_NEXT;
3157
    dc->pc = pc_start;
3158
    dc->cc_op = CC_OP_DYNAMIC;
3159
    dc->singlestep_enabled = env->singlestep_enabled;
3160
    dc->fpcr = env->fpcr;
3161
    dc->user = (env->sr & SR_S) == 0;
3162
    dc->is_mem = 0;
3163
    lj = -1;
3164
    do {
3165
        free_qreg = 0;
3166
        pc_offset = dc->pc - pc_start;
3167
        gen_throws_exception = NULL;
3168
        if (env->nb_breakpoints > 0) {
3169
            for(j = 0; j < env->nb_breakpoints; j++) {
3170
                if (env->breakpoints[j] == dc->pc) {
3171
                    gen_exception(dc, dc->pc, EXCP_DEBUG);
3172
                    dc->is_jmp = DISAS_JUMP;
3173
                    break;
3174
                }
3175
            }
3176
            if (dc->is_jmp)
3177
                break;
3178
        }
3179
        if (search_pc) {
3180
            j = gen_opc_ptr - gen_opc_buf;
3181
            if (lj < j) {
3182
                lj++;
3183
                while (lj < j)
3184
                    gen_opc_instr_start[lj++] = 0;
3185
            }
3186
            gen_opc_pc[lj] = dc->pc;
3187
            gen_opc_instr_start[lj] = 1;
3188
        }
3189
        last_cc_op = dc->cc_op;
3190
        dc->insn_pc = dc->pc;
3191
        disas_m68k_insn(env, dc);
3192

    
3193
        /* Terminate the TB on memory ops if watchpoints are present.  */
3194
        /* FIXME: This should be replacd by the deterministic execution
3195
         * IRQ raising bits.  */
3196
        if (dc->is_mem && env->nb_watchpoints)
3197
            break;
3198
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3199
             !env->singlestep_enabled &&
3200
             (pc_offset) < (TARGET_PAGE_SIZE - 32));
3201

    
3202
    if (__builtin_expect(env->singlestep_enabled, 0)) {
3203
        /* Make sure the pc is updated, and raise a debug exception.  */
3204
        if (!dc->is_jmp) {
3205
            gen_flush_cc_op(dc);
3206
            gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
3207
        }
3208
        gen_op_raise_exception(EXCP_DEBUG);
3209
    } else {
3210
        switch(dc->is_jmp) {
3211
        case DISAS_NEXT:
3212
            gen_flush_cc_op(dc);
3213
            gen_jmp_tb(dc, 0, dc->pc);
3214
            break;
3215
        default:
3216
        case DISAS_JUMP:
3217
        case DISAS_UPDATE:
3218
            gen_flush_cc_op(dc);
3219
            /* indicate that the hash table must be used to find the next TB */
3220
            tcg_gen_exit_tb(0);
3221
            break;
3222
        case DISAS_TB_JUMP:
3223
            /* nothing more to generate */
3224
            break;
3225
        }
3226
    }
3227
    *gen_opc_ptr = INDEX_op_end;
3228

    
3229
#ifdef DEBUG_DISAS
3230
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3231
        fprintf(logfile, "----------------\n");
3232
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3233
        target_disas(logfile, pc_start, dc->pc - pc_start, 0);
3234
        fprintf(logfile, "\n");
3235
    }
3236
#endif
3237
    if (search_pc) {
3238
        j = gen_opc_ptr - gen_opc_buf;
3239
        lj++;
3240
        while (lj <= j)
3241
            gen_opc_instr_start[lj++] = 0;
3242
    } else {
3243
        tb->size = dc->pc - pc_start;
3244
    }
3245

    
3246
    //optimize_flags();
3247
    //expand_target_qops();
3248
    return 0;
3249
}
3250

    
3251
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
3252
{
3253
    return gen_intermediate_code_internal(env, tb, 0);
3254
}
3255

    
3256
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
3257
{
3258
    return gen_intermediate_code_internal(env, tb, 1);
3259
}
3260

    
3261
void cpu_dump_state(CPUState *env, FILE *f,
3262
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3263
                    int flags)
3264
{
3265
    int i;
3266
    uint16_t sr;
3267
    CPU_DoubleU u;
3268
    for (i = 0; i < 8; i++)
3269
      {
3270
        u.d = env->fregs[i];
3271
        cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
3272
                     i, env->dregs[i], i, env->aregs[i],
3273
                     i, u.l.upper, u.l.lower, *(double *)&u.d);
3274
      }
3275
    cpu_fprintf (f, "PC = %08x   ", env->pc);
3276
    sr = env->sr;
3277
    cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
3278
                 (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
3279
                 (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
3280
    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
3281
}
3282

    
3283
void gen_pc_load(CPUState *env, TranslationBlock *tb,
3284
                unsigned long searched_pc, int pc_pos, void *puc)
3285
{
3286
    env->pc = gen_opc_pc[pc_pos];
3287
}