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