ia64-gen.c revision 256281
1/* ia64-gen.c -- Generate a shrunk set of opcode tables 2 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006 3 Free Software Foundation, Inc. 4 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com> 5 6 This file is part of GDB, GAS, and the GNU binutils. 7 8 GDB, GAS, and the GNU binutils are free software; you can redistribute 9 them and/or modify them under the terms of the GNU General Public 10 License as published by the Free Software Foundation; either version 11 2, or (at your option) any later version. 12 13 GDB, GAS, and the GNU binutils are distributed in the hope that they 14 will be useful, but WITHOUT ANY WARRANTY; without even the implied 15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 the GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this file; see the file COPYING. If not, write to the 20 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21 02110-1301, USA. */ 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 <stdio.h> 37#include <stdarg.h> 38#include <errno.h> 39 40#include "ansidecl.h" 41#include "libiberty.h" 42#include "safe-ctype.h" 43#include "sysdep.h" 44#include "getopt.h" 45#include "ia64-opc.h" 46#include "ia64-opc-a.c" 47#include "ia64-opc-i.c" 48#include "ia64-opc-m.c" 49#include "ia64-opc-b.c" 50#include "ia64-opc-f.c" 51#include "ia64-opc-x.c" 52#include "ia64-opc-d.c" 53 54#include <libintl.h> 55#define _(String) gettext (String) 56 57/* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this 58 always, because we might be compiled without BFD64 defined, if configured 59 for a 32-bit target and --enable-targets=all is used. This will work for 60 both 32-bit and 64-bit hosts. */ 61#define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) 62#define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) 63#define opcode_fprintf_vma(s,x) \ 64 fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x)) 65 66const char * program_name = NULL; 67int debug = 0; 68 69#define NELEMS(a) (sizeof (a) / sizeof ((a)[0])) 70#define tmalloc(X) (X *) xmalloc (sizeof (X)) 71 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 int 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, int); 294static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int); 295static void compact_distree (struct bittree *); 296static struct bittree * make_bittree_entry (void); 297static struct disent * add_dis_table_ent (struct disent *, int, int, int); 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 (ref, usersp, nusersp, notesp) 697 const char *ref; 698 int **usersp; 699 int *nusersp; 700 int **notesp; 701{ 702 int c; 703 char *line = xstrdup (ref); 704 char *tmp = line; 705 int *users = *usersp; 706 int count = *nusersp; 707 int *notes = *notesp; 708 709 c = *tmp; 710 while (c != 0) 711 { 712 char *notestr; 713 int note; 714 char *xsect; 715 int iclass; 716 int create = 0; 717 char *name; 718 719 while (ISSPACE (*tmp)) 720 ++tmp; 721 name = tmp; 722 while (*tmp && *tmp != ',') 723 ++tmp; 724 c = *tmp; 725 *tmp++ = '\0'; 726 727 xsect = strchr (name, '\\'); 728 if ((notestr = strstr (name, "+")) != NULL) 729 { 730 char *nextnotestr; 731 732 note = atoi (notestr + 1); 733 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 734 { 735 /* Note 13 always implies note 1. */ 736 if (strcmp (notestr, "+1+13") == 0) 737 note = 13; 738 else if (!xsect || nextnotestr < xsect) 739 warn (_("multiple note %s not handled\n"), notestr); 740 } 741 if (!xsect) 742 *notestr = '\0'; 743 } 744 else 745 note = 0; 746 747 /* All classes are created when the insn class table is parsed; 748 Individual instructions might not appear until the dependency tables 749 are read. Only create new classes if it's *not* an insn class, 750 or if it's a composite class (which wouldn't necessarily be in the IC 751 table). */ 752 if (! CONST_STRNEQ (name, "IC:") || xsect != NULL) 753 create = 1; 754 755 iclass = fetch_insn_class (name, create); 756 if (iclass != -1) 757 { 758 users = (int *) 759 xrealloc ((void *) users,(count + 1) * sizeof (int)); 760 notes = (int *) 761 xrealloc ((void *) notes,(count + 1) * sizeof (int)); 762 notes[count] = note; 763 users[count++] = iclass; 764 mark_used (ics[iclass], 0); 765 } 766 else if (debug) 767 printf("Class %s not found\n", name); 768 } 769 /* Update the return values. */ 770 *usersp = users; 771 *nusersp = count; 772 *notesp = notes; 773 774 free (line); 775} 776 777static int 778parse_semantics (char *sem) 779{ 780 if (strcmp (sem, "none") == 0) 781 return IA64_DVS_NONE; 782 else if (strcmp (sem, "implied") == 0) 783 return IA64_DVS_IMPLIED; 784 else if (strcmp (sem, "impliedF") == 0) 785 return IA64_DVS_IMPLIEDF; 786 else if (strcmp (sem, "data") == 0) 787 return IA64_DVS_DATA; 788 else if (strcmp (sem, "instr") == 0) 789 return IA64_DVS_INSTR; 790 else if (strcmp (sem, "specific") == 0) 791 return IA64_DVS_SPECIFIC; 792 else if (strcmp (sem, "stop") == 0) 793 return IA64_DVS_STOP; 794 else 795 return IA64_DVS_OTHER; 796} 797 798static void 799add_dep (const char *name, const char *chk, const char *reg, 800 int semantics, int mode, char *extra, int flag) 801{ 802 struct rdep *rs; 803 804 rs = insert_resource (name, mode); 805 806 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes); 807 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes); 808 809 rs->semantics = semantics; 810 rs->extra = extra; 811 rs->waw_special = flag; 812} 813 814static void 815load_depfile (const char *filename, enum ia64_dependency_mode mode) 816{ 817 FILE *fp = fopen (filename, "r"); 818 char buf[1024]; 819 820 if (fp == NULL) 821 fail (_("can't find %s for reading\n"), filename); 822 823 fgets (buf, sizeof(buf), fp); 824 while (!feof (fp)) 825 { 826 char *name, *tmp; 827 int semantics; 828 char *extra; 829 char *regp, *chkp; 830 831 if (fgets (buf, sizeof(buf), fp) == NULL) 832 break; 833 834 while (ISSPACE (buf[strlen (buf) - 1])) 835 buf[strlen (buf) - 1] = '\0'; 836 837 name = tmp = buf; 838 while (*tmp != ';') 839 ++tmp; 840 *tmp++ = '\0'; 841 842 while (ISSPACE (*tmp)) 843 ++tmp; 844 regp = tmp; 845 tmp = strchr (tmp, ';'); 846 if (!tmp) 847 abort (); 848 *tmp++ = 0; 849 while (ISSPACE (*tmp)) 850 ++tmp; 851 chkp = tmp; 852 tmp = strchr (tmp, ';'); 853 if (!tmp) 854 abort (); 855 *tmp++ = 0; 856 while (ISSPACE (*tmp)) 857 ++tmp; 858 semantics = parse_semantics (tmp); 859 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL; 860 861 /* For WAW entries, if the chks and regs differ, we need to enter the 862 entries in both positions so that the tables will be parsed properly, 863 without a lot of extra work. */ 864 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0) 865 { 866 add_dep (name, chkp, regp, semantics, mode, extra, 0); 867 add_dep (name, regp, chkp, semantics, mode, extra, 1); 868 } 869 else 870 { 871 add_dep (name, chkp, regp, semantics, mode, extra, 0); 872 } 873 } 874 fclose (fp); 875} 876 877static void 878load_dependencies (void) 879{ 880 load_depfile ("ia64-raw.tbl", IA64_DV_RAW); 881 load_depfile ("ia64-waw.tbl", IA64_DV_WAW); 882 load_depfile ("ia64-war.tbl", IA64_DV_WAR); 883 884 if (debug) 885 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen); 886} 887 888/* Is the given operand an indirect register file operand? */ 889static int 890irf_operand (int op, const char *field) 891{ 892 if (!field) 893 { 894 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3 895 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3 896 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3 897 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3; 898 } 899 else 900 { 901 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr")) 902 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr")) 903 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr")) 904 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr")) 905 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc")) 906 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd")) 907 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr")) 908 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid"))); 909 } 910} 911 912/* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and 913 mov_um insn classes. */ 914static int 915in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, 916 const char *format, const char *field) 917{ 918 int plain_mov = strcmp (idesc->name, "mov") == 0; 919 920 if (!format) 921 return 0; 922 923 switch (ic->name[4]) 924 { 925 default: 926 abort (); 927 case 'a': 928 { 929 int i = strcmp (idesc->name, "mov.i") == 0; 930 int m = strcmp (idesc->name, "mov.m") == 0; 931 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3; 932 int i28 = i && idesc->operands[1] == IA64_OPND_AR3; 933 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3; 934 int m31 = m && idesc->operands[1] == IA64_OPND_AR3; 935 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3; 936 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3; 937 938 /* IC:mov ar */ 939 if (i2627) 940 return strstr (format, "I26") || strstr (format, "I27"); 941 if (i28) 942 return strstr (format, "I28") != NULL; 943 if (m2930) 944 return strstr (format, "M29") || strstr (format, "M30"); 945 if (m31) 946 return strstr (format, "M31") != NULL; 947 if (pseudo0 || pseudo1) 948 return 1; 949 } 950 break; 951 case 'b': 952 { 953 int i21 = idesc->operands[0] == IA64_OPND_B1; 954 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2; 955 if (i22) 956 return strstr (format, "I22") != NULL; 957 if (i21) 958 return strstr (format, "I21") != NULL; 959 } 960 break; 961 case 'c': 962 { 963 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3; 964 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3; 965 if (m32) 966 return strstr (format, "M32") != NULL; 967 if (m33) 968 return strstr (format, "M33") != NULL; 969 } 970 break; 971 case 'i': 972 if (ic->name[5] == 'n') 973 { 974 int m42 = plain_mov && irf_operand (idesc->operands[0], field); 975 int m43 = plain_mov && irf_operand (idesc->operands[1], field); 976 if (m42) 977 return strstr (format, "M42") != NULL; 978 if (m43) 979 return strstr (format, "M43") != NULL; 980 } 981 else if (ic->name[5] == 'p') 982 { 983 return idesc->operands[1] == IA64_OPND_IP; 984 } 985 else 986 abort (); 987 break; 988 case 'p': 989 if (ic->name[5] == 'r') 990 { 991 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR; 992 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR; 993 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT; 994 if (i23) 995 return strstr (format, "I23") != NULL; 996 if (i24) 997 return strstr (format, "I24") != NULL; 998 if (i25) 999 return strstr (format, "I25") != NULL; 1000 } 1001 else if (ic->name[5] == 's') 1002 { 1003 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L; 1004 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR; 1005 if (m35) 1006 return strstr (format, "M35") != NULL; 1007 if (m36) 1008 return strstr (format, "M36") != NULL; 1009 } 1010 else 1011 abort (); 1012 break; 1013 case 'u': 1014 { 1015 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM; 1016 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM; 1017 if (m35) 1018 return strstr (format, "M35") != NULL; 1019 if (m36) 1020 return strstr (format, "M36") != NULL; 1021 } 1022 break; 1023 } 1024 return 0; 1025} 1026 1027/* Is the given opcode in the given insn class? */ 1028static int 1029in_iclass (struct ia64_opcode *idesc, struct iclass *ic, 1030 const char *format, const char *field, int *notep) 1031{ 1032 int i; 1033 int resolved = 0; 1034 1035 if (ic->comment) 1036 { 1037 if (CONST_STRNEQ (ic->comment, "Format")) 1038 { 1039 /* Assume that the first format seen is the most restrictive, and 1040 only keep a later one if it looks like it's more restrictive. */ 1041 if (format) 1042 { 1043 if (strlen (ic->comment) < strlen (format)) 1044 { 1045 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"), 1046 ic->comment, format); 1047 format = ic->comment; 1048 } 1049 } 1050 else 1051 format = ic->comment; 1052 } 1053 else if (CONST_STRNEQ (ic->comment, "Field")) 1054 { 1055 if (field) 1056 warn (_("overlapping field %s->%s\n"), 1057 ic->comment, field); 1058 field = ic->comment; 1059 } 1060 } 1061 1062 /* An insn class matches anything that is the same followed by completers, 1063 except when the absence and presence of completers constitutes different 1064 instructions. */ 1065 if (ic->nsubs == 0 && ic->nxsubs == 0) 1066 { 1067 int is_mov = CONST_STRNEQ (idesc->name, "mov"); 1068 int plain_mov = strcmp (idesc->name, "mov") == 0; 1069 int len = strlen(ic->name); 1070 1071 resolved = ((strncmp (ic->name, idesc->name, len) == 0) 1072 && (idesc->name[len] == '\0' 1073 || idesc->name[len] == '.')); 1074 1075 /* All break, nop, and hint variations must match exactly. */ 1076 if (resolved && 1077 (strcmp (ic->name, "break") == 0 1078 || strcmp (ic->name, "nop") == 0 1079 || strcmp (ic->name, "hint") == 0)) 1080 resolved = strcmp (ic->name, idesc->name) == 0; 1081 1082 /* Assume restrictions in the FORMAT/FIELD negate resolution, 1083 unless specifically allowed by clauses in this block. */ 1084 if (resolved && field) 1085 { 1086 /* Check Field(sf)==sN against opcode sN. */ 1087 if (strstr(field, "(sf)==") != NULL) 1088 { 1089 char *sf; 1090 1091 if ((sf = strstr (idesc->name, ".s")) != 0) 1092 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0; 1093 } 1094 /* Check Field(lftype)==XXX. */ 1095 else if (strstr (field, "(lftype)") != NULL) 1096 { 1097 if (strstr (idesc->name, "fault") != NULL) 1098 resolved = strstr (field, "fault") != NULL; 1099 else 1100 resolved = strstr (field, "fault") == NULL; 1101 } 1102 /* Handle Field(ctype)==XXX. */ 1103 else if (strstr (field, "(ctype)") != NULL) 1104 { 1105 if (strstr (idesc->name, "or.andcm")) 1106 resolved = strstr (field, "or.andcm") != NULL; 1107 else if (strstr (idesc->name, "and.orcm")) 1108 resolved = strstr (field, "and.orcm") != NULL; 1109 else if (strstr (idesc->name, "orcm")) 1110 resolved = strstr (field, "or orcm") != NULL; 1111 else if (strstr (idesc->name, "or")) 1112 resolved = strstr (field, "or orcm") != NULL; 1113 else if (strstr (idesc->name, "andcm")) 1114 resolved = strstr (field, "and andcm") != NULL; 1115 else if (strstr (idesc->name, "and")) 1116 resolved = strstr (field, "and andcm") != NULL; 1117 else if (strstr (idesc->name, "unc")) 1118 resolved = strstr (field, "unc") != NULL; 1119 else 1120 resolved = strcmp (field, "Field(ctype)==") == 0; 1121 } 1122 } 1123 1124 if (resolved && format) 1125 { 1126 if (CONST_STRNEQ (idesc->name, "dep") 1127 && strstr (format, "I13") != NULL) 1128 resolved = idesc->operands[1] == IA64_OPND_IMM8; 1129 else if (CONST_STRNEQ (idesc->name, "chk") 1130 && strstr (format, "M21") != NULL) 1131 resolved = idesc->operands[0] == IA64_OPND_F2; 1132 else if (CONST_STRNEQ (idesc->name, "lfetch")) 1133 resolved = (strstr (format, "M14 M15") != NULL 1134 && (idesc->operands[1] == IA64_OPND_R2 1135 || idesc->operands[1] == IA64_OPND_IMM9b)); 1136 else if (CONST_STRNEQ (idesc->name, "br.call") 1137 && strstr (format, "B5") != NULL) 1138 resolved = idesc->operands[1] == IA64_OPND_B2; 1139 else if (CONST_STRNEQ (idesc->name, "br.call") 1140 && strstr (format, "B3") != NULL) 1141 resolved = idesc->operands[1] == IA64_OPND_TGT25c; 1142 else if (CONST_STRNEQ (idesc->name, "brp") 1143 && strstr (format, "B7") != NULL) 1144 resolved = idesc->operands[0] == IA64_OPND_B2; 1145 else if (strcmp (ic->name, "invala") == 0) 1146 resolved = strcmp (idesc->name, ic->name) == 0; 1147 else if (CONST_STRNEQ (idesc->name, "st") 1148 && (strstr (format, "M5") != NULL 1149 || strstr (format, "M10") != NULL)) 1150 resolved = idesc->flags & IA64_OPCODE_POSTINC; 1151 else if (CONST_STRNEQ (idesc->name, "ld") 1152 && (strstr (format, "M2 M3") != NULL 1153 || strstr (format, "M12") != NULL 1154 || strstr (format, "M7 M8") != NULL)) 1155 resolved = idesc->flags & IA64_OPCODE_POSTINC; 1156 else 1157 resolved = 0; 1158 } 1159 1160 /* Misc brl variations ('.cond' is optional); 1161 plain brl matches brl.cond. */ 1162 if (!resolved 1163 && (strcmp (idesc->name, "brl") == 0 1164 || CONST_STRNEQ (idesc->name, "brl.")) 1165 && strcmp (ic->name, "brl.cond") == 0) 1166 { 1167 resolved = 1; 1168 } 1169 1170 /* Misc br variations ('.cond' is optional). */ 1171 if (!resolved 1172 && (strcmp (idesc->name, "br") == 0 1173 || CONST_STRNEQ (idesc->name, "br.")) 1174 && strcmp (ic->name, "br.cond") == 0) 1175 { 1176 if (format) 1177 resolved = (strstr (format, "B4") != NULL 1178 && idesc->operands[0] == IA64_OPND_B2) 1179 || (strstr (format, "B1") != NULL 1180 && idesc->operands[0] == IA64_OPND_TGT25c); 1181 else 1182 resolved = 1; 1183 } 1184 1185 /* probe variations. */ 1186 if (!resolved && CONST_STRNEQ (idesc->name, "probe")) 1187 { 1188 resolved = strcmp (ic->name, "probe") == 0 1189 && !((strstr (idesc->name, "fault") != NULL) 1190 ^ (format && strstr (format, "M40") != NULL)); 1191 } 1192 1193 /* mov variations. */ 1194 if (!resolved && is_mov) 1195 { 1196 if (plain_mov) 1197 { 1198 /* mov alias for fmerge. */ 1199 if (strcmp (ic->name, "fmerge") == 0) 1200 { 1201 resolved = idesc->operands[0] == IA64_OPND_F1 1202 && idesc->operands[1] == IA64_OPND_F3; 1203 } 1204 /* mov alias for adds (r3 or imm14). */ 1205 else if (strcmp (ic->name, "adds") == 0) 1206 { 1207 resolved = (idesc->operands[0] == IA64_OPND_R1 1208 && (idesc->operands[1] == IA64_OPND_R3 1209 || (idesc->operands[1] == IA64_OPND_IMM14))); 1210 } 1211 /* mov alias for addl. */ 1212 else if (strcmp (ic->name, "addl") == 0) 1213 { 1214 resolved = idesc->operands[0] == IA64_OPND_R1 1215 && idesc->operands[1] == IA64_OPND_IMM22; 1216 } 1217 } 1218 1219 /* Some variants of mov and mov.[im]. */ 1220 if (!resolved && CONST_STRNEQ (ic->name, "mov_")) 1221 resolved = in_iclass_mov_x (idesc, ic, format, field); 1222 } 1223 1224 /* Keep track of this so we can flag any insn classes which aren't 1225 mapped onto at least one real insn. */ 1226 if (resolved) 1227 ic->terminal_resolved = 1; 1228 } 1229 else for (i = 0; i < ic->nsubs; i++) 1230 { 1231 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep)) 1232 { 1233 int j; 1234 1235 for (j = 0; j < ic->nxsubs; j++) 1236 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL)) 1237 return 0; 1238 1239 if (debug > 1) 1240 printf ("%s is in IC %s\n", idesc->name, ic->name); 1241 1242 resolved = 1; 1243 break; 1244 } 1245 } 1246 1247 /* If it's in this IC, add the IC note (if any) to the insn. */ 1248 if (resolved) 1249 { 1250 if (ic->note && notep) 1251 { 1252 if (*notep && *notep != ic->note) 1253 warn (_("overwriting note %d with note %d (IC:%s)\n"), 1254 *notep, ic->note, ic->name); 1255 1256 *notep = ic->note; 1257 } 1258 } 1259 1260 return resolved; 1261} 1262 1263 1264static int 1265lookup_regindex (const char *name, int specifier) 1266{ 1267 switch (specifier) 1268 { 1269 case IA64_RS_ARX: 1270 if (strstr (name, "[RSC]")) 1271 return 16; 1272 if (strstr (name, "[BSP]")) 1273 return 17; 1274 else if (strstr (name, "[BSPSTORE]")) 1275 return 18; 1276 else if (strstr (name, "[RNAT]")) 1277 return 19; 1278 else if (strstr (name, "[FCR]")) 1279 return 21; 1280 else if (strstr (name, "[EFLAG]")) 1281 return 24; 1282 else if (strstr (name, "[CSD]")) 1283 return 25; 1284 else if (strstr (name, "[SSD]")) 1285 return 26; 1286 else if (strstr (name, "[CFLG]")) 1287 return 27; 1288 else if (strstr (name, "[FSR]")) 1289 return 28; 1290 else if (strstr (name, "[FIR]")) 1291 return 29; 1292 else if (strstr (name, "[FDR]")) 1293 return 30; 1294 else if (strstr (name, "[CCV]")) 1295 return 32; 1296 else if (strstr (name, "[ITC]")) 1297 return 44; 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 1422static int 1423lookup_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[IRR%]") != NULL) 1438 return IA64_RS_CR_IRR; 1439 if (strstr (name, "CR[LRR%]") != NULL) 1440 return IA64_RS_CR_LRR; 1441 if (strstr (name, "CR%") != NULL) 1442 return IA64_RS_CR; 1443 if (strstr (name, "FR%, % in 0") != NULL) 1444 return IA64_RS_FR; 1445 if (strstr (name, "FR%, % in 2") != NULL) 1446 return IA64_RS_FRb; 1447 if (strstr (name, "GR%") != NULL) 1448 return IA64_RS_GR; 1449 if (strstr (name, "PR%, % in 1 ") != NULL) 1450 return IA64_RS_PR; 1451 if (strstr (name, "PR%, % in 16 ") != NULL) 1452 return IA64_RS_PRr; 1453 1454 warn (_("don't know how to specify %% dependency %s\n"), 1455 name); 1456 } 1457 else if (strchr (name, '#')) 1458 { 1459 if (strstr (name, "CPUID#") != NULL) 1460 return IA64_RS_CPUID; 1461 if (strstr (name, "DBR#") != NULL) 1462 return IA64_RS_DBR; 1463 if (strstr (name, "IBR#") != NULL) 1464 return IA64_RS_IBR; 1465 if (strstr (name, "MSR#") != NULL) 1466 return IA64_RS_MSR; 1467 if (strstr (name, "PKR#") != NULL) 1468 return IA64_RS_PKR; 1469 if (strstr (name, "PMC#") != NULL) 1470 return IA64_RS_PMC; 1471 if (strstr (name, "PMD#") != NULL) 1472 return IA64_RS_PMD; 1473 if (strstr (name, "RR#") != NULL) 1474 return IA64_RS_RR; 1475 1476 warn (_("Don't know how to specify # dependency %s\n"), 1477 name); 1478 } 1479 else if (CONST_STRNEQ (name, "AR[FPSR]")) 1480 return IA64_RS_AR_FPSR; 1481 else if (CONST_STRNEQ (name, "AR[")) 1482 return IA64_RS_ARX; 1483 else if (CONST_STRNEQ (name, "CR[")) 1484 return IA64_RS_CRX; 1485 else if (CONST_STRNEQ (name, "PSR.")) 1486 return IA64_RS_PSR; 1487 else if (strcmp (name, "InService*") == 0) 1488 return IA64_RS_INSERVICE; 1489 else if (strcmp (name, "GR0") == 0) 1490 return IA64_RS_GR0; 1491 else if (strcmp (name, "CFM") == 0) 1492 return IA64_RS_CFM; 1493 else if (strcmp (name, "PR63") == 0) 1494 return IA64_RS_PR63; 1495 else if (strcmp (name, "RSE") == 0) 1496 return IA64_RS_RSE; 1497 1498 return IA64_RS_ANY; 1499} 1500 1501static void 1502print_dependency_table () 1503{ 1504 int i, j; 1505 1506 if (debug) 1507 { 1508 for (i=0;i < iclen;i++) 1509 { 1510 if (ics[i]->is_class) 1511 { 1512 if (!ics[i]->nsubs) 1513 { 1514 if (ics[i]->comment) 1515 warn (_("IC:%s [%s] has no terminals or sub-classes\n"), 1516 ics[i]->name, ics[i]->comment); 1517 else 1518 warn (_("IC:%s has no terminals or sub-classes\n"), 1519 ics[i]->name); 1520 } 1521 } 1522 else 1523 { 1524 if (!ics[i]->terminal_resolved && !ics[i]->orphan) 1525 { 1526 if (ics[i]->comment) 1527 warn (_("no insns mapped directly to terminal IC %s [%s]"), 1528 ics[i]->name, ics[i]->comment); 1529 else 1530 warn (_("no insns mapped directly to terminal IC %s\n"), 1531 ics[i]->name); 1532 } 1533 } 1534 } 1535 1536 for (i = 0; i < iclen; i++) 1537 { 1538 if (ics[i]->orphan) 1539 { 1540 mark_used (ics[i], 1); 1541 warn (_("class %s is defined but not used\n"), 1542 ics[i]->name); 1543 } 1544 } 1545 1546 if (debug > 1) 1547 for (i = 0; i < rdepslen; i++) 1548 { 1549 static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1550 1551 if (rdeps[i]->total_chks == 0) 1552 warn (_("Warning: rsrc %s (%s) has no chks%s\n"), 1553 rdeps[i]->name, mode_str[rdeps[i]->mode], 1554 rdeps[i]->total_regs ? "" : " or regs"); 1555 else if (rdeps[i]->total_regs == 0) 1556 warn (_("rsrc %s (%s) has no regs\n"), 1557 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1558 } 1559 } 1560 1561 /* The dependencies themselves. */ 1562 printf ("static const struct ia64_dependency\ndependencies[] = {\n"); 1563 for (i = 0; i < rdepslen; i++) 1564 { 1565 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual 1566 resource used. */ 1567 int specifier = lookup_specifier (rdeps[i]->name); 1568 int regindex = lookup_regindex (rdeps[i]->name, specifier); 1569 1570 printf (" { \"%s\", %d, %d, %d, %d, ", 1571 rdeps[i]->name, specifier, 1572 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); 1573 if (rdeps[i]->semantics == IA64_DVS_OTHER) 1574 { 1575 const char *quote, *rest; 1576 1577 putchar ('\"'); 1578 rest = rdeps[i]->extra; 1579 quote = strchr (rest, '\"'); 1580 while (quote != NULL) 1581 { 1582 printf ("%.*s\\\"", (int) (quote - rest), rest); 1583 rest = quote + 1; 1584 quote = strchr (rest, '\"'); 1585 } 1586 printf ("%s\", ", rest); 1587 } 1588 else 1589 printf ("NULL, "); 1590 printf("},\n"); 1591 } 1592 printf ("};\n\n"); 1593 1594 /* And dependency lists. */ 1595 for (i=0;i < dlistlen;i++) 1596 { 1597 int len = 2; 1598 printf ("static const unsigned short dep%d[] = {\n ", i); 1599 for (j=0;j < dlists[i]->len; j++) 1600 { 1601 len += printf ("%d, ", dlists[i]->deps[j]); 1602 if (len > 75) 1603 { 1604 printf("\n "); 1605 len = 2; 1606 } 1607 } 1608 printf ("\n};\n\n"); 1609 } 1610 1611 /* And opcode dependency list. */ 1612 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); 1613 printf ("static const struct ia64_opcode_dependency\n"); 1614 printf ("op_dependencies[] = {\n"); 1615 for (i = 0; i < opdeplen; i++) 1616 { 1617 printf (" { "); 1618 if (opdeps[i]->chk == -1) 1619 printf ("0, NULL, "); 1620 else 1621 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk); 1622 if (opdeps[i]->reg == -1) 1623 printf ("0, NULL, "); 1624 else 1625 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg); 1626 printf ("},\n"); 1627 } 1628 printf ("};\n\n"); 1629} 1630 1631 1632/* Add STR to the string table. */ 1633static struct string_entry * 1634insert_string (char *str) 1635{ 1636 int start = 0, end = strtablen; 1637 int i, x; 1638 1639 if (strtablen == strtabtotlen) 1640 { 1641 strtabtotlen += 20; 1642 string_table = (struct string_entry **) 1643 xrealloc (string_table, 1644 sizeof (struct string_entry **) * strtabtotlen); 1645 } 1646 1647 if (strtablen == 0) 1648 { 1649 strtablen = 1; 1650 string_table[0] = tmalloc (struct string_entry); 1651 string_table[0]->s = xstrdup (str); 1652 string_table[0]->num = 0; 1653 return string_table[0]; 1654 } 1655 1656 if (strcmp (str, string_table[strtablen - 1]->s) > 0) 1657 i = end; 1658 else if (strcmp (str, string_table[0]->s) < 0) 1659 i = 0; 1660 else 1661 { 1662 while (1) 1663 { 1664 int c; 1665 1666 i = (start + end) / 2; 1667 c = strcmp (str, string_table[i]->s); 1668 1669 if (c < 0) 1670 end = i - 1; 1671 else if (c == 0) 1672 return string_table[i]; 1673 else 1674 start = i + 1; 1675 1676 if (start > end) 1677 break; 1678 } 1679 } 1680 1681 for (; i > 0 && i < strtablen; i--) 1682 if (strcmp (str, string_table[i - 1]->s) > 0) 1683 break; 1684 1685 for (; i < strtablen; i++) 1686 if (strcmp (str, string_table[i]->s) < 0) 1687 break; 1688 1689 for (x = strtablen - 1; x >= i; x--) 1690 { 1691 string_table[x + 1] = string_table[x]; 1692 string_table[x + 1]->num = x + 1; 1693 } 1694 1695 string_table[i] = tmalloc (struct string_entry); 1696 string_table[i]->s = xstrdup (str); 1697 string_table[i]->num = i; 1698 strtablen++; 1699 1700 return string_table[i]; 1701} 1702 1703static struct bittree * 1704make_bittree_entry (void) 1705{ 1706 struct bittree *res = tmalloc (struct bittree); 1707 1708 res->disent = NULL; 1709 res->bits[0] = NULL; 1710 res->bits[1] = NULL; 1711 res->bits[2] = NULL; 1712 res->skip_flag = 0; 1713 res->bits_to_skip = 0; 1714 return res; 1715} 1716 1717 1718static struct disent * 1719add_dis_table_ent (which, insn, order, completer_index) 1720 struct disent *which; 1721 int insn; 1722 int order; 1723 int completer_index; 1724{ 1725 int ci = 0; 1726 struct disent *ent; 1727 1728 if (which != NULL) 1729 { 1730 ent = which; 1731 1732 ent->nextcnt++; 1733 while (ent->nexte != NULL) 1734 ent = ent->nexte; 1735 1736 ent = (ent->nexte = tmalloc (struct disent)); 1737 } 1738 else 1739 { 1740 ent = tmalloc (struct disent); 1741 ent->next_ent = disinsntable; 1742 disinsntable = ent; 1743 which = ent; 1744 } 1745 ent->nextcnt = 0; 1746 ent->nexte = NULL; 1747 ent->insn = insn; 1748 ent->priority = order; 1749 1750 while (completer_index != 1) 1751 { 1752 ci = (ci << 1) | (completer_index & 1); 1753 completer_index >>= 1; 1754 } 1755 ent->completer_index = ci; 1756 return which; 1757} 1758 1759static void 1760finish_distable () 1761{ 1762 struct disent *ent = disinsntable; 1763 struct disent *prev = ent; 1764 1765 ent->ournum = 32768; 1766 while ((ent = ent->next_ent) != NULL) 1767 { 1768 ent->ournum = prev->ournum + prev->nextcnt + 1; 1769 prev = ent; 1770 } 1771} 1772 1773static void 1774insert_bit_table_ent (curr_ent, bit, opcode, mask, 1775 opcodenum, order, completer_index) 1776 struct bittree *curr_ent; 1777 int bit; 1778 ia64_insn opcode; 1779 ia64_insn mask; 1780 int opcodenum; 1781 int order; 1782 int 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 1814static void 1815add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) 1816 struct bittree *first; 1817 ia64_insn opcode; 1818 ia64_insn mask; 1819 int opcodenum; 1820 struct completer_entry *ent; 1821 int completer_index; 1822{ 1823 if (completer_index & (1 << 20)) 1824 abort (); 1825 1826 while (ent != NULL) 1827 { 1828 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits; 1829 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, 1830 (completer_index << 1) | 1); 1831 1832 if (ent->is_terminal) 1833 { 1834 insert_bit_table_ent (bittree, 40, newopcode, mask, 1835 opcodenum, opcode_count - ent->order - 1, 1836 (completer_index << 1) | 1); 1837 } 1838 completer_index <<= 1; 1839 ent = ent->alternative; 1840 } 1841} 1842 1843/* This optimization pass combines multiple "don't care" nodes. */ 1844static void 1845compact_distree (ent) 1846 struct bittree *ent; 1847{ 1848#define IS_SKIP(ent) \ 1849 ((ent->bits[2] !=NULL) \ 1850 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0)) 1851 1852 int bitcnt = 0; 1853 struct bittree *nent = ent; 1854 int x; 1855 1856 while (IS_SKIP (nent)) 1857 { 1858 bitcnt++; 1859 nent = nent->bits[2]; 1860 } 1861 1862 if (bitcnt) 1863 { 1864 struct bittree *next = ent->bits[2]; 1865 1866 ent->bits[0] = nent->bits[0]; 1867 ent->bits[1] = nent->bits[1]; 1868 ent->bits[2] = nent->bits[2]; 1869 ent->disent = nent->disent; 1870 ent->skip_flag = 1; 1871 ent->bits_to_skip = bitcnt; 1872 while (next != nent) 1873 { 1874 struct bittree *b = next; 1875 next = next->bits[2]; 1876 free (b); 1877 } 1878 free (nent); 1879 } 1880 1881 for (x = 0; x < 3; x++) 1882 { 1883 struct bittree *i = ent->bits[x]; 1884 1885 if (i != NULL) 1886 compact_distree (i); 1887 } 1888} 1889 1890static unsigned char *insn_list; 1891static int insn_list_len = 0; 1892static int tot_insn_list_len = 0; 1893 1894/* Generate the disassembler state machine corresponding to the tree 1895 in ENT. */ 1896static void 1897gen_dis_table (ent) 1898 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[] = {\n"); 2128 for (x = 0; x < insn_list_len; x++) 2129 { 2130 if ((x > 0) && ((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%x, %d, %d, %d },\n", 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 (ent1, ent2) 2223 struct completer_entry *ent1, *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 (name) 2341 const char *name; 2342{ 2343 char *c; 2344 2345 if (name[0] == '\0') 2346 return 0; 2347 2348 c = strchr (name, '.'); 2349 if (c != NULL) 2350 return c - name; 2351 else 2352 return strlen (name); 2353} 2354 2355static void 2356compute_completer_bits (ment, ent) 2357 struct main_entry *ment; 2358 struct completer_entry *ent; 2359{ 2360 while (ent != NULL) 2361 { 2362 compute_completer_bits (ment, ent->addl_entries); 2363 2364 if (ent->is_terminal) 2365 { 2366 ia64_insn mask = 0; 2367 ia64_insn our_bits = ent->bits; 2368 struct completer_entry *p = ent->parent; 2369 ia64_insn p_bits; 2370 int x; 2371 2372 while (p != NULL && ! p->is_terminal) 2373 p = p->parent; 2374 2375 if (p != NULL) 2376 p_bits = p->bits; 2377 else 2378 p_bits = ment->opcode->opcode; 2379 2380 for (x = 0; x < 64; x++) 2381 { 2382 ia64_insn m = ((ia64_insn) 1) << x; 2383 2384 if ((p_bits & m) != (our_bits & m)) 2385 mask |= m; 2386 else 2387 our_bits &= ~m; 2388 } 2389 ent->bits = our_bits; 2390 ent->mask = mask; 2391 } 2392 else 2393 { 2394 ent->bits = 0; 2395 ent->mask = 0; 2396 } 2397 2398 ent = ent->alternative; 2399 } 2400} 2401 2402/* Find identical completer trees that are used in different 2403 instructions and collapse their entries. */ 2404static void 2405collapse_redundant_completers (void) 2406{ 2407 struct main_entry *ptr; 2408 int x; 2409 2410 for (ptr = maintable; ptr != NULL; ptr = ptr->next) 2411 { 2412 if (ptr->completers == NULL) 2413 abort (); 2414 2415 compute_completer_bits (ptr, ptr->completers); 2416 ptr->completers = insert_gclist (ptr->completers); 2417 } 2418 2419 /* The table has been finalized, now number the indexes. */ 2420 for (x = 0; x < glistlen; x++) 2421 glist[x]->num = x; 2422} 2423 2424 2425/* Attach two lists of dependencies to each opcode. 2426 1) all resources which, when already marked in use, conflict with this 2427 opcode (chks) 2428 2) all resources which must be marked in use when this opcode is used 2429 (regs). */ 2430static int 2431insert_opcode_dependencies (opc, cmp) 2432 struct ia64_opcode *opc; 2433 struct completer_entry *cmp ATTRIBUTE_UNUSED; 2434{ 2435 /* Note all resources which point to this opcode. rfi has the most chks 2436 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ 2437 int i; 2438 int nregs = 0; 2439 unsigned short regs[256]; 2440 int nchks = 0; 2441 unsigned short chks[256]; 2442 /* Flag insns for which no class matched; there should be none. */ 2443 int no_class_found = 1; 2444 2445 for (i = 0; i < rdepslen; i++) 2446 { 2447 struct rdep *rs = rdeps[i]; 2448 int j; 2449 2450 if (strcmp (opc->name, "cmp.eq.and") == 0 2451 && CONST_STRNEQ (rs->name, "PR%") 2452 && rs->mode == 1) 2453 no_class_found = 99; 2454 2455 for (j=0; j < rs->nregs;j++) 2456 { 2457 int ic_note = 0; 2458 2459 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) 2460 { 2461 /* We can ignore ic_note 11 for non PR resources. */ 2462 if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) 2463 ic_note = 0; 2464 2465 if (ic_note != 0 && rs->regnotes[j] != 0 2466 && ic_note != rs->regnotes[j] 2467 && !(ic_note == 11 && rs->regnotes[j] == 1)) 2468 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2469 ic_note, opc->name, ics[rs->regs[j]]->name, 2470 rs->name, rs->regnotes[j]); 2471 /* Instruction class notes override resource notes. 2472 So far, only note 11 applies to an IC instead of a resource, 2473 and note 11 implies note 1. */ 2474 if (ic_note) 2475 regs[nregs++] = RDEP(ic_note, i); 2476 else 2477 regs[nregs++] = RDEP(rs->regnotes[j], i); 2478 no_class_found = 0; 2479 ++rs->total_regs; 2480 } 2481 } 2482 2483 for (j = 0; j < rs->nchks; j++) 2484 { 2485 int ic_note = 0; 2486 2487 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) 2488 { 2489 /* We can ignore ic_note 11 for non PR resources. */ 2490 if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) 2491 ic_note = 0; 2492 2493 if (ic_note != 0 && rs->chknotes[j] != 0 2494 && ic_note != rs->chknotes[j] 2495 && !(ic_note == 11 && rs->chknotes[j] == 1)) 2496 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2497 ic_note, opc->name, ics[rs->chks[j]]->name, 2498 rs->name, rs->chknotes[j]); 2499 if (ic_note) 2500 chks[nchks++] = RDEP(ic_note, i); 2501 else 2502 chks[nchks++] = RDEP(rs->chknotes[j], i); 2503 no_class_found = 0; 2504 ++rs->total_chks; 2505 } 2506 } 2507 } 2508 2509 if (no_class_found) 2510 warn (_("opcode %s has no class (ops %d %d %d)\n"), 2511 opc->name, 2512 opc->operands[0], opc->operands[1], opc->operands[2]); 2513 2514 return insert_dependencies (nchks, chks, nregs, regs); 2515} 2516 2517static void 2518insert_completer_entry (opc, tabent, order) 2519 struct ia64_opcode *opc; 2520 struct main_entry *tabent; 2521 int order; 2522{ 2523 struct completer_entry **ptr = &tabent->completers; 2524 struct completer_entry *parent = NULL; 2525 char pcopy[129], *prefix; 2526 int at_end = 0; 2527 2528 if (strlen (opc->name) > 128) 2529 abort (); 2530 2531 strcpy (pcopy, opc->name); 2532 prefix = pcopy + get_prefix_len (pcopy); 2533 2534 if (prefix[0] != '\0') 2535 prefix++; 2536 2537 while (! at_end) 2538 { 2539 int need_new_ent = 1; 2540 int plen = get_prefix_len (prefix); 2541 struct string_entry *sent; 2542 2543 at_end = (prefix[plen] == '\0'); 2544 prefix[plen] = '\0'; 2545 sent = insert_string (prefix); 2546 2547 while (*ptr != NULL) 2548 { 2549 int cmpres = sent->num - (*ptr)->name->num; 2550 2551 if (cmpres == 0) 2552 { 2553 need_new_ent = 0; 2554 break; 2555 } 2556 else 2557 ptr = &((*ptr)->alternative); 2558 } 2559 2560 if (need_new_ent) 2561 { 2562 struct completer_entry *nent = tmalloc (struct completer_entry); 2563 2564 nent->name = sent; 2565 nent->parent = parent; 2566 nent->addl_entries = NULL; 2567 nent->alternative = *ptr; 2568 *ptr = nent; 2569 nent->is_terminal = 0; 2570 nent->dependencies = -1; 2571 } 2572 2573 if (! at_end) 2574 { 2575 parent = *ptr; 2576 ptr = &((*ptr)->addl_entries); 2577 prefix += plen + 1; 2578 } 2579 } 2580 2581 if ((*ptr)->is_terminal) 2582 abort (); 2583 2584 (*ptr)->is_terminal = 1; 2585 (*ptr)->mask = (ia64_insn)-1; 2586 (*ptr)->bits = opc->opcode; 2587 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr); 2588 (*ptr)->order = order; 2589} 2590 2591static void 2592print_completer_entry (ent) 2593 struct completer_entry *ent; 2594{ 2595 int moffset = 0; 2596 ia64_insn mask = ent->mask, bits = ent->bits; 2597 2598 if (mask != 0) 2599 { 2600 while (! (mask & 1)) 2601 { 2602 moffset++; 2603 mask = mask >> 1; 2604 bits = bits >> 1; 2605 } 2606 2607 if (bits & 0xffffffff00000000LL) 2608 abort (); 2609 } 2610 2611 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n", 2612 (int)bits, 2613 (int)mask, 2614 ent->name->num, 2615 ent->alternative != NULL ? ent->alternative->num : -1, 2616 ent->addl_entries != NULL ? ent->addl_entries->num : -1, 2617 moffset, 2618 ent->is_terminal ? 1 : 0, 2619 ent->dependencies); 2620} 2621 2622static void 2623print_completer_table () 2624{ 2625 int x; 2626 2627 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n"); 2628 for (x = 0; x < glistlen; x++) 2629 print_completer_entry (glist[x]); 2630 printf ("};\n\n"); 2631} 2632 2633static int 2634opcodes_eq (opc1, opc2) 2635 struct ia64_opcode *opc1; 2636 struct ia64_opcode *opc2; 2637{ 2638 int x; 2639 int plen1, plen2; 2640 2641 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 2642 || (opc1->num_outputs != opc2->num_outputs) 2643 || (opc1->flags != opc2->flags)) 2644 return 0; 2645 2646 for (x = 0; x < 5; x++) 2647 if (opc1->operands[x] != opc2->operands[x]) 2648 return 0; 2649 2650 plen1 = get_prefix_len (opc1->name); 2651 plen2 = get_prefix_len (opc2->name); 2652 2653 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0)) 2654 return 1; 2655 2656 return 0; 2657} 2658 2659static void 2660add_opcode_entry (opc) 2661 struct ia64_opcode *opc; 2662{ 2663 struct main_entry **place; 2664 struct string_entry *name; 2665 char prefix[129]; 2666 int found_it = 0; 2667 2668 if (strlen (opc->name) > 128) 2669 abort (); 2670 2671 place = &maintable; 2672 strcpy (prefix, opc->name); 2673 prefix[get_prefix_len (prefix)] = '\0'; 2674 name = insert_string (prefix); 2675 2676 /* Walk the list of opcode table entries. If it's a new 2677 instruction, allocate and fill in a new entry. Note 2678 the main table is alphabetical by opcode name. */ 2679 2680 while (*place != NULL) 2681 { 2682 if ((*place)->name->num == name->num 2683 && opcodes_eq ((*place)->opcode, opc)) 2684 { 2685 found_it = 1; 2686 break; 2687 } 2688 if ((*place)->name->num > name->num) 2689 break; 2690 2691 place = &((*place)->next); 2692 } 2693 if (! found_it) 2694 { 2695 struct main_entry *nent = tmalloc (struct main_entry); 2696 2697 nent->name = name; 2698 nent->opcode = opc; 2699 nent->next = *place; 2700 nent->completers = 0; 2701 *place = nent; 2702 2703 if (otlen == ottotlen) 2704 { 2705 ottotlen += 20; 2706 ordered_table = (struct main_entry **) 2707 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen); 2708 } 2709 ordered_table[otlen++] = nent; 2710 } 2711 2712 insert_completer_entry (opc, *place, opcode_count++); 2713} 2714 2715static void 2716print_main_table (void) 2717{ 2718 struct main_entry *ptr = maintable; 2719 int index = 0; 2720 2721 printf ("static const struct ia64_main_table\nmain_table[] = {\n"); 2722 while (ptr != NULL) 2723 { 2724 printf (" { %d, %d, %d, 0x", 2725 ptr->name->num, 2726 ptr->opcode->type, 2727 ptr->opcode->num_outputs); 2728 opcode_fprintf_vma (stdout, ptr->opcode->opcode); 2729 printf ("ull, 0x"); 2730 opcode_fprintf_vma (stdout, ptr->opcode->mask); 2731 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n", 2732 ptr->opcode->operands[0], 2733 ptr->opcode->operands[1], 2734 ptr->opcode->operands[2], 2735 ptr->opcode->operands[3], 2736 ptr->opcode->operands[4], 2737 ptr->opcode->flags, 2738 ptr->completers->num); 2739 2740 ptr->main_index = index++; 2741 2742 ptr = ptr->next; 2743 } 2744 printf ("};\n\n"); 2745} 2746 2747static void 2748shrink (table) 2749 struct ia64_opcode *table; 2750{ 2751 int curr_opcode; 2752 2753 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++) 2754 { 2755 add_opcode_entry (table + curr_opcode); 2756 if (table[curr_opcode].num_outputs == 2 2757 && ((table[curr_opcode].operands[0] == IA64_OPND_P1 2758 && table[curr_opcode].operands[1] == IA64_OPND_P2) 2759 || (table[curr_opcode].operands[0] == IA64_OPND_P2 2760 && table[curr_opcode].operands[1] == IA64_OPND_P1))) 2761 { 2762 struct ia64_opcode *alias = tmalloc(struct ia64_opcode); 2763 unsigned i; 2764 2765 *alias = table[curr_opcode]; 2766 for (i = 2; i < NELEMS (alias->operands); ++i) 2767 alias->operands[i - 1] = alias->operands[i]; 2768 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL; 2769 --alias->num_outputs; 2770 alias->flags |= PSEUDO; 2771 add_opcode_entry (alias); 2772 } 2773 } 2774} 2775 2776 2777/* Program options. */ 2778#define OPTION_SRCDIR 200 2779 2780struct option long_options[] = 2781{ 2782 {"srcdir", required_argument, NULL, OPTION_SRCDIR}, 2783 {"debug", no_argument, NULL, 'd'}, 2784 {"version", no_argument, NULL, 'V'}, 2785 {"help", no_argument, NULL, 'h'}, 2786 {0, no_argument, NULL, 0} 2787}; 2788 2789static void 2790print_version (void) 2791{ 2792 printf ("%s: version 1.0\n", program_name); 2793 xexit (0); 2794} 2795 2796static void 2797usage (FILE * stream, int status) 2798{ 2799 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n", 2800 program_name); 2801 xexit (status); 2802} 2803 2804int 2805main (int argc, char **argv) 2806{ 2807 extern int chdir (char *); 2808 char *srcdir = NULL; 2809 int c; 2810 2811 program_name = *argv; 2812 xmalloc_set_program_name (program_name); 2813 2814 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF) 2815 switch (c) 2816 { 2817 case OPTION_SRCDIR: 2818 srcdir = optarg; 2819 break; 2820 case 'V': 2821 case 'v': 2822 print_version (); 2823 break; 2824 case 'd': 2825 debug = 1; 2826 break; 2827 case 'h': 2828 case '?': 2829 usage (stderr, 0); 2830 default: 2831 case 0: 2832 break; 2833 } 2834 2835 if (optind != argc) 2836 usage (stdout, 1); 2837 2838 if (srcdir != NULL) 2839 if (chdir (srcdir) != 0) 2840 fail (_("unable to change directory to \"%s\", errno = %s\n"), 2841 srcdir, strerror (errno)); 2842 2843 load_insn_classes (); 2844 load_dependencies (); 2845 2846 shrink (ia64_opcodes_a); 2847 shrink (ia64_opcodes_b); 2848 shrink (ia64_opcodes_f); 2849 shrink (ia64_opcodes_i); 2850 shrink (ia64_opcodes_m); 2851 shrink (ia64_opcodes_x); 2852 shrink (ia64_opcodes_d); 2853 2854 collapse_redundant_completers (); 2855 2856 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); 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