xref: /original-bsd/sys/tahoe/inline/machdep.c (revision e59fb703)
1 /*-
2  * Copyright (c) 1984 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)machdep.c	1.4 (Berkeley) 05/08/91";
10 #endif /* not lint */
11 
12 #include <stdio.h>
13 #include <ctype.h>
14 #include "inline.h"
15 
16 extern char *strcpy();
17 extern char *strcat();
18 extern char *index();
19 
20 /*
21  * The routines and tables in this file must be rewritten
22  * for each new machine that this program is ported to.
23  */
24 
25 /*
26  * Instruction stop table.
27  * All instructions that implicitly modify any of the temporary
28  * registers, change control flow, or implicitly loop must be
29  * listed in this table. It is used to find the end of a basic
30  * block when scanning backwards through the instruction stream
31  * trying to merge the inline expansion.
32  */
33 struct inststoptbl inststoptable[] = {
34 /* control */
35 	{ "bbssi" }, { "bcc" }, { "bcs" }, { "beql" }, { "beqlu" },
36 	{ "bgeq" }, { "bgequ" }, { "bgtr" }, { "bgtru" }, { "bleq" },
37 	{ "blequ" }, { "blss" }, { "blssu" }, { "bneq" }, { "bnequ" },
38 	{ "brb" }, { "brw" }, { "bvc" }, { "bvs" }, { "jmp" },
39 /* jump versions of control */
40 	{ "jbc" }, { "jbs" }, { "jeql" }, { "jeqlu" },
41 	{ "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" }, { "jleq" },
42 	{ "jlequ" }, { "jlss" }, { "jlssu" }, { "jneq" }, { "jnequ" },
43 	{ "jcc" }, { "jcs" }, { "jvc" }, { "jvs" }, { "jbr" },
44 /* multiple registers */
45 	{ "loadr" },
46 /* bit field */
47 	{ "bbc" }, { "bbs" },
48 /* character string and block move */
49 	{ "cmps2" }, { "cmps3" }, { "movblk" }, { "movs2" }, { "movs3" },
50 /* procedure call */
51 	{ "callf" }, { "calls" }, { "ret" },
52 /* loop control */
53 	{ "aobleq" }, { "aoblss" }, { "casel" },
54 /* privileged and miscellaneous */
55 	{ "bpt" }, { "halt" }, { "kcall" }, { "ldpctx" }, { "rei" },
56 	{ "svpctx" },
57 	{ "" }
58 };
59 
60 /*
61  * Check to see if a line is a candidate for replacement.
62  * Return pointer to name to be looked up in pattern table.
63  */
64 char *
65 doreplaceon(cp)
66 	char *cp;
67 {
68 
69 	if (bcmp(cp, "callf\t", 6))
70 		return (0);
71 	if ((cp = index(cp + 6, ',')) == 0)
72 		return (0);
73 	return (++cp);
74 }
75 
76 /*
77  * Find out how many arguments the function is being called with.
78  * A return value of -1 indicates that the count can't be determined.
79  */
80 countargs(cp)
81 	char *cp;
82 {
83 	int i;
84 
85 	if ((cp = index(cp, '$')) == 0)
86 		return (-1);
87 	if (!isdigit(*++cp) || (i = atoi(cp)) == -1)
88 		return (-1);
89 	return (i/4 - 1);
90 }
91 
92 /*
93  * Find the next argument to the function being expanded.
94  */
95 nextarg(argc, argv)
96 	int argc;
97 	char *argv[];
98 {
99 	register char *lastarg = argv[2];
100 
101 	if (argc == 3 &&
102 	    bcmp(argv[0], "mov", 3) == 0 &&
103 	    bcmp(argv[1], "(sp)+", 6) == 0 &&
104 	    lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
105 		return (lastarg[1] - '0');
106 	return (-1);
107 }
108 
109 /*
110  * Determine whether the current line pushes an argument.
111  */
112 ispusharg(argc, argv)
113 	int argc;
114 	char *argv[];
115 {
116 
117 	if (argc < 2)
118 		return (0);
119 	if (argc == 2 && bcmp(argv[0], "push", 4) == 0)
120 		return (1);
121 	if (bcmp(argv[argc - 1], "-(sp)", 6) == 0)
122 		return (1);
123 	return (0);
124 }
125 
126 /*
127  * Determine which (if any) registers are modified
128  * Return register number that is modified, -1 if none are modified.
129  */
130 modifies(argc, argv)
131 	int argc;
132 	char *argv[];
133 {
134 	register char *lastarg = argv[argc - 1];
135 
136 	/*
137 	 * For the tahoe all we care about are r0 to r5
138 	 */
139 	if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
140 		return (lastarg[1] - '0');
141 	return (-1);
142 }
143 
144 /*
145  * Rewrite the instruction in (argc, argv) to store its
146  * contents into arg instead of onto the stack. The new
147  * instruction is placed in the buffer that is provided.
148  */
149 rewrite(instbuf, argc, argv, target)
150 	char *instbuf;
151 	int argc;
152 	char *argv[];
153 	int target;
154 {
155 
156 	switch (argc) {
157 	case 0:
158 		instbuf[0] = '\0';
159 		fprintf(stderr, "blank line to rewrite?\n");
160 		return;
161 	case 1:
162 		sprintf(instbuf, "\t%s\n", argv[0]);
163 		fprintf(stderr, "rewrite?-> %s", instbuf);
164 		return;
165 	case 2:
166 		if (bcmp(argv[0], "push", 4) == 0) {
167 			sprintf(instbuf, "\tmov%s\t%s,r%d\n",
168 				&argv[0][4], argv[1], target);
169 			return;
170 		}
171 		sprintf(instbuf, "\t%s\tr%d\n", argv[0], target);
172 		return;
173 	case 3:
174 		sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target);
175 		return;
176 	case 4:
177 		sprintf(instbuf, "\t%s\t%s,%s,r%d\n",
178 			argv[0], argv[1], argv[2], target);
179 		return;
180 	case 5:
181 		sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n",
182 			argv[0], argv[1], argv[2], argv[3], target);
183 		return;
184 	default:
185 		sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
186 		argc -= 2, argv += 2;
187 		while (argc-- > 0) {
188 			strcat(instbuf, ",");
189 			strcat(instbuf, *argv++);
190 		}
191 		strcat(instbuf, "\n");
192 		fprintf(stderr, "rewrite?-> %s", instbuf);
193 		return;
194 	}
195 }
196 
197 /*
198  * Do any necessary post expansion cleanup.
199  */
200 cleanup(numargs)
201 	int numargs;
202 {
203 
204 }
205