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