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