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