1/* opc2c.c --- generate C simulator code from from .opc file 2 3Copyright (C) 2005-2020 Free Software Foundation, Inc. 4Contributed by Red Hat, Inc. 5 6This file is part of the GNU simulators. 7 8This program is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 3 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along 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 27#include "safe-fgets.h" 28 29static int errors = 0; 30 31#define MAX_BYTES 10 32 33typedef struct 34{ 35 int varyno:16; 36 int byte:8; 37 int shift:8; 38} VaryRef; 39 40typedef 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 61int n_opcodes; 62opcode **opcodes; 63opcode *op; 64 65typedef struct 66{ 67 char *name; 68 int nlen; 69 unsigned char mask; 70 int n_patterns; 71 unsigned char *patterns; 72} Vary; 73 74Vary **vary = 0; 75int n_varies = 0; 76 77unsigned char cur_bits[MAX_BYTES + 1]; 78 79char *orig_filename; 80 81FILE *sim_log = 0; 82#define lprintf if (sim_log) fprintf 83 84opcode prefix_text, suffix_text; 85 86typedef enum 87{ 88 T_unused, 89 T_op, 90 T_indirect, 91 T_done 92} OpType; 93 94typedef struct Indirect 95{ 96 OpType type; 97 union 98 { 99 struct Indirect *ind; 100 opcode *op; 101 } u; 102} Indirect; 103 104Indirect indirect[256]; 105 106static int 107next_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 128static int 129valid_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 160char * 161prmb (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 186static int 187op_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 198void 199dump_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 AU = (op[%d] >> %d) & 0x%02x;\n", 253 level, "", name, byte, shift, mask); 254 else if (mask != 0xff) 255 printf ("%*s int %s AU = op[%d] & 0x%02x;\n", 256 level, "", name, byte, mask); 257 else 258 printf ("%*s int %s AU = op[%d];\n", level, "", name, byte); 259 } 260 else 261 i++; 262 } 263 if (op->comment) 264 { 265 printf ("%*s if (trace) {\n", level, ""); 266 printf ("%*s printf(\"\\033[33m%%s\\033[0m ", level, ""); 267 for (i = 0; i < op->nbytes; i++) 268 printf (" %%02x"); 269 printf ("\\n\""); 270 printf (",\n%*s \"%s\"", level, "", op->comment); 271 for (i = 0; i < op->nbytes; i++) 272 { 273 if (i == 0) 274 printf (",\n%*s op[%d]", level, "", i); 275 else 276 printf (", op[%d]", i); 277 } 278 printf (");\n"); 279 for (i = 0; i < vn; i++) 280 printf ("%*s printf(\" %s = 0x%%x%s\", %s);\n", level, "", 281 varnames[i], (i < vn - 1) ? "," : "\\n", varnames[i]); 282 printf ("%*s }\n", level, ""); 283 } 284 printf ("#line %d \"%s\"\n", op->lineno + 1, orig_filename); 285 for (i = 0; i < op->nlines; i++) 286 printf ("%*s%s", level, "", op->lines[i]); 287 if (op->comment) 288 printf ("%*s}\n", level, ""); 289} 290 291void 292store_opcode_bits (opcode * op, int byte, Indirect * ind) 293{ 294 int bits = op->b[byte].decodable_bits; 295 296 do 297 { 298 if (!valid_varybits (bits, op, byte)) 299 continue; 300 301 switch (ind[bits].type) 302 { 303 case T_unused: 304 if (byte == op->dbytes - 1) 305 { 306 ind[bits].type = T_op; 307 ind[bits].u.op = op; 308 op->last_ind = ind; 309 break; 310 } 311 else 312 { 313 int i2; 314 ind[bits].type = T_indirect; 315 ind[bits].u.ind = (Indirect *) malloc (256 * sizeof (Indirect)); 316 for (i2 = 0; i2 < 256; i2++) 317 ind[bits].u.ind[i2].type = T_unused; 318 store_opcode_bits (op, byte + 1, ind[bits].u.ind); 319 } 320 break; 321 322 case T_indirect: 323 if (byte < op->dbytes - 1) 324 store_opcode_bits (op, byte + 1, ind[bits].u.ind); 325 break; 326 327 case T_op: 328 break; 329 330 case T_done: 331 break; 332 } 333 } 334 while ((bits = next_varybits (bits, op, byte)) != 0); 335} 336 337void 338emit_indirect (Indirect * ind, int byte) 339{ 340 int unsup = 0; 341 int j, n, mask; 342 343 mask = 0; 344 for (j = 0; j < 256; j++) 345 { 346 switch (ind[j].type) 347 { 348 case T_indirect: 349 mask = 0xff; 350 break; 351 case T_op: 352 mask |= ind[j].u.op->b[byte].decodable_mask; 353 break; 354 case T_done: 355 case T_unused: 356 break; 357 } 358 } 359 360 printf ("%*s GETBYTE();\n", byte * 6, ""); 361 printf ("%*s switch (op[%d] & 0x%02x) {\n", byte * 6, "", byte, mask); 362 for (j = 0; j < 256; j++) 363 if ((j & ~mask) == 0) 364 { 365 switch (ind[j].type) 366 { 367 case T_done: 368 break; 369 case T_unused: 370 unsup = 1; 371 break; 372 case T_op: 373 for (n = j; n < 256; n++) 374 if ((n & ~mask) == 0 375 && ind[n].type == T_op && ind[n].u.op == ind[j].u.op) 376 { 377 ind[n].type = T_done; 378 printf ("%*s case 0x%02x:\n", byte * 6, "", n); 379 } 380 for (n = byte; n < ind[j].u.op->nbytes - 1; n++) 381 printf ("%*s GETBYTE();\n", byte * 6, ""); 382 dump_lines (ind[j].u.op, byte * 6 + 6, ind); 383 printf ("%*s break;\n", byte * 6, ""); 384 break; 385 case T_indirect: 386 printf ("%*s case 0x%02x:\n", byte * 6, "", j); 387 emit_indirect (ind[j].u.ind, byte + 1); 388 printf ("%*s break;\n", byte * 6, ""); 389 break; 390 } 391 } 392 if (unsup) 393 printf ("%*s default: UNSUPPORTED(); break;\n", byte * 6, ""); 394 printf ("%*s }\n", byte * 6, ""); 395} 396 397static char * 398pv_dup (char *p, char *ep) 399{ 400 int n = ep - p; 401 char *rv = (char *) malloc (n + 1); 402 memcpy (rv, p, n); 403 rv[n] = 0; 404 return rv; 405} 406 407static unsigned char 408str2mask (char *str, char *ep) 409{ 410 unsigned char rv = 0; 411 while (str < ep) 412 { 413 rv *= 2; 414 if (*str == '1') 415 rv += 1; 416 str++; 417 } 418 return rv; 419} 420 421static void 422process_vary (char *line) 423{ 424 char *cp, *ep; 425 Vary *v = (Vary *) malloc (sizeof (Vary)); 426 427 n_varies++; 428 if (vary) 429 vary = (Vary **) realloc (vary, n_varies * sizeof (Vary *)); 430 else 431 vary = (Vary **) malloc (n_varies * sizeof (Vary *)); 432 vary[n_varies - 1] = v; 433 434 cp = line; 435 436 for (cp = line; isspace (*cp); cp++); 437 for (ep = cp; *ep && !isspace (*ep); ep++); 438 439 v->name = pv_dup (cp, ep); 440 v->nlen = strlen (v->name); 441 v->mask = (1 << v->nlen) - 1; 442 443 v->n_patterns = 0; 444 v->patterns = (unsigned char *) malloc (1); 445 while (1) 446 { 447 for (cp = ep; isspace (*cp); cp++); 448 if (!isdigit (*cp)) 449 break; 450 for (ep = cp; *ep && !isspace (*ep); ep++); 451 v->n_patterns++; 452 v->patterns = (unsigned char *) realloc (v->patterns, v->n_patterns); 453 v->patterns[v->n_patterns - 1] = str2mask (cp, ep); 454 } 455} 456 457static int 458fieldcmp (opcode * op, int bit, char *name) 459{ 460 int n = strlen (name); 461 if (memcmp (op->id + bit, name, n) == 0 462 && (!isalpha (op->id[bit + n]) || op->var_start[bit + n])) 463 return 1; 464 return 0; 465} 466 467static void 468log_indirect (Indirect * ind, int byte) 469{ 470 int i, j; 471 char *last_c = 0; 472 473 for (i = 0; i < 256; i++) 474 { 475 476 for (j = 0; j < byte; j++) 477 fprintf (sim_log, "%s ", prmb (255, cur_bits[j])); 478 fprintf (sim_log, "%s ", prmb (255, i)); 479 480 switch (ind[i].type) 481 { 482 case T_op: 483 case T_done: 484 if (last_c && (ind[i].u.op->comment == last_c)) 485 fprintf (sim_log, "''\n"); 486 else 487 fprintf (sim_log, "%s\n", ind[i].u.op->comment); 488 last_c = ind[i].u.op->comment; 489 break; 490 case T_unused: 491 fprintf (sim_log, "unused\n"); 492 break; 493 case T_indirect: 494 fprintf (sim_log, "indirect\n"); 495 cur_bits[byte] = i; 496 log_indirect (ind[i].u.ind, byte + 1); 497 last_c = 0; 498 break; 499 } 500 } 501} 502 503int 504main (int argc, char **argv) 505{ 506 char *line; 507 FILE *in; 508 int lineno = 0; 509 int i; 510 VaryRef *vlist; 511 512 if (argc > 2 && strcmp (argv[1], "-l") == 0) 513 { 514 sim_log = fopen (argv[2], "w"); 515 fprintf (stderr, "sim_log: %s\n", argv[2]); 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 while ((line = safe_fgets (in)) != 0) 540 { 541 lineno++; 542 if (strncmp (line, " /** ", 6) == 0 543 && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0)) 544 line += 2; 545 if (line[0] == '/' && line[1] == '*' && line[2] == '*') 546 { 547 if (strncmp (line, "/** */", 6) == 0) 548 { 549 op = &suffix_text; 550 op->lineno = lineno; 551 } 552 else if (strncmp (line, "/** VARY ", 9) == 0) 553 process_vary (line + 9); 554 else 555 { 556 char *lp; 557 int i, bit, byte; 558 int var_start = 1; 559 560 n_opcodes++; 561 opcodes = 562 (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *)); 563 op = (opcode *) malloc (sizeof (opcode)); 564 opcodes[n_opcodes - 1] = op; 565 566 op->nbytes = op->dbytes = 0; 567 memset (op->id, 0, sizeof (op->id)); 568 memset (op->var_start, 0, sizeof (op->var_start)); 569 for (i = 0; i < MAX_BYTES; i++) 570 { 571 op->b[i].decodable_mask = 0; 572 op->b[i].decodable_bits = 0; 573 } 574 op->comment = strdup (line); 575 op->comment[strlen (op->comment) - 1] = 0; 576 while (op->comment[0] && isspace (op->comment[0])) 577 op->comment++; 578 op->lineno = lineno; 579 op->nlines = 0; 580 op->lines = 0; 581 op->last_ind = 0; 582 op->semantics_label = 0; 583 op->nvaries = 0; 584 op->vary = 0; 585 586 i = 0; 587 for (lp = line + 4; *lp; lp++) 588 { 589 bit = 7 - (i & 7); 590 byte = i >> 3; 591 592 if (strncmp (lp, "*/", 2) == 0) 593 break; 594 else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t')) 595 break; 596 else if (*lp == ' ') 597 var_start = 1; 598 else 599 { 600 if (*lp == '0' || *lp == '1') 601 { 602 op->b[byte].decodable_mask |= 1 << bit; 603 var_start = 1; 604 if (op->dbytes < byte + 1) 605 op->dbytes = byte + 1; 606 } 607 else if (var_start) 608 { 609 op->var_start[i] = 1; 610 var_start = 0; 611 } 612 if (*lp == '1') 613 op->b[byte].decodable_bits |= 1 << bit; 614 615 op->nbytes = byte + 1; 616 op->id[i++] = *lp; 617 } 618 } 619 } 620 } 621 else 622 { 623 op->nlines++; 624 if (op->lines) 625 op->lines = 626 (char **) realloc (op->lines, op->nlines * sizeof (char *)); 627 else 628 op->lines = (char **) malloc (op->nlines * sizeof (char *)); 629 op->lines[op->nlines - 1] = strdup (line); 630 } 631 } 632 633 { 634 int i, j; 635 for (i = 0; i < n_varies; i++) 636 { 637 Vary *v = vary[i]; 638 lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen); 639 for (j = 0; j < v->n_patterns; j++) 640 lprintf (sim_log, " P %02x\n", v->patterns[j]); 641 } 642 } 643 644 for (i = n_opcodes - 2; i >= 0; i--) 645 { 646 if (opcodes[i]->nlines == 0) 647 { 648 opcodes[i]->nlines = opcodes[i + 1]->nlines; 649 opcodes[i]->lines = opcodes[i + 1]->lines; 650 } 651 } 652 653 for (i = 0; i < 256; i++) 654 indirect[i].type = T_unused; 655 656 qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp); 657 658 vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef)); 659 660 for (i = 0; i < n_opcodes; i++) 661 { 662 int j, b, v; 663 664 for (j = 0; j < opcodes[i]->nbytes; j++) 665 lprintf (sim_log, "%s ", 666 prmb (opcodes[i]->b[j].decodable_mask, 667 opcodes[i]->b[j].decodable_bits)); 668 lprintf (sim_log, " %s\n", opcodes[i]->comment); 669 670 for (j = 0; j < opcodes[i]->nbytes; j++) 671 { 672 for (b = 0; b < 8; b++) 673 if (isalpha (opcodes[i]->id[j * 8 + b])) 674 for (v = 0; v < n_varies; v++) 675 if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name)) 676 { 677 int nv = opcodes[i]->nvaries++; 678 if (nv) 679 opcodes[i]->vary = 680 (VaryRef *) realloc (opcodes[i]->vary, 681 (nv + 1) * sizeof (VaryRef)); 682 else 683 opcodes[i]->vary = 684 (VaryRef *) malloc ((nv + 1) * sizeof (VaryRef)); 685 686 opcodes[i]->vary[nv].varyno = v; 687 opcodes[i]->vary[nv].byte = j; 688 opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen; 689 lprintf (sim_log, "[vary %s shift %d]\n", 690 vary[v]->name, opcodes[i]->vary[nv].shift); 691 } 692 693 } 694 } 695 696 for (i = 0; i < n_opcodes; i++) 697 { 698 int i2; 699 int bytes = opcodes[i]->dbytes; 700 701 lprintf (sim_log, "\nmask:"); 702 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 703 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask); 704 lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "", 705 opcodes[i]->comment); 706 707 lprintf (sim_log, "bits:"); 708 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 709 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits); 710 lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes, 711 "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s"); 712 713 store_opcode_bits (opcodes[i], 0, indirect); 714 } 715 716 dump_lines (&prefix_text, 0, 0); 717 718 emit_indirect (indirect, 0); 719 720 dump_lines (&suffix_text, 0, 0); 721 722 if (sim_log) 723 log_indirect (indirect, 0); 724 725 return errors; 726} 727