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