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

Defined functions

argcounterr defined in line 302; used 1 times
copyline defined in line 285; used 2 times
emptyqueue defined in line 345; used 5 times
expand defined in line 178; used 1 times
hash defined in line 357; used 8 times
isendofblock defined in line 266; used 1 times
main defined in line 58; never used
newline defined in line 331; used 5 times
parseline defined in line 229; used 2 times

Defined variables

copyright defined in line 8; never used
dflag defined in line 56; used 2 times
lineno defined in line 55; used 3 times
sccsid defined in line 14; never used
stats defined in line 50; used 8 times
vax_inittables defined in line 24; used 1 times
vaxsubset_inittables defined in line 33; used 1 times
  • in line 98
whoami defined in line 54; used 4 times

Defined struct's

stats defined in line 45; never used
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1376
Valid CSS Valid XHTML 1.0 Strict