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