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