Pristine Ack-5.5
[Ack-5.5.git] / util / int / switch / mkswitch.c
1 /*
2         Generates contents of opcode switch from ip_spec.t
3         Call is:
4                 mkswitch prefix ip_spec.t cases [ functions ]
5
6         Note:
7         The u flag has been implemented by just copying and adjusting the
8         code for 2, which is almost identical to that for 4.  When this has
9         stabilized, combine.
10 */
11
12 /* $Id: mkswitch.c,v 2.3 1994/06/24 10:50:06 ceriel Exp $ */
13
14 #include <stdio.h>
15
16 extern FILE *popen();
17
18 char *progname;
19
20 FILE    *ifp;                   /* Input File Pointer */
21 FILE    *ofp;                   /* Output File Pointer */
22 FILE    *ffp = 0;               /* Function File Pointer */
23 char    *Prefix;                /* Prefix for function name */
24
25 main(argc, argv)
26         int argc;
27         char **argv;
28 {
29         char    mnem[8];                /* Mnemonic */
30         char    flgs[8];                /* Flags */
31         char    command[32];
32
33         progname = argv[0];
34
35         if (argc < 4 || argc >5) {
36                 fatal("usage is: %s prefix ip_spec.t cases [ functions ]\n",
37                         argv[0]);
38         }
39
40         Prefix = argv[1];
41
42         if ((ifp = fopen(argv[2], "r")) == 0) {
43                 fatal("cannot open '%s' for reading\n", argv[2]);
44         }
45
46         if ((ofp = fopen(argv[3], "w")) == 0) {
47                 fatal("cannot open '%s' for writing\n", argv[3]);
48         }
49
50         if (argc == 5) {        /* Need to store functions */
51                 sprintf(command, "sort | uniq > %s", argv[4]);
52                 if ((ffp = popen(command, "w")) == 0) {
53                         fatal("cannot popen '%s'\n", command);
54                 }
55         }
56
57         /* Start reading the input file */
58         while (fscanf(ifp, "%s %s", mnem, flgs) >= 0) {
59                 int i;
60                 char *p;
61                 char *base;
62                 int cnt, first;
63
64                 /* check flags */
65                 for (p = flgs; *p; p++) {
66                         if (!in("-ms2u4eNPwo", *p)) {
67                                 fatal("bad flags ip_spec: %s\n", flgs);
68                         }
69                 }
70
71                 if (    in(flgs, '-')
72                 +       in(flgs, 'm')
73                 +       in(flgs, 's')
74                 +       in(flgs, '2')
75                 +       in(flgs, 'u')
76                 +       in(flgs, '4')
77                 !=      1
78                 ) {
79                         fatal("duplicate or missing opcode flag ip_spec: %s\n",
80                                         flgs);
81                 }
82
83                 if (    in(flgs, 'N')
84                 +       in(flgs, 'P')
85                 >       1
86                 ) {
87                         fatal("duplicate restriction flags ip_spec: %s\n", flgs);
88                 }
89
90                 /* capitalize mnemonic */
91                 for (p = mnem; *p; p++) {
92                         *p += ('A' - 'a');
93                 }
94
95                 /* scan rest of line */
96                 if (    in(flgs, '-')
97                 ||      in(flgs, '2')
98                 ||      in(flgs, 'u')
99                 ||      in(flgs, '4')
100                 ) {
101                         fscanf(ifp, " %d \n", &first);
102                 }
103                 else {
104                         fscanf(ifp, " %d %d \n", &cnt, &first);
105                 }
106
107                 /* determine base */
108                 if (in(flgs, 'e'))      /* Escaped (secondary) opcode */
109                         base = "SEC_BASE";
110                 else
111                 if (in(flgs, '4'))      /* Escaped (tertiary) opcode */
112                         base = "TERT_BASE";
113                 else
114                         base = "PRIM_BASE";
115
116                 /* analyse the opcode */
117                 if (in(flgs, '-')) {    /* No arguments */
118                         NoArgs(base, first, mnem);
119                 } else if (in(flgs, 'm')) {     /* Mini */
120                         for (i = 0; i<cnt; i++) {
121                                 Mini(i, flgs, base, first, mnem);
122                         }
123                 } else if (in(flgs, 's')) {     /* Shortie */
124                         for (i = 0; i<cnt; i++) {
125                                 Shortie(i, flgs, base, first, mnem);
126                         }
127                 } else if (in(flgs, '2')) {     /* Two byte signed */
128                         TwoSgn(flgs, base, first, mnem);
129                 } else if (in(flgs, 'u')) {     /* Two byte unsigned */
130                         TwoUns(flgs, base, first, mnem);
131                 } else if (in(flgs, '4')) {     /* Four byte signed */
132                         FourSgn(flgs, base, first, mnem);
133                 } else {
134                         fatal("no opcode flag in ip_spec %s\n", flgs);
135                 }
136         }
137         exit(0);
138 }
139
140 NoArgs(base, first, mnem)
141         char *base;
142         int first;
143         char *mnem;
144 {
145         fprintf(ofp, "\t\tcase %s+%d:\t%s%sz(); break;\n",
146                 base, first, Prefix, mnem);
147         if (ffp) {
148                 fprintf(ffp, "%s%sz() {", Prefix, mnem);
149                 fprintf(ffp, "LOG((\"@ %s%sz()\"));}\n", Prefix, mnem);
150         }
151 }
152
153 Mini(i, flgs, base, first, mnem)
154         int i;
155         char *flgs;
156         char *base;
157         int first;
158         char *mnem;
159 {
160         char arg[16];
161         int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i;
162
163         switch (newi) {
164         case -1:
165                 sprintf(arg, "%s",
166                         in(flgs, 'w') ? "-wsize" : "-1L");
167                 break;
168         case 0:
169                 sprintf(arg, "0L");
170                 break;
171         case 1:
172                 sprintf(arg, "%s",
173                         in(flgs, 'w') ? "wsize" : "1L");
174                 break;
175         default:
176                 sprintf(arg, "%dL%s",
177                         newi, in(flgs, 'w') ? "*wsize" : "");
178                 break;
179         }
180         fprintf(ofp, "\t\tcase %s+%d:\t%s%sm(%s); break;\n",
181                 base, first+i, Prefix, mnem, arg);
182         if (ffp) {
183                 fprintf(ffp, "%s%sm(arg) long arg; {",
184                                 Prefix, mnem);
185                 fprintf(ffp, "LOG((\"@ %s%sm(%%d)\", arg));}\n",
186                                 Prefix, mnem);
187         }
188 }
189
190 Shortie(i, flgs, base, first, mnem)
191         int i;
192         char *flgs;
193         char *base;
194         int first;
195         char *mnem;
196 {
197         char arg[16];
198         int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i;
199
200         sprintf(arg, "%dL, %s", newi, (in(flgs, 'w') ? "wsize" : "1L"));
201         fprintf(ofp, "\t\tcase %s+%d:\t%s%ss(%s); break;\n",
202                 base, first+i, Prefix, mnem, arg);
203         if (ffp) {
204                 fprintf(ffp, "%s%ss(hob, wfac) long hob; size wfac; {",
205                                 Prefix, mnem);
206                 fprintf(ffp, "LOG((\"@ %s%ss(%%d)\", hob, wfac));",
207                                 Prefix, mnem);
208                 fprintf(ffp, " newPC(PC+1);}\n");
209         }
210 }
211
212 TwoSgn(flgs, base, first, mnem)
213         char *flgs;
214         char *base;
215         int first;
216         char *mnem;
217 {
218         char *xy = in(flgs, 'P') ? "p2" : in(flgs, 'N') ? "n2" : "l2";
219
220         fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
221                         base, first, Prefix, mnem, xy,
222                         in(flgs, 'w') ? "wsize" : "1L");
223         if (ffp) {
224                 fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
225                 fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
226                                 Prefix, mnem, xy);
227                 fprintf(ffp, " newPC(PC+2);}\n");
228         }
229 }
230
231 TwoUns(flgs, base, first, mnem)
232         char *flgs;
233         char *base;
234         int first;
235         char *mnem;
236 {
237         char *xy = "u";
238
239         fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
240                         base, first, Prefix, mnem, xy,
241                         in(flgs, 'w') ? "wsize" : "1L");
242         if (ffp) {
243                 fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
244                 fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
245                                 Prefix, mnem, xy);
246                 fprintf(ffp, " newPC(PC+2);}\n");
247         }
248 }
249
250 FourSgn(flgs, base, first, mnem)
251         char *flgs;
252         char *base;
253         int first;
254         char *mnem;
255 {
256         char *xy = in(flgs, 'P') ? "p4" : in(flgs, 'N') ? "n4" : "l4";
257
258         fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n",
259                         base, first, Prefix, mnem, xy,
260                         in(flgs, 'w') ? "wsize" : "1L");
261         if (ffp) {
262                 fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy);
263                 fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));",
264                                 Prefix, mnem, xy);
265                 fprintf(ffp, " newPC(PC+4);}\n");
266         }
267 }
268
269 int
270 in(flgs, c)
271         char *flgs;
272         char c;
273 {
274         while (*flgs)
275                 if (c == *flgs++)
276                         return 1;
277         return 0;
278 }
279
280 fatal(fmt, str)
281         char *fmt;
282         char *str;
283 {
284         fprintf(stderr, "%s, (fatal error): ", progname);
285         fprintf(stderr, fmt, str);
286         fprintf(stderr, "\n");
287         exit(1);
288 }