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