]> Git Repo - qemu.git/blob - target-m68k/translate.c
target-m68k: switch to AREG0 free mode
[qemu.git] / target-m68k / translate.c
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 "cpu.h"
22 #include "disas.h"
23 #include "tcg-op.h"
24 #include "qemu-log.h"
25
26 #include "helpers.h"
27 #define GEN_HELPER 1
28 #include "helpers.h"
29
30 //#define DEBUG_DISPATCH 1
31
32 /* Fake floating point.  */
33 #define tcg_gen_mov_f64 tcg_gen_mov_i64
34 #define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64
35 #define tcg_gen_qemu_stf64 tcg_gen_qemu_st64
36
37 #define DEFO32(name, offset) static TCGv QREG_##name;
38 #define DEFO64(name, offset) static TCGv_i64 QREG_##name;
39 #define DEFF64(name, offset) static TCGv_i64 QREG_##name;
40 #include "qregs.def"
41 #undef DEFO32
42 #undef DEFO64
43 #undef DEFF64
44
45 static TCGv_ptr cpu_env;
46
47 static char cpu_reg_names[3*8*3 + 5*4];
48 static TCGv cpu_dregs[8];
49 static TCGv cpu_aregs[8];
50 static TCGv_i64 cpu_fregs[8];
51 static TCGv_i64 cpu_macc[4];
52
53 #define DREG(insn, pos) cpu_dregs[((insn) >> (pos)) & 7]
54 #define AREG(insn, pos) cpu_aregs[((insn) >> (pos)) & 7]
55 #define FREG(insn, pos) cpu_fregs[((insn) >> (pos)) & 7]
56 #define MACREG(acc) cpu_macc[acc]
57 #define QREG_SP cpu_aregs[7]
58
59 static TCGv NULL_QREG;
60 #define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG))
61 /* Used to distinguish stores from bad addressing modes.  */
62 static TCGv store_dummy;
63
64 #include "gen-icount.h"
65
66 void m68k_tcg_init(void)
67 {
68     char *p;
69     int i;
70
71 #define DEFO32(name,  offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
72 #define DEFO64(name,  offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
73 #define DEFF64(name,  offset) DEFO64(name, offset)
74 #include "qregs.def"
75 #undef DEFO32
76 #undef DEFO64
77 #undef DEFF64
78
79     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
80
81     p = cpu_reg_names;
82     for (i = 0; i < 8; i++) {
83         sprintf(p, "D%d", i);
84         cpu_dregs[i] = tcg_global_mem_new(TCG_AREG0,
85                                           offsetof(CPUM68KState, dregs[i]), p);
86         p += 3;
87         sprintf(p, "A%d", i);
88         cpu_aregs[i] = tcg_global_mem_new(TCG_AREG0,
89                                           offsetof(CPUM68KState, aregs[i]), p);
90         p += 3;
91         sprintf(p, "F%d", i);
92         cpu_fregs[i] = tcg_global_mem_new_i64(TCG_AREG0,
93                                           offsetof(CPUM68KState, fregs[i]), p);
94         p += 3;
95     }
96     for (i = 0; i < 4; i++) {
97         sprintf(p, "ACC%d", i);
98         cpu_macc[i] = tcg_global_mem_new_i64(TCG_AREG0,
99                                          offsetof(CPUM68KState, macc[i]), p);
100         p += 5;
101     }
102
103     NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
104     store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
105
106 #define GEN_HELPER 2
107 #include "helpers.h"
108 }
109
110 static inline void qemu_assert(int cond, const char *msg)
111 {
112     if (!cond) {
113         fprintf (stderr, "badness: %s\n", msg);
114         abort();
115     }
116 }
117
118 /* internal defines */
119 typedef struct DisasContext {
120     CPUM68KState *env;
121     target_ulong insn_pc; /* Start of the current instruction.  */
122     target_ulong pc;
123     int is_jmp;
124     int cc_op;
125     int user;
126     uint32_t fpcr;
127     struct TranslationBlock *tb;
128     int singlestep_enabled;
129     int is_mem;
130     TCGv_i64 mactmp;
131     int done_mac;
132 } DisasContext;
133
134 #define DISAS_JUMP_NEXT 4
135
136 #if defined(CONFIG_USER_ONLY)
137 #define IS_USER(s) 1
138 #else
139 #define IS_USER(s) s->user
140 #endif
141
142 /* XXX: move that elsewhere */
143 /* ??? Fix exceptions.  */
144 static void *gen_throws_exception;
145 #define gen_last_qop NULL
146
147 #define OS_BYTE 0
148 #define OS_WORD 1
149 #define OS_LONG 2
150 #define OS_SINGLE 4
151 #define OS_DOUBLE 5
152
153 typedef void (*disas_proc)(DisasContext *, uint16_t);
154
155 #ifdef DEBUG_DISPATCH
156 #define DISAS_INSN(name) \
157   static void real_disas_##name (DisasContext *s, uint16_t insn); \
158   static void disas_##name (DisasContext *s, uint16_t insn) { \
159     qemu_log("Dispatch " #name "\n"); \
160     real_disas_##name(s, insn); } \
161   static void real_disas_##name (DisasContext *s, uint16_t insn)
162 #else
163 #define DISAS_INSN(name) \
164   static void disas_##name (DisasContext *s, uint16_t insn)
165 #endif
166
167 /* Generate a load from the specified address.  Narrow values are
168    sign extended to full register width.  */
169 static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
170 {
171     TCGv tmp;
172     int index = IS_USER(s);
173     s->is_mem = 1;
174     tmp = tcg_temp_new_i32();
175     switch(opsize) {
176     case OS_BYTE:
177         if (sign)
178             tcg_gen_qemu_ld8s(tmp, addr, index);
179         else
180             tcg_gen_qemu_ld8u(tmp, addr, index);
181         break;
182     case OS_WORD:
183         if (sign)
184             tcg_gen_qemu_ld16s(tmp, addr, index);
185         else
186             tcg_gen_qemu_ld16u(tmp, addr, index);
187         break;
188     case OS_LONG:
189     case OS_SINGLE:
190         tcg_gen_qemu_ld32u(tmp, addr, index);
191         break;
192     default:
193         qemu_assert(0, "bad load size");
194     }
195     gen_throws_exception = gen_last_qop;
196     return tmp;
197 }
198
199 static inline TCGv_i64 gen_load64(DisasContext * s, TCGv addr)
200 {
201     TCGv_i64 tmp;
202     int index = IS_USER(s);
203     s->is_mem = 1;
204     tmp = tcg_temp_new_i64();
205     tcg_gen_qemu_ldf64(tmp, addr, index);
206     gen_throws_exception = gen_last_qop;
207     return tmp;
208 }
209
210 /* Generate a store.  */
211 static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
212 {
213     int index = IS_USER(s);
214     s->is_mem = 1;
215     switch(opsize) {
216     case OS_BYTE:
217         tcg_gen_qemu_st8(val, addr, index);
218         break;
219     case OS_WORD:
220         tcg_gen_qemu_st16(val, addr, index);
221         break;
222     case OS_LONG:
223     case OS_SINGLE:
224         tcg_gen_qemu_st32(val, addr, index);
225         break;
226     default:
227         qemu_assert(0, "bad store size");
228     }
229     gen_throws_exception = gen_last_qop;
230 }
231
232 static inline void gen_store64(DisasContext *s, TCGv addr, TCGv_i64 val)
233 {
234     int index = IS_USER(s);
235     s->is_mem = 1;
236     tcg_gen_qemu_stf64(val, addr, index);
237     gen_throws_exception = gen_last_qop;
238 }
239
240 typedef enum {
241     EA_STORE,
242     EA_LOADU,
243     EA_LOADS
244 } ea_what;
245
246 /* Generate an unsigned load if VAL is 0 a signed load if val is -1,
247    otherwise generate a store.  */
248 static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
249                      ea_what what)
250 {
251     if (what == EA_STORE) {
252         gen_store(s, opsize, addr, val);
253         return store_dummy;
254     } else {
255         return gen_load(s, opsize, addr, what == EA_LOADS);
256     }
257 }
258
259 /* Read a 32-bit immediate constant.  */
260 static inline uint32_t read_im32(DisasContext *s)
261 {
262     uint32_t im;
263     im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
264     s->pc += 2;
265     im |= cpu_lduw_code(cpu_single_env, s->pc);
266     s->pc += 2;
267     return im;
268 }
269
270 /* Calculate and address index.  */
271 static TCGv gen_addr_index(uint16_t ext, TCGv tmp)
272 {
273     TCGv add;
274     int scale;
275
276     add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
277     if ((ext & 0x800) == 0) {
278         tcg_gen_ext16s_i32(tmp, add);
279         add = tmp;
280     }
281     scale = (ext >> 9) & 3;
282     if (scale != 0) {
283         tcg_gen_shli_i32(tmp, add, scale);
284         add = tmp;
285     }
286     return add;
287 }
288
289 /* Handle a base + index + displacement effective addresss.
290    A NULL_QREG base means pc-relative.  */
291 static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
292 {
293     uint32_t offset;
294     uint16_t ext;
295     TCGv add;
296     TCGv tmp;
297     uint32_t bd, od;
298
299     offset = s->pc;
300     ext = cpu_lduw_code(cpu_single_env, s->pc);
301     s->pc += 2;
302
303     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
304         return NULL_QREG;
305
306     if (ext & 0x100) {
307         /* full extension word format */
308         if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
309             return NULL_QREG;
310
311         if ((ext & 0x30) > 0x10) {
312             /* base displacement */
313             if ((ext & 0x30) == 0x20) {
314                 bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
315                 s->pc += 2;
316             } else {
317                 bd = read_im32(s);
318             }
319         } else {
320             bd = 0;
321         }
322         tmp = tcg_temp_new();
323         if ((ext & 0x44) == 0) {
324             /* pre-index */
325             add = gen_addr_index(ext, tmp);
326         } else {
327             add = NULL_QREG;
328         }
329         if ((ext & 0x80) == 0) {
330             /* base not suppressed */
331             if (IS_NULL_QREG(base)) {
332                 base = tcg_const_i32(offset + bd);
333                 bd = 0;
334             }
335             if (!IS_NULL_QREG(add)) {
336                 tcg_gen_add_i32(tmp, add, base);
337                 add = tmp;
338             } else {
339                 add = base;
340             }
341         }
342         if (!IS_NULL_QREG(add)) {
343             if (bd != 0) {
344                 tcg_gen_addi_i32(tmp, add, bd);
345                 add = tmp;
346             }
347         } else {
348             add = tcg_const_i32(bd);
349         }
350         if ((ext & 3) != 0) {
351             /* memory indirect */
352             base = gen_load(s, OS_LONG, add, 0);
353             if ((ext & 0x44) == 4) {
354                 add = gen_addr_index(ext, tmp);
355                 tcg_gen_add_i32(tmp, add, base);
356                 add = tmp;
357             } else {
358                 add = base;
359             }
360             if ((ext & 3) > 1) {
361                 /* outer displacement */
362                 if ((ext & 3) == 2) {
363                     od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
364                     s->pc += 2;
365                 } else {
366                     od = read_im32(s);
367                 }
368             } else {
369                 od = 0;
370             }
371             if (od != 0) {
372                 tcg_gen_addi_i32(tmp, add, od);
373                 add = tmp;
374             }
375         }
376     } else {
377         /* brief extension word format */
378         tmp = tcg_temp_new();
379         add = gen_addr_index(ext, tmp);
380         if (!IS_NULL_QREG(base)) {
381             tcg_gen_add_i32(tmp, add, base);
382             if ((int8_t)ext)
383                 tcg_gen_addi_i32(tmp, tmp, (int8_t)ext);
384         } else {
385             tcg_gen_addi_i32(tmp, add, offset + (int8_t)ext);
386         }
387         add = tmp;
388     }
389     return add;
390 }
391
392 /* Update the CPU env CC_OP state.  */
393 static inline void gen_flush_cc_op(DisasContext *s)
394 {
395     if (s->cc_op != CC_OP_DYNAMIC)
396         tcg_gen_movi_i32(QREG_CC_OP, s->cc_op);
397 }
398
399 /* Evaluate all the CC flags.  */
400 static inline void gen_flush_flags(DisasContext *s)
401 {
402     if (s->cc_op == CC_OP_FLAGS)
403         return;
404     gen_flush_cc_op(s);
405     gen_helper_flush_flags(cpu_env, QREG_CC_OP);
406     s->cc_op = CC_OP_FLAGS;
407 }
408
409 static void gen_logic_cc(DisasContext *s, TCGv val)
410 {
411     tcg_gen_mov_i32(QREG_CC_DEST, val);
412     s->cc_op = CC_OP_LOGIC;
413 }
414
415 static void gen_update_cc_add(TCGv dest, TCGv src)
416 {
417     tcg_gen_mov_i32(QREG_CC_DEST, dest);
418     tcg_gen_mov_i32(QREG_CC_SRC, src);
419 }
420
421 static inline int opsize_bytes(int opsize)
422 {
423     switch (opsize) {
424     case OS_BYTE: return 1;
425     case OS_WORD: return 2;
426     case OS_LONG: return 4;
427     case OS_SINGLE: return 4;
428     case OS_DOUBLE: return 8;
429     default:
430         qemu_assert(0, "bad operand size");
431         return 0;
432     }
433 }
434
435 /* Assign value to a register.  If the width is less than the register width
436    only the low part of the register is set.  */
437 static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
438 {
439     TCGv tmp;
440     switch (opsize) {
441     case OS_BYTE:
442         tcg_gen_andi_i32(reg, reg, 0xffffff00);
443         tmp = tcg_temp_new();
444         tcg_gen_ext8u_i32(tmp, val);
445         tcg_gen_or_i32(reg, reg, tmp);
446         break;
447     case OS_WORD:
448         tcg_gen_andi_i32(reg, reg, 0xffff0000);
449         tmp = tcg_temp_new();
450         tcg_gen_ext16u_i32(tmp, val);
451         tcg_gen_or_i32(reg, reg, tmp);
452         break;
453     case OS_LONG:
454     case OS_SINGLE:
455         tcg_gen_mov_i32(reg, val);
456         break;
457     default:
458         qemu_assert(0, "Bad operand size");
459         break;
460     }
461 }
462
463 /* Sign or zero extend a value.  */
464 static inline TCGv gen_extend(TCGv val, int opsize, int sign)
465 {
466     TCGv tmp;
467
468     switch (opsize) {
469     case OS_BYTE:
470         tmp = tcg_temp_new();
471         if (sign)
472             tcg_gen_ext8s_i32(tmp, val);
473         else
474             tcg_gen_ext8u_i32(tmp, val);
475         break;
476     case OS_WORD:
477         tmp = tcg_temp_new();
478         if (sign)
479             tcg_gen_ext16s_i32(tmp, val);
480         else
481             tcg_gen_ext16u_i32(tmp, val);
482         break;
483     case OS_LONG:
484     case OS_SINGLE:
485         tmp = val;
486         break;
487     default:
488         qemu_assert(0, "Bad operand size");
489     }
490     return tmp;
491 }
492
493 /* Generate code for an "effective address".  Does not adjust the base
494    register for autoincrement addressing modes.  */
495 static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
496 {
497     TCGv reg;
498     TCGv tmp;
499     uint16_t ext;
500     uint32_t offset;
501
502     switch ((insn >> 3) & 7) {
503     case 0: /* Data register direct.  */
504     case 1: /* Address register direct.  */
505         return NULL_QREG;
506     case 2: /* Indirect register */
507     case 3: /* Indirect postincrement.  */
508         return AREG(insn, 0);
509     case 4: /* Indirect predecrememnt.  */
510         reg = AREG(insn, 0);
511         tmp = tcg_temp_new();
512         tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
513         return tmp;
514     case 5: /* Indirect displacement.  */
515         reg = AREG(insn, 0);
516         tmp = tcg_temp_new();
517         ext = cpu_lduw_code(cpu_single_env, s->pc);
518         s->pc += 2;
519         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
520         return tmp;
521     case 6: /* Indirect index + displacement.  */
522         reg = AREG(insn, 0);
523         return gen_lea_indexed(s, opsize, reg);
524     case 7: /* Other */
525         switch (insn & 7) {
526         case 0: /* Absolute short.  */
527             offset = cpu_ldsw_code(cpu_single_env, s->pc);
528             s->pc += 2;
529             return tcg_const_i32(offset);
530         case 1: /* Absolute long.  */
531             offset = read_im32(s);
532             return tcg_const_i32(offset);
533         case 2: /* pc displacement  */
534             offset = s->pc;
535             offset += cpu_ldsw_code(cpu_single_env, s->pc);
536             s->pc += 2;
537             return tcg_const_i32(offset);
538         case 3: /* pc index+displacement.  */
539             return gen_lea_indexed(s, opsize, NULL_QREG);
540         case 4: /* Immediate.  */
541         default:
542             return NULL_QREG;
543         }
544     }
545     /* Should never happen.  */
546     return NULL_QREG;
547 }
548
549 /* Helper function for gen_ea. Reuse the computed address between the
550    for read/write operands.  */
551 static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
552                               TCGv val, TCGv *addrp, ea_what what)
553 {
554     TCGv tmp;
555
556     if (addrp && what == EA_STORE) {
557         tmp = *addrp;
558     } else {
559         tmp = gen_lea(s, insn, opsize);
560         if (IS_NULL_QREG(tmp))
561             return tmp;
562         if (addrp)
563             *addrp = tmp;
564     }
565     return gen_ldst(s, opsize, tmp, val, what);
566 }
567
568 /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
569    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
570    ADDRP is non-null for readwrite operands.  */
571 static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
572                    TCGv *addrp, ea_what what)
573 {
574     TCGv reg;
575     TCGv result;
576     uint32_t offset;
577
578     switch ((insn >> 3) & 7) {
579     case 0: /* Data register direct.  */
580         reg = DREG(insn, 0);
581         if (what == EA_STORE) {
582             gen_partset_reg(opsize, reg, val);
583             return store_dummy;
584         } else {
585             return gen_extend(reg, opsize, what == EA_LOADS);
586         }
587     case 1: /* Address register direct.  */
588         reg = AREG(insn, 0);
589         if (what == EA_STORE) {
590             tcg_gen_mov_i32(reg, val);
591             return store_dummy;
592         } else {
593             return gen_extend(reg, opsize, what == EA_LOADS);
594         }
595     case 2: /* Indirect register */
596         reg = AREG(insn, 0);
597         return gen_ldst(s, opsize, reg, val, what);
598     case 3: /* Indirect postincrement.  */
599         reg = AREG(insn, 0);
600         result = gen_ldst(s, opsize, reg, val, what);
601         /* ??? This is not exception safe.  The instruction may still
602            fault after this point.  */
603         if (what == EA_STORE || !addrp)
604             tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize));
605         return result;
606     case 4: /* Indirect predecrememnt.  */
607         {
608             TCGv tmp;
609             if (addrp && what == EA_STORE) {
610                 tmp = *addrp;
611             } else {
612                 tmp = gen_lea(s, insn, opsize);
613                 if (IS_NULL_QREG(tmp))
614                     return tmp;
615                 if (addrp)
616                     *addrp = tmp;
617             }
618             result = gen_ldst(s, opsize, tmp, val, what);
619             /* ??? This is not exception safe.  The instruction may still
620                fault after this point.  */
621             if (what == EA_STORE || !addrp) {
622                 reg = AREG(insn, 0);
623                 tcg_gen_mov_i32(reg, tmp);
624             }
625         }
626         return result;
627     case 5: /* Indirect displacement.  */
628     case 6: /* Indirect index + displacement.  */
629         return gen_ea_once(s, insn, opsize, val, addrp, what);
630     case 7: /* Other */
631         switch (insn & 7) {
632         case 0: /* Absolute short.  */
633         case 1: /* Absolute long.  */
634         case 2: /* pc displacement  */
635         case 3: /* pc index+displacement.  */
636             return gen_ea_once(s, insn, opsize, val, addrp, what);
637         case 4: /* Immediate.  */
638             /* Sign extend values for consistency.  */
639             switch (opsize) {
640             case OS_BYTE:
641                 if (what == EA_LOADS) {
642                     offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
643                 } else {
644                     offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
645                 }
646                 s->pc += 2;
647                 break;
648             case OS_WORD:
649                 if (what == EA_LOADS) {
650                     offset = cpu_ldsw_code(cpu_single_env, s->pc);
651                 } else {
652                     offset = cpu_lduw_code(cpu_single_env, s->pc);
653                 }
654                 s->pc += 2;
655                 break;
656             case OS_LONG:
657                 offset = read_im32(s);
658                 break;
659             default:
660                 qemu_assert(0, "Bad immediate operand");
661             }
662             return tcg_const_i32(offset);
663         default:
664             return NULL_QREG;
665         }
666     }
667     /* Should never happen.  */
668     return NULL_QREG;
669 }
670
671 /* This generates a conditional branch, clobbering all temporaries.  */
672 static void gen_jmpcc(DisasContext *s, int cond, int l1)
673 {
674     TCGv tmp;
675
676     /* TODO: Optimize compare/branch pairs rather than always flushing
677        flag state to CC_OP_FLAGS.  */
678     gen_flush_flags(s);
679     switch (cond) {
680     case 0: /* T */
681         tcg_gen_br(l1);
682         break;
683     case 1: /* F */
684         break;
685     case 2: /* HI (!C && !Z) */
686         tmp = tcg_temp_new();
687         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
688         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
689         break;
690     case 3: /* LS (C || Z) */
691         tmp = tcg_temp_new();
692         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
693         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
694         break;
695     case 4: /* CC (!C) */
696         tmp = tcg_temp_new();
697         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
698         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
699         break;
700     case 5: /* CS (C) */
701         tmp = tcg_temp_new();
702         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
703         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
704         break;
705     case 6: /* NE (!Z) */
706         tmp = tcg_temp_new();
707         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
708         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
709         break;
710     case 7: /* EQ (Z) */
711         tmp = tcg_temp_new();
712         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
713         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
714         break;
715     case 8: /* VC (!V) */
716         tmp = tcg_temp_new();
717         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
718         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
719         break;
720     case 9: /* VS (V) */
721         tmp = tcg_temp_new();
722         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
723         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
724         break;
725     case 10: /* PL (!N) */
726         tmp = tcg_temp_new();
727         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
728         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
729         break;
730     case 11: /* MI (N) */
731         tmp = tcg_temp_new();
732         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
733         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
734         break;
735     case 12: /* GE (!(N ^ V)) */
736         tmp = tcg_temp_new();
737         assert(CCF_V == (CCF_N >> 2));
738         tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
739         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
740         tcg_gen_andi_i32(tmp, tmp, CCF_V);
741         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
742         break;
743     case 13: /* LT (N ^ V) */
744         tmp = tcg_temp_new();
745         assert(CCF_V == (CCF_N >> 2));
746         tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
747         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
748         tcg_gen_andi_i32(tmp, tmp, CCF_V);
749         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
750         break;
751     case 14: /* GT (!(Z || (N ^ V))) */
752         tmp = tcg_temp_new();
753         assert(CCF_V == (CCF_N >> 2));
754         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
755         tcg_gen_shri_i32(tmp, tmp, 2);
756         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
757         tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
758         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
759         break;
760     case 15: /* LE (Z || (N ^ V)) */
761         tmp = tcg_temp_new();
762         assert(CCF_V == (CCF_N >> 2));
763         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
764         tcg_gen_shri_i32(tmp, tmp, 2);
765         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
766         tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
767         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
768         break;
769     default:
770         /* Should ever happen.  */
771         abort();
772     }
773 }
774
775 DISAS_INSN(scc)
776 {
777     int l1;
778     int cond;
779     TCGv reg;
780
781     l1 = gen_new_label();
782     cond = (insn >> 8) & 0xf;
783     reg = DREG(insn, 0);
784     tcg_gen_andi_i32(reg, reg, 0xffffff00);
785     /* This is safe because we modify the reg directly, with no other values
786        live.  */
787     gen_jmpcc(s, cond ^ 1, l1);
788     tcg_gen_ori_i32(reg, reg, 0xff);
789     gen_set_label(l1);
790 }
791
792 /* Force a TB lookup after an instruction that changes the CPU state.  */
793 static void gen_lookup_tb(DisasContext *s)
794 {
795     gen_flush_cc_op(s);
796     tcg_gen_movi_i32(QREG_PC, s->pc);
797     s->is_jmp = DISAS_UPDATE;
798 }
799
800 /* Generate a jump to an immediate address.  */
801 static void gen_jmp_im(DisasContext *s, uint32_t dest)
802 {
803     gen_flush_cc_op(s);
804     tcg_gen_movi_i32(QREG_PC, dest);
805     s->is_jmp = DISAS_JUMP;
806 }
807
808 /* Generate a jump to the address in qreg DEST.  */
809 static void gen_jmp(DisasContext *s, TCGv dest)
810 {
811     gen_flush_cc_op(s);
812     tcg_gen_mov_i32(QREG_PC, dest);
813     s->is_jmp = DISAS_JUMP;
814 }
815
816 static void gen_exception(DisasContext *s, uint32_t where, int nr)
817 {
818     gen_flush_cc_op(s);
819     gen_jmp_im(s, where);
820     gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
821 }
822
823 static inline void gen_addr_fault(DisasContext *s)
824 {
825     gen_exception(s, s->insn_pc, EXCP_ADDRESS);
826 }
827
828 #define SRC_EA(result, opsize, op_sign, addrp) do { \
829     result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
830     if (IS_NULL_QREG(result)) { \
831         gen_addr_fault(s); \
832         return; \
833     } \
834     } while (0)
835
836 #define DEST_EA(insn, opsize, val, addrp) do { \
837     TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
838     if (IS_NULL_QREG(ea_result)) { \
839         gen_addr_fault(s); \
840         return; \
841     } \
842     } while (0)
843
844 /* Generate a jump to an immediate address.  */
845 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
846 {
847     TranslationBlock *tb;
848
849     tb = s->tb;
850     if (unlikely(s->singlestep_enabled)) {
851         gen_exception(s, dest, EXCP_DEBUG);
852     } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
853                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
854         tcg_gen_goto_tb(n);
855         tcg_gen_movi_i32(QREG_PC, dest);
856         tcg_gen_exit_tb((tcg_target_long)tb + n);
857     } else {
858         gen_jmp_im(s, dest);
859         tcg_gen_exit_tb(0);
860     }
861     s->is_jmp = DISAS_TB_JUMP;
862 }
863
864 DISAS_INSN(undef_mac)
865 {
866     gen_exception(s, s->pc - 2, EXCP_LINEA);
867 }
868
869 DISAS_INSN(undef_fpu)
870 {
871     gen_exception(s, s->pc - 2, EXCP_LINEF);
872 }
873
874 DISAS_INSN(undef)
875 {
876     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
877     cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
878               insn, s->pc - 2);
879 }
880
881 DISAS_INSN(mulw)
882 {
883     TCGv reg;
884     TCGv tmp;
885     TCGv src;
886     int sign;
887
888     sign = (insn & 0x100) != 0;
889     reg = DREG(insn, 9);
890     tmp = tcg_temp_new();
891     if (sign)
892         tcg_gen_ext16s_i32(tmp, reg);
893     else
894         tcg_gen_ext16u_i32(tmp, reg);
895     SRC_EA(src, OS_WORD, sign, NULL);
896     tcg_gen_mul_i32(tmp, tmp, src);
897     tcg_gen_mov_i32(reg, tmp);
898     /* Unlike m68k, coldfire always clears the overflow bit.  */
899     gen_logic_cc(s, tmp);
900 }
901
902 DISAS_INSN(divw)
903 {
904     TCGv reg;
905     TCGv tmp;
906     TCGv src;
907     int sign;
908
909     sign = (insn & 0x100) != 0;
910     reg = DREG(insn, 9);
911     if (sign) {
912         tcg_gen_ext16s_i32(QREG_DIV1, reg);
913     } else {
914         tcg_gen_ext16u_i32(QREG_DIV1, reg);
915     }
916     SRC_EA(src, OS_WORD, sign, NULL);
917     tcg_gen_mov_i32(QREG_DIV2, src);
918     if (sign) {
919         gen_helper_divs(cpu_env, tcg_const_i32(1));
920     } else {
921         gen_helper_divu(cpu_env, tcg_const_i32(1));
922     }
923
924     tmp = tcg_temp_new();
925     src = tcg_temp_new();
926     tcg_gen_ext16u_i32(tmp, QREG_DIV1);
927     tcg_gen_shli_i32(src, QREG_DIV2, 16);
928     tcg_gen_or_i32(reg, tmp, src);
929     s->cc_op = CC_OP_FLAGS;
930 }
931
932 DISAS_INSN(divl)
933 {
934     TCGv num;
935     TCGv den;
936     TCGv reg;
937     uint16_t ext;
938
939     ext = cpu_lduw_code(cpu_single_env, s->pc);
940     s->pc += 2;
941     if (ext & 0x87f8) {
942         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
943         return;
944     }
945     num = DREG(ext, 12);
946     reg = DREG(ext, 0);
947     tcg_gen_mov_i32(QREG_DIV1, num);
948     SRC_EA(den, OS_LONG, 0, NULL);
949     tcg_gen_mov_i32(QREG_DIV2, den);
950     if (ext & 0x0800) {
951         gen_helper_divs(cpu_env, tcg_const_i32(0));
952     } else {
953         gen_helper_divu(cpu_env, tcg_const_i32(0));
954     }
955     if ((ext & 7) == ((ext >> 12) & 7)) {
956         /* div */
957         tcg_gen_mov_i32 (reg, QREG_DIV1);
958     } else {
959         /* rem */
960         tcg_gen_mov_i32 (reg, QREG_DIV2);
961     }
962     s->cc_op = CC_OP_FLAGS;
963 }
964
965 DISAS_INSN(addsub)
966 {
967     TCGv reg;
968     TCGv dest;
969     TCGv src;
970     TCGv tmp;
971     TCGv addr;
972     int add;
973
974     add = (insn & 0x4000) != 0;
975     reg = DREG(insn, 9);
976     dest = tcg_temp_new();
977     if (insn & 0x100) {
978         SRC_EA(tmp, OS_LONG, 0, &addr);
979         src = reg;
980     } else {
981         tmp = reg;
982         SRC_EA(src, OS_LONG, 0, NULL);
983     }
984     if (add) {
985         tcg_gen_add_i32(dest, tmp, src);
986         gen_helper_xflag_lt(QREG_CC_X, dest, src);
987         s->cc_op = CC_OP_ADD;
988     } else {
989         gen_helper_xflag_lt(QREG_CC_X, tmp, src);
990         tcg_gen_sub_i32(dest, tmp, src);
991         s->cc_op = CC_OP_SUB;
992     }
993     gen_update_cc_add(dest, src);
994     if (insn & 0x100) {
995         DEST_EA(insn, OS_LONG, dest, &addr);
996     } else {
997         tcg_gen_mov_i32(reg, dest);
998     }
999 }
1000
1001
1002 /* Reverse the order of the bits in REG.  */
1003 DISAS_INSN(bitrev)
1004 {
1005     TCGv reg;
1006     reg = DREG(insn, 0);
1007     gen_helper_bitrev(reg, reg);
1008 }
1009
1010 DISAS_INSN(bitop_reg)
1011 {
1012     int opsize;
1013     int op;
1014     TCGv src1;
1015     TCGv src2;
1016     TCGv tmp;
1017     TCGv addr;
1018     TCGv dest;
1019
1020     if ((insn & 0x38) != 0)
1021         opsize = OS_BYTE;
1022     else
1023         opsize = OS_LONG;
1024     op = (insn >> 6) & 3;
1025     SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1026     src2 = DREG(insn, 9);
1027     dest = tcg_temp_new();
1028
1029     gen_flush_flags(s);
1030     tmp = tcg_temp_new();
1031     if (opsize == OS_BYTE)
1032         tcg_gen_andi_i32(tmp, src2, 7);
1033     else
1034         tcg_gen_andi_i32(tmp, src2, 31);
1035     src2 = tmp;
1036     tmp = tcg_temp_new();
1037     tcg_gen_shr_i32(tmp, src1, src2);
1038     tcg_gen_andi_i32(tmp, tmp, 1);
1039     tcg_gen_shli_i32(tmp, tmp, 2);
1040     /* Clear CCF_Z if bit set.  */
1041     tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1042     tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1043
1044     tcg_gen_shl_i32(tmp, tcg_const_i32(1), src2);
1045     switch (op) {
1046     case 1: /* bchg */
1047         tcg_gen_xor_i32(dest, src1, tmp);
1048         break;
1049     case 2: /* bclr */
1050         tcg_gen_not_i32(tmp, tmp);
1051         tcg_gen_and_i32(dest, src1, tmp);
1052         break;
1053     case 3: /* bset */
1054         tcg_gen_or_i32(dest, src1, tmp);
1055         break;
1056     default: /* btst */
1057         break;
1058     }
1059     if (op)
1060         DEST_EA(insn, opsize, dest, &addr);
1061 }
1062
1063 DISAS_INSN(sats)
1064 {
1065     TCGv reg;
1066     reg = DREG(insn, 0);
1067     gen_flush_flags(s);
1068     gen_helper_sats(reg, reg, QREG_CC_DEST);
1069     gen_logic_cc(s, reg);
1070 }
1071
1072 static void gen_push(DisasContext *s, TCGv val)
1073 {
1074     TCGv tmp;
1075
1076     tmp = tcg_temp_new();
1077     tcg_gen_subi_i32(tmp, QREG_SP, 4);
1078     gen_store(s, OS_LONG, tmp, val);
1079     tcg_gen_mov_i32(QREG_SP, tmp);
1080 }
1081
1082 DISAS_INSN(movem)
1083 {
1084     TCGv addr;
1085     int i;
1086     uint16_t mask;
1087     TCGv reg;
1088     TCGv tmp;
1089     int is_load;
1090
1091     mask = cpu_lduw_code(cpu_single_env, s->pc);
1092     s->pc += 2;
1093     tmp = gen_lea(s, insn, OS_LONG);
1094     if (IS_NULL_QREG(tmp)) {
1095         gen_addr_fault(s);
1096         return;
1097     }
1098     addr = tcg_temp_new();
1099     tcg_gen_mov_i32(addr, tmp);
1100     is_load = ((insn & 0x0400) != 0);
1101     for (i = 0; i < 16; i++, mask >>= 1) {
1102         if (mask & 1) {
1103             if (i < 8)
1104                 reg = DREG(i, 0);
1105             else
1106                 reg = AREG(i, 0);
1107             if (is_load) {
1108                 tmp = gen_load(s, OS_LONG, addr, 0);
1109                 tcg_gen_mov_i32(reg, tmp);
1110             } else {
1111                 gen_store(s, OS_LONG, addr, reg);
1112             }
1113             if (mask != 1)
1114                 tcg_gen_addi_i32(addr, addr, 4);
1115         }
1116     }
1117 }
1118
1119 DISAS_INSN(bitop_im)
1120 {
1121     int opsize;
1122     int op;
1123     TCGv src1;
1124     uint32_t mask;
1125     int bitnum;
1126     TCGv tmp;
1127     TCGv addr;
1128
1129     if ((insn & 0x38) != 0)
1130         opsize = OS_BYTE;
1131     else
1132         opsize = OS_LONG;
1133     op = (insn >> 6) & 3;
1134
1135     bitnum = cpu_lduw_code(cpu_single_env, s->pc);
1136     s->pc += 2;
1137     if (bitnum & 0xff00) {
1138         disas_undef(s, insn);
1139         return;
1140     }
1141
1142     SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1143
1144     gen_flush_flags(s);
1145     if (opsize == OS_BYTE)
1146         bitnum &= 7;
1147     else
1148         bitnum &= 31;
1149     mask = 1 << bitnum;
1150
1151     tmp = tcg_temp_new();
1152     assert (CCF_Z == (1 << 2));
1153     if (bitnum > 2)
1154         tcg_gen_shri_i32(tmp, src1, bitnum - 2);
1155     else if (bitnum < 2)
1156         tcg_gen_shli_i32(tmp, src1, 2 - bitnum);
1157     else
1158         tcg_gen_mov_i32(tmp, src1);
1159     tcg_gen_andi_i32(tmp, tmp, CCF_Z);
1160     /* Clear CCF_Z if bit set.  */
1161     tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1162     tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1163     if (op) {
1164         switch (op) {
1165         case 1: /* bchg */
1166             tcg_gen_xori_i32(tmp, src1, mask);
1167             break;
1168         case 2: /* bclr */
1169             tcg_gen_andi_i32(tmp, src1, ~mask);
1170             break;
1171         case 3: /* bset */
1172             tcg_gen_ori_i32(tmp, src1, mask);
1173             break;
1174         default: /* btst */
1175             break;
1176         }
1177         DEST_EA(insn, opsize, tmp, &addr);
1178     }
1179 }
1180
1181 DISAS_INSN(arith_im)
1182 {
1183     int op;
1184     uint32_t im;
1185     TCGv src1;
1186     TCGv dest;
1187     TCGv addr;
1188
1189     op = (insn >> 9) & 7;
1190     SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1191     im = read_im32(s);
1192     dest = tcg_temp_new();
1193     switch (op) {
1194     case 0: /* ori */
1195         tcg_gen_ori_i32(dest, src1, im);
1196         gen_logic_cc(s, dest);
1197         break;
1198     case 1: /* andi */
1199         tcg_gen_andi_i32(dest, src1, im);
1200         gen_logic_cc(s, dest);
1201         break;
1202     case 2: /* subi */
1203         tcg_gen_mov_i32(dest, src1);
1204         gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
1205         tcg_gen_subi_i32(dest, dest, im);
1206         gen_update_cc_add(dest, tcg_const_i32(im));
1207         s->cc_op = CC_OP_SUB;
1208         break;
1209     case 3: /* addi */
1210         tcg_gen_mov_i32(dest, src1);
1211         tcg_gen_addi_i32(dest, dest, im);
1212         gen_update_cc_add(dest, tcg_const_i32(im));
1213         gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
1214         s->cc_op = CC_OP_ADD;
1215         break;
1216     case 5: /* eori */
1217         tcg_gen_xori_i32(dest, src1, im);
1218         gen_logic_cc(s, dest);
1219         break;
1220     case 6: /* cmpi */
1221         tcg_gen_mov_i32(dest, src1);
1222         tcg_gen_subi_i32(dest, dest, im);
1223         gen_update_cc_add(dest, tcg_const_i32(im));
1224         s->cc_op = CC_OP_SUB;
1225         break;
1226     default:
1227         abort();
1228     }
1229     if (op != 6) {
1230         DEST_EA(insn, OS_LONG, dest, &addr);
1231     }
1232 }
1233
1234 DISAS_INSN(byterev)
1235 {
1236     TCGv reg;
1237
1238     reg = DREG(insn, 0);
1239     tcg_gen_bswap32_i32(reg, reg);
1240 }
1241
1242 DISAS_INSN(move)
1243 {
1244     TCGv src;
1245     TCGv dest;
1246     int op;
1247     int opsize;
1248
1249     switch (insn >> 12) {
1250     case 1: /* move.b */
1251         opsize = OS_BYTE;
1252         break;
1253     case 2: /* move.l */
1254         opsize = OS_LONG;
1255         break;
1256     case 3: /* move.w */
1257         opsize = OS_WORD;
1258         break;
1259     default:
1260         abort();
1261     }
1262     SRC_EA(src, opsize, 1, NULL);
1263     op = (insn >> 6) & 7;
1264     if (op == 1) {
1265         /* movea */
1266         /* The value will already have been sign extended.  */
1267         dest = AREG(insn, 9);
1268         tcg_gen_mov_i32(dest, src);
1269     } else {
1270         /* normal move */
1271         uint16_t dest_ea;
1272         dest_ea = ((insn >> 9) & 7) | (op << 3);
1273         DEST_EA(dest_ea, opsize, src, NULL);
1274         /* This will be correct because loads sign extend.  */
1275         gen_logic_cc(s, src);
1276     }
1277 }
1278
1279 DISAS_INSN(negx)
1280 {
1281     TCGv reg;
1282
1283     gen_flush_flags(s);
1284     reg = DREG(insn, 0);
1285     gen_helper_subx_cc(reg, cpu_env, tcg_const_i32(0), reg);
1286 }
1287
1288 DISAS_INSN(lea)
1289 {
1290     TCGv reg;
1291     TCGv tmp;
1292
1293     reg = AREG(insn, 9);
1294     tmp = gen_lea(s, insn, OS_LONG);
1295     if (IS_NULL_QREG(tmp)) {
1296         gen_addr_fault(s);
1297         return;
1298     }
1299     tcg_gen_mov_i32(reg, tmp);
1300 }
1301
1302 DISAS_INSN(clr)
1303 {
1304     int opsize;
1305
1306     switch ((insn >> 6) & 3) {
1307     case 0: /* clr.b */
1308         opsize = OS_BYTE;
1309         break;
1310     case 1: /* clr.w */
1311         opsize = OS_WORD;
1312         break;
1313     case 2: /* clr.l */
1314         opsize = OS_LONG;
1315         break;
1316     default:
1317         abort();
1318     }
1319     DEST_EA(insn, opsize, tcg_const_i32(0), NULL);
1320     gen_logic_cc(s, tcg_const_i32(0));
1321 }
1322
1323 static TCGv gen_get_ccr(DisasContext *s)
1324 {
1325     TCGv dest;
1326
1327     gen_flush_flags(s);
1328     dest = tcg_temp_new();
1329     tcg_gen_shli_i32(dest, QREG_CC_X, 4);
1330     tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
1331     return dest;
1332 }
1333
1334 DISAS_INSN(move_from_ccr)
1335 {
1336     TCGv reg;
1337     TCGv ccr;
1338
1339     ccr = gen_get_ccr(s);
1340     reg = DREG(insn, 0);
1341     gen_partset_reg(OS_WORD, reg, ccr);
1342 }
1343
1344 DISAS_INSN(neg)
1345 {
1346     TCGv reg;
1347     TCGv src1;
1348
1349     reg = DREG(insn, 0);
1350     src1 = tcg_temp_new();
1351     tcg_gen_mov_i32(src1, reg);
1352     tcg_gen_neg_i32(reg, src1);
1353     s->cc_op = CC_OP_SUB;
1354     gen_update_cc_add(reg, src1);
1355     gen_helper_xflag_lt(QREG_CC_X, tcg_const_i32(0), src1);
1356     s->cc_op = CC_OP_SUB;
1357 }
1358
1359 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1360 {
1361     tcg_gen_movi_i32(QREG_CC_DEST, val & 0xf);
1362     tcg_gen_movi_i32(QREG_CC_X, (val & 0x10) >> 4);
1363     if (!ccr_only) {
1364         gen_helper_set_sr(cpu_env, tcg_const_i32(val & 0xff00));
1365     }
1366 }
1367
1368 static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1369 {
1370     TCGv tmp;
1371     TCGv reg;
1372
1373     s->cc_op = CC_OP_FLAGS;
1374     if ((insn & 0x38) == 0)
1375       {
1376         tmp = tcg_temp_new();
1377         reg = DREG(insn, 0);
1378         tcg_gen_andi_i32(QREG_CC_DEST, reg, 0xf);
1379         tcg_gen_shri_i32(tmp, reg, 4);
1380         tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
1381         if (!ccr_only) {
1382             gen_helper_set_sr(cpu_env, reg);
1383         }
1384       }
1385     else if ((insn & 0x3f) == 0x3c)
1386       {
1387         uint16_t val;
1388         val = cpu_lduw_code(cpu_single_env, s->pc);
1389         s->pc += 2;
1390         gen_set_sr_im(s, val, ccr_only);
1391       }
1392     else
1393         disas_undef(s, insn);
1394 }
1395
1396 DISAS_INSN(move_to_ccr)
1397 {
1398     gen_set_sr(s, insn, 1);
1399 }
1400
1401 DISAS_INSN(not)
1402 {
1403     TCGv reg;
1404
1405     reg = DREG(insn, 0);
1406     tcg_gen_not_i32(reg, reg);
1407     gen_logic_cc(s, reg);
1408 }
1409
1410 DISAS_INSN(swap)
1411 {
1412     TCGv src1;
1413     TCGv src2;
1414     TCGv reg;
1415
1416     src1 = tcg_temp_new();
1417     src2 = tcg_temp_new();
1418     reg = DREG(insn, 0);
1419     tcg_gen_shli_i32(src1, reg, 16);
1420     tcg_gen_shri_i32(src2, reg, 16);
1421     tcg_gen_or_i32(reg, src1, src2);
1422     gen_logic_cc(s, reg);
1423 }
1424
1425 DISAS_INSN(pea)
1426 {
1427     TCGv tmp;
1428
1429     tmp = gen_lea(s, insn, OS_LONG);
1430     if (IS_NULL_QREG(tmp)) {
1431         gen_addr_fault(s);
1432         return;
1433     }
1434     gen_push(s, tmp);
1435 }
1436
1437 DISAS_INSN(ext)
1438 {
1439     int op;
1440     TCGv reg;
1441     TCGv tmp;
1442
1443     reg = DREG(insn, 0);
1444     op = (insn >> 6) & 7;
1445     tmp = tcg_temp_new();
1446     if (op == 3)
1447         tcg_gen_ext16s_i32(tmp, reg);
1448     else
1449         tcg_gen_ext8s_i32(tmp, reg);
1450     if (op == 2)
1451         gen_partset_reg(OS_WORD, reg, tmp);
1452     else
1453         tcg_gen_mov_i32(reg, tmp);
1454     gen_logic_cc(s, tmp);
1455 }
1456
1457 DISAS_INSN(tst)
1458 {
1459     int opsize;
1460     TCGv tmp;
1461
1462     switch ((insn >> 6) & 3) {
1463     case 0: /* tst.b */
1464         opsize = OS_BYTE;
1465         break;
1466     case 1: /* tst.w */
1467         opsize = OS_WORD;
1468         break;
1469     case 2: /* tst.l */
1470         opsize = OS_LONG;
1471         break;
1472     default:
1473         abort();
1474     }
1475     SRC_EA(tmp, opsize, 1, NULL);
1476     gen_logic_cc(s, tmp);
1477 }
1478
1479 DISAS_INSN(pulse)
1480 {
1481   /* Implemented as a NOP.  */
1482 }
1483
1484 DISAS_INSN(illegal)
1485 {
1486     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1487 }
1488
1489 /* ??? This should be atomic.  */
1490 DISAS_INSN(tas)
1491 {
1492     TCGv dest;
1493     TCGv src1;
1494     TCGv addr;
1495
1496     dest = tcg_temp_new();
1497     SRC_EA(src1, OS_BYTE, 1, &addr);
1498     gen_logic_cc(s, src1);
1499     tcg_gen_ori_i32(dest, src1, 0x80);
1500     DEST_EA(insn, OS_BYTE, dest, &addr);
1501 }
1502
1503 DISAS_INSN(mull)
1504 {
1505     uint16_t ext;
1506     TCGv reg;
1507     TCGv src1;
1508     TCGv dest;
1509
1510     /* The upper 32 bits of the product are discarded, so
1511        muls.l and mulu.l are functionally equivalent.  */
1512     ext = cpu_lduw_code(cpu_single_env, s->pc);
1513     s->pc += 2;
1514     if (ext & 0x87ff) {
1515         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1516         return;
1517     }
1518     reg = DREG(ext, 12);
1519     SRC_EA(src1, OS_LONG, 0, NULL);
1520     dest = tcg_temp_new();
1521     tcg_gen_mul_i32(dest, src1, reg);
1522     tcg_gen_mov_i32(reg, dest);
1523     /* Unlike m68k, coldfire always clears the overflow bit.  */
1524     gen_logic_cc(s, dest);
1525 }
1526
1527 DISAS_INSN(link)
1528 {
1529     int16_t offset;
1530     TCGv reg;
1531     TCGv tmp;
1532
1533     offset = cpu_ldsw_code(cpu_single_env, s->pc);
1534     s->pc += 2;
1535     reg = AREG(insn, 0);
1536     tmp = tcg_temp_new();
1537     tcg_gen_subi_i32(tmp, QREG_SP, 4);
1538     gen_store(s, OS_LONG, tmp, reg);
1539     if ((insn & 7) != 7)
1540         tcg_gen_mov_i32(reg, tmp);
1541     tcg_gen_addi_i32(QREG_SP, tmp, offset);
1542 }
1543
1544 DISAS_INSN(unlk)
1545 {
1546     TCGv src;
1547     TCGv reg;
1548     TCGv tmp;
1549
1550     src = tcg_temp_new();
1551     reg = AREG(insn, 0);
1552     tcg_gen_mov_i32(src, reg);
1553     tmp = gen_load(s, OS_LONG, src, 0);
1554     tcg_gen_mov_i32(reg, tmp);
1555     tcg_gen_addi_i32(QREG_SP, src, 4);
1556 }
1557
1558 DISAS_INSN(nop)
1559 {
1560 }
1561
1562 DISAS_INSN(rts)
1563 {
1564     TCGv tmp;
1565
1566     tmp = gen_load(s, OS_LONG, QREG_SP, 0);
1567     tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
1568     gen_jmp(s, tmp);
1569 }
1570
1571 DISAS_INSN(jump)
1572 {
1573     TCGv tmp;
1574
1575     /* Load the target address first to ensure correct exception
1576        behavior.  */
1577     tmp = gen_lea(s, insn, OS_LONG);
1578     if (IS_NULL_QREG(tmp)) {
1579         gen_addr_fault(s);
1580         return;
1581     }
1582     if ((insn & 0x40) == 0) {
1583         /* jsr */
1584         gen_push(s, tcg_const_i32(s->pc));
1585     }
1586     gen_jmp(s, tmp);
1587 }
1588
1589 DISAS_INSN(addsubq)
1590 {
1591     TCGv src1;
1592     TCGv src2;
1593     TCGv dest;
1594     int val;
1595     TCGv addr;
1596
1597     SRC_EA(src1, OS_LONG, 0, &addr);
1598     val = (insn >> 9) & 7;
1599     if (val == 0)
1600         val = 8;
1601     dest = tcg_temp_new();
1602     tcg_gen_mov_i32(dest, src1);
1603     if ((insn & 0x38) == 0x08) {
1604         /* Don't update condition codes if the destination is an
1605            address register.  */
1606         if (insn & 0x0100) {
1607             tcg_gen_subi_i32(dest, dest, val);
1608         } else {
1609             tcg_gen_addi_i32(dest, dest, val);
1610         }
1611     } else {
1612         src2 = tcg_const_i32(val);
1613         if (insn & 0x0100) {
1614             gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1615             tcg_gen_subi_i32(dest, dest, val);
1616             s->cc_op = CC_OP_SUB;
1617         } else {
1618             tcg_gen_addi_i32(dest, dest, val);
1619             gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1620             s->cc_op = CC_OP_ADD;
1621         }
1622         gen_update_cc_add(dest, src2);
1623     }
1624     DEST_EA(insn, OS_LONG, dest, &addr);
1625 }
1626
1627 DISAS_INSN(tpf)
1628 {
1629     switch (insn & 7) {
1630     case 2: /* One extension word.  */
1631         s->pc += 2;
1632         break;
1633     case 3: /* Two extension words.  */
1634         s->pc += 4;
1635         break;
1636     case 4: /* No extension words.  */
1637         break;
1638     default:
1639         disas_undef(s, insn);
1640     }
1641 }
1642
1643 DISAS_INSN(branch)
1644 {
1645     int32_t offset;
1646     uint32_t base;
1647     int op;
1648     int l1;
1649
1650     base = s->pc;
1651     op = (insn >> 8) & 0xf;
1652     offset = (int8_t)insn;
1653     if (offset == 0) {
1654         offset = cpu_ldsw_code(cpu_single_env, s->pc);
1655         s->pc += 2;
1656     } else if (offset == -1) {
1657         offset = read_im32(s);
1658     }
1659     if (op == 1) {
1660         /* bsr */
1661         gen_push(s, tcg_const_i32(s->pc));
1662     }
1663     gen_flush_cc_op(s);
1664     if (op > 1) {
1665         /* Bcc */
1666         l1 = gen_new_label();
1667         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1668         gen_jmp_tb(s, 1, base + offset);
1669         gen_set_label(l1);
1670         gen_jmp_tb(s, 0, s->pc);
1671     } else {
1672         /* Unconditional branch.  */
1673         gen_jmp_tb(s, 0, base + offset);
1674     }
1675 }
1676
1677 DISAS_INSN(moveq)
1678 {
1679     uint32_t val;
1680
1681     val = (int8_t)insn;
1682     tcg_gen_movi_i32(DREG(insn, 9), val);
1683     gen_logic_cc(s, tcg_const_i32(val));
1684 }
1685
1686 DISAS_INSN(mvzs)
1687 {
1688     int opsize;
1689     TCGv src;
1690     TCGv reg;
1691
1692     if (insn & 0x40)
1693         opsize = OS_WORD;
1694     else
1695         opsize = OS_BYTE;
1696     SRC_EA(src, opsize, (insn & 0x80) == 0, NULL);
1697     reg = DREG(insn, 9);
1698     tcg_gen_mov_i32(reg, src);
1699     gen_logic_cc(s, src);
1700 }
1701
1702 DISAS_INSN(or)
1703 {
1704     TCGv reg;
1705     TCGv dest;
1706     TCGv src;
1707     TCGv addr;
1708
1709     reg = DREG(insn, 9);
1710     dest = tcg_temp_new();
1711     if (insn & 0x100) {
1712         SRC_EA(src, OS_LONG, 0, &addr);
1713         tcg_gen_or_i32(dest, src, reg);
1714         DEST_EA(insn, OS_LONG, dest, &addr);
1715     } else {
1716         SRC_EA(src, OS_LONG, 0, NULL);
1717         tcg_gen_or_i32(dest, src, reg);
1718         tcg_gen_mov_i32(reg, dest);
1719     }
1720     gen_logic_cc(s, dest);
1721 }
1722
1723 DISAS_INSN(suba)
1724 {
1725     TCGv src;
1726     TCGv reg;
1727
1728     SRC_EA(src, OS_LONG, 0, NULL);
1729     reg = AREG(insn, 9);
1730     tcg_gen_sub_i32(reg, reg, src);
1731 }
1732
1733 DISAS_INSN(subx)
1734 {
1735     TCGv reg;
1736     TCGv src;
1737
1738     gen_flush_flags(s);
1739     reg = DREG(insn, 9);
1740     src = DREG(insn, 0);
1741     gen_helper_subx_cc(reg, cpu_env, reg, src);
1742 }
1743
1744 DISAS_INSN(mov3q)
1745 {
1746     TCGv src;
1747     int val;
1748
1749     val = (insn >> 9) & 7;
1750     if (val == 0)
1751         val = -1;
1752     src = tcg_const_i32(val);
1753     gen_logic_cc(s, src);
1754     DEST_EA(insn, OS_LONG, src, NULL);
1755 }
1756
1757 DISAS_INSN(cmp)
1758 {
1759     int op;
1760     TCGv src;
1761     TCGv reg;
1762     TCGv dest;
1763     int opsize;
1764
1765     op = (insn >> 6) & 3;
1766     switch (op) {
1767     case 0: /* cmp.b */
1768         opsize = OS_BYTE;
1769         s->cc_op = CC_OP_CMPB;
1770         break;
1771     case 1: /* cmp.w */
1772         opsize = OS_WORD;
1773         s->cc_op = CC_OP_CMPW;
1774         break;
1775     case 2: /* cmp.l */
1776         opsize = OS_LONG;
1777         s->cc_op = CC_OP_SUB;
1778         break;
1779     default:
1780         abort();
1781     }
1782     SRC_EA(src, opsize, 1, NULL);
1783     reg = DREG(insn, 9);
1784     dest = tcg_temp_new();
1785     tcg_gen_sub_i32(dest, reg, src);
1786     gen_update_cc_add(dest, src);
1787 }
1788
1789 DISAS_INSN(cmpa)
1790 {
1791     int opsize;
1792     TCGv src;
1793     TCGv reg;
1794     TCGv dest;
1795
1796     if (insn & 0x100) {
1797         opsize = OS_LONG;
1798     } else {
1799         opsize = OS_WORD;
1800     }
1801     SRC_EA(src, opsize, 1, NULL);
1802     reg = AREG(insn, 9);
1803     dest = tcg_temp_new();
1804     tcg_gen_sub_i32(dest, reg, src);
1805     gen_update_cc_add(dest, src);
1806     s->cc_op = CC_OP_SUB;
1807 }
1808
1809 DISAS_INSN(eor)
1810 {
1811     TCGv src;
1812     TCGv reg;
1813     TCGv dest;
1814     TCGv addr;
1815
1816     SRC_EA(src, OS_LONG, 0, &addr);
1817     reg = DREG(insn, 9);
1818     dest = tcg_temp_new();
1819     tcg_gen_xor_i32(dest, src, reg);
1820     gen_logic_cc(s, dest);
1821     DEST_EA(insn, OS_LONG, dest, &addr);
1822 }
1823
1824 DISAS_INSN(and)
1825 {
1826     TCGv src;
1827     TCGv reg;
1828     TCGv dest;
1829     TCGv addr;
1830
1831     reg = DREG(insn, 9);
1832     dest = tcg_temp_new();
1833     if (insn & 0x100) {
1834         SRC_EA(src, OS_LONG, 0, &addr);
1835         tcg_gen_and_i32(dest, src, reg);
1836         DEST_EA(insn, OS_LONG, dest, &addr);
1837     } else {
1838         SRC_EA(src, OS_LONG, 0, NULL);
1839         tcg_gen_and_i32(dest, src, reg);
1840         tcg_gen_mov_i32(reg, dest);
1841     }
1842     gen_logic_cc(s, dest);
1843 }
1844
1845 DISAS_INSN(adda)
1846 {
1847     TCGv src;
1848     TCGv reg;
1849
1850     SRC_EA(src, OS_LONG, 0, NULL);
1851     reg = AREG(insn, 9);
1852     tcg_gen_add_i32(reg, reg, src);
1853 }
1854
1855 DISAS_INSN(addx)
1856 {
1857     TCGv reg;
1858     TCGv src;
1859
1860     gen_flush_flags(s);
1861     reg = DREG(insn, 9);
1862     src = DREG(insn, 0);
1863     gen_helper_addx_cc(reg, cpu_env, reg, src);
1864     s->cc_op = CC_OP_FLAGS;
1865 }
1866
1867 /* TODO: This could be implemented without helper functions.  */
1868 DISAS_INSN(shift_im)
1869 {
1870     TCGv reg;
1871     int tmp;
1872     TCGv shift;
1873
1874     reg = DREG(insn, 0);
1875     tmp = (insn >> 9) & 7;
1876     if (tmp == 0)
1877         tmp = 8;
1878     shift = tcg_const_i32(tmp);
1879     /* No need to flush flags becuse we know we will set C flag.  */
1880     if (insn & 0x100) {
1881         gen_helper_shl_cc(reg, cpu_env, reg, shift);
1882     } else {
1883         if (insn & 8) {
1884             gen_helper_shr_cc(reg, cpu_env, reg, shift);
1885         } else {
1886             gen_helper_sar_cc(reg, cpu_env, reg, shift);
1887         }
1888     }
1889     s->cc_op = CC_OP_SHIFT;
1890 }
1891
1892 DISAS_INSN(shift_reg)
1893 {
1894     TCGv reg;
1895     TCGv shift;
1896
1897     reg = DREG(insn, 0);
1898     shift = DREG(insn, 9);
1899     /* Shift by zero leaves C flag unmodified.   */
1900     gen_flush_flags(s);
1901     if (insn & 0x100) {
1902         gen_helper_shl_cc(reg, cpu_env, reg, shift);
1903     } else {
1904         if (insn & 8) {
1905             gen_helper_shr_cc(reg, cpu_env, reg, shift);
1906         } else {
1907             gen_helper_sar_cc(reg, cpu_env, reg, shift);
1908         }
1909     }
1910     s->cc_op = CC_OP_SHIFT;
1911 }
1912
1913 DISAS_INSN(ff1)
1914 {
1915     TCGv reg;
1916     reg = DREG(insn, 0);
1917     gen_logic_cc(s, reg);
1918     gen_helper_ff1(reg, reg);
1919 }
1920
1921 static TCGv gen_get_sr(DisasContext *s)
1922 {
1923     TCGv ccr;
1924     TCGv sr;
1925
1926     ccr = gen_get_ccr(s);
1927     sr = tcg_temp_new();
1928     tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
1929     tcg_gen_or_i32(sr, sr, ccr);
1930     return sr;
1931 }
1932
1933 DISAS_INSN(strldsr)
1934 {
1935     uint16_t ext;
1936     uint32_t addr;
1937
1938     addr = s->pc - 2;
1939     ext = cpu_lduw_code(cpu_single_env, s->pc);
1940     s->pc += 2;
1941     if (ext != 0x46FC) {
1942         gen_exception(s, addr, EXCP_UNSUPPORTED);
1943         return;
1944     }
1945     ext = cpu_lduw_code(cpu_single_env, s->pc);
1946     s->pc += 2;
1947     if (IS_USER(s) || (ext & SR_S) == 0) {
1948         gen_exception(s, addr, EXCP_PRIVILEGE);
1949         return;
1950     }
1951     gen_push(s, gen_get_sr(s));
1952     gen_set_sr_im(s, ext, 0);
1953 }
1954
1955 DISAS_INSN(move_from_sr)
1956 {
1957     TCGv reg;
1958     TCGv sr;
1959
1960     if (IS_USER(s)) {
1961         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1962         return;
1963     }
1964     sr = gen_get_sr(s);
1965     reg = DREG(insn, 0);
1966     gen_partset_reg(OS_WORD, reg, sr);
1967 }
1968
1969 DISAS_INSN(move_to_sr)
1970 {
1971     if (IS_USER(s)) {
1972         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1973         return;
1974     }
1975     gen_set_sr(s, insn, 0);
1976     gen_lookup_tb(s);
1977 }
1978
1979 DISAS_INSN(move_from_usp)
1980 {
1981     if (IS_USER(s)) {
1982         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1983         return;
1984     }
1985     /* TODO: Implement USP.  */
1986     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1987 }
1988
1989 DISAS_INSN(move_to_usp)
1990 {
1991     if (IS_USER(s)) {
1992         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1993         return;
1994     }
1995     /* TODO: Implement USP.  */
1996     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1997 }
1998
1999 DISAS_INSN(halt)
2000 {
2001     gen_exception(s, s->pc, EXCP_HALT_INSN);
2002 }
2003
2004 DISAS_INSN(stop)
2005 {
2006     uint16_t ext;
2007
2008     if (IS_USER(s)) {
2009         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2010         return;
2011     }
2012
2013     ext = cpu_lduw_code(cpu_single_env, s->pc);
2014     s->pc += 2;
2015
2016     gen_set_sr_im(s, ext, 0);
2017     tcg_gen_movi_i32(QREG_HALTED, 1);
2018     gen_exception(s, s->pc, EXCP_HLT);
2019 }
2020
2021 DISAS_INSN(rte)
2022 {
2023     if (IS_USER(s)) {
2024         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2025         return;
2026     }
2027     gen_exception(s, s->pc - 2, EXCP_RTE);
2028 }
2029
2030 DISAS_INSN(movec)
2031 {
2032     uint16_t ext;
2033     TCGv reg;
2034
2035     if (IS_USER(s)) {
2036         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2037         return;
2038     }
2039
2040     ext = cpu_lduw_code(cpu_single_env, s->pc);
2041     s->pc += 2;
2042
2043     if (ext & 0x8000) {
2044         reg = AREG(ext, 12);
2045     } else {
2046         reg = DREG(ext, 12);
2047     }
2048     gen_helper_movec(cpu_env, tcg_const_i32(ext & 0xfff), reg);
2049     gen_lookup_tb(s);
2050 }
2051
2052 DISAS_INSN(intouch)
2053 {
2054     if (IS_USER(s)) {
2055         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2056         return;
2057     }
2058     /* ICache fetch.  Implement as no-op.  */
2059 }
2060
2061 DISAS_INSN(cpushl)
2062 {
2063     if (IS_USER(s)) {
2064         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2065         return;
2066     }
2067     /* Cache push/invalidate.  Implement as no-op.  */
2068 }
2069
2070 DISAS_INSN(wddata)
2071 {
2072     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2073 }
2074
2075 DISAS_INSN(wdebug)
2076 {
2077     if (IS_USER(s)) {
2078         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
2079         return;
2080     }
2081     /* TODO: Implement wdebug.  */
2082     qemu_assert(0, "WDEBUG not implemented");
2083 }
2084
2085 DISAS_INSN(trap)
2086 {
2087     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
2088 }
2089
2090 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
2091    immediately before the next FP instruction is executed.  */
2092 DISAS_INSN(fpu)
2093 {
2094     uint16_t ext;
2095     int32_t offset;
2096     int opmode;
2097     TCGv_i64 src;
2098     TCGv_i64 dest;
2099     TCGv_i64 res;
2100     TCGv tmp32;
2101     int round;
2102     int set_dest;
2103     int opsize;
2104
2105     ext = cpu_lduw_code(cpu_single_env, s->pc);
2106     s->pc += 2;
2107     opmode = ext & 0x7f;
2108     switch ((ext >> 13) & 7) {
2109     case 0: case 2:
2110         break;
2111     case 1:
2112         goto undef;
2113     case 3: /* fmove out */
2114         src = FREG(ext, 7);
2115         tmp32 = tcg_temp_new_i32();
2116         /* fmove */
2117         /* ??? TODO: Proper behavior on overflow.  */
2118         switch ((ext >> 10) & 7) {
2119         case 0:
2120             opsize = OS_LONG;
2121             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2122             break;
2123         case 1:
2124             opsize = OS_SINGLE;
2125             gen_helper_f64_to_f32(tmp32, cpu_env, src);
2126             break;
2127         case 4:
2128             opsize = OS_WORD;
2129             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2130             break;
2131         case 5: /* OS_DOUBLE */
2132             tcg_gen_mov_i32(tmp32, AREG(insn, 0));
2133             switch ((insn >> 3) & 7) {
2134             case 2:
2135             case 3:
2136                 break;
2137             case 4:
2138                 tcg_gen_addi_i32(tmp32, tmp32, -8);
2139                 break;
2140             case 5:
2141                 offset = cpu_ldsw_code(cpu_single_env, s->pc);
2142                 s->pc += 2;
2143                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2144                 break;
2145             default:
2146                 goto undef;
2147             }
2148             gen_store64(s, tmp32, src);
2149             switch ((insn >> 3) & 7) {
2150             case 3:
2151                 tcg_gen_addi_i32(tmp32, tmp32, 8);
2152                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2153                 break;
2154             case 4:
2155                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2156                 break;
2157             }
2158             tcg_temp_free_i32(tmp32);
2159             return;
2160         case 6:
2161             opsize = OS_BYTE;
2162             gen_helper_f64_to_i32(tmp32, cpu_env, src);
2163             break;
2164         default:
2165             goto undef;
2166         }
2167         DEST_EA(insn, opsize, tmp32, NULL);
2168         tcg_temp_free_i32(tmp32);
2169         return;
2170     case 4: /* fmove to control register.  */
2171         switch ((ext >> 10) & 7) {
2172         case 4: /* FPCR */
2173             /* Not implemented.  Ignore writes.  */
2174             break;
2175         case 1: /* FPIAR */
2176         case 2: /* FPSR */
2177         default:
2178             cpu_abort(NULL, "Unimplemented: fmove to control %d",
2179                       (ext >> 10) & 7);
2180         }
2181         break;
2182     case 5: /* fmove from control register.  */
2183         switch ((ext >> 10) & 7) {
2184         case 4: /* FPCR */
2185             /* Not implemented.  Always return zero.  */
2186             tmp32 = tcg_const_i32(0);
2187             break;
2188         case 1: /* FPIAR */
2189         case 2: /* FPSR */
2190         default:
2191             cpu_abort(NULL, "Unimplemented: fmove from control %d",
2192                       (ext >> 10) & 7);
2193             goto undef;
2194         }
2195         DEST_EA(insn, OS_LONG, tmp32, NULL);
2196         break;
2197     case 6: /* fmovem */
2198     case 7:
2199         {
2200             TCGv addr;
2201             uint16_t mask;
2202             int i;
2203             if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
2204                 goto undef;
2205             tmp32 = gen_lea(s, insn, OS_LONG);
2206             if (IS_NULL_QREG(tmp32)) {
2207                 gen_addr_fault(s);
2208                 return;
2209             }
2210             addr = tcg_temp_new_i32();
2211             tcg_gen_mov_i32(addr, tmp32);
2212             mask = 0x80;
2213             for (i = 0; i < 8; i++) {
2214                 if (ext & mask) {
2215                     s->is_mem = 1;
2216                     dest = FREG(i, 0);
2217                     if (ext & (1 << 13)) {
2218                         /* store */
2219                         tcg_gen_qemu_stf64(dest, addr, IS_USER(s));
2220                     } else {
2221                         /* load */
2222                         tcg_gen_qemu_ldf64(dest, addr, IS_USER(s));
2223                     }
2224                     if (ext & (mask - 1))
2225                         tcg_gen_addi_i32(addr, addr, 8);
2226                 }
2227                 mask >>= 1;
2228             }
2229             tcg_temp_free_i32(addr);
2230         }
2231         return;
2232     }
2233     if (ext & (1 << 14)) {
2234         /* Source effective address.  */
2235         switch ((ext >> 10) & 7) {
2236         case 0: opsize = OS_LONG; break;
2237         case 1: opsize = OS_SINGLE; break;
2238         case 4: opsize = OS_WORD; break;
2239         case 5: opsize = OS_DOUBLE; break;
2240         case 6: opsize = OS_BYTE; break;
2241         default:
2242             goto undef;
2243         }
2244         if (opsize == OS_DOUBLE) {
2245             tmp32 = tcg_temp_new_i32();
2246             tcg_gen_mov_i32(tmp32, AREG(insn, 0));
2247             switch ((insn >> 3) & 7) {
2248             case 2:
2249             case 3:
2250                 break;
2251             case 4:
2252                 tcg_gen_addi_i32(tmp32, tmp32, -8);
2253                 break;
2254             case 5:
2255                 offset = cpu_ldsw_code(cpu_single_env, s->pc);
2256                 s->pc += 2;
2257                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2258                 break;
2259             case 7:
2260                 offset = cpu_ldsw_code(cpu_single_env, s->pc);
2261                 offset += s->pc - 2;
2262                 s->pc += 2;
2263                 tcg_gen_addi_i32(tmp32, tmp32, offset);
2264                 break;
2265             default:
2266                 goto undef;
2267             }
2268             src = gen_load64(s, tmp32);
2269             switch ((insn >> 3) & 7) {
2270             case 3:
2271                 tcg_gen_addi_i32(tmp32, tmp32, 8);
2272                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2273                 break;
2274             case 4:
2275                 tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2276                 break;
2277             }
2278             tcg_temp_free_i32(tmp32);
2279         } else {
2280             SRC_EA(tmp32, opsize, 1, NULL);
2281             src = tcg_temp_new_i64();
2282             switch (opsize) {
2283             case OS_LONG:
2284             case OS_WORD:
2285             case OS_BYTE:
2286                 gen_helper_i32_to_f64(src, cpu_env, tmp32);
2287                 break;
2288             case OS_SINGLE:
2289                 gen_helper_f32_to_f64(src, cpu_env, tmp32);
2290                 break;
2291             }
2292         }
2293     } else {
2294         /* Source register.  */
2295         src = FREG(ext, 10);
2296     }
2297     dest = FREG(ext, 7);
2298     res = tcg_temp_new_i64();
2299     if (opmode != 0x3a)
2300         tcg_gen_mov_f64(res, dest);
2301     round = 1;
2302     set_dest = 1;
2303     switch (opmode) {
2304     case 0: case 0x40: case 0x44: /* fmove */
2305         tcg_gen_mov_f64(res, src);
2306         break;
2307     case 1: /* fint */
2308         gen_helper_iround_f64(res, cpu_env, src);
2309         round = 0;
2310         break;
2311     case 3: /* fintrz */
2312         gen_helper_itrunc_f64(res, cpu_env, src);
2313         round = 0;
2314         break;
2315     case 4: case 0x41: case 0x45: /* fsqrt */
2316         gen_helper_sqrt_f64(res, cpu_env, src);
2317         break;
2318     case 0x18: case 0x58: case 0x5c: /* fabs */
2319         gen_helper_abs_f64(res, src);
2320         break;
2321     case 0x1a: case 0x5a: case 0x5e: /* fneg */
2322         gen_helper_chs_f64(res, src);
2323         break;
2324     case 0x20: case 0x60: case 0x64: /* fdiv */
2325         gen_helper_div_f64(res, cpu_env, res, src);
2326         break;
2327     case 0x22: case 0x62: case 0x66: /* fadd */
2328         gen_helper_add_f64(res, cpu_env, res, src);
2329         break;
2330     case 0x23: case 0x63: case 0x67: /* fmul */
2331         gen_helper_mul_f64(res, cpu_env, res, src);
2332         break;
2333     case 0x28: case 0x68: case 0x6c: /* fsub */
2334         gen_helper_sub_f64(res, cpu_env, res, src);
2335         break;
2336     case 0x38: /* fcmp */
2337         gen_helper_sub_cmp_f64(res, cpu_env, res, src);
2338         set_dest = 0;
2339         round = 0;
2340         break;
2341     case 0x3a: /* ftst */
2342         tcg_gen_mov_f64(res, src);
2343         set_dest = 0;
2344         round = 0;
2345         break;
2346     default:
2347         goto undef;
2348     }
2349     if (ext & (1 << 14)) {
2350         tcg_temp_free_i64(src);
2351     }
2352     if (round) {
2353         if (opmode & 0x40) {
2354             if ((opmode & 0x4) != 0)
2355                 round = 0;
2356         } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2357             round = 0;
2358         }
2359     }
2360     if (round) {
2361         TCGv tmp = tcg_temp_new_i32();
2362         gen_helper_f64_to_f32(tmp, cpu_env, res);
2363         gen_helper_f32_to_f64(res, cpu_env, tmp);
2364         tcg_temp_free_i32(tmp);
2365     }
2366     tcg_gen_mov_f64(QREG_FP_RESULT, res);
2367     if (set_dest) {
2368         tcg_gen_mov_f64(dest, res);
2369     }
2370     tcg_temp_free_i64(res);
2371     return;
2372 undef:
2373     /* FIXME: Is this right for offset addressing modes?  */
2374     s->pc -= 2;
2375     disas_undef_fpu(s, insn);
2376 }
2377
2378 DISAS_INSN(fbcc)
2379 {
2380     uint32_t offset;
2381     uint32_t addr;
2382     TCGv flag;
2383     int l1;
2384
2385     addr = s->pc;
2386     offset = cpu_ldsw_code(cpu_single_env, s->pc);
2387     s->pc += 2;
2388     if (insn & (1 << 6)) {
2389         offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
2390         s->pc += 2;
2391     }
2392
2393     l1 = gen_new_label();
2394     /* TODO: Raise BSUN exception.  */
2395     flag = tcg_temp_new();
2396     gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
2397     /* Jump to l1 if condition is true.  */
2398     switch (insn & 0xf) {
2399     case 0: /* f */
2400         break;
2401     case 1: /* eq (=0) */
2402         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2403         break;
2404     case 2: /* ogt (=1) */
2405         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(1), l1);
2406         break;
2407     case 3: /* oge (=0 or =1) */
2408         tcg_gen_brcond_i32(TCG_COND_LEU, flag, tcg_const_i32(1), l1);
2409         break;
2410     case 4: /* olt (=-1) */
2411         tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(0), l1);
2412         break;
2413     case 5: /* ole (=-1 or =0) */
2414         tcg_gen_brcond_i32(TCG_COND_LE, flag, tcg_const_i32(0), l1);
2415         break;
2416     case 6: /* ogl (=-1 or =1) */
2417         tcg_gen_andi_i32(flag, flag, 1);
2418         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2419         break;
2420     case 7: /* or (=2) */
2421         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(2), l1);
2422         break;
2423     case 8: /* un (<2) */
2424         tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(2), l1);
2425         break;
2426     case 9: /* ueq (=0 or =2) */
2427         tcg_gen_andi_i32(flag, flag, 1);
2428         tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2429         break;
2430     case 10: /* ugt (>0) */
2431         tcg_gen_brcond_i32(TCG_COND_GT, flag, tcg_const_i32(0), l1);
2432         break;
2433     case 11: /* uge (>=0) */
2434         tcg_gen_brcond_i32(TCG_COND_GE, flag, tcg_const_i32(0), l1);
2435         break;
2436     case 12: /* ult (=-1 or =2) */
2437         tcg_gen_brcond_i32(TCG_COND_GEU, flag, tcg_const_i32(2), l1);
2438         break;
2439     case 13: /* ule (!=1) */
2440         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(1), l1);
2441         break;
2442     case 14: /* ne (!=0) */
2443         tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2444         break;
2445     case 15: /* t */
2446         tcg_gen_br(l1);
2447         break;
2448     }
2449     gen_jmp_tb(s, 0, s->pc);
2450     gen_set_label(l1);
2451     gen_jmp_tb(s, 1, addr + offset);
2452 }
2453
2454 DISAS_INSN(frestore)
2455 {
2456     /* TODO: Implement frestore.  */
2457     qemu_assert(0, "FRESTORE not implemented");
2458 }
2459
2460 DISAS_INSN(fsave)
2461 {
2462     /* TODO: Implement fsave.  */
2463     qemu_assert(0, "FSAVE not implemented");
2464 }
2465
2466 static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
2467 {
2468     TCGv tmp = tcg_temp_new();
2469     if (s->env->macsr & MACSR_FI) {
2470         if (upper)
2471             tcg_gen_andi_i32(tmp, val, 0xffff0000);
2472         else
2473             tcg_gen_shli_i32(tmp, val, 16);
2474     } else if (s->env->macsr & MACSR_SU) {
2475         if (upper)
2476             tcg_gen_sari_i32(tmp, val, 16);
2477         else
2478             tcg_gen_ext16s_i32(tmp, val);
2479     } else {
2480         if (upper)
2481             tcg_gen_shri_i32(tmp, val, 16);
2482         else
2483             tcg_gen_ext16u_i32(tmp, val);
2484     }
2485     return tmp;
2486 }
2487
2488 static void gen_mac_clear_flags(void)
2489 {
2490     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
2491                      ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
2492 }
2493
2494 DISAS_INSN(mac)
2495 {
2496     TCGv rx;
2497     TCGv ry;
2498     uint16_t ext;
2499     int acc;
2500     TCGv tmp;
2501     TCGv addr;
2502     TCGv loadval;
2503     int dual;
2504     TCGv saved_flags;
2505
2506     if (!s->done_mac) {
2507         s->mactmp = tcg_temp_new_i64();
2508         s->done_mac = 1;
2509     }
2510
2511     ext = cpu_lduw_code(cpu_single_env, s->pc);
2512     s->pc += 2;
2513
2514     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
2515     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
2516     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
2517         disas_undef(s, insn);
2518         return;
2519     }
2520     if (insn & 0x30) {
2521         /* MAC with load.  */
2522         tmp = gen_lea(s, insn, OS_LONG);
2523         addr = tcg_temp_new();
2524         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
2525         /* Load the value now to ensure correct exception behavior.
2526            Perform writeback after reading the MAC inputs.  */
2527         loadval = gen_load(s, OS_LONG, addr, 0);
2528
2529         acc ^= 1;
2530         rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
2531         ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
2532     } else {
2533         loadval = addr = NULL_QREG;
2534         rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2535         ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2536     }
2537
2538     gen_mac_clear_flags();
2539 #if 0
2540     l1 = -1;
2541     /* Disabled because conditional branches clobber temporary vars.  */
2542     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
2543         /* Skip the multiply if we know we will ignore it.  */
2544         l1 = gen_new_label();
2545         tmp = tcg_temp_new();
2546         tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
2547         gen_op_jmp_nz32(tmp, l1);
2548     }
2549 #endif
2550
2551     if ((ext & 0x0800) == 0) {
2552         /* Word.  */
2553         rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
2554         ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2555     }
2556     if (s->env->macsr & MACSR_FI) {
2557         gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
2558     } else {
2559         if (s->env->macsr & MACSR_SU)
2560             gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
2561         else
2562             gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
2563         switch ((ext >> 9) & 3) {
2564         case 1:
2565             tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
2566             break;
2567         case 3:
2568             tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
2569             break;
2570         }
2571     }
2572
2573     if (dual) {
2574         /* Save the overflow flag from the multiply.  */
2575         saved_flags = tcg_temp_new();
2576         tcg_gen_mov_i32(saved_flags, QREG_MACSR);
2577     } else {
2578         saved_flags = NULL_QREG;
2579     }
2580
2581 #if 0
2582     /* Disabled because conditional branches clobber temporary vars.  */
2583     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2584         /* Skip the accumulate if the value is already saturated.  */
2585         l1 = gen_new_label();
2586         tmp = tcg_temp_new();
2587         gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
2588         gen_op_jmp_nz32(tmp, l1);
2589     }
2590 #endif
2591
2592     if (insn & 0x100)
2593         tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2594     else
2595         tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2596
2597     if (s->env->macsr & MACSR_FI)
2598         gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2599     else if (s->env->macsr & MACSR_SU)
2600         gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2601     else
2602         gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2603
2604 #if 0
2605     /* Disabled because conditional branches clobber temporary vars.  */
2606     if (l1 != -1)
2607         gen_set_label(l1);
2608 #endif
2609
2610     if (dual) {
2611         /* Dual accumulate variant.  */
2612         acc = (ext >> 2) & 3;
2613         /* Restore the overflow flag from the multiplier.  */
2614         tcg_gen_mov_i32(QREG_MACSR, saved_flags);
2615 #if 0
2616         /* Disabled because conditional branches clobber temporary vars.  */
2617         if ((s->env->macsr & MACSR_OMC) != 0) {
2618             /* Skip the accumulate if the value is already saturated.  */
2619             l1 = gen_new_label();
2620             tmp = tcg_temp_new();
2621             gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
2622             gen_op_jmp_nz32(tmp, l1);
2623         }
2624 #endif
2625         if (ext & 2)
2626             tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2627         else
2628             tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2629         if (s->env->macsr & MACSR_FI)
2630             gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2631         else if (s->env->macsr & MACSR_SU)
2632             gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2633         else
2634             gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2635 #if 0
2636         /* Disabled because conditional branches clobber temporary vars.  */
2637         if (l1 != -1)
2638             gen_set_label(l1);
2639 #endif
2640     }
2641     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
2642
2643     if (insn & 0x30) {
2644         TCGv rw;
2645         rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2646         tcg_gen_mov_i32(rw, loadval);
2647         /* FIXME: Should address writeback happen with the masked or
2648            unmasked value?  */
2649         switch ((insn >> 3) & 7) {
2650         case 3: /* Post-increment.  */
2651             tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
2652             break;
2653         case 4: /* Pre-decrement.  */
2654             tcg_gen_mov_i32(AREG(insn, 0), addr);
2655         }
2656     }
2657 }
2658
2659 DISAS_INSN(from_mac)
2660 {
2661     TCGv rx;
2662     TCGv_i64 acc;
2663     int accnum;
2664
2665     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2666     accnum = (insn >> 9) & 3;
2667     acc = MACREG(accnum);
2668     if (s->env->macsr & MACSR_FI) {
2669         gen_helper_get_macf(rx, cpu_env, acc);
2670     } else if ((s->env->macsr & MACSR_OMC) == 0) {
2671         tcg_gen_trunc_i64_i32(rx, acc);
2672     } else if (s->env->macsr & MACSR_SU) {
2673         gen_helper_get_macs(rx, acc);
2674     } else {
2675         gen_helper_get_macu(rx, acc);
2676     }
2677     if (insn & 0x40) {
2678         tcg_gen_movi_i64(acc, 0);
2679         tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2680     }
2681 }
2682
2683 DISAS_INSN(move_mac)
2684 {
2685     /* FIXME: This can be done without a helper.  */
2686     int src;
2687     TCGv dest;
2688     src = insn & 3;
2689     dest = tcg_const_i32((insn >> 9) & 3);
2690     gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
2691     gen_mac_clear_flags();
2692     gen_helper_mac_set_flags(cpu_env, dest);
2693 }
2694
2695 DISAS_INSN(from_macsr)
2696 {
2697     TCGv reg;
2698
2699     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2700     tcg_gen_mov_i32(reg, QREG_MACSR);
2701 }
2702
2703 DISAS_INSN(from_mask)
2704 {
2705     TCGv reg;
2706     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2707     tcg_gen_mov_i32(reg, QREG_MAC_MASK);
2708 }
2709
2710 DISAS_INSN(from_mext)
2711 {
2712     TCGv reg;
2713     TCGv acc;
2714     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2715     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2716     if (s->env->macsr & MACSR_FI)
2717         gen_helper_get_mac_extf(reg, cpu_env, acc);
2718     else
2719         gen_helper_get_mac_exti(reg, cpu_env, acc);
2720 }
2721
2722 DISAS_INSN(macsr_to_ccr)
2723 {
2724     tcg_gen_movi_i32(QREG_CC_X, 0);
2725     tcg_gen_andi_i32(QREG_CC_DEST, QREG_MACSR, 0xf);
2726     s->cc_op = CC_OP_FLAGS;
2727 }
2728
2729 DISAS_INSN(to_mac)
2730 {
2731     TCGv_i64 acc;
2732     TCGv val;
2733     int accnum;
2734     accnum = (insn >> 9) & 3;
2735     acc = MACREG(accnum);
2736     SRC_EA(val, OS_LONG, 0, NULL);
2737     if (s->env->macsr & MACSR_FI) {
2738         tcg_gen_ext_i32_i64(acc, val);
2739         tcg_gen_shli_i64(acc, acc, 8);
2740     } else if (s->env->macsr & MACSR_SU) {
2741         tcg_gen_ext_i32_i64(acc, val);
2742     } else {
2743         tcg_gen_extu_i32_i64(acc, val);
2744     }
2745     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2746     gen_mac_clear_flags();
2747     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
2748 }
2749
2750 DISAS_INSN(to_macsr)
2751 {
2752     TCGv val;
2753     SRC_EA(val, OS_LONG, 0, NULL);
2754     gen_helper_set_macsr(cpu_env, val);
2755     gen_lookup_tb(s);
2756 }
2757
2758 DISAS_INSN(to_mask)
2759 {
2760     TCGv val;
2761     SRC_EA(val, OS_LONG, 0, NULL);
2762     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
2763 }
2764
2765 DISAS_INSN(to_mext)
2766 {
2767     TCGv val;
2768     TCGv acc;
2769     SRC_EA(val, OS_LONG, 0, NULL);
2770     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2771     if (s->env->macsr & MACSR_FI)
2772         gen_helper_set_mac_extf(cpu_env, val, acc);
2773     else if (s->env->macsr & MACSR_SU)
2774         gen_helper_set_mac_exts(cpu_env, val, acc);
2775     else
2776         gen_helper_set_mac_extu(cpu_env, val, acc);
2777 }
2778
2779 static disas_proc opcode_table[65536];
2780
2781 static void
2782 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2783 {
2784   int i;
2785   int from;
2786   int to;
2787
2788   /* Sanity check.  All set bits must be included in the mask.  */
2789   if (opcode & ~mask) {
2790       fprintf(stderr,
2791               "qemu internal error: bogus opcode definition %04x/%04x\n",
2792               opcode, mask);
2793       abort();
2794   }
2795   /* This could probably be cleverer.  For now just optimize the case where
2796      the top bits are known.  */
2797   /* Find the first zero bit in the mask.  */
2798   i = 0x8000;
2799   while ((i & mask) != 0)
2800       i >>= 1;
2801   /* Iterate over all combinations of this and lower bits.  */
2802   if (i == 0)
2803       i = 1;
2804   else
2805       i <<= 1;
2806   from = opcode & ~(i - 1);
2807   to = from + i;
2808   for (i = from; i < to; i++) {
2809       if ((i & mask) == opcode)
2810           opcode_table[i] = proc;
2811   }
2812 }
2813
2814 /* Register m68k opcode handlers.  Order is important.
2815    Later insn override earlier ones.  */
2816 void register_m68k_insns (CPUM68KState *env)
2817 {
2818 #define INSN(name, opcode, mask, feature) do { \
2819     if (m68k_feature(env, M68K_FEATURE_##feature)) \
2820         register_opcode(disas_##name, 0x##opcode, 0x##mask); \
2821     } while(0)
2822     INSN(undef,     0000, 0000, CF_ISA_A);
2823     INSN(arith_im,  0080, fff8, CF_ISA_A);
2824     INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
2825     INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
2826     INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
2827     INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
2828     INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
2829     INSN(arith_im,  0280, fff8, CF_ISA_A);
2830     INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
2831     INSN(arith_im,  0480, fff8, CF_ISA_A);
2832     INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
2833     INSN(arith_im,  0680, fff8, CF_ISA_A);
2834     INSN(bitop_im,  0800, ffc0, CF_ISA_A);
2835     INSN(bitop_im,  0840, ffc0, CF_ISA_A);
2836     INSN(bitop_im,  0880, ffc0, CF_ISA_A);
2837     INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
2838     INSN(arith_im,  0a80, fff8, CF_ISA_A);
2839     INSN(arith_im,  0c00, ff38, CF_ISA_A);
2840     INSN(move,      1000, f000, CF_ISA_A);
2841     INSN(move,      2000, f000, CF_ISA_A);
2842     INSN(move,      3000, f000, CF_ISA_A);
2843     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
2844     INSN(negx,      4080, fff8, CF_ISA_A);
2845     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
2846     INSN(lea,       41c0, f1c0, CF_ISA_A);
2847     INSN(clr,       4200, ff00, CF_ISA_A);
2848     INSN(undef,     42c0, ffc0, CF_ISA_A);
2849     INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
2850     INSN(neg,       4480, fff8, CF_ISA_A);
2851     INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
2852     INSN(not,       4680, fff8, CF_ISA_A);
2853     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
2854     INSN(pea,       4840, ffc0, CF_ISA_A);
2855     INSN(swap,      4840, fff8, CF_ISA_A);
2856     INSN(movem,     48c0, fbc0, CF_ISA_A);
2857     INSN(ext,       4880, fff8, CF_ISA_A);
2858     INSN(ext,       48c0, fff8, CF_ISA_A);
2859     INSN(ext,       49c0, fff8, CF_ISA_A);
2860     INSN(tst,       4a00, ff00, CF_ISA_A);
2861     INSN(tas,       4ac0, ffc0, CF_ISA_B);
2862     INSN(halt,      4ac8, ffff, CF_ISA_A);
2863     INSN(pulse,     4acc, ffff, CF_ISA_A);
2864     INSN(illegal,   4afc, ffff, CF_ISA_A);
2865     INSN(mull,      4c00, ffc0, CF_ISA_A);
2866     INSN(divl,      4c40, ffc0, CF_ISA_A);
2867     INSN(sats,      4c80, fff8, CF_ISA_B);
2868     INSN(trap,      4e40, fff0, CF_ISA_A);
2869     INSN(link,      4e50, fff8, CF_ISA_A);
2870     INSN(unlk,      4e58, fff8, CF_ISA_A);
2871     INSN(move_to_usp, 4e60, fff8, USP);
2872     INSN(move_from_usp, 4e68, fff8, USP);
2873     INSN(nop,       4e71, ffff, CF_ISA_A);
2874     INSN(stop,      4e72, ffff, CF_ISA_A);
2875     INSN(rte,       4e73, ffff, CF_ISA_A);
2876     INSN(rts,       4e75, ffff, CF_ISA_A);
2877     INSN(movec,     4e7b, ffff, CF_ISA_A);
2878     INSN(jump,      4e80, ffc0, CF_ISA_A);
2879     INSN(jump,      4ec0, ffc0, CF_ISA_A);
2880     INSN(addsubq,   5180, f1c0, CF_ISA_A);
2881     INSN(scc,       50c0, f0f8, CF_ISA_A);
2882     INSN(addsubq,   5080, f1c0, CF_ISA_A);
2883     INSN(tpf,       51f8, fff8, CF_ISA_A);
2884
2885     /* Branch instructions.  */
2886     INSN(branch,    6000, f000, CF_ISA_A);
2887     /* Disable long branch instructions, then add back the ones we want.  */
2888     INSN(undef,     60ff, f0ff, CF_ISA_A); /* All long branches.  */
2889     INSN(branch,    60ff, f0ff, CF_ISA_B);
2890     INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
2891     INSN(branch,    60ff, ffff, BRAL);
2892
2893     INSN(moveq,     7000, f100, CF_ISA_A);
2894     INSN(mvzs,      7100, f100, CF_ISA_B);
2895     INSN(or,        8000, f000, CF_ISA_A);
2896     INSN(divw,      80c0, f0c0, CF_ISA_A);
2897     INSN(addsub,    9000, f000, CF_ISA_A);
2898     INSN(subx,      9180, f1f8, CF_ISA_A);
2899     INSN(suba,      91c0, f1c0, CF_ISA_A);
2900
2901     INSN(undef_mac, a000, f000, CF_ISA_A);
2902     INSN(mac,       a000, f100, CF_EMAC);
2903     INSN(from_mac,  a180, f9b0, CF_EMAC);
2904     INSN(move_mac,  a110, f9fc, CF_EMAC);
2905     INSN(from_macsr,a980, f9f0, CF_EMAC);
2906     INSN(from_mask, ad80, fff0, CF_EMAC);
2907     INSN(from_mext, ab80, fbf0, CF_EMAC);
2908     INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
2909     INSN(to_mac,    a100, f9c0, CF_EMAC);
2910     INSN(to_macsr,  a900, ffc0, CF_EMAC);
2911     INSN(to_mext,   ab00, fbc0, CF_EMAC);
2912     INSN(to_mask,   ad00, ffc0, CF_EMAC);
2913
2914     INSN(mov3q,     a140, f1c0, CF_ISA_B);
2915     INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
2916     INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
2917     INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
2918     INSN(cmp,       b080, f1c0, CF_ISA_A);
2919     INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
2920     INSN(eor,       b180, f1c0, CF_ISA_A);
2921     INSN(and,       c000, f000, CF_ISA_A);
2922     INSN(mulw,      c0c0, f0c0, CF_ISA_A);
2923     INSN(addsub,    d000, f000, CF_ISA_A);
2924     INSN(addx,      d180, f1f8, CF_ISA_A);
2925     INSN(adda,      d1c0, f1c0, CF_ISA_A);
2926     INSN(shift_im,  e080, f0f0, CF_ISA_A);
2927     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
2928     INSN(undef_fpu, f000, f000, CF_ISA_A);
2929     INSN(fpu,       f200, ffc0, CF_FPU);
2930     INSN(fbcc,      f280, ffc0, CF_FPU);
2931     INSN(frestore,  f340, ffc0, CF_FPU);
2932     INSN(fsave,     f340, ffc0, CF_FPU);
2933     INSN(intouch,   f340, ffc0, CF_ISA_A);
2934     INSN(cpushl,    f428, ff38, CF_ISA_A);
2935     INSN(wddata,    fb00, ff00, CF_ISA_A);
2936     INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
2937 #undef INSN
2938 }
2939
2940 /* ??? Some of this implementation is not exception safe.  We should always
2941    write back the result to memory before setting the condition codes.  */
2942 static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
2943 {
2944     uint16_t insn;
2945
2946     insn = cpu_lduw_code(cpu_single_env, s->pc);
2947     s->pc += 2;
2948
2949     opcode_table[insn](s, insn);
2950 }
2951
2952 /* generate intermediate code for basic block 'tb'.  */
2953 static inline void
2954 gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
2955                                int search_pc)
2956 {
2957     DisasContext dc1, *dc = &dc1;
2958     uint16_t *gen_opc_end;
2959     CPUBreakpoint *bp;
2960     int j, lj;
2961     target_ulong pc_start;
2962     int pc_offset;
2963     int num_insns;
2964     int max_insns;
2965
2966     /* generate intermediate code */
2967     pc_start = tb->pc;
2968
2969     dc->tb = tb;
2970
2971     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2972
2973     dc->env = env;
2974     dc->is_jmp = DISAS_NEXT;
2975     dc->pc = pc_start;
2976     dc->cc_op = CC_OP_DYNAMIC;
2977     dc->singlestep_enabled = env->singlestep_enabled;
2978     dc->fpcr = env->fpcr;
2979     dc->user = (env->sr & SR_S) == 0;
2980     dc->is_mem = 0;
2981     dc->done_mac = 0;
2982     lj = -1;
2983     num_insns = 0;
2984     max_insns = tb->cflags & CF_COUNT_MASK;
2985     if (max_insns == 0)
2986         max_insns = CF_COUNT_MASK;
2987
2988     gen_icount_start();
2989     do {
2990         pc_offset = dc->pc - pc_start;
2991         gen_throws_exception = NULL;
2992         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2993             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
2994                 if (bp->pc == dc->pc) {
2995                     gen_exception(dc, dc->pc, EXCP_DEBUG);
2996                     dc->is_jmp = DISAS_JUMP;
2997                     break;
2998                 }
2999             }
3000             if (dc->is_jmp)
3001                 break;
3002         }
3003         if (search_pc) {
3004             j = gen_opc_ptr - gen_opc_buf;
3005             if (lj < j) {
3006                 lj++;
3007                 while (lj < j)
3008                     gen_opc_instr_start[lj++] = 0;
3009             }
3010             gen_opc_pc[lj] = dc->pc;
3011             gen_opc_instr_start[lj] = 1;
3012             gen_opc_icount[lj] = num_insns;
3013         }
3014         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3015             gen_io_start();
3016         dc->insn_pc = dc->pc;
3017         disas_m68k_insn(env, dc);
3018         num_insns++;
3019     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3020              !env->singlestep_enabled &&
3021              !singlestep &&
3022              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
3023              num_insns < max_insns);
3024
3025     if (tb->cflags & CF_LAST_IO)
3026         gen_io_end();
3027     if (unlikely(env->singlestep_enabled)) {
3028         /* Make sure the pc is updated, and raise a debug exception.  */
3029         if (!dc->is_jmp) {
3030             gen_flush_cc_op(dc);
3031             tcg_gen_movi_i32(QREG_PC, dc->pc);
3032         }
3033         gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
3034     } else {
3035         switch(dc->is_jmp) {
3036         case DISAS_NEXT:
3037             gen_flush_cc_op(dc);
3038             gen_jmp_tb(dc, 0, dc->pc);
3039             break;
3040         default:
3041         case DISAS_JUMP:
3042         case DISAS_UPDATE:
3043             gen_flush_cc_op(dc);
3044             /* indicate that the hash table must be used to find the next TB */
3045             tcg_gen_exit_tb(0);
3046             break;
3047         case DISAS_TB_JUMP:
3048             /* nothing more to generate */
3049             break;
3050         }
3051     }
3052     gen_icount_end(tb, num_insns);
3053     *gen_opc_ptr = INDEX_op_end;
3054
3055 #ifdef DEBUG_DISAS
3056     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3057         qemu_log("----------------\n");
3058         qemu_log("IN: %s\n", lookup_symbol(pc_start));
3059         log_target_disas(pc_start, dc->pc - pc_start, 0);
3060         qemu_log("\n");
3061     }
3062 #endif
3063     if (search_pc) {
3064         j = gen_opc_ptr - gen_opc_buf;
3065         lj++;
3066         while (lj <= j)
3067             gen_opc_instr_start[lj++] = 0;
3068     } else {
3069         tb->size = dc->pc - pc_start;
3070         tb->icount = num_insns;
3071     }
3072
3073     //optimize_flags();
3074     //expand_target_qops();
3075 }
3076
3077 void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
3078 {
3079     gen_intermediate_code_internal(env, tb, 0);
3080 }
3081
3082 void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
3083 {
3084     gen_intermediate_code_internal(env, tb, 1);
3085 }
3086
3087 void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
3088                     int flags)
3089 {
3090     int i;
3091     uint16_t sr;
3092     CPU_DoubleU u;
3093     for (i = 0; i < 8; i++)
3094       {
3095         u.d = env->fregs[i];
3096         cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
3097                      i, env->dregs[i], i, env->aregs[i],
3098                      i, u.l.upper, u.l.lower, *(double *)&u.d);
3099       }
3100     cpu_fprintf (f, "PC = %08x   ", env->pc);
3101     sr = env->sr;
3102     cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
3103                  (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
3104                  (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
3105     cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
3106 }
3107
3108 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, int pc_pos)
3109 {
3110     env->pc = gen_opc_pc[pc_pos];
3111 }
This page took 0.248249 seconds and 4 git commands to generate.