ad8faadc0c8a0506f3585e54b1be97f50237a840
[qemu] / target-m68k / translate.c
1 /*
2  *  m68k translation
3  * 
4  *  Copyright (c) 2005-2007 CodeSourcery
5  *  Written by Paul Brook
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
26
27 #include "config.h"
28 #include "cpu.h"
29 #include "exec-all.h"
30 #include "disas.h"
31 #include "m68k-qreg.h"
32
33 //#define DEBUG_DISPATCH 1
34
35 static inline void qemu_assert(int cond, const char *msg)
36 {
37     if (!cond) {
38         fprintf (stderr, "badness: %s\n", msg);
39         abort();
40     }
41 }
42
43 /* internal defines */
44 typedef struct DisasContext {
45     CPUM68KState *env;
46     target_ulong insn_pc; /* Start of the current instruction.  */
47     target_ulong pc;
48     int is_jmp;
49     int cc_op;
50     int user;
51     uint32_t fpcr;
52     struct TranslationBlock *tb;
53     int singlestep_enabled;
54 } DisasContext;
55
56 #define DISAS_JUMP_NEXT 4
57
58 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) 1
60 #else
61 #define IS_USER(s) s->user
62 #endif
63
64 /* XXX: move that elsewhere */
65 /* ??? Fix exceptions.  */
66 static void *gen_throws_exception;
67 #define gen_last_qop NULL
68
69 static uint16_t *gen_opc_ptr;
70 static uint32_t *gen_opparam_ptr;
71 extern FILE *logfile;
72 extern int loglevel;
73
74 enum {
75 #define DEF(s, n, copy_size) INDEX_op_ ## s,
76 #include "opc.h"
77 #undef DEF
78     NB_OPS,
79 };
80
81 #include "gen-op.h"
82
83 #if defined(CONFIG_USER_ONLY)
84 #define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
85 #define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
86 #else
87 #define gen_st(s, name, addr, val) do { \
88     if (IS_USER(s)) \
89         gen_op_st##name##_user(addr, val); \
90     else \
91         gen_op_st##name##_kernel(addr, val); \
92     } while (0)
93 #define gen_ld(s, name, val, addr) do { \
94     if (IS_USER(s)) \
95         gen_op_ld##name##_user(val, addr); \
96     else \
97         gen_op_ld##name##_kernel(val, addr); \
98     } while (0)
99 #endif
100
101 #include "op-hacks.h"
102
103 #define OS_BYTE 0
104 #define OS_WORD 1
105 #define OS_LONG 2
106 #define OS_SINGLE 4
107 #define OS_DOUBLE 5
108
109 #define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
110 #define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
111 #define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
112
113 typedef void (*disas_proc)(DisasContext *, uint16_t);
114
115 #ifdef DEBUG_DISPATCH
116 #define DISAS_INSN(name) \
117   static void real_disas_##name (DisasContext *s, uint16_t insn); \
118   static void disas_##name (DisasContext *s, uint16_t insn) { \
119     if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
120     real_disas_##name(s, insn); } \
121   static void real_disas_##name (DisasContext *s, uint16_t insn)
122 #else
123 #define DISAS_INSN(name) \
124   static void disas_##name (DisasContext *s, uint16_t insn)
125 #endif
126
127 /* Generate a load from the specified address.  Narrow values are
128    sign extended to full register width.  */
129 static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
130 {
131     int tmp;
132     switch(opsize) {
133     case OS_BYTE:
134         tmp = gen_new_qreg(QMODE_I32);
135         if (sign)
136             gen_ld(s, 8s32, tmp, addr);
137         else
138             gen_ld(s, 8u32, tmp, addr);
139         break;
140     case OS_WORD:
141         tmp = gen_new_qreg(QMODE_I32);
142         if (sign)
143             gen_ld(s, 16s32, tmp, addr);
144         else
145             gen_ld(s, 16u32, tmp, addr);
146         break;
147     case OS_LONG:
148         tmp = gen_new_qreg(QMODE_I32);
149         gen_ld(s, 32, tmp, addr);
150         break;
151     case OS_SINGLE:
152         tmp = gen_new_qreg(QMODE_F32);
153         gen_ld(s, f32, tmp, addr);
154         break;
155     case OS_DOUBLE:
156         tmp  = gen_new_qreg(QMODE_F64);
157         gen_ld(s, f64, tmp, addr);
158         break;
159     default:
160         qemu_assert(0, "bad load size");
161     }
162     gen_throws_exception = gen_last_qop;
163     return tmp;
164 }
165
166 /* Generate a store.  */
167 static inline void gen_store(DisasContext *s, int opsize, int addr, int val)
168 {
169     switch(opsize) {
170     case OS_BYTE:
171         gen_st(s, 8, addr, val);
172         break;
173     case OS_WORD:
174         gen_st(s, 16, addr, val);
175         break;
176     case OS_LONG:
177         gen_st(s, 32, addr, val);
178         break;
179     case OS_SINGLE:
180         gen_st(s, f32, addr, val);
181         break;
182     case OS_DOUBLE:
183         gen_st(s, f64, addr, val);
184         break;
185     default:
186         qemu_assert(0, "bad store size");
187     }
188     gen_throws_exception = gen_last_qop;
189 }
190
191 /* Generate an unsigned load if VAL is 0 a signed load if val is -1,
192    otherwise generate a store.  */
193 static int gen_ldst(DisasContext *s, int opsize, int addr, int val)
194 {
195     if (val > 0) {
196         gen_store(s, opsize, addr, val);
197         return 0;
198     } else {
199         return gen_load(s, opsize, addr, val != 0);
200     }
201 }
202
203 /* Read a 32-bit immediate constant.  */
204 static inline uint32_t read_im32(DisasContext *s)
205 {
206     uint32_t im;
207     im = ((uint32_t)lduw_code(s->pc)) << 16;
208     s->pc += 2;
209     im |= lduw_code(s->pc);
210     s->pc += 2;
211     return im;
212 }
213
214 /* Calculate and address index.  */
215 static int gen_addr_index(uint16_t ext, int tmp)
216 {
217     int add;
218     int scale;
219
220     add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
221     if ((ext & 0x800) == 0) {
222         gen_op_ext16s32(tmp, add);
223         add = tmp;
224     }
225     scale = (ext >> 9) & 3;
226     if (scale != 0) {
227         gen_op_shl32(tmp, add, gen_im32(scale));
228         add = tmp;
229     }
230     return add;
231 }
232
233 /* Handle a base + index + displacement effective addresss.  A base of
234    -1 means pc-relative.  */
235 static int gen_lea_indexed(DisasContext *s, int opsize, int base)
236 {
237     uint32_t offset;
238     uint16_t ext;
239     int add;
240     int tmp;
241     uint32_t bd, od;
242
243     offset = s->pc;
244     ext = lduw_code(s->pc);
245     s->pc += 2;
246
247     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
248         return -1;
249
250     if (ext & 0x100) {
251         /* full extension word format */
252         if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
253             return -1;
254
255         if ((ext & 0x30) > 0x10) {
256             /* base displacement */
257             if ((ext & 0x30) == 0x20) {
258                 bd = (int16_t)lduw_code(s->pc);
259                 s->pc += 2;
260             } else {
261                 bd = read_im32(s);
262             }
263         } else {
264             bd = 0;
265         }
266         tmp = gen_new_qreg(QMODE_I32);
267         if ((ext & 0x44) == 0) {
268             /* pre-index */
269             add = gen_addr_index(ext, tmp);
270         } else {
271             add = QREG_NULL;
272         }
273         if ((ext & 0x80) == 0) {
274             /* base not suppressed */
275             if (base == -1) {
276                 base = gen_im32(offset + bd);
277                 bd = 0;
278             }
279             if (add) {
280                 gen_op_add32(tmp, add, base);
281                 add = tmp;
282             } else {
283                 add = base;
284             }
285         }
286         if (add) {
287             if (bd != 0) {
288                 gen_op_add32(tmp, add, gen_im32(bd));
289                 add = tmp;
290             }
291         } else {
292             add = gen_im32(bd);
293         }
294         if ((ext & 3) != 0) {
295             /* memory indirect */
296             base = gen_load(s, OS_LONG, add, 0);
297             if ((ext & 0x44) == 4) {
298                 add = gen_addr_index(ext, tmp);
299                 gen_op_add32(tmp, add, base);
300                 add = tmp;
301             } else {
302                 add = base;
303             }
304             if ((ext & 3) > 1) {
305                 /* outer displacement */
306                 if ((ext & 3) == 2) {
307                     od = (int16_t)lduw_code(s->pc);
308                     s->pc += 2;
309                 } else {
310                     od = read_im32(s);
311                 }
312             } else {
313                 od = 0;
314             }
315             if (od != 0) {
316                 gen_op_add32(tmp, add, gen_im32(od));
317                 add = tmp;
318             }
319         }
320     } else {
321         /* brief extension word format */
322         tmp = gen_new_qreg(QMODE_I32);
323         add = gen_addr_index(ext, tmp);
324         if (base != -1) {
325             gen_op_add32(tmp, add, base);
326             if ((int8_t)ext)
327                 gen_op_add32(tmp, tmp, gen_im32((int8_t)ext));
328         } else {
329             gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
330         }
331         add = tmp;
332     }
333     return add;
334 }
335
336 /* Update the CPU env CC_OP state.  */
337 static inline void gen_flush_cc_op(DisasContext *s)
338 {
339     if (s->cc_op != CC_OP_DYNAMIC)
340         gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
341 }
342
343 /* Evaluate all the CC flags.  */
344 static inline void gen_flush_flags(DisasContext *s)
345 {
346     if (s->cc_op == CC_OP_FLAGS)
347         return;
348     gen_flush_cc_op(s);
349     gen_op_flush_flags();
350     s->cc_op = CC_OP_FLAGS;
351 }
352
353 static inline int opsize_bytes(int opsize)
354 {
355     switch (opsize) {
356     case OS_BYTE: return 1;
357     case OS_WORD: return 2;
358     case OS_LONG: return 4;
359     case OS_SINGLE: return 4;
360     case OS_DOUBLE: return 8;
361     default:
362         qemu_assert(0, "bad operand size");
363     }
364 }
365
366 /* Assign value to a register.  If the width is less than the register width
367    only the low part of the register is set.  */
368 static void gen_partset_reg(int opsize, int reg, int val)
369 {
370     int tmp;
371     switch (opsize) {
372     case OS_BYTE:
373         gen_op_and32(reg, reg, gen_im32(0xffffff00));
374         tmp = gen_new_qreg(QMODE_I32);
375         gen_op_and32(tmp, val, gen_im32(0xff));
376         gen_op_or32(reg, reg, tmp);
377         break;
378     case OS_WORD:
379         gen_op_and32(reg, reg, gen_im32(0xffff0000));
380         tmp = gen_new_qreg(QMODE_I32);
381         gen_op_and32(tmp, val, gen_im32(0xffff));
382         gen_op_or32(reg, reg, tmp);
383         break;
384     case OS_LONG:
385         gen_op_mov32(reg, val);
386         break;
387     case OS_SINGLE:
388         gen_op_pack_32_f32(reg, val);
389         break;
390     default:
391         qemu_assert(0, "Bad operand size");
392         break;
393     }
394 }
395
396 /* Sign or zero extend a value.  */
397 static inline int gen_extend(int val, int opsize, int sign)
398 {
399     int tmp;
400
401     switch (opsize) {
402     case OS_BYTE:
403         tmp = gen_new_qreg(QMODE_I32);
404         if (sign)
405             gen_op_ext8s32(tmp, val);
406         else
407             gen_op_ext8u32(tmp, val);
408         break;
409     case OS_WORD:
410         tmp = gen_new_qreg(QMODE_I32);
411         if (sign)
412             gen_op_ext16s32(tmp, val);
413         else
414             gen_op_ext16u32(tmp, val);
415         break;
416     case OS_LONG:
417         tmp = val;
418         break;
419     case OS_SINGLE:
420         tmp = gen_new_qreg(QMODE_F32);
421         gen_op_pack_f32_32(tmp, val);
422         break;
423     default:
424         qemu_assert(0, "Bad operand size");
425     }
426     return tmp;
427 }
428
429 /* Generate code for an "effective address".  Does not adjust the base
430    register for autoincrememnt addressing modes.  */
431 static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
432 {
433     int reg;
434     int tmp;
435     uint16_t ext;
436     uint32_t offset;
437
438     reg = insn & 7;
439     switch ((insn >> 3) & 7) {
440     case 0: /* Data register direct.  */
441     case 1: /* Address register direct.  */
442         return -1;
443     case 2: /* Indirect register */
444     case 3: /* Indirect postincrement.  */
445         reg += QREG_A0;
446         return reg;
447     case 4: /* Indirect predecrememnt.  */
448         reg += QREG_A0;
449         tmp = gen_new_qreg(QMODE_I32);
450         gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
451         return tmp;
452     case 5: /* Indirect displacement.  */
453         reg += QREG_A0;
454         tmp = gen_new_qreg(QMODE_I32);
455         ext = lduw_code(s->pc);
456         s->pc += 2;
457         gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
458         return tmp;
459     case 6: /* Indirect index + displacement.  */
460         reg += QREG_A0;
461         return gen_lea_indexed(s, opsize, reg);
462     case 7: /* Other */
463         switch (reg) {
464         case 0: /* Absolute short.  */
465             offset = ldsw_code(s->pc);
466             s->pc += 2;
467             return gen_im32(offset);
468         case 1: /* Absolute long.  */
469             offset = read_im32(s);
470             return gen_im32(offset);
471         case 2: /* pc displacement  */
472             tmp = gen_new_qreg(QMODE_I32);
473             offset = s->pc;
474             offset += ldsw_code(s->pc);
475             s->pc += 2;
476             return gen_im32(offset);
477         case 3: /* pc index+displacement.  */
478             return gen_lea_indexed(s, opsize, -1);
479         case 4: /* Immediate.  */
480         default:
481             return -1;
482         }
483     }
484     /* Should never happen.  */
485     return -1;
486 }
487
488 /* Helper function for gen_ea. Reuse the computed address between the
489    for read/write operands.  */
490 static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
491                               int val, int *addrp)
492 {
493     int tmp;
494
495     if (addrp && val > 0) {
496         tmp = *addrp;
497     } else {
498         tmp = gen_lea(s, insn, opsize);
499         if (tmp == -1)
500             return -1;
501         if (addrp)
502             *addrp = tmp;
503     }
504     return gen_ldst(s, opsize, tmp, val);
505 }
506
507 /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
508    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
509    ADDRP is non-null for readwrite operands.  */
510 static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
511                   int *addrp)
512 {
513     int reg;
514     int result;
515     uint32_t offset;
516
517     reg = insn & 7;
518     switch ((insn >> 3) & 7) {
519     case 0: /* Data register direct.  */
520         reg += QREG_D0;
521         if (val > 0) {
522             gen_partset_reg(opsize, reg, val);
523             return 0;
524         } else {
525             return gen_extend(reg, opsize, val);
526         }
527     case 1: /* Address register direct.  */
528         reg += QREG_A0;
529         if (val > 0) {
530             gen_op_mov32(reg, val);
531             return 0;
532         } else {
533             return gen_extend(reg, opsize, val);
534         }
535     case 2: /* Indirect register */
536         reg += QREG_A0;
537         return gen_ldst(s, opsize, reg, val);
538     case 3: /* Indirect postincrement.  */
539         reg += QREG_A0;
540         result = gen_ldst(s, opsize, reg, val);
541         /* ??? This is not exception safe.  The instruction may still
542            fault after this point.  */
543         if (val > 0 || !addrp)
544             gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
545         return result;
546     case 4: /* Indirect predecrememnt.  */
547         {
548             int tmp;
549             if (addrp && val > 0) {
550                 tmp = *addrp;
551             } else {
552                 tmp = gen_lea(s, insn, opsize);
553                 if (tmp == -1)
554                     return -1;
555                 if (addrp)
556                     *addrp = tmp;
557             }
558             result = gen_ldst(s, opsize, tmp, val);
559             /* ??? This is not exception safe.  The instruction may still
560                fault after this point.  */
561             if (val > 0 || !addrp) {
562                 reg += QREG_A0;
563                 gen_op_mov32(reg, tmp);
564             }
565         }
566         return result;
567     case 5: /* Indirect displacement.  */
568     case 6: /* Indirect index + displacement.  */
569         return gen_ea_once(s, insn, opsize, val, addrp);
570     case 7: /* Other */
571         switch (reg) {
572         case 0: /* Absolute short.  */
573         case 1: /* Absolute long.  */
574         case 2: /* pc displacement  */
575         case 3: /* pc index+displacement.  */
576             return gen_ea_once(s, insn, opsize, val, addrp);
577         case 4: /* Immediate.  */
578             /* Sign extend values for consistency.  */
579             switch (opsize) {
580             case OS_BYTE:
581                 if (val)
582                     offset = ldsb_code(s->pc + 1);
583                 else
584                     offset = ldub_code(s->pc + 1);
585                 s->pc += 2;
586                 break;
587             case OS_WORD:
588                 if (val)
589                     offset = ldsw_code(s->pc);
590                 else
591                     offset = lduw_code(s->pc);
592                 s->pc += 2;
593                 break;
594             case OS_LONG:
595                 offset = read_im32(s);
596                 break;
597             default:
598                 qemu_assert(0, "Bad immediate operand");
599             }
600             return gen_im32(offset);
601         default:
602             return -1;
603         }
604     }
605     /* Should never happen.  */
606     return -1;
607 }
608
609 static void gen_logic_cc(DisasContext *s, int val)
610 {
611     gen_op_logic_cc(val);
612     s->cc_op = CC_OP_LOGIC;
613 }
614
615 static void gen_jmpcc(DisasContext *s, int cond, int l1)
616 {
617     int tmp;
618
619     gen_flush_flags(s);
620     switch (cond) {
621     case 0: /* T */
622         gen_op_jmp(l1);
623         break;
624     case 1: /* F */
625         break;
626     case 2: /* HI (!C && !Z) */
627         tmp = gen_new_qreg(QMODE_I32);
628         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
629         gen_op_jmp_z32(tmp, l1);
630         break;
631     case 3: /* LS (C || Z) */
632         tmp = gen_new_qreg(QMODE_I32);
633         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
634         gen_op_jmp_nz32(tmp, l1);
635         break;
636     case 4: /* CC (!C) */
637         tmp = gen_new_qreg(QMODE_I32);
638         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
639         gen_op_jmp_z32(tmp, l1);
640         break;
641     case 5: /* CS (C) */
642         tmp = gen_new_qreg(QMODE_I32);
643         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
644         gen_op_jmp_nz32(tmp, l1);
645         break;
646     case 6: /* NE (!Z) */
647         tmp = gen_new_qreg(QMODE_I32);
648         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
649         gen_op_jmp_z32(tmp, l1);
650         break;
651     case 7: /* EQ (Z) */
652         tmp = gen_new_qreg(QMODE_I32);
653         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
654         gen_op_jmp_nz32(tmp, l1);
655         break;
656     case 8: /* VC (!V) */
657         tmp = gen_new_qreg(QMODE_I32);
658         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
659         gen_op_jmp_z32(tmp, l1);
660         break;
661     case 9: /* VS (V) */
662         tmp = gen_new_qreg(QMODE_I32);
663         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
664         gen_op_jmp_nz32(tmp, l1);
665         break;
666     case 10: /* PL (!N) */
667         tmp = gen_new_qreg(QMODE_I32);
668         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
669         gen_op_jmp_z32(tmp, l1);
670         break;
671     case 11: /* MI (N) */
672         tmp = gen_new_qreg(QMODE_I32);
673         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
674         gen_op_jmp_nz32(tmp, l1);
675         break;
676     case 12: /* GE (!(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_z32(tmp, l1);
682         break;
683     case 13: /* LT (N ^ V) */
684         tmp = gen_new_qreg(QMODE_I32);
685         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
686         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
687         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
688         gen_op_jmp_nz32(tmp, l1);
689         break;
690     case 14: /* GT (!(Z || (N ^ V))) */
691         {
692             int l2;
693             l2 = gen_new_label();
694             tmp = gen_new_qreg(QMODE_I32);
695             gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
696             gen_op_jmp_nz32(tmp, l2);
697             tmp = gen_new_qreg(QMODE_I32);
698             gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
699             gen_op_xor32(tmp, tmp, QREG_CC_DEST);
700             gen_op_and32(tmp, tmp, gen_im32(CCF_V));
701             gen_op_jmp_nz32(tmp, l2);
702             gen_op_jmp(l1);
703             gen_set_label(l2);
704         }
705         break;
706     case 15: /* LE (Z || (N ^ V)) */
707         tmp = gen_new_qreg(QMODE_I32);
708         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
709         gen_op_jmp_nz32(tmp, l1);
710         tmp = gen_new_qreg(QMODE_I32);
711         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
712         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
713         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
714         gen_op_jmp_nz32(tmp, l1);
715         break;
716     default:
717         /* Should ever happen.  */
718         abort();
719     }
720 }
721
722 DISAS_INSN(scc)
723 {
724     int l1;
725     int cond;
726     int reg;
727
728     l1 = gen_new_label();
729     cond = (insn >> 8) & 0xf;
730     reg = DREG(insn, 0);
731     gen_op_and32(reg, reg, gen_im32(0xffffff00));
732     gen_jmpcc(s, cond ^ 1, l1);
733     gen_op_or32(reg, reg, gen_im32(0xff));
734     gen_set_label(l1);
735 }
736
737 /* Force a TB lookup after an instruction that changes the CPU state.  */
738 static void gen_lookup_tb(DisasContext *s)
739 {
740     gen_flush_cc_op(s);
741     gen_op_mov32(QREG_PC, gen_im32(s->pc));
742     s->is_jmp = DISAS_UPDATE;
743 }
744
745 /* Generate a jump to to the address in qreg DEST.  */
746 static void gen_jmp(DisasContext *s, int dest)
747 {
748     gen_flush_cc_op(s);
749     gen_op_mov32(QREG_PC, dest);
750     s->is_jmp = DISAS_JUMP;
751 }
752
753 static void gen_exception(DisasContext *s, uint32_t where, int nr)
754 {
755     gen_flush_cc_op(s);
756     gen_jmp(s, gen_im32(where));
757     gen_op_raise_exception(nr);
758 }
759
760 static inline void gen_addr_fault(DisasContext *s)
761 {
762     gen_exception(s, s->insn_pc, EXCP_ADDRESS);
763 }
764
765 #define SRC_EA(result, opsize, val, addrp) do { \
766     result = gen_ea(s, insn, opsize, val, addrp); \
767     if (result == -1) { \
768         gen_addr_fault(s); \
769         return; \
770     } \
771     } while (0)
772
773 #define DEST_EA(insn, opsize, val, addrp) do { \
774     int ea_result = gen_ea(s, insn, opsize, val, addrp); \
775     if (ea_result == -1) { \
776         gen_addr_fault(s); \
777         return; \
778     } \
779     } while (0)
780
781 /* Generate a jump to an immediate address.  */
782 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
783 {
784     TranslationBlock *tb;
785
786     tb = s->tb;
787     if (__builtin_expect (s->singlestep_enabled, 0)) {
788         gen_exception(s, dest, EXCP_DEBUG);
789     } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
790                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
791         gen_op_goto_tb(0, n, (long)tb);
792         gen_op_mov32(QREG_PC, gen_im32(dest));
793         gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
794         gen_op_exit_tb();
795     } else {
796         gen_jmp(s, gen_im32(dest));
797         gen_op_mov32(QREG_T0, gen_im32(0));
798         gen_op_exit_tb();
799     }
800     s->is_jmp = DISAS_TB_JUMP;
801 }
802
803 DISAS_INSN(undef_mac)
804 {
805     gen_exception(s, s->pc - 2, EXCP_LINEA);
806 }
807
808 DISAS_INSN(undef_fpu)
809 {
810     gen_exception(s, s->pc - 2, EXCP_LINEF);
811 }
812
813 DISAS_INSN(undef)
814 {
815     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
816     cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
817               insn, s->pc - 2);
818 }
819
820 DISAS_INSN(mulw)
821 {
822     int reg;
823     int tmp;
824     int src;
825     int sign;
826
827     sign = (insn & 0x100) != 0;
828     reg = DREG(insn, 9);
829     tmp = gen_new_qreg(QMODE_I32);
830     if (sign)
831         gen_op_ext16s32(tmp, reg);
832     else
833         gen_op_ext16u32(tmp, reg);
834     SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
835     gen_op_mul32(tmp, tmp, src);
836     gen_op_mov32(reg, tmp);
837     /* Unlike m68k, coldfire always clears the overflow bit.  */
838     gen_logic_cc(s, tmp);
839 }
840
841 DISAS_INSN(divw)
842 {
843     int reg;
844     int tmp;
845     int src;
846     int sign;
847
848     sign = (insn & 0x100) != 0;
849     reg = DREG(insn, 9);
850     if (sign) {
851         gen_op_ext16s32(QREG_DIV1, reg);
852     } else {
853         gen_op_ext16u32(QREG_DIV1, reg);
854     }
855     SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
856     gen_op_mov32(QREG_DIV2, src);
857     if (sign) {
858         gen_op_divs(1);
859     } else {
860         gen_op_divu(1);
861     }
862
863     tmp = gen_new_qreg(QMODE_I32);
864     src = gen_new_qreg(QMODE_I32);
865     gen_op_ext16u32(tmp, QREG_DIV1);
866     gen_op_shl32(src, QREG_DIV2, gen_im32(16));
867     gen_op_or32(reg, tmp, src);
868     gen_op_flags_set();
869     s->cc_op = CC_OP_FLAGS;
870 }
871
872 DISAS_INSN(divl)
873 {
874     int num;
875     int den;
876     int reg;
877     uint16_t ext;
878
879     ext = lduw_code(s->pc);
880     s->pc += 2;
881     if (ext & 0x87f8) {
882         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
883         return;
884     }
885     num = DREG(ext, 12);
886     reg = DREG(ext, 0);
887     gen_op_mov32(QREG_DIV1, num);
888     SRC_EA(den, OS_LONG, 0, NULL);
889     gen_op_mov32(QREG_DIV2, den);
890     if (ext & 0x0800) {
891         gen_op_divs(2);
892     } else {
893         gen_op_divu(2);
894     }
895     if (num == reg) {
896         /* div */
897         gen_op_mov32 (reg, QREG_DIV1);
898     } else {
899         /* rem */
900         gen_op_mov32 (reg, QREG_DIV2);
901     }
902     gen_op_flags_set();
903     s->cc_op = CC_OP_FLAGS;
904 }
905
906 DISAS_INSN(addsub)
907 {
908     int reg;
909     int dest;
910     int src;
911     int tmp;
912     int addr;
913     int add;
914
915     add = (insn & 0x4000) != 0;
916     reg = DREG(insn, 9);
917     dest = gen_new_qreg(QMODE_I32);
918     if (insn & 0x100) {
919         SRC_EA(tmp, OS_LONG, 0, &addr);
920         src = reg;
921     } else {
922         tmp = reg;
923         SRC_EA(src, OS_LONG, 0, NULL);
924     }
925     if (add) {
926         gen_op_add32(dest, tmp, src);
927         gen_op_update_xflag_lt(dest, src);
928         s->cc_op = CC_OP_ADD;
929     } else {
930         gen_op_update_xflag_lt(tmp, src);
931         gen_op_sub32(dest, tmp, src);
932         s->cc_op = CC_OP_SUB;
933     }
934     gen_op_update_cc_add(dest, src);
935     if (insn & 0x100) {
936         DEST_EA(insn, OS_LONG, dest, &addr);
937     } else {
938         gen_op_mov32(reg, dest);
939     }
940 }
941
942
943 /* Reverse the order of the bits in REG.  */
944 DISAS_INSN(bitrev)
945 {
946     int val;
947     int tmp1;
948     int tmp2;
949     int reg;
950
951     val = gen_new_qreg(QMODE_I32);
952     tmp1 = gen_new_qreg(QMODE_I32);
953     tmp2 = gen_new_qreg(QMODE_I32);
954     reg = DREG(insn, 0);
955     gen_op_mov32(val, reg);
956     /* Reverse bits within each nibble.  */
957     gen_op_shl32(tmp1, val, gen_im32(3));
958     gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
959     gen_op_shl32(tmp2, val, gen_im32(1));
960     gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
961     gen_op_or32(tmp1, tmp1, tmp2);
962     gen_op_shr32(tmp2, val, gen_im32(1));
963     gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
964     gen_op_or32(tmp1, tmp1, tmp2);
965     gen_op_shr32(tmp2, val, gen_im32(3));
966     gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
967     gen_op_or32(tmp1, tmp1, tmp2);
968     /* Reverse nibbles withing bytes.  */
969     gen_op_shl32(val, tmp1, gen_im32(4));
970     gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
971     gen_op_shr32(tmp2, tmp1, gen_im32(4));
972     gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
973     gen_op_or32(val, val, tmp2);
974     /* Reverse bytes.  */
975     gen_op_bswap32(reg, val);
976     gen_op_mov32(reg, val);
977 }
978
979 DISAS_INSN(bitop_reg)
980 {
981     int opsize;
982     int op;
983     int src1;
984     int src2;
985     int tmp;
986     int addr;
987     int dest;
988
989     if ((insn & 0x38) != 0)
990         opsize = OS_BYTE;
991     else
992         opsize = OS_LONG;
993     op = (insn >> 6) & 3;
994     SRC_EA(src1, opsize, 0, op ? &addr: NULL);
995     src2 = DREG(insn, 9);
996     dest = gen_new_qreg(QMODE_I32);
997
998     gen_flush_flags(s);
999     tmp = gen_new_qreg(QMODE_I32);
1000     if (opsize == OS_BYTE)
1001         gen_op_and32(tmp, src2, gen_im32(7));
1002     else
1003         gen_op_and32(tmp, src2, gen_im32(31));
1004     src2 = tmp;
1005     tmp = gen_new_qreg(QMODE_I32);
1006     gen_op_shl32(tmp, gen_im32(1), src2);
1007
1008     gen_op_btest(src1, tmp);
1009     switch (op) {
1010     case 1: /* bchg */
1011         gen_op_xor32(dest, src1, tmp);
1012         break;
1013     case 2: /* bclr */
1014         gen_op_not32(tmp, tmp);
1015         gen_op_and32(dest, src1, tmp);
1016         break;
1017     case 3: /* bset */
1018         gen_op_or32(dest, src1, tmp);
1019         break;
1020     default: /* btst */
1021         break;
1022     }
1023     if (op)
1024         DEST_EA(insn, opsize, dest, &addr);
1025 }
1026
1027 DISAS_INSN(sats)
1028 {
1029     int reg;
1030     int tmp;
1031     int l1;
1032
1033     reg = DREG(insn, 0);
1034     tmp = gen_new_qreg(QMODE_I32);
1035     gen_flush_flags(s);
1036     gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
1037     l1 = gen_new_label();
1038     gen_op_jmp_z32(tmp, l1);
1039     tmp = gen_new_qreg(QMODE_I32);
1040     gen_op_shr32(tmp, reg, gen_im32(31));
1041     gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
1042     gen_op_mov32(reg, tmp);
1043     gen_set_label(l1);
1044     gen_logic_cc(s, tmp);
1045 }
1046
1047 static void gen_push(DisasContext *s, int val)
1048 {
1049     int tmp;
1050
1051     tmp = gen_new_qreg(QMODE_I32);
1052     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1053     gen_store(s, OS_LONG, tmp, val);
1054     gen_op_mov32(QREG_SP, tmp);
1055 }
1056
1057 DISAS_INSN(movem)
1058 {
1059     int addr;
1060     int i;
1061     uint16_t mask;
1062     int reg;
1063     int tmp;
1064     int is_load;
1065
1066     mask = lduw_code(s->pc);
1067     s->pc += 2;
1068     tmp = gen_lea(s, insn, OS_LONG);
1069     if (tmp == -1) {
1070         gen_addr_fault(s);
1071         return;
1072     }
1073     addr = gen_new_qreg(QMODE_I32);
1074     gen_op_mov32(addr, tmp);
1075     is_load = ((insn & 0x0400) != 0);
1076     for (i = 0; i < 16; i++, mask >>= 1) {
1077         if (mask & 1) {
1078             if (i < 8)
1079                 reg = DREG(i, 0);
1080             else
1081                 reg = AREG(i, 0);
1082             if (is_load) {
1083                 tmp = gen_load(s, OS_LONG, addr, 0);
1084                 gen_op_mov32(reg, tmp);
1085             } else {
1086                 gen_store(s, OS_LONG, addr, reg);
1087             }
1088             if (mask != 1)
1089                 gen_op_add32(addr, addr, gen_im32(4));
1090         }
1091     }
1092 }
1093
1094 DISAS_INSN(bitop_im)
1095 {
1096     int opsize;
1097     int op;
1098     int src1;
1099     uint32_t mask;
1100     int bitnum;
1101     int tmp;
1102     int addr;
1103     int dest;
1104
1105     if ((insn & 0x38) != 0)
1106         opsize = OS_BYTE;
1107     else
1108         opsize = OS_LONG;
1109     op = (insn >> 6) & 3;
1110
1111     bitnum = lduw_code(s->pc);
1112     s->pc += 2;
1113     if (bitnum & 0xff00) {
1114         disas_undef(s, insn);
1115         return;
1116     }
1117
1118     SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1119
1120     gen_flush_flags(s);
1121     tmp = gen_new_qreg(QMODE_I32);
1122     if (opsize == OS_BYTE)
1123         bitnum &= 7;
1124     else
1125         bitnum &= 31;
1126     mask = 1 << bitnum;
1127
1128     gen_op_btest(src1, gen_im32(mask));
1129     if (op)
1130         dest = gen_new_qreg(QMODE_I32);
1131     else
1132         dest = -1;
1133
1134     switch (op) {
1135     case 1: /* bchg */
1136         gen_op_xor32(dest, src1, gen_im32(mask));
1137         break;
1138     case 2: /* bclr */
1139         gen_op_and32(dest, src1, gen_im32(~mask));
1140         break;
1141     case 3: /* bset */
1142         gen_op_or32(dest, src1, gen_im32(mask));
1143         break;
1144     default: /* btst */
1145         break;
1146     }
1147     if (op)
1148         DEST_EA(insn, opsize, dest, &addr);
1149 }
1150
1151 DISAS_INSN(arith_im)
1152 {
1153     int op;
1154     int src1;
1155     int dest;
1156     int src2;
1157     int addr;
1158
1159     op = (insn >> 9) & 7;
1160     SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1161     src2 = gen_im32(read_im32(s));
1162     dest = gen_new_qreg(QMODE_I32);
1163     switch (op) {
1164     case 0: /* ori */
1165         gen_op_or32(dest, src1, src2);
1166         gen_logic_cc(s, dest);
1167         break;
1168     case 1: /* andi */
1169         gen_op_and32(dest, src1, src2);
1170         gen_logic_cc(s, dest);
1171         break;
1172     case 2: /* subi */
1173         gen_op_mov32(dest, src1);
1174         gen_op_update_xflag_lt(dest, src2);
1175         gen_op_sub32(dest, dest, src2);
1176         gen_op_update_cc_add(dest, src2);
1177         s->cc_op = CC_OP_SUB;
1178         break;
1179     case 3: /* addi */
1180         gen_op_mov32(dest, src1);
1181         gen_op_add32(dest, dest, src2);
1182         gen_op_update_cc_add(dest, src2);
1183         gen_op_update_xflag_lt(dest, src2);
1184         s->cc_op = CC_OP_ADD;
1185         break;
1186     case 5: /* eori */
1187         gen_op_xor32(dest, src1, src2);
1188         gen_logic_cc(s, dest);
1189         break;
1190     case 6: /* cmpi */
1191         gen_op_mov32(dest, src1);
1192         gen_op_sub32(dest, dest, src2);
1193         gen_op_update_cc_add(dest, src2);
1194         s->cc_op = CC_OP_SUB;
1195         break;
1196     default:
1197         abort();
1198     }
1199     if (op != 6) {
1200         DEST_EA(insn, OS_LONG, dest, &addr);
1201     }
1202 }
1203
1204 DISAS_INSN(byterev)
1205 {
1206     int reg;
1207
1208     reg = DREG(insn, 0);
1209     gen_op_bswap32(reg, reg);
1210 }
1211
1212 DISAS_INSN(move)
1213 {
1214     int src;
1215     int dest;
1216     int op;
1217     int opsize;
1218
1219     switch (insn >> 12) {
1220     case 1: /* move.b */
1221         opsize = OS_BYTE;
1222         break;
1223     case 2: /* move.l */
1224         opsize = OS_LONG;
1225         break;
1226     case 3: /* move.w */
1227         opsize = OS_WORD;
1228         break;
1229     default:
1230         abort();
1231     }
1232     SRC_EA(src, opsize, -1, NULL);
1233     op = (insn >> 6) & 7;
1234     if (op == 1) {
1235         /* movea */
1236         /* The value will already have been sign extended.  */
1237         dest = AREG(insn, 9);
1238         gen_op_mov32(dest, src);
1239     } else {
1240         /* normal move */
1241         uint16_t dest_ea;
1242         dest_ea = ((insn >> 9) & 7) | (op << 3);
1243         DEST_EA(dest_ea, opsize, src, NULL);
1244         /* This will be correct because loads sign extend.  */
1245         gen_logic_cc(s, src);
1246     }
1247 }
1248
1249 DISAS_INSN(negx)
1250 {
1251     int reg;
1252     int dest;
1253     int tmp;
1254
1255     gen_flush_flags(s);
1256     reg = DREG(insn, 0);
1257     dest = gen_new_qreg(QMODE_I32);
1258     gen_op_mov32 (dest, gen_im32(0));
1259     gen_op_subx_cc(dest, reg);
1260     /* !Z is sticky.  */
1261     tmp = gen_new_qreg(QMODE_I32);
1262     gen_op_mov32 (tmp, QREG_CC_DEST);
1263     gen_op_update_cc_add(dest, reg);
1264     gen_op_mov32(reg, dest);
1265     s->cc_op = CC_OP_DYNAMIC;
1266     gen_flush_flags(s);
1267     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1268     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1269     s->cc_op = CC_OP_FLAGS;
1270 }
1271
1272 DISAS_INSN(lea)
1273 {
1274     int reg;
1275     int tmp;
1276
1277     reg = AREG(insn, 9);
1278     tmp = gen_lea(s, insn, OS_LONG);
1279     if (tmp == -1) {
1280         gen_addr_fault(s);
1281         return;
1282     }
1283     gen_op_mov32(reg, tmp);
1284 }
1285
1286 DISAS_INSN(clr)
1287 {
1288     int opsize;
1289
1290     switch ((insn >> 6) & 3) {
1291     case 0: /* clr.b */
1292         opsize = OS_BYTE;
1293         break;
1294     case 1: /* clr.w */
1295         opsize = OS_WORD;
1296         break;
1297     case 2: /* clr.l */
1298         opsize = OS_LONG;
1299         break;
1300     default:
1301         abort();
1302     }
1303     DEST_EA(insn, opsize, gen_im32(0), NULL);
1304     gen_logic_cc(s, gen_im32(0));
1305 }
1306
1307 static int gen_get_ccr(DisasContext *s)
1308 {
1309     int dest;
1310
1311     gen_flush_flags(s);
1312     dest = gen_new_qreg(QMODE_I32);
1313     gen_op_get_xflag(dest);
1314     gen_op_shl32(dest, dest, gen_im32(4));
1315     gen_op_or32(dest, dest, QREG_CC_DEST);
1316     return dest;
1317 }
1318
1319 DISAS_INSN(move_from_ccr)
1320 {
1321     int reg;
1322     int ccr;
1323
1324     ccr = gen_get_ccr(s);
1325     reg = DREG(insn, 0);
1326     gen_partset_reg(OS_WORD, reg, ccr);
1327 }
1328
1329 DISAS_INSN(neg)
1330 {
1331     int reg;
1332     int src1;
1333
1334     reg = DREG(insn, 0);
1335     src1 = gen_new_qreg(QMODE_I32);
1336     gen_op_mov32(src1, reg);
1337     gen_op_neg32(reg, src1);
1338     s->cc_op = CC_OP_SUB;
1339     gen_op_update_cc_add(reg, src1);
1340     gen_op_update_xflag_lt(gen_im32(0), src1);
1341     s->cc_op = CC_OP_SUB;
1342 }
1343
1344 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1345 {
1346     gen_op_logic_cc(gen_im32(val & 0xf));
1347     gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1348     if (!ccr_only) {
1349         gen_op_set_sr(gen_im32(val & 0xff00));
1350     }
1351 }
1352
1353 static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1354 {
1355     int src1;
1356     int reg;
1357
1358     s->cc_op = CC_OP_FLAGS;
1359     if ((insn & 0x38) == 0)
1360       {
1361         src1 = gen_new_qreg(QMODE_I32);
1362         reg = DREG(insn, 0);
1363         gen_op_and32(src1, reg, gen_im32(0xf));
1364         gen_op_logic_cc(src1);
1365         gen_op_shr32(src1, reg, gen_im32(4));
1366         gen_op_and32(src1, src1, gen_im32(1));
1367         gen_op_update_xflag_tst(src1);
1368         if (!ccr_only) {
1369             gen_op_set_sr(reg);
1370         }
1371       }
1372     else if ((insn & 0x3f) == 0x3c)
1373       {
1374         uint16_t val;
1375         val = lduw_code(s->pc);
1376         s->pc += 2;
1377         gen_set_sr_im(s, val, ccr_only);
1378       }
1379     else
1380         disas_undef(s, insn);
1381 }
1382
1383 DISAS_INSN(move_to_ccr)
1384 {
1385     gen_set_sr(s, insn, 1);
1386 }
1387
1388 DISAS_INSN(not)
1389 {
1390     int reg;
1391
1392     reg = DREG(insn, 0);
1393     gen_op_not32(reg, reg);
1394     gen_logic_cc(s, reg);
1395 }
1396
1397 DISAS_INSN(swap)
1398 {
1399     int dest;
1400     int src1;
1401     int src2;
1402     int reg;
1403
1404     dest = gen_new_qreg(QMODE_I32);
1405     src1 = gen_new_qreg(QMODE_I32);
1406     src2 = gen_new_qreg(QMODE_I32);
1407     reg = DREG(insn, 0);
1408     gen_op_shl32(src1, reg, gen_im32(16));
1409     gen_op_shr32(src2, reg, gen_im32(16));
1410     gen_op_or32(dest, src1, src2);
1411     gen_op_mov32(reg, dest);
1412     gen_logic_cc(s, dest);
1413 }
1414
1415 DISAS_INSN(pea)
1416 {
1417     int tmp;
1418
1419     tmp = gen_lea(s, insn, OS_LONG);
1420     if (tmp == -1) {
1421         gen_addr_fault(s);
1422         return;
1423     }
1424     gen_push(s, tmp);
1425 }
1426
1427 DISAS_INSN(ext)
1428 {
1429     int reg;
1430     int op;
1431     int tmp;
1432
1433     reg = DREG(insn, 0);
1434     op = (insn >> 6) & 7;
1435     tmp = gen_new_qreg(QMODE_I32);
1436     if (op == 3)
1437         gen_op_ext16s32(tmp, reg);
1438     else
1439         gen_op_ext8s32(tmp, reg);
1440     if (op == 2)
1441         gen_partset_reg(OS_WORD, reg, tmp);
1442     else
1443       gen_op_mov32(reg, tmp);
1444     gen_logic_cc(s, tmp);
1445 }
1446
1447 DISAS_INSN(tst)
1448 {
1449     int opsize;
1450     int tmp;
1451
1452     switch ((insn >> 6) & 3) {
1453     case 0: /* tst.b */
1454         opsize = OS_BYTE;
1455         break;
1456     case 1: /* tst.w */
1457         opsize = OS_WORD;
1458         break;
1459     case 2: /* tst.l */
1460         opsize = OS_LONG;
1461         break;
1462     default:
1463         abort();
1464     }
1465     SRC_EA(tmp, opsize, -1, NULL);
1466     gen_logic_cc(s, tmp);
1467 }
1468
1469 DISAS_INSN(pulse)
1470 {
1471   /* Implemented as a NOP.  */
1472 }
1473
1474 DISAS_INSN(illegal)
1475 {
1476     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1477 }
1478
1479 /* ??? This should be atomic.  */
1480 DISAS_INSN(tas)
1481 {
1482     int dest;
1483     int src1;
1484     int addr;
1485
1486     dest = gen_new_qreg(QMODE_I32);
1487     SRC_EA(src1, OS_BYTE, -1, &addr);
1488     gen_logic_cc(s, src1);
1489     gen_op_or32(dest, src1, gen_im32(0x80));
1490     DEST_EA(insn, OS_BYTE, dest, &addr);
1491 }
1492
1493 DISAS_INSN(mull)
1494 {
1495     uint16_t ext;
1496     int reg;
1497     int src1;
1498     int dest;
1499
1500     /* The upper 32 bits of the product are discarded, so
1501        muls.l and mulu.l are functionally equivalent.  */
1502     ext = lduw_code(s->pc);
1503     s->pc += 2;
1504     if (ext & 0x87ff) {
1505         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1506         return;
1507     }
1508     reg = DREG(ext, 12);
1509     SRC_EA(src1, OS_LONG, 0, NULL);
1510     dest = gen_new_qreg(QMODE_I32);
1511     gen_op_mul32(dest, src1, reg);
1512     gen_op_mov32(reg, dest);
1513     /* Unlike m68k, coldfire always clears the overflow bit.  */
1514     gen_logic_cc(s, dest);
1515 }
1516
1517 DISAS_INSN(link)
1518 {
1519     int16_t offset;
1520     int reg;
1521     int tmp;
1522
1523     offset = ldsw_code(s->pc);
1524     s->pc += 2;
1525     reg = AREG(insn, 0);
1526     tmp = gen_new_qreg(QMODE_I32);
1527     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1528     gen_store(s, OS_LONG, tmp, reg);
1529     if (reg != QREG_SP)
1530         gen_op_mov32(reg, tmp);
1531     gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1532 }
1533
1534 DISAS_INSN(unlk)
1535 {
1536     int src;
1537     int reg;
1538     int tmp;
1539
1540     src = gen_new_qreg(QMODE_I32);
1541     reg = AREG(insn, 0);
1542     gen_op_mov32(src, reg);
1543     tmp = gen_load(s, OS_LONG, src, 0);
1544     gen_op_mov32(reg, tmp);
1545     gen_op_add32(QREG_SP, src, gen_im32(4));
1546 }
1547
1548 DISAS_INSN(nop)
1549 {
1550 }
1551
1552 DISAS_INSN(rts)
1553 {
1554     int tmp;
1555
1556     tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1557     gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1558     gen_jmp(s, tmp);
1559 }
1560
1561 DISAS_INSN(jump)
1562 {
1563     int tmp;
1564
1565     /* Load the target address first to ensure correct exception
1566        behavior.  */
1567     tmp = gen_lea(s, insn, OS_LONG);
1568     if (tmp == -1) {
1569         gen_addr_fault(s);
1570         return;
1571     }
1572     if ((insn & 0x40) == 0) {
1573         /* jsr */
1574         gen_push(s, gen_im32(s->pc));
1575     }
1576     gen_jmp(s, tmp);
1577 }
1578
1579 DISAS_INSN(addsubq)
1580 {
1581     int src1;
1582     int src2;
1583     int dest;
1584     int val;
1585     int addr;
1586
1587     SRC_EA(src1, OS_LONG, 0, &addr);
1588     val = (insn >> 9) & 7;
1589     if (val == 0)
1590         val = 8;
1591     src2 = gen_im32(val);
1592     dest = gen_new_qreg(QMODE_I32);
1593     gen_op_mov32(dest, src1);
1594     if ((insn & 0x38) == 0x08) {
1595         /* Don't update condition codes if the destination is an
1596            address register.  */
1597         if (insn & 0x0100) {
1598             gen_op_sub32(dest, dest, src2);
1599         } else {
1600             gen_op_add32(dest, dest, src2);
1601         }
1602     } else {
1603         if (insn & 0x0100) {
1604             gen_op_update_xflag_lt(dest, src2);
1605             gen_op_sub32(dest, dest, src2);
1606             s->cc_op = CC_OP_SUB;
1607         } else {
1608             gen_op_add32(dest, dest, src2);
1609             gen_op_update_xflag_lt(dest, src2);
1610             s->cc_op = CC_OP_ADD;
1611         }
1612         gen_op_update_cc_add(dest, src2);
1613     }
1614     DEST_EA(insn, OS_LONG, dest, &addr);
1615 }
1616
1617 DISAS_INSN(tpf)
1618 {
1619     switch (insn & 7) {
1620     case 2: /* One extension word.  */
1621         s->pc += 2;
1622         break;
1623     case 3: /* Two extension words.  */
1624         s->pc += 4;
1625         break;
1626     case 4: /* No extension words.  */
1627         break;
1628     default:
1629         disas_undef(s, insn);
1630     }
1631 }
1632
1633 DISAS_INSN(branch)
1634 {
1635     int32_t offset;
1636     uint32_t base;
1637     int op;
1638     int l1;
1639     
1640     base = s->pc;
1641     op = (insn >> 8) & 0xf;
1642     offset = (int8_t)insn;
1643     if (offset == 0) {
1644         offset = ldsw_code(s->pc);
1645         s->pc += 2;
1646     } else if (offset == -1) {
1647         offset = read_im32(s);
1648     }
1649     if (op == 1) {
1650         /* bsr */
1651         gen_push(s, gen_im32(s->pc));
1652     }
1653     gen_flush_cc_op(s);
1654     if (op > 1) {
1655         /* Bcc */
1656         l1 = gen_new_label();
1657         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1658         gen_jmp_tb(s, 1, base + offset);
1659         gen_set_label(l1);
1660         gen_jmp_tb(s, 0, s->pc);
1661     } else {
1662         /* Unconditional branch.  */
1663         gen_jmp_tb(s, 0, base + offset);
1664     }
1665 }
1666
1667 DISAS_INSN(moveq)
1668 {
1669     int tmp;
1670
1671     tmp = gen_im32((int8_t)insn);
1672     gen_op_mov32(DREG(insn, 9), tmp);
1673     gen_logic_cc(s, tmp);
1674 }
1675
1676 DISAS_INSN(mvzs)
1677 {
1678     int opsize;
1679     int src;
1680     int reg;
1681
1682     if (insn & 0x40)
1683         opsize = OS_WORD;
1684     else
1685         opsize = OS_BYTE;
1686     SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
1687     reg = DREG(insn, 9);
1688     gen_op_mov32(reg, src);
1689     gen_logic_cc(s, src);
1690 }
1691
1692 DISAS_INSN(or)
1693 {
1694     int reg;
1695     int dest;
1696     int src;
1697     int addr;
1698
1699     reg = DREG(insn, 9);
1700     dest = gen_new_qreg(QMODE_I32);
1701     if (insn & 0x100) {
1702         SRC_EA(src, OS_LONG, 0, &addr);
1703         gen_op_or32(dest, src, reg);
1704         DEST_EA(insn, OS_LONG, dest, &addr);
1705     } else {
1706         SRC_EA(src, OS_LONG, 0, NULL);
1707         gen_op_or32(dest, src, reg);
1708         gen_op_mov32(reg, dest);
1709     }
1710     gen_logic_cc(s, dest);
1711 }
1712
1713 DISAS_INSN(suba)
1714 {
1715     int src;
1716     int reg;
1717
1718     SRC_EA(src, OS_LONG, 0, NULL);
1719     reg = AREG(insn, 9);
1720     gen_op_sub32(reg, reg, src);
1721 }
1722
1723 DISAS_INSN(subx)
1724 {
1725     int reg;
1726     int src;
1727     int dest;
1728     int tmp;
1729
1730     gen_flush_flags(s);
1731     reg = DREG(insn, 9);
1732     src = DREG(insn, 0);
1733     dest = gen_new_qreg(QMODE_I32);
1734     gen_op_mov32 (dest, reg);
1735     gen_op_subx_cc(dest, src);
1736     /* !Z is sticky.  */
1737     tmp = gen_new_qreg(QMODE_I32);
1738     gen_op_mov32 (tmp, QREG_CC_DEST);
1739     gen_op_update_cc_add(dest, src);
1740     gen_op_mov32(reg, dest);
1741     s->cc_op = CC_OP_DYNAMIC;
1742     gen_flush_flags(s);
1743     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1744     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1745     s->cc_op = CC_OP_FLAGS;
1746 }
1747
1748 DISAS_INSN(mov3q)
1749 {
1750     int src;
1751     int val;
1752
1753     val = (insn >> 9) & 7;
1754     if (val == 0)
1755         val = -1;
1756     src = gen_im32(val);
1757     gen_logic_cc(s, src);
1758     DEST_EA(insn, OS_LONG, src, NULL);
1759 }
1760
1761 DISAS_INSN(cmp)
1762 {
1763     int op;
1764     int src;
1765     int reg;
1766     int dest;
1767     int opsize;
1768
1769     op = (insn >> 6) & 3;
1770     switch (op) {
1771     case 0: /* cmp.b */
1772         opsize = OS_BYTE;
1773         s->cc_op = CC_OP_CMPB;
1774         break;
1775     case 1: /* cmp.w */
1776         opsize = OS_WORD;
1777         s->cc_op = CC_OP_CMPW;
1778         break;
1779     case 2: /* cmp.l */
1780         opsize = OS_LONG;
1781         s->cc_op = CC_OP_SUB;
1782         break;
1783     default:
1784         abort();
1785     }
1786     SRC_EA(src, opsize, -1, NULL);
1787     reg = DREG(insn, 9);
1788     dest = gen_new_qreg(QMODE_I32);
1789     gen_op_sub32(dest, reg, src);
1790     gen_op_update_cc_add(dest, src);
1791 }
1792
1793 DISAS_INSN(cmpa)
1794 {
1795     int opsize;
1796     int src;
1797     int reg;
1798     int dest;
1799
1800     if (insn & 0x100) {
1801         opsize = OS_LONG;
1802     } else {
1803         opsize = OS_WORD;
1804     }
1805     SRC_EA(src, opsize, -1, NULL);
1806     reg = AREG(insn, 9);
1807     dest = gen_new_qreg(QMODE_I32);
1808     gen_op_sub32(dest, reg, src);
1809     gen_op_update_cc_add(dest, src);
1810     s->cc_op = CC_OP_SUB;
1811 }
1812
1813 DISAS_INSN(eor)
1814 {
1815     int src;
1816     int reg;
1817     int dest;
1818     int addr;
1819
1820     SRC_EA(src, OS_LONG, 0, &addr);
1821     reg = DREG(insn, 9);
1822     dest = gen_new_qreg(QMODE_I32);
1823     gen_op_xor32(dest, src, reg);
1824     gen_logic_cc(s, dest);
1825     DEST_EA(insn, OS_LONG, dest, &addr);
1826 }
1827
1828 DISAS_INSN(and)
1829 {
1830     int src;
1831     int reg;
1832     int dest;
1833     int addr;
1834
1835     reg = DREG(insn, 9);
1836     dest = gen_new_qreg(QMODE_I32);
1837     if (insn & 0x100) {
1838         SRC_EA(src, OS_LONG, 0, &addr);
1839         gen_op_and32(dest, src, reg);
1840         DEST_EA(insn, OS_LONG, dest, &addr);
1841     } else {
1842         SRC_EA(src, OS_LONG, 0, NULL);
1843         gen_op_and32(dest, src, reg);
1844         gen_op_mov32(reg, dest);
1845     }
1846     gen_logic_cc(s, dest);
1847 }
1848
1849 DISAS_INSN(adda)
1850 {
1851     int src;
1852     int reg;
1853
1854     SRC_EA(src, OS_LONG, 0, NULL);
1855     reg = AREG(insn, 9);
1856     gen_op_add32(reg, reg, src);
1857 }
1858
1859 DISAS_INSN(addx)
1860 {
1861     int reg;
1862     int src;
1863     int dest;
1864     int tmp;
1865
1866     gen_flush_flags(s);
1867     reg = DREG(insn, 9);
1868     src = DREG(insn, 0);
1869     dest = gen_new_qreg(QMODE_I32);
1870     gen_op_mov32 (dest, reg);
1871     gen_op_addx_cc(dest, src);
1872     /* !Z is sticky.  */
1873     tmp = gen_new_qreg(QMODE_I32);
1874     gen_op_mov32 (tmp, QREG_CC_DEST);
1875     gen_op_update_cc_add(dest, src);
1876     gen_op_mov32(reg, dest);
1877     s->cc_op = CC_OP_DYNAMIC;
1878     gen_flush_flags(s);
1879     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1880     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1881     s->cc_op = CC_OP_FLAGS;
1882 }
1883
1884 DISAS_INSN(shift_im)
1885 {
1886     int reg;
1887     int tmp;
1888
1889     reg = DREG(insn, 0);
1890     tmp = (insn >> 9) & 7;
1891     if (tmp == 0)
1892       tmp = 8;
1893     if (insn & 0x100) {
1894         gen_op_shl_im_cc(reg, tmp);
1895         s->cc_op = CC_OP_SHL;
1896     } else {
1897         if (insn & 8) {
1898             gen_op_shr_im_cc(reg, tmp);
1899             s->cc_op = CC_OP_SHR;
1900         } else {
1901             gen_op_sar_im_cc(reg, tmp);
1902             s->cc_op = CC_OP_SAR;
1903         }
1904     }
1905 }
1906
1907 DISAS_INSN(shift_reg)
1908 {
1909     int reg;
1910     int src;
1911     int tmp;
1912
1913     reg = DREG(insn, 0);
1914     src = DREG(insn, 9);
1915     tmp = gen_new_qreg(QMODE_I32);
1916     gen_op_and32(tmp, src, gen_im32(63));
1917     if (insn & 0x100) {
1918         gen_op_shl_cc(reg, tmp);
1919         s->cc_op = CC_OP_SHL;
1920     } else {
1921         if (insn & 8) {
1922             gen_op_shr_cc(reg, tmp);
1923             s->cc_op = CC_OP_SHR;
1924         } else {
1925             gen_op_sar_cc(reg, tmp);
1926             s->cc_op = CC_OP_SAR;
1927         }
1928     }
1929 }
1930
1931 DISAS_INSN(ff1)
1932 {
1933     int reg;
1934     reg = DREG(insn, 0);
1935     gen_logic_cc(s, reg);
1936     gen_op_ff1(reg, reg);
1937 }
1938
1939 static int gen_get_sr(DisasContext *s)
1940 {
1941     int ccr;
1942     int sr;
1943
1944     ccr = gen_get_ccr(s);
1945     sr = gen_new_qreg(QMODE_I32);
1946     gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
1947     gen_op_or32(sr, sr, ccr);
1948     return sr;
1949 }
1950
1951 DISAS_INSN(strldsr)
1952 {
1953     uint16_t ext;
1954     uint32_t addr;
1955
1956     addr = s->pc - 2;
1957     ext = lduw_code(s->pc);
1958     s->pc += 2;
1959     if (ext != 0x46FC) {
1960         gen_exception(s, addr, EXCP_UNSUPPORTED);
1961         return;
1962     }
1963     ext = lduw_code(s->pc);
1964     s->pc += 2;
1965     if (IS_USER(s) || (ext & SR_S) == 0) {
1966         gen_exception(s, addr, EXCP_PRIVILEGE);
1967         return;
1968     }
1969     gen_push(s, gen_get_sr(s));
1970     gen_set_sr_im(s, ext, 0);
1971 }
1972
1973 DISAS_INSN(move_from_sr)
1974 {
1975     int reg;
1976     int sr;
1977
1978     if (IS_USER(s)) {
1979         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1980         return;
1981     }
1982     sr = gen_get_sr(s);
1983     reg = DREG(insn, 0);
1984     gen_partset_reg(OS_WORD, reg, sr);
1985 }
1986
1987 DISAS_INSN(move_to_sr)
1988 {
1989     if (IS_USER(s)) {
1990         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1991         return;
1992     }
1993     gen_set_sr(s, insn, 0);
1994     gen_lookup_tb(s);
1995 }
1996
1997 DISAS_INSN(move_from_usp)
1998 {
1999     if (IS_USER(s)) {
2000         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2001         return;
2002     }
2003     /* TODO: Implement USP.  */
2004     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
2005 }
2006
2007 DISAS_INSN(move_to_usp)
2008 {
2009     if (IS_USER(s)) {
2010         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2011         return;
2012     }
2013     /* TODO: Implement USP.  */
2014     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
2015 }
2016
2017 DISAS_INSN(halt)
2018 {
2019     gen_jmp(s, gen_im32(s->pc));
2020     gen_op_halt();
2021 }
2022
2023 DISAS_INSN(stop)
2024 {
2025     uint16_t ext;
2026
2027     if (IS_USER(s)) {
2028         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2029         return;
2030     }
2031
2032     ext = lduw_code(s->pc);
2033     s->pc += 2;
2034
2035     gen_set_sr_im(s, ext, 0);
2036     gen_jmp(s, gen_im32(s->pc));
2037     gen_op_stop();
2038 }
2039
2040 DISAS_INSN(rte)
2041 {
2042     if (IS_USER(s)) {
2043         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2044         return;
2045     }
2046     gen_exception(s, s->pc - 2, EXCP_RTE);
2047 }
2048
2049 DISAS_INSN(movec)
2050 {
2051     uint16_t ext;
2052     int reg;
2053
2054     if (IS_USER(s)) {
2055         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2056         return;
2057     }
2058
2059     ext = lduw_code(s->pc);
2060     s->pc += 2;
2061
2062     if (ext & 0x8000) {
2063         reg = AREG(ext, 12);
2064     } else {
2065         reg = DREG(ext, 12);
2066     }
2067     gen_op_movec(gen_im32(ext & 0xfff), reg);
2068     gen_lookup_tb(s);
2069 }
2070
2071 DISAS_INSN(intouch)
2072 {
2073     if (IS_USER(s)) {
2074         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2075         return;
2076     }
2077     /* ICache fetch.  Implement as no-op.  */
2078 }
2079
2080 DISAS_INSN(cpushl)
2081 {
2082     if (IS_USER(s)) {
2083         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2084         return;
2085     }
2086     /* Cache push/invalidate.  Implement as no-op.  */
2087 }
2088
2089 DISAS_INSN(wddata)
2090 {
2091     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2092 }
2093
2094 DISAS_INSN(wdebug)
2095 {
2096     if (IS_USER(s)) {
2097         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2098         return;
2099     }
2100     /* TODO: Implement wdebug.  */
2101     qemu_assert(0, "WDEBUG not implemented");
2102 }
2103
2104 DISAS_INSN(trap)
2105 {
2106     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
2107 }
2108
2109 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
2110    immediately before the next FP instruction is executed.  */
2111 DISAS_INSN(fpu)
2112 {
2113     uint16_t ext;
2114     int opmode;
2115     int src;
2116     int dest;
2117     int res;
2118     int round;
2119     int opsize;
2120
2121     ext = lduw_code(s->pc);
2122     s->pc += 2;
2123     opmode = ext & 0x7f;
2124     switch ((ext >> 13) & 7) {
2125     case 0: case 2:
2126         break;
2127     case 1:
2128         goto undef;
2129     case 3: /* fmove out */
2130         src = FREG(ext, 7);
2131         /* fmove */
2132         /* ??? TODO: Proper behavior on overflow.  */
2133         switch ((ext >> 10) & 7) {
2134         case 0:
2135             opsize = OS_LONG;
2136             res = gen_new_qreg(QMODE_I32);
2137             gen_op_f64_to_i32(res, src);
2138             break;
2139         case 1:
2140             opsize = OS_SINGLE;
2141             res = gen_new_qreg(QMODE_F32);
2142             gen_op_f64_to_f32(res, src);
2143             break;
2144         case 4:
2145             opsize = OS_WORD;
2146             res = gen_new_qreg(QMODE_I32);
2147             gen_op_f64_to_i32(res, src);
2148             break;
2149         case 5:
2150             opsize = OS_DOUBLE;
2151             res = src;
2152             break;
2153         case 6:
2154             opsize = OS_BYTE;
2155             res = gen_new_qreg(QMODE_I32);
2156             gen_op_f64_to_i32(res, src);
2157             break;
2158         default:
2159             goto undef;
2160         }
2161         DEST_EA(insn, opsize, res, NULL);
2162         return;
2163     case 4: /* fmove to control register.  */
2164         switch ((ext >> 10) & 7) {
2165         case 4: /* FPCR */
2166             /* Not implemented.  Ignore writes.  */
2167             break;
2168         case 1: /* FPIAR */
2169         case 2: /* FPSR */
2170         default:
2171             cpu_abort(NULL, "Unimplemented: fmove to control %d",
2172                       (ext >> 10) & 7);
2173         }
2174         break;
2175     case 5: /* fmove from control register.  */
2176         switch ((ext >> 10) & 7) {
2177         case 4: /* FPCR */
2178             /* Not implemented.  Always return zero.  */
2179             res = gen_im32(0);
2180             break;
2181         case 1: /* FPIAR */
2182         case 2: /* FPSR */
2183         default:
2184             cpu_abort(NULL, "Unimplemented: fmove from control %d",
2185                       (ext >> 10) & 7);
2186             goto undef;
2187         }
2188         DEST_EA(insn, OS_LONG, res, NULL);
2189         break;
2190     case 6: /* fmovem */ 
2191     case 7:
2192         {
2193         int addr;
2194         uint16_t mask;
2195         if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2196             goto undef;
2197         src = gen_lea(s, insn, OS_LONG);
2198         if (src == -1) {
2199             gen_addr_fault(s);
2200             return;
2201         }
2202         addr = gen_new_qreg(QMODE_I32);
2203         gen_op_mov32(addr, src);
2204         mask = 0x80;
2205         dest = QREG_F0;
2206         while (mask) {
2207             if (ext & mask) {
2208                 if (ext & (1 << 13)) {
2209                     /* store */
2210                     gen_st(s, f64, addr, dest);
2211                 } else {
2212                     /* load */
2213                     gen_ld(s, f64, dest, addr);
2214                 }
2215                 if (ext & (mask - 1))
2216                     gen_op_add32(addr, addr, gen_im32(8));
2217             }
2218             mask >>= 1;
2219             dest++;
2220         }
2221         }
2222         return;
2223     }
2224     if (ext & (1 << 14)) {
2225         int tmp;
2226
2227         /* Source effective address.  */
2228         switch ((ext >> 10) & 7) {
2229         case 0: opsize = OS_LONG; break;
2230         case 1: opsize = OS_SINGLE; break;
2231         case 4: opsize = OS_WORD; break;
2232         case 5: opsize = OS_DOUBLE; break;
2233         case 6: opsize = OS_BYTE; break;
2234         default:
2235             goto undef;
2236         }
2237         SRC_EA(tmp, opsize, -1, NULL);
2238         if (opsize == OS_DOUBLE) {
2239             src = tmp;
2240         } else {
2241             src = gen_new_qreg(QMODE_F64);
2242             switch (opsize) {
2243             case OS_LONG:
2244             case OS_WORD:
2245             case OS_BYTE:
2246                 gen_op_i32_to_f64(src, tmp);
2247                 break;
2248             case OS_SINGLE:
2249                 gen_op_f32_to_f64(src, tmp);
2250                 break;
2251             }
2252         }
2253     } else {
2254         /* Source register.  */
2255         src = FREG(ext, 10);
2256     }
2257     dest = FREG(ext, 7);
2258     res = gen_new_qreg(QMODE_F64);
2259     if (opmode != 0x3a)
2260         gen_op_movf64(res, dest);
2261     round = 1;
2262     switch (opmode) {
2263     case 0: case 0x40: case 0x44: /* fmove */
2264         gen_op_movf64(res, src);
2265         break;
2266     case 1: /* fint */
2267         gen_op_iround_f64(res, src);
2268         round = 0;
2269         break;
2270     case 3: /* fintrz */
2271         gen_op_itrunc_f64(res, src);
2272         round = 0;
2273         break;
2274     case 4: case 0x41: case 0x45: /* fsqrt */
2275         gen_op_sqrtf64(res, src);
2276         break;
2277     case 0x18: case 0x58: case 0x5c: /* fabs */
2278         gen_op_absf64(res, src);
2279         break;
2280     case 0x1a: case 0x5a: case 0x5e: /* fneg */
2281         gen_op_chsf64(res, src);
2282         break;
2283     case 0x20: case 0x60: case 0x64: /* fdiv */
2284         gen_op_divf64(res, res, src);
2285         break;
2286     case 0x22: case 0x62: case 0x66: /* fadd */
2287         gen_op_addf64(res, res, src);
2288         break;
2289     case 0x23: case 0x63: case 0x67: /* fmul */
2290         gen_op_mulf64(res, res, src);
2291         break;
2292     case 0x28: case 0x68: case 0x6c: /* fsub */
2293         gen_op_subf64(res, res, src);
2294         break;
2295     case 0x38: /* fcmp */
2296         gen_op_sub_cmpf64(res, res, src);
2297         dest = 0;
2298         round = 0;
2299         break;
2300     case 0x3a: /* ftst */
2301         gen_op_movf64(res, src);
2302         dest = 0;
2303         round = 0;
2304         break;
2305     default:
2306         goto undef;
2307     }
2308     if (round) {
2309         if (opmode & 0x40) {
2310             if ((opmode & 0x4) != 0)
2311                 round = 0;
2312         } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2313             round = 0;
2314         }
2315     }
2316     if (round) {
2317         int tmp;
2318
2319         tmp = gen_new_qreg(QMODE_F32);
2320         gen_op_f64_to_f32(tmp, res);
2321         gen_op_f32_to_f64(res, tmp);
2322     } 
2323     gen_op_fp_result(res);
2324     if (dest) {
2325         gen_op_movf64(dest, res);
2326     }
2327     return;
2328 undef:
2329     s->pc -= 2;
2330     disas_undef_fpu(s, insn);
2331 }
2332
2333 DISAS_INSN(fbcc)
2334 {
2335     uint32_t offset;
2336     uint32_t addr;
2337     int flag;
2338     int zero;
2339     int l1;
2340
2341     addr = s->pc;
2342     offset = ldsw_code(s->pc);
2343     s->pc += 2;
2344     if (insn & (1 << 6)) {
2345         offset = (offset << 16) | lduw_code(s->pc);
2346         s->pc += 2;
2347     }
2348
2349     l1 = gen_new_label();
2350     /* TODO: Raise BSUN exception.  */
2351     flag = gen_new_qreg(QMODE_I32);
2352     zero = gen_new_qreg(QMODE_F64);
2353     gen_op_zerof64(zero);
2354     gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2355     /* Jump to l1 if condition is true.  */
2356     switch (insn & 0xf) {
2357     case 0: /* f */
2358         break;
2359     case 1: /* eq (=0) */
2360         gen_op_jmp_z32(flag, l1);
2361         break;
2362     case 2: /* ogt (=1) */
2363         gen_op_sub32(flag, flag, gen_im32(1));
2364         gen_op_jmp_z32(flag, l1);
2365         break;
2366     case 3: /* oge (=0 or =1) */
2367         gen_op_jmp_z32(flag, l1);
2368         gen_op_sub32(flag, flag, gen_im32(1));
2369         gen_op_jmp_z32(flag, l1);
2370         break;
2371     case 4: /* olt (=-1) */
2372         gen_op_jmp_s32(flag, l1);
2373         break;
2374     case 5: /* ole (=-1 or =0) */
2375         gen_op_jmp_s32(flag, l1);
2376         gen_op_jmp_z32(flag, l1);
2377         break;
2378     case 6: /* ogl (=-1 or =1) */
2379         gen_op_jmp_s32(flag, l1);
2380         gen_op_sub32(flag, flag, gen_im32(1));
2381         gen_op_jmp_z32(flag, l1);
2382         break;
2383     case 7: /* or (=2) */
2384         gen_op_sub32(flag, flag, gen_im32(2));
2385         gen_op_jmp_z32(flag, l1);
2386         break;
2387     case 8: /* un (<2) */
2388         gen_op_sub32(flag, flag, gen_im32(2));
2389         gen_op_jmp_s32(flag, l1);
2390         break;
2391     case 9: /* ueq (=0 or =2) */
2392         gen_op_jmp_z32(flag, l1);
2393         gen_op_sub32(flag, flag, gen_im32(2));
2394         gen_op_jmp_z32(flag, l1);
2395         break;
2396     case 10: /* ugt (>0) */
2397         /* ??? Add jmp_gtu.  */
2398         gen_op_sub32(flag, flag, gen_im32(1));
2399         gen_op_jmp_ns32(flag, l1);
2400         break;
2401     case 11: /* uge (>=0) */
2402         gen_op_jmp_ns32(flag, l1);
2403         break;
2404     case 12: /* ult (=-1 or =2) */
2405         gen_op_jmp_s32(flag, l1);
2406         gen_op_sub32(flag, flag, gen_im32(2));
2407         gen_op_jmp_z32(flag, l1);
2408         break;
2409     case 13: /* ule (!=1) */
2410         gen_op_sub32(flag, flag, gen_im32(1));
2411         gen_op_jmp_nz32(flag, l1);
2412         break;
2413     case 14: /* ne (!=0) */
2414         gen_op_jmp_nz32(flag, l1);
2415         break;
2416     case 15: /* t */
2417         gen_op_mov32(flag, gen_im32(1));
2418         break;
2419     }
2420     gen_jmp_tb(s, 0, s->pc);
2421     gen_set_label(l1);
2422     gen_jmp_tb(s, 1, addr + offset);
2423 }
2424
2425 DISAS_INSN(frestore)
2426 {
2427     /* TODO: Implement frestore.  */
2428     qemu_assert(0, "FRESTORE not implemented");
2429 }
2430
2431 DISAS_INSN(fsave)
2432 {
2433     /* TODO: Implement fsave.  */
2434     qemu_assert(0, "FSAVE not implemented");
2435 }
2436
2437 static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
2438 {
2439     int tmp = gen_new_qreg(QMODE_I32);
2440     if (s->env->macsr & MACSR_FI) {
2441         if (upper)
2442             gen_op_and32(tmp, val, gen_im32(0xffff0000));
2443         else
2444             gen_op_shl32(tmp, val, gen_im32(16));
2445     } else if (s->env->macsr & MACSR_SU) {
2446         if (upper)
2447             gen_op_sar32(tmp, val, gen_im32(16));
2448         else
2449             gen_op_ext16s32(tmp, val);
2450     } else {
2451         if (upper)
2452             gen_op_shr32(tmp, val, gen_im32(16));
2453         else
2454             gen_op_ext16u32(tmp, val);
2455     }
2456     return tmp;
2457 }
2458
2459 DISAS_INSN(mac)
2460 {
2461     int rx;
2462     int ry;
2463     uint16_t ext;
2464     int acc;
2465     int l1;
2466     int tmp;
2467     int addr;
2468     int loadval;
2469     int dual;
2470     int saved_flags = -1;
2471
2472     ext = lduw_code(s->pc);
2473     s->pc += 2;
2474
2475     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
2476     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
2477     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
2478         disas_undef(s, insn);
2479         return;
2480     }
2481     if (insn & 0x30) {
2482         /* MAC with load.  */
2483         tmp = gen_lea(s, insn, OS_LONG);
2484         addr = gen_new_qreg(QMODE_I32);
2485         gen_op_and32(addr, tmp, QREG_MAC_MASK);
2486         /* Load the value now to ensure correct exception behavior.
2487            Perform writeback after reading the MAC inputs.  */
2488         loadval = gen_load(s, OS_LONG, addr, 0);
2489
2490         acc ^= 1;
2491         rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2492         ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2493     } else {
2494         loadval = addr = -1;
2495         rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2496         ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2497     }
2498
2499     gen_op_mac_clear_flags();
2500     l1 = -1;
2501     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2502         /* Skip the multiply if we know we will ignore it.  */
2503         l1 = gen_new_label();
2504         tmp = gen_new_qreg(QMODE_I32);
2505         gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
2506         gen_op_jmp_nz32(tmp, l1);
2507     }
2508
2509     if ((ext & 0x0800) == 0) {
2510         /* Word.  */
2511         rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
2512         ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2513     }
2514     if (s->env->macsr & MACSR_FI) {
2515         gen_op_macmulf(rx, ry);
2516     } else {
2517         if (s->env->macsr & MACSR_SU)
2518             gen_op_macmuls(rx, ry);
2519         else
2520             gen_op_macmulu(rx, ry);
2521         switch ((ext >> 9) & 3) {
2522         case 1:
2523             gen_op_macshl();
2524             break;
2525         case 3:
2526             gen_op_macshr();
2527             break;
2528         }
2529     }
2530
2531     if (dual) {
2532         /* Save the overflow flag from the multiply.  */
2533         saved_flags = gen_new_qreg(QMODE_I32);
2534         gen_op_mov32(saved_flags, QREG_MACSR);
2535     }
2536
2537     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2538         /* Skip the accumulate if the value is already saturated.  */
2539         l1 = gen_new_label();
2540         tmp = gen_new_qreg(QMODE_I32);
2541         gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2542         gen_op_jmp_nz32(tmp, l1);
2543     }
2544
2545     if (insn & 0x100)
2546         gen_op_macsub(acc);
2547     else
2548         gen_op_macadd(acc);
2549
2550     if (s->env->macsr & MACSR_FI)
2551         gen_op_macsatf(acc);
2552     else if (s->env->macsr & MACSR_SU)
2553         gen_op_macsats(acc);
2554     else
2555         gen_op_macsatu(acc);
2556
2557     if (l1 != -1)
2558         gen_set_label(l1);
2559
2560     if (dual) {
2561         /* Dual accumulate variant.  */
2562         acc = (ext >> 2) & 3;
2563         /* Restore the overflow flag from the multiplier.  */
2564         gen_op_mov32(QREG_MACSR, saved_flags);
2565         if ((s->env->macsr & MACSR_OMC) != 0) {
2566             /* Skip the accumulate if the value is already saturated.  */
2567             l1 = gen_new_label();
2568             tmp = gen_new_qreg(QMODE_I32);
2569             gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2570             gen_op_jmp_nz32(tmp, l1);
2571         }
2572         if (ext & 2)
2573             gen_op_macsub(acc);
2574         else
2575             gen_op_macadd(acc);
2576         if (s->env->macsr & MACSR_FI)
2577             gen_op_macsatf(acc);
2578         else if (s->env->macsr & MACSR_SU)
2579             gen_op_macsats(acc);
2580         else
2581             gen_op_macsatu(acc);
2582         if (l1 != -1)
2583             gen_set_label(l1);
2584     }
2585     gen_op_mac_set_flags(acc);
2586
2587     if (insn & 0x30) {
2588         int rw;
2589         rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2590         gen_op_mov32(rw, loadval);
2591         /* FIXME: Should address writeback happen with the masked or
2592            unmasked value?  */
2593         switch ((insn >> 3) & 7) {
2594         case 3: /* Post-increment.  */
2595             gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
2596             break;
2597         case 4: /* Pre-decrement.  */
2598             gen_op_mov32(AREG(insn, 0), addr);
2599         }
2600     }
2601 }
2602
2603 DISAS_INSN(from_mac)
2604 {
2605     int rx;
2606     int acc;
2607
2608     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2609     acc = (insn >> 9) & 3;
2610     if (s->env->macsr & MACSR_FI) {
2611         gen_op_get_macf(rx, acc);
2612     } else if ((s->env->macsr & MACSR_OMC) == 0) {
2613         gen_op_get_maci(rx, acc);
2614     } else if (s->env->macsr & MACSR_SU) {
2615         gen_op_get_macs(rx, acc);
2616     } else {
2617         gen_op_get_macu(rx, acc);
2618     }
2619     if (insn & 0x40)
2620         gen_op_clear_mac(acc);
2621 }
2622
2623 DISAS_INSN(move_mac)
2624 {
2625     int src;
2626     int dest;
2627     src = insn & 3;
2628     dest = (insn >> 9) & 3;
2629     gen_op_move_mac(dest, src);
2630     gen_op_mac_clear_flags();
2631     gen_op_mac_set_flags(dest);
2632 }
2633
2634 DISAS_INSN(from_macsr)
2635 {
2636     int reg;
2637
2638     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2639     gen_op_mov32(reg, QREG_MACSR);
2640 }
2641
2642 DISAS_INSN(from_mask)
2643 {
2644     int reg;
2645     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2646     gen_op_mov32(reg, QREG_MAC_MASK);
2647 }
2648
2649 DISAS_INSN(from_mext)
2650 {
2651     int reg;
2652     int acc;
2653     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2654     acc = (insn & 0x400) ? 2 : 0;
2655     if (s->env->macsr & MACSR_FI)
2656         gen_op_get_mac_extf(reg, acc);
2657     else
2658         gen_op_get_mac_exti(reg, acc);
2659 }
2660
2661 DISAS_INSN(macsr_to_ccr)
2662 {
2663     gen_op_mov32(QREG_CC_X, gen_im32(0));
2664     gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
2665     s->cc_op = CC_OP_FLAGS;
2666 }
2667
2668 DISAS_INSN(to_mac)
2669 {
2670     int acc;
2671     int val;
2672     acc = (insn >>9) & 3;
2673     SRC_EA(val, OS_LONG, 0, NULL);
2674     if (s->env->macsr & MACSR_FI) {
2675         gen_op_set_macf(val, acc);
2676     } else if (s->env->macsr & MACSR_SU) {
2677         gen_op_set_macs(val, acc);
2678     } else {
2679         gen_op_set_macu(val, acc);
2680     }
2681     gen_op_mac_clear_flags();
2682     gen_op_mac_set_flags(acc);
2683 }
2684
2685 DISAS_INSN(to_macsr)
2686 {
2687     int val;
2688     SRC_EA(val, OS_LONG, 0, NULL);
2689     gen_op_set_macsr(val);
2690     gen_lookup_tb(s);
2691 }
2692
2693 DISAS_INSN(to_mask)
2694 {
2695     int val;
2696     SRC_EA(val, OS_LONG, 0, NULL);
2697     gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
2698 }
2699
2700 DISAS_INSN(to_mext)
2701 {
2702     int val;
2703     int acc;
2704     SRC_EA(val, OS_LONG, 0, NULL);
2705     acc = (insn & 0x400) ? 2 : 0;
2706     if (s->env->macsr & MACSR_FI)
2707         gen_op_set_mac_extf(val, acc);
2708     else if (s->env->macsr & MACSR_SU)
2709         gen_op_set_mac_exts(val, acc);
2710     else
2711         gen_op_set_mac_extu(val, acc);
2712 }
2713
2714 static disas_proc opcode_table[65536];
2715
2716 static void
2717 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2718 {
2719   int i;
2720   int from;
2721   int to;
2722
2723   /* Sanity check.  All set bits must be included in the mask.  */
2724   if (opcode & ~mask) {
2725       fprintf(stderr,
2726               "qemu internal error: bogus opcode definition %04x/%04x\n",
2727               opcode, mask);
2728       abort();
2729   }
2730   /* This could probably be cleverer.  For now just optimize the case where
2731      the top bits are known.  */
2732   /* Find the first zero bit in the mask.  */
2733   i = 0x8000;
2734   while ((i & mask) != 0)
2735       i >>= 1;
2736   /* Iterate over all combinations of this and lower bits.  */
2737   if (i == 0)
2738       i = 1;
2739   else
2740       i <<= 1;
2741   from = opcode & ~(i - 1);
2742   to = from + i;
2743   for (i = from; i < to; i++) {
2744       if ((i & mask) == opcode)
2745           opcode_table[i] = proc;
2746   }
2747 }
2748
2749 /* Register m68k opcode handlers.  Order is important.
2750    Later insn override earlier ones.  */
2751 void register_m68k_insns (CPUM68KState *env)
2752 {
2753 #define INSN(name, opcode, mask, feature) do { \
2754     if (m68k_feature(env, M68K_FEATURE_##feature)) \
2755         register_opcode(disas_##name, 0x##opcode, 0x##mask); \
2756     } while(0)
2757     INSN(undef,     0000, 0000, CF_ISA_A);
2758     INSN(arith_im,  0080, fff8, CF_ISA_A);
2759     INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
2760     INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2761     INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2762     INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2763     INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2764     INSN(arith_im,  0280, fff8, CF_ISA_A);
2765     INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
2766     INSN(arith_im,  0480, fff8, CF_ISA_A);
2767     INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
2768     INSN(arith_im,  0680, fff8, CF_ISA_A);
2769     INSN(bitop_im,  0800, ffc0, CF_ISA_A);
2770     INSN(bitop_im,  0840, ffc0, CF_ISA_A);
2771     INSN(bitop_im,  0880, ffc0, CF_ISA_A);
2772     INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
2773     INSN(arith_im,  0a80, fff8, CF_ISA_A);
2774     INSN(arith_im,  0c00, ff38, CF_ISA_A);
2775     INSN(move,      1000, f000, CF_ISA_A);
2776     INSN(move,      2000, f000, CF_ISA_A);
2777     INSN(move,      3000, f000, CF_ISA_A);
2778     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
2779     INSN(negx,      4080, fff8, CF_ISA_A);
2780     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2781     INSN(lea,       41c0, f1c0, CF_ISA_A);
2782     INSN(clr,       4200, ff00, CF_ISA_A);
2783     INSN(undef,     42c0, ffc0, CF_ISA_A);
2784     INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2785     INSN(neg,       4480, fff8, CF_ISA_A);
2786     INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2787     INSN(not,       4680, fff8, CF_ISA_A);
2788     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2789     INSN(pea,       4840, ffc0, CF_ISA_A);
2790     INSN(swap,      4840, fff8, CF_ISA_A);
2791     INSN(movem,     48c0, fbc0, CF_ISA_A);
2792     INSN(ext,       4880, fff8, CF_ISA_A);
2793     INSN(ext,       48c0, fff8, CF_ISA_A);
2794     INSN(ext,       49c0, fff8, CF_ISA_A);
2795     INSN(tst,       4a00, ff00, CF_ISA_A);
2796     INSN(tas,       4ac0, ffc0, CF_ISA_B);
2797     INSN(halt,      4ac8, ffff, CF_ISA_A);
2798     INSN(pulse,     4acc, ffff, CF_ISA_A);
2799     INSN(illegal,   4afc, ffff, CF_ISA_A);
2800     INSN(mull,      4c00, ffc0, CF_ISA_A);
2801     INSN(divl,      4c40, ffc0, CF_ISA_A);
2802     INSN(sats,      4c80, fff8, CF_ISA_B);
2803     INSN(trap,      4e40, fff0, CF_ISA_A);
2804     INSN(link,      4e50, fff8, CF_ISA_A);
2805     INSN(unlk,      4e58, fff8, CF_ISA_A);
2806     INSN(move_to_usp, 4e60, fff8, USP);
2807     INSN(move_from_usp, 4e68, fff8, USP);
2808     INSN(nop,       4e71, ffff, CF_ISA_A);
2809     INSN(stop,      4e72, ffff, CF_ISA_A);
2810     INSN(rte,       4e73, ffff, CF_ISA_A);
2811     INSN(rts,       4e75, ffff, CF_ISA_A);
2812     INSN(movec,     4e7b, ffff, CF_ISA_A);
2813     INSN(jump,      4e80, ffc0, CF_ISA_A);
2814     INSN(jump,      4ec0, ffc0, CF_ISA_A);
2815     INSN(addsubq,   5180, f1c0, CF_ISA_A);
2816     INSN(scc,       50c0, f0f8, CF_ISA_A);
2817     INSN(addsubq,   5080, f1c0, CF_ISA_A);
2818     INSN(tpf,       51f8, fff8, CF_ISA_A);
2819
2820     /* Branch instructions.  */
2821     INSN(branch,    6000, f000, CF_ISA_A);
2822     /* Disable long branch instructions, then add back the ones we want.  */
2823     INSN(undef,     60ff, f0ff, CF_ISA_A); /* All long branches.  */
2824     INSN(branch,    60ff, f0ff, CF_ISA_B);
2825     INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
2826     INSN(branch,    60ff, ffff, BRAL);
2827
2828     INSN(moveq,     7000, f100, CF_ISA_A);
2829     INSN(mvzs,      7100, f100, CF_ISA_B);
2830     INSN(or,        8000, f000, CF_ISA_A);
2831     INSN(divw,      80c0, f0c0, CF_ISA_A);
2832     INSN(addsub,    9000, f000, CF_ISA_A);
2833     INSN(subx,      9180, f1f8, CF_ISA_A);
2834     INSN(suba,      91c0, f1c0, CF_ISA_A);
2835
2836     INSN(undef_mac, a000, f000, CF_ISA_A);
2837     INSN(mac,       a000, f100, CF_EMAC);
2838     INSN(from_mac,  a180, f9b0, CF_EMAC);
2839     INSN(move_mac,  a110, f9fc, CF_EMAC);
2840     INSN(from_macsr,a980, f9f0, CF_EMAC);
2841     INSN(from_mask, ad80, fff0, CF_EMAC);
2842     INSN(from_mext, ab80, fbf0, CF_EMAC);
2843     INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
2844     INSN(to_mac,    a100, f9c0, CF_EMAC);
2845     INSN(to_macsr,  a900, ffc0, CF_EMAC);
2846     INSN(to_mext,   ab00, fbc0, CF_EMAC);
2847     INSN(to_mask,   ad00, ffc0, CF_EMAC);
2848
2849     INSN(mov3q,     a140, f1c0, CF_ISA_B);
2850     INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
2851     INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
2852     INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2853     INSN(cmp,       b080, f1c0, CF_ISA_A);
2854     INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
2855     INSN(eor,       b180, f1c0, CF_ISA_A);
2856     INSN(and,       c000, f000, CF_ISA_A);
2857     INSN(mulw,      c0c0, f0c0, CF_ISA_A);
2858     INSN(addsub,    d000, f000, CF_ISA_A);
2859     INSN(addx,      d180, f1f8, CF_ISA_A);
2860     INSN(adda,      d1c0, f1c0, CF_ISA_A);
2861     INSN(shift_im,  e080, f0f0, CF_ISA_A);
2862     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2863     INSN(undef_fpu, f000, f000, CF_ISA_A);
2864     INSN(fpu,       f200, ffc0, CF_FPU);
2865     INSN(fbcc,      f280, ffc0, CF_FPU);
2866     INSN(frestore,  f340, ffc0, CF_FPU);
2867     INSN(fsave,     f340, ffc0, CF_FPU);
2868     INSN(intouch,   f340, ffc0, CF_ISA_A);
2869     INSN(cpushl,    f428, ff38, CF_ISA_A);
2870     INSN(wddata,    fb00, ff00, CF_ISA_A);
2871     INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
2872 #undef INSN
2873 }
2874
2875 /* ??? Some of this implementation is not exception safe.  We should always
2876    write back the result to memory before setting the condition codes.  */
2877 static void disas_m68k_insn(CPUState * env, DisasContext *s)
2878 {
2879     uint16_t insn;
2880
2881     insn = lduw_code(s->pc);
2882     s->pc += 2;
2883
2884     opcode_table[insn](s, insn);
2885 }
2886
2887 #if 0
2888 /* Save the result of a floating point operation.  */
2889 static void expand_op_fp_result(qOP *qop)
2890 {
2891     gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2892 }
2893
2894 /* Dummy op to indicate that the flags have been set.  */
2895 static void expand_op_flags_set(qOP *qop)
2896 {
2897 }
2898
2899 /* Convert the confition codes into CC_OP_FLAGS format.  */
2900 static void expand_op_flush_flags(qOP *qop)
2901 {
2902     int cc_opreg;
2903
2904     if (qop->args[0] == CC_OP_DYNAMIC)
2905         cc_opreg = QREG_CC_OP;
2906     else
2907         cc_opreg = gen_im32(qop->args[0]);
2908     gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2909 }
2910
2911 /* Set CC_DEST after a logical or direct flag setting operation.  */
2912 static void expand_op_logic_cc(qOP *qop)
2913 {
2914     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2915 }
2916
2917 /* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2918 static void expand_op_update_cc_add(qOP *qop)
2919 {
2920     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2921     gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2922 }
2923
2924 /* Update the X flag.  */
2925 static void expand_op_update_xflag(qOP *qop)
2926 {
2927     int arg0;
2928     int arg1;
2929
2930     arg0 = qop->args[0];
2931     arg1 = qop->args[1];
2932     if (arg1 == QREG_NULL) {
2933         /* CC_X = arg0.  */
2934         gen_op_mov32(QREG_CC_X, arg0);
2935     } else {
2936         /* CC_X = arg0 < (unsigned)arg1.  */
2937         gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2938     }
2939 }
2940
2941 /* Set arg0 to the contents of the X flag.  */
2942 static void expand_op_get_xflag(qOP *qop)
2943 {
2944     gen_op_mov32(qop->args[0], QREG_CC_X);
2945 }
2946
2947 /* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2948    already know the shift is within range.  */
2949 static inline void expand_shift_im(qOP *qop, int right, int arith)
2950 {
2951     int val;
2952     int reg;
2953     int tmp;
2954     int im;
2955
2956     reg = qop->args[0];
2957     im = qop->args[1];
2958     tmp = gen_im32(im);
2959     val = gen_new_qreg(QMODE_I32);
2960     gen_op_mov32(val, reg);
2961     gen_op_mov32(QREG_CC_DEST, val);
2962     gen_op_mov32(QREG_CC_SRC, tmp);
2963     if (right) {
2964         if (arith) {
2965             gen_op_sar32(reg, val, tmp);
2966         } else {
2967             gen_op_shr32(reg, val, tmp);
2968         }
2969         if (im == 1)
2970             tmp = QREG_NULL;
2971         else
2972             tmp = gen_im32(im - 1);
2973     } else {
2974         gen_op_shl32(reg, val, tmp);
2975         tmp = gen_im32(32 - im);
2976     }
2977     if (tmp != QREG_NULL)
2978         gen_op_shr32(val, val, tmp);
2979     gen_op_and32(QREG_CC_X, val, gen_im32(1));
2980 }
2981
2982 static void expand_op_shl_im_cc(qOP *qop)
2983 {
2984     expand_shift_im(qop, 0, 0);
2985 }
2986
2987 static void expand_op_shr_im_cc(qOP *qop)
2988 {
2989     expand_shift_im(qop, 1, 0);
2990 }
2991
2992 static void expand_op_sar_im_cc(qOP *qop)
2993 {
2994     expand_shift_im(qop, 1, 1);
2995 }
2996
2997 /* Expand a shift by register.  */
2998 /* ??? This gives incorrect answers for shifts by 0 or >= 32 */
2999 static inline void expand_shift_reg(qOP *qop, int right, int arith)
3000 {
3001     int val;
3002     int reg;
3003     int shift;
3004     int tmp;
3005
3006     reg = qop->args[0];
3007     shift = qop->args[1];
3008     val = gen_new_qreg(QMODE_I32);
3009     gen_op_mov32(val, reg);
3010     gen_op_mov32(QREG_CC_DEST, val);
3011     gen_op_mov32(QREG_CC_SRC, shift);
3012     tmp = gen_new_qreg(QMODE_I32);
3013     if (right) {
3014         if (arith) {
3015             gen_op_sar32(reg, val, shift);
3016         } else {
3017             gen_op_shr32(reg, val, shift);
3018         }
3019         gen_op_sub32(tmp, shift, gen_im32(1));
3020     } else {
3021         gen_op_shl32(reg, val, shift);
3022         gen_op_sub32(tmp, gen_im32(31), shift);
3023     }
3024     gen_op_shl32(val, val, tmp);
3025     gen_op_and32(QREG_CC_X, val, gen_im32(1));
3026 }
3027
3028 static void expand_op_shl_cc(qOP *qop)
3029 {
3030     expand_shift_reg(qop, 0, 0);
3031 }
3032
3033 static void expand_op_shr_cc(qOP *qop)
3034 {
3035     expand_shift_reg(qop, 1, 0);
3036 }
3037
3038 static void expand_op_sar_cc(qOP *qop)
3039 {
3040     expand_shift_reg(qop, 1, 1);
3041 }
3042
3043 /* Set the Z flag to (arg0 & arg1) == 0.  */
3044 static void expand_op_btest(qOP *qop)
3045 {
3046     int tmp;
3047     int l1;
3048
3049     l1 = gen_new_label();
3050     tmp = gen_new_qreg(QMODE_I32);
3051     gen_op_and32(tmp, qop->args[0], qop->args[1]);
3052     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
3053     gen_op_jmp_nz32(tmp, l1);
3054     gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
3055     gen_op_label(l1);
3056 }
3057
3058 /* arg0 += arg1 + CC_X */
3059 static void expand_op_addx_cc(qOP *qop)
3060 {
3061     int arg0 = qop->args[0];
3062     int arg1 = qop->args[1];
3063     int l1, l2;
3064     
3065     gen_op_add32 (arg0, arg0, arg1);
3066     l1 = gen_new_label();
3067     l2 = gen_new_label();
3068     gen_op_jmp_z32(QREG_CC_X, l1);
3069     gen_op_add32(arg0, arg0, gen_im32(1));
3070     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
3071     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3072     gen_op_jmp(l2);
3073     gen_set_label(l1);
3074     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
3075     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3076     gen_set_label(l2);
3077 }
3078
3079 /* arg0 -= arg1 + CC_X */
3080 static void expand_op_subx_cc(qOP *qop)
3081 {
3082     int arg0 = qop->args[0];
3083     int arg1 = qop->args[1];
3084     int l1, l2;
3085
3086     l1 = gen_new_label();
3087     l2 = gen_new_label();
3088     gen_op_jmp_z32(QREG_CC_X, l1);
3089     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3090     gen_op_sub32(arg0, arg0, gen_im32(1));
3091     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
3092     gen_op_jmp(l2);
3093     gen_set_label(l1);
3094     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3095     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
3096     gen_set_label(l2);
3097     gen_op_sub32 (arg0, arg0, arg1);
3098 }
3099
3100 /* Expand target specific ops to generic qops.  */
3101 static void expand_target_qops(void)
3102 {
3103     qOP *qop;
3104     qOP *next;
3105     int c;
3106
3107     /* Copy the list of qops, expanding target specific ops as we go.  */
3108     qop = gen_first_qop;
3109     gen_first_qop = NULL;
3110     gen_last_qop = NULL;
3111     for (; qop; qop = next) {
3112         c = qop->opcode;
3113         next = qop->next;
3114         if (c < FIRST_TARGET_OP) {
3115             qop->prev = gen_last_qop;
3116             qop->next = NULL;
3117             if (gen_last_qop)
3118                 gen_last_qop->next = qop;
3119             else
3120                 gen_first_qop = qop;
3121             gen_last_qop = qop;
3122             continue;
3123         }
3124         switch (c) {
3125 #define DEF(name, nargs, barrier) \
3126         case INDEX_op_##name: \
3127             expand_op_##name(qop); \
3128             break;
3129 #include "qop-target.def"
3130 #undef DEF
3131         default:
3132             cpu_abort(NULL, "Unexpanded target qop");
3133         }
3134     }
3135 }
3136
3137 /* ??? Implement this.  */
3138 static void
3139 optimize_flags(void)
3140 {
3141 }
3142 #endif
3143
3144 /* generate intermediate code for basic block 'tb'.  */
3145 static inline int
3146 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3147                                int search_pc)
3148 {
3149     DisasContext dc1, *dc = &dc1;
3150     uint16_t *gen_opc_end;
3151     int j, lj;
3152     target_ulong pc_start;
3153     int pc_offset;
3154     int last_cc_op;
3155
3156     /* generate intermediate code */
3157     pc_start = tb->pc;
3158        
3159     dc->tb = tb;
3160
3161     gen_opc_ptr = gen_opc_buf;
3162     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3163     gen_opparam_ptr = gen_opparam_buf;
3164
3165     dc->env = env;
3166     dc->is_jmp = DISAS_NEXT;
3167     dc->pc = pc_start;
3168     dc->cc_op = CC_OP_DYNAMIC;
3169     dc->singlestep_enabled = env->singlestep_enabled;
3170     dc->fpcr = env->fpcr;
3171     dc->user = (env->sr & SR_S) == 0;
3172     nb_gen_labels = 0;
3173     lj = -1;
3174     do {
3175         free_qreg = 0;
3176         pc_offset = dc->pc - pc_start;
3177         gen_throws_exception = NULL;
3178         if (env->nb_breakpoints > 0) {
3179             for(j = 0; j < env->nb_breakpoints; j++) {
3180                 if (env->breakpoints[j] == dc->pc) {
3181                     gen_exception(dc, dc->pc, EXCP_DEBUG);
3182                     dc->is_jmp = DISAS_JUMP;
3183                     break;
3184                 }
3185             }
3186             if (dc->is_jmp)
3187                 break;
3188         }
3189         if (search_pc) {
3190             j = gen_opc_ptr - gen_opc_buf;
3191             if (lj < j) {
3192                 lj++;
3193                 while (lj < j)
3194                     gen_opc_instr_start[lj++] = 0;
3195             }
3196             gen_opc_pc[lj] = dc->pc;
3197             gen_opc_instr_start[lj] = 1;
3198         }
3199         last_cc_op = dc->cc_op;
3200         dc->insn_pc = dc->pc;
3201         disas_m68k_insn(env, dc);
3202     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3203              !env->singlestep_enabled &&
3204              (pc_offset) < (TARGET_PAGE_SIZE - 32));
3205
3206     if (__builtin_expect(env->singlestep_enabled, 0)) {
3207         /* Make sure the pc is updated, and raise a debug exception.  */
3208         if (!dc->is_jmp) {
3209             gen_flush_cc_op(dc);
3210             gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
3211         }
3212         gen_op_raise_exception(EXCP_DEBUG);
3213     } else {
3214         switch(dc->is_jmp) {
3215         case DISAS_NEXT:
3216             gen_flush_cc_op(dc);
3217             gen_jmp_tb(dc, 0, dc->pc);
3218             break;
3219         default:
3220         case DISAS_JUMP:
3221         case DISAS_UPDATE:
3222             gen_flush_cc_op(dc);
3223             /* indicate that the hash table must be used to find the next TB */
3224             gen_op_mov32(QREG_T0, gen_im32(0));
3225             gen_op_exit_tb();
3226             break;
3227         case DISAS_TB_JUMP:
3228             /* nothing more to generate */
3229             break;
3230         }
3231     }
3232     *gen_opc_ptr = INDEX_op_end;
3233
3234 #ifdef DEBUG_DISAS
3235     if (loglevel & CPU_LOG_TB_IN_ASM) {
3236         fprintf(logfile, "----------------\n");
3237         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3238         target_disas(logfile, pc_start, dc->pc - pc_start, 0);
3239         fprintf(logfile, "\n");
3240         if (loglevel & (CPU_LOG_TB_OP)) {
3241             fprintf(logfile, "OP:\n");
3242             dump_ops(gen_opc_buf, gen_opparam_buf);
3243             fprintf(logfile, "\n");
3244         }
3245     }
3246 #endif
3247     if (search_pc) {
3248         j = gen_opc_ptr - gen_opc_buf;
3249         lj++;
3250         while (lj <= j)
3251             gen_opc_instr_start[lj++] = 0;
3252         tb->size = 0;
3253     } else {
3254         tb->size = dc->pc - pc_start;
3255     }
3256
3257     //optimize_flags();
3258     //expand_target_qops();
3259     return 0;
3260 }
3261
3262 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
3263 {
3264     return gen_intermediate_code_internal(env, tb, 0);
3265 }
3266
3267 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
3268 {
3269     return gen_intermediate_code_internal(env, tb, 1);
3270 }
3271
3272 void cpu_reset(CPUM68KState *env)
3273 {
3274     memset(env, 0, offsetof(CPUM68KState, breakpoints));
3275 #if !defined (CONFIG_USER_ONLY)
3276     env->sr = 0x2700;
3277 #endif
3278     m68k_switch_sp(env);
3279     /* ??? FP regs should be initialized to NaN.  */
3280     env->cc_op = CC_OP_FLAGS;
3281     /* TODO: We should set PC from the interrupt vector.  */
3282     env->pc = 0;
3283     tlb_flush(env, 1);
3284 }
3285
3286 CPUM68KState *cpu_m68k_init(void)
3287 {
3288     CPUM68KState *env;
3289
3290     env = malloc(sizeof(CPUM68KState));
3291     if (!env)
3292         return NULL;
3293     cpu_exec_init(env);
3294
3295     cpu_reset(env);
3296     return env;
3297 }
3298
3299 void cpu_m68k_close(CPUM68KState *env)
3300 {
3301     free(env);
3302 }
3303
3304 void cpu_dump_state(CPUState *env, FILE *f, 
3305                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3306                     int flags)
3307 {
3308     int i;
3309     uint16_t sr;
3310     CPU_DoubleU u;
3311     for (i = 0; i < 8; i++)
3312       {
3313         u.d = env->fregs[i];
3314         cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
3315                      i, env->dregs[i], i, env->aregs[i],
3316                      i, u.l.upper, u.l.lower, u.d);
3317       }
3318     cpu_fprintf (f, "PC = %08x   ", env->pc);
3319     sr = env->sr;
3320     cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
3321                  (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
3322                  (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
3323     cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
3324 }
3325