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