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