xref: /csrg-svn/sys/vax/inline/main.c (revision 16980)
116962Smckusick /* Copyright (c) 1984 Regents of the University of California */
216962Smckusick 
316962Smckusick #ifndef lint
4*16980Smckusick static char sccsid[] = "@(#)main.c	1.5	(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 
21*16980Smckusick /*
22*16980Smckusick  * Statistics collection
23*16980Smckusick  */
24*16980Smckusick struct stats {
25*16980Smckusick 	int	attempted;	/* number of expansion attempts */
26*16980Smckusick 	int	finished;	/* expansions done before end of basic block */
27*16980Smckusick 	int	lostmodified;	/* mergers inhibited by intervening mod */
28*16980Smckusick 	int	savedpush;	/* successful push/pop merger */
29*16980Smckusick } stats;
30*16980Smckusick int dflag;
31*16980Smckusick 
3216962Smckusick main(argc, argv)
3316962Smckusick 	int argc;
3416962Smckusick 	char *argv[];
3516962Smckusick {
3616962Smckusick 	register char *cp, *lp;
3716962Smckusick 	register char *bufp;
3816978Smckusick 	register struct pats *pp, **php;
3916978Smckusick 	struct pats **tablep;
4016978Smckusick 	register struct inststoptbl *itp, **ithp;
4116962Smckusick 	int size;
4216962Smckusick 	extern char *index();
4316962Smckusick 
44*16980Smckusick 	if (argc > 1 && bcmp(argv[1], "-d", 3) == 0)
45*16980Smckusick 		dflag++, argc--, argv++;
4616962Smckusick 	if (argc > 1)
4716962Smckusick 		freopen(argv[1], "r", stdin);
4816962Smckusick 	if (argc > 2)
4916962Smckusick 		freopen(argv[2], "w", stdout);
5016962Smckusick 	/*
5116978Smckusick 	 * Set up the hash table for the patterns.
5216962Smckusick 	 */
5316975Smckusick 	for (tablep = inittables; *tablep; tablep++) {
5416975Smckusick 		for (pp = *tablep; pp->name[0] != '\0'; pp++) {
5516978Smckusick 			php = &patshdr[hash(pp->name, &size)];
5616975Smckusick 			pp->size = size;
5716978Smckusick 			pp->next = *php;
5816978Smckusick 			*php = pp;
5916975Smckusick 		}
6016962Smckusick 	}
6116962Smckusick 	/*
6216978Smckusick 	 * Set up the hash table for the instruction stop table.
6316978Smckusick 	 */
6416978Smckusick 	for (itp = inststoptable; itp->name[0] != '\0'; itp++) {
6516978Smckusick 		ithp = &inststoptblhdr[hash(itp->name, &size)];
6616978Smckusick 		itp->size = size;
6716978Smckusick 		itp->next = *ithp;
6816978Smckusick 		*ithp = itp;
6916978Smckusick 	}
7016978Smckusick 	/*
7116962Smckusick 	 * check each line and replace as appropriate
7216962Smckusick 	 */
7316962Smckusick 	buftail = bufhead = 0;
7416962Smckusick 	bufp = line[0];
7516962Smckusick 	while (fgets(bufp, MAXLINELEN, stdin)) {
7616962Smckusick 		lp = index(bufp, LABELCHAR);
7716962Smckusick 		if (lp != NULL) {
7816962Smckusick 			bufp = newline();
7916962Smckusick 			if (*++lp == '\n') {
8016962Smckusick 				emptyqueue();
8116962Smckusick 				continue;
8216962Smckusick 			}
8316962Smckusick 			strcpy(bufp, lp);
8416962Smckusick 			*lp++ = '\n';
8516962Smckusick 			*lp = '\0';
8616962Smckusick 			emptyqueue();
8716962Smckusick 		}
8816962Smckusick 		for (cp = bufp; isspace(*cp); cp++)
8916962Smckusick 			/* void */;
9016962Smckusick 		if ((cp = doreplaceon(cp)) == 0) {
9116962Smckusick 			bufp = newline();
9216962Smckusick 			continue;
9316962Smckusick 		}
9416978Smckusick 		for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) {
9516962Smckusick 			if (pp->size == size && bcmp(pp->name, cp, size) == 0) {
9616962Smckusick 				expand(pp->replace);
9716962Smckusick 				bufp = line[bufhead];
9816962Smckusick 				break;
9916962Smckusick 			}
10016962Smckusick 		}
10116962Smckusick 		if (!pp) {
10216962Smckusick 			emptyqueue();
10316962Smckusick 			fputs(bufp, stdout);
10416962Smckusick 		}
10516962Smckusick 	}
10616962Smckusick 	emptyqueue();
107*16980Smckusick 	if (dflag)
108*16980Smckusick 		fprintf(stderr, "inline: %s %d, %s %d, %s %d, %s %d\n",
109*16980Smckusick 			"attempts", stats.attempted,
110*16980Smckusick 			"finished", stats.finished,
111*16980Smckusick 			"inhibited", stats.lostmodified,
112*16980Smckusick 			"merged", stats.savedpush);
11316962Smckusick 	exit(0);
11416962Smckusick }
11516962Smckusick 
11616962Smckusick /*
11716962Smckusick  * Integrate an expansion into the assembly stream
11816962Smckusick  */
11916962Smckusick expand(replace)
12016962Smckusick 	char *replace;
12116962Smckusick {
12216962Smckusick 	register int curptr;
12316962Smckusick 	char *nextreplace, *argv[MAXARGS];
12416978Smckusick 	int argc, argreg, foundarg, mod = 0;
12516962Smckusick 	char parsebuf[BUFSIZ];
12616962Smckusick 
127*16980Smckusick 	stats.attempted++;
128*16980Smckusick 	for (curptr = bufhead; ; ) {
12916962Smckusick 		nextreplace = copyline(replace, line[bufhead]);
13016962Smckusick 		argc = parseline(line[bufhead], argv, parsebuf);
13116962Smckusick 		argreg = nextarg(argc, argv);
13216962Smckusick 		if (argreg == -1)
13316962Smckusick 			break;
13416978Smckusick 		for (foundarg = 0; curptr != buftail; ) {
13516978Smckusick 			curptr = PRED(curptr);
13616962Smckusick 			argc = parseline(line[curptr], argv, parsebuf);
13716978Smckusick 			if (isendofblock(argc, argv))
13816962Smckusick 				break;
13916978Smckusick 			if (foundarg = ispusharg(argc, argv))
14016978Smckusick 				break;
14116962Smckusick 			mod |= 1 << modifies(argc, argv);
14216962Smckusick 		}
14316978Smckusick 		if (!foundarg)
14416962Smckusick 			break;
14516962Smckusick 		replace = nextreplace;
14616962Smckusick 		if (mod & (1 << argreg)) {
147*16980Smckusick 			stats.lostmodified++;
14816978Smckusick 			if (curptr == buftail) {
14916978Smckusick 				(void)newline();
15016978Smckusick 				break;
15116978Smckusick 			}
15216962Smckusick 			(void)newline();
15316962Smckusick 		} else {
154*16980Smckusick 			stats.savedpush++;
15516962Smckusick 			rewrite(line[curptr], argc, argv, argreg);
15616962Smckusick 			mod |= 1 << argreg;
15716962Smckusick 		}
15816962Smckusick 	}
159*16980Smckusick 	if (argreg == -1)
160*16980Smckusick 		stats.finished++;
16116962Smckusick 	emptyqueue();
16216962Smckusick 	fputs(replace, stdout);
16316962Smckusick }
16416962Smckusick 
16516962Smckusick /*
16616962Smckusick  * Parse a line of assembly language into opcode and arguments.
16716962Smckusick  */
16816962Smckusick parseline(linep, argv, linebuf)
16916962Smckusick 	char *linep;
17016962Smckusick 	char *argv[];
17116962Smckusick 	char *linebuf;
17216962Smckusick {
17316962Smckusick 	register char *bufp = linebuf, *cp = linep;
17416962Smckusick 	register int argc = 0;
17516962Smckusick 
17616962Smckusick 	for (;;) {
17716962Smckusick 		/*
17816962Smckusick 		 * skip over white space
17916962Smckusick 		 */
18016962Smckusick 		while (isspace(*cp))
18116962Smckusick 			cp++;
18216962Smckusick 		if (*cp == '\0')
18316962Smckusick 			return (argc);
18416962Smckusick 		/*
18516962Smckusick 		 * copy argument
18616962Smckusick 		 */
18716962Smckusick 		if (argc == MAXARGS - 1) {
18816962Smckusick 			fprintf(stderr, "instruction too long->%s", linep);
18916962Smckusick 			return (argc);
19016962Smckusick 		}
19116962Smckusick 		argv[argc++] = bufp;
19216978Smckusick 		while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR)
19316962Smckusick 			*bufp++ = *cp++;
19416962Smckusick 		*bufp++ = '\0';
19516962Smckusick 		if (*cp == COMMENTCHAR)
19616962Smckusick 			return (argc);
19716978Smckusick 		if (*cp == ARGSEPCHAR)
19816962Smckusick 			cp++;
19916962Smckusick 	}
20016962Smckusick }
20116962Smckusick 
20216962Smckusick /*
20316978Smckusick  * Check for instructions that end a basic block.
20416978Smckusick  */
20516978Smckusick isendofblock(argc, argv)
20616978Smckusick 	int argc;
20716978Smckusick 	char *argv[];
20816978Smckusick {
20916978Smckusick 	register struct inststoptbl *itp;
21016978Smckusick 	int size;
21116978Smckusick 
21216978Smckusick 	if (argc == 0)
21316978Smckusick 		return (0);
21416978Smckusick 	for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next)
21516978Smckusick 		if (itp->size == size && bcmp(argv[0], itp->name, size) == 0)
21616978Smckusick 			return (1);
21716978Smckusick 	return (0);
21816978Smckusick }
21916978Smckusick 
22016978Smckusick /*
22116962Smckusick  * Copy a newline terminated string.
22216962Smckusick  * Return pointer to character following last character copied.
22316962Smckusick  */
22416962Smckusick char *
22516962Smckusick copyline(from, to)
22616962Smckusick 	register char *from, *to;
22716962Smckusick {
22816962Smckusick 
22916962Smckusick 	while (*from != '\n')
23016962Smckusick 		*to++ = *from++;
23116962Smckusick 	*to++ = *from++;
23216962Smckusick 	*to = '\0';
23316962Smckusick 	return (from);
23416962Smckusick }
23516962Smckusick 
23616962Smckusick /*
23716962Smckusick  * open space for next line in the queue
23816962Smckusick  */
23916962Smckusick char *
24016962Smckusick newline()
24116962Smckusick {
24216962Smckusick 	bufhead = SUCC(bufhead);
24316962Smckusick 	if (bufhead == buftail) {
24416962Smckusick 		fputs(line[buftail], stdout);
24516962Smckusick 		buftail = SUCC(buftail);
24616962Smckusick 	}
24716962Smckusick 	return (line[bufhead]);
24816962Smckusick }
24916962Smckusick 
25016962Smckusick /*
25116962Smckusick  * empty the queue by printing out all its lines.
25216962Smckusick  */
25316962Smckusick emptyqueue()
25416962Smckusick {
25516962Smckusick 	while (buftail != bufhead) {
25616962Smckusick 		fputs(line[buftail], stdout);
25716962Smckusick 		buftail = SUCC(buftail);
25816962Smckusick 	}
25916962Smckusick }
26016962Smckusick 
26116962Smckusick /*
26216962Smckusick  * Compute the hash of a string.
26316962Smckusick  * Return the hash and the size of the item hashed
26416962Smckusick  */
26516962Smckusick hash(cp, size)
26616962Smckusick 	char *cp;
26716962Smckusick 	int *size;
26816962Smckusick {
26916962Smckusick 	register char *cp1 = cp;
27016978Smckusick 	register int hash = 0;
27116962Smckusick 
27216962Smckusick 	while (*cp1 && *cp1 != '\n')
27316962Smckusick 		hash += (int)*cp1++;
27416962Smckusick 	*size = cp1 - cp + 1;
27516962Smckusick 	hash &= HSHSIZ - 1;
27616978Smckusick 	return (hash);
27716962Smckusick }
278