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