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