Changeset 609 for branches/GNU/src/binutils/opcodes/ia64-gen.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/ia64-gen.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* ia64-gen.c -- Generate a shrunk set of opcode tables 2 Copyright 1999, 2000 Free Software Foundation, Inc.2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3 3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com> 4 4 … … 31 31 32 32 The resource table is constructed based on some text dependency tables, 33 which are also easier to maintain than the final representation. 34 35 */ 33 which are also easier to maintain than the final representation. */ 36 34 37 35 #include <stdio.h> 38 #include <ctype.h> 36 #include <stdarg.h> 37 #include <errno.h> 39 38 40 39 #include "ansidecl.h" 41 40 #include "libiberty.h" 41 #include "safe-ctype.h" 42 42 #include "sysdep.h" 43 #include "getopt.h" 43 44 #include "ia64-opc.h" 44 45 #include "ia64-opc-a.c" … … 50 51 #include "ia64-opc-d.c" 51 52 53 #include <libintl.h> 54 #define _(String) gettext (String) 55 56 const char * program_name = NULL; 52 57 int debug = 0; 53 58 … … 56 61 /* The main opcode table entry. Each entry is a unique combination of 57 62 name and flags (no two entries in the table compare as being equal 58 via opcodes_eq). */63 via opcodes_eq). */ 59 64 struct main_entry 60 65 { 61 66 /* The base name of this opcode. The names of its completers are 62 appended to it to generate the full instruction name. */67 appended to it to generate the full instruction name. */ 63 68 struct string_entry *name; 64 69 /* The base opcode entry. Which one to use is a fairly arbitrary choice; 65 it uses the first one passed to add_opcode_entry. */70 it uses the first one passed to add_opcode_entry. */ 66 71 struct ia64_opcode *opcode; 67 /* The list of completers that can be applied to this opcode. */72 /* The list of completers that can be applied to this opcode. */ 68 73 struct completer_entry *completers; 69 /* Next entry in the chain. */74 /* Next entry in the chain. */ 70 75 struct main_entry *next; 71 /* Index in the main table. */76 /* Index in the main table. */ 72 77 int main_index; 73 78 } *maintable, **ordered_table; 79 74 80 int otlen = 0; 75 81 int ottotlen = 0; 76 82 int opcode_count = 0; 77 83 78 /* The set of possible completers for an opcode. */84 /* The set of possible completers for an opcode. */ 79 85 struct completer_entry 80 86 { 81 /* This entry's index in the ia64_completer_table[] array. */87 /* This entry's index in the ia64_completer_table[] array. */ 82 88 int num; 83 89 84 /* The name of the completer. */90 /* The name of the completer. */ 85 91 struct string_entry *name; 86 92 87 /* This entry's parent. */93 /* This entry's parent. */ 88 94 struct completer_entry *parent; 89 95 90 96 /* Set if this is a terminal completer (occurs at the end of an 91 opcode). */97 opcode). */ 92 98 int is_terminal; 93 99 94 /* An alternative completer. */100 /* An alternative completer. */ 95 101 struct completer_entry *alternative; 96 102 … … 101 107 instruction opcode for this combination of opcode and completers. 102 108 Afterwards, it contains those bits that are different from its 103 parent opcode. */109 parent opcode. */ 104 110 ia64_insn bits; 105 111 … … 107 113 that are different from its parent completer's opcode (or from 108 114 the base opcode if the entry is the root of the opcode's completer 109 list). This field is filled in by compute_completer_bits (). */115 list). This field is filled in by compute_completer_bits (). */ 110 116 ia64_insn mask; 111 117 112 /* Index into the opcode dependency list, or -1 if none. */118 /* Index into the opcode dependency list, or -1 if none. */ 113 119 int dependencies; 114 120 … … 117 123 }; 118 124 119 /* One entry in the disassembler name table. */125 /* One entry in the disassembler name table. */ 120 126 struct disent 121 127 { 122 /* The index into the ia64_name_dis array for this entry. */128 /* The index into the ia64_name_dis array for this entry. */ 123 129 int ournum; 124 130 125 /* The index into the main_table[] array. */131 /* The index into the main_table[] array. */ 126 132 int insn; 127 133 128 /* The disassmbly priority of this entry. */134 /* The disassmbly priority of this entry. */ 129 135 int priority; 130 136 131 /* The completer_index value for this entry. */137 /* The completer_index value for this entry. */ 132 138 int completer_index; 133 139 134 /* How many other entries share this decode. */140 /* How many other entries share this decode. */ 135 141 int nextcnt; 136 142 137 /* The next entry sharing the same decode. */143 /* The next entry sharing the same decode. */ 138 144 struct disent *nexte; 139 145 140 /* The next entry in the name list. */146 /* The next entry in the name list. */ 141 147 struct disent *next_ent; 142 148 } *disinsntable = NULL; 143 149 144 150 /* A state machine that will eventually be used to generate the 145 disassembler table. */151 disassembler table. */ 146 152 struct bittree 147 153 { 148 154 struct disent *disent; 149 struct bittree *bits[3]; /* 0, 1, and X (don't care) */155 struct bittree *bits[3]; /* 0, 1, and X (don't care). */ 150 156 int bits_to_skip; 151 157 int skip_flag; … … 155 161 alphabetical order. */ 156 162 157 /* One entry in the string table. */163 /* One entry in the string table. */ 158 164 struct string_entry 159 165 { 160 /* The index in the ia64_strings[] array for this entry. */166 /* The index in the ia64_strings[] array for this entry. */ 161 167 int num; 162 /* And the string. */168 /* And the string. */ 163 169 char *s; 164 170 } **string_table = NULL; 171 165 172 int strtablen = 0; 166 173 int strtabtotlen = 0; … … 168 175 169 176 170 /* resource dependency entries*/177 /* Resource dependency entries. */ 171 178 struct rdep 172 179 { 173 char *name; /* resource name*/180 char *name; /* Resource name. */ 174 181 unsigned 175 mode:2, /* RAW, WAW, or WAR */176 semantics:3; /* dependency semantics*/177 char *extra; /* additional semantics info*/182 mode:2, /* RAW, WAW, or WAR. */ 183 semantics:3; /* Dependency semantics. */ 184 char *extra; /* Additional semantics info. */ 178 185 int nchks; 179 int total_chks; /* total #of terminal insns*/180 int *chks; /* insn classes which read (RAW), write181 (WAW), or write (WAR) this rsrc */182 int *chknotes; /* dependency notes for each class*/186 int total_chks; /* Total #of terminal insns. */ 187 int *chks; /* Insn classes which read (RAW), write 188 (WAW), or write (WAR) this rsrc. */ 189 int *chknotes; /* Dependency notes for each class. */ 183 190 int nregs; 184 int total_regs; /* total #of terminal insns*/185 int *regs; /* insn class which write (RAW), write2186 (WAW), or read (WAR) this rsrc */187 int *regnotes; /* dependency notes for each class*/188 189 int waw_special; /* special WAW dependency note*/191 int total_regs; /* Total #of terminal insns. */ 192 int *regs; /* Insn class which write (RAW), write2 193 (WAW), or read (WAR) this rsrc. */ 194 int *regnotes; /* Dependency notes for each class. */ 195 196 int waw_special; /* Special WAW dependency note. */ 190 197 } **rdeps = NULL; 191 198 … … 193 200 static int rdepstotlen = 0; 194 201 195 /* array of all instruction classes*/202 /* Array of all instruction classes. */ 196 203 struct iclass 197 204 { 198 char *name; /* instruction class name*/199 int is_class; /* is a class, not a terminal*/205 char *name; /* Instruction class name. */ 206 int is_class; /* Is a class, not a terminal. */ 200 207 int nsubs; 201 int *subs; /* other classes within this class*/208 int *subs; /* Other classes within this class. */ 202 209 int nxsubs; 203 int xsubs[4]; /* exclusions*/204 char *comment; /* optional comment*/205 int note; /* optional note*/206 int terminal_resolved; /* did we match this with anything?*/207 int orphan; /* detect class orphans*/210 int xsubs[4]; /* Exclusions. */ 211 char *comment; /* Optional comment. */ 212 int note; /* Optional note. */ 213 int terminal_resolved; /* Did we match this with anything? */ 214 int orphan; /* Detect class orphans. */ 208 215 } **ics = NULL; 209 216 … … 211 218 static int ictotlen = 0; 212 219 213 /* an opcode dependency (chk/reg pair of dependency lists)*/220 /* An opcode dependency (chk/reg pair of dependency lists). */ 214 221 struct opdep 215 222 { … … 221 228 static int opdeptotlen = 0; 222 229 223 /* a generic list of dependencies w/notes encoded. these may be shared.*/230 /* A generic list of dependencies w/notes encoded. These may be shared. */ 224 231 struct deplist 225 232 { … … 231 238 static int dlisttotlen = 0; 232 239 233 /* add NAME to the resource table, where TYPE is RAW or WAW */ 240 241 static void fail (const char *, ...); 242 static void warn (const char *, ...); 243 static struct rdep * insert_resource (const char *, enum ia64_dependency_mode); 244 static int deplist_equals (struct deplist *, struct deplist *); 245 static short insert_deplist (int, unsigned short *); 246 static short insert_dependencies (int, unsigned short *, int, unsigned short *); 247 static void mark_used (struct iclass *, int); 248 static int fetch_insn_class (const char *, int); 249 static int sub_compare (const void *, const void *); 250 static void load_insn_classes (void); 251 static void parse_resource_users (const char *, int **, int *, int **); 252 static int parse_semantics (char *); 253 static void add_dep (const char *, const char *, const char *, int, int, char *, int); 254 static void load_depfile (const char *, enum ia64_dependency_mode); 255 static void load_dependencies (void); 256 static int irf_operand (int, const char *); 257 static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *); 258 static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *); 259 static int lookup_regindex (const char *, int); 260 static int lookup_specifier (const char *); 261 static void print_dependency_table (void); 262 static struct string_entry * insert_string (char *); 263 static void gen_dis_table (struct bittree *); 264 static void print_dis_table (void); 265 static void generate_disassembler (void); 266 static void print_string_table (void); 267 static int completer_entries_eq (struct completer_entry *, struct completer_entry *); 268 static struct completer_entry * insert_gclist (struct completer_entry *); 269 static int get_prefix_len (const char *); 270 static void compute_completer_bits (struct main_entry *, struct completer_entry *); 271 static void collapse_redundant_completers (void); 272 static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *); 273 static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int); 274 static void print_completer_entry (struct completer_entry *); 275 static void print_completer_table (void); 276 static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *); 277 static void add_opcode_entry (struct ia64_opcode *); 278 static void print_main_table (void); 279 static void shrink (struct ia64_opcode *); 280 static void print_version (void); 281 static void usage (FILE *, int); 282 static void finish_distable (void); 283 static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, int); 284 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int); 285 static void compact_distree (struct bittree *); 286 static struct bittree * make_bittree_entry (void); 287 static struct disent * add_dis_table_ent (struct disent *, int, int, int); 288 289 290 291 static void 292 fail (const char *message, ...) 293 { 294 va_list args; 295 296 va_start (args, message); 297 fprintf (stderr, _("%s: Error: "), program_name); 298 vfprintf (stderr, message, args); 299 va_end (args); 300 xexit (1); 301 } 302 303 static void 304 warn (const char *message, ...) 305 { 306 va_list args; 307 308 va_start (args, message); 309 310 fprintf (stderr, _("%s: Warning: "), program_name); 311 vfprintf (stderr, message, args); 312 va_end (args); 313 } 314 315 /* Add NAME to the resource table, where TYPE is RAW or WAW. */ 234 316 static struct rdep * 235 317 insert_resource (const char *name, enum ia64_dependency_mode type) … … 250 332 } 251 333 252 /* are the lists of dependency indexes equivalent?*/334 /* Are the lists of dependency indexes equivalent? */ 253 335 static int 254 336 deplist_equals (struct deplist *d1, struct deplist *d2) … … 259 341 return 0; 260 342 261 for (i=0;i < d1->len;i++) 262 { 263 if (d1->deps[i] != d2->deps[i]) 264 return 0; 265 } 343 for (i = 0; i < d1->len; i++) 344 if (d1->deps[i] != d2->deps[i]) 345 return 0; 266 346 267 347 return 1; 268 348 } 269 349 270 /* add the list of dependencies to the list of dependency lists*/350 /* Add the list of dependencies to the list of dependency lists. */ 271 351 static short 272 insert_deplist(int count, unsigned short *deps) 273 { 274 /* sort the list, then see if an equivalent list exists already. 275 this results in a much smaller set of dependency lists 276 */ 352 insert_deplist (int count, unsigned short *deps) 353 { 354 /* Sort the list, then see if an equivalent list exists already. 355 this results in a much smaller set of dependency lists. */ 277 356 struct deplist *list; 278 357 char set[0x10000]; 279 358 int i; 280 359 281 memset ((void *)set, 0, sizeof (set));282 for (i =0;i < count;i++)360 memset ((void *)set, 0, sizeof (set)); 361 for (i = 0; i < count; i++) 283 362 set[deps[i]] = 1; 363 284 364 count = 0; 285 for (i =0;i < (int)sizeof(set);i++)365 for (i = 0; i < (int) sizeof (set); i++) 286 366 if (set[i]) 287 367 ++count; 288 368 289 list = tmalloc (struct deplist);369 list = tmalloc (struct deplist); 290 370 list->len = count; 291 list->deps = (unsigned short *)malloc (sizeof(unsigned short) * count); 292 for (i=0, count=0;i < (int)sizeof(set);i++) 293 { 294 if (set[i]) 295 { 296 list->deps[count++] = i; 297 } 298 } 299 300 /* does this list exist already? */ 301 for (i=0;i < dlistlen;i++) 302 { 303 if (deplist_equals (list, dlists[i])) 304 { 305 free (list->deps); 306 free (list); 307 return i; 308 } 309 } 371 list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count); 372 373 for (i = 0, count = 0; i < (int) sizeof (set); i++) 374 if (set[i]) 375 list->deps[count++] = i; 376 377 /* Does this list exist already? */ 378 for (i = 0; i < dlistlen; i++) 379 if (deplist_equals (list, dlists[i])) 380 { 381 free (list->deps); 382 free (list); 383 return i; 384 } 310 385 311 386 if (dlistlen == dlisttotlen) … … 320 395 } 321 396 322 /* add the given pair of dependency lists to the opcode dependency list*/397 /* Add the given pair of dependency lists to the opcode dependency list. */ 323 398 static short 324 399 insert_dependencies (int nchks, unsigned short *chks, … … 335 410 chkind = insert_deplist (nchks, chks); 336 411 337 for (i=0;i < opdeplen;i++) 338 { 339 if (opdeps[i]->chk == chkind 340 && opdeps[i]->reg == regind) 341 return i; 342 } 343 pair = tmalloc(struct opdep); 412 for (i = 0; i < opdeplen; i++) 413 if (opdeps[i]->chk == chkind 414 && opdeps[i]->reg == regind) 415 return i; 416 417 pair = tmalloc (struct opdep); 344 418 pair->chk = chkind; 345 419 pair->reg = regind; … … 365 439 ic->terminal_resolved = 1; 366 440 367 for (i=0;i < ic->nsubs;i++) 368 { 369 mark_used (ics[ic->subs[i]], clear_terminals); 370 } 371 for (i=0;i < ic->nxsubs;i++) 372 { 373 mark_used (ics[ic->xsubs[i]], clear_terminals); 374 } 375 } 376 377 /* look up an instruction class; if CREATE make a new one if none found; 378 returns the index into the insn class array */ 441 for (i = 0; i < ic->nsubs; i++) 442 mark_used (ics[ic->subs[i]], clear_terminals); 443 444 for (i = 0; i < ic->nxsubs; i++) 445 mark_used (ics[ic->xsubs[i]], clear_terminals); 446 } 447 448 /* Look up an instruction class; if CREATE make a new one if none found; 449 returns the index into the insn class array. */ 379 450 static int 380 fetch_insn_class (const char *full_name, int create)451 fetch_insn_class (const char *full_name, int create) 381 452 { 382 453 char *name; … … 416 487 { 417 488 char *nextnotestr; 489 418 490 note = atoi (notestr + 1); 419 491 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) … … 422 494 note = 13; 423 495 else if (!xsect || nextnotestr < xsect) 424 fprintf (stderr, "Warning: multiple note %s not handled\n", 425 notestr); 496 warn (_("multiple note %s not handled\n"), notestr); 426 497 } 427 498 } … … 438 509 } 439 510 440 for (i =0;i < iclen;i++)441 if (strcmp (name, ics[i]->name) == 0511 for (i = 0; i < iclen; i++) 512 if (strcmp (name, ics[i]->name) == 0 442 513 && ((comment == NULL && ics[i]->comment == NULL) 443 514 || (comment != NULL && ics[i]->comment != NULL … … 450 521 return -1; 451 522 452 /* doesn't exist, so make a new one*/523 /* Doesn't exist, so make a new one. */ 453 524 if (iclen == ictotlen) 454 525 { 455 526 ictotlen += 20; 456 527 ics = (struct iclass **) 457 xrealloc(ics, (ictotlen)*sizeof(struct iclass *)); 458 } 528 xrealloc (ics, (ictotlen) * sizeof (struct iclass *)); 529 } 530 459 531 ind = iclen++; 460 ics[ind] = tmalloc (struct iclass);461 memset ((void *)ics[ind], 0, sizeof(struct iclass));462 ics[ind]->name = xstrdup (name);532 ics[ind] = tmalloc (struct iclass); 533 memset ((void *)ics[ind], 0, sizeof (struct iclass)); 534 ics[ind]->name = xstrdup (name); 463 535 ics[ind]->is_class = is_class; 464 536 ics[ind]->orphan = 1; … … 467 539 { 468 540 ics[ind]->comment = xstrdup (comment + 1); 469 ics[ind]->comment[strlen(ics[ind]->comment)-1] = 0; 470 } 541 ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0; 542 } 543 471 544 if (notestr) 472 545 ics[ind]->note = note; 473 546 474 /* if it's a composite class, there's a comment or note, look for an475 existing class or terminal with the same name. */547 /* If it's a composite class, there's a comment or note, look for an 548 existing class or terminal with the same name. */ 476 549 if ((xsect || comment || notestr) && is_class) 477 550 { 478 551 /* First, populate with the class we're based on. */ 479 552 char *subname = name; 553 480 554 if (xsect) 481 555 *xsect = 0; … … 484 558 else if (notestr) 485 559 *notestr = 0; 560 486 561 ics[ind]->nsubs = 1; 487 562 ics[ind]->subs = tmalloc(int); … … 492 567 { 493 568 char *subname = xsect + 1; 569 494 570 xsect = strchr (subname, '\\'); 495 571 if (xsect) … … 503 579 } 504 580 505 /* for sorting a class's sub-class list only; make sure classes appear before506 terminals */581 /* For sorting a class's sub-class list only; make sure classes appear before 582 terminals. */ 507 583 static int 508 584 sub_compare (const void *e1, const void *e2) … … 523 599 524 600 static void 525 load_insn_classes ()526 { 527 FILE *fp = fopen ("ia64-ic.tbl", "r");601 load_insn_classes (void) 602 { 603 FILE *fp = fopen ("ia64-ic.tbl", "r"); 528 604 char buf[2048]; 529 605 530 if (fp == NULL){ 531 fprintf (stderr, "Can't find ia64-ic.tbl for reading\n"); 532 exit(1); 533 } 534 535 /* discard first line */ 606 if (fp == NULL) 607 fail (_("can't find ia64-ic.tbl for reading\n")); 608 609 /* Discard first line. */ 536 610 fgets (buf, sizeof(buf), fp); 537 611 538 while (!feof (fp))612 while (!feof (fp)) 539 613 { 540 614 int iclass; … … 542 616 char *tmp; 543 617 544 if (fgets (buf, sizeof (buf), fp) == NULL)618 if (fgets (buf, sizeof (buf), fp) == NULL) 545 619 break; 546 620 547 while ( isspace(buf[strlen(buf)-1]))548 buf[strlen (buf)-1] = '\0';621 while (ISSPACE (buf[strlen (buf) - 1])) 622 buf[strlen (buf) - 1] = '\0'; 549 623 550 624 name = tmp = buf; … … 552 626 { 553 627 ++tmp; 554 if (tmp == buf + sizeof (buf))628 if (tmp == buf + sizeof (buf)) 555 629 abort (); 556 630 } 557 631 *tmp++ = '\0'; 558 632 559 iclass = fetch_insn_class (name, 1);633 iclass = fetch_insn_class (name, 1); 560 634 ics[iclass]->is_class = 1; 561 635 … … 567 641 } 568 642 569 /* for this class, record all sub-classes*/643 /* For this class, record all sub-classes. */ 570 644 while (*tmp) 571 645 { … … 573 647 int sub; 574 648 575 while (*tmp && isspace(*tmp))649 while (*tmp && ISSPACE (*tmp)) 576 650 { 577 651 ++tmp; 578 if (tmp == buf + sizeof (buf))579 abort ();652 if (tmp == buf + sizeof (buf)) 653 abort (); 580 654 } 581 655 subname = tmp; … … 583 657 { 584 658 ++tmp; 585 if (tmp == buf + sizeof (buf))586 abort ();659 if (tmp == buf + sizeof (buf)) 660 abort (); 587 661 } 588 662 if (*tmp == ',') … … 590 664 591 665 ics[iclass]->subs = (int *) 592 xrealloc ((void *)ics[iclass]->subs,593 (ics[iclass]->nsubs+1)*sizeof(int));594 595 sub = fetch_insn_class (subname, 1);666 xrealloc ((void *)ics[iclass]->subs, 667 (ics[iclass]->nsubs + 1) * sizeof (int)); 668 669 sub = fetch_insn_class (subname, 1); 596 670 ics[iclass]->subs = (int *) 597 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs+1)*sizeof(int));671 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int)); 598 672 ics[iclass]->subs[ics[iclass]->nsubs++] = sub; 599 673 } 600 /* make sure classes come before terminals */ 674 675 /* Make sure classes come before terminals. */ 601 676 qsort ((void *)ics[iclass]->subs, 602 677 ics[iclass]->nsubs, sizeof(int), sub_compare); 603 678 } 604 fclose (fp);679 fclose (fp); 605 680 606 681 if (debug) 607 { 608 printf ("%d classes\n", iclen); 609 } 610 } 611 612 /* extract the insn classes from the given line */ 682 printf ("%d classes\n", iclen); 683 } 684 685 /* Extract the insn classes from the given line. */ 613 686 static void 614 parse_resource_users (ref, usersp, nusersp, notesp)615 c har *ref;687 parse_resource_users (ref, usersp, nusersp, notesp) 688 const char *ref; 616 689 int **usersp; 617 690 int *nusersp; … … 635 708 char *name; 636 709 637 while ( isspace(*tmp))710 while (ISSPACE (*tmp)) 638 711 ++tmp; 639 712 name = tmp; … … 643 716 *tmp++ = '\0'; 644 717 645 xsect = strchr (name, '\\');646 if ((notestr = strstr (name, "+")) != NULL)718 xsect = strchr (name, '\\'); 719 if ((notestr = strstr (name, "+")) != NULL) 647 720 { 648 721 char *nextnotestr; 722 649 723 note = atoi (notestr + 1); 650 724 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 651 725 { 652 /* note 13 always implies note 1*/726 /* Note 13 always implies note 1. */ 653 727 if (strcmp (notestr, "+1+13") == 0) 654 728 note = 13; 655 729 else if (!xsect || nextnotestr < xsect) 656 fprintf (stderr, "Warning: multiple note %s not handled\n", 657 notestr); 730 warn (_("multiple note %s not handled\n"), notestr); 658 731 } 659 732 if (!xsect) … … 662 735 else 663 736 note = 0; 664 737 665 738 /* All classes are created when the insn class table is parsed; 666 739 Individual instructions might not appear until the dependency tables 667 740 are read. Only create new classes if it's *not* an insn class, 668 741 or if it's a composite class (which wouldn't necessarily be in the IC 669 table). 670 */ 671 if (strncmp(name, "IC:", 3) != 0 || xsect != NULL) 742 table). */ 743 if (strncmp (name, "IC:", 3) != 0 || xsect != NULL) 672 744 create = 1; 673 745 674 iclass = fetch_insn_class (name, create);746 iclass = fetch_insn_class (name, create); 675 747 if (iclass != -1) 676 748 { 677 749 users = (int *) 678 xrealloc ((void *) users,(count+1)*sizeof(int));750 xrealloc ((void *) users,(count + 1) * sizeof (int)); 679 751 notes = (int *) 680 xrealloc ((void *) notes,(count+1)*sizeof(int));752 xrealloc ((void *) notes,(count + 1) * sizeof (int)); 681 753 notes[count] = note; 682 754 users[count++] = iclass; 683 755 mark_used (ics[iclass], 0); 684 756 } 685 else 686 { 687 if (debug) 688 printf("Class %s not found\n", name); 689 } 690 } 691 /* update the return values */ 757 else if (debug) 758 printf("Class %s not found\n", name); 759 } 760 /* Update the return values. */ 692 761 *usersp = users; 693 762 *nusersp = count; … … 725 794 726 795 rs = insert_resource (name, mode); 727 parse_resource_users (chk, &rs->chks, &rs->nchks, 728 729 parse_resource_users (reg, &rs->regs, &rs->nregs, 730 &rs->regnotes); 796 797 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes); 798 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes); 799 731 800 rs->semantics = semantics; 732 801 rs->extra = extra; … … 737 806 load_depfile (const char *filename, enum ia64_dependency_mode mode) 738 807 { 739 FILE *fp = fopen (filename, "r");808 FILE *fp = fopen (filename, "r"); 740 809 char buf[1024]; 741 810 742 if (fp == NULL){ 743 fprintf (stderr, "Can't find %s for reading\n", filename); 744 exit(1); 745 } 746 747 fgets(buf, sizeof(buf), fp); 748 while (!feof(fp)) 811 if (fp == NULL) 812 fail (_("can't find %s for reading\n"), filename); 813 814 fgets (buf, sizeof(buf), fp); 815 while (!feof (fp)) 749 816 { 750 817 char *name, *tmp; … … 756 823 break; 757 824 758 while ( isspace(buf[strlen(buf)-1]))759 buf[strlen (buf)-1] = '\0';825 while (ISSPACE (buf[strlen (buf) - 1])) 826 buf[strlen (buf) - 1] = '\0'; 760 827 761 828 name = tmp = buf; … … 764 831 *tmp++ = '\0'; 765 832 766 while ( isspace(*tmp))833 while (ISSPACE (*tmp)) 767 834 ++tmp; 768 835 regp = tmp; … … 771 838 abort (); 772 839 *tmp++ = 0; 773 while ( isspace(*tmp))840 while (ISSPACE (*tmp)) 774 841 ++tmp; 775 842 chkp = tmp; … … 778 845 abort (); 779 846 *tmp++ = 0; 780 while ( isspace(*tmp))847 while (ISSPACE (*tmp)) 781 848 ++tmp; 782 849 semantics = parse_semantics (tmp); … … 785 852 /* For WAW entries, if the chks and regs differ, we need to enter the 786 853 entries in both positions so that the tables will be parsed properly, 787 without a lot of extra work */854 without a lot of extra work. */ 788 855 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0) 789 856 { … … 796 863 } 797 864 } 798 fclose (fp);865 fclose (fp); 799 866 } 800 867 801 868 static void 802 load_dependencies ()869 load_dependencies (void) 803 870 { 804 871 load_depfile ("ia64-raw.tbl", IA64_DV_RAW); … … 807 874 808 875 if (debug) 809 810 } 811 812 /* is the given operand an indirect register file operand?*/876 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen); 877 } 878 879 /* Is the given operand an indirect register file operand? */ 813 880 static int 814 881 irf_operand (int op, const char *field) … … 834 901 } 835 902 836 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and837 mov_um insn classes */903 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and 904 mov_um insn classes. */ 838 905 static int 839 906 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, … … 949 1016 } 950 1017 951 952 /* is the given opcode in the given insn class? */ 1018 /* Is the given opcode in the given insn class? */ 953 1019 static int 954 in_iclass (struct ia64_opcode *idesc, struct iclass *ic,955 1020 in_iclass (struct ia64_opcode *idesc, struct iclass *ic, 1021 const char *format, const char *field, int *notep) 956 1022 { 957 1023 int i; … … 962 1028 if (!strncmp (ic->comment, "Format", 6)) 963 1029 { 964 /* assume that the first format seen is the most restrictive, and965 only keep a later one if it looks like it's more restrictive. */1030 /* Assume that the first format seen is the most restrictive, and 1031 only keep a later one if it looks like it's more restrictive. */ 966 1032 if (format) 967 1033 { 968 1034 if (strlen (ic->comment) < strlen (format)) 969 1035 { 970 fprintf (stderr, "Warning: most recent format '%s'\n" 971 "appears more restrictive than '%s'\n", 972 ic->comment, format); 1036 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"), 1037 ic->comment, format); 973 1038 format = ic->comment; 974 1039 } … … 980 1045 { 981 1046 if (field) 982 fprintf (stderr, "Overlapping field %s->%s\n",983 1047 warn (_("overlapping field %s->%s\n"), 1048 ic->comment, field); 984 1049 field = ic->comment; 985 1050 } 986 1051 } 987 1052 988 /* an insn class matches anything that is the same followed by completers,1053 /* An insn class matches anything that is the same followed by completers, 989 1054 except when the absence and presence of completers constitutes different 990 instructions */1055 instructions. */ 991 1056 if (ic->nsubs == 0 && ic->nxsubs == 0) 992 1057 { … … 999 1064 || idesc->name[len] == '.')); 1000 1065 1001 /* all break and nop variations must match exactly*/1066 /* All break, nop, and hint variations must match exactly. */ 1002 1067 if (resolved && 1003 1068 (strcmp (ic->name, "break") == 0 1004 || strcmp (ic->name, "nop") == 0)) 1069 || strcmp (ic->name, "nop") == 0 1070 || strcmp (ic->name, "hint") == 0)) 1005 1071 resolved = strcmp (ic->name, idesc->name) == 0; 1006 1072 1007 /* assume restrictions in the FORMAT/FIELD negate resolution,1008 unless specifically allowed by clauses in this block */1073 /* Assume restrictions in the FORMAT/FIELD negate resolution, 1074 unless specifically allowed by clauses in this block. */ 1009 1075 if (resolved && field) 1010 1076 { 1011 /* check Field(sf)==sN against opcode sN*/1077 /* Check Field(sf)==sN against opcode sN. */ 1012 1078 if (strstr(field, "(sf)==") != NULL) 1013 1079 { 1014 1080 char *sf; 1081 1015 1082 if ((sf = strstr (idesc->name, ".s")) != 0) 1016 { 1017 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0; 1018 } 1083 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0; 1019 1084 } 1020 /* check Field(lftype)==XXX*/1085 /* Check Field(lftype)==XXX. */ 1021 1086 else if (strstr (field, "(lftype)") != NULL) 1022 1087 { … … 1026 1091 resolved = strstr (field, "fault") == NULL; 1027 1092 } 1028 /* handle Field(ctype)==XXX*/1093 /* Handle Field(ctype)==XXX. */ 1029 1094 else if (strstr (field, "(ctype)") != NULL) 1030 1095 { … … 1047 1112 } 1048 1113 } 1114 1049 1115 if (resolved && format) 1050 1116 { … … 1077 1143 } 1078 1144 1079 /* misc brl variations ('.cond' is optional);1080 plain brl matches brl.cond */1145 /* Misc brl variations ('.cond' is optional); 1146 plain brl matches brl.cond. */ 1081 1147 if (!resolved 1082 1148 && (strcmp (idesc->name, "brl") == 0 … … 1087 1153 } 1088 1154 1089 /* misc br variations ('.cond' is optional)*/1155 /* Misc br variations ('.cond' is optional). */ 1090 1156 if (!resolved 1091 1157 && (strcmp (idesc->name, "br") == 0 … … 1102 1168 } 1103 1169 1104 /* probe variations */1170 /* probe variations. */ 1105 1171 if (!resolved && strncmp (idesc->name, "probe", 5) == 0) 1106 1172 { … … 1109 1175 ^ (format && strstr (format, "M40") != NULL)); 1110 1176 } 1111 /* mov variations */ 1177 1178 /* mov variations. */ 1112 1179 if (!resolved && is_mov) 1113 1180 { 1114 1181 if (plain_mov) 1115 1182 { 1116 /* mov alias for fmerge */1183 /* mov alias for fmerge. */ 1117 1184 if (strcmp (ic->name, "fmerge") == 0) 1118 1185 { … … 1120 1187 && idesc->operands[1] == IA64_OPND_F3; 1121 1188 } 1122 /* mov alias for adds (r3 or imm14) */1189 /* mov alias for adds (r3 or imm14). */ 1123 1190 else if (strcmp (ic->name, "adds") == 0) 1124 1191 { … … 1127 1194 || (idesc->operands[1] == IA64_OPND_IMM14))); 1128 1195 } 1129 /* mov alias for addl */1196 /* mov alias for addl. */ 1130 1197 else if (strcmp (ic->name, "addl") == 0) 1131 1198 { … … 1134 1201 } 1135 1202 } 1136 /* some variants of mov and mov.[im] */ 1203 1204 /* Some variants of mov and mov.[im]. */ 1137 1205 if (!resolved && strncmp (ic->name, "mov_", 4) == 0) 1138 { 1139 resolved = in_iclass_mov_x (idesc, ic, format, field); 1140 } 1206 resolved = in_iclass_mov_x (idesc, ic, format, field); 1141 1207 } 1142 1208 1143 /* keep track of this so we can flag any insn classes which aren't1144 mapped onto at least one real insn */1209 /* Keep track of this so we can flag any insn classes which aren't 1210 mapped onto at least one real insn. */ 1145 1211 if (resolved) 1146 { 1147 ic->terminal_resolved = 1; 1148 } 1149 } 1150 else for (i=0;i < ic->nsubs;i++) 1151 { 1152 if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep)) 1212 ic->terminal_resolved = 1; 1213 } 1214 else for (i = 0; i < ic->nsubs; i++) 1215 { 1216 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep)) 1153 1217 { 1154 1218 int j; 1155 for (j=0;j < ic->nxsubs;j++) 1156 {1157 if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))1158 1159 } 1219 1220 for (j = 0; j < ic->nxsubs; j++) 1221 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL)) 1222 return 0; 1223 1160 1224 if (debug > 1) 1161 printf ("%s is in IC %s\n", 1162 idesc->name, ic->name); 1225 printf ("%s is in IC %s\n", idesc->name, ic->name); 1226 1163 1227 resolved = 1; 1164 1228 break; … … 1166 1230 } 1167 1231 1168 /* If it's in this IC, add the IC note (if any) to the insn */1232 /* If it's in this IC, add the IC note (if any) to the insn. */ 1169 1233 if (resolved) 1170 1234 { … … 1172 1236 { 1173 1237 if (*notep && *notep != ic->note) 1174 { 1175 fprintf (stderr, "Warning: overwriting note %d with note %d" 1176 "(IC:%s)\n", 1177 *notep, ic->note, ic->name); 1178 } 1238 warn (_("overwriting note %d with note %d (IC:%s)\n"), 1239 *notep, ic->note, ic->name); 1240 1179 1241 *notep = ic->note; 1180 1242 } … … 1200 1262 else if (strstr (name, "[RNAT]")) 1201 1263 return 19; 1264 else if (strstr (name, "[FCR]")) 1265 return 21; 1266 else if (strstr (name, "[EFLAG]")) 1267 return 24; 1268 else if (strstr (name, "[CSD]")) 1269 return 25; 1270 else if (strstr (name, "[SSD]")) 1271 return 26; 1272 else if (strstr (name, "[CFLG]")) 1273 return 27; 1274 else if (strstr (name, "[FSR]")) 1275 return 28; 1276 else if (strstr (name, "[FIR]")) 1277 return 29; 1278 else if (strstr (name, "[FDR]")) 1279 return 30; 1202 1280 else if (strstr (name, "[CCV]")) 1203 1281 return 32; … … 1358 1436 return IA64_RS_PRr; 1359 1437 1360 fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",1361 1438 warn (_("don't know how to specify %% dependency %s\n"), 1439 name); 1362 1440 } 1363 1441 else if (strchr (name, '#')) … … 1380 1458 return IA64_RS_RR; 1381 1459 1382 fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",1383 1460 warn (_("Don't know how to specify # dependency %s\n"), 1461 name); 1384 1462 } 1385 1463 else if (strncmp (name, "AR[FPSR]", 8) == 0) … … 1405 1483 } 1406 1484 1407 void1485 static void 1408 1486 print_dependency_table () 1409 1487 { … … 1418 1496 if (!ics[i]->nsubs) 1419 1497 { 1420 fprintf (stderr, "Warning: IC:%s", ics[i]->name);1421 1498 if (ics[i]->comment) 1422 fprintf (stderr, "[%s]", ics[i]->comment); 1423 fprintf (stderr, " has no terminals or sub-classes\n"); 1499 warn (_("IC:%s [%s] has no terminals or sub-classes\n"), 1500 ics[i]->name, ics[i]->comment); 1501 else 1502 warn (_("IC:%s has no terminals or sub-classes\n"), 1503 ics[i]->name); 1424 1504 } 1425 1505 } … … 1428 1508 if (!ics[i]->terminal_resolved && !ics[i]->orphan) 1429 1509 { 1430 fprintf(stderr, "Warning: no insns mapped directly to "1431 "terminal IC %s", ics[i]->name);1432 1510 if (ics[i]->comment) 1433 fprintf(stderr, "[%s] ", ics[i]->comment); 1434 fprintf(stderr, "\n"); 1511 warn (_("no insns mapped directly to terminal IC %s [%s]"), 1512 ics[i]->name, ics[i]->comment); 1513 else 1514 warn (_("no insns mapped directly to terminal IC %s\n"), 1515 ics[i]->name); 1435 1516 } 1436 1517 } 1437 1518 } 1438 1519 1439 for (i =0;i < iclen;i++)1520 for (i = 0; i < iclen; i++) 1440 1521 { 1441 1522 if (ics[i]->orphan) 1442 1523 { 1443 1524 mark_used (ics[i], 1); 1444 fprintf (stderr, "Warning: class %s is defined but not used\n",1445 1525 warn (_("class %s is defined but not used\n"), 1526 ics[i]->name); 1446 1527 } 1447 1528 } 1448 1529 1449 if (debug > 1) for (i=0;i < rdepslen;i++) 1450 { 1451 static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1452 if (rdeps[i]->total_chks == 0) 1453 { 1454 fprintf (stderr, "Warning: rsrc %s (%s) has no chks%s\n", 1455 rdeps[i]->name, mode_str[rdeps[i]->mode], 1456 rdeps[i]->total_regs ? "" : " or regs"); 1457 } 1458 else if (rdeps[i]->total_regs == 0) 1459 { 1460 fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n", 1461 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1462 } 1463 } 1464 } 1465 1466 /* the dependencies themselves */ 1530 if (debug > 1) 1531 for (i = 0; i < rdepslen; i++) 1532 { 1533 static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1534 1535 if (rdeps[i]->total_chks == 0) 1536 warn (_("Warning: rsrc %s (%s) has no chks%s\n"), 1537 rdeps[i]->name, mode_str[rdeps[i]->mode], 1538 rdeps[i]->total_regs ? "" : " or regs"); 1539 else if (rdeps[i]->total_regs == 0) 1540 warn (_("rsrc %s (%s) has no regs\n"), 1541 rdeps[i]->name, mode_str[rdeps[i]->mode]); 1542 } 1543 } 1544 1545 /* The dependencies themselves. */ 1467 1546 printf ("static const struct ia64_dependency\ndependencies[] = {\n"); 1468 for (i =0;i < rdepslen;i++)1547 for (i = 0; i < rdepslen; i++) 1469 1548 { 1470 1549 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual 1471 resource used */1550 resource used. */ 1472 1551 int specifier = lookup_specifier (rdeps[i]->name); 1473 1552 int regindex = lookup_regindex (rdeps[i]->name, specifier); … … 1484 1563 printf ("};\n\n"); 1485 1564 1486 /* and dependency lists*/1565 /* And dependency lists. */ 1487 1566 for (i=0;i < dlistlen;i++) 1488 1567 { … … 1501 1580 } 1502 1581 1503 /* and opcode dependency list*/1582 /* And opcode dependency list. */ 1504 1583 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); 1505 1584 printf ("static const struct ia64_opcode_dependency\n"); 1506 1585 printf ("op_dependencies[] = {\n"); 1507 for (i =0;i < opdeplen;i++)1586 for (i = 0; i < opdeplen; i++) 1508 1587 { 1509 1588 printf (" { "); … … 1523 1602 1524 1603 1525 /* Add STR to the string table. */ 1526 1604 /* Add STR to the string table. */ 1527 1605 static struct string_entry * 1528 insert_string (str) 1529 char *str; 1606 insert_string (char *str) 1530 1607 { 1531 1608 int start = 0, end = strtablen; … … 1550 1627 1551 1628 if (strcmp (str, string_table[strtablen - 1]->s) > 0) 1552 { 1553 i = end; 1554 } 1629 i = end; 1555 1630 else if (strcmp (str, string_table[0]->s) < 0) 1556 { 1557 i = 0; 1558 } 1631 i = 0; 1559 1632 else 1560 1633 { … … 1565 1638 i = (start + end) / 2; 1566 1639 c = strcmp (str, string_table[i]->s); 1640 1567 1641 if (c < 0) 1568 { 1569 end = i - 1; 1570 } 1642 end = i - 1; 1571 1643 else if (c == 0) 1572 { 1573 return string_table[i]; 1574 } 1644 return string_table[i]; 1575 1645 else 1576 { 1577 start = i + 1; 1578 } 1646 start = i + 1; 1647 1579 1648 if (start > end) 1580 { 1581 break; 1582 } 1649 break; 1583 1650 } 1584 1651 } 1652 1585 1653 for (; i > 0 && i < strtablen; i--) 1586 { 1587 if (strcmp (str, string_table[i - 1]->s) > 0) 1588 { 1589 break; 1590 } 1591 } 1654 if (strcmp (str, string_table[i - 1]->s) > 0) 1655 break; 1656 1592 1657 for (; i < strtablen; i++) 1593 { 1594 if (strcmp (str, string_table[i]->s) < 0) 1595 { 1596 break; 1597 } 1598 } 1658 if (strcmp (str, string_table[i]->s) < 0) 1659 break; 1660 1599 1661 for (x = strtablen - 1; x >= i; x--) 1600 1662 { … … 1602 1664 string_table[x + 1]->num = x + 1; 1603 1665 } 1666 1604 1667 string_table[i] = tmalloc (struct string_entry); 1605 1668 string_table[i]->s = xstrdup (str); 1606 1669 string_table[i]->num = i; 1607 1670 strtablen++; 1671 1608 1672 return string_table[i]; 1609 1673 } 1610 1674 1611 1675 1612 st ruct bittree *1613 make_bittree_entry ( )1676 static struct bittree * 1677 make_bittree_entry (void) 1614 1678 { 1615 1679 struct bittree *res = tmalloc (struct bittree); … … 1623 1687 return res; 1624 1688 } 1625 1626 1627 struct disent * 1689 1690 1691 1692 static struct disent * 1628 1693 add_dis_table_ent (which, insn, order, completer_index) 1629 1694 struct disent *which; … … 1641 1706 ent->nextcnt++; 1642 1707 while (ent->nexte != NULL) 1643 { 1644 ent = ent->nexte; 1645 } 1708 ent = ent->nexte; 1709 1646 1710 ent = (ent->nexte = tmalloc (struct disent)); 1647 1711 } … … 1668 1732 1669 1733 1670 void1734 static void 1671 1735 finish_distable () 1672 1736 { … … 1683 1747 1684 1748 1685 void1749 static void 1686 1750 insert_bit_table_ent (curr_ent, bit, opcode, mask, 1687 1751 opcodenum, order, completer_index) … … 1710 1774 1711 1775 if (mask & m) 1712 { 1713 b = (opcode & m) ? 1 : 0; 1714 } 1776 b = (opcode & m) ? 1 : 0; 1715 1777 else 1716 { 1717 b = 2; 1718 } 1778 b = 2; 1779 1719 1780 next = curr_ent->bits[b]; 1720 1781 if (next == NULL) … … 1728 1789 1729 1790 1730 void1791 static void 1731 1792 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index) 1732 1793 struct bittree *first; … … 1738 1799 { 1739 1800 if (completer_index & (1 << 20)) 1740 { 1741 abort (); 1742 } 1801 abort (); 1743 1802 1744 1803 while (ent != NULL) … … 1747 1806 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, 1748 1807 (completer_index << 1) | 1); 1808 1749 1809 if (ent->is_terminal) 1750 1810 { … … 1759 1819 1760 1820 1761 /* This optimization pass combines multiple "don't care" nodes. */1762 void1821 /* This optimization pass combines multiple "don't care" nodes. */ 1822 static void 1763 1823 compact_distree (ent) 1764 1824 struct bittree *ent; … … 1800 1860 { 1801 1861 struct bittree *i = ent->bits[x]; 1862 1802 1863 if (i != NULL) 1803 { 1804 compact_distree (i); 1805 } 1864 compact_distree (i); 1806 1865 } 1807 1866 } … … 1814 1873 /* Generate the disassembler state machine corresponding to the tree 1815 1874 in ENT. */ 1816 void1875 static void 1817 1876 gen_dis_table (ent) 1818 1877 struct bittree *ent; … … 1824 1883 int needed_bytes; 1825 1884 int zero_count = 0; 1826 int zero_dest = 0; /* initialize this with 0 to keep gcc quiet...*/1885 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */ 1827 1886 1828 1887 /* If this is a terminal entry, there's no point in skipping any 1829 bits. */1888 bits. */ 1830 1889 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL && 1831 1890 ent->bits[2] == NULL) 1832 1891 { 1833 1892 if (ent->disent == NULL) 1834 { 1835 abort (); 1836 } 1893 abort (); 1837 1894 else 1838 { 1839 ent->skip_flag = 0; 1840 } 1895 ent->skip_flag = 0; 1841 1896 } 1842 1897 1843 1898 /* Calculate the amount of space needed for this entry, or at least 1844 a conservatively large approximation. */1899 a conservatively large approximation. */ 1845 1900 if (ent->skip_flag) 1846 { 1847 totbits += 5; 1848 } 1901 totbits += 5; 1902 1849 1903 for (x = 1; x < 3; x++) 1850 { 1851 if (ent->bits[x] != NULL) 1852 { 1853 totbits += 16; 1854 } 1855 } 1904 if (ent->bits[x] != NULL) 1905 totbits += 16; 1856 1906 1857 1907 if (ent->disent != NULL) 1858 1908 { 1859 1909 if (ent->bits[2] != NULL) 1860 { 1861 abort (); 1862 } 1910 abort (); 1911 1863 1912 totbits += 16; 1864 1913 } 1865 1914 1866 /* Now allocate the space. */1915 /* Now allocate the space. */ 1867 1916 needed_bytes = (totbits + 7) / 8; 1868 1917 if ((needed_bytes + insn_list_len) > tot_insn_list_len) … … 1876 1925 1877 1926 /* Encode the skip entry by setting bit 6 set in the state op field, 1878 and store the # of bits to skip immediately after. */1927 and store the # of bits to skip immediately after. */ 1879 1928 if (ent->skip_flag) 1880 1929 { … … 1889 1938 1890 1939 /* Store an "if (bit is zero)" instruction by setting bit 7 in the 1891 state op field. */ 1892 1940 state op field. */ 1893 1941 if (ent->bits[0] != NULL) 1894 1942 { … … 1940 1988 } 1941 1989 else 1942 { 1943 idest = insn_list_len - our_offset; 1944 } 1990 idest = insn_list_len - our_offset; 1945 1991 } 1946 1992 else 1947 { 1948 idest = ent->disent->ournum; 1949 } 1993 idest = ent->disent->ournum; 1950 1994 1951 1995 /* If the destination offset for the if (bit is 1) test is less … … 1957 2001 Note that branchings within the table are relative, and 1958 2002 there are no branches that branch past our instruction yet 1959 so we do not need to adjust any other offsets. */ 1960 2003 so we do not need to adjust any other offsets. */ 1961 2004 if (x == 1) 1962 2005 { … … 1976 2019 } 1977 2020 else 1978 { 1979 insn_list[our_offset] |= 0x20; 1980 } 2021 insn_list[our_offset] |= 0x20; 1981 2022 } 1982 2023 else … … 2007 2048 } 2008 2049 else 2009 { 2010 insn_list[our_offset] |= 0x08; 2011 } 2050 insn_list[our_offset] |= 0x08; 2012 2051 } 2052 2013 2053 if (debug) 2014 2054 { … … 2016 2056 2017 2057 if (i == NULL) 2018 { 2019 id |= 32768; 2020 } 2058 id |= 32768; 2021 2059 else if (! (id & 32768)) 2022 { 2023 id += our_offset; 2024 } 2060 id += our_offset; 2061 2025 2062 if (x == 1) 2026 { 2027 printf ("%d: if (1) goto %d\n", our_offset, id); 2028 } 2063 printf ("%d: if (1) goto %d\n", our_offset, id); 2029 2064 else 2030 { 2031 printf ("%d: try %d\n", our_offset, id); 2032 } 2065 printf ("%d: try %d\n", our_offset, id); 2033 2066 } 2034 2067 2035 /* Store the address of the entry being branched to. */2068 /* Store the address of the entry being branched to. */ 2036 2069 while (currbits >= 0) 2037 2070 { … … 2039 2072 2040 2073 if (idest & (1 << currbits)) 2041 { 2042 *byte |= (1 << (7 - (bitsused % 8))); 2043 } 2074 *byte |= (1 << (7 - (bitsused % 8))); 2075 2044 2076 bitsused++; 2045 2077 currbits--; 2046 2078 } 2047 2079 2048 /* Now generate the states for the entry being branched to. */2080 /* Now generate the states for the entry being branched to. */ 2049 2081 if (i != NULL) 2050 { 2051 gen_dis_table (i); 2052 } 2053 2082 gen_dis_table (i); 2054 2083 } 2055 2084 } 2085 2056 2086 if (debug) 2057 2087 { 2058 2088 if (ent->skip_flag) 2059 { 2060 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip); 2061 } 2089 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip); 2062 2090 2063 2091 if (ent->bits[0] != NULL) 2064 { 2065 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1, 2066 zero_dest); 2067 } 2068 } 2092 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1, 2093 zero_dest); 2094 } 2095 2069 2096 if (bitsused != totbits) 2070 { 2071 abort (); 2072 } 2073 } 2074 2075 2076 void 2077 print_dis_table () 2097 abort (); 2098 } 2099 2100 2101 static void 2102 print_dis_table (void) 2078 2103 { 2079 2104 int x; … … 2084 2109 { 2085 2110 if ((x > 0) && ((x % 12) == 0)) 2086 { 2087 printf ("\n"); 2088 } 2111 printf ("\n"); 2112 2089 2113 printf ("0x%02x, ", insn_list[x]); 2090 2114 } … … 2109 2133 2110 2134 2111 void2112 generate_disassembler ( )2135 static void 2136 generate_disassembler (void) 2113 2137 { 2114 2138 int i; … … 2116 2140 bittree = make_bittree_entry (); 2117 2141 2118 for (i =0; i < otlen;i++)2142 for (i = 0; i < otlen; i++) 2119 2143 { 2120 2144 struct main_entry *ptr = ordered_table[i]; 2121 2145 2122 2146 if (ptr->opcode->type != IA64_TYPE_DYN) 2123 { 2124 add_dis_entry (bittree, 2125 ptr->opcode->opcode, ptr->opcode->mask, 2126 ptr->main_index, 2127 ptr->completers, 1); 2128 } 2147 add_dis_entry (bittree, 2148 ptr->opcode->opcode, ptr->opcode->mask, 2149 ptr->main_index, 2150 ptr->completers, 1); 2129 2151 } 2130 2152 … … 2137 2159 2138 2160 2139 void2140 print_string_table ( )2161 static void 2162 print_string_table (void) 2141 2163 { 2142 2164 int x; … … 2144 2166 int blen = 0; 2145 2167 2146 printf ("static const char * ia64_strings[] = {\n");2168 printf ("static const char * const ia64_strings[] = {\n"); 2147 2169 lbuf[0] = '\0'; 2170 2148 2171 for (x = 0; x < strtablen; x++) 2149 2172 { … … 2151 2174 2152 2175 if (strlen (string_table[x]->s) > 75) 2153 { 2154 abort (); 2155 } 2176 abort (); 2177 2156 2178 sprintf (buf, " \"%s\",", string_table[x]->s); 2157 2179 len = strlen (buf); 2180 2158 2181 if ((blen + len) > 75) 2159 2182 { … … 2165 2188 blen += len; 2166 2189 } 2190 2167 2191 if (blen > 0) 2168 { 2169 printf (" %s\n", lbuf); 2170 } 2192 printf (" %s\n", lbuf); 2193 2171 2194 printf ("};\n\n"); 2172 2195 } … … 2177 2200 static int glisttotlen = 0; 2178 2201 2179 /* If the completer trees ENT1 and ENT2 are equal, return 1. */2180 2181 int2202 /* If the completer trees ENT1 and ENT2 are equal, return 1. */ 2203 2204 static int 2182 2205 completer_entries_eq (ent1, ent2) 2183 2206 struct completer_entry *ent1, *ent2; … … 2191 2214 || ent1->dependencies != ent2->dependencies 2192 2215 || ent1->order != ent2->order) 2193 { 2194 return 0; 2195 } 2216 return 0; 2217 2196 2218 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries)) 2197 { 2198 return 0; 2199 } 2219 return 0; 2220 2200 2221 ent1 = ent1->alternative; 2201 2222 ent2 = ent2->alternative; 2202 2223 } 2224 2203 2225 return ent1 == ent2; 2204 2226 } … … 2207 2229 /* Insert ENT into the global list of completers and return it. If an 2208 2230 equivalent entry (according to completer_entries_eq) already exists, 2209 it is returned instead. */ 2210 struct completer_entry * 2211 insert_gclist (ent) 2212 struct completer_entry *ent; 2231 it is returned instead. */ 2232 static struct completer_entry * 2233 insert_gclist (struct completer_entry *ent) 2213 2234 { 2214 2235 if (ent != NULL) … … 2239 2260 2240 2261 if (ent->name->num < glist[0]->name->num) 2241 { 2242 i = 0; 2243 } 2262 i = 0; 2244 2263 else if (ent->name->num > glist[end - 1]->name->num) 2245 { 2246 i = end; 2247 } 2264 i = end; 2248 2265 else 2249 2266 { … … 2254 2271 i = (start + end) / 2; 2255 2272 c = ent->name->num - glist[i]->name->num; 2273 2256 2274 if (c < 0) 2257 { 2258 end = i - 1; 2259 } 2275 end = i - 1; 2260 2276 else if (c == 0) 2261 2277 { 2262 2278 while (i > 0 2263 2279 && ent->name->num == glist[i - 1]->name->num) 2264 { 2265 i--; 2266 } 2280 i--; 2281 2267 2282 break; 2268 2283 } 2269 2284 else 2270 { 2271 start = i + 1; 2272 } 2285 start = i + 1; 2286 2273 2287 if (start > end) 2274 { 2275 break; 2276 } 2288 break; 2277 2289 } 2290 2278 2291 if (c == 0) 2279 2292 { … … 2281 2294 { 2282 2295 if (ent->name->num != glist[i]->name->num) 2283 { 2284 break; 2285 } 2296 break; 2297 2286 2298 if (completer_entries_eq (ent, glist[i])) 2287 { 2288 return glist[i]; 2289 } 2299 return glist[i]; 2300 2290 2301 i++; 2291 2302 } 2292 2303 } 2293 2304 } 2305 2294 2306 for (; i > 0 && i < glistlen; i--) 2295 { 2296 if (ent->name->num >= glist[i - 1]->name->num) 2297 { 2298 break; 2299 } 2300 } 2307 if (ent->name->num >= glist[i - 1]->name->num) 2308 break; 2309 2301 2310 for (; i < glistlen; i++) 2302 { 2303 if (ent->name->num < glist[i]->name->num) 2304 { 2305 break; 2306 } 2307 } 2311 if (ent->name->num < glist[i]->name->num) 2312 break; 2313 2308 2314 for (x = glistlen - 1; x >= i; x--) 2309 { 2310 glist[x + 1] = glist[x]; 2311 } 2315 glist[x + 1] = glist[x]; 2316 2312 2317 glist[i] = ent; 2313 2318 glistlen++; … … 2324 2329 2325 2330 if (name[0] == '\0') 2326 { 2327 return 0; 2328 } 2331 return 0; 2329 2332 2330 2333 c = strchr (name, '.'); 2331 2334 if (c != NULL) 2332 { 2333 return c - name; 2334 } 2335 return c - name; 2335 2336 else 2336 { 2337 return strlen (name); 2338 } 2337 return strlen (name); 2339 2338 } 2340 2339 … … 2358 2357 2359 2358 while (p != NULL && ! p->is_terminal) 2360 { 2361 p = p->parent; 2362 } 2359 p = p->parent; 2363 2360 2364 2361 if (p != NULL) 2365 { 2366 p_bits = p->bits; 2367 } 2362 p_bits = p->bits; 2368 2363 else 2369 { 2370 p_bits = ment->opcode->opcode; 2371 } 2364 p_bits = ment->opcode->opcode; 2372 2365 2373 2366 for (x = 0; x < 64; x++) 2374 2367 { 2375 2368 ia64_insn m = ((ia64_insn) 1) << x; 2369 2376 2370 if ((p_bits & m) != (our_bits & m)) 2377 { 2378 mask |= m; 2379 } 2371 mask |= m; 2380 2372 else 2381 { 2382 our_bits &= ~m; 2383 } 2373 our_bits &= ~m; 2384 2374 } 2385 2375 ent->bits = our_bits; … … 2398 2388 2399 2389 /* Find identical completer trees that are used in different 2400 instructions and collapse their entries. */2401 void2402 collapse_redundant_completers ( )2390 instructions and collapse their entries. */ 2391 static void 2392 collapse_redundant_completers (void) 2403 2393 { 2404 2394 struct main_entry *ptr; … … 2408 2398 { 2409 2399 if (ptr->completers == NULL) 2410 { 2411 abort (); 2412 } 2400 abort (); 2401 2413 2402 compute_completer_bits (ptr, ptr->completers); 2414 2403 ptr->completers = insert_gclist (ptr->completers); … … 2417 2406 /* The table has been finalized, now number the indexes. */ 2418 2407 for (x = 0; x < glistlen; x++) 2419 { 2420 glist[x]->num = x; 2421 } 2422 } 2423 2424 2425 2426 /* attach two lists of dependencies to each opcode. 2408 glist[x]->num = x; 2409 } 2410 2411 2412 2413 /* Attach two lists of dependencies to each opcode. 2427 2414 1) all resources which, when already marked in use, conflict with this 2428 2415 opcode (chks) 2429 2416 2) all resources which must be marked in use when this opcode is used 2430 (regs) 2431 */ 2432 int 2417 (regs). */ 2418 static int 2433 2419 insert_opcode_dependencies (opc, cmp) 2434 2420 struct ia64_opcode *opc; 2435 2421 struct completer_entry *cmp ATTRIBUTE_UNUSED; 2436 2422 { 2437 /* note all resources which point to this opcode. rfi has the most chks2438 (79) and cmpxchng has the most regs (54) so 100 here should be enough */2423 /* Note all resources which point to this opcode. rfi has the most chks 2424 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ 2439 2425 int i; 2440 2426 int nregs = 0; … … 2442 2428 int nchks = 0; 2443 2429 unsigned short chks[256]; 2444 /* flag insns for which no class matched; there should be none*/2430 /* Flag insns for which no class matched; there should be none. */ 2445 2431 int no_class_found = 1; 2446 2432 2447 for (i =0;i < rdepslen;i++)2433 for (i = 0; i < rdepslen; i++) 2448 2434 { 2449 2435 struct rdep *rs = rdeps[i]; … … 2461 2447 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) 2462 2448 { 2463 /* We can ignore ic_note 11 for non PR resources */2449 /* We can ignore ic_note 11 for non PR resources. */ 2464 2450 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0) 2465 2451 ic_note = 0; … … 2468 2454 && ic_note != rs->regnotes[j] 2469 2455 && !(ic_note == 11 && rs->regnotes[j] == 1)) 2470 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)" 2471 " conflicts with resource %s note %d\n", 2472 ic_note, opc->name, ics[rs->regs[j]]->name, 2473 rs->name, rs->regnotes[j]); 2456 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2457 ic_note, opc->name, ics[rs->regs[j]]->name, 2458 rs->name, rs->regnotes[j]); 2474 2459 /* Instruction class notes override resource notes. 2475 2460 So far, only note 11 applies to an IC instead of a resource, 2476 and note 11 implies note 1. 2477 */ 2461 and note 11 implies note 1. */ 2478 2462 if (ic_note) 2479 2463 regs[nregs++] = RDEP(ic_note, i); … … 2484 2468 } 2485 2469 } 2486 for (j=0;j < rs->nchks;j++) 2470 2471 for (j = 0; j < rs->nchks; j++) 2487 2472 { 2488 2473 int ic_note = 0; … … 2490 2475 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) 2491 2476 { 2492 /* We can ignore ic_note 11 for non PR resources */2477 /* We can ignore ic_note 11 for non PR resources. */ 2493 2478 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0) 2494 2479 ic_note = 0; … … 2497 2482 && ic_note != rs->chknotes[j] 2498 2483 && !(ic_note == 11 && rs->chknotes[j] == 1)) 2499 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)" 2500 " conflicts with resource %s note %d\n", 2501 ic_note, opc->name, ics[rs->chks[j]]->name, 2502 rs->name, rs->chknotes[j]); 2484 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2485 ic_note, opc->name, ics[rs->chks[j]]->name, 2486 rs->name, rs->chknotes[j]); 2503 2487 if (ic_note) 2504 2488 chks[nchks++] = RDEP(ic_note, i); … … 2512 2496 2513 2497 if (no_class_found) 2514 fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n",2515 2516 2498 warn (_("opcode %s has no class (ops %d %d %d)\n"), 2499 opc->name, 2500 opc->operands[0], opc->operands[1], opc->operands[2]); 2517 2501 2518 2502 return insert_dependencies (nchks, chks, nregs, regs); … … 2520 2504 2521 2505 2522 void2506 static void 2523 2507 insert_completer_entry (opc, tabent, order) 2524 2508 struct ia64_opcode *opc; … … 2532 2516 2533 2517 if (strlen (opc->name) > 128) 2534 { 2535 abort (); 2536 } 2518 abort (); 2519 2537 2520 strcpy (pcopy, opc->name); 2538 2521 prefix = pcopy + get_prefix_len (pcopy); 2522 2539 2523 if (prefix[0] != '\0') 2540 { 2541 prefix++; 2542 } 2524 prefix++; 2543 2525 2544 2526 while (! at_end) … … 2562 2544 } 2563 2545 else 2564 { 2565 ptr = &((*ptr)->alternative); 2566 } 2546 ptr = &((*ptr)->alternative); 2567 2547 } 2548 2568 2549 if (need_new_ent) 2569 2550 { 2570 2551 struct completer_entry *nent = tmalloc (struct completer_entry); 2552 2571 2553 nent->name = sent; 2572 2554 nent->parent = parent; … … 2587 2569 2588 2570 if ((*ptr)->is_terminal) 2589 { 2590 abort (); 2591 } 2571 abort (); 2592 2572 2593 2573 (*ptr)->is_terminal = 1; … … 2599 2579 2600 2580 2601 void2581 static void 2602 2582 print_completer_entry (ent) 2603 2583 struct completer_entry *ent; … … 2614 2594 bits = bits >> 1; 2615 2595 } 2596 2616 2597 if (bits & 0xffffffff00000000LL) 2617 { 2618 abort (); 2619 } 2598 abort (); 2620 2599 } 2621 2600 … … 2632 2611 2633 2612 2634 void2613 static void 2635 2614 print_completer_table () 2636 2615 { … … 2639 2618 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n"); 2640 2619 for (x = 0; x < glistlen; x++) 2641 { 2642 print_completer_entry (glist[x]); 2643 } 2620 print_completer_entry (glist[x]); 2644 2621 printf ("};\n\n"); 2645 2622 } 2646 2623 2647 2624 2648 int2625 static int 2649 2626 opcodes_eq (opc1, opc2) 2650 2627 struct ia64_opcode *opc1; … … 2657 2634 || (opc1->num_outputs != opc2->num_outputs) 2658 2635 || (opc1->flags != opc2->flags)) 2659 { 2636 return 0; 2637 2638 for (x = 0; x < 5; x++) 2639 if (opc1->operands[x] != opc2->operands[x]) 2660 2640 return 0; 2661 } 2662 for (x = 0; x < 5; x++) 2663 { 2664 if (opc1->operands[x] != opc2->operands[x]) 2665 { 2666 return 0; 2667 } 2668 } 2641 2669 2642 plen1 = get_prefix_len (opc1->name); 2670 2643 plen2 = get_prefix_len (opc2->name); 2644 2671 2645 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0)) 2672 { 2673 return 1; 2674 } 2646 return 1; 2647 2675 2648 return 0; 2676 2649 } 2677 2650 2678 2651 2679 void2652 static void 2680 2653 add_opcode_entry (opc) 2681 2654 struct ia64_opcode *opc; … … 2687 2660 2688 2661 if (strlen (opc->name) > 128) 2689 { 2690 abort (); 2691 } 2662 abort (); 2663 2692 2664 place = &maintable; 2693 2665 strcpy (prefix, opc->name); … … 2697 2669 /* Walk the list of opcode table entries. If it's a new 2698 2670 instruction, allocate and fill in a new entry. Note 2699 the main table is alphabetical by opcode name. */2671 the main table is alphabetical by opcode name. */ 2700 2672 2701 2673 while (*place != NULL) … … 2708 2680 } 2709 2681 if ((*place)->name->num > name->num) 2710 { 2711 break; 2712 } 2682 break; 2683 2713 2684 place = &((*place)->next); 2714 2685 } … … 2736 2707 2737 2708 2738 void2739 print_main_table ( )2709 static void 2710 print_main_table (void) 2740 2711 { 2741 2712 struct main_entry *ptr = maintable; … … 2769 2740 2770 2741 2771 void2742 static void 2772 2743 shrink (table) 2773 2744 struct ia64_opcode *table; … … 2776 2747 2777 2748 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++) 2778 { 2779 add_opcode_entry (table + curr_opcode); 2780 } 2781 } 2782 2749 add_opcode_entry (table + curr_opcode); 2750 } 2751 2752 2753 2754 /* Program options. */ 2755 #define OPTION_SRCDIR 200 2756 2757 struct option long_options[] = 2758 { 2759 {"srcdir", required_argument, NULL, OPTION_SRCDIR}, 2760 {"debug", no_argument, NULL, 'd'}, 2761 {"version", no_argument, NULL, 'V'}, 2762 {"help", no_argument, NULL, 'h'}, 2763 {0, no_argument, NULL, 0} 2764 }; 2765 2766 static void 2767 print_version (void) 2768 { 2769 printf ("%s: version 1.0\n", program_name); 2770 xexit (0); 2771 } 2772 2773 static void 2774 usage (FILE * stream, int status) 2775 { 2776 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n", 2777 program_name); 2778 xexit (status); 2779 } 2783 2780 2784 2781 int 2785 main (argc, argv) 2786 int argc; 2787 char **argv ATTRIBUTE_UNUSED; 2788 { 2789 if (argc > 1) 2790 { 2791 debug = 1; 2792 } 2793 2794 load_insn_classes(); 2795 load_dependencies(); 2782 main (int argc, char **argv) 2783 { 2784 extern int chdir (char *); 2785 char *srcdir = NULL; 2786 int c; 2787 2788 program_name = *argv; 2789 xmalloc_set_program_name (program_name); 2790 2791 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF) 2792 switch (c) 2793 { 2794 case OPTION_SRCDIR: 2795 srcdir = optarg; 2796 break; 2797 case 'V': 2798 case 'v': 2799 print_version (); 2800 break; 2801 case 'd': 2802 debug = 1; 2803 break; 2804 case 'h': 2805 case '?': 2806 usage (stderr, 0); 2807 default: 2808 case 0: 2809 break; 2810 } 2811 2812 if (optind != argc) 2813 usage (stdout, 1); 2814 2815 if (srcdir != NULL) 2816 if (chdir (srcdir) != 0) 2817 fail (_("unable to change directory to \"%s\", errno = %s\n"), 2818 srcdir, strerror (errno)); 2819 2820 load_insn_classes (); 2821 load_dependencies (); 2796 2822 2797 2823 shrink (ia64_opcodes_a); … … 2805 2831 collapse_redundant_completers (); 2806 2832 2807 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");2833 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); 2808 2834 print_string_table (); 2809 2835 print_dependency_table (); -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.