|
|
1.1 ! root 1: /* Copyright (c) 1984 Regents of the University of California */ ! 2: ! 3: #ifndef lint ! 4: static char sccsid[] = "@(#)machdep.c 1.4 (Berkeley) 9/20/84"; ! 5: #endif not lint ! 6: ! 7: #include <stdio.h> ! 8: #include <ctype.h> ! 9: #include "inline.h" ! 10: ! 11: /* ! 12: * The routines and tables in this file must be rewritten ! 13: * for each new machine that this program is ported to. ! 14: */ ! 15: ! 16: #ifdef vax ! 17: /* ! 18: * Instruction stop table. ! 19: * All instructions that implicitly modify any of the temporary ! 20: * registers, change control flow, or implicitly loop must be ! 21: * listed in this table. It is used to find the end of a basic ! 22: * block when scanning backwards through the instruction stream ! 23: * trying to merge the inline expansion. ! 24: */ ! 25: struct inststoptbl inststoptable[] = { ! 26: { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" }, ! 27: { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" }, ! 28: { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" }, ! 29: { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" }, ! 30: { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, ! 31: { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" }, ! 32: { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" }, ! 33: { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" }, ! 34: { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" }, ! 35: { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" }, ! 36: { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" }, ! 37: { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" }, ! 38: { "bcs" }, { "brb" }, { "brw" }, { "jmp" }, ! 39: { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" }, ! 40: { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" }, ! 41: { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" }, ! 42: { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" }, ! 43: { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" }, ! 44: { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" }, ! 45: { "callg" }, { "calls" }, { "ret" }, ! 46: { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" }, ! 47: { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" }, ! 48: { "locc" }, { "skpc" }, { "matchc" }, { "crc" }, ! 49: { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" }, ! 50: { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" }, ! 51: { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" }, ! 52: { "ashp" }, { "editpc" }, ! 53: { "escd" }, { "esce" }, { "escf" }, ! 54: { "" } ! 55: }; ! 56: ! 57: /* ! 58: * Check to see if a line is a candidate for replacement. ! 59: * Return pointer to name to be looked up in pattern table. ! 60: */ ! 61: char * ! 62: doreplaceon(cp) ! 63: char *cp; ! 64: { ! 65: ! 66: if (bcmp(cp, "calls\t$", 7) == 0) ! 67: return (cp + 7); ! 68: return (0); ! 69: } ! 70: ! 71: /* ! 72: * Find the next argument to the function being expanded. ! 73: * If register ends with a '#' then source may be used directly. ! 74: * If register ends with a '@' then source may be used if an indirect ! 75: * version exists. ! 76: */ ! 77: ! 78: nextarg(argc, argv, flag) ! 79: int argc; ! 80: char *argv[]; ! 81: int *flag; ! 82: { ! 83: register char *lastarg = argv[2]; ! 84: ! 85: *flag = 0; ! 86: ! 87: if (argc == 3 && ! 88: bcmp(argv[0], "mov", 3) == 0 && ! 89: bcmp(argv[1], "(sp)+", 6) == 0 && ! 90: lastarg[0] == 'r' && isdigit(lastarg[1])) { ! 91: if (lastarg[2] == '\0') { ! 92: return (lastarg[1] - '0'); ! 93: } else if (lastarg[2] == '$') { ! 94: *flag = F_VALUE; ! 95: return (lastarg[1] - '0'); ! 96: } else if (lastarg[2] == '*') { ! 97: *flag = F_INDIRECT; ! 98: return (lastarg[1] - '0'); ! 99: } ! 100: } ! 101: return (-1); ! 102: } ! 103: ! 104: /* ! 105: * Determine whether the current line pushes an argument. ! 106: */ ! 107: ispusharg(argc, argv) ! 108: int argc; ! 109: char *argv[]; ! 110: { ! 111: ! 112: if (argc < 2) ! 113: return (0); ! 114: if (argc == 2 && bcmp(argv[0], "push", 4) == 0) ! 115: return (1); ! 116: if (bcmp(argv[argc - 1], "-(sp)", 6) == 0) ! 117: return (1); ! 118: return (0); ! 119: } ! 120: ! 121: /* ! 122: * Determine which (if any) registers are modified ! 123: * Return register number that is modified, -1 if none are modified. ! 124: */ ! 125: modifies(argc, argv) ! 126: int argc; ! 127: char *argv[]; ! 128: { ! 129: /* ! 130: * For the VAX all we care about are r0 to r5 ! 131: */ ! 132: register char *lastarg = argv[argc - 1]; ! 133: ! 134: if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 135: return (lastarg[1] - '0'); ! 136: return (-1); ! 137: } ! 138: ! 139: checkvar(argc, argv, flag, source, mod) ! 140: int argc; ! 141: char *argv[]; ! 142: int flag; ! 143: char *source; ! 144: { ! 145: register char *cp1, *cp2; ! 146: register int opind = 0; ! 147: char *indirect(); ! 148: ! 149: if (flag == 0) return(0); ! 150: ! 151: if (bcmp(argv[0], "push", 4) != 0 && bcmp(argv[0], "mov", 3) != 0) ! 152: return(0); ! 153: ! 154: cp1 = argv[1]; ! 155: while (*cp1) if (*cp1++ == 'r' && isdigit(*cp1) && ! 156: (mod & (1 << (*cp1++ - '0'))) && ! 157: (*cp1 == '\0' || *cp1 == ')' || *cp1 == ']')) ! 158: return(0); ! 159: ! 160: if ((argv[0][0] == 'p' && argv[0][4] == 'a') || ! 161: (argv[0][0] == 'm' && argv[0][3] == 'a')) ! 162: opind++; ! 163: ! 164: if (flag & F_VALUE) { ! 165: if (opind) return(0); ! 166: cp1 = argv[1]; ! 167: cp2 = source; ! 168: while (*cp2++ = *cp1++) ; ! 169: return(1); ! 170: } ! 171: ! 172: if (flag & F_INDIRECT) { ! 173: cp2 = source; ! 174: if (opind) { ! 175: cp1 = argv[1]; ! 176: } else { ! 177: cp1 = indirect(argv[1]); ! 178: if (cp1 == NULL) return(0); ! 179: } ! 180: while (*cp2++ = *cp1++) ; ! 181: return(1); ! 182: } ! 183: ! 184: return(0); ! 185: } ! 186: ! 187: /* ! 188: * Rewrite the instruction in (argc, argv) to store its ! 189: * contents into arg instead of onto the stack. The new ! 190: * instruction is placed in the buffer that is provided. ! 191: */ ! 192: rewrite(instbuf, argc, argv, target) ! 193: char *instbuf; ! 194: int argc; ! 195: char *argv[]; ! 196: int target; ! 197: { ! 198: ! 199: switch (argc) { ! 200: case 0: ! 201: instbuf[0] = '\0'; ! 202: fprintf("blank line to rewrite?\n"); ! 203: return; ! 204: case 1: ! 205: sprintf(instbuf, "\t%s\n", argv[0]); ! 206: fprintf(stderr, "rewrite?-> %s", instbuf); ! 207: return; ! 208: case 2: ! 209: if (bcmp(argv[0], "push", 4) == 0) { ! 210: sprintf(instbuf, "\tmov%s\t%s,r%d\n", ! 211: &argv[0][4], argv[1], target); ! 212: return; ! 213: } ! 214: sprintf(instbuf, "\t%s\tr%d\n", argv[0], target); ! 215: return; ! 216: case 3: ! 217: sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target); ! 218: return; ! 219: case 4: ! 220: sprintf(instbuf, "\t%s\t%s,%s,r%d\n", ! 221: argv[0], argv[1], argv[2], target); ! 222: return; ! 223: case 5: ! 224: sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n", ! 225: argv[0], argv[1], argv[2], argv[3], target); ! 226: return; ! 227: default: ! 228: sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); ! 229: argc -= 2, argv += 2; ! 230: while (argc-- > 0) { ! 231: strcat(instbuf, ","); ! 232: strcat(instbuf, *argv++); ! 233: } ! 234: strcat(instbuf, "\n"); ! 235: fprintf(stderr, "rewrite?-> %s", instbuf); ! 236: return; ! 237: } ! 238: } ! 239: ! 240: /* Return indirect version of variable: ! 241: * $Lnn -> Lnn ! 242: * rn -> (rn) ! 243: * (rn) -> *(rn) ! 244: * a(rn) -> *a(rn) ! 245: * (rn)[rm] -> *(rn)[rm] ! 246: * a(rn)[rm] -> *a(rn)[rm] ! 247: * _foo -> *_foo ! 248: * _foo(rn) -> *_foo(rn) ! 249: * _foo(rn)[rm] -> *_foo(rn)[rm] ! 250: * (rn)+ -> NULL ! 251: * -(rn) -> NULL ! 252: * *<any> -> NULL ! 253: */ ! 254: char * ! 255: indirect(cp) ! 256: register char *cp; ! 257: { ! 258: static char newvar[16]; ! 259: register char *c; ! 260: int neg = 0; ! 261: int offset = 0; ! 262: ! 263: /* *<any> | -(rn) */ ! 264: if (*cp == '*' || (*cp == '-' && *(cp+1) == '(')) return(NULL); ! 265: ! 266: /* (rn)+ | (rn)x */ ! 267: if (*cp == '(') { ! 268: c = cp; ! 269: while (*++c != ')') ; ! 270: if (*++c == '+') return(NULL); ! 271: c = newvar; ! 272: *c++ = '*'; ! 273: while (*c++ = *cp++); ! 274: return(newvar); ! 275: } ! 276: ! 277: /* $Lnn */ ! 278: if (*cp == '$' && *(cp+1) == 'L') { ! 279: c = newvar; ! 280: cp++; ! 281: while (*c++ = *cp++) ; ! 282: return(newvar); ! 283: } ! 284: ! 285: /* rn */ ! 286: if (*cp == 'r') { ! 287: c = newvar; ! 288: *c++ = '('; ! 289: while (*c++ = *cp++) ; ! 290: *(c-1) = ')'; ! 291: *c = 0; ! 292: return(newvar); ! 293: } ! 294: ! 295: /* everything else */ ! 296: c = newvar; ! 297: *c++ = '*'; ! 298: while (*c++ = *cp++) ; ! 299: return(newvar); ! 300: } ! 301: ! 302: output_replace(replace, oparg, argno, f) ! 303: register char *replace; ! 304: struct oparg oparg[]; ! 305: int argno; ! 306: FILE *f; ! 307: { ! 308: char newline[BUFSIZ]; ! 309: register int i; ! 310: register int argc; ! 311: char *argv[MAXARGS]; ! 312: char parsebuf[BUFSIZ]; ! 313: ! 314: do { ! 315: replace = copyline(replace, newline); ! 316: argc = parseline(newline, argv, parsebuf); ! 317: for (i = 0; i < argno; i++) ! 318: replace_arg(argc, argv, oparg[i].reg, oparg[i].source); ! 319: buildline(argc, argv, newline); ! 320: fputs(newline, f); ! 321: } while (*replace != '\0'); ! 322: } ! 323: ! 324: replace_arg(argc, argv, reg, source) ! 325: int argc; ! 326: char *argv[]; ! 327: int reg; ! 328: char *source; ! 329: { ! 330: register int i; ! 331: register char *c; ! 332: ! 333: for (i = 1; i < argc; i++) { ! 334: c = argv[i]; ! 335: if (*c == '(') c++; ! 336: if (*c++ == 'r' && (*c++ - '0') == reg && !isdigit(*c)) { ! 337: argv[i] = source; ! 338: } ! 339: } ! 340: } ! 341: ! 342: buildline(argc, argv, newline) ! 343: register int argc; ! 344: register char *argv[]; ! 345: register char *newline; ! 346: { ! 347: register char *cp1; ! 348: ! 349: if (argc == 0) { ! 350: *newline++ = '\n'; ! 351: *newline = '\0'; ! 352: } else if (argc == 1) { ! 353: sprintf(newline, "%s\n", argv[0]); ! 354: } else { ! 355: sprintf(newline, "\t%s\t%s", argv[0], argv[1]); ! 356: argc -= 2; ! 357: argv += 2; ! 358: while (argc-- > 0) { ! 359: strcat(newline, ","); ! 360: cp1 = *argv; ! 361: cp1 += strlen(cp1) - 1; ! 362: if (*cp1 == '$' || *cp1 == '*') *cp1 = '\0'; ! 363: strcat(newline, *argv++); ! 364: } ! 365: strcat(newline, "\n"); ! 366: } ! 367: } ! 368: ! 369: ! 370: ! 371: /* ! 372: * Do any necessary post expansion cleanup. ! 373: */ ! 374: cleanup(numargs) ! 375: int numargs; ! 376: { ! 377: ! 378: return; ! 379: } ! 380: #endif vax ! 381: ! 382: #ifdef mc68000 ! 383: /* ! 384: * Instruction stop table. ! 385: * All instructions that implicitly modify any of the temporary ! 386: * registers, change control flow, or implicitly loop must be ! 387: * listed in this table. It is used to find the end of a basic ! 388: * block when scanning backwards through the instruction stream ! 389: * trying to merge the inline expansion. ! 390: */ ! 391: struct inststoptbl inststoptable[] = { ! 392: { "" } ! 393: }; ! 394: ! 395: /* ! 396: * Check to see if a line is a candidate for replacement. ! 397: * Return pointer to name to be looked up in pattern table. ! 398: */ ! 399: char * ! 400: doreplaceon(cp) ! 401: char *cp; ! 402: { ! 403: ! 404: if (bcmp(cp, "jbsr\t", 5) == 0) ! 405: return (cp + 5); ! 406: return (0); ! 407: } ! 408: ! 409: /* ! 410: * Find the next argument to the function being expanded. ! 411: */ ! 412: nextarg(argc, argv) ! 413: int argc; ! 414: char *argv[]; ! 415: { ! 416: register char *lastarg = argv[2]; ! 417: ! 418: if (argc == 3 && ! 419: bcmp(argv[0], "movl", 5) == 0 && ! 420: bcmp(argv[1], "sp@+", 5) == 0 && ! 421: (lastarg[1] == '0' || lastarg[1] == '1') && ! 422: lastarg[2] == '\0') { ! 423: if (lastarg[0] == 'd') ! 424: return (lastarg[1] - '0'); ! 425: return (lastarg[1] - '0' + 8); ! 426: } ! 427: return (-1); ! 428: } ! 429: ! 430: /* ! 431: * Determine whether the current line pushes an argument. ! 432: */ ! 433: ispusharg(argc, argv) ! 434: int argc; ! 435: char *argv[]; ! 436: { ! 437: ! 438: if (argc < 2) ! 439: return (0); ! 440: if (argc == 2 && bcmp(argv[0], "pea", 4) == 0) ! 441: return (1); ! 442: if (bcmp(argv[argc - 1], "sp@-", 5) == 0) ! 443: return (1); ! 444: return (0); ! 445: } ! 446: ! 447: /* ! 448: * Determine which (if any) registers are modified ! 449: * Return register number that is modified, -1 if none are modified. ! 450: */ ! 451: modifies(argc, argv) ! 452: int argc; ! 453: char *argv[]; ! 454: { ! 455: /* ! 456: * For the MC68000 all we care about are d0, d1, a0, and a1. ! 457: */ ! 458: register char *lastarg = argv[argc - 1]; ! 459: ! 460: if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 461: return (lastarg[1] - '0'); ! 462: if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 463: return (lastarg[1] - '0' + 8); ! 464: return (-1); ! 465: } ! 466: ! 467: /* ! 468: * Rewrite the instruction in (argc, argv) to store its ! 469: * contents into arg instead of onto the stack. The new ! 470: * instruction is placed in the buffer that is provided. ! 471: */ ! 472: rewrite(instbuf, argc, argv, target) ! 473: char *instbuf; ! 474: int argc; ! 475: char *argv[]; ! 476: int target; ! 477: { ! 478: int regno; ! 479: char regtype; ! 480: ! 481: if (target < 8) { ! 482: regtype = 'd'; ! 483: regno = target; ! 484: } else { ! 485: regtype = 'a'; ! 486: regno = target - 8; ! 487: } ! 488: switch (argc) { ! 489: case 0: ! 490: instbuf[0] = '\0'; ! 491: fprintf("blank line to rewrite?\n"); ! 492: return; ! 493: case 1: ! 494: sprintf(instbuf, "\t%s\n", argv[0]); ! 495: fprintf(stderr, "rewrite?-> %s", instbuf); ! 496: return; ! 497: case 2: ! 498: if (bcmp(argv[0], "pea", 4) == 0) { ! 499: if (regtype == 'a') { ! 500: sprintf(instbuf, "\tlea\t%s,%c%d\n", ! 501: argv[1], regtype, regno); ! 502: return; ! 503: } ! 504: if (argv[1][0] == '_' || isdigit(argv[1][0])) { ! 505: sprintf(instbuf, "\tmovl\t#%s,%c%d\n", ! 506: argv[1], regtype, regno); ! 507: return; ! 508: } ! 509: sprintf(instbuf, ! 510: "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n", ! 511: regno, argv[1], regno); ! 512: return; ! 513: } ! 514: sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno); ! 515: return; ! 516: case 3: ! 517: sprintf(instbuf, "\t%s\t%s,%c%d\n", ! 518: argv[0], argv[1], regtype, regno); ! 519: return; ! 520: default: ! 521: sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); ! 522: argc -= 2, argv += 2; ! 523: while (argc-- > 0) { ! 524: strcat(instbuf, ","); ! 525: strcat(instbuf, *argv++); ! 526: } ! 527: strcat(instbuf, "\n"); ! 528: fprintf(stderr, "rewrite?-> %s", instbuf); ! 529: return; ! 530: } ! 531: } ! 532: ! 533: /* ! 534: * Do any necessary post expansion cleanup. ! 535: */ ! 536: cleanup(numargs) ! 537: int numargs; ! 538: { ! 539: ! 540: if (numargs == 0) ! 541: return; ! 542: /* ! 543: * delete instruction to pop arguments. ! 544: * TODO: ! 545: * CHECK FOR LABEL ! 546: * CHECK THAT INSTRUCTION IS A POP ! 547: */ ! 548: fgets(line[bufhead], MAXLINELEN, stdin); ! 549: } ! 550: #endif mc68000
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.