1/* ia64-gen.c -- Generate a shrunk set of opcode tables
2   Copyright (C) 1999-2017 Free Software Foundation, Inc.
3   Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
4
5   This file is part of the GNU opcodes library.
6
7   This library is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3, or (at your option)
10   any later version.
11
12   It is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15   License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this file; see the file COPYING.  If not, write to the
19   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20   02110-1301, USA.  */
21
22
23/* While the ia64-opc-* set of opcode tables are easy to maintain,
24   they waste a tremendous amount of space.  ia64-gen rearranges the
25   instructions into a directed acyclic graph (DAG) of instruction opcodes and
26   their possible completers, as well as compacting the set of strings used.
27
28   The disassembler table consists of a state machine that does
29   branching based on the bits of the opcode being disassembled.  The
30   state encodings have been chosen to minimize the amount of space
31   required.
32
33   The resource table is constructed based on some text dependency tables,
34   which are also easier to maintain than the final representation.  */
35
36#include "sysdep.h"
37#include <stdio.h>
38#include <stdarg.h>
39#include <errno.h>
40
41#include "libiberty.h"
42#include "safe-ctype.h"
43#include "getopt.h"
44#include "ia64-opc.h"
45#include "ia64-opc-a.c"
46#include "ia64-opc-i.c"
47#include "ia64-opc-m.c"
48#include "ia64-opc-b.c"
49#include "ia64-opc-f.c"
50#include "ia64-opc-x.c"
51#include "ia64-opc-d.c"
52
53#include <libintl.h>
54#define _(String) gettext (String)
55
56/* This is a copy of fprintf_vma from bfd/bfd-in2.h.  We have to use this
57   always, because we might be compiled without BFD64 defined, if configured
58   for a 32-bit target and --enable-targets=all is used.  This will work for
59   both 32-bit and 64-bit hosts.  */
60#define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
61#define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
62#define opcode_fprintf_vma(s,x) \
63  fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
64
65const char * program_name = NULL;
66int debug = 0;
67
68#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
69#define tmalloc(X) (X *) xmalloc (sizeof (X))
70
71typedef unsigned long long  ci_t;
72/* The main opcode table entry.  Each entry is a unique combination of
73   name and flags (no two entries in the table compare as being equal
74   via opcodes_eq).  */
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  ci_t completer_index;
150
151  /* How many other entries share this decode.  */
152  int nextcnt;
153
154  /* The next entry sharing the same decode.  */
155  struct disent *nexte;
156
157  /* The next entry in the name list.  */
158  struct disent *next_ent;
159} *disinsntable = NULL;
160
161/* A state machine that will eventually be used to generate the
162   disassembler table.  */
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, ci_t);
294static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, ci_t);
295static void compact_distree (struct bittree *);
296static struct bittree * make_bittree_entry (void);
297static struct disent * add_dis_table_ent (struct disent *, int, int, ci_t);
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 (const char *ref, int **usersp, int *nusersp,
697                      int **notesp)
698{
699  int c;
700  char *line = xstrdup (ref);
701  char *tmp = line;
702  int *users = *usersp;
703  int count = *nusersp;
704  int *notes = *notesp;
705
706  c = *tmp;
707  while (c != 0)
708    {
709      char *notestr;
710      int note;
711      char *xsect;
712      int iclass;
713      int create = 0;
714      char *name;
715
716      while (ISSPACE (*tmp))
717        ++tmp;
718      name = tmp;
719      while (*tmp && *tmp != ',')
720        ++tmp;
721      c = *tmp;
722      *tmp++ = '\0';
723
724      xsect = strchr (name, '\\');
725      if ((notestr = strstr (name, "+")) != NULL)
726        {
727          char *nextnotestr;
728
729          note = atoi (notestr + 1);
730          if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
731            {
732              /* Note 13 always implies note 1.  */
733              if (strcmp (notestr, "+1+13") == 0)
734                note = 13;
735              else if (!xsect || nextnotestr < xsect)
736                warn (_("multiple note %s not handled\n"), notestr);
737            }
738          if (!xsect)
739            *notestr = '\0';
740        }
741      else
742        note = 0;
743
744      /* All classes are created when the insn class table is parsed;
745         Individual instructions might not appear until the dependency tables
746         are read.  Only create new classes if it's *not* an insn class,
747         or if it's a composite class (which wouldn't necessarily be in the IC
748         table).  */
749      if (! CONST_STRNEQ (name, "IC:") || xsect != NULL)
750        create = 1;
751
752      iclass = fetch_insn_class (name, create);
753      if (iclass != -1)
754        {
755          users = (int *)
756            xrealloc ((void *) users,(count + 1) * sizeof (int));
757          notes = (int *)
758            xrealloc ((void *) notes,(count + 1) * sizeof (int));
759          notes[count] = note;
760          users[count++] = iclass;
761          mark_used (ics[iclass], 0);
762        }
763      else if (debug)
764	printf("Class %s not found\n", name);
765    }
766  /* Update the return values.  */
767  *usersp = users;
768  *nusersp = count;
769  *notesp = notes;
770
771  free (line);
772}
773
774static int
775parse_semantics (char *sem)
776{
777  if (strcmp (sem, "none") == 0)
778    return IA64_DVS_NONE;
779  else if (strcmp (sem, "implied") == 0)
780    return IA64_DVS_IMPLIED;
781  else if (strcmp (sem, "impliedF") == 0)
782    return IA64_DVS_IMPLIEDF;
783  else if (strcmp (sem, "data") == 0)
784    return IA64_DVS_DATA;
785  else if (strcmp (sem, "instr") == 0)
786    return IA64_DVS_INSTR;
787  else if (strcmp (sem, "specific") == 0)
788    return IA64_DVS_SPECIFIC;
789  else if (strcmp (sem, "stop") == 0)
790    return IA64_DVS_STOP;
791  else
792    return IA64_DVS_OTHER;
793}
794
795static void
796add_dep (const char *name, const char *chk, const char *reg,
797         int semantics, int mode, char *extra, int flag)
798{
799  struct rdep *rs;
800
801  rs = insert_resource (name, mode);
802
803  parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
804  parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
805
806  rs->semantics = semantics;
807  rs->extra = extra;
808  rs->waw_special = flag;
809}
810
811static void
812load_depfile (const char *filename, enum ia64_dependency_mode mode)
813{
814  FILE *fp = fopen (filename, "r");
815  char buf[1024];
816
817  if (fp == NULL)
818    fail (_("can't find %s for reading\n"), filename);
819
820  fgets (buf, sizeof(buf), fp);
821  while (!feof (fp))
822    {
823      char *name, *tmp;
824      int semantics;
825      char *extra;
826      char *regp, *chkp;
827
828      if (fgets (buf, sizeof(buf), fp) == NULL)
829        break;
830
831      while (ISSPACE (buf[strlen (buf) - 1]))
832        buf[strlen (buf) - 1] = '\0';
833
834      name = tmp = buf;
835      while (*tmp != ';')
836        ++tmp;
837      *tmp++ = '\0';
838
839      while (ISSPACE (*tmp))
840        ++tmp;
841      regp = tmp;
842      tmp = strchr (tmp, ';');
843      if (!tmp)
844        abort ();
845      *tmp++ = 0;
846      while (ISSPACE (*tmp))
847        ++tmp;
848      chkp = tmp;
849      tmp = strchr (tmp, ';');
850      if (!tmp)
851        abort ();
852      *tmp++ = 0;
853      while (ISSPACE (*tmp))
854        ++tmp;
855      semantics = parse_semantics (tmp);
856      extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
857
858      /* For WAW entries, if the chks and regs differ, we need to enter the
859         entries in both positions so that the tables will be parsed properly,
860         without a lot of extra work.  */
861      if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
862        {
863          add_dep (name, chkp, regp, semantics, mode, extra, 0);
864          add_dep (name, regp, chkp, semantics, mode, extra, 1);
865        }
866      else
867        {
868          add_dep (name, chkp, regp, semantics, mode, extra, 0);
869        }
870    }
871  fclose (fp);
872}
873
874static void
875load_dependencies (void)
876{
877  load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
878  load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
879  load_depfile ("ia64-war.tbl", IA64_DV_WAR);
880
881  if (debug)
882    printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
883}
884
885/* Is the given operand an indirect register file operand?  */
886static int
887irf_operand (int op, const char *field)
888{
889  if (!field)
890    {
891      return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
892        || op == IA64_OPND_IBR_R3  || op == IA64_OPND_PKR_R3
893	|| op == IA64_OPND_PMC_R3  || op == IA64_OPND_PMD_R3
894	|| op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
895    }
896  else
897    {
898      return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
899              || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
900              || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
901              || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
902              || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
903              || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
904              || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
905              || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid"))
906              || (op == IA64_OPND_DAHR_R3  && strstr (field, "dahr")));
907    }
908}
909
910/* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
911 * mov_psr, and  mov_um insn classes.  */
912static int
913in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
914                 const char *format, const char *field)
915{
916  int plain_mov = strcmp (idesc->name, "mov") == 0;
917
918  if (!format)
919    return 0;
920
921  switch (ic->name[4])
922    {
923    default:
924      abort ();
925    case 'a':
926      {
927        int i = strcmp (idesc->name, "mov.i") == 0;
928        int m = strcmp (idesc->name, "mov.m") == 0;
929        int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
930        int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
931        int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
932        int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
933        int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
934        int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
935
936        /* IC:mov ar */
937        if (i2627)
938          return strstr (format, "I26") || strstr (format, "I27");
939        if (i28)
940          return strstr (format, "I28") != NULL;
941        if (m2930)
942          return strstr (format, "M29") || strstr (format, "M30");
943        if (m31)
944          return strstr (format, "M31") != NULL;
945        if (pseudo0 || pseudo1)
946          return 1;
947      }
948      break;
949    case 'b':
950      {
951        int i21 = idesc->operands[0] == IA64_OPND_B1;
952        int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
953        if (i22)
954          return strstr (format, "I22") != NULL;
955        if (i21)
956          return strstr (format, "I21") != NULL;
957      }
958      break;
959    case 'c':
960      {
961        int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
962        int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
963        if (m32)
964          return strstr (format, "M32") != NULL;
965        if (m33)
966          return strstr (format, "M33") != NULL;
967      }
968      break;
969    case 'd':
970      {
971        int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3;
972        if (m50)
973          return strstr (format, "M50") != NULL;
974      }
975      break;
976    case 'i':
977      if (ic->name[5] == 'n')
978        {
979          int m42 = plain_mov && irf_operand (idesc->operands[0], field);
980          int m43 = plain_mov && irf_operand (idesc->operands[1], field);
981          if (m42)
982            return strstr (format, "M42") != NULL;
983          if (m43)
984            return strstr (format, "M43") != NULL;
985        }
986      else if (ic->name[5] == 'p')
987        {
988          return idesc->operands[1] == IA64_OPND_IP;
989        }
990      else
991        abort ();
992      break;
993    case 'p':
994      if (ic->name[5] == 'r')
995        {
996          int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
997          int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
998          int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
999          if (i23)
1000            return strstr (format, "I23") != NULL;
1001          if (i24)
1002            return strstr (format, "I24") != NULL;
1003          if (i25)
1004            return strstr (format, "I25") != NULL;
1005        }
1006      else if (ic->name[5] == 's')
1007        {
1008          int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
1009          int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
1010          if (m35)
1011            return strstr (format, "M35") != NULL;
1012          if (m36)
1013            return strstr (format, "M36") != NULL;
1014        }
1015      else
1016        abort ();
1017      break;
1018    case 'u':
1019      {
1020        int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
1021        int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
1022        if (m35)
1023          return strstr (format, "M35") != NULL;
1024        if (m36)
1025          return strstr (format, "M36") != NULL;
1026      }
1027      break;
1028    }
1029  return 0;
1030}
1031
1032/* Is the given opcode in the given insn class?  */
1033static int
1034in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1035	   const char *format, const char *field, int *notep)
1036{
1037  int i;
1038  int resolved = 0;
1039
1040  if (ic->comment)
1041    {
1042      if (CONST_STRNEQ (ic->comment, "Format"))
1043        {
1044          /* Assume that the first format seen is the most restrictive, and
1045             only keep a later one if it looks like it's more restrictive.  */
1046          if (format)
1047            {
1048              if (strlen (ic->comment) < strlen (format))
1049                {
1050                  warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1051			ic->comment, format);
1052                  format = ic->comment;
1053                }
1054            }
1055          else
1056            format = ic->comment;
1057        }
1058      else if (CONST_STRNEQ (ic->comment, "Field"))
1059        {
1060          if (field)
1061            warn (_("overlapping field %s->%s\n"),
1062		  ic->comment, field);
1063          field = ic->comment;
1064        }
1065    }
1066
1067  /* An insn class matches anything that is the same followed by completers,
1068     except when the absence and presence of completers constitutes different
1069     instructions.  */
1070  if (ic->nsubs == 0 && ic->nxsubs == 0)
1071    {
1072      int is_mov = CONST_STRNEQ (idesc->name, "mov");
1073      int plain_mov = strcmp (idesc->name, "mov") == 0;
1074      int len = strlen(ic->name);
1075
1076      resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1077                  && (idesc->name[len] == '\0'
1078                      || idesc->name[len] == '.'));
1079
1080      /* All break, nop, and hint variations must match exactly.  */
1081      if (resolved &&
1082          (strcmp (ic->name, "break") == 0
1083           || strcmp (ic->name, "nop") == 0
1084	   || strcmp (ic->name, "hint") == 0))
1085        resolved = strcmp (ic->name, idesc->name) == 0;
1086
1087      /* Assume restrictions in the FORMAT/FIELD negate resolution,
1088         unless specifically allowed by clauses in this block.  */
1089      if (resolved && field)
1090        {
1091          /* Check Field(sf)==sN against opcode sN.  */
1092          if (strstr(field, "(sf)==") != NULL)
1093            {
1094              char *sf;
1095
1096              if ((sf = strstr (idesc->name, ".s")) != 0)
1097		resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1098            }
1099          /* Check Field(lftype)==XXX.  */
1100          else if (strstr (field, "(lftype)") != NULL)
1101            {
1102              if (strstr (idesc->name, "fault") != NULL)
1103                resolved = strstr (field, "fault") != NULL;
1104              else
1105                resolved = strstr (field, "fault") == NULL;
1106            }
1107          /* Handle Field(ctype)==XXX.  */
1108          else if (strstr (field, "(ctype)") != NULL)
1109            {
1110              if (strstr (idesc->name, "or.andcm"))
1111                resolved = strstr (field, "or.andcm") != NULL;
1112              else if (strstr (idesc->name, "and.orcm"))
1113                resolved = strstr (field, "and.orcm") != NULL;
1114              else if (strstr (idesc->name, "orcm"))
1115                resolved = strstr (field, "or orcm") != NULL;
1116              else if (strstr (idesc->name, "or"))
1117                resolved = strstr (field, "or orcm") != NULL;
1118              else if (strstr (idesc->name, "andcm"))
1119                resolved = strstr (field, "and andcm") != NULL;
1120              else if (strstr (idesc->name, "and"))
1121                resolved = strstr (field, "and andcm") != NULL;
1122              else if (strstr (idesc->name, "unc"))
1123                resolved = strstr (field, "unc") != NULL;
1124              else
1125                resolved = strcmp (field, "Field(ctype)==") == 0;
1126            }
1127        }
1128
1129      if (resolved && format)
1130        {
1131          if (CONST_STRNEQ (idesc->name, "dep")
1132                   && strstr (format, "I13") != NULL)
1133            resolved = idesc->operands[1] == IA64_OPND_IMM8;
1134          else if (CONST_STRNEQ (idesc->name, "chk")
1135                   && strstr (format, "M21") != NULL)
1136            resolved = idesc->operands[0] == IA64_OPND_F2;
1137          else if (CONST_STRNEQ (idesc->name, "lfetch"))
1138            resolved = (strstr (format, "M14 M15") != NULL
1139                        && (idesc->operands[1] == IA64_OPND_R2
1140                            || idesc->operands[1] == IA64_OPND_IMM9b));
1141          else if (CONST_STRNEQ (idesc->name, "br.call")
1142                   && strstr (format, "B5") != NULL)
1143            resolved = idesc->operands[1] == IA64_OPND_B2;
1144          else if (CONST_STRNEQ (idesc->name, "br.call")
1145                   && strstr (format, "B3") != NULL)
1146            resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1147          else if (CONST_STRNEQ (idesc->name, "brp")
1148                   && strstr (format, "B7") != NULL)
1149            resolved = idesc->operands[0] == IA64_OPND_B2;
1150          else if (strcmp (ic->name, "invala") == 0)
1151            resolved = strcmp (idesc->name, ic->name) == 0;
1152	  else if (CONST_STRNEQ (idesc->name, "st")
1153		   && (strstr (format, "M5") != NULL
1154		       || strstr (format, "M10") != NULL))
1155	    resolved = idesc->flags & IA64_OPCODE_POSTINC;
1156	  else if (CONST_STRNEQ (idesc->name, "ld")
1157		   && (strstr (format, "M2 M3") != NULL
1158		       || strstr (format, "M12") != NULL
1159		       || strstr (format, "M7 M8") != NULL))
1160	    resolved = idesc->flags & IA64_OPCODE_POSTINC;
1161          else
1162            resolved = 0;
1163        }
1164
1165      /* Misc brl variations ('.cond' is optional);
1166         plain brl matches brl.cond.  */
1167      if (!resolved
1168          && (strcmp (idesc->name, "brl") == 0
1169              || CONST_STRNEQ (idesc->name, "brl."))
1170          && strcmp (ic->name, "brl.cond") == 0)
1171        {
1172          resolved = 1;
1173        }
1174
1175      /* Misc br variations ('.cond' is optional).  */
1176      if (!resolved
1177          && (strcmp (idesc->name, "br") == 0
1178              || CONST_STRNEQ (idesc->name, "br."))
1179          && strcmp (ic->name, "br.cond") == 0)
1180        {
1181          if (format)
1182            resolved = (strstr (format, "B4") != NULL
1183                        && idesc->operands[0] == IA64_OPND_B2)
1184              || (strstr (format, "B1") != NULL
1185                  && idesc->operands[0] == IA64_OPND_TGT25c);
1186          else
1187            resolved = 1;
1188        }
1189
1190      /* probe variations.  */
1191      if (!resolved && CONST_STRNEQ (idesc->name, "probe"))
1192        {
1193          resolved = strcmp (ic->name, "probe") == 0
1194            && !((strstr (idesc->name, "fault") != NULL)
1195                 ^ (format && strstr (format, "M40") != NULL));
1196        }
1197
1198      /* mov variations.  */
1199      if (!resolved && is_mov)
1200        {
1201          if (plain_mov)
1202            {
1203              /* mov alias for fmerge.  */
1204              if (strcmp (ic->name, "fmerge") == 0)
1205                {
1206                  resolved = idesc->operands[0] == IA64_OPND_F1
1207                    && idesc->operands[1] == IA64_OPND_F3;
1208                }
1209              /* mov alias for adds (r3 or imm14).  */
1210              else if (strcmp (ic->name, "adds") == 0)
1211                {
1212                  resolved = (idesc->operands[0] == IA64_OPND_R1
1213                              && (idesc->operands[1] == IA64_OPND_R3
1214                                  || (idesc->operands[1] == IA64_OPND_IMM14)));
1215                }
1216              /* mov alias for addl.  */
1217              else if (strcmp (ic->name, "addl") == 0)
1218                {
1219                  resolved = idesc->operands[0] == IA64_OPND_R1
1220                    && idesc->operands[1] == IA64_OPND_IMM22;
1221                }
1222            }
1223
1224          /* Some variants of mov and mov.[im].  */
1225          if (!resolved && CONST_STRNEQ (ic->name, "mov_"))
1226	    resolved = in_iclass_mov_x (idesc, ic, format, field);
1227        }
1228
1229      /* Keep track of this so we can flag any insn classes which aren't
1230         mapped onto at least one real insn.  */
1231      if (resolved)
1232	ic->terminal_resolved = 1;
1233    }
1234  else for (i = 0; i < ic->nsubs; i++)
1235    {
1236      if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1237        {
1238          int j;
1239
1240          for (j = 0; j < ic->nxsubs; j++)
1241	    if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1242	      return 0;
1243
1244          if (debug > 1)
1245            printf ("%s is in IC %s\n", idesc->name, ic->name);
1246
1247          resolved = 1;
1248          break;
1249        }
1250    }
1251
1252  /* If it's in this IC, add the IC note (if any) to the insn.  */
1253  if (resolved)
1254    {
1255      if (ic->note && notep)
1256        {
1257          if (*notep && *notep != ic->note)
1258	    warn (_("overwriting note %d with note %d (IC:%s)\n"),
1259		  *notep, ic->note, ic->name);
1260
1261          *notep = ic->note;
1262        }
1263    }
1264
1265  return resolved;
1266}
1267
1268
1269static int
1270lookup_regindex (const char *name, int specifier)
1271{
1272  switch (specifier)
1273    {
1274    case IA64_RS_ARX:
1275      if (strstr (name, "[RSC]"))
1276        return 16;
1277      if (strstr (name, "[BSP]"))
1278        return 17;
1279      else if (strstr (name, "[BSPSTORE]"))
1280        return 18;
1281      else if (strstr (name, "[RNAT]"))
1282        return 19;
1283      else if (strstr (name, "[FCR]"))
1284        return 21;
1285      else if (strstr (name, "[EFLAG]"))
1286        return 24;
1287      else if (strstr (name, "[CSD]"))
1288        return 25;
1289      else if (strstr (name, "[SSD]"))
1290        return 26;
1291      else if (strstr (name, "[CFLG]"))
1292        return 27;
1293      else if (strstr (name, "[FSR]"))
1294        return 28;
1295      else if (strstr (name, "[FIR]"))
1296        return 29;
1297      else if (strstr (name, "[FDR]"))
1298        return 30;
1299      else if (strstr (name, "[CCV]"))
1300        return 32;
1301      else if (strstr (name, "[ITC]"))
1302        return 44;
1303      else if (strstr (name, "[RUC]"))
1304        return 45;
1305      else if (strstr (name, "[PFS]"))
1306        return 64;
1307      else if (strstr (name, "[LC]"))
1308        return 65;
1309      else if (strstr (name, "[EC]"))
1310        return 66;
1311      abort ();
1312    case IA64_RS_CRX:
1313      if (strstr (name, "[DCR]"))
1314        return 0;
1315      else if (strstr (name, "[ITM]"))
1316        return 1;
1317      else if (strstr (name, "[IVA]"))
1318        return 2;
1319      else if (strstr (name, "[PTA]"))
1320        return 8;
1321      else if (strstr (name, "[GPTA]"))
1322        return 9;
1323      else if (strstr (name, "[IPSR]"))
1324        return 16;
1325      else if (strstr (name, "[ISR]"))
1326        return 17;
1327      else if (strstr (name, "[IIP]"))
1328        return 19;
1329      else if (strstr (name, "[IFA]"))
1330        return 20;
1331      else if (strstr (name, "[ITIR]"))
1332        return 21;
1333      else if (strstr (name, "[IIPA]"))
1334        return 22;
1335      else if (strstr (name, "[IFS]"))
1336        return 23;
1337      else if (strstr (name, "[IIM]"))
1338        return 24;
1339      else if (strstr (name, "[IHA]"))
1340        return 25;
1341      else if (strstr (name, "[LID]"))
1342        return 64;
1343      else if (strstr (name, "[IVR]"))
1344        return 65;
1345      else if (strstr (name, "[TPR]"))
1346        return 66;
1347      else if (strstr (name, "[EOI]"))
1348        return 67;
1349      else if (strstr (name, "[ITV]"))
1350        return 72;
1351      else if (strstr (name, "[PMV]"))
1352        return 73;
1353      else if (strstr (name, "[CMCV]"))
1354        return 74;
1355      abort ();
1356    case IA64_RS_PSR:
1357      if (strstr (name, ".be"))
1358        return 1;
1359      else if (strstr (name, ".up"))
1360        return 2;
1361      else if (strstr (name, ".ac"))
1362        return 3;
1363      else if (strstr (name, ".mfl"))
1364        return 4;
1365      else if (strstr (name, ".mfh"))
1366        return 5;
1367      else if (strstr (name, ".ic"))
1368        return 13;
1369      else if (strstr (name, ".i"))
1370        return 14;
1371      else if (strstr (name, ".pk"))
1372        return 15;
1373      else if (strstr (name, ".dt"))
1374        return 17;
1375      else if (strstr (name, ".dfl"))
1376        return 18;
1377      else if (strstr (name, ".dfh"))
1378        return 19;
1379      else if (strstr (name, ".sp"))
1380        return 20;
1381      else if (strstr (name, ".pp"))
1382        return 21;
1383      else if (strstr (name, ".di"))
1384        return 22;
1385      else if (strstr (name, ".si"))
1386        return 23;
1387      else if (strstr (name, ".db"))
1388        return 24;
1389      else if (strstr (name, ".lp"))
1390        return 25;
1391      else if (strstr (name, ".tb"))
1392        return 26;
1393      else if (strstr (name, ".rt"))
1394        return 27;
1395      else if (strstr (name, ".cpl"))
1396        return 32;
1397      else if (strstr (name, ".rs"))
1398        return 34;
1399      else if (strstr (name, ".mc"))
1400        return 35;
1401      else if (strstr (name, ".it"))
1402        return 36;
1403      else if (strstr (name, ".id"))
1404        return 37;
1405      else if (strstr (name, ".da"))
1406        return 38;
1407      else if (strstr (name, ".dd"))
1408        return 39;
1409      else if (strstr (name, ".ss"))
1410        return 40;
1411      else if (strstr (name, ".ri"))
1412        return 41;
1413      else if (strstr (name, ".ed"))
1414        return 43;
1415      else if (strstr (name, ".bn"))
1416        return 44;
1417      else if (strstr (name, ".ia"))
1418        return 45;
1419      else if (strstr (name, ".vm"))
1420        return 46;
1421      else
1422        abort ();
1423    default:
1424      break;
1425    }
1426  return REG_NONE;
1427}
1428
1429static int
1430lookup_specifier (const char *name)
1431{
1432  if (strchr (name, '%'))
1433    {
1434      if (strstr (name, "AR[K%]") != NULL)
1435        return IA64_RS_AR_K;
1436      if (strstr (name, "AR[UNAT]") != NULL)
1437        return IA64_RS_AR_UNAT;
1438      if (strstr (name, "AR%, % in 8") != NULL)
1439        return IA64_RS_AR;
1440      if (strstr (name, "AR%, % in 48") != NULL)
1441        return IA64_RS_ARb;
1442      if (strstr (name, "BR%") != NULL)
1443        return IA64_RS_BR;
1444      if (strstr (name, "CR[IIB%]") != NULL)
1445        return IA64_RS_CR_IIB;
1446      if (strstr (name, "CR[IRR%]") != NULL)
1447        return IA64_RS_CR_IRR;
1448      if (strstr (name, "CR[LRR%]") != NULL)
1449        return IA64_RS_CR_LRR;
1450      if (strstr (name, "CR%") != NULL)
1451        return IA64_RS_CR;
1452      if (strstr (name, "DAHR%, % in 0") != NULL)
1453        return IA64_RS_DAHR;
1454      if (strstr (name, "FR%, % in 0") != NULL)
1455        return IA64_RS_FR;
1456      if (strstr (name, "FR%, % in 2") != NULL)
1457        return IA64_RS_FRb;
1458      if (strstr (name, "GR%") != NULL)
1459        return IA64_RS_GR;
1460      if (strstr (name, "PR%, % in 1 ") != NULL)
1461        return IA64_RS_PR;
1462      if (strstr (name, "PR%, % in 16 ") != NULL)
1463	return IA64_RS_PRr;
1464
1465      warn (_("don't know how to specify %% dependency %s\n"),
1466	    name);
1467    }
1468  else if (strchr (name, '#'))
1469    {
1470      if (strstr (name, "CPUID#") != NULL)
1471        return IA64_RS_CPUID;
1472      if (strstr (name, "DBR#") != NULL)
1473        return IA64_RS_DBR;
1474      if (strstr (name, "IBR#") != NULL)
1475        return IA64_RS_IBR;
1476      if (strstr (name, "MSR#") != NULL)
1477	return IA64_RS_MSR;
1478      if (strstr (name, "PKR#") != NULL)
1479        return IA64_RS_PKR;
1480      if (strstr (name, "PMC#") != NULL)
1481        return IA64_RS_PMC;
1482      if (strstr (name, "PMD#") != NULL)
1483        return IA64_RS_PMD;
1484      if (strstr (name, "RR#") != NULL)
1485        return IA64_RS_RR;
1486
1487      warn (_("Don't know how to specify # dependency %s\n"),
1488	    name);
1489    }
1490  else if (CONST_STRNEQ (name, "AR[FPSR]"))
1491    return IA64_RS_AR_FPSR;
1492  else if (CONST_STRNEQ (name, "AR["))
1493    return IA64_RS_ARX;
1494  else if (CONST_STRNEQ (name, "CR["))
1495    return IA64_RS_CRX;
1496  else if (CONST_STRNEQ (name, "PSR."))
1497    return IA64_RS_PSR;
1498  else if (strcmp (name, "InService*") == 0)
1499    return IA64_RS_INSERVICE;
1500  else if (strcmp (name, "GR0") == 0)
1501    return IA64_RS_GR0;
1502  else if (strcmp (name, "CFM") == 0)
1503    return IA64_RS_CFM;
1504  else if (strcmp (name, "PR63") == 0)
1505    return IA64_RS_PR63;
1506  else if (strcmp (name, "RSE") == 0)
1507    return IA64_RS_RSE;
1508
1509  return IA64_RS_ANY;
1510}
1511
1512static void
1513print_dependency_table (void)
1514{
1515  int i, j;
1516
1517  if (debug)
1518    {
1519      for (i=0;i < iclen;i++)
1520        {
1521          if (ics[i]->is_class)
1522            {
1523              if (!ics[i]->nsubs)
1524                {
1525                  if (ics[i]->comment)
1526		    warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1527			  ics[i]->name, ics[i]->comment);
1528		  else
1529		    warn (_("IC:%s has no terminals or sub-classes\n"),
1530			  ics[i]->name);
1531                }
1532            }
1533          else
1534            {
1535              if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1536                {
1537                  if (ics[i]->comment)
1538		    warn (_("no insns mapped directly to terminal IC %s [%s]"),
1539			  ics[i]->name, ics[i]->comment);
1540		  else
1541		    warn (_("no insns mapped directly to terminal IC %s\n"),
1542			  ics[i]->name);
1543                }
1544            }
1545        }
1546
1547      for (i = 0; i < iclen; i++)
1548        {
1549          if (ics[i]->orphan)
1550            {
1551              mark_used (ics[i], 1);
1552              warn (_("class %s is defined but not used\n"),
1553		    ics[i]->name);
1554            }
1555        }
1556
1557      if (debug > 1)
1558	for (i = 0; i < rdepslen; i++)
1559	  {
1560	    static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1561
1562	    if (rdeps[i]->total_chks == 0)
1563	      {
1564		if (rdeps[i]->total_regs)
1565		  warn (_("Warning: rsrc %s (%s) has no chks\n"),
1566			rdeps[i]->name, mode_str[rdeps[i]->mode]);
1567		else
1568		  warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1569			rdeps[i]->name, mode_str[rdeps[i]->mode]);
1570	      }
1571	    else if (rdeps[i]->total_regs == 0)
1572	      warn (_("rsrc %s (%s) has no regs\n"),
1573		    rdeps[i]->name, mode_str[rdeps[i]->mode]);
1574	  }
1575    }
1576
1577  /* The dependencies themselves.  */
1578  printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1579  for (i = 0; i < rdepslen; i++)
1580    {
1581      /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1582         resource used.  */
1583      int specifier = lookup_specifier (rdeps[i]->name);
1584      int regindex = lookup_regindex (rdeps[i]->name, specifier);
1585
1586      printf ("  { \"%s\", %d, %d, %d, %d, ",
1587              rdeps[i]->name, specifier,
1588              (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1589      if (rdeps[i]->semantics == IA64_DVS_OTHER)
1590	{
1591	  const char *quote, *rest;
1592
1593	  putchar ('\"');
1594	  rest = rdeps[i]->extra;
1595	  quote = strchr (rest, '\"');
1596	  while (quote != NULL)
1597	    {
1598	      printf ("%.*s\\\"", (int) (quote - rest), rest);
1599	      rest = quote + 1;
1600	      quote = strchr (rest, '\"');
1601	    }
1602	  printf ("%s\", ", rest);
1603	}
1604      else
1605	printf ("NULL, ");
1606      printf("},\n");
1607    }
1608  printf ("};\n\n");
1609
1610  /* And dependency lists.  */
1611  for (i=0;i < dlistlen;i++)
1612    {
1613      unsigned int len = (unsigned) -1;
1614      printf ("static const unsigned short dep%d[] = {", i);
1615      for (j=0;j < dlists[i]->len; j++)
1616        {
1617          if (len > 74)
1618            {
1619              printf("\n ");
1620              len = 1;
1621            }
1622          len += printf (" %d,", dlists[i]->deps[j]);
1623        }
1624      printf ("\n};\n\n");
1625    }
1626
1627  /* And opcode dependency list.  */
1628  printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1629  printf ("static const struct ia64_opcode_dependency\n");
1630  printf ("op_dependencies[] = {\n");
1631  for (i = 0; i < opdeplen; i++)
1632    {
1633      printf ("  { ");
1634      if (opdeps[i]->chk == -1)
1635        printf ("0, NULL, ");
1636      else
1637        printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1638      if (opdeps[i]->reg == -1)
1639        printf ("0, NULL, ");
1640      else
1641        printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1642      printf ("},\n");
1643    }
1644  printf ("};\n\n");
1645}
1646
1647
1648/* Add STR to the string table.  */
1649static struct string_entry *
1650insert_string (char *str)
1651{
1652  int start = 0, end = strtablen;
1653  int i, x;
1654
1655  if (strtablen == strtabtotlen)
1656    {
1657      strtabtotlen += 20;
1658      string_table = (struct string_entry **)
1659	xrealloc (string_table,
1660		  sizeof (struct string_entry **) * strtabtotlen);
1661    }
1662
1663  if (strtablen == 0)
1664    {
1665      strtablen = 1;
1666      string_table[0] = tmalloc (struct string_entry);
1667      string_table[0]->s = xstrdup (str);
1668      string_table[0]->num = 0;
1669      return string_table[0];
1670    }
1671
1672  if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1673    i = end;
1674  else if (strcmp (str, string_table[0]->s) < 0)
1675    i = 0;
1676  else
1677    {
1678      while (1)
1679	{
1680	  int c;
1681
1682	  i = (start + end) / 2;
1683	  c = strcmp (str, string_table[i]->s);
1684
1685	  if (c < 0)
1686	    end = i - 1;
1687	  else if (c == 0)
1688	    return string_table[i];
1689	  else
1690	    start = i + 1;
1691
1692	  if (start > end)
1693	    break;
1694	}
1695    }
1696
1697  for (; i > 0 && i < strtablen; i--)
1698    if (strcmp (str, string_table[i - 1]->s) > 0)
1699      break;
1700
1701  for (; i < strtablen; i++)
1702    if (strcmp (str, string_table[i]->s) < 0)
1703      break;
1704
1705  for (x = strtablen - 1; x >= i; x--)
1706    {
1707      string_table[x + 1] = string_table[x];
1708      string_table[x + 1]->num = x + 1;
1709    }
1710
1711  string_table[i] = tmalloc (struct string_entry);
1712  string_table[i]->s = xstrdup (str);
1713  string_table[i]->num = i;
1714  strtablen++;
1715
1716  return string_table[i];
1717}
1718
1719static struct bittree *
1720make_bittree_entry (void)
1721{
1722  struct bittree *res = tmalloc (struct bittree);
1723
1724  res->disent = NULL;
1725  res->bits[0] = NULL;
1726  res->bits[1] = NULL;
1727  res->bits[2] = NULL;
1728  res->skip_flag = 0;
1729  res->bits_to_skip = 0;
1730  return res;
1731}
1732
1733
1734static struct disent *
1735add_dis_table_ent (struct disent *which, int insn, int order,
1736                   ci_t completer_index)
1737{
1738  int ci = 0;
1739  struct disent *ent;
1740
1741  if (which != NULL)
1742    {
1743      ent = which;
1744
1745      ent->nextcnt++;
1746      while (ent->nexte != NULL)
1747	ent = ent->nexte;
1748
1749      ent = (ent->nexte = tmalloc (struct disent));
1750    }
1751  else
1752    {
1753      ent = tmalloc (struct disent);
1754      ent->next_ent = disinsntable;
1755      disinsntable = ent;
1756      which = ent;
1757    }
1758  ent->nextcnt = 0;
1759  ent->nexte = NULL;
1760  ent->insn = insn;
1761  ent->priority = order;
1762
1763  while (completer_index != 1)
1764    {
1765      ci = (ci << 1) | (completer_index & 1);
1766      completer_index >>= 1;
1767    }
1768  ent->completer_index = ci;
1769  return which;
1770}
1771
1772static void
1773finish_distable (void)
1774{
1775  struct disent *ent = disinsntable;
1776  struct disent *prev = ent;
1777
1778  ent->ournum = 32768;
1779  while ((ent = ent->next_ent) != NULL)
1780    {
1781      ent->ournum = prev->ournum + prev->nextcnt + 1;
1782      prev = ent;
1783    }
1784}
1785
1786static void
1787insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode,
1788                      ia64_insn mask, int opcodenum, int order,
1789                      ci_t completer_index)
1790{
1791  ia64_insn m;
1792  int b;
1793  struct bittree *next;
1794
1795  if (bit == -1)
1796    {
1797      struct disent *nent = add_dis_table_ent (curr_ent->disent,
1798                                               opcodenum, order,
1799					       completer_index);
1800      curr_ent->disent = nent;
1801      return;
1802    }
1803
1804  m = ((ia64_insn) 1) << bit;
1805
1806  if (mask & m)
1807    b = (opcode & m) ? 1 : 0;
1808  else
1809    b = 2;
1810
1811  next = curr_ent->bits[b];
1812  if (next == NULL)
1813    {
1814      next = make_bittree_entry ();
1815      curr_ent->bits[b] = next;
1816    }
1817  insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1818			completer_index);
1819}
1820
1821static void
1822add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask,
1823               int opcodenum, struct completer_entry *ent, ci_t completer_index)
1824{
1825  if (completer_index & ((ci_t)1 << 32) )
1826    abort ();
1827
1828  while (ent != NULL)
1829    {
1830      ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1831      add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1832		     (completer_index << 1) | 1);
1833
1834      if (ent->is_terminal)
1835	{
1836	  insert_bit_table_ent (bittree, 40, newopcode, mask,
1837                                opcodenum, opcode_count - ent->order - 1,
1838				(completer_index << 1) | 1);
1839	}
1840      completer_index <<= 1;
1841      ent = ent->alternative;
1842    }
1843}
1844
1845/* This optimization pass combines multiple "don't care" nodes.  */
1846static void
1847compact_distree (struct bittree *ent)
1848{
1849#define IS_SKIP(ent) \
1850    ((ent->bits[2] !=NULL) \
1851     && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1852
1853  int bitcnt = 0;
1854  struct bittree *nent = ent;
1855  int x;
1856
1857  while (IS_SKIP (nent))
1858    {
1859      bitcnt++;
1860      nent = nent->bits[2];
1861    }
1862
1863  if (bitcnt)
1864    {
1865      struct bittree *next = ent->bits[2];
1866
1867      ent->bits[0] = nent->bits[0];
1868      ent->bits[1] = nent->bits[1];
1869      ent->bits[2] = nent->bits[2];
1870      ent->disent = nent->disent;
1871      ent->skip_flag = 1;
1872      ent->bits_to_skip = bitcnt;
1873      while (next != nent)
1874	{
1875	  struct bittree *b = next;
1876	  next = next->bits[2];
1877	  free (b);
1878	}
1879      free (nent);
1880    }
1881
1882  for (x = 0; x < 3; x++)
1883    {
1884      struct bittree *i = ent->bits[x];
1885
1886      if (i != NULL)
1887	compact_distree (i);
1888    }
1889}
1890
1891static unsigned char *insn_list;
1892static int insn_list_len = 0;
1893static int tot_insn_list_len = 0;
1894
1895/* Generate the disassembler state machine corresponding to the tree
1896   in ENT.  */
1897static void
1898gen_dis_table (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[] = {");
2128  for (x = 0; x < insn_list_len; x++)
2129    {
2130      if (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%lx, %d, %d, %d },\n", ( long ) 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 (struct completer_entry *ent1,
2223                      struct completer_entry *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 (const char *name)
2341{
2342  char *c;
2343
2344  if (name[0] == '\0')
2345    return 0;
2346
2347  c = strchr (name, '.');
2348  if (c != NULL)
2349    return c - name;
2350  else
2351    return strlen (name);
2352}
2353
2354static void
2355compute_completer_bits (struct main_entry *ment, struct completer_entry *ent)
2356{
2357  while (ent != NULL)
2358    {
2359      compute_completer_bits (ment, ent->addl_entries);
2360
2361      if (ent->is_terminal)
2362	{
2363	  ia64_insn mask = 0;
2364	  ia64_insn our_bits = ent->bits;
2365	  struct completer_entry *p = ent->parent;
2366	  ia64_insn p_bits;
2367	  int x;
2368
2369	  while (p != NULL && ! p->is_terminal)
2370	    p = p->parent;
2371
2372	  if (p != NULL)
2373	    p_bits = p->bits;
2374	  else
2375	    p_bits = ment->opcode->opcode;
2376
2377	  for (x = 0; x < 64; x++)
2378	    {
2379	      ia64_insn m = ((ia64_insn) 1) << x;
2380
2381	      if ((p_bits & m) != (our_bits & m))
2382		mask |= m;
2383	      else
2384		our_bits &= ~m;
2385	    }
2386	  ent->bits = our_bits;
2387	  ent->mask = mask;
2388	}
2389      else
2390	{
2391	  ent->bits = 0;
2392	  ent->mask = 0;
2393	}
2394
2395      ent = ent->alternative;
2396    }
2397}
2398
2399/* Find identical completer trees that are used in different
2400   instructions and collapse their entries.  */
2401static void
2402collapse_redundant_completers (void)
2403{
2404  struct main_entry *ptr;
2405  int x;
2406
2407  for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2408    {
2409      if (ptr->completers == NULL)
2410	abort ();
2411
2412      compute_completer_bits (ptr, ptr->completers);
2413      ptr->completers = insert_gclist (ptr->completers);
2414    }
2415
2416  /* The table has been finalized, now number the indexes.  */
2417  for (x = 0; x < glistlen; x++)
2418    glist[x]->num = x;
2419}
2420
2421
2422/* Attach two lists of dependencies to each opcode.
2423   1) all resources which, when already marked in use, conflict with this
2424   opcode (chks)
2425   2) all resources which must be marked in use when this opcode is used
2426   (regs).  */
2427static int
2428insert_opcode_dependencies (struct ia64_opcode *opc,
2429                            struct completer_entry *cmp ATTRIBUTE_UNUSED)
2430{
2431  /* Note all resources which point to this opcode.  rfi has the most chks
2432     (79) and cmpxchng has the most regs (54) so 100 here should be enough.  */
2433  int i;
2434  int nregs = 0;
2435  unsigned short regs[256];
2436  int nchks = 0;
2437  unsigned short chks[256];
2438  /* Flag insns for which no class matched; there should be none.  */
2439  int no_class_found = 1;
2440
2441  for (i = 0; i < rdepslen; i++)
2442    {
2443      struct rdep *rs = rdeps[i];
2444      int j;
2445
2446      if (strcmp (opc->name, "cmp.eq.and") == 0
2447          && CONST_STRNEQ (rs->name, "PR%")
2448          && rs->mode == 1)
2449        no_class_found = 99;
2450
2451      for (j=0; j < rs->nregs;j++)
2452        {
2453          int ic_note = 0;
2454
2455          if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2456            {
2457              /* We can ignore ic_note 11 for non PR resources.  */
2458              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2459                ic_note = 0;
2460
2461              if (ic_note != 0 && rs->regnotes[j] != 0
2462                  && ic_note != rs->regnotes[j]
2463                  && !(ic_note == 11 && rs->regnotes[j] == 1))
2464                warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2465		      ic_note, opc->name, ics[rs->regs[j]]->name,
2466		      rs->name, rs->regnotes[j]);
2467              /* Instruction class notes override resource notes.
2468                 So far, only note 11 applies to an IC instead of a resource,
2469                 and note 11 implies note 1.  */
2470              if (ic_note)
2471                regs[nregs++] = RDEP(ic_note, i);
2472              else
2473                regs[nregs++] = RDEP(rs->regnotes[j], i);
2474              no_class_found = 0;
2475              ++rs->total_regs;
2476            }
2477        }
2478
2479      for (j = 0; j < rs->nchks; j++)
2480        {
2481          int ic_note = 0;
2482
2483          if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2484            {
2485              /* We can ignore ic_note 11 for non PR resources.  */
2486              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2487                ic_note = 0;
2488
2489              if (ic_note != 0 && rs->chknotes[j] != 0
2490                  && ic_note != rs->chknotes[j]
2491                  && !(ic_note == 11 && rs->chknotes[j] == 1))
2492                warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2493		      ic_note, opc->name, ics[rs->chks[j]]->name,
2494		      rs->name, rs->chknotes[j]);
2495              if (ic_note)
2496                chks[nchks++] = RDEP(ic_note, i);
2497              else
2498                chks[nchks++] = RDEP(rs->chknotes[j], i);
2499              no_class_found = 0;
2500              ++rs->total_chks;
2501            }
2502        }
2503    }
2504
2505  if (no_class_found)
2506    warn (_("opcode %s has no class (ops %d %d %d)\n"),
2507	  opc->name,
2508	  opc->operands[0], opc->operands[1], opc->operands[2]);
2509
2510  return insert_dependencies (nchks, chks, nregs, regs);
2511}
2512
2513static void
2514insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent,
2515                        int order)
2516{
2517  struct completer_entry **ptr = &tabent->completers;
2518  struct completer_entry *parent = NULL;
2519  char pcopy[129], *prefix;
2520  int at_end = 0;
2521
2522  if (strlen (opc->name) > 128)
2523    abort ();
2524
2525  strcpy (pcopy, opc->name);
2526  prefix = pcopy + get_prefix_len (pcopy);
2527
2528  if (prefix[0] != '\0')
2529    prefix++;
2530
2531  while (! at_end)
2532    {
2533      int need_new_ent = 1;
2534      int plen = get_prefix_len (prefix);
2535      struct string_entry *sent;
2536
2537      at_end = (prefix[plen] == '\0');
2538      prefix[plen] = '\0';
2539      sent = insert_string (prefix);
2540
2541      while (*ptr != NULL)
2542	{
2543	  int cmpres = sent->num - (*ptr)->name->num;
2544
2545	  if (cmpres == 0)
2546	    {
2547	      need_new_ent = 0;
2548	      break;
2549	    }
2550	  else
2551	    ptr = &((*ptr)->alternative);
2552	}
2553
2554      if (need_new_ent)
2555	{
2556	  struct completer_entry *nent = tmalloc (struct completer_entry);
2557
2558	  nent->name = sent;
2559	  nent->parent = parent;
2560	  nent->addl_entries = NULL;
2561	  nent->alternative = *ptr;
2562	  *ptr = nent;
2563	  nent->is_terminal = 0;
2564          nent->dependencies = -1;
2565	}
2566
2567      if (! at_end)
2568	{
2569	  parent = *ptr;
2570	  ptr = &((*ptr)->addl_entries);
2571	  prefix += plen + 1;
2572	}
2573    }
2574
2575  if ((*ptr)->is_terminal)
2576    abort ();
2577
2578  (*ptr)->is_terminal = 1;
2579  (*ptr)->mask = (ia64_insn)-1;
2580  (*ptr)->bits = opc->opcode;
2581  (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2582  (*ptr)->order = order;
2583}
2584
2585static void
2586print_completer_entry (struct completer_entry *ent)
2587{
2588  int moffset = 0;
2589  ia64_insn mask = ent->mask, bits = ent->bits;
2590
2591  if (mask != 0)
2592    {
2593      while (! (mask & 1))
2594	{
2595	  moffset++;
2596	  mask = mask >> 1;
2597	  bits = bits >> 1;
2598	}
2599
2600      if (bits & 0xffffffff00000000LL)
2601	abort ();
2602    }
2603
2604  printf ("  { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2605	  (int)bits,
2606	  (int)mask,
2607	  ent->name->num,
2608	  ent->alternative != NULL ? ent->alternative->num : -1,
2609	  ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2610	  moffset,
2611	  ent->is_terminal ? 1 : 0,
2612          ent->dependencies);
2613}
2614
2615static void
2616print_completer_table (void)
2617{
2618  int x;
2619
2620  printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2621  for (x = 0; x < glistlen; x++)
2622    print_completer_entry (glist[x]);
2623  printf ("};\n\n");
2624}
2625
2626static int
2627opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2)
2628{
2629  int x;
2630  int plen1, plen2;
2631
2632  if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2633      || (opc1->num_outputs != opc2->num_outputs)
2634      || (opc1->flags != opc2->flags))
2635    return 0;
2636
2637  for (x = 0; x < 5; x++)
2638    if (opc1->operands[x] != opc2->operands[x])
2639      return 0;
2640
2641  plen1 = get_prefix_len (opc1->name);
2642  plen2 = get_prefix_len (opc2->name);
2643
2644  if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2645    return 1;
2646
2647  return 0;
2648}
2649
2650static void
2651add_opcode_entry (struct ia64_opcode *opc)
2652{
2653  struct main_entry **place;
2654  struct string_entry *name;
2655  char prefix[129];
2656  int found_it = 0;
2657
2658  if (strlen (opc->name) > 128)
2659    abort ();
2660
2661  place = &maintable;
2662  strcpy (prefix, opc->name);
2663  prefix[get_prefix_len (prefix)] = '\0';
2664  name = insert_string (prefix);
2665
2666  /* Walk the list of opcode table entries.  If it's a new
2667     instruction, allocate and fill in a new entry.  Note
2668     the main table is alphabetical by opcode name.  */
2669
2670  while (*place != NULL)
2671    {
2672      if ((*place)->name->num == name->num
2673	  && opcodes_eq ((*place)->opcode, opc))
2674	{
2675	  found_it = 1;
2676	  break;
2677	}
2678      if ((*place)->name->num > name->num)
2679	break;
2680
2681      place = &((*place)->next);
2682    }
2683  if (! found_it)
2684    {
2685      struct main_entry *nent = tmalloc (struct main_entry);
2686
2687      nent->name = name;
2688      nent->opcode = opc;
2689      nent->next = *place;
2690      nent->completers = 0;
2691      *place = nent;
2692
2693      if (otlen == ottotlen)
2694        {
2695          ottotlen += 20;
2696          ordered_table = (struct main_entry **)
2697            xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2698        }
2699      ordered_table[otlen++] = nent;
2700    }
2701
2702  insert_completer_entry (opc, *place, opcode_count++);
2703}
2704
2705static void
2706print_main_table (void)
2707{
2708  struct main_entry *ptr = maintable;
2709  int tindex = 0;
2710
2711  printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2712  while (ptr != NULL)
2713    {
2714      printf ("  { %d, %d, %d, 0x",
2715	      ptr->name->num,
2716	      ptr->opcode->type,
2717	      ptr->opcode->num_outputs);
2718      opcode_fprintf_vma (stdout, ptr->opcode->opcode);
2719      printf ("ull, 0x");
2720      opcode_fprintf_vma (stdout, ptr->opcode->mask);
2721      printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2722	      ptr->opcode->operands[0],
2723	      ptr->opcode->operands[1],
2724	      ptr->opcode->operands[2],
2725	      ptr->opcode->operands[3],
2726	      ptr->opcode->operands[4],
2727	      ptr->opcode->flags,
2728	      ptr->completers->num);
2729
2730      ptr->main_index = tindex++;
2731
2732      ptr = ptr->next;
2733    }
2734  printf ("};\n\n");
2735}
2736
2737static void
2738shrink (struct ia64_opcode *table)
2739{
2740  int curr_opcode;
2741
2742  for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2743    {
2744      add_opcode_entry (table + curr_opcode);
2745      if (table[curr_opcode].num_outputs == 2
2746	  && ((table[curr_opcode].operands[0] == IA64_OPND_P1
2747	       && table[curr_opcode].operands[1] == IA64_OPND_P2)
2748	      || (table[curr_opcode].operands[0] == IA64_OPND_P2
2749		  && table[curr_opcode].operands[1] == IA64_OPND_P1)))
2750	{
2751	  struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2752	  unsigned i;
2753
2754	  *alias = table[curr_opcode];
2755	  for (i = 2; i < NELEMS (alias->operands); ++i)
2756	    alias->operands[i - 1] = alias->operands[i];
2757	  alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2758	  --alias->num_outputs;
2759	  alias->flags |= PSEUDO;
2760	  add_opcode_entry (alias);
2761	}
2762    }
2763}
2764
2765
2766/* Program options.  */
2767#define OPTION_SRCDIR	200
2768
2769struct option long_options[] =
2770{
2771  {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
2772  {"debug",   no_argument,       NULL, 'd'},
2773  {"version", no_argument,       NULL, 'V'},
2774  {"help",    no_argument,       NULL, 'h'},
2775  {0,         no_argument,       NULL, 0}
2776};
2777
2778static void
2779print_version (void)
2780{
2781  printf ("%s: version 1.0\n", program_name);
2782  xexit (0);
2783}
2784
2785static void
2786usage (FILE * stream, int status)
2787{
2788  fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2789	   program_name);
2790  xexit (status);
2791}
2792
2793int
2794main (int argc, char **argv)
2795{
2796  extern int chdir (char *);
2797  char *srcdir = NULL;
2798  int c;
2799
2800  program_name = *argv;
2801  xmalloc_set_program_name (program_name);
2802
2803  while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2804    switch (c)
2805      {
2806      case OPTION_SRCDIR:
2807	srcdir = optarg;
2808	break;
2809      case 'V':
2810      case 'v':
2811	print_version ();
2812	break;
2813      case 'd':
2814	debug = 1;
2815	break;
2816      case 'h':
2817      case '?':
2818	usage (stderr, 0);
2819      default:
2820      case 0:
2821	break;
2822      }
2823
2824  if (optind != argc)
2825    usage (stdout, 1);
2826
2827  if (srcdir != NULL)
2828    if (chdir (srcdir) != 0)
2829      fail (_("unable to change directory to \"%s\", errno = %s\n"),
2830	    srcdir, strerror (errno));
2831
2832  load_insn_classes ();
2833  load_dependencies ();
2834
2835  shrink (ia64_opcodes_a);
2836  shrink (ia64_opcodes_b);
2837  shrink (ia64_opcodes_f);
2838  shrink (ia64_opcodes_i);
2839  shrink (ia64_opcodes_m);
2840  shrink (ia64_opcodes_x);
2841  shrink (ia64_opcodes_d);
2842
2843  collapse_redundant_completers ();
2844
2845  printf ("/* This file is automatically generated by ia64-gen.  Do not edit!  */\n");
2846  printf ("/* Copyright (C) 2007-2017 Free Software Foundation, Inc.\n\
2847\n\
2848   This file is part of the GNU opcodes library.\n\
2849\n\
2850   This library is free software; you can redistribute it and/or modify\n\
2851   it under the terms of the GNU General Public License as published by\n\
2852   the Free Software Foundation; either version 3, or (at your option)\n\
2853   any later version.\n\
2854\n\
2855   It is distributed in the hope that it will be useful, but WITHOUT\n\
2856   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2857   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
2858   License for more details.\n\
2859\n\
2860   You should have received a copy of the GNU General Public License\n\
2861   along with this program; see the file COPYING.  If not, write to the\n\
2862   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2863   02110-1301, USA.  */\n");
2864
2865  print_string_table ();
2866  print_dependency_table ();
2867  print_completer_table ();
2868  print_main_table ();
2869
2870  generate_disassembler ();
2871
2872  exit (0);
2873}
2874