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