1/* opc2c.c --- generate C opcode decoder code from from .opc file 2 3 Copyright (C) 2005-2017 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 29static char * line_buf = NULL; 30static int line_buf_size = 0; 31 32#define LBUFINCR 100 33 34char * 35safe_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 73static int errors = 0; 74 75#define MAX_BYTES 10 76 77typedef struct 78{ 79 int varyno:16; 80 int byte:8; 81 int shift:8; 82} VaryRef; 83 84typedef 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 106int n_opcodes; 107opcode ** opcodes; 108opcode * op; 109 110typedef struct 111{ 112 char * name; 113 int nlen; 114 unsigned char mask; 115 int n_patterns; 116 unsigned char * patterns; 117} Vary; 118 119Vary ** vary = 0; 120int n_varies = 0; 121 122unsigned char cur_bits[MAX_BYTES + 1]; 123 124const char * orig_filename; 125 126FILE * sim_log = NULL; 127#define lprintf if (sim_log) fprintf 128 129opcode prefix_text, suffix_text; 130 131typedef enum 132{ 133 T_unused, 134 T_op, 135 T_indirect, 136 T_done 137} OpType; 138 139typedef struct Indirect 140{ 141 OpType type; 142 union 143 { 144 struct Indirect * ind; 145 opcode * op; 146 } u; 147} Indirect; 148 149Indirect indirect[256]; 150 151static int 152next_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 173static int 174valid_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 207char * 208prmb (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 234static int 235op_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 246void 247dump_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 351void 352store_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 398void 399emit_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 460static char * 461pv_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 471static unsigned char 472str2mask (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 486static void 487process_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 523static int 524fieldcmp (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 534static void 535log_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 570int 571main (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 && strcmp (argv[1], "-l") == 0) 581 { 582 sim_log = fopen (argv[2], "w"); 583 fprintf (stderr, "sim_log: %s\n", argv[2]); 584 argc -= 2; 585 argv += 2; 586 } 587 588 if (argc < 2) 589 { 590 fprintf (stderr, "usage: opc2c infile.opc > outfile.opc\n"); 591 exit (1); 592 } 593 594 orig_filename = lbasename (argv[1]); 595 in = fopen (argv[1], "r"); 596 if (!in) 597 { 598 fprintf (stderr, "Unable to open file %s for reading: %s\n", argv[1], 599 xstrerror (errno)); 600 exit (1); 601 } 602 603 n_opcodes = 0; 604 opcodes = (opcode **) malloc (sizeof (opcode *)); 605 op = &prefix_text; 606 op->lineno = 0; 607 while ((line = safe_fgets (in)) != 0) 608 { 609 lineno++; 610 if (strncmp (line, "/*?* ", 5) == 0) 611 { 612 skipping_section = 1; 613 continue; 614 } 615 if (strncmp (line, " /** ", 6) == 0 616 && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0)) 617 line += 2; 618 if (line[0] == '/' && line[1] == '*' && line[2] == '*') 619 { 620 skipping_section = 0; 621 if (strncmp (line, "/** */", 6) == 0) 622 { 623 op = &suffix_text; 624 op->lineno = lineno; 625 } 626 else if (strncmp (line, "/** VARY ", 9) == 0) 627 process_vary (line + 9); 628 else 629 { 630 char * lp; 631 int i, bit, byte; 632 int var_start = 1; 633 634 n_opcodes++; 635 opcodes = 636 (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *)); 637 op = (opcode *) malloc (sizeof (opcode)); 638 opcodes[n_opcodes - 1] = op; 639 640 op->nbytes = op->dbytes = 0; 641 memset (op->id, 0, sizeof (op->id)); 642 memset (op->var_start, 0, sizeof (op->var_start)); 643 for (i = 0; i < MAX_BYTES; i++) 644 { 645 op->b[i].decodable_mask = 0; 646 op->b[i].decodable_bits = 0; 647 } 648 op->comment = strdup (line); 649 op->comment[strlen (op->comment) - 1] = 0; 650 while (op->comment[0] && isspace (op->comment[0])) 651 op->comment++; 652 op->lineno = lineno; 653 op->nlines = 0; 654 op->lines = 0; 655 op->last_ind = 0; 656 op->semantics_label = 0; 657 op->nvaries = 0; 658 op->vary = 0; 659 660 i = 0; 661 for (lp = line + 4; *lp; lp++) 662 { 663 bit = 7 - (i & 7); 664 byte = i >> 3; 665 666 if (strncmp (lp, "*/", 2) == 0) 667 break; 668 else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t')) 669 { 670 while (*lp == ' ' || *lp == '\t') 671 lp ++; 672 op->syntax = strdup (lp); 673 lp = strstr (op->syntax, "*/"); 674 if (lp) 675 { 676 *lp-- = 0; 677 while ((*lp == ' ' || *lp == '\t') 678 && lp > op->syntax) 679 *lp-- = 0; 680 } 681 break; 682 } 683 else if (*lp == ' ') 684 var_start = 1; 685 else 686 { 687 if (*lp == '0' || *lp == '1') 688 { 689 op->b[byte].decodable_mask |= 1 << bit; 690 var_start = 1; 691 if (op->dbytes < byte + 1) 692 op->dbytes = byte + 1; 693 } 694 else if (var_start) 695 { 696 op->var_start[i] = 1; 697 var_start = 0; 698 if (op->dbytes < byte + 1) 699 op->dbytes = byte + 1; 700 } 701 if (*lp == '1') 702 op->b[byte].decodable_bits |= 1 << bit; 703 704 op->nbytes = byte + 1; 705 op->id[i++] = *lp; 706 } 707 } 708 } 709 } 710 else if (!skipping_section) 711 { 712 op->nlines++; 713 if (op->lines) 714 op->lines = 715 (char **) realloc (op->lines, op->nlines * sizeof (char *)); 716 else 717 op->lines = (char **) malloc (op->nlines * sizeof (char *)); 718 op->lines[op->nlines - 1] = strdup (line); 719 } 720 } 721 722 { 723 int i, j; 724 for (i = 0; i < n_varies; i++) 725 { 726 Vary *v = vary[i]; 727 lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen); 728 for (j = 0; j < v->n_patterns; j++) 729 lprintf (sim_log, " P %02x\n", v->patterns[j]); 730 } 731 } 732 733 for (i = n_opcodes - 2; i >= 0; i--) 734 { 735 if (opcodes[i]->nlines == 0) 736 { 737 opcodes[i]->nlines = opcodes[i + 1]->nlines; 738 opcodes[i]->lines = opcodes[i + 1]->lines; 739 } 740 } 741 742 for (i = 0; i < 256; i++) 743 indirect[i].type = T_unused; 744 745 qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp); 746 747 vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef)); 748 749 for (i = 0; i < n_opcodes; i++) 750 { 751 int j, b, v; 752 753 for (j = 0; j < opcodes[i]->nbytes; j++) 754 lprintf (sim_log, "%s ", 755 prmb (opcodes[i]->b[j].decodable_mask, 756 opcodes[i]->b[j].decodable_bits)); 757 lprintf (sim_log, " %s\n", opcodes[i]->comment); 758 759 for (j = 0; j < opcodes[i]->nbytes; j++) 760 { 761 for (b = 0; b < 8; b++) 762 if (isalpha (opcodes[i]->id[j * 8 + b])) 763 for (v = 0; v < n_varies; v++) 764 if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name)) 765 { 766 int nv = opcodes[i]->nvaries++; 767 if (nv) 768 opcodes[i]->vary = 769 (VaryRef *) realloc (opcodes[i]->vary, 770 (nv + 1) * sizeof (VaryRef)); 771 else 772 opcodes[i]->vary = 773 (VaryRef *) malloc ((nv + 1) * sizeof (VaryRef)); 774 775 opcodes[i]->vary[nv].varyno = v; 776 opcodes[i]->vary[nv].byte = j; 777 opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen; 778 lprintf (sim_log, "[vary %s shift %d]\n", 779 vary[v]->name, opcodes[i]->vary[nv].shift); 780 } 781 782 } 783 } 784 785 for (i = 0; i < n_opcodes; i++) 786 { 787 int i2; 788 int bytes = opcodes[i]->dbytes; 789 790 lprintf (sim_log, "\nmask:"); 791 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 792 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask); 793 lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "", 794 opcodes[i]->comment); 795 796 lprintf (sim_log, "bits:"); 797 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 798 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits); 799 lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes, 800 "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s"); 801 802 store_opcode_bits (opcodes[i], 0, indirect); 803 } 804 805 dump_lines (&prefix_text, 0, 0); 806 807 emit_indirect (indirect, 0); 808 809 dump_lines (&suffix_text, 0, 0); 810 811 if (sim_log) 812 log_indirect (indirect, 0); 813 814 return errors; 815} 816