116962Smckusick /* Copyright (c) 1984 Regents of the University of California */ 216962Smckusick 316962Smckusick #ifndef lint 4*16978Smckusick static char sccsid[] = "@(#)main.c 1.4 (Berkeley) 08/20/84"; 516962Smckusick #endif not lint 616962Smckusick 716962Smckusick #include <stdio.h> 816962Smckusick #include <ctype.h> 916963Smckusick #include "inline.h" 1016962Smckusick 1116975Smckusick /* 1216975Smckusick * These are the pattern tables to be loaded 1316975Smckusick */ 1416975Smckusick struct pats *inittables[] = { 1516975Smckusick language_ptab, 1616975Smckusick libc_ptab, 1716975Smckusick machine_ptab, 1816975Smckusick 0 1916975Smckusick }; 2016975Smckusick 2116962Smckusick main(argc, argv) 2216962Smckusick int argc; 2316962Smckusick char *argv[]; 2416962Smckusick { 2516962Smckusick register char *cp, *lp; 2616962Smckusick register char *bufp; 27*16978Smckusick register struct pats *pp, **php; 28*16978Smckusick struct pats **tablep; 29*16978Smckusick register struct inststoptbl *itp, **ithp; 3016962Smckusick int size; 3116962Smckusick extern char *index(); 3216962Smckusick 3316962Smckusick if (argc > 1) 3416962Smckusick freopen(argv[1], "r", stdin); 3516962Smckusick if (argc > 2) 3616962Smckusick freopen(argv[2], "w", stdout); 3716962Smckusick /* 38*16978Smckusick * Set up the hash table for the patterns. 3916962Smckusick */ 4016975Smckusick for (tablep = inittables; *tablep; tablep++) { 4116975Smckusick for (pp = *tablep; pp->name[0] != '\0'; pp++) { 42*16978Smckusick php = &patshdr[hash(pp->name, &size)]; 4316975Smckusick pp->size = size; 44*16978Smckusick pp->next = *php; 45*16978Smckusick *php = pp; 4616975Smckusick } 4716962Smckusick } 4816962Smckusick /* 49*16978Smckusick * Set up the hash table for the instruction stop table. 50*16978Smckusick */ 51*16978Smckusick for (itp = inststoptable; itp->name[0] != '\0'; itp++) { 52*16978Smckusick ithp = &inststoptblhdr[hash(itp->name, &size)]; 53*16978Smckusick itp->size = size; 54*16978Smckusick itp->next = *ithp; 55*16978Smckusick *ithp = itp; 56*16978Smckusick } 57*16978Smckusick /* 5816962Smckusick * check each line and replace as appropriate 5916962Smckusick */ 6016962Smckusick buftail = bufhead = 0; 6116962Smckusick bufp = line[0]; 6216962Smckusick while (fgets(bufp, MAXLINELEN, stdin)) { 6316962Smckusick lp = index(bufp, LABELCHAR); 6416962Smckusick if (lp != NULL) { 6516962Smckusick bufp = newline(); 6616962Smckusick if (*++lp == '\n') { 6716962Smckusick emptyqueue(); 6816962Smckusick continue; 6916962Smckusick } 7016962Smckusick strcpy(bufp, lp); 7116962Smckusick *lp++ = '\n'; 7216962Smckusick *lp = '\0'; 7316962Smckusick emptyqueue(); 7416962Smckusick } 7516962Smckusick for (cp = bufp; isspace(*cp); cp++) 7616962Smckusick /* void */; 7716962Smckusick if ((cp = doreplaceon(cp)) == 0) { 7816962Smckusick bufp = newline(); 7916962Smckusick continue; 8016962Smckusick } 81*16978Smckusick for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) { 8216962Smckusick if (pp->size == size && bcmp(pp->name, cp, size) == 0) { 8316962Smckusick expand(pp->replace); 8416962Smckusick bufp = line[bufhead]; 8516962Smckusick break; 8616962Smckusick } 8716962Smckusick } 8816962Smckusick if (!pp) { 8916962Smckusick emptyqueue(); 9016962Smckusick fputs(bufp, stdout); 9116962Smckusick } 9216962Smckusick } 9316962Smckusick emptyqueue(); 9416962Smckusick exit(0); 9516962Smckusick } 9616962Smckusick 9716962Smckusick /* 9816962Smckusick * Integrate an expansion into the assembly stream 9916962Smckusick */ 10016962Smckusick expand(replace) 10116962Smckusick char *replace; 10216962Smckusick { 10316962Smckusick register int curptr; 10416962Smckusick char *nextreplace, *argv[MAXARGS]; 105*16978Smckusick int argc, argreg, foundarg, mod = 0; 10616962Smckusick char parsebuf[BUFSIZ]; 10716962Smckusick 10816962Smckusick for (curptr = bufhead; curptr != buftail; ) { 10916962Smckusick nextreplace = copyline(replace, line[bufhead]); 11016962Smckusick argc = parseline(line[bufhead], argv, parsebuf); 11116962Smckusick argreg = nextarg(argc, argv); 11216962Smckusick if (argreg == -1) 11316962Smckusick break; 114*16978Smckusick for (foundarg = 0; curptr != buftail; ) { 115*16978Smckusick curptr = PRED(curptr); 11616962Smckusick argc = parseline(line[curptr], argv, parsebuf); 117*16978Smckusick if (isendofblock(argc, argv)) 11816962Smckusick break; 119*16978Smckusick if (foundarg = ispusharg(argc, argv)) 120*16978Smckusick break; 12116962Smckusick mod |= 1 << modifies(argc, argv); 12216962Smckusick } 123*16978Smckusick if (!foundarg) 12416962Smckusick break; 12516962Smckusick replace = nextreplace; 12616962Smckusick if (mod & (1 << argreg)) { 127*16978Smckusick if (curptr == buftail) { 128*16978Smckusick (void)newline(); 129*16978Smckusick break; 130*16978Smckusick } 13116962Smckusick (void)newline(); 13216962Smckusick } else { 13316962Smckusick rewrite(line[curptr], argc, argv, argreg); 13416962Smckusick mod |= 1 << argreg; 13516962Smckusick } 13616962Smckusick } 13716962Smckusick emptyqueue(); 13816962Smckusick fputs(replace, stdout); 13916962Smckusick } 14016962Smckusick 14116962Smckusick /* 14216962Smckusick * Parse a line of assembly language into opcode and arguments. 14316962Smckusick */ 14416962Smckusick parseline(linep, argv, linebuf) 14516962Smckusick char *linep; 14616962Smckusick char *argv[]; 14716962Smckusick char *linebuf; 14816962Smckusick { 14916962Smckusick register char *bufp = linebuf, *cp = linep; 15016962Smckusick register int argc = 0; 15116962Smckusick 15216962Smckusick for (;;) { 15316962Smckusick /* 15416962Smckusick * skip over white space 15516962Smckusick */ 15616962Smckusick while (isspace(*cp)) 15716962Smckusick cp++; 15816962Smckusick if (*cp == '\0') 15916962Smckusick return (argc); 16016962Smckusick /* 16116962Smckusick * copy argument 16216962Smckusick */ 16316962Smckusick if (argc == MAXARGS - 1) { 16416962Smckusick fprintf(stderr, "instruction too long->%s", linep); 16516962Smckusick return (argc); 16616962Smckusick } 16716962Smckusick argv[argc++] = bufp; 168*16978Smckusick while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR) 16916962Smckusick *bufp++ = *cp++; 17016962Smckusick *bufp++ = '\0'; 17116962Smckusick if (*cp == COMMENTCHAR) 17216962Smckusick return (argc); 173*16978Smckusick if (*cp == ARGSEPCHAR) 17416962Smckusick cp++; 17516962Smckusick } 17616962Smckusick } 17716962Smckusick 17816962Smckusick /* 179*16978Smckusick * Check for instructions that end a basic block. 180*16978Smckusick */ 181*16978Smckusick isendofblock(argc, argv) 182*16978Smckusick int argc; 183*16978Smckusick char *argv[]; 184*16978Smckusick { 185*16978Smckusick register struct inststoptbl *itp; 186*16978Smckusick int size; 187*16978Smckusick 188*16978Smckusick if (argc == 0) 189*16978Smckusick return (0); 190*16978Smckusick for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next) 191*16978Smckusick if (itp->size == size && bcmp(argv[0], itp->name, size) == 0) 192*16978Smckusick return (1); 193*16978Smckusick return (0); 194*16978Smckusick } 195*16978Smckusick 196*16978Smckusick /* 19716962Smckusick * Copy a newline terminated string. 19816962Smckusick * Return pointer to character following last character copied. 19916962Smckusick */ 20016962Smckusick char * 20116962Smckusick copyline(from, to) 20216962Smckusick register char *from, *to; 20316962Smckusick { 20416962Smckusick 20516962Smckusick while (*from != '\n') 20616962Smckusick *to++ = *from++; 20716962Smckusick *to++ = *from++; 20816962Smckusick *to = '\0'; 20916962Smckusick return (from); 21016962Smckusick } 21116962Smckusick 21216962Smckusick /* 21316962Smckusick * open space for next line in the queue 21416962Smckusick */ 21516962Smckusick char * 21616962Smckusick newline() 21716962Smckusick { 21816962Smckusick bufhead = SUCC(bufhead); 21916962Smckusick if (bufhead == buftail) { 22016962Smckusick fputs(line[buftail], stdout); 22116962Smckusick buftail = SUCC(buftail); 22216962Smckusick } 22316962Smckusick return (line[bufhead]); 22416962Smckusick } 22516962Smckusick 22616962Smckusick /* 22716962Smckusick * empty the queue by printing out all its lines. 22816962Smckusick */ 22916962Smckusick emptyqueue() 23016962Smckusick { 23116962Smckusick while (buftail != bufhead) { 23216962Smckusick fputs(line[buftail], stdout); 23316962Smckusick buftail = SUCC(buftail); 23416962Smckusick } 23516962Smckusick } 23616962Smckusick 23716962Smckusick /* 23816962Smckusick * Compute the hash of a string. 23916962Smckusick * Return the hash and the size of the item hashed 24016962Smckusick */ 24116962Smckusick hash(cp, size) 24216962Smckusick char *cp; 24316962Smckusick int *size; 24416962Smckusick { 24516962Smckusick register char *cp1 = cp; 246*16978Smckusick register int hash = 0; 24716962Smckusick 24816962Smckusick while (*cp1 && *cp1 != '\n') 24916962Smckusick hash += (int)*cp1++; 25016962Smckusick *size = cp1 - cp + 1; 25116962Smckusick hash &= HSHSIZ - 1; 252*16978Smckusick return (hash); 25316962Smckusick } 254