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