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 67 const char * program_name = NULL; 68 int 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). */ 76 struct 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 92 int otlen = 0; 93 int ottotlen = 0; 94 int opcode_count = 0; 95 96 /* The set of possible completers for an opcode. */ 97 struct 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. */ 138 struct 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. */ 164 struct 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. */ 176 struct 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 184 int strtablen = 0; 185 int strtabtotlen = 0; 186 187 188 /* Resource dependency entries. */ 189 struct 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 210 static int rdepslen = 0; 211 static int rdepstotlen = 0; 212 213 /* Array of all instruction classes. */ 214 struct 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 228 static int iclen = 0; 229 static int ictotlen = 0; 230 231 /* An opcode dependency (chk/reg pair of dependency lists). */ 232 struct opdep 233 { 234 int chk; /* index into dlists */ 235 int reg; /* index into dlists */ 236 } **opdeps; 237 238 static int opdeplen = 0; 239 static int opdeptotlen = 0; 240 241 /* A generic list of dependencies w/notes encoded. These may be shared. */ 242 struct deplist 243 { 244 int len; 245 unsigned short *deps; 246 } **dlists; 247 248 static int dlistlen = 0; 249 static int dlisttotlen = 0; 250 251 252 static void fail (const char *, ...) ATTRIBUTE_PRINTF_1; 253 static void warn (const char *, ...) ATTRIBUTE_PRINTF_1; 254 static struct rdep * insert_resource (const char *, enum ia64_dependency_mode); 255 static int deplist_equals (struct deplist *, struct deplist *); 256 static short insert_deplist (int, unsigned short *); 257 static short insert_dependencies (int, unsigned short *, int, unsigned short *); 258 static void mark_used (struct iclass *, int); 259 static int fetch_insn_class (const char *, int); 260 static int sub_compare (const void *, const void *); 261 static void load_insn_classes (void); 262 static void parse_resource_users (const char *, int **, int *, int **); 263 static int parse_semantics (char *); 264 static void add_dep (const char *, const char *, const char *, int, int, char *, int); 265 static void load_depfile (const char *, enum ia64_dependency_mode); 266 static void load_dependencies (void); 267 static int irf_operand (int, const char *); 268 static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *); 269 static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *); 270 static int lookup_regindex (const char *, int); 271 static int lookup_specifier (const char *); 272 static void print_dependency_table (void); 273 static struct string_entry * insert_string (char *); 274 static void gen_dis_table (struct bittree *); 275 static void print_dis_table (void); 276 static void generate_disassembler (void); 277 static void print_string_table (void); 278 static int completer_entries_eq (struct completer_entry *, struct completer_entry *); 279 static struct completer_entry * insert_gclist (struct completer_entry *); 280 static int get_prefix_len (const char *); 281 static void compute_completer_bits (struct main_entry *, struct completer_entry *); 282 static void collapse_redundant_completers (void); 283 static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *); 284 static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int); 285 static void print_completer_entry (struct completer_entry *); 286 static void print_completer_table (void); 287 static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *); 288 static void add_opcode_entry (struct ia64_opcode *); 289 static void print_main_table (void); 290 static void shrink (struct ia64_opcode *); 291 static void print_version (void); 292 static void usage (FILE *, int); 293 static void finish_distable (void); 294 static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, int); 295 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int); 296 static void compact_distree (struct bittree *); 297 static struct bittree * make_bittree_entry (void); 298 static struct disent * add_dis_table_ent (struct disent *, int, int, int); 299 300 301 static void 302 fail (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 313 static void 314 warn (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. */ 326 static struct rdep * 327 insert_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? */ 345 static int 346 deplist_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. */ 361 static short 362 insert_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. */ 408 static short 409 insert_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 442 static void 443 mark_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. */ 460 static int 461 fetch_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. */ 593 static int 594 sub_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 610 static void 611 load_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. */ 696 static void 697 parse_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 778 static int 779 parse_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 799 static void 800 add_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 815 static void 816 load_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 878 static void 879 load_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? */ 890 static int 891 irf_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. */ 915 static int 916 in_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? */ 1029 static int 1030 in_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 1265 static int 1266 lookup_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, "[RUC]")) 1300 return 45; 1301 else if (strstr (name, "[PFS]")) 1302 return 64; 1303 else if (strstr (name, "[LC]")) 1304 return 65; 1305 else if (strstr (name, "[EC]")) 1306 return 66; 1307 abort (); 1308 case IA64_RS_CRX: 1309 if (strstr (name, "[DCR]")) 1310 return 0; 1311 else if (strstr (name, "[ITM]")) 1312 return 1; 1313 else if (strstr (name, "[IVA]")) 1314 return 2; 1315 else if (strstr (name, "[PTA]")) 1316 return 8; 1317 else if (strstr (name, "[GPTA]")) 1318 return 9; 1319 else if (strstr (name, "[IPSR]")) 1320 return 16; 1321 else if (strstr (name, "[ISR]")) 1322 return 17; 1323 else if (strstr (name, "[IIP]")) 1324 return 19; 1325 else if (strstr (name, "[IFA]")) 1326 return 20; 1327 else if (strstr (name, "[ITIR]")) 1328 return 21; 1329 else if (strstr (name, "[IIPA]")) 1330 return 22; 1331 else if (strstr (name, "[IFS]")) 1332 return 23; 1333 else if (strstr (name, "[IIM]")) 1334 return 24; 1335 else if (strstr (name, "[IHA]")) 1336 return 25; 1337 else if (strstr (name, "[LID]")) 1338 return 64; 1339 else if (strstr (name, "[IVR]")) 1340 return 65; 1341 else if (strstr (name, "[TPR]")) 1342 return 66; 1343 else if (strstr (name, "[EOI]")) 1344 return 67; 1345 else if (strstr (name, "[ITV]")) 1346 return 72; 1347 else if (strstr (name, "[PMV]")) 1348 return 73; 1349 else if (strstr (name, "[CMCV]")) 1350 return 74; 1351 abort (); 1352 case IA64_RS_PSR: 1353 if (strstr (name, ".be")) 1354 return 1; 1355 else if (strstr (name, ".up")) 1356 return 2; 1357 else if (strstr (name, ".ac")) 1358 return 3; 1359 else if (strstr (name, ".mfl")) 1360 return 4; 1361 else if (strstr (name, ".mfh")) 1362 return 5; 1363 else if (strstr (name, ".ic")) 1364 return 13; 1365 else if (strstr (name, ".i")) 1366 return 14; 1367 else if (strstr (name, ".pk")) 1368 return 15; 1369 else if (strstr (name, ".dt")) 1370 return 17; 1371 else if (strstr (name, ".dfl")) 1372 return 18; 1373 else if (strstr (name, ".dfh")) 1374 return 19; 1375 else if (strstr (name, ".sp")) 1376 return 20; 1377 else if (strstr (name, ".pp")) 1378 return 21; 1379 else if (strstr (name, ".di")) 1380 return 22; 1381 else if (strstr (name, ".si")) 1382 return 23; 1383 else if (strstr (name, ".db")) 1384 return 24; 1385 else if (strstr (name, ".lp")) 1386 return 25; 1387 else if (strstr (name, ".tb")) 1388 return 26; 1389 else if (strstr (name, ".rt")) 1390 return 27; 1391 else if (strstr (name, ".cpl")) 1392 return 32; 1393 else if (strstr (name, ".rs")) 1394 return 34; 1395 else if (strstr (name, ".mc")) 1396 return 35; 1397 else if (strstr (name, ".it")) 1398 return 36; 1399 else if (strstr (name, ".id")) 1400 return 37; 1401 else if (strstr (name, ".da")) 1402 return 38; 1403 else if (strstr (name, ".dd")) 1404 return 39; 1405 else if (strstr (name, ".ss")) 1406 return 40; 1407 else if (strstr (name, ".ri")) 1408 return 41; 1409 else if (strstr (name, ".ed")) 1410 return 43; 1411 else if (strstr (name, ".bn")) 1412 return 44; 1413 else if (strstr (name, ".ia")) 1414 return 45; 1415 else if (strstr (name, ".vm")) 1416 return 46; 1417 else 1418 abort (); 1419 default: 1420 break; 1421 } 1422 return REG_NONE; 1423 } 1424 1425 static int 1426 lookup_specifier (const char *name) 1427 { 1428 if (strchr (name, '%')) 1429 { 1430 if (strstr (name, "AR[K%]") != NULL) 1431 return IA64_RS_AR_K; 1432 if (strstr (name, "AR[UNAT]") != NULL) 1433 return IA64_RS_AR_UNAT; 1434 if (strstr (name, "AR%, % in 8") != NULL) 1435 return IA64_RS_AR; 1436 if (strstr (name, "AR%, % in 48") != NULL) 1437 return IA64_RS_ARb; 1438 if (strstr (name, "BR%") != NULL) 1439 return IA64_RS_BR; 1440 if (strstr (name, "CR[IIB%]") != NULL) 1441 return IA64_RS_CR_IIB; 1442 if (strstr (name, "CR[IRR%]") != NULL) 1443 return IA64_RS_CR_IRR; 1444 if (strstr (name, "CR[LRR%]") != NULL) 1445 return IA64_RS_CR_LRR; 1446 if (strstr (name, "CR%") != NULL) 1447 return IA64_RS_CR; 1448 if (strstr (name, "FR%, % in 0") != NULL) 1449 return IA64_RS_FR; 1450 if (strstr (name, "FR%, % in 2") != NULL) 1451 return IA64_RS_FRb; 1452 if (strstr (name, "GR%") != NULL) 1453 return IA64_RS_GR; 1454 if (strstr (name, "PR%, % in 1 ") != NULL) 1455 return IA64_RS_PR; 1456 if (strstr (name, "PR%, % in 16 ") != NULL) 1457 return IA64_RS_PRr; 1458 1459 warn (_("don't know how to specify %% dependency %s\n"), 1460 name); 1461 } 1462 else if (strchr (name, '#')) 1463 { 1464 if (strstr (name, "CPUID#") != NULL) 1465 return IA64_RS_CPUID; 1466 if (strstr (name, "DBR#") != NULL) 1467 return IA64_RS_DBR; 1468 if (strstr (name, "IBR#") != NULL) 1469 return IA64_RS_IBR; 1470 if (strstr (name, "MSR#") != NULL) 1471 return IA64_RS_MSR; 1472 if (strstr (name, "PKR#") != NULL) 1473 return IA64_RS_PKR; 1474 if (strstr (name, "PMC#") != NULL) 1475 return IA64_RS_PMC; 1476 if (strstr (name, "PMD#") != NULL) 1477 return IA64_RS_PMD; 1478 if (strstr (name, "RR#") != NULL) 1479 return IA64_RS_RR; 1480 1481 warn (_("Don't know how to specify # dependency %s\n"), 1482 name); 1483 } 1484 else if (CONST_STRNEQ (name, "AR[FPSR]")) 1485 return IA64_RS_AR_FPSR; 1486 else if (CONST_STRNEQ (name, "AR[")) 1487 return IA64_RS_ARX; 1488 else if (CONST_STRNEQ (name, "CR[")) 1489 return IA64_RS_CRX; 1490 else if (CONST_STRNEQ (name, "PSR.")) 1491 return IA64_RS_PSR; 1492 else if (strcmp (name, "InService*") == 0) 1493 return IA64_RS_INSERVICE; 1494 else if (strcmp (name, "GR0") == 0) 1495 return IA64_RS_GR0; 1496 else if (strcmp (name, "CFM") == 0) 1497 return IA64_RS_CFM; 1498 else if (strcmp (name, "PR63") == 0) 1499 return IA64_RS_PR63; 1500 else if (strcmp (name, "RSE") == 0) 1501 return IA64_RS_RSE; 1502 1503 return IA64_RS_ANY; 1504 } 1505 1506 static void 1507 print_dependency_table () 1508 { 1509 int i, j; 1510 1511 if (debug) 1512 { 1513 for (i=0;i < iclen;i++) 1514 { 1515 if (ics[i]->is_class) 1516 { 1517 if (!ics[i]->nsubs) 1518 { 1519 if (ics[i]->comment) 1520 warn (_("IC:%s [%s] has no terminals or sub-classes\n"), 1521 ics[i]->name, ics[i]->comment); 1522 else 1523 warn (_("IC:%s has no terminals or sub-classes\n"), 1524 ics[i]->name); 1525 } 1526 } 1527 else 1528 { 1529 if (!ics[i]->terminal_resolved && !ics[i]->orphan) 1530 { 1531 if (ics[i]->comment) 1532 warn (_("no insns mapped directly to terminal IC %s [%s]"), 1533 ics[i]->name, ics[i]->comment); 1534 else 1535 warn (_("no insns mapped directly to terminal IC %s\n"), 1536 ics[i]->name); 1537 } 1538 } 1539 } 1540 1541 for (i = 0; i < iclen; i++) 1542 { 1543 if (ics[i]->orphan) 1544 { 1545 mark_used (ics[i], 1); 1546 warn (_("class %s is defined but not used\n"), 1547 ics[i]->name); 1548 } 1549 } 1550 1551 if (debug > 1) 1552 for (i = 0; i < rdepslen; i++) 1553 { 1554 static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1555 1556 if (rdeps[i]->total_chks == 0) 1557 { 1558 if (rdeps[i]->total_regs) 1559 warn (_("Warning: rsrc %s (%s) has no chks\n"), 1560 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1561 else 1562 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"), 1563 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1564 } 1565 else if (rdeps[i]->total_regs == 0) 1566 warn (_("rsrc %s (%s) has no regs\n"), 1567 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1568 } 1569 } 1570 1571 /* The dependencies themselves. */ 1572 printf ("static const struct ia64_dependency\ndependencies[] = {\n"); 1573 for (i = 0; i < rdepslen; i++) 1574 { 1575 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual 1576 resource used. */ 1577 int specifier = lookup_specifier (rdeps[i]->name); 1578 int regindex = lookup_regindex (rdeps[i]->name, specifier); 1579 1580 printf (" { \"%s\", %d, %d, %d, %d, ", 1581 rdeps[i]->name, specifier, 1582 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); 1583 if (rdeps[i]->semantics == IA64_DVS_OTHER) 1584 { 1585 const char *quote, *rest; 1586 1587 putchar ('\"'); 1588 rest = rdeps[i]->extra; 1589 quote = strchr (rest, '\"'); 1590 while (quote != NULL) 1591 { 1592 printf ("%.*s\\\"", (int) (quote - rest), rest); 1593 rest = quote + 1; 1594 quote = strchr (rest, '\"'); 1595 } 1596 printf ("%s\", ", rest); 1597 } 1598 else 1599 printf ("NULL, "); 1600 printf("},\n"); 1601 } 1602 printf ("};\n\n"); 1603 1604 /* And dependency lists. */ 1605 for (i=0;i < dlistlen;i++) 1606 { 1607 int len = 2; 1608 printf ("static const unsigned short dep%d[] = {\n ", i); 1609 for (j=0;j < dlists[i]->len; j++) 1610 { 1611 len += printf ("%d, ", dlists[i]->deps[j]); 1612 if (len > 75) 1613 { 1614 printf("\n "); 1615 len = 2; 1616 } 1617 } 1618 printf ("\n};\n\n"); 1619 } 1620 1621 /* And opcode dependency list. */ 1622 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); 1623 printf ("static const struct ia64_opcode_dependency\n"); 1624 printf ("op_dependencies[] = {\n"); 1625 for (i = 0; i < opdeplen; i++) 1626 { 1627 printf (" { "); 1628 if (opdeps[i]->chk == -1) 1629 printf ("0, NULL, "); 1630 else 1631 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk); 1632 if (opdeps[i]->reg == -1) 1633 printf ("0, NULL, "); 1634 else 1635 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg); 1636 printf ("},\n"); 1637 } 1638 printf ("};\n\n"); 1639 } 1640 1641 1642 /* Add STR to the string table. */ 1643 static struct string_entry * 1644 insert_string (char *str) 1645 { 1646 int start = 0, end = strtablen; 1647 int i, x; 1648 1649 if (strtablen == strtabtotlen) 1650 { 1651 strtabtotlen += 20; 1652 string_table = (struct string_entry **) 1653 xrealloc (string_table, 1654 sizeof (struct string_entry **) * strtabtotlen); 1655 } 1656 1657 if (strtablen == 0) 1658 { 1659 strtablen = 1; 1660 string_table[0] = tmalloc (struct string_entry); 1661 string_table[0]->s = xstrdup (str); 1662 string_table[0]->num = 0; 1663 return string_table[0]; 1664 } 1665 1666 if (strcmp (str, string_table[strtablen - 1]->s) > 0) 1667 i = end; 1668 else if (strcmp (str, string_table[0]->s) < 0) 1669 i = 0; 1670 else 1671 { 1672 while (1) 1673 { 1674 int c; 1675 1676 i = (start + end) / 2; 1677 c = strcmp (str, string_table[i]->s); 1678 1679 if (c < 0) 1680 end = i - 1; 1681 else if (c == 0) 1682 return string_table[i]; 1683 else 1684 start = i + 1; 1685 1686 if (start > end) 1687 break; 1688 } 1689 } 1690 1691 for (; i > 0 && i < strtablen; i--) 1692 if (strcmp (str, string_table[i - 1]->s) > 0) 1693 break; 1694 1695 for (; i < strtablen; i++) 1696 if (strcmp (str, string_table[i]->s) < 0) 1697 break; 1698 1699 for (x = strtablen - 1; x >= i; x--) 1700 { 1701 string_table[x + 1] = string_table[x]; 1702 string_table[x + 1]->num = x + 1; 1703 } 1704 1705 string_table[i] = tmalloc (struct string_entry); 1706 string_table[i]->s = xstrdup (str); 1707 string_table[i]->num = i; 1708 strtablen++; 1709 1710 return string_table[i]; 1711 } 1712 1713 static struct bittree * 1714 make_bittree_entry (void) 1715 { 1716 struct bittree *res = tmalloc (struct bittree); 1717 1718 res->disent = NULL; 1719 res->bits[0] = NULL; 1720 res->bits[1] = NULL; 1721 res->bits[2] = NULL; 1722 res->skip_flag = 0; 1723 res->bits_to_skip = 0; 1724 return res; 1725 } 1726 1727 1728 static struct disent * 1729 add_dis_table_ent (which, insn, order, completer_index) 1730 struct disent *which; 1731 int insn; 1732 int order; 1733 int completer_index; 1734 { 1735 int ci = 0; 1736 struct disent *ent; 1737 1738 if (which != NULL) 1739 { 1740 ent = which; 1741 1742 ent->nextcnt++; 1743 while (ent->nexte != NULL) 1744 ent = ent->nexte; 1745 1746 ent = (ent->nexte = tmalloc (struct disent)); 1747 } 1748 else 1749 { 1750 ent = tmalloc (struct disent); 1751 ent->next_ent = disinsntable; 1752 disinsntable = ent; 1753 which = ent; 1754 } 1755 ent->nextcnt = 0; 1756 ent->nexte = NULL; 1757 ent->insn = insn; 1758 ent->priority = order; 1759 1760 while (completer_index != 1) 1761 { 1762 ci = (ci << 1) | (completer_index & 1); 1763 completer_index >>= 1; 1764 } 1765 ent->completer_index = ci; 1766 return which; 1767 } 1768 1769 static void 1770 finish_distable () 1771 { 1772 struct disent *ent = disinsntable; 1773 struct disent *prev = ent; 1774 1775 ent->ournum = 32768; 1776 while ((ent = ent->next_ent) != NULL) 1777 { 1778 ent->ournum = prev->ournum + prev->nextcnt + 1; 1779 prev = ent; 1780 } 1781 } 1782 1783 static void 1784 insert_bit_table_ent (curr_ent, bit, opcode, mask, 1785 opcodenum, order, completer_index) 1786 struct bittree *curr_ent; 1787 int bit; 1788 ia64_insn opcode; 1789 ia64_insn mask; 1790 int opcodenum; 1791 int order; 1792 int completer_index; 1793 { 1794 ia64_insn m; 1795 int b; 1796 struct bittree *next; 1797 1798 if (bit == -1) 1799 { 1800 struct disent *nent = add_dis_table_ent (curr_ent->disent, 1801 opcodenum, order, 1802 completer_index); 1803 curr_ent->disent = nent; 1804 return; 1805 } 1806 1807 m = ((ia64_insn) 1) << bit; 1808 1809 if (mask & m) 1810 b = (opcode & m) ? 1 : 0; 1811 else 1812 b = 2; 1813 1814 next = curr_ent->bits[b]; 1815 if (next == NULL) 1816 { 1817 next = make_bittree_entry (); 1818 curr_ent->bits[b] = next; 1819 } 1820 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order, 1821 completer_index); 1822 } 1823 1824 static void 1825 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) 1826 struct bittree *first; 1827 ia64_insn opcode; 1828 ia64_insn mask; 1829 int opcodenum; 1830 struct completer_entry *ent; 1831 int completer_index; 1832 { 1833 if (completer_index & (1 << 20)) 1834 abort (); 1835 1836 while (ent != NULL) 1837 { 1838 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits; 1839 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, 1840 (completer_index << 1) | 1); 1841 1842 if (ent->is_terminal) 1843 { 1844 insert_bit_table_ent (bittree, 40, newopcode, mask, 1845 opcodenum, opcode_count - ent->order - 1, 1846 (completer_index << 1) | 1); 1847 } 1848 completer_index <<= 1; 1849 ent = ent->alternative; 1850 } 1851 } 1852 1853 /* This optimization pass combines multiple "don't care" nodes. */ 1854 static void 1855 compact_distree (ent) 1856 struct bittree *ent; 1857 { 1858 #define IS_SKIP(ent) \ 1859 ((ent->bits[2] !=NULL) \ 1860 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0)) 1861 1862 int bitcnt = 0; 1863 struct bittree *nent = ent; 1864 int x; 1865 1866 while (IS_SKIP (nent)) 1867 { 1868 bitcnt++; 1869 nent = nent->bits[2]; 1870 } 1871 1872 if (bitcnt) 1873 { 1874 struct bittree *next = ent->bits[2]; 1875 1876 ent->bits[0] = nent->bits[0]; 1877 ent->bits[1] = nent->bits[1]; 1878 ent->bits[2] = nent->bits[2]; 1879 ent->disent = nent->disent; 1880 ent->skip_flag = 1; 1881 ent->bits_to_skip = bitcnt; 1882 while (next != nent) 1883 { 1884 struct bittree *b = next; 1885 next = next->bits[2]; 1886 free (b); 1887 } 1888 free (nent); 1889 } 1890 1891 for (x = 0; x < 3; x++) 1892 { 1893 struct bittree *i = ent->bits[x]; 1894 1895 if (i != NULL) 1896 compact_distree (i); 1897 } 1898 } 1899 1900 static unsigned char *insn_list; 1901 static int insn_list_len = 0; 1902 static int tot_insn_list_len = 0; 1903 1904 /* Generate the disassembler state machine corresponding to the tree 1905 in ENT. */ 1906 static void 1907 gen_dis_table (ent) 1908 struct bittree *ent; 1909 { 1910 int x; 1911 int our_offset = insn_list_len; 1912 int bitsused = 5; 1913 int totbits = bitsused; 1914 int needed_bytes; 1915 int zero_count = 0; 1916 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */ 1917 1918 /* If this is a terminal entry, there's no point in skipping any 1919 bits. */ 1920 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL && 1921 ent->bits[2] == NULL) 1922 { 1923 if (ent->disent == NULL) 1924 abort (); 1925 else 1926 ent->skip_flag = 0; 1927 } 1928 1929 /* Calculate the amount of space needed for this entry, or at least 1930 a conservatively large approximation. */ 1931 if (ent->skip_flag) 1932 totbits += 5; 1933 1934 for (x = 1; x < 3; x++) 1935 if (ent->bits[x] != NULL) 1936 totbits += 16; 1937 1938 if (ent->disent != NULL) 1939 { 1940 if (ent->bits[2] != NULL) 1941 abort (); 1942 1943 totbits += 16; 1944 } 1945 1946 /* Now allocate the space. */ 1947 needed_bytes = (totbits + 7) / 8; 1948 if ((needed_bytes + insn_list_len) > tot_insn_list_len) 1949 { 1950 tot_insn_list_len += 256; 1951 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len); 1952 } 1953 our_offset = insn_list_len; 1954 insn_list_len += needed_bytes; 1955 memset (insn_list + our_offset, 0, needed_bytes); 1956 1957 /* Encode the skip entry by setting bit 6 set in the state op field, 1958 and store the # of bits to skip immediately after. */ 1959 if (ent->skip_flag) 1960 { 1961 bitsused += 5; 1962 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf); 1963 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6); 1964 } 1965 1966 #define IS_ONLY_IFZERO(ENT) \ 1967 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \ 1968 && (ENT)->disent == NULL && (ENT)->skip_flag == 0) 1969 1970 /* Store an "if (bit is zero)" instruction by setting bit 7 in the 1971 state op field. */ 1972 if (ent->bits[0] != NULL) 1973 { 1974 struct bittree *nent = ent->bits[0]; 1975 zero_count = 0; 1976 1977 insn_list[our_offset] |= 0x80; 1978 1979 /* We can encode sequences of multiple "if (bit is zero)" tests 1980 by storing the # of zero bits to check in the lower 3 bits of 1981 the instruction. However, this only applies if the state 1982 solely tests for a zero bit. */ 1983 1984 if (IS_ONLY_IFZERO (ent)) 1985 { 1986 while (IS_ONLY_IFZERO (nent) && zero_count < 7) 1987 { 1988 nent = nent->bits[0]; 1989 zero_count++; 1990 } 1991 1992 insn_list[our_offset + 0] |= zero_count; 1993 } 1994 zero_dest = insn_list_len; 1995 gen_dis_table (nent); 1996 } 1997 1998 /* Now store the remaining tests. We also handle a sole "termination 1999 entry" by storing it as an "any bit" test. */ 2000 2001 for (x = 1; x < 3; x++) 2002 { 2003 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL)) 2004 { 2005 struct bittree *i = ent->bits[x]; 2006 int idest; 2007 int currbits = 15; 2008 2009 if (i != NULL) 2010 { 2011 /* If the instruction being branched to only consists of 2012 a termination entry, use the termination entry as the 2013 place to branch to instead. */ 2014 if (i->bits[0] == NULL && i->bits[1] == NULL 2015 && i->bits[2] == NULL && i->disent != NULL) 2016 { 2017 idest = i->disent->ournum; 2018 i = NULL; 2019 } 2020 else 2021 idest = insn_list_len - our_offset; 2022 } 2023 else 2024 idest = ent->disent->ournum; 2025 2026 /* If the destination offset for the if (bit is 1) test is less 2027 than 256 bytes away, we can store it as 8-bits instead of 16; 2028 the instruction has bit 5 set for the 16-bit address, and bit 2029 4 for the 8-bit address. Since we've already allocated 16 2030 bits for the address we need to deallocate the space. 2031 2032 Note that branchings within the table are relative, and 2033 there are no branches that branch past our instruction yet 2034 so we do not need to adjust any other offsets. */ 2035 if (x == 1) 2036 { 2037 if (idest <= 256) 2038 { 2039 int start = our_offset + bitsused / 8 + 1; 2040 2041 memmove (insn_list + start, 2042 insn_list + start + 1, 2043 insn_list_len - (start + 1)); 2044 currbits = 7; 2045 totbits -= 8; 2046 needed_bytes--; 2047 insn_list_len--; 2048 insn_list[our_offset] |= 0x10; 2049 idest--; 2050 } 2051 else 2052 insn_list[our_offset] |= 0x20; 2053 } 2054 else 2055 { 2056 /* An instruction which solely consists of a termination 2057 marker and whose disassembly name index is < 4096 2058 can be stored in 16 bits. The encoding is slightly 2059 odd; the upper 4 bits of the instruction are 0x3, and 2060 bit 3 loses its normal meaning. */ 2061 2062 if (ent->bits[0] == NULL && ent->bits[1] == NULL 2063 && ent->bits[2] == NULL && ent->skip_flag == 0 2064 && ent->disent != NULL 2065 && ent->disent->ournum < (32768 + 4096)) 2066 { 2067 int start = our_offset + bitsused / 8 + 1; 2068 2069 memmove (insn_list + start, 2070 insn_list + start + 1, 2071 insn_list_len - (start + 1)); 2072 currbits = 11; 2073 totbits -= 5; 2074 bitsused--; 2075 needed_bytes--; 2076 insn_list_len--; 2077 insn_list[our_offset] |= 0x30; 2078 idest &= ~32768; 2079 } 2080 else 2081 insn_list[our_offset] |= 0x08; 2082 } 2083 2084 if (debug) 2085 { 2086 int id = idest; 2087 2088 if (i == NULL) 2089 id |= 32768; 2090 else if (! (id & 32768)) 2091 id += our_offset; 2092 2093 if (x == 1) 2094 printf ("%d: if (1) goto %d\n", our_offset, id); 2095 else 2096 printf ("%d: try %d\n", our_offset, id); 2097 } 2098 2099 /* Store the address of the entry being branched to. */ 2100 while (currbits >= 0) 2101 { 2102 unsigned char *byte = insn_list + our_offset + bitsused / 8; 2103 2104 if (idest & (1 << currbits)) 2105 *byte |= (1 << (7 - (bitsused % 8))); 2106 2107 bitsused++; 2108 currbits--; 2109 } 2110 2111 /* Now generate the states for the entry being branched to. */ 2112 if (i != NULL) 2113 gen_dis_table (i); 2114 } 2115 } 2116 2117 if (debug) 2118 { 2119 if (ent->skip_flag) 2120 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip); 2121 2122 if (ent->bits[0] != NULL) 2123 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1, 2124 zero_dest); 2125 } 2126 2127 if (bitsused != totbits) 2128 abort (); 2129 } 2130 2131 static void 2132 print_dis_table (void) 2133 { 2134 int x; 2135 struct disent *cent = disinsntable; 2136 2137 printf ("static const char dis_table[] = {\n"); 2138 for (x = 0; x < insn_list_len; x++) 2139 { 2140 if ((x > 0) && ((x % 12) == 0)) 2141 printf ("\n"); 2142 2143 printf ("0x%02x, ", insn_list[x]); 2144 } 2145 printf ("\n};\n\n"); 2146 2147 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n"); 2148 while (cent != NULL) 2149 { 2150 struct disent *ent = cent; 2151 2152 while (ent != NULL) 2153 { 2154 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index, 2155 ent->insn, (ent->nexte != NULL ? 1 : 0), 2156 ent->priority); 2157 ent = ent->nexte; 2158 } 2159 cent = cent->next_ent; 2160 } 2161 printf ("};\n\n"); 2162 } 2163 2164 static void 2165 generate_disassembler (void) 2166 { 2167 int i; 2168 2169 bittree = make_bittree_entry (); 2170 2171 for (i = 0; i < otlen; i++) 2172 { 2173 struct main_entry *ptr = ordered_table[i]; 2174 2175 if (ptr->opcode->type != IA64_TYPE_DYN) 2176 add_dis_entry (bittree, 2177 ptr->opcode->opcode, ptr->opcode->mask, 2178 ptr->main_index, 2179 ptr->completers, 1); 2180 } 2181 2182 compact_distree (bittree); 2183 finish_distable (); 2184 gen_dis_table (bittree); 2185 2186 print_dis_table (); 2187 } 2188 2189 static void 2190 print_string_table (void) 2191 { 2192 int x; 2193 char lbuf[80], buf[80]; 2194 int blen = 0; 2195 2196 printf ("static const char * const ia64_strings[] = {\n"); 2197 lbuf[0] = '\0'; 2198 2199 for (x = 0; x < strtablen; x++) 2200 { 2201 int len; 2202 2203 if (strlen (string_table[x]->s) > 75) 2204 abort (); 2205 2206 sprintf (buf, " \"%s\",", string_table[x]->s); 2207 len = strlen (buf); 2208 2209 if ((blen + len) > 75) 2210 { 2211 printf (" %s\n", lbuf); 2212 lbuf[0] = '\0'; 2213 blen = 0; 2214 } 2215 strcat (lbuf, buf); 2216 blen += len; 2217 } 2218 2219 if (blen > 0) 2220 printf (" %s\n", lbuf); 2221 2222 printf ("};\n\n"); 2223 } 2224 2225 static struct completer_entry **glist; 2226 static int glistlen = 0; 2227 static int glisttotlen = 0; 2228 2229 /* If the completer trees ENT1 and ENT2 are equal, return 1. */ 2230 2231 static int 2232 completer_entries_eq (ent1, ent2) 2233 struct completer_entry *ent1, *ent2; 2234 { 2235 while (ent1 != NULL && ent2 != NULL) 2236 { 2237 if (ent1->name->num != ent2->name->num 2238 || ent1->bits != ent2->bits 2239 || ent1->mask != ent2->mask 2240 || ent1->is_terminal != ent2->is_terminal 2241 || ent1->dependencies != ent2->dependencies 2242 || ent1->order != ent2->order) 2243 return 0; 2244 2245 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries)) 2246 return 0; 2247 2248 ent1 = ent1->alternative; 2249 ent2 = ent2->alternative; 2250 } 2251 2252 return ent1 == ent2; 2253 } 2254 2255 /* Insert ENT into the global list of completers and return it. If an 2256 equivalent entry (according to completer_entries_eq) already exists, 2257 it is returned instead. */ 2258 static struct completer_entry * 2259 insert_gclist (struct completer_entry *ent) 2260 { 2261 if (ent != NULL) 2262 { 2263 int i; 2264 int x; 2265 int start = 0, end; 2266 2267 ent->addl_entries = insert_gclist (ent->addl_entries); 2268 ent->alternative = insert_gclist (ent->alternative); 2269 2270 i = glistlen / 2; 2271 end = glistlen; 2272 2273 if (glisttotlen == glistlen) 2274 { 2275 glisttotlen += 20; 2276 glist = (struct completer_entry **) 2277 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen); 2278 } 2279 2280 if (glistlen == 0) 2281 { 2282 glist[0] = ent; 2283 glistlen = 1; 2284 return ent; 2285 } 2286 2287 if (ent->name->num < glist[0]->name->num) 2288 i = 0; 2289 else if (ent->name->num > glist[end - 1]->name->num) 2290 i = end; 2291 else 2292 { 2293 int c; 2294 2295 while (1) 2296 { 2297 i = (start + end) / 2; 2298 c = ent->name->num - glist[i]->name->num; 2299 2300 if (c < 0) 2301 end = i - 1; 2302 else if (c == 0) 2303 { 2304 while (i > 0 2305 && ent->name->num == glist[i - 1]->name->num) 2306 i--; 2307 2308 break; 2309 } 2310 else 2311 start = i + 1; 2312 2313 if (start > end) 2314 break; 2315 } 2316 2317 if (c == 0) 2318 { 2319 while (i < glistlen) 2320 { 2321 if (ent->name->num != glist[i]->name->num) 2322 break; 2323 2324 if (completer_entries_eq (ent, glist[i])) 2325 return glist[i]; 2326 2327 i++; 2328 } 2329 } 2330 } 2331 2332 for (; i > 0 && i < glistlen; i--) 2333 if (ent->name->num >= glist[i - 1]->name->num) 2334 break; 2335 2336 for (; i < glistlen; i++) 2337 if (ent->name->num < glist[i]->name->num) 2338 break; 2339 2340 for (x = glistlen - 1; x >= i; x--) 2341 glist[x + 1] = glist[x]; 2342 2343 glist[i] = ent; 2344 glistlen++; 2345 } 2346 return ent; 2347 } 2348 2349 static int 2350 get_prefix_len (name) 2351 const char *name; 2352 { 2353 char *c; 2354 2355 if (name[0] == '\0') 2356 return 0; 2357 2358 c = strchr (name, '.'); 2359 if (c != NULL) 2360 return c - name; 2361 else 2362 return strlen (name); 2363 } 2364 2365 static void 2366 compute_completer_bits (ment, ent) 2367 struct main_entry *ment; 2368 struct completer_entry *ent; 2369 { 2370 while (ent != NULL) 2371 { 2372 compute_completer_bits (ment, ent->addl_entries); 2373 2374 if (ent->is_terminal) 2375 { 2376 ia64_insn mask = 0; 2377 ia64_insn our_bits = ent->bits; 2378 struct completer_entry *p = ent->parent; 2379 ia64_insn p_bits; 2380 int x; 2381 2382 while (p != NULL && ! p->is_terminal) 2383 p = p->parent; 2384 2385 if (p != NULL) 2386 p_bits = p->bits; 2387 else 2388 p_bits = ment->opcode->opcode; 2389 2390 for (x = 0; x < 64; x++) 2391 { 2392 ia64_insn m = ((ia64_insn) 1) << x; 2393 2394 if ((p_bits & m) != (our_bits & m)) 2395 mask |= m; 2396 else 2397 our_bits &= ~m; 2398 } 2399 ent->bits = our_bits; 2400 ent->mask = mask; 2401 } 2402 else 2403 { 2404 ent->bits = 0; 2405 ent->mask = 0; 2406 } 2407 2408 ent = ent->alternative; 2409 } 2410 } 2411 2412 /* Find identical completer trees that are used in different 2413 instructions and collapse their entries. */ 2414 static void 2415 collapse_redundant_completers (void) 2416 { 2417 struct main_entry *ptr; 2418 int x; 2419 2420 for (ptr = maintable; ptr != NULL; ptr = ptr->next) 2421 { 2422 if (ptr->completers == NULL) 2423 abort (); 2424 2425 compute_completer_bits (ptr, ptr->completers); 2426 ptr->completers = insert_gclist (ptr->completers); 2427 } 2428 2429 /* The table has been finalized, now number the indexes. */ 2430 for (x = 0; x < glistlen; x++) 2431 glist[x]->num = x; 2432 } 2433 2434 2435 /* Attach two lists of dependencies to each opcode. 2436 1) all resources which, when already marked in use, conflict with this 2437 opcode (chks) 2438 2) all resources which must be marked in use when this opcode is used 2439 (regs). */ 2440 static int 2441 insert_opcode_dependencies (opc, cmp) 2442 struct ia64_opcode *opc; 2443 struct completer_entry *cmp ATTRIBUTE_UNUSED; 2444 { 2445 /* Note all resources which point to this opcode. rfi has the most chks 2446 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ 2447 int i; 2448 int nregs = 0; 2449 unsigned short regs[256]; 2450 int nchks = 0; 2451 unsigned short chks[256]; 2452 /* Flag insns for which no class matched; there should be none. */ 2453 int no_class_found = 1; 2454 2455 for (i = 0; i < rdepslen; i++) 2456 { 2457 struct rdep *rs = rdeps[i]; 2458 int j; 2459 2460 if (strcmp (opc->name, "cmp.eq.and") == 0 2461 && CONST_STRNEQ (rs->name, "PR%") 2462 && rs->mode == 1) 2463 no_class_found = 99; 2464 2465 for (j=0; j < rs->nregs;j++) 2466 { 2467 int ic_note = 0; 2468 2469 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) 2470 { 2471 /* We can ignore ic_note 11 for non PR resources. */ 2472 if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) 2473 ic_note = 0; 2474 2475 if (ic_note != 0 && rs->regnotes[j] != 0 2476 && ic_note != rs->regnotes[j] 2477 && !(ic_note == 11 && rs->regnotes[j] == 1)) 2478 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2479 ic_note, opc->name, ics[rs->regs[j]]->name, 2480 rs->name, rs->regnotes[j]); 2481 /* Instruction class notes override resource notes. 2482 So far, only note 11 applies to an IC instead of a resource, 2483 and note 11 implies note 1. */ 2484 if (ic_note) 2485 regs[nregs++] = RDEP(ic_note, i); 2486 else 2487 regs[nregs++] = RDEP(rs->regnotes[j], i); 2488 no_class_found = 0; 2489 ++rs->total_regs; 2490 } 2491 } 2492 2493 for (j = 0; j < rs->nchks; j++) 2494 { 2495 int ic_note = 0; 2496 2497 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) 2498 { 2499 /* We can ignore ic_note 11 for non PR resources. */ 2500 if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR")) 2501 ic_note = 0; 2502 2503 if (ic_note != 0 && rs->chknotes[j] != 0 2504 && ic_note != rs->chknotes[j] 2505 && !(ic_note == 11 && rs->chknotes[j] == 1)) 2506 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2507 ic_note, opc->name, ics[rs->chks[j]]->name, 2508 rs->name, rs->chknotes[j]); 2509 if (ic_note) 2510 chks[nchks++] = RDEP(ic_note, i); 2511 else 2512 chks[nchks++] = RDEP(rs->chknotes[j], i); 2513 no_class_found = 0; 2514 ++rs->total_chks; 2515 } 2516 } 2517 } 2518 2519 if (no_class_found) 2520 warn (_("opcode %s has no class (ops %d %d %d)\n"), 2521 opc->name, 2522 opc->operands[0], opc->operands[1], opc->operands[2]); 2523 2524 return insert_dependencies (nchks, chks, nregs, regs); 2525 } 2526 2527 static void 2528 insert_completer_entry (opc, tabent, order) 2529 struct ia64_opcode *opc; 2530 struct main_entry *tabent; 2531 int order; 2532 { 2533 struct completer_entry **ptr = &tabent->completers; 2534 struct completer_entry *parent = NULL; 2535 char pcopy[129], *prefix; 2536 int at_end = 0; 2537 2538 if (strlen (opc->name) > 128) 2539 abort (); 2540 2541 strcpy (pcopy, opc->name); 2542 prefix = pcopy + get_prefix_len (pcopy); 2543 2544 if (prefix[0] != '\0') 2545 prefix++; 2546 2547 while (! at_end) 2548 { 2549 int need_new_ent = 1; 2550 int plen = get_prefix_len (prefix); 2551 struct string_entry *sent; 2552 2553 at_end = (prefix[plen] == '\0'); 2554 prefix[plen] = '\0'; 2555 sent = insert_string (prefix); 2556 2557 while (*ptr != NULL) 2558 { 2559 int cmpres = sent->num - (*ptr)->name->num; 2560 2561 if (cmpres == 0) 2562 { 2563 need_new_ent = 0; 2564 break; 2565 } 2566 else 2567 ptr = &((*ptr)->alternative); 2568 } 2569 2570 if (need_new_ent) 2571 { 2572 struct completer_entry *nent = tmalloc (struct completer_entry); 2573 2574 nent->name = sent; 2575 nent->parent = parent; 2576 nent->addl_entries = NULL; 2577 nent->alternative = *ptr; 2578 *ptr = nent; 2579 nent->is_terminal = 0; 2580 nent->dependencies = -1; 2581 } 2582 2583 if (! at_end) 2584 { 2585 parent = *ptr; 2586 ptr = &((*ptr)->addl_entries); 2587 prefix += plen + 1; 2588 } 2589 } 2590 2591 if ((*ptr)->is_terminal) 2592 abort (); 2593 2594 (*ptr)->is_terminal = 1; 2595 (*ptr)->mask = (ia64_insn)-1; 2596 (*ptr)->bits = opc->opcode; 2597 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr); 2598 (*ptr)->order = order; 2599 } 2600 2601 static void 2602 print_completer_entry (ent) 2603 struct completer_entry *ent; 2604 { 2605 int moffset = 0; 2606 ia64_insn mask = ent->mask, bits = ent->bits; 2607 2608 if (mask != 0) 2609 { 2610 while (! (mask & 1)) 2611 { 2612 moffset++; 2613 mask = mask >> 1; 2614 bits = bits >> 1; 2615 } 2616 2617 if (bits & 0xffffffff00000000LL) 2618 abort (); 2619 } 2620 2621 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n", 2622 (int)bits, 2623 (int)mask, 2624 ent->name->num, 2625 ent->alternative != NULL ? ent->alternative->num : -1, 2626 ent->addl_entries != NULL ? ent->addl_entries->num : -1, 2627 moffset, 2628 ent->is_terminal ? 1 : 0, 2629 ent->dependencies); 2630 } 2631 2632 static void 2633 print_completer_table () 2634 { 2635 int x; 2636 2637 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n"); 2638 for (x = 0; x < glistlen; x++) 2639 print_completer_entry (glist[x]); 2640 printf ("};\n\n"); 2641 } 2642 2643 static int 2644 opcodes_eq (opc1, opc2) 2645 struct ia64_opcode *opc1; 2646 struct ia64_opcode *opc2; 2647 { 2648 int x; 2649 int plen1, plen2; 2650 2651 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 2652 || (opc1->num_outputs != opc2->num_outputs) 2653 || (opc1->flags != opc2->flags)) 2654 return 0; 2655 2656 for (x = 0; x < 5; x++) 2657 if (opc1->operands[x] != opc2->operands[x]) 2658 return 0; 2659 2660 plen1 = get_prefix_len (opc1->name); 2661 plen2 = get_prefix_len (opc2->name); 2662 2663 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0)) 2664 return 1; 2665 2666 return 0; 2667 } 2668 2669 static void 2670 add_opcode_entry (opc) 2671 struct ia64_opcode *opc; 2672 { 2673 struct main_entry **place; 2674 struct string_entry *name; 2675 char prefix[129]; 2676 int found_it = 0; 2677 2678 if (strlen (opc->name) > 128) 2679 abort (); 2680 2681 place = &maintable; 2682 strcpy (prefix, opc->name); 2683 prefix[get_prefix_len (prefix)] = '\0'; 2684 name = insert_string (prefix); 2685 2686 /* Walk the list of opcode table entries. If it's a new 2687 instruction, allocate and fill in a new entry. Note 2688 the main table is alphabetical by opcode name. */ 2689 2690 while (*place != NULL) 2691 { 2692 if ((*place)->name->num == name->num 2693 && opcodes_eq ((*place)->opcode, opc)) 2694 { 2695 found_it = 1; 2696 break; 2697 } 2698 if ((*place)->name->num > name->num) 2699 break; 2700 2701 place = &((*place)->next); 2702 } 2703 if (! found_it) 2704 { 2705 struct main_entry *nent = tmalloc (struct main_entry); 2706 2707 nent->name = name; 2708 nent->opcode = opc; 2709 nent->next = *place; 2710 nent->completers = 0; 2711 *place = nent; 2712 2713 if (otlen == ottotlen) 2714 { 2715 ottotlen += 20; 2716 ordered_table = (struct main_entry **) 2717 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen); 2718 } 2719 ordered_table[otlen++] = nent; 2720 } 2721 2722 insert_completer_entry (opc, *place, opcode_count++); 2723 } 2724 2725 static void 2726 print_main_table (void) 2727 { 2728 struct main_entry *ptr = maintable; 2729 int index = 0; 2730 2731 printf ("static const struct ia64_main_table\nmain_table[] = {\n"); 2732 while (ptr != NULL) 2733 { 2734 printf (" { %d, %d, %d, 0x", 2735 ptr->name->num, 2736 ptr->opcode->type, 2737 ptr->opcode->num_outputs); 2738 opcode_fprintf_vma (stdout, ptr->opcode->opcode); 2739 printf ("ull, 0x"); 2740 opcode_fprintf_vma (stdout, ptr->opcode->mask); 2741 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n", 2742 ptr->opcode->operands[0], 2743 ptr->opcode->operands[1], 2744 ptr->opcode->operands[2], 2745 ptr->opcode->operands[3], 2746 ptr->opcode->operands[4], 2747 ptr->opcode->flags, 2748 ptr->completers->num); 2749 2750 ptr->main_index = index++; 2751 2752 ptr = ptr->next; 2753 } 2754 printf ("};\n\n"); 2755 } 2756 2757 static void 2758 shrink (table) 2759 struct ia64_opcode *table; 2760 { 2761 int curr_opcode; 2762 2763 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++) 2764 { 2765 add_opcode_entry (table + curr_opcode); 2766 if (table[curr_opcode].num_outputs == 2 2767 && ((table[curr_opcode].operands[0] == IA64_OPND_P1 2768 && table[curr_opcode].operands[1] == IA64_OPND_P2) 2769 || (table[curr_opcode].operands[0] == IA64_OPND_P2 2770 && table[curr_opcode].operands[1] == IA64_OPND_P1))) 2771 { 2772 struct ia64_opcode *alias = tmalloc(struct ia64_opcode); 2773 unsigned i; 2774 2775 *alias = table[curr_opcode]; 2776 for (i = 2; i < NELEMS (alias->operands); ++i) 2777 alias->operands[i - 1] = alias->operands[i]; 2778 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL; 2779 --alias->num_outputs; 2780 alias->flags |= PSEUDO; 2781 add_opcode_entry (alias); 2782 } 2783 } 2784 } 2785 2786 2787 /* Program options. */ 2788 #define OPTION_SRCDIR 200 2789 2790 struct option long_options[] = 2791 { 2792 {"srcdir", required_argument, NULL, OPTION_SRCDIR}, 2793 {"debug", no_argument, NULL, 'd'}, 2794 {"version", no_argument, NULL, 'V'}, 2795 {"help", no_argument, NULL, 'h'}, 2796 {0, no_argument, NULL, 0} 2797 }; 2798 2799 static void 2800 print_version (void) 2801 { 2802 printf ("%s: version 1.0\n", program_name); 2803 xexit (0); 2804 } 2805 2806 static void 2807 usage (FILE * stream, int status) 2808 { 2809 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n", 2810 program_name); 2811 xexit (status); 2812 } 2813 2814 int 2815 main (int argc, char **argv) 2816 { 2817 extern int chdir (char *); 2818 char *srcdir = NULL; 2819 int c; 2820 2821 program_name = *argv; 2822 xmalloc_set_program_name (program_name); 2823 2824 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF) 2825 switch (c) 2826 { 2827 case OPTION_SRCDIR: 2828 srcdir = optarg; 2829 break; 2830 case 'V': 2831 case 'v': 2832 print_version (); 2833 break; 2834 case 'd': 2835 debug = 1; 2836 break; 2837 case 'h': 2838 case '?': 2839 usage (stderr, 0); 2840 default: 2841 case 0: 2842 break; 2843 } 2844 2845 if (optind != argc) 2846 usage (stdout, 1); 2847 2848 if (srcdir != NULL) 2849 if (chdir (srcdir) != 0) 2850 fail (_("unable to change directory to \"%s\", errno = %s\n"), 2851 srcdir, strerror (errno)); 2852 2853 load_insn_classes (); 2854 load_dependencies (); 2855 2856 shrink (ia64_opcodes_a); 2857 shrink (ia64_opcodes_b); 2858 shrink (ia64_opcodes_f); 2859 shrink (ia64_opcodes_i); 2860 shrink (ia64_opcodes_m); 2861 shrink (ia64_opcodes_x); 2862 shrink (ia64_opcodes_d); 2863 2864 collapse_redundant_completers (); 2865 2866 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); 2867 printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\ 2868 \n\ 2869 This file is part of the GNU opcodes library.\n\ 2870 \n\ 2871 This library is free software; you can redistribute it and/or modify\n\ 2872 it under the terms of the GNU General Public License as published by\n\ 2873 the Free Software Foundation; either version 3, or (at your option)\n\ 2874 any later version.\n\ 2875 \n\ 2876 It is distributed in the hope that it will be useful, but WITHOUT\n\ 2877 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\ 2878 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\ 2879 License for more details.\n\ 2880 \n\ 2881 You should have received a copy of the GNU General Public License\n\ 2882 along with this program; see the file COPYING. If not, write to the\n\ 2883 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\ 2884 02110-1301, USA. */\n"); 2885 2886 print_string_table (); 2887 print_dependency_table (); 2888 print_completer_table (); 2889 print_main_table (); 2890 2891 generate_disassembler (); 2892 2893 exit (0); 2894 } 2895