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