|
|
1.1 ! root 1: /* Copyright (c) 1984 Regents of the University of California */ ! 2: ! 3: #ifndef lint ! 4: static char sccsid[] = "@(#)main.c 1.6 (Berkeley) 9/20/84"; ! 5: #endif not lint ! 6: ! 7: #include <stdio.h> ! 8: #include <ctype.h> ! 9: #include "inline.h" ! 10: ! 11: /* ! 12: * These are the pattern tables to be loaded ! 13: */ ! 14: struct pats *inittables[] = { ! 15: language_ptab, ! 16: libc_ptab, ! 17: machine_ptab, ! 18: 0 ! 19: }; ! 20: ! 21: /* ! 22: * Statistics collection ! 23: */ ! 24: struct stats { ! 25: int attempted; /* number of expansion attempts */ ! 26: int finished; /* expansions done before end of basic block */ ! 27: int lostmodified; /* mergers inhibited by intervening mod */ ! 28: int savedpush; /* successful push/pop merger */ ! 29: int savedmove; /* move to tmp reg eliminated */ ! 30: } stats; ! 31: int dflag; ! 32: ! 33: main(argc, argv) ! 34: int argc; ! 35: char *argv[]; ! 36: { ! 37: register char *cp, *lp, *qp; ! 38: register char *bufp; ! 39: register struct pats *pp, **php; ! 40: struct pats **tablep; ! 41: register struct inststoptbl *itp, **ithp; ! 42: int size; ! 43: extern char *index(); ! 44: ! 45: if (argc > 1 && bcmp(argv[1], "-d", 3) == 0) ! 46: dflag++, argc--, argv++; ! 47: if (argc > 1) ! 48: freopen(argv[1], "r", stdin); ! 49: if (argc > 2) ! 50: freopen(argv[2], "w", stdout); ! 51: /* ! 52: * Set up the hash table for the patterns. ! 53: */ ! 54: for (tablep = inittables; *tablep; tablep++) { ! 55: for (pp = *tablep; pp->name[0] != '\0'; pp++) { ! 56: php = &patshdr[hash(pp->name, &size)]; ! 57: pp->size = size; ! 58: pp->next = *php; ! 59: *php = pp; ! 60: } ! 61: } ! 62: /* ! 63: * Set up the hash table for the instruction stop table. ! 64: */ ! 65: for (itp = inststoptable; itp->name[0] != '\0'; itp++) { ! 66: ithp = &inststoptblhdr[hash(itp->name, &size)]; ! 67: itp->size = size; ! 68: itp->next = *ithp; ! 69: *ithp = itp; ! 70: } ! 71: /* ! 72: * check each line and replace as appropriate ! 73: */ ! 74: buftail = bufhead = 0; ! 75: bufp = line[0]; ! 76: while (fgets(bufp, MAXLINELEN, stdin)) { ! 77: lp = index(bufp, LABELCHAR); ! 78: if (lp != NULL) { ! 79: qp = index(bufp, QUOTECHAR); ! 80: if (qp == NULL) { ! 81: bufp = newline(); ! 82: if (*++lp == '\n') { ! 83: emptyqueue(); ! 84: continue; ! 85: } ! 86: strcpy(bufp, lp); ! 87: *lp++ = '\n'; ! 88: *lp = '\0'; ! 89: emptyqueue(); ! 90: } ! 91: } ! 92: for (cp = bufp; isspace(*cp); cp++) ! 93: /* void */; ! 94: if ((cp = doreplaceon(cp)) == 0) { ! 95: bufp = newline(); ! 96: continue; ! 97: } ! 98: for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) { ! 99: if (pp->size == size && bcmp(pp->name, cp, size) == 0) { ! 100: expand(pp->replace); ! 101: bufp = line[bufhead]; ! 102: break; ! 103: } ! 104: } ! 105: if (!pp) { ! 106: emptyqueue(); ! 107: fputs(bufp, stdout); ! 108: } ! 109: } ! 110: emptyqueue(); ! 111: if (dflag) ! 112: fprintf(stderr, "inline: %s %d, %s %d, %s %d, %s %d\n", ! 113: "attempts", stats.attempted, ! 114: "finished", stats.finished, ! 115: "inhibited", stats.lostmodified, ! 116: "merged", stats.savedpush, ! 117: "nomoves", stats.savedmove); ! 118: exit(0); ! 119: } ! 120: ! 121: /* ! 122: * Integrate an expansion into the assembly stream ! 123: */ ! 124: expand(replace) ! 125: char *replace; ! 126: { ! 127: register int curptr; ! 128: char *nextreplace, *argv[MAXARGS]; ! 129: int argc, argreg, foundarg, mod = 0, args = 0; ! 130: char parsebuf[BUFSIZ]; ! 131: int argno = 0; ! 132: int flag; ! 133: struct oparg oparg[MAXARGS]; ! 134: ! 135: stats.attempted++; ! 136: for (curptr = bufhead; ; ) { ! 137: nextreplace = copyline(replace, line[bufhead]); ! 138: argc = parseline(line[bufhead], argv, parsebuf); ! 139: argreg = nextarg(argc, argv, &flag); ! 140: if (argreg == -1) ! 141: break; ! 142: args++; ! 143: for (foundarg = 0; curptr != buftail; ) { ! 144: curptr = PRED(curptr); ! 145: argc = parseline(line[curptr], argv, parsebuf); ! 146: if (isendofblock(argc, argv)) ! 147: break; ! 148: if (foundarg = ispusharg(argc, argv)) ! 149: break; ! 150: mod |= 1 << modifies(argc, argv); ! 151: } ! 152: if (!foundarg) ! 153: break; ! 154: replace = nextreplace; ! 155: if (mod & (1 << argreg)) { ! 156: stats.lostmodified++; ! 157: if (curptr == buftail) { ! 158: (void)newline(); ! 159: break; ! 160: } ! 161: (void)newline(); ! 162: } else { ! 163: if (checkvar(argc, argv, flag, oparg[argno].source, mod)) { ! 164: line[curptr][0] = '\0'; ! 165: oparg[argno].reg = argreg; ! 166: argno++; ! 167: stats.savedmove++; ! 168: } else { ! 169: rewrite(line[curptr], argc, argv, argreg); ! 170: stats.savedpush++; ! 171: mod |= 1 << argreg; ! 172: } ! 173: } ! 174: } ! 175: if (argreg == -1) ! 176: stats.finished++; ! 177: emptyqueue(); ! 178: output_replace(replace, oparg, argno, stdout); ! 179: cleanup(args); ! 180: } ! 181: ! 182: /* ! 183: * Parse a line of assembly language into opcode and arguments. ! 184: */ ! 185: parseline(linep, argv, linebuf) ! 186: char *linep; ! 187: char *argv[]; ! 188: char *linebuf; ! 189: { ! 190: register char *bufp = linebuf, *cp = linep; ! 191: register int argc = 0; ! 192: ! 193: for (;;) { ! 194: /* ! 195: * skip over white space ! 196: */ ! 197: while (isspace(*cp)) ! 198: cp++; ! 199: if (*cp == '\0') ! 200: return (argc); ! 201: /* ! 202: * copy argument ! 203: */ ! 204: if (argc == MAXARGS - 1) { ! 205: fprintf(stderr, "instruction too long->%s", linep); ! 206: return (argc); ! 207: } ! 208: argv[argc++] = bufp; ! 209: while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR) ! 210: *bufp++ = *cp++; ! 211: *bufp++ = '\0'; ! 212: if (*cp == COMMENTCHAR) ! 213: return (argc); ! 214: if (*cp == ARGSEPCHAR) ! 215: cp++; ! 216: } ! 217: } ! 218: ! 219: /* ! 220: * Check for instructions that end a basic block. ! 221: */ ! 222: isendofblock(argc, argv) ! 223: int argc; ! 224: char *argv[]; ! 225: { ! 226: register struct inststoptbl *itp; ! 227: int size; ! 228: ! 229: if (argc == 0) ! 230: return (0); ! 231: for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next) ! 232: if (itp->size == size && bcmp(argv[0], itp->name, size) == 0) ! 233: return (1); ! 234: return (0); ! 235: } ! 236: ! 237: /* ! 238: * Copy a newline terminated string. ! 239: * Return pointer to character following last character copied. ! 240: */ ! 241: char * ! 242: copyline(from, to) ! 243: register char *from, *to; ! 244: { ! 245: ! 246: while (*from != '\n') ! 247: *to++ = *from++; ! 248: *to++ = *from++; ! 249: *to = '\0'; ! 250: return (from); ! 251: } ! 252: ! 253: /* ! 254: * open space for next line in the queue ! 255: */ ! 256: char * ! 257: newline() ! 258: { ! 259: bufhead = SUCC(bufhead); ! 260: if (bufhead == buftail) { ! 261: fputs(line[buftail], stdout); ! 262: buftail = SUCC(buftail); ! 263: } ! 264: return (line[bufhead]); ! 265: } ! 266: ! 267: /* ! 268: * empty the queue by printing out all its lines. ! 269: */ ! 270: emptyqueue() ! 271: { ! 272: while (buftail != bufhead) { ! 273: fputs(line[buftail], stdout); ! 274: buftail = SUCC(buftail); ! 275: } ! 276: } ! 277: ! 278: /* ! 279: * Compute the hash of a string. ! 280: * Return the hash and the size of the item hashed ! 281: */ ! 282: hash(cp, size) ! 283: char *cp; ! 284: int *size; ! 285: { ! 286: register char *cp1 = cp; ! 287: register int hash = 0; ! 288: ! 289: while (*cp1 && *cp1 != '\n') ! 290: hash += (int)*cp1++; ! 291: *size = cp1 - cp + 1; ! 292: hash &= HSHSIZ - 1; ! 293: return (hash); ! 294: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.