1/* opc2c.c --- generate C simulator code from from .opc file 2 3Copyright (C) 2005, 2007 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 if (ind[i].type == T_unused) 476 continue; 477 478 for (j = 0; j < byte; j++) 479 fprintf (sim_log, "%s ", prmb (255, cur_bits[j])); 480 fprintf (sim_log, "%s ", prmb (255, i)); 481 482 switch (ind[i].type) 483 { 484 case T_op: 485 case T_done: 486 if (last_c && (ind[i].u.op->comment == last_c)) 487 fprintf (sim_log, "''\n"); 488 else 489 fprintf (sim_log, "%s\n", ind[i].u.op->comment); 490 last_c = ind[i].u.op->comment; 491 break; 492 case T_unused: 493 fprintf (sim_log, "-\n"); 494 break; 495 case T_indirect: 496 fprintf (sim_log, "indirect\n"); 497 cur_bits[byte] = i; 498 log_indirect (ind[i].u.ind, byte + 1); 499 last_c = 0; 500 break; 501 } 502 } 503} 504 505int 506main (int argc, char **argv) 507{ 508 char *line; 509 FILE *in; 510 int lineno = 0; 511 int i; 512 VaryRef *vlist; 513 514 if (argc > 2 && strcmp (argv[1], "-l") == 0) 515 { 516 sim_log = fopen (argv[2], "w"); 517 fprintf (stderr, "sim_log: %s\n", argv[2]); 518 argc -= 2; 519 argv += 2; 520 } 521 522 if (argc < 2) 523 { 524 fprintf (stderr, "usage: opc2c infile.opc > outfile.opc\n"); 525 exit (1); 526 } 527 528 orig_filename = argv[1]; 529 in = fopen (argv[1], "r"); 530 if (!in) 531 { 532 fprintf (stderr, "Unable to open file %s for reading\n", argv[1]); 533 perror ("The error was"); 534 exit (1); 535 } 536 537 n_opcodes = 0; 538 opcodes = (opcode **) malloc (sizeof (opcode *)); 539 op = &prefix_text; 540 op->lineno = 1; 541 while ((line = safe_fgets (in)) != 0) 542 { 543 lineno++; 544 if (strncmp (line, " /** ", 6) == 0 545 && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0)) 546 line += 2; 547 if (line[0] == '/' && line[1] == '*' && line[2] == '*') 548 { 549 if (strncmp (line, "/** */", 6) == 0) 550 { 551 op = &suffix_text; 552 op->lineno = lineno; 553 } 554 else if (strncmp (line, "/** VARY ", 9) == 0) 555 process_vary (line + 9); 556 else 557 { 558 char *lp; 559 int i, bit, byte; 560 int var_start = 1; 561 562 n_opcodes++; 563 opcodes = 564 (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *)); 565 op = (opcode *) malloc (sizeof (opcode)); 566 opcodes[n_opcodes - 1] = op; 567 568 op->nbytes = op->dbytes = 0; 569 memset (op->id, 0, sizeof (op->id)); 570 memset (op->var_start, 0, sizeof (op->var_start)); 571 for (i = 0; i < MAX_BYTES; i++) 572 { 573 op->b[i].decodable_mask = 0; 574 op->b[i].decodable_bits = 0; 575 } 576 op->comment = strdup (line); 577 op->comment[strlen (op->comment) - 1] = 0; 578 while (op->comment[0] && isspace (op->comment[0])) 579 op->comment++; 580 op->lineno = lineno; 581 op->nlines = 0; 582 op->lines = 0; 583 op->last_ind = 0; 584 op->semantics_label = 0; 585 op->nvaries = 0; 586 op->vary = 0; 587 588 i = 0; 589 for (lp = line + 4; *lp; lp++) 590 { 591 bit = 7 - (i & 7); 592 byte = i >> 3; 593 594 if (strncmp (lp, "*/", 2) == 0) 595 break; 596 else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t')) 597 break; 598 else if (*lp == ' ') 599 var_start = 1; 600 else 601 { 602 if (*lp == '0' || *lp == '1') 603 { 604 op->b[byte].decodable_mask |= 1 << bit; 605 var_start = 1; 606 if (op->dbytes < byte + 1) 607 op->dbytes = byte + 1; 608 } 609 else if (var_start) 610 { 611 op->var_start[i] = 1; 612 var_start = 0; 613 } 614 if (*lp == '1') 615 op->b[byte].decodable_bits |= 1 << bit; 616 617 op->nbytes = byte + 1; 618 op->id[i++] = *lp; 619 } 620 } 621 } 622 } 623 else 624 { 625 op->nlines++; 626 if (op->lines) 627 op->lines = 628 (char **) realloc (op->lines, op->nlines * sizeof (char *)); 629 else 630 op->lines = (char **) malloc (op->nlines * sizeof (char *)); 631 op->lines[op->nlines - 1] = strdup (line); 632 } 633 } 634 635 { 636 int i, j; 637 for (i = 0; i < n_varies; i++) 638 { 639 Vary *v = vary[i]; 640 lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen); 641 for (j = 0; j < v->n_patterns; j++) 642 lprintf (sim_log, " P %02x\n", v->patterns[j]); 643 } 644 } 645 646 for (i = n_opcodes - 2; i >= 0; i--) 647 { 648 if (opcodes[i]->nlines == 0) 649 { 650 opcodes[i]->nlines = opcodes[i + 1]->nlines; 651 opcodes[i]->lines = opcodes[i + 1]->lines; 652 } 653 } 654 655 for (i = 0; i < 256; i++) 656 indirect[i].type = T_unused; 657 658 qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp); 659 660 vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef)); 661 662 for (i = 0; i < n_opcodes; i++) 663 { 664 int j, b, v; 665 666 for (j = 0; j < opcodes[i]->nbytes; j++) 667 lprintf (sim_log, "%s ", 668 prmb (opcodes[i]->b[j].decodable_mask, 669 opcodes[i]->b[j].decodable_bits)); 670 lprintf (sim_log, " %s\n", opcodes[i]->comment); 671 672 for (j = 0; j < opcodes[i]->nbytes; j++) 673 { 674 for (b = 0; b < 8; b++) 675 if (isalpha (opcodes[i]->id[j * 8 + b])) 676 for (v = 0; v < n_varies; v++) 677 if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name)) 678 { 679 int nv = opcodes[i]->nvaries++; 680 if (nv) 681 opcodes[i]->vary = 682 (VaryRef *) realloc (opcodes[i]->vary, 683 (nv + 1) * sizeof (VaryRef)); 684 else 685 opcodes[i]->vary = 686 (VaryRef *) malloc ((nv + 1) * sizeof (VaryRef)); 687 688 opcodes[i]->vary[nv].varyno = v; 689 opcodes[i]->vary[nv].byte = j; 690 opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen; 691 lprintf (sim_log, "[vary %s shift %d]\n", 692 vary[v]->name, opcodes[i]->vary[nv].shift); 693 } 694 695 } 696 } 697 698 for (i = 0; i < n_opcodes; i++) 699 { 700 int i2; 701 int bytes = opcodes[i]->dbytes; 702 703 lprintf (sim_log, "\nmask:"); 704 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 705 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask); 706 lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "", 707 opcodes[i]->comment); 708 709 lprintf (sim_log, "bits:"); 710 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 711 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits); 712 lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes, 713 "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s"); 714 715 store_opcode_bits (opcodes[i], 0, indirect); 716 } 717 718 dump_lines (&prefix_text, 0, 0); 719 720 emit_indirect (indirect, 0); 721 722 dump_lines (&suffix_text, 0, 0); 723 724 if (sim_log) 725 log_indirect (indirect, 0); 726 727 return errors; 728} 729