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