00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <stdio.h>
00041 #include <stdarg.h>
00042 #include <errno.h>
00043
00044 #include "ansidecl.h"
00045 #include "libiberty.h"
00046 #include "safe-ctype.h"
00047 #include "sysdep.h"
00048 #include "getopt.h"
00049 #include "ia64-opc.h"
00050 #include "ia64-opc-a.c"
00051 #include "ia64-opc-i.c"
00052 #include "ia64-opc-m.c"
00053 #include "ia64-opc-b.c"
00054 #include "ia64-opc-f.c"
00055 #include "ia64-opc-x.c"
00056 #include "ia64-opc-d.c"
00057
00058 #include <libintl.h>
00059 #define _(String) gettext (String)
00060
00061 const char * program_name = NULL;
00062 int debug = 0;
00063
00064 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
00065 #define tmalloc(X) (X *) xmalloc (sizeof (X))
00066
00067
00068
00069
00070 struct main_entry
00071 {
00072
00073
00074 struct string_entry *name;
00075
00076
00077 struct ia64_opcode *opcode;
00078
00079 struct completer_entry *completers;
00080
00081 struct main_entry *next;
00082
00083 int main_index;
00084 } *maintable, **ordered_table;
00085
00086 int otlen = 0;
00087 int ottotlen = 0;
00088 int opcode_count = 0;
00089
00090
00091 struct completer_entry
00092 {
00093
00094 int num;
00095
00096
00097 struct string_entry *name;
00098
00099
00100 struct completer_entry *parent;
00101
00102
00103
00104 int is_terminal;
00105
00106
00107 struct completer_entry *alternative;
00108
00109
00110 struct completer_entry *addl_entries;
00111
00112
00113
00114
00115
00116 ia64_insn bits;
00117
00118
00119
00120
00121
00122 ia64_insn mask;
00123
00124
00125 int dependencies;
00126
00127
00128 int order;
00129 };
00130
00131
00132 struct disent
00133 {
00134
00135 int ournum;
00136
00137
00138 int insn;
00139
00140
00141 int priority;
00142
00143
00144 int completer_index;
00145
00146
00147 int nextcnt;
00148
00149
00150 struct disent *nexte;
00151
00152
00153 struct disent *next_ent;
00154 } *disinsntable = NULL;
00155
00156
00157
00158 struct bittree
00159 {
00160 struct disent *disent;
00161 struct bittree *bits[3];
00162 int bits_to_skip;
00163 int skip_flag;
00164 } *bittree;
00165
00166
00167
00168
00169
00170 struct string_entry
00171 {
00172
00173 int num;
00174
00175 char *s;
00176 } **string_table = NULL;
00177
00178 int strtablen = 0;
00179 int strtabtotlen = 0;
00180
00181
00182
00183 struct rdep
00184 {
00185 char *name;
00186 unsigned
00187 mode:2,
00188 semantics:3;
00189 char *extra;
00190 int nchks;
00191 int total_chks;
00192 int *chks;
00193
00194 int *chknotes;
00195 int nregs;
00196 int total_regs;
00197 int *regs;
00198
00199 int *regnotes;
00200
00201 int waw_special;
00202 } **rdeps = NULL;
00203
00204 static int rdepslen = 0;
00205 static int rdepstotlen = 0;
00206
00207
00208 struct iclass
00209 {
00210 char *name;
00211 int is_class;
00212 int nsubs;
00213 int *subs;
00214 int nxsubs;
00215 int xsubs[4];
00216 char *comment;
00217 int note;
00218 int terminal_resolved;
00219 int orphan;
00220 } **ics = NULL;
00221
00222 static int iclen = 0;
00223 static int ictotlen = 0;
00224
00225
00226 struct opdep
00227 {
00228 int chk;
00229 int reg;
00230 } **opdeps;
00231
00232 static int opdeplen = 0;
00233 static int opdeptotlen = 0;
00234
00235
00236 struct deplist
00237 {
00238 int len;
00239 unsigned short *deps;
00240 } **dlists;
00241
00242 static int dlistlen = 0;
00243 static int dlisttotlen = 0;
00244
00245
00246 static void fail (const char *, ...);
00247 static void warn (const char *, ...);
00248 static struct rdep * insert_resource (const char *, enum ia64_dependency_mode);
00249 static int deplist_equals (struct deplist *, struct deplist *);
00250 static short insert_deplist (int, unsigned short *);
00251 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
00252 static void mark_used (struct iclass *, int);
00253 static int fetch_insn_class (const char *, int);
00254 static int sub_compare (const void *, const void *);
00255 static void load_insn_classes (void);
00256 static void parse_resource_users (const char *, int **, int *, int **);
00257 static int parse_semantics (char *);
00258 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
00259 static void load_depfile (const char *, enum ia64_dependency_mode);
00260 static void load_dependencies (void);
00261 static int irf_operand (int, const char *);
00262 static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *);
00263 static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *);
00264 static int lookup_regindex (const char *, int);
00265 static int lookup_specifier (const char *);
00266 static void print_dependency_table (void);
00267 static struct string_entry * insert_string (char *);
00268 static void gen_dis_table (struct bittree *);
00269 static void print_dis_table (void);
00270 static void generate_disassembler (void);
00271 static void print_string_table (void);
00272 static int completer_entries_eq (struct completer_entry *, struct completer_entry *);
00273 static struct completer_entry * insert_gclist (struct completer_entry *);
00274 static int get_prefix_len (const char *);
00275 static void compute_completer_bits (struct main_entry *, struct completer_entry *);
00276 static void collapse_redundant_completers (void);
00277 static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *);
00278 static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int);
00279 static void print_completer_entry (struct completer_entry *);
00280 static void print_completer_table (void);
00281 static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *);
00282 static void add_opcode_entry (struct ia64_opcode *);
00283 static void print_main_table (void);
00284 static void shrink (struct ia64_opcode *);
00285 static void print_version (void);
00286 static void usage (FILE *, int);
00287 static void finish_distable (void);
00288 static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, int);
00289 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int);
00290 static void compact_distree (struct bittree *);
00291 static struct bittree * make_bittree_entry (void);
00292 static struct disent * add_dis_table_ent (struct disent *, int, int, int);
00293
00294
00295 static void
00296 fail (const char *message, ...)
00297 {
00298 va_list args;
00299
00300 va_start (args, message);
00301 fprintf (stderr, _("%s: Error: "), program_name);
00302 vfprintf (stderr, message, args);
00303 va_end (args);
00304 xexit (1);
00305 }
00306
00307 static void
00308 warn (const char *message, ...)
00309 {
00310 va_list args;
00311
00312 va_start (args, message);
00313
00314 fprintf (stderr, _("%s: Warning: "), program_name);
00315 vfprintf (stderr, message, args);
00316 va_end (args);
00317 }
00318
00319
00320 static struct rdep *
00321 insert_resource (const char *name, enum ia64_dependency_mode type)
00322 {
00323 if (rdepslen == rdepstotlen)
00324 {
00325 rdepstotlen += 20;
00326 rdeps = (struct rdep **)
00327 xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
00328 }
00329 rdeps[rdepslen] = tmalloc(struct rdep);
00330 memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep));
00331 rdeps[rdepslen]->name = xstrdup (name);
00332 rdeps[rdepslen]->mode = type;
00333 rdeps[rdepslen]->waw_special = 0;
00334
00335 return rdeps[rdepslen++];
00336 }
00337
00338
00339 static int
00340 deplist_equals (struct deplist *d1, struct deplist *d2)
00341 {
00342 int i;
00343
00344 if (d1->len != d2->len)
00345 return 0;
00346
00347 for (i = 0; i < d1->len; i++)
00348 if (d1->deps[i] != d2->deps[i])
00349 return 0;
00350
00351 return 1;
00352 }
00353
00354
00355 static short
00356 insert_deplist (int count, unsigned short *deps)
00357 {
00358
00359
00360 struct deplist *list;
00361 char set[0x10000];
00362 int i;
00363
00364 memset ((void *)set, 0, sizeof (set));
00365 for (i = 0; i < count; i++)
00366 set[deps[i]] = 1;
00367
00368 count = 0;
00369 for (i = 0; i < (int) sizeof (set); i++)
00370 if (set[i])
00371 ++count;
00372
00373 list = tmalloc (struct deplist);
00374 list->len = count;
00375 list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count);
00376
00377 for (i = 0, count = 0; i < (int) sizeof (set); i++)
00378 if (set[i])
00379 list->deps[count++] = i;
00380
00381
00382 for (i = 0; i < dlistlen; i++)
00383 if (deplist_equals (list, dlists[i]))
00384 {
00385 free (list->deps);
00386 free (list);
00387 return i;
00388 }
00389
00390 if (dlistlen == dlisttotlen)
00391 {
00392 dlisttotlen += 20;
00393 dlists = (struct deplist **)
00394 xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
00395 }
00396 dlists[dlistlen] = list;
00397
00398 return dlistlen++;
00399 }
00400
00401
00402 static short
00403 insert_dependencies (int nchks, unsigned short *chks,
00404 int nregs, unsigned short *regs)
00405 {
00406 struct opdep *pair;
00407 int i;
00408 int regind = -1;
00409 int chkind = -1;
00410
00411 if (nregs > 0)
00412 regind = insert_deplist (nregs, regs);
00413 if (nchks > 0)
00414 chkind = insert_deplist (nchks, chks);
00415
00416 for (i = 0; i < opdeplen; i++)
00417 if (opdeps[i]->chk == chkind
00418 && opdeps[i]->reg == regind)
00419 return i;
00420
00421 pair = tmalloc (struct opdep);
00422 pair->chk = chkind;
00423 pair->reg = regind;
00424
00425 if (opdeplen == opdeptotlen)
00426 {
00427 opdeptotlen += 20;
00428 opdeps = (struct opdep **)
00429 xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
00430 }
00431 opdeps[opdeplen] = pair;
00432
00433 return opdeplen++;
00434 }
00435
00436 static void
00437 mark_used (struct iclass *ic, int clear_terminals)
00438 {
00439 int i;
00440
00441 ic->orphan = 0;
00442 if (clear_terminals)
00443 ic->terminal_resolved = 1;
00444
00445 for (i = 0; i < ic->nsubs; i++)
00446 mark_used (ics[ic->subs[i]], clear_terminals);
00447
00448 for (i = 0; i < ic->nxsubs; i++)
00449 mark_used (ics[ic->xsubs[i]], clear_terminals);
00450 }
00451
00452
00453
00454 static int
00455 fetch_insn_class (const char *full_name, int create)
00456 {
00457 char *name;
00458 char *notestr;
00459 char *xsect;
00460 char *comment;
00461 int i, note = 0;
00462 int ind;
00463 int is_class = 0;
00464
00465 if (strncmp (full_name, "IC:", 3) == 0)
00466 {
00467 name = xstrdup (full_name + 3);
00468 is_class = 1;
00469 }
00470 else
00471 name = xstrdup (full_name);
00472
00473 if ((xsect = strchr(name, '\\')) != NULL)
00474 is_class = 1;
00475 if ((comment = strchr(name, '[')) != NULL)
00476 is_class = 1;
00477 if ((notestr = strchr(name, '+')) != NULL)
00478 is_class = 1;
00479
00480
00481
00482 if (xsect)
00483 {
00484 if (comment > xsect)
00485 comment = 0;
00486 if (notestr > xsect)
00487 notestr = 0;
00488 }
00489
00490 if (notestr)
00491 {
00492 char *nextnotestr;
00493
00494 note = atoi (notestr + 1);
00495 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
00496 {
00497 if (strcmp (notestr, "+1+13") == 0)
00498 note = 13;
00499 else if (!xsect || nextnotestr < xsect)
00500 warn (_("multiple note %s not handled\n"), notestr);
00501 }
00502 }
00503
00504
00505
00506
00507 if (!xsect)
00508 {
00509 if (notestr)
00510 *notestr = 0;
00511 if (comment)
00512 *comment = 0;
00513 }
00514
00515 for (i = 0; i < iclen; i++)
00516 if (strcmp (name, ics[i]->name) == 0
00517 && ((comment == NULL && ics[i]->comment == NULL)
00518 || (comment != NULL && ics[i]->comment != NULL
00519 && strncmp (ics[i]->comment, comment,
00520 strlen (ics[i]->comment)) == 0))
00521 && note == ics[i]->note)
00522 return i;
00523
00524 if (!create)
00525 return -1;
00526
00527
00528 if (iclen == ictotlen)
00529 {
00530 ictotlen += 20;
00531 ics = (struct iclass **)
00532 xrealloc (ics, (ictotlen) * sizeof (struct iclass *));
00533 }
00534
00535 ind = iclen++;
00536 ics[ind] = tmalloc (struct iclass);
00537 memset ((void *)ics[ind], 0, sizeof (struct iclass));
00538 ics[ind]->name = xstrdup (name);
00539 ics[ind]->is_class = is_class;
00540 ics[ind]->orphan = 1;
00541
00542 if (comment)
00543 {
00544 ics[ind]->comment = xstrdup (comment + 1);
00545 ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0;
00546 }
00547
00548 if (notestr)
00549 ics[ind]->note = note;
00550
00551
00552
00553 if ((xsect || comment || notestr) && is_class)
00554 {
00555
00556 char *subname = name;
00557
00558 if (xsect)
00559 *xsect = 0;
00560 else if (comment)
00561 *comment = 0;
00562 else if (notestr)
00563 *notestr = 0;
00564
00565 ics[ind]->nsubs = 1;
00566 ics[ind]->subs = tmalloc(int);
00567 ics[ind]->subs[0] = fetch_insn_class (subname, 1);;
00568 }
00569
00570 while (xsect)
00571 {
00572 char *subname = xsect + 1;
00573
00574 xsect = strchr (subname, '\\');
00575 if (xsect)
00576 *xsect = 0;
00577 ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
00578 ics[ind]->nxsubs++;
00579 }
00580 free (name);
00581
00582 return ind;
00583 }
00584
00585
00586
00587 static int
00588 sub_compare (const void *e1, const void *e2)
00589 {
00590 struct iclass *ic1 = ics[*(int *)e1];
00591 struct iclass *ic2 = ics[*(int *)e2];
00592
00593 if (ic1->is_class)
00594 {
00595 if (!ic2->is_class)
00596 return -1;
00597 }
00598 else if (ic2->is_class)
00599 return 1;
00600
00601 return strcmp (ic1->name, ic2->name);
00602 }
00603
00604 static void
00605 load_insn_classes (void)
00606 {
00607 FILE *fp = fopen ("ia64-ic.tbl", "r");
00608 char buf[2048];
00609
00610 if (fp == NULL)
00611 fail (_("can't find ia64-ic.tbl for reading\n"));
00612
00613
00614 fgets (buf, sizeof(buf), fp);
00615
00616 while (!feof (fp))
00617 {
00618 int iclass;
00619 char *name;
00620 char *tmp;
00621
00622 if (fgets (buf, sizeof (buf), fp) == NULL)
00623 break;
00624
00625 while (ISSPACE (buf[strlen (buf) - 1]))
00626 buf[strlen (buf) - 1] = '\0';
00627
00628 name = tmp = buf;
00629 while (*tmp != ';')
00630 {
00631 ++tmp;
00632 if (tmp == buf + sizeof (buf))
00633 abort ();
00634 }
00635 *tmp++ = '\0';
00636
00637 iclass = fetch_insn_class (name, 1);
00638 ics[iclass]->is_class = 1;
00639
00640 if (strcmp (name, "none") == 0)
00641 {
00642 ics[iclass]->is_class = 0;
00643 ics[iclass]->terminal_resolved = 1;
00644 continue;
00645 }
00646
00647
00648 while (*tmp)
00649 {
00650 char *subname;
00651 int sub;
00652
00653 while (*tmp && ISSPACE (*tmp))
00654 {
00655 ++tmp;
00656 if (tmp == buf + sizeof (buf))
00657 abort ();
00658 }
00659 subname = tmp;
00660 while (*tmp && *tmp != ',')
00661 {
00662 ++tmp;
00663 if (tmp == buf + sizeof (buf))
00664 abort ();
00665 }
00666 if (*tmp == ',')
00667 *tmp++ = '\0';
00668
00669 ics[iclass]->subs = (int *)
00670 xrealloc ((void *)ics[iclass]->subs,
00671 (ics[iclass]->nsubs + 1) * sizeof (int));
00672
00673 sub = fetch_insn_class (subname, 1);
00674 ics[iclass]->subs = (int *)
00675 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int));
00676 ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
00677 }
00678
00679
00680 qsort ((void *)ics[iclass]->subs,
00681 ics[iclass]->nsubs, sizeof(int), sub_compare);
00682 }
00683 fclose (fp);
00684
00685 if (debug)
00686 printf ("%d classes\n", iclen);
00687 }
00688
00689
00690 static void
00691 parse_resource_users (ref, usersp, nusersp, notesp)
00692 const char *ref;
00693 int **usersp;
00694 int *nusersp;
00695 int **notesp;
00696 {
00697 int c;
00698 char *line = xstrdup (ref);
00699 char *tmp = line;
00700 int *users = *usersp;
00701 int count = *nusersp;
00702 int *notes = *notesp;
00703
00704 c = *tmp;
00705 while (c != 0)
00706 {
00707 char *notestr;
00708 int note;
00709 char *xsect;
00710 int iclass;
00711 int create = 0;
00712 char *name;
00713
00714 while (ISSPACE (*tmp))
00715 ++tmp;
00716 name = tmp;
00717 while (*tmp && *tmp != ',')
00718 ++tmp;
00719 c = *tmp;
00720 *tmp++ = '\0';
00721
00722 xsect = strchr (name, '\\');
00723 if ((notestr = strstr (name, "+")) != NULL)
00724 {
00725 char *nextnotestr;
00726
00727 note = atoi (notestr + 1);
00728 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
00729 {
00730
00731 if (strcmp (notestr, "+1+13") == 0)
00732 note = 13;
00733 else if (!xsect || nextnotestr < xsect)
00734 warn (_("multiple note %s not handled\n"), notestr);
00735 }
00736 if (!xsect)
00737 *notestr = '\0';
00738 }
00739 else
00740 note = 0;
00741
00742
00743
00744
00745
00746
00747 if (strncmp (name, "IC:", 3) != 0 || xsect != NULL)
00748 create = 1;
00749
00750 iclass = fetch_insn_class (name, create);
00751 if (iclass != -1)
00752 {
00753 users = (int *)
00754 xrealloc ((void *) users,(count + 1) * sizeof (int));
00755 notes = (int *)
00756 xrealloc ((void *) notes,(count + 1) * sizeof (int));
00757 notes[count] = note;
00758 users[count++] = iclass;
00759 mark_used (ics[iclass], 0);
00760 }
00761 else if (debug)
00762 printf("Class %s not found\n", name);
00763 }
00764
00765 *usersp = users;
00766 *nusersp = count;
00767 *notesp = notes;
00768
00769 free (line);
00770 }
00771
00772 static int
00773 parse_semantics (char *sem)
00774 {
00775 if (strcmp (sem, "none") == 0)
00776 return IA64_DVS_NONE;
00777 else if (strcmp (sem, "implied") == 0)
00778 return IA64_DVS_IMPLIED;
00779 else if (strcmp (sem, "impliedF") == 0)
00780 return IA64_DVS_IMPLIEDF;
00781 else if (strcmp (sem, "data") == 0)
00782 return IA64_DVS_DATA;
00783 else if (strcmp (sem, "instr") == 0)
00784 return IA64_DVS_INSTR;
00785 else if (strcmp (sem, "specific") == 0)
00786 return IA64_DVS_SPECIFIC;
00787 else if (strcmp (sem, "stop") == 0)
00788 return IA64_DVS_STOP;
00789 else
00790 return IA64_DVS_OTHER;
00791 }
00792
00793 static void
00794 add_dep (const char *name, const char *chk, const char *reg,
00795 int semantics, int mode, char *extra, int flag)
00796 {
00797 struct rdep *rs;
00798
00799 rs = insert_resource (name, mode);
00800
00801 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
00802 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
00803
00804 rs->semantics = semantics;
00805 rs->extra = extra;
00806 rs->waw_special = flag;
00807 }
00808
00809 static void
00810 load_depfile (const char *filename, enum ia64_dependency_mode mode)
00811 {
00812 FILE *fp = fopen (filename, "r");
00813 char buf[1024];
00814
00815 if (fp == NULL)
00816 fail (_("can't find %s for reading\n"), filename);
00817
00818 fgets (buf, sizeof(buf), fp);
00819 while (!feof (fp))
00820 {
00821 char *name, *tmp;
00822 int semantics;
00823 char *extra;
00824 char *regp, *chkp;
00825
00826 if (fgets (buf, sizeof(buf), fp) == NULL)
00827 break;
00828
00829 while (ISSPACE (buf[strlen (buf) - 1]))
00830 buf[strlen (buf) - 1] = '\0';
00831
00832 name = tmp = buf;
00833 while (*tmp != ';')
00834 ++tmp;
00835 *tmp++ = '\0';
00836
00837 while (ISSPACE (*tmp))
00838 ++tmp;
00839 regp = tmp;
00840 tmp = strchr (tmp, ';');
00841 if (!tmp)
00842 abort ();
00843 *tmp++ = 0;
00844 while (ISSPACE (*tmp))
00845 ++tmp;
00846 chkp = tmp;
00847 tmp = strchr (tmp, ';');
00848 if (!tmp)
00849 abort ();
00850 *tmp++ = 0;
00851 while (ISSPACE (*tmp))
00852 ++tmp;
00853 semantics = parse_semantics (tmp);
00854 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
00855
00856
00857
00858
00859 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
00860 {
00861 add_dep (name, chkp, regp, semantics, mode, extra, 0);
00862 add_dep (name, regp, chkp, semantics, mode, extra, 1);
00863 }
00864 else
00865 {
00866 add_dep (name, chkp, regp, semantics, mode, extra, 0);
00867 }
00868 }
00869 fclose (fp);
00870 }
00871
00872 static void
00873 load_dependencies (void)
00874 {
00875 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
00876 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
00877 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
00878
00879 if (debug)
00880 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
00881 }
00882
00883
00884 static int
00885 irf_operand (int op, const char *field)
00886 {
00887 if (!field)
00888 {
00889 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
00890 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
00891 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
00892 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
00893 }
00894 else
00895 {
00896 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
00897 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
00898 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
00899 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
00900 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
00901 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
00902 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
00903 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
00904 }
00905 }
00906
00907
00908
00909 static int
00910 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
00911 const char *format, const char *field)
00912 {
00913 int plain_mov = strcmp (idesc->name, "mov") == 0;
00914
00915 if (!format)
00916 return 0;
00917
00918 switch (ic->name[4])
00919 {
00920 default:
00921 abort ();
00922 case 'a':
00923 {
00924 int i = strcmp (idesc->name, "mov.i") == 0;
00925 int m = strcmp (idesc->name, "mov.m") == 0;
00926 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
00927 int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
00928 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
00929 int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
00930 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
00931 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
00932
00933
00934 if (i2627)
00935 return strstr (format, "I26") || strstr (format, "I27");
00936 if (i28)
00937 return strstr (format, "I28") != NULL;
00938 if (m2930)
00939 return strstr (format, "M29") || strstr (format, "M30");
00940 if (m31)
00941 return strstr (format, "M31") != NULL;
00942 if (pseudo0 || pseudo1)
00943 return 1;
00944 }
00945 break;
00946 case 'b':
00947 {
00948 int i21 = idesc->operands[0] == IA64_OPND_B1;
00949 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
00950 if (i22)
00951 return strstr (format, "I22") != NULL;
00952 if (i21)
00953 return strstr (format, "I21") != NULL;
00954 }
00955 break;
00956 case 'c':
00957 {
00958 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
00959 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
00960 if (m32)
00961 return strstr (format, "M32") != NULL;
00962 if (m33)
00963 return strstr (format, "M33") != NULL;
00964 }
00965 break;
00966 case 'i':
00967 if (ic->name[5] == 'n')
00968 {
00969 int m42 = plain_mov && irf_operand (idesc->operands[0], field);
00970 int m43 = plain_mov && irf_operand (idesc->operands[1], field);
00971 if (m42)
00972 return strstr (format, "M42") != NULL;
00973 if (m43)
00974 return strstr (format, "M43") != NULL;
00975 }
00976 else if (ic->name[5] == 'p')
00977 {
00978 return idesc->operands[1] == IA64_OPND_IP;
00979 }
00980 else
00981 abort ();
00982 break;
00983 case 'p':
00984 if (ic->name[5] == 'r')
00985 {
00986 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
00987 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
00988 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
00989 if (i23)
00990 return strstr (format, "I23") != NULL;
00991 if (i24)
00992 return strstr (format, "I24") != NULL;
00993 if (i25)
00994 return strstr (format, "I25") != NULL;
00995 }
00996 else if (ic->name[5] == 's')
00997 {
00998 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
00999 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
01000 if (m35)
01001 return strstr (format, "M35") != NULL;
01002 if (m36)
01003 return strstr (format, "M36") != NULL;
01004 }
01005 else
01006 abort ();
01007 break;
01008 case 'u':
01009 {
01010 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
01011 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
01012 if (m35)
01013 return strstr (format, "M35") != NULL;
01014 if (m36)
01015 return strstr (format, "M36") != NULL;
01016 }
01017 break;
01018 }
01019 return 0;
01020 }
01021
01022
01023 static int
01024 in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
01025 const char *format, const char *field, int *notep)
01026 {
01027 int i;
01028 int resolved = 0;
01029
01030 if (ic->comment)
01031 {
01032 if (!strncmp (ic->comment, "Format", 6))
01033 {
01034
01035
01036 if (format)
01037 {
01038 if (strlen (ic->comment) < strlen (format))
01039 {
01040 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
01041 ic->comment, format);
01042 format = ic->comment;
01043 }
01044 }
01045 else
01046 format = ic->comment;
01047 }
01048 else if (!strncmp (ic->comment, "Field", 5))
01049 {
01050 if (field)
01051 warn (_("overlapping field %s->%s\n"),
01052 ic->comment, field);
01053 field = ic->comment;
01054 }
01055 }
01056
01057
01058
01059
01060 if (ic->nsubs == 0 && ic->nxsubs == 0)
01061 {
01062 int is_mov = strncmp (idesc->name, "mov", 3) == 0;
01063 int plain_mov = strcmp (idesc->name, "mov") == 0;
01064 int len = strlen(ic->name);
01065
01066 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
01067 && (idesc->name[len] == '\0'
01068 || idesc->name[len] == '.'));
01069
01070
01071 if (resolved &&
01072 (strcmp (ic->name, "break") == 0
01073 || strcmp (ic->name, "nop") == 0
01074 || strcmp (ic->name, "hint") == 0))
01075 resolved = strcmp (ic->name, idesc->name) == 0;
01076
01077
01078
01079 if (resolved && field)
01080 {
01081
01082 if (strstr(field, "(sf)==") != NULL)
01083 {
01084 char *sf;
01085
01086 if ((sf = strstr (idesc->name, ".s")) != 0)
01087 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
01088 }
01089
01090 else if (strstr (field, "(lftype)") != NULL)
01091 {
01092 if (strstr (idesc->name, "fault") != NULL)
01093 resolved = strstr (field, "fault") != NULL;
01094 else
01095 resolved = strstr (field, "fault") == NULL;
01096 }
01097
01098 else if (strstr (field, "(ctype)") != NULL)
01099 {
01100 if (strstr (idesc->name, "or.andcm"))
01101 resolved = strstr (field, "or.andcm") != NULL;
01102 else if (strstr (idesc->name, "and.orcm"))
01103 resolved = strstr (field, "and.orcm") != NULL;
01104 else if (strstr (idesc->name, "orcm"))
01105 resolved = strstr (field, "or orcm") != NULL;
01106 else if (strstr (idesc->name, "or"))
01107 resolved = strstr (field, "or orcm") != NULL;
01108 else if (strstr (idesc->name, "andcm"))
01109 resolved = strstr (field, "and andcm") != NULL;
01110 else if (strstr (idesc->name, "and"))
01111 resolved = strstr (field, "and andcm") != NULL;
01112 else if (strstr (idesc->name, "unc"))
01113 resolved = strstr (field, "unc") != NULL;
01114 else
01115 resolved = strcmp (field, "Field(ctype)==") == 0;
01116 }
01117 }
01118
01119 if (resolved && format)
01120 {
01121 if (strncmp (idesc->name, "dep", 3) == 0
01122 && strstr (format, "I13") != NULL)
01123 resolved = idesc->operands[1] == IA64_OPND_IMM8;
01124 else if (strncmp (idesc->name, "chk", 3) == 0
01125 && strstr (format, "M21") != NULL)
01126 resolved = idesc->operands[0] == IA64_OPND_F2;
01127 else if (strncmp (idesc->name, "lfetch", 6) == 0)
01128 resolved = (strstr (format, "M14 M15") != NULL
01129 && (idesc->operands[1] == IA64_OPND_R2
01130 || idesc->operands[1] == IA64_OPND_IMM9b));
01131 else if (strncmp (idesc->name, "br.call", 7) == 0
01132 && strstr (format, "B5") != NULL)
01133 resolved = idesc->operands[1] == IA64_OPND_B2;
01134 else if (strncmp (idesc->name, "br.call", 7) == 0
01135 && strstr (format, "B3") != NULL)
01136 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
01137 else if (strncmp (idesc->name, "brp", 3) == 0
01138 && strstr (format, "B7") != NULL)
01139 resolved = idesc->operands[0] == IA64_OPND_B2;
01140 else if (strcmp (ic->name, "invala") == 0)
01141 resolved = strcmp (idesc->name, ic->name) == 0;
01142 else if (strncmp (idesc->name, "st", 2) == 0
01143 && (strstr (format, "M5") != NULL
01144 || strstr (format, "M10") != NULL))
01145 resolved = idesc->flags & IA64_OPCODE_POSTINC;
01146 else if (strncmp (idesc->name, "ld", 2) == 0
01147 && (strstr (format, "M2 M3") != NULL
01148 || strstr (format, "M12") != NULL
01149 || strstr (format, "M7 M8") != NULL))
01150 resolved = idesc->flags & IA64_OPCODE_POSTINC;
01151 else
01152 resolved = 0;
01153 }
01154
01155
01156
01157 if (!resolved
01158 && (strcmp (idesc->name, "brl") == 0
01159 || strncmp (idesc->name, "brl.", 4) == 0)
01160 && strcmp (ic->name, "brl.cond") == 0)
01161 {
01162 resolved = 1;
01163 }
01164
01165
01166 if (!resolved
01167 && (strcmp (idesc->name, "br") == 0
01168 || strncmp (idesc->name, "br.", 3) == 0)
01169 && strcmp (ic->name, "br.cond") == 0)
01170 {
01171 if (format)
01172 resolved = (strstr (format, "B4") != NULL
01173 && idesc->operands[0] == IA64_OPND_B2)
01174 || (strstr (format, "B1") != NULL
01175 && idesc->operands[0] == IA64_OPND_TGT25c);
01176 else
01177 resolved = 1;
01178 }
01179
01180
01181 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
01182 {
01183 resolved = strcmp (ic->name, "probe") == 0
01184 && !((strstr (idesc->name, "fault") != NULL)
01185 ^ (format && strstr (format, "M40") != NULL));
01186 }
01187
01188
01189 if (!resolved && is_mov)
01190 {
01191 if (plain_mov)
01192 {
01193
01194 if (strcmp (ic->name, "fmerge") == 0)
01195 {
01196 resolved = idesc->operands[0] == IA64_OPND_F1
01197 && idesc->operands[1] == IA64_OPND_F3;
01198 }
01199
01200 else if (strcmp (ic->name, "adds") == 0)
01201 {
01202 resolved = (idesc->operands[0] == IA64_OPND_R1
01203 && (idesc->operands[1] == IA64_OPND_R3
01204 || (idesc->operands[1] == IA64_OPND_IMM14)));
01205 }
01206
01207 else if (strcmp (ic->name, "addl") == 0)
01208 {
01209 resolved = idesc->operands[0] == IA64_OPND_R1
01210 && idesc->operands[1] == IA64_OPND_IMM22;
01211 }
01212 }
01213
01214
01215 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
01216 resolved = in_iclass_mov_x (idesc, ic, format, field);
01217 }
01218
01219
01220
01221 if (resolved)
01222 ic->terminal_resolved = 1;
01223 }
01224 else for (i = 0; i < ic->nsubs; i++)
01225 {
01226 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
01227 {
01228 int j;
01229
01230 for (j = 0; j < ic->nxsubs; j++)
01231 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
01232 return 0;
01233
01234 if (debug > 1)
01235 printf ("%s is in IC %s\n", idesc->name, ic->name);
01236
01237 resolved = 1;
01238 break;
01239 }
01240 }
01241
01242
01243 if (resolved)
01244 {
01245 if (ic->note && notep)
01246 {
01247 if (*notep && *notep != ic->note)
01248 warn (_("overwriting note %d with note %d (IC:%s)\n"),
01249 *notep, ic->note, ic->name);
01250
01251 *notep = ic->note;
01252 }
01253 }
01254
01255 return resolved;
01256 }
01257
01258
01259 static int
01260 lookup_regindex (const char *name, int specifier)
01261 {
01262 switch (specifier)
01263 {
01264 case IA64_RS_ARX:
01265 if (strstr (name, "[RSC]"))
01266 return 16;
01267 if (strstr (name, "[BSP]"))
01268 return 17;
01269 else if (strstr (name, "[BSPSTORE]"))
01270 return 18;
01271 else if (strstr (name, "[RNAT]"))
01272 return 19;
01273 else if (strstr (name, "[FCR]"))
01274 return 21;
01275 else if (strstr (name, "[EFLAG]"))
01276 return 24;
01277 else if (strstr (name, "[CSD]"))
01278 return 25;
01279 else if (strstr (name, "[SSD]"))
01280 return 26;
01281 else if (strstr (name, "[CFLG]"))
01282 return 27;
01283 else if (strstr (name, "[FSR]"))
01284 return 28;
01285 else if (strstr (name, "[FIR]"))
01286 return 29;
01287 else if (strstr (name, "[FDR]"))
01288 return 30;
01289 else if (strstr (name, "[CCV]"))
01290 return 32;
01291 else if (strstr (name, "[ITC]"))
01292 return 44;
01293 else if (strstr (name, "[PFS]"))
01294 return 64;
01295 else if (strstr (name, "[LC]"))
01296 return 65;
01297 else if (strstr (name, "[EC]"))
01298 return 66;
01299 abort ();
01300 case IA64_RS_CRX:
01301 if (strstr (name, "[DCR]"))
01302 return 0;
01303 else if (strstr (name, "[ITM]"))
01304 return 1;
01305 else if (strstr (name, "[IVA]"))
01306 return 2;
01307 else if (strstr (name, "[PTA]"))
01308 return 8;
01309 else if (strstr (name, "[GPTA]"))
01310 return 9;
01311 else if (strstr (name, "[IPSR]"))
01312 return 16;
01313 else if (strstr (name, "[ISR]"))
01314 return 17;
01315 else if (strstr (name, "[IIP]"))
01316 return 19;
01317 else if (strstr (name, "[IFA]"))
01318 return 20;
01319 else if (strstr (name, "[ITIR]"))
01320 return 21;
01321 else if (strstr (name, "[IIPA]"))
01322 return 22;
01323 else if (strstr (name, "[IFS]"))
01324 return 23;
01325 else if (strstr (name, "[IIM]"))
01326 return 24;
01327 else if (strstr (name, "[IHA]"))
01328 return 25;
01329 else if (strstr (name, "[LID]"))
01330 return 64;
01331 else if (strstr (name, "[IVR]"))
01332 return 65;
01333 else if (strstr (name, "[TPR]"))
01334 return 66;
01335 else if (strstr (name, "[EOI]"))
01336 return 67;
01337 else if (strstr (name, "[ITV]"))
01338 return 72;
01339 else if (strstr (name, "[PMV]"))
01340 return 73;
01341 else if (strstr (name, "[CMCV]"))
01342 return 74;
01343 abort ();
01344 case IA64_RS_PSR:
01345 if (strstr (name, ".be"))
01346 return 1;
01347 else if (strstr (name, ".up"))
01348 return 2;
01349 else if (strstr (name, ".ac"))
01350 return 3;
01351 else if (strstr (name, ".mfl"))
01352 return 4;
01353 else if (strstr (name, ".mfh"))
01354 return 5;
01355 else if (strstr (name, ".ic"))
01356 return 13;
01357 else if (strstr (name, ".i"))
01358 return 14;
01359 else if (strstr (name, ".pk"))
01360 return 15;
01361 else if (strstr (name, ".dt"))
01362 return 17;
01363 else if (strstr (name, ".dfl"))
01364 return 18;
01365 else if (strstr (name, ".dfh"))
01366 return 19;
01367 else if (strstr (name, ".sp"))
01368 return 20;
01369 else if (strstr (name, ".pp"))
01370 return 21;
01371 else if (strstr (name, ".di"))
01372 return 22;
01373 else if (strstr (name, ".si"))
01374 return 23;
01375 else if (strstr (name, ".db"))
01376 return 24;
01377 else if (strstr (name, ".lp"))
01378 return 25;
01379 else if (strstr (name, ".tb"))
01380 return 26;
01381 else if (strstr (name, ".rt"))
01382 return 27;
01383 else if (strstr (name, ".cpl"))
01384 return 32;
01385 else if (strstr (name, ".rs"))
01386 return 34;
01387 else if (strstr (name, ".mc"))
01388 return 35;
01389 else if (strstr (name, ".it"))
01390 return 36;
01391 else if (strstr (name, ".id"))
01392 return 37;
01393 else if (strstr (name, ".da"))
01394 return 38;
01395 else if (strstr (name, ".dd"))
01396 return 39;
01397 else if (strstr (name, ".ss"))
01398 return 40;
01399 else if (strstr (name, ".ri"))
01400 return 41;
01401 else if (strstr (name, ".ed"))
01402 return 43;
01403 else if (strstr (name, ".bn"))
01404 return 44;
01405 else if (strstr (name, ".ia"))
01406 return 45;
01407 else
01408 abort ();
01409 default:
01410 break;
01411 }
01412 return REG_NONE;
01413 }
01414
01415 static int
01416 lookup_specifier (const char *name)
01417 {
01418 if (strchr (name, '%'))
01419 {
01420 if (strstr (name, "AR[K%]") != NULL)
01421 return IA64_RS_AR_K;
01422 if (strstr (name, "AR[UNAT]") != NULL)
01423 return IA64_RS_AR_UNAT;
01424 if (strstr (name, "AR%, % in 8") != NULL)
01425 return IA64_RS_AR;
01426 if (strstr (name, "AR%, % in 48") != NULL)
01427 return IA64_RS_ARb;
01428 if (strstr (name, "BR%") != NULL)
01429 return IA64_RS_BR;
01430 if (strstr (name, "CR[IRR%]") != NULL)
01431 return IA64_RS_CR_IRR;
01432 if (strstr (name, "CR[LRR%]") != NULL)
01433 return IA64_RS_CR_LRR;
01434 if (strstr (name, "CR%") != NULL)
01435 return IA64_RS_CR;
01436 if (strstr (name, "FR%, % in 0") != NULL)
01437 return IA64_RS_FR;
01438 if (strstr (name, "FR%, % in 2") != NULL)
01439 return IA64_RS_FRb;
01440 if (strstr (name, "GR%") != NULL)
01441 return IA64_RS_GR;
01442 if (strstr (name, "PR%, % in 1 ") != NULL)
01443 return IA64_RS_PR;
01444 if (strstr (name, "PR%, % in 16 ") != NULL)
01445 return IA64_RS_PRr;
01446
01447 warn (_("don't know how to specify %% dependency %s\n"),
01448 name);
01449 }
01450 else if (strchr (name, '#'))
01451 {
01452 if (strstr (name, "CPUID#") != NULL)
01453 return IA64_RS_CPUID;
01454 if (strstr (name, "DBR#") != NULL)
01455 return IA64_RS_DBR;
01456 if (strstr (name, "IBR#") != NULL)
01457 return IA64_RS_IBR;
01458 if (strstr (name, "MSR#") != NULL)
01459 return IA64_RS_MSR;
01460 if (strstr (name, "PKR#") != NULL)
01461 return IA64_RS_PKR;
01462 if (strstr (name, "PMC#") != NULL)
01463 return IA64_RS_PMC;
01464 if (strstr (name, "PMD#") != NULL)
01465 return IA64_RS_PMD;
01466 if (strstr (name, "RR#") != NULL)
01467 return IA64_RS_RR;
01468
01469 warn (_("Don't know how to specify # dependency %s\n"),
01470 name);
01471 }
01472 else if (strncmp (name, "AR[FPSR]", 8) == 0)
01473 return IA64_RS_AR_FPSR;
01474 else if (strncmp (name, "AR[", 3) == 0)
01475 return IA64_RS_ARX;
01476 else if (strncmp (name, "CR[", 3) == 0)
01477 return IA64_RS_CRX;
01478 else if (strncmp (name, "PSR.", 4) == 0)
01479 return IA64_RS_PSR;
01480 else if (strcmp (name, "InService*") == 0)
01481 return IA64_RS_INSERVICE;
01482 else if (strcmp (name, "GR0") == 0)
01483 return IA64_RS_GR0;
01484 else if (strcmp (name, "CFM") == 0)
01485 return IA64_RS_CFM;
01486 else if (strcmp (name, "PR63") == 0)
01487 return IA64_RS_PR63;
01488 else if (strcmp (name, "RSE") == 0)
01489 return IA64_RS_RSE;
01490
01491 return IA64_RS_ANY;
01492 }
01493
01494 static void
01495 print_dependency_table ()
01496 {
01497 int i, j;
01498
01499 if (debug)
01500 {
01501 for (i=0;i < iclen;i++)
01502 {
01503 if (ics[i]->is_class)
01504 {
01505 if (!ics[i]->nsubs)
01506 {
01507 if (ics[i]->comment)
01508 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
01509 ics[i]->name, ics[i]->comment);
01510 else
01511 warn (_("IC:%s has no terminals or sub-classes\n"),
01512 ics[i]->name);
01513 }
01514 }
01515 else
01516 {
01517 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
01518 {
01519 if (ics[i]->comment)
01520 warn (_("no insns mapped directly to terminal IC %s [%s]"),
01521 ics[i]->name, ics[i]->comment);
01522 else
01523 warn (_("no insns mapped directly to terminal IC %s\n"),
01524 ics[i]->name);
01525 }
01526 }
01527 }
01528
01529 for (i = 0; i < iclen; i++)
01530 {
01531 if (ics[i]->orphan)
01532 {
01533 mark_used (ics[i], 1);
01534 warn (_("class %s is defined but not used\n"),
01535 ics[i]->name);
01536 }
01537 }
01538
01539 if (debug > 1)
01540 for (i = 0; i < rdepslen; i++)
01541 {
01542 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
01543
01544 if (rdeps[i]->total_chks == 0)
01545 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
01546 rdeps[i]->name, mode_str[rdeps[i]->mode],
01547 rdeps[i]->total_regs ? "" : " or regs");
01548 else if (rdeps[i]->total_regs == 0)
01549 warn (_("rsrc %s (%s) has no regs\n"),
01550 rdeps[i]->name, mode_str[rdeps[i]->mode]);
01551 }
01552 }
01553
01554
01555 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
01556 for (i = 0; i < rdepslen; i++)
01557 {
01558
01559
01560 int specifier = lookup_specifier (rdeps[i]->name);
01561 int regindex = lookup_regindex (rdeps[i]->name, specifier);
01562
01563 printf (" { \"%s\", %d, %d, %d, %d, ",
01564 rdeps[i]->name, specifier,
01565 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
01566 if (rdeps[i]->semantics == IA64_DVS_OTHER)
01567 printf ("\"%s\", ", rdeps[i]->extra);
01568 else
01569 printf ("NULL, ");
01570 printf("},\n");
01571 }
01572 printf ("};\n\n");
01573
01574
01575 for (i=0;i < dlistlen;i++)
01576 {
01577 int len = 2;
01578 printf ("static const unsigned short dep%d[] = {\n ", i);
01579 for (j=0;j < dlists[i]->len; j++)
01580 {
01581 len += printf ("%d, ", dlists[i]->deps[j]);
01582 if (len > 75)
01583 {
01584 printf("\n ");
01585 len = 2;
01586 }
01587 }
01588 printf ("\n};\n\n");
01589 }
01590
01591
01592 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
01593 printf ("static const struct ia64_opcode_dependency\n");
01594 printf ("op_dependencies[] = {\n");
01595 for (i = 0; i < opdeplen; i++)
01596 {
01597 printf (" { ");
01598 if (opdeps[i]->chk == -1)
01599 printf ("0, NULL, ");
01600 else
01601 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
01602 if (opdeps[i]->reg == -1)
01603 printf ("0, NULL, ");
01604 else
01605 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
01606 printf ("},\n");
01607 }
01608 printf ("};\n\n");
01609 }
01610
01611
01612
01613 static struct string_entry *
01614 insert_string (char *str)
01615 {
01616 int start = 0, end = strtablen;
01617 int i, x;
01618
01619 if (strtablen == strtabtotlen)
01620 {
01621 strtabtotlen += 20;
01622 string_table = (struct string_entry **)
01623 xrealloc (string_table,
01624 sizeof (struct string_entry **) * strtabtotlen);
01625 }
01626
01627 if (strtablen == 0)
01628 {
01629 strtablen = 1;
01630 string_table[0] = tmalloc (struct string_entry);
01631 string_table[0]->s = xstrdup (str);
01632 string_table[0]->num = 0;
01633 return string_table[0];
01634 }
01635
01636 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
01637 i = end;
01638 else if (strcmp (str, string_table[0]->s) < 0)
01639 i = 0;
01640 else
01641 {
01642 while (1)
01643 {
01644 int c;
01645
01646 i = (start + end) / 2;
01647 c = strcmp (str, string_table[i]->s);
01648
01649 if (c < 0)
01650 end = i - 1;
01651 else if (c == 0)
01652 return string_table[i];
01653 else
01654 start = i + 1;
01655
01656 if (start > end)
01657 break;
01658 }
01659 }
01660
01661 for (; i > 0 && i < strtablen; i--)
01662 if (strcmp (str, string_table[i - 1]->s) > 0)
01663 break;
01664
01665 for (; i < strtablen; i++)
01666 if (strcmp (str, string_table[i]->s) < 0)
01667 break;
01668
01669 for (x = strtablen - 1; x >= i; x--)
01670 {
01671 string_table[x + 1] = string_table[x];
01672 string_table[x + 1]->num = x + 1;
01673 }
01674
01675 string_table[i] = tmalloc (struct string_entry);
01676 string_table[i]->s = xstrdup (str);
01677 string_table[i]->num = i;
01678 strtablen++;
01679
01680 return string_table[i];
01681 }
01682
01683 static struct bittree *
01684 make_bittree_entry (void)
01685 {
01686 struct bittree *res = tmalloc (struct bittree);
01687
01688 res->disent = NULL;
01689 res->bits[0] = NULL;
01690 res->bits[1] = NULL;
01691 res->bits[2] = NULL;
01692 res->skip_flag = 0;
01693 res->bits_to_skip = 0;
01694 return res;
01695 }
01696
01697
01698 static struct disent *
01699 add_dis_table_ent (which, insn, order, completer_index)
01700 struct disent *which;
01701 int insn;
01702 int order;
01703 int completer_index;
01704 {
01705 int ci = 0;
01706 struct disent *ent;
01707
01708 if (which != NULL)
01709 {
01710 ent = which;
01711
01712 ent->nextcnt++;
01713 while (ent->nexte != NULL)
01714 ent = ent->nexte;
01715
01716 ent = (ent->nexte = tmalloc (struct disent));
01717 }
01718 else
01719 {
01720 ent = tmalloc (struct disent);
01721 ent->next_ent = disinsntable;
01722 disinsntable = ent;
01723 which = ent;
01724 }
01725 ent->nextcnt = 0;
01726 ent->nexte = NULL;
01727 ent->insn = insn;
01728 ent->priority = order;
01729
01730 while (completer_index != 1)
01731 {
01732 ci = (ci << 1) | (completer_index & 1);
01733 completer_index >>= 1;
01734 }
01735 ent->completer_index = ci;
01736 return which;
01737 }
01738
01739 static void
01740 finish_distable ()
01741 {
01742 struct disent *ent = disinsntable;
01743 struct disent *prev = ent;
01744
01745 ent->ournum = 32768;
01746 while ((ent = ent->next_ent) != NULL)
01747 {
01748 ent->ournum = prev->ournum + prev->nextcnt + 1;
01749 prev = ent;
01750 }
01751 }
01752
01753 static void
01754 insert_bit_table_ent (curr_ent, bit, opcode, mask,
01755 opcodenum, order, completer_index)
01756 struct bittree *curr_ent;
01757 int bit;
01758 ia64_insn opcode;
01759 ia64_insn mask;
01760 int opcodenum;
01761 int order;
01762 int completer_index;
01763 {
01764 ia64_insn m;
01765 int b;
01766 struct bittree *next;
01767
01768 if (bit == -1)
01769 {
01770 struct disent *nent = add_dis_table_ent (curr_ent->disent,
01771 opcodenum, order,
01772 completer_index);
01773 curr_ent->disent = nent;
01774 return;
01775 }
01776
01777 m = ((ia64_insn) 1) << bit;
01778
01779 if (mask & m)
01780 b = (opcode & m) ? 1 : 0;
01781 else
01782 b = 2;
01783
01784 next = curr_ent->bits[b];
01785 if (next == NULL)
01786 {
01787 next = make_bittree_entry ();
01788 curr_ent->bits[b] = next;
01789 }
01790 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
01791 completer_index);
01792 }
01793
01794 static void
01795 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
01796 struct bittree *first;
01797 ia64_insn opcode;
01798 ia64_insn mask;
01799 int opcodenum;
01800 struct completer_entry *ent;
01801 int completer_index;
01802 {
01803 if (completer_index & (1 << 20))
01804 abort ();
01805
01806 while (ent != NULL)
01807 {
01808 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
01809 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
01810 (completer_index << 1) | 1);
01811
01812 if (ent->is_terminal)
01813 {
01814 insert_bit_table_ent (bittree, 40, newopcode, mask,
01815 opcodenum, opcode_count - ent->order - 1,
01816 (completer_index << 1) | 1);
01817 }
01818 completer_index <<= 1;
01819 ent = ent->alternative;
01820 }
01821 }
01822
01823
01824 static void
01825 compact_distree (ent)
01826 struct bittree *ent;
01827 {
01828 #define IS_SKIP(ent) \
01829 ((ent->bits[2] !=NULL) \
01830 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
01831
01832 int bitcnt = 0;
01833 struct bittree *nent = ent;
01834 int x;
01835
01836 while (IS_SKIP (nent))
01837 {
01838 bitcnt++;
01839 nent = nent->bits[2];
01840 }
01841
01842 if (bitcnt)
01843 {
01844 struct bittree *next = ent->bits[2];
01845
01846 ent->bits[0] = nent->bits[0];
01847 ent->bits[1] = nent->bits[1];
01848 ent->bits[2] = nent->bits[2];
01849 ent->disent = nent->disent;
01850 ent->skip_flag = 1;
01851 ent->bits_to_skip = bitcnt;
01852 while (next != nent)
01853 {
01854 struct bittree *b = next;
01855 next = next->bits[2];
01856 free (b);
01857 }
01858 free (nent);
01859 }
01860
01861 for (x = 0; x < 3; x++)
01862 {
01863 struct bittree *i = ent->bits[x];
01864
01865 if (i != NULL)
01866 compact_distree (i);
01867 }
01868 }
01869
01870 static unsigned char *insn_list;
01871 static int insn_list_len = 0;
01872 static int tot_insn_list_len = 0;
01873
01874
01875
01876 static void
01877 gen_dis_table (ent)
01878 struct bittree *ent;
01879 {
01880 int x;
01881 int our_offset = insn_list_len;
01882 int bitsused = 5;
01883 int totbits = bitsused;
01884 int needed_bytes;
01885 int zero_count = 0;
01886 int zero_dest = 0;
01887
01888
01889
01890 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
01891 ent->bits[2] == NULL)
01892 {
01893 if (ent->disent == NULL)
01894 abort ();
01895 else
01896 ent->skip_flag = 0;
01897 }
01898
01899
01900
01901 if (ent->skip_flag)
01902 totbits += 5;
01903
01904 for (x = 1; x < 3; x++)
01905 if (ent->bits[x] != NULL)
01906 totbits += 16;
01907
01908 if (ent->disent != NULL)
01909 {
01910 if (ent->bits[2] != NULL)
01911 abort ();
01912
01913 totbits += 16;
01914 }
01915
01916
01917 needed_bytes = (totbits + 7) / 8;
01918 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
01919 {
01920 tot_insn_list_len += 256;
01921 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
01922 }
01923 our_offset = insn_list_len;
01924 insn_list_len += needed_bytes;
01925 memset (insn_list + our_offset, 0, needed_bytes);
01926
01927
01928
01929 if (ent->skip_flag)
01930 {
01931 bitsused += 5;
01932 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
01933 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
01934 }
01935
01936 #define IS_ONLY_IFZERO(ENT) \
01937 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
01938 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
01939
01940
01941
01942 if (ent->bits[0] != NULL)
01943 {
01944 struct bittree *nent = ent->bits[0];
01945 zero_count = 0;
01946
01947 insn_list[our_offset] |= 0x80;
01948
01949
01950
01951
01952
01953
01954 if (IS_ONLY_IFZERO (ent))
01955 {
01956 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
01957 {
01958 nent = nent->bits[0];
01959 zero_count++;
01960 }
01961
01962 insn_list[our_offset + 0] |= zero_count;
01963 }
01964 zero_dest = insn_list_len;
01965 gen_dis_table (nent);
01966 }
01967
01968
01969
01970
01971 for (x = 1; x < 3; x++)
01972 {
01973 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
01974 {
01975 struct bittree *i = ent->bits[x];
01976 int idest;
01977 int currbits = 15;
01978
01979 if (i != NULL)
01980 {
01981
01982
01983
01984 if (i->bits[0] == NULL && i->bits[1] == NULL
01985 && i->bits[2] == NULL && i->disent != NULL)
01986 {
01987 idest = i->disent->ournum;
01988 i = NULL;
01989 }
01990 else
01991 idest = insn_list_len - our_offset;
01992 }
01993 else
01994 idest = ent->disent->ournum;
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005 if (x == 1)
02006 {
02007 if (idest <= 256)
02008 {
02009 int start = our_offset + bitsused / 8 + 1;
02010
02011 memmove (insn_list + start,
02012 insn_list + start + 1,
02013 insn_list_len - (start + 1));
02014 currbits = 7;
02015 totbits -= 8;
02016 needed_bytes--;
02017 insn_list_len--;
02018 insn_list[our_offset] |= 0x10;
02019 idest--;
02020 }
02021 else
02022 insn_list[our_offset] |= 0x20;
02023 }
02024 else
02025 {
02026
02027
02028
02029
02030
02031
02032 if (ent->bits[0] == NULL && ent->bits[1] == NULL
02033 && ent->bits[2] == NULL && ent->skip_flag == 0
02034 && ent->disent != NULL
02035 && ent->disent->ournum < (32768 + 4096))
02036 {
02037 int start = our_offset + bitsused / 8 + 1;
02038
02039 memmove (insn_list + start,
02040 insn_list + start + 1,
02041 insn_list_len - (start + 1));
02042 currbits = 11;
02043 totbits -= 5;
02044 bitsused--;
02045 needed_bytes--;
02046 insn_list_len--;
02047 insn_list[our_offset] |= 0x30;
02048 idest &= ~32768;
02049 }
02050 else
02051 insn_list[our_offset] |= 0x08;
02052 }
02053
02054 if (debug)
02055 {
02056 int id = idest;
02057
02058 if (i == NULL)
02059 id |= 32768;
02060 else if (! (id & 32768))
02061 id += our_offset;
02062
02063 if (x == 1)
02064 printf ("%d: if (1) goto %d\n", our_offset, id);
02065 else
02066 printf ("%d: try %d\n", our_offset, id);
02067 }
02068
02069
02070 while (currbits >= 0)
02071 {
02072 unsigned char *byte = insn_list + our_offset + bitsused / 8;
02073
02074 if (idest & (1 << currbits))
02075 *byte |= (1 << (7 - (bitsused % 8)));
02076
02077 bitsused++;
02078 currbits--;
02079 }
02080
02081
02082 if (i != NULL)
02083 gen_dis_table (i);
02084 }
02085 }
02086
02087 if (debug)
02088 {
02089 if (ent->skip_flag)
02090 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
02091
02092 if (ent->bits[0] != NULL)
02093 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
02094 zero_dest);
02095 }
02096
02097 if (bitsused != totbits)
02098 abort ();
02099 }
02100
02101 static void
02102 print_dis_table (void)
02103 {
02104 int x;
02105 struct disent *cent = disinsntable;
02106
02107 printf ("static const char dis_table[] = {\n");
02108 for (x = 0; x < insn_list_len; x++)
02109 {
02110 if ((x > 0) && ((x % 12) == 0))
02111 printf ("\n");
02112
02113 printf ("0x%02x, ", insn_list[x]);
02114 }
02115 printf ("\n};\n\n");
02116
02117 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
02118 while (cent != NULL)
02119 {
02120 struct disent *ent = cent;
02121
02122 while (ent != NULL)
02123 {
02124 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
02125 ent->insn, (ent->nexte != NULL ? 1 : 0),
02126 ent->priority);
02127 ent = ent->nexte;
02128 }
02129 cent = cent->next_ent;
02130 }
02131 printf ("};\n\n");
02132 }
02133
02134 static void
02135 generate_disassembler (void)
02136 {
02137 int i;
02138
02139 bittree = make_bittree_entry ();
02140
02141 for (i = 0; i < otlen; i++)
02142 {
02143 struct main_entry *ptr = ordered_table[i];
02144
02145 if (ptr->opcode->type != IA64_TYPE_DYN)
02146 add_dis_entry (bittree,
02147 ptr->opcode->opcode, ptr->opcode->mask,
02148 ptr->main_index,
02149 ptr->completers, 1);
02150 }
02151
02152 compact_distree (bittree);
02153 finish_distable ();
02154 gen_dis_table (bittree);
02155
02156 print_dis_table ();
02157 }
02158
02159 static void
02160 print_string_table (void)
02161 {
02162 int x;
02163 char lbuf[80], buf[80];
02164 int blen = 0;
02165
02166 printf ("static const char * const ia64_strings[] = {\n");
02167 lbuf[0] = '\0';
02168
02169 for (x = 0; x < strtablen; x++)
02170 {
02171 int len;
02172
02173 if (strlen (string_table[x]->s) > 75)
02174 abort ();
02175
02176 sprintf (buf, " \"%s\",", string_table[x]->s);
02177 len = strlen (buf);
02178
02179 if ((blen + len) > 75)
02180 {
02181 printf (" %s\n", lbuf);
02182 lbuf[0] = '\0';
02183 blen = 0;
02184 }
02185 strcat (lbuf, buf);
02186 blen += len;
02187 }
02188
02189 if (blen > 0)
02190 printf (" %s\n", lbuf);
02191
02192 printf ("};\n\n");
02193 }
02194
02195 static struct completer_entry **glist;
02196 static int glistlen = 0;
02197 static int glisttotlen = 0;
02198
02199
02200
02201 static int
02202 completer_entries_eq (ent1, ent2)
02203 struct completer_entry *ent1, *ent2;
02204 {
02205 while (ent1 != NULL && ent2 != NULL)
02206 {
02207 if (ent1->name->num != ent2->name->num
02208 || ent1->bits != ent2->bits
02209 || ent1->mask != ent2->mask
02210 || ent1->is_terminal != ent2->is_terminal
02211 || ent1->dependencies != ent2->dependencies
02212 || ent1->order != ent2->order)
02213 return 0;
02214
02215 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
02216 return 0;
02217
02218 ent1 = ent1->alternative;
02219 ent2 = ent2->alternative;
02220 }
02221
02222 return ent1 == ent2;
02223 }
02224
02225
02226
02227
02228 static struct completer_entry *
02229 insert_gclist (struct completer_entry *ent)
02230 {
02231 if (ent != NULL)
02232 {
02233 int i;
02234 int x;
02235 int start = 0, end;
02236
02237 ent->addl_entries = insert_gclist (ent->addl_entries);
02238 ent->alternative = insert_gclist (ent->alternative);
02239
02240 i = glistlen / 2;
02241 end = glistlen;
02242
02243 if (glisttotlen == glistlen)
02244 {
02245 glisttotlen += 20;
02246 glist = (struct completer_entry **)
02247 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
02248 }
02249
02250 if (glistlen == 0)
02251 {
02252 glist[0] = ent;
02253 glistlen = 1;
02254 return ent;
02255 }
02256
02257 if (ent->name->num < glist[0]->name->num)
02258 i = 0;
02259 else if (ent->name->num > glist[end - 1]->name->num)
02260 i = end;
02261 else
02262 {
02263 int c;
02264
02265 while (1)
02266 {
02267 i = (start + end) / 2;
02268 c = ent->name->num - glist[i]->name->num;
02269
02270 if (c < 0)
02271 end = i - 1;
02272 else if (c == 0)
02273 {
02274 while (i > 0
02275 && ent->name->num == glist[i - 1]->name->num)
02276 i--;
02277
02278 break;
02279 }
02280 else
02281 start = i + 1;
02282
02283 if (start > end)
02284 break;
02285 }
02286
02287 if (c == 0)
02288 {
02289 while (i < glistlen)
02290 {
02291 if (ent->name->num != glist[i]->name->num)
02292 break;
02293
02294 if (completer_entries_eq (ent, glist[i]))
02295 return glist[i];
02296
02297 i++;
02298 }
02299 }
02300 }
02301
02302 for (; i > 0 && i < glistlen; i--)
02303 if (ent->name->num >= glist[i - 1]->name->num)
02304 break;
02305
02306 for (; i < glistlen; i++)
02307 if (ent->name->num < glist[i]->name->num)
02308 break;
02309
02310 for (x = glistlen - 1; x >= i; x--)
02311 glist[x + 1] = glist[x];
02312
02313 glist[i] = ent;
02314 glistlen++;
02315 }
02316 return ent;
02317 }
02318
02319 static int
02320 get_prefix_len (name)
02321 const char *name;
02322 {
02323 char *c;
02324
02325 if (name[0] == '\0')
02326 return 0;
02327
02328 c = strchr (name, '.');
02329 if (c != NULL)
02330 return c - name;
02331 else
02332 return strlen (name);
02333 }
02334
02335 static void
02336 compute_completer_bits (ment, ent)
02337 struct main_entry *ment;
02338 struct completer_entry *ent;
02339 {
02340 while (ent != NULL)
02341 {
02342 compute_completer_bits (ment, ent->addl_entries);
02343
02344 if (ent->is_terminal)
02345 {
02346 ia64_insn mask = 0;
02347 ia64_insn our_bits = ent->bits;
02348 struct completer_entry *p = ent->parent;
02349 ia64_insn p_bits;
02350 int x;
02351
02352 while (p != NULL && ! p->is_terminal)
02353 p = p->parent;
02354
02355 if (p != NULL)
02356 p_bits = p->bits;
02357 else
02358 p_bits = ment->opcode->opcode;
02359
02360 for (x = 0; x < 64; x++)
02361 {
02362 ia64_insn m = ((ia64_insn) 1) << x;
02363
02364 if ((p_bits & m) != (our_bits & m))
02365 mask |= m;
02366 else
02367 our_bits &= ~m;
02368 }
02369 ent->bits = our_bits;
02370 ent->mask = mask;
02371 }
02372 else
02373 {
02374 ent->bits = 0;
02375 ent->mask = 0;
02376 }
02377
02378 ent = ent->alternative;
02379 }
02380 }
02381
02382
02383
02384 static void
02385 collapse_redundant_completers (void)
02386 {
02387 struct main_entry *ptr;
02388 int x;
02389
02390 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
02391 {
02392 if (ptr->completers == NULL)
02393 abort ();
02394
02395 compute_completer_bits (ptr, ptr->completers);
02396 ptr->completers = insert_gclist (ptr->completers);
02397 }
02398
02399
02400 for (x = 0; x < glistlen; x++)
02401 glist[x]->num = x;
02402 }
02403
02404
02405
02406
02407
02408
02409
02410 static int
02411 insert_opcode_dependencies (opc, cmp)
02412 struct ia64_opcode *opc;
02413 struct completer_entry *cmp ATTRIBUTE_UNUSED;
02414 {
02415
02416
02417 int i;
02418 int nregs = 0;
02419 unsigned short regs[256];
02420 int nchks = 0;
02421 unsigned short chks[256];
02422
02423 int no_class_found = 1;
02424
02425 for (i = 0; i < rdepslen; i++)
02426 {
02427 struct rdep *rs = rdeps[i];
02428 int j;
02429
02430 if (strcmp (opc->name, "cmp.eq.and") == 0
02431 && strncmp (rs->name, "PR%", 3) == 0
02432 && rs->mode == 1)
02433 no_class_found = 99;
02434
02435 for (j=0; j < rs->nregs;j++)
02436 {
02437 int ic_note = 0;
02438
02439 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
02440 {
02441
02442 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
02443 ic_note = 0;
02444
02445 if (ic_note != 0 && rs->regnotes[j] != 0
02446 && ic_note != rs->regnotes[j]
02447 && !(ic_note == 11 && rs->regnotes[j] == 1))
02448 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
02449 ic_note, opc->name, ics[rs->regs[j]]->name,
02450 rs->name, rs->regnotes[j]);
02451
02452
02453
02454 if (ic_note)
02455 regs[nregs++] = RDEP(ic_note, i);
02456 else
02457 regs[nregs++] = RDEP(rs->regnotes[j], i);
02458 no_class_found = 0;
02459 ++rs->total_regs;
02460 }
02461 }
02462
02463 for (j = 0; j < rs->nchks; j++)
02464 {
02465 int ic_note = 0;
02466
02467 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
02468 {
02469
02470 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
02471 ic_note = 0;
02472
02473 if (ic_note != 0 && rs->chknotes[j] != 0
02474 && ic_note != rs->chknotes[j]
02475 && !(ic_note == 11 && rs->chknotes[j] == 1))
02476 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
02477 ic_note, opc->name, ics[rs->chks[j]]->name,
02478 rs->name, rs->chknotes[j]);
02479 if (ic_note)
02480 chks[nchks++] = RDEP(ic_note, i);
02481 else
02482 chks[nchks++] = RDEP(rs->chknotes[j], i);
02483 no_class_found = 0;
02484 ++rs->total_chks;
02485 }
02486 }
02487 }
02488
02489 if (no_class_found)
02490 warn (_("opcode %s has no class (ops %d %d %d)\n"),
02491 opc->name,
02492 opc->operands[0], opc->operands[1], opc->operands[2]);
02493
02494 return insert_dependencies (nchks, chks, nregs, regs);
02495 }
02496
02497 static void
02498 insert_completer_entry (opc, tabent, order)
02499 struct ia64_opcode *opc;
02500 struct main_entry *tabent;
02501 int order;
02502 {
02503 struct completer_entry **ptr = &tabent->completers;
02504 struct completer_entry *parent = NULL;
02505 char pcopy[129], *prefix;
02506 int at_end = 0;
02507
02508 if (strlen (opc->name) > 128)
02509 abort ();
02510
02511 strcpy (pcopy, opc->name);
02512 prefix = pcopy + get_prefix_len (pcopy);
02513
02514 if (prefix[0] != '\0')
02515 prefix++;
02516
02517 while (! at_end)
02518 {
02519 int need_new_ent = 1;
02520 int plen = get_prefix_len (prefix);
02521 struct string_entry *sent;
02522
02523 at_end = (prefix[plen] == '\0');
02524 prefix[plen] = '\0';
02525 sent = insert_string (prefix);
02526
02527 while (*ptr != NULL)
02528 {
02529 int cmpres = sent->num - (*ptr)->name->num;
02530
02531 if (cmpres == 0)
02532 {
02533 need_new_ent = 0;
02534 break;
02535 }
02536 else
02537 ptr = &((*ptr)->alternative);
02538 }
02539
02540 if (need_new_ent)
02541 {
02542 struct completer_entry *nent = tmalloc (struct completer_entry);
02543
02544 nent->name = sent;
02545 nent->parent = parent;
02546 nent->addl_entries = NULL;
02547 nent->alternative = *ptr;
02548 *ptr = nent;
02549 nent->is_terminal = 0;
02550 nent->dependencies = -1;
02551 }
02552
02553 if (! at_end)
02554 {
02555 parent = *ptr;
02556 ptr = &((*ptr)->addl_entries);
02557 prefix += plen + 1;
02558 }
02559 }
02560
02561 if ((*ptr)->is_terminal)
02562 abort ();
02563
02564 (*ptr)->is_terminal = 1;
02565 (*ptr)->mask = (ia64_insn)-1;
02566 (*ptr)->bits = opc->opcode;
02567 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
02568 (*ptr)->order = order;
02569 }
02570
02571 static void
02572 print_completer_entry (ent)
02573 struct completer_entry *ent;
02574 {
02575 int moffset = 0;
02576 ia64_insn mask = ent->mask, bits = ent->bits;
02577
02578 if (mask != 0)
02579 {
02580 while (! (mask & 1))
02581 {
02582 moffset++;
02583 mask = mask >> 1;
02584 bits = bits >> 1;
02585 }
02586
02587 if (bits & 0xffffffff00000000LL)
02588 abort ();
02589 }
02590
02591 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
02592 (int)bits,
02593 (int)mask,
02594 ent->name->num,
02595 ent->alternative != NULL ? ent->alternative->num : -1,
02596 ent->addl_entries != NULL ? ent->addl_entries->num : -1,
02597 moffset,
02598 ent->is_terminal ? 1 : 0,
02599 ent->dependencies);
02600 }
02601
02602 static void
02603 print_completer_table ()
02604 {
02605 int x;
02606
02607 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
02608 for (x = 0; x < glistlen; x++)
02609 print_completer_entry (glist[x]);
02610 printf ("};\n\n");
02611 }
02612
02613 static int
02614 opcodes_eq (opc1, opc2)
02615 struct ia64_opcode *opc1;
02616 struct ia64_opcode *opc2;
02617 {
02618 int x;
02619 int plen1, plen2;
02620
02621 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
02622 || (opc1->num_outputs != opc2->num_outputs)
02623 || (opc1->flags != opc2->flags))
02624 return 0;
02625
02626 for (x = 0; x < 5; x++)
02627 if (opc1->operands[x] != opc2->operands[x])
02628 return 0;
02629
02630 plen1 = get_prefix_len (opc1->name);
02631 plen2 = get_prefix_len (opc2->name);
02632
02633 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
02634 return 1;
02635
02636 return 0;
02637 }
02638
02639 static void
02640 add_opcode_entry (opc)
02641 struct ia64_opcode *opc;
02642 {
02643 struct main_entry **place;
02644 struct string_entry *name;
02645 char prefix[129];
02646 int found_it = 0;
02647
02648 if (strlen (opc->name) > 128)
02649 abort ();
02650
02651 place = &maintable;
02652 strcpy (prefix, opc->name);
02653 prefix[get_prefix_len (prefix)] = '\0';
02654 name = insert_string (prefix);
02655
02656
02657
02658
02659
02660 while (*place != NULL)
02661 {
02662 if ((*place)->name->num == name->num
02663 && opcodes_eq ((*place)->opcode, opc))
02664 {
02665 found_it = 1;
02666 break;
02667 }
02668 if ((*place)->name->num > name->num)
02669 break;
02670
02671 place = &((*place)->next);
02672 }
02673 if (! found_it)
02674 {
02675 struct main_entry *nent = tmalloc (struct main_entry);
02676
02677 nent->name = name;
02678 nent->opcode = opc;
02679 nent->next = *place;
02680 nent->completers = 0;
02681 *place = nent;
02682
02683 if (otlen == ottotlen)
02684 {
02685 ottotlen += 20;
02686 ordered_table = (struct main_entry **)
02687 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
02688 }
02689 ordered_table[otlen++] = nent;
02690 }
02691
02692 insert_completer_entry (opc, *place, opcode_count++);
02693 }
02694
02695 static void
02696 print_main_table (void)
02697 {
02698 struct main_entry *ptr = maintable;
02699 int index = 0;
02700
02701 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
02702 while (ptr != NULL)
02703 {
02704 printf (" { %d, %d, %d, 0x",
02705 ptr->name->num,
02706 ptr->opcode->type,
02707 ptr->opcode->num_outputs);
02708 fprintf_vma (stdout, ptr->opcode->opcode);
02709 printf ("ull, 0x");
02710 fprintf_vma (stdout, ptr->opcode->mask);
02711 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
02712 ptr->opcode->operands[0],
02713 ptr->opcode->operands[1],
02714 ptr->opcode->operands[2],
02715 ptr->opcode->operands[3],
02716 ptr->opcode->operands[4],
02717 ptr->opcode->flags,
02718 ptr->completers->num);
02719
02720 ptr->main_index = index++;
02721
02722 ptr = ptr->next;
02723 }
02724 printf ("};\n\n");
02725 }
02726
02727 static void
02728 shrink (table)
02729 struct ia64_opcode *table;
02730 {
02731 int curr_opcode;
02732
02733 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
02734 {
02735 add_opcode_entry (table + curr_opcode);
02736 if (table[curr_opcode].num_outputs == 2
02737 && ((table[curr_opcode].operands[0] == IA64_OPND_P1
02738 && table[curr_opcode].operands[1] == IA64_OPND_P2)
02739 || (table[curr_opcode].operands[0] == IA64_OPND_P2
02740 && table[curr_opcode].operands[1] == IA64_OPND_P1)))
02741 {
02742 struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
02743 unsigned i;
02744
02745 *alias = table[curr_opcode];
02746 for (i = 2; i < NELEMS (alias->operands); ++i)
02747 alias->operands[i - 1] = alias->operands[i];
02748 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
02749 --alias->num_outputs;
02750 alias->flags |= PSEUDO;
02751 add_opcode_entry (alias);
02752 }
02753 }
02754 }
02755
02756
02757
02758 #define OPTION_SRCDIR 200
02759
02760 struct option long_options[] =
02761 {
02762 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
02763 {"debug", no_argument, NULL, 'd'},
02764 {"version", no_argument, NULL, 'V'},
02765 {"help", no_argument, NULL, 'h'},
02766 {0, no_argument, NULL, 0}
02767 };
02768
02769 static void
02770 print_version (void)
02771 {
02772 printf ("%s: version 1.0\n", program_name);
02773 xexit (0);
02774 }
02775
02776 static void
02777 usage (FILE * stream, int status)
02778 {
02779 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
02780 program_name);
02781 xexit (status);
02782 }
02783
02784 int
02785 main (int argc, char **argv)
02786 {
02787 extern int chdir (char *);
02788 char *srcdir = NULL;
02789 int c;
02790
02791 program_name = *argv;
02792 xmalloc_set_program_name (program_name);
02793
02794 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
02795 switch (c)
02796 {
02797 case OPTION_SRCDIR:
02798 srcdir = optarg;
02799 break;
02800 case 'V':
02801 case 'v':
02802 print_version ();
02803 break;
02804 case 'd':
02805 debug = 1;
02806 break;
02807 case 'h':
02808 case '?':
02809 usage (stderr, 0);
02810 default:
02811 case 0:
02812 break;
02813 }
02814
02815 if (optind != argc)
02816 usage (stdout, 1);
02817
02818 if (srcdir != NULL)
02819 if (chdir (srcdir) != 0)
02820 fail (_("unable to change directory to \"%s\", errno = %s\n"),
02821 srcdir, strerror (errno));
02822
02823 load_insn_classes ();
02824 load_dependencies ();
02825
02826 shrink (ia64_opcodes_a);
02827 shrink (ia64_opcodes_b);
02828 shrink (ia64_opcodes_f);
02829 shrink (ia64_opcodes_i);
02830 shrink (ia64_opcodes_m);
02831 shrink (ia64_opcodes_x);
02832 shrink (ia64_opcodes_d);
02833
02834 collapse_redundant_completers ();
02835
02836 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
02837 print_string_table ();
02838 print_dependency_table ();
02839 print_completer_table ();
02840 print_main_table ();
02841
02842 generate_disassembler ();
02843
02844 exit (0);
02845 }