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