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