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