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: }

Defined functions

copyline defined in line 241; used 3 times
emptyqueue defined in line 270; used 5 times
expand defined in line 124; used 1 times
hash defined in line 282; used 8 times
isendofblock defined in line 222; used 1 times
main defined in line 33; never used
newline defined in line 256; used 5 times
parseline defined in line 185; used 3 times

Defined variables

dflag defined in line 31; used 2 times
inittables defined in line 14; used 1 times
  • in line 54
sccsid defined in line 4; never used
stats defined in line 30; used 10 times

Defined struct's

stats defined in line 24; never used
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1123
Valid CSS Valid XHTML 1.0 Strict