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