1 1.1 christos /* opc2c.c --- generate C opcode decoder code from from .opc file 2 1.1 christos 3 1.11 christos Copyright (C) 2005-2024 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