|
|
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: char copyright[] = ! 36: "@(#) Copyright (c) 1984, 1986 The Regents of the University of California.\n\ ! 37: All rights reserved.\n"; ! 38: #endif /* not lint */ ! 39: ! 40: #ifndef lint ! 41: static char sccsid[] = "@(#)main.c 7.2 (Berkeley) 5/8/91"; ! 42: #endif /* not lint */ ! 43: ! 44: #include <stdio.h> ! 45: #include <ctype.h> ! 46: #include "inline.h" ! 47: ! 48: /* ! 49: * These are the pattern tables to be loaded ! 50: */ ! 51: struct pats *vax_inittables[] = { ! 52: language_ptab, ! 53: libc_ptab, ! 54: vax_libc_ptab, ! 55: machine_ptab, ! 56: vax_ptab, ! 57: 0 ! 58: }; ! 59: ! 60: struct pats *vaxsubset_inittables[] = { ! 61: language_ptab, ! 62: libc_ptab, ! 63: vaxsubset_libc_ptab, ! 64: machine_ptab, ! 65: vaxsubset_ptab, ! 66: 0 ! 67: }; ! 68: ! 69: /* ! 70: * Statistics collection ! 71: */ ! 72: struct stats { ! 73: int attempted; /* number of expansion attempts */ ! 74: int finished; /* expansions done before end of basic block */ ! 75: int lostmodified; /* mergers inhibited by intervening mod */ ! 76: int savedpush; /* successful push/pop merger */ ! 77: } stats; ! 78: ! 79: extern char *strcpy(); ! 80: ! 81: char *whoami; ! 82: int lineno = 0; ! 83: int dflag; ! 84: ! 85: main(argc, argv) ! 86: int argc; ! 87: char *argv[]; ! 88: { ! 89: register char *cp, *lp; ! 90: register char *bufp; ! 91: register struct pats *pp, **php; ! 92: struct pats **tablep; ! 93: register struct inststoptbl *itp, **ithp; ! 94: int size; ! 95: extern char *index(); ! 96: int subset = 0; ! 97: ! 98: whoami = argv[0]; ! 99: argc--; ! 100: argv++; ! 101: while (argc > 0 && argv[0][0] == '-') { ! 102: switch(argv[0][1]) { ! 103: ! 104: case 's': ! 105: subset++; ! 106: break; ! 107: ! 108: case 'd': ! 109: dflag++; ! 110: break; ! 111: ! 112: default: ! 113: break; ! 114: } ! 115: argc--, argv++; ! 116: } ! 117: if (argc > 0) ! 118: freopen(argv[0], "r", stdin); ! 119: if (argc > 1) ! 120: freopen(argv[1], "w", stdout); ! 121: /* ! 122: * Set up the hash table for the patterns. ! 123: */ ! 124: if (subset) ! 125: tablep = vaxsubset_inittables; ! 126: else ! 127: tablep = vax_inittables; ! 128: for ( ; *tablep; tablep++) { ! 129: for (pp = *tablep; pp->name[0] != '\0'; pp++) { ! 130: php = &patshdr[hash(pp->name, &size)]; ! 131: pp->size = size; ! 132: pp->next = *php; ! 133: *php = pp; ! 134: } ! 135: } ! 136: /* ! 137: * Set up the hash table for the instruction stop table. ! 138: */ ! 139: for (itp = inststoptable; itp->name[0] != '\0'; itp++) { ! 140: ithp = &inststoptblhdr[hash(itp->name, &size)]; ! 141: itp->size = size; ! 142: itp->next = *ithp; ! 143: *ithp = itp; ! 144: } ! 145: /* ! 146: * check each line and replace as appropriate ! 147: */ ! 148: buftail = bufhead = 0; ! 149: bufp = line[0]; ! 150: while (fgets(bufp, MAXLINELEN, stdin)) { ! 151: lineno++; ! 152: lp = index(bufp, LABELCHAR); ! 153: if (lp != NULL) { ! 154: for (cp = bufp; cp < lp; cp++) ! 155: if (!isalnum(*cp)) ! 156: break; ! 157: if (cp == lp) { ! 158: bufp = newline(); ! 159: if (*++lp == '\n') { ! 160: emptyqueue(); ! 161: continue; ! 162: } ! 163: (void) strcpy(bufp, lp); ! 164: *lp++ = '\n'; ! 165: *lp = '\0'; ! 166: emptyqueue(); ! 167: } ! 168: } ! 169: for (cp = bufp; isspace(*cp); cp++) ! 170: /* void */; ! 171: if ((cp = doreplaceon(cp)) == 0) { ! 172: bufp = newline(); ! 173: continue; ! 174: } ! 175: for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) { ! 176: if (pp->size == size && bcmp(pp->name, cp, size) == 0) { ! 177: if (argcounterr(pp->args, countargs(bufp), pp->name)) { ! 178: pp = NULL; ! 179: break; ! 180: } ! 181: expand(pp->replace); ! 182: bufp = line[bufhead]; ! 183: break; ! 184: } ! 185: } ! 186: if (!pp) { ! 187: emptyqueue(); ! 188: fputs(bufp, stdout); ! 189: } ! 190: } ! 191: emptyqueue(); ! 192: if (dflag) ! 193: fprintf(stderr, "%s: %s %d, %s %d, %s %d, %s %d\n", ! 194: whoami, ! 195: "attempts", stats.attempted, ! 196: "finished", stats.finished, ! 197: "inhibited", stats.lostmodified, ! 198: "merged", stats.savedpush); ! 199: exit(0); ! 200: } ! 201: ! 202: /* ! 203: * Integrate an expansion into the assembly stream ! 204: */ ! 205: expand(replace) ! 206: char *replace; ! 207: { ! 208: register int curptr; ! 209: char *nextreplace, *argv[MAXARGS]; ! 210: int argc, argreg, foundarg, mod = 0, args = 0; ! 211: char parsebuf[BUFSIZ]; ! 212: ! 213: stats.attempted++; ! 214: for (curptr = bufhead; ; ) { ! 215: nextreplace = copyline(replace, line[bufhead]); ! 216: argc = parseline(line[bufhead], argv, parsebuf); ! 217: argreg = nextarg(argc, argv); ! 218: if (argreg == -1) ! 219: break; ! 220: args++; ! 221: for (foundarg = 0; curptr != buftail; ) { ! 222: curptr = PRED(curptr); ! 223: argc = parseline(line[curptr], argv, parsebuf); ! 224: if (isendofblock(argc, argv)) ! 225: break; ! 226: if (foundarg = ispusharg(argc, argv)) ! 227: break; ! 228: mod |= 1 << modifies(argc, argv); ! 229: } ! 230: if (!foundarg) ! 231: break; ! 232: replace = nextreplace; ! 233: if (mod & (1 << argreg)) { ! 234: stats.lostmodified++; ! 235: if (curptr == buftail) { ! 236: (void)newline(); ! 237: break; ! 238: } ! 239: (void)newline(); ! 240: } else { ! 241: stats.savedpush++; ! 242: rewrite(line[curptr], argc, argv, argreg); ! 243: mod |= 1 << argreg; ! 244: } ! 245: } ! 246: if (argreg == -1) ! 247: stats.finished++; ! 248: emptyqueue(); ! 249: fputs(replace, stdout); ! 250: cleanup(args); ! 251: } ! 252: ! 253: /* ! 254: * Parse a line of assembly language into opcode and arguments. ! 255: */ ! 256: parseline(linep, argv, linebuf) ! 257: char *linep; ! 258: char *argv[]; ! 259: char *linebuf; ! 260: { ! 261: register char *bufp = linebuf, *cp = linep; ! 262: register int argc = 0; ! 263: ! 264: for (;;) { ! 265: /* ! 266: * skip over white space ! 267: */ ! 268: while (isspace(*cp)) ! 269: cp++; ! 270: if (*cp == '\0') ! 271: return (argc); ! 272: /* ! 273: * copy argument ! 274: */ ! 275: if (argc == MAXARGS - 1) { ! 276: fprintf(stderr, "instruction too long->%s", linep); ! 277: return (argc); ! 278: } ! 279: argv[argc++] = bufp; ! 280: while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR) ! 281: *bufp++ = *cp++; ! 282: *bufp++ = '\0'; ! 283: if (*cp == COMMENTCHAR) ! 284: return (argc); ! 285: if (*cp == ARGSEPCHAR) ! 286: cp++; ! 287: } ! 288: } ! 289: ! 290: /* ! 291: * Check for instructions that end a basic block. ! 292: */ ! 293: isendofblock(argc, argv) ! 294: int argc; ! 295: char *argv[]; ! 296: { ! 297: register struct inststoptbl *itp; ! 298: int size; ! 299: ! 300: if (argc == 0) ! 301: return (0); ! 302: for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next) ! 303: if (itp->size == size && bcmp(argv[0], itp->name, size) == 0) ! 304: return (1); ! 305: return (0); ! 306: } ! 307: ! 308: /* ! 309: * Copy a newline terminated string. ! 310: * Return pointer to character following last character copied. ! 311: */ ! 312: char * ! 313: copyline(from, to) ! 314: register char *from, *to; ! 315: { ! 316: ! 317: while (*from != '\n') ! 318: *to++ = *from++; ! 319: *to++ = *from++; ! 320: *to = '\0'; ! 321: return (from); ! 322: } ! 323: ! 324: /* ! 325: * Check for a disparity between the number of arguments a function ! 326: * is called with and the number which we expect to see. ! 327: * If the error is unrecoverable, return 1, otherwise 0. ! 328: */ ! 329: argcounterr(args, callargs, name) ! 330: int args, callargs; ! 331: char *name; ! 332: { ! 333: register char *cp; ! 334: char namebuf[MAXLINELEN]; ! 335: ! 336: if (args == callargs) ! 337: return (0); ! 338: cp = strcpy(namebuf, name); ! 339: while (*cp != '\0' && *cp != '\n') ! 340: ++cp; ! 341: if (*cp == '\n') ! 342: *cp = '\0'; ! 343: if (callargs >= 0) { ! 344: fprintf(stderr, ! 345: "%s: error: arg count mismatch, %d != %d for '%s' at line %d\n", ! 346: whoami, callargs, args, namebuf, lineno); ! 347: return (1); ! 348: } ! 349: fprintf(stderr, ! 350: "%s: warning: can't verify arg count for '%s' at line %d\n", ! 351: whoami, namebuf, lineno); ! 352: return (0); ! 353: } ! 354: ! 355: /* ! 356: * open space for next line in the queue ! 357: */ ! 358: char * ! 359: newline() ! 360: { ! 361: bufhead = SUCC(bufhead); ! 362: if (bufhead == buftail) { ! 363: fputs(line[buftail], stdout); ! 364: buftail = SUCC(buftail); ! 365: } ! 366: return (line[bufhead]); ! 367: } ! 368: ! 369: /* ! 370: * empty the queue by printing out all its lines. ! 371: */ ! 372: emptyqueue() ! 373: { ! 374: while (buftail != bufhead) { ! 375: fputs(line[buftail], stdout); ! 376: buftail = SUCC(buftail); ! 377: } ! 378: } ! 379: ! 380: /* ! 381: * Compute the hash of a string. ! 382: * Return the hash and the size of the item hashed ! 383: */ ! 384: hash(cp, size) ! 385: char *cp; ! 386: int *size; ! 387: { ! 388: register char *cp1 = cp; ! 389: register int hash = 0; ! 390: ! 391: while (*cp1 && *cp1 != '\n') ! 392: hash += (int)*cp1++; ! 393: *size = cp1 - cp + 1; ! 394: hash &= HSHSIZ - 1; ! 395: return (hash); ! 396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.