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