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