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