xref: /openbmc/qemu/target/m68k/translate.c (revision 1ff7b531)
1 /*
2  *  m68k translation
3  *
4  *  Copyright (c) 2005-2007 CodeSourcery
5  *  Written by Paul Brook
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg-op.h"
26 #include "qemu/log.h"
27 #include "exec/cpu_ldst.h"
28 
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 
32 #include "trace-tcg.h"
33 #include "exec/log.h"
34 
35 //#define DEBUG_DISPATCH 1
36 
37 #define DEFO32(name, offset) static TCGv QREG_##name;
38 #define DEFO64(name, offset) static TCGv_i64 QREG_##name;
39 #include "qregs.def"
40 #undef DEFO32
41 #undef DEFO64
42 
43 static TCGv_i32 cpu_halted;
44 static TCGv_i32 cpu_exception_index;
45 
46 static TCGv_env cpu_env;
47 
48 static char cpu_reg_names[2 * 8 * 3 + 5 * 4];
49 static TCGv cpu_dregs[8];
50 static TCGv cpu_aregs[8];
51 static TCGv_i64 cpu_macc[4];
52 
53 #define REG(insn, pos)  (((insn) >> (pos)) & 7)
54 #define DREG(insn, pos) cpu_dregs[REG(insn, pos)]
55 #define AREG(insn, pos) get_areg(s, REG(insn, pos))
56 #define MACREG(acc)     cpu_macc[acc]
57 #define QREG_SP         get_areg(s, 7)
58 
59 static TCGv NULL_QREG;
60 #define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG))
61 /* Used to distinguish stores from bad addressing modes.  */
62 static TCGv store_dummy;
63 
64 #include "exec/gen-icount.h"
65 
66 void m68k_tcg_init(void)
67 {
68     char *p;
69     int i;
70 
71     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
72     tcg_ctx.tcg_env = cpu_env;
73 
74 #define DEFO32(name, offset) \
75     QREG_##name = tcg_global_mem_new_i32(cpu_env, \
76         offsetof(CPUM68KState, offset), #name);
77 #define DEFO64(name, offset) \
78     QREG_##name = tcg_global_mem_new_i64(cpu_env, \
79         offsetof(CPUM68KState, offset), #name);
80 #include "qregs.def"
81 #undef DEFO32
82 #undef DEFO64
83 
84     cpu_halted = tcg_global_mem_new_i32(cpu_env,
85                                         -offsetof(M68kCPU, env) +
86                                         offsetof(CPUState, halted), "HALTED");
87     cpu_exception_index = tcg_global_mem_new_i32(cpu_env,
88                                                  -offsetof(M68kCPU, env) +
89                                                  offsetof(CPUState, exception_index),
90                                                  "EXCEPTION");
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(cpu_env,
96                                           offsetof(CPUM68KState, dregs[i]), p);
97         p += 3;
98         sprintf(p, "A%d", i);
99         cpu_aregs[i] = tcg_global_mem_new(cpu_env,
100                                           offsetof(CPUM68KState, aregs[i]), p);
101         p += 3;
102     }
103     for (i = 0; i < 4; i++) {
104         sprintf(p, "ACC%d", i);
105         cpu_macc[i] = tcg_global_mem_new_i64(cpu_env,
106                                          offsetof(CPUM68KState, macc[i]), p);
107         p += 5;
108     }
109 
110     NULL_QREG = tcg_global_mem_new(cpu_env, -4, "NULL");
111     store_dummy = tcg_global_mem_new(cpu_env, -8, "NULL");
112 }
113 
114 /* internal defines */
115 typedef struct DisasContext {
116     CPUM68KState *env;
117     target_ulong insn_pc; /* Start of the current instruction.  */
118     target_ulong pc;
119     int is_jmp;
120     CCOp cc_op; /* Current CC operation */
121     int cc_op_synced;
122     int user;
123     struct TranslationBlock *tb;
124     int singlestep_enabled;
125     TCGv_i64 mactmp;
126     int done_mac;
127     int writeback_mask;
128     TCGv writeback[8];
129 } DisasContext;
130 
131 static TCGv get_areg(DisasContext *s, unsigned regno)
132 {
133     if (s->writeback_mask & (1 << regno)) {
134         return s->writeback[regno];
135     } else {
136         return cpu_aregs[regno];
137     }
138 }
139 
140 static void delay_set_areg(DisasContext *s, unsigned regno,
141                            TCGv val, bool give_temp)
142 {
143     if (s->writeback_mask & (1 << regno)) {
144         if (give_temp) {
145             tcg_temp_free(s->writeback[regno]);
146             s->writeback[regno] = val;
147         } else {
148             tcg_gen_mov_i32(s->writeback[regno], val);
149         }
150     } else {
151         s->writeback_mask |= 1 << regno;
152         if (give_temp) {
153             s->writeback[regno] = val;
154         } else {
155             TCGv tmp = tcg_temp_new();
156             s->writeback[regno] = tmp;
157             tcg_gen_mov_i32(tmp, val);
158         }
159     }
160 }
161 
162 static void do_writebacks(DisasContext *s)
163 {
164     unsigned mask = s->writeback_mask;
165     if (mask) {
166         s->writeback_mask = 0;
167         do {
168             unsigned regno = ctz32(mask);
169             tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]);
170             tcg_temp_free(s->writeback[regno]);
171             mask &= mask - 1;
172         } while (mask);
173     }
174 }
175 
176 #define DISAS_JUMP_NEXT 4
177 
178 #if defined(CONFIG_USER_ONLY)
179 #define IS_USER(s) 1
180 #else
181 #define IS_USER(s) s->user
182 #endif
183 
184 /* XXX: move that elsewhere */
185 /* ??? Fix exceptions.  */
186 static void *gen_throws_exception;
187 #define gen_last_qop NULL
188 
189 typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
190 
191 #ifdef DEBUG_DISPATCH
192 #define DISAS_INSN(name)                                                \
193     static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
194                                   uint16_t insn);                       \
195     static void disas_##name(CPUM68KState *env, DisasContext *s,        \
196                              uint16_t insn)                             \
197     {                                                                   \
198         qemu_log("Dispatch " #name "\n");                               \
199         real_disas_##name(env, s, insn);                                \
200     }                                                                   \
201     static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
202                                   uint16_t insn)
203 #else
204 #define DISAS_INSN(name)                                                \
205     static void disas_##name(CPUM68KState *env, DisasContext *s,        \
206                              uint16_t insn)
207 #endif
208 
209 static const uint8_t cc_op_live[CC_OP_NB] = {
210     [CC_OP_FLAGS] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X,
211     [CC_OP_ADDB ... CC_OP_ADDL] = CCF_X | CCF_N | CCF_V,
212     [CC_OP_SUBB ... CC_OP_SUBL] = CCF_X | CCF_N | CCF_V,
213     [CC_OP_CMPB ... CC_OP_CMPL] = CCF_X | CCF_N | CCF_V,
214     [CC_OP_LOGIC] = CCF_X | CCF_N
215 };
216 
217 static void set_cc_op(DisasContext *s, CCOp op)
218 {
219     CCOp old_op = s->cc_op;
220     int dead;
221 
222     if (old_op == op) {
223         return;
224     }
225     s->cc_op = op;
226     s->cc_op_synced = 0;
227 
228     /* Discard CC computation that will no longer be used.
229        Note that X and N are never dead.  */
230     dead = cc_op_live[old_op] & ~cc_op_live[op];
231     if (dead & CCF_C) {
232         tcg_gen_discard_i32(QREG_CC_C);
233     }
234     if (dead & CCF_Z) {
235         tcg_gen_discard_i32(QREG_CC_Z);
236     }
237     if (dead & CCF_V) {
238         tcg_gen_discard_i32(QREG_CC_V);
239     }
240 }
241 
242 /* Update the CPU env CC_OP state.  */
243 static void update_cc_op(DisasContext *s)
244 {
245     if (!s->cc_op_synced) {
246         s->cc_op_synced = 1;
247         tcg_gen_movi_i32(QREG_CC_OP, s->cc_op);
248     }
249 }
250 
251 /* Generate a jump to an immediate address.  */
252 static void gen_jmp_im(DisasContext *s, uint32_t dest)
253 {
254     update_cc_op(s);
255     tcg_gen_movi_i32(QREG_PC, dest);
256     s->is_jmp = DISAS_JUMP;
257 }
258 
259 /* Generate a jump to the address in qreg DEST.  */
260 static void gen_jmp(DisasContext *s, TCGv dest)
261 {
262     update_cc_op(s);
263     tcg_gen_mov_i32(QREG_PC, dest);
264     s->is_jmp = DISAS_JUMP;
265 }
266 
267 static void gen_raise_exception(int nr)
268 {
269     TCGv_i32 tmp = tcg_const_i32(nr);
270 
271     gen_helper_raise_exception(cpu_env, tmp);
272     tcg_temp_free_i32(tmp);
273 }
274 
275 static void gen_exception(DisasContext *s, uint32_t where, int nr)
276 {
277     update_cc_op(s);
278     gen_jmp_im(s, where);
279     gen_raise_exception(nr);
280 }
281 
282 static inline void gen_addr_fault(DisasContext *s)
283 {
284     gen_exception(s, s->insn_pc, EXCP_ADDRESS);
285 }
286 
287 /* Generate a load from the specified address.  Narrow values are
288    sign extended to full register width.  */
289 static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
290 {
291     TCGv tmp;
292     int index = IS_USER(s);
293     tmp = tcg_temp_new_i32();
294     switch(opsize) {
295     case OS_BYTE:
296         if (sign)
297             tcg_gen_qemu_ld8s(tmp, addr, index);
298         else
299             tcg_gen_qemu_ld8u(tmp, addr, index);
300         break;
301     case OS_WORD:
302         if (sign)
303             tcg_gen_qemu_ld16s(tmp, addr, index);
304         else
305             tcg_gen_qemu_ld16u(tmp, addr, index);
306         break;
307     case OS_LONG:
308         tcg_gen_qemu_ld32u(tmp, addr, index);
309         break;
310     default:
311         g_assert_not_reached();
312     }
313     gen_throws_exception = gen_last_qop;
314     return tmp;
315 }
316 
317 /* Generate a store.  */
318 static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
319 {
320     int index = IS_USER(s);
321     switch(opsize) {
322     case OS_BYTE:
323         tcg_gen_qemu_st8(val, addr, index);
324         break;
325     case OS_WORD:
326         tcg_gen_qemu_st16(val, addr, index);
327         break;
328     case OS_LONG:
329         tcg_gen_qemu_st32(val, addr, index);
330         break;
331     default:
332         g_assert_not_reached();
333     }
334     gen_throws_exception = gen_last_qop;
335 }
336 
337 typedef enum {
338     EA_STORE,
339     EA_LOADU,
340     EA_LOADS
341 } ea_what;
342 
343 /* Generate an unsigned load if VAL is 0 a signed load if val is -1,
344    otherwise generate a store.  */
345 static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
346                      ea_what what)
347 {
348     if (what == EA_STORE) {
349         gen_store(s, opsize, addr, val);
350         return store_dummy;
351     } else {
352         return gen_load(s, opsize, addr, what == EA_LOADS);
353     }
354 }
355 
356 /* Read a 16-bit immediate constant */
357 static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s)
358 {
359     uint16_t im;
360     im = cpu_lduw_code(env, s->pc);
361     s->pc += 2;
362     return im;
363 }
364 
365 /* Read an 8-bit immediate constant */
366 static inline uint8_t read_im8(CPUM68KState *env, DisasContext *s)
367 {
368     return read_im16(env, s);
369 }
370 
371 /* Read a 32-bit immediate constant.  */
372 static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s)
373 {
374     uint32_t im;
375     im = read_im16(env, s) << 16;
376     im |= 0xffff & read_im16(env, s);
377     return im;
378 }
379 
380 /* Read a 64-bit immediate constant.  */
381 static inline uint64_t read_im64(CPUM68KState *env, DisasContext *s)
382 {
383     uint64_t im;
384     im = (uint64_t)read_im32(env, s) << 32;
385     im |= (uint64_t)read_im32(env, s);
386     return im;
387 }
388 
389 /* Calculate and address index.  */
390 static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp)
391 {
392     TCGv add;
393     int scale;
394 
395     add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
396     if ((ext & 0x800) == 0) {
397         tcg_gen_ext16s_i32(tmp, add);
398         add = tmp;
399     }
400     scale = (ext >> 9) & 3;
401     if (scale != 0) {
402         tcg_gen_shli_i32(tmp, add, scale);
403         add = tmp;
404     }
405     return add;
406 }
407 
408 /* Handle a base + index + displacement effective addresss.
409    A NULL_QREG base means pc-relative.  */
410 static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
411 {
412     uint32_t offset;
413     uint16_t ext;
414     TCGv add;
415     TCGv tmp;
416     uint32_t bd, od;
417 
418     offset = s->pc;
419     ext = read_im16(env, s);
420 
421     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
422         return NULL_QREG;
423 
424     if (m68k_feature(s->env, M68K_FEATURE_M68000) &&
425         !m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) {
426         ext &= ~(3 << 9);
427     }
428 
429     if (ext & 0x100) {
430         /* full extension word format */
431         if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
432             return NULL_QREG;
433 
434         if ((ext & 0x30) > 0x10) {
435             /* base displacement */
436             if ((ext & 0x30) == 0x20) {
437                 bd = (int16_t)read_im16(env, s);
438             } else {
439                 bd = read_im32(env, s);
440             }
441         } else {
442             bd = 0;
443         }
444         tmp = tcg_temp_new();
445         if ((ext & 0x44) == 0) {
446             /* pre-index */
447             add = gen_addr_index(s, ext, tmp);
448         } else {
449             add = NULL_QREG;
450         }
451         if ((ext & 0x80) == 0) {
452             /* base not suppressed */
453             if (IS_NULL_QREG(base)) {
454                 base = tcg_const_i32(offset + bd);
455                 bd = 0;
456             }
457             if (!IS_NULL_QREG(add)) {
458                 tcg_gen_add_i32(tmp, add, base);
459                 add = tmp;
460             } else {
461                 add = base;
462             }
463         }
464         if (!IS_NULL_QREG(add)) {
465             if (bd != 0) {
466                 tcg_gen_addi_i32(tmp, add, bd);
467                 add = tmp;
468             }
469         } else {
470             add = tcg_const_i32(bd);
471         }
472         if ((ext & 3) != 0) {
473             /* memory indirect */
474             base = gen_load(s, OS_LONG, add, 0);
475             if ((ext & 0x44) == 4) {
476                 add = gen_addr_index(s, ext, tmp);
477                 tcg_gen_add_i32(tmp, add, base);
478                 add = tmp;
479             } else {
480                 add = base;
481             }
482             if ((ext & 3) > 1) {
483                 /* outer displacement */
484                 if ((ext & 3) == 2) {
485                     od = (int16_t)read_im16(env, s);
486                 } else {
487                     od = read_im32(env, s);
488                 }
489             } else {
490                 od = 0;
491             }
492             if (od != 0) {
493                 tcg_gen_addi_i32(tmp, add, od);
494                 add = tmp;
495             }
496         }
497     } else {
498         /* brief extension word format */
499         tmp = tcg_temp_new();
500         add = gen_addr_index(s, ext, tmp);
501         if (!IS_NULL_QREG(base)) {
502             tcg_gen_add_i32(tmp, add, base);
503             if ((int8_t)ext)
504                 tcg_gen_addi_i32(tmp, tmp, (int8_t)ext);
505         } else {
506             tcg_gen_addi_i32(tmp, add, offset + (int8_t)ext);
507         }
508         add = tmp;
509     }
510     return add;
511 }
512 
513 /* Sign or zero extend a value.  */
514 
515 static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign)
516 {
517     switch (opsize) {
518     case OS_BYTE:
519         if (sign) {
520             tcg_gen_ext8s_i32(res, val);
521         } else {
522             tcg_gen_ext8u_i32(res, val);
523         }
524         break;
525     case OS_WORD:
526         if (sign) {
527             tcg_gen_ext16s_i32(res, val);
528         } else {
529             tcg_gen_ext16u_i32(res, val);
530         }
531         break;
532     case OS_LONG:
533         tcg_gen_mov_i32(res, val);
534         break;
535     default:
536         g_assert_not_reached();
537     }
538 }
539 
540 /* Evaluate all the CC flags.  */
541 
542 static void gen_flush_flags(DisasContext *s)
543 {
544     TCGv t0, t1;
545 
546     switch (s->cc_op) {
547     case CC_OP_FLAGS:
548         return;
549 
550     case CC_OP_ADDB:
551     case CC_OP_ADDW:
552     case CC_OP_ADDL:
553         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
554         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
555         /* Compute signed overflow for addition.  */
556         t0 = tcg_temp_new();
557         t1 = tcg_temp_new();
558         tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V);
559         gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1);
560         tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
561         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
562         tcg_temp_free(t0);
563         tcg_gen_andc_i32(QREG_CC_V, t1, QREG_CC_V);
564         tcg_temp_free(t1);
565         break;
566 
567     case CC_OP_SUBB:
568     case CC_OP_SUBW:
569     case CC_OP_SUBL:
570         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
571         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
572         /* Compute signed overflow for subtraction.  */
573         t0 = tcg_temp_new();
574         t1 = tcg_temp_new();
575         tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V);
576         gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1);
577         tcg_gen_xor_i32(t1, QREG_CC_N, t0);
578         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
579         tcg_temp_free(t0);
580         tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1);
581         tcg_temp_free(t1);
582         break;
583 
584     case CC_OP_CMPB:
585     case CC_OP_CMPW:
586     case CC_OP_CMPL:
587         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V);
588         tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V);
589         gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1);
590         /* Compute signed overflow for subtraction.  */
591         t0 = tcg_temp_new();
592         tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N);
593         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, QREG_CC_N);
594         tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t0);
595         tcg_temp_free(t0);
596         tcg_gen_mov_i32(QREG_CC_N, QREG_CC_Z);
597         break;
598 
599     case CC_OP_LOGIC:
600         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
601         tcg_gen_movi_i32(QREG_CC_C, 0);
602         tcg_gen_movi_i32(QREG_CC_V, 0);
603         break;
604 
605     case CC_OP_DYNAMIC:
606         gen_helper_flush_flags(cpu_env, QREG_CC_OP);
607         s->cc_op_synced = 1;
608         break;
609 
610     default:
611         t0 = tcg_const_i32(s->cc_op);
612         gen_helper_flush_flags(cpu_env, t0);
613         tcg_temp_free(t0);
614         s->cc_op_synced = 1;
615         break;
616     }
617 
618     /* Note that flush_flags also assigned to env->cc_op.  */
619     s->cc_op = CC_OP_FLAGS;
620 }
621 
622 static inline TCGv gen_extend(TCGv val, int opsize, int sign)
623 {
624     TCGv tmp;
625 
626     if (opsize == OS_LONG) {
627         tmp = val;
628     } else {
629         tmp = tcg_temp_new();
630         gen_ext(tmp, val, opsize, sign);
631     }
632 
633     return tmp;
634 }
635 
636 static void gen_logic_cc(DisasContext *s, TCGv val, int opsize)
637 {
638     gen_ext(QREG_CC_N, val, opsize, 1);
639     set_cc_op(s, CC_OP_LOGIC);
640 }
641 
642 static void gen_update_cc_cmp(DisasContext *s, TCGv dest, TCGv src, int opsize)
643 {
644     tcg_gen_mov_i32(QREG_CC_N, dest);
645     tcg_gen_mov_i32(QREG_CC_V, src);
646     set_cc_op(s, CC_OP_CMPB + opsize);
647 }
648 
649 static void gen_update_cc_add(TCGv dest, TCGv src, int opsize)
650 {
651     gen_ext(QREG_CC_N, dest, opsize, 1);
652     tcg_gen_mov_i32(QREG_CC_V, src);
653 }
654 
655 static inline int opsize_bytes(int opsize)
656 {
657     switch (opsize) {
658     case OS_BYTE: return 1;
659     case OS_WORD: return 2;
660     case OS_LONG: return 4;
661     case OS_SINGLE: return 4;
662     case OS_DOUBLE: return 8;
663     case OS_EXTENDED: return 12;
664     case OS_PACKED: return 12;
665     default:
666         g_assert_not_reached();
667     }
668 }
669 
670 static inline int insn_opsize(int insn)
671 {
672     switch ((insn >> 6) & 3) {
673     case 0: return OS_BYTE;
674     case 1: return OS_WORD;
675     case 2: return OS_LONG;
676     default:
677         g_assert_not_reached();
678     }
679 }
680 
681 static inline int ext_opsize(int ext, int pos)
682 {
683     switch ((ext >> pos) & 7) {
684     case 0: return OS_LONG;
685     case 1: return OS_SINGLE;
686     case 2: return OS_EXTENDED;
687     case 3: return OS_PACKED;
688     case 4: return OS_WORD;
689     case 5: return OS_DOUBLE;
690     case 6: return OS_BYTE;
691     default:
692         g_assert_not_reached();
693     }
694 }
695 
696 /* Assign value to a register.  If the width is less than the register width
697    only the low part of the register is set.  */
698 static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
699 {
700     TCGv tmp;
701     switch (opsize) {
702     case OS_BYTE:
703         tcg_gen_andi_i32(reg, reg, 0xffffff00);
704         tmp = tcg_temp_new();
705         tcg_gen_ext8u_i32(tmp, val);
706         tcg_gen_or_i32(reg, reg, tmp);
707         tcg_temp_free(tmp);
708         break;
709     case OS_WORD:
710         tcg_gen_andi_i32(reg, reg, 0xffff0000);
711         tmp = tcg_temp_new();
712         tcg_gen_ext16u_i32(tmp, val);
713         tcg_gen_or_i32(reg, reg, tmp);
714         tcg_temp_free(tmp);
715         break;
716     case OS_LONG:
717     case OS_SINGLE:
718         tcg_gen_mov_i32(reg, val);
719         break;
720     default:
721         g_assert_not_reached();
722     }
723 }
724 
725 /* Generate code for an "effective address".  Does not adjust the base
726    register for autoincrement addressing modes.  */
727 static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
728                          int mode, int reg0, int opsize)
729 {
730     TCGv reg;
731     TCGv tmp;
732     uint16_t ext;
733     uint32_t offset;
734 
735     switch (mode) {
736     case 0: /* Data register direct.  */
737     case 1: /* Address register direct.  */
738         return NULL_QREG;
739     case 3: /* Indirect postincrement.  */
740         if (opsize == OS_UNSIZED) {
741             return NULL_QREG;
742         }
743         /* fallthru */
744     case 2: /* Indirect register */
745         return get_areg(s, reg0);
746     case 4: /* Indirect predecrememnt.  */
747         if (opsize == OS_UNSIZED) {
748             return NULL_QREG;
749         }
750         reg = get_areg(s, reg0);
751         tmp = tcg_temp_new();
752         if (reg0 == 7 && opsize == OS_BYTE &&
753             m68k_feature(s->env, M68K_FEATURE_M68000)) {
754             tcg_gen_subi_i32(tmp, reg, 2);
755         } else {
756             tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
757         }
758         return tmp;
759     case 5: /* Indirect displacement.  */
760         reg = get_areg(s, reg0);
761         tmp = tcg_temp_new();
762         ext = read_im16(env, s);
763         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
764         return tmp;
765     case 6: /* Indirect index + displacement.  */
766         reg = get_areg(s, reg0);
767         return gen_lea_indexed(env, s, reg);
768     case 7: /* Other */
769         switch (reg0) {
770         case 0: /* Absolute short.  */
771             offset = (int16_t)read_im16(env, s);
772             return tcg_const_i32(offset);
773         case 1: /* Absolute long.  */
774             offset = read_im32(env, s);
775             return tcg_const_i32(offset);
776         case 2: /* pc displacement  */
777             offset = s->pc;
778             offset += (int16_t)read_im16(env, s);
779             return tcg_const_i32(offset);
780         case 3: /* pc index+displacement.  */
781             return gen_lea_indexed(env, s, NULL_QREG);
782         case 4: /* Immediate.  */
783         default:
784             return NULL_QREG;
785         }
786     }
787     /* Should never happen.  */
788     return NULL_QREG;
789 }
790 
791 static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
792                     int opsize)
793 {
794     int mode = extract32(insn, 3, 3);
795     int reg0 = REG(insn, 0);
796     return gen_lea_mode(env, s, mode, reg0, opsize);
797 }
798 
799 /* Generate code to load/store a value from/into an EA.  If WHAT > 0 this is
800    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
801    ADDRP is non-null for readwrite operands.  */
802 static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0,
803                         int opsize, TCGv val, TCGv *addrp, ea_what what)
804 {
805     TCGv reg, tmp, result;
806     int32_t offset;
807 
808     switch (mode) {
809     case 0: /* Data register direct.  */
810         reg = cpu_dregs[reg0];
811         if (what == EA_STORE) {
812             gen_partset_reg(opsize, reg, val);
813             return store_dummy;
814         } else {
815             return gen_extend(reg, opsize, what == EA_LOADS);
816         }
817     case 1: /* Address register direct.  */
818         reg = get_areg(s, reg0);
819         if (what == EA_STORE) {
820             tcg_gen_mov_i32(reg, val);
821             return store_dummy;
822         } else {
823             return gen_extend(reg, opsize, what == EA_LOADS);
824         }
825     case 2: /* Indirect register */
826         reg = get_areg(s, reg0);
827         return gen_ldst(s, opsize, reg, val, what);
828     case 3: /* Indirect postincrement.  */
829         reg = get_areg(s, reg0);
830         result = gen_ldst(s, opsize, reg, val, what);
831         if (what == EA_STORE || !addrp) {
832             TCGv tmp = tcg_temp_new();
833             if (reg0 == 7 && opsize == OS_BYTE &&
834                 m68k_feature(s->env, M68K_FEATURE_M68000)) {
835                 tcg_gen_addi_i32(tmp, reg, 2);
836             } else {
837                 tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize));
838             }
839             delay_set_areg(s, reg0, tmp, true);
840         }
841         return result;
842     case 4: /* Indirect predecrememnt.  */
843         if (addrp && what == EA_STORE) {
844             tmp = *addrp;
845         } else {
846             tmp = gen_lea_mode(env, s, mode, reg0, opsize);
847             if (IS_NULL_QREG(tmp)) {
848                 return tmp;
849             }
850             if (addrp) {
851                 *addrp = tmp;
852             }
853         }
854         result = gen_ldst(s, opsize, tmp, val, what);
855         if (what == EA_STORE || !addrp) {
856             delay_set_areg(s, reg0, tmp, false);
857         }
858         return result;
859     case 5: /* Indirect displacement.  */
860     case 6: /* Indirect index + displacement.  */
861     do_indirect:
862         if (addrp && what == EA_STORE) {
863             tmp = *addrp;
864         } else {
865             tmp = gen_lea_mode(env, s, mode, reg0, opsize);
866             if (IS_NULL_QREG(tmp)) {
867                 return tmp;
868             }
869             if (addrp) {
870                 *addrp = tmp;
871             }
872         }
873         return gen_ldst(s, opsize, tmp, val, what);
874     case 7: /* Other */
875         switch (reg0) {
876         case 0: /* Absolute short.  */
877         case 1: /* Absolute long.  */
878         case 2: /* pc displacement  */
879         case 3: /* pc index+displacement.  */
880             goto do_indirect;
881         case 4: /* Immediate.  */
882             /* Sign extend values for consistency.  */
883             switch (opsize) {
884             case OS_BYTE:
885                 if (what == EA_LOADS) {
886                     offset = (int8_t)read_im8(env, s);
887                 } else {
888                     offset = read_im8(env, s);
889                 }
890                 break;
891             case OS_WORD:
892                 if (what == EA_LOADS) {
893                     offset = (int16_t)read_im16(env, s);
894                 } else {
895                     offset = read_im16(env, s);
896                 }
897                 break;
898             case OS_LONG:
899                 offset = read_im32(env, s);
900                 break;
901             default:
902                 g_assert_not_reached();
903             }
904             return tcg_const_i32(offset);
905         default:
906             return NULL_QREG;
907         }
908     }
909     /* Should never happen.  */
910     return NULL_QREG;
911 }
912 
913 static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
914                    int opsize, TCGv val, TCGv *addrp, ea_what what)
915 {
916     int mode = extract32(insn, 3, 3);
917     int reg0 = REG(insn, 0);
918     return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what);
919 }
920 
921 static TCGv_ptr gen_fp_ptr(int freg)
922 {
923     TCGv_ptr fp = tcg_temp_new_ptr();
924     tcg_gen_addi_ptr(fp, cpu_env, offsetof(CPUM68KState, fregs[freg]));
925     return fp;
926 }
927 
928 static TCGv_ptr gen_fp_result_ptr(void)
929 {
930     TCGv_ptr fp = tcg_temp_new_ptr();
931     tcg_gen_addi_ptr(fp, cpu_env, offsetof(CPUM68KState, fp_result));
932     return fp;
933 }
934 
935 static void gen_fp_move(TCGv_ptr dest, TCGv_ptr src)
936 {
937     TCGv t32;
938     TCGv_i64 t64;
939 
940     t32 = tcg_temp_new();
941     tcg_gen_ld16u_i32(t32, src, offsetof(FPReg, l.upper));
942     tcg_gen_st16_i32(t32, dest, offsetof(FPReg, l.upper));
943     tcg_temp_free(t32);
944 
945     t64 = tcg_temp_new_i64();
946     tcg_gen_ld_i64(t64, src, offsetof(FPReg, l.lower));
947     tcg_gen_st_i64(t64, dest, offsetof(FPReg, l.lower));
948     tcg_temp_free_i64(t64);
949 }
950 
951 static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp)
952 {
953     TCGv tmp;
954     TCGv_i64 t64;
955     int index = IS_USER(s);
956 
957     t64 = tcg_temp_new_i64();
958     tmp = tcg_temp_new();
959     switch (opsize) {
960     case OS_BYTE:
961         tcg_gen_qemu_ld8s(tmp, addr, index);
962         gen_helper_exts32(cpu_env, fp, tmp);
963         break;
964     case OS_WORD:
965         tcg_gen_qemu_ld16s(tmp, addr, index);
966         gen_helper_exts32(cpu_env, fp, tmp);
967         break;
968     case OS_LONG:
969         tcg_gen_qemu_ld32u(tmp, addr, index);
970         gen_helper_exts32(cpu_env, fp, tmp);
971         break;
972     case OS_SINGLE:
973         tcg_gen_qemu_ld32u(tmp, addr, index);
974         gen_helper_extf32(cpu_env, fp, tmp);
975         break;
976     case OS_DOUBLE:
977         tcg_gen_qemu_ld64(t64, addr, index);
978         gen_helper_extf64(cpu_env, fp, t64);
979         tcg_temp_free_i64(t64);
980         break;
981     case OS_EXTENDED:
982         if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
983             gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
984             break;
985         }
986         tcg_gen_qemu_ld32u(tmp, addr, index);
987         tcg_gen_shri_i32(tmp, tmp, 16);
988         tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
989         tcg_gen_addi_i32(tmp, addr, 4);
990         tcg_gen_qemu_ld64(t64, tmp, index);
991         tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
992         break;
993     case OS_PACKED:
994         /* unimplemented data type on 68040/ColdFire
995          * FIXME if needed for another FPU
996          */
997         gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
998         break;
999     default:
1000         g_assert_not_reached();
1001     }
1002     tcg_temp_free(tmp);
1003     tcg_temp_free_i64(t64);
1004     gen_throws_exception = gen_last_qop;
1005 }
1006 
1007 static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp)
1008 {
1009     TCGv tmp;
1010     TCGv_i64 t64;
1011     int index = IS_USER(s);
1012 
1013     t64 = tcg_temp_new_i64();
1014     tmp = tcg_temp_new();
1015     switch (opsize) {
1016     case OS_BYTE:
1017         gen_helper_reds32(tmp, cpu_env, fp);
1018         tcg_gen_qemu_st8(tmp, addr, index);
1019         break;
1020     case OS_WORD:
1021         gen_helper_reds32(tmp, cpu_env, fp);
1022         tcg_gen_qemu_st16(tmp, addr, index);
1023         break;
1024     case OS_LONG:
1025         gen_helper_reds32(tmp, cpu_env, fp);
1026         tcg_gen_qemu_st32(tmp, addr, index);
1027         break;
1028     case OS_SINGLE:
1029         gen_helper_redf32(tmp, cpu_env, fp);
1030         tcg_gen_qemu_st32(tmp, addr, index);
1031         break;
1032     case OS_DOUBLE:
1033         gen_helper_redf64(t64, cpu_env, fp);
1034         tcg_gen_qemu_st64(t64, addr, index);
1035         break;
1036     case OS_EXTENDED:
1037         if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
1038             gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
1039             break;
1040         }
1041         tcg_gen_ld16u_i32(tmp, fp, offsetof(FPReg, l.upper));
1042         tcg_gen_shli_i32(tmp, tmp, 16);
1043         tcg_gen_qemu_st32(tmp, addr, index);
1044         tcg_gen_addi_i32(tmp, addr, 4);
1045         tcg_gen_ld_i64(t64, fp, offsetof(FPReg, l.lower));
1046         tcg_gen_qemu_st64(t64, tmp, index);
1047         break;
1048     case OS_PACKED:
1049         /* unimplemented data type on 68040/ColdFire
1050          * FIXME if needed for another FPU
1051          */
1052         gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
1053         break;
1054     default:
1055         g_assert_not_reached();
1056     }
1057     tcg_temp_free(tmp);
1058     tcg_temp_free_i64(t64);
1059     gen_throws_exception = gen_last_qop;
1060 }
1061 
1062 static void gen_ldst_fp(DisasContext *s, int opsize, TCGv addr,
1063                         TCGv_ptr fp, ea_what what)
1064 {
1065     if (what == EA_STORE) {
1066         gen_store_fp(s, opsize, addr, fp);
1067     } else {
1068         gen_load_fp(s, opsize, addr, fp);
1069     }
1070 }
1071 
1072 static int gen_ea_mode_fp(CPUM68KState *env, DisasContext *s, int mode,
1073                           int reg0, int opsize, TCGv_ptr fp, ea_what what)
1074 {
1075     TCGv reg, addr, tmp;
1076     TCGv_i64 t64;
1077 
1078     switch (mode) {
1079     case 0: /* Data register direct.  */
1080         reg = cpu_dregs[reg0];
1081         if (what == EA_STORE) {
1082             switch (opsize) {
1083             case OS_BYTE:
1084             case OS_WORD:
1085             case OS_LONG:
1086                 gen_helper_reds32(reg, cpu_env, fp);
1087                 break;
1088             case OS_SINGLE:
1089                 gen_helper_redf32(reg, cpu_env, fp);
1090                 break;
1091             default:
1092                 g_assert_not_reached();
1093             }
1094         } else {
1095             tmp = tcg_temp_new();
1096             switch (opsize) {
1097             case OS_BYTE:
1098                 tcg_gen_ext8s_i32(tmp, reg);
1099                 gen_helper_exts32(cpu_env, fp, tmp);
1100                 break;
1101             case OS_WORD:
1102                 tcg_gen_ext16s_i32(tmp, reg);
1103                 gen_helper_exts32(cpu_env, fp, tmp);
1104                 break;
1105             case OS_LONG:
1106                 gen_helper_exts32(cpu_env, fp, reg);
1107                 break;
1108             case OS_SINGLE:
1109                 gen_helper_extf32(cpu_env, fp, reg);
1110                 break;
1111             default:
1112                 g_assert_not_reached();
1113             }
1114             tcg_temp_free(tmp);
1115         }
1116         return 0;
1117     case 1: /* Address register direct.  */
1118         return -1;
1119     case 2: /* Indirect register */
1120         addr = get_areg(s, reg0);
1121         gen_ldst_fp(s, opsize, addr, fp, what);
1122         return 0;
1123     case 3: /* Indirect postincrement.  */
1124         addr = cpu_aregs[reg0];
1125         gen_ldst_fp(s, opsize, addr, fp, what);
1126         tcg_gen_addi_i32(addr, addr, opsize_bytes(opsize));
1127         return 0;
1128     case 4: /* Indirect predecrememnt.  */
1129         addr = gen_lea_mode(env, s, mode, reg0, opsize);
1130         if (IS_NULL_QREG(addr)) {
1131             return -1;
1132         }
1133         gen_ldst_fp(s, opsize, addr, fp, what);
1134         tcg_gen_mov_i32(cpu_aregs[reg0], addr);
1135         return 0;
1136     case 5: /* Indirect displacement.  */
1137     case 6: /* Indirect index + displacement.  */
1138     do_indirect:
1139         addr = gen_lea_mode(env, s, mode, reg0, opsize);
1140         if (IS_NULL_QREG(addr)) {
1141             return -1;
1142         }
1143         gen_ldst_fp(s, opsize, addr, fp, what);
1144         return 0;
1145     case 7: /* Other */
1146         switch (reg0) {
1147         case 0: /* Absolute short.  */
1148         case 1: /* Absolute long.  */
1149         case 2: /* pc displacement  */
1150         case 3: /* pc index+displacement.  */
1151             goto do_indirect;
1152         case 4: /* Immediate.  */
1153             if (what == EA_STORE) {
1154                 return -1;
1155             }
1156             switch (opsize) {
1157             case OS_BYTE:
1158                 tmp = tcg_const_i32((int8_t)read_im8(env, s));
1159                 gen_helper_exts32(cpu_env, fp, tmp);
1160                 tcg_temp_free(tmp);
1161                 break;
1162             case OS_WORD:
1163                 tmp = tcg_const_i32((int16_t)read_im16(env, s));
1164                 gen_helper_exts32(cpu_env, fp, tmp);
1165                 tcg_temp_free(tmp);
1166                 break;
1167             case OS_LONG:
1168                 tmp = tcg_const_i32(read_im32(env, s));
1169                 gen_helper_exts32(cpu_env, fp, tmp);
1170                 tcg_temp_free(tmp);
1171                 break;
1172             case OS_SINGLE:
1173                 tmp = tcg_const_i32(read_im32(env, s));
1174                 gen_helper_extf32(cpu_env, fp, tmp);
1175                 tcg_temp_free(tmp);
1176                 break;
1177             case OS_DOUBLE:
1178                 t64 = tcg_const_i64(read_im64(env, s));
1179                 gen_helper_extf64(cpu_env, fp, t64);
1180                 tcg_temp_free_i64(t64);
1181                 break;
1182             case OS_EXTENDED:
1183                 if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
1184                     gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
1185                     break;
1186                 }
1187                 tmp = tcg_const_i32(read_im32(env, s) >> 16);
1188                 tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
1189                 tcg_temp_free(tmp);
1190                 t64 = tcg_const_i64(read_im64(env, s));
1191                 tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
1192                 tcg_temp_free_i64(t64);
1193                 break;
1194             case OS_PACKED:
1195                 /* unimplemented data type on 68040/ColdFire
1196                  * FIXME if needed for another FPU
1197                  */
1198                 gen_exception(s, s->insn_pc, EXCP_FP_UNIMP);
1199                 break;
1200             default:
1201                 g_assert_not_reached();
1202             }
1203             return 0;
1204         default:
1205             return -1;
1206         }
1207     }
1208     return -1;
1209 }
1210 
1211 static int gen_ea_fp(CPUM68KState *env, DisasContext *s, uint16_t insn,
1212                        int opsize, TCGv_ptr fp, ea_what what)
1213 {
1214     int mode = extract32(insn, 3, 3);
1215     int reg0 = REG(insn, 0);
1216     return gen_ea_mode_fp(env, s, mode, reg0, opsize, fp, what);
1217 }
1218 
1219 typedef struct {
1220     TCGCond tcond;
1221     bool g1;
1222     bool g2;
1223     TCGv v1;
1224     TCGv v2;
1225 } DisasCompare;
1226 
1227 static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
1228 {
1229     TCGv tmp, tmp2;
1230     TCGCond tcond;
1231     CCOp op = s->cc_op;
1232 
1233     /* The CC_OP_CMP form can handle most normal comparisons directly.  */
1234     if (op == CC_OP_CMPB || op == CC_OP_CMPW || op == CC_OP_CMPL) {
1235         c->g1 = c->g2 = 1;
1236         c->v1 = QREG_CC_N;
1237         c->v2 = QREG_CC_V;
1238         switch (cond) {
1239         case 2: /* HI */
1240         case 3: /* LS */
1241             tcond = TCG_COND_LEU;
1242             goto done;
1243         case 4: /* CC */
1244         case 5: /* CS */
1245             tcond = TCG_COND_LTU;
1246             goto done;
1247         case 6: /* NE */
1248         case 7: /* EQ */
1249             tcond = TCG_COND_EQ;
1250             goto done;
1251         case 10: /* PL */
1252         case 11: /* MI */
1253             c->g1 = c->g2 = 0;
1254             c->v2 = tcg_const_i32(0);
1255             c->v1 = tmp = tcg_temp_new();
1256             tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V);
1257             gen_ext(tmp, tmp, op - CC_OP_CMPB, 1);
1258             /* fallthru */
1259         case 12: /* GE */
1260         case 13: /* LT */
1261             tcond = TCG_COND_LT;
1262             goto done;
1263         case 14: /* GT */
1264         case 15: /* LE */
1265             tcond = TCG_COND_LE;
1266             goto done;
1267         }
1268     }
1269 
1270     c->g1 = 1;
1271     c->g2 = 0;
1272     c->v2 = tcg_const_i32(0);
1273 
1274     switch (cond) {
1275     case 0: /* T */
1276     case 1: /* F */
1277         c->v1 = c->v2;
1278         tcond = TCG_COND_NEVER;
1279         goto done;
1280     case 14: /* GT (!(Z || (N ^ V))) */
1281     case 15: /* LE (Z || (N ^ V)) */
1282         /* Logic operations clear V, which simplifies LE to (Z || N),
1283            and since Z and N are co-located, this becomes a normal
1284            comparison vs N.  */
1285         if (op == CC_OP_LOGIC) {
1286             c->v1 = QREG_CC_N;
1287             tcond = TCG_COND_LE;
1288             goto done;
1289         }
1290         break;
1291     case 12: /* GE (!(N ^ V)) */
1292     case 13: /* LT (N ^ V) */
1293         /* Logic operations clear V, which simplifies this to N.  */
1294         if (op != CC_OP_LOGIC) {
1295             break;
1296         }
1297         /* fallthru */
1298     case 10: /* PL (!N) */
1299     case 11: /* MI (N) */
1300         /* Several cases represent N normally.  */
1301         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
1302             op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
1303             op == CC_OP_LOGIC) {
1304             c->v1 = QREG_CC_N;
1305             tcond = TCG_COND_LT;
1306             goto done;
1307         }
1308         break;
1309     case 6: /* NE (!Z) */
1310     case 7: /* EQ (Z) */
1311         /* Some cases fold Z into N.  */
1312         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
1313             op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
1314             op == CC_OP_LOGIC) {
1315             tcond = TCG_COND_EQ;
1316             c->v1 = QREG_CC_N;
1317             goto done;
1318         }
1319         break;
1320     case 4: /* CC (!C) */
1321     case 5: /* CS (C) */
1322         /* Some cases fold C into X.  */
1323         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
1324             op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL) {
1325             tcond = TCG_COND_NE;
1326             c->v1 = QREG_CC_X;
1327             goto done;
1328         }
1329         /* fallthru */
1330     case 8: /* VC (!V) */
1331     case 9: /* VS (V) */
1332         /* Logic operations clear V and C.  */
1333         if (op == CC_OP_LOGIC) {
1334             tcond = TCG_COND_NEVER;
1335             c->v1 = c->v2;
1336             goto done;
1337         }
1338         break;
1339     }
1340 
1341     /* Otherwise, flush flag state to CC_OP_FLAGS.  */
1342     gen_flush_flags(s);
1343 
1344     switch (cond) {
1345     case 0: /* T */
1346     case 1: /* F */
1347     default:
1348         /* Invalid, or handled above.  */
1349         abort();
1350     case 2: /* HI (!C && !Z) -> !(C || Z)*/
1351     case 3: /* LS (C || Z) */
1352         c->v1 = tmp = tcg_temp_new();
1353         c->g1 = 0;
1354         tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
1355         tcg_gen_or_i32(tmp, tmp, QREG_CC_C);
1356         tcond = TCG_COND_NE;
1357         break;
1358     case 4: /* CC (!C) */
1359     case 5: /* CS (C) */
1360         c->v1 = QREG_CC_C;
1361         tcond = TCG_COND_NE;
1362         break;
1363     case 6: /* NE (!Z) */
1364     case 7: /* EQ (Z) */
1365         c->v1 = QREG_CC_Z;
1366         tcond = TCG_COND_EQ;
1367         break;
1368     case 8: /* VC (!V) */
1369     case 9: /* VS (V) */
1370         c->v1 = QREG_CC_V;
1371         tcond = TCG_COND_LT;
1372         break;
1373     case 10: /* PL (!N) */
1374     case 11: /* MI (N) */
1375         c->v1 = QREG_CC_N;
1376         tcond = TCG_COND_LT;
1377         break;
1378     case 12: /* GE (!(N ^ V)) */
1379     case 13: /* LT (N ^ V) */
1380         c->v1 = tmp = tcg_temp_new();
1381         c->g1 = 0;
1382         tcg_gen_xor_i32(tmp, QREG_CC_N, QREG_CC_V);
1383         tcond = TCG_COND_LT;
1384         break;
1385     case 14: /* GT (!(Z || (N ^ V))) */
1386     case 15: /* LE (Z || (N ^ V)) */
1387         c->v1 = tmp = tcg_temp_new();
1388         c->g1 = 0;
1389         tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
1390         tcg_gen_neg_i32(tmp, tmp);
1391         tmp2 = tcg_temp_new();
1392         tcg_gen_xor_i32(tmp2, QREG_CC_N, QREG_CC_V);
1393         tcg_gen_or_i32(tmp, tmp, tmp2);
1394         tcg_temp_free(tmp2);
1395         tcond = TCG_COND_LT;
1396         break;
1397     }
1398 
1399  done:
1400     if ((cond & 1) == 0) {
1401         tcond = tcg_invert_cond(tcond);
1402     }
1403     c->tcond = tcond;
1404 }
1405 
1406 static void free_cond(DisasCompare *c)
1407 {
1408     if (!c->g1) {
1409         tcg_temp_free(c->v1);
1410     }
1411     if (!c->g2) {
1412         tcg_temp_free(c->v2);
1413     }
1414 }
1415 
1416 static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
1417 {
1418   DisasCompare c;
1419 
1420   gen_cc_cond(&c, s, cond);
1421   update_cc_op(s);
1422   tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
1423   free_cond(&c);
1424 }
1425 
1426 /* Force a TB lookup after an instruction that changes the CPU state.  */
1427 static void gen_lookup_tb(DisasContext *s)
1428 {
1429     update_cc_op(s);
1430     tcg_gen_movi_i32(QREG_PC, s->pc);
1431     s->is_jmp = DISAS_UPDATE;
1432 }
1433 
1434 #define SRC_EA(env, result, opsize, op_sign, addrp) do {                \
1435         result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp,         \
1436                         op_sign ? EA_LOADS : EA_LOADU);                 \
1437         if (IS_NULL_QREG(result)) {                                     \
1438             gen_addr_fault(s);                                          \
1439             return;                                                     \
1440         }                                                               \
1441     } while (0)
1442 
1443 #define DEST_EA(env, insn, opsize, val, addrp) do {                     \
1444         TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \
1445         if (IS_NULL_QREG(ea_result)) {                                  \
1446             gen_addr_fault(s);                                          \
1447             return;                                                     \
1448         }                                                               \
1449     } while (0)
1450 
1451 static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
1452 {
1453 #ifndef CONFIG_USER_ONLY
1454     return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
1455            (s->insn_pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
1456 #else
1457     return true;
1458 #endif
1459 }
1460 
1461 /* Generate a jump to an immediate address.  */
1462 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
1463 {
1464     if (unlikely(s->singlestep_enabled)) {
1465         gen_exception(s, dest, EXCP_DEBUG);
1466     } else if (use_goto_tb(s, dest)) {
1467         tcg_gen_goto_tb(n);
1468         tcg_gen_movi_i32(QREG_PC, dest);
1469         tcg_gen_exit_tb((uintptr_t)s->tb + n);
1470     } else {
1471         gen_jmp_im(s, dest);
1472         tcg_gen_exit_tb(0);
1473     }
1474     s->is_jmp = DISAS_TB_JUMP;
1475 }
1476 
1477 DISAS_INSN(scc)
1478 {
1479     DisasCompare c;
1480     int cond;
1481     TCGv tmp;
1482 
1483     cond = (insn >> 8) & 0xf;
1484     gen_cc_cond(&c, s, cond);
1485 
1486     tmp = tcg_temp_new();
1487     tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
1488     free_cond(&c);
1489 
1490     tcg_gen_neg_i32(tmp, tmp);
1491     DEST_EA(env, insn, OS_BYTE, tmp, NULL);
1492     tcg_temp_free(tmp);
1493 }
1494 
1495 DISAS_INSN(dbcc)
1496 {
1497     TCGLabel *l1;
1498     TCGv reg;
1499     TCGv tmp;
1500     int16_t offset;
1501     uint32_t base;
1502 
1503     reg = DREG(insn, 0);
1504     base = s->pc;
1505     offset = (int16_t)read_im16(env, s);
1506     l1 = gen_new_label();
1507     gen_jmpcc(s, (insn >> 8) & 0xf, l1);
1508 
1509     tmp = tcg_temp_new();
1510     tcg_gen_ext16s_i32(tmp, reg);
1511     tcg_gen_addi_i32(tmp, tmp, -1);
1512     gen_partset_reg(OS_WORD, reg, tmp);
1513     tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, -1, l1);
1514     gen_jmp_tb(s, 1, base + offset);
1515     gen_set_label(l1);
1516     gen_jmp_tb(s, 0, s->pc);
1517 }
1518 
1519 DISAS_INSN(undef_mac)
1520 {
1521     gen_exception(s, s->pc - 2, EXCP_LINEA);
1522 }
1523 
1524 DISAS_INSN(undef_fpu)
1525 {
1526     gen_exception(s, s->pc - 2, EXCP_LINEF);
1527 }
1528 
1529 DISAS_INSN(undef)
1530 {
1531     /* ??? This is both instructions that are as yet unimplemented
1532        for the 680x0 series, as well as those that are implemented
1533        but actually illegal for CPU32 or pre-68020.  */
1534     qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x",
1535                   insn, s->pc - 2);
1536     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
1537 }
1538 
1539 DISAS_INSN(mulw)
1540 {
1541     TCGv reg;
1542     TCGv tmp;
1543     TCGv src;
1544     int sign;
1545 
1546     sign = (insn & 0x100) != 0;
1547     reg = DREG(insn, 9);
1548     tmp = tcg_temp_new();
1549     if (sign)
1550         tcg_gen_ext16s_i32(tmp, reg);
1551     else
1552         tcg_gen_ext16u_i32(tmp, reg);
1553     SRC_EA(env, src, OS_WORD, sign, NULL);
1554     tcg_gen_mul_i32(tmp, tmp, src);
1555     tcg_gen_mov_i32(reg, tmp);
1556     gen_logic_cc(s, tmp, OS_LONG);
1557     tcg_temp_free(tmp);
1558 }
1559 
1560 DISAS_INSN(divw)
1561 {
1562     int sign;
1563     TCGv src;
1564     TCGv destr;
1565 
1566     /* divX.w <EA>,Dn    32/16 -> 16r:16q */
1567 
1568     sign = (insn & 0x100) != 0;
1569 
1570     /* dest.l / src.w */
1571 
1572     SRC_EA(env, src, OS_WORD, sign, NULL);
1573     destr = tcg_const_i32(REG(insn, 9));
1574     if (sign) {
1575         gen_helper_divsw(cpu_env, destr, src);
1576     } else {
1577         gen_helper_divuw(cpu_env, destr, src);
1578     }
1579     tcg_temp_free(destr);
1580 
1581     set_cc_op(s, CC_OP_FLAGS);
1582 }
1583 
1584 DISAS_INSN(divl)
1585 {
1586     TCGv num, reg, den;
1587     int sign;
1588     uint16_t ext;
1589 
1590     ext = read_im16(env, s);
1591 
1592     sign = (ext & 0x0800) != 0;
1593 
1594     if (ext & 0x400) {
1595         if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
1596             gen_exception(s, s->insn_pc, EXCP_ILLEGAL);
1597             return;
1598         }
1599 
1600         /* divX.l <EA>, Dr:Dq    64/32 -> 32r:32q */
1601 
1602         SRC_EA(env, den, OS_LONG, 0, NULL);
1603         num = tcg_const_i32(REG(ext, 12));
1604         reg = tcg_const_i32(REG(ext, 0));
1605         if (sign) {
1606             gen_helper_divsll(cpu_env, num, reg, den);
1607         } else {
1608             gen_helper_divull(cpu_env, num, reg, den);
1609         }
1610         tcg_temp_free(reg);
1611         tcg_temp_free(num);
1612         set_cc_op(s, CC_OP_FLAGS);
1613         return;
1614     }
1615 
1616     /* divX.l <EA>, Dq        32/32 -> 32q     */
1617     /* divXl.l <EA>, Dr:Dq    32/32 -> 32r:32q */
1618 
1619     SRC_EA(env, den, OS_LONG, 0, NULL);
1620     num = tcg_const_i32(REG(ext, 12));
1621     reg = tcg_const_i32(REG(ext, 0));
1622     if (sign) {
1623         gen_helper_divsl(cpu_env, num, reg, den);
1624     } else {
1625         gen_helper_divul(cpu_env, num, reg, den);
1626     }
1627     tcg_temp_free(reg);
1628     tcg_temp_free(num);
1629 
1630     set_cc_op(s, CC_OP_FLAGS);
1631 }
1632 
1633 static void bcd_add(TCGv dest, TCGv src)
1634 {
1635     TCGv t0, t1;
1636 
1637     /*  dest10 = dest10 + src10 + X
1638      *
1639      *        t1 = src
1640      *        t2 = t1 + 0x066
1641      *        t3 = t2 + dest + X
1642      *        t4 = t2 ^ dest
1643      *        t5 = t3 ^ t4
1644      *        t6 = ~t5 & 0x110
1645      *        t7 = (t6 >> 2) | (t6 >> 3)
1646      *        return t3 - t7
1647      */
1648 
1649     /* t1 = (src + 0x066) + dest + X
1650      *    = result with some possible exceding 0x6
1651      */
1652 
1653     t0 = tcg_const_i32(0x066);
1654     tcg_gen_add_i32(t0, t0, src);
1655 
1656     t1 = tcg_temp_new();
1657     tcg_gen_add_i32(t1, t0, dest);
1658     tcg_gen_add_i32(t1, t1, QREG_CC_X);
1659 
1660     /* we will remove exceding 0x6 where there is no carry */
1661 
1662     /* t0 = (src + 0x0066) ^ dest
1663      *    = t1 without carries
1664      */
1665 
1666     tcg_gen_xor_i32(t0, t0, dest);
1667 
1668     /* extract the carries
1669      * t0 = t0 ^ t1
1670      *    = only the carries
1671      */
1672 
1673     tcg_gen_xor_i32(t0, t0, t1);
1674 
1675     /* generate 0x1 where there is no carry
1676      * and for each 0x10, generate a 0x6
1677      */
1678 
1679     tcg_gen_shri_i32(t0, t0, 3);
1680     tcg_gen_not_i32(t0, t0);
1681     tcg_gen_andi_i32(t0, t0, 0x22);
1682     tcg_gen_add_i32(dest, t0, t0);
1683     tcg_gen_add_i32(dest, dest, t0);
1684     tcg_temp_free(t0);
1685 
1686     /* remove the exceding 0x6
1687      * for digits that have not generated a carry
1688      */
1689 
1690     tcg_gen_sub_i32(dest, t1, dest);
1691     tcg_temp_free(t1);
1692 }
1693 
1694 static void bcd_sub(TCGv dest, TCGv src)
1695 {
1696     TCGv t0, t1, t2;
1697 
1698     /*  dest10 = dest10 - src10 - X
1699      *         = bcd_add(dest + 1 - X, 0x199 - src)
1700      */
1701 
1702     /* t0 = 0x066 + (0x199 - src) */
1703 
1704     t0 = tcg_temp_new();
1705     tcg_gen_subfi_i32(t0, 0x1ff, src);
1706 
1707     /* t1 = t0 + dest + 1 - X*/
1708 
1709     t1 = tcg_temp_new();
1710     tcg_gen_add_i32(t1, t0, dest);
1711     tcg_gen_addi_i32(t1, t1, 1);
1712     tcg_gen_sub_i32(t1, t1, QREG_CC_X);
1713 
1714     /* t2 = t0 ^ dest */
1715 
1716     t2 = tcg_temp_new();
1717     tcg_gen_xor_i32(t2, t0, dest);
1718 
1719     /* t0 = t1 ^ t2 */
1720 
1721     tcg_gen_xor_i32(t0, t1, t2);
1722 
1723     /* t2 = ~t0 & 0x110
1724      * t0 = (t2 >> 2) | (t2 >> 3)
1725      *
1726      * to fit on 8bit operands, changed in:
1727      *
1728      * t2 = ~(t0 >> 3) & 0x22
1729      * t0 = t2 + t2
1730      * t0 = t0 + t2
1731      */
1732 
1733     tcg_gen_shri_i32(t2, t0, 3);
1734     tcg_gen_not_i32(t2, t2);
1735     tcg_gen_andi_i32(t2, t2, 0x22);
1736     tcg_gen_add_i32(t0, t2, t2);
1737     tcg_gen_add_i32(t0, t0, t2);
1738     tcg_temp_free(t2);
1739 
1740     /* return t1 - t0 */
1741 
1742     tcg_gen_sub_i32(dest, t1, t0);
1743     tcg_temp_free(t0);
1744     tcg_temp_free(t1);
1745 }
1746 
1747 static void bcd_flags(TCGv val)
1748 {
1749     tcg_gen_andi_i32(QREG_CC_C, val, 0x0ff);
1750     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_C);
1751 
1752     tcg_gen_shri_i32(QREG_CC_C, val, 8);
1753     tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
1754 
1755     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
1756 }
1757 
1758 DISAS_INSN(abcd_reg)
1759 {
1760     TCGv src;
1761     TCGv dest;
1762 
1763     gen_flush_flags(s); /* !Z is sticky */
1764 
1765     src = gen_extend(DREG(insn, 0), OS_BYTE, 0);
1766     dest = gen_extend(DREG(insn, 9), OS_BYTE, 0);
1767     bcd_add(dest, src);
1768     gen_partset_reg(OS_BYTE, DREG(insn, 9), dest);
1769 
1770     bcd_flags(dest);
1771 }
1772 
1773 DISAS_INSN(abcd_mem)
1774 {
1775     TCGv src, dest, addr;
1776 
1777     gen_flush_flags(s); /* !Z is sticky */
1778 
1779     /* Indirect pre-decrement load (mode 4) */
1780 
1781     src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
1782                       NULL_QREG, NULL, EA_LOADU);
1783     dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
1784                        NULL_QREG, &addr, EA_LOADU);
1785 
1786     bcd_add(dest, src);
1787 
1788     gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE);
1789 
1790     bcd_flags(dest);
1791 }
1792 
1793 DISAS_INSN(sbcd_reg)
1794 {
1795     TCGv src, dest;
1796 
1797     gen_flush_flags(s); /* !Z is sticky */
1798 
1799     src = gen_extend(DREG(insn, 0), OS_BYTE, 0);
1800     dest = gen_extend(DREG(insn, 9), OS_BYTE, 0);
1801 
1802     bcd_sub(dest, src);
1803 
1804     gen_partset_reg(OS_BYTE, DREG(insn, 9), dest);
1805 
1806     bcd_flags(dest);
1807 }
1808 
1809 DISAS_INSN(sbcd_mem)
1810 {
1811     TCGv src, dest, addr;
1812 
1813     gen_flush_flags(s); /* !Z is sticky */
1814 
1815     /* Indirect pre-decrement load (mode 4) */
1816 
1817     src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
1818                       NULL_QREG, NULL, EA_LOADU);
1819     dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
1820                        NULL_QREG, &addr, EA_LOADU);
1821 
1822     bcd_sub(dest, src);
1823 
1824     gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE);
1825 
1826     bcd_flags(dest);
1827 }
1828 
1829 DISAS_INSN(nbcd)
1830 {
1831     TCGv src, dest;
1832     TCGv addr;
1833 
1834     gen_flush_flags(s); /* !Z is sticky */
1835 
1836     SRC_EA(env, src, OS_BYTE, 0, &addr);
1837 
1838     dest = tcg_const_i32(0);
1839     bcd_sub(dest, src);
1840 
1841     DEST_EA(env, insn, OS_BYTE, dest, &addr);
1842 
1843     bcd_flags(dest);
1844 
1845     tcg_temp_free(dest);
1846 }
1847 
1848 DISAS_INSN(addsub)
1849 {
1850     TCGv reg;
1851     TCGv dest;
1852     TCGv src;
1853     TCGv tmp;
1854     TCGv addr;
1855     int add;
1856     int opsize;
1857 
1858     add = (insn & 0x4000) != 0;
1859     opsize = insn_opsize(insn);
1860     reg = gen_extend(DREG(insn, 9), opsize, 1);
1861     dest = tcg_temp_new();
1862     if (insn & 0x100) {
1863         SRC_EA(env, tmp, opsize, 1, &addr);
1864         src = reg;
1865     } else {
1866         tmp = reg;
1867         SRC_EA(env, src, opsize, 1, NULL);
1868     }
1869     if (add) {
1870         tcg_gen_add_i32(dest, tmp, src);
1871         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src);
1872         set_cc_op(s, CC_OP_ADDB + opsize);
1873     } else {
1874         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src);
1875         tcg_gen_sub_i32(dest, tmp, src);
1876         set_cc_op(s, CC_OP_SUBB + opsize);
1877     }
1878     gen_update_cc_add(dest, src, opsize);
1879     if (insn & 0x100) {
1880         DEST_EA(env, insn, opsize, dest, &addr);
1881     } else {
1882         gen_partset_reg(opsize, DREG(insn, 9), dest);
1883     }
1884     tcg_temp_free(dest);
1885 }
1886 
1887 /* Reverse the order of the bits in REG.  */
1888 DISAS_INSN(bitrev)
1889 {
1890     TCGv reg;
1891     reg = DREG(insn, 0);
1892     gen_helper_bitrev(reg, reg);
1893 }
1894 
1895 DISAS_INSN(bitop_reg)
1896 {
1897     int opsize;
1898     int op;
1899     TCGv src1;
1900     TCGv src2;
1901     TCGv tmp;
1902     TCGv addr;
1903     TCGv dest;
1904 
1905     if ((insn & 0x38) != 0)
1906         opsize = OS_BYTE;
1907     else
1908         opsize = OS_LONG;
1909     op = (insn >> 6) & 3;
1910     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
1911 
1912     gen_flush_flags(s);
1913     src2 = tcg_temp_new();
1914     if (opsize == OS_BYTE)
1915         tcg_gen_andi_i32(src2, DREG(insn, 9), 7);
1916     else
1917         tcg_gen_andi_i32(src2, DREG(insn, 9), 31);
1918 
1919     tmp = tcg_const_i32(1);
1920     tcg_gen_shl_i32(tmp, tmp, src2);
1921     tcg_temp_free(src2);
1922 
1923     tcg_gen_and_i32(QREG_CC_Z, src1, tmp);
1924 
1925     dest = tcg_temp_new();
1926     switch (op) {
1927     case 1: /* bchg */
1928         tcg_gen_xor_i32(dest, src1, tmp);
1929         break;
1930     case 2: /* bclr */
1931         tcg_gen_andc_i32(dest, src1, tmp);
1932         break;
1933     case 3: /* bset */
1934         tcg_gen_or_i32(dest, src1, tmp);
1935         break;
1936     default: /* btst */
1937         break;
1938     }
1939     tcg_temp_free(tmp);
1940     if (op) {
1941         DEST_EA(env, insn, opsize, dest, &addr);
1942     }
1943     tcg_temp_free(dest);
1944 }
1945 
1946 DISAS_INSN(sats)
1947 {
1948     TCGv reg;
1949     reg = DREG(insn, 0);
1950     gen_flush_flags(s);
1951     gen_helper_sats(reg, reg, QREG_CC_V);
1952     gen_logic_cc(s, reg, OS_LONG);
1953 }
1954 
1955 static void gen_push(DisasContext *s, TCGv val)
1956 {
1957     TCGv tmp;
1958 
1959     tmp = tcg_temp_new();
1960     tcg_gen_subi_i32(tmp, QREG_SP, 4);
1961     gen_store(s, OS_LONG, tmp, val);
1962     tcg_gen_mov_i32(QREG_SP, tmp);
1963     tcg_temp_free(tmp);
1964 }
1965 
1966 static TCGv mreg(int reg)
1967 {
1968     if (reg < 8) {
1969         /* Dx */
1970         return cpu_dregs[reg];
1971     }
1972     /* Ax */
1973     return cpu_aregs[reg & 7];
1974 }
1975 
1976 DISAS_INSN(movem)
1977 {
1978     TCGv addr, incr, tmp, r[16];
1979     int is_load = (insn & 0x0400) != 0;
1980     int opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD;
1981     uint16_t mask = read_im16(env, s);
1982     int mode = extract32(insn, 3, 3);
1983     int reg0 = REG(insn, 0);
1984     int i;
1985 
1986     tmp = cpu_aregs[reg0];
1987 
1988     switch (mode) {
1989     case 0: /* data register direct */
1990     case 1: /* addr register direct */
1991     do_addr_fault:
1992         gen_addr_fault(s);
1993         return;
1994 
1995     case 2: /* indirect */
1996         break;
1997 
1998     case 3: /* indirect post-increment */
1999         if (!is_load) {
2000             /* post-increment is not allowed */
2001             goto do_addr_fault;
2002         }
2003         break;
2004 
2005     case 4: /* indirect pre-decrement */
2006         if (is_load) {
2007             /* pre-decrement is not allowed */
2008             goto do_addr_fault;
2009         }
2010         /* We want a bare copy of the address reg, without any pre-decrement
2011            adjustment, as gen_lea would provide.  */
2012         break;
2013 
2014     default:
2015         tmp = gen_lea_mode(env, s, mode, reg0, opsize);
2016         if (IS_NULL_QREG(tmp)) {
2017             goto do_addr_fault;
2018         }
2019         break;
2020     }
2021 
2022     addr = tcg_temp_new();
2023     tcg_gen_mov_i32(addr, tmp);
2024     incr = tcg_const_i32(opsize_bytes(opsize));
2025 
2026     if (is_load) {
2027         /* memory to register */
2028         for (i = 0; i < 16; i++) {
2029             if (mask & (1 << i)) {
2030                 r[i] = gen_load(s, opsize, addr, 1);
2031                 tcg_gen_add_i32(addr, addr, incr);
2032             }
2033         }
2034         for (i = 0; i < 16; i++) {
2035             if (mask & (1 << i)) {
2036                 tcg_gen_mov_i32(mreg(i), r[i]);
2037                 tcg_temp_free(r[i]);
2038             }
2039         }
2040         if (mode == 3) {
2041             /* post-increment: movem (An)+,X */
2042             tcg_gen_mov_i32(cpu_aregs[reg0], addr);
2043         }
2044     } else {
2045         /* register to memory */
2046         if (mode == 4) {
2047             /* pre-decrement: movem X,-(An) */
2048             for (i = 15; i >= 0; i--) {
2049                 if ((mask << i) & 0x8000) {
2050                     tcg_gen_sub_i32(addr, addr, incr);
2051                     if (reg0 + 8 == i &&
2052                         m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) {
2053                         /* M68020+: if the addressing register is the
2054                          * register moved to memory, the value written
2055                          * is the initial value decremented by the size of
2056                          * the operation, regardless of how many actual
2057                          * stores have been performed until this point.
2058                          * M68000/M68010: the value is the initial value.
2059                          */
2060                         tmp = tcg_temp_new();
2061                         tcg_gen_sub_i32(tmp, cpu_aregs[reg0], incr);
2062                         gen_store(s, opsize, addr, tmp);
2063                         tcg_temp_free(tmp);
2064                     } else {
2065                         gen_store(s, opsize, addr, mreg(i));
2066                     }
2067                 }
2068             }
2069             tcg_gen_mov_i32(cpu_aregs[reg0], addr);
2070         } else {
2071             for (i = 0; i < 16; i++) {
2072                 if (mask & (1 << i)) {
2073                     gen_store(s, opsize, addr, mreg(i));
2074                     tcg_gen_add_i32(addr, addr, incr);
2075                 }
2076             }
2077         }
2078     }
2079 
2080     tcg_temp_free(incr);
2081     tcg_temp_free(addr);
2082 }
2083 
2084 DISAS_INSN(bitop_im)
2085 {
2086     int opsize;
2087     int op;
2088     TCGv src1;
2089     uint32_t mask;
2090     int bitnum;
2091     TCGv tmp;
2092     TCGv addr;
2093 
2094     if ((insn & 0x38) != 0)
2095         opsize = OS_BYTE;
2096     else
2097         opsize = OS_LONG;
2098     op = (insn >> 6) & 3;
2099 
2100     bitnum = read_im16(env, s);
2101     if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
2102         if (bitnum & 0xfe00) {
2103             disas_undef(env, s, insn);
2104             return;
2105         }
2106     } else {
2107         if (bitnum & 0xff00) {
2108             disas_undef(env, s, insn);
2109             return;
2110         }
2111     }
2112 
2113     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
2114 
2115     gen_flush_flags(s);
2116     if (opsize == OS_BYTE)
2117         bitnum &= 7;
2118     else
2119         bitnum &= 31;
2120     mask = 1 << bitnum;
2121 
2122    tcg_gen_andi_i32(QREG_CC_Z, src1, mask);
2123 
2124     if (op) {
2125         tmp = tcg_temp_new();
2126         switch (op) {
2127         case 1: /* bchg */
2128             tcg_gen_xori_i32(tmp, src1, mask);
2129             break;
2130         case 2: /* bclr */
2131             tcg_gen_andi_i32(tmp, src1, ~mask);
2132             break;
2133         case 3: /* bset */
2134             tcg_gen_ori_i32(tmp, src1, mask);
2135             break;
2136         default: /* btst */
2137             break;
2138         }
2139         DEST_EA(env, insn, opsize, tmp, &addr);
2140         tcg_temp_free(tmp);
2141     }
2142 }
2143 
2144 DISAS_INSN(arith_im)
2145 {
2146     int op;
2147     TCGv im;
2148     TCGv src1;
2149     TCGv dest;
2150     TCGv addr;
2151     int opsize;
2152 
2153     op = (insn >> 9) & 7;
2154     opsize = insn_opsize(insn);
2155     switch (opsize) {
2156     case OS_BYTE:
2157         im = tcg_const_i32((int8_t)read_im8(env, s));
2158         break;
2159     case OS_WORD:
2160         im = tcg_const_i32((int16_t)read_im16(env, s));
2161         break;
2162     case OS_LONG:
2163         im = tcg_const_i32(read_im32(env, s));
2164         break;
2165     default:
2166        abort();
2167     }
2168     SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : &addr);
2169     dest = tcg_temp_new();
2170     switch (op) {
2171     case 0: /* ori */
2172         tcg_gen_or_i32(dest, src1, im);
2173         gen_logic_cc(s, dest, opsize);
2174         break;
2175     case 1: /* andi */
2176         tcg_gen_and_i32(dest, src1, im);
2177         gen_logic_cc(s, dest, opsize);
2178         break;
2179     case 2: /* subi */
2180         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, src1, im);
2181         tcg_gen_sub_i32(dest, src1, im);
2182         gen_update_cc_add(dest, im, opsize);
2183         set_cc_op(s, CC_OP_SUBB + opsize);
2184         break;
2185     case 3: /* addi */
2186         tcg_gen_add_i32(dest, src1, im);
2187         gen_update_cc_add(dest, im, opsize);
2188         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
2189         set_cc_op(s, CC_OP_ADDB + opsize);
2190         break;
2191     case 5: /* eori */
2192         tcg_gen_xor_i32(dest, src1, im);
2193         gen_logic_cc(s, dest, opsize);
2194         break;
2195     case 6: /* cmpi */
2196         gen_update_cc_cmp(s, src1, im, opsize);
2197         break;
2198     default:
2199         abort();
2200     }
2201     tcg_temp_free(im);
2202     if (op != 6) {
2203         DEST_EA(env, insn, opsize, dest, &addr);
2204     }
2205     tcg_temp_free(dest);
2206 }
2207 
2208 DISAS_INSN(cas)
2209 {
2210     int opsize;
2211     TCGv addr;
2212     uint16_t ext;
2213     TCGv load;
2214     TCGv cmp;
2215     TCGMemOp opc;
2216 
2217     switch ((insn >> 9) & 3) {
2218     case 1:
2219         opsize = OS_BYTE;
2220         opc = MO_SB;
2221         break;
2222     case 2:
2223         opsize = OS_WORD;
2224         opc = MO_TESW;
2225         break;
2226     case 3:
2227         opsize = OS_LONG;
2228         opc = MO_TESL;
2229         break;
2230     default:
2231         g_assert_not_reached();
2232     }
2233 
2234     ext = read_im16(env, s);
2235 
2236     /* cas Dc,Du,<EA> */
2237 
2238     addr = gen_lea(env, s, insn, opsize);
2239     if (IS_NULL_QREG(addr)) {
2240         gen_addr_fault(s);
2241         return;
2242     }
2243 
2244     cmp = gen_extend(DREG(ext, 0), opsize, 1);
2245 
2246     /* if  <EA> == Dc then
2247      *     <EA> = Du
2248      *     Dc = <EA> (because <EA> == Dc)
2249      * else
2250      *     Dc = <EA>
2251      */
2252 
2253     load = tcg_temp_new();
2254     tcg_gen_atomic_cmpxchg_i32(load, addr, cmp, DREG(ext, 6),
2255                                IS_USER(s), opc);
2256     /* update flags before setting cmp to load */
2257     gen_update_cc_cmp(s, load, cmp, opsize);
2258     gen_partset_reg(opsize, DREG(ext, 0), load);
2259 
2260     tcg_temp_free(load);
2261 
2262     switch (extract32(insn, 3, 3)) {
2263     case 3: /* Indirect postincrement.  */
2264         tcg_gen_addi_i32(AREG(insn, 0), addr, opsize_bytes(opsize));
2265         break;
2266     case 4: /* Indirect predecrememnt.  */
2267         tcg_gen_mov_i32(AREG(insn, 0), addr);
2268         break;
2269     }
2270 }
2271 
2272 DISAS_INSN(cas2w)
2273 {
2274     uint16_t ext1, ext2;
2275     TCGv addr1, addr2;
2276     TCGv regs;
2277 
2278     /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */
2279 
2280     ext1 = read_im16(env, s);
2281 
2282     if (ext1 & 0x8000) {
2283         /* Address Register */
2284         addr1 = AREG(ext1, 12);
2285     } else {
2286         /* Data Register */
2287         addr1 = DREG(ext1, 12);
2288     }
2289 
2290     ext2 = read_im16(env, s);
2291     if (ext2 & 0x8000) {
2292         /* Address Register */
2293         addr2 = AREG(ext2, 12);
2294     } else {
2295         /* Data Register */
2296         addr2 = DREG(ext2, 12);
2297     }
2298 
2299     /* if (R1) == Dc1 && (R2) == Dc2 then
2300      *     (R1) = Du1
2301      *     (R2) = Du2
2302      * else
2303      *     Dc1 = (R1)
2304      *     Dc2 = (R2)
2305      */
2306 
2307     regs = tcg_const_i32(REG(ext2, 6) |
2308                          (REG(ext1, 6) << 3) |
2309                          (REG(ext2, 0) << 6) |
2310                          (REG(ext1, 0) << 9));
2311     gen_helper_cas2w(cpu_env, regs, addr1, addr2);
2312     tcg_temp_free(regs);
2313 
2314     /* Note that cas2w also assigned to env->cc_op.  */
2315     s->cc_op = CC_OP_CMPW;
2316     s->cc_op_synced = 1;
2317 }
2318 
2319 DISAS_INSN(cas2l)
2320 {
2321     uint16_t ext1, ext2;
2322     TCGv addr1, addr2, regs;
2323 
2324     /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */
2325 
2326     ext1 = read_im16(env, s);
2327 
2328     if (ext1 & 0x8000) {
2329         /* Address Register */
2330         addr1 = AREG(ext1, 12);
2331     } else {
2332         /* Data Register */
2333         addr1 = DREG(ext1, 12);
2334     }
2335 
2336     ext2 = read_im16(env, s);
2337     if (ext2 & 0x8000) {
2338         /* Address Register */
2339         addr2 = AREG(ext2, 12);
2340     } else {
2341         /* Data Register */
2342         addr2 = DREG(ext2, 12);
2343     }
2344 
2345     /* if (R1) == Dc1 && (R2) == Dc2 then
2346      *     (R1) = Du1
2347      *     (R2) = Du2
2348      * else
2349      *     Dc1 = (R1)
2350      *     Dc2 = (R2)
2351      */
2352 
2353     regs = tcg_const_i32(REG(ext2, 6) |
2354                          (REG(ext1, 6) << 3) |
2355                          (REG(ext2, 0) << 6) |
2356                          (REG(ext1, 0) << 9));
2357     gen_helper_cas2l(cpu_env, regs, addr1, addr2);
2358     tcg_temp_free(regs);
2359 
2360     /* Note that cas2l also assigned to env->cc_op.  */
2361     s->cc_op = CC_OP_CMPL;
2362     s->cc_op_synced = 1;
2363 }
2364 
2365 DISAS_INSN(byterev)
2366 {
2367     TCGv reg;
2368 
2369     reg = DREG(insn, 0);
2370     tcg_gen_bswap32_i32(reg, reg);
2371 }
2372 
2373 DISAS_INSN(move)
2374 {
2375     TCGv src;
2376     TCGv dest;
2377     int op;
2378     int opsize;
2379 
2380     switch (insn >> 12) {
2381     case 1: /* move.b */
2382         opsize = OS_BYTE;
2383         break;
2384     case 2: /* move.l */
2385         opsize = OS_LONG;
2386         break;
2387     case 3: /* move.w */
2388         opsize = OS_WORD;
2389         break;
2390     default:
2391         abort();
2392     }
2393     SRC_EA(env, src, opsize, 1, NULL);
2394     op = (insn >> 6) & 7;
2395     if (op == 1) {
2396         /* movea */
2397         /* The value will already have been sign extended.  */
2398         dest = AREG(insn, 9);
2399         tcg_gen_mov_i32(dest, src);
2400     } else {
2401         /* normal move */
2402         uint16_t dest_ea;
2403         dest_ea = ((insn >> 9) & 7) | (op << 3);
2404         DEST_EA(env, dest_ea, opsize, src, NULL);
2405         /* This will be correct because loads sign extend.  */
2406         gen_logic_cc(s, src, opsize);
2407     }
2408 }
2409 
2410 DISAS_INSN(negx)
2411 {
2412     TCGv z;
2413     TCGv src;
2414     TCGv addr;
2415     int opsize;
2416 
2417     opsize = insn_opsize(insn);
2418     SRC_EA(env, src, opsize, 1, &addr);
2419 
2420     gen_flush_flags(s); /* compute old Z */
2421 
2422     /* Perform substract with borrow.
2423      * (X, N) =  -(src + X);
2424      */
2425 
2426     z = tcg_const_i32(0);
2427     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, z, QREG_CC_X, z);
2428     tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, z, z, QREG_CC_N, QREG_CC_X);
2429     tcg_temp_free(z);
2430     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
2431 
2432     tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
2433 
2434     /* Compute signed-overflow for negation.  The normal formula for
2435      * subtraction is (res ^ src) & (src ^ dest), but with dest==0
2436      * this simplies to res & src.
2437      */
2438 
2439     tcg_gen_and_i32(QREG_CC_V, QREG_CC_N, src);
2440 
2441     /* Copy the rest of the results into place.  */
2442     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
2443     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
2444 
2445     set_cc_op(s, CC_OP_FLAGS);
2446 
2447     /* result is in QREG_CC_N */
2448 
2449     DEST_EA(env, insn, opsize, QREG_CC_N, &addr);
2450 }
2451 
2452 DISAS_INSN(lea)
2453 {
2454     TCGv reg;
2455     TCGv tmp;
2456 
2457     reg = AREG(insn, 9);
2458     tmp = gen_lea(env, s, insn, OS_LONG);
2459     if (IS_NULL_QREG(tmp)) {
2460         gen_addr_fault(s);
2461         return;
2462     }
2463     tcg_gen_mov_i32(reg, tmp);
2464 }
2465 
2466 DISAS_INSN(clr)
2467 {
2468     int opsize;
2469     TCGv zero;
2470 
2471     zero = tcg_const_i32(0);
2472 
2473     opsize = insn_opsize(insn);
2474     DEST_EA(env, insn, opsize, zero, NULL);
2475     gen_logic_cc(s, zero, opsize);
2476     tcg_temp_free(zero);
2477 }
2478 
2479 static TCGv gen_get_ccr(DisasContext *s)
2480 {
2481     TCGv dest;
2482 
2483     gen_flush_flags(s);
2484     update_cc_op(s);
2485     dest = tcg_temp_new();
2486     gen_helper_get_ccr(dest, cpu_env);
2487     return dest;
2488 }
2489 
2490 DISAS_INSN(move_from_ccr)
2491 {
2492     TCGv ccr;
2493 
2494     ccr = gen_get_ccr(s);
2495     DEST_EA(env, insn, OS_WORD, ccr, NULL);
2496 }
2497 
2498 DISAS_INSN(neg)
2499 {
2500     TCGv src1;
2501     TCGv dest;
2502     TCGv addr;
2503     int opsize;
2504 
2505     opsize = insn_opsize(insn);
2506     SRC_EA(env, src1, opsize, 1, &addr);
2507     dest = tcg_temp_new();
2508     tcg_gen_neg_i32(dest, src1);
2509     set_cc_op(s, CC_OP_SUBB + opsize);
2510     gen_update_cc_add(dest, src1, opsize);
2511     tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, dest, 0);
2512     DEST_EA(env, insn, opsize, dest, &addr);
2513     tcg_temp_free(dest);
2514 }
2515 
2516 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
2517 {
2518     if (ccr_only) {
2519         tcg_gen_movi_i32(QREG_CC_C, val & CCF_C ? 1 : 0);
2520         tcg_gen_movi_i32(QREG_CC_V, val & CCF_V ? -1 : 0);
2521         tcg_gen_movi_i32(QREG_CC_Z, val & CCF_Z ? 0 : 1);
2522         tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0);
2523         tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0);
2524     } else {
2525         gen_helper_set_sr(cpu_env, tcg_const_i32(val));
2526     }
2527     set_cc_op(s, CC_OP_FLAGS);
2528 }
2529 
2530 static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
2531                        int ccr_only)
2532 {
2533     if ((insn & 0x38) == 0) {
2534         if (ccr_only) {
2535             gen_helper_set_ccr(cpu_env, DREG(insn, 0));
2536         } else {
2537             gen_helper_set_sr(cpu_env, DREG(insn, 0));
2538         }
2539         set_cc_op(s, CC_OP_FLAGS);
2540     } else if ((insn & 0x3f) == 0x3c) {
2541         uint16_t val;
2542         val = read_im16(env, s);
2543         gen_set_sr_im(s, val, ccr_only);
2544     } else {
2545         disas_undef(env, s, insn);
2546     }
2547 }
2548 
2549 
2550 DISAS_INSN(move_to_ccr)
2551 {
2552     gen_set_sr(env, s, insn, 1);
2553 }
2554 
2555 DISAS_INSN(not)
2556 {
2557     TCGv src1;
2558     TCGv dest;
2559     TCGv addr;
2560     int opsize;
2561 
2562     opsize = insn_opsize(insn);
2563     SRC_EA(env, src1, opsize, 1, &addr);
2564     dest = tcg_temp_new();
2565     tcg_gen_not_i32(dest, src1);
2566     DEST_EA(env, insn, opsize, dest, &addr);
2567     gen_logic_cc(s, dest, opsize);
2568 }
2569 
2570 DISAS_INSN(swap)
2571 {
2572     TCGv src1;
2573     TCGv src2;
2574     TCGv reg;
2575 
2576     src1 = tcg_temp_new();
2577     src2 = tcg_temp_new();
2578     reg = DREG(insn, 0);
2579     tcg_gen_shli_i32(src1, reg, 16);
2580     tcg_gen_shri_i32(src2, reg, 16);
2581     tcg_gen_or_i32(reg, src1, src2);
2582     tcg_temp_free(src2);
2583     tcg_temp_free(src1);
2584     gen_logic_cc(s, reg, OS_LONG);
2585 }
2586 
2587 DISAS_INSN(bkpt)
2588 {
2589     gen_exception(s, s->pc - 2, EXCP_DEBUG);
2590 }
2591 
2592 DISAS_INSN(pea)
2593 {
2594     TCGv tmp;
2595 
2596     tmp = gen_lea(env, s, insn, OS_LONG);
2597     if (IS_NULL_QREG(tmp)) {
2598         gen_addr_fault(s);
2599         return;
2600     }
2601     gen_push(s, tmp);
2602 }
2603 
2604 DISAS_INSN(ext)
2605 {
2606     int op;
2607     TCGv reg;
2608     TCGv tmp;
2609 
2610     reg = DREG(insn, 0);
2611     op = (insn >> 6) & 7;
2612     tmp = tcg_temp_new();
2613     if (op == 3)
2614         tcg_gen_ext16s_i32(tmp, reg);
2615     else
2616         tcg_gen_ext8s_i32(tmp, reg);
2617     if (op == 2)
2618         gen_partset_reg(OS_WORD, reg, tmp);
2619     else
2620         tcg_gen_mov_i32(reg, tmp);
2621     gen_logic_cc(s, tmp, OS_LONG);
2622     tcg_temp_free(tmp);
2623 }
2624 
2625 DISAS_INSN(tst)
2626 {
2627     int opsize;
2628     TCGv tmp;
2629 
2630     opsize = insn_opsize(insn);
2631     SRC_EA(env, tmp, opsize, 1, NULL);
2632     gen_logic_cc(s, tmp, opsize);
2633 }
2634 
2635 DISAS_INSN(pulse)
2636 {
2637   /* Implemented as a NOP.  */
2638 }
2639 
2640 DISAS_INSN(illegal)
2641 {
2642     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
2643 }
2644 
2645 /* ??? This should be atomic.  */
2646 DISAS_INSN(tas)
2647 {
2648     TCGv dest;
2649     TCGv src1;
2650     TCGv addr;
2651 
2652     dest = tcg_temp_new();
2653     SRC_EA(env, src1, OS_BYTE, 1, &addr);
2654     gen_logic_cc(s, src1, OS_BYTE);
2655     tcg_gen_ori_i32(dest, src1, 0x80);
2656     DEST_EA(env, insn, OS_BYTE, dest, &addr);
2657     tcg_temp_free(dest);
2658 }
2659 
2660 DISAS_INSN(mull)
2661 {
2662     uint16_t ext;
2663     TCGv src1;
2664     int sign;
2665 
2666     ext = read_im16(env, s);
2667 
2668     sign = ext & 0x800;
2669 
2670     if (ext & 0x400) {
2671         if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
2672             gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
2673             return;
2674         }
2675 
2676         SRC_EA(env, src1, OS_LONG, 0, NULL);
2677 
2678         if (sign) {
2679             tcg_gen_muls2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12));
2680         } else {
2681             tcg_gen_mulu2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12));
2682         }
2683         /* if Dl == Dh, 68040 returns low word */
2684         tcg_gen_mov_i32(DREG(ext, 0), QREG_CC_N);
2685         tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_Z);
2686         tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N);
2687 
2688         tcg_gen_movi_i32(QREG_CC_V, 0);
2689         tcg_gen_movi_i32(QREG_CC_C, 0);
2690 
2691         set_cc_op(s, CC_OP_FLAGS);
2692         return;
2693     }
2694     SRC_EA(env, src1, OS_LONG, 0, NULL);
2695     if (m68k_feature(s->env, M68K_FEATURE_M68000)) {
2696         tcg_gen_movi_i32(QREG_CC_C, 0);
2697         if (sign) {
2698             tcg_gen_muls2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12));
2699             /* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */
2700             tcg_gen_sari_i32(QREG_CC_Z, QREG_CC_N, 31);
2701             tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_Z);
2702         } else {
2703             tcg_gen_mulu2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12));
2704             /* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */
2705             tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_C);
2706         }
2707         tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
2708         tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_N);
2709 
2710         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
2711 
2712         set_cc_op(s, CC_OP_FLAGS);
2713     } else {
2714         /* The upper 32 bits of the product are discarded, so
2715            muls.l and mulu.l are functionally equivalent.  */
2716         tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12));
2717         gen_logic_cc(s, DREG(ext, 12), OS_LONG);
2718     }
2719 }
2720 
2721 static void gen_link(DisasContext *s, uint16_t insn, int32_t offset)
2722 {
2723     TCGv reg;
2724     TCGv tmp;
2725 
2726     reg = AREG(insn, 0);
2727     tmp = tcg_temp_new();
2728     tcg_gen_subi_i32(tmp, QREG_SP, 4);
2729     gen_store(s, OS_LONG, tmp, reg);
2730     if ((insn & 7) != 7) {
2731         tcg_gen_mov_i32(reg, tmp);
2732     }
2733     tcg_gen_addi_i32(QREG_SP, tmp, offset);
2734     tcg_temp_free(tmp);
2735 }
2736 
2737 DISAS_INSN(link)
2738 {
2739     int16_t offset;
2740 
2741     offset = read_im16(env, s);
2742     gen_link(s, insn, offset);
2743 }
2744 
2745 DISAS_INSN(linkl)
2746 {
2747     int32_t offset;
2748 
2749     offset = read_im32(env, s);
2750     gen_link(s, insn, offset);
2751 }
2752 
2753 DISAS_INSN(unlk)
2754 {
2755     TCGv src;
2756     TCGv reg;
2757     TCGv tmp;
2758 
2759     src = tcg_temp_new();
2760     reg = AREG(insn, 0);
2761     tcg_gen_mov_i32(src, reg);
2762     tmp = gen_load(s, OS_LONG, src, 0);
2763     tcg_gen_mov_i32(reg, tmp);
2764     tcg_gen_addi_i32(QREG_SP, src, 4);
2765     tcg_temp_free(src);
2766 }
2767 
2768 DISAS_INSN(nop)
2769 {
2770 }
2771 
2772 DISAS_INSN(rtd)
2773 {
2774     TCGv tmp;
2775     int16_t offset = read_im16(env, s);
2776 
2777     tmp = gen_load(s, OS_LONG, QREG_SP, 0);
2778     tcg_gen_addi_i32(QREG_SP, QREG_SP, offset + 4);
2779     gen_jmp(s, tmp);
2780 }
2781 
2782 DISAS_INSN(rts)
2783 {
2784     TCGv tmp;
2785 
2786     tmp = gen_load(s, OS_LONG, QREG_SP, 0);
2787     tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
2788     gen_jmp(s, tmp);
2789 }
2790 
2791 DISAS_INSN(jump)
2792 {
2793     TCGv tmp;
2794 
2795     /* Load the target address first to ensure correct exception
2796        behavior.  */
2797     tmp = gen_lea(env, s, insn, OS_LONG);
2798     if (IS_NULL_QREG(tmp)) {
2799         gen_addr_fault(s);
2800         return;
2801     }
2802     if ((insn & 0x40) == 0) {
2803         /* jsr */
2804         gen_push(s, tcg_const_i32(s->pc));
2805     }
2806     gen_jmp(s, tmp);
2807 }
2808 
2809 DISAS_INSN(addsubq)
2810 {
2811     TCGv src;
2812     TCGv dest;
2813     TCGv val;
2814     int imm;
2815     TCGv addr;
2816     int opsize;
2817 
2818     if ((insn & 070) == 010) {
2819         /* Operation on address register is always long.  */
2820         opsize = OS_LONG;
2821     } else {
2822         opsize = insn_opsize(insn);
2823     }
2824     SRC_EA(env, src, opsize, 1, &addr);
2825     imm = (insn >> 9) & 7;
2826     if (imm == 0) {
2827         imm = 8;
2828     }
2829     val = tcg_const_i32(imm);
2830     dest = tcg_temp_new();
2831     tcg_gen_mov_i32(dest, src);
2832     if ((insn & 0x38) == 0x08) {
2833         /* Don't update condition codes if the destination is an
2834            address register.  */
2835         if (insn & 0x0100) {
2836             tcg_gen_sub_i32(dest, dest, val);
2837         } else {
2838             tcg_gen_add_i32(dest, dest, val);
2839         }
2840     } else {
2841         if (insn & 0x0100) {
2842             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
2843             tcg_gen_sub_i32(dest, dest, val);
2844             set_cc_op(s, CC_OP_SUBB + opsize);
2845         } else {
2846             tcg_gen_add_i32(dest, dest, val);
2847             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
2848             set_cc_op(s, CC_OP_ADDB + opsize);
2849         }
2850         gen_update_cc_add(dest, val, opsize);
2851     }
2852     tcg_temp_free(val);
2853     DEST_EA(env, insn, opsize, dest, &addr);
2854     tcg_temp_free(dest);
2855 }
2856 
2857 DISAS_INSN(tpf)
2858 {
2859     switch (insn & 7) {
2860     case 2: /* One extension word.  */
2861         s->pc += 2;
2862         break;
2863     case 3: /* Two extension words.  */
2864         s->pc += 4;
2865         break;
2866     case 4: /* No extension words.  */
2867         break;
2868     default:
2869         disas_undef(env, s, insn);
2870     }
2871 }
2872 
2873 DISAS_INSN(branch)
2874 {
2875     int32_t offset;
2876     uint32_t base;
2877     int op;
2878     TCGLabel *l1;
2879 
2880     base = s->pc;
2881     op = (insn >> 8) & 0xf;
2882     offset = (int8_t)insn;
2883     if (offset == 0) {
2884         offset = (int16_t)read_im16(env, s);
2885     } else if (offset == -1) {
2886         offset = read_im32(env, s);
2887     }
2888     if (op == 1) {
2889         /* bsr */
2890         gen_push(s, tcg_const_i32(s->pc));
2891     }
2892     if (op > 1) {
2893         /* Bcc */
2894         l1 = gen_new_label();
2895         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
2896         gen_jmp_tb(s, 1, base + offset);
2897         gen_set_label(l1);
2898         gen_jmp_tb(s, 0, s->pc);
2899     } else {
2900         /* Unconditional branch.  */
2901         gen_jmp_tb(s, 0, base + offset);
2902     }
2903 }
2904 
2905 DISAS_INSN(moveq)
2906 {
2907     tcg_gen_movi_i32(DREG(insn, 9), (int8_t)insn);
2908     gen_logic_cc(s, DREG(insn, 9), OS_LONG);
2909 }
2910 
2911 DISAS_INSN(mvzs)
2912 {
2913     int opsize;
2914     TCGv src;
2915     TCGv reg;
2916 
2917     if (insn & 0x40)
2918         opsize = OS_WORD;
2919     else
2920         opsize = OS_BYTE;
2921     SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
2922     reg = DREG(insn, 9);
2923     tcg_gen_mov_i32(reg, src);
2924     gen_logic_cc(s, src, opsize);
2925 }
2926 
2927 DISAS_INSN(or)
2928 {
2929     TCGv reg;
2930     TCGv dest;
2931     TCGv src;
2932     TCGv addr;
2933     int opsize;
2934 
2935     opsize = insn_opsize(insn);
2936     reg = gen_extend(DREG(insn, 9), opsize, 0);
2937     dest = tcg_temp_new();
2938     if (insn & 0x100) {
2939         SRC_EA(env, src, opsize, 0, &addr);
2940         tcg_gen_or_i32(dest, src, reg);
2941         DEST_EA(env, insn, opsize, dest, &addr);
2942     } else {
2943         SRC_EA(env, src, opsize, 0, NULL);
2944         tcg_gen_or_i32(dest, src, reg);
2945         gen_partset_reg(opsize, DREG(insn, 9), dest);
2946     }
2947     gen_logic_cc(s, dest, opsize);
2948     tcg_temp_free(dest);
2949 }
2950 
2951 DISAS_INSN(suba)
2952 {
2953     TCGv src;
2954     TCGv reg;
2955 
2956     SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
2957     reg = AREG(insn, 9);
2958     tcg_gen_sub_i32(reg, reg, src);
2959 }
2960 
2961 static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize)
2962 {
2963     TCGv tmp;
2964 
2965     gen_flush_flags(s); /* compute old Z */
2966 
2967     /* Perform substract with borrow.
2968      * (X, N) = dest - (src + X);
2969      */
2970 
2971     tmp = tcg_const_i32(0);
2972     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, tmp, QREG_CC_X, tmp);
2973     tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, dest, tmp, QREG_CC_N, QREG_CC_X);
2974     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
2975     tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
2976 
2977     /* Compute signed-overflow for substract.  */
2978 
2979     tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, dest);
2980     tcg_gen_xor_i32(tmp, dest, src);
2981     tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, tmp);
2982     tcg_temp_free(tmp);
2983 
2984     /* Copy the rest of the results into place.  */
2985     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
2986     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
2987 
2988     set_cc_op(s, CC_OP_FLAGS);
2989 
2990     /* result is in QREG_CC_N */
2991 }
2992 
2993 DISAS_INSN(subx_reg)
2994 {
2995     TCGv dest;
2996     TCGv src;
2997     int opsize;
2998 
2999     opsize = insn_opsize(insn);
3000 
3001     src = gen_extend(DREG(insn, 0), opsize, 1);
3002     dest = gen_extend(DREG(insn, 9), opsize, 1);
3003 
3004     gen_subx(s, src, dest, opsize);
3005 
3006     gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
3007 }
3008 
3009 DISAS_INSN(subx_mem)
3010 {
3011     TCGv src;
3012     TCGv addr_src;
3013     TCGv dest;
3014     TCGv addr_dest;
3015     int opsize;
3016 
3017     opsize = insn_opsize(insn);
3018 
3019     addr_src = AREG(insn, 0);
3020     tcg_gen_subi_i32(addr_src, addr_src, opsize);
3021     src = gen_load(s, opsize, addr_src, 1);
3022 
3023     addr_dest = AREG(insn, 9);
3024     tcg_gen_subi_i32(addr_dest, addr_dest, opsize);
3025     dest = gen_load(s, opsize, addr_dest, 1);
3026 
3027     gen_subx(s, src, dest, opsize);
3028 
3029     gen_store(s, opsize, addr_dest, QREG_CC_N);
3030 }
3031 
3032 DISAS_INSN(mov3q)
3033 {
3034     TCGv src;
3035     int val;
3036 
3037     val = (insn >> 9) & 7;
3038     if (val == 0)
3039         val = -1;
3040     src = tcg_const_i32(val);
3041     gen_logic_cc(s, src, OS_LONG);
3042     DEST_EA(env, insn, OS_LONG, src, NULL);
3043     tcg_temp_free(src);
3044 }
3045 
3046 DISAS_INSN(cmp)
3047 {
3048     TCGv src;
3049     TCGv reg;
3050     int opsize;
3051 
3052     opsize = insn_opsize(insn);
3053     SRC_EA(env, src, opsize, 1, NULL);
3054     reg = gen_extend(DREG(insn, 9), opsize, 1);
3055     gen_update_cc_cmp(s, reg, src, opsize);
3056 }
3057 
3058 DISAS_INSN(cmpa)
3059 {
3060     int opsize;
3061     TCGv src;
3062     TCGv reg;
3063 
3064     if (insn & 0x100) {
3065         opsize = OS_LONG;
3066     } else {
3067         opsize = OS_WORD;
3068     }
3069     SRC_EA(env, src, opsize, 1, NULL);
3070     reg = AREG(insn, 9);
3071     gen_update_cc_cmp(s, reg, src, OS_LONG);
3072 }
3073 
3074 DISAS_INSN(cmpm)
3075 {
3076     int opsize = insn_opsize(insn);
3077     TCGv src, dst;
3078 
3079     /* Post-increment load (mode 3) from Ay.  */
3080     src = gen_ea_mode(env, s, 3, REG(insn, 0), opsize,
3081                       NULL_QREG, NULL, EA_LOADS);
3082     /* Post-increment load (mode 3) from Ax.  */
3083     dst = gen_ea_mode(env, s, 3, REG(insn, 9), opsize,
3084                       NULL_QREG, NULL, EA_LOADS);
3085 
3086     gen_update_cc_cmp(s, dst, src, opsize);
3087 }
3088 
3089 DISAS_INSN(eor)
3090 {
3091     TCGv src;
3092     TCGv dest;
3093     TCGv addr;
3094     int opsize;
3095 
3096     opsize = insn_opsize(insn);
3097 
3098     SRC_EA(env, src, opsize, 0, &addr);
3099     dest = tcg_temp_new();
3100     tcg_gen_xor_i32(dest, src, DREG(insn, 9));
3101     gen_logic_cc(s, dest, opsize);
3102     DEST_EA(env, insn, opsize, dest, &addr);
3103     tcg_temp_free(dest);
3104 }
3105 
3106 static void do_exg(TCGv reg1, TCGv reg2)
3107 {
3108     TCGv temp = tcg_temp_new();
3109     tcg_gen_mov_i32(temp, reg1);
3110     tcg_gen_mov_i32(reg1, reg2);
3111     tcg_gen_mov_i32(reg2, temp);
3112     tcg_temp_free(temp);
3113 }
3114 
3115 DISAS_INSN(exg_dd)
3116 {
3117     /* exchange Dx and Dy */
3118     do_exg(DREG(insn, 9), DREG(insn, 0));
3119 }
3120 
3121 DISAS_INSN(exg_aa)
3122 {
3123     /* exchange Ax and Ay */
3124     do_exg(AREG(insn, 9), AREG(insn, 0));
3125 }
3126 
3127 DISAS_INSN(exg_da)
3128 {
3129     /* exchange Dx and Ay */
3130     do_exg(DREG(insn, 9), AREG(insn, 0));
3131 }
3132 
3133 DISAS_INSN(and)
3134 {
3135     TCGv src;
3136     TCGv reg;
3137     TCGv dest;
3138     TCGv addr;
3139     int opsize;
3140 
3141     dest = tcg_temp_new();
3142 
3143     opsize = insn_opsize(insn);
3144     reg = DREG(insn, 9);
3145     if (insn & 0x100) {
3146         SRC_EA(env, src, opsize, 0, &addr);
3147         tcg_gen_and_i32(dest, src, reg);
3148         DEST_EA(env, insn, opsize, dest, &addr);
3149     } else {
3150         SRC_EA(env, src, opsize, 0, NULL);
3151         tcg_gen_and_i32(dest, src, reg);
3152         gen_partset_reg(opsize, reg, dest);
3153     }
3154     gen_logic_cc(s, dest, opsize);
3155     tcg_temp_free(dest);
3156 }
3157 
3158 DISAS_INSN(adda)
3159 {
3160     TCGv src;
3161     TCGv reg;
3162 
3163     SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
3164     reg = AREG(insn, 9);
3165     tcg_gen_add_i32(reg, reg, src);
3166 }
3167 
3168 static inline void gen_addx(DisasContext *s, TCGv src, TCGv dest, int opsize)
3169 {
3170     TCGv tmp;
3171 
3172     gen_flush_flags(s); /* compute old Z */
3173 
3174     /* Perform addition with carry.
3175      * (X, N) = src + dest + X;
3176      */
3177 
3178     tmp = tcg_const_i32(0);
3179     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, tmp, dest, tmp);
3180     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, tmp);
3181     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
3182 
3183     /* Compute signed-overflow for addition.  */
3184 
3185     tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
3186     tcg_gen_xor_i32(tmp, dest, src);
3187     tcg_gen_andc_i32(QREG_CC_V, QREG_CC_V, tmp);
3188     tcg_temp_free(tmp);
3189 
3190     /* Copy the rest of the results into place.  */
3191     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
3192     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
3193 
3194     set_cc_op(s, CC_OP_FLAGS);
3195 
3196     /* result is in QREG_CC_N */
3197 }
3198 
3199 DISAS_INSN(addx_reg)
3200 {
3201     TCGv dest;
3202     TCGv src;
3203     int opsize;
3204 
3205     opsize = insn_opsize(insn);
3206 
3207     dest = gen_extend(DREG(insn, 9), opsize, 1);
3208     src = gen_extend(DREG(insn, 0), opsize, 1);
3209 
3210     gen_addx(s, src, dest, opsize);
3211 
3212     gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
3213 }
3214 
3215 DISAS_INSN(addx_mem)
3216 {
3217     TCGv src;
3218     TCGv addr_src;
3219     TCGv dest;
3220     TCGv addr_dest;
3221     int opsize;
3222 
3223     opsize = insn_opsize(insn);
3224 
3225     addr_src = AREG(insn, 0);
3226     tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(opsize));
3227     src = gen_load(s, opsize, addr_src, 1);
3228 
3229     addr_dest = AREG(insn, 9);
3230     tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(opsize));
3231     dest = gen_load(s, opsize, addr_dest, 1);
3232 
3233     gen_addx(s, src, dest, opsize);
3234 
3235     gen_store(s, opsize, addr_dest, QREG_CC_N);
3236 }
3237 
3238 static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
3239 {
3240     int count = (insn >> 9) & 7;
3241     int logical = insn & 8;
3242     int left = insn & 0x100;
3243     int bits = opsize_bytes(opsize) * 8;
3244     TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical);
3245 
3246     if (count == 0) {
3247         count = 8;
3248     }
3249 
3250     tcg_gen_movi_i32(QREG_CC_V, 0);
3251     if (left) {
3252         tcg_gen_shri_i32(QREG_CC_C, reg, bits - count);
3253         tcg_gen_shli_i32(QREG_CC_N, reg, count);
3254 
3255         /* Note that ColdFire always clears V (done above),
3256            while M68000 sets if the most significant bit is changed at
3257            any time during the shift operation */
3258         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
3259             /* if shift count >= bits, V is (reg != 0) */
3260             if (count >= bits) {
3261                 tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, reg, QREG_CC_V);
3262             } else {
3263                 TCGv t0 = tcg_temp_new();
3264                 tcg_gen_sari_i32(QREG_CC_V, reg, bits - 1);
3265                 tcg_gen_sari_i32(t0, reg, bits - count - 1);
3266                 tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, t0);
3267                 tcg_temp_free(t0);
3268             }
3269             tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
3270         }
3271     } else {
3272         tcg_gen_shri_i32(QREG_CC_C, reg, count - 1);
3273         if (logical) {
3274             tcg_gen_shri_i32(QREG_CC_N, reg, count);
3275         } else {
3276             tcg_gen_sari_i32(QREG_CC_N, reg, count);
3277         }
3278     }
3279 
3280     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
3281     tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
3282     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
3283     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
3284 
3285     gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N);
3286     set_cc_op(s, CC_OP_FLAGS);
3287 }
3288 
3289 static inline void shift_reg(DisasContext *s, uint16_t insn, int opsize)
3290 {
3291     int logical = insn & 8;
3292     int left = insn & 0x100;
3293     int bits = opsize_bytes(opsize) * 8;
3294     TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical);
3295     TCGv s32;
3296     TCGv_i64 t64, s64;
3297 
3298     t64 = tcg_temp_new_i64();
3299     s64 = tcg_temp_new_i64();
3300     s32 = tcg_temp_new();
3301 
3302     /* Note that m68k truncates the shift count modulo 64, not 32.
3303        In addition, a 64-bit shift makes it easy to find "the last
3304        bit shifted out", for the carry flag.  */
3305     tcg_gen_andi_i32(s32, DREG(insn, 9), 63);
3306     tcg_gen_extu_i32_i64(s64, s32);
3307     tcg_gen_extu_i32_i64(t64, reg);
3308 
3309     /* Optimistically set V=0.  Also used as a zero source below.  */
3310     tcg_gen_movi_i32(QREG_CC_V, 0);
3311     if (left) {
3312         tcg_gen_shl_i64(t64, t64, s64);
3313 
3314         if (opsize == OS_LONG) {
3315             tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64);
3316             /* Note that C=0 if shift count is 0, and we get that for free.  */
3317         } else {
3318             TCGv zero = tcg_const_i32(0);
3319             tcg_gen_extrl_i64_i32(QREG_CC_N, t64);
3320             tcg_gen_shri_i32(QREG_CC_C, QREG_CC_N, bits);
3321             tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
3322                                 s32, zero, zero, QREG_CC_C);
3323             tcg_temp_free(zero);
3324         }
3325         tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
3326 
3327         /* X = C, but only if the shift count was non-zero.  */
3328         tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V,
3329                             QREG_CC_C, QREG_CC_X);
3330 
3331         /* M68000 sets V if the most significant bit is changed at
3332          * any time during the shift operation.  Do this via creating
3333          * an extension of the sign bit, comparing, and discarding
3334          * the bits below the sign bit.  I.e.
3335          *     int64_t s = (intN_t)reg;
3336          *     int64_t t = (int64_t)(intN_t)reg << count;
3337          *     V = ((s ^ t) & (-1 << (bits - 1))) != 0
3338          */
3339         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
3340             TCGv_i64 tt = tcg_const_i64(32);
3341             /* if shift is greater than 32, use 32 */
3342             tcg_gen_movcond_i64(TCG_COND_GT, s64, s64, tt, tt, s64);
3343             tcg_temp_free_i64(tt);
3344             /* Sign extend the input to 64 bits; re-do the shift.  */
3345             tcg_gen_ext_i32_i64(t64, reg);
3346             tcg_gen_shl_i64(s64, t64, s64);
3347             /* Clear all bits that are unchanged.  */
3348             tcg_gen_xor_i64(t64, t64, s64);
3349             /* Ignore the bits below the sign bit.  */
3350             tcg_gen_andi_i64(t64, t64, -1ULL << (bits - 1));
3351             /* If any bits remain set, we have overflow.  */
3352             tcg_gen_setcondi_i64(TCG_COND_NE, t64, t64, 0);
3353             tcg_gen_extrl_i64_i32(QREG_CC_V, t64);
3354             tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
3355         }
3356     } else {
3357         tcg_gen_shli_i64(t64, t64, 32);
3358         if (logical) {
3359             tcg_gen_shr_i64(t64, t64, s64);
3360         } else {
3361             tcg_gen_sar_i64(t64, t64, s64);
3362         }
3363         tcg_gen_extr_i64_i32(QREG_CC_C, QREG_CC_N, t64);
3364 
3365         /* Note that C=0 if shift count is 0, and we get that for free.  */
3366         tcg_gen_shri_i32(QREG_CC_C, QREG_CC_C, 31);
3367 
3368         /* X = C, but only if the shift count was non-zero.  */
3369         tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V,
3370                             QREG_CC_C, QREG_CC_X);
3371     }
3372     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
3373     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
3374 
3375     tcg_temp_free(s32);
3376     tcg_temp_free_i64(s64);
3377     tcg_temp_free_i64(t64);
3378 
3379     /* Write back the result.  */
3380     gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N);
3381     set_cc_op(s, CC_OP_FLAGS);
3382 }
3383 
3384 DISAS_INSN(shift8_im)
3385 {
3386     shift_im(s, insn, OS_BYTE);
3387 }
3388 
3389 DISAS_INSN(shift16_im)
3390 {
3391     shift_im(s, insn, OS_WORD);
3392 }
3393 
3394 DISAS_INSN(shift_im)
3395 {
3396     shift_im(s, insn, OS_LONG);
3397 }
3398 
3399 DISAS_INSN(shift8_reg)
3400 {
3401     shift_reg(s, insn, OS_BYTE);
3402 }
3403 
3404 DISAS_INSN(shift16_reg)
3405 {
3406     shift_reg(s, insn, OS_WORD);
3407 }
3408 
3409 DISAS_INSN(shift_reg)
3410 {
3411     shift_reg(s, insn, OS_LONG);
3412 }
3413 
3414 DISAS_INSN(shift_mem)
3415 {
3416     int logical = insn & 8;
3417     int left = insn & 0x100;
3418     TCGv src;
3419     TCGv addr;
3420 
3421     SRC_EA(env, src, OS_WORD, !logical, &addr);
3422     tcg_gen_movi_i32(QREG_CC_V, 0);
3423     if (left) {
3424         tcg_gen_shri_i32(QREG_CC_C, src, 15);
3425         tcg_gen_shli_i32(QREG_CC_N, src, 1);
3426 
3427         /* Note that ColdFire always clears V,
3428            while M68000 sets if the most significant bit is changed at
3429            any time during the shift operation */
3430         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
3431             src = gen_extend(src, OS_WORD, 1);
3432             tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
3433         }
3434     } else {
3435         tcg_gen_mov_i32(QREG_CC_C, src);
3436         if (logical) {
3437             tcg_gen_shri_i32(QREG_CC_N, src, 1);
3438         } else {
3439             tcg_gen_sari_i32(QREG_CC_N, src, 1);
3440         }
3441     }
3442 
3443     gen_ext(QREG_CC_N, QREG_CC_N, OS_WORD, 1);
3444     tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
3445     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
3446     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
3447 
3448     DEST_EA(env, insn, OS_WORD, QREG_CC_N, &addr);
3449     set_cc_op(s, CC_OP_FLAGS);
3450 }
3451 
3452 static void rotate(TCGv reg, TCGv shift, int left, int size)
3453 {
3454     switch (size) {
3455     case 8:
3456         /* Replicate the 8-bit input so that a 32-bit rotate works.  */
3457         tcg_gen_ext8u_i32(reg, reg);
3458         tcg_gen_muli_i32(reg, reg, 0x01010101);
3459         goto do_long;
3460     case 16:
3461         /* Replicate the 16-bit input so that a 32-bit rotate works.  */
3462         tcg_gen_deposit_i32(reg, reg, reg, 16, 16);
3463         goto do_long;
3464     do_long:
3465     default:
3466         if (left) {
3467             tcg_gen_rotl_i32(reg, reg, shift);
3468         } else {
3469             tcg_gen_rotr_i32(reg, reg, shift);
3470         }
3471     }
3472 
3473     /* compute flags */
3474 
3475     switch (size) {
3476     case 8:
3477         tcg_gen_ext8s_i32(reg, reg);
3478         break;
3479     case 16:
3480         tcg_gen_ext16s_i32(reg, reg);
3481         break;
3482     default:
3483         break;
3484     }
3485 
3486     /* QREG_CC_X is not affected */
3487 
3488     tcg_gen_mov_i32(QREG_CC_N, reg);
3489     tcg_gen_mov_i32(QREG_CC_Z, reg);
3490 
3491     if (left) {
3492         tcg_gen_andi_i32(QREG_CC_C, reg, 1);
3493     } else {
3494         tcg_gen_shri_i32(QREG_CC_C, reg, 31);
3495     }
3496 
3497     tcg_gen_movi_i32(QREG_CC_V, 0); /* always cleared */
3498 }
3499 
3500 static void rotate_x_flags(TCGv reg, TCGv X, int size)
3501 {
3502     switch (size) {
3503     case 8:
3504         tcg_gen_ext8s_i32(reg, reg);
3505         break;
3506     case 16:
3507         tcg_gen_ext16s_i32(reg, reg);
3508         break;
3509     default:
3510         break;
3511     }
3512     tcg_gen_mov_i32(QREG_CC_N, reg);
3513     tcg_gen_mov_i32(QREG_CC_Z, reg);
3514     tcg_gen_mov_i32(QREG_CC_X, X);
3515     tcg_gen_mov_i32(QREG_CC_C, X);
3516     tcg_gen_movi_i32(QREG_CC_V, 0);
3517 }
3518 
3519 /* Result of rotate_x() is valid if 0 <= shift <= size */
3520 static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size)
3521 {
3522     TCGv X, shl, shr, shx, sz, zero;
3523 
3524     sz = tcg_const_i32(size);
3525 
3526     shr = tcg_temp_new();
3527     shl = tcg_temp_new();
3528     shx = tcg_temp_new();
3529     if (left) {
3530         tcg_gen_mov_i32(shl, shift);      /* shl = shift */
3531         tcg_gen_movi_i32(shr, size + 1);
3532         tcg_gen_sub_i32(shr, shr, shift); /* shr = size + 1 - shift */
3533         tcg_gen_subi_i32(shx, shift, 1);  /* shx = shift - 1 */
3534         /* shx = shx < 0 ? size : shx; */
3535         zero = tcg_const_i32(0);
3536         tcg_gen_movcond_i32(TCG_COND_LT, shx, shx, zero, sz, shx);
3537         tcg_temp_free(zero);
3538     } else {
3539         tcg_gen_mov_i32(shr, shift);      /* shr = shift */
3540         tcg_gen_movi_i32(shl, size + 1);
3541         tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */
3542         tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */
3543     }
3544 
3545     /* reg = (reg << shl) | (reg >> shr) | (x << shx); */
3546 
3547     tcg_gen_shl_i32(shl, reg, shl);
3548     tcg_gen_shr_i32(shr, reg, shr);
3549     tcg_gen_or_i32(reg, shl, shr);
3550     tcg_temp_free(shl);
3551     tcg_temp_free(shr);
3552     tcg_gen_shl_i32(shx, QREG_CC_X, shx);
3553     tcg_gen_or_i32(reg, reg, shx);
3554     tcg_temp_free(shx);
3555 
3556     /* X = (reg >> size) & 1 */
3557 
3558     X = tcg_temp_new();
3559     tcg_gen_shr_i32(X, reg, sz);
3560     tcg_gen_andi_i32(X, X, 1);
3561     tcg_temp_free(sz);
3562 
3563     return X;
3564 }
3565 
3566 /* Result of rotate32_x() is valid if 0 <= shift < 33 */
3567 static TCGv rotate32_x(TCGv reg, TCGv shift, int left)
3568 {
3569     TCGv_i64 t0, shift64;
3570     TCGv X, lo, hi, zero;
3571 
3572     shift64 = tcg_temp_new_i64();
3573     tcg_gen_extu_i32_i64(shift64, shift);
3574 
3575     t0 = tcg_temp_new_i64();
3576 
3577     X = tcg_temp_new();
3578     lo = tcg_temp_new();
3579     hi = tcg_temp_new();
3580 
3581     if (left) {
3582         /* create [reg:X:..] */
3583 
3584         tcg_gen_shli_i32(lo, QREG_CC_X, 31);
3585         tcg_gen_concat_i32_i64(t0, lo, reg);
3586 
3587         /* rotate */
3588 
3589         tcg_gen_rotl_i64(t0, t0, shift64);
3590         tcg_temp_free_i64(shift64);
3591 
3592         /* result is [reg:..:reg:X] */
3593 
3594         tcg_gen_extr_i64_i32(lo, hi, t0);
3595         tcg_gen_andi_i32(X, lo, 1);
3596 
3597         tcg_gen_shri_i32(lo, lo, 1);
3598     } else {
3599         /* create [..:X:reg] */
3600 
3601         tcg_gen_concat_i32_i64(t0, reg, QREG_CC_X);
3602 
3603         tcg_gen_rotr_i64(t0, t0, shift64);
3604         tcg_temp_free_i64(shift64);
3605 
3606         /* result is value: [X:reg:..:reg] */
3607 
3608         tcg_gen_extr_i64_i32(lo, hi, t0);
3609 
3610         /* extract X */
3611 
3612         tcg_gen_shri_i32(X, hi, 31);
3613 
3614         /* extract result */
3615 
3616         tcg_gen_shli_i32(hi, hi, 1);
3617     }
3618     tcg_temp_free_i64(t0);
3619     tcg_gen_or_i32(lo, lo, hi);
3620     tcg_temp_free(hi);
3621 
3622     /* if shift == 0, register and X are not affected */
3623 
3624     zero = tcg_const_i32(0);
3625     tcg_gen_movcond_i32(TCG_COND_EQ, X, shift, zero, QREG_CC_X, X);
3626     tcg_gen_movcond_i32(TCG_COND_EQ, reg, shift, zero, reg, lo);
3627     tcg_temp_free(zero);
3628     tcg_temp_free(lo);
3629 
3630     return X;
3631 }
3632 
3633 DISAS_INSN(rotate_im)
3634 {
3635     TCGv shift;
3636     int tmp;
3637     int left = (insn & 0x100);
3638 
3639     tmp = (insn >> 9) & 7;
3640     if (tmp == 0) {
3641         tmp = 8;
3642     }
3643 
3644     shift = tcg_const_i32(tmp);
3645     if (insn & 8) {
3646         rotate(DREG(insn, 0), shift, left, 32);
3647     } else {
3648         TCGv X = rotate32_x(DREG(insn, 0), shift, left);
3649         rotate_x_flags(DREG(insn, 0), X, 32);
3650         tcg_temp_free(X);
3651     }
3652     tcg_temp_free(shift);
3653 
3654     set_cc_op(s, CC_OP_FLAGS);
3655 }
3656 
3657 DISAS_INSN(rotate8_im)
3658 {
3659     int left = (insn & 0x100);
3660     TCGv reg;
3661     TCGv shift;
3662     int tmp;
3663 
3664     reg = gen_extend(DREG(insn, 0), OS_BYTE, 0);
3665 
3666     tmp = (insn >> 9) & 7;
3667     if (tmp == 0) {
3668         tmp = 8;
3669     }
3670 
3671     shift = tcg_const_i32(tmp);
3672     if (insn & 8) {
3673         rotate(reg, shift, left, 8);
3674     } else {
3675         TCGv X = rotate_x(reg, shift, left, 8);
3676         rotate_x_flags(reg, X, 8);
3677         tcg_temp_free(X);
3678     }
3679     tcg_temp_free(shift);
3680     gen_partset_reg(OS_BYTE, DREG(insn, 0), reg);
3681     set_cc_op(s, CC_OP_FLAGS);
3682 }
3683 
3684 DISAS_INSN(rotate16_im)
3685 {
3686     int left = (insn & 0x100);
3687     TCGv reg;
3688     TCGv shift;
3689     int tmp;
3690 
3691     reg = gen_extend(DREG(insn, 0), OS_WORD, 0);
3692     tmp = (insn >> 9) & 7;
3693     if (tmp == 0) {
3694         tmp = 8;
3695     }
3696 
3697     shift = tcg_const_i32(tmp);
3698     if (insn & 8) {
3699         rotate(reg, shift, left, 16);
3700     } else {
3701         TCGv X = rotate_x(reg, shift, left, 16);
3702         rotate_x_flags(reg, X, 16);
3703         tcg_temp_free(X);
3704     }
3705     tcg_temp_free(shift);
3706     gen_partset_reg(OS_WORD, DREG(insn, 0), reg);
3707     set_cc_op(s, CC_OP_FLAGS);
3708 }
3709 
3710 DISAS_INSN(rotate_reg)
3711 {
3712     TCGv reg;
3713     TCGv src;
3714     TCGv t0, t1;
3715     int left = (insn & 0x100);
3716 
3717     reg = DREG(insn, 0);
3718     src = DREG(insn, 9);
3719     /* shift in [0..63] */
3720     t0 = tcg_temp_new();
3721     tcg_gen_andi_i32(t0, src, 63);
3722     t1 = tcg_temp_new_i32();
3723     if (insn & 8) {
3724         tcg_gen_andi_i32(t1, src, 31);
3725         rotate(reg, t1, left, 32);
3726         /* if shift == 0, clear C */
3727         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
3728                             t0, QREG_CC_V /* 0 */,
3729                             QREG_CC_V /* 0 */, QREG_CC_C);
3730     } else {
3731         TCGv X;
3732         /* modulo 33 */
3733         tcg_gen_movi_i32(t1, 33);
3734         tcg_gen_remu_i32(t1, t0, t1);
3735         X = rotate32_x(DREG(insn, 0), t1, left);
3736         rotate_x_flags(DREG(insn, 0), X, 32);
3737         tcg_temp_free(X);
3738     }
3739     tcg_temp_free(t1);
3740     tcg_temp_free(t0);
3741     set_cc_op(s, CC_OP_FLAGS);
3742 }
3743 
3744 DISAS_INSN(rotate8_reg)
3745 {
3746     TCGv reg;
3747     TCGv src;
3748     TCGv t0, t1;
3749     int left = (insn & 0x100);
3750 
3751     reg = gen_extend(DREG(insn, 0), OS_BYTE, 0);
3752     src = DREG(insn, 9);
3753     /* shift in [0..63] */
3754     t0 = tcg_temp_new_i32();
3755     tcg_gen_andi_i32(t0, src, 63);
3756     t1 = tcg_temp_new_i32();
3757     if (insn & 8) {
3758         tcg_gen_andi_i32(t1, src, 7);
3759         rotate(reg, t1, left, 8);
3760         /* if shift == 0, clear C */
3761         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
3762                             t0, QREG_CC_V /* 0 */,
3763                             QREG_CC_V /* 0 */, QREG_CC_C);
3764     } else {
3765         TCGv X;
3766         /* modulo 9 */
3767         tcg_gen_movi_i32(t1, 9);
3768         tcg_gen_remu_i32(t1, t0, t1);
3769         X = rotate_x(reg, t1, left, 8);
3770         rotate_x_flags(reg, X, 8);
3771         tcg_temp_free(X);
3772     }
3773     tcg_temp_free(t1);
3774     tcg_temp_free(t0);
3775     gen_partset_reg(OS_BYTE, DREG(insn, 0), reg);
3776     set_cc_op(s, CC_OP_FLAGS);
3777 }
3778 
3779 DISAS_INSN(rotate16_reg)
3780 {
3781     TCGv reg;
3782     TCGv src;
3783     TCGv t0, t1;
3784     int left = (insn & 0x100);
3785 
3786     reg = gen_extend(DREG(insn, 0), OS_WORD, 0);
3787     src = DREG(insn, 9);
3788     /* shift in [0..63] */
3789     t0 = tcg_temp_new_i32();
3790     tcg_gen_andi_i32(t0, src, 63);
3791     t1 = tcg_temp_new_i32();
3792     if (insn & 8) {
3793         tcg_gen_andi_i32(t1, src, 15);
3794         rotate(reg, t1, left, 16);
3795         /* if shift == 0, clear C */
3796         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
3797                             t0, QREG_CC_V /* 0 */,
3798                             QREG_CC_V /* 0 */, QREG_CC_C);
3799     } else {
3800         TCGv X;
3801         /* modulo 17 */
3802         tcg_gen_movi_i32(t1, 17);
3803         tcg_gen_remu_i32(t1, t0, t1);
3804         X = rotate_x(reg, t1, left, 16);
3805         rotate_x_flags(reg, X, 16);
3806         tcg_temp_free(X);
3807     }
3808     tcg_temp_free(t1);
3809     tcg_temp_free(t0);
3810     gen_partset_reg(OS_WORD, DREG(insn, 0), reg);
3811     set_cc_op(s, CC_OP_FLAGS);
3812 }
3813 
3814 DISAS_INSN(rotate_mem)
3815 {
3816     TCGv src;
3817     TCGv addr;
3818     TCGv shift;
3819     int left = (insn & 0x100);
3820 
3821     SRC_EA(env, src, OS_WORD, 0, &addr);
3822 
3823     shift = tcg_const_i32(1);
3824     if (insn & 0x0200) {
3825         rotate(src, shift, left, 16);
3826     } else {
3827         TCGv X = rotate_x(src, shift, left, 16);
3828         rotate_x_flags(src, X, 16);
3829         tcg_temp_free(X);
3830     }
3831     tcg_temp_free(shift);
3832     DEST_EA(env, insn, OS_WORD, src, &addr);
3833     set_cc_op(s, CC_OP_FLAGS);
3834 }
3835 
3836 DISAS_INSN(bfext_reg)
3837 {
3838     int ext = read_im16(env, s);
3839     int is_sign = insn & 0x200;
3840     TCGv src = DREG(insn, 0);
3841     TCGv dst = DREG(ext, 12);
3842     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
3843     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
3844     int pos = 32 - ofs - len;        /* little bit-endian */
3845     TCGv tmp = tcg_temp_new();
3846     TCGv shift;
3847 
3848     /* In general, we're going to rotate the field so that it's at the
3849        top of the word and then right-shift by the compliment of the
3850        width to extend the field.  */
3851     if (ext & 0x20) {
3852         /* Variable width.  */
3853         if (ext & 0x800) {
3854             /* Variable offset.  */
3855             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
3856             tcg_gen_rotl_i32(tmp, src, tmp);
3857         } else {
3858             tcg_gen_rotli_i32(tmp, src, ofs);
3859         }
3860 
3861         shift = tcg_temp_new();
3862         tcg_gen_neg_i32(shift, DREG(ext, 0));
3863         tcg_gen_andi_i32(shift, shift, 31);
3864         tcg_gen_sar_i32(QREG_CC_N, tmp, shift);
3865         if (is_sign) {
3866             tcg_gen_mov_i32(dst, QREG_CC_N);
3867         } else {
3868             tcg_gen_shr_i32(dst, tmp, shift);
3869         }
3870         tcg_temp_free(shift);
3871     } else {
3872         /* Immediate width.  */
3873         if (ext & 0x800) {
3874             /* Variable offset */
3875             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
3876             tcg_gen_rotl_i32(tmp, src, tmp);
3877             src = tmp;
3878             pos = 32 - len;
3879         } else {
3880             /* Immediate offset.  If the field doesn't wrap around the
3881                end of the word, rely on (s)extract completely.  */
3882             if (pos < 0) {
3883                 tcg_gen_rotli_i32(tmp, src, ofs);
3884                 src = tmp;
3885                 pos = 32 - len;
3886             }
3887         }
3888 
3889         tcg_gen_sextract_i32(QREG_CC_N, src, pos, len);
3890         if (is_sign) {
3891             tcg_gen_mov_i32(dst, QREG_CC_N);
3892         } else {
3893             tcg_gen_extract_i32(dst, src, pos, len);
3894         }
3895     }
3896 
3897     tcg_temp_free(tmp);
3898     set_cc_op(s, CC_OP_LOGIC);
3899 }
3900 
3901 DISAS_INSN(bfext_mem)
3902 {
3903     int ext = read_im16(env, s);
3904     int is_sign = insn & 0x200;
3905     TCGv dest = DREG(ext, 12);
3906     TCGv addr, len, ofs;
3907 
3908     addr = gen_lea(env, s, insn, OS_UNSIZED);
3909     if (IS_NULL_QREG(addr)) {
3910         gen_addr_fault(s);
3911         return;
3912     }
3913 
3914     if (ext & 0x20) {
3915         len = DREG(ext, 0);
3916     } else {
3917         len = tcg_const_i32(extract32(ext, 0, 5));
3918     }
3919     if (ext & 0x800) {
3920         ofs = DREG(ext, 6);
3921     } else {
3922         ofs = tcg_const_i32(extract32(ext, 6, 5));
3923     }
3924 
3925     if (is_sign) {
3926         gen_helper_bfexts_mem(dest, cpu_env, addr, ofs, len);
3927         tcg_gen_mov_i32(QREG_CC_N, dest);
3928     } else {
3929         TCGv_i64 tmp = tcg_temp_new_i64();
3930         gen_helper_bfextu_mem(tmp, cpu_env, addr, ofs, len);
3931         tcg_gen_extr_i64_i32(dest, QREG_CC_N, tmp);
3932         tcg_temp_free_i64(tmp);
3933     }
3934     set_cc_op(s, CC_OP_LOGIC);
3935 
3936     if (!(ext & 0x20)) {
3937         tcg_temp_free(len);
3938     }
3939     if (!(ext & 0x800)) {
3940         tcg_temp_free(ofs);
3941     }
3942 }
3943 
3944 DISAS_INSN(bfop_reg)
3945 {
3946     int ext = read_im16(env, s);
3947     TCGv src = DREG(insn, 0);
3948     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
3949     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
3950     TCGv mask, tofs, tlen;
3951 
3952     TCGV_UNUSED(tofs);
3953     TCGV_UNUSED(tlen);
3954     if ((insn & 0x0f00) == 0x0d00) { /* bfffo */
3955         tofs = tcg_temp_new();
3956         tlen = tcg_temp_new();
3957     }
3958 
3959     if ((ext & 0x820) == 0) {
3960         /* Immediate width and offset.  */
3961         uint32_t maski = 0x7fffffffu >> (len - 1);
3962         if (ofs + len <= 32) {
3963             tcg_gen_shli_i32(QREG_CC_N, src, ofs);
3964         } else {
3965             tcg_gen_rotli_i32(QREG_CC_N, src, ofs);
3966         }
3967         tcg_gen_andi_i32(QREG_CC_N, QREG_CC_N, ~maski);
3968         mask = tcg_const_i32(ror32(maski, ofs));
3969         if (!TCGV_IS_UNUSED(tofs)) {
3970             tcg_gen_movi_i32(tofs, ofs);
3971             tcg_gen_movi_i32(tlen, len);
3972         }
3973     } else {
3974         TCGv tmp = tcg_temp_new();
3975         if (ext & 0x20) {
3976             /* Variable width */
3977             tcg_gen_subi_i32(tmp, DREG(ext, 0), 1);
3978             tcg_gen_andi_i32(tmp, tmp, 31);
3979             mask = tcg_const_i32(0x7fffffffu);
3980             tcg_gen_shr_i32(mask, mask, tmp);
3981             if (!TCGV_IS_UNUSED(tlen)) {
3982                 tcg_gen_addi_i32(tlen, tmp, 1);
3983             }
3984         } else {
3985             /* Immediate width */
3986             mask = tcg_const_i32(0x7fffffffu >> (len - 1));
3987             if (!TCGV_IS_UNUSED(tlen)) {
3988                 tcg_gen_movi_i32(tlen, len);
3989             }
3990         }
3991         if (ext & 0x800) {
3992             /* Variable offset */
3993             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
3994             tcg_gen_rotl_i32(QREG_CC_N, src, tmp);
3995             tcg_gen_andc_i32(QREG_CC_N, QREG_CC_N, mask);
3996             tcg_gen_rotr_i32(mask, mask, tmp);
3997             if (!TCGV_IS_UNUSED(tofs)) {
3998                 tcg_gen_mov_i32(tofs, tmp);
3999             }
4000         } else {
4001             /* Immediate offset (and variable width) */
4002             tcg_gen_rotli_i32(QREG_CC_N, src, ofs);
4003             tcg_gen_andc_i32(QREG_CC_N, QREG_CC_N, mask);
4004             tcg_gen_rotri_i32(mask, mask, ofs);
4005             if (!TCGV_IS_UNUSED(tofs)) {
4006                 tcg_gen_movi_i32(tofs, ofs);
4007             }
4008         }
4009         tcg_temp_free(tmp);
4010     }
4011     set_cc_op(s, CC_OP_LOGIC);
4012 
4013     switch (insn & 0x0f00) {
4014     case 0x0a00: /* bfchg */
4015         tcg_gen_eqv_i32(src, src, mask);
4016         break;
4017     case 0x0c00: /* bfclr */
4018         tcg_gen_and_i32(src, src, mask);
4019         break;
4020     case 0x0d00: /* bfffo */
4021         gen_helper_bfffo_reg(DREG(ext, 12), QREG_CC_N, tofs, tlen);
4022         tcg_temp_free(tlen);
4023         tcg_temp_free(tofs);
4024         break;
4025     case 0x0e00: /* bfset */
4026         tcg_gen_orc_i32(src, src, mask);
4027         break;
4028     case 0x0800: /* bftst */
4029         /* flags already set; no other work to do.  */
4030         break;
4031     default:
4032         g_assert_not_reached();
4033     }
4034     tcg_temp_free(mask);
4035 }
4036 
4037 DISAS_INSN(bfop_mem)
4038 {
4039     int ext = read_im16(env, s);
4040     TCGv addr, len, ofs;
4041     TCGv_i64 t64;
4042 
4043     addr = gen_lea(env, s, insn, OS_UNSIZED);
4044     if (IS_NULL_QREG(addr)) {
4045         gen_addr_fault(s);
4046         return;
4047     }
4048 
4049     if (ext & 0x20) {
4050         len = DREG(ext, 0);
4051     } else {
4052         len = tcg_const_i32(extract32(ext, 0, 5));
4053     }
4054     if (ext & 0x800) {
4055         ofs = DREG(ext, 6);
4056     } else {
4057         ofs = tcg_const_i32(extract32(ext, 6, 5));
4058     }
4059 
4060     switch (insn & 0x0f00) {
4061     case 0x0a00: /* bfchg */
4062         gen_helper_bfchg_mem(QREG_CC_N, cpu_env, addr, ofs, len);
4063         break;
4064     case 0x0c00: /* bfclr */
4065         gen_helper_bfclr_mem(QREG_CC_N, cpu_env, addr, ofs, len);
4066         break;
4067     case 0x0d00: /* bfffo */
4068         t64 = tcg_temp_new_i64();
4069         gen_helper_bfffo_mem(t64, cpu_env, addr, ofs, len);
4070         tcg_gen_extr_i64_i32(DREG(ext, 12), QREG_CC_N, t64);
4071         tcg_temp_free_i64(t64);
4072         break;
4073     case 0x0e00: /* bfset */
4074         gen_helper_bfset_mem(QREG_CC_N, cpu_env, addr, ofs, len);
4075         break;
4076     case 0x0800: /* bftst */
4077         gen_helper_bfexts_mem(QREG_CC_N, cpu_env, addr, ofs, len);
4078         break;
4079     default:
4080         g_assert_not_reached();
4081     }
4082     set_cc_op(s, CC_OP_LOGIC);
4083 
4084     if (!(ext & 0x20)) {
4085         tcg_temp_free(len);
4086     }
4087     if (!(ext & 0x800)) {
4088         tcg_temp_free(ofs);
4089     }
4090 }
4091 
4092 DISAS_INSN(bfins_reg)
4093 {
4094     int ext = read_im16(env, s);
4095     TCGv dst = DREG(insn, 0);
4096     TCGv src = DREG(ext, 12);
4097     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
4098     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
4099     int pos = 32 - ofs - len;        /* little bit-endian */
4100     TCGv tmp;
4101 
4102     tmp = tcg_temp_new();
4103 
4104     if (ext & 0x20) {
4105         /* Variable width */
4106         tcg_gen_neg_i32(tmp, DREG(ext, 0));
4107         tcg_gen_andi_i32(tmp, tmp, 31);
4108         tcg_gen_shl_i32(QREG_CC_N, src, tmp);
4109     } else {
4110         /* Immediate width */
4111         tcg_gen_shli_i32(QREG_CC_N, src, 32 - len);
4112     }
4113     set_cc_op(s, CC_OP_LOGIC);
4114 
4115     /* Immediate width and offset */
4116     if ((ext & 0x820) == 0) {
4117         /* Check for suitability for deposit.  */
4118         if (pos >= 0) {
4119             tcg_gen_deposit_i32(dst, dst, src, pos, len);
4120         } else {
4121             uint32_t maski = -2U << (len - 1);
4122             uint32_t roti = (ofs + len) & 31;
4123             tcg_gen_andi_i32(tmp, src, ~maski);
4124             tcg_gen_rotri_i32(tmp, tmp, roti);
4125             tcg_gen_andi_i32(dst, dst, ror32(maski, roti));
4126             tcg_gen_or_i32(dst, dst, tmp);
4127         }
4128     } else {
4129         TCGv mask = tcg_temp_new();
4130         TCGv rot = tcg_temp_new();
4131 
4132         if (ext & 0x20) {
4133             /* Variable width */
4134             tcg_gen_subi_i32(rot, DREG(ext, 0), 1);
4135             tcg_gen_andi_i32(rot, rot, 31);
4136             tcg_gen_movi_i32(mask, -2);
4137             tcg_gen_shl_i32(mask, mask, rot);
4138             tcg_gen_mov_i32(rot, DREG(ext, 0));
4139             tcg_gen_andc_i32(tmp, src, mask);
4140         } else {
4141             /* Immediate width (variable offset) */
4142             uint32_t maski = -2U << (len - 1);
4143             tcg_gen_andi_i32(tmp, src, ~maski);
4144             tcg_gen_movi_i32(mask, maski);
4145             tcg_gen_movi_i32(rot, len & 31);
4146         }
4147         if (ext & 0x800) {
4148             /* Variable offset */
4149             tcg_gen_add_i32(rot, rot, DREG(ext, 6));
4150         } else {
4151             /* Immediate offset (variable width) */
4152             tcg_gen_addi_i32(rot, rot, ofs);
4153         }
4154         tcg_gen_andi_i32(rot, rot, 31);
4155         tcg_gen_rotr_i32(mask, mask, rot);
4156         tcg_gen_rotr_i32(tmp, tmp, rot);
4157         tcg_gen_and_i32(dst, dst, mask);
4158         tcg_gen_or_i32(dst, dst, tmp);
4159 
4160         tcg_temp_free(rot);
4161         tcg_temp_free(mask);
4162     }
4163     tcg_temp_free(tmp);
4164 }
4165 
4166 DISAS_INSN(bfins_mem)
4167 {
4168     int ext = read_im16(env, s);
4169     TCGv src = DREG(ext, 12);
4170     TCGv addr, len, ofs;
4171 
4172     addr = gen_lea(env, s, insn, OS_UNSIZED);
4173     if (IS_NULL_QREG(addr)) {
4174         gen_addr_fault(s);
4175         return;
4176     }
4177 
4178     if (ext & 0x20) {
4179         len = DREG(ext, 0);
4180     } else {
4181         len = tcg_const_i32(extract32(ext, 0, 5));
4182     }
4183     if (ext & 0x800) {
4184         ofs = DREG(ext, 6);
4185     } else {
4186         ofs = tcg_const_i32(extract32(ext, 6, 5));
4187     }
4188 
4189     gen_helper_bfins_mem(QREG_CC_N, cpu_env, addr, src, ofs, len);
4190     set_cc_op(s, CC_OP_LOGIC);
4191 
4192     if (!(ext & 0x20)) {
4193         tcg_temp_free(len);
4194     }
4195     if (!(ext & 0x800)) {
4196         tcg_temp_free(ofs);
4197     }
4198 }
4199 
4200 DISAS_INSN(ff1)
4201 {
4202     TCGv reg;
4203     reg = DREG(insn, 0);
4204     gen_logic_cc(s, reg, OS_LONG);
4205     gen_helper_ff1(reg, reg);
4206 }
4207 
4208 static TCGv gen_get_sr(DisasContext *s)
4209 {
4210     TCGv ccr;
4211     TCGv sr;
4212 
4213     ccr = gen_get_ccr(s);
4214     sr = tcg_temp_new();
4215     tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
4216     tcg_gen_or_i32(sr, sr, ccr);
4217     return sr;
4218 }
4219 
4220 DISAS_INSN(strldsr)
4221 {
4222     uint16_t ext;
4223     uint32_t addr;
4224 
4225     addr = s->pc - 2;
4226     ext = read_im16(env, s);
4227     if (ext != 0x46FC) {
4228         gen_exception(s, addr, EXCP_UNSUPPORTED);
4229         return;
4230     }
4231     ext = read_im16(env, s);
4232     if (IS_USER(s) || (ext & SR_S) == 0) {
4233         gen_exception(s, addr, EXCP_PRIVILEGE);
4234         return;
4235     }
4236     gen_push(s, gen_get_sr(s));
4237     gen_set_sr_im(s, ext, 0);
4238 }
4239 
4240 DISAS_INSN(move_from_sr)
4241 {
4242     TCGv sr;
4243 
4244     if (IS_USER(s) && !m68k_feature(env, M68K_FEATURE_M68000)) {
4245         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4246         return;
4247     }
4248     sr = gen_get_sr(s);
4249     DEST_EA(env, insn, OS_WORD, sr, NULL);
4250 }
4251 
4252 DISAS_INSN(move_to_sr)
4253 {
4254     if (IS_USER(s)) {
4255         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4256         return;
4257     }
4258     gen_set_sr(env, s, insn, 0);
4259     gen_lookup_tb(s);
4260 }
4261 
4262 DISAS_INSN(move_from_usp)
4263 {
4264     if (IS_USER(s)) {
4265         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4266         return;
4267     }
4268     tcg_gen_ld_i32(AREG(insn, 0), cpu_env,
4269                    offsetof(CPUM68KState, sp[M68K_USP]));
4270 }
4271 
4272 DISAS_INSN(move_to_usp)
4273 {
4274     if (IS_USER(s)) {
4275         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4276         return;
4277     }
4278     tcg_gen_st_i32(AREG(insn, 0), cpu_env,
4279                    offsetof(CPUM68KState, sp[M68K_USP]));
4280 }
4281 
4282 DISAS_INSN(halt)
4283 {
4284     gen_exception(s, s->pc, EXCP_HALT_INSN);
4285 }
4286 
4287 DISAS_INSN(stop)
4288 {
4289     uint16_t ext;
4290 
4291     if (IS_USER(s)) {
4292         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4293         return;
4294     }
4295 
4296     ext = read_im16(env, s);
4297 
4298     gen_set_sr_im(s, ext, 0);
4299     tcg_gen_movi_i32(cpu_halted, 1);
4300     gen_exception(s, s->pc, EXCP_HLT);
4301 }
4302 
4303 DISAS_INSN(rte)
4304 {
4305     if (IS_USER(s)) {
4306         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4307         return;
4308     }
4309     gen_exception(s, s->pc - 2, EXCP_RTE);
4310 }
4311 
4312 DISAS_INSN(movec)
4313 {
4314     uint16_t ext;
4315     TCGv reg;
4316 
4317     if (IS_USER(s)) {
4318         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4319         return;
4320     }
4321 
4322     ext = read_im16(env, s);
4323 
4324     if (ext & 0x8000) {
4325         reg = AREG(ext, 12);
4326     } else {
4327         reg = DREG(ext, 12);
4328     }
4329     gen_helper_movec(cpu_env, tcg_const_i32(ext & 0xfff), reg);
4330     gen_lookup_tb(s);
4331 }
4332 
4333 DISAS_INSN(intouch)
4334 {
4335     if (IS_USER(s)) {
4336         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4337         return;
4338     }
4339     /* ICache fetch.  Implement as no-op.  */
4340 }
4341 
4342 DISAS_INSN(cpushl)
4343 {
4344     if (IS_USER(s)) {
4345         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4346         return;
4347     }
4348     /* Cache push/invalidate.  Implement as no-op.  */
4349 }
4350 
4351 DISAS_INSN(wddata)
4352 {
4353     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4354 }
4355 
4356 DISAS_INSN(wdebug)
4357 {
4358     M68kCPU *cpu = m68k_env_get_cpu(env);
4359 
4360     if (IS_USER(s)) {
4361         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
4362         return;
4363     }
4364     /* TODO: Implement wdebug.  */
4365     cpu_abort(CPU(cpu), "WDEBUG not implemented");
4366 }
4367 
4368 DISAS_INSN(trap)
4369 {
4370     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
4371 }
4372 
4373 static void gen_load_fcr(DisasContext *s, TCGv res, int reg)
4374 {
4375     switch (reg) {
4376     case M68K_FPIAR:
4377         tcg_gen_movi_i32(res, 0);
4378         break;
4379     case M68K_FPSR:
4380         tcg_gen_ld_i32(res, cpu_env, offsetof(CPUM68KState, fpsr));
4381         break;
4382     case M68K_FPCR:
4383         tcg_gen_ld_i32(res, cpu_env, offsetof(CPUM68KState, fpcr));
4384         break;
4385     }
4386 }
4387 
4388 static void gen_store_fcr(DisasContext *s, TCGv val, int reg)
4389 {
4390     switch (reg) {
4391     case M68K_FPIAR:
4392         break;
4393     case M68K_FPSR:
4394         tcg_gen_st_i32(val, cpu_env, offsetof(CPUM68KState, fpsr));
4395         break;
4396     case M68K_FPCR:
4397         gen_helper_set_fpcr(cpu_env, val);
4398         break;
4399     }
4400 }
4401 
4402 static void gen_qemu_store_fcr(DisasContext *s, TCGv addr, int reg)
4403 {
4404     int index = IS_USER(s);
4405     TCGv tmp;
4406 
4407     tmp = tcg_temp_new();
4408     gen_load_fcr(s, tmp, reg);
4409     tcg_gen_qemu_st32(tmp, addr, index);
4410     tcg_temp_free(tmp);
4411 }
4412 
4413 static void gen_qemu_load_fcr(DisasContext *s, TCGv addr, int reg)
4414 {
4415     int index = IS_USER(s);
4416     TCGv tmp;
4417 
4418     tmp = tcg_temp_new();
4419     tcg_gen_qemu_ld32u(tmp, addr, index);
4420     gen_store_fcr(s, tmp, reg);
4421     tcg_temp_free(tmp);
4422 }
4423 
4424 
4425 static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
4426                              uint32_t insn, uint32_t ext)
4427 {
4428     int mask = (ext >> 10) & 7;
4429     int is_write = (ext >> 13) & 1;
4430     int mode = extract32(insn, 3, 3);
4431     int i;
4432     TCGv addr, tmp;
4433 
4434     switch (mode) {
4435     case 0: /* Dn */
4436         if (mask != M68K_FPIAR && mask != M68K_FPSR && mask != M68K_FPCR) {
4437             gen_exception(s, s->insn_pc, EXCP_ILLEGAL);
4438             return;
4439         }
4440         if (is_write) {
4441             gen_load_fcr(s, DREG(insn, 0), mask);
4442         } else {
4443             gen_store_fcr(s, DREG(insn, 0), mask);
4444         }
4445         return;
4446     case 1: /* An, only with FPIAR */
4447         if (mask != M68K_FPIAR) {
4448             gen_exception(s, s->insn_pc, EXCP_ILLEGAL);
4449             return;
4450         }
4451         if (is_write) {
4452             gen_load_fcr(s, AREG(insn, 0), mask);
4453         } else {
4454             gen_store_fcr(s, AREG(insn, 0), mask);
4455         }
4456         return;
4457     default:
4458         break;
4459     }
4460 
4461     tmp = gen_lea(env, s, insn, OS_LONG);
4462     if (IS_NULL_QREG(tmp)) {
4463         gen_addr_fault(s);
4464         return;
4465     }
4466 
4467     addr = tcg_temp_new();
4468     tcg_gen_mov_i32(addr, tmp);
4469 
4470     /* mask:
4471      *
4472      * 0b100 Floating-Point Control Register
4473      * 0b010 Floating-Point Status Register
4474      * 0b001 Floating-Point Instruction Address Register
4475      *
4476      */
4477 
4478     if (is_write && mode == 4) {
4479         for (i = 2; i >= 0; i--, mask >>= 1) {
4480             if (mask & 1) {
4481                 gen_qemu_store_fcr(s, addr, 1 << i);
4482                 if (mask != 1) {
4483                     tcg_gen_subi_i32(addr, addr, opsize_bytes(OS_LONG));
4484                 }
4485             }
4486        }
4487        tcg_gen_mov_i32(AREG(insn, 0), addr);
4488     } else {
4489         for (i = 0; i < 3; i++, mask >>= 1) {
4490             if (mask & 1) {
4491                 if (is_write) {
4492                     gen_qemu_store_fcr(s, addr, 1 << i);
4493                 } else {
4494                     gen_qemu_load_fcr(s, addr, 1 << i);
4495                 }
4496                 if (mask != 1 || mode == 3) {
4497                     tcg_gen_addi_i32(addr, addr, opsize_bytes(OS_LONG));
4498                 }
4499             }
4500         }
4501         if (mode == 3) {
4502             tcg_gen_mov_i32(AREG(insn, 0), addr);
4503         }
4504     }
4505     tcg_temp_free_i32(addr);
4506 }
4507 
4508 static void gen_op_fmovem(CPUM68KState *env, DisasContext *s,
4509                           uint32_t insn, uint32_t ext)
4510 {
4511     int opsize;
4512     TCGv addr, tmp;
4513     int mode = (ext >> 11) & 0x3;
4514     int is_load = ((ext & 0x2000) == 0);
4515 
4516     if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
4517         opsize = OS_EXTENDED;
4518     } else {
4519         opsize = OS_DOUBLE;  /* FIXME */
4520     }
4521 
4522     addr = gen_lea(env, s, insn, opsize);
4523     if (IS_NULL_QREG(addr)) {
4524         gen_addr_fault(s);
4525         return;
4526     }
4527 
4528     tmp = tcg_temp_new();
4529     if (mode & 0x1) {
4530         /* Dynamic register list */
4531         tcg_gen_ext8u_i32(tmp, DREG(ext, 4));
4532     } else {
4533         /* Static register list */
4534         tcg_gen_movi_i32(tmp, ext & 0xff);
4535     }
4536 
4537     if (!is_load && (mode & 2) == 0) {
4538         /* predecrement addressing mode
4539          * only available to store register to memory
4540          */
4541         if (opsize == OS_EXTENDED) {
4542             gen_helper_fmovemx_st_predec(tmp, cpu_env, addr, tmp);
4543         } else {
4544             gen_helper_fmovemd_st_predec(tmp, cpu_env, addr, tmp);
4545         }
4546     } else {
4547         /* postincrement addressing mode */
4548         if (opsize == OS_EXTENDED) {
4549             if (is_load) {
4550                 gen_helper_fmovemx_ld_postinc(tmp, cpu_env, addr, tmp);
4551             } else {
4552                 gen_helper_fmovemx_st_postinc(tmp, cpu_env, addr, tmp);
4553             }
4554         } else {
4555             if (is_load) {
4556                 gen_helper_fmovemd_ld_postinc(tmp, cpu_env, addr, tmp);
4557             } else {
4558                 gen_helper_fmovemd_st_postinc(tmp, cpu_env, addr, tmp);
4559             }
4560         }
4561     }
4562     if ((insn & 070) == 030 || (insn & 070) == 040) {
4563         tcg_gen_mov_i32(AREG(insn, 0), tmp);
4564     }
4565     tcg_temp_free(tmp);
4566 }
4567 
4568 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
4569    immediately before the next FP instruction is executed.  */
4570 DISAS_INSN(fpu)
4571 {
4572     uint16_t ext;
4573     int opmode;
4574     int opsize;
4575     TCGv_ptr cpu_src, cpu_dest;
4576 
4577     ext = read_im16(env, s);
4578     opmode = ext & 0x7f;
4579     switch ((ext >> 13) & 7) {
4580     case 0:
4581         break;
4582     case 1:
4583         goto undef;
4584     case 2:
4585         if (insn == 0xf200 && (ext & 0xfc00) == 0x5c00) {
4586             /* fmovecr */
4587             TCGv rom_offset = tcg_const_i32(opmode);
4588             cpu_dest = gen_fp_ptr(REG(ext, 7));
4589             gen_helper_fconst(cpu_env, cpu_dest, rom_offset);
4590             tcg_temp_free_ptr(cpu_dest);
4591             tcg_temp_free(rom_offset);
4592             return;
4593         }
4594         break;
4595     case 3: /* fmove out */
4596         cpu_src = gen_fp_ptr(REG(ext, 7));
4597         opsize = ext_opsize(ext, 10);
4598         if (gen_ea_fp(env, s, insn, opsize, cpu_src, EA_STORE) == -1) {
4599             gen_addr_fault(s);
4600         }
4601         gen_helper_ftst(cpu_env, cpu_src);
4602         tcg_temp_free_ptr(cpu_src);
4603         return;
4604     case 4: /* fmove to control register.  */
4605     case 5: /* fmove from control register.  */
4606         gen_op_fmove_fcr(env, s, insn, ext);
4607         return;
4608     case 6: /* fmovem */
4609     case 7:
4610         if ((ext & 0x1000) == 0 && !m68k_feature(s->env, M68K_FEATURE_FPU)) {
4611             goto undef;
4612         }
4613         gen_op_fmovem(env, s, insn, ext);
4614         return;
4615     }
4616     if (ext & (1 << 14)) {
4617         /* Source effective address.  */
4618         opsize = ext_opsize(ext, 10);
4619         cpu_src = gen_fp_result_ptr();
4620         if (gen_ea_fp(env, s, insn, opsize, cpu_src, EA_LOADS) == -1) {
4621             gen_addr_fault(s);
4622             return;
4623         }
4624     } else {
4625         /* Source register.  */
4626         opsize = OS_EXTENDED;
4627         cpu_src = gen_fp_ptr(REG(ext, 10));
4628     }
4629     cpu_dest = gen_fp_ptr(REG(ext, 7));
4630     switch (opmode) {
4631     case 0: /* fmove */
4632         gen_fp_move(cpu_dest, cpu_src);
4633         break;
4634     case 0x40: /* fsmove */
4635         gen_helper_fsround(cpu_env, cpu_dest, cpu_src);
4636         break;
4637     case 0x44: /* fdmove */
4638         gen_helper_fdround(cpu_env, cpu_dest, cpu_src);
4639         break;
4640     case 1: /* fint */
4641         gen_helper_firound(cpu_env, cpu_dest, cpu_src);
4642         break;
4643     case 3: /* fintrz */
4644         gen_helper_fitrunc(cpu_env, cpu_dest, cpu_src);
4645         break;
4646     case 4: /* fsqrt */
4647         gen_helper_fsqrt(cpu_env, cpu_dest, cpu_src);
4648         break;
4649     case 0x41: /* fssqrt */
4650         gen_helper_fssqrt(cpu_env, cpu_dest, cpu_src);
4651         break;
4652     case 0x45: /* fdsqrt */
4653         gen_helper_fdsqrt(cpu_env, cpu_dest, cpu_src);
4654         break;
4655     case 0x18: /* fabs */
4656         gen_helper_fabs(cpu_env, cpu_dest, cpu_src);
4657         break;
4658     case 0x58: /* fsabs */
4659         gen_helper_fsabs(cpu_env, cpu_dest, cpu_src);
4660         break;
4661     case 0x5c: /* fdabs */
4662         gen_helper_fdabs(cpu_env, cpu_dest, cpu_src);
4663         break;
4664     case 0x1a: /* fneg */
4665         gen_helper_fneg(cpu_env, cpu_dest, cpu_src);
4666         break;
4667     case 0x5a: /* fsneg */
4668         gen_helper_fsneg(cpu_env, cpu_dest, cpu_src);
4669         break;
4670     case 0x5e: /* fdneg */
4671         gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
4672         break;
4673     case 0x20: /* fdiv */
4674         gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
4675         break;
4676     case 0x60: /* fsdiv */
4677         gen_helper_fsdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
4678         break;
4679     case 0x64: /* fddiv */
4680         gen_helper_fddiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
4681         break;
4682     case 0x22: /* fadd */
4683         gen_helper_fadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
4684         break;
4685     case 0x62: /* fsadd */
4686         gen_helper_fsadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
4687         break;
4688     case 0x66: /* fdadd */
4689         gen_helper_fdadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
4690         break;
4691     case 0x23: /* fmul */
4692         gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
4693         break;
4694     case 0x63: /* fsmul */
4695         gen_helper_fsmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
4696         break;
4697     case 0x67: /* fdmul */
4698         gen_helper_fdmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
4699         break;
4700     case 0x24: /* fsgldiv */
4701         gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
4702         break;
4703     case 0x27: /* fsglmul */
4704         gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
4705         break;
4706     case 0x28: /* fsub */
4707         gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
4708         break;
4709     case 0x68: /* fssub */
4710         gen_helper_fssub(cpu_env, cpu_dest, cpu_src, cpu_dest);
4711         break;
4712     case 0x6c: /* fdsub */
4713         gen_helper_fdsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
4714         break;
4715     case 0x38: /* fcmp */
4716         gen_helper_fcmp(cpu_env, cpu_src, cpu_dest);
4717         return;
4718     case 0x3a: /* ftst */
4719         gen_helper_ftst(cpu_env, cpu_src);
4720         return;
4721     default:
4722         goto undef;
4723     }
4724     tcg_temp_free_ptr(cpu_src);
4725     gen_helper_ftst(cpu_env, cpu_dest);
4726     tcg_temp_free_ptr(cpu_dest);
4727     return;
4728 undef:
4729     /* FIXME: Is this right for offset addressing modes?  */
4730     s->pc -= 2;
4731     disas_undef_fpu(env, s, insn);
4732 }
4733 
4734 static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
4735 {
4736     TCGv fpsr;
4737 
4738     c->g1 = 1;
4739     c->v2 = tcg_const_i32(0);
4740     c->g2 = 0;
4741     /* TODO: Raise BSUN exception.  */
4742     fpsr = tcg_temp_new();
4743     gen_load_fcr(s, fpsr, M68K_FPSR);
4744     switch (cond) {
4745     case 0:  /* False */
4746     case 16: /* Signaling False */
4747         c->v1 = c->v2;
4748         c->tcond = TCG_COND_NEVER;
4749         break;
4750     case 1:  /* EQual Z */
4751     case 17: /* Signaling EQual Z */
4752         c->v1 = tcg_temp_new();
4753         c->g1 = 0;
4754         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
4755         c->tcond = TCG_COND_NE;
4756         break;
4757     case 2:  /* Ordered Greater Than !(A || Z || N) */
4758     case 18: /* Greater Than !(A || Z || N) */
4759         c->v1 = tcg_temp_new();
4760         c->g1 = 0;
4761         tcg_gen_andi_i32(c->v1, fpsr,
4762                          FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
4763         c->tcond = TCG_COND_EQ;
4764         break;
4765     case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
4766     case 19: /* Greater than or Equal Z || !(A || N) */
4767         c->v1 = tcg_temp_new();
4768         c->g1 = 0;
4769         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
4770         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
4771         tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
4772         tcg_gen_or_i32(c->v1, c->v1, fpsr);
4773         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
4774         c->tcond = TCG_COND_NE;
4775         break;
4776     case 4:  /* Ordered Less Than !(!N || A || Z); */
4777     case 20: /* Less Than !(!N || A || Z); */
4778         c->v1 = tcg_temp_new();
4779         c->g1 = 0;
4780         tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
4781         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
4782         c->tcond = TCG_COND_EQ;
4783         break;
4784     case 5:  /* Ordered Less than or Equal Z || (N && !A) */
4785     case 21: /* Less than or Equal Z || (N && !A) */
4786         c->v1 = tcg_temp_new();
4787         c->g1 = 0;
4788         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
4789         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
4790         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
4791         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_Z | FPSR_CC_N);
4792         c->tcond = TCG_COND_NE;
4793         break;
4794     case 6:  /* Ordered Greater or Less than !(A || Z) */
4795     case 22: /* Greater or Less than !(A || Z) */
4796         c->v1 = tcg_temp_new();
4797         c->g1 = 0;
4798         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
4799         c->tcond = TCG_COND_EQ;
4800         break;
4801     case 7:  /* Ordered !A */
4802     case 23: /* Greater, Less or Equal !A */
4803         c->v1 = tcg_temp_new();
4804         c->g1 = 0;
4805         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
4806         c->tcond = TCG_COND_EQ;
4807         break;
4808     case 8:  /* Unordered A */
4809     case 24: /* Not Greater, Less or Equal A */
4810         c->v1 = tcg_temp_new();
4811         c->g1 = 0;
4812         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
4813         c->tcond = TCG_COND_NE;
4814         break;
4815     case 9:  /* Unordered or Equal A || Z */
4816     case 25: /* Not Greater or Less then A || Z */
4817         c->v1 = tcg_temp_new();
4818         c->g1 = 0;
4819         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
4820         c->tcond = TCG_COND_NE;
4821         break;
4822     case 10: /* Unordered or Greater Than A || !(N || Z)) */
4823     case 26: /* Not Less or Equal A || !(N || Z)) */
4824         c->v1 = tcg_temp_new();
4825         c->g1 = 0;
4826         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
4827         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
4828         tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_A | FPSR_CC_N);
4829         tcg_gen_or_i32(c->v1, c->v1, fpsr);
4830         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
4831         c->tcond = TCG_COND_NE;
4832         break;
4833     case 11: /* Unordered or Greater or Equal A || Z || !N */
4834     case 27: /* Not Less Than A || Z || !N */
4835         c->v1 = tcg_temp_new();
4836         c->g1 = 0;
4837         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
4838         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
4839         c->tcond = TCG_COND_NE;
4840         break;
4841     case 12: /* Unordered or Less Than A || (N && !Z) */
4842     case 28: /* Not Greater than or Equal A || (N && !Z) */
4843         c->v1 = tcg_temp_new();
4844         c->g1 = 0;
4845         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
4846         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
4847         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
4848         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N);
4849         c->tcond = TCG_COND_NE;
4850         break;
4851     case 13: /* Unordered or Less or Equal A || Z || N */
4852     case 29: /* Not Greater Than A || Z || N */
4853         c->v1 = tcg_temp_new();
4854         c->g1 = 0;
4855         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
4856         c->tcond = TCG_COND_NE;
4857         break;
4858     case 14: /* Not Equal !Z */
4859     case 30: /* Signaling Not Equal !Z */
4860         c->v1 = tcg_temp_new();
4861         c->g1 = 0;
4862         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
4863         c->tcond = TCG_COND_EQ;
4864         break;
4865     case 15: /* True */
4866     case 31: /* Signaling True */
4867         c->v1 = c->v2;
4868         c->tcond = TCG_COND_ALWAYS;
4869         break;
4870     }
4871     tcg_temp_free(fpsr);
4872 }
4873 
4874 static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1)
4875 {
4876     DisasCompare c;
4877 
4878     gen_fcc_cond(&c, s, cond);
4879     tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
4880     free_cond(&c);
4881 }
4882 
4883 DISAS_INSN(fbcc)
4884 {
4885     uint32_t offset;
4886     uint32_t base;
4887     TCGLabel *l1;
4888 
4889     base = s->pc;
4890     offset = (int16_t)read_im16(env, s);
4891     if (insn & (1 << 6)) {
4892         offset = (offset << 16) | read_im16(env, s);
4893     }
4894 
4895     l1 = gen_new_label();
4896     update_cc_op(s);
4897     gen_fjmpcc(s, insn & 0x3f, l1);
4898     gen_jmp_tb(s, 0, s->pc);
4899     gen_set_label(l1);
4900     gen_jmp_tb(s, 1, base + offset);
4901 }
4902 
4903 DISAS_INSN(fscc)
4904 {
4905     DisasCompare c;
4906     int cond;
4907     TCGv tmp;
4908     uint16_t ext;
4909 
4910     ext = read_im16(env, s);
4911     cond = ext & 0x3f;
4912     gen_fcc_cond(&c, s, cond);
4913 
4914     tmp = tcg_temp_new();
4915     tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
4916     free_cond(&c);
4917 
4918     tcg_gen_neg_i32(tmp, tmp);
4919     DEST_EA(env, insn, OS_BYTE, tmp, NULL);
4920     tcg_temp_free(tmp);
4921 }
4922 
4923 DISAS_INSN(frestore)
4924 {
4925     M68kCPU *cpu = m68k_env_get_cpu(env);
4926 
4927     /* TODO: Implement frestore.  */
4928     cpu_abort(CPU(cpu), "FRESTORE not implemented");
4929 }
4930 
4931 DISAS_INSN(fsave)
4932 {
4933     M68kCPU *cpu = m68k_env_get_cpu(env);
4934 
4935     /* TODO: Implement fsave.  */
4936     cpu_abort(CPU(cpu), "FSAVE not implemented");
4937 }
4938 
4939 static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
4940 {
4941     TCGv tmp = tcg_temp_new();
4942     if (s->env->macsr & MACSR_FI) {
4943         if (upper)
4944             tcg_gen_andi_i32(tmp, val, 0xffff0000);
4945         else
4946             tcg_gen_shli_i32(tmp, val, 16);
4947     } else if (s->env->macsr & MACSR_SU) {
4948         if (upper)
4949             tcg_gen_sari_i32(tmp, val, 16);
4950         else
4951             tcg_gen_ext16s_i32(tmp, val);
4952     } else {
4953         if (upper)
4954             tcg_gen_shri_i32(tmp, val, 16);
4955         else
4956             tcg_gen_ext16u_i32(tmp, val);
4957     }
4958     return tmp;
4959 }
4960 
4961 static void gen_mac_clear_flags(void)
4962 {
4963     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
4964                      ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
4965 }
4966 
4967 DISAS_INSN(mac)
4968 {
4969     TCGv rx;
4970     TCGv ry;
4971     uint16_t ext;
4972     int acc;
4973     TCGv tmp;
4974     TCGv addr;
4975     TCGv loadval;
4976     int dual;
4977     TCGv saved_flags;
4978 
4979     if (!s->done_mac) {
4980         s->mactmp = tcg_temp_new_i64();
4981         s->done_mac = 1;
4982     }
4983 
4984     ext = read_im16(env, s);
4985 
4986     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
4987     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
4988     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
4989         disas_undef(env, s, insn);
4990         return;
4991     }
4992     if (insn & 0x30) {
4993         /* MAC with load.  */
4994         tmp = gen_lea(env, s, insn, OS_LONG);
4995         addr = tcg_temp_new();
4996         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
4997         /* Load the value now to ensure correct exception behavior.
4998            Perform writeback after reading the MAC inputs.  */
4999         loadval = gen_load(s, OS_LONG, addr, 0);
5000 
5001         acc ^= 1;
5002         rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
5003         ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
5004     } else {
5005         loadval = addr = NULL_QREG;
5006         rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
5007         ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
5008     }
5009 
5010     gen_mac_clear_flags();
5011 #if 0
5012     l1 = -1;
5013     /* Disabled because conditional branches clobber temporary vars.  */
5014     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
5015         /* Skip the multiply if we know we will ignore it.  */
5016         l1 = gen_new_label();
5017         tmp = tcg_temp_new();
5018         tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
5019         gen_op_jmp_nz32(tmp, l1);
5020     }
5021 #endif
5022 
5023     if ((ext & 0x0800) == 0) {
5024         /* Word.  */
5025         rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
5026         ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
5027     }
5028     if (s->env->macsr & MACSR_FI) {
5029         gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
5030     } else {
5031         if (s->env->macsr & MACSR_SU)
5032             gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
5033         else
5034             gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
5035         switch ((ext >> 9) & 3) {
5036         case 1:
5037             tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
5038             break;
5039         case 3:
5040             tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
5041             break;
5042         }
5043     }
5044 
5045     if (dual) {
5046         /* Save the overflow flag from the multiply.  */
5047         saved_flags = tcg_temp_new();
5048         tcg_gen_mov_i32(saved_flags, QREG_MACSR);
5049     } else {
5050         saved_flags = NULL_QREG;
5051     }
5052 
5053 #if 0
5054     /* Disabled because conditional branches clobber temporary vars.  */
5055     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
5056         /* Skip the accumulate if the value is already saturated.  */
5057         l1 = gen_new_label();
5058         tmp = tcg_temp_new();
5059         gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
5060         gen_op_jmp_nz32(tmp, l1);
5061     }
5062 #endif
5063 
5064     if (insn & 0x100)
5065         tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
5066     else
5067         tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
5068 
5069     if (s->env->macsr & MACSR_FI)
5070         gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
5071     else if (s->env->macsr & MACSR_SU)
5072         gen_helper_macsats(cpu_env, tcg_const_i32(acc));
5073     else
5074         gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
5075 
5076 #if 0
5077     /* Disabled because conditional branches clobber temporary vars.  */
5078     if (l1 != -1)
5079         gen_set_label(l1);
5080 #endif
5081 
5082     if (dual) {
5083         /* Dual accumulate variant.  */
5084         acc = (ext >> 2) & 3;
5085         /* Restore the overflow flag from the multiplier.  */
5086         tcg_gen_mov_i32(QREG_MACSR, saved_flags);
5087 #if 0
5088         /* Disabled because conditional branches clobber temporary vars.  */
5089         if ((s->env->macsr & MACSR_OMC) != 0) {
5090             /* Skip the accumulate if the value is already saturated.  */
5091             l1 = gen_new_label();
5092             tmp = tcg_temp_new();
5093             gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
5094             gen_op_jmp_nz32(tmp, l1);
5095         }
5096 #endif
5097         if (ext & 2)
5098             tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
5099         else
5100             tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
5101         if (s->env->macsr & MACSR_FI)
5102             gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
5103         else if (s->env->macsr & MACSR_SU)
5104             gen_helper_macsats(cpu_env, tcg_const_i32(acc));
5105         else
5106             gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
5107 #if 0
5108         /* Disabled because conditional branches clobber temporary vars.  */
5109         if (l1 != -1)
5110             gen_set_label(l1);
5111 #endif
5112     }
5113     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
5114 
5115     if (insn & 0x30) {
5116         TCGv rw;
5117         rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
5118         tcg_gen_mov_i32(rw, loadval);
5119         /* FIXME: Should address writeback happen with the masked or
5120            unmasked value?  */
5121         switch ((insn >> 3) & 7) {
5122         case 3: /* Post-increment.  */
5123             tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
5124             break;
5125         case 4: /* Pre-decrement.  */
5126             tcg_gen_mov_i32(AREG(insn, 0), addr);
5127         }
5128     }
5129 }
5130 
5131 DISAS_INSN(from_mac)
5132 {
5133     TCGv rx;
5134     TCGv_i64 acc;
5135     int accnum;
5136 
5137     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
5138     accnum = (insn >> 9) & 3;
5139     acc = MACREG(accnum);
5140     if (s->env->macsr & MACSR_FI) {
5141         gen_helper_get_macf(rx, cpu_env, acc);
5142     } else if ((s->env->macsr & MACSR_OMC) == 0) {
5143         tcg_gen_extrl_i64_i32(rx, acc);
5144     } else if (s->env->macsr & MACSR_SU) {
5145         gen_helper_get_macs(rx, acc);
5146     } else {
5147         gen_helper_get_macu(rx, acc);
5148     }
5149     if (insn & 0x40) {
5150         tcg_gen_movi_i64(acc, 0);
5151         tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
5152     }
5153 }
5154 
5155 DISAS_INSN(move_mac)
5156 {
5157     /* FIXME: This can be done without a helper.  */
5158     int src;
5159     TCGv dest;
5160     src = insn & 3;
5161     dest = tcg_const_i32((insn >> 9) & 3);
5162     gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
5163     gen_mac_clear_flags();
5164     gen_helper_mac_set_flags(cpu_env, dest);
5165 }
5166 
5167 DISAS_INSN(from_macsr)
5168 {
5169     TCGv reg;
5170 
5171     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
5172     tcg_gen_mov_i32(reg, QREG_MACSR);
5173 }
5174 
5175 DISAS_INSN(from_mask)
5176 {
5177     TCGv reg;
5178     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
5179     tcg_gen_mov_i32(reg, QREG_MAC_MASK);
5180 }
5181 
5182 DISAS_INSN(from_mext)
5183 {
5184     TCGv reg;
5185     TCGv acc;
5186     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
5187     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
5188     if (s->env->macsr & MACSR_FI)
5189         gen_helper_get_mac_extf(reg, cpu_env, acc);
5190     else
5191         gen_helper_get_mac_exti(reg, cpu_env, acc);
5192 }
5193 
5194 DISAS_INSN(macsr_to_ccr)
5195 {
5196     TCGv tmp = tcg_temp_new();
5197     tcg_gen_andi_i32(tmp, QREG_MACSR, 0xf);
5198     gen_helper_set_sr(cpu_env, tmp);
5199     tcg_temp_free(tmp);
5200     set_cc_op(s, CC_OP_FLAGS);
5201 }
5202 
5203 DISAS_INSN(to_mac)
5204 {
5205     TCGv_i64 acc;
5206     TCGv val;
5207     int accnum;
5208     accnum = (insn >> 9) & 3;
5209     acc = MACREG(accnum);
5210     SRC_EA(env, val, OS_LONG, 0, NULL);
5211     if (s->env->macsr & MACSR_FI) {
5212         tcg_gen_ext_i32_i64(acc, val);
5213         tcg_gen_shli_i64(acc, acc, 8);
5214     } else if (s->env->macsr & MACSR_SU) {
5215         tcg_gen_ext_i32_i64(acc, val);
5216     } else {
5217         tcg_gen_extu_i32_i64(acc, val);
5218     }
5219     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
5220     gen_mac_clear_flags();
5221     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
5222 }
5223 
5224 DISAS_INSN(to_macsr)
5225 {
5226     TCGv val;
5227     SRC_EA(env, val, OS_LONG, 0, NULL);
5228     gen_helper_set_macsr(cpu_env, val);
5229     gen_lookup_tb(s);
5230 }
5231 
5232 DISAS_INSN(to_mask)
5233 {
5234     TCGv val;
5235     SRC_EA(env, val, OS_LONG, 0, NULL);
5236     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
5237 }
5238 
5239 DISAS_INSN(to_mext)
5240 {
5241     TCGv val;
5242     TCGv acc;
5243     SRC_EA(env, val, OS_LONG, 0, NULL);
5244     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
5245     if (s->env->macsr & MACSR_FI)
5246         gen_helper_set_mac_extf(cpu_env, val, acc);
5247     else if (s->env->macsr & MACSR_SU)
5248         gen_helper_set_mac_exts(cpu_env, val, acc);
5249     else
5250         gen_helper_set_mac_extu(cpu_env, val, acc);
5251 }
5252 
5253 static disas_proc opcode_table[65536];
5254 
5255 static void
5256 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
5257 {
5258   int i;
5259   int from;
5260   int to;
5261 
5262   /* Sanity check.  All set bits must be included in the mask.  */
5263   if (opcode & ~mask) {
5264       fprintf(stderr,
5265               "qemu internal error: bogus opcode definition %04x/%04x\n",
5266               opcode, mask);
5267       abort();
5268   }
5269   /* This could probably be cleverer.  For now just optimize the case where
5270      the top bits are known.  */
5271   /* Find the first zero bit in the mask.  */
5272   i = 0x8000;
5273   while ((i & mask) != 0)
5274       i >>= 1;
5275   /* Iterate over all combinations of this and lower bits.  */
5276   if (i == 0)
5277       i = 1;
5278   else
5279       i <<= 1;
5280   from = opcode & ~(i - 1);
5281   to = from + i;
5282   for (i = from; i < to; i++) {
5283       if ((i & mask) == opcode)
5284           opcode_table[i] = proc;
5285   }
5286 }
5287 
5288 /* Register m68k opcode handlers.  Order is important.
5289    Later insn override earlier ones.  */
5290 void register_m68k_insns (CPUM68KState *env)
5291 {
5292     /* Build the opcode table only once to avoid
5293        multithreading issues. */
5294     if (opcode_table[0] != NULL) {
5295         return;
5296     }
5297 
5298     /* use BASE() for instruction available
5299      * for CF_ISA_A and M68000.
5300      */
5301 #define BASE(name, opcode, mask) \
5302     register_opcode(disas_##name, 0x##opcode, 0x##mask)
5303 #define INSN(name, opcode, mask, feature) do { \
5304     if (m68k_feature(env, M68K_FEATURE_##feature)) \
5305         BASE(name, opcode, mask); \
5306     } while(0)
5307     BASE(undef,     0000, 0000);
5308     INSN(arith_im,  0080, fff8, CF_ISA_A);
5309     INSN(arith_im,  0000, ff00, M68000);
5310     INSN(undef,     00c0, ffc0, M68000);
5311     INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
5312     BASE(bitop_reg, 0100, f1c0);
5313     BASE(bitop_reg, 0140, f1c0);
5314     BASE(bitop_reg, 0180, f1c0);
5315     BASE(bitop_reg, 01c0, f1c0);
5316     INSN(arith_im,  0280, fff8, CF_ISA_A);
5317     INSN(arith_im,  0200, ff00, M68000);
5318     INSN(undef,     02c0, ffc0, M68000);
5319     INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
5320     INSN(arith_im,  0480, fff8, CF_ISA_A);
5321     INSN(arith_im,  0400, ff00, M68000);
5322     INSN(undef,     04c0, ffc0, M68000);
5323     INSN(arith_im,  0600, ff00, M68000);
5324     INSN(undef,     06c0, ffc0, M68000);
5325     INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
5326     INSN(arith_im,  0680, fff8, CF_ISA_A);
5327     INSN(arith_im,  0c00, ff38, CF_ISA_A);
5328     INSN(arith_im,  0c00, ff00, M68000);
5329     BASE(bitop_im,  0800, ffc0);
5330     BASE(bitop_im,  0840, ffc0);
5331     BASE(bitop_im,  0880, ffc0);
5332     BASE(bitop_im,  08c0, ffc0);
5333     INSN(arith_im,  0a80, fff8, CF_ISA_A);
5334     INSN(arith_im,  0a00, ff00, M68000);
5335     INSN(cas,       0ac0, ffc0, CAS);
5336     INSN(cas,       0cc0, ffc0, CAS);
5337     INSN(cas,       0ec0, ffc0, CAS);
5338     INSN(cas2w,     0cfc, ffff, CAS);
5339     INSN(cas2l,     0efc, ffff, CAS);
5340     BASE(move,      1000, f000);
5341     BASE(move,      2000, f000);
5342     BASE(move,      3000, f000);
5343     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
5344     INSN(negx,      4080, fff8, CF_ISA_A);
5345     INSN(negx,      4000, ff00, M68000);
5346     INSN(undef,     40c0, ffc0, M68000);
5347     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
5348     INSN(move_from_sr, 40c0, ffc0, M68000);
5349     BASE(lea,       41c0, f1c0);
5350     BASE(clr,       4200, ff00);
5351     BASE(undef,     42c0, ffc0);
5352     INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
5353     INSN(move_from_ccr, 42c0, ffc0, M68000);
5354     INSN(neg,       4480, fff8, CF_ISA_A);
5355     INSN(neg,       4400, ff00, M68000);
5356     INSN(undef,     44c0, ffc0, M68000);
5357     BASE(move_to_ccr, 44c0, ffc0);
5358     INSN(not,       4680, fff8, CF_ISA_A);
5359     INSN(not,       4600, ff00, M68000);
5360     INSN(undef,     46c0, ffc0, M68000);
5361     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
5362     INSN(nbcd,      4800, ffc0, M68000);
5363     INSN(linkl,     4808, fff8, M68000);
5364     BASE(pea,       4840, ffc0);
5365     BASE(swap,      4840, fff8);
5366     INSN(bkpt,      4848, fff8, BKPT);
5367     INSN(movem,     48d0, fbf8, CF_ISA_A);
5368     INSN(movem,     48e8, fbf8, CF_ISA_A);
5369     INSN(movem,     4880, fb80, M68000);
5370     BASE(ext,       4880, fff8);
5371     BASE(ext,       48c0, fff8);
5372     BASE(ext,       49c0, fff8);
5373     BASE(tst,       4a00, ff00);
5374     INSN(tas,       4ac0, ffc0, CF_ISA_B);
5375     INSN(tas,       4ac0, ffc0, M68000);
5376     INSN(halt,      4ac8, ffff, CF_ISA_A);
5377     INSN(pulse,     4acc, ffff, CF_ISA_A);
5378     BASE(illegal,   4afc, ffff);
5379     INSN(mull,      4c00, ffc0, CF_ISA_A);
5380     INSN(mull,      4c00, ffc0, LONG_MULDIV);
5381     INSN(divl,      4c40, ffc0, CF_ISA_A);
5382     INSN(divl,      4c40, ffc0, LONG_MULDIV);
5383     INSN(sats,      4c80, fff8, CF_ISA_B);
5384     BASE(trap,      4e40, fff0);
5385     BASE(link,      4e50, fff8);
5386     BASE(unlk,      4e58, fff8);
5387     INSN(move_to_usp, 4e60, fff8, USP);
5388     INSN(move_from_usp, 4e68, fff8, USP);
5389     BASE(nop,       4e71, ffff);
5390     BASE(stop,      4e72, ffff);
5391     BASE(rte,       4e73, ffff);
5392     INSN(rtd,       4e74, ffff, RTD);
5393     BASE(rts,       4e75, ffff);
5394     INSN(movec,     4e7b, ffff, CF_ISA_A);
5395     BASE(jump,      4e80, ffc0);
5396     BASE(jump,      4ec0, ffc0);
5397     INSN(addsubq,   5000, f080, M68000);
5398     BASE(addsubq,   5080, f0c0);
5399     INSN(scc,       50c0, f0f8, CF_ISA_A); /* Scc.B Dx   */
5400     INSN(scc,       50c0, f0c0, M68000);   /* Scc.B <EA> */
5401     INSN(dbcc,      50c8, f0f8, M68000);
5402     INSN(tpf,       51f8, fff8, CF_ISA_A);
5403 
5404     /* Branch instructions.  */
5405     BASE(branch,    6000, f000);
5406     /* Disable long branch instructions, then add back the ones we want.  */
5407     BASE(undef,     60ff, f0ff); /* All long branches.  */
5408     INSN(branch,    60ff, f0ff, CF_ISA_B);
5409     INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
5410     INSN(branch,    60ff, ffff, BRAL);
5411     INSN(branch,    60ff, f0ff, BCCL);
5412 
5413     BASE(moveq,     7000, f100);
5414     INSN(mvzs,      7100, f100, CF_ISA_B);
5415     BASE(or,        8000, f000);
5416     BASE(divw,      80c0, f0c0);
5417     INSN(sbcd_reg,  8100, f1f8, M68000);
5418     INSN(sbcd_mem,  8108, f1f8, M68000);
5419     BASE(addsub,    9000, f000);
5420     INSN(undef,     90c0, f0c0, CF_ISA_A);
5421     INSN(subx_reg,  9180, f1f8, CF_ISA_A);
5422     INSN(subx_reg,  9100, f138, M68000);
5423     INSN(subx_mem,  9108, f138, M68000);
5424     INSN(suba,      91c0, f1c0, CF_ISA_A);
5425     INSN(suba,      90c0, f0c0, M68000);
5426 
5427     BASE(undef_mac, a000, f000);
5428     INSN(mac,       a000, f100, CF_EMAC);
5429     INSN(from_mac,  a180, f9b0, CF_EMAC);
5430     INSN(move_mac,  a110, f9fc, CF_EMAC);
5431     INSN(from_macsr,a980, f9f0, CF_EMAC);
5432     INSN(from_mask, ad80, fff0, CF_EMAC);
5433     INSN(from_mext, ab80, fbf0, CF_EMAC);
5434     INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
5435     INSN(to_mac,    a100, f9c0, CF_EMAC);
5436     INSN(to_macsr,  a900, ffc0, CF_EMAC);
5437     INSN(to_mext,   ab00, fbc0, CF_EMAC);
5438     INSN(to_mask,   ad00, ffc0, CF_EMAC);
5439 
5440     INSN(mov3q,     a140, f1c0, CF_ISA_B);
5441     INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
5442     INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
5443     INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
5444     INSN(cmp,       b080, f1c0, CF_ISA_A);
5445     INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
5446     INSN(cmp,       b000, f100, M68000);
5447     INSN(eor,       b100, f100, M68000);
5448     INSN(cmpm,      b108, f138, M68000);
5449     INSN(cmpa,      b0c0, f0c0, M68000);
5450     INSN(eor,       b180, f1c0, CF_ISA_A);
5451     BASE(and,       c000, f000);
5452     INSN(exg_dd,    c140, f1f8, M68000);
5453     INSN(exg_aa,    c148, f1f8, M68000);
5454     INSN(exg_da,    c188, f1f8, M68000);
5455     BASE(mulw,      c0c0, f0c0);
5456     INSN(abcd_reg,  c100, f1f8, M68000);
5457     INSN(abcd_mem,  c108, f1f8, M68000);
5458     BASE(addsub,    d000, f000);
5459     INSN(undef,     d0c0, f0c0, CF_ISA_A);
5460     INSN(addx_reg,      d180, f1f8, CF_ISA_A);
5461     INSN(addx_reg,  d100, f138, M68000);
5462     INSN(addx_mem,  d108, f138, M68000);
5463     INSN(adda,      d1c0, f1c0, CF_ISA_A);
5464     INSN(adda,      d0c0, f0c0, M68000);
5465     INSN(shift_im,  e080, f0f0, CF_ISA_A);
5466     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
5467     INSN(shift8_im, e000, f0f0, M68000);
5468     INSN(shift16_im, e040, f0f0, M68000);
5469     INSN(shift_im,  e080, f0f0, M68000);
5470     INSN(shift8_reg, e020, f0f0, M68000);
5471     INSN(shift16_reg, e060, f0f0, M68000);
5472     INSN(shift_reg, e0a0, f0f0, M68000);
5473     INSN(shift_mem, e0c0, fcc0, M68000);
5474     INSN(rotate_im, e090, f0f0, M68000);
5475     INSN(rotate8_im, e010, f0f0, M68000);
5476     INSN(rotate16_im, e050, f0f0, M68000);
5477     INSN(rotate_reg, e0b0, f0f0, M68000);
5478     INSN(rotate8_reg, e030, f0f0, M68000);
5479     INSN(rotate16_reg, e070, f0f0, M68000);
5480     INSN(rotate_mem, e4c0, fcc0, M68000);
5481     INSN(bfext_mem, e9c0, fdc0, BITFIELD);  /* bfextu & bfexts */
5482     INSN(bfext_reg, e9c0, fdf8, BITFIELD);
5483     INSN(bfins_mem, efc0, ffc0, BITFIELD);
5484     INSN(bfins_reg, efc0, fff8, BITFIELD);
5485     INSN(bfop_mem, eac0, ffc0, BITFIELD);   /* bfchg */
5486     INSN(bfop_reg, eac0, fff8, BITFIELD);   /* bfchg */
5487     INSN(bfop_mem, ecc0, ffc0, BITFIELD);   /* bfclr */
5488     INSN(bfop_reg, ecc0, fff8, BITFIELD);   /* bfclr */
5489     INSN(bfop_mem, edc0, ffc0, BITFIELD);   /* bfffo */
5490     INSN(bfop_reg, edc0, fff8, BITFIELD);   /* bfffo */
5491     INSN(bfop_mem, eec0, ffc0, BITFIELD);   /* bfset */
5492     INSN(bfop_reg, eec0, fff8, BITFIELD);   /* bfset */
5493     INSN(bfop_mem, e8c0, ffc0, BITFIELD);   /* bftst */
5494     INSN(bfop_reg, e8c0, fff8, BITFIELD);   /* bftst */
5495     BASE(undef_fpu, f000, f000);
5496     INSN(fpu,       f200, ffc0, CF_FPU);
5497     INSN(fbcc,      f280, ffc0, CF_FPU);
5498     INSN(frestore,  f340, ffc0, CF_FPU);
5499     INSN(fsave,     f300, ffc0, CF_FPU);
5500     INSN(fpu,       f200, ffc0, FPU);
5501     INSN(fscc,      f240, ffc0, FPU);
5502     INSN(fbcc,      f280, ff80, FPU);
5503     INSN(frestore,  f340, ffc0, FPU);
5504     INSN(fsave,     f300, ffc0, FPU);
5505     INSN(intouch,   f340, ffc0, CF_ISA_A);
5506     INSN(cpushl,    f428, ff38, CF_ISA_A);
5507     INSN(wddata,    fb00, ff00, CF_ISA_A);
5508     INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
5509 #undef INSN
5510 }
5511 
5512 /* ??? Some of this implementation is not exception safe.  We should always
5513    write back the result to memory before setting the condition codes.  */
5514 static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
5515 {
5516     uint16_t insn = read_im16(env, s);
5517     opcode_table[insn](env, s, insn);
5518     do_writebacks(s);
5519 }
5520 
5521 /* generate intermediate code for basic block 'tb'.  */
5522 void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
5523 {
5524     M68kCPU *cpu = m68k_env_get_cpu(env);
5525     CPUState *cs = CPU(cpu);
5526     DisasContext dc1, *dc = &dc1;
5527     target_ulong pc_start;
5528     int pc_offset;
5529     int num_insns;
5530     int max_insns;
5531 
5532     /* generate intermediate code */
5533     pc_start = tb->pc;
5534 
5535     dc->tb = tb;
5536 
5537     dc->env = env;
5538     dc->is_jmp = DISAS_NEXT;
5539     dc->pc = pc_start;
5540     dc->cc_op = CC_OP_DYNAMIC;
5541     dc->cc_op_synced = 1;
5542     dc->singlestep_enabled = cs->singlestep_enabled;
5543     dc->user = (env->sr & SR_S) == 0;
5544     dc->done_mac = 0;
5545     dc->writeback_mask = 0;
5546     num_insns = 0;
5547     max_insns = tb->cflags & CF_COUNT_MASK;
5548     if (max_insns == 0) {
5549         max_insns = CF_COUNT_MASK;
5550     }
5551     if (max_insns > TCG_MAX_INSNS) {
5552         max_insns = TCG_MAX_INSNS;
5553     }
5554 
5555     gen_tb_start(tb);
5556     do {
5557         pc_offset = dc->pc - pc_start;
5558         gen_throws_exception = NULL;
5559         tcg_gen_insn_start(dc->pc, dc->cc_op);
5560         num_insns++;
5561 
5562         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
5563             gen_exception(dc, dc->pc, EXCP_DEBUG);
5564             dc->is_jmp = DISAS_JUMP;
5565             /* The address covered by the breakpoint must be included in
5566                [tb->pc, tb->pc + tb->size) in order to for it to be
5567                properly cleared -- thus we increment the PC here so that
5568                the logic setting tb->size below does the right thing.  */
5569             dc->pc += 2;
5570             break;
5571         }
5572 
5573         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
5574             gen_io_start();
5575         }
5576 
5577         dc->insn_pc = dc->pc;
5578 	disas_m68k_insn(env, dc);
5579     } while (!dc->is_jmp && !tcg_op_buf_full() &&
5580              !cs->singlestep_enabled &&
5581              !singlestep &&
5582              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
5583              num_insns < max_insns);
5584 
5585     if (tb->cflags & CF_LAST_IO)
5586         gen_io_end();
5587     if (unlikely(cs->singlestep_enabled)) {
5588         /* Make sure the pc is updated, and raise a debug exception.  */
5589         if (!dc->is_jmp) {
5590             update_cc_op(dc);
5591             tcg_gen_movi_i32(QREG_PC, dc->pc);
5592         }
5593         gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
5594     } else {
5595         switch(dc->is_jmp) {
5596         case DISAS_NEXT:
5597             update_cc_op(dc);
5598             gen_jmp_tb(dc, 0, dc->pc);
5599             break;
5600         default:
5601         case DISAS_JUMP:
5602         case DISAS_UPDATE:
5603             update_cc_op(dc);
5604             /* indicate that the hash table must be used to find the next TB */
5605             tcg_gen_exit_tb(0);
5606             break;
5607         case DISAS_TB_JUMP:
5608             /* nothing more to generate */
5609             break;
5610         }
5611     }
5612     gen_tb_end(tb, num_insns);
5613 
5614 #ifdef DEBUG_DISAS
5615     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
5616         && qemu_log_in_addr_range(pc_start)) {
5617         qemu_log_lock();
5618         qemu_log("----------------\n");
5619         qemu_log("IN: %s\n", lookup_symbol(pc_start));
5620         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
5621         qemu_log("\n");
5622         qemu_log_unlock();
5623     }
5624 #endif
5625     tb->size = dc->pc - pc_start;
5626     tb->icount = num_insns;
5627 }
5628 
5629 static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_t low)
5630 {
5631     floatx80 a = { .high = high, .low = low };
5632     union {
5633         float64 f64;
5634         double d;
5635     } u;
5636 
5637     u.f64 = floatx80_to_float64(a, &env->fp_status);
5638     return u.d;
5639 }
5640 
5641 void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
5642                          int flags)
5643 {
5644     M68kCPU *cpu = M68K_CPU(cs);
5645     CPUM68KState *env = &cpu->env;
5646     int i;
5647     uint16_t sr;
5648     for (i = 0; i < 8; i++) {
5649         cpu_fprintf(f, "D%d = %08x   A%d = %08x   "
5650                     "F%d = %04x %016"PRIx64"  (%12g)\n",
5651                     i, env->dregs[i], i, env->aregs[i],
5652                     i, env->fregs[i].l.upper, env->fregs[i].l.lower,
5653                     floatx80_to_double(env, env->fregs[i].l.upper,
5654                                        env->fregs[i].l.lower));
5655     }
5656     cpu_fprintf (f, "PC = %08x   ", env->pc);
5657     sr = env->sr | cpu_m68k_get_ccr(env);
5658     cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-',
5659                 (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
5660                 (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
5661     cpu_fprintf(f, "FPSR = %08x %c%c%c%c ", env->fpsr,
5662                 (env->fpsr & FPSR_CC_A) ? 'A' : '-',
5663                 (env->fpsr & FPSR_CC_I) ? 'I' : '-',
5664                 (env->fpsr & FPSR_CC_Z) ? 'Z' : '-',
5665                 (env->fpsr & FPSR_CC_N) ? 'N' : '-');
5666     cpu_fprintf(f, "\n                                "
5667                    "FPCR =     %04x ", env->fpcr);
5668     switch (env->fpcr & FPCR_PREC_MASK) {
5669     case FPCR_PREC_X:
5670         cpu_fprintf(f, "X ");
5671         break;
5672     case FPCR_PREC_S:
5673         cpu_fprintf(f, "S ");
5674         break;
5675     case FPCR_PREC_D:
5676         cpu_fprintf(f, "D ");
5677         break;
5678     }
5679     switch (env->fpcr & FPCR_RND_MASK) {
5680     case FPCR_RND_N:
5681         cpu_fprintf(f, "RN ");
5682         break;
5683     case FPCR_RND_Z:
5684         cpu_fprintf(f, "RZ ");
5685         break;
5686     case FPCR_RND_M:
5687         cpu_fprintf(f, "RM ");
5688         break;
5689     case FPCR_RND_P:
5690         cpu_fprintf(f, "RP ");
5691         break;
5692     }
5693 }
5694 
5695 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb,
5696                           target_ulong *data)
5697 {
5698     int cc_op = data[1];
5699     env->pc = data[0];
5700     if (cc_op != CC_OP_DYNAMIC) {
5701         env->cc_op = cc_op;
5702     }
5703 }
5704