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