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