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