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