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