1 #include "sysdeps.h"
2 #include <math.h>
3
4 #include "memory-uae.h"
5 #include "newcpu.h"
6 #include "m68k.h"
7 #include "cpu_emulation.h"
8 #include "disasm-glue.h"
9
10 #ifdef DISASM_USE_BUILTIN /* rest of file */
11
12
13 /*
14 opcode overview:
15
16 BITREV 0000 000 011 000 rrr
17 ORI 0000 000 0ss eee eee
18 BYTEREV 0000 001 011 000 rrr
19 ANDI 0000 001 0ss eee eee
20 FF1 0000 010 011 000 rrr
21 SUBI 0000 010 0ss eee eee
22 RTM 0000 011 011 00d rrr
23 CALLM 0000 011 011 eee eee
24 ADDI 0000 011 0ss eee eee
25 CMP2/CHK2 0000 0ss 011 eee eee
26 BTST 0000 100 000 eee eee
27 BCHG 0000 100 001 eee eee
28 BCLR 0000 100 010 eee eee
29 BSET 0000 100 011 eee eee
30 EORI 0000 101 0ss eee eee
31 CMPI 0000 110 0ss eee eee
32 MOVES 0000 111 0ss eee eee
33 CAS2 0000 1ss 011 111 100
34 CAS 0000 1ss 011 eee eee
35 MOVEP 0000 rrr 1oo 001 rrr
36 BTST 0000 rrr 100 eee eee
37 BCHG 0000 rrr 101 eee eee
38 BCLR 0000 rrr 110 eee eee
39 BSET 0000 rrr 111 eee eee
40 MOVE 0001 eee eee eee eee
41 MOVE 0010 eee eee eee eee
42 MOVE 0011 eee eee eee eee
43 MOVE SR 0100 000 011 eee eee
44 NEGX 0100 000 0ss eee eee
45 MOVE CCR 0100 001 011 eee eee
46 CLR 0100 001 0ss eee eee
47 MOVE CCR 0100 010 011 eee eee
48 NEG 0100 010 0ss eee eee
49 MOVE SR 0100 011 011 eee eee
50 NOT 0100 011 0ss eee eee
51 LINK.L 0100 100 000 001 rrr
52 NBCD 0100 100 000 eee eee
53 SWAP 0100 100 001 000 rrr
54 BKPT 0100 100 001 001 vvv
55 PEA 0100 100 001 eee eee
56 EXT 0100 100 01s 000 rrr
57 EXTB 0100 100 111 000 rrr
58 HALT 0100 101 011 001 000
59 PULSE 0100 101 011 001 100
60 BGND 0100 101 011 111 010
61 ILLEGAL 0100 101 011 111 100 ; sysV68: swbeg.w
62 SWBEGL 0100 101 011 111 101 ; sysV68
63 TAS 0100 101 011 eee eee
64 TST 0100 101 0ss eee eee
65 MULS/U 0100 110 000 eee eee
66 DIVS/U 0100 110 001 eee eee
67 SATS 0100 110 010 000 rrr
68 MOVEM 0100 1d0 01s eee eee
69 TRAP 0100 111 001 00v vvv
70 LINK 0100 111 001 010 rrr
71 UNLK 0100 111 001 011 rrr
72 MOVE USP 0100 111 001 10d rrr
73 RESET 0100 111 001 110 000
74 NOP 0100 111 001 110 001
75 STOP 0100 111 001 110 010
76 RTE 0100 111 001 110 011
77 RTD 0100 111 001 110 100
78 RTS 0100 111 001 110 101
79 TRAPV 0100 111 001 110 110
80 RTR 0100 111 001 110 111
81 MOVEC 0100 111 001 111 01d
82 JSR 0100 111 010 eee eee
83 JMP 0100 111 011 eee eee
84 LEA 0100 rrr 111 eee eee
85 CHK 0100 rrr ss0 eee eee
86 DBcc 0101 ccc c11 001 rrr
87 TRAPcc 0101 ccc c11 111 sss
88 Scc 0101 ccc c11 eee eee
89 ADDQ 0101 iii 0ss eee eee
90 SUBQ 0101 iii 1ss eee eee
91 BRA 0110 000 0dd ddd ddd
92 BSR 0110 000 1dd ddd ddd
93 Bcc 0110 ccc cdd ddd ddd
94 MVS 0111 rrr 10s eee eee
95 MVZ 0111 rrr 11s eee eee
96 MOVEQ 0111 rrr 0ii iii iii
97 DIVU 1000 rrr 011 eee eee
98 SBCD 1000 rrr 100 00m rrr
99 PACK 1000 rrr 101 00m rrr
100 UNPK 1000 rrr 110 00m rrr
101 DIVS 1000 rrr 111 eee eee
102 OR 1000 rrr ooo eee eee
103 SUBX 1001 rrr 1ss 00m rrr
104 SUB 1001 rrr oss eee eee
105 SUBA 1001 rrr s11 eee eee
106 MOV3Q 1010 iii 101 eee eee
107 MOVCLR 1010 0aa 111 00r rrr
108 MOVACC 1010 0aa 110 00r rrr
109 MOVMACSR 1010 100 100 eee eee
110 MOVACCEXT01 1010 101 110 00r rrr
111 MOVACCEXT23 1010 111 110 00r rrr
112 MOVMACSR 1010 100 110 00r rrr
113 MAC 1010 xxx 0ax 00y yyy
114 LINEA 1010 xxx xxx xxx xxx
115 CMPA 1011 rrr s11 eee eee
116 CMPM 1011 rrr 1ss 001 eee
117 EOR 1011 rrr 1ss eee eee
118 CMP 1011 rrr ooo eee eee
119 MULU 1100 rrr 011 eee eee
120 ABCD 1100 rrr 100 00m rrr
121 EXG 1100 rrr 101 000 rrr
122 EXG 1100 rrr 101 001 rrr
123 EXG 1100 rrr 110 001 rrr
124 MULS 1100 rrr 111 eee eee
125 AND 1100 rrr ooo eee eee
126 ADDX 1101 rrr 1ss 00m rrr
127 ADDA 1101 rrr s11 eee eee
128 ADD 1101 rrr oss eee eee
129 BFTST 1110 100 011 eee eee
130 BFEXTU 1110 100 111 eee eee
131 BFCHG 1110 101 011 eee eee
132 BFEXTS 1110 101 111 eee eee
133 BFCLR 1110 110 011 eee eee
134 BFFFO 1110 110 111 eee eee
135 BFSET 1110 111 011 eee eee
136 BFINS 1110 111 111 eee eee
137 ASR 1110 rrr 0ss i00 eee
138 ASL 1110 rrr 1ss i00 eee
139 LSR 1110 rrr 0ss i01 eee
140 LSL 1110 rrr 1ss i01 eee
141 ROXL 1110 rrr 0ss i10 eee
142 ROXR 1110 rrr 1ss i10 eee
143 ROL 1110 rrr 0ss i11 eee
144 ROR 1110 rrr 1ss i11 eee
145
146
147 MOVE16 1111 011 000 100 rrr
148 cpGEN 1111 ppp 000 eee eee
149 cpDBcc 1111 ppp 001 001 rrr
150 cpTRAPcc 1111 ppp 001 111 sss
151 cpScc 1111 ppp 001 eee eee
152 cpBcc 1111 ppp 01s ccc ccc
153 */
154
155
156 #define dstreg(opcode) (((opcode) >> 9) & 7)
157 #define dstmod(opcode) (((opcode) >> 6) & 7)
158 #define srcmod(opcode) (((opcode) >> 3) & 7)
159 #define srcreg(opcode) (((opcode) ) & 7)
160 #define insize(ocpode) (((opcode) >> 6) & 3)
161
162 #define sputc(c) *(((struct priv_data *)(info->disasm_data))->lp)++ = c
163 #define pcomma(info) sputc(',')
164
165 #define GETUW(a) ((uae_u16)phys_get_word(a))
166 #define GETW(a) ((uae_s16)phys_get_word(a))
167 #define GETL(a) ((uae_s32)phys_get_long(a))
168 #define GETUL(a) ((uae_u32)phys_get_long(a))
169
170 struct priv_data {
171 memptr oldaddr;
172 char *lp;
173 };
174
175 #define REG_PC 8
176
177 enum fpu_size {
178 FPU_SIZE_LONG = 4,
179 FPU_SIZE_SINGLE,
180 FPU_SIZE_EXTENDED,
181 FPU_SIZE_PACKED,
182 FPU_SIZE_WORD,
183 FPU_SIZE_DOUBLE,
184 FPU_SIZE_BYTE,
185 FPU_SIZE_PACKED_VARIABLE
186 };
187
188 static const char *const fpregs[8] = { "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7" };
189 static const char *const fpcregs[3] = { "fpiar", "fpsr", "fpcr" };
190
191 #if defined(__WIN32__) || defined(_WIN32)
192 # define NO_LONGDOUBLE_PRINTF
193 #endif
194
195 #if defined(SIZEOF_LONG_DOUBLE) && defined(SIZEOF_DOUBLE) && (SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE)
196 /*
197 * Android currently has some functions commented out in the math.h header file,
198 * even if autoconf detects them to be present.
199 */
200 #undef logl
201 #define logl(x) ((long double)log((double)(x)))
202 #undef powl
203 #define powl(x, y) ((long double)pow((double)(x), (double)(y)))
204 #undef ldexpl
205 #define ldexpl(x, y) ((long double)ldexp((double)(x), y))
206 #endif
207
208 /******************************************************************************/
209 /*** ---------------------------------------------------------------------- ***/
210 /******************************************************************************/
211
212 static const char *const condtable[] =
213 {
214 "t", "f", "hi", "ls", "cc", "cs", "ne", "eq",
215 "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"
216 };
217
218 static const char *const pmmucondtable[64] =
219 {
220 "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac",
221 "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc",
222 "??", "??", "??", "??", "??", "??", "??", "??",
223 "??", "??", "??", "??", "??", "??", "??", "??",
224 "??", "??", "??", "??", "??", "??", "??", "??",
225 "??", "??", "??", "??", "??", "??", "??", "??",
226 "??", "??", "??", "??", "??", "??", "??", "??",
227 "??", "??", "??", "??", "??", "??", "??", "??"
228 };
229
230 static const char *const cpcondtable[64] =
231 {
232 "??", "??", "??", "??", "??", "??", "??", "??",
233 "??", "??", "??", "??", "??", "??", "??", "??",
234 "??", "??", "??", "??", "??", "??", "??", "??",
235 "??", "??", "??", "??", "??", "??", "??", "??",
236 "??", "??", "??", "??", "??", "??", "??", "??",
237 "??", "??", "??", "??", "??", "??", "??", "??",
238 "??", "??", "??", "??", "??", "??", "??", "??",
239 "??", "??", "??", "??", "??", "??", "??", "??"
240 };
241
242 static const char *const fpucondtable[64] =
243 {
244 "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or",
245 "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t",
246 "sf", "seq", "gt", "ge", "lt", "le", "gl", "gle",
247 "ngle","ngl", "nle", "nlt", "nge", "ngt", "sne", "st",
248 "???", "???", "???", "???", "???", "???", "???", "???",
249 "???", "???", "???", "???", "???", "???", "???", "???",
250 "???", "???", "???", "???", "???", "???", "???", "???",
251 "???", "???", "???", "???", "???", "???", "???", "???"
252 };
253
254 static const char *const bittable[] =
255 {
256 "btst", "bchg", "bclr", "bset"
257 };
258
259 static const char *const immedtable[] =
260 {
261 "ori", "andi", "subi", "addi", "???", "eori", "cmpi", "???"
262 };
263
264 static const char *const shfttable[] =
265 {
266 "as", "ls", "rox", "ro"
267 };
268
269 static const char *const bitfieldtable[] =
270 {
271 "bftst", "bfextu", "bfchg", "bfexts", "bfclr", "bfffo", "bfset", "bfins"
272 };
273
274 /******************************************************************************/
275 /*** ---------------------------------------------------------------------- ***/
276 /******************************************************************************/
277
ps(m68k_disasm_info * info,const char * str)278 static void ps(m68k_disasm_info *info, const char *str)
279 {
280 register char c;
281
282 while ((c = *str++) != '\0')
283 {
284 sputc(c);
285 }
286 }
287
288 /*** ---------------------------------------------------------------------- ***/
289
startoperands(m68k_disasm_info * info)290 static void startoperands(m68k_disasm_info *info)
291 {
292 #if 0
293 while (((info->lp - info->asmline) % 10) != 0)
294 sputc(' ');
295 #else
296 sputc('\0');
297 ((struct priv_data *)(info->disasm_data))->lp = info->operands;
298 #endif
299 }
300
301 /*** ---------------------------------------------------------------------- ***/
302
only_if(m68k_disasm_info * info,const char * cpu)303 static void only_if(m68k_disasm_info *info, const char *cpu)
304 {
305 if (*info->comments == '\0')
306 {
307 strcat(info->comments, cpu);
308 strcat(info->comments, " only");
309 }
310 }
311 #define only_68020() only_if(info, "68020+")
312 #define only_cf(rev) only_if(info, "ColdFire " rev)
313
314 /*** ---------------------------------------------------------------------- ***/
315
pudec(m68k_disasm_info * info,uae_u32 x)316 static void pudec(m68k_disasm_info *info, uae_u32 x)
317 {
318 char buf[20];
319 char *cp;
320
321 cp = buf + sizeof(buf);
322 *--cp = '\0';
323 if (x != 0)
324 {
325 while (x)
326 {
327 *--cp = (char) (x % 10 + '0');
328 x /= 10;
329 }
330 } else
331 {
332 *--cp = '0';
333 }
334 ps(info, cp);
335 }
336
337 /*** ---------------------------------------------------------------------- ***/
338
psdec(m68k_disasm_info * info,uae_s32 val)339 static void psdec(m68k_disasm_info *info, uae_s32 val)
340 {
341 if (val < 0)
342 {
343 sputc('-');
344 val = -val;
345 }
346 pudec(info, val);
347 }
348
349 /*** ---------------------------------------------------------------------- ***/
350
351 #if 0
352 static void pfloat(m68k_disasm_info *info, double val)
353 {
354 gcvt(val, 6, ((struct priv_data *)(info->disasm_data))->lp);
355 while (*(((struct priv_data *)(info->disasm_data))->lp) != '\0')
356 (((struct priv_data *)(info->disasm_data))->lp)++;
357 }
358 #endif
359
360 /*** ---------------------------------------------------------------------- ***/
361
pbyte(m68k_disasm_info * info,unsigned short val)362 static void pbyte(m68k_disasm_info *info, unsigned short val)
363 {
364 unsigned short c;
365
366 val &= 0xff;
367 c = val >> 4;
368 c = c >= 10 ? (c + 'A' - 10) : (c + '0');
369 sputc(c);
370 c = val & 0x0f;
371 c = c >= 10 ? (c + 'A' - 10) : (c + '0');
372 sputc(c);
373 }
374
375 /*** ---------------------------------------------------------------------- ***/
376
p2hex(m68k_disasm_info * info,unsigned short val)377 static void p2hex(m68k_disasm_info *info, unsigned short val)
378 {
379 sputc('$');
380 pbyte(info, val);
381 }
382
383 /*** ---------------------------------------------------------------------- ***/
384
p4hex0(m68k_disasm_info * info,unsigned short val)385 static void p4hex0(m68k_disasm_info *info, unsigned short val)
386 {
387 pbyte(info, val >> 8);
388 pbyte(info, val);
389 }
390
391 /*** ---------------------------------------------------------------------- ***/
392
p4hex(m68k_disasm_info * info,unsigned short val)393 static void p4hex(m68k_disasm_info *info, unsigned short val)
394 {
395 sputc('$');
396 p4hex0(info, val);
397 }
398
399 /*** ---------------------------------------------------------------------- ***/
400
p8hex(m68k_disasm_info * info,uae_u32 val)401 static void p8hex(m68k_disasm_info *info, uae_u32 val)
402 {
403 sputc('$');
404 p4hex0(info, (unsigned short) (val >> 16));
405 p4hex0(info, (unsigned short) (val));
406 }
407
408 /*** ---------------------------------------------------------------------- ***/
409
pcond(m68k_disasm_info * info,int cond)410 static void pcond(m68k_disasm_info *info, int cond)
411 {
412 ps(info, condtable[cond]);
413 }
414
415 /*** ---------------------------------------------------------------------- ***/
416
odcw(m68k_disasm_info * info,int val)417 static void odcw(m68k_disasm_info *info, int val)
418 {
419 ps(info, "dc.w");
420 startoperands(info);
421 p4hex(info, val);
422 info->num_oper = 1;
423 }
424
425 /*** ---------------------------------------------------------------------- ***/
426
od(m68k_disasm_info * info,int regnum)427 static void od(m68k_disasm_info *info, int regnum)
428 {
429 sputc('d');
430 if (regnum >= 0 && regnum <= 7)
431 sputc(regnum + '0');
432 else
433 sputc('?');
434 }
435
436 /*** ---------------------------------------------------------------------- ***/
437
oa(m68k_disasm_info * info,int regnum)438 static void oa(m68k_disasm_info *info, int regnum)
439 {
440 if (regnum == REG_PC)
441 {
442 ps(info, "pc");
443 } else
444 {
445 sputc('a');
446 sputc(regnum + '0');
447 }
448 }
449
450 /*** ---------------------------------------------------------------------- ***/
451
oad(m68k_disasm_info * info,int regnum)452 static void oad(m68k_disasm_info *info, int regnum)
453 {
454 if (regnum & 0xfff8)
455 oa(info, regnum & 7);
456 else
457 od(info, regnum & 7);
458 }
459
460 /*** ---------------------------------------------------------------------- ***/
461
oddstreg(m68k_disasm_info * info,int opcode)462 static void oddstreg(m68k_disasm_info *info, int opcode)
463 {
464 od(info, dstreg(opcode));
465 }
466
467 /*** ---------------------------------------------------------------------- ***/
468
oai(m68k_disasm_info * info,int regnum)469 static void oai(m68k_disasm_info *info, int regnum)
470 {
471 sputc('(');
472 oa(info, regnum);
473 sputc(')');
474 }
475
476 /*** ---------------------------------------------------------------------- ***/
477
oadi(m68k_disasm_info * info,int regnum)478 static void oadi(m68k_disasm_info *info, int regnum)
479 {
480 sputc('(');
481 oad(info, regnum);
482 sputc(')');
483 }
484
485 /*** ---------------------------------------------------------------------- ***/
486
os(m68k_disasm_info * info,int opcode)487 static int os(m68k_disasm_info *info, int opcode)
488 {
489 register int size;
490
491 size = insize(opcode);
492 sputc('.');
493 sputc(size == 2 ? 'l' :
494 size == 1 ? 'w' :
495 size == 0 ? 'b' : '?');
496 startoperands(info);
497 return size;
498 }
499
500 /*** ---------------------------------------------------------------------- ***/
501
os2(m68k_disasm_info * info,int opcode)502 static int os2(m68k_disasm_info *info, int opcode)
503 {
504 register int size;
505
506 size = (opcode >> 9) & 3;
507 sputc('.');
508 sputc(size == 3 ? 'l' :
509 size == 2 ? 'w' :
510 size == 1 ? 'b' : '?');
511 startoperands(info);
512 return size;
513 }
514
515 /*** ---------------------------------------------------------------------- ***/
516
osa(m68k_disasm_info * info,int opcode,int mask)517 static int osa(m68k_disasm_info *info, int opcode, int mask)
518 {
519 sputc('.');
520 sputc(opcode & mask ? 'l' : 'w');
521 startoperands(info);
522 return opcode & mask ? 2 : 1;
523 }
524
525 /*** ---------------------------------------------------------------------- ***/
526
make_single(uae_u32 value)527 static float make_single(uae_u32 value)
528 {
529 float frac, result;
530 int sign = (value & 0x80000000) != 0;
531
532 if ((value & 0x7fffffff) == 0)
533 return sign ? -0.0 : 0.0;
534
535 if ((value & 0x7f800000) == 0x7f800000)
536 {
537 if ((value & 0x003fffff) == 0)
538 return sign ? -1.0 / 0.0 : 1.0 / 0.0;
539 return sign ? -log(-1) : log(-1);
540 }
541
542 frac = (float) ((value & 0x7fffff) | 0x800000) / 8388608.0;
543 if (sign)
544 frac = -frac;
545
546 result = ldexp(frac, (int)((value >> 23) & 0xff) - 127);
547
548 return result;
549 }
550
make_double(uae_u32 wrd1,uae_u32 wrd2)551 static double make_double(uae_u32 wrd1, uae_u32 wrd2)
552 {
553 double frac, result;
554 int sign = (wrd1 & 0x80000000) != 0;
555
556 if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
557 return sign ? -0.0 : 0.0;
558
559 if ((wrd1 & 0x7ff00000) == 0x7ff00000)
560 {
561 if ((wrd1 & 0x0007ffff) == 0)
562 return sign ? -1.0 / 0.0 : 1.0 / 0.0;
563 return sign ? -log(-1) : log(-1);
564 }
565
566 frac =
567 (double) ((wrd1 & 0x000fffff) | 0x100000) / 1048576.0 +
568 (double) wrd2 / 4503599627370496.0;
569
570 if (wrd1 & 0x80000000)
571 frac = -frac;
572
573 result = ldexp(frac, (int)((wrd1 >> 20) & 0x7ff) - 1023);
574
575 return result;
576 }
577
578
make_extended(uae_u32 wrd1,uae_u32 wrd2,uae_u32 wrd3)579 static long double make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
580 {
581 long double frac, result;
582 int sign = (wrd1 & 0x80000000) != 0;
583 uae_u32 exp = (wrd1 >> 16) & 0x7fff;
584
585 if (exp == 0 && wrd2 == 0 && wrd3 == 0)
586 return sign ? -0.0L : 0.0L;
587
588 if (exp == 0x7fff)
589 {
590 if ((wrd2 & 0x3fffffff) == 0)
591 return sign ? -1.0L / 0.0L : 1.0L / 0.0L;
592 return sign ? -logl(-1) : logl(-1);
593 }
594
595 frac =
596 (long double) ((wrd2 & 0x7fffffff) | 0x80000000) / 2147483648.0L +
597 (long double) wrd3 / 9223372036854775808.0L;
598 if (sign)
599 frac = -frac;
600
601 result = ldexpl(frac, (int)exp - 16383);
602
603 return result;
604 }
605
606
make_packed(uae_u32 wrd1,uae_u32 wrd2,uae_u32 wrd3)607 static long double make_packed(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
608 {
609 long double d;
610 bool sign = (wrd1 & 0x80000000) != 0;
611 bool se = (wrd1 & 0x40000000) != 0;
612 int exp = (wrd1 & 0x0fff0000) >> 16;
613 unsigned int dig;
614 long double pwr;
615
616 if (exp == 0xfff)
617 {
618 if (wrd2 == 0 && wrd3 == 0)
619 {
620 return sign ? -1.0L / 0.0L : 1.0L / 0.0L;
621 } else
622 {
623 return sign ? -logl(-1) : logl(-1);
624 }
625 }
626 dig = wrd1 & 0x0000000f;
627 if (dig == 0 && wrd2 == 0 && wrd3 == 0)
628 {
629 return sign ? -0.0L : 0.0L;
630 }
631
632 /*
633 * Convert the bcd exponent to binary by successive adds and
634 * muls. Set the sign according to SE. Subtract 16 to compensate
635 * for the mantissa which is to be interpreted as 17 integer
636 * digits, rather than 1 integer and 16 fraction digits.
637 * Note: this operation can never overflow.
638 */
639 exp = ((wrd1 >> 24) & 0xf);
640 exp = exp * 10 + ((wrd1 >> 20) & 0xf);
641 exp = exp * 10 + ((wrd1 >> 16) & 0xf);
642 if (se)
643 exp = -exp;
644 /* sub to compensate for shift of mant */
645 exp = exp - 16;
646
647 /*
648 * Convert the bcd mantissa to binary by successive
649 * adds and muls. Set the sign according to SM.
650 * The mantissa digits will be converted with the decimal point
651 * assumed following the least-significant digit.
652 * Note: this operation can never overflow.
653 */
654 d = wrd1 & 0xf;
655 d = d * 10.0L + ((wrd2 >> 28) & 0xf);
656 d = d * 10.0L + ((wrd2 >> 24) & 0xf);
657 d = d * 10.0L + ((wrd2 >> 20) & 0xf);
658 d = d * 10.0L + ((wrd2 >> 16) & 0xf);
659 d = d * 10.0L + ((wrd2 >> 12) & 0xf);
660 d = d * 10.0L + ((wrd2 >> 8) & 0xf);
661 d = d * 10.0L + ((wrd2 >> 4) & 0xf);
662 d = d * 10.0L + ((wrd2 ) & 0xf);
663 d = d * 10.0L + ((wrd3 >> 28) & 0xf);
664 d = d * 10.0L + ((wrd3 >> 24) & 0xf);
665 d = d * 10.0L + ((wrd3 >> 20) & 0xf);
666 d = d * 10.0L + ((wrd3 >> 16) & 0xf);
667 d = d * 10.0L + ((wrd3 >> 12) & 0xf);
668 d = d * 10.0L + ((wrd3 >> 8) & 0xf);
669 d = d * 10.0L + ((wrd3 >> 4) & 0xf);
670 d = d * 10.0L + ((wrd3 ) & 0xf);
671
672 /* Check the sign of the mant and make the value in fp0 the same sign. */
673 if (sign)
674 d = -d;
675
676 /*
677 * Calculate power-of-ten factor from exponent.
678 */
679 if (exp < 0)
680 {
681 exp = -exp;
682 pwr = powl(10.0L, exp);
683 d = d / pwr;
684 } else
685 {
686 pwr = powl(10.0L, exp);
687 d = d * pwr;
688 }
689
690 return d;
691 }
692
693 /*** ---------------------------------------------------------------------- ***/
694
oi(m68k_disasm_info * info,int size,bool immed)695 static void oi(m68k_disasm_info *info, int size, bool immed)
696 {
697 char str[100];
698
699 if (immed)
700 sputc('#');
701 switch (size)
702 {
703 case 2:
704 p8hex(info, GETL(info->memory_vma));
705 info->memory_vma += 4;
706 break;
707 case 1:
708 p4hex(info, GETUW(info->memory_vma));
709 info->memory_vma += 2;
710 break;
711 case 0:
712 p2hex(info, (uae_s32) ((signed char) (GETW(info->memory_vma) & 0xff)));
713 info->memory_vma += 2;
714 break;
715 case FPU_SIZE_LONG:
716 psdec(info, GETL(info->memory_vma));
717 info->memory_vma += 4;
718 break;
719 case FPU_SIZE_SINGLE:
720 sprintf(str, "%.17e", make_single(GETUL(info->memory_vma)));
721 ps(info, str);
722 info->memory_vma += 4;
723 break;
724 case FPU_SIZE_EXTENDED:
725 #ifdef NO_LONGDOUBLE_PRINTF
726 sprintf(str, "%.17e", (double) make_extended(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
727 #else
728 sprintf(str, "%.17Le", make_extended(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
729 #endif
730 ps(info, str);
731 info->memory_vma += 12;
732 break;
733 case FPU_SIZE_PACKED:
734 #ifdef NO_LONGDOUBLE_PRINTF
735 sprintf(str, "%.17e", (double) make_packed(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
736 #else
737 sprintf(str, "%.17Le", make_packed(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
738 #endif
739 ps(info, str);
740 info->memory_vma += 12;
741 break;
742 case FPU_SIZE_WORD:
743 psdec(info, GETW(info->memory_vma));
744 info->memory_vma += 2;
745 break;
746 case FPU_SIZE_DOUBLE:
747 sprintf(str, "%.17e", make_double(GETUL(info->memory_vma), GETUL(info->memory_vma + 4)));
748 ps(info, str);
749 info->memory_vma += 8;
750 break;
751 case FPU_SIZE_BYTE:
752 psdec(info, (uae_s32) ((signed char) (GETW(info->memory_vma) & 0xff)));
753 info->memory_vma += 2;
754 break;
755 case FPU_SIZE_PACKED_VARIABLE:
756 #ifdef NO_LONGDOUBLE_PRINTF
757 sprintf(str, "%.17e", (double) make_packed(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
758 #else
759 sprintf(str, "%.17Le", make_packed(GETUL(info->memory_vma), GETUL(info->memory_vma + 4), GETUL(info->memory_vma + 8)));
760 #endif
761 ps(info, str);
762 info->memory_vma += 12;
763 break;
764 }
765 }
766
767 /*** ---------------------------------------------------------------------- ***/
768
pscale(m68k_disasm_info * info,int opcode)769 static void pscale(m68k_disasm_info *info, int opcode)
770 {
771 switch (opcode & 0x600)
772 {
773 case 0x0200: ps(info, "*2"); only_68020(); break;
774 case 0x0400: ps(info, "*4"); only_68020(); break;
775 case 0x0600: ps(info, "*8"); only_68020(); break;
776 }
777 }
778
779 /*** ---------------------------------------------------------------------- ***/
780
doextended(m68k_disasm_info * info,int opcode2,int srcr)781 static void doextended(m68k_disasm_info *info, int opcode2, int srcr)
782 {
783 uae_s32 disp;
784 uae_s32 outer;
785 bool con2 = false;
786 int bd = (opcode2 & 0x30) >> 4;
787 bool bs = (opcode2 & 0x80) != 0;
788 int iis;
789 uae_u32 relpc = info->reloffset + ((struct priv_data *)(info->disasm_data))->oldaddr;
790
791 only_68020();
792 switch (bd)
793 {
794 case 2:
795 disp = GETW(info->memory_vma);
796 info->memory_vma += 2;
797 break;
798 case 3:
799 disp = GETL(info->memory_vma);
800 info->memory_vma += 4;
801 break;
802 case 1:
803 disp = 0;
804 break;
805 case 0:
806 default:
807 disp = 0;
808 strcat(info->comments, "; reserved BD=0");
809 break;
810 }
811 switch (opcode2 & 0x47)
812 {
813 case 0x00:
814 /* no memory indirect */
815 outer = 0;
816 iis = 0;
817 break;
818 case 0x01:
819 /* Indirect Preindexed with Null Outer Displacement */
820 outer = 0;
821 iis = 1;
822 break;
823 case 0x02:
824 iis = 2;
825 /* Indirect Preindexed with Word Outer Displacement */
826 outer = GETW(info->memory_vma);
827 info->memory_vma += 2;
828 break;
829 case 0x03:
830 iis = 3;
831 /* Indirect Preindexed with Long Outer Displacement */
832 outer = GETL(info->memory_vma);
833 info->memory_vma += 4;
834 break;
835 case 0x04:
836 iis = 4;
837 /* reserved */
838 outer = 0;
839 strcat(info->comments, "; reserved OD=0");
840 break;
841 case 0x05:
842 iis = 5;
843 /* Indirect Postindexed with Null Outer Displacement */
844 outer = 0;
845 break;
846 case 0x06:
847 iis = 6;
848 /* Indirect Postindexed with Word Outer Displacement */
849 outer = GETW(info->memory_vma);
850 info->memory_vma += 2;
851 break;
852 case 0x07:
853 iis = 7;
854 /* Indirect Postindexed with Long Outer Displacement */
855 outer = GETL(info->memory_vma);
856 info->memory_vma += 4;
857 break;
858 case 0x40:
859 iis = 0;
860 /* no memory indirect */
861 outer = 0;
862 break;
863 case 0x41:
864 iis = 1;
865 /* Memory Indirect with Null Outer Displacement */
866 outer = 0;
867 break;
868 case 0x42:
869 iis = 2;
870 /* Memory Indirect with Word Outer Displacement */
871 outer = GETW(info->memory_vma);
872 info->memory_vma += 2;
873 break;
874 case 0x43:
875 iis = 3;
876 /* Memory Indirect with Long Outer Displacement */
877 outer = GETL(info->memory_vma);
878 info->memory_vma += 4;
879 break;
880 case 0x44:
881 default:
882 iis = 4;
883 outer = 0;
884 strcat(info->comments, "; reserved OD=0");
885 break;
886 case 0x45:
887 iis = 5;
888 outer = 0;
889 strcat(info->comments, "; reserved OD=1");
890 break;
891 case 0x46:
892 iis = 6;
893 outer = GETW(info->memory_vma);
894 info->memory_vma += 2;
895 strcat(info->comments, "; reserved OD=2");
896 break;
897 case 0x47:
898 iis = 7;
899 outer = GETL(info->memory_vma);
900 info->memory_vma += 4;
901 strcat(info->comments, "; reserved OD=3");
902 break;
903 }
904 sputc('(');
905 if (iis != 0)
906 sputc('[');
907 if (bd == 3)
908 {
909 if (srcr != REG_PC || (srcr == REG_PC && bs))
910 p8hex(info, disp);
911 else
912 p8hex(info, relpc + disp);
913 con2 = true;
914 } else if (bd == 2)
915 {
916 if (srcr != REG_PC || (srcr == REG_PC && bs))
917 p4hex(info, disp);
918 else
919 p8hex(info, relpc + disp);
920 con2 = true;
921 }
922 if (srcr == REG_PC)
923 {
924 if (con2)
925 pcomma(info);
926 if (bs)
927 sputc('z');
928 oa(info, srcr);
929 con2 = true;
930 } else
931 {
932 if (!bs)
933 {
934 if (con2)
935 pcomma(info);
936 oa(info, srcr);
937 con2 = true;
938 }
939 }
940 if (iis >= 0x4)
941 {
942 sputc(']');
943 con2 = true;
944 }
945 if ((opcode2 & 0x40) == 0)
946 {
947 if (con2)
948 pcomma(info);
949 oad(info, (opcode2 >> 12) & 0x0f);
950 ps(info, opcode2 & 0x0800 ? ".l" : ".w");
951 }
952 pscale(info, opcode2);
953 if (iis < 0x4 && iis > 0)
954 {
955 sputc(']');
956 }
957 if ((opcode2 & 0x03) >= 0x02)
958 {
959 sputc(',');
960 if ((opcode2 & 0x03) >= 0x03)
961 p8hex(info, outer);
962 else
963 p4hex(info, outer);
964 }
965 sputc(')');
966 }
967
968
doea(m68k_disasm_info * info,int opcode,int size)969 static void doea(m68k_disasm_info *info, int opcode, int size)
970 {
971 register int srcr;
972 register int opcode2;
973 uae_s32 offset;
974 register uae_s32 adr;
975
976 srcr = srcreg(opcode);
977 switch (srcmod(opcode))
978 {
979 case 0: /* Datenregister direkt */
980 od(info, srcr);
981 break;
982 case 1: /* Adressregister direkt */
983 oa(info, srcr);
984 break;
985 case 2: /* Adressregister indirekt */
986 oai(info, srcr);
987 break;
988 case 3: /* Adressregister indirekt mit Postinkrement */
989 oai(info, srcr);
990 sputc('+');
991 break;
992 case 4: /* Adressregister indirekt mit Predecrement */
993 sputc('-');
994 oai(info, srcr);
995 break;
996 case 5: /* Adressregister indirekt mit Offset */
997 psdec(info, (uae_s32) (GETW(info->memory_vma)));
998 info->memory_vma += 2;
999 oai(info, srcr);
1000 break;
1001 case 6: /* Adressregister indirekt indiziert mit Offset */
1002 opcode2 = GETUW(info->memory_vma);
1003 info->memory_vma += 2;
1004 if (opcode2 & 0x100)
1005 {
1006 doextended(info, opcode2, srcr);
1007 } else
1008 {
1009 offset = opcode2 & 0xff;
1010 psdec(info, (uae_s32) (char) offset);
1011 sputc('(');
1012 oa(info, srcr);
1013 pcomma(info);
1014 oad(info, (opcode2 >> 12) & 0x0f);
1015 ps(info, opcode2 & 0x0800 ? ".l" : ".w");
1016 pscale(info, opcode2);
1017 sputc(')');
1018 }
1019 break;
1020 case 7:
1021 switch (srcr)
1022 {
1023 case 0: /* Absolut kurz */
1024 sputc('(');
1025 adr = GETW(info->memory_vma);
1026 info->memory_vma += 2;
1027 p8hex(info, adr);
1028 ps(info, ").w");
1029 break;
1030 case 1: /* Absolut lang */
1031 adr = GETL(info->memory_vma);
1032 info->memory_vma += 4;
1033 p8hex(info, adr);
1034 break;
1035 case 2: /* PC-relative */
1036 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
1037 info->memory_vma += 2;
1038 p8hex(info, adr);
1039 oai(info, REG_PC);
1040 break;
1041 case 3: /* PC-relative indiziert */
1042 opcode2 = GETUW(info->memory_vma);
1043 info->memory_vma += 2;
1044 if (opcode2 & 0x100)
1045 {
1046 doextended(info, opcode2, REG_PC);
1047 } else
1048 {
1049 adr = (uae_s32)(signed char)(opcode2 & 0xff) + info->reloffset + ((struct priv_data *)(info->disasm_data))->oldaddr;
1050 p8hex(info, adr);
1051 sputc('(');
1052 oa(info, REG_PC);
1053 pcomma(info);
1054 oad(info, (opcode2 >> 12) & 0x0f);
1055 ps(info, opcode2 & 0x0800 ? ".l" : ".w");
1056 pscale(info, opcode2);
1057 sputc(')');
1058 }
1059 break;
1060 case 4: /* immediate */
1061 oi(info, size, true);
1062 break;
1063 default:
1064 ps(info, "???");
1065 break;
1066 }
1067 }
1068 }
1069
1070 /*** ---------------------------------------------------------------------- ***/
1071
reglist(m68k_disasm_info * info,int regmask)1072 static void reglist(m68k_disasm_info *info, int regmask)
1073 {
1074 register int regnum;
1075 int liststart;
1076 int lastreg;
1077 int status;
1078
1079 liststart = status = 0;
1080 lastreg = 20;
1081 for (regnum = 0; regnum < 16; regnum++)
1082 {
1083 if ((1 << regnum) & regmask)
1084 {
1085 if (regnum == (lastreg + 1) && regnum != 8)
1086 {
1087 if (liststart != 0)
1088 sputc('-');
1089 liststart = 0;
1090 status = 1;
1091 lastreg = regnum;
1092 } else
1093 {
1094 if (status != 0)
1095 {
1096 oad(info, lastreg);
1097 status = 0;
1098 liststart = 1;
1099 }
1100 if (liststart != 0)
1101 sputc('/');
1102 oad(info, regnum);
1103 lastreg = regnum;
1104 liststart = 1;
1105 }
1106 }
1107 }
1108 if (status != 0)
1109 oad(info, lastreg);
1110 }
1111
1112 /*** ---------------------------------------------------------------------- ***/
1113
revbits(int mask,int n)1114 static int revbits(int mask, int n)
1115 {
1116 register int i;
1117 register int newmask;
1118
1119 for (newmask = 0, i = n; i > 0; i--)
1120 {
1121 newmask = (newmask << 1) | (mask & 1);
1122 mask >>= 1;
1123 }
1124 return newmask;
1125 }
1126
1127 /******************************************************************************/
1128 /*** ---------------------------------------------------------------------- ***/
1129 /******************************************************************************/
1130
group0(m68k_disasm_info * info,int opcode)1131 static void group0(m68k_disasm_info *info, int opcode)
1132 {
1133 unsigned int opcode2;
1134 int size;
1135
1136 if (opcode & 0x0100)
1137 {
1138 if (srcmod(opcode) != 1)
1139 {
1140 /* 0000 rrr 1 xx yyyyyy */
1141 ps(info, bittable[insize(opcode)]);
1142 startoperands(info);
1143 oddstreg(info, opcode);
1144 pcomma(info);
1145 doea(info, opcode, 0);
1146 info->num_oper = 2;
1147 } else
1148 {
1149 /* 0000 000 1xx 001 yyy */
1150 ps(info, "movep");
1151 ps(info, opcode & 0x0040 ? ".l" : ".w");
1152 startoperands(info);
1153 if (opcode & 0x0080)
1154 {
1155 oddstreg(info, opcode);
1156 pcomma(info);
1157 psdec(info, GETW(info->memory_vma));
1158 info->memory_vma += 2;
1159 oai(info, srcreg(opcode));
1160 } else
1161 {
1162 psdec(info, GETW(info->memory_vma));
1163 info->memory_vma += 2;
1164 oai(info, srcreg(opcode));
1165 pcomma(info);
1166 oddstreg(info, opcode);
1167 }
1168 info->num_oper = 2;
1169 }
1170 } else
1171 {
1172 switch (opcode2 = dstreg(opcode))
1173 {
1174 case 4:
1175 /* 0000 100 0ss yyy yyy */
1176 ps(info, bittable[insize(opcode)]);
1177 startoperands(info);
1178 sputc('#');
1179 psdec(info, GETW(info->memory_vma));
1180 info->memory_vma += 2;
1181 pcomma(info);
1182 doea(info, opcode, 0);
1183 info->num_oper = 2;
1184 break;
1185
1186 default:
1187 if (insize(opcode) == 3)
1188 {
1189 switch (opcode2)
1190 {
1191 case 0:
1192 /* 0000 000 011 xxx yyy */
1193 switch (srcmod(opcode))
1194 {
1195 case 2:
1196 case 5:
1197 case 6:
1198 case 7:
1199 opcode2 = GETUW(info->memory_vma);
1200 info->memory_vma += 2;
1201 ps(info, opcode2 & 0x0800 ? "chk2.b" : "cmp2.b");
1202 startoperands(info);
1203 doea(info, opcode, 0);
1204 pcomma(info);
1205 oad(info, (opcode2 >> 12) & 0x0f);
1206 info->num_oper = 2;
1207 only_68020();
1208 break;
1209 case 0:
1210 ps(info, "bitrev.l");
1211 startoperands(info);
1212 od(info, srcreg(opcode));
1213 info->num_oper = 1;
1214 only_cf("isa_c");
1215 break;
1216 default:
1217 odcw(info, opcode);
1218 break;
1219 }
1220 break;
1221 case 1:
1222 /* 0000 001 011 xxx yyy */
1223 switch (srcmod(opcode))
1224 {
1225 case 2:
1226 case 5:
1227 case 6:
1228 case 7:
1229 opcode2 = GETUW(info->memory_vma);
1230 info->memory_vma += 2;
1231 ps(info, opcode2 & 0x0800 ? "chk2.w" : "cmp2.w");
1232 startoperands(info);
1233 doea(info, opcode, 0);
1234 pcomma(info);
1235 oad(info, (opcode2 >> 12) & 0x0f);
1236 info->num_oper = 2;
1237 only_68020();
1238 break;
1239 case 0:
1240 ps(info, "byterev.l");
1241 startoperands(info);
1242 od(info, srcreg(opcode));
1243 info->num_oper = 1;
1244 only_cf("isa_c");
1245 break;
1246 default:
1247 odcw(info, opcode);
1248 break;
1249 }
1250 break;
1251 case 2:
1252 /* 0000 010 011 xxx yyy */
1253 switch (srcmod(opcode))
1254 {
1255 case 2:
1256 case 5:
1257 case 6:
1258 case 7:
1259 opcode2 = GETUW(info->memory_vma);
1260 info->memory_vma += 2;
1261 ps(info, opcode2 & 0x0800 ? "chk2.l" : "cmpl.w");
1262 startoperands(info);
1263 doea(info, opcode, 1);
1264 pcomma(info);
1265 oad(info, (opcode2 >> 12) & 0x0f);
1266 info->num_oper = 2;
1267 only_68020();
1268 break;
1269 case 0:
1270 ps(info, "ff1.l");
1271 startoperands(info);
1272 od(info, srcreg(opcode));
1273 info->num_oper = 1;
1274 only_cf("isa_c");
1275 break;
1276 default:
1277 odcw(info, opcode);
1278 break;
1279 }
1280 break;
1281 case 3:
1282 /* 0000 011 011 xxx yyy */
1283 if ((opcode & 0x0030) == 0)
1284 {
1285 ps(info, "rtm");
1286 startoperands(info);
1287 oad(info, opcode);
1288 info->num_oper = 1;
1289 only_if(info, "68020");
1290 } else
1291 {
1292 ps(info, "callm");
1293 startoperands(info);
1294 oi(info, 1, true);
1295 pcomma(info);
1296 doea(info, opcode, 0);
1297 info->num_oper = 2;
1298 only_if(info, "68020");
1299 }
1300 break;
1301 case 5:
1302 case 6:
1303 case 7:
1304 /* 0000 101 011 xxx yyy */
1305 /* 0000 110 011 xxx yyy */
1306 /* 0000 111 011 xxx yyy */
1307 if ((opcode & 0x3f) == 0x3c)
1308 {
1309 unsigned int opcode3;
1310
1311 opcode2 = GETUW(info->memory_vma);
1312 info->memory_vma += 2;
1313 opcode3 = GETUW(info->memory_vma);
1314 info->memory_vma += 2;
1315 ps(info, "cas2");
1316 os2(info, opcode);
1317 od(info, opcode2 & 0x07);
1318 sputc(':');
1319 od(info, opcode3 & 0x07);
1320 pcomma(info);
1321 od(info, (opcode2 >> 6) & 0x07);
1322 sputc(':');
1323 od(info, (opcode3 >> 6) & 0x07);
1324 pcomma(info);
1325 oadi(info, (opcode2 >> 12) & 0x0f);
1326 pcomma(info);
1327 oadi(info, (opcode3 >> 12) & 0x0f);
1328 } else
1329 {
1330 opcode2 = GETUW(info->memory_vma);
1331 info->memory_vma += 2;
1332 ps(info, "cas");
1333 os2(info, opcode);
1334 od(info, opcode2 & 0x07);
1335 pcomma(info);
1336 od(info, (opcode2 >> 6) & 0x07);
1337 pcomma(info);
1338 doea(info, opcode, 0);
1339 }
1340 only_68020();
1341 info->num_oper = 3;
1342 break;
1343 default:
1344 odcw(info, opcode);
1345 break;
1346 }
1347 } else if (opcode2 == 7)
1348 {
1349 /* 0000 111 0ss yyy yyy */
1350
1351 ps(info, "moves");
1352 os(info, opcode);
1353 opcode2 = GETUW(info->memory_vma);
1354 info->memory_vma += 2;
1355 if (opcode2 & 0x0800)
1356 {
1357 oad(info, (opcode2 >> 12) & 0x0f);
1358 pcomma(info);
1359 doea(info, opcode, 0);
1360 } else
1361 {
1362 doea(info, opcode, 0);
1363 pcomma(info);
1364 oad(info, (opcode2 >> 12) & 0x0f);
1365 }
1366 info->num_oper = 2;
1367 } else
1368 {
1369 ps(info, immedtable[opcode2]);
1370 size = os(info, opcode);
1371 oi(info, size, true);
1372 pcomma(info);
1373 if ((opcode & 0x003f) == 0x003c)
1374 {
1375 ps(info, opcode & 0x0040 ? "sr" : "ccr");
1376 } else
1377 {
1378 doea(info, opcode, size);
1379 }
1380 info->num_oper = 2;
1381 }
1382 break;
1383 }
1384 }
1385 }
1386
1387 /******************************************************************************/
1388 /*** ---------------------------------------------------------------------- ***/
1389 /******************************************************************************/
1390
group11(m68k_disasm_info * info,int opcode)1391 static void group11(m68k_disasm_info *info, int opcode)
1392 {
1393 register int size;
1394
1395 if ((opcode & 0x0100) != 0 && insize(opcode) != 3)
1396 {
1397 if (srcmod(opcode) == 1)
1398 {
1399 ps(info, "cmpm");
1400 os(info, opcode);
1401 oai(info, srcreg(opcode));
1402 sputc('+');
1403 pcomma(info);
1404 oai(info, dstreg(opcode));
1405 sputc('+');
1406 } else
1407 {
1408 ps(info, "eor");
1409 size = os(info, opcode);
1410 oddstreg(info, opcode);
1411 pcomma(info);
1412 doea(info, opcode, size);
1413 }
1414 } else
1415 {
1416 ps(info, "cmp");
1417 switch (dstmod(opcode))
1418 {
1419 case 3:
1420 case 7:
1421 sputc('a');
1422 size = osa(info, opcode, 0x0100);
1423 doea(info, opcode, size);
1424 pcomma(info);
1425 oa(info, dstreg(opcode));
1426 break;
1427 default:
1428 size = os(info, opcode);
1429 doea(info, opcode, size);
1430 pcomma(info);
1431 oddstreg(info, opcode);
1432 break;
1433 }
1434 }
1435 info->num_oper = 2;
1436 }
1437
1438 /******************************************************************************/
1439 /*** ---------------------------------------------------------------------- ***/
1440 /******************************************************************************/
1441
group1(m68k_disasm_info * info,int opcode)1442 static void group1(m68k_disasm_info *info, int opcode)
1443 {
1444 register int size = 0;
1445
1446 ps(info, "move");
1447 if (dstmod(opcode) == 1)
1448 sputc('a');
1449 sputc('.');
1450 switch (opcode >> 12)
1451 {
1452 case 1: /* move.b */
1453 sputc('b');
1454 size = 0;
1455 break;
1456 case 2: /* move.l */
1457 sputc('l');
1458 size = 2;
1459 break;
1460 case 3: /* move.w */
1461 sputc('w');
1462 size = 1;
1463 break;
1464 }
1465 startoperands(info);
1466 doea(info, opcode, size);
1467 pcomma(info);
1468 doea(info, (dstmod(opcode) << 3) | dstreg(opcode), size);
1469 info->num_oper = 2;
1470 }
1471
1472 /******************************************************************************/
1473 /*** ---------------------------------------------------------------------- ***/
1474 /******************************************************************************/
1475
group14(m68k_disasm_info * info,int opcode)1476 static void group14(m68k_disasm_info *info, int opcode)
1477 {
1478 register short size;
1479 unsigned int opcode2;
1480 unsigned int bf;
1481
1482 if ((size = insize(opcode)) == 3 && (opcode & 0x0800) == 0)
1483 {
1484 ps(info, shfttable[(opcode >> 9) & 3]);
1485 sputc(opcode & 0x0100 ? 'l' : 'r');
1486 ps(info, ".b");
1487 startoperands(info);
1488 doea(info, opcode, size);
1489 info->num_oper = 1;
1490 } else if (size == 3 && (opcode & 0x0800) != 0)
1491 {
1492 uae_u16 cmd = (opcode >> 8) & 7;
1493
1494 only_68020();
1495 ps(info, bitfieldtable[cmd]);
1496 startoperands(info);
1497 opcode2 = GETUW(info->memory_vma);
1498 info->memory_vma += 2;
1499 info->num_oper = 1;
1500 if (cmd == 0x7) /* bfins */
1501 {
1502 od(info, (opcode2 >> 12) & 0x7);
1503 pcomma(info);
1504 info->num_oper = 2;
1505 }
1506 doea(info, opcode, size);
1507 sputc('{');
1508 bf = (opcode2 >> 6) & 0x1f;
1509 if (opcode2 & 0x800)
1510 od(info, bf);
1511 else
1512 pudec(info, bf);
1513 sputc(':');
1514 bf = opcode2 & 0x1f;
1515 if (opcode2 & 0x20)
1516 {
1517 od(info, bf);
1518 } else
1519 {
1520 if (bf == 0)
1521 bf = 32;
1522 pudec(info, bf);
1523 }
1524 sputc('}');
1525 if ((opcode & 0x100) && cmd != 0x7)
1526 {
1527 pcomma(info);
1528 od(info, (opcode2 >> 12) & 0x7);
1529 info->num_oper = 2;
1530 }
1531 } else
1532 {
1533 ps(info, shfttable[(opcode >> 3) & 3]);
1534 sputc(opcode & 0x0100 ? 'l' : 'r');
1535 os(info, opcode);
1536 if (opcode & 0x0020)
1537 {
1538 oddstreg(info, opcode);
1539 } else
1540 {
1541 sputc('#');
1542 psdec(info, dstreg(opcode) != 0 ? dstreg(opcode) : 8);
1543 }
1544 pcomma(info);
1545 od(info, srcreg(opcode));
1546 info->num_oper = 2;
1547 }
1548 }
1549
1550 /******************************************************************************/
1551 /*** ---------------------------------------------------------------------- ***/
1552 /******************************************************************************/
1553
pmmureg(m68k_disasm_info * info,int preg,int num)1554 static void pmmureg(m68k_disasm_info *info, int preg, int num)
1555 {
1556 switch (preg)
1557 {
1558 case 0x02:
1559 ps(info, "tt0");
1560 break;
1561 case 0x03:
1562 ps(info, "tt1");
1563 break;
1564 case 0x10:
1565 ps(info, "tc");
1566 break;
1567 case 0x11:
1568 ps(info, "drp");
1569 break;
1570 case 0x12:
1571 ps(info, "srp");
1572 break;
1573 case 0x13:
1574 ps(info, "crp");
1575 break;
1576 case 0x14:
1577 ps(info, "cal");
1578 break;
1579 case 0x15:
1580 ps(info, "val");
1581 break;
1582 case 0x16:
1583 ps(info, "scc");
1584 break;
1585 case 0x17:
1586 ps(info, "ac");
1587 break;
1588 case 0x18:
1589 ps(info, "psr");
1590 break;
1591 case 0x19:
1592 ps(info, "pcsr");
1593 break;
1594 case 0x1c:
1595 ps(info, "bad");
1596 sputc(num + '0');
1597 break;
1598 case 0x1d:
1599 ps(info, "bac");
1600 sputc(num + '0');
1601 break;
1602 default:
1603 ps(info, "???");
1604 break;
1605 }
1606 }
1607
1608 /*** ---------------------------------------------------------------------- ***/
1609
group_pmmu_030(m68k_disasm_info * info,int opcode)1610 static void group_pmmu_030(m68k_disasm_info *info, int opcode)
1611 {
1612 unsigned int opcode2;
1613 uae_s32 adr;
1614
1615 switch ((opcode >> 6) & 0x07)
1616 {
1617 case 0:
1618 opcode2 = GETUW(info->memory_vma);
1619 info->memory_vma += 2;
1620 info->reloffset += 2;
1621 switch (opcode2 & 0xE000)
1622 {
1623 case 0x0000:
1624 case 0x4000:
1625 case 0x6000:
1626 {
1627 int r;
1628
1629 r = (opcode2 >> 10) & 0x1f;
1630 ps(info, "pmove");
1631 if (opcode2 & 0x100)
1632 ps(info, "fd");
1633 if (r == 0x11 || r == 0x12 || r == 0x13)
1634 ps(info, ".q");
1635 else if (r == 0x18)
1636 ps(info, ".w");
1637 else
1638 ps(info, ".l");
1639 startoperands(info);
1640 if (opcode2 & 0x0200)
1641 {
1642 pmmureg(info, r, (opcode2 >> 2) & 0x07);
1643 pcomma(info);
1644 doea(info, opcode, 0);
1645 } else
1646 {
1647 doea(info, opcode, 0);
1648 pcomma(info);
1649 pmmureg(info, r, (opcode2 >> 2) & 0x07);
1650 }
1651 }
1652 info->num_oper = 2;
1653 break;
1654 case 0x2000:
1655 switch (opcode2 & 0x1c00)
1656 {
1657 case 0x0400:
1658 ps(info, "pflusha");
1659 info->num_oper = 0;
1660 break;
1661 case 0x1000:
1662 case 0x1400:
1663 case 0x1800:
1664 case 0x1c00:
1665 ps(info, "pflush");
1666 if (opcode2 & 0x400)
1667 sputc('s');
1668 startoperands(info);
1669 switch (opcode2 & 0x18)
1670 {
1671 case 0x10:
1672 case 0x18:
1673 sputc('#');
1674 p2hex(info, opcode2 & 0x0f);
1675 break;
1676 case 0x08:
1677 od(info, opcode2 & 0x07);
1678 break;
1679 case 0x00:
1680 ps(info, opcode2 & 1 ? "dfc" : "sfc");
1681 break;
1682 }
1683 pcomma(info);
1684 sputc('#');
1685 p2hex(info, (opcode2 >> 5) & 0x07);
1686 if (opcode2 & 0x0800)
1687 {
1688 pcomma(info);
1689 info->num_oper = 3;
1690 doea(info, opcode, 0);
1691 } else
1692 {
1693 info->num_oper = 2;
1694 }
1695 break;
1696 case 0x0000:
1697 if ((opcode2 & 0x01de0) == 0x0000)
1698 {
1699 ps(info, "pload");
1700 sputc(opcode2 & 0x200 ? 'r' : 'w');
1701 startoperands(info);
1702 switch (opcode2 & 0x18)
1703 {
1704 case 0x10:
1705 case 0x18:
1706 sputc('#');
1707 p2hex(info, opcode2 & 0x0f);
1708 break;
1709 case 0x08:
1710 od(info, opcode2 & 0x07);
1711 break;
1712 case 0x00:
1713 ps(info, opcode2 & 1 ? "dfc" : "sfc");
1714 break;
1715 }
1716 pcomma(info);
1717 doea(info, opcode, 0);
1718 info->num_oper = 2;
1719 } else
1720 {
1721 info->memory_vma -= 2;
1722 odcw(info, opcode);
1723 }
1724 break;
1725 case 0x0800:
1726 ps(info, "pvalid");
1727 startoperands(info);
1728 doea(info, opcode, 1);
1729 info->num_oper = 1;
1730 break;
1731 default:
1732 info->memory_vma -= 2;
1733 odcw(info, opcode);
1734 break;
1735 }
1736 break;
1737 case 0xa000:
1738 ps(info, "pflushr");
1739 startoperands(info);
1740 doea(info, opcode, 0);
1741 info->num_oper = 1;
1742 break;
1743 case 0x8000:
1744 ps(info, "ptest");
1745 sputc(opcode2 & 0x0200 ? 'r' : 'w');
1746 startoperands(info);
1747 info->num_oper = 3;
1748 switch ((opcode2 >> 3) & 0x03)
1749 {
1750 case 0x00:
1751 if ((opcode2 & 7) == 0)
1752 ps(info, "sfc");
1753 else
1754 ps(info, "dfc");
1755 break;
1756 case 0x01:
1757 od(info, opcode2 & 0x07);
1758 break;
1759 case 0x02:
1760 sputc('#');
1761 p2hex(info, opcode2 & 0x07);
1762 break;
1763 case 0x03:
1764 sputc('#');
1765 p2hex(info, opcode2 & 0x0f);
1766 break;
1767 }
1768 pcomma(info);
1769 doea(info, opcode, 1);
1770 pcomma(info);
1771 pudec(info, (opcode2 >> 10) & 0x07);
1772 if (opcode2 & 0x100)
1773 {
1774 pcomma(info);
1775 info->num_oper++;
1776 oa(info, (opcode2 >> 5) & 7);
1777 }
1778 break;
1779 default:
1780 info->memory_vma -= 2;
1781 odcw(info, opcode);
1782 break;
1783 }
1784 break;
1785 case 1:
1786 if (srcmod(opcode) == 1)
1787 {
1788 opcode2 = GETUW(info->memory_vma);
1789 info->memory_vma += 2;
1790 info->reloffset += 2;
1791 ps(info, "pdb");
1792 /*
1793 * The manual states:
1794 * "The value of the program counter used in the branch address
1795 * calculation is the address of the PDBcc instruction plus two."
1796 * I think this is wrong, for other co-pros its the address of the
1797 * displacement word.
1798 */
1799 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
1800 info->memory_vma += 2;
1801 ps(info, pmmucondtable[opcode2 & 0x3f]);
1802 startoperands(info);
1803 od(info, opcode & 0x07);
1804 pcomma(info);
1805 p8hex(info, adr);
1806 info->num_oper = 2;
1807 } else if (srcmod(opcode) == 7 && srcreg(opcode) > 1)
1808 {
1809 opcode2 = GETUW(info->memory_vma);
1810 info->memory_vma += 2;
1811 info->reloffset += 2;
1812 ps(info, "ptrap");
1813 ps(info, pmmucondtable[opcode2 & 0x3f]);
1814 switch (srcreg(opcode))
1815 {
1816 case 2:
1817 startoperands(info);
1818 oi(info, 1, true);
1819 info->num_oper = 1;
1820 break;
1821 case 3:
1822 startoperands(info);
1823 oi(info, 2, true);
1824 info->num_oper = 1;
1825 break;
1826 }
1827 } else
1828 {
1829 opcode2 = GETUW(info->memory_vma);
1830 info->memory_vma += 2;
1831 info->reloffset += 2;
1832 ps(info, "ps");
1833 ps(info, pmmucondtable[opcode2 & 0x3f]);
1834 startoperands(info);
1835 doea(info, opcode, 1);
1836 info->num_oper = 1;
1837 }
1838 break;
1839 case 2:
1840 case 3:
1841 if (opcode & 0x40)
1842 {
1843 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETL(info->memory_vma) + info->reloffset;
1844 info->memory_vma += 4;
1845 ps(info, "pb");
1846 ps(info, pmmucondtable[opcode & 0x3f]);
1847 ps(info, ".l");
1848 } else
1849 {
1850 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
1851 info->memory_vma += 2;
1852 ps(info, "pb");
1853 ps(info, pmmucondtable[opcode & 0x3f]);
1854 ps(info, ".w");
1855 }
1856 startoperands(info);
1857 p8hex(info, adr);
1858 info->num_oper = 1;
1859 break;
1860 case 4:
1861 switch (srcmod(opcode))
1862 {
1863 case 0:
1864 ps(info, "pflushn");
1865 startoperands(info);
1866 oai(info, srcreg(opcode));
1867 info->num_oper = 1;
1868 break;
1869 case 1:
1870 ps(info, "pflush");
1871 startoperands(info);
1872 oai(info, srcreg(opcode));
1873 info->num_oper = 1;
1874 break;
1875 case 2:
1876 ps(info, "pflushan"); /* conflicts with psave (ax) */
1877 info->num_oper = 0;
1878 break;
1879 case 3:
1880 ps(info, "pflusha");
1881 info->num_oper = 0;
1882 break;
1883 default:
1884 ps(info, "psave");
1885 startoperands(info);
1886 doea(info, opcode, 1);
1887 info->num_oper = 1;
1888 break;
1889 }
1890 break;
1891 case 5:
1892 ps(info, "prestore");
1893 startoperands(info);
1894 doea(info, opcode, 1);
1895 info->num_oper = 1;
1896 break;
1897 default:
1898 odcw(info, opcode);
1899 break;
1900 }
1901 }
1902
1903 /*** ---------------------------------------------------------------------- ***/
1904
group_pmmu_040(m68k_disasm_info * info,int opcode)1905 static void group_pmmu_040(m68k_disasm_info *info, int opcode)
1906 {
1907 static const char *const caches[4] = { "nc", "dc", "ic", "bc" };
1908
1909 if (opcode & 0x0100)
1910 {
1911 if ((opcode & 0xd8) == 0x48)
1912 {
1913 ps(info, "ptest");
1914 sputc(opcode & 0x20 ? 'r' : 'w');
1915 startoperands(info);
1916 oai(info, srcreg(opcode));
1917 info->num_oper = 1;
1918 } else if ((opcode & 0xc0) == 0)
1919 {
1920 switch (srcmod(opcode))
1921 {
1922 case 0x00:
1923 ps(info, "pflushn");
1924 startoperands(info);
1925 oai(info, srcreg(opcode));
1926 info->num_oper = 1;
1927 break;
1928 case 0x01:
1929 ps(info, "pflush");
1930 startoperands(info);
1931 oai(info, srcreg(opcode));
1932 info->num_oper = 1;
1933 break;
1934 case 0x02:
1935 ps(info, "pflushan");
1936 info->num_oper = 0;
1937 break;
1938 case 0x03:
1939 ps(info, "pflusha");
1940 info->num_oper = 0;
1941 break;
1942 default:
1943 odcw(info, opcode);
1944 break;
1945 }
1946 } else
1947 {
1948 odcw(info, opcode);
1949 }
1950 } else
1951 {
1952 switch (srcmod(opcode))
1953 {
1954 case 0x0001:
1955 ps(info, "cinvl");
1956 startoperands(info);
1957 ps(info, caches[(opcode >> 6) & 3]);
1958 pcomma(info);
1959 oai(info, srcreg(opcode));
1960 info->num_oper = 2;
1961 break;
1962 case 0x0002:
1963 ps(info, "cinvp");
1964 startoperands(info);
1965 ps(info, caches[(opcode >> 6) & 3]);
1966 pcomma(info);
1967 oai(info, srcreg(opcode));
1968 info->num_oper = 2;
1969 break;
1970 case 0x0003:
1971 ps(info, "cinva");
1972 startoperands(info);
1973 ps(info, caches[(opcode >> 6) & 3]);
1974 info->num_oper = 1;
1975 break;
1976 case 0x0005:
1977 if (((opcode >> 6) & 3) == 0)
1978 {
1979 ps(info, "intouch");
1980 startoperands(info);
1981 info->num_oper = 1;
1982 } else
1983 {
1984 ps(info, "cpushl");
1985 startoperands(info);
1986 ps(info, caches[(opcode >> 6) & 3]);
1987 pcomma(info);
1988 info->num_oper = 2;
1989 }
1990 oai(info, srcreg(opcode));
1991 break;
1992 case 0x0006:
1993 ps(info, "cpushp");
1994 startoperands(info);
1995 ps(info, caches[(opcode >> 6) & 3]);
1996 pcomma(info);
1997 oai(info, srcreg(opcode));
1998 info->num_oper = 2;
1999 break;
2000 case 0x0007:
2001 ps(info, "cpusha");
2002 startoperands(info);
2003 ps(info, caches[(opcode >> 6) & 3]);
2004 info->num_oper = 1;
2005 break;
2006 default:
2007 odcw(info, opcode);
2008 break;
2009 }
2010 }
2011 }
2012
2013 /******************************************************************************/
2014 /*** ---------------------------------------------------------------------- ***/
2015 /******************************************************************************/
2016
pfreg(m68k_disasm_info * info,int reg)2017 static void pfreg(m68k_disasm_info *info, int reg)
2018 {
2019 ps(info, fpregs[reg]);
2020 }
2021
2022 /*** ---------------------------------------------------------------------- ***/
2023
print_fpsize(m68k_disasm_info * info,int mask)2024 static enum fpu_size print_fpsize(m68k_disasm_info *info, int mask)
2025 {
2026 enum fpu_size sz;
2027
2028 switch (mask)
2029 {
2030 default:
2031 case 0:
2032 sputc('l');
2033 sz = FPU_SIZE_LONG;
2034 break;
2035 case 1:
2036 sputc('s');
2037 sz = FPU_SIZE_SINGLE;
2038 break;
2039 case 2:
2040 sputc('x');
2041 sz = FPU_SIZE_EXTENDED;
2042 break;
2043 case 3:
2044 sputc('p');
2045 sz = FPU_SIZE_PACKED;
2046 break;
2047 case 4:
2048 sputc('w');
2049 sz = FPU_SIZE_WORD;
2050 break;
2051 case 5:
2052 sputc('d');
2053 sz = FPU_SIZE_DOUBLE;
2054 break;
2055 case 6:
2056 sputc('b');
2057 sz = FPU_SIZE_BYTE;
2058 break;
2059 case 7:
2060 sputc('p');
2061 sz = FPU_SIZE_PACKED_VARIABLE;
2062 break;
2063 }
2064 return sz;
2065 }
2066
2067 /*** ---------------------------------------------------------------------- ***/
2068
print_freglist(m68k_disasm_info * info,int regmask,int mode,bool cntl)2069 static void print_freglist(m68k_disasm_info *info, int regmask, int mode, bool cntl)
2070 {
2071 const char *const * regs;
2072 register int regnum;
2073 int liststart;
2074 int lastreg;
2075 int status;
2076 int upper;
2077
2078 regs = cntl ? fpcregs : fpregs;
2079 upper = cntl ? 3 : 8;
2080 if (!cntl && mode != 4)
2081 {
2082 regmask = revbits(regmask, upper);
2083 }
2084 liststart = status = 0;
2085 lastreg = 20;
2086 for (regnum = 0; regnum < upper; regnum++)
2087 {
2088 if ((1 << regnum) & regmask)
2089 {
2090 if (regnum == (lastreg + 1) && regnum != 8)
2091 {
2092 if (liststart != 0)
2093 sputc('-');
2094 liststart = 0;
2095 status = 1;
2096 lastreg = regnum;
2097 } else
2098 {
2099 if (status != 0)
2100 {
2101 ps(info, regs[lastreg]);
2102 status = 0;
2103 liststart = 1;
2104 }
2105 if (liststart != 0)
2106 sputc('/');
2107 ps(info, regs[regnum]);
2108 lastreg = regnum;
2109 liststart = 1;
2110 }
2111 }
2112 }
2113 if (status != 0)
2114 ps(info, regs[lastreg]);
2115 }
2116
2117 /*** ---------------------------------------------------------------------- ***/
2118
fpu_stdgen(m68k_disasm_info * info,unsigned int opcode,unsigned int opcode2,const char * name)2119 static void fpu_stdgen(m68k_disasm_info *info, unsigned int opcode, unsigned int opcode2, const char *name)
2120 {
2121 enum fpu_size sz;
2122
2123 ps(info, name);
2124
2125 info->num_oper = 1;
2126 sputc('.');
2127 if ((opcode2 & 0x4000) != 0)
2128 {
2129 sz = print_fpsize(info, (opcode2 >> 10) & 0x07);
2130 startoperands(info);
2131 doea(info, opcode, sz);
2132 if (((opcode2 >> 3) & 0x0f) == 6) /* fsincos */
2133 {
2134 pcomma(info);
2135 pfreg(info, (opcode2 >> 0) & 0x07);
2136 sputc(':');
2137 pfreg(info, (opcode2 >> 7) & 0x07);
2138 info->num_oper = 2;
2139 } else if ((opcode2 & 0x3f) != 0x3a) /* ftst */
2140 {
2141 pcomma(info);
2142 pfreg(info, (opcode2 >> 7) & 0x07);
2143 info->num_oper = 2;
2144 }
2145 } else
2146 {
2147 sputc('x');
2148 startoperands(info);
2149 pfreg(info, (opcode2 >> 10) & 0x07);
2150 if (((opcode2 >> 3) & 0x0f) == 6) /* fsincos */
2151 {
2152 pcomma(info);
2153 pfreg(info, (opcode2 >> 0) & 0x07);
2154 sputc(':');
2155 pfreg(info, (opcode2 >> 7) & 0x07);
2156 info->num_oper = 2;
2157 } else if ((opcode2 & 0x3f) != 0x3a) /* ftst */
2158 {
2159 pcomma(info);
2160 pfreg(info, (opcode2 >> 7) & 0x07);
2161 info->num_oper = 2;
2162 }
2163 }
2164 }
2165
2166 /*** ---------------------------------------------------------------------- ***/
2167
group_fpu(m68k_disasm_info * info,int opcode)2168 static void group_fpu(m68k_disasm_info *info, int opcode)
2169 {
2170 unsigned int opcode2;
2171 uae_s32 adr;
2172 enum fpu_size sz;
2173
2174 switch ((opcode >> 6) & 0x07)
2175 {
2176 case 0:
2177 opcode2 = GETUW(info->memory_vma);
2178 info->memory_vma += 2;
2179 info->reloffset += 2;
2180 switch ((opcode2 >> 13) & 0x07)
2181 {
2182 case 0:
2183 case 2:
2184 if ((opcode & 0x01ff) == 0x0000 && (opcode2 & 0xfc00) == 0x5c00)
2185 {
2186 ps(info, "fmovecr.x");
2187 startoperands(info);
2188 sputc('#');
2189 p2hex(info, opcode2 & 0x7f);
2190 pcomma(info);
2191 pfreg(info, (opcode2 >> 7) & 7);
2192 info->num_oper = 2;
2193 switch (opcode2 & 0x7f)
2194 {
2195 case 0x00: strcpy(info->comments, "pi"); break;
2196 case 0x0b: strcpy(info->comments, "log10(2)"); break;
2197 case 0x0c: strcpy(info->comments, "e"); break;
2198 case 0x0d: strcpy(info->comments, "log2(e)"); break;
2199 case 0x0e: strcpy(info->comments, "log10(e)"); break;
2200 case 0x0f: strcpy(info->comments, "0.0"); break;
2201 case 0x30: strcpy(info->comments, "ln(2)"); break;
2202 case 0x31: strcpy(info->comments, "ln(10)"); break;
2203 case 0x32: strcpy(info->comments, "10e0"); break;
2204 case 0x33: strcpy(info->comments, "10e1"); break;
2205 case 0x34: strcpy(info->comments, "10e2"); break;
2206 case 0x35: strcpy(info->comments, "10e4"); break;
2207 case 0x36: strcpy(info->comments, "10e8"); break;
2208 case 0x37: strcpy(info->comments, "10e16"); break;
2209 case 0x38: strcpy(info->comments, "10e32"); break;
2210 case 0x39: strcpy(info->comments, "10e64"); break;
2211 case 0x3a: strcpy(info->comments, "10e128"); break;
2212 case 0x3b: strcpy(info->comments, "10e256"); break;
2213 case 0x3c: strcpy(info->comments, "10e512"); break;
2214 case 0x3d: strcpy(info->comments, "10e1024"); break;
2215 case 0x3e: strcpy(info->comments, "10e2048"); break;
2216 case 0x3f: strcpy(info->comments, "10e4096"); break;
2217 }
2218 } else
2219 {
2220 switch (opcode2 & 0x7f)
2221 {
2222 case 0x00:
2223 fpu_stdgen(info, opcode, opcode2, "fmove");
2224 break;
2225 case 0x40:
2226 fpu_stdgen(info, opcode, opcode2, "fsmove");
2227 break;
2228 case 0x44:
2229 fpu_stdgen(info, opcode, opcode2, "fdmove");
2230 break;
2231 case 0x01:
2232 fpu_stdgen(info, opcode, opcode2, "fint");
2233 break;
2234 case 0x02:
2235 fpu_stdgen(info, opcode, opcode2, "fsinh");
2236 break;
2237 case 0x03:
2238 fpu_stdgen(info, opcode, opcode2, "fintrz");
2239 break;
2240 case 0x04:
2241 fpu_stdgen(info, opcode, opcode2, "fsqrt");
2242 break;
2243 case 0x45:
2244 fpu_stdgen(info, opcode, opcode2, "fdsqrt");
2245 break;
2246 case 0x41:
2247 fpu_stdgen(info, opcode, opcode2, "fssqrt");
2248 break;
2249 /* 0x05: illegal */
2250 case 0x06:
2251 fpu_stdgen(info, opcode, opcode2, "flognp1");
2252 break;
2253 case 0x46:
2254 fpu_stdgen(info, opcode, opcode2, "fdlognp1");
2255 break;
2256 /* 0x07: illegal */
2257 case 0x08:
2258 fpu_stdgen(info, opcode, opcode2, "fetoxm1");
2259 break;
2260 case 0x09:
2261 fpu_stdgen(info, opcode, opcode2, "ftanh");
2262 break;
2263 case 0x0a:
2264 fpu_stdgen(info, opcode, opcode2, "fatan");
2265 break;
2266 /* 0x0b: illegal */
2267 case 0x0c:
2268 fpu_stdgen(info, opcode, opcode2, "fasin");
2269 break;
2270 case 0x0d:
2271 fpu_stdgen(info, opcode, opcode2, "fatanh");
2272 break;
2273 case 0x0e:
2274 fpu_stdgen(info, opcode, opcode2, "fsin");
2275 break;
2276 case 0x0f:
2277 fpu_stdgen(info, opcode, opcode2, "ftan");
2278 break;
2279 case 0x10:
2280 fpu_stdgen(info, opcode, opcode2, "fetox");
2281 break;
2282 case 0x11:
2283 fpu_stdgen(info, opcode, opcode2, "ftwotox");
2284 break;
2285 case 0x12:
2286 fpu_stdgen(info, opcode, opcode2, "ftentox");
2287 break;
2288 /* 0x13: illegal */
2289 case 0x14:
2290 fpu_stdgen(info, opcode, opcode2, "flogn");
2291 break;
2292 case 0x15:
2293 fpu_stdgen(info, opcode, opcode2, "flog10");
2294 break;
2295 case 0x16:
2296 fpu_stdgen(info, opcode, opcode2, "flog2");
2297 break;
2298 /* 0x17: illegal */
2299 case 0x18:
2300 fpu_stdgen(info, opcode, opcode2, "fabs");
2301 break;
2302 case 0x58:
2303 fpu_stdgen(info, opcode, opcode2, "fsabs");
2304 break;
2305 case 0x5c:
2306 fpu_stdgen(info, opcode, opcode2, "fdabs");
2307 break;
2308 case 0x19:
2309 fpu_stdgen(info, opcode, opcode2, "fcosh");
2310 break;
2311 case 0x1a:
2312 fpu_stdgen(info, opcode, opcode2, "fneg");
2313 break;
2314 case 0x5a:
2315 fpu_stdgen(info, opcode, opcode2, "fsneg");
2316 break;
2317 case 0x5e:
2318 fpu_stdgen(info, opcode, opcode2, "fdneg");
2319 break;
2320 /* 0x1b: illegal */
2321 case 0x1c:
2322 fpu_stdgen(info, opcode, opcode2, "facos");
2323 break;
2324 case 0x1d:
2325 fpu_stdgen(info, opcode, opcode2, "fcos");
2326 break;
2327 case 0x1e:
2328 fpu_stdgen(info, opcode, opcode2, "fgetexp");
2329 break;
2330 case 0x1f:
2331 fpu_stdgen(info, opcode, opcode2, "fgetman");
2332 break;
2333 case 0x20:
2334 fpu_stdgen(info, opcode, opcode2, "fdiv");
2335 break;
2336 case 0x60:
2337 fpu_stdgen(info, opcode, opcode2, "fsdiv");
2338 break;
2339 case 0x64:
2340 fpu_stdgen(info, opcode, opcode2, "fddiv");
2341 break;
2342 case 0x21:
2343 fpu_stdgen(info, opcode, opcode2, "fmod");
2344 break;
2345 case 0x22:
2346 fpu_stdgen(info, opcode, opcode2, "fadd");
2347 break;
2348 case 0x62:
2349 fpu_stdgen(info, opcode, opcode2, "fsadd");
2350 break;
2351 case 0x66:
2352 fpu_stdgen(info, opcode, opcode2, "fdadd");
2353 break;
2354 case 0x23:
2355 fpu_stdgen(info, opcode, opcode2, "fmul");
2356 break;
2357 case 0x63:
2358 fpu_stdgen(info, opcode, opcode2, "fsmul");
2359 break;
2360 case 0x67:
2361 fpu_stdgen(info, opcode, opcode2, "fdmul");
2362 break;
2363 case 0x24:
2364 fpu_stdgen(info, opcode, opcode2, "fsgldiv");
2365 break;
2366 case 0x25:
2367 fpu_stdgen(info, opcode, opcode2, "frem");
2368 break;
2369 case 0x26:
2370 fpu_stdgen(info, opcode, opcode2, "fscale");
2371 break;
2372 case 0x27:
2373 fpu_stdgen(info, opcode, opcode2, "fsglmul");
2374 break;
2375 case 0x28:
2376 fpu_stdgen(info, opcode, opcode2, "fsub");
2377 break;
2378 case 0x68:
2379 fpu_stdgen(info, opcode, opcode2, "fssub");
2380 break;
2381 case 0x6c:
2382 fpu_stdgen(info, opcode, opcode2, "fdsub");
2383 break;
2384 /* 0x29: illegal */
2385 /* 0x2a: illegal */
2386 /* 0x2b: illegal */
2387 /* 0x2c: illegal */
2388 /* 0x2d: illegal */
2389 /* 0x2d: illegal */
2390 /* 0x2e: illegal */
2391 /* 0x2f: illegal */
2392 case 0x30:
2393 case 0x31:
2394 case 0x32:
2395 case 0x33:
2396 case 0x34:
2397 case 0x35:
2398 case 0x36:
2399 case 0x37:
2400 fpu_stdgen(info, opcode, opcode2, "fsincos");
2401 break;
2402 case 0x38:
2403 fpu_stdgen(info, opcode, opcode2, "fcmp");
2404 break;
2405 /* 0x39: illegal */
2406 case 0x3a:
2407 fpu_stdgen(info, opcode, opcode2, "ftst");
2408 break;
2409 /* 0x3b: illegal */
2410 /* 0x3c: illegal */
2411 /* 0x3d: illegal */
2412 /* 0x3e: illegal */
2413 /* 0x3f: illegal */
2414 default:
2415 odcw(info, opcode);
2416 pcomma(info);
2417 p4hex(info, opcode2);
2418 info->num_oper = 2;
2419 break;
2420 }
2421 }
2422 break;
2423 case 3:
2424 info->num_oper = 2;
2425 /* fmove r ==> m */
2426 ps(info, "fmove.");
2427 sz = print_fpsize(info, (opcode2 >> 10) & 0x07);
2428 startoperands(info);
2429 pfreg(info, (opcode2 >> 7) & 0x07);
2430 pcomma(info);
2431 doea(info, opcode, sz);
2432 if (sz == FPU_SIZE_PACKED_VARIABLE)
2433 {
2434 sputc('{');
2435 if ((opcode2 & 0x1000) != 0)
2436 {
2437 od(info, (opcode2 >> 4) & 0x7);
2438 } else
2439 {
2440 sputc('#');
2441 pudec(info, (opcode2 >> 4) & 0x07);
2442 }
2443 sputc('}');
2444 }
2445 break;
2446 case 4:
2447 case 5:
2448 info->num_oper = 2;
2449 switch ((opcode2 >> 10) & 0x07)
2450 {
2451 case 0x01:
2452 case 0x02:
2453 case 0x04:
2454 ps(info, "fmove.l");
2455 break;
2456 default:
2457 ps(info, "fmovem.l");
2458 break;
2459 }
2460 /* fmove[m] control reg */
2461 startoperands(info);
2462
2463 if ((opcode2 & 0x2000) != 0)
2464 {
2465 print_freglist(info, (opcode2 >> 10) & 0x07, 4, true);
2466 pcomma(info);
2467 }
2468 doea(info, opcode, FPU_SIZE_LONG);
2469 if ((opcode2 & 0x2000) == 0)
2470 {
2471 pcomma(info);
2472 print_freglist(info, (opcode2 >> 10) & 0x07, 4, true);
2473 }
2474 info->num_oper = 2;
2475 break;
2476 case 6:
2477 case 7:
2478 info->num_oper = 2;
2479 ps(info, "fmovem.x");
2480 startoperands(info);
2481
2482 if ((opcode2 & 0x0800) != 0)
2483 {
2484 if ((opcode2 & 0x2000) != 0)
2485 {
2486 od(info, (opcode2 >> 4) & 0x07);
2487 pcomma(info);
2488 }
2489 doea(info, opcode, FPU_SIZE_EXTENDED);
2490 if ((opcode2 & 0x2000) == 0)
2491 {
2492 pcomma(info);
2493 od(info, (opcode2 >> 4) & 0x07);
2494 }
2495 } else
2496 {
2497 if ((opcode2 & 0x2000) != 0)
2498 {
2499 print_freglist(info, opcode2 & 0xff, srcmod(opcode), false);
2500 pcomma(info);
2501 }
2502 doea(info, opcode, FPU_SIZE_EXTENDED);
2503 if ((opcode2 & 0x2000) == 0)
2504 {
2505 pcomma(info);
2506 print_freglist(info, opcode2 & 0xff, srcmod(opcode), false);
2507 }
2508 }
2509 break;
2510 }
2511 break;
2512 case 1:
2513 if (srcmod(opcode) == 1)
2514 {
2515 opcode2 = GETUW(info->memory_vma);
2516 info->memory_vma += 2;
2517 info->reloffset += 2;
2518 ps(info, "fdb");
2519 /*
2520 * The value of the program counter used in the branch
2521 * address calculation is the address of the displacement word.
2522 */
2523 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
2524 info->memory_vma += 2;
2525 ps(info, fpucondtable[opcode2 & 0x3f]);
2526 startoperands(info);
2527 od(info, opcode & 0x07);
2528 pcomma(info);
2529 p8hex(info, adr);
2530 info->num_oper = 2;
2531 } else if (srcmod(opcode) == 7 && srcreg(opcode) > 1)
2532 {
2533 opcode2 = GETUW(info->memory_vma);
2534 info->memory_vma += 2;
2535 info->reloffset += 2;
2536 ps(info, "ftrap");
2537 ps(info, fpucondtable[opcode2 & 0x3f]);
2538 switch (srcreg(opcode))
2539 {
2540 case 2:
2541 startoperands(info);
2542 oi(info, 1, true);
2543 info->num_oper = 1;
2544 break;
2545 case 3:
2546 startoperands(info);
2547 oi(info, 2, true);
2548 info->num_oper = 1;
2549 break;
2550 }
2551 } else
2552 {
2553 opcode2 = GETUW(info->memory_vma);
2554 info->memory_vma += 2;
2555 info->reloffset += 2;
2556 ps(info, "fs");
2557 ps(info, fpucondtable[opcode2 & 0x3f]);
2558 startoperands(info);
2559 doea(info, opcode, 1);
2560 info->num_oper = 1;
2561 }
2562 break;
2563 case 2:
2564 case 3:
2565 opcode2 = GETUW(info->memory_vma);
2566 if (((opcode >> 6) & 0x07) == 2 && (opcode & 0x3f) == 0 && opcode2 == 0)
2567 {
2568 ps(info, "fnop");
2569 return;
2570 }
2571 if (opcode & 0x40)
2572 {
2573 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETL(info->memory_vma) + info->reloffset;
2574 info->memory_vma += 4;
2575 ps(info, "fb");
2576 ps(info, fpucondtable[opcode & 0x3f]);
2577 ps(info, ".l");
2578 } else
2579 {
2580 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
2581 info->memory_vma += 2;
2582 ps(info, "fb");
2583 ps(info, fpucondtable[opcode & 0x3f]);
2584 ps(info, ".w");
2585 }
2586 startoperands(info);
2587 p8hex(info, adr);
2588 info->num_oper = 1;
2589 break;
2590 case 4:
2591 ps(info, "fsave");
2592 startoperands(info);
2593 doea(info, opcode, 0);
2594 info->num_oper = 1;
2595 break;
2596 case 5:
2597 ps(info, "frestore");
2598 startoperands(info);
2599 doea(info, opcode, 0);
2600 info->num_oper = 1;
2601 break;
2602 default:
2603 odcw(info, opcode);
2604 break;
2605 }
2606 }
2607
2608 /*** ---------------------------------------------------------------------- ***/
2609
coprocessor_general(m68k_disasm_info * info,int opcode,const char * prefix)2610 static void coprocessor_general(m68k_disasm_info *info, int opcode, const char *prefix)
2611 {
2612 int adr;
2613 unsigned int opcode2;
2614
2615 switch ((opcode >> 6) & 0x07)
2616 {
2617 case 0:
2618 opcode2 = GETUW(info->memory_vma);
2619 info->memory_vma += 2;
2620 info->reloffset += 2;
2621 ps(info, prefix);
2622 ps(info, "GEN");
2623 startoperands(info);
2624 oi(info, 1, true);
2625 pcomma(info);
2626 doea(info, opcode, 1);
2627 info->num_oper = 2;
2628 break;
2629 case 1:
2630 if (srcmod(opcode) == 1)
2631 {
2632 opcode2 = GETUW(info->memory_vma);
2633 info->memory_vma += 2;
2634 info->reloffset += 2;
2635 ps(info, prefix);
2636 ps(info, "DB");
2637 /*
2638 * The value of the scan PC is the address of the displacement word.
2639 */
2640 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
2641 info->memory_vma += 2;
2642 ps(info, cpcondtable[opcode2 & 0x3f]);
2643 startoperands(info);
2644 od(info, opcode & 0x07);
2645 pcomma(info);
2646 p8hex(info, adr);
2647 info->num_oper = 2;
2648 } else if (srcmod(opcode) == 7 && srcreg(opcode) > 1)
2649 {
2650 opcode2 = GETUW(info->memory_vma);
2651 info->memory_vma += 2;
2652 info->reloffset += 2;
2653 ps(info, prefix);
2654 ps(info, "TRAP");
2655 ps(info, cpcondtable[opcode2 & 0x3f]);
2656 switch (srcreg(opcode))
2657 {
2658 case 2:
2659 startoperands(info);
2660 oi(info, 1, true);
2661 info->num_oper = 1;
2662 break;
2663 case 3:
2664 startoperands(info);
2665 oi(info, 2, true);
2666 info->num_oper = 1;
2667 break;
2668 }
2669 } else
2670 {
2671 opcode2 = GETUW(info->memory_vma);
2672 info->memory_vma += 2;
2673 info->reloffset += 2;
2674 ps(info, prefix);
2675 ps(info, "S");
2676 ps(info, cpcondtable[opcode2 & 0x3f]);
2677 startoperands(info);
2678 doea(info, opcode, 1);
2679 info->num_oper = 1;
2680 }
2681 break;
2682 case 2:
2683 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETW(info->memory_vma) + info->reloffset;
2684 info->memory_vma += 2;
2685 ps(info, prefix);
2686 ps(info, "B");
2687 ps(info, cpcondtable[opcode & 0x3f]);
2688 ps(info, ".w");
2689 startoperands(info);
2690 p8hex(info, adr);
2691 info->num_oper = 1;
2692 break;
2693 case 3:
2694 adr = ((struct priv_data *)(info->disasm_data))->oldaddr + GETL(info->memory_vma) + info->reloffset;
2695 info->memory_vma += 4;
2696 ps(info, prefix);
2697 ps(info, "B");
2698 ps(info, cpcondtable[opcode & 0x3f]);
2699 ps(info, ".l");
2700 startoperands(info);
2701 p8hex(info, adr);
2702 info->num_oper = 1;
2703 break;
2704 case 4:
2705 case 5:
2706 case 6:
2707 if (((opcode >> 9) & 0x07) == 5)
2708 {
2709 ps(info, "wddata");
2710 os(info, opcode);
2711 doea(info, opcode, insize(opcode));
2712 info->num_oper = 1;
2713 } else
2714 {
2715 odcw(info, opcode);
2716 }
2717 break;
2718 case 7:
2719 if (((opcode >> 9) & 0x07) == 5)
2720 {
2721 opcode2 = GETUW(info->memory_vma);
2722 info->memory_vma += 2;
2723 ps(info, "wdebug");
2724 startoperands(info);
2725 doea(info, opcode, 2);
2726 info->num_oper = 1;
2727 } else
2728 {
2729 odcw(info, opcode);
2730 }
2731 break;
2732 default:
2733 odcw(info, opcode);
2734 break;
2735 }
2736 }
2737
2738 /*** ---------------------------------------------------------------------- ***/
2739
group15(m68k_disasm_info * info,int opcode)2740 static void group15(m68k_disasm_info *info, int opcode)
2741 {
2742 int opcode2;
2743
2744 switch ((opcode >> 9) & 0x07)
2745 {
2746 case 0:
2747 /* ID 0: m68851 or 68030 onchip pmmu */
2748 if (info->cpu == CPU_68020 && info->mmu != MMU_NONE)
2749 {
2750 if ((opcode & 0x01c0) != 0)
2751 coprocessor_general(info, opcode, "p");
2752 else
2753 group_pmmu_030(info, opcode);
2754 } else
2755 {
2756 group_pmmu_030(info, opcode);
2757 }
2758 break;
2759 case 1:
2760 /* ID 1: m68881/2 fpu */
2761 group_fpu(info, opcode);
2762 break;
2763 case 2:
2764 /* ID 2: 68040/60 on chip pmmu */
2765 group_pmmu_040(info, opcode);
2766 break;
2767 case 3:
2768 /* ID 3: move16 */
2769 odcw(info, opcode);
2770 break;
2771 case 4:
2772 /* ID 4: */
2773 if ((opcode & 0x01c0) == 0 && (opcode & 0x003f) == 0 && GETUW(info->memory_vma) == 0x01c0)
2774 {
2775 ps(info, "lpstop");
2776 info->memory_vma += 2;
2777 info->reloffset += 2;
2778 startoperands(info);
2779 oi(info, 1, true);
2780 info->num_oper = 1;
2781 } else if ((opcode & 0x01c0) == 0 && (GETUW(info->memory_vma) & 0x8338) == 0x0100)
2782 {
2783 opcode2 = GETUW(info->memory_vma);
2784 info->memory_vma += 2;
2785 info->reloffset += 2;
2786 ps(info, "tbl");
2787 sputc(opcode2 & 0x0800 ? 's' : 'u');
2788 if (opcode2 & 0x400)
2789 sputc('n');
2790 os(info, opcode2);
2791 if (srcmod(opcode) == 0)
2792 {
2793 od(info, srcreg(opcode));
2794 sputc(':');
2795 od(info, srcreg(opcode2));
2796 } else
2797 {
2798 doea(info, opcode, insize(opcode2));
2799 }
2800 pcomma(info);
2801 od(info, (opcode2 >> 12) & 7);
2802 info->num_oper = 2;
2803 } else
2804 {
2805 coprocessor_general(info, opcode, "lp");
2806 }
2807 break;
2808 case 5:
2809 /* ID 5: ColdFire FPU */
2810 coprocessor_general(info, opcode, "cp5");
2811 break;
2812 case 6:
2813 /* ID 6: */
2814 coprocessor_general(info, opcode, "cp6");
2815 break;
2816 case 7:
2817 /* ID 7: */
2818 coprocessor_general(info, opcode, "nf");
2819 break;
2820 }
2821 }
2822
2823 /******************************************************************************/
2824 /*** ---------------------------------------------------------------------- ***/
2825 /******************************************************************************/
2826
pspreg(m68k_disasm_info * info,int mask)2827 static void pspreg(m68k_disasm_info *info, int mask)
2828 {
2829 const char *reg = "???";
2830
2831 switch (mask & 0xfff)
2832 {
2833 case 0x000:
2834 reg = "sfc";
2835 break;
2836 case 0x001:
2837 reg = "dfc";
2838 break;
2839 case 0x002:
2840 /* if (info->cpu >= CPU_68020 && info->cpu != CPU_CPU32) */
2841 reg = "cacr";
2842 break;
2843 case 0x003:
2844 /* if (info->mmu == MMU_68851 || info->cpu == CPU_68030 || info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2845 reg = "tc";
2846 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2847 reg = "asid";
2848 break;
2849 case 0x004:
2850 /* if (info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2851 reg = "itt0";
2852 if (info->cpu == CPU_68EC040)
2853 reg = "iacr0";
2854 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2855 reg = "acr0";
2856 break;
2857 case 0x005:
2858 /* if (info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2859 reg = "itt1";
2860 if (info->cpu == CPU_68EC040)
2861 reg = "iacr1";
2862 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2863 reg = "acr1";
2864 break;
2865 case 0x006:
2866 /* if (info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2867 reg = "dtt0";
2868 if (info->cpu == CPU_68EC040)
2869 reg = "dacr0";
2870 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2871 reg = "acr2";
2872 break;
2873 case 0x007:
2874 /* if (info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2875 reg = "dtt1";
2876 if (info->cpu == CPU_68EC040)
2877 reg = "dacr1";
2878 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2879 reg = "acr3";
2880 break;
2881 case 0x008:
2882 /* if (info->cpu == CPU_68060) */
2883 reg = "buscr";
2884 if (info->cpu >= CPU_CF_FIRST && info->cpu <= CPU_CF_LAST)
2885 reg = "mmubar";
2886 break;
2887 case 0x009:
2888 reg = "rgpiobar";
2889 break;
2890 case 0x00c:
2891 reg = "acr4";
2892 break;
2893 case 0x00d:
2894 reg = "acr5";
2895 break;
2896 case 0x00e:
2897 reg = "acr6";
2898 break;
2899 case 0x00f:
2900 reg = "acr7";
2901 break;
2902 case 0x800:
2903 reg = "usp";
2904 break;
2905 case 0x801:
2906 reg = "vbr";
2907 break;
2908 case 0x802:
2909 /* if (info->cpu == CPU_68020 || info->cpu == CPU_68030 || info->cpu == CPU_68EC030) */
2910 reg = "caar";
2911 break;
2912 case 0x803:
2913 reg = "msp";
2914 break;
2915 case 0x804:
2916 reg = "isp";
2917 break;
2918 case 0x805:
2919 /* if (info->mmu == MMU_68851 || info->cpu == CPU_68030 || info->cpu == CPU_68040 || info->cpu == CPU_68LC040) */
2920 reg = "psr"; /* sometimes named mmusr */
2921 break;
2922 case 0x806:
2923 /* if (info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2924 reg = "urp";
2925 break;
2926 case 0x807:
2927 /* if (info->mmu == MMU_68851 || info->cpu == CPU_68030 || info->cpu == CPU_68040 || info->cpu == CPU_68LC040 || info->cpu == CPU_68060) */
2928 reg = "srp";
2929 break;
2930 case 0x808:
2931 /* if (info->cpu == CPU_68060) */
2932 reg = "pcr";
2933 break;
2934 case 0x80e:
2935 reg = "sr";
2936 break;
2937 case 0x80f:
2938 reg = "pc";
2939 break;
2940 case 0xc00:
2941 reg = "rombar0";
2942 break;
2943 case 0xc01:
2944 reg = "rombar1";
2945 break;
2946 case 0xc04:
2947 reg = "rambar0";
2948 break;
2949 case 0xc05:
2950 reg = "rambar1";
2951 break;
2952 case 0xc0c:
2953 reg = "mpcr";
2954 break;
2955 case 0xc0d:
2956 reg = "edrambar";
2957 break;
2958 case 0xc0e:
2959 reg = "secmbar"; /* sometimes called mbar0 or mbar2 */
2960 break;
2961 case 0xc0f:
2962 reg = "mbar"; /* sometimes called mbar1 */
2963 break;
2964 case 0xd02:
2965 reg = "pcr1u0";
2966 break;
2967 case 0xd03:
2968 reg = "pcr1l0";
2969 break;
2970 case 0xd04:
2971 reg = "pcr2u0";
2972 break;
2973 case 0xd05:
2974 reg = "pcr2l0";
2975 break;
2976 case 0xd06:
2977 reg = "pcr3u0";
2978 break;
2979 case 0xd07:
2980 reg = "pcr3l0";
2981 break;
2982 case 0xd0a:
2983 reg = "pcr1u1";
2984 break;
2985 case 0xd0b:
2986 reg = "pcr1l1";
2987 break;
2988 case 0xd0c:
2989 reg = "pcr2u1";
2990 break;
2991 case 0xd0d:
2992 reg = "pcr2l1";
2993 break;
2994 case 0xd0e:
2995 reg = "pcr3u1";
2996 break;
2997 case 0xd0f:
2998 reg = "pcr3l1";
2999 break;
3000 case 0xffe:
3001 reg = "cac";
3002 break;
3003 case 0xfff:
3004 reg = "mbo";
3005 break;
3006 }
3007 ps(info, reg);
3008 }
3009
3010 /*** ---------------------------------------------------------------------- ***/
3011
group4(m68k_disasm_info * info,int opcode)3012 static void group4(m68k_disasm_info *info, int opcode)
3013 {
3014 register int mask;
3015 register int size;
3016
3017 if (opcode & 0x0100)
3018 {
3019 /* 0100 000 1 ss 000000 */
3020 switch (insize(opcode))
3021 {
3022 case 1:
3023 case 3:
3024 if ((opcode & 0xfff8) == 0x49c0)
3025 {
3026 ps(info, "extb.l");
3027 startoperands(info);
3028 od(info, srcreg(opcode));
3029 info->num_oper = 1;
3030 only_68020();
3031 } else
3032 {
3033 ps(info, "lea.l");
3034 startoperands(info);
3035 doea(info, opcode, 2);
3036 pcomma(info);
3037 oa(info, dstreg(opcode));
3038 info->num_oper = 2;
3039 }
3040 break;
3041 case 2:
3042 ps(info, "chk.w");
3043 startoperands(info);
3044 doea(info, opcode, 1);
3045 pcomma(info);
3046 oddstreg(info, opcode);
3047 info->num_oper = 2;
3048 break;
3049 case 0:
3050 ps(info, "chk.l");
3051 startoperands(info);
3052 doea(info, opcode, 1);
3053 pcomma(info);
3054 oddstreg(info, opcode);
3055 info->num_oper = 2;
3056 only_68020();
3057 break;
3058 default:
3059 odcw(info, opcode);
3060 break;
3061 }
3062 } else
3063 {
3064 switch (dstreg(opcode))
3065 {
3066 case 0: /* move from sr, negx */
3067 if ((size = insize(opcode)) == 3)
3068 {
3069 /* 0100 000 011 xxxxxx */
3070 ps(info, "move.w");
3071 startoperands(info);
3072 ps(info, "sr");
3073 pcomma(info);
3074 doea(info, opcode, 1);
3075 info->num_oper = 2;
3076 } else
3077 {
3078 ps(info, "negx");
3079 os(info, opcode);
3080 doea(info, opcode, size);
3081 info->num_oper = 1;
3082 }
3083 break;
3084 case 1: /* clr */
3085 if (insize(opcode) == 3)
3086 {
3087 /* 0100 001 011 xxxxxx */
3088 /* move.w from ccr, illegal for CPU_68000 */
3089 ps(info, "move.w");
3090 startoperands(info);
3091 ps(info, "ccr");
3092 pcomma(info);
3093 doea(info, opcode, 1);
3094 info->num_oper = 2;
3095 } else
3096 {
3097 ps(info, "clr");
3098 size = os(info, opcode);
3099 doea(info, opcode, size);
3100 info->num_oper = 1;
3101 }
3102 break;
3103 case 2: /* move to ccr, neg */
3104 if ((size = insize(opcode)) == 3)
3105 {
3106 /* 0100 010 011 xxxxxx */
3107 ps(info, "move.b");
3108 startoperands(info);
3109 doea(info, opcode, 1);
3110 pcomma(info);
3111 ps(info, "ccr");
3112 info->num_oper = 2;
3113 } else
3114 {
3115 ps(info, "neg");
3116 os(info, opcode);
3117 doea(info, opcode, size);
3118 info->num_oper = 1;
3119 }
3120 break;
3121 case 3: /* move to sr, not */
3122 if ((size = insize(opcode)) == 3)
3123 {
3124 ps(info, "move.w");
3125 startoperands(info);
3126 doea(info, opcode, 1);
3127 pcomma(info);
3128 ps(info, "sr");
3129 info->num_oper = 2;
3130 } else
3131 {
3132 ps(info, "not");
3133 os(info, opcode);
3134 doea(info, opcode, size);
3135 info->num_oper = 1;
3136 }
3137 break;
3138 case 4: /* ext, movem to ram, nbcd, pea, swap */
3139 switch (insize(opcode))
3140 {
3141 case 0:
3142 /* 0100 100 000 yyyyyy */
3143 if (srcmod(opcode) == 1)
3144 {
3145 ps(info, "link.l");
3146 startoperands(info);
3147 doea(info, opcode, 2);
3148 pcomma(info);
3149 oi(info, 2, true);
3150 info->num_oper = 2;
3151 only_68020();
3152 } else
3153 {
3154 ps(info, "nbcd");
3155 startoperands(info);
3156 doea(info, opcode, 0);
3157 info->num_oper = 1;
3158 }
3159 break;
3160 case 1:
3161 /* 0100 100 001 yyyyyy */
3162 if (srcmod(opcode) != 0)
3163 {
3164 if (srcmod(opcode) == 1)
3165 {
3166 ps(info, "bkpt");
3167 startoperands(info);
3168 sputc('#');
3169 psdec(info, opcode & 7);
3170 } else
3171 {
3172 ps(info, "pea.l");
3173 startoperands(info);
3174 doea(info, opcode, 2);
3175 }
3176 } else
3177 {
3178 ps(info, "swap");
3179 startoperands(info);
3180 od(info, srcreg(opcode));
3181 }
3182 info->num_oper = 1;
3183 break;
3184 case 2:
3185 case 3:
3186 /* 0100 100 010 yyyyyy */
3187 /* 0100 100 011 yyyyyy */
3188 if (srcmod(opcode) == 0)
3189 {
3190 ps(info, "ext");
3191 osa(info, opcode, 0x0040);
3192 od(info, srcreg(opcode));
3193 info->num_oper = 1;
3194 } else
3195 {
3196 ps(info, "movem");
3197 size = osa(info, opcode, 0x0040);
3198 mask = GETW(info->memory_vma);
3199 info->memory_vma += 2;
3200 if (srcmod(opcode) == 4)
3201 {
3202 reglist(info, revbits(mask, 16));
3203 } else
3204 {
3205 reglist(info, mask);
3206 }
3207 pcomma(info);
3208 doea(info, opcode, size);
3209 info->num_oper = 2;
3210 }
3211 break;
3212 }
3213 break;
3214 case 5: /* illegal, tas, tst */
3215 if ((size = insize(opcode)) == 3)
3216 {
3217 if (srcmod(opcode) == 7 && srcreg(opcode) > 1)
3218 {
3219 info->num_oper = 0;
3220 switch (srcreg(opcode))
3221 {
3222 case 2:
3223 ps(info, "bgnd");
3224 only_if(info, "cpu32 & fidoa");
3225 break;
3226 case 5:
3227 ps(info, "swbeg.l");
3228 only_if(info, "sysV68");
3229 startoperands(info);
3230 oi(info, 2, true);
3231 info->num_oper = 1;
3232 break;
3233 case 4:
3234 ps(info, "illegal");
3235 break;
3236 default:
3237 odcw(info, opcode);
3238 break;
3239 }
3240 } else if (srcmod(opcode) == 1)
3241 {
3242 info->num_oper = 0;
3243 switch (srcreg(opcode))
3244 {
3245 case 0:
3246 ps(info, "halt");
3247 only_if(info, "68060 & ColdFire");
3248 break;
3249 case 4:
3250 ps(info, "pulse");
3251 only_if(info, "68060 & ColdFire");
3252 break;
3253 default:
3254 odcw(info, opcode);
3255 break;
3256 }
3257 } else
3258 {
3259 ps(info, "tas.b");
3260 startoperands(info);
3261 doea(info, opcode, 1);
3262 info->num_oper = 1;
3263 }
3264 } else
3265 {
3266 ps(info, "tst");
3267 os(info, opcode);
3268 doea(info, opcode, size);
3269 info->num_oper = 1;
3270 }
3271 break;
3272 case 6:
3273 if (opcode & 0x0080)
3274 {
3275 switch (srcmod(opcode))
3276 {
3277 case 2:
3278 case 3:
3279 case 5:
3280 case 6:
3281 case 7:
3282 /* movem from ram */
3283 if (srcmod(opcode) != 7 || srcreg(opcode) <= 1)
3284 {
3285 ps(info, "movem");
3286 size = osa(info, opcode, 0x0040);
3287 mask = GETW(info->memory_vma);
3288 info->memory_vma += 2;
3289 doea(info, opcode, size);
3290 pcomma(info);
3291 reglist(info, mask);
3292 info->num_oper = 2;
3293 } else
3294 {
3295 odcw(info, opcode);
3296 }
3297 break;
3298 case 0:
3299 ps(info, "sats.l");
3300 startoperands(info);
3301 od(info, srcreg(opcode));
3302 break;
3303 default:
3304 odcw(info, opcode);
3305 break;
3306 }
3307 } else
3308 {
3309 uae_u16 opcode2;
3310 uae_u16 dr, dq;
3311
3312 only_68020();
3313 opcode2 = GETUW(info->memory_vma);
3314 info->memory_vma += 2;
3315 dr = srcreg(opcode2);
3316 dq = (opcode2 >> 12) & 0x07;
3317 ps(info, opcode & 0x0040 ? "div" : "mul");
3318 sputc(opcode2 & 0x0800 ? 's' : 'u');
3319 if (opcode & 0x0040)
3320 {
3321 if (opcode2 & 0x0400)
3322 {
3323 /* div 64/32 -> dr/dq */
3324 info->num_oper = 3;
3325 ps(info, ".l");
3326 startoperands(info);
3327 doea(info, opcode, 2);
3328 pcomma(info);
3329 od(info, dr);
3330 pcomma(info);
3331 od(info, dq);
3332 } else
3333 {
3334 /* 32/32 -> dr/dq */
3335 info->num_oper = 3;
3336 ps(info, "l.l");
3337 startoperands(info);
3338 doea(info, opcode, 2);
3339 pcomma(info);
3340 od(info, dr);
3341 pcomma(info);
3342 od(info, dq);
3343 if (dr != dq)
3344 {
3345 if (opcode2 & 0x0800)
3346 strcpy(info->comments, "rems.l for ColdFire");
3347 else
3348 strcpy(info->comments, "remu.l for ColdFire");
3349 }
3350 }
3351 } else
3352 {
3353 if (opcode2 & 0x0400)
3354 {
3355 /* mul 32*32 -> dh-dl */
3356 info->num_oper = 3;
3357 ps(info, ".l");
3358 startoperands(info);
3359 doea(info, opcode, 2);
3360 pcomma(info);
3361 od(info, dr);
3362 pcomma(info);
3363 od(info, dq);
3364 } else
3365 {
3366 /* 32*32 -> dl */
3367 info->num_oper = 2;
3368 ps(info, ".l");
3369 startoperands(info);
3370 doea(info, opcode, 2);
3371 pcomma(info);
3372 od(info, dq);
3373 }
3374 }
3375 }
3376 break;
3377 case 7: /* jmp, jsr, link, move usp, nop, reset, rte, rtr, rts, stop, trap, trapv, unlk */
3378 switch (dstmod(opcode))
3379 {
3380 case 1:
3381 switch (srcmod(opcode))
3382 {
3383 case 0:
3384 case 1:
3385 /* 0100 111 001 00 xxxx */
3386 ps(info, "trap");
3387 startoperands(info);
3388 sputc('#');
3389 psdec(info, opcode & 0x000f);
3390 info->num_oper = 1;
3391 break;
3392 case 2:
3393 /* 0100 111 001 010 xxx */
3394 ps(info, "link");
3395 startoperands(info);
3396 oa(info, srcreg(opcode));
3397 pcomma(info);
3398 oi(info, 1, true);
3399 info->num_oper = 2;
3400 break;
3401 case 3:
3402 /* 0100 111 001 011 xxx */
3403 ps(info, "unlk");
3404 startoperands(info);
3405 oa(info, srcreg(opcode));
3406 info->num_oper = 1;
3407 break;
3408 case 4:
3409 /* 0100 111 001 100 xxx */
3410 ps(info, "move.l");
3411 startoperands(info);
3412 oa(info, srcreg(opcode));
3413 pcomma(info);
3414 ps(info, "usp");
3415 info->num_oper = 2;
3416 break;
3417 case 5:
3418 /* 0100 111 001 101 xxx */
3419 ps(info, "move.l");
3420 startoperands(info);
3421 ps(info, "usp");
3422 pcomma(info);
3423 oa(info, srcreg(opcode));
3424 info->num_oper = 2;
3425 break;
3426 case 6:
3427 /* 0100 111 001 110 xxx */
3428 switch (srcreg(opcode))
3429 {
3430 case 0:
3431 ps(info, "reset");
3432 info->num_oper = 0;
3433 break;
3434 case 1:
3435 ps(info, "nop");
3436 info->num_oper = 0;
3437 break;
3438 case 2:
3439 ps(info, "stop");
3440 startoperands(info);
3441 sputc('#');
3442 psdec(info, GETW(info->memory_vma));
3443 info->memory_vma += 2;
3444 info->num_oper = 1;
3445 break;
3446 case 3:
3447 ps(info, "rte");
3448 info->num_oper = 0;
3449 break;
3450 case 4:
3451 ps(info, "rtd");
3452 startoperands(info);
3453 sputc('#');
3454 psdec(info, GETW(info->memory_vma));
3455 info->memory_vma += 2;
3456 info->num_oper = 1;
3457 break;
3458 case 5:
3459 ps(info, "rts");
3460 info->num_oper = 0;
3461 break;
3462 case 6:
3463 ps(info, "trapv");
3464 info->num_oper = 0;
3465 break;
3466 case 7:
3467 ps(info, "rtr");
3468 info->num_oper = 0;
3469 break;
3470 }
3471 break;
3472 case 7:
3473 /* 0100 111 001 111 xxx */
3474 switch (srcreg(opcode))
3475 {
3476 default:
3477 odcw(info, opcode);
3478 break;
3479 case 2:
3480 if (info->cpu >= CPU_68010)
3481 {
3482 ps(info, "movec");
3483 startoperands(info);
3484 mask = GETUW(info->memory_vma);
3485 info->memory_vma += 2;
3486 pspreg(info, mask);
3487 pcomma(info);
3488 oad(info, (mask >> 12) & 0x0f);
3489 info->num_oper = 2;
3490 only_68020();
3491 } else
3492 {
3493 odcw(info, opcode);
3494 }
3495 break;
3496 case 3:
3497 if (info->cpu >= CPU_68010)
3498 {
3499 ps(info, "movec");
3500 startoperands(info);
3501 mask = GETUW(info->memory_vma);
3502 info->memory_vma += 2;
3503 oad(info, (mask >> 12) & 0x0f);
3504 pcomma(info);
3505 pspreg(info, mask);
3506 info->num_oper = 2;
3507 } else
3508 {
3509 odcw(info, opcode);
3510 }
3511 break;
3512 }
3513 break;
3514 }
3515 break;
3516 case 2:
3517 ps(info, "jsr");
3518 startoperands(info);
3519 doea(info, opcode, 0);
3520 info->num_oper = 1;
3521 break;
3522 case 3:
3523 ps(info, "jmp");
3524 startoperands(info);
3525 doea(info, opcode, 0);
3526 info->num_oper = 1;
3527 break;
3528 default:
3529 odcw(info, opcode);
3530 break;
3531 }
3532 break;
3533 }
3534 }
3535 }
3536
3537 /******************************************************************************/
3538 /*** ---------------------------------------------------------------------- ***/
3539 /******************************************************************************/
3540
group5(m68k_disasm_info * info,int opcode)3541 static void group5(m68k_disasm_info *info, int opcode)
3542 {
3543 register uae_s32 adr;
3544
3545 if (insize(opcode) == 3)
3546 {
3547 if ((opcode & 0x3f) == 0x3a ||
3548 (opcode & 0x3f) == 0x3b ||
3549 (opcode & 0x3f) == 0x3c)
3550 {
3551 ps(info, "trap");
3552 pcond(info, (opcode >> 8) & 0x000f);
3553 if (srcreg(opcode) == 2)
3554 {
3555 ps(info, ".w");
3556 startoperands(info);
3557 oi(info, 1, true);
3558 info->num_oper = 1;
3559 } else if (srcreg(opcode) == 3)
3560 {
3561 ps(info, ".l");
3562 startoperands(info);
3563 oi(info, 2, true);
3564 info->num_oper = 2;
3565 } else
3566 {
3567 info->num_oper = 0;
3568 }
3569 } else
3570 {
3571 ps(info, srcmod(opcode) == 1 ? "db" : "s");
3572 pcond(info, (opcode >> 8) & 0x000f);
3573 startoperands(info);
3574 if (srcmod(opcode) != 1)
3575 {
3576 doea(info, opcode, 0);
3577 info->num_oper = 1;
3578 } else
3579 {
3580 od(info, srcreg(opcode));
3581 pcomma(info);
3582 adr = GETW(info->memory_vma) + ((struct priv_data *)(info->disasm_data))->oldaddr + info->reloffset;
3583 info->memory_vma += 2;
3584 p8hex(info, adr);
3585 info->num_oper = 2;
3586 }
3587 }
3588 } else
3589 {
3590 ps(info, opcode & 0x0100 ? "subq" : "addq");
3591 os(info, opcode);
3592 sputc('#');
3593 psdec(info, dstreg(opcode) != 0 ? dstreg(opcode) : 8);
3594 pcomma(info);
3595 doea(info, opcode, 0);
3596 info->num_oper = 2;
3597 }
3598 }
3599
3600 /******************************************************************************/
3601 /*** ---------------------------------------------------------------------- ***/
3602 /******************************************************************************/
3603
group6(m68k_disasm_info * info,int opcode)3604 static void group6(m68k_disasm_info *info, int opcode)
3605 {
3606 register uae_s32 adr;
3607 register int cond;
3608 register signed char dist;
3609
3610 /* 0110 cccc dddddddd */
3611 switch (cond = (opcode >> 8) & 0x000f)
3612 {
3613 case 1:
3614 ps(info, "bsr");
3615 break;
3616 case 0:
3617 ps(info, "bra");
3618 break;
3619 default:
3620 sputc('b');
3621 pcond(info, cond);
3622 break;
3623 }
3624 if ((dist = (signed char) opcode) != 0)
3625 {
3626 if (dist == -1)
3627 {
3628 ps(info, ".l");
3629 startoperands(info);
3630 adr = GETL(info->memory_vma) + ((struct priv_data *)(info->disasm_data))->oldaddr + info->reloffset;
3631 info->memory_vma += 4;
3632 p8hex(info, adr);
3633 only_68020();
3634 } else
3635 {
3636 ps(info, ".s");
3637 startoperands(info);
3638 adr = dist + ((struct priv_data *)(info->disasm_data))->oldaddr + info->reloffset;
3639 p8hex(info, adr);
3640 }
3641 } else
3642 {
3643 startoperands(info);
3644 adr = GETW(info->memory_vma) + ((struct priv_data *)(info->disasm_data))->oldaddr + info->reloffset;
3645 info->memory_vma += 2;
3646 p8hex(info, adr);
3647 }
3648 info->num_oper = 1;
3649 }
3650
3651 /******************************************************************************/
3652 /*** ---------------------------------------------------------------------- ***/
3653 /******************************************************************************/
3654
group7(m68k_disasm_info * info,int opcode)3655 static void group7(m68k_disasm_info *info, int opcode)
3656 {
3657 int size;
3658
3659 if (opcode & 0x0100)
3660 {
3661 /* ColdFire only */
3662 only_if(info, "ColdFire");
3663 ps(info, opcode & 0x0080 ? "mvz" : "mvs");
3664 size = opcode & 0x0040 ? 1 : 0;
3665 sputc('.');
3666 sputc(size == 0 ? 'b' : 'w');
3667 startoperands(info);
3668 doea(info, opcode, size);
3669 pcomma(info);
3670 oddstreg(info, opcode);
3671 } else
3672 {
3673 ps(info, "moveq.l");
3674 startoperands(info);
3675 sputc('#');
3676 psdec(info, (int) ((char) (opcode & 0xff)));
3677 pcomma(info);
3678 oddstreg(info, opcode);
3679 info->num_oper = 2;
3680 }
3681 }
3682
3683 /******************************************************************************/
3684 /*** ---------------------------------------------------------------------- ***/
3685 /******************************************************************************/
3686
g812(m68k_disasm_info * info,int opcode,const char * andor,const char * muldiv,const char * as)3687 static void g812(m68k_disasm_info *info, int opcode, const char *andor, const char *muldiv, const char *as)
3688 {
3689 register int size;
3690
3691 info->num_oper = 2;
3692 if (dstmod(opcode) == 3)
3693 {
3694 ps(info, muldiv);
3695 ps(info, "u.w");
3696 startoperands(info);
3697 doea(info, opcode, 1);
3698 pcomma(info);
3699 oddstreg(info, opcode);
3700 } else if (dstmod(opcode) == 7)
3701 {
3702 ps(info, muldiv);
3703 ps(info, "s.w");
3704 startoperands(info);
3705 doea(info, opcode, 1);
3706 pcomma(info);
3707 oddstreg(info, opcode);
3708 } else if (dstmod(opcode) == 4 && ((opcode >> 4) & 3) == 0)
3709 {
3710 ps(info, as);
3711 ps(info, "bcd.b");
3712 startoperands(info);
3713 if (srcmod(opcode) != 0)
3714 {
3715 sputc('-');
3716 oai(info, srcreg(opcode));
3717 pcomma(info);
3718 sputc('-');
3719 oai(info, dstreg(opcode));
3720 } else
3721 {
3722 od(info, srcreg(opcode));
3723 pcomma(info);
3724 oddstreg(info, opcode);
3725 }
3726 } else if ((opcode & 0x01f0) == 0x140 || (opcode & 0x01f0) == 0x180)
3727 {
3728 ps(info, opcode & 0x08 ? "unpk" : "pack");
3729 startoperands(info);
3730 if (opcode & 0x08)
3731 {
3732 od(info, srcreg(opcode));
3733 pcomma(info);
3734 od(info, dstreg(opcode));
3735 } else
3736 {
3737 sputc('-');
3738 oa(info, srcreg(opcode));
3739 pcomma(info);
3740 sputc('-');
3741 oa(info, dstreg(opcode));
3742 }
3743 pcomma(info);
3744 oi(info, 1, true);
3745 info->num_oper = 3;
3746 } else
3747 {
3748 ps(info, andor);
3749 size = os(info, opcode);
3750 if (opcode & 0x0100)
3751 {
3752 oddstreg(info, opcode);
3753 pcomma(info);
3754 doea(info, opcode, size);
3755 } else
3756 {
3757 doea(info, opcode, size);
3758 pcomma(info);
3759 oddstreg(info, opcode);
3760 }
3761 }
3762 }
3763
3764 /*** ---------------------------------------------------------------------- ***/
3765
group8(m68k_disasm_info * info,int opcode)3766 static void group8(m68k_disasm_info *info, int opcode)
3767 {
3768 g812(info, opcode, "or", "div", "s");
3769 }
3770
3771 /*** ---------------------------------------------------------------------- ***/
3772
group12(m68k_disasm_info * info,int opcode)3773 static void group12(m68k_disasm_info *info, int opcode)
3774 {
3775 register int d5;
3776
3777 if ((d5 = (opcode >> 3) & 0x003f) == 0x0028)
3778 {
3779 ps(info, "exg");
3780 startoperands(info);
3781 oddstreg(info, opcode);
3782 pcomma(info);
3783 od(info, srcreg(opcode));
3784 info->num_oper = 2;
3785 } else if (d5 == 0x0029)
3786 {
3787 ps(info, "exg");
3788 startoperands(info);
3789 oa(info, dstreg(opcode));
3790 pcomma(info);
3791 oa(info, srcreg(opcode));
3792 info->num_oper = 2;
3793 } else if (d5 == 0x0031)
3794 {
3795 ps(info, "exg");
3796 startoperands(info);
3797 oddstreg(info, opcode);
3798 pcomma(info);
3799 oa(info, srcreg(opcode));
3800 info->num_oper = 2;
3801 } else if (d5 == 0x0030)
3802 {
3803 odcw(info, opcode);
3804 } else
3805 {
3806 g812(info, opcode, "and", "mul", "a");
3807 }
3808 }
3809
3810 /******************************************************************************/
3811 /*** ---------------------------------------------------------------------- ***/
3812 /******************************************************************************/
3813
g913(m68k_disasm_info * info,int opcode,const char * addsub)3814 static void g913(m68k_disasm_info *info, int opcode, const char *addsub)
3815 {
3816 register int size;
3817
3818 ps(info, addsub);
3819 if ((opcode & 0x0100) != 0 && insize(opcode) != 3 && ((opcode >> 4) & 3) == 0)
3820 {
3821 /*
3822 * 1x01rrr1sseeeeee
3823 * ss != 3
3824 *
3825 * addx/subx ea
3826 */
3827 sputc('x');
3828 os(info, opcode);
3829 if (opcode & 0x0008)
3830 {
3831 sputc('-');
3832 oai(info, srcreg(opcode));
3833 pcomma(info);
3834 sputc('-');
3835 oai(info, dstreg(opcode));
3836 } else
3837 {
3838 od(info, srcreg(opcode));
3839 pcomma(info);
3840 oddstreg(info, opcode);
3841 }
3842 } else
3843 {
3844 switch (dstmod(opcode))
3845 {
3846 case 3:
3847 case 7:
3848 sputc('a');
3849 size = osa(info, opcode, 0x0100);
3850 doea(info, opcode, size);
3851 pcomma(info);
3852 oa(info, dstreg(opcode));
3853 break;
3854 default:
3855 size = os(info, opcode);
3856 if (opcode & 0x0100)
3857 {
3858 oddstreg(info, opcode);
3859 pcomma(info);
3860 doea(info, opcode, size);
3861 } else
3862 {
3863 doea(info, opcode, size);
3864 pcomma(info);
3865 oddstreg(info, opcode);
3866 }
3867 break;
3868 }
3869 }
3870 info->num_oper = 2;
3871 }
3872
3873 /*** ---------------------------------------------------------------------- ***/
3874
group9(m68k_disasm_info * info,int opcode)3875 static void group9(m68k_disasm_info *info, int opcode)
3876 {
3877 g913(info, opcode, "sub");
3878 }
3879
3880 /*** ---------------------------------------------------------------------- ***/
3881
group13(m68k_disasm_info * info,int opcode)3882 static void group13(m68k_disasm_info *info, int opcode)
3883 {
3884 g913(info, opcode, "add");
3885 }
3886
3887
3888 /******************************************************************************/
3889 /*** ---------------------------------------------------------------------- ***/
3890 /******************************************************************************/
3891
pacc(m68k_disasm_info * info,int acc)3892 static void pacc(m68k_disasm_info *info, int acc)
3893 {
3894 ps(info, "acc");
3895 sputc('0' + acc);
3896 }
3897
3898
group10(m68k_disasm_info * info,int iw)3899 static void group10(m68k_disasm_info *info, int iw)
3900 {
3901 int x;
3902
3903 switch ((iw >> 6) & 0x0007)
3904 {
3905 case 0x00:
3906 case 0x01:
3907 case 0x02:
3908 case 0x03:
3909 {
3910 uae_u16 opcode2 = GETUW(info->memory_vma);
3911 unsigned int acc = ((iw >> 7) & 1) | ((opcode2 >> 3) & 0x02);
3912 unsigned int rx, rxa, ry, rya, rw, rwa;
3913 uae_u16 mode;
3914
3915 info->memory_vma += 2;
3916 info->num_oper = 4;
3917 mode = (iw >> 3) & 7;
3918 rx = ry = rw = -1;
3919 rxa = rya = rwa = 0;
3920 switch (mode)
3921 {
3922 case 0:
3923 case 1:
3924 rx = (iw >> 9) & 7;
3925 rxa = (iw >> 6) & 1;
3926 ry = (iw & 7);
3927 rya = (iw >> 3) & 1;
3928 break;
3929 case 2:
3930 case 3:
3931 case 4:
3932 case 5:
3933 rw = (iw >> 9) & 7;
3934 rwa = (iw >> 6) & 1;
3935 rx = (opcode2 >> 12) & 7;
3936 rxa = (opcode2 >> 15) & 1;
3937 ry = (opcode2 & 7);
3938 rya = (opcode2 >> 3) & 1;
3939 acc ^= 1; /* WTF */
3940 break;
3941 }
3942 if ((mode == 0 || mode == 1) && (opcode2 & 0x03) == 0x01)
3943 ps(info, opcode2 & 0x0100 ? "msaac" : "maaac");
3944 else if ((mode == 0 || mode == 1) && (opcode2 & 0x03) == 0x03)
3945 ps(info, opcode2 & 0x0100 ? "mssac" : "masac");
3946 else
3947 ps(info, opcode2 & 0x0100 ? "msac" : "mac");
3948 sputc('.');
3949 sputc(opcode2 & 0x0800 ? 'l' : 'w');
3950 startoperands(info);
3951 if (rya)
3952 oa(info, ry);
3953 else
3954 od(info, ry);
3955 if ((opcode2 & 0x0800) == 0)
3956 {
3957 sputc('.');
3958 sputc(opcode2 & 0x0040 ? 'u' : 'l');
3959 }
3960 pcomma(info);
3961 if (rxa)
3962 oa(info, rx);
3963 else
3964 od(info, rx);
3965 if ((opcode2 & 0x0800) == 0)
3966 {
3967 sputc('.');
3968 sputc(opcode2 & 0x0080 ? 'u' : 'l');
3969 }
3970 pcomma(info);
3971 switch ((opcode2 >> 9) & 3)
3972 {
3973 case 0x00: ps(info, "0"); break;
3974 case 0x01: ps(info, "<<1"); break;
3975 case 0x02: ps(info, "??"); break;
3976 case 0x03: ps(info, ">>1"); break;
3977 }
3978 switch (mode)
3979 {
3980 case 2:
3981 case 3:
3982 case 4:
3983 case 5:
3984 pcomma(info);
3985 doea(info, iw, 0);
3986 if (opcode2 & 0x0020)
3987 sputc('&');
3988 pcomma(info);
3989 if (rwa)
3990 oa(info, rw);
3991 else
3992 od(info, rw);
3993 info->num_oper += 2;
3994 break;
3995 }
3996 pcomma(info);
3997 pacc(info, acc);
3998 if ((mode == 0 || mode == 1) && ((opcode2 & 0x03) == 0x01 || (opcode2 & 0x03) == 0x03))
3999 {
4000 pcomma(info);
4001 pacc(info, ((opcode2 >> 2) & 3));
4002 info->num_oper += 1;
4003 }
4004 }
4005 break;
4006 case 0x04:
4007 if ((iw & 0x0800) == 0)
4008 {
4009 ps(info, "move.l");
4010 startoperands(info);
4011 pacc(info, ((iw >> 9) & 3));
4012 pcomma(info);
4013 pacc(info, ((iw) & 3));
4014 info->num_oper = 2;
4015 } else
4016 {
4017 ps(info, "move.l");
4018 startoperands(info);
4019 doea(info, iw, 2);
4020 pcomma(info);
4021 info->num_oper = 2;
4022 switch ((iw >> 9) & 3)
4023 {
4024 case 0x00:
4025 ps(info, "macsr");
4026 break;
4027 case 0x01:
4028 ps(info, "accext01");
4029 break;
4030 case 0x02:
4031 ps(info, "mask");
4032 break;
4033 case 0x03:
4034 ps(info, "accext23");
4035 break;
4036 }
4037 }
4038 break;
4039 case 0x05:
4040 ps(info, "mov3q.l");
4041 startoperands(info);
4042 x = dstreg(iw);
4043 sputc('#');
4044 psdec(info, x == 0 ? -1 : x);
4045 pcomma(info);
4046 doea(info, iw, 0);
4047 info->num_oper = 2;
4048 break;
4049 case 0x06:
4050 if ((iw & 0x0800) == 0)
4051 {
4052 ps(info, "move.l");
4053 startoperands(info);
4054 pacc(info, ((iw >> 9) & 3));
4055 pcomma(info);
4056 oad(info, iw & 0x0f);
4057 info->num_oper = 2;
4058 } else
4059 {
4060 ps(info, "move.l");
4061 startoperands(info);
4062 switch ((iw >> 9) & 3)
4063 {
4064 case 0x00:
4065 ps(info, "macsr");
4066 break;
4067 case 0x01:
4068 ps(info, "accext01");
4069 break;
4070 case 0x02:
4071 ps(info, "mask");
4072 break;
4073 case 0x03:
4074 ps(info, "accext23");
4075 break;
4076 }
4077 pcomma(info);
4078 oad(info, iw & 0x0f);
4079 info->num_oper = 2;
4080 }
4081 break;
4082 case 0x07:
4083 if ((iw & 0x0800) == 0)
4084 {
4085 ps(info, "movclr.l");
4086 startoperands(info);
4087 pacc(info, ((iw >> 9) & 3));
4088 pcomma(info);
4089 oad(info, iw & 0x0f);
4090 info->num_oper = 2;
4091 } else
4092 {
4093 switch ((iw >> 9) & 3)
4094 {
4095 case 0x00:
4096 ps(info, "move.l");
4097 startoperands(info);
4098 ps(info, "macsr,ccr");
4099 info->num_oper = 2;
4100 break;
4101 default:
4102 odcw(info, iw);
4103 break;
4104 }
4105 }
4106 break;
4107 default:
4108 odcw(info, iw);
4109 break;
4110 }
4111 }
4112
4113 /******************************************************************************/
4114 /*** ---------------------------------------------------------------------- ***/
4115 /******************************************************************************/
4116
4117 static void (*const grphdlrs[])(m68k_disasm_info *, int) = {
4118 group0, group1, group1, group1,
4119 group4, group5, group6, group7,
4120 group8, group9, group10, group11,
4121 group12, group13, group14, group15
4122 };
4123
4124 /*** ---------------------------------------------------------------------- ***/
4125
m68k_disasm_builtin(m68k_disasm_info * info)4126 int m68k_disasm_builtin(m68k_disasm_info *info)
4127 {
4128 register int opcode;
4129 register void (*hdlr)(m68k_disasm_info *info, int opcode);
4130 unsigned int insn_size;
4131 struct priv_data *priv;
4132
4133 if (info->disasm_data == NULL)
4134 {
4135 priv = (struct priv_data *)malloc(sizeof(*priv));
4136 info->disasm_data = priv;
4137 }
4138 priv = (struct priv_data *)info->disasm_data;
4139 priv->oldaddr = info->memory_vma;
4140 priv->lp = info->opcode;
4141 opcode = GETUW(info->memory_vma);
4142 info->memory_vma += 2;
4143 info->reloffset = 2;
4144 hdlr = grphdlrs[(opcode >> 12) & 15];
4145 (*hdlr)(info, opcode);
4146 sputc('\0');
4147 insn_size = (unsigned int)(info->memory_vma - priv->oldaddr);
4148 info->memory_vma = priv->oldaddr;
4149 return insn_size;
4150 }
4151
4152 #else
4153
4154 extern int i_dont_care_that_ISOC_doesnt_like_empty_sourcefiles;
4155
4156 #endif /* DISASM_USE_BUILTIN */
4157