Annotation of 43BSDReno/sys/vax/inline/main.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.