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