1 %{ 2 /* Parser for i386 CPU description. 3 Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 2004. 5 6 Red Hat elfutils is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by the 8 Free Software Foundation; version 2 of the License. 9 10 Red Hat elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with Red Hat elfutils; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18 19 Red Hat elfutils is an included package of the Open Invention Network. 20 An included package of the Open Invention Network is a package for which 21 Open Invention Network licensees cross-license their patents. No patent 22 license is granted, either expressly or impliedly, by designation as an 23 included package. Should you wish to participate in the Open Invention 24 Network licensing program, please visit www.openinventionnetwork.com 25 <http://www.openinventionnetwork.com>. */ 26 27 #ifdef HAVE_CONFIG_H 28 # include <config.h> 29 #endif 30 31 #include <assert.h> 32 #include <ctype.h> 33 #include <errno.h> 34 #include <error.h> 35 #include <inttypes.h> 36 #include <libintl.h> 37 #include <math.h> 38 #include <obstack.h> 39 #include <search.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <sys/param.h> 44 45 #include <system.h> 46 47 #define obstack_chunk_alloc xmalloc 48 #define obstack_chunk_free free 49 50 /* The error handler. */ 51 static void yyerror (const char *s); 52 53 extern int yylex (void); 54 extern int i386_lineno; 55 extern char *infname; 56 57 58 struct known_bitfield 59 { 60 char *name; 61 unsigned long int bits; 62 int tmp; 63 }; 64 65 66 struct bitvalue 67 { 68 enum bittype { zeroone, field, failure } type; 69 union 70 { 71 unsigned int value; 72 struct known_bitfield *field; 73 }; 74 struct bitvalue *next; 75 }; 76 77 78 struct argname 79 { 80 enum nametype { string, nfield } type; 81 union 82 { 83 char *str; 84 struct known_bitfield *field; 85 }; 86 struct argname *next; 87 }; 88 89 90 struct argument 91 { 92 struct argname *name; 93 struct argument *next; 94 }; 95 96 97 struct instruction 98 { 99 /* The byte encoding. */ 100 struct bitvalue *bytes; 101 102 /* Prefix possible. */ 103 int repe; 104 int rep; 105 106 /* Mnemonic. */ 107 char *mnemonic; 108 109 /* Suffix. */ 110 enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn, 111 suffix_w1, suffix_W1, suffix_D } suffix; 112 113 /* Flag set if modr/m is used. */ 114 int modrm; 115 116 /* Operands. */ 117 struct operand 118 { 119 char *fct; 120 char *str; 121 int off1; 122 int off2; 123 int off3; 124 } operands[3]; 125 126 struct instruction *next; 127 }; 128 129 130 struct synonym 131 { 132 char *from; 133 char *to; 134 }; 135 136 137 struct suffix 138 { 139 char *name; 140 int idx; 141 }; 142 143 144 struct argstring 145 { 146 char *str; 147 int idx; 148 int off; 149 }; 150 151 152 static struct known_bitfield ax_reg = 153 { 154 .name = "ax", .bits = 0, .tmp = 0 155 }; 156 157 static struct known_bitfield dx_reg = 158 { 159 .name = "dx", .bits = 0, .tmp = 0 160 }; 161 162 static struct known_bitfield di_reg = 163 { 164 .name = "es_di", .bits = 0, .tmp = 0 165 }; 166 167 static struct known_bitfield si_reg = 168 { 169 .name = "ds_si", .bits = 0, .tmp = 0 170 }; 171 172 static struct known_bitfield bx_reg = 173 { 174 .name = "ds_bx", .bits = 0, .tmp = 0 175 }; 176 177 178 static int bitfield_compare (const void *p1, const void *p2); 179 static void new_bitfield (char *name, unsigned long int num); 180 static void check_bits (struct bitvalue *value); 181 static int check_duplicates (struct bitvalue *val); 182 static int check_argsdef (struct bitvalue *bitval, struct argument *args); 183 static int check_bitsused (struct bitvalue *bitval, 184 struct known_bitfield *suffix, 185 struct argument *args); 186 static struct argname *combine (struct argname *name); 187 static void fillin_arg (struct bitvalue *bytes, struct argname *name, 188 struct instruction *instr, int n); 189 static void find_numbers (void); 190 static int compare_syn (const void *p1, const void *p2); 191 static int compare_suf (const void *p1, const void *p2); 192 static void instrtable_out (void); 193 #if 0 194 static void create_mnemonic_table (void); 195 #endif 196 197 static void *bitfields; 198 static struct instruction *instructions; 199 static size_t ninstructions; 200 static void *synonyms; 201 static void *suffixes; 202 static int nsuffixes; 203 static void *mnemonics; 204 size_t nmnemonics; 205 extern FILE *outfile; 206 207 /* Number of bits used mnemonics. */ 208 #if 0 209 static size_t best_mnemonic_bits; 210 #endif 211 %} 212 213 %union { 214 unsigned long int num; 215 char *str; 216 char ch; 217 struct known_bitfield *field; 218 struct bitvalue *bit; 219 struct argname *name; 220 struct argument *arg; 221 } 222 223 %token kMASK 224 %token kPREFIX 225 %token kSUFFIX 226 %token kSYNONYM 227 %token <str> kID 228 %token <num> kNUMBER 229 %token kPERCPERC 230 %token <str> kBITFIELD 231 %token <ch> kCHAR 232 %token kSPACE 233 234 %type <bit> bit byte bytes 235 %type <field> bitfieldopt 236 %type <name> argcomp arg 237 %type <arg> args optargs 238 239 %defines 240 241 %% 242 243 spec: masks kPERCPERC '\n' instrs 244 { 245 if (error_message_count != 0) 246 error (EXIT_FAILURE, 0, 247 "terminated due to previous error"); 248 249 instrtable_out (); 250 } 251 ; 252 253 masks: masks '\n' mask 254 | mask 255 ; 256 257 mask: kMASK kBITFIELD kNUMBER 258 { new_bitfield ($2, $3); } 259 | kPREFIX kBITFIELD 260 { new_bitfield ($2, -1); } 261 | kSUFFIX kBITFIELD 262 { new_bitfield ($2, -2); } 263 | kSYNONYM kBITFIELD kBITFIELD 264 { 265 struct synonym *newp = xmalloc (sizeof (*newp)); 266 newp->from = $2; 267 newp->to = $3; 268 if (tfind (newp, &synonyms, compare_syn) != NULL) 269 error (0, 0, 270 "%d: duplicate definition for synonym '%s'", 271 i386_lineno, $2); 272 else if (tsearch ( newp, &synonyms, compare_syn) == NULL) 273 error (EXIT_FAILURE, 0, "tsearch"); 274 } 275 | 276 ; 277 278 instrs: instrs '\n' instr 279 | instr 280 ; 281 282 instr: bytes ':' bitfieldopt kID bitfieldopt optargs 283 { 284 if ($3 != NULL && strcmp ($3->name, "RE") != 0 285 && strcmp ($3->name, "R") != 0) 286 { 287 error (0, 0, "%d: only 'R' and 'RE' prefix allowed", 288 i386_lineno - 1); 289 } 290 if (check_duplicates ($1) == 0 291 && check_argsdef ($1, $6) == 0 292 && check_bitsused ($1, $5, $6) == 0) 293 { 294 struct instruction *newp = xcalloc (sizeof (*newp), 295 1); 296 if ($3 != NULL) 297 { 298 if (strcmp ($3->name, "RE") == 0) 299 newp->repe = 1; 300 else if (strcmp ($3->name, "R") == 0) 301 newp->rep = 1; 302 } 303 304 newp->bytes = $1; 305 newp->mnemonic = $4; 306 if (newp->mnemonic != (void *) -1l 307 && tfind ($4, &mnemonics, 308 (comparison_fn_t) strcmp) == NULL) 309 { 310 if (tsearch ($4, &mnemonics, 311 (comparison_fn_t) strcmp) == NULL) 312 error (EXIT_FAILURE, errno, "tsearch"); 313 ++nmnemonics; 314 } 315 316 if ($5 != NULL) 317 { 318 if (strcmp ($5->name, "w") == 0) 319 newp->suffix = suffix_w; 320 else if (strcmp ($5->name, "w0") == 0) 321 newp->suffix = suffix_w0; 322 else if (strcmp ($5->name, "tttn") == 0) 323 newp->suffix = suffix_tttn; 324 else if (strcmp ($5->name, "w1") == 0) 325 newp->suffix = suffix_w1; 326 else if (strcmp ($5->name, "W") == 0) 327 newp->suffix = suffix_W; 328 else if (strcmp ($5->name, "W1") == 0) 329 newp->suffix = suffix_W1; 330 else if (strcmp ($5->name, "D") == 0) 331 newp->suffix = suffix_D; 332 else 333 error (EXIT_FAILURE, 0, 334 "%s: %d: unknown suffix '%s'", 335 infname, i386_lineno - 1, $5->name); 336 337 struct suffix search = { .name = $5->name }; 338 if (tfind (&search, &suffixes, compare_suf) 339 == NULL) 340 { 341 struct suffix *ns = xmalloc (sizeof (*ns)); 342 ns->name = $5->name; 343 ns->idx = ++nsuffixes; 344 if (tsearch (ns, &suffixes, compare_suf) 345 == NULL) 346 error (EXIT_FAILURE, errno, "tsearch"); 347 } 348 } 349 350 struct argument *args = $6; 351 int n = 0; 352 while (args != NULL) 353 { 354 fillin_arg ($1, args->name, newp, n); 355 356 args = args->next; 357 ++n; 358 } 359 360 newp->next = instructions; 361 instructions = newp; 362 ++ninstructions; 363 } 364 } 365 | 366 ; 367 368 bitfieldopt: kBITFIELD 369 { 370 struct known_bitfield search; 371 search.name = $1; 372 struct known_bitfield **res; 373 res = tfind (&search, &bitfields, bitfield_compare); 374 if (res == NULL) 375 { 376 error (0, 0, "%d: unknown bitfield '%s'", 377 i386_lineno, search.name); 378 $$ = NULL; 379 } 380 else 381 $$ = *res; 382 } 383 | 384 { $$ = NULL; } 385 ; 386 387 bytes: bytes ',' byte 388 { 389 check_bits ($3); 390 391 struct bitvalue *runp = $1; 392 while (runp->next != NULL) 393 runp = runp->next; 394 runp->next = $3; 395 $$ = $1; 396 } 397 | byte 398 { 399 check_bits ($1); 400 $$ = $1; 401 } 402 ; 403 404 byte: byte bit 405 { 406 struct bitvalue *runp = $1; 407 while (runp->next != NULL) 408 runp = runp->next; 409 runp->next = $2; 410 $$ = $1; 411 } 412 | bit 413 { $$ = $1; } 414 ; 415 416 bit: '0' 417 { 418 $$ = xmalloc (sizeof (struct bitvalue)); 419 $$->type = zeroone; 420 $$->value = 0; 421 $$->next = NULL; 422 } 423 | '1' 424 { 425 $$ = xmalloc (sizeof (struct bitvalue)); 426 $$->type = zeroone; 427 $$->value = 1; 428 $$->next = NULL; 429 } 430 | kBITFIELD 431 { 432 $$ = xmalloc (sizeof (struct bitvalue)); 433 struct known_bitfield search; 434 search.name = $1; 435 struct known_bitfield **res; 436 res = tfind (&search, &bitfields, bitfield_compare); 437 if (res == NULL) 438 { 439 error (0, 0, "%d: unknown bitfield '%s'", 440 i386_lineno, search.name); 441 $$->type = failure; 442 } 443 else 444 { 445 $$->type = field; 446 $$->field = *res; 447 } 448 $$->next = NULL; 449 } 450 ; 451 452 optargs: kSPACE args 453 { $$ = $2; } 454 | 455 { $$ = NULL; } 456 ; 457 458 args: args ',' arg 459 { 460 struct argument *runp = $1; 461 while (runp->next != NULL) 462 runp = runp->next; 463 runp->next = xmalloc (sizeof (struct argument)); 464 runp->next->name = combine ($3); 465 runp->next->next = NULL; 466 $$ = $1; 467 } 468 | arg 469 { 470 $$ = xmalloc (sizeof (struct argument)); 471 $$->name = combine ($1); 472 $$->next = NULL; 473 } 474 ; 475 476 arg: arg argcomp 477 { 478 struct argname *runp = $1; 479 while (runp->next != NULL) 480 runp = runp->next; 481 runp->next = $2; 482 $$ = $1; 483 } 484 | argcomp 485 { $$ = $1; } 486 ; 487 argcomp: kBITFIELD 488 { 489 $$ = xmalloc (sizeof (struct argname)); 490 $$->type = nfield; 491 $$->next = NULL; 492 493 struct known_bitfield search; 494 search.name = $1; 495 struct known_bitfield **res; 496 res = tfind (&search, &bitfields, bitfield_compare); 497 if (res == NULL) 498 { 499 if (strcmp ($1, "ax") == 0) 500 $$->field = &ax_reg; 501 else if (strcmp ($1, "dx") == 0) 502 $$->field = &dx_reg; 503 else if (strcmp ($1, "es_di") == 0) 504 $$->field = &di_reg; 505 else if (strcmp ($1, "ds_si") == 0) 506 $$->field = &si_reg; 507 else if (strcmp ($1, "ds_bx") == 0) 508 $$->field = &bx_reg; 509 else 510 { 511 error (0, 0, "%d: unknown bitfield '%s'", 512 i386_lineno, search.name); 513 $$->field = NULL; 514 } 515 } 516 else 517 $$->field = *res; 518 } 519 | kCHAR 520 { 521 $$ = xmalloc (sizeof (struct argname)); 522 $$->type = string; 523 $$->next = NULL; 524 $$->str = xmalloc (2); 525 $$->str[0] = $1; 526 $$->str[1] = '\0'; 527 } 528 | kID 529 { 530 $$ = xmalloc (sizeof (struct argname)); 531 $$->type = string; 532 $$->next = NULL; 533 $$->str = $1; 534 } 535 | ':' 536 { 537 $$ = xmalloc (sizeof (struct argname)); 538 $$->type = string; 539 $$->next = NULL; 540 $$->str = xmalloc (2); 541 $$->str[0] = ':'; 542 $$->str[1] = '\0'; 543 } 544 ; 545 546 %% 547 548 static void 549 yyerror (const char *s) 550 { 551 error (0, 0, gettext ("while reading i386 CPU description: %s at line %d"), 552 gettext (s), i386_lineno); 553 } 554 555 556 static int 557 bitfield_compare (const void *p1, const void *p2) 558 { 559 struct known_bitfield *f1 = (struct known_bitfield *) p1; 560 struct known_bitfield *f2 = (struct known_bitfield *) p2; 561 562 return strcmp (f1->name, f2->name); 563 } 564 565 566 static void 567 new_bitfield (char *name, unsigned long int num) 568 { 569 struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield)); 570 newp->name = name; 571 newp->bits = num; 572 newp->tmp = 0; 573 574 if (tfind (newp, &bitfields, bitfield_compare) != NULL) 575 { 576 error (0, 0, "%d: duplicated definition of bitfield '%s'", 577 i386_lineno, name); 578 free (name); 579 return; 580 } 581 582 if (tsearch (newp, &bitfields, bitfield_compare) == NULL) 583 error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'", 584 i386_lineno, name); 585 } 586 587 588 /* Check that the number of bits is a multiple of 8. */ 589 static void 590 check_bits (struct bitvalue *val) 591 { 592 struct bitvalue *runp = val; 593 unsigned int total = 0; 594 595 while (runp != NULL) 596 { 597 if (runp->type == zeroone) 598 ++total; 599 else if (runp->field == NULL) 600 /* No sense doing anything, the field is not known. */ 601 return; 602 else 603 total += runp->field->bits; 604 605 runp = runp->next; 606 } 607 608 if (total % 8 != 0) 609 { 610 struct obstack os; 611 obstack_init (&os); 612 613 while (val != NULL) 614 { 615 if (val->type == zeroone) 616 obstack_printf (&os, "%u", val->value); 617 else 618 obstack_printf (&os, "{%s}", val->field->name); 619 val = val->next; 620 } 621 obstack_1grow (&os, '\0'); 622 623 error (0, 0, "%d: field '%s' not a multiple of 8 bits in size", 624 i386_lineno, (char *) obstack_finish (&os)); 625 626 obstack_free (&os, NULL); 627 } 628 } 629 630 631 static int 632 check_duplicates (struct bitvalue *val) 633 { 634 static int testcnt; 635 ++testcnt; 636 637 int result = 0; 638 while (val != NULL) 639 { 640 if (val->type == field && val->field != NULL) 641 { 642 if (val->field->tmp == testcnt) 643 { 644 error (0, 0, "%d: bitfield '%s' used more than once", 645 i386_lineno - 1, val->field->name); 646 result = 1; 647 } 648 val->field->tmp = testcnt; 649 } 650 651 val = val->next; 652 } 653 654 return result; 655 } 656 657 658 static int 659 check_argsdef (struct bitvalue *bitval, struct argument *args) 660 { 661 int result = 0; 662 663 while (args != NULL) 664 { 665 for (struct argname *name = args->name; name != NULL; name = name->next) 666 if (name->type == nfield && name->field != NULL 667 && name->field != &ax_reg && name->field != &dx_reg 668 && name->field != &di_reg && name->field != &si_reg 669 && name->field != &bx_reg) 670 { 671 struct bitvalue *runp = bitval; 672 673 while (runp != NULL) 674 if (runp->type == field && runp->field == name->field) 675 break; 676 else 677 runp = runp->next; 678 679 if (runp == NULL) 680 { 681 error (0, 0, "%d: unknown bitfield '%s' used in output format", 682 i386_lineno - 1, name->field->name); 683 result = 1; 684 } 685 } 686 687 args = args->next; 688 } 689 690 return result; 691 } 692 693 694 static int 695 check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix, 696 struct argument *args) 697 { 698 int result = 0; 699 700 while (bitval != NULL) 701 { 702 if (bitval->type == field && bitval->field != NULL 703 && bitval->field != suffix 704 /* {w} is handled special. */ 705 && strcmp (bitval->field->name, "w") != 0) 706 { 707 struct argument *runp; 708 for (runp = args; runp != NULL; runp = runp->next) 709 { 710 struct argname *name = runp->name; 711 712 while (name != NULL) 713 if (name->type == nfield && name->field == bitval->field) 714 break; 715 else 716 name = name->next; 717 718 if (name != NULL) 719 break; 720 } 721 722 #if 0 723 if (runp == NULL) 724 { 725 error (0, 0, "%d: bitfield '%s' not used", 726 i386_lineno - 1, bitval->field->name); 727 result = 1; 728 } 729 #endif 730 } 731 732 bitval = bitval->next; 733 } 734 735 return result; 736 } 737 738 739 static struct argname * 740 combine (struct argname *name) 741 { 742 struct argname *last_str = NULL; 743 for (struct argname *runp = name; runp != NULL; runp = runp->next) 744 { 745 if (runp->type == string) 746 { 747 if (last_str == NULL) 748 last_str = runp; 749 else 750 { 751 last_str->str = xrealloc (last_str->str, 752 strlen (last_str->str) 753 + strlen (runp->str) + 1); 754 strcat (last_str->str, runp->str); 755 last_str->next = runp->next; 756 } 757 } 758 else 759 last_str = NULL; 760 } 761 return name; 762 } 763 764 765 #define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str)) 766 767 768 static void 769 fillin_arg (struct bitvalue *bytes, struct argname *name, 770 struct instruction *instr, int n) 771 { 772 static struct obstack ob; 773 static int initialized; 774 if (! initialized) 775 { 776 initialized = 1; 777 obstack_init (&ob); 778 } 779 780 struct argname *runp = name; 781 int cnt = 0; 782 while (runp != NULL) 783 { 784 /* We ignore strings in the function name. */ 785 if (runp->type == string) 786 { 787 if (instr->operands[n].str != NULL) 788 error (EXIT_FAILURE, 0, 789 "%d: cannot have more than one string parameter", 790 i386_lineno - 1); 791 792 instr->operands[n].str = runp->str; 793 } 794 else 795 { 796 assert (runp->type == nfield); 797 798 /* Construct the function name. */ 799 if (cnt++ > 0) 800 obstack_1grow (&ob, '$'); 801 802 if (runp->field == NULL) 803 /* Add some string which contains invalid characters. */ 804 obstack_grow_str (&ob, "!!!INVALID!!!"); 805 else 806 { 807 char *fieldname = runp->field->name; 808 809 struct synonym search = { .from = fieldname }; 810 811 struct synonym **res = tfind (&search, &synonyms, compare_syn); 812 if (res != NULL) 813 fieldname = (*res)->to; 814 815 obstack_grow_str (&ob, fieldname); 816 } 817 818 /* Now compute the bit offset of the field. */ 819 struct bitvalue *b = bytes; 820 int bitoff = 0; 821 if (runp->field != NULL) 822 while (b != NULL) 823 { 824 if (b->type == field && b->field != NULL) 825 { 826 if (strcmp (b->field->name, runp->field->name) == 0) 827 break; 828 bitoff += b->field->bits; 829 } 830 else 831 ++bitoff; 832 833 b = b->next; 834 } 835 if (instr->operands[n].off1 == 0) 836 instr->operands[n].off1 = bitoff; 837 else if (instr->operands[n].off2 == 0) 838 instr->operands[n].off2 = bitoff; 839 else if (instr->operands[n].off3 == 0) 840 instr->operands[n].off3 = bitoff; 841 else 842 error (EXIT_FAILURE, 0, 843 "%d: cannot have more than three fields in parameter", 844 i386_lineno - 1); 845 846 if (runp->field != NULL 847 && strncasecmp (runp->field->name, "mod", 3) == 0) 848 instr->modrm = 1; 849 } 850 851 runp = runp->next; 852 } 853 if (obstack_object_size (&ob) == 0) 854 obstack_grow_str (&ob, "string"); 855 obstack_1grow (&ob, '\0'); 856 char *fct = obstack_finish (&ob); 857 858 instr->operands[n].fct = fct; 859 } 860 861 862 #if 0 863 static void 864 nameout (const void *nodep, VISIT value, int level) 865 { 866 if (value == leaf || value == postorder) 867 printf (" %s\n", *(const char **) nodep); 868 } 869 #endif 870 871 872 static int 873 compare_argstring (const void *p1, const void *p2) 874 { 875 const struct argstring *a1 = (const struct argstring *) p1; 876 const struct argstring *a2 = (const struct argstring *) p2; 877 878 return strcmp (a1->str, a2->str); 879 } 880 881 882 static int maxoff[3][3]; 883 static int minoff[3][3] = { { 1000, 1000, 1000 }, 884 { 1000, 1000, 1000 }, 885 { 1000, 1000, 1000 } }; 886 static int nbitoff[3][3]; 887 static void *fct_names[3]; 888 static int nbitfct[3]; 889 static int nbitsuf; 890 static void *strs[3]; 891 static int nbitstr[3]; 892 static int total_bits = 2; // Already counted the rep/repe bits. 893 894 static void 895 find_numbers (void) 896 { 897 int nfct_names[3] = { 0, 0, 0 }; 898 int nstrs[3] = { 0, 0, 0 }; 899 900 /* We reverse the order of the instruction list while processing it. 901 Later phases need it in the order in which the input file has 902 them. */ 903 struct instruction *reversed = NULL; 904 905 struct instruction *runp = instructions; 906 while (runp != NULL) 907 { 908 for (int i = 0; i < 3; ++i) 909 if (runp->operands[i].fct != NULL) 910 { 911 struct argstring search = { .str = runp->operands[i].fct }; 912 if (tfind (&search, &fct_names[i], compare_argstring) == NULL) 913 { 914 struct argstring *newp = xmalloc (sizeof (*newp)); 915 newp->str = runp->operands[i].fct; 916 newp->idx = 0; 917 if (tsearch (newp, &fct_names[i], compare_argstring) == NULL) 918 error (EXIT_FAILURE, errno, "tsearch"); 919 ++nfct_names[i]; 920 } 921 922 if (runp->operands[i].str != NULL) 923 { 924 search.str = runp->operands[i].str; 925 if (tfind (&search, &strs[i], compare_argstring) == NULL) 926 { 927 struct argstring *newp = xmalloc (sizeof (*newp)); 928 newp->str = runp->operands[i].str; 929 newp->idx = 0; 930 if (tsearch (newp, &strs[i], compare_argstring) == NULL) 931 error (EXIT_FAILURE, errno, "tsearch"); 932 ++nstrs[i]; 933 } 934 } 935 936 maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1); 937 maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2); 938 maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3); 939 940 if (runp->operands[i].off1 > 0) 941 minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1); 942 if (runp->operands[i].off2 > 0) 943 minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2); 944 if (runp->operands[i].off3 > 0) 945 minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3); 946 } 947 948 struct instruction *old = runp; 949 runp = runp->next; 950 951 old->next = reversed; 952 reversed = old; 953 } 954 instructions = reversed; 955 956 int d; 957 int c; 958 for (int i = 0; i < 3; ++i) 959 { 960 // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]); 961 // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]); 962 963 if (minoff[i][0] == 1000) 964 nbitoff[i][0] = 0; 965 else 966 { 967 nbitoff[i][0] = 1; 968 d = maxoff[i][0] - minoff[i][0]; 969 c = 1; 970 while (c < d) 971 { 972 ++nbitoff[i][0]; 973 c *= 2; 974 } 975 total_bits += nbitoff[i][0]; 976 } 977 978 if (minoff[i][1] == 1000) 979 nbitoff[i][1] = 0; 980 else 981 { 982 nbitoff[i][1] = 1; 983 d = maxoff[i][1] - minoff[i][1]; 984 c = 1; 985 while (c < d) 986 { 987 ++nbitoff[i][1]; 988 c *= 2; 989 } 990 total_bits += nbitoff[i][1]; 991 } 992 993 if (minoff[i][2] == 1000) 994 nbitoff[i][2] = 0; 995 else 996 { 997 nbitoff[i][2] = 1; 998 d = maxoff[i][2] - minoff[i][2]; 999 c = 1; 1000 while (c < d) 1001 { 1002 ++nbitoff[i][2]; 1003 c *= 2; 1004 } 1005 total_bits += nbitoff[i][2]; 1006 } 1007 // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]); 1008 1009 nbitfct[i] = 1; 1010 d = nfct_names[i]; 1011 c = 1; 1012 while (c < d) 1013 { 1014 ++nbitfct[i]; 1015 c *= 2; 1016 } 1017 total_bits += nbitfct[i]; 1018 // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]); 1019 1020 if (nstrs[i] != 0) 1021 { 1022 nbitstr[i] = 1; 1023 d = nstrs[i]; 1024 c = 1; 1025 while (c < d) 1026 { 1027 ++nbitstr[i]; 1028 c *= 2; 1029 } 1030 total_bits += nbitstr[i]; 1031 } 1032 1033 // twalk (fct_names[i], nameout); 1034 } 1035 1036 nbitsuf = 0; 1037 d = nsuffixes; 1038 c = 1; 1039 while (c < d) 1040 { 1041 ++nbitsuf; 1042 c *= 2; 1043 } 1044 total_bits += nbitsuf; 1045 // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf); 1046 } 1047 1048 1049 static int 1050 compare_syn (const void *p1, const void *p2) 1051 { 1052 const struct synonym *s1 = (const struct synonym *) p1; 1053 const struct synonym *s2 = (const struct synonym *) p2; 1054 1055 return strcmp (s1->from, s2->from); 1056 } 1057 1058 1059 static int 1060 compare_suf (const void *p1, const void *p2) 1061 { 1062 const struct suffix *s1 = (const struct suffix *) p1; 1063 const struct suffix *s2 = (const struct suffix *) p2; 1064 1065 return strcmp (s1->name, s2->name); 1066 } 1067 1068 1069 static int count_op_str; 1070 static int off_op_str; 1071 static void 1072 print_op_str (const void *nodep, VISIT value, 1073 int level __attribute__ ((unused))) 1074 { 1075 if (value == leaf || value == postorder) 1076 { 1077 const char *str = (*(struct argstring **) nodep)->str; 1078 fprintf (outfile, "%s\n \"%s", 1079 count_op_str == 0 ? "" : "\\0\"", str); 1080 (*(struct argstring **) nodep)->idx = ++count_op_str; 1081 (*(struct argstring **) nodep)->off = off_op_str; 1082 off_op_str += strlen (str) + 1; 1083 } 1084 } 1085 1086 1087 static void 1088 print_op_str_idx (const void *nodep, VISIT value, 1089 int level __attribute__ ((unused))) 1090 { 1091 if (value == leaf || value == postorder) 1092 printf (" %d,\n", (*(struct argstring **) nodep)->off); 1093 } 1094 1095 1096 static void 1097 print_op_fct (const void *nodep, VISIT value, 1098 int level __attribute__ ((unused))) 1099 { 1100 if (value == leaf || value == postorder) 1101 { 1102 fprintf (outfile, " FCT_%s,\n", (*(struct argstring **) nodep)->str); 1103 (*(struct argstring **) nodep)->idx = ++count_op_str; 1104 } 1105 } 1106 1107 1108 #if NMNES < 2 1109 # error "bogus NMNES value" 1110 #endif 1111 1112 static void 1113 instrtable_out (void) 1114 { 1115 find_numbers (); 1116 1117 #if 0 1118 create_mnemonic_table (); 1119 1120 fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits); 1121 #else 1122 fprintf (outfile, "#define MNEMONIC_BITS %ld\n", 1123 lrint (ceil (log2 (NMNES)))); 1124 #endif 1125 fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf); 1126 for (int i = 0; i < 3; ++i) 1127 { 1128 fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]); 1129 if (nbitstr[i] != 0) 1130 fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]); 1131 fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]); 1132 fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]); 1133 if (nbitoff[i][1] != 0) 1134 { 1135 fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]); 1136 fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]); 1137 } 1138 if (nbitoff[i][2] != 0) 1139 { 1140 fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]); 1141 fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]); 1142 } 1143 } 1144 1145 fputs ("\n#include <i386_data.h>\n\n", outfile); 1146 1147 1148 #define APPEND(a, b) APPEND_ (a, b) 1149 #define APPEND_(a, b) a##b 1150 #define EMIT_SUFFIX(suf) \ 1151 fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf)) 1152 EMIT_SUFFIX (none); 1153 EMIT_SUFFIX (w); 1154 EMIT_SUFFIX (w0); 1155 EMIT_SUFFIX (W); 1156 EMIT_SUFFIX (tttn); 1157 EMIT_SUFFIX (D); 1158 EMIT_SUFFIX (w1); 1159 EMIT_SUFFIX (W1); 1160 1161 fputc_unlocked ('\n', outfile); 1162 1163 for (int i = 0; i < 3; ++i) 1164 { 1165 /* Functions. */ 1166 count_op_str = 0; 1167 fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n NULL,\n", 1168 i + 1); 1169 twalk (fct_names[i], print_op_fct); 1170 fputs ("};\n", outfile); 1171 1172 /* The operand strings. */ 1173 if (nbitstr[i] != 0) 1174 { 1175 count_op_str = 0; 1176 off_op_str = 0; 1177 fprintf (outfile, "static const char op%d_str[] =", i + 1); 1178 twalk (strs[i], print_op_str); 1179 fputs ("\";\n", outfile); 1180 1181 fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n", 1182 i + 1); 1183 twalk (strs[i], print_op_str_idx); 1184 fputs ("};\n", outfile); 1185 } 1186 } 1187 1188 1189 fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile); 1190 struct instruction *instr; 1191 for (instr = instructions; instr != NULL; instr = instr->next) 1192 { 1193 fputs (" {", outfile); 1194 if (instr->mnemonic == (void *) -1l) 1195 fputs (" .mnemonic = MNE_INVALID,", outfile); 1196 else 1197 fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic); 1198 fprintf (outfile, " .rep = %d,", instr->rep); 1199 fprintf (outfile, " .repe = %d,", instr->repe); 1200 fprintf (outfile, " .suffix = %d,", instr->suffix); 1201 fprintf (outfile, " .modrm = %d,", instr->modrm); 1202 1203 for (int i = 0; i < 3; ++i) 1204 { 1205 int idx = 0; 1206 if (instr->operands[i].fct != NULL) 1207 { 1208 struct argstring search = { .str = instr->operands[i].fct }; 1209 struct argstring **res = tfind (&search, &fct_names[i], 1210 compare_argstring); 1211 assert (res != NULL); 1212 idx = (*res)->idx; 1213 } 1214 fprintf (outfile, " .fct%d = %d,", i + 1, idx); 1215 1216 idx = 0; 1217 if (instr->operands[i].str != NULL) 1218 { 1219 struct argstring search = { .str = instr->operands[i].str }; 1220 struct argstring **res = tfind (&search, &strs[i], 1221 compare_argstring); 1222 assert (res != NULL); 1223 idx = (*res)->idx; 1224 } 1225 if (nbitstr[i] != 0) 1226 fprintf (outfile, " .str%d = %d,", i + 1, idx); 1227 1228 fprintf (outfile, " .off%d_1 = %d,", i + 1, 1229 MAX (0, instr->operands[i].off1 - minoff[i][0])); 1230 1231 if (nbitoff[i][1] != 0) 1232 fprintf (outfile, " .off%d_2 = %d,", i + 1, 1233 MAX (0, instr->operands[i].off2 - minoff[i][1])); 1234 1235 if (nbitoff[i][2] != 0) 1236 fprintf (outfile, " .off%d_3 = %d,", i + 1, 1237 MAX (0, instr->operands[i].off3 - minoff[i][2])); 1238 } 1239 1240 fputs (" },\n", outfile); 1241 } 1242 fputs ("};\n", outfile); 1243 1244 fputs ("static const uint8_t match_data[] =\n{\n", outfile); 1245 size_t cnt = 0; 1246 for (instr = instructions; instr != NULL; instr = instr->next, ++cnt) 1247 { 1248 /* First count the number of bytes. */ 1249 size_t totalbits = 0; 1250 size_t zerobits = 0; 1251 struct bitvalue *b = instr->bytes; 1252 while (b != NULL) 1253 { 1254 if (b->type == zeroone) 1255 { 1256 ++totalbits; 1257 zerobits = 0; 1258 } 1259 else 1260 { 1261 totalbits += b->field->bits; 1262 /* We must always count the mod/rm byte. */ 1263 if (strncasecmp (b->field->name, "mod", 3) == 0) 1264 zerobits = 0; 1265 else 1266 zerobits += b->field->bits; 1267 } 1268 b = b->next; 1269 } 1270 size_t nbytes = (totalbits - zerobits + 7) / 8; 1271 assert (nbytes > 0); 1272 1273 fprintf (outfile, " %#zx,", nbytes); 1274 1275 /* Now create the mask and byte values. */ 1276 uint8_t byte = 0; 1277 uint8_t mask = 0; 1278 int nbits = 0; 1279 b = instr->bytes; 1280 while (b != NULL) 1281 { 1282 if (b->type == zeroone) 1283 { 1284 byte = (byte << 1) | b->value; 1285 mask = (mask << 1) | 1; 1286 if (++nbits == 8) 1287 { 1288 fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte); 1289 byte = mask = nbits = 0; 1290 if (--nbytes == 0) 1291 break; 1292 } 1293 } 1294 else 1295 { 1296 unsigned long int remaining = b->field->bits; 1297 while (nbits + remaining > 8) 1298 { 1299 fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", 1300 mask << (8 - nbits), byte << (8 - nbits)); 1301 remaining = nbits + remaining - 8; 1302 byte = mask = nbits = 0; 1303 if (--nbytes == 0) 1304 break; 1305 } 1306 byte <<= remaining; 1307 mask <<= remaining; 1308 nbits += remaining; 1309 if (nbits == 8) 1310 { 1311 fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte); 1312 byte = mask = nbits = 0; 1313 if (--nbytes == 0) 1314 break; 1315 } 1316 } 1317 b = b->next; 1318 } 1319 1320 fputc_unlocked ('\n', outfile); 1321 } 1322 fputs ("};\n", outfile); 1323 } 1324 1325 1326 #if 0 1327 static size_t mnemonic_maxlen; 1328 static size_t mnemonic_minlen; 1329 static size_t 1330 which_chars (const char *str[], size_t nstr) 1331 { 1332 char used_char[256]; 1333 memset (used_char, '\0', sizeof (used_char)); 1334 mnemonic_maxlen = 0; 1335 mnemonic_minlen = 10000; 1336 for (size_t cnt = 0; cnt < nstr; ++cnt) 1337 { 1338 const unsigned char *cp = (const unsigned char *) str[cnt]; 1339 mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp)); 1340 mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp)); 1341 do 1342 used_char[*cp++] = 1; 1343 while (*cp != '\0'); 1344 } 1345 size_t nused_char = 0; 1346 for (size_t cnt = 0; cnt < 256; ++cnt) 1347 if (used_char[cnt] != 0) 1348 ++nused_char; 1349 return nused_char; 1350 } 1351 1352 1353 static const char **mnemonic_strs; 1354 static size_t nmnemonic_strs; 1355 static void 1356 add_mnemonics (const void *nodep, VISIT value, 1357 int level __attribute__ ((unused))) 1358 { 1359 if (value == leaf || value == postorder) 1360 mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep; 1361 } 1362 1363 1364 struct charfreq 1365 { 1366 char ch; 1367 int freq; 1368 }; 1369 static struct charfreq pfxfreq[256]; 1370 static struct charfreq sfxfreq[256]; 1371 1372 1373 static int 1374 compare_freq (const void *p1, const void *p2) 1375 { 1376 const struct charfreq *c1 = (const struct charfreq *) p1; 1377 const struct charfreq *c2 = (const struct charfreq *) p2; 1378 1379 if (c1->freq > c2->freq) 1380 return -1; 1381 if (c1->freq < c2->freq) 1382 return 1; 1383 return 0; 1384 } 1385 1386 1387 static size_t 1388 compute_pfxfreq (const char *str[], size_t nstr) 1389 { 1390 memset (pfxfreq, '\0', sizeof (pfxfreq)); 1391 1392 for (size_t i = 0; i < nstr; ++i) 1393 pfxfreq[i].ch = i; 1394 1395 for (size_t i = 0; i < nstr; ++i) 1396 ++pfxfreq[*((const unsigned char *) str[i])].freq; 1397 1398 qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq); 1399 1400 size_t n = 0; 1401 while (n < 256 && pfxfreq[n].freq != 0) 1402 ++n; 1403 return n; 1404 } 1405 1406 1407 struct strsnlen 1408 { 1409 const char *str; 1410 size_t len; 1411 }; 1412 1413 static size_t 1414 compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen) 1415 { 1416 memset (sfxfreq, '\0', sizeof (sfxfreq)); 1417 1418 for (size_t i = 0; i < nstr; ++i) 1419 sfxfreq[i].ch = i; 1420 1421 for (size_t i = 0; i < nstr; ++i) 1422 ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq; 1423 1424 qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq); 1425 1426 size_t n = 0; 1427 while (n < 256 && sfxfreq[n].freq != 0) 1428 ++n; 1429 return n; 1430 } 1431 1432 1433 static void 1434 create_mnemonic_table (void) 1435 { 1436 mnemonic_strs = xmalloc (nmnemonics * sizeof (char *)); 1437 1438 twalk (mnemonics, add_mnemonics); 1439 1440 (void) which_chars (mnemonic_strs, nmnemonic_strs); 1441 1442 size_t best_so_far = 100000000; 1443 char *best_prefix = NULL; 1444 char *best_suffix = NULL; 1445 char *best_table = NULL; 1446 size_t best_table_size = 0; 1447 size_t best_table_bits = 0; 1448 size_t best_prefix_bits = 0; 1449 1450 /* We can precompute the prefix characters. */ 1451 size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs); 1452 1453 /* Compute best size for string representation including explicit NUL. */ 1454 for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits) 1455 { 1456 char prefix[1 << pfxbits]; 1457 size_t i; 1458 for (i = 0; i < (1u << pfxbits) - 1; ++i) 1459 prefix[i] = pfxfreq[i].ch; 1460 prefix[i] = '\0'; 1461 1462 struct strsnlen strsnlen[nmnemonic_strs]; 1463 1464 for (i = 0; i < nmnemonic_strs; ++i) 1465 { 1466 if (strchr (prefix, *mnemonic_strs[i]) != NULL) 1467 strsnlen[i].str = mnemonic_strs[i] + 1; 1468 else 1469 strsnlen[i].str = mnemonic_strs[i]; 1470 strsnlen[i].len = strlen (strsnlen[i].str); 1471 } 1472 1473 /* With the prefixes gone, try to combine strings. */ 1474 size_t nstrsnlen = 1; 1475 for (i = 1; i < nmnemonic_strs; ++i) 1476 { 1477 size_t j; 1478 for (j = 0; j < nstrsnlen; ++j) 1479 if (strsnlen[i].len > strsnlen[j].len 1480 && strcmp (strsnlen[j].str, 1481 strsnlen[i].str + (strsnlen[i].len 1482 - strsnlen[j].len)) == 0) 1483 { 1484 strsnlen[j] = strsnlen[i]; 1485 break; 1486 } 1487 else if (strsnlen[i].len < strsnlen[j].len 1488 && strcmp (strsnlen[i].str, 1489 strsnlen[j].str + (strsnlen[j].len 1490 - strsnlen[i].len)) == 0) 1491 break; 1492 ; 1493 if (j == nstrsnlen) 1494 strsnlen[nstrsnlen++] = strsnlen[i]; 1495 } 1496 1497 size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen); 1498 1499 for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits) 1500 { 1501 char suffix[1 << sfxbits]; 1502 1503 for (i = 0; i < (1u << sfxbits) - 1; ++i) 1504 suffix[i] = sfxfreq[i].ch; 1505 suffix[i] = '\0'; 1506 1507 size_t newlen[nstrsnlen]; 1508 1509 for (i = 0; i < nstrsnlen; ++i) 1510 if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL) 1511 newlen[i] = strsnlen[i].len - 1; 1512 else 1513 newlen[i] = strsnlen[i].len; 1514 1515 char charused[256]; 1516 memset (charused, '\0', sizeof (charused)); 1517 size_t ncharused = 0; 1518 1519 const char *tablestr[nstrsnlen]; 1520 size_t ntablestr = 1; 1521 tablestr[0] = strsnlen[0].str; 1522 size_t table = newlen[0] + 1; 1523 for (i = 1; i < nstrsnlen; ++i) 1524 { 1525 size_t j; 1526 for (j = 0; j < ntablestr; ++j) 1527 if (newlen[i] > newlen[j] 1528 && memcmp (tablestr[j], 1529 strsnlen[i].str + (newlen[i] - newlen[j]), 1530 newlen[j]) == 0) 1531 { 1532 table += newlen[i] - newlen[j]; 1533 tablestr[j] = strsnlen[i].str; 1534 newlen[j] = newlen[i]; 1535 break; 1536 } 1537 else if (newlen[i] < newlen[j] 1538 && memcmp (strsnlen[i].str, 1539 tablestr[j] + (newlen[j] - newlen[i]), 1540 newlen[i]) == 0) 1541 break; 1542 1543 if (j == ntablestr) 1544 { 1545 table += newlen[i] + 1; 1546 tablestr[ntablestr] = strsnlen[i].str; 1547 newlen[ntablestr] = newlen[i]; 1548 1549 ++ntablestr; 1550 } 1551 1552 for (size_t x = 0; x < newlen[j]; ++x) 1553 if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0) 1554 ++ncharused; 1555 } 1556 1557 size_t ncharused_bits = 0; 1558 i = 1; 1559 while (i < ncharused) 1560 { 1561 i *= 2; 1562 ++ncharused_bits; 1563 } 1564 1565 size_t table_bits = 0; 1566 i = 1; 1567 while (i < table) 1568 { 1569 i *= 2; 1570 ++table_bits; 1571 } 1572 1573 size_t mnemonic_bits = table_bits + pfxbits + sfxbits; 1574 size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused 1575 + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1) 1576 + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1) 1577 + (((total_bits + mnemonic_bits + 7) / 8) 1578 * ninstructions)); 1579 1580 if (new_total < best_so_far) 1581 { 1582 best_so_far = new_total; 1583 best_mnemonic_bits = mnemonic_bits; 1584 1585 free (best_suffix); 1586 best_suffix = xstrdup (suffix); 1587 1588 free (best_prefix); 1589 best_prefix = xstrdup (prefix); 1590 best_prefix_bits = pfxbits; 1591 1592 best_table_size = table; 1593 best_table_bits = table_bits; 1594 char *cp = best_table = xrealloc (best_table, table); 1595 for (i = 0; i < ntablestr; ++i) 1596 { 1597 assert (cp + newlen[i] + 1 <= best_table + table); 1598 cp = mempcpy (cp, tablestr[i], newlen[i]); 1599 *cp++ = '\0'; 1600 } 1601 assert (cp == best_table + table); 1602 } 1603 } 1604 } 1605 1606 fputs ("static const char mnemonic_table[] =\n\"", outfile); 1607 for (size_t i = 0; i < best_table_size; ++i) 1608 { 1609 if (((i + 1) % 60) == 0) 1610 fputs ("\"\n\"", outfile); 1611 if (!isascii (best_table[i]) || !isprint (best_table[i])) 1612 fprintf (outfile, "\\%03o", best_table[i]); 1613 else 1614 fputc (best_table[i], outfile); 1615 } 1616 fputs ("\";\n", outfile); 1617 1618 if (best_prefix[0] != '\0') 1619 fprintf (outfile, 1620 "static const char prefix[%zu] = \"%s\";\n" 1621 "#define PREFIXCHAR_BITS %zu\n", 1622 strlen (best_prefix), best_prefix, best_prefix_bits); 1623 else 1624 fputs ("#define NO_PREFIX\n", outfile); 1625 1626 if (best_suffix[0] != '\0') 1627 fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n", 1628 strlen (best_suffix), best_suffix); 1629 else 1630 fputs ("#define NO_SUFFIX\n", outfile); 1631 1632 for (size_t i = 0; i < nmnemonic_strs; ++i) 1633 { 1634 const char *mne = mnemonic_strs[i]; 1635 1636 size_t pfxval = 0; 1637 char *cp = strchr (best_prefix, *mne); 1638 if (cp != NULL) 1639 { 1640 pfxval = 1 + (cp - best_prefix); 1641 ++mne; 1642 } 1643 1644 size_t l = strlen (mne); 1645 1646 size_t sfxval = 0; 1647 cp = strchr (best_suffix, mne[l - 1]); 1648 if (cp != NULL) 1649 { 1650 sfxval = 1 + (cp - best_suffix); 1651 --l; 1652 } 1653 1654 char *off = memmem (best_table, best_table_size, mne, l); 1655 while (off[l] != '\0') 1656 { 1657 off = memmem (off + 1, best_table_size, mne, l); 1658 assert (off != NULL); 1659 } 1660 1661 fprintf (outfile, "#define MNE_%s %#zx\n", 1662 mnemonic_strs[i], 1663 (off - best_table) 1664 + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits)); 1665 } 1666 } 1667 #endif 1668