M68k build fix.
[qemu] / target-m68k / translate.c
1 /*
2  *  m68k translation
3  * 
4  *  Copyright (c) 2005-2006 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, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
26
27 #include "config.h"
28 #include "cpu.h"
29 #include "exec-all.h"
30 #include "disas.h"
31 #include "m68k-qreg.h"
32
33 static inline void qemu_assert(int cond, const char *msg)
34 {
35     if (!cond) {
36         fprintf (stderr, "badness: %s\n", msg);
37         abort();
38     }
39 }
40
41 /* internal defines */
42 typedef struct DisasContext {
43     target_ulong pc;
44     int is_jmp;
45     int cc_op;
46     uint32_t fpcr;
47     struct TranslationBlock *tb;
48     int singlestep_enabled;
49 } DisasContext;
50
51 #define DISAS_JUMP_NEXT 4
52
53 /* XXX: move that elsewhere */
54 /* ??? Fix exceptions.  */
55 static void *gen_throws_exception;
56 #define gen_last_qop NULL
57
58 static uint16_t *gen_opc_ptr;
59 static uint32_t *gen_opparam_ptr;
60 extern FILE *logfile;
61 extern int loglevel;
62
63 enum {
64 #define DEF(s, n, copy_size) INDEX_op_ ## s,
65 #include "opc.h"
66 #undef DEF
67     NB_OPS,
68 };
69
70 #include "gen-op.h"
71 #include "op-hacks.h"
72
73 #define OS_BYTE 0
74 #define OS_WORD 1
75 #define OS_LONG 2
76 #define OS_SINGLE 4
77 #define OS_DOUBLE 5
78
79 #define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
80 #define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
81 #define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
82
83 #define M68K_INSN_CF_A    (1 << 0)
84 #define M68K_INSN_CF_B    (1 << 1)
85 #define M68K_INSN_CF_C    (1 << 2)
86 #define M68K_INSN_CF_MAC  (1 << 3)
87 #define M68K_INSN_CF_EMAC (1 << 4)
88 #define M68K_INSN_CF_FPU  (1 << 5)
89
90 struct m68k_def_t {
91     const char * name;
92     uint32_t insns;
93 };
94
95 static m68k_def_t m68k_cpu_defs[] = {
96     {"m5206", M68K_INSN_CF_A},
97     {"cfv4e", M68K_INSN_CF_A | M68K_INSN_CF_B | M68K_INSN_CF_C
98             | M68K_INSN_CF_MAC | M68K_INSN_CF_EMAC | M68K_INSN_CF_FPU},
99     {NULL, 0}, 
100 };
101
102 typedef void (*disas_proc)(DisasContext *, uint16_t);
103
104 #define DISAS_INSN(name) \
105   static void disas_##name (DisasContext *s, uint16_t insn)
106
107 /* Generate a load from the specified address.  Narrow values are
108    sign extended to full register width.  */
109 static inline int gen_load(int opsize, int addr, int sign)
110 {
111     int tmp;
112     switch(opsize) {
113     case OS_BYTE:
114         tmp = gen_new_qreg(QMODE_I32);
115         if (sign)
116             gen_op_ld8s32(tmp, addr);
117         else
118             gen_op_ld8u32(tmp, addr);
119         break;
120     case OS_WORD:
121         tmp = gen_new_qreg(QMODE_I32);
122         if (sign)
123             gen_op_ld16s32(tmp, addr);
124         else
125             gen_op_ld16u32(tmp, addr);
126         break;
127     case OS_LONG:
128         tmp = gen_new_qreg(QMODE_I32);
129         gen_op_ld32(tmp, addr);
130         break;
131     case OS_SINGLE:
132         tmp = gen_new_qreg(QMODE_F32);
133         gen_op_ldf32(tmp, addr);
134         break;
135     case OS_DOUBLE:
136         tmp  = gen_new_qreg(QMODE_F64);
137         gen_op_ldf64(tmp, addr);
138         break;
139     default:
140         qemu_assert(0, "bad load size");
141     }
142     gen_throws_exception = gen_last_qop;
143     return tmp;
144 }
145
146 /* Generate a store.  */
147 static inline void gen_store(int opsize, int addr, int val)
148 {
149     switch(opsize) {
150     case OS_BYTE:
151         gen_op_st8(addr, val);
152         break;
153     case OS_WORD:
154         gen_op_st16(addr, val);
155         break;
156     case OS_LONG:
157         gen_op_st32(addr, val);
158         break;
159     case OS_SINGLE:
160         gen_op_stf32(addr, val);
161         break;
162     case OS_DOUBLE:
163         gen_op_stf64(addr, val);
164         break;
165     default:
166         qemu_assert(0, "bad store size");
167     }
168     gen_throws_exception = gen_last_qop;
169 }
170
171 /* Generate an unsigned load if VAL is 0 a signed load if val is -1,
172    otherwise generate a store.  */
173 static int gen_ldst(int opsize, int addr, int val)
174 {
175     if (val > 0) {
176         gen_store(opsize, addr, val);
177         return 0;
178     } else {
179         return gen_load(opsize, addr, val != 0);
180     }
181 }
182
183 /* Handle a base + index + displacement effective addresss.  A base of
184    -1 means pc-relative.  */
185 static int gen_lea_indexed(DisasContext *s, int opsize, int base)
186 {
187     int scale;
188     uint32_t offset;
189     uint16_t ext;
190     int add;
191     int tmp;
192
193     offset = s->pc;
194     ext = lduw(s->pc);
195     s->pc += 2;
196     tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
197     /* ??? Check W/L bit.  */
198     scale = (ext >> 9) & 3;
199     if (scale == 0) {
200         add = tmp;
201     } else {
202         add = gen_new_qreg(QMODE_I32);
203         gen_op_shl32(add, tmp, gen_im32(scale));
204     }
205     tmp = gen_new_qreg(QMODE_I32);
206     if (base != -1) {
207         gen_op_add32(tmp, base, gen_im32((int8_t)ext));
208         gen_op_add32(tmp, tmp, add);
209     } else {
210         gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
211     }
212     return tmp;
213 }
214
215 /* Read a 32-bit immediate constant.  */
216 static inline uint32_t read_im32(DisasContext *s)
217 {
218     uint32_t im;
219     im = ((uint32_t)lduw(s->pc)) << 16;
220     s->pc += 2;
221     im |= lduw(s->pc);
222     s->pc += 2;
223     return im;
224 }
225
226
227 /* Update the CPU env CC_OP state.  */
228 static inline void gen_flush_cc_op(DisasContext *s)
229 {
230     if (s->cc_op != CC_OP_DYNAMIC)
231         gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
232 }
233
234 /* Evaluate all the CC flags.  */
235 static inline void gen_flush_flags(DisasContext *s)
236 {
237     if (s->cc_op == CC_OP_FLAGS)
238         return;
239     gen_op_flush_flags(s->cc_op);
240     s->cc_op = CC_OP_FLAGS;
241 }
242
243 static inline int opsize_bytes(int opsize)
244 {
245     switch (opsize) {
246     case OS_BYTE: return 1;
247     case OS_WORD: return 2;
248     case OS_LONG: return 4;
249     case OS_SINGLE: return 4;
250     case OS_DOUBLE: return 8;
251     default:
252         qemu_assert(0, "bad operand size");
253     }
254 }
255
256 /* Assign value to a register.  If the width is less than the register width
257    only the low part of the register is set.  */
258 static void gen_partset_reg(int opsize, int reg, int val)
259 {
260     int tmp;
261     switch (opsize) {
262     case OS_BYTE:
263         gen_op_and32(reg, reg, gen_im32(0xffffff00));
264         tmp = gen_new_qreg(QMODE_I32);
265         gen_op_and32(tmp, val, gen_im32(0xff));
266         gen_op_or32(reg, reg, tmp);
267         break;
268     case OS_WORD:
269         gen_op_and32(reg, reg, gen_im32(0xffff0000));
270         tmp = gen_new_qreg(QMODE_I32);
271         gen_op_and32(tmp, val, gen_im32(0xffff));
272         gen_op_or32(reg, reg, tmp);
273         break;
274     case OS_LONG:
275         gen_op_mov32(reg, val);
276         break;
277     case OS_SINGLE:
278         gen_op_pack_32_f32(reg, val);
279         break;
280     default:
281         qemu_assert(0, "Bad operand size");
282         break;
283     }
284 }
285
286 /* Sign or zero extend a value.  */
287 static inline int gen_extend(int val, int opsize, int sign)
288 {
289     int tmp;
290
291     switch (opsize) {
292     case OS_BYTE:
293         tmp = gen_new_qreg(QMODE_I32);
294         if (sign)
295             gen_op_ext8s32(tmp, val);
296         else
297             gen_op_ext8u32(tmp, val);
298         break;
299     case OS_WORD:
300         tmp = gen_new_qreg(QMODE_I32);
301         if (sign)
302             gen_op_ext16s32(tmp, val);
303         else
304             gen_op_ext16u32(tmp, val);
305         break;
306     case OS_LONG:
307         tmp = val;
308         break;
309     case OS_SINGLE:
310         tmp = gen_new_qreg(QMODE_F32);
311         gen_op_pack_f32_32(tmp, val);
312         break;
313     default:
314         qemu_assert(0, "Bad operand size");
315     }
316     return tmp;
317 }
318
319 /* Generate code for an "effective address".  Does not adjust the base
320    register for autoincrememnt addressing modes.  */
321 static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
322 {
323     int reg;
324     int tmp;
325     uint16_t ext;
326     uint32_t offset;
327
328     reg = insn & 7;
329     switch ((insn >> 3) & 7) {
330     case 0: /* Data register direct.  */
331     case 1: /* Address register direct.  */
332         /* ??? generate bad addressing mode fault.  */
333         qemu_assert(0, "invalid addressing mode");
334     case 2: /* Indirect register */
335     case 3: /* Indirect postincrement.  */
336         reg += QREG_A0;
337         return reg;
338     case 4: /* Indirect predecrememnt.  */
339         reg += QREG_A0;
340         tmp = gen_new_qreg(QMODE_I32);
341         gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
342         return tmp;
343     case 5: /* Indirect displacement.  */
344         reg += QREG_A0;
345         tmp = gen_new_qreg(QMODE_I32);
346         ext = lduw(s->pc);
347         s->pc += 2;
348         gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
349         return tmp;
350     case 6: /* Indirect index + displacement.  */
351         reg += QREG_A0;
352         return gen_lea_indexed(s, opsize, reg);
353     case 7: /* Other */
354         switch (reg) {
355         case 0: /* Absolute short.  */
356             offset = ldsw(s->pc);
357             s->pc += 2;
358             return gen_im32(offset);
359         case 1: /* Absolute long.  */
360             offset = read_im32(s);
361             return gen_im32(offset);
362         case 2: /* pc displacement  */
363             tmp = gen_new_qreg(QMODE_I32);
364             offset = s->pc;
365             offset += ldsw(s->pc);
366             s->pc += 2;
367             return gen_im32(offset);
368         case 3: /* pc index+displacement.  */
369             return gen_lea_indexed(s, opsize, -1);
370         case 4: /* Immediate.  */
371         default:
372             /* ??? generate bad addressing mode fault.  */
373             qemu_assert(0, "invalid addressing mode");
374         }
375     }
376     /* Should never happen.  */
377     return -1;
378 }
379
380 /* Helper function for gen_ea. Reuse the computed address between the
381    for read/write operands.  */
382 static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
383                               int val, int *addrp)
384 {
385     int tmp;
386
387     if (addrp && val > 0) {
388         tmp = *addrp;
389     } else {
390         tmp = gen_lea(s, insn, opsize);
391         if (addrp)
392             *addrp = tmp;
393     }
394     return gen_ldst(opsize, tmp, val);
395 }
396
397 /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
398    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
399    ADDRP is non-null for readwrite operands.  */
400 static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
401                   int *addrp)
402 {
403     int reg;
404     int result;
405     uint32_t offset;
406
407     reg = insn & 7;
408     switch ((insn >> 3) & 7) {
409     case 0: /* Data register direct.  */
410         reg += QREG_D0;
411         if (val > 0) {
412             gen_partset_reg(opsize, reg, val);
413             return 0;
414         } else {
415             return gen_extend(reg, opsize, val);
416         }
417     case 1: /* Address register direct.  */
418         reg += QREG_A0;
419         if (val > 0) {
420             gen_op_mov32(reg, val);
421             return 0;
422         } else {
423             return gen_extend(reg, opsize, val);
424         }
425     case 2: /* Indirect register */
426         reg += QREG_A0;
427         return gen_ldst(opsize, reg, val);
428     case 3: /* Indirect postincrement.  */
429         reg += QREG_A0;
430         result = gen_ldst(opsize, reg, val);
431         /* ??? This is not exception safe.  The instruction may still
432            fault after this point.  */
433         if (val > 0 || !addrp)
434             gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
435         return result;
436     case 4: /* Indirect predecrememnt.  */
437         {
438             int tmp;
439             if (addrp && val > 0) {
440                 tmp = *addrp;
441             } else {
442                 tmp = gen_lea(s, insn, opsize);
443                 if (addrp)
444                     *addrp = tmp;
445             }
446             result = gen_ldst(opsize, tmp, val);
447             /* ??? This is not exception safe.  The instruction may still
448                fault after this point.  */
449             if (val > 0 || !addrp) {
450                 reg += QREG_A0;
451                 gen_op_mov32(reg, tmp);
452             }
453         }
454         return result;
455     case 5: /* Indirect displacement.  */
456     case 6: /* Indirect index + displacement.  */
457         return gen_ea_once(s, insn, opsize, val, addrp);
458     case 7: /* Other */
459         switch (reg) {
460         case 0: /* Absolute short.  */
461         case 1: /* Absolute long.  */
462         case 2: /* pc displacement  */
463         case 3: /* pc index+displacement.  */
464             return gen_ea_once(s, insn, opsize, val, addrp);
465         case 4: /* Immediate.  */
466             /* Sign extend values for consistency.  */
467             switch (opsize) {
468             case OS_BYTE:
469                 if (val)
470                     offset = ldsb(s->pc + 1);
471                 else
472                     offset = ldub(s->pc + 1);
473                 s->pc += 2;
474                 break;
475             case OS_WORD:
476                 if (val)
477                     offset = ldsw(s->pc);
478                 else
479                     offset = lduw(s->pc);
480                 s->pc += 2;
481                 break;
482             case OS_LONG:
483                 offset = read_im32(s);
484                 break;
485             default:
486                 qemu_assert(0, "Bad immediate operand");
487             }
488             return gen_im32(offset);
489         default:
490             qemu_assert(0, "invalid addressing mode");
491         }
492     }
493     /* Should never happen.  */
494     return -1;
495 }
496
497 static void gen_logic_cc(DisasContext *s, int val)
498 {
499     gen_op_logic_cc(val);
500     s->cc_op = CC_OP_LOGIC;
501 }
502
503 static void gen_jmpcc(DisasContext *s, int cond, int l1)
504 {
505     int tmp;
506
507     gen_flush_flags(s);
508     switch (cond) {
509     case 0: /* T */
510         gen_op_jmp(l1);
511         break;
512     case 1: /* F */
513         break;
514     case 2: /* HI (!C && !Z) */
515         tmp = gen_new_qreg(QMODE_I32);
516         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
517         gen_op_jmp_z32(tmp, l1);
518         break;
519     case 3: /* LS (C || Z) */
520         tmp = gen_new_qreg(QMODE_I32);
521         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
522         gen_op_jmp_nz32(tmp, l1);
523         break;
524     case 4: /* CC (!C) */
525         tmp = gen_new_qreg(QMODE_I32);
526         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
527         gen_op_jmp_z32(tmp, l1);
528         break;
529     case 5: /* CS (C) */
530         tmp = gen_new_qreg(QMODE_I32);
531         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
532         gen_op_jmp_nz32(tmp, l1);
533         break;
534     case 6: /* NE (!Z) */
535         tmp = gen_new_qreg(QMODE_I32);
536         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
537         gen_op_jmp_z32(tmp, l1);
538         break;
539     case 7: /* EQ (Z) */
540         tmp = gen_new_qreg(QMODE_I32);
541         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
542         gen_op_jmp_nz32(tmp, l1);
543         break;
544     case 8: /* VC (!V) */
545         tmp = gen_new_qreg(QMODE_I32);
546         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
547         gen_op_jmp_z32(tmp, l1);
548         break;
549     case 9: /* VS (V) */
550         tmp = gen_new_qreg(QMODE_I32);
551         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
552         gen_op_jmp_nz32(tmp, l1);
553         break;
554     case 10: /* PL (!N) */
555         tmp = gen_new_qreg(QMODE_I32);
556         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
557         gen_op_jmp_z32(tmp, l1);
558         break;
559     case 11: /* MI (N) */
560         tmp = gen_new_qreg(QMODE_I32);
561         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
562         gen_op_jmp_nz32(tmp, l1);
563         break;
564     case 12: /* GE (!(N ^ V)) */
565         tmp = gen_new_qreg(QMODE_I32);
566         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
567         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
568         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
569         gen_op_jmp_z32(tmp, l1);
570         break;
571     case 13: /* LT (N ^ V) */
572         tmp = gen_new_qreg(QMODE_I32);
573         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
574         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
575         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
576         gen_op_jmp_nz32(tmp, l1);
577         break;
578     case 14: /* GT (!(Z || (N ^ V))) */
579         {
580             int l2;
581             l2 = gen_new_label();
582             tmp = gen_new_qreg(QMODE_I32);
583             gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
584             gen_op_jmp_nz32(tmp, l2);
585             tmp = gen_new_qreg(QMODE_I32);
586             gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
587             gen_op_xor32(tmp, tmp, QREG_CC_DEST);
588             gen_op_and32(tmp, tmp, gen_im32(CCF_V));
589             gen_op_jmp_nz32(tmp, l2);
590             gen_op_jmp(l1);
591             gen_set_label(l2);
592         }
593         break;
594     case 15: /* LE (Z || (N ^ V)) */
595         tmp = gen_new_qreg(QMODE_I32);
596         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
597         gen_op_jmp_nz32(tmp, l1);
598         tmp = gen_new_qreg(QMODE_I32);
599         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
600         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
601         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
602         gen_op_jmp_nz32(tmp, l1);
603         break;
604     default:
605         /* Should ever happen.  */
606         abort();
607     }
608 }
609
610 DISAS_INSN(scc)
611 {
612     int l1;
613     int cond;
614     int reg;
615
616     l1 = gen_new_label();
617     cond = (insn >> 8) & 0xf;
618     reg = DREG(insn, 0);
619     gen_op_and32(reg, reg, gen_im32(0xffffff00));
620     gen_jmpcc(s, cond ^ 1, l1);
621     gen_op_or32(reg, reg, gen_im32(0xff));
622     gen_set_label(l1);
623 }
624
625 /* Generate a jump to to the address in qreg DEST.  */
626 static void gen_jmp(DisasContext *s, int dest)
627 {
628     gen_flush_cc_op(s);
629     gen_op_mov32(QREG_PC, dest);
630     s->is_jmp = DISAS_JUMP;
631 }
632
633 static void gen_exception(DisasContext *s, uint32_t where, int nr)
634 {
635     gen_flush_cc_op(s);
636     gen_jmp(s, gen_im32(where));
637     gen_op_raise_exception(nr);
638 }
639
640 /* Generate a jump to an immediate address.  */
641 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
642 {
643     TranslationBlock *tb;
644
645     tb = s->tb;
646     if (__builtin_expect (s->singlestep_enabled, 0)) {
647         gen_exception(s, dest, EXCP_DEBUG);
648     } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
649                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
650         gen_op_goto_tb(0, n, (long)tb);
651         gen_op_mov32(QREG_PC, gen_im32(dest));
652         gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
653         gen_op_exit_tb();
654     } else {
655         gen_jmp(s, gen_im32(dest));
656         gen_op_mov32(QREG_T0, gen_im32(0));
657         gen_op_exit_tb();
658     }
659     s->is_jmp = DISAS_TB_JUMP;
660 }
661
662 DISAS_INSN(undef_mac)
663 {
664     gen_exception(s, s->pc - 2, EXCP_LINEA);
665 }
666
667 DISAS_INSN(undef_fpu)
668 {
669     gen_exception(s, s->pc - 2, EXCP_LINEF);
670 }
671
672 DISAS_INSN(undef)
673 {
674     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
675     cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
676               insn, s->pc - 2);
677 }
678
679 DISAS_INSN(mulw)
680 {
681     int reg;
682     int tmp;
683     int src;
684     int sign;
685
686     sign = (insn & 0x100) != 0;
687     reg = DREG(insn, 9);
688     tmp = gen_new_qreg(QMODE_I32);
689     if (sign)
690         gen_op_ext16s32(tmp, reg);
691     else
692         gen_op_ext16u32(tmp, reg);
693     src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
694     gen_op_mul32(tmp, tmp, src);
695     gen_op_mov32(reg, tmp);
696     /* Unlike m68k, coldfire always clears the overflow bit.  */
697     gen_logic_cc(s, tmp);
698 }
699
700 DISAS_INSN(divw)
701 {
702     int reg;
703     int tmp;
704     int src;
705     int sign;
706
707     sign = (insn & 0x100) != 0;
708     reg = DREG(insn, 9);
709     if (sign) {
710         gen_op_ext16s32(QREG_DIV1, reg);
711     } else {
712         gen_op_ext16u32(QREG_DIV1, reg);
713     }
714     src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
715     gen_op_mov32(QREG_DIV2, src);
716     if (sign) {
717         gen_op_divs(1);
718     } else {
719         gen_op_divu(1);
720     }
721
722     tmp = gen_new_qreg(QMODE_I32);
723     src = gen_new_qreg(QMODE_I32);
724     gen_op_ext16u32(tmp, QREG_DIV1);
725     gen_op_shl32(src, QREG_DIV2, gen_im32(16));
726     gen_op_or32(reg, tmp, src);
727     gen_op_flags_set();
728     s->cc_op = CC_OP_FLAGS;
729 }
730
731 DISAS_INSN(divl)
732 {
733     int num;
734     int den;
735     int reg;
736     uint16_t ext;
737
738     ext = lduw(s->pc);
739     s->pc += 2;
740     if (ext & 0x87f8) {
741         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
742         return;
743     }
744     num = DREG(ext, 12);
745     reg = DREG(ext, 0);
746     gen_op_mov32(QREG_DIV1, num);
747     den = gen_ea(s, insn, OS_LONG, 0, NULL);
748     gen_op_mov32(QREG_DIV2, den);
749     if (ext & 0x0800) {
750         gen_op_divs(2);
751     } else {
752         gen_op_divu(2);
753     }
754     if (num == reg) {
755         /* div */
756         gen_op_mov32 (reg, QREG_DIV1);
757     } else {
758         /* rem */
759         gen_op_mov32 (reg, QREG_DIV2);
760     }
761     gen_op_flags_set();
762     s->cc_op = CC_OP_FLAGS;
763 }
764
765 DISAS_INSN(addsub)
766 {
767     int reg;
768     int dest;
769     int src;
770     int tmp;
771     int addr;
772     int add;
773
774     add = (insn & 0x4000) != 0;
775     reg = DREG(insn, 9);
776     dest = gen_new_qreg(QMODE_I32);
777     if (insn & 0x100) {
778         tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
779         src = reg;
780     } else {
781         tmp = reg;
782         src = gen_ea(s, insn, OS_LONG, 0, NULL);
783     }
784     if (add) {
785         gen_op_add32(dest, tmp, src);
786         gen_op_update_xflag_lt(dest, src);
787         s->cc_op = CC_OP_ADD;
788     } else {
789         gen_op_update_xflag_lt(tmp, src);
790         gen_op_sub32(dest, tmp, src);
791         s->cc_op = CC_OP_SUB;
792     }
793     gen_op_update_cc_add(dest, src);
794     if (insn & 0x100) {
795         gen_ea(s, insn, OS_LONG, dest, &addr);
796     } else {
797         gen_op_mov32(reg, dest);
798     }
799 }
800
801
802 /* Reverse the order of the bits in REG.  */
803 DISAS_INSN(bitrev)
804 {
805     int val;
806     int tmp1;
807     int tmp2;
808     int reg;
809
810     val = gen_new_qreg(QMODE_I32);
811     tmp1 = gen_new_qreg(QMODE_I32);
812     tmp2 = gen_new_qreg(QMODE_I32);
813     reg = DREG(insn, 0);
814     gen_op_mov32(val, reg);
815     /* Reverse bits within each nibble.  */
816     gen_op_shl32(tmp1, val, gen_im32(3));
817     gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
818     gen_op_shl32(tmp2, val, gen_im32(1));
819     gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
820     gen_op_or32(tmp1, tmp1, tmp2);
821     gen_op_shr32(tmp2, val, gen_im32(1));
822     gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
823     gen_op_or32(tmp1, tmp1, tmp2);
824     gen_op_shr32(tmp2, val, gen_im32(3));
825     gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
826     gen_op_or32(tmp1, tmp1, tmp2);
827     /* Reverse nibbles withing bytes.  */
828     gen_op_shl32(val, tmp1, gen_im32(4));
829     gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
830     gen_op_shr32(tmp2, tmp1, gen_im32(4));
831     gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
832     gen_op_or32(val, val, tmp2);
833     /* Reverse bytes.  */
834     gen_op_bswap32(reg, val);
835     gen_op_mov32(reg, val);
836 }
837
838 DISAS_INSN(bitop_reg)
839 {
840     int opsize;
841     int op;
842     int src1;
843     int src2;
844     int tmp;
845     int addr;
846     int dest;
847
848     if ((insn & 0x38) != 0)
849         opsize = OS_BYTE;
850     else
851         opsize = OS_LONG;
852     op = (insn >> 6) & 3;
853     src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
854     src2 = DREG(insn, 9);
855     dest = gen_new_qreg(QMODE_I32);
856
857     gen_flush_flags(s);
858     tmp = gen_new_qreg(QMODE_I32);
859     if (opsize == OS_BYTE)
860         gen_op_and32(tmp, src2, gen_im32(7));
861     else
862         gen_op_and32(tmp, src2, gen_im32(31));
863     src2 = tmp;
864     tmp = gen_new_qreg(QMODE_I32);
865     gen_op_shl32(tmp, gen_im32(1), src2);
866
867     gen_op_btest(src1, tmp);
868     switch (op) {
869     case 1: /* bchg */
870         gen_op_xor32(dest, src1, tmp);
871         break;
872     case 2: /* bclr */
873         gen_op_not32(tmp, tmp);
874         gen_op_and32(dest, src1, tmp);
875         break;
876     case 3: /* bset */
877         gen_op_or32(dest, src1, tmp);
878         break;
879     default: /* btst */
880         break;
881     }
882     if (op)
883         gen_ea(s, insn, opsize, dest, &addr);
884 }
885
886 DISAS_INSN(sats)
887 {
888     int reg;
889     int tmp;
890     int l1;
891
892     reg = DREG(insn, 0);
893     tmp = gen_new_qreg(QMODE_I32);
894     gen_flush_flags(s);
895     gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
896     l1 = gen_new_label();
897     gen_op_jmp_z32(tmp, l1);
898     tmp = gen_new_qreg(QMODE_I32);
899     gen_op_shr32(tmp, reg, gen_im32(31));
900     gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
901     gen_op_mov32(reg, tmp);
902     gen_set_label(l1);
903     gen_logic_cc(s, tmp);
904 }
905
906 static void gen_push(int val)
907 {
908     int tmp;
909
910     tmp = gen_new_qreg(QMODE_I32);
911     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
912     gen_store(OS_LONG, tmp, val);
913     gen_op_mov32(QREG_SP, tmp);
914 }
915
916 DISAS_INSN(movem)
917 {
918     int addr;
919     int i;
920     uint16_t mask;
921     int reg;
922     int tmp;
923     int is_load;
924
925     mask = lduw(s->pc);
926     s->pc += 2;
927     tmp = gen_lea(s, insn, OS_LONG);
928     addr = gen_new_qreg(QMODE_I32);
929     gen_op_mov32(addr, tmp);
930     is_load = ((insn & 0x0400) != 0);
931     for (i = 0; i < 16; i++, mask >>= 1) {
932         if (mask & 1) {
933             if (i < 8)
934                 reg = DREG(i, 0);
935             else
936                 reg = AREG(i, 0);
937             if (is_load) {
938                 tmp = gen_load(OS_LONG, addr, 0);
939                 gen_op_mov32(reg, tmp);
940             } else {
941                 gen_store(OS_LONG, addr, reg);
942             }
943             if (mask != 1)
944                 gen_op_add32(addr, addr, gen_im32(4));
945         }
946     }
947 }
948
949 DISAS_INSN(bitop_im)
950 {
951     int opsize;
952     int op;
953     int src1;
954     uint32_t mask;
955     int bitnum;
956     int tmp;
957     int addr;
958     int dest;
959
960     if ((insn & 0x38) != 0)
961         opsize = OS_BYTE;
962     else
963         opsize = OS_LONG;
964     op = (insn >> 6) & 3;
965
966     bitnum = lduw(s->pc);
967     s->pc += 2;
968     if (bitnum & 0xff00) {
969         disas_undef(s, insn);
970         return;
971     }
972
973     src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
974
975     gen_flush_flags(s);
976     tmp = gen_new_qreg(QMODE_I32);
977     if (opsize == OS_BYTE)
978         bitnum &= 7;
979     else
980         bitnum &= 31;
981     mask = 1 << bitnum;
982
983     gen_op_btest(src1, gen_im32(mask));
984     if (op)
985         dest = gen_new_qreg(QMODE_I32);
986     else
987         dest = -1;
988
989     switch (op) {
990     case 1: /* bchg */
991         gen_op_xor32(dest, src1, gen_im32(mask));
992         break;
993     case 2: /* bclr */
994         gen_op_and32(dest, src1, gen_im32(~mask));
995         break;
996     case 3: /* bset */
997         gen_op_or32(dest, src1, gen_im32(mask));
998         break;
999     default: /* btst */
1000         break;
1001     }
1002     if (op)
1003         gen_ea(s, insn, opsize, dest, &addr);
1004 }
1005
1006 DISAS_INSN(arith_im)
1007 {
1008     int op;
1009     int src1;
1010     int dest;
1011     int src2;
1012     int addr;
1013
1014     op = (insn >> 9) & 7;
1015     src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
1016     src2 = gen_im32(read_im32(s));
1017     dest = gen_new_qreg(QMODE_I32);
1018     switch (op) {
1019     case 0: /* ori */
1020         gen_op_or32(dest, src1, src2);
1021         gen_logic_cc(s, dest);
1022         break;
1023     case 1: /* andi */
1024         gen_op_and32(dest, src1, src2);
1025         gen_logic_cc(s, dest);
1026         break;
1027     case 2: /* subi */
1028         gen_op_mov32(dest, src1);
1029         gen_op_update_xflag_lt(dest, src2);
1030         gen_op_sub32(dest, dest, src2);
1031         gen_op_update_cc_add(dest, src2);
1032         s->cc_op = CC_OP_SUB;
1033         break;
1034     case 3: /* addi */
1035         gen_op_mov32(dest, src1);
1036         gen_op_add32(dest, dest, src2);
1037         gen_op_update_cc_add(dest, src2);
1038         gen_op_update_xflag_lt(dest, src2);
1039         s->cc_op = CC_OP_ADD;
1040         break;
1041     case 5: /* eori */
1042         gen_op_xor32(dest, src1, src2);
1043         gen_logic_cc(s, dest);
1044         break;
1045     case 6: /* cmpi */
1046         gen_op_mov32(dest, src1);
1047         gen_op_sub32(dest, dest, src2);
1048         gen_op_update_cc_add(dest, src2);
1049         s->cc_op = CC_OP_SUB;
1050         break;
1051     default:
1052         abort();
1053     }
1054     if (op != 6) {
1055         gen_ea(s, insn, OS_LONG, dest, &addr);
1056     }
1057 }
1058
1059 DISAS_INSN(byterev)
1060 {
1061     int reg;
1062
1063     reg = DREG(insn, 0);
1064     gen_op_bswap32(reg, reg);
1065 }
1066
1067 DISAS_INSN(move)
1068 {
1069     int src;
1070     int dest;
1071     int op;
1072     int opsize;
1073
1074     switch (insn >> 12) {
1075     case 1: /* move.b */
1076         opsize = OS_BYTE;
1077         break;
1078     case 2: /* move.l */
1079         opsize = OS_LONG;
1080         break;
1081     case 3: /* move.w */
1082         opsize = OS_WORD;
1083         break;
1084     default:
1085         abort();
1086     }
1087     src = gen_ea(s, insn, opsize, -1, NULL);
1088     op = (insn >> 6) & 7;
1089     if (op == 1) {
1090         /* movea */
1091         /* The value will already have been sign extended.  */
1092         dest = AREG(insn, 9);
1093         gen_op_mov32(dest, src);
1094     } else {
1095         /* normal move */
1096         uint16_t dest_ea;
1097         dest_ea = ((insn >> 9) & 7) | (op << 3);
1098         gen_ea(s, dest_ea, opsize, src, NULL);
1099         /* This will be correct because loads sign extend.  */
1100         gen_logic_cc(s, src);
1101     }
1102 }
1103
1104 DISAS_INSN(negx)
1105 {
1106     int reg;
1107     int dest;
1108     int tmp;
1109
1110     gen_flush_flags(s);
1111     reg = DREG(insn, 0);
1112     dest = gen_new_qreg(QMODE_I32);
1113     gen_op_mov32 (dest, gen_im32(0));
1114     gen_op_subx_cc(dest, reg);
1115     /* !Z is sticky.  */
1116     tmp = gen_new_qreg(QMODE_I32);
1117     gen_op_mov32 (tmp, QREG_CC_DEST);
1118     gen_op_update_cc_add(dest, reg);
1119     gen_op_mov32(reg, dest);
1120     s->cc_op = CC_OP_DYNAMIC;
1121     gen_flush_flags(s);
1122     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1123     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1124     s->cc_op = CC_OP_FLAGS;
1125 }
1126
1127 DISAS_INSN(lea)
1128 {
1129     int reg;
1130     int tmp;
1131
1132     reg = AREG(insn, 9);
1133     tmp = gen_lea(s, insn, OS_LONG);
1134     gen_op_mov32(reg, tmp);
1135 }
1136
1137 DISAS_INSN(clr)
1138 {
1139     int opsize;
1140
1141     switch ((insn >> 6) & 3) {
1142     case 0: /* clr.b */
1143         opsize = OS_BYTE;
1144         break;
1145     case 1: /* clr.w */
1146         opsize = OS_WORD;
1147         break;
1148     case 2: /* clr.l */
1149         opsize = OS_LONG;
1150         break;
1151     default:
1152         abort();
1153     }
1154     gen_ea (s, insn, opsize, gen_im32(0), NULL);
1155     gen_logic_cc(s, gen_im32(0));
1156 }
1157
1158 DISAS_INSN(move_from_ccr)
1159 {
1160     int reg;
1161     int dest;
1162
1163     gen_flush_flags(s);
1164     dest = gen_new_qreg(QMODE_I32);
1165     gen_op_get_xflag(dest);
1166     gen_op_shl32(dest, dest, gen_im32(4));
1167     gen_op_or32(dest, dest, QREG_CC_DEST);
1168     reg = DREG(insn, 0);
1169     gen_partset_reg(OS_WORD, reg, dest);
1170 }
1171
1172 DISAS_INSN(neg)
1173 {
1174     int reg;
1175     int src1;
1176
1177     reg = DREG(insn, 0);
1178     src1 = gen_new_qreg(QMODE_I32);
1179     gen_op_mov32(src1, reg);
1180     gen_op_neg32(reg, src1);
1181     s->cc_op = CC_OP_SUB;
1182     gen_op_update_cc_add(reg, src1);
1183     gen_op_update_xflag_lt(gen_im32(0), src1);
1184     s->cc_op = CC_OP_SUB;
1185 }
1186
1187 DISAS_INSN(move_to_ccr)
1188 {
1189     int src1;
1190     int reg;
1191
1192     s->cc_op = CC_OP_FLAGS;
1193     if ((insn & 0x38) == 0)
1194       {
1195         src1 = gen_new_qreg(QMODE_I32);
1196         reg = DREG(insn, 0);
1197         gen_op_and32(src1, reg, gen_im32(0xf));
1198         gen_op_logic_cc(src1);
1199         gen_op_shr32(src1, reg, gen_im32(4));
1200         gen_op_and32(src1, src1, gen_im32(1));
1201         gen_op_update_xflag_tst(src1);
1202       }
1203     else if ((insn & 0x3f) != 0x3c)
1204       {
1205         uint8_t val;
1206         val = ldsb(s->pc);
1207         s->pc += 2;
1208         gen_op_logic_cc(gen_im32(val & 0xf));
1209         gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1210       }
1211     else
1212         disas_undef(s, insn);
1213 }
1214
1215 DISAS_INSN(not)
1216 {
1217     int reg;
1218
1219     reg = DREG(insn, 0);
1220     gen_op_not32(reg, reg);
1221     gen_logic_cc(s, reg);
1222 }
1223
1224 DISAS_INSN(swap)
1225 {
1226     int dest;
1227     int src1;
1228     int src2;
1229     int reg;
1230
1231     dest = gen_new_qreg(QMODE_I32);
1232     src1 = gen_new_qreg(QMODE_I32);
1233     src2 = gen_new_qreg(QMODE_I32);
1234     reg = DREG(insn, 0);
1235     gen_op_shl32(src1, reg, gen_im32(16));
1236     gen_op_shr32(src2, reg, gen_im32(16));
1237     gen_op_or32(dest, src1, src2);
1238     gen_op_mov32(reg, dest);
1239     gen_logic_cc(s, dest);
1240 }
1241
1242 DISAS_INSN(pea)
1243 {
1244     int tmp;
1245
1246     tmp = gen_lea(s, insn, OS_LONG);
1247     gen_push(tmp);
1248 }
1249
1250 DISAS_INSN(ext)
1251 {
1252     int reg;
1253     int op;
1254     int tmp;
1255
1256     reg = DREG(insn, 0);
1257     op = (insn >> 6) & 7;
1258     tmp = gen_new_qreg(QMODE_I32);
1259     if (op == 3)
1260         gen_op_ext16s32(tmp, reg);
1261     else
1262         gen_op_ext8s32(tmp, reg);
1263     if (op == 2)
1264         gen_partset_reg(OS_WORD, reg, tmp);
1265     else
1266       gen_op_mov32(reg, tmp);
1267     gen_logic_cc(s, tmp);
1268 }
1269
1270 DISAS_INSN(tst)
1271 {
1272     int opsize;
1273     int tmp;
1274
1275     switch ((insn >> 6) & 3) {
1276     case 0: /* tst.b */
1277         opsize = OS_BYTE;
1278         break;
1279     case 1: /* tst.w */
1280         opsize = OS_WORD;
1281         break;
1282     case 2: /* tst.l */
1283         opsize = OS_LONG;
1284         break;
1285     default:
1286         abort();
1287     }
1288     tmp = gen_ea(s, insn, opsize, -1, NULL);
1289     gen_logic_cc(s, tmp);
1290 }
1291
1292 DISAS_INSN(pulse)
1293 {
1294   /* Implemented as a NOP.  */
1295 }
1296
1297 DISAS_INSN(illegal)
1298 {
1299     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
1300 }
1301
1302 /* ??? This should be atomic.  */
1303 DISAS_INSN(tas)
1304 {
1305     int dest;
1306     int src1;
1307     int addr;
1308
1309     dest = gen_new_qreg(QMODE_I32);
1310     src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
1311     gen_logic_cc(s, src1);
1312     gen_op_or32(dest, src1, gen_im32(0x80));
1313     gen_ea(s, insn, OS_BYTE, dest, &addr);
1314 }
1315
1316 DISAS_INSN(mull)
1317 {
1318     uint16_t ext;
1319     int reg;
1320     int src1;
1321     int dest;
1322
1323     /* The upper 32 bits of the product are discarded, so
1324        muls.l and mulu.l are functionally equivalent.  */
1325     ext = lduw(s->pc);
1326     s->pc += 2;
1327     if (ext & 0x87ff) {
1328         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
1329         return;
1330     }
1331     reg = DREG(ext, 12);
1332     src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
1333     dest = gen_new_qreg(QMODE_I32);
1334     gen_op_mul32(dest, src1, reg);
1335     gen_op_mov32(reg, dest);
1336     /* Unlike m68k, coldfire always clears the overflow bit.  */
1337     gen_logic_cc(s, dest);
1338 }
1339
1340 DISAS_INSN(link)
1341 {
1342     int16_t offset;
1343     int reg;
1344     int tmp;
1345
1346     offset = ldsw(s->pc);
1347     s->pc += 2;
1348     reg = AREG(insn, 0);
1349     tmp = gen_new_qreg(QMODE_I32);
1350     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
1351     gen_store(OS_LONG, tmp, reg);
1352     if (reg != QREG_SP)
1353         gen_op_mov32(reg, tmp);
1354     gen_op_add32(QREG_SP, tmp, gen_im32(offset));
1355 }
1356
1357 DISAS_INSN(unlk)
1358 {
1359     int src;
1360     int reg;
1361     int tmp;
1362
1363     src = gen_new_qreg(QMODE_I32);
1364     reg = AREG(insn, 0);
1365     gen_op_mov32(src, reg);
1366     tmp = gen_load(OS_LONG, src, 0);
1367     gen_op_mov32(reg, tmp);
1368     gen_op_add32(QREG_SP, src, gen_im32(4));
1369 }
1370
1371 DISAS_INSN(nop)
1372 {
1373 }
1374
1375 DISAS_INSN(rts)
1376 {
1377     int tmp;
1378
1379     tmp = gen_load(OS_LONG, QREG_SP, 0);
1380     gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
1381     gen_jmp(s, tmp);
1382 }
1383
1384 DISAS_INSN(jump)
1385 {
1386     int tmp;
1387
1388     /* Load the target address first to ensure correct exception
1389        behavior.  */
1390     tmp = gen_lea(s, insn, OS_LONG);
1391     if ((insn & 0x40) == 0) {
1392         /* jsr */
1393         gen_push(gen_im32(s->pc));
1394     }
1395     gen_jmp(s, tmp);
1396 }
1397
1398 DISAS_INSN(addsubq)
1399 {
1400     int src1;
1401     int src2;
1402     int dest;
1403     int val;
1404     int addr;
1405
1406     src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
1407     val = (insn >> 9) & 7;
1408     if (val == 0)
1409         val = 8;
1410     src2 = gen_im32(val);
1411     dest = gen_new_qreg(QMODE_I32);
1412     gen_op_mov32(dest, src1);
1413     if ((insn & 0x38) == 0x08) {
1414         /* Don't update condition codes if the destination is an
1415            address register.  */
1416         if (insn & 0x0100) {
1417             gen_op_sub32(dest, dest, src2);
1418         } else {
1419             gen_op_add32(dest, dest, src2);
1420         }
1421     } else {
1422         if (insn & 0x0100) {
1423             gen_op_update_xflag_lt(dest, src2);
1424             gen_op_sub32(dest, dest, src2);
1425             s->cc_op = CC_OP_SUB;
1426         } else {
1427             gen_op_add32(dest, dest, src2);
1428             gen_op_update_xflag_lt(dest, src2);
1429             s->cc_op = CC_OP_ADD;
1430         }
1431         gen_op_update_cc_add(dest, src2);
1432     }
1433     gen_ea(s, insn, OS_LONG, dest, &addr);
1434 }
1435
1436 DISAS_INSN(tpf)
1437 {
1438     switch (insn & 7) {
1439     case 2: /* One extension word.  */
1440         s->pc += 2;
1441         break;
1442     case 3: /* Two extension words.  */
1443         s->pc += 4;
1444         break;
1445     case 4: /* No extension words.  */
1446         break;
1447     default:
1448         disas_undef(s, insn);
1449     }
1450 }
1451
1452 DISAS_INSN(branch)
1453 {
1454     int32_t offset;
1455     uint32_t base;
1456     int op;
1457     int l1;
1458     
1459     base = s->pc;
1460     op = (insn >> 8) & 0xf;
1461     offset = (int8_t)insn;
1462     if (offset == 0) {
1463         offset = ldsw(s->pc);
1464         s->pc += 2;
1465     } else if (offset == -1) {
1466         offset = read_im32(s);
1467     }
1468     if (op == 1) {
1469         /* bsr */
1470         gen_push(gen_im32(s->pc));
1471     }
1472     gen_flush_cc_op(s);
1473     if (op > 1) {
1474         /* Bcc */
1475         l1 = gen_new_label();
1476         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
1477         gen_jmp_tb(s, 1, base + offset);
1478         gen_set_label(l1);
1479         gen_jmp_tb(s, 0, s->pc);
1480     } else {
1481         /* Unconditional branch.  */
1482         gen_jmp_tb(s, 0, base + offset);
1483     }
1484 }
1485
1486 DISAS_INSN(moveq)
1487 {
1488     int tmp;
1489
1490     tmp = gen_im32((int8_t)insn);
1491     gen_op_mov32(DREG(insn, 9), tmp);
1492     gen_logic_cc(s, tmp);
1493 }
1494
1495 DISAS_INSN(mvzs)
1496 {
1497     int opsize;
1498     int src;
1499     int reg;
1500
1501     if (insn & 0x40)
1502         opsize = OS_WORD;
1503     else
1504         opsize = OS_BYTE;
1505     src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
1506     reg = DREG(insn, 9);
1507     gen_op_mov32(reg, src);
1508     gen_logic_cc(s, src);
1509 }
1510
1511 DISAS_INSN(or)
1512 {
1513     int reg;
1514     int dest;
1515     int src;
1516     int addr;
1517
1518     reg = DREG(insn, 9);
1519     dest = gen_new_qreg(QMODE_I32);
1520     if (insn & 0x100) {
1521         src = gen_ea(s, insn, OS_LONG, 0, &addr);
1522         gen_op_or32(dest, src, reg);
1523         gen_ea(s, insn, OS_LONG, dest, &addr);
1524     } else {
1525         src = gen_ea(s, insn, OS_LONG, 0, NULL);
1526         gen_op_or32(dest, src, reg);
1527         gen_op_mov32(reg, dest);
1528     }
1529     gen_logic_cc(s, dest);
1530 }
1531
1532 DISAS_INSN(suba)
1533 {
1534     int src;
1535     int reg;
1536
1537     src = gen_ea(s, insn, OS_LONG, 0, NULL);
1538     reg = AREG(insn, 9);
1539     gen_op_sub32(reg, reg, src);
1540 }
1541
1542 DISAS_INSN(subx)
1543 {
1544     int reg;
1545     int src;
1546     int dest;
1547     int tmp;
1548
1549     gen_flush_flags(s);
1550     reg = DREG(insn, 9);
1551     src = DREG(insn, 0);
1552     dest = gen_new_qreg(QMODE_I32);
1553     gen_op_mov32 (dest, reg);
1554     gen_op_subx_cc(dest, src);
1555     /* !Z is sticky.  */
1556     tmp = gen_new_qreg(QMODE_I32);
1557     gen_op_mov32 (tmp, QREG_CC_DEST);
1558     gen_op_update_cc_add(dest, src);
1559     gen_op_mov32(reg, dest);
1560     s->cc_op = CC_OP_DYNAMIC;
1561     gen_flush_flags(s);
1562     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1563     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1564     s->cc_op = CC_OP_FLAGS;
1565 }
1566
1567 DISAS_INSN(mov3q)
1568 {
1569     int src;
1570     int val;
1571
1572     val = (insn >> 9) & 7;
1573     if (val == 0)
1574         val = -1;
1575     src = gen_im32(val);
1576     gen_logic_cc(s, src);
1577     gen_ea(s, insn, OS_LONG, src, NULL);
1578 }
1579
1580 DISAS_INSN(cmp)
1581 {
1582     int op;
1583     int src;
1584     int reg;
1585     int dest;
1586     int opsize;
1587
1588     op = (insn >> 6) & 3;
1589     switch (op) {
1590     case 0: /* cmp.b */
1591         opsize = OS_BYTE;
1592         s->cc_op = CC_OP_CMPB;
1593         break;
1594     case 1: /* cmp.w */
1595         opsize = OS_WORD;
1596         s->cc_op = CC_OP_CMPW;
1597         break;
1598     case 2: /* cmp.l */
1599         opsize = OS_LONG;
1600         s->cc_op = CC_OP_SUB;
1601         break;
1602     default:
1603         abort();
1604     }
1605     src = gen_ea(s, insn, opsize, -1, NULL);
1606     reg = DREG(insn, 9);
1607     dest = gen_new_qreg(QMODE_I32);
1608     gen_op_sub32(dest, reg, src);
1609     gen_op_update_cc_add(dest, src);
1610 }
1611
1612 DISAS_INSN(cmpa)
1613 {
1614     int opsize;
1615     int src;
1616     int reg;
1617     int dest;
1618
1619     if (insn & 0x100) {
1620         opsize = OS_LONG;
1621     } else {
1622         opsize = OS_WORD;
1623     }
1624     src = gen_ea(s, insn, opsize, -1, NULL);
1625     reg = AREG(insn, 9);
1626     dest = gen_new_qreg(QMODE_I32);
1627     gen_op_sub32(dest, reg, src);
1628     gen_op_update_cc_add(dest, src);
1629     s->cc_op = CC_OP_SUB;
1630 }
1631
1632 DISAS_INSN(eor)
1633 {
1634     int src;
1635     int reg;
1636     int dest;
1637     int addr;
1638
1639     src = gen_ea(s, insn, OS_LONG, 0, &addr);
1640     reg = DREG(insn, 9);
1641     dest = gen_new_qreg(QMODE_I32);
1642     gen_op_xor32(dest, src, reg);
1643     gen_logic_cc(s, dest);
1644     gen_ea(s, insn, OS_LONG, dest, &addr);
1645 }
1646
1647 DISAS_INSN(and)
1648 {
1649     int src;
1650     int reg;
1651     int dest;
1652     int addr;
1653
1654     reg = DREG(insn, 9);
1655     dest = gen_new_qreg(QMODE_I32);
1656     if (insn & 0x100) {
1657         src = gen_ea(s, insn, OS_LONG, 0, &addr);
1658         gen_op_and32(dest, src, reg);
1659         gen_ea(s, insn, OS_LONG, dest, &addr);
1660     } else {
1661         src = gen_ea(s, insn, OS_LONG, 0, NULL);
1662         gen_op_and32(dest, src, reg);
1663         gen_op_mov32(reg, dest);
1664     }
1665     gen_logic_cc(s, dest);
1666 }
1667
1668 DISAS_INSN(adda)
1669 {
1670     int src;
1671     int reg;
1672
1673     src = gen_ea(s, insn, OS_LONG, 0, NULL);
1674     reg = AREG(insn, 9);
1675     gen_op_add32(reg, reg, src);
1676 }
1677
1678 DISAS_INSN(addx)
1679 {
1680     int reg;
1681     int src;
1682     int dest;
1683     int tmp;
1684
1685     gen_flush_flags(s);
1686     reg = DREG(insn, 9);
1687     src = DREG(insn, 0);
1688     dest = gen_new_qreg(QMODE_I32);
1689     gen_op_mov32 (dest, reg);
1690     gen_op_addx_cc(dest, src);
1691     /* !Z is sticky.  */
1692     tmp = gen_new_qreg(QMODE_I32);
1693     gen_op_mov32 (tmp, QREG_CC_DEST);
1694     gen_op_update_cc_add(dest, src);
1695     gen_op_mov32(reg, dest);
1696     s->cc_op = CC_OP_DYNAMIC;
1697     gen_flush_flags(s);
1698     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1699     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1700     s->cc_op = CC_OP_FLAGS;
1701 }
1702
1703 DISAS_INSN(shift_im)
1704 {
1705     int reg;
1706     int tmp;
1707
1708     reg = DREG(insn, 0);
1709     tmp = (insn >> 9) & 7;
1710     if (tmp == 0)
1711       tmp = 8;
1712     if (insn & 0x100) {
1713         gen_op_shl_im_cc(reg, tmp);
1714         s->cc_op = CC_OP_SHL;
1715     } else {
1716         if (insn & 8) {
1717             gen_op_shr_im_cc(reg, tmp);
1718             s->cc_op = CC_OP_SHR;
1719         } else {
1720             gen_op_sar_im_cc(reg, tmp);
1721             s->cc_op = CC_OP_SAR;
1722         }
1723     }
1724 }
1725
1726 DISAS_INSN(shift_reg)
1727 {
1728     int reg;
1729     int src;
1730     int tmp;
1731
1732     reg = DREG(insn, 0);
1733     src = DREG(insn, 9);
1734     tmp = gen_new_qreg(QMODE_I32);
1735     gen_op_and32(tmp, src, gen_im32(63));
1736     if (insn & 0x100) {
1737         gen_op_shl_cc(reg, tmp);
1738         s->cc_op = CC_OP_SHL;
1739     } else {
1740         if (insn & 8) {
1741             gen_op_shr_cc(reg, tmp);
1742             s->cc_op = CC_OP_SHR;
1743         } else {
1744             gen_op_sar_cc(reg, tmp);
1745             s->cc_op = CC_OP_SAR;
1746         }
1747     }
1748 }
1749
1750 DISAS_INSN(ff1)
1751 {
1752     cpu_abort(NULL, "Unimplemented insn: ff1");
1753 }
1754
1755 DISAS_INSN(strldsr)
1756 {
1757     uint16_t ext;
1758     uint32_t addr;
1759
1760     addr = s->pc - 2;
1761     ext = lduw(s->pc);
1762     s->pc += 2;
1763     if (ext != 0x46FC)
1764         gen_exception(s, addr, EXCP_UNSUPPORTED);
1765     else
1766         gen_exception(s, addr, EXCP_PRIVILEGE);
1767 }
1768
1769 DISAS_INSN(move_from_sr)
1770 {
1771     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1772 }
1773
1774 DISAS_INSN(move_to_sr)
1775 {
1776     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1777 }
1778
1779 DISAS_INSN(move_from_usp)
1780 {
1781     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1782 }
1783
1784 DISAS_INSN(move_to_usp)
1785 {
1786     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1787 }
1788
1789 DISAS_INSN(halt)
1790 {
1791     gen_exception(s, s->pc, EXCP_HLT);
1792 }
1793
1794 DISAS_INSN(stop)
1795 {
1796     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1797 }
1798
1799 DISAS_INSN(rte)
1800 {
1801     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1802 }
1803
1804 DISAS_INSN(movec)
1805 {
1806     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1807 }
1808
1809 DISAS_INSN(intouch)
1810 {
1811     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1812 }
1813
1814 DISAS_INSN(cpushl)
1815 {
1816     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1817 }
1818
1819 DISAS_INSN(wddata)
1820 {
1821     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1822 }
1823
1824 DISAS_INSN(wdebug)
1825 {
1826     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
1827 }
1828
1829 DISAS_INSN(trap)
1830 {
1831     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
1832 }
1833
1834 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
1835    immediately before the next FP instruction is executed.  */
1836 DISAS_INSN(fpu)
1837 {
1838     uint16_t ext;
1839     int opmode;
1840     int src;
1841     int dest;
1842     int res;
1843     int round;
1844     int opsize;
1845
1846     ext = lduw(s->pc);
1847     s->pc += 2;
1848     opmode = ext & 0x7f;
1849     switch ((ext >> 13) & 7) {
1850     case 0: case 2:
1851         break;
1852     case 1:
1853         goto undef;
1854     case 3: /* fmove out */
1855         src = FREG(ext, 7);
1856         /* fmove */
1857         /* ??? TODO: Proper behavior on overflow.  */
1858         switch ((ext >> 10) & 7) {
1859         case 0:
1860             opsize = OS_LONG;
1861             res = gen_new_qreg(QMODE_I32);
1862             gen_op_f64_to_i32(res, src);
1863             break;
1864         case 1:
1865             opsize = OS_SINGLE;
1866             res = gen_new_qreg(QMODE_F32);
1867             gen_op_f64_to_f32(res, src);
1868             break;
1869         case 4:
1870             opsize = OS_WORD;
1871             res = gen_new_qreg(QMODE_I32);
1872             gen_op_f64_to_i32(res, src);
1873             break;
1874         case 5:
1875             opsize = OS_DOUBLE;
1876             res = src;
1877             break;
1878         case 6:
1879             opsize = OS_BYTE;
1880             res = gen_new_qreg(QMODE_I32);
1881             gen_op_f64_to_i32(res, src);
1882             break;
1883         default:
1884             goto undef;
1885         }
1886         gen_ea(s, insn, opsize, res, NULL);
1887         return;
1888     case 4: /* fmove to control register.  */
1889         switch ((ext >> 10) & 7) {
1890         case 4: /* FPCR */
1891             /* Not implemented.  Ignore writes.  */
1892             break;
1893         case 1: /* FPIAR */
1894         case 2: /* FPSR */
1895         default:
1896             cpu_abort(NULL, "Unimplemented: fmove to control %d",
1897                       (ext >> 10) & 7);
1898         }
1899         break;
1900     case 5: /* fmove from control register.  */
1901         switch ((ext >> 10) & 7) {
1902         case 4: /* FPCR */
1903             /* Not implemented.  Always return zero.  */
1904             res = gen_im32(0);
1905             break;
1906         case 1: /* FPIAR */
1907         case 2: /* FPSR */
1908         default:
1909             cpu_abort(NULL, "Unimplemented: fmove from control %d",
1910                       (ext >> 10) & 7);
1911             goto undef;
1912         }
1913         gen_ea(s, insn, OS_LONG, res, NULL);
1914         break;
1915     case 6: /* fmovem */ 
1916     case 7:
1917         {
1918         int addr;
1919         uint16_t mask;
1920         if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
1921             goto undef;
1922         src = gen_lea(s, insn, OS_LONG);
1923         addr = gen_new_qreg(QMODE_I32);
1924         gen_op_mov32(addr, src);
1925         mask = 0x80;
1926         dest = QREG_F0;
1927         while (mask) {
1928             if (ext & mask) {
1929                 if (ext & (1 << 13)) {
1930                     /* store */
1931                     gen_op_stf64(addr, dest);
1932                 } else {
1933                     /* load */
1934                     gen_op_ldf64(dest, addr);
1935                 }
1936                 if (ext & (mask - 1))
1937                     gen_op_add32(addr, addr, gen_im32(8));
1938             }
1939             mask >>= 1;
1940             dest++;
1941         }
1942         }
1943         return;
1944     }
1945     if (ext & (1 << 14)) {
1946         int tmp;
1947
1948         /* Source effective address.  */
1949         switch ((ext >> 10) & 7) {
1950         case 0: opsize = OS_LONG; break;
1951         case 1: opsize = OS_SINGLE; break;
1952         case 4: opsize = OS_WORD; break;
1953         case 5: opsize = OS_DOUBLE; break;
1954         case 6: opsize = OS_BYTE; break;
1955         default:
1956             goto undef;
1957         }
1958         tmp = gen_ea(s, insn, opsize, -1, NULL);
1959         if (opsize == OS_DOUBLE) {
1960             src = tmp;
1961         } else {
1962             src = gen_new_qreg(QMODE_F64);
1963             switch (opsize) {
1964             case OS_LONG:
1965             case OS_WORD:
1966             case OS_BYTE:
1967                 gen_op_i32_to_f64(src, tmp);
1968                 break;
1969             case OS_SINGLE:
1970                 gen_op_f32_to_f64(src, tmp);
1971                 break;
1972             }
1973         }
1974     } else {
1975         /* Source register.  */
1976         src = FREG(ext, 10);
1977     }
1978     dest = FREG(ext, 7);
1979     res = gen_new_qreg(QMODE_F64);
1980     if (opmode != 0x3a)
1981         gen_op_movf64(res, dest);
1982     round = 1;
1983     switch (opmode) {
1984     case 0: case 0x40: case 0x44: /* fmove */
1985         gen_op_movf64(res, src);
1986         break;
1987     case 1: /* fint */
1988         gen_op_iround_f64(res, src);
1989         round = 0;
1990         break;
1991     case 3: /* fintrz */
1992         gen_op_itrunc_f64(res, src);
1993         round = 0;
1994         break;
1995     case 4: case 0x41: case 0x45: /* fsqrt */
1996         gen_op_sqrtf64(res, src);
1997         break;
1998     case 0x18: case 0x58: case 0x5c: /* fabs */
1999         gen_op_absf64(res, src);
2000         break;
2001     case 0x1a: case 0x5a: case 0x5e: /* fneg */
2002         gen_op_chsf64(res, src);
2003         break;
2004     case 0x20: case 0x60: case 0x64: /* fdiv */
2005         gen_op_divf64(res, res, src);
2006         break;
2007     case 0x22: case 0x62: case 0x66: /* fadd */
2008         gen_op_addf64(res, res, src);
2009         break;
2010     case 0x23: case 0x63: case 0x67: /* fmul */
2011         gen_op_mulf64(res, res, src);
2012         break;
2013     case 0x28: case 0x68: case 0x6c: /* fsub */
2014         gen_op_subf64(res, res, src);
2015         break;
2016     case 0x38: /* fcmp */
2017         gen_op_sub_cmpf64(res, res, src);
2018         dest = 0;
2019         round = 0;
2020         break;
2021     case 0x3a: /* ftst */
2022         gen_op_movf64(res, src);
2023         dest = 0;
2024         round = 0;
2025         break;
2026     default:
2027         goto undef;
2028     }
2029     if (round) {
2030         if (opmode & 0x40) {
2031             if ((opmode & 0x4) != 0)
2032                 round = 0;
2033         } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
2034             round = 0;
2035         }
2036     }
2037     if (round) {
2038         int tmp;
2039
2040         tmp = gen_new_qreg(QMODE_F32);
2041         gen_op_f64_to_f32(tmp, res);
2042         gen_op_f32_to_f64(res, tmp);
2043     } 
2044     gen_op_fp_result(res);
2045     if (dest) {
2046         gen_op_movf64(dest, res);
2047     }
2048     return;
2049 undef:
2050     s->pc -= 2;
2051     disas_undef_fpu(s, insn);
2052 }
2053
2054 DISAS_INSN(fbcc)
2055 {
2056     uint32_t offset;
2057     uint32_t addr;
2058     int flag;
2059     int zero;
2060     int l1;
2061
2062     addr = s->pc;
2063     offset = ldsw(s->pc);
2064     s->pc += 2;
2065     if (insn & (1 << 6)) {
2066         offset = (offset << 16) | lduw(s->pc);
2067         s->pc += 2;
2068     }
2069
2070     l1 = gen_new_label();
2071     /* TODO: Raise BSUN exception.  */
2072     flag = gen_new_qreg(QMODE_I32);
2073     zero = gen_new_qreg(QMODE_F64);
2074     gen_op_zerof64(zero);
2075     gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2076     /* Jump to l1 if condition is true.  */
2077     switch (insn & 0xf) {
2078     case 0: /* f */
2079         break;
2080     case 1: /* eq (=0) */
2081         gen_op_jmp_z32(flag, l1);
2082         break;
2083     case 2: /* ogt (=1) */
2084         gen_op_sub32(flag, flag, gen_im32(1));
2085         gen_op_jmp_z32(flag, l1);
2086         break;
2087     case 3: /* oge (=0 or =1) */
2088         gen_op_jmp_z32(flag, l1);
2089         gen_op_sub32(flag, flag, gen_im32(1));
2090         gen_op_jmp_z32(flag, l1);
2091         break;
2092     case 4: /* olt (=-1) */
2093         gen_op_jmp_s32(flag, l1);
2094         break;
2095     case 5: /* ole (=-1 or =0) */
2096         gen_op_jmp_s32(flag, l1);
2097         gen_op_jmp_z32(flag, l1);
2098         break;
2099     case 6: /* ogl (=-1 or =1) */
2100         gen_op_jmp_s32(flag, l1);
2101         gen_op_sub32(flag, flag, gen_im32(1));
2102         gen_op_jmp_z32(flag, l1);
2103         break;
2104     case 7: /* or (=2) */
2105         gen_op_sub32(flag, flag, gen_im32(2));
2106         gen_op_jmp_z32(flag, l1);
2107         break;
2108     case 8: /* un (<2) */
2109         gen_op_sub32(flag, flag, gen_im32(2));
2110         gen_op_jmp_s32(flag, l1);
2111         break;
2112     case 9: /* ueq (=0 or =2) */
2113         gen_op_jmp_z32(flag, l1);
2114         gen_op_sub32(flag, flag, gen_im32(2));
2115         gen_op_jmp_z32(flag, l1);
2116         break;
2117     case 10: /* ugt (>0) */
2118         /* ??? Add jmp_gtu.  */
2119         gen_op_sub32(flag, flag, gen_im32(1));
2120         gen_op_jmp_ns32(flag, l1);
2121         break;
2122     case 11: /* uge (>=0) */
2123         gen_op_jmp_ns32(flag, l1);
2124         break;
2125     case 12: /* ult (=-1 or =2) */
2126         gen_op_jmp_s32(flag, l1);
2127         gen_op_sub32(flag, flag, gen_im32(2));
2128         gen_op_jmp_z32(flag, l1);
2129         break;
2130     case 13: /* ule (!=1) */
2131         gen_op_sub32(flag, flag, gen_im32(1));
2132         gen_op_jmp_nz32(flag, l1);
2133         break;
2134     case 14: /* ne (!=0) */
2135         gen_op_jmp_nz32(flag, l1);
2136         break;
2137     case 15: /* t */
2138         gen_op_mov32(flag, gen_im32(1));
2139         break;
2140     }
2141     gen_jmp_tb(s, 0, s->pc);
2142     gen_set_label(l1);
2143     gen_jmp_tb(s, 1, addr + offset);
2144 }
2145
2146 static disas_proc opcode_table[65536];
2147
2148 static void
2149 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
2150 {
2151   int i;
2152   int from;
2153   int to;
2154
2155   /* Sanity check.  All set bits must be included in the mask.  */
2156   if (opcode & ~mask)
2157       abort();
2158   /* This could probably be cleverer.  For now just optimize the case where
2159      the top bits are known.  */
2160   /* Find the first zero bit in the mask.  */
2161   i = 0x8000;
2162   while ((i & mask) != 0)
2163       i >>= 1;
2164   /* Iterate over all combinations of this and lower bits.  */
2165   if (i == 0)
2166       i = 1;
2167   else
2168       i <<= 1;
2169   from = opcode & ~(i - 1);
2170   to = from + i;
2171   for (i = from; i < to; i++)
2172     {
2173       if ((i & mask) == opcode)
2174           opcode_table[i] = proc;
2175     }
2176 }
2177
2178 /* Register m68k opcode handlers.  Order is important.
2179    Later insn override earlier ones.  */
2180 static void
2181 register_m68k_insns (m68k_def_t *def)
2182 {
2183     uint32_t iflags;
2184
2185     iflags = def->insns;
2186 #define INSN(name, opcode, mask, isa) \
2187     if (iflags & M68K_INSN_##isa) \
2188         register_opcode(disas_##name, 0x##opcode, 0x##mask)
2189     INSN(undef,     0000, 0000, CF_A);
2190     INSN(arith_im,  0080, fff8, CF_A);
2191     INSN(bitrev,    00c0, fff8, CF_C);
2192     INSN(bitop_reg, 0100, f1c0, CF_A);
2193     INSN(bitop_reg, 0140, f1c0, CF_A);
2194     INSN(bitop_reg, 0180, f1c0, CF_A);
2195     INSN(bitop_reg, 01c0, f1c0, CF_A);
2196     INSN(arith_im,  0280, fff8, CF_A);
2197     INSN(byterev,   02c0, fff8, CF_A);
2198     INSN(arith_im,  0480, fff8, CF_A);
2199     INSN(ff1,       04c0, fff8, CF_C);
2200     INSN(arith_im,  0680, fff8, CF_A);
2201     INSN(bitop_im,  0800, ffc0, CF_A);
2202     INSN(bitop_im,  0840, ffc0, CF_A);
2203     INSN(bitop_im,  0880, ffc0, CF_A);
2204     INSN(bitop_im,  08c0, ffc0, CF_A);
2205     INSN(arith_im,  0a80, fff8, CF_A);
2206     INSN(arith_im,  0c00, ff38, CF_A);
2207     INSN(move,      1000, f000, CF_A);
2208     INSN(move,      2000, f000, CF_A);
2209     INSN(move,      3000, f000, CF_A);
2210     INSN(strldsr,   40e7, ffff, CF_A);
2211     INSN(negx,      4080, fff8, CF_A);
2212     INSN(move_from_sr, 40c0, fff8, CF_A);
2213     INSN(lea,       41c0, f1c0, CF_A);
2214     INSN(clr,       4200, ff00, CF_A);
2215     INSN(undef,     42c0, ffc0, CF_A);
2216     INSN(move_from_ccr, 42c0, fff8, CF_A);
2217     INSN(neg,       4480, fff8, CF_A);
2218     INSN(move_to_ccr, 44c0, ffc0, CF_A);
2219     INSN(not,       4680, fff8, CF_A);
2220     INSN(move_to_sr, 46c0, ffc0, CF_A);
2221     INSN(pea,       4840, ffc0, CF_A);
2222     INSN(swap,      4840, fff8, CF_A);
2223     INSN(movem,     48c0, fbc0, CF_A);
2224     INSN(ext,       4880, fff8, CF_A);
2225     INSN(ext,       48c0, fff8, CF_A);
2226     INSN(ext,       49c0, fff8, CF_A);
2227     INSN(tst,       4a00, ff00, CF_A);
2228     INSN(tas,       4ac0, ffc0, CF_B);
2229     INSN(halt,      4ac8, ffff, CF_A);
2230     INSN(pulse,     4acc, ffff, CF_A);
2231     INSN(illegal,   4afc, ffff, CF_A);
2232     INSN(mull,      4c00, ffc0, CF_A);
2233     INSN(divl,      4c40, ffc0, CF_A);
2234     INSN(sats,      4c80, fff8, CF_B);
2235     INSN(trap,      4e40, fff0, CF_A);
2236     INSN(link,      4e50, fff8, CF_A);
2237     INSN(unlk,      4e58, fff8, CF_A);
2238     INSN(move_to_usp, 4e60, fff8, CF_B);
2239     INSN(move_from_usp, 4e68, fff8, CF_B);
2240     INSN(nop,       4e71, ffff, CF_A);
2241     INSN(stop,      4e72, ffff, CF_A);
2242     INSN(rte,       4e73, ffff, CF_A);
2243     INSN(rts,       4e75, ffff, CF_A);
2244     INSN(movec,     4e7b, ffff, CF_A);
2245     INSN(jump,      4e80, ffc0, CF_A);
2246     INSN(jump,      4ec0, ffc0, CF_A);
2247     INSN(addsubq,   5180, f1c0, CF_A);
2248     INSN(scc,       50c0, f0f8, CF_A);
2249     INSN(addsubq,   5080, f1c0, CF_A);
2250     INSN(tpf,       51f8, fff8, CF_A);
2251     INSN(branch,    6000, f000, CF_A);
2252     INSN(moveq,     7000, f100, CF_A);
2253     INSN(mvzs,      7100, f100, CF_B);
2254     INSN(or,        8000, f000, CF_A);
2255     INSN(divw,      80c0, f0c0, CF_A);
2256     INSN(addsub,    9000, f000, CF_A);
2257     INSN(subx,      9180, f1f8, CF_A);
2258     INSN(suba,      91c0, f1c0, CF_A);
2259     INSN(undef_mac, a000, f000, CF_A);
2260     INSN(mov3q,     a140, f1c0, CF_B);
2261     INSN(cmp,       b000, f1c0, CF_B); /* cmp.b */
2262     INSN(cmp,       b040, f1c0, CF_B); /* cmp.w */
2263     INSN(cmpa,      b0c0, f1c0, CF_B); /* cmpa.w */
2264     INSN(cmp,       b080, f1c0, CF_A);
2265     INSN(cmpa,      b1c0, f1c0, CF_A);
2266     INSN(eor,       b180, f1c0, CF_A);
2267     INSN(and,       c000, f000, CF_A);
2268     INSN(mulw,      c0c0, f0c0, CF_A);
2269     INSN(addsub,    d000, f000, CF_A);
2270     INSN(addx,      d180, f1f8, CF_A);
2271     INSN(adda,      d1c0, f1c0, CF_A);
2272     INSN(shift_im,  e080, f0f0, CF_A);
2273     INSN(shift_reg, e0a0, f0f0, CF_A);
2274     INSN(undef_fpu, f000, f000, CF_A);
2275     INSN(fpu,       f200, ffc0, CF_FPU);
2276     INSN(fbcc,      f280, ffc0, CF_FPU);
2277     INSN(intouch,   f340, ffc0, CF_A);
2278     INSN(cpushl,    f428, ff38, CF_A);
2279     INSN(wddata,    fb00, ff00, CF_A);
2280     INSN(wdebug,    fbc0, ffc0, CF_A);
2281 #undef INSN
2282 }
2283
2284 /* ??? Some of this implementation is not exception safe.  We should always
2285    write back the result to memory before setting the condition codes.  */
2286 static void disas_m68k_insn(CPUState * env, DisasContext *s)
2287 {
2288     uint16_t insn;
2289
2290     insn = lduw(s->pc);
2291     s->pc += 2;
2292
2293     opcode_table[insn](s, insn);
2294 }
2295
2296 #if 0
2297 /* Save the result of a floating point operation.  */
2298 static void expand_op_fp_result(qOP *qop)
2299 {
2300     gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2301 }
2302
2303 /* Dummy op to indicate that the flags have been set.  */
2304 static void expand_op_flags_set(qOP *qop)
2305 {
2306 }
2307
2308 /* Convert the confition codes into CC_OP_FLAGS format.  */
2309 static void expand_op_flush_flags(qOP *qop)
2310 {
2311     int cc_opreg;
2312
2313     if (qop->args[0] == CC_OP_DYNAMIC)
2314         cc_opreg = QREG_CC_OP;
2315     else
2316         cc_opreg = gen_im32(qop->args[0]);
2317     gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2318 }
2319
2320 /* Set CC_DEST after a logical or direct flag setting operation.  */
2321 static void expand_op_logic_cc(qOP *qop)
2322 {
2323     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2324 }
2325
2326 /* Set CC_SRC and CC_DEST after an arithmetic operation.  */
2327 static void expand_op_update_cc_add(qOP *qop)
2328 {
2329     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2330     gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2331 }
2332
2333 /* Update the X flag.  */
2334 static void expand_op_update_xflag(qOP *qop)
2335 {
2336     int arg0;
2337     int arg1;
2338
2339     arg0 = qop->args[0];
2340     arg1 = qop->args[1];
2341     if (arg1 == QREG_NULL) {
2342         /* CC_X = arg0.  */
2343         gen_op_mov32(QREG_CC_X, arg0);
2344     } else {
2345         /* CC_X = arg0 < (unsigned)arg1.  */
2346         gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2347     }
2348 }
2349
2350 /* Set arg0 to the contents of the X flag.  */
2351 static void expand_op_get_xflag(qOP *qop)
2352 {
2353     gen_op_mov32(qop->args[0], QREG_CC_X);
2354 }
2355
2356 /* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
2357    already know the shift is within range.  */
2358 static inline void expand_shift_im(qOP *qop, int right, int arith)
2359 {
2360     int val;
2361     int reg;
2362     int tmp;
2363     int im;
2364
2365     reg = qop->args[0];
2366     im = qop->args[1];
2367     tmp = gen_im32(im);
2368     val = gen_new_qreg(QMODE_I32);
2369     gen_op_mov32(val, reg);
2370     gen_op_mov32(QREG_CC_DEST, val);
2371     gen_op_mov32(QREG_CC_SRC, tmp);
2372     if (right) {
2373         if (arith) {
2374             gen_op_sar32(reg, val, tmp);
2375         } else {
2376             gen_op_shr32(reg, val, tmp);
2377         }
2378         if (im == 1)
2379             tmp = QREG_NULL;
2380         else
2381             tmp = gen_im32(im - 1);
2382     } else {
2383         gen_op_shl32(reg, val, tmp);
2384         tmp = gen_im32(32 - im);
2385     }
2386     if (tmp != QREG_NULL)
2387         gen_op_shr32(val, val, tmp);
2388     gen_op_and32(QREG_CC_X, val, gen_im32(1));
2389 }
2390
2391 static void expand_op_shl_im_cc(qOP *qop)
2392 {
2393     expand_shift_im(qop, 0, 0);
2394 }
2395
2396 static void expand_op_shr_im_cc(qOP *qop)
2397 {
2398     expand_shift_im(qop, 1, 0);
2399 }
2400
2401 static void expand_op_sar_im_cc(qOP *qop)
2402 {
2403     expand_shift_im(qop, 1, 1);
2404 }
2405
2406 /* Expand a shift by register.  */
2407 /* ??? This gives incorrect answers for shifts by 0 or >= 32 */
2408 static inline void expand_shift_reg(qOP *qop, int right, int arith)
2409 {
2410     int val;
2411     int reg;
2412     int shift;
2413     int tmp;
2414
2415     reg = qop->args[0];
2416     shift = qop->args[1];
2417     val = gen_new_qreg(QMODE_I32);
2418     gen_op_mov32(val, reg);
2419     gen_op_mov32(QREG_CC_DEST, val);
2420     gen_op_mov32(QREG_CC_SRC, shift);
2421     tmp = gen_new_qreg(QMODE_I32);
2422     if (right) {
2423         if (arith) {
2424             gen_op_sar32(reg, val, shift);
2425         } else {
2426             gen_op_shr32(reg, val, shift);
2427         }
2428         gen_op_sub32(tmp, shift, gen_im32(1));
2429     } else {
2430         gen_op_shl32(reg, val, shift);
2431         gen_op_sub32(tmp, gen_im32(31), shift);
2432     }
2433     gen_op_shl32(val, val, tmp);
2434     gen_op_and32(QREG_CC_X, val, gen_im32(1));
2435 }
2436
2437 static void expand_op_shl_cc(qOP *qop)
2438 {
2439     expand_shift_reg(qop, 0, 0);
2440 }
2441
2442 static void expand_op_shr_cc(qOP *qop)
2443 {
2444     expand_shift_reg(qop, 1, 0);
2445 }
2446
2447 static void expand_op_sar_cc(qOP *qop)
2448 {
2449     expand_shift_reg(qop, 1, 1);
2450 }
2451
2452 /* Set the Z flag to (arg0 & arg1) == 0.  */
2453 static void expand_op_btest(qOP *qop)
2454 {
2455     int tmp;
2456     int l1;
2457
2458     l1 = gen_new_label();
2459     tmp = gen_new_qreg(QMODE_I32);
2460     gen_op_and32(tmp, qop->args[0], qop->args[1]);
2461     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
2462     gen_op_jmp_nz32(tmp, l1);
2463     gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
2464     gen_op_label(l1);
2465 }
2466
2467 /* arg0 += arg1 + CC_X */
2468 static void expand_op_addx_cc(qOP *qop)
2469 {
2470     int arg0 = qop->args[0];
2471     int arg1 = qop->args[1];
2472     int l1, l2;
2473     
2474     gen_op_add32 (arg0, arg0, arg1);
2475     l1 = gen_new_label();
2476     l2 = gen_new_label();
2477     gen_op_jmp_z32(QREG_CC_X, l1);
2478     gen_op_add32(arg0, arg0, gen_im32(1));
2479     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
2480     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2481     gen_op_jmp(l2);
2482     gen_set_label(l1);
2483     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
2484     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2485     gen_set_label(l2);
2486 }
2487
2488 /* arg0 -= arg1 + CC_X */
2489 static void expand_op_subx_cc(qOP *qop)
2490 {
2491     int arg0 = qop->args[0];
2492     int arg1 = qop->args[1];
2493     int l1, l2;
2494
2495     l1 = gen_new_label();
2496     l2 = gen_new_label();
2497     gen_op_jmp_z32(QREG_CC_X, l1);
2498     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
2499     gen_op_sub32(arg0, arg0, gen_im32(1));
2500     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
2501     gen_op_jmp(l2);
2502     gen_set_label(l1);
2503     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2504     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
2505     gen_set_label(l2);
2506     gen_op_sub32 (arg0, arg0, arg1);
2507 }
2508
2509 /* Expand target specific ops to generic qops.  */
2510 static void expand_target_qops(void)
2511 {
2512     qOP *qop;
2513     qOP *next;
2514     int c;
2515
2516     /* Copy the list of qops, expanding target specific ops as we go.  */
2517     qop = gen_first_qop;
2518     gen_first_qop = NULL;
2519     gen_last_qop = NULL;
2520     for (; qop; qop = next) {
2521         c = qop->opcode;
2522         next = qop->next;
2523         if (c < FIRST_TARGET_OP) {
2524             qop->prev = gen_last_qop;
2525             qop->next = NULL;
2526             if (gen_last_qop)
2527                 gen_last_qop->next = qop;
2528             else
2529                 gen_first_qop = qop;
2530             gen_last_qop = qop;
2531             continue;
2532         }
2533         switch (c) {
2534 #define DEF(name, nargs, barrier) \
2535         case INDEX_op_##name: \
2536             expand_op_##name(qop); \
2537             break;
2538 #include "qop-target.def"
2539 #undef DEF
2540         default:
2541             cpu_abort(NULL, "Unexpanded target qop");
2542         }
2543     }
2544 }
2545
2546 /* ??? Implement this.  */
2547 static void
2548 optimize_flags(void)
2549 {
2550 }
2551 #endif
2552
2553 /* generate intermediate code for basic block 'tb'.  */
2554 int gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2555                                    int search_pc)
2556 {
2557     DisasContext dc1, *dc = &dc1;
2558     uint16_t *gen_opc_end;
2559     int j, lj;
2560     target_ulong pc_start;
2561     int pc_offset;
2562     int last_cc_op;
2563
2564     /* generate intermediate code */
2565     pc_start = tb->pc;
2566        
2567     dc->tb = tb;
2568
2569     gen_opc_ptr = gen_opc_buf;
2570     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2571     gen_opparam_ptr = gen_opparam_buf;
2572
2573     dc->is_jmp = DISAS_NEXT;
2574     dc->pc = pc_start;
2575     dc->cc_op = CC_OP_DYNAMIC;
2576     dc->singlestep_enabled = env->singlestep_enabled;
2577     dc->fpcr = env->fpcr;
2578     nb_gen_labels = 0;
2579     lj = -1;
2580     do {
2581         free_qreg = 0;
2582         pc_offset = dc->pc - pc_start;
2583         gen_throws_exception = NULL;
2584         if (env->nb_breakpoints > 0) {
2585             for(j = 0; j < env->nb_breakpoints; j++) {
2586                 if (env->breakpoints[j] == dc->pc) {
2587                     gen_exception(dc, dc->pc, EXCP_DEBUG);
2588                     dc->is_jmp = DISAS_JUMP;
2589                     break;
2590                 }
2591             }
2592             if (dc->is_jmp)
2593                 break;
2594         }
2595         if (search_pc) {
2596             j = gen_opc_ptr - gen_opc_buf;
2597             if (lj < j) {
2598                 lj++;
2599                 while (lj < j)
2600                     gen_opc_instr_start[lj++] = 0;
2601             }
2602             gen_opc_pc[lj] = dc->pc;
2603             gen_opc_instr_start[lj] = 1;
2604         }
2605         last_cc_op = dc->cc_op;
2606         disas_m68k_insn(env, dc);
2607     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
2608              !env->singlestep_enabled &&
2609              (pc_offset) < (TARGET_PAGE_SIZE - 32));
2610
2611     if (__builtin_expect(env->singlestep_enabled, 0)) {
2612         /* Make sure the pc is updated, and raise a debug exception.  */
2613         if (!dc->is_jmp) {
2614             gen_flush_cc_op(dc);
2615             gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
2616         }
2617         gen_op_raise_exception(EXCP_DEBUG);
2618     } else {
2619         switch(dc->is_jmp) {
2620         case DISAS_NEXT:
2621             gen_flush_cc_op(dc);
2622             gen_jmp_tb(dc, 0, dc->pc);
2623             break;
2624         default:
2625         case DISAS_JUMP:
2626         case DISAS_UPDATE:
2627             gen_flush_cc_op(dc);
2628             /* indicate that the hash table must be used to find the next TB */
2629             gen_op_mov32(QREG_T0, gen_im32(0));
2630             gen_op_exit_tb();
2631             break;
2632         case DISAS_TB_JUMP:
2633             /* nothing more to generate */
2634             break;
2635         }
2636     }
2637     *gen_opc_ptr = INDEX_op_end;
2638
2639 #ifdef DEBUG_DISAS
2640     if (loglevel & CPU_LOG_TB_IN_ASM) {
2641         fprintf(logfile, "----------------\n");
2642         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2643         target_disas(logfile, pc_start, dc->pc - pc_start, 0);
2644         fprintf(logfile, "\n");
2645         if (loglevel & (CPU_LOG_TB_OP)) {
2646             fprintf(logfile, "OP:\n");
2647             dump_ops(gen_opc_buf, gen_opparam_buf);
2648             fprintf(logfile, "\n");
2649         }
2650     }
2651 #endif
2652     if (search_pc) {
2653         j = gen_opc_ptr - gen_opc_buf;
2654         lj++;
2655         while (lj <= j)
2656             gen_opc_instr_start[lj++] = 0;
2657         tb->size = 0;
2658     } else {
2659         tb->size = dc->pc - pc_start;
2660     }
2661
2662     //optimize_flags();
2663     //expand_target_qops();
2664     return 0;
2665 }
2666
2667 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2668 {
2669     return gen_intermediate_code_internal(env, tb, 0);
2670 }
2671
2672 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2673 {
2674     return gen_intermediate_code_internal(env, tb, 1);
2675 }
2676
2677 CPUM68KState *cpu_m68k_init(void)
2678 {
2679     CPUM68KState *env;
2680
2681     env = malloc(sizeof(CPUM68KState));
2682     if (!env)
2683         return NULL;
2684     cpu_exec_init(env);
2685
2686     memset(env, 0, sizeof(CPUM68KState));
2687     /* ??? FP regs should be initialized to NaN.  */
2688     cpu_single_env = env;
2689     env->cc_op = CC_OP_FLAGS;
2690     return env;
2691 }
2692
2693 void cpu_m68k_close(CPUM68KState *env)
2694 {
2695     free(env);
2696 }
2697
2698 m68k_def_t *m68k_find_by_name(const char *name)
2699 {
2700     m68k_def_t *def;
2701
2702     def = m68k_cpu_defs;
2703     while (def->name)
2704       {
2705         if (strcmp(def->name, name) == 0)
2706             return def;
2707         def++;
2708       }
2709     return NULL;
2710 }
2711
2712 void cpu_m68k_register(CPUM68KState *env, m68k_def_t *def)
2713 {
2714     register_m68k_insns(def);
2715 }
2716
2717 void cpu_dump_state(CPUState *env, FILE *f, 
2718                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2719                     int flags)
2720 {
2721     int i;
2722     uint16_t sr;
2723     CPU_DoubleU u;
2724     for (i = 0; i < 8; i++)
2725       {
2726         u.d = env->fregs[i];
2727         cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
2728                      i, env->dregs[i], i, env->aregs[i],
2729                      i, u.l.upper, u.l.lower, u.d);
2730       }
2731     cpu_fprintf (f, "PC = %08x   ", env->pc);
2732     sr = env->sr;
2733     cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
2734                  (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
2735                  (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
2736     cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
2737 }
2738
2739 /* ??? */
2740 target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2741 {
2742     return addr;
2743 }
2744
2745 #if defined(CONFIG_USER_ONLY) 
2746
2747 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
2748                                int is_user, int is_softmmu)
2749 {
2750     env->exception_index = EXCP_ACCESS;
2751     env->mmu.ar = address;
2752     return 1;
2753 }
2754
2755 #else
2756
2757 #error not implemented
2758
2759 #endif