man macros distributed with 4.3BSD
[unix-history] / usr / src / sys / vax / inline / machdep.c
CommitLineData
58248d62
KM
1/* Copyright (c) 1984 Regents of the University of California */
2
3#ifndef lint
41346a4f 4static char sccsid[] = "@(#)machdep.c 1.4 (Berkeley) %G%";
58248d62
KM
5#endif not lint
6
7#include <stdio.h>
8#include <ctype.h>
f22df3ae 9#include "inline.h"
58248d62
KM
10
11/*
f22df3ae
KM
12 * The routines and tables in this file must be rewritten
13 * for each new machine that this program is ported to.
58248d62
KM
14 */
15
41346a4f 16#ifdef vax
f22df3ae
KM
17/*
18 * Instruction stop table.
19 * All instructions that implicitly modify any of the temporary
20 * registers, change control flow, or implicitly loop must be
21 * listed in this table. It is used to find the end of a basic
22 * block when scanning backwards through the instruction stream
23 * trying to merge the inline expansion.
24 */
25struct inststoptbl inststoptable[] = {
26 { "jbc" }, { "jlbc" }, { "jbs" }, { "jlbs" }, { "jbcc" },
27 { "jbsc" }, { "jbcs" }, { "jbss" }, { "jbr" }, { "jcc" },
28 { "jcs" }, { "jvc" }, { "jvs" }, { "jlss" }, { "jlssu" },
29 { "jleq" }, { "jlequ" }, { "jeql" }, { "jeqlu" }, { "jneq" },
30 { "jnequ" }, { "jgeq" }, { "jgequ" }, { "jgtr" }, { "jgtru" },
31 { "chmk" }, { "chme" }, { "chms" }, { "chmu" }, { "rei" },
32 { "ldpctx" }, { "svpctx" }, { "xfc" }, { "bpt" },
33 { "bugw" }, { "bugl" }, { "halt" }, { "pushr" }, { "popr" },
34 { "polyf" }, { "polyd" }, { "polyg" }, { "polyh" },
35 { "bneq" }, { "bnequ" }, { "beql" }, { "beqlu" }, { "bgtr" },
36 { "bleq" }, { "bgeq" }, { "blss" }, { "bgtru" }, { "blequ" },
37 { "bvc" }, { "bvs" }, { "bgequ" }, { "bcc" }, { "blssu" },
38 { "bcs" }, { "brb" }, { "brw" }, { "jmp" },
39 { "bbs" }, { "bbc" }, { "bbss" }, { "bbcs" }, { "bbsc" },
40 { "bbcc" }, { "bbssi" }, { "bbcci" }, { "blbs" }, { "blbc" },
41 { "acbb" }, { "acbw" }, { "acbl" }, { "acbf" }, { "acbd" },
42 { "acbg" }, { "acbh" }, { "aoblss" }, { "aobleq" },
43 { "sobgeq" }, { "sobgtr" }, { "caseb" }, { "casew" }, { "casel" },
44 { "bsbb" }, { "bsbw" }, { "jsb" }, { "rsb" },
45 { "callg" }, { "calls" }, { "ret" },
46 { "movc3" }, { "movc5" }, { "movtc" }, { "movtuc" },
47 { "cmpc3" }, { "cmpc5" }, { "scanc" }, { "spanc" },
48 { "locc" }, { "skpc" }, { "matchc" }, { "crc" },
49 { "movp" }, { "cmpp3" }, { "cmpp4" }, { "addp4" }, { "addp6" },
50 { "subp4" }, { "subp6" }, { "mulp" }, { "divp" }, { "cvtlp" },
51 { "cvtpl" }, { "cvtpt" }, { "cvttp" }, { "cvtps" }, { "cvtsp" },
52 { "ashp" }, { "editpc" },
53 { "escd" }, { "esce" }, { "escf" },
54 { "" }
55};
56
58248d62
KM
57/*
58 * Check to see if a line is a candidate for replacement.
59 * Return pointer to name to be looked up in pattern table.
60 */
61char *
62doreplaceon(cp)
63 char *cp;
64{
65
66 if (bcmp(cp, "calls\t$", 7) == 0)
67 return (cp + 7);
68 return (0);
69}
70
71/*
72 * Find the next argument to the function being expanded.
58248d62
KM
73 */
74nextarg(argc, argv)
75 int argc;
76 char *argv[];
77{
78 register char *lastarg = argv[2];
79
80 if (argc == 3 &&
81 bcmp(argv[0], "mov", 3) == 0 &&
82 bcmp(argv[1], "(sp)+", 6) == 0 &&
83 lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
84 return (lastarg[1] - '0');
85 return (-1);
86}
87
88/*
89 * Determine whether the current line pushes an argument.
58248d62
KM
90 */
91 ispusharg(argc, argv)
92 int argc;
93 char *argv[];
94{
95
96 if (argc < 2)
97 return (0);
98 if (argc == 2 && bcmp(argv[0], "push", 4) == 0)
99 return (1);
100 if (bcmp(argv[argc - 1], "-(sp)", 6) == 0)
101 return (1);
102 return (0);
103}
104
105/*
106 * Determine which (if any) registers are modified
107 * Return register number that is modified, -1 if none are modified.
58248d62
KM
108 */
109modifies(argc, argv)
110 int argc;
111 char *argv[];
112{
113 /*
114 * For the VAX all we care about are r0 to r5
115 */
116 register char *lastarg = argv[argc - 1];
117
118 if (lastarg[0] == 'r' && isdigit(lastarg[1]) && lastarg[2] == '\0')
119 return (lastarg[1] - '0');
120 return (-1);
121}
122
123/*
124 * Rewrite the instruction in (argc, argv) to store its
125 * contents into arg instead of onto the stack. The new
126 * instruction is placed in the buffer that is provided.
58248d62
KM
127 */
128rewrite(instbuf, argc, argv, target)
129 char *instbuf;
130 int argc;
131 char *argv[];
132 int target;
133{
134
135 switch (argc) {
136 case 0:
137 instbuf[0] = '\0';
138 fprintf("blank line to rewrite?\n");
139 return;
140 case 1:
141 sprintf(instbuf, "\t%s\n", argv[0]);
142 fprintf(stderr, "rewrite?-> %s", instbuf);
143 return;
144 case 2:
145 if (bcmp(argv[0], "push", 4) == 0) {
146 sprintf(instbuf, "\tmov%s\t%s,r%d\n",
147 &argv[0][4], argv[1], target);
148 return;
149 }
150 sprintf(instbuf, "\t%s\tr%d\n", argv[0], target);
151 return;
152 case 3:
153 sprintf(instbuf, "\t%s\t%s,r%d\n", argv[0], argv[1], target);
154 return;
155 case 4:
156 sprintf(instbuf, "\t%s\t%s,%s,r%d\n",
157 argv[0], argv[1], argv[2], target);
158 return;
52a9f051
KM
159 case 5:
160 sprintf(instbuf, "\t%s\t%s,%s,%s,r%d\n",
161 argv[0], argv[1], argv[2], argv[3], target);
162 return;
58248d62
KM
163 default:
164 sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
165 argc -= 2, argv += 2;
166 while (argc-- > 0) {
167 strcat(instbuf, ",");
168 strcat(instbuf, *argv++);
169 }
170 strcat(instbuf, "\n");
171 fprintf(stderr, "rewrite?-> %s", instbuf);
172 return;
173 }
174}
41346a4f
KM
175
176/*
177 * Do any necessary post expansion cleanup.
178 */
179cleanup(numargs)
180 int numargs;
181{
182
183 return;
184}
185#endif vax
186
187#ifdef mc68000
188/*
189 * Instruction stop table.
190 * All instructions that implicitly modify any of the temporary
191 * registers, change control flow, or implicitly loop must be
192 * listed in this table. It is used to find the end of a basic
193 * block when scanning backwards through the instruction stream
194 * trying to merge the inline expansion.
195 */
196struct inststoptbl inststoptable[] = {
197 { "" }
198};
199
200/*
201 * Check to see if a line is a candidate for replacement.
202 * Return pointer to name to be looked up in pattern table.
203 */
204char *
205doreplaceon(cp)
206 char *cp;
207{
208
209 if (bcmp(cp, "jbsr\t", 5) == 0)
210 return (cp + 5);
211 return (0);
212}
213
214/*
215 * Find the next argument to the function being expanded.
216 */
217nextarg(argc, argv)
218 int argc;
219 char *argv[];
220{
221 register char *lastarg = argv[2];
222
223 if (argc == 3 &&
224 bcmp(argv[0], "movl", 5) == 0 &&
225 bcmp(argv[1], "sp@+", 5) == 0 &&
226 (lastarg[1] == '0' || lastarg[1] == '1') &&
227 lastarg[2] == '\0') {
228 if (lastarg[0] == 'd')
229 return (lastarg[1] - '0');
230 return (lastarg[1] - '0' + 8);
231 }
232 return (-1);
233}
234
235/*
236 * Determine whether the current line pushes an argument.
237 */
238 ispusharg(argc, argv)
239 int argc;
240 char *argv[];
241{
242
243 if (argc < 2)
244 return (0);
245 if (argc == 2 && bcmp(argv[0], "pea", 4) == 0)
246 return (1);
247 if (bcmp(argv[argc - 1], "sp@-", 5) == 0)
248 return (1);
249 return (0);
250}
251
252/*
253 * Determine which (if any) registers are modified
254 * Return register number that is modified, -1 if none are modified.
255 */
256modifies(argc, argv)
257 int argc;
258 char *argv[];
259{
260 /*
261 * For the MC68000 all we care about are d0, d1, a0, and a1.
262 */
263 register char *lastarg = argv[argc - 1];
264
265 if (lastarg[0] == 'd' && isdigit(lastarg[1]) && lastarg[2] == '\0')
266 return (lastarg[1] - '0');
267 if (lastarg[0] == 'a' && isdigit(lastarg[1]) && lastarg[2] == '\0')
268 return (lastarg[1] - '0' + 8);
269 return (-1);
270}
271
272/*
273 * Rewrite the instruction in (argc, argv) to store its
274 * contents into arg instead of onto the stack. The new
275 * instruction is placed in the buffer that is provided.
276 */
277rewrite(instbuf, argc, argv, target)
278 char *instbuf;
279 int argc;
280 char *argv[];
281 int target;
282{
283 int regno;
284 char regtype;
285
286 if (target < 8) {
287 regtype = 'd';
288 regno = target;
289 } else {
290 regtype = 'a';
291 regno = target - 8;
292 }
293 switch (argc) {
294 case 0:
295 instbuf[0] = '\0';
296 fprintf("blank line to rewrite?\n");
297 return;
298 case 1:
299 sprintf(instbuf, "\t%s\n", argv[0]);
300 fprintf(stderr, "rewrite?-> %s", instbuf);
301 return;
302 case 2:
303 if (bcmp(argv[0], "pea", 4) == 0) {
304 if (regtype == 'a') {
305 sprintf(instbuf, "\tlea\t%s,%c%d\n",
306 argv[1], regtype, regno);
307 return;
308 }
309 if (argv[1][0] == '_' || isdigit(argv[1][0])) {
310 sprintf(instbuf, "\tmovl\t#%s,%c%d\n",
311 argv[1], regtype, regno);
312 return;
313 }
314 sprintf(instbuf,
315 "\texg\ta0,d%d\n\tlea\t%s,a0\n\texg\ta0,d%d\n",
316 regno, argv[1], regno);
317 return;
318 }
319 sprintf(instbuf, "\t%s\t%c%d\n", argv[0], regtype, regno);
320 return;
321 case 3:
322 sprintf(instbuf, "\t%s\t%s,%c%d\n",
323 argv[0], argv[1], regtype, regno);
324 return;
325 default:
326 sprintf(instbuf, "\t%s\t%s", argv[0], argv[1]);
327 argc -= 2, argv += 2;
328 while (argc-- > 0) {
329 strcat(instbuf, ",");
330 strcat(instbuf, *argv++);
331 }
332 strcat(instbuf, "\n");
333 fprintf(stderr, "rewrite?-> %s", instbuf);
334 return;
335 }
336}
337
338/*
339 * Do any necessary post expansion cleanup.
340 */
341cleanup(numargs)
342 int numargs;
343{
344
345 if (numargs == 0)
346 return;
347 /*
348 * delete instruction to pop arguments.
349 * TODO:
350 * CHECK FOR LABEL
351 * CHECK THAT INSTRUCTION IS A POP
352 */
353 fgets(line[bufhead], MAXLINELEN, stdin);
354}
355#endif mc68000