1 /*
2  * UAE - The Un*x Amiga Emulator - CPU core
3  *
4  * Read 68000 CPU specs from file "table68k"
5  *
6  * Copyright 1995,1996 Bernd Schmidt
7  *
8  * Adaptation to Hatari by Thomas Huth
9  * Adaptation to Virtual Jaguar by James Hammons
10  *
11  * This file is distributed under the GNU Public License, version 3 or at
12  * your option any later version. Read the file GPLv3 for details.
13  */
14 
15 
16 /* 2008/04/26	[NP]	Handle sz_byte for Areg as a valid srcmode if current instruction is a MOVE	*/
17 /*			(e.g. move.b a1,(a0) ($1089)) (fix Blood Money on Superior 65)			*/
18 
19 
20 //const char ReadCpu_fileid[] = "Hatari readcpu.c : " __DATE__ " " __TIME__;
21 
22 #include <ctype.h>
23 #include <string.h>
24 
25 #include "readcpu.h"
26 
27 int nr_cpuop_funcs;
28 
29 const struct mnemolookup lookuptab[] = {
30 	{ i_ILLG, "ILLEGAL" },
31 	{ i_OR, "OR" },
32 	{ i_CHK, "CHK" },
33 	{ i_CHK2, "CHK2" },
34 	{ i_AND, "AND" },
35 	{ i_EOR, "EOR" },
36 	{ i_ORSR, "ORSR" },
37 	{ i_ANDSR, "ANDSR" },
38 	{ i_EORSR, "EORSR" },
39 	{ i_SUB, "SUB" },
40 	{ i_SUBA, "SUBA" },
41 	{ i_SUBX, "SUBX" },
42 	{ i_SBCD, "SBCD" },
43 	{ i_ADD, "ADD" },
44 	{ i_ADDA, "ADDA" },
45 	{ i_ADDX, "ADDX" },
46 	{ i_ABCD, "ABCD" },
47 	{ i_NEG, "NEG" },
48 	{ i_NEGX, "NEGX" },
49 	{ i_NBCD, "NBCD" },
50 	{ i_CLR, "CLR" },
51 	{ i_NOT, "NOT" },
52 	{ i_TST, "TST" },
53 	{ i_BTST, "BTST" },
54 	{ i_BCHG, "BCHG" },
55 	{ i_BCLR, "BCLR" },
56 	{ i_BSET, "BSET" },
57 	{ i_CMP, "CMP" },
58 	{ i_CMPM, "CMPM" },
59 	{ i_CMPA, "CMPA" },
60 	{ i_MVPRM, "MVPRM" },
61 	{ i_MVPMR, "MVPMR" },
62 	{ i_MOVE, "MOVE" },
63 	{ i_MOVEA, "MOVEA" },
64 	{ i_MVSR2, "MVSR2" },
65 	{ i_MV2SR, "MV2SR" },
66 	{ i_SWAP, "SWAP" },
67 	{ i_EXG, "EXG" },
68 	{ i_EXT, "EXT" },
69 	{ i_MVMEL, "MVMEL" },
70 	{ i_MVMLE, "MVMLE" },
71 	{ i_TRAP, "TRAP" },
72 	{ i_MVR2USP, "MVR2USP" },
73 	{ i_MVUSP2R, "MVUSP2R" },
74 	{ i_NOP, "NOP" },
75 	{ i_RESET, "RESET" },
76 	{ i_RTE, "RTE" },
77 	{ i_RTD, "RTD" },
78 	{ i_LINK, "LINK" },
79 	{ i_UNLK, "UNLK" },
80 	{ i_RTS, "RTS" },
81 	{ i_STOP, "STOP" },
82 	{ i_TRAPV, "TRAPV" },
83 	{ i_RTR, "RTR" },
84 	{ i_JSR, "JSR" },
85 	{ i_JMP, "JMP" },
86 	{ i_BSR, "BSR" },
87 	{ i_Bcc, "Bcc" },
88 	{ i_LEA, "LEA" },
89 	{ i_PEA, "PEA" },
90 	{ i_DBcc, "DBcc" },
91 	{ i_Scc, "Scc" },
92 	{ i_DIVU, "DIVU" },
93 	{ i_DIVS, "DIVS" },
94 	{ i_MULU, "MULU" },
95 	{ i_MULS, "MULS" },
96 	{ i_ASR, "ASR" },
97 	{ i_ASL, "ASL" },
98 	{ i_LSR, "LSR" },
99 	{ i_LSL, "LSL" },
100 	{ i_ROL, "ROL" },
101 	{ i_ROR, "ROR" },
102 	{ i_ROXL, "ROXL" },
103 	{ i_ROXR, "ROXR" },
104 	{ i_ASRW, "ASRW" },
105 	{ i_ASLW, "ASLW" },
106 	{ i_LSRW, "LSRW" },
107 	{ i_LSLW, "LSLW" },
108 	{ i_ROLW, "ROLW" },
109 	{ i_RORW, "RORW" },
110 	{ i_ROXLW, "ROXLW" },
111 	{ i_ROXRW, "ROXRW" },
112 
113 	{ i_MOVE2C, "MOVE2C" },
114 	{ i_MOVEC2, "MOVEC2" },
115 	{ i_CAS, "CAS" },
116 	{ i_CAS2, "CAS2" },
117 	{ i_MULL, "MULL" },
118 	{ i_DIVL, "DIVL" },
119 	{ i_BFTST, "BFTST" },
120 	{ i_BFEXTU, "BFEXTU" },
121 	{ i_BFCHG, "BFCHG" },
122 	{ i_BFEXTS, "BFEXTS" },
123 	{ i_BFCLR, "BFCLR" },
124 	{ i_BFFFO, "BFFFO" },
125 	{ i_BFSET, "BFSET" },
126 	{ i_BFINS, "BFINS" },
127 	{ i_PACK, "PACK" },
128 	{ i_UNPK, "UNPK" },
129 	{ i_TAS, "TAS" },
130 	{ i_BKPT, "BKPT" },
131 	{ i_CALLM, "CALLM" },
132 	{ i_RTM, "RTM" },
133 	{ i_TRAPcc, "TRAPcc" },
134 	{ i_MOVES, "MOVES" },
135 	{ i_FPP, "FPP" },
136 	{ i_FDBcc, "FDBcc" },
137 	{ i_FScc, "FScc" },
138 	{ i_FTRAPcc, "FTRAPcc" },
139 	{ i_FBcc, "FBcc" },
140 	{ i_FBcc, "FBcc" },
141 	{ i_FSAVE, "FSAVE" },
142 	{ i_FRESTORE, "FRESTORE" },
143 
144 	{ i_CINVL, "CINVL" },
145 	{ i_CINVP, "CINVP" },
146 	{ i_CINVA, "CINVA" },
147 	{ i_CPUSHL, "CPUSHL" },
148 	{ i_CPUSHP, "CPUSHP" },
149 	{ i_CPUSHA, "CPUSHA" },
150 	{ i_MOVE16, "MOVE16" },
151 
152 	{ i_MMUOP, "MMUOP" },
153 	{ i_ILLG, "" },
154 };
155 
156 
157 struct instr * table68k;
158 
159 
mode_from_str(const char * str)160 static INLINE amodes mode_from_str(const char * str)
161 {
162 	if (strncmp (str, "Dreg", 4) == 0) return Dreg;
163 	if (strncmp (str, "Areg", 4) == 0) return Areg;
164 	if (strncmp (str, "Aind", 4) == 0) return Aind;
165 	if (strncmp (str, "Apdi", 4) == 0) return Apdi;
166 	if (strncmp (str, "Aipi", 4) == 0) return Aipi;
167 	if (strncmp (str, "Ad16", 4) == 0) return Ad16;
168 	if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
169 	if (strncmp (str, "absw", 4) == 0) return absw;
170 	if (strncmp (str, "absl", 4) == 0) return absl;
171 	if (strncmp (str, "PC16", 4) == 0) return PC16;
172 	if (strncmp (str, "PC8r", 4) == 0) return PC8r;
173 	if (strncmp (str, "Immd", 4) == 0) return imm;
174 
175 	abort();
176 	return 0;
177 }
178 
179 
mode_from_mr(int mode,int reg)180 static INLINE amodes mode_from_mr(int mode, int reg)
181 {
182 	switch (mode)
183 	{
184 		case 0: return Dreg;
185 		case 1: return Areg;
186 		case 2: return Aind;
187 		case 3: return Aipi;
188 		case 4: return Apdi;
189 		case 5: return Ad16;
190 		case 6: return Ad8r;
191 		case 7:
192 		switch (reg)
193 		{
194 			case 0: return absw;
195 			case 1: return absl;
196 			case 2: return PC16;
197 			case 3: return PC8r;
198 			case 4: return imm;
199 			case 5:
200 			case 6:
201 			case 7: return am_illg;
202 		}
203 	}
204 
205 	abort();
206 	return 0;
207 }
208 
209 
build_insn(int insn)210 static void build_insn(int insn)
211 {
212 	int find = -1;
213 	int variants;
214 	int isjmp = 0;
215 	struct instr_def id;
216 	const char * opcstr;
217 	int j;
218 
219 	int flaglive = 0, flagdead = 0;
220 	id = defs68k[insn];
221 
222 	/* Note: We treat anything with unknown flags as a jump. That
223 	   is overkill, but "the programmer" was lazy quite often, and
224 	   *this* programmer can't be bothered to work out what can and
225 	   can't trap. Usually, this will be overwritten with the gencomp
226 	   based information, anyway. */
227 
228 	for(j=0; j<5; j++)
229 	{
230 		switch (id.flaginfo[j].flagset)
231 		{
232 		case fa_unset: break;
233 		case fa_isjmp: isjmp = 1; break;
234 		case fa_isbranch: isjmp = 1; break;
235 		case fa_zero: flagdead |= 1 << j; break;
236 		case fa_one: flagdead |= 1 << j; break;
237 		case fa_dontcare: flagdead |= 1 << j; break;
238 		case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
239 		case fa_set: flagdead |= 1 << j; break;
240 		}
241     }
242 
243 out1:
244 	for(j=0; j<5; j++)
245 	{
246 		switch (id.flaginfo[j].flaguse)
247 		{
248 		case fu_unused: break;
249 		case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
250 		case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
251 		case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
252 		case fu_used: flaglive |= 1 << j; break;
253 		}
254 	}
255 
256 	opcstr = id.opcstr;
257 
258 	for(variants=0; variants<(1 << id.n_variable); variants++)
259 	{
260 		int bitcnt[lastbit];
261 		int bitval[lastbit];
262 		int bitpos[lastbit];
263 		int i;
264 		uint16_t opc = id.bits;
265 		uint16_t msk, vmsk;
266 		int pos = 0;
267 		int mnp = 0;
268 		int bitno = 0;
269 		char mnemonic[10];
270 
271 		wordsizes sz = sz_long;
272 		int srcgather = 0, dstgather = 0;
273 		int usesrc = 0, usedst = 0;
274 		int srctype = 0;
275 		int srcpos = -1, dstpos = -1;
276 
277 		amodes srcmode = am_unknown, destmode = am_unknown;
278 		int srcreg = -1, destreg = -1;
279 
280 		for(i=0; i<lastbit; i++)
281 			bitcnt[i] = bitval[i] = 0;
282 
283 		vmsk = 1 << id.n_variable;
284 
285 		for(i=0, msk=0x8000; i<16; i++, msk >>= 1)
286 		{
287 			if (!(msk & id.mask))
288 			{
289 				int currbit = id.bitpos[bitno++];
290 				int bit_set;
291 				vmsk >>= 1;
292 				bit_set = (variants & vmsk ? 1 : 0);
293 
294 				if (bit_set)
295 					opc |= msk;
296 
297 				bitpos[currbit] = 15 - i;
298 				bitcnt[currbit]++;
299 				bitval[currbit] <<= 1;
300 				bitval[currbit] |= bit_set;
301 			}
302 		}
303 
304 		if (bitval[bitj] == 0)
305 			bitval[bitj] = 8;
306 
307 		/* first check whether this one does not match after all */
308 		if (bitval[bitz] == 3 || bitval[bitC] == 1)
309 			continue;
310 
311 		if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
312 			continue;
313 
314 		/* bitI and bitC get copied to biti and bitc */
315 		if (bitcnt[bitI])
316 		{
317 			bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
318 		}
319 
320 		if (bitcnt[bitC])
321 			bitval[bitc] = bitval[bitC];
322 
323 		pos = 0;
324 		while (opcstr[pos] && !isspace((unsigned)opcstr[pos]))
325 		{
326 			if (opcstr[pos] == '.')
327 			{
328 				pos++;
329 
330 				switch (opcstr[pos])
331 				{
332 				case 'B': sz = sz_byte; break;
333 				case 'W': sz = sz_word; break;
334 				case 'L': sz = sz_long; break;
335 				case 'z':
336 					switch (bitval[bitz])
337 					{
338 					case 0: sz = sz_byte; break;
339 					case 1: sz = sz_word; break;
340 					case 2: sz = sz_long; break;
341 					default: abort();
342 					}
343 					break;
344 				default: abort();
345 				}
346 			}
347 			else
348 			{
349 				mnemonic[mnp] = opcstr[pos];
350 
351 				if (mnemonic[mnp] == 'f')
352 				{
353 					find = -1;
354 					switch (bitval[bitf])
355 					{
356 					case 0: mnemonic[mnp] = 'R'; break;
357 					case 1: mnemonic[mnp] = 'L'; break;
358 					default: abort();
359 					}
360 				}
361 
362 				mnp++;
363 			}
364 
365 			pos++;
366 		}
367 
368 		mnemonic[mnp] = 0;
369 
370 		/* now, we have read the mnemonic and the size */
371 		while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
372 			pos++;
373 
374 		/* A goto a day keeps the D******a away. */
375 		if (opcstr[pos] == 0)
376 			goto endofline;
377 
378 		/* parse the source address */
379 		usesrc = 1;
380 		switch (opcstr[pos++])
381 		{
382 		case 'D':
383 			srcmode = Dreg;
384 
385 			switch (opcstr[pos++])
386 			{
387 			case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
388 			case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
389 			default: abort();
390 			}
391 
392 			break;
393 		case 'A':
394 			srcmode = Areg;
395 
396 			switch (opcstr[pos++])
397 			{
398 			case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
399 			case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
400 			default: abort();
401 			}
402 
403 			switch (opcstr[pos])
404 			{
405 			case 'p': srcmode = Apdi; pos++; break;
406 			case 'P': srcmode = Aipi; pos++; break;
407 			}
408 			break;
409 
410 		case 'L':
411 			srcmode = absl;
412 			break;
413 		case '#':
414 			switch (opcstr[pos++])
415 			{
416 			case 'z': srcmode = imm; break;
417 			case '0': srcmode = imm0; break;
418 			case '1': srcmode = imm1; break;
419 			case '2': srcmode = imm2; break;
420 			case 'i':
421 				srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
422 
423 				if (CPU_EMU_SIZE < 4)
424 				{
425 					/* Used for branch instructions */
426 					srctype = 1;
427 					srcgather = 1;
428 					srcpos = bitpos[biti];
429 				}
430 
431 				break;
432 			case 'j':
433 				srcmode = immi; srcreg = bitval[bitj];
434 
435 				if (CPU_EMU_SIZE < 3)
436 				{
437 					/* 1..8 for ADDQ/SUBQ and rotshi insns */
438 					srcgather = 1;
439 					srctype = 3;
440 					srcpos = bitpos[bitj];
441 				}
442 
443 				break;
444 			case 'J':
445 				srcmode = immi; srcreg = bitval[bitJ];
446 
447 				if (CPU_EMU_SIZE < 5)
448 				{
449 					/* 0..15 */
450 					srcgather = 1;
451 					srctype = 2;
452 					srcpos = bitpos[bitJ];
453 				}
454 
455 				break;
456 			case 'k':
457 				srcmode = immi; srcreg = bitval[bitk];
458 
459 				if (CPU_EMU_SIZE < 3)
460 				{
461 					srcgather = 1;
462 					srctype = 4;
463 					srcpos = bitpos[bitk];
464 				}
465 
466 				break;
467 			case 'K':
468 				srcmode = immi; srcreg = bitval[bitK];
469 
470 				if (CPU_EMU_SIZE < 5)
471 				{
472 					/* 0..15 */
473 					srcgather = 1;
474 					srctype = 5;
475 					srcpos = bitpos[bitK];
476 				}
477 
478 				break;
479 			case 'p':
480 				srcmode = immi; srcreg = bitval[bitK];
481 
482 				if (CPU_EMU_SIZE < 5)
483 				{
484 					/* 0..3 */
485 					srcgather = 1;
486 					srctype = 7;
487 					srcpos = bitpos[bitp];
488 				}
489 
490 				break;
491 			default: abort();
492 			}
493 
494 			break;
495 		case 'd':
496 			srcreg = bitval[bitD];
497 			srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
498 
499 			if (srcmode == am_illg)
500 				continue;
501 
502 			if (CPU_EMU_SIZE < 2
503 				&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
504 				|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
505 				|| srcmode == Apdi))
506 			{
507 				srcgather = 1;
508 				srcpos = bitpos[bitD];
509 			}
510 
511 			if (opcstr[pos] == '[')
512 			{
513 				pos++;
514 
515 				if (opcstr[pos] == '!')
516 				{
517 					/* exclusion */
518 					do
519 					{
520 						pos++;
521 
522 						if (mode_from_str(opcstr + pos) == srcmode)
523 							goto nomatch;
524 
525 						pos += 4;
526 					}
527 					while (opcstr[pos] == ',');
528 
529 					pos++;
530 				}
531 				else
532 				{
533 					if (opcstr[pos + 4] == '-')
534 					{
535 						/* replacement */
536 						if (mode_from_str(opcstr + pos) == srcmode)
537 							srcmode = mode_from_str(opcstr + pos + 5);
538 						else
539 							goto nomatch;
540 
541 						pos += 10;
542 					}
543 					else
544 					{
545 						/* normal */
546 						while(mode_from_str(opcstr + pos) != srcmode)
547 						{
548 							pos += 4;
549 
550 							if (opcstr[pos] == ']')
551 								goto nomatch;
552 
553 							pos++;
554 						}
555 
556 						while(opcstr[pos] != ']')
557 							pos++;
558 
559 						pos++;
560 						break;
561 					}
562 				}
563 			}
564 
565 			/* Some addressing modes are invalid as destination */
566 			if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
567 				goto nomatch;
568 
569 			break;
570 		case 's':
571 			srcreg = bitval[bitS];
572 			srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
573 
574 			if (srcmode == am_illg)
575 				continue;
576 
577 			if (CPU_EMU_SIZE < 2
578 				&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
579 				|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
580 				|| srcmode == Apdi))
581 			{
582 				srcgather = 1;
583 				srcpos = bitpos[bitS];
584 			}
585 
586 			if (opcstr[pos] == '[')
587 			{
588 				pos++;
589 
590 				if (opcstr[pos] == '!')
591 				{
592 					/* exclusion */
593 					do
594 					{
595 						pos++;
596 
597 						if (mode_from_str(opcstr + pos) == srcmode)
598 							goto nomatch;
599 
600 						pos += 4;
601 					}
602 					while (opcstr[pos] == ',');
603 
604 					pos++;
605 				}
606 				else
607 				{
608 					if (opcstr[pos + 4] == '-')
609 					{
610 						/* replacement */
611 						if (mode_from_str(opcstr + pos) == srcmode)
612 							srcmode = mode_from_str(opcstr + pos + 5);
613 						else
614 							goto nomatch;
615 
616 						pos += 10;
617 					}
618 					else
619 					{
620 						/* normal */
621 						while(mode_from_str(opcstr+pos) != srcmode)
622 						{
623 							pos += 4;
624 
625 							if (opcstr[pos] == ']')
626 								goto nomatch;
627 
628 							pos++;
629 						}
630 
631 						while(opcstr[pos] != ']')
632 							pos++;
633 
634 						pos++;
635 					}
636 				}
637 			}
638 			break;
639 		default: abort();
640 		}
641 
642 		/* safety check - might have changed */
643 		if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
644 			&& srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
645 			&& srcmode != Apdi && srcmode != immi)
646 		{
647 			srcgather = 0;
648 		}
649 
650 //		if (srcmode == Areg && sz == sz_byte)
651 		if (srcmode == Areg && sz == sz_byte && strcmp(mnemonic, "MOVE") != 0 )	// [NP] move.b is valid on 68000
652 			goto nomatch;
653 
654 		if (opcstr[pos] != ',')
655 			goto endofline;
656 
657 		pos++;
658 
659 		/* parse the destination address */
660 		usedst = 1;
661 
662 		switch (opcstr[pos++])
663 		{
664 		case 'D':
665 			destmode = Dreg;
666 
667 			switch (opcstr[pos++])
668 			{
669 			case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
670 			case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
671 			default: abort();
672 			}
673 
674 			if (dstpos < 0 || dstpos >= 32)
675 				abort();
676 
677 			break;
678 		case 'A':
679 			destmode = Areg;
680 
681 			switch (opcstr[pos++])
682 			{
683 			case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
684 			case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
685 			case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
686 			default: abort();
687 			}
688 
689 			if (dstpos < 0 || dstpos >= 32)
690 				abort();
691 
692 			switch (opcstr[pos])
693 			{
694 			case 'p': destmode = Apdi; pos++; break;
695 			case 'P': destmode = Aipi; pos++; break;
696 			}
697 
698 			break;
699 		case 'L':
700 			destmode = absl;
701 			break;
702 		case '#':
703 			switch (opcstr[pos++])
704 			{
705 			case 'z': destmode = imm; break;
706 			case '0': destmode = imm0; break;
707 			case '1': destmode = imm1; break;
708 			case '2': destmode = imm2; break;
709 			case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
710 			case 'j': destmode = immi; destreg = bitval[bitj]; break;
711 			case 'J': destmode = immi; destreg = bitval[bitJ]; break;
712 			case 'k': destmode = immi; destreg = bitval[bitk]; break;
713 			case 'K': destmode = immi; destreg = bitval[bitK]; break;
714 			default: abort();
715 			}
716 			break;
717 		case 'd':
718 			destreg = bitval[bitD];
719 			destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
720 
721 			if (destmode == am_illg)
722 				continue;
723 
724 			if (CPU_EMU_SIZE < 1
725 				&& (destmode == Areg || destmode == Dreg || destmode == Aind
726 				|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
727 				|| destmode == Apdi))
728 			{
729 				dstgather = 1;
730 				dstpos = bitpos[bitD];
731 			}
732 
733 			if (opcstr[pos] == '[')
734 			{
735 				pos++;
736 
737 				if (opcstr[pos] == '!')
738 				{
739 					/* exclusion */
740 					do
741 					{
742 						pos++;
743 
744 						if (mode_from_str(opcstr + pos) == destmode)
745 							goto nomatch;
746 
747 						pos += 4;
748 					}
749 					while (opcstr[pos] == ',');
750 
751 					pos++;
752 				}
753 				else
754 				{
755 					if (opcstr[pos+4] == '-')
756 					{
757 						/* replacement */
758 						if (mode_from_str(opcstr + pos) == destmode)
759 							destmode = mode_from_str(opcstr + pos + 5);
760 						else
761 							goto nomatch;
762 
763 						pos += 10;
764 					}
765 					else
766 					{
767 						/* normal */
768 						while(mode_from_str(opcstr + pos) != destmode)
769 						{
770 							pos += 4;
771 
772 							if (opcstr[pos] == ']')
773 								goto nomatch;
774 
775 							pos++;
776 						}
777 
778 						while(opcstr[pos] != ']')
779 							pos++;
780 
781 						pos++;
782 						break;
783 					}
784 				}
785 			}
786 
787 			/* Some addressing modes are invalid as destination */
788 			if (destmode == imm || destmode == PC16 || destmode == PC8r)
789 				goto nomatch;
790 
791 			break;
792 		case 's':
793 			destreg = bitval[bitS];
794 			destmode = mode_from_mr(bitval[bits], bitval[bitS]);
795 
796 			if (destmode == am_illg)
797 			continue;
798 			if (CPU_EMU_SIZE < 1
799 				&& (destmode == Areg || destmode == Dreg || destmode == Aind
800 				|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
801 				|| destmode == Apdi))
802 			{
803 				dstgather = 1;
804 				dstpos = bitpos[bitS];
805 			}
806 
807 			if (opcstr[pos] == '[')
808 			{
809 				pos++;
810 
811 				if (opcstr[pos] == '!')
812 				{
813 					/* exclusion */
814 					do
815 					{
816 						pos++;
817 
818 						if (mode_from_str(opcstr + pos) == destmode)
819 							goto nomatch;
820 
821 						pos += 4;
822 					}
823 					while (opcstr[pos] == ',');
824 
825 					pos++;
826 				}
827 				else
828 				{
829 					if (opcstr[pos+4] == '-')
830 					{
831 						/* replacement */
832 						if (mode_from_str(opcstr + pos) == destmode)
833 							destmode = mode_from_str(opcstr + pos + 5);
834 						else
835 							goto nomatch;
836 
837 						pos += 10;
838 					}
839 					else
840 					{
841 						/* normal */
842 						while (mode_from_str(opcstr + pos) != destmode)
843 						{
844 							pos += 4;
845 
846 							if (opcstr[pos] == ']')
847 								goto nomatch;
848 
849 							pos++;
850 						}
851 
852 						while (opcstr[pos] != ']')
853 							pos++;
854 
855 						pos++;
856 					}
857 				}
858 			}
859 			break;
860 		default: abort();
861 		}
862 
863 		/* safety check - might have changed */
864 		if (destmode != Areg && destmode != Dreg && destmode != Aind
865 			&& destmode != Ad16 && destmode != Ad8r && destmode != Aipi
866 			&& destmode != Apdi)
867 		{
868 			dstgather = 0;
869 		}
870 
871 		if (destmode == Areg && sz == sz_byte)
872 			goto nomatch;
873 endofline:
874 		/* now, we have a match */
875 		if (table68k[opc].mnemo != i_ILLG)
876 			fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
877 
878 		if (find == -1)
879 		{
880 			for(find=0; ; find++)
881 			{
882 				if (strcmp(mnemonic, lookuptab[find].name) == 0)
883 				{
884 					table68k[opc].mnemo = lookuptab[find].mnemo;
885 					break;
886 				}
887 
888 				if (strlen(lookuptab[find].name) == 0)
889 					abort();
890 			}
891 		}
892 		else
893 		{
894 			table68k[opc].mnemo = lookuptab[find].mnemo;
895 		}
896 
897 		table68k[opc].cc = bitval[bitc];
898 
899 		if (table68k[opc].mnemo == i_BTST
900 			|| table68k[opc].mnemo == i_BSET
901 			|| table68k[opc].mnemo == i_BCLR
902 			|| table68k[opc].mnemo == i_BCHG)
903 		{
904 			sz = (destmode == Dreg ? sz_long : sz_byte);
905 		}
906 
907 		table68k[opc].size = sz;
908 		table68k[opc].sreg = srcreg;
909 		table68k[opc].dreg = destreg;
910 		table68k[opc].smode = srcmode;
911 		table68k[opc].dmode = destmode;
912 		table68k[opc].spos = (srcgather ? srcpos : -1);
913 		table68k[opc].dpos = (dstgather ? dstpos : -1);
914 		table68k[opc].suse = usesrc;
915 		table68k[opc].duse = usedst;
916 		table68k[opc].stype = srctype;
917 		table68k[opc].plev = id.plevel;
918 		table68k[opc].clev = id.cpulevel;
919 		table68k[opc].flagdead = flagdead;
920 		table68k[opc].flaglive = flaglive;
921 		table68k[opc].isjmp = isjmp;
922 
923 nomatch:
924 	/* FOO! */;
925     }
926 }
927 
928 
read_table68k(void)929 void read_table68k(void)
930 {
931 	int i;
932 	table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
933 
934 	for(i=0; i<65536; i++)
935 	{
936 		table68k[i].mnemo = i_ILLG;
937 		table68k[i].handler = -1;
938 	}
939 
940 	for(i=0; i<n_defs68k; i++)
941 		build_insn(i);
942 }
943 
944 
945 static int mismatch;
946 
947 
handle_merges(long int opcode)948 static void handle_merges (long int opcode)
949 {
950 	uint16_t smsk;
951 	uint16_t dmsk;
952 	int sbitdst, dstend;
953 	int srcreg, dstreg;
954 
955 //0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W  s,d[!Areg]
956 //31C3 ->
957 //0011 0001 1100 0011 : DDD = 0, ddd = 7, sss = 0, SSS = 3
958 
959 	if (table68k[opcode].spos == -1)
960 	{
961 		sbitdst = 1;
962 		smsk = 0;
963 	}
964 	else
965 	{
966 		switch (table68k[opcode].stype)
967 		{
968 		case 0:
969 			smsk = 7; sbitdst = 8; break;
970 		case 1:
971 			smsk = 255; sbitdst = 256; break;
972 		case 2:
973 			smsk = 15; sbitdst = 16; break;
974 		case 3:
975 			smsk = 7; sbitdst = 8; break;
976 		case 4:
977 			smsk = 7; sbitdst = 8; break;
978 		case 5:
979 			smsk = 63; sbitdst = 64; break;
980 		case 7:
981 			smsk = 3; sbitdst = 4; break;
982 		default:
983 			smsk = 0; sbitdst = 0;
984 			abort();
985 			break;
986 		}
987 
988 		smsk <<= table68k[opcode].spos;
989 	}
990 
991 	if (table68k[opcode].dpos == -1)
992 	{
993 		dmsk = 0;
994 		dstend = 1;
995 	}
996 	else
997 	{
998 		dmsk = 7 << table68k[opcode].dpos;
999 		dstend = 8;
1000 	}
1001 
1002 	for(srcreg=0; srcreg<sbitdst; srcreg++)
1003 	{
1004 		for(dstreg=0; dstreg<dstend; dstreg++)
1005 		{
1006 			uint16_t code = opcode;
1007 
1008 			code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
1009 			code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
1010 
1011 			/* Check whether this is in fact the same instruction.
1012 			* The instructions should never differ, except for the
1013 			* Bcc.(BW) case. */
1014 			if (table68k[code].mnemo != table68k[opcode].mnemo
1015 				|| table68k[code].size != table68k[opcode].size
1016 				|| table68k[code].suse != table68k[opcode].suse
1017 				|| table68k[code].duse != table68k[opcode].duse)
1018 			{
1019 				mismatch++;
1020 				continue;
1021 			}
1022 
1023 			if (table68k[opcode].suse
1024 				&& (table68k[opcode].spos != table68k[code].spos
1025 				|| table68k[opcode].smode != table68k[code].smode
1026 				|| table68k[opcode].stype != table68k[code].stype))
1027 			{
1028 				mismatch++;
1029 				continue;
1030 			}
1031 
1032 			if (table68k[opcode].duse
1033 				&& (table68k[opcode].dpos != table68k[code].dpos
1034 				|| table68k[opcode].dmode != table68k[code].dmode))
1035 			{
1036 				mismatch++;
1037 				continue;
1038 			}
1039 
1040 			if (code != opcode)
1041 				table68k[code].handler = opcode;
1042 		}
1043 	}
1044 }
1045 
1046 
1047 // What this really does is expand the # of handlers, which is why the
1048 // opcode has to be passed into the opcode handler...
1049 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
do_merges(void)1050 void do_merges(void)
1051 {
1052 	long int opcode;
1053 	int nr = 0;
1054 	mismatch = 0;
1055 
1056 	for(opcode=0; opcode<65536; opcode++)
1057 	{
1058 		if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
1059 			continue;
1060 
1061 		nr++;
1062 		handle_merges(opcode);
1063 	}
1064 
1065 	nr_cpuop_funcs = nr;
1066 }
1067 
1068 
get_no_mismatches(void)1069 int get_no_mismatches(void)
1070 {
1071 	return mismatch;
1072 }
1073 
1074