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