1 /* opc2c.c --- generate C simulator code from from .opc file 2 3 Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 Contributed by Red Hat, Inc. 6 7 This file is part of the GNU simulators. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <ctype.h> 26 #include <stdlib.h> 27 28 #include "safe-fgets.h" 29 30 static int errors = 0; 31 32 #define MAX_BYTES 10 33 34 typedef struct 35 { 36 int varyno:16; 37 int byte:8; 38 int shift:8; 39 } VaryRef; 40 41 typedef struct 42 { 43 char nbytes; 44 char dbytes; 45 char id[MAX_BYTES * 8 + 1]; 46 unsigned char var_start[MAX_BYTES * 8 + 1]; 47 struct 48 { 49 unsigned char decodable_mask; 50 unsigned char decodable_bits; 51 } b[MAX_BYTES]; 52 char *comment; 53 int lineno; 54 int nlines; 55 char **lines; 56 struct Indirect *last_ind; 57 int semantics_label; 58 int nvaries; 59 VaryRef *vary; 60 } opcode; 61 62 int n_opcodes; 63 opcode **opcodes; 64 opcode *op; 65 66 typedef struct 67 { 68 char *name; 69 int nlen; 70 unsigned char mask; 71 int n_patterns; 72 unsigned char *patterns; 73 } Vary; 74 75 Vary **vary = 0; 76 int n_varies = 0; 77 78 unsigned char cur_bits[MAX_BYTES + 1]; 79 80 char *orig_filename; 81 82 FILE *sim_log = 0; 83 #define lprintf if (sim_log) fprintf 84 85 opcode prefix_text, suffix_text; 86 87 typedef enum 88 { 89 T_unused, 90 T_op, 91 T_indirect, 92 T_done 93 } OpType; 94 95 typedef struct Indirect 96 { 97 OpType type; 98 union 99 { 100 struct Indirect *ind; 101 opcode *op; 102 } u; 103 } Indirect; 104 105 Indirect indirect[256]; 106 107 static int 108 next_varybits (int bits, opcode * op, int byte) 109 { 110 int mask = op->b[byte].decodable_mask; 111 int i; 112 113 for (i = 0; i < 8; i++) 114 if (!(mask & (1 << i))) 115 { 116 if (bits & (1 << i)) 117 { 118 bits &= ~(1 << i); 119 } 120 else 121 { 122 bits |= (1 << i); 123 return bits; 124 } 125 } 126 return 0; 127 } 128 129 static int 130 valid_varybits (int bits, opcode * op, int byte) 131 { 132 if (op->nvaries) 133 { 134 int vn; 135 for (vn = 0; vn < op->nvaries; vn++) 136 { 137 int found = 0; 138 int i; 139 int ob; 140 141 if (byte != op->vary[vn].byte) 142 continue; 143 Vary *v = vary[op->vary[vn].varyno]; 144 ob = (bits >> op->vary[vn].shift) & v->mask; 145 lprintf (sim_log, "varybits: vary %s ob %x\n", v->name, ob); 146 147 for (i = 0; i < v->n_patterns; i++) 148 if (ob == v->patterns[i]) 149 { 150 lprintf (sim_log, " found at %d\n", i); 151 found = 1; 152 break; 153 } 154 if (!found) 155 return 0; 156 } 157 } 158 return 1; 159 } 160 161 char * 162 prmb (int mask, int bits) 163 { 164 static char buf[8][30]; 165 static int bn = 0; 166 char *bp; 167 168 bn = (bn + 1) % 8; 169 bp = buf[bn]; 170 int i; 171 for (i = 0; i < 8; i++) 172 { 173 int bit = 0x80 >> i; 174 if (!(mask & bit)) 175 *bp++ = '-'; 176 else if (bits & bit) 177 *bp++ = '1'; 178 else 179 *bp++ = '0'; 180 if (i % 4 == 3) 181 *bp++ = ' '; 182 } 183 *--bp = 0; 184 return buf[bn]; 185 } 186 187 static int 188 op_cmp (const void *va, const void *vb) 189 { 190 const opcode *a = *(const opcode **) va; 191 const opcode *b = *(const opcode **) vb; 192 193 if (a->nbytes != b->nbytes) 194 return a->nbytes - b->nbytes; 195 196 return strcmp (a->id, b->id); 197 } 198 199 void 200 dump_lines (opcode * op, int level, Indirect * ind) 201 { 202 char *varnames[40]; 203 int i, vn = 0; 204 205 if (op->semantics_label) 206 { 207 printf ("%*sgoto op_semantics_%d;\n", level, "", op->semantics_label); 208 return; 209 } 210 211 if (ind != op->last_ind) 212 { 213 static int labelno = 0; 214 labelno++; 215 printf ("%*sop_semantics_%d:\n", level, "", labelno); 216 op->semantics_label = labelno; 217 } 218 219 if (op->comment) 220 { 221 level += 2; 222 printf ("%*s{\n", level, ""); 223 printf ("%*s %s\n", level, "", op->comment); 224 } 225 226 for (i = 0; i < op->nbytes * 8;) 227 { 228 if (isalpha (op->id[i])) 229 { 230 int byte = i >> 3; 231 int mask = 0; 232 int shift = 0; 233 char name[33]; 234 char *np = name; 235 while (op->id[i] && isalpha (op->id[i])) 236 { 237 mask = (mask << 1) | 1; 238 shift = 7 - (i & 7); 239 *np++ = op->id[i++]; 240 if (op->var_start[i]) 241 break; 242 } 243 *np = 0; 244 varnames[vn++] = strdup (name); 245 printf ("#line %d \"%s\"\n", op->lineno, orig_filename); 246 if (mask & ~0xff) 247 { 248 fprintf (stderr, "Error: variable %s spans bytes: %s\n", 249 name, op->comment); 250 errors++; 251 } 252 else if (shift && (mask != 0xff)) 253 printf ("%*s int %s AU = (op[%d] >> %d) & 0x%02x;\n", 254 level, "", name, byte, shift, mask); 255 else if (mask != 0xff) 256 printf ("%*s int %s AU = op[%d] & 0x%02x;\n", 257 level, "", name, byte, mask); 258 else 259 printf ("%*s int %s AU = op[%d];\n", level, "", name, 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 *line; 508 FILE *in; 509 int lineno = 0; 510 int i; 511 VaryRef *vlist; 512 513 if (argc > 2 && strcmp (argv[1], "-l") == 0) 514 { 515 sim_log = fopen (argv[2], "w"); 516 fprintf (stderr, "sim_log: %s\n", argv[2]); 517 argc -= 2; 518 argv += 2; 519 } 520 521 if (argc < 2) 522 { 523 fprintf (stderr, "usage: opc2c infile.opc > outfile.opc\n"); 524 exit (1); 525 } 526 527 orig_filename = argv[1]; 528 in = fopen (argv[1], "r"); 529 if (!in) 530 { 531 fprintf (stderr, "Unable to open file %s for reading\n", argv[1]); 532 perror ("The error was"); 533 exit (1); 534 } 535 536 n_opcodes = 0; 537 opcodes = (opcode **) malloc (sizeof (opcode *)); 538 op = &prefix_text; 539 op->lineno = 1; 540 while ((line = safe_fgets (in)) != 0) 541 { 542 lineno++; 543 if (strncmp (line, " /** ", 6) == 0 544 && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0)) 545 line += 2; 546 if (line[0] == '/' && line[1] == '*' && line[2] == '*') 547 { 548 if (strncmp (line, "/** */", 6) == 0) 549 { 550 op = &suffix_text; 551 op->lineno = lineno; 552 } 553 else if (strncmp (line, "/** VARY ", 9) == 0) 554 process_vary (line + 9); 555 else 556 { 557 char *lp; 558 int i, bit, byte; 559 int var_start = 1; 560 561 n_opcodes++; 562 opcodes = 563 (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *)); 564 op = (opcode *) malloc (sizeof (opcode)); 565 opcodes[n_opcodes - 1] = op; 566 567 op->nbytes = op->dbytes = 0; 568 memset (op->id, 0, sizeof (op->id)); 569 memset (op->var_start, 0, sizeof (op->var_start)); 570 for (i = 0; i < MAX_BYTES; i++) 571 { 572 op->b[i].decodable_mask = 0; 573 op->b[i].decodable_bits = 0; 574 } 575 op->comment = strdup (line); 576 op->comment[strlen (op->comment) - 1] = 0; 577 while (op->comment[0] && isspace (op->comment[0])) 578 op->comment++; 579 op->lineno = lineno; 580 op->nlines = 0; 581 op->lines = 0; 582 op->last_ind = 0; 583 op->semantics_label = 0; 584 op->nvaries = 0; 585 op->vary = 0; 586 587 i = 0; 588 for (lp = line + 4; *lp; lp++) 589 { 590 bit = 7 - (i & 7); 591 byte = i >> 3; 592 593 if (strncmp (lp, "*/", 2) == 0) 594 break; 595 else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t')) 596 break; 597 else if (*lp == ' ') 598 var_start = 1; 599 else 600 { 601 if (*lp == '0' || *lp == '1') 602 { 603 op->b[byte].decodable_mask |= 1 << bit; 604 var_start = 1; 605 if (op->dbytes < byte + 1) 606 op->dbytes = byte + 1; 607 } 608 else if (var_start) 609 { 610 op->var_start[i] = 1; 611 var_start = 0; 612 } 613 if (*lp == '1') 614 op->b[byte].decodable_bits |= 1 << bit; 615 616 op->nbytes = byte + 1; 617 op->id[i++] = *lp; 618 } 619 } 620 } 621 } 622 else 623 { 624 op->nlines++; 625 if (op->lines) 626 op->lines = 627 (char **) realloc (op->lines, op->nlines * sizeof (char *)); 628 else 629 op->lines = (char **) malloc (op->nlines * sizeof (char *)); 630 op->lines[op->nlines - 1] = strdup (line); 631 } 632 } 633 634 { 635 int i, j; 636 for (i = 0; i < n_varies; i++) 637 { 638 Vary *v = vary[i]; 639 lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen); 640 for (j = 0; j < v->n_patterns; j++) 641 lprintf (sim_log, " P %02x\n", v->patterns[j]); 642 } 643 } 644 645 for (i = n_opcodes - 2; i >= 0; i--) 646 { 647 if (opcodes[i]->nlines == 0) 648 { 649 opcodes[i]->nlines = opcodes[i + 1]->nlines; 650 opcodes[i]->lines = opcodes[i + 1]->lines; 651 } 652 } 653 654 for (i = 0; i < 256; i++) 655 indirect[i].type = T_unused; 656 657 qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp); 658 659 vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef)); 660 661 for (i = 0; i < n_opcodes; i++) 662 { 663 int j, b, v; 664 665 for (j = 0; j < opcodes[i]->nbytes; j++) 666 lprintf (sim_log, "%s ", 667 prmb (opcodes[i]->b[j].decodable_mask, 668 opcodes[i]->b[j].decodable_bits)); 669 lprintf (sim_log, " %s\n", opcodes[i]->comment); 670 671 for (j = 0; j < opcodes[i]->nbytes; j++) 672 { 673 for (b = 0; b < 8; b++) 674 if (isalpha (opcodes[i]->id[j * 8 + b])) 675 for (v = 0; v < n_varies; v++) 676 if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name)) 677 { 678 int nv = opcodes[i]->nvaries++; 679 if (nv) 680 opcodes[i]->vary = 681 (VaryRef *) realloc (opcodes[i]->vary, 682 (nv + 1) * sizeof (VaryRef)); 683 else 684 opcodes[i]->vary = 685 (VaryRef *) malloc ((nv + 1) * sizeof (VaryRef)); 686 687 opcodes[i]->vary[nv].varyno = v; 688 opcodes[i]->vary[nv].byte = j; 689 opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen; 690 lprintf (sim_log, "[vary %s shift %d]\n", 691 vary[v]->name, opcodes[i]->vary[nv].shift); 692 } 693 694 } 695 } 696 697 for (i = 0; i < n_opcodes; i++) 698 { 699 int i2; 700 int bytes = opcodes[i]->dbytes; 701 702 lprintf (sim_log, "\nmask:"); 703 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 704 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask); 705 lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "", 706 opcodes[i]->comment); 707 708 lprintf (sim_log, "bits:"); 709 for (i2 = 0; i2 < opcodes[i]->nbytes; i2++) 710 lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits); 711 lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes, 712 "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s"); 713 714 store_opcode_bits (opcodes[i], 0, indirect); 715 } 716 717 dump_lines (&prefix_text, 0, 0); 718 719 emit_indirect (indirect, 0); 720 721 dump_lines (&suffix_text, 0, 0); 722 723 if (sim_log) 724 log_indirect (indirect, 0); 725 726 return errors; 727 } 728