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