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