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