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