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