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