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