opc2c.c revision 1.8 1 1.1 christos /* opc2c.c --- generate C opcode decoder code from from .opc file
2 1.1 christos
3 1.8 christos Copyright (C) 2005-2019 Free Software Foundation, Inc.
4 1.1 christos Contributed by Red Hat, Inc.
5 1.1 christos
6 1.1 christos This file is part of the GNU opcode library.
7 1.1 christos
8 1.1 christos This program is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3 of the License, or
11 1.1 christos (at your option) any later version.
12 1.1 christos
13 1.1 christos This program is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos
22 1.1 christos #include <stdio.h>
23 1.1 christos #include <string.h>
24 1.1 christos #include <ctype.h>
25 1.1 christos #include <stdlib.h>
26 1.1 christos #include <errno.h>
27 1.1 christos #include "libiberty.h"
28 1.1 christos
29 1.1 christos static char * line_buf = NULL;
30 1.1 christos static int line_buf_size = 0;
31 1.1 christos
32 1.1 christos #define LBUFINCR 100
33 1.1 christos
34 1.1 christos char *
35 1.1 christos safe_fgets (FILE * f)
36 1.1 christos {
37 1.1 christos char * line_ptr;
38 1.1 christos
39 1.1 christos if (line_buf == NULL)
40 1.1 christos {
41 1.1 christos line_buf = (char *) malloc (LBUFINCR);
42 1.1 christos line_buf_size = LBUFINCR;
43 1.1 christos }
44 1.1 christos
45 1.1 christos /* Points to last byte. */
46 1.1 christos line_ptr = line_buf + line_buf_size - 1;
47 1.1 christos
48 1.1 christos /* So we can see if fgets put a 0 there. */
49 1.1 christos *line_ptr = 1;
50 1.1 christos if (fgets (line_buf, line_buf_size, f) == 0)
51 1.1 christos return NULL;
52 1.1 christos
53 1.1 christos /* We filled the buffer? */
54 1.1 christos while (line_ptr[0] == 0 && line_ptr[-1] != '\n')
55 1.1 christos {
56 1.1 christos /* Make the buffer bigger and read more of the line. */
57 1.1 christos line_buf_size += LBUFINCR;
58 1.1 christos line_buf = (char *) realloc (line_buf, line_buf_size);
59 1.1 christos
60 1.1 christos /* Points to last byte again. */
61 1.1 christos line_ptr = line_buf + line_buf_size - 1;
62 1.1 christos /* So we can see if fgets put a 0 there. */
63 1.1 christos *line_ptr = 1;
64 1.1 christos
65 1.1 christos if (fgets (line_buf + line_buf_size - LBUFINCR - 1, LBUFINCR + 1, f) == 0)
66 1.1 christos return NULL;
67 1.1 christos }
68 1.1 christos
69 1.1 christos return line_buf;
70 1.1 christos }
71 1.1 christos
72 1.1 christos
73 1.1 christos static int errors = 0;
74 1.1 christos
75 1.1 christos #define MAX_BYTES 10
76 1.1 christos
77 1.1 christos typedef struct
78 1.1 christos {
79 1.1 christos int varyno:16;
80 1.1 christos int byte:8;
81 1.1 christos int shift:8;
82 1.1 christos } VaryRef;
83 1.1 christos
84 1.1 christos typedef struct
85 1.1 christos {
86 1.1 christos char nbytes;
87 1.1 christos char dbytes;
88 1.1 christos char id[MAX_BYTES * 8 + 1];
89 1.1 christos unsigned char var_start[MAX_BYTES * 8 + 1];
90 1.1 christos struct
91 1.1 christos {
92 1.1 christos unsigned char decodable_mask;
93 1.1 christos unsigned char decodable_bits;
94 1.1 christos } b[MAX_BYTES];
95 1.1 christos char * comment;
96 1.1 christos char * syntax;
97 1.1 christos int lineno;
98 1.1 christos int nlines;
99 1.1 christos char ** lines;
100 1.1 christos struct Indirect * last_ind;
101 1.1 christos int semantics_label;
102 1.1 christos int nvaries;
103 1.1 christos VaryRef * vary;
104 1.1 christos } opcode;
105 1.1 christos
106 1.1 christos int n_opcodes;
107 1.1 christos opcode ** opcodes;
108 1.1 christos opcode * op;
109 1.1 christos
110 1.1 christos typedef struct
111 1.1 christos {
112 1.1 christos char * name;
113 1.1 christos int nlen;
114 1.1 christos unsigned char mask;
115 1.1 christos int n_patterns;
116 1.1 christos unsigned char * patterns;
117 1.1 christos } Vary;
118 1.1 christos
119 1.1 christos Vary ** vary = 0;
120 1.1 christos int n_varies = 0;
121 1.1 christos
122 1.1 christos unsigned char cur_bits[MAX_BYTES + 1];
123 1.1 christos
124 1.6 christos const char * orig_filename;
125 1.1 christos
126 1.1 christos FILE * sim_log = NULL;
127 1.1 christos #define lprintf if (sim_log) fprintf
128 1.1 christos
129 1.1 christos opcode prefix_text, suffix_text;
130 1.1 christos
131 1.1 christos typedef enum
132 1.1 christos {
133 1.1 christos T_unused,
134 1.1 christos T_op,
135 1.1 christos T_indirect,
136 1.1 christos T_done
137 1.1 christos } OpType;
138 1.1 christos
139 1.1 christos typedef struct Indirect
140 1.1 christos {
141 1.1 christos OpType type;
142 1.1 christos union
143 1.1 christos {
144 1.1 christos struct Indirect * ind;
145 1.1 christos opcode * op;
146 1.1 christos } u;
147 1.1 christos } Indirect;
148 1.1 christos
149 1.1 christos Indirect indirect[256];
150 1.1 christos
151 1.1 christos static int
152 1.1 christos next_varybits (int bits, opcode * op, int byte)
153 1.1 christos {
154 1.1 christos int mask = op->b[byte].decodable_mask;
155 1.1 christos int i;
156 1.1 christos
157 1.1 christos for (i = 0; i < 8; i++)
158 1.1 christos if (!(mask & (1 << i)))
159 1.1 christos {
160 1.1 christos if (bits & (1 << i))
161 1.1 christos {
162 1.1 christos bits &= ~(1 << i);
163 1.1 christos }
164 1.1 christos else
165 1.1 christos {
166 1.1 christos bits |= (1 << i);
167 1.1 christos return bits;
168 1.1 christos }
169 1.1 christos }
170 1.1 christos return 0;
171 1.1 christos }
172 1.1 christos
173 1.1 christos static int
174 1.1 christos valid_varybits (int bits, opcode * op, int byte)
175 1.1 christos {
176 1.1 christos if (op->nvaries)
177 1.1 christos {
178 1.1 christos int vn;
179 1.1 christos
180 1.1 christos for (vn = 0; vn < op->nvaries; vn++)
181 1.1 christos {
182 1.1 christos Vary * v;
183 1.1 christos int found = 0;
184 1.1 christos int i;
185 1.1 christos int ob;
186 1.1 christos
187 1.1 christos if (byte != op->vary[vn].byte)
188 1.1 christos continue;
189 1.1 christos v = vary[op->vary[vn].varyno];
190 1.1 christos ob = (bits >> op->vary[vn].shift) & v->mask;
191 1.1 christos lprintf (sim_log, "varybits: vary %s ob %x\n", v->name, ob);
192 1.1 christos
193 1.1 christos for (i = 0; i < v->n_patterns; i++)
194 1.1 christos if (ob == v->patterns[i])
195 1.1 christos {
196 1.1 christos lprintf (sim_log, " found at %d\n", i);
197 1.1 christos found = 1;
198 1.1 christos break;
199 1.1 christos }
200 1.1 christos if (!found)
201 1.1 christos return 0;
202 1.1 christos }
203 1.1 christos }
204 1.1 christos return 1;
205 1.1 christos }
206 1.1 christos
207 1.1 christos char *
208 1.1 christos prmb (int mask, int bits)
209 1.1 christos {
210 1.1 christos static char buf[8][30];
211 1.1 christos static int bn = 0;
212 1.1 christos char * bp;
213 1.1 christos
214 1.1 christos bn = (bn + 1) % 8;
215 1.1 christos bp = buf[bn];
216 1.1 christos int i;
217 1.1 christos for (i = 0; i < 8; i++)
218 1.1 christos {
219 1.1 christos int bit = 0x80 >> i;
220 1.1 christos
221 1.1 christos if (!(mask & bit))
222 1.1 christos *bp++ = '-';
223 1.1 christos else if (bits & bit)
224 1.1 christos *bp++ = '1';
225 1.1 christos else
226 1.1 christos *bp++ = '0';
227 1.1 christos if (i % 4 == 3)
228 1.1 christos *bp++ = ' ';
229 1.1 christos }
230 1.1 christos *--bp = 0;
231 1.1 christos return buf[bn];
232 1.1 christos }
233 1.1 christos
234 1.1 christos static int
235 1.1 christos op_cmp (const void *va, const void *vb)
236 1.1 christos {
237 1.1 christos const opcode * a = *(const opcode **) va;
238 1.1 christos const opcode * b = *(const opcode **) vb;
239 1.1 christos
240 1.1 christos if (a->nbytes != b->nbytes)
241 1.1 christos return a->nbytes - b->nbytes;
242 1.1 christos
243 1.1 christos return strcmp (a->id, b->id);
244 1.1 christos }
245 1.1 christos
246 1.1 christos void
247 1.1 christos dump_lines (opcode * op, int level, Indirect * ind)
248 1.1 christos {
249 1.1 christos char * varnames[40];
250 1.1 christos int i, vn = 0;
251 1.1 christos
252 1.1 christos if (op->semantics_label)
253 1.1 christos {
254 1.1 christos printf ("%*sgoto op_semantics_%d;\n", level, "", op->semantics_label);
255 1.1 christos return;
256 1.1 christos }
257 1.1 christos
258 1.1 christos if (ind != op->last_ind)
259 1.1 christos {
260 1.1 christos static int labelno = 0;
261 1.1 christos labelno++;
262 1.1 christos printf ("%*sop_semantics_%d:\n", level, "", labelno);
263 1.1 christos op->semantics_label = labelno;
264 1.1 christos }
265 1.1 christos
266 1.1 christos if (op->comment)
267 1.1 christos {
268 1.1 christos level += 2;
269 1.1 christos printf ("%*s{\n", level, "");
270 1.1 christos printf ("%*s %s\n", level, "", op->comment);
271 1.1 christos }
272 1.1 christos
273 1.1 christos for (i = 0; i < op->nbytes * 8;)
274 1.1 christos {
275 1.1 christos if (isalpha (op->id[i]))
276 1.1 christos {
277 1.1 christos int byte = i >> 3;
278 1.1 christos int mask = 0;
279 1.1 christos int shift = 0;
280 1.1 christos char name[33];
281 1.1 christos char * np = name;
282 1.1 christos
283 1.1 christos while (op->id[i] && isalpha (op->id[i]))
284 1.1 christos {
285 1.1 christos mask = (mask << 1) | 1;
286 1.1 christos shift = 7 - (i & 7);
287 1.1 christos *np++ = op->id[i++];
288 1.1 christos if (op->var_start[i])
289 1.1 christos break;
290 1.1 christos }
291 1.1 christos *np = 0;
292 1.1 christos varnames[vn++] = strdup (name);
293 1.1 christos printf ("#line %d \"%s\"\n", op->lineno + 1, orig_filename);
294 1.1 christos if (mask & ~0xff)
295 1.1 christos {
296 1.1 christos fprintf (stderr, "Error: variable %s spans bytes: %s\n",
297 1.1 christos name, op->comment);
298 1.1 christos errors++;
299 1.1 christos }
300 1.1 christos else if (shift && (mask != 0xff))
301 1.1 christos printf ("%*s int %s AU = (op[%d] >> %d) & 0x%02x;\n",
302 1.1 christos level, "", name, byte, shift, mask);
303 1.1 christos else if (mask != 0xff)
304 1.1 christos printf ("%*s int %s AU = op[%d] & 0x%02x;\n",
305 1.1 christos level, "", name, byte, mask);
306 1.1 christos else
307 1.1 christos printf ("%*s int %s AU = op[%d];\n", level, "", name, byte);
308 1.1 christos }
309 1.1 christos else
310 1.1 christos i++;
311 1.1 christos }
312 1.1 christos
313 1.1 christos if (op->comment)
314 1.1 christos {
315 1.1 christos printf ("%*s if (trace)\n", level, "");
316 1.1 christos printf ("%*s {\n", level, "");
317 1.1 christos printf ("%*s printf (\"\\033[33m%%s\\033[0m ", level, "");
318 1.1 christos for (i = 0; i < op->nbytes; i++)
319 1.1 christos printf (" %%02x");
320 1.1 christos printf ("\\n\"");
321 1.1 christos printf (",\n%*s \"%s\"", level, "", op->comment);
322 1.1 christos for (i = 0; i < op->nbytes; i++)
323 1.1 christos {
324 1.1 christos if (i == 0)
325 1.1 christos printf (",\n%*s op[%d]", level, "", i);
326 1.1 christos else
327 1.1 christos printf (", op[%d]", i);
328 1.1 christos }
329 1.1 christos printf (");\n");
330 1.1 christos for (i = 0; i < vn; i++)
331 1.1 christos printf ("%*s printf (\" %s = 0x%%x%s\", %s);\n", level, "",
332 1.1 christos varnames[i], (i < vn - 1) ? "," : "\\n", varnames[i]);
333 1.1 christos printf ("%*s }\n", level, "");
334 1.1 christos }
335 1.1 christos
336 1.1 christos if (op->syntax)
337 1.1 christos printf ("%*s SYNTAX(\"%s\");\n", level, "", op->syntax);
338 1.1 christos
339 1.1 christos printf ("#line %d \"%s\"\n", op->lineno + 1, orig_filename);
340 1.1 christos
341 1.1 christos for (i = 0; i < op->nlines; i++)
342 1.6 christos if (op->lines[i][0] == '\n')
343 1.6 christos printf ("%s", op->lines[i]);
344 1.6 christos else
345 1.6 christos printf ("%*s%s", level, "", op->lines[i]);
346 1.1 christos
347 1.1 christos if (op->comment)
348 1.1 christos printf ("%*s}\n", level, "");
349 1.1 christos }
350 1.1 christos
351 1.1 christos void
352 1.1 christos store_opcode_bits (opcode * op, int byte, Indirect * ind)
353 1.1 christos {
354 1.1 christos int bits = op->b[byte].decodable_bits;
355 1.1 christos
356 1.1 christos do
357 1.1 christos {
358 1.1 christos if (!valid_varybits (bits, op, byte))
359 1.1 christos continue;
360 1.1 christos
361 1.1 christos switch (ind[bits].type)
362 1.1 christos {
363 1.1 christos case T_unused:
364 1.1 christos if (byte == op->dbytes - 1)
365 1.1 christos {
366 1.1 christos ind[bits].type = T_op;
367 1.1 christos ind[bits].u.op = op;
368 1.1 christos op->last_ind = ind;
369 1.1 christos break;
370 1.1 christos }
371 1.1 christos else
372 1.1 christos {
373 1.1 christos int i2;
374 1.1 christos
375 1.1 christos ind[bits].type = T_indirect;
376 1.1 christos ind[bits].u.ind = (Indirect *) malloc (256 * sizeof (Indirect));
377 1.1 christos for (i2 = 0; i2 < 256; i2++)
378 1.1 christos ind[bits].u.ind[i2].type = T_unused;
379 1.1 christos store_opcode_bits (op, byte + 1, ind[bits].u.ind);
380 1.1 christos }
381 1.1 christos break;
382 1.1 christos
383 1.1 christos case T_indirect:
384 1.1 christos if (byte < op->dbytes - 1)
385 1.1 christos store_opcode_bits (op, byte + 1, ind[bits].u.ind);
386 1.1 christos break;
387 1.1 christos
388 1.1 christos case T_op:
389 1.1 christos break;
390 1.1 christos
391 1.1 christos case T_done:
392 1.1 christos break;
393 1.1 christos }
394 1.1 christos }
395 1.1 christos while ((bits = next_varybits (bits, op, byte)) != 0);
396 1.1 christos }
397 1.1 christos
398 1.1 christos void
399 1.1 christos emit_indirect (Indirect * ind, int byte)
400 1.1 christos {
401 1.1 christos int unsup = 0;
402 1.1 christos int j, n, mask;
403 1.1 christos
404 1.1 christos mask = 0;
405 1.1 christos for (j = 0; j < 256; j++)
406 1.1 christos {
407 1.1 christos switch (ind[j].type)
408 1.1 christos {
409 1.1 christos case T_indirect:
410 1.1 christos mask = 0xff;
411 1.1 christos break;
412 1.1 christos case T_op:
413 1.1 christos mask |= ind[j].u.op->b[byte].decodable_mask;
414 1.1 christos break;
415 1.1 christos case T_done:
416 1.1 christos case T_unused:
417 1.1 christos break;
418 1.1 christos }
419 1.1 christos }
420 1.1 christos
421 1.1 christos printf ("%*s GETBYTE ();\n", byte * 6, "");
422 1.1 christos printf ("%*s switch (op[%d] & 0x%02x)\n", byte * 6, "", byte, mask);
423 1.1 christos printf ("%*s {\n", byte * 6, "");
424 1.1 christos
425 1.1 christos for (j = 0; j < 256; j++)
426 1.1 christos if ((j & ~mask) == 0)
427 1.1 christos {
428 1.1 christos switch (ind[j].type)
429 1.1 christos {
430 1.1 christos case T_done:
431 1.1 christos break;
432 1.1 christos case T_unused:
433 1.1 christos unsup = 1;
434 1.1 christos break;
435 1.1 christos case T_op:
436 1.1 christos for (n = j; n < 256; n++)
437 1.1 christos if ((n & ~mask) == 0
438 1.1 christos && ind[n].type == T_op && ind[n].u.op == ind[j].u.op)
439 1.1 christos {
440 1.1 christos ind[n].type = T_done;
441 1.1 christos printf ("%*s case 0x%02x:\n", byte * 6, "", n);
442 1.1 christos }
443 1.1 christos for (n = byte; n < ind[j].u.op->nbytes - 1; n++)
444 1.1 christos printf ("%*s GETBYTE();\n", byte * 6, "");
445 1.1 christos dump_lines (ind[j].u.op, byte * 6 + 6, ind);
446 1.1 christos printf ("%*s break;\n", byte * 6, "");
447 1.1 christos break;
448 1.1 christos case T_indirect:
449 1.1 christos printf ("%*s case 0x%02x:\n", byte * 6, "", j);
450 1.1 christos emit_indirect (ind[j].u.ind, byte + 1);
451 1.1 christos printf ("%*s break;\n", byte * 6, "");
452 1.1 christos break;
453 1.1 christos }
454 1.1 christos }
455 1.1 christos if (unsup)
456 1.1 christos printf ("%*s default: UNSUPPORTED(); break;\n", byte * 6, "");
457 1.1 christos printf ("%*s }\n", byte * 6, "");
458 1.1 christos }
459 1.1 christos
460 1.1 christos static char *
461 1.1 christos pv_dup (char * p, char * ep)
462 1.1 christos {
463 1.1 christos int n = ep - p;
464 1.1 christos char *rv = (char *) malloc (n + 1);
465 1.1 christos
466 1.1 christos memcpy (rv, p, n);
467 1.1 christos rv[n] = 0;
468 1.1 christos return rv;
469 1.1 christos }
470 1.1 christos
471 1.1 christos static unsigned char
472 1.1 christos str2mask (char * str, char * ep)
473 1.1 christos {
474 1.1 christos unsigned char rv = 0;
475 1.1 christos
476 1.1 christos while (str < ep)
477 1.1 christos {
478 1.1 christos rv *= 2;
479 1.1 christos if (*str == '1')
480 1.1 christos rv += 1;
481 1.1 christos str++;
482 1.1 christos }
483 1.1 christos return rv;
484 1.1 christos }
485 1.1 christos
486 1.1 christos static void
487 1.1 christos process_vary (char * line)
488 1.1 christos {
489 1.1 christos char * cp;
490 1.1 christos char * ep;
491 1.1 christos Vary * v = (Vary *) malloc (sizeof (Vary));
492 1.1 christos
493 1.1 christos n_varies++;
494 1.1 christos if (vary)
495 1.1 christos vary = (Vary **) realloc (vary, n_varies * sizeof (Vary *));
496 1.1 christos else
497 1.1 christos vary = (Vary **) malloc (n_varies * sizeof (Vary *));
498 1.1 christos vary[n_varies - 1] = v;
499 1.1 christos
500 1.1 christos cp = line;
501 1.1 christos
502 1.1 christos for (cp = line; isspace (*cp); cp++);
503 1.1 christos for (ep = cp; *ep && !isspace (*ep); ep++);
504 1.1 christos
505 1.1 christos v->name = pv_dup (cp, ep);
506 1.1 christos v->nlen = strlen (v->name);
507 1.1 christos v->mask = (1 << v->nlen) - 1;
508 1.1 christos
509 1.1 christos v->n_patterns = 0;
510 1.1 christos v->patterns = (unsigned char *) malloc (1);
511 1.1 christos while (1)
512 1.1 christos {
513 1.1 christos for (cp = ep; isspace (*cp); cp++);
514 1.1 christos if (!isdigit (*cp))
515 1.1 christos break;
516 1.1 christos for (ep = cp; *ep && !isspace (*ep); ep++);
517 1.1 christos v->n_patterns++;
518 1.1 christos v->patterns = (unsigned char *) realloc (v->patterns, v->n_patterns);
519 1.1 christos v->patterns[v->n_patterns - 1] = str2mask (cp, ep);
520 1.1 christos }
521 1.1 christos }
522 1.1 christos
523 1.1 christos static int
524 1.1 christos fieldcmp (opcode * op, int bit, char *name)
525 1.1 christos {
526 1.1 christos int n = strlen (name);
527 1.1 christos
528 1.1 christos if (memcmp (op->id + bit, name, n) == 0
529 1.1 christos && (!isalpha (op->id[bit + n]) || op->var_start[bit + n]))
530 1.1 christos return 1;
531 1.1 christos return 0;
532 1.1 christos }
533 1.1 christos
534 1.1 christos static void
535 1.1 christos log_indirect (Indirect * ind, int byte)
536 1.1 christos {
537 1.1 christos int i, j;
538 1.1 christos char * last_c = 0;
539 1.1 christos
540 1.1 christos for (i = 0; i < 256; i++)
541 1.1 christos {
542 1.1 christos
543 1.1 christos for (j = 0; j < byte; j++)
544 1.1 christos fprintf (sim_log, "%s ", prmb (255, cur_bits[j]));
545 1.1 christos fprintf (sim_log, "%s ", prmb (255, i));
546 1.1 christos
547 1.1 christos switch (ind[i].type)
548 1.1 christos {
549 1.1 christos case T_op:
550 1.1 christos case T_done:
551 1.1 christos if (last_c && (ind[i].u.op->comment == last_c))
552 1.1 christos fprintf (sim_log, "''\n");
553 1.1 christos else
554 1.1 christos fprintf (sim_log, "%s\n", ind[i].u.op->comment);
555 1.1 christos last_c = ind[i].u.op->comment;
556 1.1 christos break;
557 1.1 christos case T_unused:
558 1.1 christos fprintf (sim_log, "unused\n");
559 1.1 christos break;
560 1.1 christos case T_indirect:
561 1.1 christos fprintf (sim_log, "indirect\n");
562 1.1 christos cur_bits[byte] = i;
563 1.1 christos log_indirect (ind[i].u.ind, byte + 1);
564 1.1 christos last_c = 0;
565 1.1 christos break;
566 1.1 christos }
567 1.1 christos }
568 1.1 christos }
569 1.1 christos
570 1.1 christos int
571 1.1 christos main (int argc, char ** argv)
572 1.1 christos {
573 1.1 christos char * line;
574 1.1 christos FILE * in;
575 1.1 christos int lineno = 0;
576 1.1 christos int i;
577 1.1 christos VaryRef * vlist;
578 1.1 christos int skipping_section = 0;
579 1.1 christos
580 1.1 christos if (argc < 2)
581 1.1 christos {
582 1.1 christos fprintf (stderr, "usage: opc2c infile.opc > outfile.opc\n");
583 1.1 christos exit (1);
584 1.1 christos }
585 1.1 christos
586 1.1 christos orig_filename = lbasename (argv[1]);
587 1.1 christos in = fopen (argv[1], "r");
588 1.1 christos if (!in)
589 1.1 christos {
590 1.1 christos fprintf (stderr, "Unable to open file %s for reading: %s\n", argv[1],
591 1.1 christos xstrerror (errno));
592 1.1 christos exit (1);
593 1.1 christos }
594 1.1 christos
595 1.1 christos n_opcodes = 0;
596 1.1 christos opcodes = (opcode **) malloc (sizeof (opcode *));
597 1.1 christos op = &prefix_text;
598 1.1 christos op->lineno = 0;
599 1.1 christos while ((line = safe_fgets (in)) != 0)
600 1.1 christos {
601 1.1 christos lineno++;
602 1.1 christos if (strncmp (line, "/*?* ", 5) == 0)
603 1.1 christos {
604 1.1 christos skipping_section = 1;
605 1.1 christos continue;
606 1.1 christos }
607 1.1 christos if (strncmp (line, " /** ", 6) == 0
608 1.1 christos && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0))
609 1.1 christos line += 2;
610 1.1 christos if (line[0] == '/' && line[1] == '*' && line[2] == '*')
611 1.1 christos {
612 1.1 christos skipping_section = 0;
613 1.1 christos if (strncmp (line, "/** */", 6) == 0)
614 1.1 christos {
615 1.1 christos op = &suffix_text;
616 1.1 christos op->lineno = lineno;
617 1.1 christos }
618 1.1 christos else if (strncmp (line, "/** VARY ", 9) == 0)
619 1.1 christos process_vary (line + 9);
620 1.1 christos else
621 1.1 christos {
622 1.1 christos char * lp;
623 1.1 christos int i, bit, byte;
624 1.1 christos int var_start = 1;
625 1.1 christos
626 1.1 christos n_opcodes++;
627 1.1 christos opcodes =
628 1.1 christos (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *));
629 1.1 christos op = (opcode *) malloc (sizeof (opcode));
630 1.1 christos opcodes[n_opcodes - 1] = op;
631 1.1 christos
632 1.1 christos op->nbytes = op->dbytes = 0;
633 1.1 christos memset (op->id, 0, sizeof (op->id));
634 1.1 christos memset (op->var_start, 0, sizeof (op->var_start));
635 1.1 christos for (i = 0; i < MAX_BYTES; i++)
636 1.1 christos {
637 1.1 christos op->b[i].decodable_mask = 0;
638 1.1 christos op->b[i].decodable_bits = 0;
639 1.1 christos }
640 1.1 christos op->comment = strdup (line);
641 1.1 christos op->comment[strlen (op->comment) - 1] = 0;
642 1.1 christos while (op->comment[0] && isspace (op->comment[0]))
643 1.1 christos op->comment++;
644 1.1 christos op->lineno = lineno;
645 1.1 christos op->nlines = 0;
646 1.1 christos op->lines = 0;
647 1.1 christos op->last_ind = 0;
648 1.1 christos op->semantics_label = 0;
649 1.1 christos op->nvaries = 0;
650 1.1 christos op->vary = 0;
651 1.1 christos
652 1.1 christos i = 0;
653 1.1 christos for (lp = line + 4; *lp; lp++)
654 1.1 christos {
655 1.1 christos bit = 7 - (i & 7);
656 1.1 christos byte = i >> 3;
657 1.1 christos
658 1.1 christos if (strncmp (lp, "*/", 2) == 0)
659 1.1 christos break;
660 1.1 christos else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t'))
661 1.1 christos {
662 1.1 christos while (*lp == ' ' || *lp == '\t')
663 1.1 christos lp ++;
664 1.1 christos op->syntax = strdup (lp);
665 1.1 christos lp = strstr (op->syntax, "*/");
666 1.1 christos if (lp)
667 1.1 christos {
668 1.1 christos *lp-- = 0;
669 1.1 christos while ((*lp == ' ' || *lp == '\t')
670 1.1 christos && lp > op->syntax)
671 1.1 christos *lp-- = 0;
672 1.1 christos }
673 1.1 christos break;
674 1.1 christos }
675 1.1 christos else if (*lp == ' ')
676 1.1 christos var_start = 1;
677 1.1 christos else
678 1.1 christos {
679 1.1 christos if (*lp == '0' || *lp == '1')
680 1.1 christos {
681 1.1 christos op->b[byte].decodable_mask |= 1 << bit;
682 1.1 christos var_start = 1;
683 1.1 christos if (op->dbytes < byte + 1)
684 1.1 christos op->dbytes = byte + 1;
685 1.1 christos }
686 1.1 christos else if (var_start)
687 1.1 christos {
688 1.1 christos op->var_start[i] = 1;
689 1.1 christos var_start = 0;
690 1.1 christos if (op->dbytes < byte + 1)
691 1.1 christos op->dbytes = byte + 1;
692 1.1 christos }
693 1.1 christos if (*lp == '1')
694 1.1 christos op->b[byte].decodable_bits |= 1 << bit;
695 1.1 christos
696 1.1 christos op->nbytes = byte + 1;
697 1.1 christos op->id[i++] = *lp;
698 1.1 christos }
699 1.1 christos }
700 1.1 christos }
701 1.1 christos }
702 1.1 christos else if (!skipping_section)
703 1.1 christos {
704 1.1 christos op->nlines++;
705 1.1 christos if (op->lines)
706 1.1 christos op->lines =
707 1.1 christos (char **) realloc (op->lines, op->nlines * sizeof (char *));
708 1.1 christos else
709 1.1 christos op->lines = (char **) malloc (op->nlines * sizeof (char *));
710 1.1 christos op->lines[op->nlines - 1] = strdup (line);
711 1.1 christos }
712 1.1 christos }
713 1.1 christos
714 1.1 christos {
715 1.1 christos int i, j;
716 1.1 christos for (i = 0; i < n_varies; i++)
717 1.1 christos {
718 1.1 christos Vary *v = vary[i];
719 1.1 christos lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen);
720 1.1 christos for (j = 0; j < v->n_patterns; j++)
721 1.1 christos lprintf (sim_log, " P %02x\n", v->patterns[j]);
722 1.1 christos }
723 1.1 christos }
724 1.1 christos
725 1.1 christos for (i = n_opcodes - 2; i >= 0; i--)
726 1.1 christos {
727 1.1 christos if (opcodes[i]->nlines == 0)
728 1.1 christos {
729 1.1 christos opcodes[i]->nlines = opcodes[i + 1]->nlines;
730 1.1 christos opcodes[i]->lines = opcodes[i + 1]->lines;
731 1.1 christos }
732 1.1 christos }
733 1.1 christos
734 1.1 christos for (i = 0; i < 256; i++)
735 1.1 christos indirect[i].type = T_unused;
736 1.1 christos
737 1.1 christos qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp);
738 1.1 christos
739 1.1 christos vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef));
740 1.1 christos
741 1.1 christos for (i = 0; i < n_opcodes; i++)
742 1.1 christos {
743 1.1 christos int j, b, v;
744 1.1 christos
745 1.1 christos for (j = 0; j < opcodes[i]->nbytes; j++)
746 1.1 christos lprintf (sim_log, "%s ",
747 1.1 christos prmb (opcodes[i]->b[j].decodable_mask,
748 1.1 christos opcodes[i]->b[j].decodable_bits));
749 1.1 christos lprintf (sim_log, " %s\n", opcodes[i]->comment);
750 1.1 christos
751 1.1 christos for (j = 0; j < opcodes[i]->nbytes; j++)
752 1.1 christos {
753 1.1 christos for (b = 0; b < 8; b++)
754 1.1 christos if (isalpha (opcodes[i]->id[j * 8 + b]))
755 1.1 christos for (v = 0; v < n_varies; v++)
756 1.1 christos if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name))
757 1.1 christos {
758 1.1 christos int nv = opcodes[i]->nvaries++;
759 1.1 christos if (nv)
760 1.1 christos opcodes[i]->vary =
761 1.1 christos (VaryRef *) realloc (opcodes[i]->vary,
762 1.1 christos (nv + 1) * sizeof (VaryRef));
763 1.1 christos else
764 1.1 christos opcodes[i]->vary =
765 1.1 christos (VaryRef *) malloc ((nv + 1) * sizeof (VaryRef));
766 1.1 christos
767 1.1 christos opcodes[i]->vary[nv].varyno = v;
768 1.1 christos opcodes[i]->vary[nv].byte = j;
769 1.1 christos opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen;
770 1.1 christos lprintf (sim_log, "[vary %s shift %d]\n",
771 1.1 christos vary[v]->name, opcodes[i]->vary[nv].shift);
772 1.1 christos }
773 1.1 christos
774 1.1 christos }
775 1.1 christos }
776 1.1 christos
777 1.1 christos for (i = 0; i < n_opcodes; i++)
778 1.1 christos {
779 1.1 christos int i2;
780 1.1 christos int bytes = opcodes[i]->dbytes;
781 1.1 christos
782 1.1 christos lprintf (sim_log, "\nmask:");
783 1.1 christos for (i2 = 0; i2 < opcodes[i]->nbytes; i2++)
784 1.1 christos lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask);
785 1.1 christos lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "",
786 1.1 christos opcodes[i]->comment);
787 1.1 christos
788 1.1 christos lprintf (sim_log, "bits:");
789 1.1 christos for (i2 = 0; i2 < opcodes[i]->nbytes; i2++)
790 1.1 christos lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits);
791 1.1 christos lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes,
792 1.1 christos "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s");
793 1.1 christos
794 1.1 christos store_opcode_bits (opcodes[i], 0, indirect);
795 1.1 christos }
796 1.1 christos
797 1.8 christos printf ("/* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */\n");
798 1.8 christos
799 1.1 christos dump_lines (&prefix_text, 0, 0);
800 1.1 christos
801 1.1 christos emit_indirect (indirect, 0);
802 1.1 christos
803 1.1 christos dump_lines (&suffix_text, 0, 0);
804 1.1 christos
805 1.1 christos if (sim_log)
806 1.1 christos log_indirect (indirect, 0);
807 1.1 christos
808 1.1 christos return errors;
809 1.1 christos }
810