|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1984, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)machdep.c 7.1 (Berkeley) 6/5/86"; ! 9: #endif not lint ! 10: ! 11: #include <stdio.h> ! 12: #include <ctype.h> ! 13: #include "inline.h" ! 14: ! 15: extern char *strcpy(); ! 16: extern char *strcat(); ! 17: extern char *index(); ! 18: ! 19: /* ! 20: * The routines and tables in this file must be rewritten ! 21: * for each new machine that this program is ported to. ! 22: */ ! 23: ! 24: #ifdef vax ! 25: /* ! 26: * Instruction stop table. ! 27: * All instructions that implicitly modify any of the temporary ! 28: * registers, change control flow, or implicitly loop must be ! 29: * listed in this table. It is used to find the end of a basic ! 30: * block when scanning backwards through the instruction stream ! 31: * trying to merge the inline expansion. ! 32: */ ! 33: struct inststoptbl inststoptable[] = { ! 34: { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" }, ! 35: { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" }, ! 36: { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" }, ! 37: { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" }, ! 38: { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, ! 39: { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" }, ! 40: { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" }, ! 41: { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" }, ! 42: { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" }, ! 43: { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" }, ! 44: { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" }, ! 45: { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" }, ! 46: { "bcs" }, { "brb" }, { "brw" }, { "jmp" }, ! 47: { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" }, ! 48: { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" }, ! 49: { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" }, ! 50: { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" }, ! 51: { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" }, ! 52: { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" }, ! 53: { "callg" }, { "calls" }, { "ret" }, ! 54: { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" }, ! 55: { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" }, ! 56: { "locc" }, { "skpc" }, { "matchc" }, { "crc" }, ! 57: { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" }, ! 58: { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" }, ! 59: { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" }, ! 60: { "ashp" }, { "editpc" }, ! 61: { "escd" }, { "esce" }, { "escf" }, ! 62: { "" } ! 63: }; ! 64: ! 65: /* ! 66: * Check to see if a line is a candidate for replacement. ! 67: * Return pointer to name to be looked up in pattern table. ! 68: */ ! 69: char * ! 70: doreplaceon(cp) ! 71: char *cp; ! 72: { ! 73: ! 74: if (bcmp(cp, "calls\t", 6) != 0) ! 75: return (0); ! 76: if ((cp = index(cp + 6, ',')) == 0) ! 77: return (0); ! 78: return (++cp); ! 79: } ! 80: ! 81: /* ! 82: * Find out how many arguments the function is being called with. ! 83: * A return value of -1 indicates that the count can't be determined. ! 84: */ ! 85: int ! 86: countargs(cp) ! 87: char *cp; ! 88: { ! 89: ! 90: if ((cp = index(cp, '$')) == 0) ! 91: return (-1); ! 92: if (!isdigit(*++cp)) ! 93: return (-1); ! 94: return (atoi(cp)); ! 95: } ! 96: ! 97: /* ! 98: * Find the next argument to the function being expanded. ! 99: */ ! 100: nextarg(argc, argv) ! 101: int argc; ! 102: char *argv[]; ! 103: { ! 104: register char *lastarg = argv[2]; ! 105: ! 106: if (argc == 3 && ! 107: bcmp(argv[0], "mov", 3) == 0 && ! 108: bcmp(argv[1], "(sp)+", 6) == 0 && ! 109: lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 110: return (lastarg[1] - '0'); ! 111: return (-1); ! 112: } ! 113: ! 114: /* ! 115: * Determine whether the current line pushes an argument. ! 116: */ ! 117: ispusharg(argc, argv) ! 118: int argc; ! 119: char *argv[]; ! 120: { ! 121: ! 122: if (argc < 2) ! 123: return (0); ! 124: if (argc == 2 && bcmp(argv[0], "push", 4) == 0) ! 125: return (1); ! 126: if (bcmp(argv[argc - 1], "-(sp)", 6) == 0) ! 127: return (1); ! 128: return (0); ! 129: } ! 130: ! 131: /* ! 132: * Determine which (if any) registers are modified ! 133: * Return register number that is modified, -1 if none are modified. ! 134: */ ! 135: modifies(argc, argv) ! 136: int argc; ! 137: char *argv[]; ! 138: { ! 139: /* ! 140: * For the VAX all we care about are r0 to r5 ! 141: */ ! 142: register char *lastarg = argv[argc - 1]; ! 143: ! 144: if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 145: return (lastarg[1] - '0'); ! 146: return (-1); ! 147: } ! 148: ! 149: /* ! 150: * Rewrite the instruction in (argc, argv) to store its ! 151: * contents into arg instead of onto the stack. The new ! 152: * instruction is placed in the buffer that is provided. ! 153: */ ! 154: rewrite(instbuf, argc, argv, target) ! 155: char *instbuf; ! 156: int argc; ! 157: char *argv[]; ! 158: int target; ! 159: { ! 160: ! 161: switch (argc) { ! 162: case 0: ! 163: instbuf[0] = '\0'; ! 164: fprintf(stderr, "blank line to rewrite?\n"); ! 165: return; ! 166: case 1: ! 167: sprintf(instbuf, "\t%s\n", argv[0]); ! 168: fprintf(stderr, "rewrite?-> %s", instbuf); ! 169: return; ! 170: case 2: ! 171: if (bcmp(argv[0], "push", 4) == 0) { ! 172: sprintf(instbuf, "\tmov%s\t%s,r%d\n", ! 173: &argv[0][4], argv[1], target); ! 174: return; ! 175: } ! 176: sprintf(instbuf, "\t%s\tr%d\n", argv[0], target); ! 177: return; ! 178: case 3: ! 179: sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target); ! 180: return; ! 181: case 4: ! 182: sprintf(instbuf, "\t%s\t%s,%s,r%d\n", ! 183: argv[0], argv[1], argv[2], target); ! 184: return; ! 185: case 5: ! 186: sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n", ! 187: argv[0], argv[1], argv[2], argv[3], target); ! 188: return; ! 189: default: ! 190: sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); ! 191: argc -= 2, argv += 2; ! 192: while (argc-- > 0) { ! 193: (void) strcat(instbuf, ","); ! 194: (void) strcat(instbuf, *argv++); ! 195: } ! 196: (void) strcat(instbuf, "\n"); ! 197: fprintf(stderr, "rewrite?-> %s", instbuf); ! 198: return; ! 199: } ! 200: } ! 201: ! 202: /* ! 203: * Do any necessary post expansion cleanup. ! 204: */ ! 205: /*ARGSUSED*/ ! 206: cleanup(numargs) ! 207: int numargs; ! 208: { ! 209: ! 210: return; ! 211: } ! 212: #endif vax ! 213: ! 214: #ifdef mc68000 ! 215: /* ! 216: * Instruction stop table. ! 217: * All instructions that implicitly modify any of the temporary ! 218: * registers, change control flow, or implicitly loop must be ! 219: * listed in this table. It is used to find the end of a basic ! 220: * block when scanning backwards through the instruction stream ! 221: * trying to merge the inline expansion. ! 222: */ ! 223: struct inststoptbl inststoptable[] = { ! 224: { "" } ! 225: }; ! 226: ! 227: /* ! 228: * Check to see if a line is a candidate for replacement. ! 229: * Return pointer to name to be looked up in pattern table. ! 230: */ ! 231: char * ! 232: doreplaceon(cp) ! 233: char *cp; ! 234: { ! 235: ! 236: if (bcmp(cp, "jbsr\t", 5) == 0) ! 237: return (cp + 5); ! 238: return (0); ! 239: } ! 240: ! 241: /* ! 242: * Find out how many arguments the function is being called with. ! 243: * A return value of -1 indicates that the count can't be determined. ! 244: */ ! 245: /* ARGSUSED */ ! 246: int ! 247: countargs(cp) ! 248: char *cp; ! 249: { ! 250: ! 251: /* ! 252: * TODO ! 253: * Figure out what the count should be. ! 254: * Probably have to read the next instruction here ! 255: * instead of in cleanup() below. ! 256: */ ! 257: return (-1); ! 258: } ! 259: ! 260: /* ! 261: * Find the next argument to the function being expanded. ! 262: */ ! 263: nextarg(argc, argv) ! 264: int argc; ! 265: char *argv[]; ! 266: { ! 267: register char *lastarg = argv[2]; ! 268: ! 269: if (argc == 3 && ! 270: bcmp(argv[0], "movl", 5) == 0 && ! 271: bcmp(argv[1], "sp@+", 5) == 0 && ! 272: (lastarg[1] == '0' || lastarg[1] == '1') && ! 273: lastarg[2] == '\0') { ! 274: if (lastarg[0] == 'd') ! 275: return (lastarg[1] - '0'); ! 276: return (lastarg[1] - '0' + 8); ! 277: } ! 278: return (-1); ! 279: } ! 280: ! 281: /* ! 282: * Determine whether the current line pushes an argument. ! 283: */ ! 284: ispusharg(argc, argv) ! 285: int argc; ! 286: char *argv[]; ! 287: { ! 288: ! 289: if (argc < 2) ! 290: return (0); ! 291: if (argc == 2 && bcmp(argv[0], "pea", 4) == 0) ! 292: return (1); ! 293: if (bcmp(argv[argc - 1], "sp@-", 5) == 0) ! 294: return (1); ! 295: return (0); ! 296: } ! 297: ! 298: /* ! 299: * Determine which (if any) registers are modified ! 300: * Return register number that is modified, -1 if none are modified. ! 301: */ ! 302: modifies(argc, argv) ! 303: int argc; ! 304: char *argv[]; ! 305: { ! 306: /* ! 307: * For the MC68000 all we care about are d0, d1, a0, and a1. ! 308: */ ! 309: register char *lastarg = argv[argc - 1]; ! 310: ! 311: if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 312: return (lastarg[1] - '0'); ! 313: if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0') ! 314: return (lastarg[1] - '0' + 8); ! 315: return (-1); ! 316: } ! 317: ! 318: /* ! 319: * Rewrite the instruction in (argc, argv) to store its ! 320: * contents into arg instead of onto the stack. The new ! 321: * instruction is placed in the buffer that is provided. ! 322: */ ! 323: rewrite(instbuf, argc, argv, target) ! 324: char *instbuf; ! 325: int argc; ! 326: char *argv[]; ! 327: int target; ! 328: { ! 329: int regno; ! 330: char regtype; ! 331: ! 332: if (target < 8) { ! 333: regtype = 'd'; ! 334: regno = target; ! 335: } else { ! 336: regtype = 'a'; ! 337: regno = target - 8; ! 338: } ! 339: switch (argc) { ! 340: case 0: ! 341: instbuf[0] = '\0'; ! 342: fprintf(stderr, "blank line to rewrite?\n"); ! 343: return; ! 344: case 1: ! 345: sprintf(instbuf, "\t%s\n", argv[0]); ! 346: fprintf(stderr, "rewrite?-> %s", instbuf); ! 347: return; ! 348: case 2: ! 349: if (bcmp(argv[0], "pea", 4) == 0) { ! 350: if (regtype == 'a') { ! 351: sprintf(instbuf, "\tlea\t%s,%c%d\n", ! 352: argv[1], regtype, regno); ! 353: return; ! 354: } ! 355: if (argv[1][0] == '_' || isdigit(argv[1][0])) { ! 356: sprintf(instbuf, "\tmovl\t#%s,%c%d\n", ! 357: argv[1], regtype, regno); ! 358: return; ! 359: } ! 360: sprintf(instbuf, ! 361: "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n", ! 362: regno, argv[1], regno); ! 363: return; ! 364: } ! 365: sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno); ! 366: return; ! 367: case 3: ! 368: sprintf(instbuf, "\t%s\t%s,%c%d\n", ! 369: argv[0], argv[1], regtype, regno); ! 370: return; ! 371: default: ! 372: sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]); ! 373: argc -= 2, argv += 2; ! 374: while (argc-- > 0) { ! 375: (void) strcat(instbuf, ","); ! 376: (void) strcat(instbuf, *argv++); ! 377: } ! 378: (void) strcat(instbuf, "\n"); ! 379: fprintf(stderr, "rewrite?-> %s", instbuf); ! 380: return; ! 381: } ! 382: } ! 383: ! 384: /* ! 385: * Do any necessary post expansion cleanup. ! 386: */ ! 387: cleanup(numargs) ! 388: int numargs; ! 389: { ! 390: extern int lineno; ! 391: ! 392: if (numargs == 0) ! 393: return; ! 394: /* ! 395: * delete instruction to pop arguments. ! 396: * TODO: ! 397: * CHECK FOR LABEL ! 398: * CHECK THAT INSTRUCTION IS A POP ! 399: */ ! 400: fgets(line[bufhead], MAXLINELEN, stdin); ! 401: lineno++; ! 402: } ! 403: #endif mc68000
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.