]> Git Repo - qemu.git/blob - target-m68k/translate.c
cpu: Move watchpoint fields from CPU_COMMON to CPUState
[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     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
885     cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2);
886 }
887
888 DISAS_INSN(mulw)
889 {
890     TCGv reg;
891     TCGv tmp;
892     TCGv src;
893     int sign;
894
895     sign = (insn & 0x100) != 0;
896     reg = DREG(insn, 9);
897     tmp = tcg_temp_new();
898     if (sign)
899         tcg_gen_ext16s_i32(tmp, reg);
900     else
901         tcg_gen_ext16u_i32(tmp, reg);
902     SRC_EA(env, src, OS_WORD, sign, NULL);
903     tcg_gen_mul_i32(tmp, tmp, src);
904     tcg_gen_mov_i32(reg, tmp);
905     /* Unlike m68k, coldfire always clears the overflow bit.  */
906     gen_logic_cc(s, tmp);
907 }
908
909 DISAS_INSN(divw)
910 {
911     TCGv reg;
912     TCGv tmp;
913     TCGv src;
914     int sign;
915
916     sign = (insn & 0x100) != 0;
917     reg = DREG(insn, 9);
918     if (sign) {
919         tcg_gen_ext16s_i32(QREG_DIV1, reg);
920     } else {
921         tcg_gen_ext16u_i32(QREG_DIV1, reg);
922     }
923     SRC_EA(env, src, OS_WORD, sign, NULL);
924     tcg_gen_mov_i32(QREG_DIV2, src);
925     if (sign) {
926         gen_helper_divs(cpu_env, tcg_const_i32(1));
927     } else {
928         gen_helper_divu(cpu_env, tcg_const_i32(1));
929     }
930
931     tmp = tcg_temp_new();
932     src = tcg_temp_new();
933     tcg_gen_ext16u_i32(tmp, QREG_DIV1);
934     tcg_gen_shli_i32(src, QREG_DIV2, 16);
935     tcg_gen_or_i32(reg, tmp, src);
936     s->cc_op = CC_OP_FLAGS;
937 }
938
939 DISAS_INSN(divl)
940 {
941     TCGv num;
942     TCGv den;
943     TCGv reg;
944     uint16_t ext;
945
946     ext = cpu_lduw_code(env, s->pc);
947     s->pc += 2;
948     if (ext & 0x87f8) {
949         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
950         return;
951     }
952     num = DREG(ext, 12);
953     reg = DREG(ext, 0);
954     tcg_gen_mov_i32(QREG_DIV1, num);
955     SRC_EA(env, den, OS_LONG, 0, NULL);
956     tcg_gen_mov_i32(QREG_DIV2, den);
957     if (ext & 0x0800) {
958         gen_helper_divs(cpu_env, tcg_const_i32(0));
959     } else {
960         gen_helper_divu(cpu_env, tcg_const_i32(0));
961     }
962     if ((ext & 7) == ((ext >> 12) & 7)) {
963         /* div */
964         tcg_gen_mov_i32 (reg, QREG_DIV1);
965     } else {
966         /* rem */
967         tcg_gen_mov_i32 (reg, QREG_DIV2);
968     }
969     s->cc_op = CC_OP_FLAGS;
970 }
971
972 DISAS_INSN(addsub)
973 {
974     TCGv reg;
975     TCGv dest;
976     TCGv src;
977     TCGv tmp;
978     TCGv addr;
979     int add;
980
981     add = (insn & 0x4000) != 0;
982     reg = DREG(insn, 9);
983     dest = tcg_temp_new();
984     if (insn & 0x100) {
985         SRC_EA(env, tmp, OS_LONG, 0, &addr);
986         src = reg;
987     } else {
988         tmp = reg;
989         SRC_EA(env, src, OS_LONG, 0, NULL);
990     }
991     if (add) {
992         tcg_gen_add_i32(dest, tmp, src);
993         gen_helper_xflag_lt(QREG_CC_X, dest, src);
994         s->cc_op = CC_OP_ADD;
995     } else {
996         gen_helper_xflag_lt(QREG_CC_X, tmp, src);
997         tcg_gen_sub_i32(dest, tmp, src);
998         s->cc_op = CC_OP_SUB;
999     }
1000     gen_update_cc_add(dest, src);
1001     if (insn & 0x100) {
1002         DEST_EA(env, insn, OS_LONG, dest, &addr);
1003     } else {
1004         tcg_gen_mov_i32(reg, dest);
1005     }
1006 }
1007
1008
1009 /* Reverse the order of the bits in REG.  */
1010 DISAS_INSN(bitrev)
1011 {
1012     TCGv reg;
1013     reg = DREG(insn, 0);
1014     gen_helper_bitrev(reg, reg);
1015 }
1016
1017 DISAS_INSN(bitop_reg)
1018 {
1019     int opsize;
1020     int op;
1021     TCGv src1;
1022     TCGv src2;
1023     TCGv tmp;
1024     TCGv addr;
1025     TCGv dest;
1026
1027     if ((insn & 0x38) != 0)
1028         opsize = OS_BYTE;
1029     else
1030         opsize = OS_LONG;
1031     op = (insn >> 6) & 3;
1032     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
1033     src2 = DREG(insn, 9);
1034     dest = tcg_temp_new();
1035
1036     gen_flush_flags(s);
1037     tmp = tcg_temp_new();
1038     if (opsize == OS_BYTE)
1039         tcg_gen_andi_i32(tmp, src2, 7);
1040     else
1041         tcg_gen_andi_i32(tmp, src2, 31);
1042     src2 = tmp;
1043     tmp = tcg_temp_new();
1044     tcg_gen_shr_i32(tmp, src1, src2);
1045     tcg_gen_andi_i32(tmp, tmp, 1);
1046     tcg_gen_shli_i32(tmp, tmp, 2);
1047     /* Clear CCF_Z if bit set.  */
1048     tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1049     tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1050
1051     tcg_gen_shl_i32(tmp, tcg_const_i32(1), src2);
1052     switch (op) {
1053     case 1: /* bchg */
1054         tcg_gen_xor_i32(dest, src1, tmp);
1055         break;
1056     case 2: /* bclr */
1057         tcg_gen_not_i32(tmp, tmp);
1058         tcg_gen_and_i32(dest, src1, tmp);
1059         break;
1060     case 3: /* bset */
1061         tcg_gen_or_i32(dest, src1, tmp);
1062         break;
1063     default: /* btst */
1064         break;
1065     }
1066     if (op)
1067         DEST_EA(env, insn, opsize, dest, &addr);
1068 }
1069
1070 DISAS_INSN(sats)
1071 {
1072     TCGv reg;
1073     reg = DREG(insn, 0);
1074     gen_flush_flags(s);
1075     gen_helper_sats(reg, reg, QREG_CC_DEST);
1076     gen_logic_cc(s, reg);
1077 }
1078
1079 static void gen_push(DisasContext *s, TCGv val)
1080 {
1081     TCGv tmp;
1082
1083     tmp = tcg_temp_new();
1084     tcg_gen_subi_i32(tmp, QREG_SP, 4);
1085     gen_store(s, OS_LONG, tmp, val);
1086     tcg_gen_mov_i32(QREG_SP, tmp);
1087 }
1088
1089 DISAS_INSN(movem)
1090 {
1091     TCGv addr;
1092     int i;
1093     uint16_t mask;
1094     TCGv reg;
1095     TCGv tmp;
1096     int is_load;
1097
1098     mask = cpu_lduw_code(env, s->pc);
1099     s->pc += 2;
1100     tmp = gen_lea(env, s, insn, OS_LONG);
1101     if (IS_NULL_QREG(tmp)) {
1102         gen_addr_fault(s);
1103         return;
1104     }
1105     addr = tcg_temp_new();
1106     tcg_gen_mov_i32(addr, tmp);
1107     is_load = ((insn & 0x0400) != 0);
1108     for (i = 0; i < 16; i++, mask >>= 1) {
1109         if (mask & 1) {
1110             if (i < 8)
1111                 reg = DREG(i, 0);
1112             else
1113                 reg = AREG(i, 0);
1114             if (is_load) {
1115                 tmp = gen_load(s, OS_LONG, addr, 0);
1116                 tcg_gen_mov_i32(reg, tmp);
1117             } else {
1118                 gen_store(s, OS_LONG, addr, reg);
1119             }
1120             if (mask != 1)
1121                 tcg_gen_addi_i32(addr, addr, 4);
1122         }
1123     }
1124 }
1125
1126 DISAS_INSN(bitop_im)
1127 {
1128     int opsize;
1129     int op;
1130     TCGv src1;
1131     uint32_t mask;
1132     int bitnum;
1133     TCGv tmp;
1134     TCGv addr;
1135
1136     if ((insn & 0x38) != 0)
1137         opsize = OS_BYTE;
1138     else
1139         opsize = OS_LONG;
1140     op = (insn >> 6) & 3;
1141
1142     bitnum = cpu_lduw_code(env, s->pc);
1143     s->pc += 2;
1144     if (bitnum & 0xff00) {
1145         disas_undef(env, s, insn);
1146         return;
1147     }
1148
1149     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
1150
1151     gen_flush_flags(s);
1152     if (opsize == OS_BYTE)
1153         bitnum &= 7;
1154     else
1155         bitnum &= 31;
1156     mask = 1 << bitnum;
1157
1158     tmp = tcg_temp_new();
1159     assert (CCF_Z == (1 << 2));
1160     if (bitnum > 2)
1161         tcg_gen_shri_i32(tmp, src1, bitnum - 2);
1162     else if (bitnum < 2)
1163         tcg_gen_shli_i32(tmp, src1, 2 - bitnum);
1164     else
1165         tcg_gen_mov_i32(tmp, src1);
1166     tcg_gen_andi_i32(tmp, tmp, CCF_Z);
1167     /* Clear CCF_Z if bit set.  */
1168     tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1169     tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1170     if (op) {
1171         switch (op) {
1172         case 1: /* bchg */
1173             tcg_gen_xori_i32(tmp, src1, mask);
1174             break;
1175         case 2: /* bclr */
1176             tcg_gen_andi_i32(tmp, src1, ~mask);
1177             break;
1178         case 3: /* bset */
1179             tcg_gen_ori_i32(tmp, src1, mask);
1180             break;
1181         default: /* btst */
1182             break;
1183         }
1184         DEST_EA(env, insn, opsize, tmp, &addr);
1185     }
1186 }
1187
1188 DISAS_INSN(arith_im)
1189 {
1190     int op;
1191     uint32_t im;
1192     TCGv src1;
1193     TCGv dest;
1194     TCGv addr;
1195
1196     op = (insn >> 9) & 7;
1197     SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1198     im = read_im32(env, s);
1199     dest = tcg_temp_new();
1200     switch (op) {
1201     case 0: /* ori */
1202         tcg_gen_ori_i32(dest, src1, im);
1203         gen_logic_cc(s, dest);
1204         break;
1205     case 1: /* andi */
1206         tcg_gen_andi_i32(dest, src1, im);
1207         gen_logic_cc(s, dest);
1208         break;
1209     case 2: /* subi */
1210         tcg_gen_mov_i32(dest, src1);
1211         gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
1212         tcg_gen_subi_i32(dest, dest, im);
1213         gen_update_cc_add(dest, tcg_const_i32(im));
1214         s->cc_op = CC_OP_SUB;
1215         break;
1216     case 3: /* addi */
1217         tcg_gen_mov_i32(dest, src1);
1218         tcg_gen_addi_i32(dest, dest, im);
1219         gen_update_cc_add(dest, tcg_const_i32(im));
1220         gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
1221         s->cc_op = CC_OP_ADD;
1222         break;
1223     case 5: /* eori */
1224         tcg_gen_xori_i32(dest, src1, im);
1225         gen_logic_cc(s, dest);
1226         break;
1227     case 6: /* cmpi */
1228         tcg_gen_mov_i32(dest, src1);
1229         tcg_gen_subi_i32(dest, dest, im);
1230         gen_update_cc_add(dest, tcg_const_i32(im));
1231         s->cc_op = CC_OP_SUB;
1232         break;
1233     default:
1234         abort();
1235     }
1236     if (op != 6) {
1237         DEST_EA(env, insn, OS_LONG, dest, &addr);
1238     }
1239 }
1240
1241 DISAS_INSN(byterev)
1242 {
1243     TCGv reg;
1244
1245     reg = DREG(insn, 0);
1246     tcg_gen_bswap32_i32(reg, reg);
1247 }
1248
1249 DISAS_INSN(move)
1250 {
1251     TCGv src;
1252     TCGv dest;
1253     int op;
1254     int opsize;
1255
1256     switch (insn >> 12) {
1257     case 1: /* move.b */
1258         opsize = OS_BYTE;
1259         break;
1260     case 2: /* move.l */
1261         opsize = OS_LONG;
1262         break;
1263     case 3: /* move.w */
1264         opsize = OS_WORD;
1265         break;
1266     default:
1267         abort();
1268     }
1269     SRC_EA(env, src, opsize, 1, NULL);
1270     op = (insn >> 6) & 7;
1271     if (op == 1) {
1272         /* movea */
1273         /* The value will already have been sign extended.  */
1274         dest = AREG(insn, 9);
1275         tcg_gen_mov_i32(dest, src);
1276     } else {
1277         /* normal move */
1278         uint16_t dest_ea;
1279         dest_ea = ((insn >> 9) & 7) | (op << 3);
1280         DEST_EA(env, dest_ea, opsize, src, NULL);
1281         /* This will be correct because loads sign extend.  */
1282         gen_logic_cc(s, src);
1283     }
1284 }
1285
1286 DISAS_INSN(negx)
1287 {
1288     TCGv reg;
1289
1290     gen_flush_flags(s);
1291     reg = DREG(insn, 0);
1292     gen_helper_subx_cc(reg, cpu_env, tcg_const_i32(0), reg);
1293 }
1294
1295 DISAS_INSN(lea)
1296 {
1297     TCGv reg;
1298     TCGv tmp;
1299
1300     reg = AREG(insn, 9);
1301     tmp = gen_lea(env, s, insn, OS_LONG);
1302     if (IS_NULL_QREG(tmp)) {
1303         gen_addr_fault(s);
1304         return;
1305     }
1306     tcg_gen_mov_i32(reg, tmp);
1307 }
1308
1309 DISAS_INSN(clr)
1310 {
1311     int opsize;
1312
1313     switch ((insn >> 6) & 3) {
1314     case 0: /* clr.b */
1315         opsize = OS_BYTE;
1316         break;
1317     case 1: /* clr.w */
1318         opsize = OS_WORD;
1319         break;
1320     case 2: /* clr.l */
1321         opsize = OS_LONG;
1322         break;
1323     default:
1324         abort();
1325     }
1326     DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL);
1327     gen_logic_cc(s, tcg_const_i32(0));
1328 }
1329
1330 static TCGv gen_get_ccr(DisasContext *s)
1331 {
1332     TCGv dest;
1333
1334     gen_flush_flags(s);
1335     dest = tcg_temp_new();
1336     tcg_gen_shli_i32(dest, QREG_CC_X, 4);
1337     tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
1338     return dest;
1339 }
1340
1341 DISAS_INSN(move_from_ccr)
1342 {
1343     TCGv reg;
1344     TCGv ccr;
1345
1346     ccr = gen_get_ccr(s);
1347     reg = DREG(insn, 0);
1348     gen_partset_reg(OS_WORD, reg, ccr);
1349 }
1350
1351 DISAS_INSN(neg)
1352 {
1353     TCGv reg;
1354     TCGv src1;
1355
1356     reg = DREG(insn, 0);
1357     src1 = tcg_temp_new();
1358     tcg_gen_mov_i32(src1, reg);
1359     tcg_gen_neg_i32(reg, src1);
1360     s->cc_op = CC_OP_SUB;
1361     gen_update_cc_add(reg, src1);
1362     gen_helper_xflag_lt(QREG_CC_X, tcg_const_i32(0), src1);
1363     s->cc_op = CC_OP_SUB;
1364 }
1365
1366 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1367 {
1368     tcg_gen_movi_i32(QREG_CC_DEST, val & 0xf);
1369     tcg_gen_movi_i32(QREG_CC_X, (val & 0x10) >> 4);
1370     if (!ccr_only) {
1371         gen_helper_set_sr(cpu_env, tcg_const_i32(val & 0xff00));
1372     }
1373 }
1374
1375 static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
1376                        int ccr_only)
1377 {
1378     TCGv tmp;
1379     TCGv reg;
1380
1381     s->cc_op = CC_OP_FLAGS;
1382     if ((insn & 0x38) == 0)
1383       {
1384         tmp = tcg_temp_new();
1385         reg = DREG(insn, 0);
1386         tcg_gen_andi_i32(QREG_CC_DEST, reg, 0xf);
1387         tcg_gen_shri_i32(tmp, reg, 4);
1388         tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
1389         if (!ccr_only) {
1390             gen_helper_set_sr(cpu_env, reg);
1391         }
1392       }
1393     else if ((insn & 0x3f) == 0x3c)
1394       {
1395         uint16_t val;
1396         val = cpu_lduw_code(env, s->pc);
1397         s->pc += 2;
1398         gen_set_sr_im(s, val, ccr_only);
1399       }
1400     else
1401         disas_undef(env, s, insn);
1402 }
1403
1404 DISAS_INSN(move_to_ccr)
1405 {
1406     gen_set_sr(env, s, insn, 1);
1407 }
1408
1409 DISAS_INSN(not)
1410 {
1411     TCGv reg;
1412
1413     reg = DREG(insn, 0);
1414     tcg_gen_not_i32(reg, reg);
1415     gen_logic_cc(s, reg);
1416 }
1417
1418 DISAS_INSN(swap)
1419 {
1420     TCGv src1;
1421     TCGv src2;
1422     TCGv reg;
1423
1424     src1 = tcg_temp_new();
1425     src2 = tcg_temp_new();
1426     reg = DREG(insn, 0);
1427     tcg_gen_shli_i32(src1, reg, 16);
1428     tcg_gen_shri_i32(src2, reg, 16);
1429     tcg_gen_or_i32(reg, src1, src2);
1430     gen_logic_cc(s, reg);
1431 }
1432
1433 DISAS_INSN(pea)
1434 {
1435     TCGv tmp;
1436
1437     tmp = gen_lea(env, s, insn, OS_LONG);
1438     if (IS_NULL_QREG(tmp)) {
1439         gen_addr_fault(s);
1440         return;
1441     }
1442     gen_push(s, tmp);
1443 }
1444
1445 DISAS_INSN(ext)
1446 {
1447     int op;
1448     TCGv reg;
1449     TCGv tmp;
1450
1451     reg = DREG(insn, 0);
1452     op = (insn >> 6) & 7;
1453     tmp = tcg_temp_new();
1454     if (op == 3)
1455         tcg_gen_ext16s_i32(tmp, reg);
1456     else
1457         tcg_gen_ext8s_i32(tmp, reg);
1458     if (op == 2)
1459         gen_partset_reg(OS_WORD, reg, tmp);
1460     else
1461         tcg_gen_mov_i32(reg, tmp);
1462     gen_logic_cc(s, tmp);
1463 }
1464
1465 DISAS_INSN(tst)
1466 {
1467     int opsize;
1468     TCGv tmp;
1469
1470     switch ((insn >> 6) & 3) {
1471     case 0: /* tst.b */
1472         opsize = OS_BYTE;
1473         break;
1474     case 1: /* tst.w */
1475         opsize = OS_WORD;
1476         break;
1477     case 2: /* tst.l */
1478         opsize = OS_LONG;
1479         break;
1480     default:
1481         abort();
1482     }
1483     SRC_EA(env, tmp, opsize, 1, NULL);
1484     gen_logic_cc(s, tmp);
1485 }
1486
1487 DISAS_INSN(pulse)
1488 {
1489   /* Implemented as a NOP.  */
1490 }
1491
1492 DISAS_INSN(illegal)
1493 {
1494     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1495 }
1496
1497 /* ??? This should be atomic.  */
1498 DISAS_INSN(tas)
1499 {
1500     TCGv dest;
1501     TCGv src1;
1502     TCGv addr;
1503
1504     dest = tcg_temp_new();
1505     SRC_EA(env, src1, OS_BYTE, 1, &addr);
1506     gen_logic_cc(s, src1);
1507     tcg_gen_ori_i32(dest, src1, 0x80);
1508     DEST_EA(env, insn, OS_BYTE, dest, &addr);
1509 }
1510
1511 DISAS_INSN(mull)
1512 {
1513     uint16_t ext;
1514     TCGv reg;
1515     TCGv src1;
1516     TCGv dest;
1517
1518     /* The upper 32 bits of the product are discarded, so
1519        muls.l and mulu.l are functionally equivalent.  */
1520     ext = cpu_lduw_code(env, s->pc);
1521     s->pc += 2;
1522     if (ext & 0x87ff) {
1523         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1524         return;
1525     }
1526     reg = DREG(ext, 12);
1527     SRC_EA(env, src1, OS_LONG, 0, NULL);
1528     dest = tcg_temp_new();
1529     tcg_gen_mul_i32(dest, src1, reg);
1530     tcg_gen_mov_i32(reg, dest);
1531     /* Unlike m68k, coldfire always clears the overflow bit.  */
1532     gen_logic_cc(s, dest);
1533 }
1534
1535 DISAS_INSN(link)
1536 {
1537     int16_t offset;
1538     TCGv reg;
1539     TCGv tmp;
1540
1541     offset = cpu_ldsw_code(env, s->pc);
1542     s->pc += 2;
1543     reg = AREG(insn, 0);
1544     tmp = tcg_temp_new();
1545     tcg_gen_subi_i32(tmp, QREG_SP, 4);
1546     gen_store(s, OS_LONG, tmp, reg);
1547     if ((insn & 7) != 7)
1548         tcg_gen_mov_i32(reg, tmp);
1549     tcg_gen_addi_i32(QREG_SP, tmp, offset);
1550 }
1551
1552 DISAS_INSN(unlk)
1553 {
1554     TCGv src;
1555     TCGv reg;
1556     TCGv tmp;
1557
1558     src = tcg_temp_new();
1559     reg = AREG(insn, 0);
1560     tcg_gen_mov_i32(src, reg);
1561     tmp = gen_load(s, OS_LONG, src, 0);
1562     tcg_gen_mov_i32(reg, tmp);
1563     tcg_gen_addi_i32(QREG_SP, src, 4);
1564 }
1565
1566 DISAS_INSN(nop)
1567 {
1568 }
1569
1570 DISAS_INSN(rts)
1571 {
1572     TCGv tmp;
1573
1574     tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1575     tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
1576     gen_jmp(s, tmp);
1577 }
1578
1579 DISAS_INSN(jump)
1580 {
1581     TCGv tmp;
1582
1583     /* Load the target address first to ensure correct exception
1584        behavior.  */
1585     tmp = gen_lea(env, s, insn, OS_LONG);
1586     if (IS_NULL_QREG(tmp)) {
1587         gen_addr_fault(s);
1588         return;
1589     }
1590     if ((insn & 0x40) == 0) {
1591         /* jsr */
1592         gen_push(s, tcg_const_i32(s->pc));
1593     }
1594     gen_jmp(s, tmp);
1595 }
1596
1597 DISAS_INSN(addsubq)
1598 {
1599     TCGv src1;
1600     TCGv src2;
1601     TCGv dest;
1602     int val;
1603     TCGv addr;
1604
1605     SRC_EA(env, src1, OS_LONG, 0, &addr);
1606     val = (insn >> 9) & 7;
1607     if (val == 0)
1608         val = 8;
1609     dest = tcg_temp_new();
1610     tcg_gen_mov_i32(dest, src1);
1611     if ((insn & 0x38) == 0x08) {
1612         /* Don't update condition codes if the destination is an
1613            address register.  */
1614         if (insn & 0x0100) {
1615             tcg_gen_subi_i32(dest, dest, val);
1616         } else {
1617             tcg_gen_addi_i32(dest, dest, val);
1618         }
1619     } else {
1620         src2 = tcg_const_i32(val);
1621         if (insn & 0x0100) {
1622             gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1623             tcg_gen_subi_i32(dest, dest, val);
1624             s->cc_op = CC_OP_SUB;
1625         } else {
1626             tcg_gen_addi_i32(dest, dest, val);
1627             gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1628             s->cc_op = CC_OP_ADD;
1629         }
1630         gen_update_cc_add(dest, src2);
1631     }
1632     DEST_EA(env, insn, OS_LONG, dest, &addr);
1633 }
1634
1635 DISAS_INSN(tpf)
1636 {
1637     switch (insn & 7) {
1638     case 2: /* One extension word.  */
1639         s->pc += 2;
1640         break;
1641     case 3: /* Two extension words.  */
1642         s->pc += 4;
1643         break;
1644     case 4: /* No extension words.  */
1645         break;
1646     default:
1647         disas_undef(env, s, insn);
1648     }
1649 }
1650
1651 DISAS_INSN(branch)
1652 {
1653     int32_t offset;
1654     uint32_t base;
1655     int op;
1656     int l1;
1657
1658     base = s->pc;
1659     op = (insn >> 8) & 0xf;
1660     offset = (int8_t)insn;
1661     if (offset == 0) {
1662         offset = cpu_ldsw_code(env, s->pc);
1663         s->pc += 2;
1664     } else if (offset == -1) {
1665         offset = read_im32(env, s);
1666     }
1667     if (op == 1) {
1668         /* bsr */
1669         gen_push(s, tcg_const_i32(s->pc));
1670     }
1671     gen_flush_cc_op(s);
1672     if (op > 1) {
1673         /* Bcc */
1674         l1 = gen_new_label();
1675         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1676         gen_jmp_tb(s, 1, base + offset);
1677         gen_set_label(l1);
1678         gen_jmp_tb(s, 0, s->pc);
1679     } else {
1680         /* Unconditional branch.  */
1681         gen_jmp_tb(s, 0, base + offset);
1682     }
1683 }
1684
1685 DISAS_INSN(moveq)
1686 {
1687     uint32_t val;
1688
1689     val = (int8_t)insn;
1690     tcg_gen_movi_i32(DREG(insn, 9), val);
1691     gen_logic_cc(s, tcg_const_i32(val));
1692 }
1693
1694 DISAS_INSN(mvzs)
1695 {
1696     int opsize;
1697     TCGv src;
1698     TCGv reg;
1699
1700     if (insn & 0x40)
1701         opsize = OS_WORD;
1702     else
1703         opsize = OS_BYTE;
1704     SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
1705     reg = DREG(insn, 9);
1706     tcg_gen_mov_i32(reg, src);
1707     gen_logic_cc(s, src);
1708 }
1709
1710 DISAS_INSN(or)
1711 {
1712     TCGv reg;
1713     TCGv dest;
1714     TCGv src;
1715     TCGv addr;
1716
1717     reg = DREG(insn, 9);
1718     dest = tcg_temp_new();
1719     if (insn & 0x100) {
1720         SRC_EA(env, src, OS_LONG, 0, &addr);
1721         tcg_gen_or_i32(dest, src, reg);
1722         DEST_EA(env, insn, OS_LONG, dest, &addr);
1723     } else {
1724         SRC_EA(env, src, OS_LONG, 0, NULL);
1725         tcg_gen_or_i32(dest, src, reg);
1726         tcg_gen_mov_i32(reg, dest);
1727     }
1728     gen_logic_cc(s, dest);
1729 }
1730
1731 DISAS_INSN(suba)
1732 {
1733     TCGv src;
1734     TCGv reg;
1735
1736     SRC_EA(env, src, OS_LONG, 0, NULL);
1737     reg = AREG(insn, 9);
1738     tcg_gen_sub_i32(reg, reg, src);
1739 }
1740
1741 DISAS_INSN(subx)
1742 {
1743     TCGv reg;
1744     TCGv src;
1745
1746     gen_flush_flags(s);
1747     reg = DREG(insn, 9);
1748     src = DREG(insn, 0);
1749     gen_helper_subx_cc(reg, cpu_env, reg, src);
1750 }
1751
1752 DISAS_INSN(mov3q)
1753 {
1754     TCGv src;
1755     int val;
1756
1757     val = (insn >> 9) & 7;
1758     if (val == 0)
1759         val = -1;
1760     src = tcg_const_i32(val);
1761     gen_logic_cc(s, src);
1762     DEST_EA(env, insn, OS_LONG, src, NULL);
1763 }
1764
1765 DISAS_INSN(cmp)
1766 {
1767     int op;
1768     TCGv src;
1769     TCGv reg;
1770     TCGv dest;
1771     int opsize;
1772
1773     op = (insn >> 6) & 3;
1774     switch (op) {
1775     case 0: /* cmp.b */
1776         opsize = OS_BYTE;
1777         s->cc_op = CC_OP_CMPB;
1778         break;
1779     case 1: /* cmp.w */
1780         opsize = OS_WORD;
1781         s->cc_op = CC_OP_CMPW;
1782         break;
1783     case 2: /* cmp.l */
1784         opsize = OS_LONG;
1785         s->cc_op = CC_OP_SUB;
1786         break;
1787     default:
1788         abort();
1789     }
1790     SRC_EA(env, src, opsize, 1, NULL);
1791     reg = DREG(insn, 9);
1792     dest = tcg_temp_new();
1793     tcg_gen_sub_i32(dest, reg, src);
1794     gen_update_cc_add(dest, src);
1795 }
1796
1797 DISAS_INSN(cmpa)
1798 {
1799     int opsize;
1800     TCGv src;
1801     TCGv reg;
1802     TCGv dest;
1803
1804     if (insn & 0x100) {
1805         opsize = OS_LONG;
1806     } else {
1807         opsize = OS_WORD;
1808     }
1809     SRC_EA(env, src, opsize, 1, NULL);
1810     reg = AREG(insn, 9);
1811     dest = tcg_temp_new();
1812     tcg_gen_sub_i32(dest, reg, src);
1813     gen_update_cc_add(dest, src);
1814     s->cc_op = CC_OP_SUB;
1815 }
1816
1817 DISAS_INSN(eor)
1818 {
1819     TCGv src;
1820     TCGv reg;
1821     TCGv dest;
1822     TCGv addr;
1823
1824     SRC_EA(env, src, OS_LONG, 0, &addr);
1825     reg = DREG(insn, 9);
1826     dest = tcg_temp_new();
1827     tcg_gen_xor_i32(dest, src, reg);
1828     gen_logic_cc(s, dest);
1829     DEST_EA(env, insn, OS_LONG, dest, &addr);
1830 }
1831
1832 DISAS_INSN(and)
1833 {
1834     TCGv src;
1835     TCGv reg;
1836     TCGv dest;
1837     TCGv addr;
1838
1839     reg = DREG(insn, 9);
1840     dest = tcg_temp_new();
1841     if (insn & 0x100) {
1842         SRC_EA(env, src, OS_LONG, 0, &addr);
1843         tcg_gen_and_i32(dest, src, reg);
1844         DEST_EA(env, insn, OS_LONG, dest, &addr);
1845     } else {
1846         SRC_EA(env, src, OS_LONG, 0, NULL);
1847         tcg_gen_and_i32(dest, src, reg);
1848         tcg_gen_mov_i32(reg, dest);
1849     }
1850     gen_logic_cc(s, dest);
1851 }
1852
1853 DISAS_INSN(adda)
1854 {
1855     TCGv src;
1856     TCGv reg;
1857
1858     SRC_EA(env, src, OS_LONG, 0, NULL);
1859     reg = AREG(insn, 9);
1860     tcg_gen_add_i32(reg, reg, src);
1861 }
1862
1863 DISAS_INSN(addx)
1864 {
1865     TCGv reg;
1866     TCGv src;
1867
1868     gen_flush_flags(s);
1869     reg = DREG(insn, 9);
1870     src = DREG(insn, 0);
1871     gen_helper_addx_cc(reg, cpu_env, reg, src);
1872     s->cc_op = CC_OP_FLAGS;
1873 }
1874
1875 /* TODO: This could be implemented without helper functions.  */
1876 DISAS_INSN(shift_im)
1877 {
1878     TCGv reg;
1879     int tmp;
1880     TCGv shift;
1881
1882     reg = DREG(insn, 0);
1883     tmp = (insn >> 9) & 7;
1884     if (tmp == 0)
1885         tmp = 8;
1886     shift = tcg_const_i32(tmp);
1887     /* No need to flush flags becuse we know we will set C flag.  */
1888     if (insn & 0x100) {
1889         gen_helper_shl_cc(reg, cpu_env, reg, shift);
1890     } else {
1891         if (insn & 8) {
1892             gen_helper_shr_cc(reg, cpu_env, reg, shift);
1893         } else {
1894             gen_helper_sar_cc(reg, cpu_env, reg, shift);
1895         }
1896     }
1897     s->cc_op = CC_OP_SHIFT;
1898 }
1899
1900 DISAS_INSN(shift_reg)
1901 {
1902     TCGv reg;
1903     TCGv shift;
1904
1905     reg = DREG(insn, 0);
1906     shift = DREG(insn, 9);
1907     /* Shift by zero leaves C flag unmodified.   */
1908     gen_flush_flags(s);
1909     if (insn & 0x100) {
1910         gen_helper_shl_cc(reg, cpu_env, reg, shift);
1911     } else {
1912         if (insn & 8) {
1913             gen_helper_shr_cc(reg, cpu_env, reg, shift);
1914         } else {
1915             gen_helper_sar_cc(reg, cpu_env, reg, shift);
1916         }
1917     }
1918     s->cc_op = CC_OP_SHIFT;
1919 }
1920
1921 DISAS_INSN(ff1)
1922 {
1923     TCGv reg;
1924     reg = DREG(insn, 0);
1925     gen_logic_cc(s, reg);
1926     gen_helper_ff1(reg, reg);
1927 }
1928
1929 static TCGv gen_get_sr(DisasContext *s)
1930 {
1931     TCGv ccr;
1932     TCGv sr;
1933
1934     ccr = gen_get_ccr(s);
1935     sr = tcg_temp_new();
1936     tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
1937     tcg_gen_or_i32(sr, sr, ccr);
1938     return sr;
1939 }
1940
1941 DISAS_INSN(strldsr)
1942 {
1943     uint16_t ext;
1944     uint32_t addr;
1945
1946     addr = s->pc - 2;
1947     ext = cpu_lduw_code(env, s->pc);
1948     s->pc += 2;
1949     if (ext != 0x46FC) {
1950         gen_exception(s, addr, EXCP_UNSUPPORTED);
1951         return;
1952     }
1953     ext = cpu_lduw_code(env, s->pc);
1954     s->pc += 2;
1955     if (IS_USER(s) || (ext & SR_S) == 0) {
1956         gen_exception(s, addr, EXCP_PRIVILEGE);
1957         return;
1958     }
1959     gen_push(s, gen_get_sr(s));
1960     gen_set_sr_im(s, ext, 0);
1961 }
1962
1963 DISAS_INSN(move_from_sr)
1964 {
1965     TCGv reg;
1966     TCGv sr;
1967
1968     if (IS_USER(s)) {
1969         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1970         return;
1971     }
1972     sr = gen_get_sr(s);
1973     reg = DREG(insn, 0);
1974     gen_partset_reg(OS_WORD, reg, sr);
1975 }
1976
1977 DISAS_INSN(move_to_sr)
1978 {
1979     if (IS_USER(s)) {
1980         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1981         return;
1982     }
1983     gen_set_sr(env, s, insn, 0);
1984     gen_lookup_tb(s);
1985 }
1986
1987 DISAS_INSN(move_from_usp)
1988 {
1989     if (IS_USER(s)) {
1990         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1991         return;
1992     }
1993     /* TODO: Implement USP.  */
1994     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1995 }
1996
1997 DISAS_INSN(move_to_usp)
1998 {
1999     if (IS_USER(s)) {
2000         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2001         return;
2002     }
2003     /* TODO: Implement USP.  */
2004     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
2005 }
2006
2007 DISAS_INSN(halt)
2008 {
2009     gen_exception(s, s->pc, EXCP_HALT_INSN);
2010 }
2011
2012 DISAS_INSN(stop)
2013 {
2014     uint16_t ext;
2015
2016     if (IS_USER(s)) {
2017         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2018         return;
2019     }
2020
2021     ext = cpu_lduw_code(env, s->pc);
2022     s->pc += 2;
2023
2024     gen_set_sr_im(s, ext, 0);
2025     tcg_gen_movi_i32(cpu_halted, 1);
2026     gen_exception(s, s->pc, EXCP_HLT);
2027 }
2028
2029 DISAS_INSN(rte)
2030 {
2031     if (IS_USER(s)) {
2032         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2033         return;
2034     }
2035     gen_exception(s, s->pc - 2, EXCP_RTE);
2036 }
2037
2038 DISAS_INSN(movec)
2039 {
2040     uint16_t ext;
2041     TCGv reg;
2042
2043     if (IS_USER(s)) {
2044         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2045         return;
2046     }
2047
2048     ext = cpu_lduw_code(env, s->pc);
2049     s->pc += 2;
2050
2051     if (ext & 0x8000) {
2052         reg = AREG(ext, 12);
2053     } else {
2054         reg = DREG(ext, 12);
2055     }
2056     gen_helper_movec(cpu_env, tcg_const_i32(ext & 0xfff), reg);
2057     gen_lookup_tb(s);
2058 }
2059
2060 DISAS_INSN(intouch)
2061 {
2062     if (IS_USER(s)) {
2063         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2064         return;
2065     }
2066     /* ICache fetch.  Implement as no-op.  */
2067 }
2068
2069 DISAS_INSN(cpushl)
2070 {
2071     if (IS_USER(s)) {
2072         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2073         return;
2074     }
2075     /* Cache push/invalidate.  Implement as no-op.  */
2076 }
2077
2078 DISAS_INSN(wddata)
2079 {
2080     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2081 }
2082
2083 DISAS_INSN(wdebug)
2084 {
2085     if (IS_USER(s)) {
2086         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2087         return;
2088     }
2089     /* TODO: Implement wdebug.  */
2090     cpu_abort(env, "WDEBUG not implemented");
2091 }
2092
2093 DISAS_INSN(trap)
2094 {
2095     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
2096 }
2097
2098 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
2099    immediately before the next FP instruction is executed.  */
2100 DISAS_INSN(fpu)
2101 {
2102     uint16_t ext;
2103     int32_t offset;
2104     int opmode;
2105     TCGv_i64 src;
2106     TCGv_i64 dest;
2107     TCGv_i64 res;
2108     TCGv tmp32;
2109     int round;
2110     int set_dest;
2111     int opsize;
2112
2113     ext = cpu_lduw_code(env, s->pc);
2114     s->pc += 2;
2115     opmode = ext & 0x7f;
2116     switch ((ext >> 13) & 7) {
2117     case 0: case 2:
2118         break;
2119     case 1:
2120         goto undef;
2121     case 3: /* fmove out */
2122         src = FREG(ext, 7);
2123         tmp32 = tcg_temp_new_i32();
2124         /* fmove */
2125         /* ??? TODO: Proper behavior on overflow.  */
2126         switch ((ext >> 10) & 7) {
2127         case 0:
2128             opsize = OS_LONG;
2129             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2130             break;
2131         case 1:
2132             opsize = OS_SINGLE;
2133             gen_helper_f64_to_f32(tmp32, cpu_env, src);
2134             break;
2135         case 4:
2136             opsize = OS_WORD;
2137             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2138             break;
2139         case 5: /* OS_DOUBLE */
2140             tcg_gen_mov_i32(tmp32, AREG(insn, 0));
2141             switch ((insn >> 3) & 7) {
2142             case 2:
2143             case 3:
2144                 break;
2145             case 4:
2146                 tcg_gen_addi_i32(tmp32, tmp32, -8);
2147                 break;
2148             case 5:
2149                 offset = cpu_ldsw_code(env, s->pc);
2150                 s->pc += 2;
2151                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2152                 break;
2153             default:
2154                 goto undef;
2155             }
2156             gen_store64(s, tmp32, src);
2157             switch ((insn >> 3) & 7) {
2158             case 3:
2159                 tcg_gen_addi_i32(tmp32, tmp32, 8);
2160                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2161                 break;
2162             case 4:
2163                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2164                 break;
2165             }
2166             tcg_temp_free_i32(tmp32);
2167             return;
2168         case 6:
2169             opsize = OS_BYTE;
2170             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2171             break;
2172         default:
2173             goto undef;
2174         }
2175         DEST_EA(env, insn, opsize, tmp32, NULL);
2176         tcg_temp_free_i32(tmp32);
2177         return;
2178     case 4: /* fmove to control register.  */
2179         switch ((ext >> 10) & 7) {
2180         case 4: /* FPCR */
2181             /* Not implemented.  Ignore writes.  */
2182             break;
2183         case 1: /* FPIAR */
2184         case 2: /* FPSR */
2185         default:
2186             cpu_abort(NULL, "Unimplemented: fmove to control %d",
2187                       (ext >> 10) & 7);
2188         }
2189         break;
2190     case 5: /* fmove from control register.  */
2191         switch ((ext >> 10) & 7) {
2192         case 4: /* FPCR */
2193             /* Not implemented.  Always return zero.  */
2194             tmp32 = tcg_const_i32(0);
2195             break;
2196         case 1: /* FPIAR */
2197         case 2: /* FPSR */
2198         default:
2199             cpu_abort(NULL, "Unimplemented: fmove from control %d",
2200                       (ext >> 10) & 7);
2201             goto undef;
2202         }
2203         DEST_EA(env, insn, OS_LONG, tmp32, NULL);
2204         break;
2205     case 6: /* fmovem */
2206     case 7:
2207         {
2208             TCGv addr;
2209             uint16_t mask;
2210             int i;
2211             if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2212                 goto undef;
2213             tmp32 = gen_lea(env, s, insn, OS_LONG);
2214             if (IS_NULL_QREG(tmp32)) {
2215                 gen_addr_fault(s);
2216                 return;
2217             }
2218             addr = tcg_temp_new_i32();
2219             tcg_gen_mov_i32(addr, tmp32);
2220             mask = 0x80;
2221             for (i = 0; i < 8; i++) {
2222                 if (ext & mask) {
2223                     s->is_mem = 1;
2224                     dest = FREG(i, 0);
2225                     if (ext & (1 << 13)) {
2226                         /* store */
2227                         tcg_gen_qemu_stf64(dest, addr, IS_USER(s));
2228                     } else {
2229                         /* load */
2230                         tcg_gen_qemu_ldf64(dest, addr, IS_USER(s));
2231                     }
2232                     if (ext & (mask - 1))
2233                         tcg_gen_addi_i32(addr, addr, 8);
2234                 }
2235                 mask >>= 1;
2236             }
2237             tcg_temp_free_i32(addr);
2238         }
2239         return;
2240     }
2241     if (ext & (1 << 14)) {
2242         /* Source effective address.  */
2243         switch ((ext >> 10) & 7) {
2244         case 0: opsize = OS_LONG; break;
2245         case 1: opsize = OS_SINGLE; break;
2246         case 4: opsize = OS_WORD; break;
2247         case 5: opsize = OS_DOUBLE; break;
2248         case 6: opsize = OS_BYTE; break;
2249         default:
2250             goto undef;
2251         }
2252         if (opsize == OS_DOUBLE) {
2253             tmp32 = tcg_temp_new_i32();
2254             tcg_gen_mov_i32(tmp32, AREG(insn, 0));
2255             switch ((insn >> 3) & 7) {
2256             case 2:
2257             case 3:
2258                 break;
2259             case 4:
2260                 tcg_gen_addi_i32(tmp32, tmp32, -8);
2261                 break;
2262             case 5:
2263                 offset = cpu_ldsw_code(env, s->pc);
2264                 s->pc += 2;
2265                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2266                 break;
2267             case 7:
2268                 offset = cpu_ldsw_code(env, s->pc);
2269                 offset += s->pc - 2;
2270                 s->pc += 2;
2271                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2272                 break;
2273             default:
2274                 goto undef;
2275             }
2276             src = gen_load64(s, tmp32);
2277             switch ((insn >> 3) & 7) {
2278             case 3:
2279                 tcg_gen_addi_i32(tmp32, tmp32, 8);
2280                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2281                 break;
2282             case 4:
2283                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2284                 break;
2285             }
2286             tcg_temp_free_i32(tmp32);
2287         } else {
2288             SRC_EA(env, tmp32, opsize, 1, NULL);
2289             src = tcg_temp_new_i64();
2290             switch (opsize) {
2291             case OS_LONG:
2292             case OS_WORD:
2293             case OS_BYTE:
2294                 gen_helper_i32_to_f64(src, cpu_env, tmp32);
2295                 break;
2296             case OS_SINGLE:
2297                 gen_helper_f32_to_f64(src, cpu_env, tmp32);
2298                 break;
2299             }
2300         }
2301     } else {
2302         /* Source register.  */
2303         src = FREG(ext, 10);
2304     }
2305     dest = FREG(ext, 7);
2306     res = tcg_temp_new_i64();
2307     if (opmode != 0x3a)
2308         tcg_gen_mov_f64(res, dest);
2309     round = 1;
2310     set_dest = 1;
2311     switch (opmode) {
2312     case 0: case 0x40: case 0x44: /* fmove */
2313         tcg_gen_mov_f64(res, src);
2314         break;
2315     case 1: /* fint */
2316         gen_helper_iround_f64(res, cpu_env, src);
2317         round = 0;
2318         break;
2319     case 3: /* fintrz */
2320         gen_helper_itrunc_f64(res, cpu_env, src);
2321         round = 0;
2322         break;
2323     case 4: case 0x41: case 0x45: /* fsqrt */
2324         gen_helper_sqrt_f64(res, cpu_env, src);
2325         break;
2326     case 0x18: case 0x58: case 0x5c: /* fabs */
2327         gen_helper_abs_f64(res, src);
2328         break;
2329     case 0x1a: case 0x5a: case 0x5e: /* fneg */
2330         gen_helper_chs_f64(res, src);
2331         break;
2332     case 0x20: case 0x60: case 0x64: /* fdiv */
2333         gen_helper_div_f64(res, cpu_env, res, src);
2334         break;
2335     case 0x22: case 0x62: case 0x66: /* fadd */
2336         gen_helper_add_f64(res, cpu_env, res, src);
2337         break;
2338     case 0x23: case 0x63: case 0x67: /* fmul */
2339         gen_helper_mul_f64(res, cpu_env, res, src);
2340         break;
2341     case 0x28: case 0x68: case 0x6c: /* fsub */
2342         gen_helper_sub_f64(res, cpu_env, res, src);
2343         break;
2344     case 0x38: /* fcmp */
2345         gen_helper_sub_cmp_f64(res, cpu_env, res, src);
2346         set_dest = 0;
2347         round = 0;
2348         break;
2349     case 0x3a: /* ftst */
2350         tcg_gen_mov_f64(res, src);
2351         set_dest = 0;
2352         round = 0;
2353         break;
2354     default:
2355         goto undef;
2356     }
2357     if (ext & (1 << 14)) {
2358         tcg_temp_free_i64(src);
2359     }
2360     if (round) {
2361         if (opmode & 0x40) {
2362             if ((opmode & 0x4) != 0)
2363                 round = 0;
2364         } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2365             round = 0;
2366         }
2367     }
2368     if (round) {
2369         TCGv tmp = tcg_temp_new_i32();
2370         gen_helper_f64_to_f32(tmp, cpu_env, res);
2371         gen_helper_f32_to_f64(res, cpu_env, tmp);
2372         tcg_temp_free_i32(tmp);
2373     }
2374     tcg_gen_mov_f64(QREG_FP_RESULT, res);
2375     if (set_dest) {
2376         tcg_gen_mov_f64(dest, res);
2377     }
2378     tcg_temp_free_i64(res);
2379     return;
2380 undef:
2381     /* FIXME: Is this right for offset addressing modes?  */
2382     s->pc -= 2;
2383     disas_undef_fpu(env, s, insn);
2384 }
2385
2386 DISAS_INSN(fbcc)
2387 {
2388     uint32_t offset;
2389     uint32_t addr;
2390     TCGv flag;
2391     int l1;
2392
2393     addr = s->pc;
2394     offset = cpu_ldsw_code(env, s->pc);
2395     s->pc += 2;
2396     if (insn & (1 << 6)) {
2397         offset = (offset << 16) | cpu_lduw_code(env, s->pc);
2398         s->pc += 2;
2399     }
2400
2401     l1 = gen_new_label();
2402     /* TODO: Raise BSUN exception.  */
2403     flag = tcg_temp_new();
2404     gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
2405     /* Jump to l1 if condition is true.  */
2406     switch (insn & 0xf) {
2407     case 0: /* f */
2408         break;
2409     case 1: /* eq (=0) */
2410         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2411         break;
2412     case 2: /* ogt (=1) */
2413         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(1), l1);
2414         break;
2415     case 3: /* oge (=0 or =1) */
2416         tcg_gen_brcond_i32(TCG_COND_LEU, flag, tcg_const_i32(1), l1);
2417         break;
2418     case 4: /* olt (=-1) */
2419         tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(0), l1);
2420         break;
2421     case 5: /* ole (=-1 or =0) */
2422         tcg_gen_brcond_i32(TCG_COND_LE, flag, tcg_const_i32(0), l1);
2423         break;
2424     case 6: /* ogl (=-1 or =1) */
2425         tcg_gen_andi_i32(flag, flag, 1);
2426         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2427         break;
2428     case 7: /* or (=2) */
2429         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(2), l1);
2430         break;
2431     case 8: /* un (<2) */
2432         tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(2), l1);
2433         break;
2434     case 9: /* ueq (=0 or =2) */
2435         tcg_gen_andi_i32(flag, flag, 1);
2436         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2437         break;
2438     case 10: /* ugt (>0) */
2439         tcg_gen_brcond_i32(TCG_COND_GT, flag, tcg_const_i32(0), l1);
2440         break;
2441     case 11: /* uge (>=0) */
2442         tcg_gen_brcond_i32(TCG_COND_GE, flag, tcg_const_i32(0), l1);
2443         break;
2444     case 12: /* ult (=-1 or =2) */
2445         tcg_gen_brcond_i32(TCG_COND_GEU, flag, tcg_const_i32(2), l1);
2446         break;
2447     case 13: /* ule (!=1) */
2448         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(1), l1);
2449         break;
2450     case 14: /* ne (!=0) */
2451         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2452         break;
2453     case 15: /* t */
2454         tcg_gen_br(l1);
2455         break;
2456     }
2457     gen_jmp_tb(s, 0, s->pc);
2458     gen_set_label(l1);
2459     gen_jmp_tb(s, 1, addr + offset);
2460 }
2461
2462 DISAS_INSN(frestore)
2463 {
2464     /* TODO: Implement frestore.  */
2465     cpu_abort(env, "FRESTORE not implemented");
2466 }
2467
2468 DISAS_INSN(fsave)
2469 {
2470     /* TODO: Implement fsave.  */
2471     cpu_abort(env, "FSAVE not implemented");
2472 }
2473
2474 static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
2475 {
2476     TCGv tmp = tcg_temp_new();
2477     if (s->env->macsr & MACSR_FI) {
2478         if (upper)
2479             tcg_gen_andi_i32(tmp, val, 0xffff0000);
2480         else
2481             tcg_gen_shli_i32(tmp, val, 16);
2482     } else if (s->env->macsr & MACSR_SU) {
2483         if (upper)
2484             tcg_gen_sari_i32(tmp, val, 16);
2485         else
2486             tcg_gen_ext16s_i32(tmp, val);
2487     } else {
2488         if (upper)
2489             tcg_gen_shri_i32(tmp, val, 16);
2490         else
2491             tcg_gen_ext16u_i32(tmp, val);
2492     }
2493     return tmp;
2494 }
2495
2496 static void gen_mac_clear_flags(void)
2497 {
2498     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
2499                      ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
2500 }
2501
2502 DISAS_INSN(mac)
2503 {
2504     TCGv rx;
2505     TCGv ry;
2506     uint16_t ext;
2507     int acc;
2508     TCGv tmp;
2509     TCGv addr;
2510     TCGv loadval;
2511     int dual;
2512     TCGv saved_flags;
2513
2514     if (!s->done_mac) {
2515         s->mactmp = tcg_temp_new_i64();
2516         s->done_mac = 1;
2517     }
2518
2519     ext = cpu_lduw_code(env, s->pc);
2520     s->pc += 2;
2521
2522     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
2523     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
2524     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
2525         disas_undef(env, s, insn);
2526         return;
2527     }
2528     if (insn & 0x30) {
2529         /* MAC with load.  */
2530         tmp = gen_lea(env, s, insn, OS_LONG);
2531         addr = tcg_temp_new();
2532         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
2533         /* Load the value now to ensure correct exception behavior.
2534            Perform writeback after reading the MAC inputs.  */
2535         loadval = gen_load(s, OS_LONG, addr, 0);
2536
2537         acc ^= 1;
2538         rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2539         ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2540     } else {
2541         loadval = addr = NULL_QREG;
2542         rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2543         ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2544     }
2545
2546     gen_mac_clear_flags();
2547 #if 0
2548     l1 = -1;
2549     /* Disabled because conditional branches clobber temporary vars.  */
2550     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2551         /* Skip the multiply if we know we will ignore it.  */
2552         l1 = gen_new_label();
2553         tmp = tcg_temp_new();
2554         tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
2555         gen_op_jmp_nz32(tmp, l1);
2556     }
2557 #endif
2558
2559     if ((ext & 0x0800) == 0) {
2560         /* Word.  */
2561         rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
2562         ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2563     }
2564     if (s->env->macsr & MACSR_FI) {
2565         gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
2566     } else {
2567         if (s->env->macsr & MACSR_SU)
2568             gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
2569         else
2570             gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
2571         switch ((ext >> 9) & 3) {
2572         case 1:
2573             tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
2574             break;
2575         case 3:
2576             tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
2577             break;
2578         }
2579     }
2580
2581     if (dual) {
2582         /* Save the overflow flag from the multiply.  */
2583         saved_flags = tcg_temp_new();
2584         tcg_gen_mov_i32(saved_flags, QREG_MACSR);
2585     } else {
2586         saved_flags = NULL_QREG;
2587     }
2588
2589 #if 0
2590     /* Disabled because conditional branches clobber temporary vars.  */
2591     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2592         /* Skip the accumulate if the value is already saturated.  */
2593         l1 = gen_new_label();
2594         tmp = tcg_temp_new();
2595         gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
2596         gen_op_jmp_nz32(tmp, l1);
2597     }
2598 #endif
2599
2600     if (insn & 0x100)
2601         tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2602     else
2603         tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2604
2605     if (s->env->macsr & MACSR_FI)
2606         gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2607     else if (s->env->macsr & MACSR_SU)
2608         gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2609     else
2610         gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2611
2612 #if 0
2613     /* Disabled because conditional branches clobber temporary vars.  */
2614     if (l1 != -1)
2615         gen_set_label(l1);
2616 #endif
2617
2618     if (dual) {
2619         /* Dual accumulate variant.  */
2620         acc = (ext >> 2) & 3;
2621         /* Restore the overflow flag from the multiplier.  */
2622         tcg_gen_mov_i32(QREG_MACSR, saved_flags);
2623 #if 0
2624         /* Disabled because conditional branches clobber temporary vars.  */
2625         if ((s->env->macsr & MACSR_OMC) != 0) {
2626             /* Skip the accumulate if the value is already saturated.  */
2627             l1 = gen_new_label();
2628             tmp = tcg_temp_new();
2629             gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
2630             gen_op_jmp_nz32(tmp, l1);
2631         }
2632 #endif
2633         if (ext & 2)
2634             tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2635         else
2636             tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2637         if (s->env->macsr & MACSR_FI)
2638             gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2639         else if (s->env->macsr & MACSR_SU)
2640             gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2641         else
2642             gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2643 #if 0
2644         /* Disabled because conditional branches clobber temporary vars.  */
2645         if (l1 != -1)
2646             gen_set_label(l1);
2647 #endif
2648     }
2649     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
2650
2651     if (insn & 0x30) {
2652         TCGv rw;
2653         rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2654         tcg_gen_mov_i32(rw, loadval);
2655         /* FIXME: Should address writeback happen with the masked or
2656            unmasked value?  */
2657         switch ((insn >> 3) & 7) {
2658         case 3: /* Post-increment.  */
2659             tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
2660             break;
2661         case 4: /* Pre-decrement.  */
2662             tcg_gen_mov_i32(AREG(insn, 0), addr);
2663         }
2664     }
2665 }
2666
2667 DISAS_INSN(from_mac)
2668 {
2669     TCGv rx;
2670     TCGv_i64 acc;
2671     int accnum;
2672
2673     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2674     accnum = (insn >> 9) & 3;
2675     acc = MACREG(accnum);
2676     if (s->env->macsr & MACSR_FI) {
2677         gen_helper_get_macf(rx, cpu_env, acc);
2678     } else if ((s->env->macsr & MACSR_OMC) == 0) {
2679         tcg_gen_trunc_i64_i32(rx, acc);
2680     } else if (s->env->macsr & MACSR_SU) {
2681         gen_helper_get_macs(rx, acc);
2682     } else {
2683         gen_helper_get_macu(rx, acc);
2684     }
2685     if (insn & 0x40) {
2686         tcg_gen_movi_i64(acc, 0);
2687         tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2688     }
2689 }
2690
2691 DISAS_INSN(move_mac)
2692 {
2693     /* FIXME: This can be done without a helper.  */
2694     int src;
2695     TCGv dest;
2696     src = insn & 3;
2697     dest = tcg_const_i32((insn >> 9) & 3);
2698     gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
2699     gen_mac_clear_flags();
2700     gen_helper_mac_set_flags(cpu_env, dest);
2701 }
2702
2703 DISAS_INSN(from_macsr)
2704 {
2705     TCGv reg;
2706
2707     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2708     tcg_gen_mov_i32(reg, QREG_MACSR);
2709 }
2710
2711 DISAS_INSN(from_mask)
2712 {
2713     TCGv reg;
2714     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2715     tcg_gen_mov_i32(reg, QREG_MAC_MASK);
2716 }
2717
2718 DISAS_INSN(from_mext)
2719 {
2720     TCGv reg;
2721     TCGv acc;
2722     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2723     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2724     if (s->env->macsr & MACSR_FI)
2725         gen_helper_get_mac_extf(reg, cpu_env, acc);
2726     else
2727         gen_helper_get_mac_exti(reg, cpu_env, acc);
2728 }
2729
2730 DISAS_INSN(macsr_to_ccr)
2731 {
2732     tcg_gen_movi_i32(QREG_CC_X, 0);
2733     tcg_gen_andi_i32(QREG_CC_DEST, QREG_MACSR, 0xf);
2734     s->cc_op = CC_OP_FLAGS;
2735 }
2736
2737 DISAS_INSN(to_mac)
2738 {
2739     TCGv_i64 acc;
2740     TCGv val;
2741     int accnum;
2742     accnum = (insn >> 9) & 3;
2743     acc = MACREG(accnum);
2744     SRC_EA(env, val, OS_LONG, 0, NULL);
2745     if (s->env->macsr & MACSR_FI) {
2746         tcg_gen_ext_i32_i64(acc, val);
2747         tcg_gen_shli_i64(acc, acc, 8);
2748     } else if (s->env->macsr & MACSR_SU) {
2749         tcg_gen_ext_i32_i64(acc, val);
2750     } else {
2751         tcg_gen_extu_i32_i64(acc, val);
2752     }
2753     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2754     gen_mac_clear_flags();
2755     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
2756 }
2757
2758 DISAS_INSN(to_macsr)
2759 {
2760     TCGv val;
2761     SRC_EA(env, val, OS_LONG, 0, NULL);
2762     gen_helper_set_macsr(cpu_env, val);
2763     gen_lookup_tb(s);
2764 }
2765
2766 DISAS_INSN(to_mask)
2767 {
2768     TCGv val;
2769     SRC_EA(env, val, OS_LONG, 0, NULL);
2770     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
2771 }
2772
2773 DISAS_INSN(to_mext)
2774 {
2775     TCGv val;
2776     TCGv acc;
2777     SRC_EA(env, val, OS_LONG, 0, NULL);
2778     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2779     if (s->env->macsr & MACSR_FI)
2780         gen_helper_set_mac_extf(cpu_env, val, acc);
2781     else if (s->env->macsr & MACSR_SU)
2782         gen_helper_set_mac_exts(cpu_env, val, acc);
2783     else
2784         gen_helper_set_mac_extu(cpu_env, val, acc);
2785 }
2786
2787 static disas_proc opcode_table[65536];
2788
2789 static void
2790 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2791 {
2792   int i;
2793   int from;
2794   int to;
2795
2796   /* Sanity check.  All set bits must be included in the mask.  */
2797   if (opcode & ~mask) {
2798       fprintf(stderr,
2799               "qemu internal error: bogus opcode definition %04x/%04x\n",
2800               opcode, mask);
2801       abort();
2802   }
2803   /* This could probably be cleverer.  For now just optimize the case where
2804      the top bits are known.  */
2805   /* Find the first zero bit in the mask.  */
2806   i = 0x8000;
2807   while ((i & mask) != 0)
2808       i >>= 1;
2809   /* Iterate over all combinations of this and lower bits.  */
2810   if (i == 0)
2811       i = 1;
2812   else
2813       i <<= 1;
2814   from = opcode & ~(i - 1);
2815   to = from + i;
2816   for (i = from; i < to; i++) {
2817       if ((i & mask) == opcode)
2818           opcode_table[i] = proc;
2819   }
2820 }
2821
2822 /* Register m68k opcode handlers.  Order is important.
2823    Later insn override earlier ones.  */
2824 void register_m68k_insns (CPUM68KState *env)
2825 {
2826 #define INSN(name, opcode, mask, feature) do { \
2827     if (m68k_feature(env, M68K_FEATURE_##feature)) \
2828         register_opcode(disas_##name, 0x##opcode, 0x##mask); \
2829     } while(0)
2830     INSN(undef,     0000, 0000, CF_ISA_A);
2831     INSN(arith_im,  0080, fff8, CF_ISA_A);
2832     INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
2833     INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2834     INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2835     INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2836     INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2837     INSN(arith_im,  0280, fff8, CF_ISA_A);
2838     INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
2839     INSN(arith_im,  0480, fff8, CF_ISA_A);
2840     INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
2841     INSN(arith_im,  0680, fff8, CF_ISA_A);
2842     INSN(bitop_im,  0800, ffc0, CF_ISA_A);
2843     INSN(bitop_im,  0840, ffc0, CF_ISA_A);
2844     INSN(bitop_im,  0880, ffc0, CF_ISA_A);
2845     INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
2846     INSN(arith_im,  0a80, fff8, CF_ISA_A);
2847     INSN(arith_im,  0c00, ff38, CF_ISA_A);
2848     INSN(move,      1000, f000, CF_ISA_A);
2849     INSN(move,      2000, f000, CF_ISA_A);
2850     INSN(move,      3000, f000, CF_ISA_A);
2851     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
2852     INSN(negx,      4080, fff8, CF_ISA_A);
2853     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2854     INSN(lea,       41c0, f1c0, CF_ISA_A);
2855     INSN(clr,       4200, ff00, CF_ISA_A);
2856     INSN(undef,     42c0, ffc0, CF_ISA_A);
2857     INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2858     INSN(neg,       4480, fff8, CF_ISA_A);
2859     INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2860     INSN(not,       4680, fff8, CF_ISA_A);
2861     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2862     INSN(pea,       4840, ffc0, CF_ISA_A);
2863     INSN(swap,      4840, fff8, CF_ISA_A);
2864     INSN(movem,     48c0, fbc0, CF_ISA_A);
2865     INSN(ext,       4880, fff8, CF_ISA_A);
2866     INSN(ext,       48c0, fff8, CF_ISA_A);
2867     INSN(ext,       49c0, fff8, CF_ISA_A);
2868     INSN(tst,       4a00, ff00, CF_ISA_A);
2869     INSN(tas,       4ac0, ffc0, CF_ISA_B);
2870     INSN(halt,      4ac8, ffff, CF_ISA_A);
2871     INSN(pulse,     4acc, ffff, CF_ISA_A);
2872     INSN(illegal,   4afc, ffff, CF_ISA_A);
2873     INSN(mull,      4c00, ffc0, CF_ISA_A);
2874     INSN(divl,      4c40, ffc0, CF_ISA_A);
2875     INSN(sats,      4c80, fff8, CF_ISA_B);
2876     INSN(trap,      4e40, fff0, CF_ISA_A);
2877     INSN(link,      4e50, fff8, CF_ISA_A);
2878     INSN(unlk,      4e58, fff8, CF_ISA_A);
2879     INSN(move_to_usp, 4e60, fff8, USP);
2880     INSN(move_from_usp, 4e68, fff8, USP);
2881     INSN(nop,       4e71, ffff, CF_ISA_A);
2882     INSN(stop,      4e72, ffff, CF_ISA_A);
2883     INSN(rte,       4e73, ffff, CF_ISA_A);
2884     INSN(rts,       4e75, ffff, CF_ISA_A);
2885     INSN(movec,     4e7b, ffff, CF_ISA_A);
2886     INSN(jump,      4e80, ffc0, CF_ISA_A);
2887     INSN(jump,      4ec0, ffc0, CF_ISA_A);
2888     INSN(addsubq,   5180, f1c0, CF_ISA_A);
2889     INSN(scc,       50c0, f0f8, CF_ISA_A);
2890     INSN(addsubq,   5080, f1c0, CF_ISA_A);
2891     INSN(tpf,       51f8, fff8, CF_ISA_A);
2892
2893     /* Branch instructions.  */
2894     INSN(branch,    6000, f000, CF_ISA_A);
2895     /* Disable long branch instructions, then add back the ones we want.  */
2896     INSN(undef,     60ff, f0ff, CF_ISA_A); /* All long branches.  */
2897     INSN(branch,    60ff, f0ff, CF_ISA_B);
2898     INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
2899     INSN(branch,    60ff, ffff, BRAL);
2900
2901     INSN(moveq,     7000, f100, CF_ISA_A);
2902     INSN(mvzs,      7100, f100, CF_ISA_B);
2903     INSN(or,        8000, f000, CF_ISA_A);
2904     INSN(divw,      80c0, f0c0, CF_ISA_A);
2905     INSN(addsub,    9000, f000, CF_ISA_A);
2906     INSN(subx,      9180, f1f8, CF_ISA_A);
2907     INSN(suba,      91c0, f1c0, CF_ISA_A);
2908
2909     INSN(undef_mac, a000, f000, CF_ISA_A);
2910     INSN(mac,       a000, f100, CF_EMAC);
2911     INSN(from_mac,  a180, f9b0, CF_EMAC);
2912     INSN(move_mac,  a110, f9fc, CF_EMAC);
2913     INSN(from_macsr,a980, f9f0, CF_EMAC);
2914     INSN(from_mask, ad80, fff0, CF_EMAC);
2915     INSN(from_mext, ab80, fbf0, CF_EMAC);
2916     INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
2917     INSN(to_mac,    a100, f9c0, CF_EMAC);
2918     INSN(to_macsr,  a900, ffc0, CF_EMAC);
2919     INSN(to_mext,   ab00, fbc0, CF_EMAC);
2920     INSN(to_mask,   ad00, ffc0, CF_EMAC);
2921
2922     INSN(mov3q,     a140, f1c0, CF_ISA_B);
2923     INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
2924     INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
2925     INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2926     INSN(cmp,       b080, f1c0, CF_ISA_A);
2927     INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
2928     INSN(eor,       b180, f1c0, CF_ISA_A);
2929     INSN(and,       c000, f000, CF_ISA_A);
2930     INSN(mulw,      c0c0, f0c0, CF_ISA_A);
2931     INSN(addsub,    d000, f000, CF_ISA_A);
2932     INSN(addx,      d180, f1f8, CF_ISA_A);
2933     INSN(adda,      d1c0, f1c0, CF_ISA_A);
2934     INSN(shift_im,  e080, f0f0, CF_ISA_A);
2935     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2936     INSN(undef_fpu, f000, f000, CF_ISA_A);
2937     INSN(fpu,       f200, ffc0, CF_FPU);
2938     INSN(fbcc,      f280, ffc0, CF_FPU);
2939     INSN(frestore,  f340, ffc0, CF_FPU);
2940     INSN(fsave,     f340, ffc0, CF_FPU);
2941     INSN(intouch,   f340, ffc0, CF_ISA_A);
2942     INSN(cpushl,    f428, ff38, CF_ISA_A);
2943     INSN(wddata,    fb00, ff00, CF_ISA_A);
2944     INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
2945 #undef INSN
2946 }
2947
2948 /* ??? Some of this implementation is not exception safe.  We should always
2949    write back the result to memory before setting the condition codes.  */
2950 static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
2951 {
2952     uint16_t insn;
2953
2954     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
2955         tcg_gen_debug_insn_start(s->pc);
2956     }
2957
2958     insn = cpu_lduw_code(env, s->pc);
2959     s->pc += 2;
2960
2961     opcode_table[insn](env, s, insn);
2962 }
2963
2964 /* generate intermediate code for basic block 'tb'.  */
2965 static inline void
2966 gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
2967                                bool search_pc)
2968 {
2969     CPUState *cs = CPU(cpu);
2970     CPUM68KState *env = &cpu->env;
2971     DisasContext dc1, *dc = &dc1;
2972     uint16_t *gen_opc_end;
2973     CPUBreakpoint *bp;
2974     int j, lj;
2975     target_ulong pc_start;
2976     int pc_offset;
2977     int num_insns;
2978     int max_insns;
2979
2980     /* generate intermediate code */
2981     pc_start = tb->pc;
2982
2983     dc->tb = tb;
2984
2985     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
2986
2987     dc->env = env;
2988     dc->is_jmp = DISAS_NEXT;
2989     dc->pc = pc_start;
2990     dc->cc_op = CC_OP_DYNAMIC;
2991     dc->singlestep_enabled = cs->singlestep_enabled;
2992     dc->fpcr = env->fpcr;
2993     dc->user = (env->sr & SR_S) == 0;
2994     dc->is_mem = 0;
2995     dc->done_mac = 0;
2996     lj = -1;
2997     num_insns = 0;
2998     max_insns = tb->cflags & CF_COUNT_MASK;
2999     if (max_insns == 0)
3000         max_insns = CF_COUNT_MASK;
3001
3002     gen_tb_start();
3003     do {
3004         pc_offset = dc->pc - pc_start;
3005         gen_throws_exception = NULL;
3006         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3007             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3008                 if (bp->pc == dc->pc) {
3009                     gen_exception(dc, dc->pc, EXCP_DEBUG);
3010                     dc->is_jmp = DISAS_JUMP;
3011                     break;
3012                 }
3013             }
3014             if (dc->is_jmp)
3015                 break;
3016         }
3017         if (search_pc) {
3018             j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3019             if (lj < j) {
3020                 lj++;
3021                 while (lj < j)
3022                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
3023             }
3024             tcg_ctx.gen_opc_pc[lj] = dc->pc;
3025             tcg_ctx.gen_opc_instr_start[lj] = 1;
3026             tcg_ctx.gen_opc_icount[lj] = num_insns;
3027         }
3028         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3029             gen_io_start();
3030         dc->insn_pc = dc->pc;
3031         disas_m68k_insn(env, dc);
3032         num_insns++;
3033     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
3034              !cs->singlestep_enabled &&
3035              !singlestep &&
3036              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
3037              num_insns < max_insns);
3038
3039     if (tb->cflags & CF_LAST_IO)
3040         gen_io_end();
3041     if (unlikely(cs->singlestep_enabled)) {
3042         /* Make sure the pc is updated, and raise a debug exception.  */
3043         if (!dc->is_jmp) {
3044             gen_flush_cc_op(dc);
3045             tcg_gen_movi_i32(QREG_PC, dc->pc);
3046         }
3047         gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
3048     } else {
3049         switch(dc->is_jmp) {
3050         case DISAS_NEXT:
3051             gen_flush_cc_op(dc);
3052             gen_jmp_tb(dc, 0, dc->pc);
3053             break;
3054         default:
3055         case DISAS_JUMP:
3056         case DISAS_UPDATE:
3057             gen_flush_cc_op(dc);
3058             /* indicate that the hash table must be used to find the next TB */
3059             tcg_gen_exit_tb(0);
3060             break;
3061         case DISAS_TB_JUMP:
3062             /* nothing more to generate */
3063             break;
3064         }
3065     }
3066     gen_tb_end(tb, num_insns);
3067     *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3068
3069 #ifdef DEBUG_DISAS
3070     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3071         qemu_log("----------------\n");
3072         qemu_log("IN: %s\n", lookup_symbol(pc_start));
3073         log_target_disas(env, pc_start, dc->pc - pc_start, 0);
3074         qemu_log("\n");
3075     }
3076 #endif
3077     if (search_pc) {
3078         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3079         lj++;
3080         while (lj <= j)
3081             tcg_ctx.gen_opc_instr_start[lj++] = 0;
3082     } else {
3083         tb->size = dc->pc - pc_start;
3084         tb->icount = num_insns;
3085     }
3086
3087     //optimize_flags();
3088     //expand_target_qops();
3089 }
3090
3091 void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
3092 {
3093     gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, false);
3094 }
3095
3096 void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
3097 {
3098     gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, true);
3099 }
3100
3101 void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
3102                          int flags)
3103 {
3104     M68kCPU *cpu = M68K_CPU(cs);
3105     CPUM68KState *env = &cpu->env;
3106     int i;
3107     uint16_t sr;
3108     CPU_DoubleU u;
3109     for (i = 0; i < 8; i++)
3110       {
3111         u.d = env->fregs[i];
3112         cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
3113                      i, env->dregs[i], i, env->aregs[i],
3114                      i, u.l.upper, u.l.lower, *(double *)&u.d);
3115       }
3116     cpu_fprintf (f, "PC = %08x   ", env->pc);
3117     sr = env->sr;
3118     cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
3119                  (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
3120                  (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
3121     cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
3122 }
3123
3124 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, int pc_pos)
3125 {
3126     env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3127 }
This page took 0.197052 seconds and 4 git commands to generate.