|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * MC68000 emulation generator ! 5: * ! 6: * This is a fairly stupid program that generates a lot of case labels that ! 7: * can be #included in a switch statement. ! 8: * As an alternative, it can generate functions that handle specific ! 9: * MC68000 instructions, plus a prototype header file and a function pointer ! 10: * array to look up the function for an opcode. ! 11: * Error checking is bad, an illegal table68k file will cause the program to ! 12: * call abort(). ! 13: * The generated code is sometimes sub-optimal, an optimizing compiler should ! 14: * take care of this. ! 15: * ! 16: * (c) 1995 Bernd Schmidt ! 17: * ! 18: */ ! 19: ! 20: #include <assert.h> ! 21: #include <string.h> ! 22: #include <stdio.h> ! 23: #include <stdlib.h> ! 24: #include <ctype.h> ! 25: ! 26: #include "config.h" ! 27: #include "amiga.h" ! 28: ! 29: typedef enum { ! 30: Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, ! 31: absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg ! 32: } amodes; ! 33: ! 34: FILE *tablef; ! 35: int nextch = 0; ! 36: ! 37: typedef enum { ! 38: i_ILLG, ! 39: ! 40: i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR, ! 41: i_SUB, i_SUBA, i_SUBX, i_SBCD, ! 42: i_ADD, i_ADDA, i_ADDX, i_ABCD, ! 43: i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST, ! 44: i_BTST, i_BCHG, i_BCLR, i_BSET, ! 45: i_CMP, i_CMPM, i_CMPA, ! 46: i_MOVEP, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR, ! 47: i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE, ! 48: i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD, ! 49: i_LINK, i_UNLK, ! 50: i_RTS, i_TRAPV, i_RTR, ! 51: i_JSR, i_JMP, i_BSR, i_Bcc, ! 52: i_LEA, i_PEA, i_DBcc, i_Scc, ! 53: i_DIVU, i_DIVS, i_MULU, i_MULS, ! 54: i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR, ! 55: i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW ! 56: } instrmnem; ! 57: ! 58: struct mnemolookup { ! 59: instrmnem mnemo; ! 60: char name[10]; ! 61: } lookuptab[] = { ! 62: { i_OR, "OR" }, ! 63: { i_AND, "AND" }, ! 64: { i_EOR, "EOR" }, ! 65: { i_ORSR, "ORSR" }, ! 66: { i_ANDSR, "ANDSR" }, ! 67: { i_EORSR, "EORSR" }, ! 68: { i_SUB, "SUB" }, ! 69: { i_SUBA, "SUBA" }, ! 70: { i_SUBX, "SUBX" }, ! 71: { i_SBCD, "SBCD" }, ! 72: { i_ADD, "ADD" }, ! 73: { i_ADDA, "ADDA" }, ! 74: { i_ADDX, "ADDX" }, ! 75: { i_ABCD, "ABCD" }, ! 76: { i_NEG, "NEG" }, ! 77: { i_NEGX, "NEGX" }, ! 78: { i_NBCD, "NBCD" }, ! 79: { i_CLR, "CLR" }, ! 80: { i_NOT, "NOT" }, ! 81: { i_TST, "TST" }, ! 82: { i_BTST, "BTST" }, ! 83: { i_BCHG, "BCHG" }, ! 84: { i_BCLR, "BCLR" }, ! 85: { i_BSET, "BSET" }, ! 86: { i_CMP, "CMP" }, ! 87: { i_CMPM, "CMPM" }, ! 88: { i_CMPA, "CMPA" }, ! 89: { i_MOVEP, "MOVEP" }, ! 90: { i_MOVE, "MOVE" }, ! 91: { i_MOVEA, "MOVEA" }, ! 92: { i_MVSR2, "MVSR2" }, ! 93: { i_MV2SR, "MV2SR" }, ! 94: { i_SWAP, "SWAP" }, ! 95: { i_EXG, "EXG" }, ! 96: { i_EXT, "EXT" }, ! 97: { i_MVMEL, "MVMEL" }, ! 98: { i_MVMLE, "MVMLE" }, ! 99: { i_TRAP, "TRAP" }, ! 100: { i_MVR2USP, "MVR2USP" }, ! 101: { i_MVUSP2R, "MVUSP2R" }, ! 102: { i_RESET, "RESET" }, ! 103: { i_NOP, "NOP" }, ! 104: { i_STOP, "STOP" }, ! 105: { i_RTE, "RTE" }, ! 106: { i_RTD, "RTD" }, ! 107: { i_LINK, "LINK" }, ! 108: { i_UNLK, "UNLK" }, ! 109: { i_RTS, "RTS" }, ! 110: { i_TRAPV, "TRAPV" }, ! 111: { i_RTR, "RTR" }, ! 112: { i_JSR, "JSR" }, ! 113: { i_JMP, "JMP" }, ! 114: { i_BSR, "BSR" }, ! 115: { i_Bcc, "Bcc" }, ! 116: { i_LEA, "LEA" }, ! 117: { i_PEA, "PEA" }, ! 118: { i_DBcc, "DBcc" }, ! 119: { i_Scc, "Scc" }, ! 120: { i_DIVU, "DIVU" }, ! 121: { i_DIVS, "DIVS" }, ! 122: { i_MULU, "MULU" }, ! 123: { i_MULS, "MULS" }, ! 124: { i_ASR, "ASR" }, ! 125: { i_ASL, "ASL" }, ! 126: { i_LSR, "LSR" }, ! 127: { i_LSL, "LSL" }, ! 128: { i_ROL, "ROL" }, ! 129: { i_ROR, "ROR" }, ! 130: { i_ROXL, "ROXL" }, ! 131: { i_ROXR, "ROXR" }, ! 132: { i_ASRW, "ASRW" }, ! 133: { i_ASLW, "ASLW" }, ! 134: { i_LSRW, "LSRW" }, ! 135: { i_LSLW, "LSLW" }, ! 136: { i_ROLW, "ROLW" }, ! 137: { i_RORW, "RORW" }, ! 138: { i_ROXLW, "ROXLW" }, ! 139: { i_ROXRW, "ROXRW" } ! 140: }; ! 141: ! 142: char patbits[16]; ! 143: char opcstr[256]; ! 144: ! 145: UWORD bitmask,bitpattern; ! 146: ! 147: typedef enum { ! 148: bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bits, bitS, bitd, bitD, bitr, bitR, bitz, lastbit ! 149: } bitvals; ! 150: ! 151: typedef enum { ! 152: sz_unknown, sz_byte, sz_word, sz_long ! 153: } wordsizes; ! 154: ! 155: struct instr { ! 156: instrmnem mnemo; ! 157: wordsizes size; ! 158: amodes dmode, smode; ! 159: unsigned char dreg; ! 160: unsigned char sreg; ! 161: unsigned int suse:1; ! 162: unsigned int duse:1; ! 163: unsigned int sbtarg:1; ! 164: unsigned int generated:1; ! 165: unsigned int cc:4; ! 166: signed char dpos; ! 167: signed char spos; ! 168: UWORD handler; ! 169: } *table; ! 170: ! 171: #ifdef DEBUG ! 172: static void myabort(void) ! 173: { ! 174: abort(); ! 175: } ! 176: #else ! 177: #define myabort abort ! 178: #endif ! 179: static void getnextch(void) ! 180: { ! 181: do { ! 182: nextch = fgetc(tablef); ! 183: if (nextch == '%') { ! 184: do { ! 185: nextch = fgetc(tablef); ! 186: } while (nextch != EOF && nextch != '\n'); ! 187: } ! 188: } while (nextch != EOF && isspace(nextch)); ! 189: } ! 190: ! 191: static void get_bits(void) ! 192: { ! 193: int i; ! 194: ! 195: bitmask = bitpattern = 0; ! 196: for(i=0; i<16; i++) { ! 197: bitmask <<= 1; ! 198: bitpattern <<= 1; ! 199: if (nextch == '0' || nextch == '1') bitmask |= 1; ! 200: if (nextch == '1') bitpattern |= 1; ! 201: patbits[i] = nextch; ! 202: getnextch(); ! 203: } ! 204: } ! 205: ! 206: static amodes mode_from_str(char *str) ! 207: { ! 208: if (strncmp(str,"Dreg",4) == 0) return Dreg; ! 209: if (strncmp(str,"Areg",4) == 0) return Areg; ! 210: if (strncmp(str,"Aind",4) == 0) return Aind; ! 211: if (strncmp(str,"Apdi",4) == 0) return Apdi; ! 212: if (strncmp(str,"Aipi",4) == 0) return Aipi; ! 213: if (strncmp(str,"Ad16",4) == 0) return Ad16; ! 214: if (strncmp(str,"Ad8r",4) == 0) return Ad8r; ! 215: if (strncmp(str,"absw",4) == 0) return absw; ! 216: if (strncmp(str,"absl",4) == 0) return absl; ! 217: if (strncmp(str,"PC16",4) == 0) return PC16; ! 218: if (strncmp(str,"PC8r",4) == 0) return PC8r; ! 219: if (strncmp(str,"Immd",4) == 0) return imm; ! 220: myabort(); ! 221: } ! 222: ! 223: static amodes mode_from_mr(int mode, int reg) ! 224: { ! 225: switch(mode) { ! 226: case 0: return Dreg; ! 227: case 1: return Areg; ! 228: case 2: return Aind; ! 229: case 3: return Aipi; ! 230: case 4: return Apdi; ! 231: case 5: return Ad16; ! 232: case 6: return Ad8r; ! 233: case 7: ! 234: switch(reg) { ! 235: case 0: return absw; ! 236: case 1: return absl; ! 237: case 2: return PC16; ! 238: case 3: return PC8r; ! 239: case 4: return imm; ! 240: case 5: ! 241: case 6: ! 242: case 7: return am_illg; ! 243: } ! 244: } ! 245: myabort(); ! 246: } ! 247: ! 248: static void get_strs(void) ! 249: { ! 250: fgets(opcstr, 250, tablef); ! 251: getnextch(); ! 252: } ! 253: ! 254: static void parse_bits(void) ! 255: { ! 256: int find; ! 257: long int opc; ! 258: ! 259: for(opc = 0; opc < 65536; opc ++) { ! 260: if ((opc & bitmask) == bitpattern) { ! 261: int bitcnt[lastbit]; ! 262: int bitval[lastbit]; ! 263: int bitpos[lastbit]; ! 264: int i,j; ! 265: ! 266: UWORD msk = 0x8000; ! 267: ! 268: int pos = 0; ! 269: ! 270: int mnp = 0; ! 271: char mnemonic[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ! 272: wordsizes sz = sz_unknown; ! 273: bool srcgather = false, dstgather = false; ! 274: bool usesrc = false, usedst = false; ! 275: bool srcbtarg = false; ! 276: int srcpos, dstpos; ! 277: ! 278: amodes srcmode = am_unknown, destmode = am_unknown; ! 279: int srcreg, destreg; ! 280: ! 281: for(i=0; i < lastbit; i++) bitcnt[i] = bitval[i] = 0; ! 282: ! 283: for(j=0; j < 16; j++, msk >>= 1) { ! 284: bitvals currbit; ! 285: switch(patbits[j]) { ! 286: case '0': currbit = bit0; break; ! 287: case '1': currbit = bit1; break; ! 288: case 'c': currbit = bitc; break; ! 289: case 'C': currbit = bitC; break; ! 290: case 'f': currbit = bitf; break; ! 291: case 'i': currbit = biti; break; ! 292: case 'I': currbit = bitI; break; ! 293: case 'j': currbit = bitj; break; ! 294: case 'J': currbit = bitJ; break; ! 295: case 's': currbit = bits; break; ! 296: case 'S': currbit = bitS; break; ! 297: case 'd': currbit = bitd; break; ! 298: case 'D': currbit = bitD; break; ! 299: case 'r': currbit = bitr; break; ! 300: case 'R': currbit = bitR; break; ! 301: case 'z': currbit = bitz; break; ! 302: default: myabort(); ! 303: } ! 304: bitpos[currbit] = 15 - j; ! 305: bitcnt[currbit]++; ! 306: bitval[currbit] = (bitval[currbit] << 1) | ((opc & msk) ? 1 : 0); ! 307: } ! 308: if (bitval[bitj] == 0) bitval[bitj] = 8; ! 309: /* first check whether this one does not match after all */ ! 310: if (bitval[bitz] == 3) continue; ! 311: if (bitval[bitC] == 1) continue; ! 312: if (bitcnt[bitI] && bitval[bitI] == 0) continue; ! 313: ! 314: /* bitI and bitC get copied to biti and bitc */ ! 315: if (bitcnt[bitI]) { bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; } ! 316: if (bitcnt[bitC]) bitval[bitc] = bitval[bitC]; ! 317: ! 318: while (isspace(opcstr[pos]) || opcstr[pos] == ':') pos++; ! 319: while (!isspace(opcstr[pos])) { ! 320: if (opcstr[pos] == '.') { ! 321: pos++; ! 322: switch(opcstr[pos]) { ! 323: ! 324: case 'B': sz = sz_byte; break; ! 325: case 'W': sz = sz_word; break; ! 326: case 'L': sz = sz_long; break; ! 327: case 'z': ! 328: switch(bitval[bitz]) { ! 329: case 0: sz = sz_byte; break; ! 330: case 1: sz = sz_word; break; ! 331: case 2: sz = sz_long; break; ! 332: default: myabort(); ! 333: } ! 334: break; ! 335: default: myabort(); ! 336: } ! 337: } else { ! 338: mnemonic[mnp] = opcstr[pos]; ! 339: if(mnemonic[mnp] == 'f') { ! 340: switch(bitval[bitf]) { ! 341: case 0: mnemonic[mnp] = 'R'; break; ! 342: case 1: mnemonic[mnp] = 'L'; break; ! 343: default: myabort(); ! 344: } ! 345: } ! 346: mnp++; ! 347: } ! 348: pos++; ! 349: } ! 350: ! 351: /* now, we have read the mnemonic and the size */ ! 352: while (isspace(opcstr[pos])) pos++; ! 353: ! 354: /* A goto a day keeps the D******a away. */ ! 355: if (opcstr[pos] == 0 || opcstr[pos] == ':') goto endofline; ! 356: ! 357: /* parse the source address */ ! 358: usesrc = true; ! 359: switch(opcstr[pos++]) { ! 360: case 'D': ! 361: srcmode = Dreg; ! 362: switch (opcstr[pos++]) { ! 363: case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break; ! 364: case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break; ! 365: default: myabort(); ! 366: } ! 367: ! 368: break; ! 369: case 'A': ! 370: srcmode = Areg; ! 371: switch (opcstr[pos++]) { ! 372: case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break; ! 373: case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break; ! 374: default: myabort(); ! 375: } ! 376: switch (opcstr[pos]) { ! 377: case 'p': srcmode = Apdi; pos++; break; ! 378: case 'P': srcmode = Aipi; pos++; break; ! 379: } ! 380: break; ! 381: case '#': ! 382: switch(opcstr[pos++]) { ! 383: case 'z': srcmode = imm; break; ! 384: case '0': srcmode = imm0; break; ! 385: case '1': srcmode = imm1; break; ! 386: case '2': srcmode = imm2; break; ! 387: case 'i': srcmode = immi; srcreg = (LONG)(BYTE)bitval[biti]; srcbtarg = true; srcgather = true; srcpos = bitpos[biti]; break; ! 388: case 'j': srcmode = immi; srcreg = bitval[bitj]; break; ! 389: case 'J': srcmode = immi; srcreg = bitval[bitJ]; break; ! 390: default: myabort(); ! 391: } ! 392: break; ! 393: case 'd': ! 394: srcreg = bitval[bitD]; ! 395: srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); ! 396: if (srcmode == am_illg) continue; ! 397: if (srcmode == Areg || srcmode == Dreg || srcmode == Aind ! 398: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi ! 399: || srcmode == Apdi) ! 400: { ! 401: srcgather = true; srcpos = bitpos[bitD]; ! 402: } ! 403: if (opcstr[pos] == '[') { ! 404: pos++; ! 405: if (opcstr[pos] == '!') { ! 406: /* exclusion */ ! 407: do { ! 408: pos++; ! 409: if (mode_from_str(opcstr+pos) == srcmode) goto nomatch; ! 410: pos += 4; ! 411: } while (opcstr[pos] == ','); ! 412: pos++; ! 413: } else { ! 414: if (opcstr[pos+4] == '-') { ! 415: /* replacement */ ! 416: if (mode_from_str(opcstr+pos) == srcmode) ! 417: srcmode = mode_from_str(opcstr+pos+5); ! 418: else ! 419: goto nomatch; ! 420: pos += 10; ! 421: } else { ! 422: /* normal */ ! 423: while(mode_from_str(opcstr+pos) != srcmode) { ! 424: pos += 4; ! 425: if (opcstr[pos] == ']') 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) ! 436: goto nomatch; ! 437: break; ! 438: case 's': ! 439: srcreg = bitval[bitS]; ! 440: srcmode = mode_from_mr(bitval[bits],bitval[bitS]); ! 441: ! 442: if(srcmode == am_illg) continue; ! 443: if (srcmode == Areg || srcmode == Dreg || srcmode == Aind ! 444: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi ! 445: || srcmode == Apdi) ! 446: { ! 447: srcgather = true; srcpos = bitpos[bitS]; ! 448: } ! 449: if (opcstr[pos] == '[') { ! 450: pos++; ! 451: if (opcstr[pos] == '!') { ! 452: /* exclusion */ ! 453: do { ! 454: pos++; ! 455: if (mode_from_str(opcstr+pos) == srcmode) goto nomatch; ! 456: pos += 4; ! 457: } while (opcstr[pos] == ','); ! 458: pos++; ! 459: } else { ! 460: if (opcstr[pos+4] == '-') { ! 461: /* replacement */ ! 462: if (mode_from_str(opcstr+pos) == srcmode) ! 463: srcmode = mode_from_str(opcstr+pos+5); ! 464: else ! 465: goto nomatch; ! 466: pos += 10; ! 467: } else { ! 468: /* normal */ ! 469: while(mode_from_str(opcstr+pos) != srcmode) { ! 470: pos += 4; ! 471: if (opcstr[pos] == ']') goto nomatch; ! 472: pos++; ! 473: } ! 474: while(opcstr[pos] != ']') pos++; ! 475: pos++; ! 476: } ! 477: } ! 478: } ! 479: break; ! 480: default: myabort(); ! 481: } ! 482: /* safety check - might have changed */ ! 483: if (srcmode != Areg && srcmode != Dreg && srcmode != Aind ! 484: && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi ! 485: && srcmode != Apdi && srcmode != immi) ! 486: { ! 487: srcgather = false; ! 488: } ! 489: if (srcmode == Areg && sz == sz_byte) ! 490: goto nomatch; ! 491: ! 492: if (opcstr[pos] != ',') goto endofline; ! 493: pos++; ! 494: ! 495: /* parse the destination address */ ! 496: usedst = true; ! 497: switch(opcstr[pos++]) { ! 498: case 'D': ! 499: destmode = Dreg; ! 500: switch (opcstr[pos++]) { ! 501: case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break; ! 502: case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break; ! 503: default: myabort(); ! 504: } ! 505: break; ! 506: case 'A': ! 507: destmode = Areg; ! 508: switch (opcstr[pos++]) { ! 509: case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break; ! 510: case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break; ! 511: default: myabort(); ! 512: } ! 513: switch (opcstr[pos]) { ! 514: case 'p': destmode = Apdi; pos++; break; ! 515: case 'P': destmode = Aipi; pos++; break; ! 516: } ! 517: break; ! 518: case '#': ! 519: switch(opcstr[pos++]) { ! 520: case 'z': destmode = imm; break; ! 521: case '0': destmode = imm0; break; ! 522: case '1': destmode = imm1; break; ! 523: case '2': destmode = imm2; break; ! 524: case 'i': destmode = immi; destreg = (LONG)(BYTE)bitval[biti]; break; ! 525: case 'j': destmode = immi; destreg = bitval[bitj]; break; ! 526: case 'J': destmode = immi; destreg = bitval[bitJ]; break; ! 527: default: myabort(); ! 528: } ! 529: break; ! 530: case 'd': ! 531: destreg = bitval[bitD]; ! 532: destmode = mode_from_mr(bitval[bitd],bitval[bitD]); ! 533: if(destmode == am_illg) continue; ! 534: if (destmode == Areg || destmode == Dreg || destmode == Aind ! 535: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi ! 536: || destmode == Apdi) ! 537: { ! 538: dstgather = true; dstpos = bitpos[bitD]; ! 539: } ! 540: ! 541: if (opcstr[pos] == '[') { ! 542: pos++; ! 543: if (opcstr[pos] == '!') { ! 544: /* exclusion */ ! 545: do { ! 546: pos++; ! 547: if (mode_from_str(opcstr+pos) == destmode) goto nomatch; ! 548: pos += 4; ! 549: } while (opcstr[pos] == ','); ! 550: pos++; ! 551: } else { ! 552: if (opcstr[pos+4] == '-') { ! 553: /* replacement */ ! 554: if (mode_from_str(opcstr+pos) == destmode) ! 555: destmode = mode_from_str(opcstr+pos+5); ! 556: else ! 557: goto nomatch; ! 558: pos += 10; ! 559: } else { ! 560: /* normal */ ! 561: while(mode_from_str(opcstr+pos) != destmode) { ! 562: pos += 4; ! 563: if (opcstr[pos] == ']') goto nomatch; ! 564: pos++; ! 565: } ! 566: while(opcstr[pos] != ']') pos++; ! 567: pos++; ! 568: break; ! 569: } ! 570: } ! 571: } ! 572: /* Some addressing modes are invalid as destination */ ! 573: if (destmode == imm || destmode == PC16 || destmode == PC8r) ! 574: goto nomatch; ! 575: break; ! 576: case 's': ! 577: destreg = bitval[bitS]; ! 578: destmode = mode_from_mr(bitval[bits],bitval[bitS]); ! 579: ! 580: if(destmode == am_illg) continue; ! 581: if (destmode == Areg || destmode == Dreg || destmode == Aind ! 582: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi ! 583: || destmode == Apdi) ! 584: { ! 585: dstgather = true; dstpos = bitpos[bitS]; ! 586: } ! 587: ! 588: if (opcstr[pos] == '[') { ! 589: pos++; ! 590: if (opcstr[pos] == '!') { ! 591: /* exclusion */ ! 592: do { ! 593: pos++; ! 594: if (mode_from_str(opcstr+pos) == destmode) goto nomatch; ! 595: pos += 4; ! 596: } while (opcstr[pos] == ','); ! 597: pos++; ! 598: } else { ! 599: if (opcstr[pos+4] == '-') { ! 600: /* replacement */ ! 601: if (mode_from_str(opcstr+pos) == destmode) ! 602: destmode = mode_from_str(opcstr+pos+5); ! 603: else ! 604: goto nomatch; ! 605: pos += 10; ! 606: } else { ! 607: /* normal */ ! 608: while(mode_from_str(opcstr+pos) != destmode) { ! 609: pos += 4; ! 610: if (opcstr[pos] == ']') goto nomatch; ! 611: pos++; ! 612: } ! 613: while(opcstr[pos] != ']') pos++; ! 614: pos++; ! 615: } ! 616: } ! 617: } ! 618: break; ! 619: default: myabort(); ! 620: } ! 621: /* safety check - might have changed */ ! 622: if (destmode != Areg && destmode != Dreg && destmode != Aind ! 623: && destmode != Ad16 && destmode != Ad8r && destmode != Aipi ! 624: && destmode != Apdi) ! 625: { ! 626: dstgather = false; ! 627: } ! 628: ! 629: if (destmode == Areg && sz == sz_byte) ! 630: goto nomatch; ! 631: #if 0 ! 632: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { ! 633: dstgather = false; ! 634: } ! 635: #endif ! 636: endofline: ! 637: /* now, we have a match */ ! 638: if (table[opc].mnemo != i_ILLG) ! 639: fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); ! 640: for(find = 0;; find++) { ! 641: if (strcmp(mnemonic, lookuptab[find].name) == 0) { ! 642: table[opc].mnemo = lookuptab[find].mnemo; ! 643: break; ! 644: } ! 645: if (strlen(lookuptab[find].name) == 0) myabort(); ! 646: } ! 647: table[opc].cc = bitval[bitc]; ! 648: if (table[opc].mnemo == i_BTST ! 649: || table[opc].mnemo == i_BSET ! 650: || table[opc].mnemo == i_BCLR ! 651: || table[opc].mnemo == i_BCHG) ! 652: { ! 653: sz = destmode == Dreg ? sz_long : sz_byte; ! 654: } ! 655: table[opc].generated = false; ! 656: table[opc].size = sz; ! 657: table[opc].sreg = srcreg; ! 658: table[opc].dreg = destreg; ! 659: table[opc].smode = srcmode; ! 660: table[opc].dmode = destmode; ! 661: table[opc].spos = srcgather ? srcpos : -1; ! 662: table[opc].dpos = dstgather ? dstpos : -1; ! 663: table[opc].suse = usesrc; ! 664: table[opc].duse = usedst; ! 665: table[opc].sbtarg = srcbtarg; ! 666: nomatch: ! 667: /* FOO! */; ! 668: } ! 669: } ! 670: } ! 671: ! 672: static int n_braces = 0; ! 673: ! 674: static void start_brace(void) ! 675: { ! 676: n_braces++; ! 677: printf("{"); ! 678: } ! 679: ! 680: static void close_brace(void) ! 681: { ! 682: assert (n_braces > 0); ! 683: n_braces--; ! 684: printf("}"); ! 685: } ! 686: ! 687: static void finish_braces(void) ! 688: { ! 689: while (n_braces > 0) ! 690: close_brace(); ! 691: } ! 692: ! 693: static void pop_braces(int to) ! 694: { ! 695: while (n_braces > to) ! 696: close_brace(); ! 697: } ! 698: ! 699: static void genamode(amodes mode, char *reg, wordsizes size, char *name, bool getv, bool movem) ! 700: { ! 701: start_brace (); ! 702: switch(mode) { ! 703: case Dreg: ! 704: if (movem) ! 705: abort(); ! 706: if (getv) ! 707: switch(size) { ! 708: case sz_byte: ! 709: printf("\tBYTE %s = regs.d[%s];\n", name, reg); ! 710: break; ! 711: case sz_word: ! 712: printf("\tWORD %s = regs.d[%s];\n", name, reg); ! 713: break; ! 714: case sz_long: ! 715: printf("\tLONG %s = regs.d[%s];\n", name, reg); ! 716: break; ! 717: default: myabort(); ! 718: } ! 719: break; ! 720: case Areg: ! 721: if (movem) ! 722: abort(); ! 723: if (getv) ! 724: switch(size) { ! 725: case sz_word: ! 726: printf("\tWORD %s = regs.a[%s];\n", name, reg); ! 727: break; ! 728: case sz_long: ! 729: printf("\tLONG %s = regs.a[%s];\n", name, reg); ! 730: break; ! 731: default: myabort(); ! 732: } ! 733: break; ! 734: case Aind: ! 735: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 736: if (getv) ! 737: switch(size) { ! 738: case sz_byte: ! 739: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 740: break; ! 741: case sz_word: ! 742: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 743: break; ! 744: case sz_long: ! 745: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 746: break; ! 747: default: myabort(); ! 748: } ! 749: break; ! 750: case Aipi: ! 751: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 752: switch(size) { ! 753: case sz_byte: ! 754: if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 755: if (!movem) { ! 756: start_brace(); ! 757: printf("\tregs.a[%s] += (%s == 7) ? 2 : 1;\n", reg, reg); ! 758: } ! 759: break; ! 760: case sz_word: ! 761: if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name); ! 762: if (!movem) { ! 763: start_brace(); ! 764: printf("\tregs.a[%s] += 2;\n", reg); ! 765: } ! 766: break; ! 767: case sz_long: ! 768: if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name); ! 769: if (!movem) { ! 770: start_brace(); ! 771: printf("\tregs.a[%s] += 4;\n", reg); ! 772: } ! 773: break; ! 774: default: myabort(); ! 775: } ! 776: break; ! 777: case Apdi: ! 778: switch(size) { ! 779: case sz_byte: ! 780: if (!movem) printf("\tregs.a[%s] -= (%s == 7) ? 2 : 1;\n", reg, reg); ! 781: start_brace(); ! 782: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 783: if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 784: break; ! 785: case sz_word: ! 786: if (!movem) printf("\tregs.a[%s] -= 2;\n", reg); ! 787: start_brace(); ! 788: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 789: if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name); ! 790: break; ! 791: case sz_long: ! 792: if (!movem) printf("\tregs.a[%s] -= 4;\n", reg); ! 793: start_brace(); ! 794: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 795: if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name); ! 796: break; ! 797: default: myabort(); ! 798: } ! 799: break; ! 800: case Ad16: ! 801: printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg); ! 802: if (getv) ! 803: switch(size) { ! 804: case sz_byte: ! 805: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 806: break; ! 807: case sz_word: ! 808: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 809: break; ! 810: case sz_long: ! 811: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 812: break; ! 813: default: myabort(); ! 814: } ! 815: break; ! 816: case Ad8r: ! 817: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); ! 818: printf("\tUWORD %sdp = nextiword();\n", name); ! 819: printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name); ! 820: start_brace(); ! 821: printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name); ! 822: printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name); ! 823: printf("\t%sa += %sdpr;\n", name, name); ! 824: if (getv) { ! 825: start_brace(); ! 826: switch(size) { ! 827: case sz_byte: ! 828: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 829: break; ! 830: case sz_word: ! 831: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 832: break; ! 833: case sz_long: ! 834: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 835: break; ! 836: default: myabort(); ! 837: } ! 838: } ! 839: break; ! 840: case PC16: ! 841: printf("\tCPTR %sa = m68k_getpc();\n", name); ! 842: printf("\t%sa += (LONG)(WORD)nextiword();\n", name); ! 843: if (getv) { ! 844: start_brace(); ! 845: switch(size) { ! 846: case sz_byte: ! 847: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 848: break; ! 849: case sz_word: ! 850: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 851: break; ! 852: case sz_long: ! 853: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 854: break; ! 855: default: myabort(); ! 856: } ! 857: } ! 858: break; ! 859: case PC8r: ! 860: printf("\tCPTR %sa = m68k_getpc();\n", name); ! 861: printf("\tUWORD %sdp = nextiword();\n", name); ! 862: printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name); ! 863: start_brace(); ! 864: printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name); ! 865: printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name); ! 866: printf("\t%sa += %sdpr;\n", name, name); ! 867: if (getv) { ! 868: start_brace(); ! 869: switch(size) { ! 870: case sz_byte: ! 871: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 872: break; ! 873: case sz_word: ! 874: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 875: break; ! 876: case sz_long: ! 877: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 878: break; ! 879: default: myabort(); ! 880: } ! 881: } ! 882: break; ! 883: case absw: ! 884: printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name); ! 885: if (getv) ! 886: switch(size) { ! 887: case sz_byte: ! 888: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 889: break; ! 890: case sz_word: ! 891: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 892: break; ! 893: case sz_long: ! 894: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 895: break; ! 896: default: myabort(); ! 897: } ! 898: break; ! 899: case absl: ! 900: printf("\tCPTR %sa = nextilong();\n", name); ! 901: if (getv) ! 902: switch(size) { ! 903: case sz_byte: ! 904: printf("\tBYTE %s = get_byte(%sa);\n", name, name); ! 905: break; ! 906: case sz_word: ! 907: printf("\tWORD %s = get_word(%sa);\n", name, name); ! 908: break; ! 909: case sz_long: ! 910: printf("\tLONG %s = get_long(%sa);\n", name, name); ! 911: break; ! 912: default: myabort(); ! 913: } ! 914: break; ! 915: case imm: ! 916: if (getv) ! 917: switch(size) { ! 918: case sz_byte: ! 919: printf("\tBYTE %s = nextiword();\n", name); ! 920: break; ! 921: case sz_word: ! 922: printf("\tWORD %s = nextiword();\n", name); ! 923: break; ! 924: case sz_long: ! 925: printf("\tLONG %s = nextilong();\n", name); ! 926: break; ! 927: default: myabort(); ! 928: } ! 929: break; ! 930: case imm0: ! 931: if (!getv) myabort(); ! 932: printf("\tBYTE %s = nextiword();\n", name); ! 933: break; ! 934: case imm1: ! 935: if (!getv) myabort(); ! 936: printf("\tWORD %s = nextiword();\n", name); ! 937: break; ! 938: case imm2: ! 939: if (!getv) myabort(); ! 940: printf("\tLONG %s = nextilong();\n", name); ! 941: break; ! 942: case immi: ! 943: if (!getv) myabort(); ! 944: printf("\tULONG %s = %s;\n", name, reg); ! 945: break; ! 946: default: ! 947: myabort(); ! 948: } ! 949: } ! 950: ! 951: static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to) ! 952: { ! 953: switch(mode) { ! 954: case Dreg: ! 955: switch(size) { ! 956: case sz_byte: ! 957: printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from); ! 958: break; ! 959: case sz_word: ! 960: printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from); ! 961: break; ! 962: case sz_long: ! 963: printf("\tregs.d[%s] = (%s);\n", reg, from); ! 964: break; ! 965: default: myabort(); ! 966: } ! 967: break; ! 968: case Areg: ! 969: switch(size) { ! 970: case sz_word: ! 971: printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from); ! 972: break; ! 973: case sz_long: ! 974: printf("\tregs.a[%s] = (%s);\n", reg, from); ! 975: break; ! 976: default: myabort(); ! 977: } ! 978: break; ! 979: case Aind: ! 980: case Aipi: ! 981: case Apdi: ! 982: case Ad16: ! 983: case Ad8r: ! 984: case absw: ! 985: case absl: ! 986: switch(size) { ! 987: case sz_byte: ! 988: printf("\tput_byte(%sa,%s);\n", to, from); ! 989: break; ! 990: case sz_word: ! 991: printf("\tput_word(%sa,%s);\n", to, from); ! 992: break; ! 993: case sz_long: ! 994: printf("\tput_long(%sa,%s);\n", to, from); ! 995: break; ! 996: default: myabort(); ! 997: } ! 998: break; ! 999: case PC16: ! 1000: case PC8r: ! 1001: switch(size) { ! 1002: case sz_byte: ! 1003: printf("\tput_byte(%sa,%s);\n", to, from); ! 1004: break; ! 1005: /* These are only used for byte-sized bit ops */ ! 1006: default: myabort(); ! 1007: } ! 1008: break; ! 1009: case imm: ! 1010: case imm0: ! 1011: case imm1: ! 1012: case imm2: ! 1013: case immi: ! 1014: myabort(); ! 1015: break; ! 1016: default: ! 1017: myabort(); ! 1018: } ! 1019: } ! 1020: ! 1021: static void genmovemel(UWORD opcode) ! 1022: { ! 1023: char getcode[100]; ! 1024: int size = table[opcode].size == sz_long ? 4 : 2; ! 1025: ! 1026: if (table[opcode].size == sz_long) { ! 1027: strcpy(getcode, "get_long(srca)"); ! 1028: } else { ! 1029: strcpy(getcode, "(LONG)(WORD)get_word(srca)"); ! 1030: } ! 1031: ! 1032: printf("\tUWORD mask = nextiword(), bitmask = mask;\n"); ! 1033: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true); ! 1034: start_brace(); ! 1035: printf("\tint i, bitcnt = 0;\n"); ! 1036: printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n"); ! 1037: ! 1038: printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.d[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size); ! 1039: printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.a[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size); ! 1040: ! 1041: if (table[opcode].smode == Aipi) ! 1042: printf("\tregs.a[srcreg] = srca;\n"); ! 1043: } ! 1044: ! 1045: static void genmovemle(UWORD opcode) ! 1046: { ! 1047: char putcode[100], shiftcode[] = ">>"; ! 1048: int size = table[opcode].size == sz_long ? 4 : 2; ! 1049: int mask = 1; ! 1050: if (table[opcode].size == sz_long) { ! 1051: strcpy(putcode, "put_long(srca,"); ! 1052: } else { ! 1053: strcpy(putcode, "put_word(srca,"); ! 1054: } ! 1055: ! 1056: printf("\tUWORD mask = nextiword(), bitmask = mask;\n"); ! 1057: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true); ! 1058: start_brace(); ! 1059: printf("\tint i, bitcnt = 0;\n"); ! 1060: printf("\tULONG rd[8], ra[8];\n"); ! 1061: printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n"); ! 1062: printf("\tfor(i=0;i<8;i++) { rd[i] = regs.d[i]; ra[i] = regs.a[i]; }\n"); ! 1063: if (table[opcode].smode == Apdi) { ! 1064: printf("\tsrca -= %d*bitcnt;\n", size); ! 1065: printf("\tregs.a[srcreg] = srca;\n"); ! 1066: strcpy(shiftcode, "<<"); ! 1067: mask = 0x8000; ! 1068: } ! 1069: ! 1070: printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s rd[i]); srca += %d; } mask %s= 1; }\n", ! 1071: mask, putcode, size, shiftcode); ! 1072: printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s ra[i]); srca += %d; } mask %s= 1; }\n", ! 1073: mask, putcode, size, shiftcode); ! 1074: } ! 1075: ! 1076: typedef enum { ! 1077: flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn ! 1078: } flagtypes; ! 1079: ! 1080: static void genflags(flagtypes type, wordsizes size, char *value, char *src, char *dst) ! 1081: { ! 1082: char vstr[100],sstr[100],dstr[100]; ! 1083: char usstr[100],udstr[100]; ! 1084: char unsstr[100],undstr[100]; ! 1085: ULONG mask; ! 1086: switch(size) { ! 1087: case sz_byte: mask = 0xFF; break; ! 1088: case sz_word: mask = 0xFFFF; break; ! 1089: case sz_long: mask = 0xFFFFFFFF; break; ! 1090: default: myabort(); ! 1091: } ! 1092: #ifndef NO_INLINE_FLAGS ! 1093: switch(size) { ! 1094: case sz_byte: ! 1095: strcpy(vstr, "((BYTE)("); ! 1096: strcpy(usstr, "((UBYTE)("); ! 1097: break; ! 1098: case sz_word: ! 1099: strcpy(vstr, "((WORD)("); ! 1100: strcpy(usstr, "((UWORD)("); ! 1101: break; ! 1102: case sz_long: ! 1103: strcpy(vstr, "((LONG)("); ! 1104: strcpy(usstr, "((ULONG)("); ! 1105: break; ! 1106: default: ! 1107: myabort(); ! 1108: } ! 1109: strcpy(unsstr, usstr); ! 1110: ! 1111: strcpy(sstr, vstr); ! 1112: strcpy(dstr, vstr); ! 1113: strcat(vstr, value); strcat(vstr,"))"); ! 1114: strcat(dstr, dst); strcat(dstr,"))"); ! 1115: strcat(sstr, src); strcat(sstr,"))"); ! 1116: ! 1117: strcpy(udstr, usstr); ! 1118: strcat(udstr, dst); strcat(udstr,"))"); ! 1119: strcat(usstr, src); strcat(usstr,"))"); ! 1120: ! 1121: strcpy(undstr, unsstr); ! 1122: strcat(unsstr, "-"); ! 1123: strcat(undstr, "~"); ! 1124: strcat(undstr, dst); strcat(undstr,"))"); ! 1125: strcat(unsstr, src); strcat(unsstr,"))"); ! 1126: ! 1127: switch(type) { ! 1128: case flag_logical: ! 1129: printf("\tregs.v = regs.c = 0;\n"); ! 1130: /* fall through */ ! 1131: case flag_zn: ! 1132: switch(size) { ! 1133: case sz_byte: ! 1134: printf("\tregs.z = %s == 0;\n", vstr); ! 1135: printf("\tregs.n = %s < 0;\n", vstr); ! 1136: break; ! 1137: case sz_word: ! 1138: printf("\tregs.z = %s == 0;\n", vstr); ! 1139: printf("\tregs.n = %s < 0;\n", vstr); ! 1140: break; ! 1141: case sz_long: ! 1142: printf("\tregs.z = %s == 0;\n", vstr); ! 1143: printf("\tregs.n = %s < 0;\n", vstr); ! 1144: break; ! 1145: default: ! 1146: myabort(); ! 1147: } ! 1148: break; ! 1149: case flag_add: ! 1150: start_brace(); ! 1151: printf("\tbool flgs = %s < 0;\n", sstr); ! 1152: printf("\tbool flgo = %s < 0;\n", dstr); ! 1153: printf("\tbool flgn = %s < 0;\n", vstr); ! 1154: printf("\tregs.z = %s == 0;\n", vstr); ! 1155: printf("\tregs.v = (flgs == flgo) && (flgn != flgo);\n"); ! 1156: printf("\tregs.c = regs.x = %s < %s;\n", undstr, usstr); ! 1157: printf("\tregs.n = flgn != 0;\n"); ! 1158: break; ! 1159: case flag_sub: ! 1160: start_brace(); ! 1161: printf("\tbool flgs = %s < 0;\n", sstr); ! 1162: printf("\tbool flgo = %s < 0;\n", dstr); ! 1163: printf("\tbool flgn = %s < 0;\n", vstr); ! 1164: printf("\tregs.z = %s == 0;\n", vstr); ! 1165: printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n"); ! 1166: printf("\tregs.c = regs.x = %s > %s;\n", usstr, udstr); ! 1167: printf("\tregs.n = flgn != 0;\n"); ! 1168: break; ! 1169: case flag_addx: ! 1170: start_brace(); ! 1171: printf("\tbool flgs = %s < 0;\n", sstr); ! 1172: printf("\tbool flgo = %s < 0;\n", dstr); ! 1173: printf("\tbool flgn = %s < 0;\n", vstr); ! 1174: printf("\tif ((flgs && flgo && !flgn) || (!flgs && !flgo && flgn)) regs.v = 1;\n"); ! 1175: printf("\tif ((flgs && flgo) || (!flgn && (flgo || flgs))) regs.c = regs.x = 1;\n"); ! 1176: break; ! 1177: case flag_subx: ! 1178: start_brace(); ! 1179: printf("\tbool flgs = %s < 0;\n", sstr); ! 1180: printf("\tbool flgo = %s < 0;\n", dstr); ! 1181: printf("\tbool flgn = %s < 0;\n", vstr); ! 1182: printf("\tif ((!flgs && flgo && !flgn) || (flgs && !flgo && flgn)) regs.v = 1;\n"); ! 1183: printf("\tif ((flgs && !flgo) || (flgn && (!flgo || flgs))) regs.c = regs.x = 1;\n"); ! 1184: break; ! 1185: case flag_cmp: ! 1186: start_brace(); ! 1187: printf("\tbool flgs = %s < 0;\n", sstr); ! 1188: printf("\tbool flgo = %s < 0;\n", dstr); ! 1189: printf("\tbool flgn = %s < 0;\n", vstr); ! 1190: printf("\tregs.z = %s == 0;\n", vstr); ! 1191: printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n"); ! 1192: printf("\tregs.c = %s > %s;\n", usstr, udstr); ! 1193: printf("\tregs.n = flgn != 0;\n"); ! 1194: break; ! 1195: } ! 1196: #else ! 1197: switch(type) { ! 1198: case flag_logical: ! 1199: printf("\tsetflags_logical(%s,%s);\n", value, mask); ! 1200: break; ! 1201: case flag_add: ! 1202: printf("\tsetflags_add(%s,%s,%s);\n", src, dest, value); ! 1203: break; ! 1204: case flag_sub: ! 1205: printf("\tsetflags_sub(%s,%s,%s);\n", src, dest, value); ! 1206: break; ! 1207: case flag_addx: ! 1208: printf("\tsetflags_addx(%s,%s,%s);\n", src, dest, value); ! 1209: break; ! 1210: case flag_subx: ! 1211: printf("\tsetflags_subx(%s,%s,%s);\n", src, dest, value); ! 1212: break; ! 1213: case flag_cmp: ! 1214: printf("\tsetflags_cmp(%s,%s,%s);\n", src, dest, value); ! 1215: break; ! 1216: } ! 1217: #endif ! 1218: } ! 1219: ! 1220: static void gen_opcode(unsigned long int opcode) ! 1221: { ! 1222: start_brace (); ! 1223: switch(table[opcode].mnemo) { ! 1224: case i_OR: ! 1225: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1226: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1227: printf("\tsrc |= dst;\n"); ! 1228: genflags(flag_logical, table[opcode].size, "src", "", ""); ! 1229: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1230: break; ! 1231: case i_AND: ! 1232: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1233: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1234: printf("\tsrc &= dst;\n"); ! 1235: genflags(flag_logical, table[opcode].size, "src", "", ""); ! 1236: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1237: break; ! 1238: case i_EOR: ! 1239: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1240: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1241: printf("\tsrc ^= dst;\n"); ! 1242: genflags(flag_logical, table[opcode].size, "src", "", ""); ! 1243: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1244: break; ! 1245: case i_ORSR: ! 1246: if (table[opcode].size != sz_byte) { ! 1247: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n"); ! 1248: } ! 1249: start_brace (); ! 1250: printf("\tMakeSR();\n"); ! 1251: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1252: if (table[opcode].size == sz_byte) { ! 1253: printf("\tsrc &= 0xFF;\n"); ! 1254: } ! 1255: printf("\tregs.sr |= src;\n"); ! 1256: printf("\tMakeFromSR();\n"); ! 1257: break; ! 1258: case i_ANDSR: ! 1259: if (table[opcode].size != sz_byte) { ! 1260: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n"); ! 1261: } ! 1262: start_brace(); ! 1263: ! 1264: printf("\tMakeSR();\n"); ! 1265: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1266: if (table[opcode].size == sz_byte) { ! 1267: printf("\tsrc |= 0xFF00;\n"); ! 1268: } ! 1269: printf("\tregs.sr &= src;\n"); ! 1270: printf("\tMakeFromSR();\n"); ! 1271: break; ! 1272: case i_EORSR: ! 1273: if (table[opcode].size != sz_byte) { ! 1274: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n"); ! 1275: } ! 1276: start_brace (); ! 1277: printf("\tMakeSR();\n"); ! 1278: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1279: if (table[opcode].size == sz_byte) { ! 1280: printf("\tsrc &= 0xFF;\n"); ! 1281: } ! 1282: printf("\tregs.sr ^= src;\n"); ! 1283: printf("\tMakeFromSR();\n"); ! 1284: break; ! 1285: case i_SUB: ! 1286: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1287: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1288: start_brace (); ! 1289: printf("\tULONG newv = dst - src;\n"); ! 1290: genflags(flag_sub, table[opcode].size, "newv", "src", "dst"); ! 1291: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1292: break; ! 1293: case i_SUBA: ! 1294: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1295: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false); ! 1296: start_brace (); ! 1297: printf("\tULONG newv = dst - src;\n"); ! 1298: genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1299: break; ! 1300: case i_SUBX: ! 1301: { ! 1302: int old_brace_level; ! 1303: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1304: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1305: start_brace (); ! 1306: printf("\tbool xflg = regs.x;\n"); ! 1307: printf("\tregs.v = regs.c = regs.x = 0;\n"); ! 1308: start_brace (); ! 1309: printf("\tULONG newv = dst - src;\n"); ! 1310: genflags(flag_subx, table[opcode].size, "newv", "src", "dst"); ! 1311: /* FIXME: I'm not entirely sure how to handle this */ ! 1312: printf("\tif (xflg)\n"); ! 1313: old_brace_level = n_braces; ! 1314: start_brace (); ! 1315: genflags(flag_subx, table[opcode].size, "(newv-1)", "1", "newv"); ! 1316: printf("\tnewv--;\n"); ! 1317: pop_braces(old_brace_level); ! 1318: ! 1319: genflags(flag_zn, table[opcode].size, "newv", "", ""); ! 1320: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1321: } ! 1322: break; ! 1323: case i_SBCD: ! 1324: /* Let's hope this works... */ ! 1325: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1326: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1327: start_brace (); ! 1328: printf("\tUWORD newv = dst - src - regs.x;\n"); ! 1329: printf("\tif ((newv & 0xF) > 9) newv-=6;\n"); ! 1330: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n"); ! 1331: printf("\tif (regs.c) newv -= 0x60;\n"); ! 1332: printf("\tif (newv != 0) regs.z = 0;\n"); ! 1333: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1334: break; ! 1335: case i_ADD: ! 1336: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1337: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1338: start_brace (); ! 1339: printf("\tULONG newv = dst + src;\n"); ! 1340: genflags(flag_add, table[opcode].size, "newv", "src", "dst"); ! 1341: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1342: break; ! 1343: case i_ADDA: ! 1344: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1345: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false); ! 1346: start_brace (); ! 1347: printf("\tULONG newv = dst + src;\n"); ! 1348: genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1349: break; ! 1350: case i_ADDX: ! 1351: { ! 1352: int old_brace_level; ! 1353: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1354: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1355: start_brace (); ! 1356: printf("\tbool xflg = regs.x;\n"); ! 1357: printf("\tregs.v = regs.c = regs.x = 0;\n"); ! 1358: start_brace (); ! 1359: printf("\tULONG newv = dst + src;\n"); ! 1360: genflags(flag_addx, table[opcode].size, "newv", "src", "dst"); ! 1361: printf("\tif (xflg)\n"); ! 1362: old_brace_level = n_braces; ! 1363: start_brace (); ! 1364: genflags(flag_addx, table[opcode].size, "(newv+1)", "newv", "1"); ! 1365: printf("\tnewv++;\n"); ! 1366: pop_braces(old_brace_level); ! 1367: genflags(flag_zn, table[opcode].size, "newv", "", ""); ! 1368: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1369: } ! 1370: break; ! 1371: case i_ABCD: ! 1372: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1373: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1374: start_brace (); ! 1375: printf("\tUWORD newv = src + dst + regs.x;\n"); ! 1376: printf("\tif ((newv & 0xF) > 9) newv+=6;\n"); ! 1377: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n"); ! 1378: printf("\tif (regs.c) newv += 0x60;\n"); ! 1379: printf("\tif (newv != 0) regs.z = 0;\n"); ! 1380: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1381: break; ! 1382: case i_NEG: ! 1383: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1384: start_brace (); ! 1385: printf("\tULONG dst = -src;\n"); ! 1386: genflags(flag_sub, table[opcode].size, "dst", "src", "0"); ! 1387: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1388: break; ! 1389: case i_NEGX: ! 1390: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1391: start_brace (); ! 1392: printf("\tULONG dst = -src-regs.x;\n"); ! 1393: genflags(flag_sub, table[opcode].size, "dst", "src", "0"); ! 1394: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1395: break; ! 1396: case i_NBCD: ! 1397: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1398: start_brace (); ! 1399: printf("\tUWORD newv = - src - regs.x;\n"); ! 1400: printf("\tif ((newv & 0xF) > 9) newv-=6;\n"); ! 1401: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n"); ! 1402: printf("\tif (regs.c) newv -= 0x60;\n"); ! 1403: printf("\tif (newv != 0) regs.z = 0;\n"); ! 1404: genastore("newv", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1405: break; ! 1406: case i_CLR: ! 1407: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1408: genflags(flag_logical, table[opcode].size, "0", "", ""); ! 1409: genastore("0",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1410: break; ! 1411: case i_NOT: ! 1412: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1413: start_brace (); ! 1414: printf("\tULONG dst = ~src;\n"); ! 1415: genflags(flag_logical, table[opcode].size, "dst", "", ""); ! 1416: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1417: break; ! 1418: case i_TST: ! 1419: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1420: genflags(flag_logical, table[opcode].size, "src", "", ""); ! 1421: break; ! 1422: case i_BTST: ! 1423: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1424: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1425: if (table[opcode].size == sz_byte) ! 1426: printf("\tsrc &= 7;\n"); ! 1427: else ! 1428: printf("\tsrc &= 31;\n"); ! 1429: printf("\tregs.z = !(dst & (1 << src));\n"); ! 1430: break; ! 1431: case i_BCHG: ! 1432: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1433: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1434: if (table[opcode].size == sz_byte) ! 1435: printf("\tsrc &= 7;\n"); ! 1436: else ! 1437: printf("\tsrc &= 31;\n"); ! 1438: printf("\tregs.z = !(dst & (1 << src));\n"); ! 1439: printf("\tdst ^= (1 << src);\n"); ! 1440: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1441: break; ! 1442: case i_BCLR: ! 1443: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1444: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1445: if (table[opcode].size == sz_byte) ! 1446: printf("\tsrc &= 7;\n"); ! 1447: else ! 1448: printf("\tsrc &= 31;\n"); ! 1449: printf("\tregs.z = !(dst & (1 << src));\n"); ! 1450: printf("\tdst &= ~(1 << src);\n"); ! 1451: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1452: break; ! 1453: case i_BSET: ! 1454: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1455: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1456: if (table[opcode].size == sz_byte) ! 1457: printf("\tsrc &= 7;\n"); ! 1458: else ! 1459: printf("\tsrc &= 31;\n"); ! 1460: printf("\tregs.z = !(dst & (1 << src));\n"); ! 1461: printf("\tdst |= (1 << src);\n"); ! 1462: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1463: break; ! 1464: case i_CMPM: ! 1465: case i_CMP: ! 1466: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1467: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1468: start_brace (); ! 1469: printf("\tULONG newv = dst - src;\n"); ! 1470: genflags(flag_cmp, table[opcode].size, "newv", "src", "dst"); ! 1471: break; ! 1472: case i_CMPA: ! 1473: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1474: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false); ! 1475: start_brace (); ! 1476: printf("\tULONG newv = dst - src;\n"); ! 1477: genflags(flag_cmp, sz_long, "newv", "src", "dst"); ! 1478: break; ! 1479: case i_MOVEP: ! 1480: printf("\tfprintf(stderr, \"MOVEP\\n\");\n"); ! 1481: break; ! 1482: case i_MOVE: ! 1483: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1484: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false); ! 1485: genflags(flag_logical, table[opcode].size, "src", "", ""); ! 1486: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1487: break; ! 1488: case i_MOVEA: ! 1489: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1490: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false); ! 1491: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1492: break; ! 1493: case i_MVSR2: ! 1494: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1495: printf("\tMakeSR();\n"); ! 1496: genastore("regs.sr", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1497: break; ! 1498: case i_MV2SR: ! 1499: if (table[opcode].size != sz_byte) { ! 1500: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n"); ! 1501: } ! 1502: start_brace (); ! 1503: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1504: if (table[opcode].size == sz_byte) ! 1505: printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); ! 1506: else { ! 1507: printf("\tregs.sr = src;\n"); ! 1508: } ! 1509: printf("\tMakeFromSR();\n"); ! 1510: break; ! 1511: case i_SWAP: ! 1512: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1513: start_brace (); ! 1514: printf("\tULONG dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); ! 1515: genflags(flag_logical, table[opcode].size, "dst", "", ""); ! 1516: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1517: break; ! 1518: case i_EXG: ! 1519: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1520: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false); ! 1521: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1522: genastore("src",table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1523: break; ! 1524: case i_EXT: ! 1525: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1526: start_brace (); ! 1527: switch(table[opcode].size) { ! 1528: case sz_word: printf("\tULONG dst = (LONG)(BYTE)src;\n"); break; ! 1529: case sz_long: printf("\tULONG dst = (LONG)(WORD)src;\n"); break; ! 1530: default: myabort(); ! 1531: } ! 1532: genflags(flag_logical, table[opcode].size, "dst", "", ""); ! 1533: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1534: break; ! 1535: case i_MVMEL: ! 1536: genmovemel(opcode); ! 1537: break; ! 1538: case i_MVMLE: ! 1539: genmovemle(opcode); ! 1540: break; ! 1541: case i_TRAP: ! 1542: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1543: printf("\tException(src+32);\n"); ! 1544: break; ! 1545: case i_MVR2USP: ! 1546: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n"); ! 1547: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1548: printf("\tregs.usp = src;\n"); ! 1549: printf("\t}\n"); ! 1550: break; ! 1551: case i_MVUSP2R: ! 1552: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n"); ! 1553: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1554: genastore("regs.usp", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1555: printf("\t}\n"); ! 1556: break; ! 1557: case i_RESET: ! 1558: printf("\tcustomreset();\n"); ! 1559: break; ! 1560: case i_NOP: ! 1561: break; ! 1562: case i_STOP: ! 1563: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n"); ! 1564: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1565: printf("\tregs.sr = src;\n"); ! 1566: printf("\tMakeFromSR();\n"); ! 1567: printf("\tm68k_setstopped(1);\n"); ! 1568: printf("\t}\n"); ! 1569: break; ! 1570: case i_RTE: ! 1571: genamode(Aipi, "7", sz_word, "sr", true, false); ! 1572: genamode(Aipi, "7", sz_long, "pc", true, false); ! 1573: printf("\tregs.sr = sr; m68k_setpc(pc);\n"); ! 1574: printf("\tMakeFromSR();\n"); ! 1575: break; ! 1576: case i_RTD: ! 1577: break; ! 1578: case i_LINK: ! 1579: genamode(Apdi, "7", sz_long, "old", false, false); ! 1580: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1581: genastore("src", Apdi, "7", sz_long, "old"); ! 1582: genastore("regs.a[7]", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1583: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false); ! 1584: printf("\tregs.a[7] += offs;\n"); ! 1585: break; ! 1586: case i_UNLK: ! 1587: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1588: printf("\tregs.a[7] = src;\n"); ! 1589: genamode(Aipi, "7", sz_long, "old", true, false); ! 1590: genastore("old", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1591: break; ! 1592: case i_RTS: ! 1593: genamode(Aipi, "7", sz_long, "pc", true, false); ! 1594: printf("\tm68k_setpc(pc);\n"); ! 1595: break; ! 1596: case i_TRAPV: ! 1597: printf("\tif(regs.v) Exception(7);\n"); ! 1598: break; ! 1599: case i_RTR: ! 1600: printf("\tMakeSR();\n"); ! 1601: genamode(Aipi, "7", sz_word, "sr", true, false); ! 1602: genamode(Aipi, "7", sz_long, "pc", true, false); ! 1603: printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); ! 1604: printf("\tregs.sr |= sr; m68k_setpc(pc);\n"); ! 1605: printf("\tMakeFromSR();\n"); ! 1606: break; ! 1607: case i_JSR: ! 1608: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1609: genamode(Apdi, "7", sz_long, "sp", false, false); ! 1610: genastore("m68k_getpc()", Apdi, "7", sz_long, "sp"); ! 1611: printf("\tm68k_setpc(srca);\n"); ! 1612: break; ! 1613: case i_JMP: ! 1614: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1615: printf("\tm68k_setpc(srca);\n"); ! 1616: break; ! 1617: case i_BSR: ! 1618: printf("\tchar *oldpcp = (char *)regs.pc_p;\n"); ! 1619: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1620: genamode(Apdi, "7", sz_long, "sp", false, false); ! 1621: genastore("m68k_getpc()", Apdi, "7", sz_long, "sp"); ! 1622: printf("\tregs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n"); ! 1623: break; ! 1624: case i_Bcc: ! 1625: printf("\tchar *oldpcp = (char *)regs.pc_p;\n"); ! 1626: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1627: printf("\tif (cctrue(%d)) regs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n", table[opcode].cc); ! 1628: break; ! 1629: case i_LEA: ! 1630: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1631: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false); ! 1632: genastore("srca", table[opcode].dmode, "dstreg", table[opcode].size, "dst"); ! 1633: break; ! 1634: case i_PEA: ! 1635: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1636: genamode(Apdi, "7", sz_long, "dst", false, false); ! 1637: genastore("srca", Apdi, "7", sz_long, "dst"); ! 1638: break; ! 1639: case i_DBcc: ! 1640: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false); ! 1641: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false); ! 1642: printf("\tif (!cctrue(%d)) {\n", table[opcode].cc); ! 1643: printf("\tif (src--) regs.pc_p = (UWORD *)((char *)regs.pc_p + (LONG)offs - 2);\n"); ! 1644: genastore("src", table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1645: printf("\t}\n"); ! 1646: break; ! 1647: case i_Scc: ! 1648: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false); ! 1649: start_brace (); ! 1650: printf("\tint val = cctrue(%d) ? 0xff : 0;\n", table[opcode].cc); ! 1651: genastore("val",table[opcode].smode, "srcreg", table[opcode].size, "src"); ! 1652: break; ! 1653: case i_DIVU: ! 1654: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false); ! 1655: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false); ! 1656: printf("\tif(src != 0){\n"); ! 1657: printf("\tULONG newv = (ULONG)dst / (UWORD)src;\n"); ! 1658: printf("\tULONG rem = (ULONG)dst %% (UWORD)src;\n"); ! 1659: /* The N flag appears to be set each time there is an overflow. ! 1660: * Weird. */ ! 1661: printf("\tif (newv > 0xffff) { regs.v = regs.n = 1; } else\n\t{\n"); ! 1662: genflags(flag_logical, sz_word, "newv", "", ""); ! 1663: printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n"); ! 1664: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1665: printf("\t}\n"); ! 1666: printf("\t}\n"); ! 1667: break; ! 1668: case i_DIVS: ! 1669: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false); ! 1670: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false); ! 1671: printf("\tif(src != 0){\n"); ! 1672: printf("\tLONG newv = (LONG)dst / (WORD)src;\n"); ! 1673: printf("\tUWORD rem = (LONG)dst %% (WORD)src;\n"); ! 1674: printf("\tif ((newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000) { regs.v = regs.n = 1; } else\n\t{\n"); ! 1675: printf("\tif (((WORD)rem < 0) != ((LONG)dst < 0)) rem = -rem;\n"); ! 1676: genflags(flag_logical, sz_word, "newv", "", ""); ! 1677: printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n"); ! 1678: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1679: printf("\t}\n"); ! 1680: printf("\t}\n"); ! 1681: break; ! 1682: case i_MULU: ! 1683: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false); ! 1684: genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false); ! 1685: start_brace (); ! 1686: printf("\tULONG newv = (ULONG)(UWORD)dst * (ULONG)(UWORD)src;\n"); ! 1687: genflags(flag_logical, sz_long, "newv", "", ""); ! 1688: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1689: #ifdef WANT_SLOW_MULTIPLY ! 1690: printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n"); ! 1691: #endif ! 1692: break; ! 1693: case i_MULS: ! 1694: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false); ! 1695: genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false); ! 1696: start_brace (); ! 1697: printf("\tULONG newv = (LONG)(WORD)dst * (LONG)(WORD)src;\n"); ! 1698: genflags(flag_logical, sz_long, "newv", "", ""); ! 1699: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst"); ! 1700: #ifdef WANT_SLOW_MULTIPLY ! 1701: printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n"); ! 1702: #endif ! 1703: break; ! 1704: case i_ASR: ! 1705: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1706: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1707: start_brace (); ! 1708: switch(table[opcode].size) { ! 1709: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1710: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1711: case sz_long: printf("\tULONG val = data;\n"); break; ! 1712: default: myabort(); ! 1713: } ! 1714: printf("\tcnt &= 63;\n"); ! 1715: printf("\tregs.v = 0;\n"); ! 1716: start_brace (); ! 1717: switch(table[opcode].size) { ! 1718: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1719: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1720: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1721: default: myabort(); ! 1722: } ! 1723: printf("\tULONG sign = cmask & val;\n"); ! 1724: printf("\tfor(;cnt;--cnt){\n"); ! 1725: printf("\tregs.c=regs.x=val&1; val = ((ULONG)val >> 1) | sign;\n"); ! 1726: printf("\t}\n\tregs.n = sign != 0;\n"); ! 1727: printf("\tregs.z = val == 0;\n"); ! 1728: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1729: break; ! 1730: case i_ASL: ! 1731: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1732: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1733: start_brace (); ! 1734: switch(table[opcode].size) { ! 1735: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1736: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1737: case sz_long: printf("\tULONG val = data;\n"); break; ! 1738: default: myabort(); ! 1739: } ! 1740: printf("\tcnt &= 63;\n"); ! 1741: printf("\tregs.v = 0;\n"); ! 1742: start_brace (); ! 1743: switch(table[opcode].size) { ! 1744: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1745: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1746: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1747: default: myabort(); ! 1748: } ! 1749: printf("\tULONG sign = cmask & val;\n"); ! 1750: printf("\tfor(;cnt;--cnt){\n"); ! 1751: printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n"); ! 1752: printf("\tif ((val&cmask)!=sign)regs.v=1;\n"); ! 1753: printf("\t}\n\tregs.n = (val&cmask) != 0;\n"); ! 1754: printf("\tregs.z = val == 0;\n"); ! 1755: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1756: break; ! 1757: case i_LSR: ! 1758: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1759: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1760: start_brace (); ! 1761: switch(table[opcode].size) { ! 1762: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1763: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1764: case sz_long: printf("\tULONG val = data;\n"); break; ! 1765: default: myabort(); ! 1766: } ! 1767: printf("\tcnt &= 63;\n"); ! 1768: start_brace (); ! 1769: printf("\tint carry = 0;\n"); ! 1770: printf("\tfor(;cnt;--cnt){\n"); ! 1771: printf("\tcarry=val&1; val >>= 1;\n"); ! 1772: printf("\t}\n"); ! 1773: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1774: printf("regs.c = regs.x = carry!=0;\n"); ! 1775: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1776: break; ! 1777: case i_LSL: ! 1778: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1779: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1780: start_brace (); ! 1781: switch(table[opcode].size) { ! 1782: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1783: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1784: case sz_long: printf("\tULONG val = data;\n"); break; ! 1785: default: myabort(); ! 1786: } ! 1787: printf("\tcnt &= 63;\n"); ! 1788: start_brace (); ! 1789: printf("\tint carry = 0;\n"); ! 1790: switch(table[opcode].size) { ! 1791: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1792: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1793: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1794: default: myabort(); ! 1795: } ! 1796: printf("\tfor(;cnt;--cnt){\n"); ! 1797: printf("\tcarry=val&cmask; val <<= 1;\n"); ! 1798: printf("\t}\n"); ! 1799: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1800: printf("regs.c = regs.x = carry!=0;\n"); ! 1801: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1802: break; ! 1803: case i_ROL: ! 1804: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1805: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1806: start_brace (); ! 1807: switch(table[opcode].size) { ! 1808: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1809: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1810: case sz_long: printf("\tULONG val = data;\n"); break; ! 1811: default: myabort(); ! 1812: } ! 1813: printf("\tcnt &= 63;\n"); ! 1814: start_brace (); ! 1815: printf("\tint carry = 0;\n"); ! 1816: switch(table[opcode].size) { ! 1817: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1818: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1819: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1820: default: myabort(); ! 1821: } ! 1822: printf("\tfor(;cnt;--cnt){\n"); ! 1823: printf("\tcarry=val&cmask; val <<= 1;\n"); ! 1824: printf("\tif(carry) val |= 1;\n"); ! 1825: printf("\t}\n"); ! 1826: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1827: printf("regs.c = carry!=0;\n"); ! 1828: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1829: break; ! 1830: case i_ROR: ! 1831: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1832: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1833: start_brace (); ! 1834: switch(table[opcode].size) { ! 1835: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1836: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1837: case sz_long: printf("\tULONG val = data;\n"); break; ! 1838: default: myabort(); ! 1839: } ! 1840: ! 1841: printf("\tcnt &= 63;\n"); ! 1842: start_brace (); ! 1843: printf("\tint carry = 0;\n"); ! 1844: switch(table[opcode].size) { ! 1845: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1846: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1847: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1848: default: myabort(); ! 1849: } ! 1850: printf("\tfor(;cnt;--cnt){\n"); ! 1851: printf("\tcarry=val&1; val = (ULONG)val >> 1;\n"); ! 1852: printf("\tif(carry) val |= cmask;\n"); ! 1853: printf("\t}\n"); ! 1854: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1855: printf("\tregs.c = carry!=0;\n"); ! 1856: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1857: break; ! 1858: case i_ROXL: ! 1859: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1860: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1861: start_brace (); ! 1862: switch(table[opcode].size) { ! 1863: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1864: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1865: case sz_long: printf("\tULONG val = data;\n"); break; ! 1866: default: myabort(); ! 1867: } ! 1868: printf("\tcnt &= 63;\n"); ! 1869: start_brace (); ! 1870: printf("\tint carry = 0;\n"); ! 1871: switch(table[opcode].size) { ! 1872: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1873: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1874: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1875: default: myabort(); ! 1876: } ! 1877: printf("\tfor(;cnt;--cnt){\n"); ! 1878: printf("\tcarry=val&cmask; val <<= 1;\n"); ! 1879: printf("\tif(regs.x) val |= 1;\n"); ! 1880: printf("\tregs.x = carry != 0;\n"); ! 1881: printf("\t}\n"); ! 1882: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1883: printf("\tregs.x = regs.c = carry!=0;\n"); ! 1884: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1885: break; ! 1886: case i_ROXR: ! 1887: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false); ! 1888: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false); ! 1889: start_brace (); ! 1890: switch(table[opcode].size) { ! 1891: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1892: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1893: case sz_long: printf("\tULONG val = data;\n"); break; ! 1894: default: myabort(); ! 1895: } ! 1896: printf("\tcnt &= 63;\n"); ! 1897: start_brace (); ! 1898: printf("\tint carry = 0;\n"); ! 1899: switch(table[opcode].size) { ! 1900: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1901: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1902: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1903: default: myabort(); ! 1904: } ! 1905: printf("\tfor(;cnt;--cnt){\n"); ! 1906: printf("\tcarry=val&1; val >>= 1;\n"); ! 1907: printf("\tif(regs.x) val |= cmask;\n"); ! 1908: printf("\tregs.x = carry != 0;\n"); ! 1909: printf("\t}\n"); ! 1910: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1911: printf("\tregs.x = regs.c = carry!=0;\n"); ! 1912: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data"); ! 1913: break; ! 1914: case i_ASRW: ! 1915: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 1916: printf("\tregs.v = 0;\n"); ! 1917: start_brace (); ! 1918: switch(table[opcode].size) { ! 1919: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1920: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1921: case sz_long: printf("\tULONG val = data;\n"); break; ! 1922: default: myabort(); ! 1923: } ! 1924: switch(table[opcode].size) { ! 1925: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1926: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1927: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1928: default: myabort(); ! 1929: } ! 1930: printf("\tULONG sign = cmask & val;\n"); ! 1931: printf("\tregs.c=regs.x=val&1; val = (val >> 1) | sign;\n"); ! 1932: printf("\tregs.n = sign != 0;\n"); ! 1933: printf("\tregs.z = val == 0;\n"); ! 1934: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 1935: break; ! 1936: case i_ASLW: ! 1937: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 1938: printf("\tregs.v = 0;\n"); ! 1939: start_brace (); ! 1940: switch(table[opcode].size) { ! 1941: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1942: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1943: case sz_long: printf("\tULONG val = data;\n"); break; ! 1944: default: myabort(); ! 1945: } ! 1946: switch(table[opcode].size) { ! 1947: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1948: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1949: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1950: default: myabort(); ! 1951: } ! 1952: printf("\tULONG sign = cmask & val;\n"); ! 1953: printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n"); ! 1954: printf("\tif ((val&cmask)!=sign)regs.v=1;\n"); ! 1955: printf("\tregs.n = (val&cmask) != 0;\n"); ! 1956: printf("\tregs.z = val == 0;\n"); ! 1957: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 1958: break; ! 1959: case i_LSRW: ! 1960: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 1961: start_brace (); ! 1962: switch(table[opcode].size) { ! 1963: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1964: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1965: case sz_long: printf("\tULONG val = data;\n"); break; ! 1966: default: myabort(); ! 1967: } ! 1968: printf("\tint carry = val&1;\n"); ! 1969: printf("\tcarry=val&1; val >>= 1;\n"); ! 1970: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1971: printf("regs.c = regs.x = carry!=0;\n"); ! 1972: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 1973: break; ! 1974: case i_LSLW: ! 1975: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 1976: start_brace (); ! 1977: switch(table[opcode].size) { ! 1978: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 1979: case sz_word: printf("\tUWORD val = data;\n"); break; ! 1980: case sz_long: printf("\tULONG val = data;\n"); break; ! 1981: default: myabort(); ! 1982: } ! 1983: switch(table[opcode].size) { ! 1984: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 1985: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 1986: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 1987: default: myabort(); ! 1988: } ! 1989: printf("\tint carry = val&cmask;\n"); ! 1990: printf("\tval <<= 1;\n"); ! 1991: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 1992: printf("regs.c = regs.x = carry!=0;\n"); ! 1993: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 1994: break; ! 1995: case i_ROLW: ! 1996: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 1997: start_brace (); ! 1998: switch(table[opcode].size) { ! 1999: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 2000: case sz_word: printf("\tUWORD val = data;\n"); break; ! 2001: case sz_long: printf("\tULONG val = data;\n"); break; ! 2002: default: myabort(); ! 2003: } ! 2004: switch(table[opcode].size) { ! 2005: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 2006: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 2007: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 2008: default: myabort(); ! 2009: } ! 2010: printf("\tint carry = val&cmask;\n"); ! 2011: printf("\tval <<= 1;\n"); ! 2012: printf("\tif(carry) val |= 1;\n"); ! 2013: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 2014: printf("regs.c = carry!=0;\n"); ! 2015: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 2016: break; ! 2017: case i_RORW: ! 2018: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 2019: start_brace (); ! 2020: switch(table[opcode].size) { ! 2021: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 2022: case sz_word: printf("\tUWORD val = data;\n"); break; ! 2023: case sz_long: printf("\tULONG val = data;\n"); break; ! 2024: default: myabort(); ! 2025: } ! 2026: printf("\tint carry = val&1;\n"); ! 2027: switch(table[opcode].size) { ! 2028: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 2029: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 2030: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 2031: default: myabort(); ! 2032: } ! 2033: printf("\tval >>= 1;\n"); ! 2034: printf("\tif(carry) val |= cmask;\n"); ! 2035: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 2036: printf("regs.c = carry!=0;\n"); ! 2037: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 2038: break; ! 2039: case i_ROXLW: ! 2040: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 2041: start_brace (); ! 2042: switch(table[opcode].size) { ! 2043: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 2044: case sz_word: printf("\tUWORD val = data;\n"); break; ! 2045: case sz_long: printf("\tULONG val = data;\n"); break; ! 2046: default: myabort(); ! 2047: } ! 2048: switch(table[opcode].size) { ! 2049: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 2050: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 2051: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 2052: default: myabort(); ! 2053: } ! 2054: printf("\tint carry = val&cmask;\n"); ! 2055: printf("\tval <<= 1;\n"); ! 2056: printf("\tif(regs.x) val |= 1;\n"); ! 2057: printf("\tregs.x = carry != 0;\n"); ! 2058: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 2059: printf("regs.x = regs.c = carry!=0;\n"); ! 2060: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 2061: break; ! 2062: case i_ROXRW: ! 2063: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false); ! 2064: start_brace (); ! 2065: switch(table[opcode].size) { ! 2066: case sz_byte: printf("\tUBYTE val = data;\n"); break; ! 2067: case sz_word: printf("\tUWORD val = data;\n"); break; ! 2068: case sz_long: printf("\tULONG val = data;\n"); break; ! 2069: default: myabort(); ! 2070: } ! 2071: printf("\tint carry = val&1;\n"); ! 2072: switch(table[opcode].size) { ! 2073: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break; ! 2074: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break; ! 2075: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break; ! 2076: default: myabort(); ! 2077: } ! 2078: printf("\tval >>= 1;\n"); ! 2079: printf("\tif(regs.x) val |= cmask;\n"); ! 2080: printf("\tregs.x = carry != 0;\n"); ! 2081: genflags(flag_logical, table[opcode].size, "val", "", ""); ! 2082: printf("regs.x = regs.c = carry!=0;\n"); ! 2083: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data"); ! 2084: break; ! 2085: default: ! 2086: myabort(); ! 2087: break; ! 2088: }; ! 2089: finish_braces (); ! 2090: } ! 2091: ! 2092: static int mismatch; ! 2093: ! 2094: static void handle_merges(long int opcode) ! 2095: { ! 2096: UWORD smsk; ! 2097: UWORD dmsk; ! 2098: int sbitsrc, sbitdst; ! 2099: int srcreg, dstreg; ! 2100: ! 2101: smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos; ! 2102: dmsk = 7 << table[opcode].dpos; ! 2103: sbitsrc = table[opcode].spos == -1 ? 0 : 0; ! 2104: sbitdst = table[opcode].spos == -1 ? 1 : (table[opcode].sbtarg ? 256 : 8); ! 2105: for (srcreg=sbitsrc; srcreg < sbitdst; srcreg++) { ! 2106: for (dstreg=0; dstreg < (table[opcode].dpos == -1 ? 1 : 8); dstreg++) { ! 2107: UWORD code = opcode; ! 2108: ! 2109: if (table[opcode].spos != -1) code &= ~(smsk << table[opcode].spos); ! 2110: if (table[opcode].dpos != -1) code &= ~(dmsk << table[opcode].dpos); ! 2111: ! 2112: if (table[opcode].spos != -1) code |= srcreg << table[opcode].spos; ! 2113: if (table[opcode].dpos != -1) code |= dstreg << table[opcode].dpos; ! 2114: ! 2115: /* Check whether this is in fact the same instruction. ! 2116: * The instructions should never differ, except for the ! 2117: * Bcc.(BW) case. */ ! 2118: if (table[code].mnemo != table[opcode].mnemo ! 2119: || table[code].size != table[opcode].size ! 2120: || table[code].suse != table[opcode].suse ! 2121: || table[code].duse != table[opcode].duse) ! 2122: { ! 2123: mismatch++; continue; ! 2124: } ! 2125: if (table[opcode].suse ! 2126: && (table[opcode].spos != table[code].spos ! 2127: || table[opcode].smode != table[code].smode ! 2128: || table[opcode].sbtarg != table[code].sbtarg)) ! 2129: { ! 2130: mismatch++; continue; ! 2131: } ! 2132: if (table[opcode].duse ! 2133: && (table[opcode].dpos != table[code].dpos ! 2134: || table[opcode].dmode != table[code].dmode)) ! 2135: { ! 2136: mismatch++; continue; ! 2137: } ! 2138: ! 2139: table[code].generated = true; ! 2140: table[code].handler = opcode; ! 2141: } ! 2142: } ! 2143: } ! 2144: ! 2145: static void generate_func(long int from, long int to) ! 2146: { ! 2147: int illg = 0; ! 2148: long int opcode; ! 2149: UWORD smsk; ! 2150: UWORD dmsk; ! 2151: mismatch = 0; ! 2152: ! 2153: printf("#include <stdlib.h>\n"); ! 2154: printf("#include \"config.h\"\n"); ! 2155: printf("#include \"amiga.h\"\n"); ! 2156: printf("#include \"options.h\"\n"); ! 2157: printf("#include \"memory.h\"\n"); ! 2158: printf("#include \"custom.h\"\n"); ! 2159: printf("#include \"newcpu.h\"\n"); ! 2160: printf("#include \"cputbl.h\"\n"); ! 2161: for(opcode=from; opcode < to; opcode++) { ! 2162: if (table[opcode].mnemo == i_ILLG) { ! 2163: illg++; ! 2164: continue; ! 2165: } ! 2166: if (table[opcode].generated) { ! 2167: continue; ! 2168: } ! 2169: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS ! 2170: ! 2171: handle_merges (opcode); ! 2172: ! 2173: smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos; ! 2174: dmsk = 7 << table[opcode].dpos; ! 2175: ! 2176: printf("void op_%lx(UWORD opcode)\n{\n", opcode); ! 2177: if (table[opcode].suse ! 2178: && table[opcode].smode != imm && table[opcode].smode != imm0 ! 2179: && table[opcode].smode != imm1 && table[opcode].smode != imm2 ! 2180: && table[opcode].smode != absw && table[opcode].smode != absl ! 2181: && table[opcode].smode != PC8r && table[opcode].smode != PC16) ! 2182: { ! 2183: if (table[opcode].spos == -1) { ! 2184: printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg); ! 2185: } else { ! 2186: printf("\tULONG srcreg = (LONG)(BYTE)((opcode & %d) >> %d);\n", smsk, (int)table[opcode].spos); ! 2187: } ! 2188: } ! 2189: if (table[opcode].duse ! 2190: /* Yes, the dmode can be imm, in case of LINK or DBcc */ ! 2191: && table[opcode].dmode != imm && table[opcode].dmode != imm0 ! 2192: && table[opcode].dmode != imm1 && table[opcode].dmode != imm2 ! 2193: && table[opcode].dmode != absw && table[opcode].dmode != absl) { ! 2194: if (table[opcode].dpos == -1) { ! 2195: printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg); ! 2196: } else { ! 2197: printf("\tULONG dstreg = (opcode & %d) >> %d;\n", dmsk, (int)table[opcode].dpos); ! 2198: } ! 2199: } ! 2200: #else ! 2201: printf("void op_%lx(UWORD opcode)\n{\n", opcode); ! 2202: if (table[opcode].suse) ! 2203: printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg); ! 2204: if (table[opcode].duse) ! 2205: printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg); ! 2206: #endif ! 2207: gen_opcode(opcode); ! 2208: printf("}\n"); ! 2209: } ! 2210: ! 2211: fprintf (stderr, "%d illegals generated.\n", illg); ! 2212: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch); ! 2213: } ! 2214: ! 2215: static void generate_table(void) ! 2216: { ! 2217: int illg = 0; ! 2218: long int opcode; ! 2219: ! 2220: mismatch = 0; ! 2221: ! 2222: printf("#include <stdlib.h>\n"); ! 2223: printf("#include \"config.h\"\n"); ! 2224: printf("#include \"amiga.h\"\n"); ! 2225: printf("#include \"options.h\"\n"); ! 2226: printf("#include \"memory.h\"\n"); ! 2227: printf("#include \"custom.h\"\n"); ! 2228: printf("#include \"newcpu.h\"\n"); ! 2229: printf("#include \"cputbl.h\"\n"); ! 2230: ! 2231: printf("cpuop_func *cpufunctbl[65536] = {\n"); ! 2232: for(opcode=0; opcode < 65536; opcode++) { ! 2233: if (table[opcode].mnemo == i_ILLG) { ! 2234: printf("op_illg"); ! 2235: illg++; ! 2236: goto loop_end; ! 2237: } ! 2238: if (table[opcode].generated) { ! 2239: printf("op_%x", table[opcode].handler); ! 2240: goto loop_end; ! 2241: } ! 2242: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS ! 2243: handle_merges (opcode); ! 2244: #endif ! 2245: printf("op_%lx", opcode); ! 2246: ! 2247: loop_end: ! 2248: if (opcode < 65535) printf(","); ! 2249: if ((opcode & 7) == 7) printf("\n"); ! 2250: } ! 2251: printf("\n};\n"); ! 2252: fprintf (stderr, "%d illegals generated.\n", illg); ! 2253: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch); ! 2254: } ! 2255: ! 2256: static void generate_header(void) ! 2257: { ! 2258: int illg = 0; ! 2259: long int opcode; ! 2260: ! 2261: mismatch = 0; ! 2262: ! 2263: printf("extern void op_illg(UWORD) REGPARAM;\n"); ! 2264: ! 2265: for(opcode=0; opcode < 65536; opcode++) { ! 2266: if (table[opcode].mnemo == i_ILLG) { ! 2267: illg++; ! 2268: continue; ! 2269: } ! 2270: if (table[opcode].generated) ! 2271: continue; ! 2272: ! 2273: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS ! 2274: handle_merges (opcode); ! 2275: #endif ! 2276: printf("extern cpuop_func op_%lx;\n", opcode); ! 2277: } ! 2278: ! 2279: fprintf (stderr, "%d illegals generated.\n", illg); ! 2280: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch); ! 2281: } ! 2282: ! 2283: int main(int argc, char **argv) ! 2284: { ! 2285: long int range = -1; ! 2286: char mode = 'n'; ! 2287: int i; ! 2288: ! 2289: if (argc == 2) ! 2290: mode = *argv[1]; ! 2291: ! 2292: if (argc == 3) { ! 2293: range = atoi(argv[2]); ! 2294: mode = *argv[1]; ! 2295: } ! 2296: tablef = fopen("table68k","r"); ! 2297: if (tablef == NULL) { ! 2298: fprintf(stderr, "table68k not found\n"); ! 2299: exit(1); ! 2300: } ! 2301: table = (struct instr *) malloc (sizeof(struct instr) * 65536); ! 2302: for(i = 0; i < 65536; i++) { ! 2303: table[i].mnemo = i_ILLG; ! 2304: } ! 2305: getnextch(); ! 2306: while (nextch != EOF) { ! 2307: get_bits(); ! 2308: get_strs(); ! 2309: parse_bits(); ! 2310: } ! 2311: switch(mode) { ! 2312: case 'f': ! 2313: generate_func(range * 0x1000, (range + 1) * 0x1000); ! 2314: break; ! 2315: case 'h': ! 2316: generate_header(); ! 2317: break; ! 2318: case 't': ! 2319: generate_table(); ! 2320: break; ! 2321: default: ! 2322: myabort(); ! 2323: } ! 2324: fclose(tablef); ! 2325: free(table); ! 2326: return 0; ! 2327: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.