|
|
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" }, 133: { i_MMUOP, "MMUOP" }, 134: { i_ILLG, "" }, 135: }; 136: 137: struct instr *table68k; 138: 139: static __inline__ amodes mode_from_str(const char *str) 140: { 141: if (strncmp(str,"Dreg",4) == 0) return Dreg; 142: if (strncmp(str,"Areg",4) == 0) return Areg; 143: if (strncmp(str,"Aind",4) == 0) return Aind; 144: if (strncmp(str,"Apdi",4) == 0) return Apdi; 145: if (strncmp(str,"Aipi",4) == 0) return Aipi; 146: if (strncmp(str,"Ad16",4) == 0) return Ad16; 147: if (strncmp(str,"Ad8r",4) == 0) return Ad8r; 148: if (strncmp(str,"absw",4) == 0) return absw; 149: if (strncmp(str,"absl",4) == 0) return absl; 150: if (strncmp(str,"PC16",4) == 0) return PC16; 151: if (strncmp(str,"PC8r",4) == 0) return PC8r; 152: if (strncmp(str,"Immd",4) == 0) return imm; 153: abort(); 154: return(0); 155: } 156: 1.1.1.2 ! root 157: static __inline__ amodes mode_from_mr(int mode, int reg) 1.1 root 158: { 159: switch(mode) { 1.1.1.2 ! root 160: case 0: return Dreg; 1.1 root 161: case 1: return Areg; 162: case 2: return Aind; 163: case 3: return Aipi; 164: case 4: return Apdi; 165: case 5: return Ad16; 166: case 6: return Ad8r; 1.1.1.2 ! root 167: case 7: 1.1 root 168: switch(reg) { 169: case 0: return absw; 170: case 1: return absl; 171: case 2: return PC16; 172: case 3: return PC8r; 173: case 4: return imm; 174: case 5: 175: case 6: 176: case 7: return am_illg; 177: } 178: } 179: abort(); 180: return(0); 181: } 182: 183: static void build_insn(int insn) 184: { 185: int find = -1; 186: int variants; 187: struct instr_def id; 188: const char *opcstr; 189: int i; 190: 191: int flaglive = 0, flagdead = 0; 192: 193: id = defs68k[insn]; 1.1.1.2 ! root 194: 1.1 root 195: for(i = 0; i < 5; i++) { 196: switch(id.flaginfo[i].flagset){ 197: case fa_unset: break; 198: case fa_isjmp: break; 199: case fa_zero: flagdead |= 1 << i; break; 200: case fa_one: flagdead |= 1 << i; break; 201: case fa_dontcare: flagdead |= 1 << i; break; 202: case fa_unknown: flagdead = -1; goto out1; 203: case fa_set: flagdead |= 1 << i; break; 204: } 205: } 206: 207: out1: 208: for(i = 0; i < 5; i++) { 209: switch(id.flaginfo[i].flaguse) { 210: case fu_unused: break; 211: case fu_isjmp: flaglive |= 1 << i; break; 212: case fu_maybecc: flaglive |= 1 << i; break; 213: case fu_unknown: flaglive = -1; goto out2; 214: case fu_used: flaglive |= 1 << i; break; 215: } 216: } 217: out2: 1.1.1.2 ! root 218: 1.1 root 219: opcstr = id.opcstr; 220: for (variants = 0; variants < (1 << id.n_variable); variants++) { 221: int bitcnt[lastbit]; 222: int bitval[lastbit]; 223: int bitpos[lastbit]; 224: int i; 1.1.1.2 ! root 225: uae_u16 opc = id.bits; ! 226: uae_u16 msk, vmsk; 1.1 root 227: int pos = 0; 228: int mnp = 0; 229: int bitno = 0; 230: char mnemonic[10]; 1.1.1.2 ! root 231: 1.1 root 232: wordsizes sz = sz_long; 233: int srcgather = 0, dstgather = 0; 234: int usesrc = 0, usedst = 0; 235: int srctype = 0; 236: int srcpos = -1, dstpos = -1; 1.1.1.2 ! root 237: 1.1 root 238: amodes srcmode = am_unknown, destmode = am_unknown; 239: int srcreg = -1, destreg = -1; 1.1.1.2 ! root 240: ! 241: for(i = 0; i < lastbit; i++) 1.1 root 242: bitcnt[i] = bitval[i] = 0; 243: 244: vmsk = 1 << id.n_variable; 1.1.1.2 ! root 245: ! 246: for(i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { 1.1 root 247: if (!(msk & id.mask)) { 248: int currbit = id.bitpos[bitno++]; 249: int bit_set; 250: vmsk >>= 1; 251: bit_set = variants & vmsk ? 1 : 0; 252: if (bit_set) 253: opc |= msk; 254: bitpos[currbit] = 15 - i; 255: bitcnt[currbit]++; 256: bitval[currbit] <<= 1; 257: bitval[currbit] |= bit_set; 258: } 259: } 1.1.1.2 ! root 260: 1.1 root 261: if (bitval[bitj] == 0) bitval[bitj] = 8; 262: /* first check whether this one does not match after all */ 263: if (bitval[bitz] == 3 || bitval[bitC] == 1) 1.1.1.2 ! root 264: continue; ! 265: if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) 1.1 root 266: continue; 267: 268: /* bitI and bitC get copied to biti and bitc */ 269: if (bitcnt[bitI]) { 1.1.1.2 ! root 270: bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; 1.1 root 271: } 1.1.1.2 ! root 272: if (bitcnt[bitC]) 1.1 root 273: bitval[bitc] = bitval[bitC]; 1.1.1.2 ! root 274: 1.1 root 275: pos = 0; 276: while (opcstr[pos] && !isspace(opcstr[pos])) { 277: if (opcstr[pos] == '.') { 278: pos++; 279: switch(opcstr[pos]) { 1.1.1.2 ! root 280: 1.1 root 281: case 'B': sz = sz_byte; break; 282: case 'W': sz = sz_word; break; 283: case 'L': sz = sz_long; break; 1.1.1.2 ! root 284: case 'z': 1.1 root 285: switch(bitval[bitz]) { 286: case 0: sz = sz_byte; break; 287: case 1: sz = sz_word; break; 288: case 2: sz = sz_long; break; 289: default: abort(); 290: } 291: break; 292: default: abort(); 293: } 1.1.1.2 ! root 294: } else { 1.1 root 295: mnemonic[mnp] = opcstr[pos]; 296: if(mnemonic[mnp] == 'f') { 297: find = -1; 298: switch(bitval[bitf]) { 299: case 0: mnemonic[mnp] = 'R'; break; 300: case 1: mnemonic[mnp] = 'L'; break; 301: default: abort(); 302: } 303: } 304: mnp++; 305: } 1.1.1.2 ! root 306: pos++; 1.1 root 307: } 308: mnemonic[mnp] = 0; 1.1.1.2 ! root 309: 1.1 root 310: /* now, we have read the mnemonic and the size */ 1.1.1.2 ! root 311: while (opcstr[pos] && isspace(opcstr[pos])) 1.1 root 312: pos++; 1.1.1.2 ! root 313: 1.1 root 314: /* A goto a day keeps the D******a away. */ 315: if (opcstr[pos] == 0) 316: goto endofline; 1.1.1.2 ! root 317: 1.1 root 318: /* parse the source address */ 319: usesrc = 1; 320: switch(opcstr[pos++]) { 1.1.1.2 ! root 321: case 'D': 1.1 root 322: srcmode = Dreg; 323: switch (opcstr[pos++]) { 324: case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; 325: case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; 326: default: abort(); 327: } 1.1.1.2 ! root 328: 1.1 root 329: break; 1.1.1.2 ! root 330: case 'A': 1.1 root 331: srcmode = Areg; 332: switch (opcstr[pos++]) { 333: case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; 334: case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; 335: default: abort(); 336: } 337: switch (opcstr[pos]) { 338: case 'p': srcmode = Apdi; pos++; break; 339: case 'P': srcmode = Aipi; pos++; break; 340: } 341: break; 342: case '#': 343: switch(opcstr[pos++]) { 344: case 'z': srcmode = imm; break; 345: case '0': srcmode = imm0; break; 346: case '1': srcmode = imm1; break; 347: case '2': srcmode = imm2; break; 1.1.1.2 ! root 348: case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; 1.1 root 349: if (CPU_EMU_SIZE < 4) { 350: /* Used for branch instructions */ 351: srctype = 1; 1.1.1.2 ! root 352: srcgather = 1; 1.1 root 353: srcpos = bitpos[biti]; 354: } 355: break; 356: case 'j': srcmode = immi; srcreg = bitval[bitj]; 357: if (CPU_EMU_SIZE < 3) { 358: /* 1..8 for ADDQ/SUBQ and rotshi insns */ 359: srcgather = 1; 360: srctype = 3; 361: srcpos = bitpos[bitj]; 362: } 363: break; 364: case 'J': srcmode = immi; srcreg = bitval[bitJ]; 365: if (CPU_EMU_SIZE < 5) { 366: /* 0..15 */ 367: srcgather = 1; 368: srctype = 2; 369: srcpos = bitpos[bitJ]; 370: } 371: break; 372: case 'k': srcmode = immi; srcreg = bitval[bitk]; 373: if (CPU_EMU_SIZE < 3) { 374: srcgather = 1; 375: srctype = 4; 376: srcpos = bitpos[bitk]; 377: } 378: break; 379: case 'K': srcmode = immi; srcreg = bitval[bitK]; 380: if (CPU_EMU_SIZE < 5) { 381: /* 0..15 */ 382: srcgather = 1; 383: srctype = 5; 384: srcpos = bitpos[bitK]; 385: } 386: break; 387: default: abort(); 388: } 389: break; 390: case 'd': 391: srcreg = bitval[bitD]; 392: srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); 393: if (srcmode == am_illg) continue; 1.1.1.2 ! root 394: if (CPU_EMU_SIZE < 2 && ! 395: (srcmode == Areg || srcmode == Dreg || srcmode == Aind 1.1 root 396: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi 397: || srcmode == Apdi)) 398: { 399: srcgather = 1; srcpos = bitpos[bitD]; 400: } 401: if (opcstr[pos] == '[') { 402: pos++; 403: if (opcstr[pos] == '!') { 404: /* exclusion */ 1.1.1.2 ! root 405: do { 1.1 root 406: pos++; 1.1.1.2 ! root 407: if (mode_from_str(opcstr+pos) == srcmode) 1.1 root 408: goto nomatch; 1.1.1.2 ! root 409: pos += 4; 1.1 root 410: } while (opcstr[pos] == ','); 411: pos++; 412: } else { 413: if (opcstr[pos+4] == '-') { 414: /* replacement */ 1.1.1.2 ! root 415: if (mode_from_str(opcstr+pos) == srcmode) 1.1 root 416: srcmode = mode_from_str(opcstr+pos+5); 417: else 418: goto nomatch; 419: pos += 10; 420: } else { 421: /* normal */ 422: while(mode_from_str(opcstr+pos) != srcmode) { 423: pos += 4; 424: if (opcstr[pos] == ']') 425: goto nomatch; 426: pos++; 427: } 428: while(opcstr[pos] != ']') pos++; 429: pos++; 430: break; 431: } 432: } 433: } 434: /* Some addressing modes are invalid as destination */ 435: if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) 1.1.1.2 ! root 436: goto nomatch; 1.1 root 437: break; 438: case 's': 439: srcreg = bitval[bitS]; 440: srcmode = mode_from_mr(bitval[bits],bitval[bitS]); 1.1.1.2 ! root 441: ! 442: if (srcmode == am_illg) continue; ! 443: if (CPU_EMU_SIZE < 2 && ! 444: (srcmode == Areg || srcmode == Dreg || srcmode == Aind 1.1 root 445: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi 446: || srcmode == Apdi)) 447: { 448: srcgather = 1; srcpos = bitpos[bitS]; 449: } 450: if (opcstr[pos] == '[') { 451: pos++; 452: if (opcstr[pos] == '!') { 453: /* exclusion */ 1.1.1.2 ! root 454: do { 1.1 root 455: pos++; 1.1.1.2 ! root 456: if (mode_from_str(opcstr+pos) == srcmode) 1.1 root 457: goto nomatch; 1.1.1.2 ! root 458: pos += 4; 1.1 root 459: } while (opcstr[pos] == ','); 460: pos++; 461: } else { 462: if (opcstr[pos+4] == '-') { 463: /* replacement */ 1.1.1.2 ! root 464: if (mode_from_str(opcstr+pos) == srcmode) 1.1 root 465: srcmode = mode_from_str(opcstr+pos+5); 466: else 467: goto nomatch; 468: pos += 10; 469: } else { 470: /* normal */ 471: while(mode_from_str(opcstr+pos) != srcmode) { 472: pos += 4; 1.1.1.2 ! root 473: if (opcstr[pos] == ']') 1.1 root 474: goto nomatch; 475: pos++; 476: } 477: while(opcstr[pos] != ']') pos++; 478: pos++; 479: } 480: } 481: } 482: break; 483: default: abort(); 484: } 485: /* safety check - might have changed */ 1.1.1.2 ! root 486: if (srcmode != Areg && srcmode != Dreg && srcmode != Aind 1.1 root 487: && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi 488: && srcmode != Apdi && srcmode != immi) 489: { 490: srcgather = 0; 491: } 492: if (srcmode == Areg && sz == sz_byte) 493: goto nomatch; 1.1.1.2 ! root 494: 1.1 root 495: if (opcstr[pos] != ',') 496: goto endofline; 497: pos++; 1.1.1.2 ! root 498: 1.1 root 499: /* parse the destination address */ 1.1.1.2 ! root 500: usedst = 1; 1.1 root 501: switch(opcstr[pos++]) { 1.1.1.2 ! root 502: case 'D': 1.1 root 503: destmode = Dreg; 504: switch (opcstr[pos++]) { 505: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; 506: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; 507: default: abort(); 508: } 509: break; 1.1.1.2 ! root 510: case 'A': 1.1 root 511: destmode = Areg; 512: switch (opcstr[pos++]) { 513: case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; 514: case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; 515: default: abort(); 516: } 517: switch (opcstr[pos]) { 518: case 'p': destmode = Apdi; pos++; break; 519: case 'P': destmode = Aipi; pos++; break; 520: } 521: break; 522: case '#': 523: switch(opcstr[pos++]) { 524: case 'z': destmode = imm; break; 525: case '0': destmode = imm0; break; 526: case '1': destmode = imm1; break; 527: case '2': destmode = imm2; break; 1.1.1.2 ! root 528: case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; 1.1 root 529: case 'j': destmode = immi; destreg = bitval[bitj]; break; 530: case 'J': destmode = immi; destreg = bitval[bitJ]; break; 531: case 'k': destmode = immi; destreg = bitval[bitk]; break; 532: case 'K': destmode = immi; destreg = bitval[bitK]; break; 533: default: abort(); 534: } 535: break; 536: case 'd': 537: destreg = bitval[bitD]; 538: destmode = mode_from_mr(bitval[bitd],bitval[bitD]); 539: if(destmode == am_illg) continue; 1.1.1.2 ! root 540: if (CPU_EMU_SIZE < 1 && ! 541: (destmode == Areg || destmode == Dreg || destmode == Aind 1.1 root 542: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi 543: || destmode == Apdi)) 544: { 545: dstgather = 1; dstpos = bitpos[bitD]; 546: } 1.1.1.2 ! root 547: 1.1 root 548: if (opcstr[pos] == '[') { 549: pos++; 550: if (opcstr[pos] == '!') { 551: /* exclusion */ 1.1.1.2 ! root 552: do { 1.1 root 553: pos++; 1.1.1.2 ! root 554: if (mode_from_str(opcstr+pos) == destmode) 1.1 root 555: goto nomatch; 1.1.1.2 ! root 556: pos += 4; 1.1 root 557: } while (opcstr[pos] == ','); 558: pos++; 559: } else { 560: if (opcstr[pos+4] == '-') { 561: /* replacement */ 1.1.1.2 ! root 562: if (mode_from_str(opcstr+pos) == destmode) 1.1 root 563: destmode = mode_from_str(opcstr+pos+5); 564: else 565: goto nomatch; 566: pos += 10; 567: } else { 568: /* normal */ 569: while(mode_from_str(opcstr+pos) != destmode) { 570: pos += 4; 571: if (opcstr[pos] == ']') 572: goto nomatch; 573: pos++; 574: } 575: while(opcstr[pos] != ']') pos++; 576: pos++; 577: break; 578: } 579: } 580: } 581: /* Some addressing modes are invalid as destination */ 582: if (destmode == imm || destmode == PC16 || destmode == PC8r) 583: goto nomatch; 584: break; 585: case 's': 586: destreg = bitval[bitS]; 587: destmode = mode_from_mr(bitval[bits],bitval[bitS]); 1.1.1.2 ! root 588: ! 589: if (destmode == am_illg) continue; ! 590: if (CPU_EMU_SIZE < 1 && ! 591: (destmode == Areg || destmode == Dreg || destmode == Aind 1.1 root 592: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi 593: || destmode == Apdi)) 594: { 595: dstgather = 1; dstpos = bitpos[bitS]; 596: } 1.1.1.2 ! root 597: 1.1 root 598: if (opcstr[pos] == '[') { 599: pos++; 600: if (opcstr[pos] == '!') { 601: /* exclusion */ 1.1.1.2 ! root 602: do { 1.1 root 603: pos++; 604: if (mode_from_str(opcstr+pos) == destmode) 605: goto nomatch; 1.1.1.2 ! root 606: pos += 4; 1.1 root 607: } while (opcstr[pos] == ','); 608: pos++; 609: } else { 610: if (opcstr[pos+4] == '-') { 611: /* replacement */ 1.1.1.2 ! root 612: if (mode_from_str(opcstr+pos) == destmode) 1.1 root 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: } 628: } 629: } 630: break; 631: default: abort(); 632: } 633: /* safety check - might have changed */ 1.1.1.2 ! root 634: if (destmode != Areg && destmode != Dreg && destmode != Aind 1.1 root 635: && destmode != Ad16 && destmode != Ad8r && destmode != Aipi 636: && destmode != Apdi) 637: { 638: dstgather = 0; 639: } 1.1.1.2 ! root 640: 1.1 root 641: if (destmode == Areg && sz == sz_byte) 642: goto nomatch; 643: #if 0 644: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { 645: dstgather = 0; 646: } 647: #endif 648: endofline: 649: /* now, we have a match */ 650: if (table68k[opc].mnemo != i_ILLG) 651: fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); 652: if (find == -1) { 653: for(find = 0;; find++) { 1.1.1.2 ! root 654: if (strcmp(mnemonic, lookuptab[find].name) == 0) { 1.1 root 655: table68k[opc].mnemo = lookuptab[find].mnemo; 656: break; 1.1.1.2 ! root 657: } ! 658: if (strlen(lookuptab[find].name) == 0) abort(); 1.1 root 659: } 660: } 661: else { 662: table68k[opc].mnemo = lookuptab[find].mnemo; 663: } 664: table68k[opc].cc = bitval[bitc]; 665: if (table68k[opc].mnemo == i_BTST 666: || table68k[opc].mnemo == i_BSET 667: || table68k[opc].mnemo == i_BCLR 1.1.1.2 ! root 668: || table68k[opc].mnemo == i_BCHG) 1.1 root 669: { 670: sz = destmode == Dreg ? sz_long : sz_byte; 671: } 672: table68k[opc].size = sz; 673: table68k[opc].sreg = srcreg; 674: table68k[opc].dreg = destreg; 675: table68k[opc].smode = srcmode; 676: table68k[opc].dmode = destmode; 677: table68k[opc].spos = srcgather ? srcpos : -1; 678: table68k[opc].dpos = dstgather ? dstpos : -1; 679: table68k[opc].suse = usesrc; 680: table68k[opc].duse = usedst; 681: table68k[opc].stype = srctype; 682: table68k[opc].plev = id.plevel; 1.1.1.2 ! root 683: table68k[opc].clev = id.cpulevel; 1.1 root 684: #if 0 685: for (i = 0; i < 5; i++) { 686: table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; 687: table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; 688: } 689: #endif 690: table68k[opc].flagdead = flagdead; 691: table68k[opc].flaglive = flaglive; 692: nomatch: 693: /* FOO! */; 694: } 695: } 696: 697: 698: void read_table68k () 699: { 700: int i; 701: 1.1.1.2 ! root 702: table68k = (struct instr *)xmalloc (65536 * sizeof (struct instr)); 1.1 root 703: for(i = 0; i < 65536; i++) { 704: table68k[i].mnemo = i_ILLG; 705: table68k[i].handler = -1; 706: } 707: for (i = 0; i < n_defs68k; i++) { 708: build_insn (i); 709: } 710: } 711: 712: static int mismatch; 713: 714: static void handle_merges(long int opcode) 715: { 1.1.1.2 ! root 716: uae_u16 smsk; ! 717: uae_u16 dmsk; 1.1 root 718: int sbitdst, dstend; 719: int srcreg, dstreg; 1.1.1.2 ! root 720: 1.1 root 721: if (table68k[opcode].spos == -1) { 722: sbitdst = 1; smsk = 0; 1.1.1.2 ! root 723: } else { ! 724: switch (table68k[opcode].stype) { ! 725: case 0: 1.1 root 726: smsk = 7; sbitdst = 8; break; 1.1.1.2 ! root 727: case 1: 1.1 root 728: smsk = 255; sbitdst = 256; break; 1.1.1.2 ! root 729: case 2: 1.1 root 730: smsk = 15; sbitdst = 16; break; 1.1.1.2 ! root 731: case 3: 1.1 root 732: smsk = 7; sbitdst = 8; break; 1.1.1.2 ! root 733: case 4: 1.1 root 734: smsk = 7; sbitdst = 8; break; 1.1.1.2 ! root 735: case 5: 1.1 root 736: smsk = 63; sbitdst = 64; break; 1.1.1.2 ! root 737: default: 1.1 root 738: smsk = 0; sbitdst = 0; 739: abort(); 740: break; 1.1.1.2 ! root 741: } ! 742: smsk <<= table68k[opcode].spos; 1.1 root 743: } 744: if (table68k[opcode].dpos == -1) { 745: dstend = 1; dmsk = 0; 1.1.1.2 ! root 746: } else { ! 747: dmsk = 7 << table68k[opcode].dpos; 1.1 root 748: dstend = 8; 749: } 750: for (srcreg=0; srcreg < sbitdst; srcreg++) { 751: for (dstreg=0; dstreg < dstend; dstreg++) { 1.1.1.2 ! root 752: uae_u16 code = opcode; 1.1 root 753: 754: code = (code & ~smsk) | (srcreg << table68k[opcode].spos); 1.1.1.2 ! root 755: code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); ! 756: 1.1 root 757: /* Check whether this is in fact the same instruction. 758: * The instructions should never differ, except for the 759: * Bcc.(BW) case. */ 760: if (table68k[code].mnemo != table68k[opcode].mnemo 761: || table68k[code].size != table68k[opcode].size 762: || table68k[code].suse != table68k[opcode].suse 1.1.1.2 ! root 763: || table68k[code].duse != table68k[opcode].duse) 1.1 root 764: { 765: mismatch++; continue; 766: } 1.1.1.2 ! root 767: if (table68k[opcode].suse 1.1 root 768: && (table68k[opcode].spos != table68k[code].spos 769: || table68k[opcode].smode != table68k[code].smode 770: || table68k[opcode].stype != table68k[code].stype)) 771: { 772: mismatch++; continue; 773: } 1.1.1.2 ! root 774: if (table68k[opcode].duse 1.1 root 775: && (table68k[opcode].dpos != table68k[code].dpos 776: || table68k[opcode].dmode != table68k[code].dmode)) 777: { 778: mismatch++; continue; 779: } 1.1.1.2 ! root 780: 1.1 root 781: if (code != opcode) 782: table68k[code].handler = opcode; 783: } 784: } 785: } 786: 787: void do_merges () 788: { 789: long int opcode; 1.1.1.2 ! root 790: int nr = 0; 1.1 root 791: mismatch = 0; 792: for (opcode = 0; opcode < 65536; opcode++) { 793: if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) 794: continue; 1.1.1.2 ! root 795: nr++; 1.1 root 796: handle_merges (opcode); 797: } 1.1.1.2 ! root 798: nr_cpuop_funcs = nr; 1.1 root 799: } 800: 801: int get_no_mismatches () 802: { 803: return mismatch; 804: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.