|
|
1.1 ! root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ ! 2: ! 3: #include <errno.h> ! 4: #include <stdio.h> ! 5: #include <string.h> ! 6: #include <ctype.h> ! 7: #include <stdlib.h> ! 8: ! 9: #include "generator.h" ! 10: ! 11: #define BUFLEN 1024 ! 12: #define FNAME_CPUDEF "def68k.def" ! 13: #define FNAME_OUTIIBS "def68k-iibs.h" ! 14: #define FNAME_OUTFUNCS "def68k-funcs.h" ! 15: #define FNAME_OUTPROTO "def68k-proto.h" ! 16: ! 17: typedef enum { ! 18: bit0, bit1, bitz, bite, bitE, bitf, bitF, biti, bitn, bitN, bitc, bitv ! 19: } t_bit; ! 20: ! 21: /* file-scope global variables */ ! 22: ! 23: static int total = 0; ! 24: static int clocks_movetable[]; /* pre-declaration */ ! 25: ! 26: /* private functions for forward references */ ! 27: ! 28: void procline(char *line, int lineno, FILE *outiibs, FILE *outfuncs, ! 29: FILE *outproto); ! 30: int clocks_ea(t_datatype type); ! 31: int clocks_eacalc(t_datatype type, t_size size); ! 32: int clocks_6or8(t_datatype type); ! 33: int clocks_typetoindex(t_datatype type); ! 34: ! 35: /* program entry routine */ ! 36: ! 37: int main(int argc, char *argv[]) ! 38: { ! 39: FILE *input, *outiibs, *outfuncs, *outproto; ! 40: char buf[BUFLEN], *p; ! 41: int lineno = 0; ! 42: ! 43: /* open output files and write headers */ ! 44: ! 45: if ((outiibs = fopen(FNAME_OUTIIBS, "w")) == NULL) { ! 46: perror("fopen outiibs"); ! 47: exit(1); ! 48: } ! 49: fprintf(outiibs, "/* automatically generated by def68k.c */\n\n"); ! 50: fprintf(outiibs, "t_iib iibs[] = {\n"); ! 51: fprintf(outiibs, " /* mask, bits, mnemonic, { priv, endblk, zero, "); ! 52: fprintf(outiibs, "used, set },\n"); ! 53: fprintf(outiibs, " size, stype, dtype, sbitpos, dbitpos, immvalue, "); ! 54: fprintf(outiibs, "cc, funcnum */\n"); ! 55: ! 56: if ((outfuncs = fopen(FNAME_OUTFUNCS, "w")) == NULL) { ! 57: perror("fopen outfuncs"); ! 58: exit(1); ! 59: } ! 60: fprintf(outfuncs, "/* automatically generated by def68k.c */\n\n"); ! 61: fprintf(outfuncs, "void (*cpu68k_funcindex[])(t_ipc *ipc) = {\n"); ! 62: fprintf(outfuncs, " /* function */\n"); ! 63: ! 64: if ((outproto = fopen(FNAME_OUTPROTO, "w")) == NULL) { ! 65: perror("fopen outproto"); ! 66: exit(1); ! 67: } ! 68: fprintf(outproto, "/* automatically generated by def68k.c */\n\n"); ! 69: ! 70: /* open input file */ ! 71: ! 72: if ((input = fopen(FNAME_CPUDEF, "r")) == NULL) { ! 73: perror("fopen input"); ! 74: exit(1); ! 75: } ! 76: ! 77: /* loop until end of file */ ! 78: ! 79: printf("Writing CPU definitions... "); ! 80: fflush(stdout); ! 81: ! 82: while (!feof(input)) { ! 83: /* use unix line numbering from 1 */ ! 84: lineno++; ! 85: /* read a line */ ! 86: if (ferror(input)) { ! 87: break; ! 88: } ! 89: if (fgets(buf, BUFLEN, input) == NULL) { ! 90: break; ! 91: /* huh? why does this cause fgets to say 'Unknown error'?! */ ! 92: perror("fgets"); ! 93: exit(1); ! 94: } ! 95: /* remove newline */ ! 96: buf[strlen(buf)-1] = '\0'; ! 97: /* remove comment */ ! 98: if ((p = strchr(buf, ';')) != NULL) { ! 99: *p = '\0'; ! 100: } ! 101: /* remove leading spaces */ ! 102: p = buf; ! 103: while (*p == ' ') ! 104: p++; ! 105: /* blank line? */ ! 106: if (!*p) ! 107: continue; ! 108: /* process line */ ! 109: procline(buf, lineno, outiibs, outfuncs, outproto); ! 110: } ! 111: ! 112: /* close input */ ! 113: ! 114: if (fclose(input)) { ! 115: perror("fclose input"); ! 116: exit(1); ! 117: } ! 118: ! 119: /* output footer */ ! 120: ! 121: fprintf(outiibs, " { 0, 0, 0, { 0, 0, 0, 0, 0 }, " ! 122: "0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n"); ! 123: fprintf(outiibs, "};\n"); ! 124: fprintf(outiibs, "int iibs_num = %d;\n", total); ! 125: ! 126: fprintf(outfuncs, "};\n"); ! 127: ! 128: /* close outputs */ ! 129: ! 130: if (fclose(outiibs)) { ! 131: perror("fclose outiibs"); ! 132: exit(1); ! 133: } ! 134: if (fclose(outfuncs)) { ! 135: perror("fclose outfuncs"); ! 136: exit(1); ! 137: } ! 138: if (fclose(outproto)) { ! 139: perror("fclose outproto"); ! 140: exit(1); ! 141: } ! 142: ! 143: printf("done.\n"); ! 144: fflush(stdout); ! 145: ! 146: return(0); ! 147: } ! 148: ! 149: /* process a line */ ! 150: ! 151: void procline(char *line, int lineno, FILE *outiibs, FILE *outfuncs, ! 152: FILE *outproto) { ! 153: int i; ! 154: char *p; ! 155: t_bit bit = bit0, lastbit = bit0; ! 156: int start[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ! 157: int num[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ! 158: char mnemonic[16], *m; ! 159: int setting; ! 160: int clocks; ! 161: ! 162: /* parameters to fill in about instruction */ ! 163: int mnemonic_num; ! 164: uint16 mask = 0, bits = 0; /* see struct t_iib for details on */ ! 165: int priv = 0, endblk = 0; /* these variables */ ! 166: int imm_notzero = 0; ! 167: int used = 0, set = 0; ! 168: t_size isize = sz_none; ! 169: int expand_s_immsize = 0, expand_s_ea_e = 0; ! 170: int expand_d_ea_e = 0, expand_d_ea_f = 0; ! 171: t_datatype dtype = dt_Ill; ! 172: t_datatype stype = dt_Ill; ! 173: int e[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ! 174: int f[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; ! 175: int immvalue = 0; ! 176: int sbitpos = 0, dbitpos = 0; ! 177: ! 178: p = line; ! 179: ! 180: /* bitpattern */ ! 181: ! 182: for (i = 15; i >= 0; i--) { ! 183: while (*p == ' ') ! 184: p++; ! 185: ! 186: switch(*p) { ! 187: case '0': bit = bit0; mask |= 1<<i; break; ! 188: case '1': bit = bit1; mask |= 1<<i; bits |= 1<<i; break; ! 189: case 'z': bit = bitz; break; ! 190: case 'e': bit = bite; break; ! 191: case 'E': bit = bitE; break; ! 192: case 'f': bit = bitf; break; ! 193: case 'F': bit = bitF; break; ! 194: case 'n': bit = bitn; break; ! 195: case 'N': bit = bitN; break; ! 196: case 'i': bit = biti; break; ! 197: case 'c': bit = bitc; break; ! 198: case 'V': bit = bitv; break; ! 199: default: ! 200: fprintf(stderr, "%d: unknown char %c in bitpattern\n", lineno, *p); ! 201: exit(1); ! 202: } ! 203: ! 204: if (*p != '0' && *p != '1') { ! 205: if (num[bit]) { ! 206: /* we've seen this bit before, make sure the last bit was the same */ ! 207: if (bit < 15 && bit != lastbit) { ! 208: fprintf(stderr, "%d: Non contiguous bits of %c\n", lineno, *p); ! 209: exit(1); ! 210: } ! 211: } ! 212: /* we're looping down, so the last time start[bit] is set is the start */ ! 213: start[bit] = i; ! 214: /* record how many of these bits there are */ ! 215: num[bit]++; ! 216: } ! 217: p++; ! 218: lastbit = bit; ! 219: } ! 220: /* skip spaces and skip tab to get to next field */ ! 221: while (*p == ' ') ! 222: p++; ! 223: if (*p++ != '\t') { ! 224: fprintf(stderr, "%d: Tab not found at end of bitpattern\n", lineno); ! 225: exit(1); ! 226: } ! 227: ! 228: /* misc flags */ ! 229: ! 230: if (*p == '0') { ! 231: priv = 0; ! 232: } else if (*p == '1') { ! 233: priv = 1; ! 234: } else { ! 235: fprintf(stderr, "%d: Priv flag not 0 or 1\n", lineno); ! 236: exit(1); ! 237: } ! 238: p++; ! 239: /* skip spaces to next field */ ! 240: while (*p == ' ') ! 241: p++; ! 242: if (*p == '0') { ! 243: endblk = 0; ! 244: } else if (*p == '1') { ! 245: endblk = 1; ! 246: } else { ! 247: fprintf(stderr, "%d: End-block flag not 0 or 1\n", lineno); ! 248: exit(1); ! 249: } ! 250: p++; ! 251: /* skip spaces and skip tab to get to next field */ ! 252: while (*p == ' ') ! 253: p++; ! 254: if (*p++ != '\t') { ! 255: fprintf(stderr, "%d: Tab not found at end of flags\n", lineno); ! 256: exit(1); ! 257: } ! 258: ! 259: /* used flags */ ! 260: ! 261: for (i = 0; i < 5; i++) { ! 262: while (*p == ' ') ! 263: p++; ! 264: switch(*p++) { ! 265: case '-': break; ! 266: case 'x': break; ! 267: case 'X': used |= 1<<i; break; ! 268: case 'N': used |= 1<<i; break; ! 269: case 'Z': used |= 1<<i; break; ! 270: case 'V': used |= 1<<i; break; ! 271: case 'C': used |= 1<<i; break; ! 272: case '0': used |= 1<<i; break; ! 273: case '1': used |= 1<<i; break; ! 274: default: ! 275: fprintf(stderr, "%d: Did not understand used flag %d\n", lineno, i); ! 276: exit(1); ! 277: } ! 278: } ! 279: /* skip spaces and skip tab to get to next field */ ! 280: while (*p == ' ') ! 281: p++; ! 282: if (*p++ != '\t') { ! 283: fprintf(stderr, "%d: Tab not found at end of used flags\n", lineno); ! 284: exit(1); ! 285: } ! 286: ! 287: /* set flags */ ! 288: ! 289: for (i = 0; i < 5; i++) { ! 290: while (*p == ' ') ! 291: p++; ! 292: switch(*p++) { ! 293: case '-': break; ! 294: case 'x': break; ! 295: case 'X': set |= 1<<i; break; ! 296: case 'N': set |= 1<<i; break; ! 297: case 'Z': set |= 1<<i; break; ! 298: case 'V': set |= 1<<i; break; ! 299: case 'C': set |= 1<<i; break; ! 300: case '0': set |= 1<<i; break; ! 301: case '1': set |= 1<<i; break; ! 302: default: ! 303: fprintf(stderr, "%d: Did not understand set flag %d\n", lineno, i); ! 304: exit(1); ! 305: } ! 306: } ! 307: /* skip spaces and skip tab to get to next field */ ! 308: while (*p == ' ') ! 309: p++; ! 310: if (*p++ != '\t') { ! 311: fprintf(stderr, "%d: Tab not found at end of set flags\n", lineno); ! 312: exit(1); ! 313: } ! 314: ! 315: /* mnemonic */ ! 316: ! 317: m = mnemonic; ! 318: while (*p && (*p != '.') && (*p != ' ') && (*p != '\t')) { ! 319: *m++ = *p++; ! 320: } ! 321: if (*p == '\t') { ! 322: fprintf(stderr, "%d: Incorrect number of fields - extra tab found\n", ! 323: lineno); ! 324: exit(1); ! 325: } ! 326: *m = '\0'; ! 327: for (mnemonic_num = 0; *mnemonic_table[mnemonic_num].name; mnemonic_num++) ! 328: if (!strcmp(mnemonic_table[mnemonic_num].name, mnemonic)) ! 329: break; ! 330: if (!*mnemonic_table[mnemonic_num].name) { ! 331: fprintf(stderr, "%d: Unknown mnemonic '%s'\n", lineno, mnemonic); ! 332: exit(1); ! 333: } ! 334: /* set defaults for isize */ ! 335: isize = sz_none; ! 336: if (*p == '.') { ! 337: switch(*++p) { ! 338: case 'B': isize = sz_byte; break; ! 339: case 'W': isize = sz_word; break; ! 340: case 'L': isize = sz_long; break; ! 341: case 'z': ! 342: if (!num[bitz]) { ! 343: fprintf(stderr, "%d: 'z' given as size but no 'z' in bit pattern\n", ! 344: lineno); ! 345: exit(1); ! 346: } ! 347: /* size will be set automatically later */ ! 348: break; ! 349: default: ! 350: fprintf(stderr, "%d: Unknown size '%c' after mnemonic\n", ! 351: lineno, *p); ! 352: exit(1); ! 353: } ! 354: p++; ! 355: } else { ! 356: /* instruction is not sized */ ! 357: if (num[bitz]) { ! 358: /* oh, perhaps it is but it's a mistake */ ! 359: fprintf(stderr, "%d: 'z's in bit pattern but no .z after mnemonic\n", ! 360: lineno); ! 361: exit(1); ! 362: } ! 363: } ! 364: while (*p == ' ') ! 365: p++; ! 366: if (*p == '\0') { ! 367: /* no source and destination information given */ ! 368: if (num[bite] || num[bitE] || num[bitf] || num[bitF] || ! 369: num[biti] || num[bitn] || num[bitN] || num[bitv]) { ! 370: fprintf(stderr, "%d: No information given after mnemonic\n", lineno); ! 371: exit(1); ! 372: } ! 373: } else { ! 374: switch(*p++) { ! 375: case 'n': ! 376: case 'N': ! 377: if (*(p-1) == 'n') { ! 378: sbitpos = start[bitn]; ! 379: } else { ! 380: sbitpos = start[bitN]; ! 381: } ! 382: if (*p++ != '(') { ! 383: fprintf(stderr, "%d: missing qualifier for n()\n", lineno); ! 384: exit(1); ! 385: } ! 386: if (!strncmp(p, "Dreg", 4)) { stype = dt_Dreg; p = p+4; ! 387: } else if (!strncmp(p, "Areg", 4)) { stype = dt_Areg; p = p+4; ! 388: } else if (!strncmp(p, "Aind", 4)) { stype = dt_Aind; p = p+4; ! 389: } else if (!strncmp(p, "Ainc", 4)) { stype = dt_Ainc; p = p+4; ! 390: } else if (!strncmp(p, "Adec", 4)) { stype = dt_Adec; p = p+4; ! 391: } else if (!strncmp(p, "Adis", 4)) { stype = dt_Adis; p = p+4; ! 392: } else if (!strncmp(p, "Aidx", 4)) { stype = dt_Aidx; p = p+4; ! 393: } else if (!strncmp(p, "AbsW", 4)) { stype = dt_AbsW; p = p+4; ! 394: } else if (!strncmp(p, "AbsL", 4)) { stype = dt_AbsL; p = p+4; ! 395: } else if (!strncmp(p, "Pdis", 4)) { stype = dt_Pdis; p = p+4; ! 396: } else if (!strncmp(p, "Pidx", 4)) { stype = dt_Pidx; p = p+4; ! 397: } else { ! 398: fprintf(stderr, "%d: unknown qualifier for n()\n", lineno); ! 399: exit(1); ! 400: } ! 401: if (*p++ != ')') { ! 402: fprintf(stderr, "%d: unknown qualifier for n()\n", lineno); ! 403: exit(1); ! 404: } ! 405: break; ! 406: case '#': ! 407: switch(*p++) { ! 408: case 'B': stype = dt_ImmB; break; ! 409: case 'W': stype = dt_ImmW; break; ! 410: case 'L': stype = dt_ImmL; break; ! 411: case 'z': expand_s_immsize = 1; break; ! 412: case 's': ! 413: if (num[biti] != 8) { ! 414: fprintf(stderr, "%d: sign extend not from 8 bits\n", lineno); ! 415: exit(1); ! 416: } ! 417: stype = dt_Imm8s; ! 418: break; ! 419: case 'i': ! 420: switch (num[biti]) { ! 421: case 3: stype = dt_Imm3; break; ! 422: case 4: stype = dt_Imm4; break; ! 423: case 8: stype = dt_Imm8; break; ! 424: default: ! 425: fprintf(stderr, "%d: unknown immediate data size or bad dimension\n", ! 426: lineno); ! 427: exit(1); ! 428: } ! 429: sbitpos = start[biti]; ! 430: break; ! 431: case 'I': ! 432: imm_notzero = 1; ! 433: switch (num[biti]) { ! 434: case 3: stype = dt_Imm3; break; ! 435: case 4: stype = dt_Imm4; break; ! 436: case 8: stype = dt_Imm8; break; ! 437: default: ! 438: fprintf(stderr, "%d: unknown immediate data size or bad dimension\n", ! 439: lineno); ! 440: exit(1); ! 441: } ! 442: sbitpos = start[biti]; ! 443: break; ! 444: case 'V': ! 445: stype = dt_ImmV; ! 446: sbitpos = start[bitv]; ! 447: break; ! 448: default: ! 449: p--; ! 450: if (isdigit((int)*p)) { ! 451: immvalue = strtol(p, &p, 10); ! 452: stype = dt_ImmS; ! 453: } else { ! 454: fprintf(stderr, "%d: unknown source immediate type #%c\n", ! 455: lineno, *(p-1)); ! 456: exit(1); ! 457: } ! 458: } ! 459: break; ! 460: case 'e': ! 461: expand_s_ea_e = 1; ! 462: ! 463: if (*p++ != '(') { ! 464: fprintf(stderr, "%d: missing qualifier for EA\n", lineno); ! 465: exit(1); ! 466: } ! 467: do { ! 468: setting = 1; ! 469: if (*p == '-') { ! 470: p++; ! 471: setting = 0; ! 472: } ! 473: if (!strncmp(p, "*", 1)) { ! 474: e[ea_Dreg] = e[ea_Areg] = e[ea_Aind] = e[ea_Ainc] = setting; ! 475: e[ea_Adec] = e[ea_Adis] = e[ea_Aidx] = e[ea_AbsW] = setting; ! 476: e[ea_AbsL] = e[ea_Pdis] = e[ea_Pidx] = e[ea_Imm] = setting; ! 477: p = p+1; ! 478: } else if (!strncmp(p, "Regs", 4)) { ! 479: e[ea_Dreg] = e[ea_Areg] = setting; ! 480: p = p+4; ! 481: } else if (!strncmp(p, "PC", 2)) { ! 482: e[ea_Pdis] = e[ea_Pidx] = setting; ! 483: p = p+2; ! 484: } else if (!strncmp(p, "Amod", 4)) { ! 485: e[ea_Ainc] = e[ea_Adec] = setting; ! 486: p = p+4; ! 487: } else if (!strncmp(p, "Dreg", 4)) { e[ea_Dreg] = setting; p = p+4; ! 488: } else if (!strncmp(p, "Areg", 4)) { e[ea_Areg] = setting; p = p+4; ! 489: } else if (!strncmp(p, "Aind", 4)) { e[ea_Aind] = setting; p = p+4; ! 490: } else if (!strncmp(p, "Ainc", 4)) { e[ea_Ainc] = setting; p = p+4; ! 491: } else if (!strncmp(p, "Adec", 4)) { e[ea_Adec] = setting; p = p+4; ! 492: } else if (!strncmp(p, "Adis", 4)) { e[ea_Adis] = setting; p = p+4; ! 493: } else if (!strncmp(p, "Aidx", 4)) { e[ea_Aidx] = setting; p = p+4; ! 494: } else if (!strncmp(p, "AbsW", 4)) { e[ea_AbsW] = setting; p = p+4; ! 495: } else if (!strncmp(p, "AbsL", 4)) { e[ea_AbsL] = setting; p = p+4; ! 496: } else if (!strncmp(p, "Pdis", 4)) { e[ea_Pdis] = setting; p = p+4; ! 497: } else if (!strncmp(p, "Pidx", 4)) { e[ea_Pidx] = setting; p = p+4; ! 498: } else if (!strncmp(p, "Imm", 3)) { e[ea_Imm] = setting; p = p+3; ! 499: } else { ! 500: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 501: exit(1); ! 502: } ! 503: } while (*p++ == ','); ! 504: if (*(p-1) != ')') { ! 505: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 506: exit(1); ! 507: } ! 508: break; ! 509: default: ! 510: fprintf(stderr, "%d: did not understand source operand\n", lineno); ! 511: exit(1); ! 512: } ! 513: if (*p == ',') { ! 514: /* there is a destination part */ ! 515: p++; ! 516: switch(*p++) { ! 517: case 'n': ! 518: case 'N': ! 519: if (*(p-1) == 'n') { ! 520: dbitpos = start[bitn]; ! 521: } else { ! 522: dbitpos = start[bitN]; ! 523: } ! 524: if (*p++ != '(') { ! 525: fprintf(stderr, "%d: missing qualifier for n()\n", lineno); ! 526: exit(1); ! 527: } ! 528: if (!strncmp(p, "Dreg", 4)) { dtype = dt_Dreg; p = p+4; ! 529: } else if (!strncmp(p, "Areg", 4)) { dtype = dt_Areg; p = p+4; ! 530: } else if (!strncmp(p, "Aind", 4)) { dtype = dt_Aind; p = p+4; ! 531: } else if (!strncmp(p, "Ainc", 4)) { dtype = dt_Ainc; p = p+4; ! 532: } else if (!strncmp(p, "Adec", 4)) { dtype = dt_Adec; p = p+4; ! 533: } else if (!strncmp(p, "Adis", 4)) { dtype = dt_Adis; p = p+4; ! 534: } else if (!strncmp(p, "Aidx", 4)) { dtype = dt_Aidx; p = p+4; ! 535: } else if (!strncmp(p, "AbsW", 4)) { dtype = dt_AbsW; p = p+4; ! 536: } else if (!strncmp(p, "AbsL", 4)) { dtype = dt_AbsL; p = p+4; ! 537: } else if (!strncmp(p, "Pdis", 4)) { dtype = dt_Pdis; p = p+4; ! 538: } else if (!strncmp(p, "Pidx", 4)) { dtype = dt_Pidx; p = p+4; ! 539: } else { ! 540: fprintf(stderr, "%d: unknown qualifier for n()\n", lineno); ! 541: exit(1); ! 542: } ! 543: if (*p++ != ')') { ! 544: fprintf(stderr, "%d: unknown qualifier for n()\n", lineno); ! 545: exit(1); ! 546: } ! 547: break; ! 548: case 'e': ! 549: expand_d_ea_e = 1; ! 550: ! 551: if (*p++ != '(') { ! 552: fprintf(stderr, "%d: missing qualifier for EA\n", lineno); ! 553: exit(1); ! 554: } ! 555: do { ! 556: setting = 1; ! 557: if (*p == '-') { ! 558: p++; ! 559: setting = 0; ! 560: } ! 561: if (!strncmp(p, "*", 1)) { ! 562: e[ea_Dreg] = e[ea_Areg] = e[ea_Aind] = e[ea_Ainc] = setting; ! 563: e[ea_Adec] = e[ea_Adis] = e[ea_Aidx] = e[ea_AbsW] = setting; ! 564: e[ea_AbsL] = e[ea_Pdis] = e[ea_Pidx] = e[ea_Imm] = setting; ! 565: p = p+1; ! 566: } else if (!strncmp(p, "Regs", 4)) { ! 567: e[ea_Dreg] = e[ea_Areg] = setting; ! 568: p = p+4; ! 569: } else if (!strncmp(p, "PC", 2)) { ! 570: e[ea_Pdis] = e[ea_Pidx] = setting; ! 571: p = p+2; ! 572: } else if (!strncmp(p, "Amod", 4)) { ! 573: e[ea_Ainc] = e[ea_Adec] = setting; ! 574: p = p+4; ! 575: } else if (!strncmp(p, "Dreg", 4)) { e[ea_Dreg] = setting; p = p+4; ! 576: } else if (!strncmp(p, "Areg", 4)) { e[ea_Areg] = setting; p = p+4; ! 577: } else if (!strncmp(p, "Aind", 4)) { e[ea_Aind] = setting; p = p+4; ! 578: } else if (!strncmp(p, "Ainc", 4)) { e[ea_Ainc] = setting; p = p+4; ! 579: } else if (!strncmp(p, "Adec", 4)) { e[ea_Adec] = setting; p = p+4; ! 580: } else if (!strncmp(p, "Adis", 4)) { e[ea_Adis] = setting; p = p+4; ! 581: } else if (!strncmp(p, "Aidx", 4)) { e[ea_Aidx] = setting; p = p+4; ! 582: } else if (!strncmp(p, "AbsW", 4)) { e[ea_AbsW] = setting; p = p+4; ! 583: } else if (!strncmp(p, "AbsL", 4)) { e[ea_AbsL] = setting; p = p+4; ! 584: } else if (!strncmp(p, "Pdis", 4)) { e[ea_Pdis] = setting; p = p+4; ! 585: } else if (!strncmp(p, "Pidx", 4)) { e[ea_Pidx] = setting; p = p+4; ! 586: } else if (!strncmp(p, "Imm", 3)) { e[ea_Imm] = setting; p = p+3; ! 587: } else { ! 588: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 589: exit(1); ! 590: } ! 591: } while (*p++ == ','); ! 592: if (*(p-1) != ')') { ! 593: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 594: exit(1); ! 595: } ! 596: break; ! 597: case 'f': ! 598: expand_d_ea_f = 1; ! 599: ! 600: if (*p++ != '(') { ! 601: fprintf(stderr, "%d: missing qualifier for EA\n", lineno); ! 602: exit(1); ! 603: } ! 604: do { ! 605: setting = 1; ! 606: if (*p == '-') { ! 607: p++; ! 608: setting = 0; ! 609: } ! 610: if (!strncmp(p, "*", 1)) { ! 611: f[ea_Dreg] = f[ea_Areg] = f[ea_Aind] = f[ea_Ainc] = setting; ! 612: f[ea_Adec] = f[ea_Adis] = f[ea_Aidx] = f[ea_AbsW] = setting; ! 613: f[ea_AbsL] = f[ea_Pdis] = f[ea_Pidx] = f[ea_Imm] = setting; ! 614: p = p+1; ! 615: } else if (!strncmp(p, "Regs", 4)) { ! 616: f[ea_Dreg] = f[ea_Areg] = setting; ! 617: p = p+4; ! 618: } else if (!strncmp(p, "PC", 2)) { ! 619: f[ea_Pdis] = f[ea_Pidx] = setting; ! 620: p = p+2; ! 621: } else if (!strncmp(p, "Amod", 4)) { ! 622: f[ea_Ainc] = f[ea_Adec] = setting; ! 623: p = p+4; ! 624: } else if (!strncmp(p, "Dreg", 4)) { f[ea_Dreg] = setting; p = p+4; ! 625: } else if (!strncmp(p, "Areg", 4)) { f[ea_Areg] = setting; p = p+4; ! 626: } else if (!strncmp(p, "Aind", 4)) { f[ea_Aind] = setting; p = p+4; ! 627: } else if (!strncmp(p, "Ainc", 4)) { f[ea_Ainc] = setting; p = p+4; ! 628: } else if (!strncmp(p, "Adec", 4)) { f[ea_Adec] = setting; p = p+4; ! 629: } else if (!strncmp(p, "Adis", 4)) { f[ea_Adis] = setting; p = p+4; ! 630: } else if (!strncmp(p, "Aidx", 4)) { f[ea_Aidx] = setting; p = p+4; ! 631: } else if (!strncmp(p, "AbsW", 4)) { f[ea_AbsW] = setting; p = p+4; ! 632: } else if (!strncmp(p, "AbsL", 4)) { f[ea_AbsL] = setting; p = p+4; ! 633: } else if (!strncmp(p, "Pdis", 4)) { f[ea_Pdis] = setting; p = p+4; ! 634: } else if (!strncmp(p, "Pidx", 4)) { f[ea_Pidx] = setting; p = p+4; ! 635: } else if (!strncmp(p, "Imm", 3)) { f[ea_Imm] = setting; p = p+3; ! 636: } else { ! 637: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 638: exit(1); ! 639: } ! 640: } while (*p++ == ','); ! 641: if (*(p-1) != ')') { ! 642: fprintf(stderr, "%d: unknown qualifier for EA\n", lineno); ! 643: exit(1); ! 644: } ! 645: break; ! 646: default: ! 647: fprintf(stderr, "%d: did not understand dest operand\n", lineno); ! 648: exit(1); ! 649: } ! 650: } ! 651: } ! 652: if (*p != '\0') { ! 653: fprintf(stderr, "%d: no end-of-line found at end of line\n", lineno); ! 654: exit(1); ! 655: } ! 656: ! 657: /* checks */ ! 658: ! 659: if (expand_d_ea_e) { ! 660: if (e[ea_Imm]) { ! 661: fprintf(stderr, "%d: Immediate data not allowed as dest\n", lineno); ! 662: exit(1); ! 663: } ! 664: } ! 665: ! 666: if (expand_d_ea_f) { ! 667: if (f[ea_Imm]) { ! 668: fprintf(stderr, "%d: Immediate data not allowed as dest\n", lineno); ! 669: exit(1); ! 670: } ! 671: } ! 672: ! 673: if ((num[bite] && !num[bitE]) || (num[bitE] && !num[bite])) { ! 674: fprintf(stderr, "%d: There must be both eee and EEE\n", lineno); ! 675: exit(1); ! 676: } ! 677: ! 678: if ((num[bitf] && !num[bitF]) || (num[bitF] && !num[bitf])) { ! 679: fprintf(stderr, "%d: There must be both fff and FFF\n", lineno); ! 680: exit(1); ! 681: } ! 682: ! 683: if (num[bitf] && !expand_d_ea_f) { ! 684: fprintf(stderr, "%d: EA 'f' found but not used in description!\n", lineno); ! 685: exit(1); ! 686: } ! 687: ! 688: if (num[bite] && expand_d_ea_e && expand_s_ea_e) { ! 689: fprintf(stderr, "%d: EA used as both source and destination!\n", lineno); ! 690: exit(1); ! 691: } ! 692: ! 693: /* ok, now write to the output a structure for each line we're going to ! 694: do a CPU emulation routine for - this means we will expand anything ! 695: that might require control flow statements, e.g. EA and size bit ! 696: sections but not registers and immediate data that can be done in a ! 697: single instruction-wide '&' (and) statement. */ ! 698: ! 699: /* convert size/EA bits to static */ ! 700: ! 701: { ! 702: t_size size; ! 703: t_datatype ea_e; ! 704: t_datatype ea_f; ! 705: int skip; ! 706: int cc; ! 707: int wordlen, type; ! 708: int idx; ! 709: ! 710: /* loop through 3 different sizes or just once if no size to loop on */ ! 711: ! 712: for (size = isize; ! 713: (size == isize) || (num[bitz] && (size <= sz_long)); size++) { ! 714: ! 715: /* loop through 'e' EA or just once if no EA 'e' to loop on */ ! 716: ! 717: for (ea_e = ea_Dreg; ! 718: (ea_e == ea_Dreg) || (num[bite] && (ea_e <= ea_Imm)); ea_e++) { ! 719: ! 720: /* loop through 'f' EA or just once if no EA 'e' to loop on */ ! 721: ! 722: for (ea_f = ea_Dreg; ! 723: (ea_f == ea_Dreg) || (num[bitf] && (ea_f <= ea_Imm)); ea_f++) { ! 724: ! 725: for (cc = 0; (cc == 0) || (num[bitc] && (cc < 16)); cc++) { ! 726: ! 727: if (cc == 1) ! 728: continue; ! 729: ! 730: if ((size == sz_none) && num[bitz]) ! 731: continue; ! 732: ! 733: /* deal with size */ ! 734: ! 735: if (num[bitz]) { ! 736: /* set mask where zz is */ ! 737: mask |= (3<<start[bitz]); ! 738: /* clear bits where zz is */ ! 739: bits &= ~(3<<start[bitz]); ! 740: /* set correct value into where zz is */ ! 741: switch (size) { ! 742: case sz_byte: break; ! 743: case sz_word: bits |= (1<<start[bitz]); break; ! 744: case sz_long: bits |= (2<<start[bitz]); break; ! 745: default: ! 746: printf("%d: Invalid size\n", lineno); ! 747: continue; ! 748: } ! 749: if (expand_s_immsize) { ! 750: /* source immediate data depends on size of instruction */ ! 751: switch (size) { ! 752: case sz_byte: stype = dt_ImmB; break; ! 753: case sz_word: stype = dt_ImmW; break; ! 754: case sz_long: stype = dt_ImmL; break; ! 755: default: ! 756: printf("%d: Invalid size\n", lineno); ! 757: exit(1); ! 758: } ! 759: } ! 760: } ! 761: ! 762: /* deal with cc */ ! 763: ! 764: if (num[bitc]) { ! 765: /* set mask where cccc is */ ! 766: mask |= (15<<start[bitc]); ! 767: /* clear bits where cccc is */ ! 768: bits &= ~(15<<start[bitc]); ! 769: /* set correct value into where cccc is */ ! 770: bits |= cc<<start[bitc]; ! 771: } ! 772: ! 773: /* deal with EA 'e' when used as source */ ! 774: ! 775: if (num[bite] && expand_s_ea_e) { ! 776: if (!e[ea_e]) { ! 777: /* this has been disabled using -Axyz */ ! 778: continue; ! 779: } ! 780: /* clear everything */ ! 781: mask |= (7<<start[bite]); /* set mask for eee */ ! 782: mask &= ~(7<<start[bitE]); /* clear mask for EEE */ ! 783: bits &= ~(7<<start[bite]); /* clear bits in eee */ ! 784: bits &= ~(7<<start[bitE]); /* clear bits in EEE */ ! 785: if (ea_e <= ea_Aidx) { ! 786: /* ea mode with register in second part */ ! 787: bits |= (ea_e<<start[bite]); ! 788: switch (ea_e) { ! 789: case ea_Dreg: stype = dt_Dreg; sbitpos = start[bitE]; break; ! 790: case ea_Areg: stype = dt_Areg; sbitpos = start[bitE]; break; ! 791: case ea_Aind: stype = dt_Aind; sbitpos = start[bitE]; break; ! 792: case ea_Ainc: stype = dt_Ainc; sbitpos = start[bitE]; break; ! 793: case ea_Adec: stype = dt_Adec; sbitpos = start[bitE]; break; ! 794: case ea_Adis: stype = dt_Adis; sbitpos = start[bitE]; break; ! 795: case ea_Aidx: stype = dt_Aidx; sbitpos = start[bitE]; break; ! 796: default: abort(); ! 797: } ! 798: } else { ! 799: bits |= (7<<start[bite]); /* eee should be 111 */ ! 800: mask |= (7<<start[bitE]); ! 801: switch (ea_e) { ! 802: case ea_AbsW: stype = dt_AbsW; bits |= (0<<start[bitE]); break; ! 803: case ea_AbsL: stype = dt_AbsL; bits |= (1<<start[bitE]); break; ! 804: case ea_Pdis: stype = dt_Pdis; bits |= (2<<start[bitE]); break; ! 805: case ea_Pidx: stype = dt_Pidx; bits |= (3<<start[bitE]); break; ! 806: case ea_Imm: ! 807: bits |= (4<<start[bitE]); ! 808: switch (size) { ! 809: case sz_byte: stype = dt_ImmB; break; ! 810: case sz_word: stype = dt_ImmW; break; ! 811: case sz_long: stype = dt_ImmL; break; ! 812: default: ! 813: printf("%d: Invalid size\n", lineno); ! 814: exit(1); ! 815: } ! 816: break; ! 817: default: abort(); ! 818: } ! 819: } ! 820: } ! 821: ! 822: /* deal with EA 'e' when used as destination */ ! 823: ! 824: if (num[bite] && expand_d_ea_e) { ! 825: if (!e[ea_e]) { ! 826: /* this has been disabled using -Axyz */ ! 827: continue; ! 828: } ! 829: /* clear everything */ ! 830: mask |= (7<<start[bite]); /* set mask for eee */ ! 831: mask &= ~(7<<start[bitE]); /* clear mask for EEE */ ! 832: bits &= ~(7<<start[bite]); /* clear bits in eee */ ! 833: bits &= ~(7<<start[bitE]); /* clear bits in EEE */ ! 834: if (ea_e <= ea_Aidx) { ! 835: /* ea mode with register in second part */ ! 836: bits |= (ea_e<<start[bite]); ! 837: switch (ea_e) { ! 838: case ea_Dreg: dtype = dt_Dreg; dbitpos = start[bitE]; break; ! 839: case ea_Areg: dtype = dt_Areg; dbitpos = start[bitE]; break; ! 840: case ea_Aind: dtype = dt_Aind; dbitpos = start[bitE]; break; ! 841: case ea_Ainc: dtype = dt_Ainc; dbitpos = start[bitE]; break; ! 842: case ea_Adec: dtype = dt_Adec; dbitpos = start[bitE]; break; ! 843: case ea_Adis: dtype = dt_Adis; dbitpos = start[bitE]; break; ! 844: case ea_Aidx: dtype = dt_Aidx; dbitpos = start[bitE]; break; ! 845: default: abort(); ! 846: } ! 847: } else { ! 848: bits |= (7<<start[bite]); /* eee should be 111 */ ! 849: mask |= (7<<start[bitE]); ! 850: switch (ea_e) { ! 851: case ea_AbsW: dtype = dt_AbsW; bits |= (0<<start[bitE]); break; ! 852: case ea_AbsL: dtype = dt_AbsL; bits |= (1<<start[bitE]); break; ! 853: case ea_Pdis: dtype = dt_Pdis; bits |= (2<<start[bitE]); break; ! 854: case ea_Pidx: dtype = dt_Pidx; bits |= (3<<start[bitE]); break; ! 855: case ea_Imm: ! 856: bits |= (4<<start[bitE]); ! 857: switch (size) { ! 858: case sz_byte: dtype = dt_ImmB; break; ! 859: case sz_word: dtype = dt_ImmW; break; ! 860: case sz_long: dtype = dt_ImmL; break; ! 861: default: ! 862: printf("%d: Invalid size\n", lineno); ! 863: exit(1); ! 864: } ! 865: break; ! 866: default: abort(); ! 867: } ! 868: } ! 869: } ! 870: ! 871: /* deal with EA 'f' when used as destination */ ! 872: ! 873: if (num[bitf] && expand_d_ea_f) { ! 874: if (!f[ea_f]) { ! 875: /* this has been disabled using -Axyz */ ! 876: continue; ! 877: } ! 878: /* clear everything */ ! 879: mask |= (7<<start[bitf]); /* set mask for fff */ ! 880: mask &= ~(7<<start[bitF]); /* clear mask for FFF */ ! 881: bits &= ~(7<<start[bitf]); /* clear bits in fff */ ! 882: bits &= ~(7<<start[bitF]); /* clear bits in FFF */ ! 883: if (ea_f <= ea_Aidx) { ! 884: /* ea mode with register in second part */ ! 885: bits |= (ea_f<<start[bitf]); ! 886: switch (ea_f) { ! 887: case ea_Dreg: dtype = dt_Dreg; dbitpos = start[bitF]; break; ! 888: case ea_Areg: dtype = dt_Areg; dbitpos = start[bitF]; break; ! 889: case ea_Aind: dtype = dt_Aind; dbitpos = start[bitF]; break; ! 890: case ea_Ainc: dtype = dt_Ainc; dbitpos = start[bitF]; break; ! 891: case ea_Adec: dtype = dt_Adec; dbitpos = start[bitF]; break; ! 892: case ea_Adis: dtype = dt_Adis; dbitpos = start[bitF]; break; ! 893: case ea_Aidx: dtype = dt_Aidx; dbitpos = start[bitF]; break; ! 894: default: abort(); ! 895: } ! 896: } else { ! 897: bits |= (7<<start[bitf]); /* eee should be 111 */ ! 898: mask |= (7<<start[bitF]); ! 899: switch (ea_f) { ! 900: case ea_AbsW: dtype = dt_AbsW; bits |= (0<<start[bitF]); break; ! 901: case ea_AbsL: dtype = dt_AbsL; bits |= (1<<start[bitF]); break; ! 902: case ea_Pdis: dtype = dt_Pdis; bits |= (2<<start[bitF]); break; ! 903: case ea_Pidx: dtype = dt_Pidx; bits |= (3<<start[bitF]); break; ! 904: case ea_Imm: ! 905: bits |= (4<<start[bitF]); ! 906: switch (size) { ! 907: case sz_byte: dtype = dt_ImmB; break; ! 908: case sz_word: dtype = dt_ImmW; break; ! 909: case sz_long: dtype = dt_ImmL; break; ! 910: default: ! 911: printf("%d: Invalid size\n", lineno); ! 912: exit(1); ! 913: } ! 914: break; ! 915: default: abort(); ! 916: } ! 917: } ! 918: } ! 919: ! 920: wordlen = 1; ! 921: for (type = 0; type < 2; type++) { ! 922: switch(type ? stype : dtype) { ! 923: case dt_Ill: ! 924: case dt_Dreg: ! 925: case dt_Areg: ! 926: case dt_Aind: ! 927: case dt_Ainc: ! 928: case dt_Adec: ! 929: break; ! 930: case dt_Adis: ! 931: case dt_Aidx: ! 932: case dt_AbsW: ! 933: case dt_Pdis: ! 934: case dt_Pidx: ! 935: case dt_ImmB: ! 936: case dt_ImmW: ! 937: wordlen++; ! 938: break; ! 939: case dt_AbsL: ! 940: case dt_ImmL: ! 941: wordlen+= 2; ! 942: break; ! 943: case dt_ImmS: ! 944: case dt_Imm3: ! 945: case dt_Imm4: ! 946: case dt_Imm8: ! 947: case dt_Imm8s: ! 948: case dt_ImmV: ! 949: break; ! 950: default: ! 951: printf("%d: Invalid type\n", lineno); ! 952: exit(1); ! 953: } ! 954: } ! 955: ! 956: /* BUG: The immediate instructions are probably not correct, ! 957: e.g. ADDI, ADDQ, ANDI, CMPI, EORI, MOVEQ, ORI, SUBI, SUBQ */ ! 958: ! 959: clocks = -1; ! 960: ! 961: switch(mnemonic_num) { ! 962: case i_EOR: ! 963: if (dtype == dt_Dreg) { ! 964: clocks = size != sz_long ? 4 : 8; ! 965: clocks+= clocks_eacalc(stype, size); ! 966: } else if (stype == dt_Dreg) { ! 967: clocks = size != sz_long ? 8 : 12; ! 968: clocks+= clocks_eacalc(dtype, size); ! 969: } else { ! 970: clocks = size != sz_long ? 20 : 12; ! 971: clocks+= clocks_eacalc(dtype, size); ! 972: } ! 973: break; ! 974: case i_OR: ! 975: case i_AND: ! 976: if (dtype == dt_Dreg) { ! 977: clocks = size != sz_long ? 4 : clocks_6or8(stype); ! 978: clocks+= clocks_eacalc(stype, size); ! 979: } else if (stype == dt_Dreg) { ! 980: clocks = size != sz_long ? 8 : 12; ! 981: clocks+= clocks_eacalc(dtype, size); ! 982: } else { ! 983: clocks = size != sz_long ? 20 : 12; ! 984: clocks+= clocks_eacalc(dtype, size); ! 985: } ! 986: break; ! 987: case i_ADDA: ! 988: case i_SUBA: ! 989: if (dtype == dt_Areg) { ! 990: clocks = size != sz_long ? 8 : clocks_6or8(stype); ! 991: clocks+= clocks_eacalc(stype, size); ! 992: } else { ! 993: printf("%d: clock count invalid type\n", lineno); ! 994: exit(1); ! 995: } ! 996: break; ! 997: case i_ADD: ! 998: case i_SUB: ! 999: if (dtype == dt_Dreg) { ! 1000: clocks = size != sz_long ? 4 : clocks_6or8(stype); ! 1001: clocks+= clocks_eacalc(stype, size); ! 1002: } else if (stype == dt_Dreg) { ! 1003: clocks = size != sz_long ? 8 : 12; ! 1004: clocks+= clocks_eacalc(dtype, size); ! 1005: } else { ! 1006: clocks = size != sz_long ? 20 : 12; ! 1007: clocks+= clocks_eacalc(dtype, size); ! 1008: } ! 1009: break; ! 1010: case i_CMP: ! 1011: case i_CMPA: ! 1012: if (dtype == dt_Areg) { ! 1013: clocks = 6; ! 1014: clocks+= clocks_eacalc(stype, size); ! 1015: } else if (dtype == dt_Dreg) { ! 1016: clocks = size != sz_long ? 4 : 6; ! 1017: clocks+= clocks_eacalc(stype, size); ! 1018: } else { /* CMPM */ ! 1019: clocks = 12 + clocks_eacalc(stype, size) + ! 1020: clocks_eacalc(dtype, size); ! 1021: } ! 1022: break; ! 1023: case i_DIVS: ! 1024: clocks = 158 - 8 + clocks_eacalc(stype, size); ! 1025: break; ! 1026: case i_DIVU: ! 1027: clocks = 140 - 8 + clocks_eacalc(stype, size); ! 1028: break; ! 1029: case i_MULS: ! 1030: clocks = 38 + clocks_eacalc(stype, size); ! 1031: break; ! 1032: case i_MULU: ! 1033: clocks = 38 + clocks_eacalc(stype, size); ! 1034: break; ! 1035: case i_MOVE: ! 1036: case i_MOVEA: ! 1037: if ((idx = clocks_typetoindex(dtype)) == -1) { ! 1038: printf("%d: clock count invalid MOVE type\n", lineno); ! 1039: exit(1); ! 1040: } ! 1041: clocks = clocks_movetable[clocks_typetoindex(stype)*9+idx]; ! 1042: break; ! 1043: case i_CLR: ! 1044: case i_NEG: ! 1045: case i_NEGX: ! 1046: case i_NOT: ! 1047: if (stype == dt_Dreg || stype == dt_Areg) { ! 1048: clocks = size != sz_long ? 4 : 6; ! 1049: } else { ! 1050: clocks = size != sz_long ? 8 : 12; ! 1051: clocks+= clocks_eacalc(stype, size); ! 1052: } ! 1053: break; ! 1054: case i_NBCD: ! 1055: if (stype == dt_Dreg || stype == dt_Areg) { ! 1056: clocks = 6; ! 1057: } else { ! 1058: clocks = 8 + clocks_eacalc(stype, size); ! 1059: } ! 1060: break; ! 1061: case i_Scc: ! 1062: case i_SF: ! 1063: if (stype == dt_Dreg || stype == dt_Areg) { ! 1064: clocks = size != sz_long ? 4 : 6; ! 1065: } else { ! 1066: clocks = 8 + clocks_eacalc(stype, size); ! 1067: } ! 1068: break; ! 1069: case i_TAS: ! 1070: if (stype == dt_Dreg || stype == dt_Areg) { ! 1071: clocks = 4; ! 1072: } else { ! 1073: clocks = 10 + clocks_eacalc(stype, size); ! 1074: } ! 1075: break; ! 1076: case i_TST: ! 1077: if (stype == dt_Dreg || stype == dt_Areg) { ! 1078: clocks = 4; ! 1079: } else { ! 1080: clocks = 4 + clocks_eacalc(stype, size); ! 1081: } ! 1082: break; ! 1083: case i_ASR: ! 1084: case i_ASL: ! 1085: case i_LSR: ! 1086: case i_LSL: ! 1087: case i_ROR: ! 1088: case i_ROL: ! 1089: case i_ROXR: ! 1090: case i_ROXL: ! 1091: if (stype == dt_Dreg || stype == dt_Areg) { ! 1092: clocks = size != sz_long ? 8 : 10; /* minimums */ ! 1093: } else { ! 1094: clocks = 8 + clocks_eacalc(stype, size); ! 1095: } ! 1096: break; ! 1097: case i_BCHG: ! 1098: case i_BSET: ! 1099: if (stype == dt_Dreg) { /* dynamic */ ! 1100: clocks = (dtype == dt_Dreg) ? 8 : 8 + ! 1101: clocks_eacalc(stype, size); ! 1102: } else { /* static */ ! 1103: clocks = (dtype == dt_Dreg) ? 14 : 12 + ! 1104: clocks_eacalc(stype, size); ! 1105: } ! 1106: case i_BCLR: ! 1107: if (stype == dt_Dreg) { /* dynamic */ ! 1108: clocks = (dtype == dt_Dreg) ? 10 : 8 + ! 1109: clocks_eacalc(stype, size); ! 1110: } else { /* static */ ! 1111: clocks = (dtype == dt_Dreg) ? 14 : 12 + ! 1112: clocks_eacalc(stype, size); ! 1113: } ! 1114: break; ! 1115: case i_BTST: ! 1116: if (stype == dt_Dreg) { /* dynamic */ ! 1117: clocks = (dtype == dt_Dreg) ? 6 : 4 + ! 1118: clocks_eacalc(stype, size); ! 1119: } else { /* static */ ! 1120: clocks = (dtype == dt_Dreg) ? 10 : 8 + ! 1121: clocks_eacalc(stype, size); ! 1122: } ! 1123: break; ! 1124: case i_JMP: ! 1125: switch(stype) { ! 1126: case dt_Aind: clocks = 8; break; ! 1127: case dt_Adis: clocks = 10; break; ! 1128: case dt_Aidx: clocks = 14; break; ! 1129: case dt_AbsW: clocks = 10; break; ! 1130: case dt_AbsL: clocks = 12; break; ! 1131: case dt_Pdis: clocks = 10; break; ! 1132: case dt_Pidx: clocks = 14; break; ! 1133: default: ! 1134: printf("%d: clock count invalid type\n", lineno); ! 1135: exit(1); ! 1136: } ! 1137: break; ! 1138: case i_JSR: ! 1139: switch(stype) { ! 1140: case dt_Aind: clocks = 16; break; ! 1141: case dt_Adis: clocks = 18; break; ! 1142: case dt_Aidx: clocks = 22; break; ! 1143: case dt_AbsW: clocks = 18; break; ! 1144: case dt_AbsL: clocks = 20; break; ! 1145: case dt_Pdis: clocks = 18; break; ! 1146: case dt_Pidx: clocks = 22; break; ! 1147: default: ! 1148: printf("%d: clock count invalid type\n", lineno); ! 1149: exit(1); ! 1150: } ! 1151: break; ! 1152: case i_LEA: ! 1153: switch(stype) { ! 1154: case dt_Aind: clocks = 4; break; ! 1155: case dt_Adis: clocks = 8; break; ! 1156: case dt_Aidx: clocks = 12; break; ! 1157: case dt_AbsW: clocks = 8; break; ! 1158: case dt_AbsL: clocks = 12; break; ! 1159: case dt_Pdis: clocks = 8; break; ! 1160: case dt_Pidx: clocks = 12; break; ! 1161: default: ! 1162: printf("%d: clock count invalid type\n", lineno); ! 1163: exit(1); ! 1164: } ! 1165: break; ! 1166: case i_PEA: ! 1167: switch(stype) { ! 1168: case dt_Aind: clocks = 12; break; ! 1169: case dt_Adis: clocks = 16; break; ! 1170: case dt_Aidx: clocks = 20; break; ! 1171: case dt_AbsW: clocks = 16; break; ! 1172: case dt_AbsL: clocks = 20; break; ! 1173: case dt_Pdis: clocks = 16; break; ! 1174: case dt_Pidx: clocks = 20; break; ! 1175: default: ! 1176: printf("%d: clock count invalid type\n", lineno); ! 1177: exit(1); ! 1178: } ! 1179: break; ! 1180: case i_MOVEMMR: ! 1181: clocks = 20; ! 1182: break; ! 1183: case i_MOVEMRM: ! 1184: clocks = 16; ! 1185: break; ! 1186: case i_SUBX: ! 1187: case i_ADDX: ! 1188: if (stype == dt_Dreg) { ! 1189: clocks = size != sz_long ? 4 : 8; ! 1190: } else { ! 1191: clocks = size != sz_long ? 18 : 30; ! 1192: } ! 1193: break; ! 1194: case i_ABCD: ! 1195: case i_SBCD: ! 1196: clocks = (stype == dt_Dreg) ? 6 : 18; ! 1197: break; ! 1198: case i_ORSR: ! 1199: case i_ANDSR: ! 1200: case i_EORSR: ! 1201: clocks = 20; ! 1202: break; ! 1203: case i_CHK: ! 1204: clocks = 10 + clocks_eacalc(stype, size); ! 1205: break; ! 1206: case i_EXG: ! 1207: clocks = 6; ! 1208: break; ! 1209: case i_EXT: ! 1210: clocks = 4; ! 1211: break; ! 1212: case i_LINK: ! 1213: clocks = 16; ! 1214: break; ! 1215: case i_MOVEFSR: ! 1216: clocks = (stype == dt_Dreg) ? 6 : 8 + clocks_eacalc(stype, size); ! 1217: break; ! 1218: case i_MOVETSR: ! 1219: clocks = (stype == dt_Dreg) ? 12 : 12 + ! 1220: clocks_eacalc(stype, size); ! 1221: break; ! 1222: case i_MOVETUSP: ! 1223: case i_MOVEFUSP: ! 1224: clocks = 4; ! 1225: break; ! 1226: case i_NOP: ! 1227: clocks = 4; ! 1228: break; ! 1229: case i_RESET: ! 1230: clocks = 132; ! 1231: break; ! 1232: case i_RTE: ! 1233: case i_RTR: ! 1234: clocks = 20; ! 1235: break; ! 1236: case i_RTS: ! 1237: clocks = 20; ! 1238: break; ! 1239: case i_STOP: ! 1240: clocks = 4; ! 1241: break; ! 1242: case i_SWAP: ! 1243: clocks = 4; ! 1244: break; ! 1245: case i_TRAPV: ! 1246: clocks = 4; ! 1247: break; ! 1248: case i_TRAP: ! 1249: clocks = 4; /* exception */ ! 1250: break; ! 1251: case i_UNLK: ! 1252: clocks = 12; ! 1253: break; ! 1254: case i_DBcc: ! 1255: case i_DBRA: ! 1256: case i_Bcc: ! 1257: clocks = 10; ! 1258: break; ! 1259: case i_BSR: ! 1260: clocks = 18; ! 1261: break; ! 1262: case i_MOVEPRM: ! 1263: case i_MOVEPMR: ! 1264: clocks = (size != sz_long) ? 16 : 24; ! 1265: break; ! 1266: case i_ILLG: ! 1267: clocks = 0; ! 1268: break; ! 1269: case i_LINE10: ! 1270: case i_LINE15: ! 1271: clocks = 4; /* exception */ ! 1272: break; ! 1273: default: ! 1274: printf("%d: Invalid mnemonic type\n", lineno); ! 1275: exit(1); ! 1276: } ! 1277: ! 1278: if (clocks == -1) { ! 1279: printf("%d: Clocks not found\n", lineno); ! 1280: exit(1); ! 1281: } ! 1282: ! 1283: /* write output lines */ ! 1284: ! 1285: fprintf(outiibs, " { 0x%x, 0x%x, %d, { %d, %d, %d, %d, %d }, ", ! 1286: mask, bits, mnemonic_num, priv, endblk, imm_notzero, used, ! 1287: set); ! 1288: fprintf(outiibs, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d},\n", ! 1289: size, stype, dtype, sbitpos, dbitpos, immvalue, ! 1290: cc, total, wordlen, clocks); ! 1291: fprintf(outiibs, "%60s/* %s */\n", "", mnemonic); ! 1292: if (set == 0) { ! 1293: fprintf(outfuncs, " cpu_op_%ia, /* %s */\n", total, mnemonic); ! 1294: fprintf(outfuncs, " cpu_op_%ia, /* %s */\n", total, mnemonic); ! 1295: fprintf(outproto, "extern void cpu_op_%ia(" ! 1296: "t_ipc *ipc); /* %s */\n", total, mnemonic); ! 1297: } else { ! 1298: fprintf(outfuncs, " cpu_op_%ia, /* %s - normal */\n", total, ! 1299: mnemonic); ! 1300: fprintf(outfuncs, " cpu_op_%ib, /* %s - no flags */\n", total, ! 1301: mnemonic); ! 1302: fprintf(outproto, "extern void cpu_op_%ia(" ! 1303: "t_ipc *ipc); /* %s */\n", total, mnemonic); ! 1304: fprintf(outproto, "extern void cpu_op_%ib(" ! 1305: "t_ipc *ipc); /* %s */\n", total, mnemonic); ! 1306: } ! 1307: ! 1308: total++; ! 1309: ! 1310: } /* cc */ ! 1311: } /* ea_f */ ! 1312: } /* ea_e */ ! 1313: } /* size */ ! 1314: } /* block */ ! 1315: } ! 1316: ! 1317: int clocks_movetable[] = { ! 1318: 4, 4, 8, 8, 8, 12, 14, 12, 16, ! 1319: 4, 4, 8, 8, 8, 12, 14, 12, 16, ! 1320: 8, 8, 12, 12, 12, 16, 18, 16, 20, ! 1321: 8, 8, 12, 12, 12, 16, 18, 16, 20, ! 1322: 10, 10, 14, 14, 14, 18, 20, 18, 22, ! 1323: 12, 12, 16, 16, 16, 20, 22, 20, 24, ! 1324: 14, 14, 18, 18, 18, 22, 24, 22, 26, ! 1325: 12, 12, 16, 16, 16, 20, 22, 20, 24, ! 1326: 16, 16, 20, 20, 20, 24, 26, 24, 28, ! 1327: 12, 12, 16, 16, 16, 20, 22, 20, 24, ! 1328: 14, 14, 18, 18, 18, 22, 24, 22, 26, ! 1329: 8, 8, 12, 12, 12, 16, 18, 16, 20 ! 1330: }; ! 1331: ! 1332: int clocks_typetoindex(t_datatype type) ! 1333: { ! 1334: switch(type) { ! 1335: case dt_Dreg: return 0; ! 1336: case dt_Areg: return 1; ! 1337: case dt_Aind: return 2; ! 1338: case dt_Ainc: return 3; ! 1339: case dt_Adec: return 4; ! 1340: case dt_Adis: return 5; ! 1341: case dt_Aidx: return 6; ! 1342: case dt_AbsW: return 7; ! 1343: case dt_AbsL: return 8; ! 1344: case dt_Pdis: return 9; ! 1345: case dt_Pidx: return 10; ! 1346: case dt_ImmB: ! 1347: case dt_ImmW: ! 1348: case dt_ImmL: ! 1349: case dt_ImmS: ! 1350: case dt_Imm3: ! 1351: case dt_Imm4: ! 1352: case dt_Imm8: ! 1353: case dt_Imm8s: return 11; ! 1354: default: ! 1355: break; ! 1356: } ! 1357: printf("Invalid type for clocks\n"); ! 1358: exit(1); ! 1359: } ! 1360: ! 1361: int clocks_eacalc(t_datatype type, t_size size) ! 1362: { ! 1363: int clks = 0; ! 1364: ! 1365: switch(type) { ! 1366: case dt_Dreg: ! 1367: case dt_Areg: return 0; ! 1368: case dt_Aind: return (size != sz_long) ? 4 : 8; ! 1369: case dt_Ainc: return (size != sz_long) ? 6 : 10; /* should this be 4/8? */ ! 1370: case dt_Adec: return (size != sz_long) ? 6 : 10; ! 1371: case dt_Adis: return (size != sz_long) ? 8 : 12; ! 1372: case dt_Aidx: return (size != sz_long) ? 10 : 14; ! 1373: case dt_AbsW: return (size != sz_long) ? 8 : 12; ! 1374: case dt_AbsL: return (size != sz_long) ? 12 : 16; ! 1375: case dt_Pdis: return (size != sz_long) ? 8 : 12; ! 1376: case dt_Pidx: return (size != sz_long) ? 10 : 14; ! 1377: case dt_ImmB: ! 1378: case dt_ImmW: ! 1379: case dt_ImmL: return (size != sz_long) ? 4 : 8; ! 1380: case dt_ImmS: ! 1381: case dt_Imm3: ! 1382: case dt_Imm4: ! 1383: case dt_Imm8: ! 1384: case dt_Imm8s: ! 1385: case dt_Ill: return 0; ! 1386: default: ! 1387: } ! 1388: printf("Invalid type for clocks\n"); ! 1389: exit(1); ! 1390: } ! 1391: ! 1392: int clocks_6or8(t_datatype type) ! 1393: { ! 1394: int type_imm = (type == dt_ImmB) || (type == dt_ImmW) || ! 1395: (type == dt_ImmL) || (type == dt_Imm3) || (type == dt_Imm4) || ! 1396: (type == dt_Imm8) || (type == dt_Imm8s) || (type == dt_ImmS); ! 1397: ! 1398: return (type_imm || type == dt_Dreg || type == dt_Areg) ? 8 : 6; ! 1399: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.