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 *
doreplaceon(cp)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 */
countargs(cp)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 */
nextarg(argc,argv)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 */
ispusharg(argc,argv)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 */
modifies(argc,argv)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 */
rewrite(instbuf,argc,argv,target)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 */
cleanup(numargs)200 cleanup(numargs)
201 int numargs;
202 {
203
204 }
205