1/* ia64-gen.c -- Generate a shrunk set of opcode tables 2 Copyright (C) 1999-2022 Free Software Foundation, Inc. 3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com> 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this file; see the file COPYING. If not, write to the 19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 23/* While the ia64-opc-* set of opcode tables are easy to maintain, 24 they waste a tremendous amount of space. ia64-gen rearranges the 25 instructions into a directed acyclic graph (DAG) of instruction opcodes and 26 their possible completers, as well as compacting the set of strings used. 27 28 The disassembler table consists of a state machine that does 29 branching based on the bits of the opcode being disassembled. The 30 state encodings have been chosen to minimize the amount of space 31 required. 32 33 The resource table is constructed based on some text dependency tables, 34 which are also easier to maintain than the final representation. */ 35 36#include "sysdep.h" 37#include <stdio.h> 38#include <stdarg.h> 39#include <errno.h> 40 41#include "libiberty.h" 42#include "safe-ctype.h" 43#include "getopt.h" 44#include "ia64-opc.h" 45#include "ia64-opc-a.c" 46#include "ia64-opc-i.c" 47#include "ia64-opc-m.c" 48#include "ia64-opc-b.c" 49#include "ia64-opc-f.c" 50#include "ia64-opc-x.c" 51#include "ia64-opc-d.c" 52 53#include <libintl.h> 54#define _(String) gettext (String) 55 56const char * program_name = NULL; 57int debug = 0; 58 59#define NELEMS(a) (sizeof (a) / sizeof ((a)[0])) 60#define tmalloc(X) (X *) xmalloc (sizeof (X)) 61 62typedef unsigned long long ci_t; 63/* The main opcode table entry. Each entry is a unique combination of 64 name and flags (no two entries in the table compare as being equal 65 via opcodes_eq). */ 66struct main_entry 67{ 68 /* The base name of this opcode. The names of its completers are 69 appended to it to generate the full instruction name. */ 70 struct string_entry *name; 71 /* The base opcode entry. Which one to use is a fairly arbitrary choice; 72 it uses the first one passed to add_opcode_entry. */ 73 struct ia64_opcode *opcode; 74 /* The list of completers that can be applied to this opcode. */ 75 struct completer_entry *completers; 76 /* Next entry in the chain. */ 77 struct main_entry *next; 78 /* Index in the main table. */ 79 int main_index; 80} *maintable, **ordered_table; 81 82int otlen = 0; 83int ottotlen = 0; 84int opcode_count = 0; 85 86/* The set of possible completers for an opcode. */ 87struct completer_entry 88{ 89 /* This entry's index in the ia64_completer_table[] array. */ 90 int num; 91 92 /* The name of the completer. */ 93 struct string_entry *name; 94 95 /* This entry's parent. */ 96 struct completer_entry *parent; 97 98 /* Set if this is a terminal completer (occurs at the end of an 99 opcode). */ 100 int is_terminal; 101 102 /* An alternative completer. */ 103 struct completer_entry *alternative; 104 105 /* Additional completers that can be appended to this one. */ 106 struct completer_entry *addl_entries; 107 108 /* Before compute_completer_bits () is invoked, this contains the actual 109 instruction opcode for this combination of opcode and completers. 110 Afterwards, it contains those bits that are different from its 111 parent opcode. */ 112 ia64_insn bits; 113 114 /* Bits set to 1 correspond to those bits in this completer's opcode 115 that are different from its parent completer's opcode (or from 116 the base opcode if the entry is the root of the opcode's completer 117 list). This field is filled in by compute_completer_bits (). */ 118 ia64_insn mask; 119 120 /* Index into the opcode dependency list, or -1 if none. */ 121 int dependencies; 122 123 /* Remember the order encountered in the opcode tables. */ 124 int order; 125}; 126 127/* One entry in the disassembler name table. */ 128struct disent 129{ 130 /* The index into the ia64_name_dis array for this entry. */ 131 int ournum; 132 133 /* The index into the main_table[] array. */ 134 int insn; 135 136 /* The disassmbly priority of this entry. */ 137 int priority; 138 139 /* The completer_index value for this entry. */ 140 ci_t completer_index; 141 142 /* How many other entries share this decode. */ 143 int nextcnt; 144 145 /* The next entry sharing the same decode. */ 146 struct disent *nexte; 147 148 /* The next entry in the name list. */ 149 struct disent *next_ent; 150} *disinsntable = NULL; 151 152/* A state machine that will eventually be used to generate the 153 disassembler table. */ 154struct bittree 155{ 156 struct disent *disent; 157 struct bittree *bits[3]; /* 0, 1, and X (don't care). */ 158 int bits_to_skip; 159 int skip_flag; 160} *bittree; 161 162/* The string table contains all opcodes and completers sorted in 163 alphabetical order. */ 164 165/* One entry in the string table. */ 166struct string_entry 167{ 168 /* The index in the ia64_strings[] array for this entry. */ 169 int num; 170 /* And the string. */ 171 char *s; 172} **string_table = NULL; 173 174int strtablen = 0; 175int strtabtotlen = 0; 176 177 178/* Resource dependency entries. */ 179struct rdep 180{ 181 char *name; /* Resource name. */ 182 unsigned 183 mode:2, /* RAW, WAW, or WAR. */ 184 semantics:3; /* Dependency semantics. */ 185 char *extra; /* Additional semantics info. */ 186 int nchks; 187 int total_chks; /* Total #of terminal insns. */ 188 int *chks; /* Insn classes which read (RAW), write 189 (WAW), or write (WAR) this rsrc. */ 190 int *chknotes; /* Dependency notes for each class. */ 191 int nregs; 192 int total_regs; /* Total #of terminal insns. */ 193 int *regs; /* Insn class which write (RAW), write2 194 (WAW), or read (WAR) this rsrc. */ 195 int *regnotes; /* Dependency notes for each class. */ 196 197 int waw_special; /* Special WAW dependency note. */ 198} **rdeps = NULL; 199 200static int rdepslen = 0; 201static int rdepstotlen = 0; 202 203/* Array of all instruction classes. */ 204struct iclass 205{ 206 char *name; /* Instruction class name. */ 207 int is_class; /* Is a class, not a terminal. */ 208 int nsubs; 209 int *subs; /* Other classes within this class. */ 210 int nxsubs; 211 int xsubs[4]; /* Exclusions. */ 212 char *comment; /* Optional comment. */ 213 int note; /* Optional note. */ 214 int terminal_resolved; /* Did we match this with anything? */ 215 int orphan; /* Detect class orphans. */ 216} **ics = NULL; 217 218static int iclen = 0; 219static int ictotlen = 0; 220 221/* An opcode dependency (chk/reg pair of dependency lists). */ 222struct opdep 223{ 224 int chk; /* index into dlists */ 225 int reg; /* index into dlists */ 226} **opdeps; 227 228static int opdeplen = 0; 229static int opdeptotlen = 0; 230 231/* A generic list of dependencies w/notes encoded. These may be shared. */ 232struct deplist 233{ 234 int len; 235 unsigned short *deps; 236} **dlists; 237 238static int dlistlen = 0; 239static int dlisttotlen = 0; 240 241 242static void fail (const char *, ...) ATTRIBUTE_PRINTF_1; 243static void warn (const char *, ...) ATTRIBUTE_PRINTF_1; 244static struct rdep * insert_resource (const char *, enum ia64_dependency_mode); 245static int deplist_equals (struct deplist *, struct deplist *); 246static short insert_deplist (int, unsigned short *); 247static short insert_dependencies (int, unsigned short *, int, unsigned short *); 248static void mark_used (struct iclass *, int); 249static int fetch_insn_class (const char *, int); 250static int sub_compare (const void *, const void *); 251static void load_insn_classes (void); 252static void parse_resource_users (const char *, int **, int *, int **); 253static int parse_semantics (char *); 254static void add_dep (const char *, const char *, const char *, int, int, char *, int); 255static void load_depfile (const char *, enum ia64_dependency_mode); 256static void load_dependencies (void); 257static int irf_operand (int, const char *); 258static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *); 259static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *); 260static int lookup_regindex (const char *, int); 261static int lookup_specifier (const char *); 262static void print_dependency_table (void); 263static struct string_entry * insert_string (char *); 264static void gen_dis_table (struct bittree *); 265static void print_dis_table (void); 266static void generate_disassembler (void); 267static void print_string_table (void); 268static int completer_entries_eq (struct completer_entry *, struct completer_entry *); 269static struct completer_entry * insert_gclist (struct completer_entry *); 270static int get_prefix_len (const char *); 271static void compute_completer_bits (struct main_entry *, struct completer_entry *); 272static void collapse_redundant_completers (void); 273static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *); 274static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int); 275static void print_completer_entry (struct completer_entry *); 276static void print_completer_table (void); 277static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *); 278static void add_opcode_entry (struct ia64_opcode *); 279static void print_main_table (void); 280static void shrink (struct ia64_opcode *); 281static void print_version (void); 282static void usage (FILE *, int); 283static void finish_distable (void); 284static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, ci_t); 285static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, ci_t); 286static void compact_distree (struct bittree *); 287static struct bittree * make_bittree_entry (void); 288static struct disent * add_dis_table_ent (struct disent *, int, int, ci_t); 289 290 291static void 292fail (const char *message, ...) 293{ 294 va_list args; 295 296 va_start (args, message); 297 fprintf (stderr, _("%s: Error: "), program_name); 298 vfprintf (stderr, message, args); 299 va_end (args); 300 xexit (1); 301} 302 303static void 304warn (const char *message, ...) 305{ 306 va_list args; 307 308 va_start (args, message); 309 310 fprintf (stderr, _("%s: Warning: "), program_name); 311 vfprintf (stderr, message, args); 312 va_end (args); 313} 314 315/* Add NAME to the resource table, where TYPE is RAW or WAW. */ 316static struct rdep * 317insert_resource (const char *name, enum ia64_dependency_mode type) 318{ 319 if (rdepslen == rdepstotlen) 320 { 321 rdepstotlen += 20; 322 rdeps = (struct rdep **) 323 xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen); 324 } 325 rdeps[rdepslen] = tmalloc(struct rdep); 326 memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep)); 327 rdeps[rdepslen]->name = xstrdup (name); 328 rdeps[rdepslen]->mode = type; 329 rdeps[rdepslen]->waw_special = 0; 330 331 return rdeps[rdepslen++]; 332} 333 334/* Are the lists of dependency indexes equivalent? */ 335static int 336deplist_equals (struct deplist *d1, struct deplist *d2) 337{ 338 int i; 339 340 if (d1->len != d2->len) 341 return 0; 342 343 for (i = 0; i < d1->len; i++) 344 if (d1->deps[i] != d2->deps[i]) 345 return 0; 346 347 return 1; 348} 349 350/* Add the list of dependencies to the list of dependency lists. */ 351static short 352insert_deplist (int count, unsigned short *deps) 353{ 354 /* Sort the list, then see if an equivalent list exists already. 355 this results in a much smaller set of dependency lists. */ 356 struct deplist *list; 357 char set[0x10000]; 358 int i; 359 360 memset ((void *)set, 0, sizeof (set)); 361 for (i = 0; i < count; i++) 362 set[deps[i]] = 1; 363 364 count = 0; 365 for (i = 0; i < (int) sizeof (set); i++) 366 if (set[i]) 367 ++count; 368 369 list = tmalloc (struct deplist); 370 list->len = count; 371 list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count); 372 373 for (i = 0, count = 0; i < (int) sizeof (set); i++) 374 if (set[i]) 375 list->deps[count++] = i; 376 377 /* Does this list exist already? */ 378 for (i = 0; i < dlistlen; i++) 379 if (deplist_equals (list, dlists[i])) 380 { 381 free (list->deps); 382 free (list); 383 return i; 384 } 385 386 if (dlistlen == dlisttotlen) 387 { 388 dlisttotlen += 20; 389 dlists = (struct deplist **) 390 xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen); 391 } 392 dlists[dlistlen] = list; 393 394 return dlistlen++; 395} 396 397/* Add the given pair of dependency lists to the opcode dependency list. */ 398static short 399insert_dependencies (int nchks, unsigned short *chks, 400 int nregs, unsigned short *regs) 401{ 402 struct opdep *pair; 403 int i; 404 int regind = -1; 405 int chkind = -1; 406 407 if (nregs > 0) 408 regind = insert_deplist (nregs, regs); 409 if (nchks > 0) 410 chkind = insert_deplist (nchks, chks); 411 412 for (i = 0; i < opdeplen; i++) 413 if (opdeps[i]->chk == chkind 414 && opdeps[i]->reg == regind) 415 return i; 416 417 pair = tmalloc (struct opdep); 418 pair->chk = chkind; 419 pair->reg = regind; 420 421 if (opdeplen == opdeptotlen) 422 { 423 opdeptotlen += 20; 424 opdeps = (struct opdep **) 425 xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen); 426 } 427 opdeps[opdeplen] = pair; 428 429 return opdeplen++; 430} 431 432static void 433mark_used (struct iclass *ic, int clear_terminals) 434{ 435 int i; 436 437 ic->orphan = 0; 438 if (clear_terminals) 439 ic->terminal_resolved = 1; 440 441 for (i = 0; i < ic->nsubs; i++) 442 mark_used (ics[ic->subs[i]], clear_terminals); 443 444 for (i = 0; i < ic->nxsubs; i++) 445 mark_used (ics[ic->xsubs[i]], clear_terminals); 446} 447 448/* Look up an instruction class; if CREATE make a new one if none found; 449 returns the index into the insn class array. */ 450static int 451fetch_insn_class (const char *full_name, int create) 452{ 453 char *name; 454 char *notestr; 455 char *xsect; 456 char *comment; 457 int i, note = 0; 458 int ind; 459 int is_class = 0; 460 461 if (startswith (full_name, "IC:")) 462 { 463 name = xstrdup (full_name + 3); 464 is_class = 1; 465 } 466 else 467 name = xstrdup (full_name); 468 469 if ((xsect = strchr(name, '\\')) != NULL) 470 is_class = 1; 471 if ((comment = strchr(name, '[')) != NULL) 472 is_class = 1; 473 if ((notestr = strchr(name, '+')) != NULL) 474 is_class = 1; 475 476 /* If it is a composite class, then ignore comments and notes that come after 477 the '\\', since they don't apply to the part we are decoding now. */ 478 if (xsect) 479 { 480 if (comment > xsect) 481 comment = 0; 482 if (notestr > xsect) 483 notestr = 0; 484 } 485 486 if (notestr) 487 { 488 char *nextnotestr; 489 490 note = atoi (notestr + 1); 491 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 492 { 493 if (strcmp (notestr, "+1+13") == 0) 494 note = 13; 495 else if (!xsect || nextnotestr < xsect) 496 warn (_("multiple note %s not handled\n"), notestr); 497 } 498 } 499 500 /* If it's a composite class, leave the notes and comments in place so that 501 we have a unique name for the composite class. Otherwise, we remove 502 them. */ 503 if (!xsect) 504 { 505 if (notestr) 506 *notestr = 0; 507 if (comment) 508 *comment = 0; 509 } 510 511 for (i = 0; i < iclen; i++) 512 if (strcmp (name, ics[i]->name) == 0 513 && ((comment == NULL && ics[i]->comment == NULL) 514 || (comment != NULL && ics[i]->comment != NULL 515 && strncmp (ics[i]->comment, comment, 516 strlen (ics[i]->comment)) == 0)) 517 && note == ics[i]->note) 518 return i; 519 520 if (!create) 521 return -1; 522 523 /* Doesn't exist, so make a new one. */ 524 if (iclen == ictotlen) 525 { 526 ictotlen += 20; 527 ics = (struct iclass **) 528 xrealloc (ics, (ictotlen) * sizeof (struct iclass *)); 529 } 530 531 ind = iclen++; 532 ics[ind] = tmalloc (struct iclass); 533 memset ((void *)ics[ind], 0, sizeof (struct iclass)); 534 ics[ind]->name = xstrdup (name); 535 ics[ind]->is_class = is_class; 536 ics[ind]->orphan = 1; 537 538 if (comment) 539 { 540 ics[ind]->comment = xstrdup (comment + 1); 541 ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0; 542 } 543 544 if (notestr) 545 ics[ind]->note = note; 546 547 /* If it's a composite class, there's a comment or note, look for an 548 existing class or terminal with the same name. */ 549 if ((xsect || comment || notestr) && is_class) 550 { 551 /* First, populate with the class we're based on. */ 552 char *subname = name; 553 554 if (xsect) 555 *xsect = 0; 556 else if (comment) 557 *comment = 0; 558 else if (notestr) 559 *notestr = 0; 560 561 ics[ind]->nsubs = 1; 562 ics[ind]->subs = tmalloc(int); 563 ics[ind]->subs[0] = fetch_insn_class (subname, 1); 564 } 565 566 while (xsect) 567 { 568 char *subname = xsect + 1; 569 570 xsect = strchr (subname, '\\'); 571 if (xsect) 572 *xsect = 0; 573 ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1); 574 ics[ind]->nxsubs++; 575 } 576 free (name); 577 578 return ind; 579} 580 581/* For sorting a class's sub-class list only; make sure classes appear before 582 terminals. */ 583static int 584sub_compare (const void *e1, const void *e2) 585{ 586 struct iclass *ic1 = ics[*(int *)e1]; 587 struct iclass *ic2 = ics[*(int *)e2]; 588 589 if (ic1->is_class) 590 { 591 if (!ic2->is_class) 592 return -1; 593 } 594 else if (ic2->is_class) 595 return 1; 596 597 return strcmp (ic1->name, ic2->name); 598} 599 600static void 601load_insn_classes (void) 602{ 603 FILE *fp = fopen ("ia64-ic.tbl", "r"); 604 char buf[2048]; 605 606 if (fp == NULL) 607 fail (_("can't find ia64-ic.tbl for reading\n")); 608 609 /* Discard first line. */ 610 fgets (buf, sizeof(buf), fp); 611 612 while (!feof (fp)) 613 { 614 int iclass; 615 char *name; 616 char *tmp; 617 618 if (fgets (buf, sizeof (buf), fp) == NULL) 619 break; 620 621 while (ISSPACE (buf[strlen (buf) - 1])) 622 buf[strlen (buf) - 1] = '\0'; 623 624 name = tmp = buf; 625 while (*tmp != ';') 626 { 627 ++tmp; 628 if (tmp == buf + sizeof (buf)) 629 abort (); 630 } 631 *tmp++ = '\0'; 632 633 iclass = fetch_insn_class (name, 1); 634 ics[iclass]->is_class = 1; 635 636 if (strcmp (name, "none") == 0) 637 { 638 ics[iclass]->is_class = 0; 639 ics[iclass]->terminal_resolved = 1; 640 continue; 641 } 642 643 /* For this class, record all sub-classes. */ 644 while (*tmp) 645 { 646 char *subname; 647 int sub; 648 649 while (*tmp && ISSPACE (*tmp)) 650 { 651 ++tmp; 652 if (tmp == buf + sizeof (buf)) 653 abort (); 654 } 655 subname = tmp; 656 while (*tmp && *tmp != ',') 657 { 658 ++tmp; 659 if (tmp == buf + sizeof (buf)) 660 abort (); 661 } 662 if (*tmp == ',') 663 *tmp++ = '\0'; 664 665 ics[iclass]->subs = (int *) 666 xrealloc ((void *)ics[iclass]->subs, 667 (ics[iclass]->nsubs + 1) * sizeof (int)); 668 669 sub = fetch_insn_class (subname, 1); 670 ics[iclass]->subs = (int *) 671 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int)); 672 ics[iclass]->subs[ics[iclass]->nsubs++] = sub; 673 } 674 675 /* Make sure classes come before terminals. */ 676 qsort ((void *)ics[iclass]->subs, 677 ics[iclass]->nsubs, sizeof(int), sub_compare); 678 } 679 fclose (fp); 680 681 if (debug) 682 printf ("%d classes\n", iclen); 683} 684 685/* Extract the insn classes from the given line. */ 686static void 687parse_resource_users (const char *ref, int **usersp, int *nusersp, 688 int **notesp) 689{ 690 int c; 691 char *line = xstrdup (ref); 692 char *tmp = line; 693 int *users = *usersp; 694 int count = *nusersp; 695 int *notes = *notesp; 696 697 c = *tmp; 698 while (c != 0) 699 { 700 char *notestr; 701 int note; 702 char *xsect; 703 int iclass; 704 int create = 0; 705 char *name; 706 707 while (ISSPACE (*tmp)) 708 ++tmp; 709 name = tmp; 710 while (*tmp && *tmp != ',') 711 ++tmp; 712 c = *tmp; 713 *tmp++ = '\0'; 714 715 xsect = strchr (name, '\\'); 716 if ((notestr = strstr (name, "+")) != NULL) 717 { 718 char *nextnotestr; 719 720 note = atoi (notestr + 1); 721 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 722 { 723 /* Note 13 always implies note 1. */ 724 if (strcmp (notestr, "+1+13") == 0) 725 note = 13; 726 else if (!xsect || nextnotestr < xsect) 727 warn (_("multiple note %s not handled\n"), notestr); 728 } 729 if (!xsect) 730 *notestr = '\0'; 731 } 732 else 733 note = 0; 734 735 /* All classes are created when the insn class table is parsed; 736 Individual instructions might not appear until the dependency tables 737 are read. Only create new classes if it's *not* an insn class, 738 or if it's a composite class (which wouldn't necessarily be in the IC 739 table). */ 740 if (! startswith (name, "IC:") || xsect != NULL) 741 create = 1; 742 743 iclass = fetch_insn_class (name, create); 744 if (iclass != -1) 745 { 746 users = (int *) 747 xrealloc ((void *) users,(count + 1) * sizeof (int)); 748 notes = (int *) 749 xrealloc ((void *) notes,(count + 1) * sizeof (int)); 750 notes[count] = note; 751 users[count++] = iclass; 752 mark_used (ics[iclass], 0); 753 } 754 else if (debug) 755 printf("Class %s not found\n", name); 756 } 757 /* Update the return values. */ 758 *usersp = users; 759 *nusersp = count; 760 *notesp = notes; 761 762 free (line); 763} 764 765static int 766parse_semantics (char *sem) 767{ 768 if (strcmp (sem, "none") == 0) 769 return IA64_DVS_NONE; 770 else if (strcmp (sem, "implied") == 0) 771 return IA64_DVS_IMPLIED; 772 else if (strcmp (sem, "impliedF") == 0) 773 return IA64_DVS_IMPLIEDF; 774 else if (strcmp (sem, "data") == 0) 775 return IA64_DVS_DATA; 776 else if (strcmp (sem, "instr") == 0) 777 return IA64_DVS_INSTR; 778 else if (strcmp (sem, "specific") == 0) 779 return IA64_DVS_SPECIFIC; 780 else if (strcmp (sem, "stop") == 0) 781 return IA64_DVS_STOP; 782 else 783 return IA64_DVS_OTHER; 784} 785 786static void 787add_dep (const char *name, const char *chk, const char *reg, 788 int semantics, int mode, char *extra, int flag) 789{ 790 struct rdep *rs; 791 792 rs = insert_resource (name, mode); 793 794 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes); 795 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes); 796 797 rs->semantics = semantics; 798 rs->extra = extra; 799 rs->waw_special = flag; 800} 801 802static void 803load_depfile (const char *filename, enum ia64_dependency_mode mode) 804{ 805 FILE *fp = fopen (filename, "r"); 806 char buf[1024]; 807 808 if (fp == NULL) 809 fail (_("can't find %s for reading\n"), filename); 810 811 fgets (buf, sizeof(buf), fp); 812 while (!feof (fp)) 813 { 814 char *name, *tmp; 815 int semantics; 816 char *extra; 817 char *regp, *chkp; 818 819 if (fgets (buf, sizeof(buf), fp) == NULL) 820 break; 821 822 while (ISSPACE (buf[strlen (buf) - 1])) 823 buf[strlen (buf) - 1] = '\0'; 824 825 name = tmp = buf; 826 while (*tmp != ';') 827 ++tmp; 828 *tmp++ = '\0'; 829 830 while (ISSPACE (*tmp)) 831 ++tmp; 832 regp = tmp; 833 tmp = strchr (tmp, ';'); 834 if (!tmp) 835 abort (); 836 *tmp++ = 0; 837 while (ISSPACE (*tmp)) 838 ++tmp; 839 chkp = tmp; 840 tmp = strchr (tmp, ';'); 841 if (!tmp) 842 abort (); 843 *tmp++ = 0; 844 while (ISSPACE (*tmp)) 845 ++tmp; 846 semantics = parse_semantics (tmp); 847 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL; 848 849 /* For WAW entries, if the chks and regs differ, we need to enter the 850 entries in both positions so that the tables will be parsed properly, 851 without a lot of extra work. */ 852 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0) 853 { 854 add_dep (name, chkp, regp, semantics, mode, extra, 0); 855 add_dep (name, regp, chkp, semantics, mode, extra, 1); 856 } 857 else 858 { 859 add_dep (name, chkp, regp, semantics, mode, extra, 0); 860 } 861 } 862 fclose (fp); 863} 864 865static void 866load_dependencies (void) 867{ 868 load_depfile ("ia64-raw.tbl", IA64_DV_RAW); 869 load_depfile ("ia64-waw.tbl", IA64_DV_WAW); 870 load_depfile ("ia64-war.tbl", IA64_DV_WAR); 871 872 if (debug) 873 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen); 874} 875 876/* Is the given operand an indirect register file operand? */ 877static int 878irf_operand (int op, const char *field) 879{ 880 if (!field) 881 { 882 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3 883 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3 884 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3 885 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3; 886 } 887 else 888 { 889 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr")) 890 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr")) 891 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr")) 892 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr")) 893 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc")) 894 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd")) 895 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr")) 896 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")) 897 || (op == IA64_OPND_DAHR_R3 && strstr (field, "dahr"))); 898 } 899} 900 901/* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr, 902 * mov_psr, and mov_um insn classes. */ 903static int 904in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, 905 const char *format, const char *field) 906{ 907 int plain_mov = strcmp (idesc->name, "mov") == 0; 908 909 if (!format) 910 return 0; 911 912 switch (ic->name[4]) 913 { 914 default: 915 abort (); 916 case 'a': 917 { 918 int i = strcmp (idesc->name, "mov.i") == 0; 919 int m = strcmp (idesc->name, "mov.m") == 0; 920 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3; 921 int i28 = i && idesc->operands[1] == IA64_OPND_AR3; 922 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3; 923 int m31 = m && idesc->operands[1] == IA64_OPND_AR3; 924 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3; 925 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3; 926 927 /* IC:mov ar */ 928 if (i2627) 929 return strstr (format, "I26") || strstr (format, "I27"); 930 if (i28) 931 return strstr (format, "I28") != NULL; 932 if (m2930) 933 return strstr (format, "M29") || strstr (format, "M30"); 934 if (m31) 935 return strstr (format, "M31") != NULL; 936 if (pseudo0 || pseudo1) 937 return 1; 938 } 939 break; 940 case 'b': 941 { 942 int i21 = idesc->operands[0] == IA64_OPND_B1; 943 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2; 944 if (i22) 945 return strstr (format, "I22") != NULL; 946 if (i21) 947 return strstr (format, "I21") != NULL; 948 } 949 break; 950 case 'c': 951 { 952 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3; 953 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3; 954 if (m32) 955 return strstr (format, "M32") != NULL; 956 if (m33) 957 return strstr (format, "M33") != NULL; 958 } 959 break; 960 case 'd': 961 { 962 int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3; 963 if (m50) 964 return strstr (format, "M50") != NULL; 965 } 966 break; 967 case 'i': 968 if (ic->name[5] == 'n') 969 { 970 int m42 = plain_mov && irf_operand (idesc->operands[0], field); 971 int m43 = plain_mov && irf_operand (idesc->operands[1], field); 972 if (m42) 973 return strstr (format, "M42") != NULL; 974 if (m43) 975 return strstr (format, "M43") != NULL; 976 } 977 else if (ic->name[5] == 'p') 978 { 979 return idesc->operands[1] == IA64_OPND_IP; 980 } 981 else 982 abort (); 983 break; 984 case 'p': 985 if (ic->name[5] == 'r') 986 { 987 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR; 988 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR; 989 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT; 990 if (i23) 991 return strstr (format, "I23") != NULL; 992 if (i24) 993 return strstr (format, "I24") != NULL; 994 if (i25) 995 return strstr (format, "I25") != NULL; 996 } 997 else if (ic->name[5] == 's') 998 { 999 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L; 1000 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR; 1001 if (m35) 1002 return strstr (format, "M35") != NULL; 1003 if (m36) 1004 return strstr (format, "M36") != NULL; 1005 } 1006 else 1007 abort (); 1008 break; 1009 case 'u': 1010 { 1011 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM; 1012 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM; 1013 if (m35) 1014 return strstr (format, "M35") != NULL; 1015 if (m36) 1016 return strstr (format, "M36") != NULL; 1017 } 1018 break; 1019 } 1020 return 0; 1021} 1022 1023/* Is the given opcode in the given insn class? */ 1024static int 1025in_iclass (struct ia64_opcode *idesc, struct iclass *ic, 1026 const char *format, const char *field, int *notep) 1027{ 1028 int i; 1029 int resolved = 0; 1030 1031 if (ic->comment) 1032 { 1033 if (startswith (ic->comment, "Format")) 1034 { 1035 /* Assume that the first format seen is the most restrictive, and 1036 only keep a later one if it looks like it's more restrictive. */ 1037 if (format) 1038 { 1039 if (strlen (ic->comment) < strlen (format)) 1040 { 1041 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"), 1042 ic->comment, format); 1043 format = ic->comment; 1044 } 1045 } 1046 else 1047 format = ic->comment; 1048 } 1049 else if (startswith (ic->comment, "Field")) 1050 { 1051 if (field) 1052 warn (_("overlapping field %s->%s\n"), 1053 ic->comment, field); 1054 field = ic->comment; 1055 } 1056 } 1057 1058 /* An insn class matches anything that is the same followed by completers, 1059 except when the absence and presence of completers constitutes different 1060 instructions. */ 1061 if (ic->nsubs == 0 && ic->nxsubs == 0) 1062 { 1063 int is_mov = startswith (idesc->name, "mov"); 1064 int plain_mov = strcmp (idesc->name, "mov") == 0; 1065 int len = strlen(ic->name); 1066 1067 resolved = ((strncmp (ic->name, idesc->name, len) == 0) 1068 && (idesc->name[len] == '\0' 1069 || idesc->name[len] == '.')); 1070 1071 /* All break, nop, and hint variations must match exactly. */ 1072 if (resolved && 1073 (strcmp (ic->name, "break") == 0 1074 || strcmp (ic->name, "nop") == 0 1075 || strcmp (ic->name, "hint") == 0)) 1076 resolved = strcmp (ic->name, idesc->name) == 0; 1077 1078 /* Assume restrictions in the FORMAT/FIELD negate resolution, 1079 unless specifically allowed by clauses in this block. */ 1080 if (resolved && field) 1081 { 1082 /* Check Field(sf)==sN against opcode sN. */ 1083 if (strstr(field, "(sf)==") != NULL) 1084 { 1085 char *sf; 1086 1087 if ((sf = strstr (idesc->name, ".s")) != 0) 1088 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0; 1089 } 1090 /* Check Field(lftype)==XXX. */ 1091 else if (strstr (field, "(lftype)") != NULL) 1092 { 1093 if (strstr (idesc->name, "fault") != NULL) 1094 resolved = strstr (field, "fault") != NULL; 1095 else 1096 resolved = strstr (field, "fault") == NULL; 1097 } 1098 /* Handle Field(ctype)==XXX. */ 1099 else if (strstr (field, "(ctype)") != NULL) 1100 { 1101 if (strstr (idesc->name, "or.andcm")) 1102 resolved = strstr (field, "or.andcm") != NULL; 1103 else if (strstr (idesc->name, "and.orcm")) 1104 resolved = strstr (field, "and.orcm") != NULL; 1105 else if (strstr (idesc->name, "orcm")) 1106 resolved = strstr (field, "or orcm") != NULL; 1107 else if (strstr (idesc->name, "or")) 1108 resolved = strstr (field, "or orcm") != NULL; 1109 else if (strstr (idesc->name, "andcm")) 1110 resolved = strstr (field, "and andcm") != NULL; 1111 else if (strstr (idesc->name, "and")) 1112 resolved = strstr (field, "and andcm") != NULL; 1113 else if (strstr (idesc->name, "unc")) 1114 resolved = strstr (field, "unc") != NULL; 1115 else 1116 resolved = strcmp (field, "Field(ctype)==") == 0; 1117 } 1118 } 1119 1120 if (resolved && format) 1121 { 1122 if (startswith (idesc->name, "dep") 1123 && strstr (format, "I13") != NULL) 1124 resolved = idesc->operands[1] == IA64_OPND_IMM8; 1125 else if (startswith (idesc->name, "chk") 1126 && strstr (format, "M21") != NULL) 1127 resolved = idesc->operands[0] == IA64_OPND_F2; 1128 else if (startswith (idesc->name, "lfetch")) 1129 resolved = (strstr (format, "M14 M15") != NULL 1130 && (idesc->operands[1] == IA64_OPND_R2 1131 || idesc->operands[1] == IA64_OPND_IMM9b)); 1132 else if (startswith (idesc->name, "br.call") 1133 && strstr (format, "B5") != NULL) 1134 resolved = idesc->operands[1] == IA64_OPND_B2; 1135 else if (startswith (idesc->name, "br.call") 1136 && strstr (format, "B3") != NULL) 1137 resolved = idesc->operands[1] == IA64_OPND_TGT25c; 1138 else if (startswith (idesc->name, "brp") 1139 && strstr (format, "B7") != NULL) 1140 resolved = idesc->operands[0] == IA64_OPND_B2; 1141 else if (strcmp (ic->name, "invala") == 0) 1142 resolved = strcmp (idesc->name, ic->name) == 0; 1143 else if (startswith (idesc->name, "st") 1144 && (strstr (format, "M5") != NULL 1145 || strstr (format, "M10") != NULL)) 1146 resolved = idesc->flags & IA64_OPCODE_POSTINC; 1147 else if (startswith (idesc->name, "ld") 1148 && (strstr (format, "M2 M3") != NULL 1149 || strstr (format, "M12") != NULL 1150 || strstr (format, "M7 M8") != NULL)) 1151 resolved = idesc->flags & IA64_OPCODE_POSTINC; 1152 else 1153 resolved = 0; 1154 } 1155 1156 /* Misc brl variations ('.cond' is optional); 1157 plain brl matches brl.cond. */ 1158 if (!resolved 1159 && (strcmp (idesc->name, "brl") == 0 1160 || startswith (idesc->name, "brl.")) 1161 && strcmp (ic->name, "brl.cond") == 0) 1162 { 1163 resolved = 1; 1164 } 1165 1166 /* Misc br variations ('.cond' is optional). */ 1167 if (!resolved 1168 && (strcmp (idesc->name, "br") == 0 1169 || startswith (idesc->name, "br.")) 1170 && strcmp (ic->name, "br.cond") == 0) 1171 { 1172 if (format) 1173 resolved = (strstr (format, "B4") != NULL 1174 && idesc->operands[0] == IA64_OPND_B2) 1175 || (strstr (format, "B1") != NULL 1176 && idesc->operands[0] == IA64_OPND_TGT25c); 1177 else 1178 resolved = 1; 1179 } 1180 1181 /* probe variations. */ 1182 if (!resolved && startswith (idesc->name, "probe")) 1183 { 1184 resolved = strcmp (ic->name, "probe") == 0 1185 && !((strstr (idesc->name, "fault") != NULL) 1186 ^ (format && strstr (format, "M40") != NULL)); 1187 } 1188 1189 /* mov variations. */ 1190 if (!resolved && is_mov) 1191 { 1192 if (plain_mov) 1193 { 1194 /* mov alias for fmerge. */ 1195 if (strcmp (ic->name, "fmerge") == 0) 1196 { 1197 resolved = idesc->operands[0] == IA64_OPND_F1 1198 && idesc->operands[1] == IA64_OPND_F3; 1199 } 1200 /* mov alias for adds (r3 or imm14). */ 1201 else if (strcmp (ic->name, "adds") == 0) 1202 { 1203 resolved = (idesc->operands[0] == IA64_OPND_R1 1204 && (idesc->operands[1] == IA64_OPND_R3 1205 || (idesc->operands[1] == IA64_OPND_IMM14))); 1206 } 1207 /* mov alias for addl. */ 1208 else if (strcmp (ic->name, "addl") == 0) 1209 { 1210 resolved = idesc->operands[0] == IA64_OPND_R1 1211 && idesc->operands[1] == IA64_OPND_IMM22; 1212 } 1213 } 1214 1215 /* Some variants of mov and mov.[im]. */ 1216 if (!resolved && startswith (ic->name, "mov_")) 1217 resolved = in_iclass_mov_x (idesc, ic, format, field); 1218 } 1219 1220 /* Keep track of this so we can flag any insn classes which aren't 1221 mapped onto at least one real insn. */ 1222 if (resolved) 1223 ic->terminal_resolved = 1; 1224 } 1225 else for (i = 0; i < ic->nsubs; i++) 1226 { 1227 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep)) 1228 { 1229 int j; 1230 1231 for (j = 0; j < ic->nxsubs; j++) 1232 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL)) 1233 return 0; 1234 1235 if (debug > 1) 1236 printf ("%s is in IC %s\n", idesc->name, ic->name); 1237 1238 resolved = 1; 1239 break; 1240 } 1241 } 1242 1243 /* If it's in this IC, add the IC note (if any) to the insn. */ 1244 if (resolved) 1245 { 1246 if (ic->note && notep) 1247 { 1248 if (*notep && *notep != ic->note) 1249 warn (_("overwriting note %d with note %d (IC:%s)\n"), 1250 *notep, ic->note, ic->name); 1251 1252 *notep = ic->note; 1253 } 1254 } 1255 1256 return resolved; 1257} 1258 1259 1260static int 1261lookup_regindex (const char *name, int specifier) 1262{ 1263 switch (specifier) 1264 { 1265 case IA64_RS_ARX: 1266 if (strstr (name, "[RSC]")) 1267 return 16; 1268 if (strstr (name, "[BSP]")) 1269 return 17; 1270 else if (strstr (name, "[BSPSTORE]")) 1271 return 18; 1272 else if (strstr (name, "[RNAT]")) 1273 return 19; 1274 else if (strstr (name, "[FCR]")) 1275 return 21; 1276 else if (strstr (name, "[EFLAG]")) 1277 return 24; 1278 else if (strstr (name, "[CSD]")) 1279 return 25; 1280 else if (strstr (name, "[SSD]")) 1281 return 26; 1282 else if (strstr (name, "[CFLG]")) 1283 return 27; 1284 else if (strstr (name, "[FSR]")) 1285 return 28; 1286 else if (strstr (name, "[FIR]")) 1287 return 29; 1288 else if (strstr (name, "[FDR]")) 1289 return 30; 1290 else if (strstr (name, "[CCV]")) 1291 return 32; 1292 else if (strstr (name, "[ITC]")) 1293 return 44; 1294 else if (strstr (name, "[RUC]")) 1295 return 45; 1296 else if (strstr (name, "[PFS]")) 1297 return 64; 1298 else if (strstr (name, "[LC]")) 1299 return 65; 1300 else if (strstr (name, "[EC]")) 1301 return 66; 1302 abort (); 1303 case IA64_RS_CRX: 1304 if (strstr (name, "[DCR]")) 1305 return 0; 1306 else if (strstr (name, "[ITM]")) 1307 return 1; 1308 else if (strstr (name, "[IVA]")) 1309 return 2; 1310 else if (strstr (name, "[PTA]")) 1311 return 8; 1312 else if (strstr (name, "[GPTA]")) 1313 return 9; 1314 else if (strstr (name, "[IPSR]")) 1315 return 16; 1316 else if (strstr (name, "[ISR]")) 1317 return 17; 1318 else if (strstr (name, "[IIP]")) 1319 return 19; 1320 else if (strstr (name, "[IFA]")) 1321 return 20; 1322 else if (strstr (name, "[ITIR]")) 1323 return 21; 1324 else if (strstr (name, "[IIPA]")) 1325 return 22; 1326 else if (strstr (name, "[IFS]")) 1327 return 23; 1328 else if (strstr (name, "[IIM]")) 1329 return 24; 1330 else if (strstr (name, "[IHA]")) 1331 return 25; 1332 else if (strstr (name, "[LID]")) 1333 return 64; 1334 else if (strstr (name, "[IVR]")) 1335 return 65; 1336 else if (strstr (name, "[TPR]")) 1337 return 66; 1338 else if (strstr (name, "[EOI]")) 1339 return 67; 1340 else if (strstr (name, "[ITV]")) 1341 return 72; 1342 else if (strstr (name, "[PMV]")) 1343 return 73; 1344 else if (strstr (name, "[CMCV]")) 1345 return 74; 1346 abort (); 1347 case IA64_RS_PSR: 1348 if (strstr (name, ".be")) 1349 return 1; 1350 else if (strstr (name, ".up")) 1351 return 2; 1352 else if (strstr (name, ".ac")) 1353 return 3; 1354 else if (strstr (name, ".mfl")) 1355 return 4; 1356 else if (strstr (name, ".mfh")) 1357 return 5; 1358 else if (strstr (name, ".ic")) 1359 return 13; 1360 else if (strstr (name, ".i")) 1361 return 14; 1362 else if (strstr (name, ".pk")) 1363 return 15; 1364 else if (strstr (name, ".dt")) 1365 return 17; 1366 else if (strstr (name, ".dfl")) 1367 return 18; 1368 else if (strstr (name, ".dfh")) 1369 return 19; 1370 else if (strstr (name, ".sp")) 1371 return 20; 1372 else if (strstr (name, ".pp")) 1373 return 21; 1374 else if (strstr (name, ".di")) 1375 return 22; 1376 else if (strstr (name, ".si")) 1377 return 23; 1378 else if (strstr (name, ".db")) 1379 return 24; 1380 else if (strstr (name, ".lp")) 1381 return 25; 1382 else if (strstr (name, ".tb")) 1383 return 26; 1384 else if (strstr (name, ".rt")) 1385 return 27; 1386 else if (strstr (name, ".cpl")) 1387 return 32; 1388 else if (strstr (name, ".rs")) 1389 return 34; 1390 else if (strstr (name, ".mc")) 1391 return 35; 1392 else if (strstr (name, ".it")) 1393 return 36; 1394 else if (strstr (name, ".id")) 1395 return 37; 1396 else if (strstr (name, ".da")) 1397 return 38; 1398 else if (strstr (name, ".dd")) 1399 return 39; 1400 else if (strstr (name, ".ss")) 1401 return 40; 1402 else if (strstr (name, ".ri")) 1403 return 41; 1404 else if (strstr (name, ".ed")) 1405 return 43; 1406 else if (strstr (name, ".bn")) 1407 return 44; 1408 else if (strstr (name, ".ia")) 1409 return 45; 1410 else if (strstr (name, ".vm")) 1411 return 46; 1412 else 1413 abort (); 1414 default: 1415 break; 1416 } 1417 return REG_NONE; 1418} 1419 1420static int 1421lookup_specifier (const char *name) 1422{ 1423 if (strchr (name, '%')) 1424 { 1425 if (strstr (name, "AR[K%]") != NULL) 1426 return IA64_RS_AR_K; 1427 if (strstr (name, "AR[UNAT]") != NULL) 1428 return IA64_RS_AR_UNAT; 1429 if (strstr (name, "AR%, % in 8") != NULL) 1430 return IA64_RS_AR; 1431 if (strstr (name, "AR%, % in 48") != NULL) 1432 return IA64_RS_ARb; 1433 if (strstr (name, "BR%") != NULL) 1434 return IA64_RS_BR; 1435 if (strstr (name, "CR[IIB%]") != NULL) 1436 return IA64_RS_CR_IIB; 1437 if (strstr (name, "CR[IRR%]") != NULL) 1438 return IA64_RS_CR_IRR; 1439 if (strstr (name, "CR[LRR%]") != NULL) 1440 return IA64_RS_CR_LRR; 1441 if (strstr (name, "CR%") != NULL) 1442 return IA64_RS_CR; 1443 if (strstr (name, "DAHR%, % in 0") != NULL) 1444 return IA64_RS_DAHR; 1445 if (strstr (name, "FR%, % in 0") != NULL) 1446 return IA64_RS_FR; 1447 if (strstr (name, "FR%, % in 2") != NULL) 1448 return IA64_RS_FRb; 1449 if (strstr (name, "GR%") != NULL) 1450 return IA64_RS_GR; 1451 if (strstr (name, "PR%, % in 1 ") != NULL) 1452 return IA64_RS_PR; 1453 if (strstr (name, "PR%, % in 16 ") != NULL) 1454 return IA64_RS_PRr; 1455 1456 warn (_("don't know how to specify %% dependency %s\n"), 1457 name); 1458 } 1459 else if (strchr (name, '#')) 1460 { 1461 if (strstr (name, "CPUID#") != NULL) 1462 return IA64_RS_CPUID; 1463 if (strstr (name, "DBR#") != NULL) 1464 return IA64_RS_DBR; 1465 if (strstr (name, "IBR#") != NULL) 1466 return IA64_RS_IBR; 1467 if (strstr (name, "MSR#") != NULL) 1468 return IA64_RS_MSR; 1469 if (strstr (name, "PKR#") != NULL) 1470 return IA64_RS_PKR; 1471 if (strstr (name, "PMC#") != NULL) 1472 return IA64_RS_PMC; 1473 if (strstr (name, "PMD#") != NULL) 1474 return IA64_RS_PMD; 1475 if (strstr (name, "RR#") != NULL) 1476 return IA64_RS_RR; 1477 1478 warn (_("Don't know how to specify # dependency %s\n"), 1479 name); 1480 } 1481 else if (startswith (name, "AR[FPSR]")) 1482 return IA64_RS_AR_FPSR; 1483 else if (startswith (name, "AR[")) 1484 return IA64_RS_ARX; 1485 else if (startswith (name, "CR[")) 1486 return IA64_RS_CRX; 1487 else if (startswith (name, "PSR.")) 1488 return IA64_RS_PSR; 1489 else if (strcmp (name, "InService*") == 0) 1490 return IA64_RS_INSERVICE; 1491 else if (strcmp (name, "GR0") == 0) 1492 return IA64_RS_GR0; 1493 else if (strcmp (name, "CFM") == 0) 1494 return IA64_RS_CFM; 1495 else if (strcmp (name, "PR63") == 0) 1496 return IA64_RS_PR63; 1497 else if (strcmp (name, "RSE") == 0) 1498 return IA64_RS_RSE; 1499 1500 return IA64_RS_ANY; 1501} 1502 1503static void 1504print_dependency_table (void) 1505{ 1506 int i, j; 1507 1508 if (debug) 1509 { 1510 for (i=0;i < iclen;i++) 1511 { 1512 if (ics[i]->is_class) 1513 { 1514 if (!ics[i]->nsubs) 1515 { 1516 if (ics[i]->comment) 1517 warn (_("IC:%s [%s] has no terminals or sub-classes\n"), 1518 ics[i]->name, ics[i]->comment); 1519 else 1520 warn (_("IC:%s has no terminals or sub-classes\n"), 1521 ics[i]->name); 1522 } 1523 } 1524 else 1525 { 1526 if (!ics[i]->terminal_resolved && !ics[i]->orphan) 1527 { 1528 if (ics[i]->comment) 1529 warn (_("no insns mapped directly to terminal IC %s [%s]"), 1530 ics[i]->name, ics[i]->comment); 1531 else 1532 warn (_("no insns mapped directly to terminal IC %s\n"), 1533 ics[i]->name); 1534 } 1535 } 1536 } 1537 1538 for (i = 0; i < iclen; i++) 1539 { 1540 if (ics[i]->orphan) 1541 { 1542 mark_used (ics[i], 1); 1543 warn (_("class %s is defined but not used\n"), 1544 ics[i]->name); 1545 } 1546 } 1547 1548 if (debug > 1) 1549 for (i = 0; i < rdepslen; i++) 1550 { 1551 static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1552 1553 if (rdeps[i]->total_chks == 0) 1554 { 1555 if (rdeps[i]->total_regs) 1556 warn (_("Warning: rsrc %s (%s) has no chks\n"), 1557 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1558 else 1559 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"), 1560 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1561 } 1562 else if (rdeps[i]->total_regs == 0) 1563 warn (_("rsrc %s (%s) has no regs\n"), 1564 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1565 } 1566 } 1567 1568 /* The dependencies themselves. */ 1569 printf ("static const struct ia64_dependency\ndependencies[] = {\n"); 1570 for (i = 0; i < rdepslen; i++) 1571 { 1572 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual 1573 resource used. */ 1574 int specifier = lookup_specifier (rdeps[i]->name); 1575 int regindex = lookup_regindex (rdeps[i]->name, specifier); 1576 1577 printf (" { \"%s\", %d, %d, %d, %d, ", 1578 rdeps[i]->name, specifier, 1579 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); 1580 if (rdeps[i]->semantics == IA64_DVS_OTHER) 1581 { 1582 const char *quote, *rest; 1583 1584 putchar ('\"'); 1585 rest = rdeps[i]->extra; 1586 quote = strchr (rest, '\"'); 1587 while (quote != NULL) 1588 { 1589 printf ("%.*s\\\"", (int) (quote - rest), rest); 1590 rest = quote + 1; 1591 quote = strchr (rest, '\"'); 1592 } 1593 printf ("%s\", ", rest); 1594 } 1595 else 1596 printf ("NULL, "); 1597 printf("},\n"); 1598 } 1599 printf ("};\n\n"); 1600 1601 /* And dependency lists. */ 1602 for (i=0;i < dlistlen;i++) 1603 { 1604 unsigned int len = (unsigned) -1; 1605 printf ("static const unsigned short dep%d[] = {", i); 1606 for (j=0;j < dlists[i]->len; j++) 1607 { 1608 if (len > 74) 1609 { 1610 printf("\n "); 1611 len = 1; 1612 } 1613 len += printf (" %d,", dlists[i]->deps[j]); 1614 } 1615 printf ("\n};\n\n"); 1616 } 1617 1618 /* And opcode dependency list. */ 1619 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); 1620 printf ("static const struct ia64_opcode_dependency\n"); 1621 printf ("op_dependencies[] = {\n"); 1622 for (i = 0; i < opdeplen; i++) 1623 { 1624 printf (" { "); 1625 if (opdeps[i]->chk == -1) 1626 printf ("0, NULL, "); 1627 else 1628 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk); 1629 if (opdeps[i]->reg == -1) 1630 printf ("0, NULL, "); 1631 else 1632 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg); 1633 printf ("},\n"); 1634 } 1635 printf ("};\n\n"); 1636} 1637 1638 1639/* Add STR to the string table. */ 1640static struct string_entry * 1641insert_string (char *str) 1642{ 1643 int start = 0, end = strtablen; 1644 int i, x; 1645 1646 if (strtablen == strtabtotlen) 1647 { 1648 strtabtotlen += 20; 1649 string_table = (struct string_entry **) 1650 xrealloc (string_table, 1651 sizeof (struct string_entry **) * strtabtotlen); 1652 } 1653 1654 if (strtablen == 0) 1655 { 1656 strtablen = 1; 1657 string_table[0] = tmalloc (struct string_entry); 1658 string_table[0]->s = xstrdup (str); 1659 string_table[0]->num = 0; 1660 return string_table[0]; 1661 } 1662 1663 if (strcmp (str, string_table[strtablen - 1]->s) > 0) 1664 i = end; 1665 else if (strcmp (str, string_table[0]->s) < 0) 1666 i = 0; 1667 else 1668 { 1669 while (1) 1670 { 1671 int c; 1672 1673 i = (start + end) / 2; 1674 c = strcmp (str, string_table[i]->s); 1675 1676 if (c < 0) 1677 end = i - 1; 1678 else if (c == 0) 1679 return string_table[i]; 1680 else 1681 start = i + 1; 1682 1683 if (start > end) 1684 break; 1685 } 1686 } 1687 1688 for (; i > 0 && i < strtablen; i--) 1689 if (strcmp (str, string_table[i - 1]->s) > 0) 1690 break; 1691 1692 for (; i < strtablen; i++) 1693 if (strcmp (str, string_table[i]->s) < 0) 1694 break; 1695 1696 for (x = strtablen - 1; x >= i; x--) 1697 { 1698 string_table[x + 1] = string_table[x]; 1699 string_table[x + 1]->num = x + 1; 1700 } 1701 1702 string_table[i] = tmalloc (struct string_entry); 1703 string_table[i]->s = xstrdup (str); 1704 string_table[i]->num = i; 1705 strtablen++; 1706 1707 return string_table[i]; 1708} 1709 1710static struct bittree * 1711make_bittree_entry (void) 1712{ 1713 struct bittree *res = tmalloc (struct bittree); 1714 1715 res->disent = NULL; 1716 res->bits[0] = NULL; 1717 res->bits[1] = NULL; 1718 res->bits[2] = NULL; 1719 res->skip_flag = 0; 1720 res->bits_to_skip = 0; 1721 return res; 1722} 1723 1724 1725static struct disent * 1726add_dis_table_ent (struct disent *which, int insn, int order, 1727 ci_t completer_index) 1728{ 1729 int ci = 0; 1730 struct disent *ent; 1731 1732 if (which != NULL) 1733 { 1734 ent = which; 1735 1736 ent->nextcnt++; 1737 while (ent->nexte != NULL) 1738 ent = ent->nexte; 1739 1740 ent = (ent->nexte = tmalloc (struct disent)); 1741 } 1742 else 1743 { 1744 ent = tmalloc (struct disent); 1745 ent->next_ent = disinsntable; 1746 disinsntable = ent; 1747 which = ent; 1748 } 1749 ent->nextcnt = 0; 1750 ent->nexte = NULL; 1751 ent->insn = insn; 1752 ent->priority = order; 1753 1754 while (completer_index != 1) 1755 { 1756 ci = (ci << 1) | (completer_index & 1); 1757 completer_index >>= 1; 1758 } 1759 ent->completer_index = ci; 1760 return which; 1761} 1762 1763static void 1764finish_distable (void) 1765{ 1766 struct disent *ent = disinsntable; 1767 struct disent *prev = ent; 1768 1769 ent->ournum = 32768; 1770 while ((ent = ent->next_ent) != NULL) 1771 { 1772 ent->ournum = prev->ournum + prev->nextcnt + 1; 1773 prev = ent; 1774 } 1775} 1776 1777static void 1778insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode, 1779 ia64_insn mask, int opcodenum, int order, 1780 ci_t completer_index) 1781{ 1782 ia64_insn m; 1783 int b; 1784 struct bittree *next; 1785 1786 if (bit == -1) 1787 { 1788 struct disent *nent = add_dis_table_ent (curr_ent->disent, 1789 opcodenum, order, 1790 completer_index); 1791 curr_ent->disent = nent; 1792 return; 1793 } 1794 1795 m = ((ia64_insn) 1) << bit; 1796 1797 if (mask & m) 1798 b = (opcode & m) ? 1 : 0; 1799 else 1800 b = 2; 1801 1802 next = curr_ent->bits[b]; 1803 if (next == NULL) 1804 { 1805 next = make_bittree_entry (); 1806 curr_ent->bits[b] = next; 1807 } 1808 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order, 1809 completer_index); 1810} 1811 1812static void 1813add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask, 1814 int opcodenum, struct completer_entry *ent, ci_t completer_index) 1815{ 1816 if (completer_index & ((ci_t)1 << 32) ) 1817 abort (); 1818 1819 while (ent != NULL) 1820 { 1821 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits; 1822 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, 1823 (completer_index << 1) | 1); 1824 1825 if (ent->is_terminal) 1826 { 1827 insert_bit_table_ent (bittree, 40, newopcode, mask, 1828 opcodenum, opcode_count - ent->order - 1, 1829 (completer_index << 1) | 1); 1830 } 1831 completer_index <<= 1; 1832 ent = ent->alternative; 1833 } 1834} 1835 1836/* This optimization pass combines multiple "don't care" nodes. */ 1837static void 1838compact_distree (struct bittree *ent) 1839{ 1840#define IS_SKIP(ent) \ 1841 ((ent->bits[2] !=NULL) \ 1842 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0)) 1843 1844 int bitcnt = 0; 1845 struct bittree *nent = ent; 1846 int x; 1847 1848 while (IS_SKIP (nent)) 1849 { 1850 bitcnt++; 1851 nent = nent->bits[2]; 1852 } 1853 1854 if (bitcnt) 1855 { 1856 struct bittree *next = ent->bits[2]; 1857 1858 ent->bits[0] = nent->bits[0]; 1859 ent->bits[1] = nent->bits[1]; 1860 ent->bits[2] = nent->bits[2]; 1861 ent->disent = nent->disent; 1862 ent->skip_flag = 1; 1863 ent->bits_to_skip = bitcnt; 1864 while (next != nent) 1865 { 1866 struct bittree *b = next; 1867 next = next->bits[2]; 1868 free (b); 1869 } 1870 free (nent); 1871 } 1872 1873 for (x = 0; x < 3; x++) 1874 { 1875 struct bittree *i = ent->bits[x]; 1876 1877 if (i != NULL) 1878 compact_distree (i); 1879 } 1880} 1881 1882static unsigned char *insn_list; 1883static int insn_list_len = 0; 1884static int tot_insn_list_len = 0; 1885 1886/* Generate the disassembler state machine corresponding to the tree 1887 in ENT. */ 1888static void 1889gen_dis_table (struct bittree *ent) 1890{ 1891 int x; 1892 int our_offset = insn_list_len; 1893 int bitsused = 5; 1894 int totbits = bitsused; 1895 int needed_bytes; 1896 int zero_count = 0; 1897 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */ 1898 1899 /* If this is a terminal entry, there's no point in skipping any 1900 bits. */ 1901 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL && 1902 ent->bits[2] == NULL) 1903 { 1904 if (ent->disent == NULL) 1905 abort (); 1906 else 1907 ent->skip_flag = 0; 1908 } 1909 1910 /* Calculate the amount of space needed for this entry, or at least 1911 a conservatively large approximation. */ 1912 if (ent->skip_flag) 1913 totbits += 5; 1914 1915 for (x = 1; x < 3; x++) 1916 if (ent->bits[x] != NULL) 1917 totbits += 16; 1918 1919 if (ent->disent != NULL) 1920 { 1921 if (ent->bits[2] != NULL) 1922 abort (); 1923 1924 totbits += 16; 1925 } 1926 1927 /* Now allocate the space. */ 1928 needed_bytes = (totbits + 7) / 8; 1929 if ((needed_bytes + insn_list_len) > tot_insn_list_len) 1930 { 1931 tot_insn_list_len += 256; 1932 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len); 1933 } 1934 our_offset = insn_list_len; 1935 insn_list_len += needed_bytes; 1936 memset (insn_list + our_offset, 0, needed_bytes); 1937 1938 /* Encode the skip entry by setting bit 6 set in the state op field, 1939 and store the # of bits to skip immediately after. */ 1940 if (ent->skip_flag) 1941 { 1942 bitsused += 5; 1943 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf); 1944 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6); 1945 } 1946 1947#define IS_ONLY_IFZERO(ENT) \ 1948 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \ 1949 && (ENT)->disent == NULL && (ENT)->skip_flag == 0) 1950 1951 /* Store an "if (bit is zero)" instruction by setting bit 7 in the 1952 state op field. */ 1953 if (ent->bits[0] != NULL) 1954 { 1955 struct bittree *nent = ent->bits[0]; 1956 zero_count = 0; 1957 1958 insn_list[our_offset] |= 0x80; 1959 1960 /* We can encode sequences of multiple "if (bit is zero)" tests 1961 by storing the # of zero bits to check in the lower 3 bits of 1962 the instruction. However, this only applies if the state 1963 solely tests for a zero bit. */ 1964 1965 if (IS_ONLY_IFZERO (ent)) 1966 { 1967 while (IS_ONLY_IFZERO (nent) && zero_count < 7) 1968 { 1969 nent = nent->bits[0]; 1970 zero_count++; 1971 } 1972 1973 insn_list[our_offset + 0] |= zero_count; 1974 } 1975 zero_dest = insn_list_len; 1976 gen_dis_table (nent); 1977 } 1978 1979 /* Now store the remaining tests. We also handle a sole "termination 1980 entry" by storing it as an "any bit" test. */ 1981 1982 for (x = 1; x < 3; x++) 1983 { 1984 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL)) 1985 { 1986 struct bittree *i = ent->bits[x]; 1987 int idest; 1988 int currbits = 15; 1989 1990 if (i != NULL) 1991 { 1992 /* If the instruction being branched to only consists of 1993 a termination entry, use the termination entry as the 1994 place to branch to instead. */ 1995 if (i->bits[0] == NULL && i->bits[1] == NULL 1996 && i->bits[2] == NULL && i->disent != NULL) 1997 { 1998 idest = i->disent->ournum; 1999 i = NULL; 2000 } 2001 else 2002 idest = insn_list_len - our_offset; 2003 } 2004 else 2005 idest = ent->disent->ournum; 2006 2007 /* If the destination offset for the if (bit is 1) test is less 2008 than 256 bytes away, we can store it as 8-bits instead of 16; 2009 the instruction has bit 5 set for the 16-bit address, and bit 2010 4 for the 8-bit address. Since we've already allocated 16 2011 bits for the address we need to deallocate the space. 2012 2013 Note that branchings within the table are relative, and 2014 there are no branches that branch past our instruction yet 2015 so we do not need to adjust any other offsets. */ 2016 if (x == 1) 2017 { 2018 if (idest <= 256) 2019 { 2020 int start = our_offset + bitsused / 8 + 1; 2021 2022 memmove (insn_list + start, 2023 insn_list + start + 1, 2024 insn_list_len - (start + 1)); 2025 currbits = 7; 2026 totbits -= 8; 2027 needed_bytes--; 2028 insn_list_len--; 2029 insn_list[our_offset] |= 0x10; 2030 idest--; 2031 } 2032 else 2033 insn_list[our_offset] |= 0x20; 2034 } 2035 else 2036 { 2037 /* An instruction which solely consists of a termination 2038 marker and whose disassembly name index is < 4096 2039 can be stored in 16 bits. The encoding is slightly 2040 odd; the upper 4 bits of the instruction are 0x3, and 2041 bit 3 loses its normal meaning. */ 2042 2043 if (ent->bits[0] == NULL && ent->bits[1] == NULL 2044 && ent->bits[2] == NULL && ent->skip_flag == 0 2045 && ent->disent != NULL 2046 && ent->disent->ournum < (32768 + 4096)) 2047 { 2048 int start = our_offset + bitsused / 8 + 1; 2049 2050 memmove (insn_list + start, 2051 insn_list + start + 1, 2052 insn_list_len - (start + 1)); 2053 currbits = 11; 2054 totbits -= 5; 2055 bitsused--; 2056 needed_bytes--; 2057 insn_list_len--; 2058 insn_list[our_offset] |= 0x30; 2059 idest &= ~32768; 2060 } 2061 else 2062 insn_list[our_offset] |= 0x08; 2063 } 2064 2065 if (debug) 2066 { 2067 int id = idest; 2068 2069 if (i == NULL) 2070 id |= 32768; 2071 else if (! (id & 32768)) 2072 id += our_offset; 2073 2074 if (x == 1) 2075 printf ("%d: if (1) goto %d\n", our_offset, id); 2076 else 2077 printf ("%d: try %d\n", our_offset, id); 2078 } 2079 2080 /* Store the address of the entry being branched to. */ 2081 while (currbits >= 0) 2082 { 2083 unsigned char *byte = insn_list + our_offset + bitsused / 8; 2084 2085 if (idest & (1 << currbits)) 2086 *byte |= (1 << (7 - (bitsused % 8))); 2087 2088 bitsused++; 2089 currbits--; 2090 } 2091 2092 /* Now generate the states for the entry being branched to. */ 2093 if (i != NULL) 2094 gen_dis_table (i); 2095 } 2096 } 2097 2098 if (debug) 2099 { 2100 if (ent->skip_flag) 2101 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip); 2102 2103 if (ent->bits[0] != NULL) 2104 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1, 2105 zero_dest); 2106 } 2107 2108 if (bitsused != totbits) 2109 abort (); 2110} 2111 2112static void 2113print_dis_table (void) 2114{ 2115 int x; 2116 struct disent *cent = disinsntable; 2117 2118 printf ("static const char dis_table[] = {"); 2119 for (x = 0; x < insn_list_len; x++) 2120 { 2121 if (x % 12 == 0) 2122 printf ("\n "); 2123 2124 printf (" 0x%02x,", insn_list[x]); 2125 } 2126 printf ("\n};\n\n"); 2127 2128 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n"); 2129 while (cent != NULL) 2130 { 2131 struct disent *ent = cent; 2132 2133 while (ent != NULL) 2134 { 2135 printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent->completer_index, 2136 ent->insn, (ent->nexte != NULL ? 1 : 0), 2137 ent->priority); 2138 ent = ent->nexte; 2139 } 2140 cent = cent->next_ent; 2141 } 2142 printf ("};\n\n"); 2143} 2144 2145static void 2146generate_disassembler (void) 2147{ 2148 int i; 2149 2150 bittree = make_bittree_entry (); 2151 2152 for (i = 0; i < otlen; i++) 2153 { 2154 struct main_entry *ptr = ordered_table[i]; 2155 2156 if (ptr->opcode->type != IA64_TYPE_DYN) 2157 add_dis_entry (bittree, 2158 ptr->opcode->opcode, ptr->opcode->mask, 2159 ptr->main_index, 2160 ptr->completers, 1); 2161 } 2162 2163 compact_distree (bittree); 2164 finish_distable (); 2165 gen_dis_table (bittree); 2166 2167 print_dis_table (); 2168} 2169 2170static void 2171print_string_table (void) 2172{ 2173 int x; 2174 char lbuf[80], buf[80]; 2175 int blen = 0; 2176 2177 printf ("static const char * const ia64_strings[] = {\n"); 2178 lbuf[0] = '\0'; 2179 2180 for (x = 0; x < strtablen; x++) 2181 { 2182 int len; 2183 2184 if (strlen (string_table[x]->s) > 75) 2185 abort (); 2186 2187 sprintf (buf, " \"%s\",", string_table[x]->s); 2188 len = strlen (buf); 2189 2190 if ((blen + len) > 75) 2191 { 2192 printf (" %s\n", lbuf); 2193 lbuf[0] = '\0'; 2194 blen = 0; 2195 } 2196 strcat (lbuf, buf); 2197 blen += len; 2198 } 2199 2200 if (blen > 0) 2201 printf (" %s\n", lbuf); 2202 2203 printf ("};\n\n"); 2204} 2205 2206static struct completer_entry **glist; 2207static int glistlen = 0; 2208static int glisttotlen = 0; 2209 2210/* If the completer trees ENT1 and ENT2 are equal, return 1. */ 2211 2212static int 2213completer_entries_eq (struct completer_entry *ent1, 2214 struct completer_entry *ent2) 2215{ 2216 while (ent1 != NULL && ent2 != NULL) 2217 { 2218 if (ent1->name->num != ent2->name->num 2219 || ent1->bits != ent2->bits 2220 || ent1->mask != ent2->mask 2221 || ent1->is_terminal != ent2->is_terminal 2222 || ent1->dependencies != ent2->dependencies 2223 || ent1->order != ent2->order) 2224 return 0; 2225 2226 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries)) 2227 return 0; 2228 2229 ent1 = ent1->alternative; 2230 ent2 = ent2->alternative; 2231 } 2232 2233 return ent1 == ent2; 2234} 2235 2236/* Insert ENT into the global list of completers and return it. If an 2237 equivalent entry (according to completer_entries_eq) already exists, 2238 it is returned instead. */ 2239static struct completer_entry * 2240insert_gclist (struct completer_entry *ent) 2241{ 2242 if (ent != NULL) 2243 { 2244 int i; 2245 int x; 2246 int start = 0, end; 2247 2248 ent->addl_entries = insert_gclist (ent->addl_entries); 2249 ent->alternative = insert_gclist (ent->alternative); 2250 2251 i = glistlen / 2; 2252 end = glistlen; 2253 2254 if (glisttotlen == glistlen) 2255 { 2256 glisttotlen += 20; 2257 glist = (struct completer_entry **) 2258 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen); 2259 } 2260 2261 if (glistlen == 0) 2262 { 2263 glist[0] = ent; 2264 glistlen = 1; 2265 return ent; 2266 } 2267 2268 if (ent->name->num < glist[0]->name->num) 2269 i = 0; 2270 else if (ent->name->num > glist[end - 1]->name->num) 2271 i = end; 2272 else 2273 { 2274 int c; 2275 2276 while (1) 2277 { 2278 i = (start + end) / 2; 2279 c = ent->name->num - glist[i]->name->num; 2280 2281 if (c < 0) 2282 end = i - 1; 2283 else if (c == 0) 2284 { 2285 while (i > 0 2286 && ent->name->num == glist[i - 1]->name->num) 2287 i--; 2288 2289 break; 2290 } 2291 else 2292 start = i + 1; 2293 2294 if (start > end) 2295 break; 2296 } 2297 2298 if (c == 0) 2299 { 2300 while (i < glistlen) 2301 { 2302 if (ent->name->num != glist[i]->name->num) 2303 break; 2304 2305 if (completer_entries_eq (ent, glist[i])) 2306 return glist[i]; 2307 2308 i++; 2309 } 2310 } 2311 } 2312 2313 for (; i > 0 && i < glistlen; i--) 2314 if (ent->name->num >= glist[i - 1]->name->num) 2315 break; 2316 2317 for (; i < glistlen; i++) 2318 if (ent->name->num < glist[i]->name->num) 2319 break; 2320 2321 for (x = glistlen - 1; x >= i; x--) 2322 glist[x + 1] = glist[x]; 2323 2324 glist[i] = ent; 2325 glistlen++; 2326 } 2327 return ent; 2328} 2329 2330static int 2331get_prefix_len (const char *name) 2332{ 2333 char *c; 2334 2335 if (name[0] == '\0') 2336 return 0; 2337 2338 c = strchr (name, '.'); 2339 if (c != NULL) 2340 return c - name; 2341 else 2342 return strlen (name); 2343} 2344 2345static void 2346compute_completer_bits (struct main_entry *ment, struct completer_entry *ent) 2347{ 2348 while (ent != NULL) 2349 { 2350 compute_completer_bits (ment, ent->addl_entries); 2351 2352 if (ent->is_terminal) 2353 { 2354 ia64_insn mask = 0; 2355 ia64_insn our_bits = ent->bits; 2356 struct completer_entry *p = ent->parent; 2357 ia64_insn p_bits; 2358 int x; 2359 2360 while (p != NULL && ! p->is_terminal) 2361 p = p->parent; 2362 2363 if (p != NULL) 2364 p_bits = p->bits; 2365 else 2366 p_bits = ment->opcode->opcode; 2367 2368 for (x = 0; x < 64; x++) 2369 { 2370 ia64_insn m = ((ia64_insn) 1) << x; 2371 2372 if ((p_bits & m) != (our_bits & m)) 2373 mask |= m; 2374 else 2375 our_bits &= ~m; 2376 } 2377 ent->bits = our_bits; 2378 ent->mask = mask; 2379 } 2380 else 2381 { 2382 ent->bits = 0; 2383 ent->mask = 0; 2384 } 2385 2386 ent = ent->alternative; 2387 } 2388} 2389 2390/* Find identical completer trees that are used in different 2391 instructions and collapse their entries. */ 2392static void 2393collapse_redundant_completers (void) 2394{ 2395 struct main_entry *ptr; 2396 int x; 2397 2398 for (ptr = maintable; ptr != NULL; ptr = ptr->next) 2399 { 2400 if (ptr->completers == NULL) 2401 abort (); 2402 2403 compute_completer_bits (ptr, ptr->completers); 2404 ptr->completers = insert_gclist (ptr->completers); 2405 } 2406 2407 /* The table has been finalized, now number the indexes. */ 2408 for (x = 0; x < glistlen; x++) 2409 glist[x]->num = x; 2410} 2411 2412 2413/* Attach two lists of dependencies to each opcode. 2414 1) all resources which, when already marked in use, conflict with this 2415 opcode (chks) 2416 2) all resources which must be marked in use when this opcode is used 2417 (regs). */ 2418static int 2419insert_opcode_dependencies (struct ia64_opcode *opc, 2420 struct completer_entry *cmp ATTRIBUTE_UNUSED) 2421{ 2422 /* Note all resources which point to this opcode. rfi has the most chks 2423 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ 2424 int i; 2425 int nregs = 0; 2426 unsigned short regs[256]; 2427 int nchks = 0; 2428 unsigned short chks[256]; 2429 /* Flag insns for which no class matched; there should be none. */ 2430 int no_class_found = 1; 2431 2432 for (i = 0; i < rdepslen; i++) 2433 { 2434 struct rdep *rs = rdeps[i]; 2435 int j; 2436 2437 if (strcmp (opc->name, "cmp.eq.and") == 0 2438 && startswith (rs->name, "PR%") 2439 && rs->mode == 1) 2440 no_class_found = 99; 2441 2442 for (j=0; j < rs->nregs;j++) 2443 { 2444 int ic_note = 0; 2445 2446 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) 2447 { 2448 /* We can ignore ic_note 11 for non PR resources. */ 2449 if (ic_note == 11 && ! startswith (rs->name, "PR")) 2450 ic_note = 0; 2451 2452 if (ic_note != 0 && rs->regnotes[j] != 0 2453 && ic_note != rs->regnotes[j] 2454 && !(ic_note == 11 && rs->regnotes[j] == 1)) 2455 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2456 ic_note, opc->name, ics[rs->regs[j]]->name, 2457 rs->name, rs->regnotes[j]); 2458 /* Instruction class notes override resource notes. 2459 So far, only note 11 applies to an IC instead of a resource, 2460 and note 11 implies note 1. */ 2461 if (ic_note) 2462 regs[nregs++] = RDEP(ic_note, i); 2463 else 2464 regs[nregs++] = RDEP(rs->regnotes[j], i); 2465 no_class_found = 0; 2466 ++rs->total_regs; 2467 } 2468 } 2469 2470 for (j = 0; j < rs->nchks; j++) 2471 { 2472 int ic_note = 0; 2473 2474 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) 2475 { 2476 /* We can ignore ic_note 11 for non PR resources. */ 2477 if (ic_note == 11 && ! startswith (rs->name, "PR")) 2478 ic_note = 0; 2479 2480 if (ic_note != 0 && rs->chknotes[j] != 0 2481 && ic_note != rs->chknotes[j] 2482 && !(ic_note == 11 && rs->chknotes[j] == 1)) 2483 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2484 ic_note, opc->name, ics[rs->chks[j]]->name, 2485 rs->name, rs->chknotes[j]); 2486 if (ic_note) 2487 chks[nchks++] = RDEP(ic_note, i); 2488 else 2489 chks[nchks++] = RDEP(rs->chknotes[j], i); 2490 no_class_found = 0; 2491 ++rs->total_chks; 2492 } 2493 } 2494 } 2495 2496 if (no_class_found) 2497 warn (_("opcode %s has no class (ops %d %d %d)\n"), 2498 opc->name, 2499 opc->operands[0], opc->operands[1], opc->operands[2]); 2500 2501 return insert_dependencies (nchks, chks, nregs, regs); 2502} 2503 2504static void 2505insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent, 2506 int order) 2507{ 2508 struct completer_entry **ptr = &tabent->completers; 2509 struct completer_entry *parent = NULL; 2510 char pcopy[129], *prefix; 2511 int at_end = 0; 2512 2513 if (strlen (opc->name) > 128) 2514 abort (); 2515 2516 strcpy (pcopy, opc->name); 2517 prefix = pcopy + get_prefix_len (pcopy); 2518 2519 if (prefix[0] != '\0') 2520 prefix++; 2521 2522 while (! at_end) 2523 { 2524 int need_new_ent = 1; 2525 int plen = get_prefix_len (prefix); 2526 struct string_entry *sent; 2527 2528 at_end = (prefix[plen] == '\0'); 2529 prefix[plen] = '\0'; 2530 sent = insert_string (prefix); 2531 2532 while (*ptr != NULL) 2533 { 2534 int cmpres = sent->num - (*ptr)->name->num; 2535 2536 if (cmpres == 0) 2537 { 2538 need_new_ent = 0; 2539 break; 2540 } 2541 else 2542 ptr = &((*ptr)->alternative); 2543 } 2544 2545 if (need_new_ent) 2546 { 2547 struct completer_entry *nent = tmalloc (struct completer_entry); 2548 2549 nent->name = sent; 2550 nent->parent = parent; 2551 nent->addl_entries = NULL; 2552 nent->alternative = *ptr; 2553 *ptr = nent; 2554 nent->is_terminal = 0; 2555 nent->dependencies = -1; 2556 } 2557 2558 if (! at_end) 2559 { 2560 parent = *ptr; 2561 ptr = &((*ptr)->addl_entries); 2562 prefix += plen + 1; 2563 } 2564 } 2565 2566 if ((*ptr)->is_terminal) 2567 abort (); 2568 2569 (*ptr)->is_terminal = 1; 2570 (*ptr)->mask = (ia64_insn)-1; 2571 (*ptr)->bits = opc->opcode; 2572 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr); 2573 (*ptr)->order = order; 2574} 2575 2576static void 2577print_completer_entry (struct completer_entry *ent) 2578{ 2579 int moffset = 0; 2580 ia64_insn mask = ent->mask, bits = ent->bits; 2581 2582 if (mask != 0) 2583 { 2584 while (! (mask & 1)) 2585 { 2586 moffset++; 2587 mask = mask >> 1; 2588 bits = bits >> 1; 2589 } 2590 2591 if (bits & 0xffffffff00000000LL) 2592 abort (); 2593 } 2594 2595 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n", 2596 (int)bits, 2597 (int)mask, 2598 ent->name->num, 2599 ent->alternative != NULL ? ent->alternative->num : -1, 2600 ent->addl_entries != NULL ? ent->addl_entries->num : -1, 2601 moffset, 2602 ent->is_terminal ? 1 : 0, 2603 ent->dependencies); 2604} 2605 2606static void 2607print_completer_table (void) 2608{ 2609 int x; 2610 2611 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n"); 2612 for (x = 0; x < glistlen; x++) 2613 print_completer_entry (glist[x]); 2614 printf ("};\n\n"); 2615} 2616 2617static int 2618opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2) 2619{ 2620 int x; 2621 int plen1, plen2; 2622 2623 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 2624 || (opc1->num_outputs != opc2->num_outputs) 2625 || (opc1->flags != opc2->flags)) 2626 return 0; 2627 2628 for (x = 0; x < 5; x++) 2629 if (opc1->operands[x] != opc2->operands[x]) 2630 return 0; 2631 2632 plen1 = get_prefix_len (opc1->name); 2633 plen2 = get_prefix_len (opc2->name); 2634 2635 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0)) 2636 return 1; 2637 2638 return 0; 2639} 2640 2641static void 2642add_opcode_entry (struct ia64_opcode *opc) 2643{ 2644 struct main_entry **place; 2645 struct string_entry *name; 2646 char prefix[129]; 2647 int found_it = 0; 2648 2649 if (strlen (opc->name) > 128) 2650 abort (); 2651 2652 place = &maintable; 2653 strcpy (prefix, opc->name); 2654 prefix[get_prefix_len (prefix)] = '\0'; 2655 name = insert_string (prefix); 2656 2657 /* Walk the list of opcode table entries. If it's a new 2658 instruction, allocate and fill in a new entry. Note 2659 the main table is alphabetical by opcode name. */ 2660 2661 while (*place != NULL) 2662 { 2663 if ((*place)->name->num == name->num 2664 && opcodes_eq ((*place)->opcode, opc)) 2665 { 2666 found_it = 1; 2667 break; 2668 } 2669 if ((*place)->name->num > name->num) 2670 break; 2671 2672 place = &((*place)->next); 2673 } 2674 if (! found_it) 2675 { 2676 struct main_entry *nent = tmalloc (struct main_entry); 2677 2678 nent->name = name; 2679 nent->opcode = opc; 2680 nent->next = *place; 2681 nent->completers = 0; 2682 *place = nent; 2683 2684 if (otlen == ottotlen) 2685 { 2686 ottotlen += 20; 2687 ordered_table = (struct main_entry **) 2688 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen); 2689 } 2690 ordered_table[otlen++] = nent; 2691 } 2692 2693 insert_completer_entry (opc, *place, opcode_count++); 2694} 2695 2696static void 2697print_main_table (void) 2698{ 2699 struct main_entry *ptr = maintable; 2700 int tindex = 0; 2701 2702 printf ("static const struct ia64_main_table\nmain_table[] = {\n"); 2703 while (ptr != NULL) 2704 { 2705 printf (" { %d, %d, %d, 0x%016" PRIx64 "ull, 0x%016" PRIx64 2706 "ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n", 2707 ptr->name->num, 2708 ptr->opcode->type, 2709 ptr->opcode->num_outputs, 2710 ptr->opcode->opcode, 2711 ptr->opcode->mask, 2712 ptr->opcode->operands[0], 2713 ptr->opcode->operands[1], 2714 ptr->opcode->operands[2], 2715 ptr->opcode->operands[3], 2716 ptr->opcode->operands[4], 2717 ptr->opcode->flags, 2718 ptr->completers->num); 2719 2720 ptr->main_index = tindex++; 2721 2722 ptr = ptr->next; 2723 } 2724 printf ("};\n\n"); 2725} 2726 2727static void 2728shrink (struct ia64_opcode *table) 2729{ 2730 int curr_opcode; 2731 2732 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++) 2733 { 2734 add_opcode_entry (table + curr_opcode); 2735 if (table[curr_opcode].num_outputs == 2 2736 && ((table[curr_opcode].operands[0] == IA64_OPND_P1 2737 && table[curr_opcode].operands[1] == IA64_OPND_P2) 2738 || (table[curr_opcode].operands[0] == IA64_OPND_P2 2739 && table[curr_opcode].operands[1] == IA64_OPND_P1))) 2740 { 2741 struct ia64_opcode *alias = tmalloc(struct ia64_opcode); 2742 unsigned i; 2743 2744 *alias = table[curr_opcode]; 2745 for (i = 2; i < NELEMS (alias->operands); ++i) 2746 alias->operands[i - 1] = alias->operands[i]; 2747 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL; 2748 --alias->num_outputs; 2749 alias->flags |= PSEUDO; 2750 add_opcode_entry (alias); 2751 } 2752 } 2753} 2754 2755 2756/* Program options. */ 2757#define OPTION_SRCDIR 200 2758 2759struct option long_options[] = 2760{ 2761 {"srcdir", required_argument, NULL, OPTION_SRCDIR}, 2762 {"debug", no_argument, NULL, 'd'}, 2763 {"version", no_argument, NULL, 'V'}, 2764 {"help", no_argument, NULL, 'h'}, 2765 {0, no_argument, NULL, 0} 2766}; 2767 2768static void 2769print_version (void) 2770{ 2771 printf ("%s: version 1.0\n", program_name); 2772 xexit (0); 2773} 2774 2775static void 2776usage (FILE * stream, int status) 2777{ 2778 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n", 2779 program_name); 2780 xexit (status); 2781} 2782 2783int 2784main (int argc, char **argv) 2785{ 2786 extern int chdir (char *); 2787 char *srcdir = NULL; 2788 int c; 2789 2790 program_name = *argv; 2791 xmalloc_set_program_name (program_name); 2792 2793 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF) 2794 switch (c) 2795 { 2796 case OPTION_SRCDIR: 2797 srcdir = optarg; 2798 break; 2799 case 'V': 2800 case 'v': 2801 print_version (); 2802 break; 2803 case 'd': 2804 debug = 1; 2805 break; 2806 case 'h': 2807 case '?': 2808 usage (stderr, 0); 2809 default: 2810 case 0: 2811 break; 2812 } 2813 2814 if (optind != argc) 2815 usage (stdout, 1); 2816 2817 if (srcdir != NULL) 2818 if (chdir (srcdir) != 0) 2819 fail (_("unable to change directory to \"%s\", errno = %s\n"), 2820 srcdir, strerror (errno)); 2821 2822 load_insn_classes (); 2823 load_dependencies (); 2824 2825 shrink (ia64_opcodes_a); 2826 shrink (ia64_opcodes_b); 2827 shrink (ia64_opcodes_f); 2828 shrink (ia64_opcodes_i); 2829 shrink (ia64_opcodes_m); 2830 shrink (ia64_opcodes_x); 2831 shrink (ia64_opcodes_d); 2832 2833 collapse_redundant_completers (); 2834 2835 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); 2836 printf ("/* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\ 2837\n\ 2838 This file is part of the GNU opcodes library.\n\ 2839\n\ 2840 This library is free software; you can redistribute it and/or modify\n\ 2841 it under the terms of the GNU General Public License as published by\n\ 2842 the Free Software Foundation; either version 3, or (at your option)\n\ 2843 any later version.\n\ 2844\n\ 2845 It is distributed in the hope that it will be useful, but WITHOUT\n\ 2846 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\ 2847 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\ 2848 License for more details.\n\ 2849\n\ 2850 You should have received a copy of the GNU General Public License\n\ 2851 along with this program; see the file COPYING. If not, write to the\n\ 2852 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\ 2853 02110-1301, USA. */\n"); 2854 2855 print_string_table (); 2856 print_dependency_table (); 2857 print_completer_table (); 2858 print_main_table (); 2859 2860 generate_disassembler (); 2861 2862 exit (0); 2863} 2864