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