2000-08-24 Kazu Hirata <kazu@hxi.com>
[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 
701     return IA64_DVS_OTHER;
702 }
703
704 static void
705 add_dep (const char *name, const char *chk, const char *reg,
706          int semantics, int mode, char *extra, int flag)
707 {
708   struct rdep *rs;
709
710   rs = insert_resource (name, mode);
711   parse_resource_users (chk, &rs->chks, &rs->nchks,
712                         &rs->chknotes);
713   parse_resource_users (reg, &rs->regs, &rs->nregs,
714                         &rs->regnotes);
715   rs->semantics = semantics;
716   rs->extra = extra;
717   rs->waw_special = flag;
718 }
719
720 static void
721 load_depfile (const char *filename, enum ia64_dependency_mode mode)
722 {
723   FILE *fp = fopen(filename, "r");
724   char buf[1024];
725
726   if (fp == NULL){
727     fprintf (stderr, "Can't find %s for reading\n", filename);
728     exit(1);
729   }
730
731   fgets(buf, sizeof(buf), fp);
732   while (!feof(fp))
733     {
734       char *name, *tmp;
735       int semantics;
736       char *extra;
737       char *regp, *chkp;
738
739       if (fgets (buf, sizeof(buf), fp) == NULL)
740         break;
741
742       while (isspace(buf[strlen(buf)-1]))
743         buf[strlen(buf)-1] = '\0';
744
745       name = tmp = buf;
746       while (*tmp != ';')
747         ++tmp;
748       *tmp++ = '\0';
749       
750       while (isspace (*tmp))
751         ++tmp;
752       regp = tmp;
753       tmp = strchr (tmp, ';');
754       if (!tmp)
755         abort ();
756       *tmp++ = 0;
757       while (isspace (*tmp))
758         ++tmp;
759       chkp = tmp;
760       tmp = strchr (tmp, ';');
761       if (!tmp)
762         abort ();
763       *tmp++ = 0;
764       while (isspace (*tmp))
765         ++tmp;
766       semantics = parse_semantics (tmp);
767       extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
768
769       /* For WAW entries, if the chks and regs differ, we need to enter the
770          entries in both positions so that the tables will be parsed properly,
771          without a lot of extra work */
772       if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
773         {
774           add_dep (name, chkp, regp, semantics, mode, extra, 0);
775           add_dep (name, regp, chkp, semantics, mode, extra, 1);
776         }
777       else
778         {
779           add_dep (name, chkp, regp, semantics, mode, extra, 0);
780         }
781     }
782   fclose(fp);
783 }
784
785 static void
786 load_dependencies()
787 {
788   load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
789   load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
790   load_depfile ("ia64-war.tbl", IA64_DV_WAR);
791
792   if (debug)
793       printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
794 }
795
796 /* is the given operand an indirect register file operand? */
797 static int 
798 irf_operand (int op, const char *field)
799 {
800   if (!field)
801     {
802       return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
803         || op == IA64_OPND_IBR_R3  || op == IA64_OPND_PKR_R3
804         || op == IA64_OPND_PMC_R3  || op == IA64_OPND_PMD_R3
805         || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
806     }
807   else
808     {
809       return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
810               || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
811               || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
812               || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
813               || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
814               || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
815               || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
816               || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
817     }
818 }
819
820 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
821    mov_um insn classes */
822 static int
823 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, 
824                  const char *format, const char *field)
825 {
826   int plain_mov = strcmp (idesc->name, "mov") == 0;
827
828   if (!format)
829     return 0;
830
831   switch (ic->name[4])
832     {
833     default:
834       abort ();
835     case 'a':
836       {
837         int i = strcmp (idesc->name, "mov.i") == 0;
838         int m = strcmp (idesc->name, "mov.m") == 0;
839         int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
840         int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
841         int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
842         int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
843         int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
844         int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
845
846         /* IC:mov ar */
847         if (i2627)
848           return strstr (format, "I26") || strstr (format, "I27");
849         if (i28)
850           return strstr (format, "I28") != NULL;
851         if (m2930)
852           return strstr (format, "M29") || strstr (format, "M30");
853         if (m31)
854           return strstr (format, "M31") != NULL;
855         if (pseudo0 || pseudo1)
856           return 1;
857       }
858       break;
859     case 'b':
860       {
861         int i21 = idesc->operands[0] == IA64_OPND_B1;
862         int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
863         if (i22)
864           return strstr (format, "I22") != NULL;
865         if (i21)
866           return strstr (format, "I21") != NULL;
867       }
868       break;
869     case 'c':
870       {
871         int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
872         int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
873         if (m32)
874           return strstr (format, "M32") != NULL;
875         if (m33)
876           return strstr (format, "M33") != NULL;
877       }
878       break;
879     case 'i':
880       if (ic->name[5] == 'n')
881         {
882           int m42 = plain_mov && irf_operand (idesc->operands[0], field);
883           int m43 = plain_mov && irf_operand (idesc->operands[1], field);
884           if (m42)
885             return strstr (format, "M42") != NULL;
886           if (m43)
887             return strstr (format, "M43") != NULL;
888         }
889       else if (ic->name[5] == 'p')
890         {
891           return idesc->operands[1] == IA64_OPND_IP;
892         }
893       else
894         abort ();
895       break;
896     case 'p':
897       if (ic->name[5] == 'r')
898         {
899           int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
900           int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
901           int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
902           if (i23)
903             return strstr (format, "I23") != NULL;
904           if (i24)
905             return strstr (format, "I24") != NULL;
906           if (i25)
907             return strstr (format, "I25") != NULL;
908         }
909       else if (ic->name[5] == 's')
910         {
911           int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
912           int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
913           if (m35)
914             return strstr (format, "M35") != NULL;
915           if (m36)
916             return strstr (format, "M36") != NULL;
917         }
918       else
919         abort ();
920       break;
921     case 'u':
922       {
923         int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
924         int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
925         if (m35)
926           return strstr (format, "M35") != NULL;
927         if (m36)
928           return strstr (format, "M36") != NULL;
929       }
930       break;
931     }
932   return 0;
933 }
934
935
936 /* is the given opcode in the given insn class? */
937 static int
938 in_iclass(struct ia64_opcode *idesc, struct iclass *ic, 
939           const char *format, const char *field, int *notep)
940 {
941   int i;
942   int resolved = 0;
943
944   if (ic->comment)
945     {
946       if (!strncmp (ic->comment, "Format", 6))
947         {
948           /* assume that the first format seen is the most restrictive, and
949              only keep a later one if it looks like it's more restrictive. */
950           if (format)
951             {
952               if (strlen (ic->comment) < strlen (format))
953                 {
954                   fprintf (stderr, "Warning: most recent format '%s'\n"
955                            "appears more restrictive than '%s'\n",
956                            ic->comment, format);
957                   format = ic->comment; 
958                 }
959             }
960           else
961             format = ic->comment;
962         }
963       else if (!strncmp (ic->comment, "Field", 5))
964         {
965           if (field)
966             fprintf (stderr, "Overlapping field %s->%s\n",
967                      ic->comment, field);
968           field = ic->comment;
969         }
970     }
971
972   /* an insn class matches anything that is the same followed by completers,
973      except when the absence and presence of completers constitutes different
974      instructions */
975   if (ic->nsubs == 0 && ic->nxsubs == 0)
976     {
977       int is_mov = strncmp (idesc->name, "mov", 3) == 0;
978       int plain_mov = strcmp (idesc->name, "mov") == 0;
979       int len = strlen(ic->name);
980
981       resolved = ((strncmp (ic->name, idesc->name, len) == 0)
982                   && (idesc->name[len] == '\0' 
983                       || idesc->name[len] == '.'));
984
985       /* all break and nop variations must match exactly */
986       if (resolved &&
987           (strcmp (ic->name, "break") == 0
988            || strcmp (ic->name, "nop") == 0))
989         resolved = strcmp (ic->name, idesc->name) == 0;
990
991       /* assume restrictions in the FORMAT/FIELD negate resolution,
992          unless specifically allowed by clauses in this block */
993       if (resolved && field)
994         {
995           /* check Field(sf)==sN against opcode sN */
996           if (strstr(field, "(sf)==") != NULL)
997             {
998               char *sf;
999               if ((sf = strstr (idesc->name, ".s")) != 0)
1000                 {
1001                   resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1002                 }
1003             }
1004           /* check Field(lftype)==XXX */
1005           else if (strstr (field, "(lftype)") != NULL)
1006             {
1007               if (strstr (idesc->name, "fault") != NULL)
1008                 resolved = strstr (field, "fault") != NULL;
1009               else
1010                 resolved = strstr (field, "fault") == NULL;
1011             }
1012           /* handle Field(ctype)==XXX */
1013           else if (strstr (field, "(ctype)") != NULL)
1014             {
1015               if (strstr (idesc->name, "or.andcm"))
1016                 resolved = strstr (field, "or.andcm") != NULL;
1017               else if (strstr (idesc->name, "and.orcm"))
1018                 resolved = strstr (field, "and.orcm") != NULL;
1019               else if (strstr (idesc->name, "orcm"))
1020                 resolved = strstr (field, "or orcm") != NULL;
1021               else if (strstr (idesc->name, "or"))
1022                 resolved = strstr (field, "or orcm") != NULL;
1023               else if (strstr (idesc->name, "andcm"))
1024                 resolved = strstr (field, "and andcm") != NULL;
1025               else if (strstr (idesc->name, "and"))
1026                 resolved = strstr (field, "and andcm") != NULL;
1027               else if (strstr (idesc->name, "unc"))
1028                 resolved = strstr (field, "unc") != NULL;
1029               else
1030                 resolved = strcmp (field, "Field(ctype)==") == 0;
1031             }
1032         }
1033       if (resolved && format)
1034         {
1035           if (strncmp (idesc->name, "dep", 3) == 0
1036                    && strstr (format, "I13") != NULL)
1037             resolved = idesc->operands[1] == IA64_OPND_IMM8;
1038           else if (strncmp (idesc->name, "chk", 3) == 0
1039                    && strstr (format, "M21") != NULL)
1040             resolved = idesc->operands[0] == IA64_OPND_F2;
1041           else if (strncmp (idesc->name, "lfetch", 6) == 0)
1042             resolved = (strstr (format, "M14 M15") != NULL
1043                         && (idesc->operands[1] == IA64_OPND_R2
1044                             || idesc->operands[1] == IA64_OPND_IMM9b));
1045           else if (strncmp (idesc->name, "br.call", 7) == 0
1046                    && strstr (format, "B5") != NULL)
1047             resolved = idesc->operands[1] == IA64_OPND_B2;
1048           else if (strncmp (idesc->name, "br.call", 7) == 0
1049                    && strstr (format, "B3") != NULL)
1050             resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1051           else if (strncmp (idesc->name, "brp", 3) == 0
1052                    && strstr (format, "B7") != NULL)
1053             resolved = idesc->operands[0] == IA64_OPND_B2;
1054           else if (strcmp (ic->name, "invala") == 0)
1055             resolved = strcmp (idesc->name, ic->name) == 0;
1056           else
1057             resolved = 0;
1058         }
1059
1060       /* misc brl variations ('.cond' is optional); 
1061          plain brl matches brl.cond */
1062       if (!resolved
1063           && (strcmp (idesc->name, "brl") == 0
1064               || strncmp (idesc->name, "brl.", 4) == 0)
1065           && strcmp (ic->name, "brl.cond") == 0)
1066         {
1067           resolved = 1;
1068         }
1069
1070       /* misc br variations ('.cond' is optional) */
1071       if (!resolved 
1072           && (strcmp (idesc->name, "br") == 0
1073               || strncmp (idesc->name, "br.", 3) == 0)
1074           && strcmp (ic->name, "br.cond") == 0)
1075         {
1076           if (format)
1077             resolved = (strstr (format, "B4") != NULL
1078                         && idesc->operands[0] == IA64_OPND_B2)
1079               || (strstr (format, "B1") != NULL
1080                   && idesc->operands[0] == IA64_OPND_TGT25c);
1081           else
1082             resolved = 1;
1083         }
1084
1085       /* probe variations */
1086       if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1087         {
1088           resolved = strcmp (ic->name, "probe") == 0 
1089             && !((strstr (idesc->name, "fault") != NULL) 
1090                  ^ (format && strstr (format, "M40") != NULL));
1091         }
1092       /* mov variations */
1093       if (!resolved && is_mov)
1094         {
1095           if (plain_mov)
1096             {
1097               /* mov alias for fmerge */
1098               if (strcmp (ic->name, "fmerge") == 0)
1099                 {
1100                   resolved = idesc->operands[0] == IA64_OPND_F1
1101                     && idesc->operands[1] == IA64_OPND_F3;
1102                 }
1103               /* mov alias for adds (r3 or imm14) */
1104               else if (strcmp (ic->name, "adds") == 0)
1105                 {
1106                   resolved = (idesc->operands[0] == IA64_OPND_R1
1107                               && (idesc->operands[1] == IA64_OPND_R3
1108                                   || (idesc->operands[1] == IA64_OPND_IMM14)));
1109                 }
1110               /* mov alias for addl */
1111               else if (strcmp (ic->name, "addl") == 0)
1112                 {
1113                   resolved = idesc->operands[0] == IA64_OPND_R1
1114                     && idesc->operands[1] == IA64_OPND_IMM22;
1115                 }
1116             }
1117           /* some variants of mov and mov.[im] */
1118           if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1119             {
1120               resolved = in_iclass_mov_x (idesc, ic, format, field);
1121             }
1122         }
1123
1124       /* keep track of this so we can flag any insn classes which aren't 
1125          mapped onto at least one real insn */
1126       if (resolved)
1127         {
1128           ic->terminal_resolved = 1;
1129         }
1130     }
1131   else for (i=0;i < ic->nsubs;i++)
1132     {
1133       if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep))
1134         {
1135           int j;
1136           for (j=0;j < ic->nxsubs;j++)
1137             {
1138               if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1139                 return 0;
1140             }
1141           if (debug > 1)
1142             printf ("%s is in IC %s\n",
1143                     idesc->name, ic->name);
1144           resolved = 1;
1145           break;
1146         }
1147     }
1148   
1149   /* If it's in this IC, add the IC note (if any) to the insn */
1150   if (resolved)
1151     {
1152       if (ic->note && notep)
1153         {
1154           if (*notep && *notep != ic->note)
1155             {
1156               fprintf (stderr, "Warning: overwriting note %d with note %d"
1157                        "(IC:%s)\n",
1158                        *notep, ic->note, ic->name);
1159             }
1160           *notep = ic->note;
1161         }
1162     }
1163
1164   return resolved;
1165 }
1166
1167 \f
1168 static int
1169 lookup_regindex (const char *name, int specifier)
1170 {
1171   switch (specifier)
1172     {
1173     case IA64_RS_ARX:
1174       if (strstr (name, "[RSC]"))
1175         return 16;
1176       if (strstr (name, "[BSP]"))
1177         return 17;
1178       else if (strstr (name, "[BSPSTORE]"))
1179         return 18;
1180       else if (strstr (name, "[RNAT]"))
1181         return 19;
1182       else if (strstr (name, "[CCV]"))
1183         return 32;
1184       else if (strstr (name, "[ITC]"))
1185         return 44;
1186       else if (strstr (name, "[PFS]"))
1187         return 64;
1188       else if (strstr (name, "[LC]"))
1189         return 65;
1190       else if (strstr (name, "[EC]"))
1191         return 66;
1192       abort ();
1193     case IA64_RS_CRX:
1194       if (strstr (name, "[DCR]"))
1195         return 0;
1196       else if (strstr (name, "[ITM]"))
1197         return 1;
1198       else if (strstr (name, "[IVA]"))
1199         return 2;
1200       else if (strstr (name, "[PTA]"))
1201         return 8;
1202       else if (strstr (name, "[GPTA]"))
1203         return 9;
1204       else if (strstr (name, "[IPSR]"))
1205         return 16;
1206       else if (strstr (name, "[ISR]"))
1207         return 17;
1208       else if (strstr (name, "[IIP]"))
1209         return 19;
1210       else if (strstr (name, "[IFA]"))
1211         return 20;
1212       else if (strstr (name, "[ITIR]"))
1213         return 21;
1214       else if (strstr (name, "[IIPA]"))
1215         return 22;
1216       else if (strstr (name, "[IFS]"))
1217         return 23;
1218       else if (strstr (name, "[IIM]"))
1219         return 24;
1220       else if (strstr (name, "[IHA]"))
1221         return 25;
1222       else if (strstr (name, "[LID]"))
1223         return 64;
1224       else if (strstr (name, "[IVR]"))
1225         return 65;
1226       else if (strstr (name, "[TPR]"))
1227         return 66;
1228       else if (strstr (name, "[EOI]"))
1229         return 67;
1230       else if (strstr (name, "[ITV]"))
1231         return 72;
1232       else if (strstr (name, "[PMV]"))
1233         return 73;
1234       else if (strstr (name, "[CMCV]"))
1235         return 74;
1236       abort ();
1237     case IA64_RS_PSR:
1238       if (strstr (name, ".be"))
1239         return 1;
1240       else if (strstr (name, ".up"))
1241         return 2;
1242       else if (strstr (name, ".ac"))
1243         return 3;
1244       else if (strstr (name, ".mfl"))
1245         return 4;
1246       else if (strstr (name, ".mfh"))
1247         return 5;
1248       else if (strstr (name, ".ic"))
1249         return 13;
1250       else if (strstr (name, ".i"))
1251         return 14;
1252       else if (strstr (name, ".pk"))
1253         return 15;
1254       else if (strstr (name, ".dt"))
1255         return 17;
1256       else if (strstr (name, ".dfl"))
1257         return 18;
1258       else if (strstr (name, ".dfh"))
1259         return 19;
1260       else if (strstr (name, ".sp"))
1261         return 20;
1262       else if (strstr (name, ".pp"))
1263         return 21;
1264       else if (strstr (name, ".di"))
1265         return 22;
1266       else if (strstr (name, ".si"))
1267         return 23;
1268       else if (strstr (name, ".db"))
1269         return 24;
1270       else if (strstr (name, ".lp"))
1271         return 25;
1272       else if (strstr (name, ".tb"))
1273         return 26;
1274       else if (strstr (name, ".rt"))
1275         return 27;
1276       else if (strstr (name, ".cpl"))
1277         return 32;
1278       else if (strstr (name, ".rs"))
1279         return 34;
1280       else if (strstr (name, ".mc"))
1281         return 35;
1282       else if (strstr (name, ".it"))
1283         return 36;
1284       else if (strstr (name, ".id"))
1285         return 37;
1286       else if (strstr (name, ".da"))
1287         return 38;
1288       else if (strstr (name, ".dd"))
1289         return 39;
1290       else if (strstr (name, ".ss"))
1291         return 40;
1292       else if (strstr (name, ".ri"))
1293         return 41;
1294       else if (strstr (name, ".ed"))
1295         return 43;
1296       else if (strstr (name, ".bn"))
1297         return 44;
1298       else if (strstr (name, ".ia"))
1299         return 45;
1300       else
1301         abort ();
1302     default:
1303       break;
1304     }
1305   return REG_NONE;
1306 }
1307
1308 static int
1309 lookup_specifier (const char *name)
1310 {
1311   if (strchr (name, '%'))
1312     {
1313       if (strstr (name, "AR[K%]") != NULL)
1314         return IA64_RS_AR_K;
1315       if (strstr (name, "AR[UNAT]") != NULL)
1316         return IA64_RS_AR_UNAT;
1317       if (strstr (name, "AR%, % in 8") != NULL)
1318         return IA64_RS_AR;
1319       if (strstr (name, "AR%, % in 48") != NULL)
1320         return IA64_RS_ARb;
1321       if (strstr (name, "BR%") != NULL)
1322         return IA64_RS_BR;
1323       if (strstr (name, "CR[IRR%]") != NULL)
1324         return IA64_RS_CR_IRR;
1325       if (strstr (name, "CR[LRR%]") != NULL)
1326         return IA64_RS_CR_LRR;
1327       if (strstr (name, "CR%") != NULL)
1328         return IA64_RS_CR;
1329       if (strstr (name, "FR%, % in 0") != NULL)
1330         return IA64_RS_FR;
1331       if (strstr (name, "FR%, % in 2") != NULL)
1332         return IA64_RS_FRb;
1333       if (strstr (name, "GR%") != NULL)
1334         return IA64_RS_GR;
1335       if (strstr (name, "PR%") != NULL)
1336         return IA64_RS_PR;
1337
1338       fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
1339                name);
1340     }
1341   else if (strchr (name, '#'))
1342     {
1343       if (strstr (name, "CPUID#") != NULL)
1344         return IA64_RS_CPUID;
1345       if (strstr (name, "DBR#") != NULL)
1346         return IA64_RS_DBR;
1347       if (strstr (name, "IBR#") != NULL)
1348         return IA64_RS_IBR;
1349       if (strstr (name, "MSR#") != NULL)
1350         return IA64_RS_MSR;
1351       if (strstr (name, "PKR#") != NULL)
1352         return IA64_RS_PKR;
1353       if (strstr (name, "PMC#") != NULL)
1354         return IA64_RS_PMC;
1355       if (strstr (name, "PMD#") != NULL)
1356         return IA64_RS_PMD;
1357       if (strstr (name, "RR#") != NULL)
1358         return IA64_RS_RR;
1359       
1360       fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",
1361                name);
1362     }
1363   else if (strncmp (name, "AR[FPSR]", 8) == 0)
1364     return IA64_RS_AR_FPSR;
1365   else if (strncmp (name, "AR[", 3) == 0)
1366     return IA64_RS_ARX;
1367   else if (strncmp (name, "CR[", 3) == 0)
1368     return IA64_RS_CRX;
1369   else if (strncmp (name, "PSR.", 4) == 0)
1370     return IA64_RS_PSR;
1371   else if (strcmp (name, "InService*") == 0)
1372     return IA64_RS_INSERVICE;
1373   else if (strcmp (name, "GR0") == 0)
1374     return IA64_RS_GR0;
1375   else if (strcmp (name, "CFM") == 0)
1376     return IA64_RS_CFM;
1377   else if (strcmp (name, "PR63") == 0)
1378     return IA64_RS_PR63;
1379   else if (strcmp (name, "RSE") == 0)
1380     return IA64_RS_RSE;
1381
1382   return IA64_RS_ANY;
1383 }
1384
1385 void
1386 print_dependency_table ()
1387 {
1388   int i, j;
1389
1390   if (debug) 
1391     {
1392       for (i=0;i < iclen;i++)
1393         {
1394           if (ics[i]->is_class)
1395             {
1396               if (!ics[i]->nsubs)
1397                 {
1398                   fprintf (stderr, "Warning: IC:%s", ics[i]->name);
1399                   if (ics[i]->comment)
1400                     fprintf (stderr, "[%s]", ics[i]->comment);
1401                   fprintf (stderr, " has no terminals or sub-classes\n");
1402                 }
1403             }
1404           else 
1405             {
1406               if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1407                 {
1408                   fprintf(stderr, "Warning: no insns mapped directly to "
1409                           "terminal IC %s", ics[i]->name);
1410                   if (ics[i]->comment)
1411                     fprintf(stderr, "[%s] ", ics[i]->comment);
1412                   fprintf(stderr, "\n");
1413                 }
1414             }
1415         }
1416
1417       for (i=0;i < iclen;i++)
1418         {
1419           if (ics[i]->orphan)
1420             {
1421               mark_used (ics[i], 1);
1422               fprintf (stderr, "Warning: class %s is defined but not used\n", 
1423                        ics[i]->name);
1424             }
1425         }
1426
1427       if (debug > 1) for (i=0;i < rdepslen;i++)
1428         {  
1429           static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1430           if (rdeps[i]->total_chks == 0)
1431             {
1432               fprintf (stderr, "Warning: rsrc %s (%s) has no chks%s\n", 
1433                        rdeps[i]->name, mode_str[rdeps[i]->mode],
1434                        rdeps[i]->total_regs ? "" : " or regs");
1435             }
1436           else if (rdeps[i]->total_regs == 0)
1437             {
1438               fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n", 
1439                        rdeps[i]->name, mode_str[rdeps[i]->mode]);
1440             }
1441         }
1442     }
1443
1444   /* the dependencies themselves */
1445   printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1446   for (i=0;i < rdepslen;i++)
1447     {
1448       /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1449          resource used */ 
1450       int specifier = lookup_specifier (rdeps[i]->name);
1451       int regindex = lookup_regindex (rdeps[i]->name, specifier);
1452
1453       printf ("  { \"%s\", %d, %d, %d, %d, ",
1454               rdeps[i]->name, specifier,
1455               (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1456       if (rdeps[i]->semantics == IA64_DVS_OTHER)
1457         printf ("\"%s\", ", rdeps[i]->extra);
1458       printf("},\n");
1459     }
1460   printf ("};\n\n");
1461
1462   /* and dependency lists */
1463   for (i=0;i < dlistlen;i++)
1464     {
1465       int len = 2;
1466       printf ("static const short dep%d[] = {\n  ", i);
1467       for (j=0;j < dlists[i]->len; j++)
1468         {
1469           len += printf ("%d, ", dlists[i]->deps[j]);
1470           if (len > 75)
1471             {
1472               printf("\n  ");
1473               len = 2;
1474             }
1475         }
1476       printf ("\n};\n\n");
1477     }
1478
1479   /* and opcode dependency list */
1480   printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1481   printf ("static const struct ia64_opcode_dependency\n");
1482   printf ("op_dependencies[] = {\n");
1483   for (i=0;i < opdeplen;i++)
1484     {
1485       printf ("  { ");
1486       if (opdeps[i]->chk == -1)
1487         printf ("0, NULL, ");
1488       else 
1489         printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1490       if (opdeps[i]->reg == -1)
1491         printf ("0, NULL, ");
1492       else 
1493         printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1494       printf ("},\n");
1495     }
1496   printf ("};\n\n");
1497 }
1498
1499 \f
1500 /* Add STR to the string table. */
1501
1502 static struct string_entry *
1503 insert_string (str)
1504      char *str;
1505 {
1506   int start = 0, end = strtablen;
1507   int i, x;
1508
1509   if (strtablen == strtabtotlen)
1510     {
1511       strtabtotlen += 20;
1512       string_table = (struct string_entry **)
1513         xrealloc (string_table, 
1514                   sizeof (struct string_entry **) * strtabtotlen);
1515     }
1516
1517   if (strtablen == 0)
1518     {
1519       strtablen = 1;
1520       string_table[0] = tmalloc (struct string_entry);
1521       string_table[0]->s = xstrdup (str);
1522       string_table[0]->num = 0;
1523       return string_table[0];
1524     }
1525
1526   if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1527     {
1528       i = end;
1529     }
1530   else if (strcmp (str, string_table[0]->s) < 0)
1531     {
1532       i = 0;
1533     }
1534   else
1535     {
1536       while (1)
1537         {
1538           int c;
1539
1540           i = (start + end) / 2;
1541           c = strcmp (str, string_table[i]->s);
1542           if (c < 0)
1543             {
1544               end = i - 1;
1545             }
1546           else if (c == 0)
1547             {
1548               return string_table[i];
1549             }
1550           else
1551             {
1552               start = i + 1;
1553             }
1554           if (start > end)
1555             {
1556               break;
1557             }
1558         }
1559     }
1560   for (; i > 0 && i < strtablen; i--)
1561     {
1562       if (strcmp (str, string_table[i - 1]->s) > 0)
1563         {
1564           break;
1565         }
1566     }
1567   for (; i < strtablen; i++)
1568     {
1569       if (strcmp (str, string_table[i]->s) < 0)
1570         {
1571           break;
1572         }
1573     }
1574   for (x = strtablen - 1; x >= i; x--)
1575     {
1576       string_table[x + 1] = string_table[x];
1577       string_table[x + 1]->num = x + 1;
1578     }
1579   string_table[i] = tmalloc (struct string_entry);
1580   string_table[i]->s = xstrdup (str);
1581   string_table[i]->num = i;
1582   strtablen++;
1583   return string_table[i];
1584 }
1585 \f
1586 struct bittree *
1587 make_bittree_entry ()
1588 {
1589   struct bittree *res = tmalloc (struct bittree);
1590
1591   res->disent = NULL;
1592   res->bits[0] = NULL;
1593   res->bits[1] = NULL;
1594   res->bits[2] = NULL;
1595   res->skip_flag = 0;
1596   res->bits_to_skip = 0;
1597   return res;
1598 }
1599 \f
1600 struct disent *
1601 add_dis_table_ent (which, insn, order, completer_index)
1602      struct disent *which;
1603      int insn;
1604      int order;
1605      int completer_index;
1606 {
1607   int ci = 0;
1608   struct disent *ent;
1609
1610   if (which != NULL)
1611     {
1612       ent = which;
1613
1614       ent->nextcnt++;
1615       while (ent->nexte != NULL)
1616         {
1617           ent = ent->nexte;
1618         }
1619       ent = (ent->nexte = tmalloc (struct disent));
1620     }
1621   else
1622     {
1623       ent = tmalloc (struct disent);
1624       ent->next_ent = disinsntable;
1625       disinsntable = ent;
1626       which = ent;
1627     }
1628   ent->nextcnt = 0;
1629   ent->nexte = NULL;
1630   ent->insn = insn;
1631   ent->priority = order;
1632
1633   while (completer_index != 1)
1634     {
1635       ci = (ci << 1) | (completer_index & 1);
1636       completer_index >>= 1;
1637     }
1638   ent->completer_index = ci;
1639   return which;
1640 }
1641 \f
1642 void
1643 finish_distable ()
1644 {
1645   struct disent *ent = disinsntable;
1646   struct disent *prev = ent;
1647
1648   ent->ournum = 32768;
1649   while ((ent = ent->next_ent) != NULL)
1650     {
1651       ent->ournum = prev->ournum + prev->nextcnt + 1;
1652       prev = ent;
1653     }
1654 }
1655 \f
1656 void
1657 insert_bit_table_ent (curr_ent, bit, opcode, mask, 
1658                       opcodenum, order, completer_index)
1659      struct bittree *curr_ent;
1660      int bit;
1661      ia64_insn opcode; 
1662      ia64_insn mask;
1663      int opcodenum;
1664      int order;
1665      int completer_index;
1666 {
1667   ia64_insn m;
1668   int b;
1669   struct bittree *next;
1670
1671   if (bit == -1)
1672     {
1673       struct disent *nent = add_dis_table_ent (curr_ent->disent, 
1674                                                opcodenum, order,
1675                                                completer_index);
1676       curr_ent->disent = nent;
1677       return;
1678     }
1679
1680   m = ((ia64_insn) 1) << bit;
1681
1682   if (mask & m)
1683     {
1684       b = (opcode & m) ? 1 : 0;
1685     }
1686   else
1687     {
1688       b = 2;
1689     }
1690   next = curr_ent->bits[b];
1691   if (next == NULL)
1692     {
1693       next = make_bittree_entry ();
1694       curr_ent->bits[b] = next;
1695     }
1696   insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1697                         completer_index);
1698 }
1699 \f
1700 void
1701 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1702      struct bittree *first;
1703      ia64_insn opcode;
1704      ia64_insn mask;
1705      int opcodenum;
1706      struct completer_entry *ent;
1707      int completer_index;
1708 {
1709   if (completer_index & (1 << 20))
1710     {
1711       abort ();
1712     }
1713
1714   while (ent != NULL)
1715     {
1716       ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1717       add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1718                      (completer_index << 1) | 1);
1719       if (ent->is_terminal)
1720         {
1721           insert_bit_table_ent (bittree, 40, newopcode, mask, 
1722                                 opcodenum, opcode_count - ent->order - 1, 
1723                                 (completer_index << 1) | 1);
1724         }
1725       completer_index <<= 1;
1726       ent = ent->alternative;
1727     }
1728 }
1729 \f
1730 /* This optimization pass combines multiple "don't care" nodes. */
1731 void
1732 compact_distree (ent)
1733      struct bittree *ent;
1734 {
1735 #define IS_SKIP(ent) \
1736     ((ent->bits[2] !=NULL) \
1737      && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1738
1739   int bitcnt = 0;
1740   struct bittree *nent = ent;
1741   int x;
1742
1743   while (IS_SKIP (nent))
1744     {
1745       bitcnt++;
1746       nent = nent->bits[2];
1747     }
1748
1749   if (bitcnt)
1750     {
1751       struct bittree *next = ent->bits[2];
1752
1753       ent->bits[0] = nent->bits[0];
1754       ent->bits[1] = nent->bits[1];
1755       ent->bits[2] = nent->bits[2];
1756       ent->disent = nent->disent;
1757       ent->skip_flag = 1;
1758       ent->bits_to_skip = bitcnt;
1759       while (next != nent)
1760         {
1761           struct bittree *b = next;
1762           next = next->bits[2];
1763           free (b);
1764         }
1765       free (nent);
1766     }
1767
1768   for (x = 0; x < 3; x++)
1769     {
1770       struct bittree *i = ent->bits[x];
1771       if (i != NULL)
1772         {
1773           compact_distree (i);
1774         }
1775     }
1776 }
1777 \f
1778 static unsigned char *insn_list;
1779 static int insn_list_len = 0;
1780 static int tot_insn_list_len = 0;
1781
1782 /* Generate the disassembler state machine corresponding to the tree
1783    in ENT.  */
1784 void
1785 gen_dis_table (ent)
1786      struct bittree *ent;
1787 {
1788   int x;
1789   int our_offset = insn_list_len;
1790   int bitsused = 5;
1791   int totbits = bitsused;
1792   int needed_bytes;
1793   int zero_count = 0;
1794   int zero_dest = 0;    /* initialize this with 0 to keep gcc quiet... */
1795
1796   /* If this is a terminal entry, there's no point in skipping any
1797      bits. */
1798   if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1799       ent->bits[2] == NULL)
1800     {
1801       if (ent->disent == NULL)
1802         {
1803           abort ();
1804         }
1805       else
1806         {
1807           ent->skip_flag = 0;
1808         }
1809     }
1810
1811   /* Calculate the amount of space needed for this entry, or at least
1812      a conservatively large approximation. */
1813   if (ent->skip_flag)
1814     {
1815       totbits += 5;
1816     }
1817   for (x = 1; x < 3; x++)
1818     {
1819       if (ent->bits[x] != NULL)
1820         {
1821           totbits += 16;
1822         }
1823     }
1824
1825   if (ent->disent != NULL)
1826     {
1827       if (ent->bits[2] != NULL)
1828         {
1829           abort ();
1830         }
1831       totbits += 16;
1832     }
1833
1834   /* Now allocate the space. */
1835   needed_bytes = (totbits + 7) / 8;
1836   if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1837     {
1838       tot_insn_list_len += 256;
1839       insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1840     }
1841   our_offset = insn_list_len;
1842   insn_list_len += needed_bytes;
1843   memset (insn_list + our_offset, 0, needed_bytes);
1844
1845   /* Encode the skip entry by setting bit 6 set in the state op field,
1846      and store the # of bits to skip immediately after. */
1847   if (ent->skip_flag)
1848     {
1849       bitsused += 5;
1850       insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1851       insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1852     }
1853
1854 #define IS_ONLY_IFZERO(ENT) \
1855   ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1856    && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1857
1858   /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1859      state op field. */
1860
1861   if (ent->bits[0] != NULL)
1862     {
1863       struct bittree *nent = ent->bits[0];
1864       zero_count = 0;
1865
1866       insn_list[our_offset] |= 0x80;
1867
1868       /* We can encode sequences of multiple "if (bit is zero)" tests
1869          by storing the # of zero bits to check in the lower 3 bits of
1870          the instruction.  However, this only applies if the state
1871          solely tests for a zero bit.  */
1872
1873       if (IS_ONLY_IFZERO (ent))
1874         {
1875           while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1876             {
1877               nent = nent->bits[0];
1878               zero_count++;
1879             }
1880
1881           insn_list[our_offset + 0] |= zero_count;
1882         }
1883       zero_dest = insn_list_len;
1884       gen_dis_table (nent);
1885     }
1886
1887   /* Now store the remaining tests.  We also handle a sole "termination
1888      entry" by storing it as an "any bit" test.  */
1889
1890   for (x = 1; x < 3; x++)
1891     {
1892       if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1893         {
1894           struct bittree *i = ent->bits[x];
1895           int idest;
1896           int currbits = 15;
1897
1898           if (i != NULL)
1899             {
1900               /* If the instruction being branched to only consists of
1901                  a termination entry, use the termination entry as the
1902                  place to branch to instead.  */
1903               if (i->bits[0] == NULL && i->bits[1] == NULL
1904                   && i->bits[2] == NULL && i->disent != NULL)
1905                 {
1906                   idest = i->disent->ournum;
1907                   i = NULL;
1908                 }
1909               else
1910                 {
1911                   idest = insn_list_len - our_offset;
1912                 }
1913             }
1914           else
1915             {
1916               idest = ent->disent->ournum;
1917             }
1918
1919           /* If the destination offset for the if (bit is 1) test is less 
1920              than 256 bytes away, we can store it as 8-bits instead of 16;
1921              the instruction has bit 5 set for the 16-bit address, and bit
1922              4 for the 8-bit address.  Since we've already allocated 16
1923              bits for the address we need to deallocate the space.
1924
1925              Note that branchings within the table are relative, and
1926              there are no branches that branch past our instruction yet
1927              so we do not need to adjust any other offsets. */
1928
1929           if (x == 1)
1930             {
1931               if (idest <= 256)
1932                 {
1933                   int start = our_offset + bitsused / 8 + 1;
1934
1935                   memmove (insn_list + start,
1936                            insn_list + start + 1,
1937                            insn_list_len - (start + 1));
1938                   currbits = 7;
1939                   totbits -= 8;
1940                   needed_bytes--;
1941                   insn_list_len--;
1942                   insn_list[our_offset] |= 0x10;
1943                   idest--;
1944                 }
1945               else
1946                 {
1947                   insn_list[our_offset] |= 0x20;
1948                 }
1949             }
1950           else
1951             {
1952               /* An instruction which solely consists of a termination
1953                  marker and whose disassembly name index is < 4096
1954                  can be stored in 16 bits.  The encoding is slightly
1955                  odd; the upper 4 bits of the instruction are 0x3, and
1956                  bit 3 loses its normal meaning.  */
1957
1958               if (ent->bits[0] == NULL && ent->bits[1] == NULL
1959                   && ent->bits[2] == NULL && ent->skip_flag == 0
1960                   && ent->disent != NULL
1961                   && ent->disent->ournum < (32768 + 4096))
1962                 {
1963                   int start = our_offset + bitsused / 8 + 1;
1964
1965                   memmove (insn_list + start,
1966                            insn_list + start + 1,
1967                            insn_list_len - (start + 1));
1968                   currbits = 11;
1969                   totbits -= 5;
1970                   bitsused--;
1971                   needed_bytes--;
1972                   insn_list_len--;
1973                   insn_list[our_offset] |= 0x30;
1974                   idest &= ~32768;
1975                 }
1976               else
1977                 {
1978                   insn_list[our_offset] |= 0x08;
1979                 }
1980             }
1981           if (debug)
1982             {
1983               int id = idest;
1984
1985               if (i == NULL)
1986                 {
1987                   id |= 32768;
1988                 }
1989               else if (! (id & 32768))
1990                 {
1991                   id += our_offset;
1992                 }
1993               if (x == 1)
1994                 {
1995                   printf ("%d: if (1) goto %d\n", our_offset, id);
1996                 }
1997               else
1998                 {
1999                   printf ("%d: try %d\n", our_offset, id);
2000                 }
2001             }
2002
2003           /* Store the address of the entry being branched to. */
2004           while (currbits >= 0)
2005             {
2006               char *byte = insn_list + our_offset + bitsused / 8;
2007
2008               if (idest & (1 << currbits))
2009                 {
2010                   *byte |= (1 << (7 - (bitsused % 8)));
2011                 }
2012               bitsused++;
2013               currbits--;
2014             }
2015
2016           /* Now generate the states for the entry being branched to. */
2017           if (i != NULL)
2018             {
2019               gen_dis_table (i);
2020             }
2021
2022         }
2023     }
2024   if (debug)
2025     {
2026       if (ent->skip_flag)
2027         {
2028           printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2029         }
2030   
2031       if (ent->bits[0] != NULL)
2032         {
2033           printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2034                   zero_dest);
2035         }
2036     }
2037   if (bitsused != totbits)
2038     {
2039       abort ();
2040     }
2041 }
2042 \f
2043 void
2044 print_dis_table ()
2045 {
2046   int x;
2047   struct disent *cent = disinsntable;
2048
2049   printf ("static const char dis_table[] = {\n");
2050   for (x = 0; x < insn_list_len; x++)
2051     {
2052       if ((x > 0) && ((x % 12) == 0))
2053         {
2054           printf ("\n");
2055         }
2056       printf ("0x%02x, ", insn_list[x]);
2057     }
2058   printf ("\n};\n\n");
2059
2060   printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2061   while (cent != NULL)
2062     {
2063       struct disent *ent = cent;
2064
2065       while (ent != NULL)
2066         {
2067           printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2068                   ent->insn, (ent->nexte != NULL ? 1 : 0),
2069                   ent->priority);
2070           ent = ent->nexte;
2071         }
2072       cent = cent->next_ent;
2073     }
2074   printf ("};\n\n");
2075 }
2076 \f
2077 void
2078 generate_disassembler ()
2079 {
2080   int i;
2081
2082   bittree = make_bittree_entry ();
2083
2084   for (i=0; i < otlen;i++)
2085     {
2086       struct main_entry *ptr = ordered_table[i];
2087
2088       if (ptr->opcode->type != IA64_TYPE_DYN)
2089         {
2090           add_dis_entry (bittree,
2091                          ptr->opcode->opcode, ptr->opcode->mask, 
2092                          ptr->main_index,
2093                          ptr->completers, 1);
2094         }
2095     }
2096
2097   compact_distree (bittree);
2098   finish_distable ();
2099   gen_dis_table (bittree);
2100
2101   print_dis_table ();
2102 }
2103 \f
2104 void
2105 print_string_table ()
2106 {
2107   int x;
2108   char lbuf[80], buf[80];
2109   int blen = 0;
2110
2111   printf ("static const char *ia64_strings[] = {\n");
2112   lbuf[0] = '\0';
2113   for (x = 0; x < strtablen; x++)
2114     {
2115       int len;
2116       
2117       if (strlen (string_table[x]->s) > 75)
2118         {
2119           abort ();
2120         }
2121       sprintf (buf, " \"%s\",", string_table[x]->s);
2122       len = strlen (buf);
2123       if ((blen + len) > 75)
2124         {
2125           printf (" %s\n", lbuf);
2126           lbuf[0] = '\0';
2127           blen = 0;
2128         }
2129       strcat (lbuf, buf);
2130       blen += len;
2131     }
2132   if (blen > 0)
2133     {
2134       printf (" %s\n", lbuf);
2135     }
2136   printf ("};\n\n");
2137 }
2138 \f
2139 static struct completer_entry **glist;
2140 static int glistlen = 0;
2141 static int glisttotlen = 0;
2142
2143 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2144
2145 int
2146 completer_entries_eq (ent1, ent2)
2147      struct completer_entry *ent1, *ent2;
2148 {
2149   while (ent1 != NULL && ent2 != NULL)
2150     {
2151       if (ent1->name->num != ent2->name->num
2152           || ent1->bits != ent2->bits
2153           || ent1->mask != ent2->mask
2154           || ent1->is_terminal != ent2->is_terminal
2155           || ent1->dependencies != ent2->dependencies
2156           || ent1->order != ent2->order)
2157         {
2158           return 0;
2159         }
2160       if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2161         {
2162           return 0;
2163         }
2164       ent1 = ent1->alternative;
2165       ent2 = ent2->alternative;
2166     }
2167   return ent1 == ent2;
2168 }
2169 \f
2170 /* Insert ENT into the global list of completers and return it.  If an
2171    equivalent entry (according to completer_entries_eq) already exists,
2172    it is returned instead. */
2173 struct completer_entry *
2174 insert_gclist (ent)
2175      struct completer_entry *ent;
2176 {
2177   if (ent != NULL)
2178     {
2179       int i;
2180       int x;
2181       int start = 0, end;
2182
2183       ent->addl_entries = insert_gclist (ent->addl_entries);
2184       ent->alternative = insert_gclist (ent->alternative);
2185
2186       i = glistlen / 2;
2187       end = glistlen;
2188
2189       if (glisttotlen == glistlen)
2190         {
2191           glisttotlen += 20;
2192           glist = (struct completer_entry **)
2193             xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2194         }
2195
2196       if (glistlen == 0)
2197         {
2198           glist[0] = ent;
2199           glistlen = 1;
2200           return ent;
2201         }
2202
2203       if (ent->name->num < glist[0]->name->num)
2204         {
2205           i = 0;
2206         }
2207       else if (ent->name->num > glist[end - 1]->name->num)
2208         {
2209           i = end;
2210         }
2211       else
2212         {
2213           int c;
2214
2215           while (1)
2216             {
2217               i = (start + end) / 2;
2218               c = ent->name->num - glist[i]->name->num;
2219               if (c < 0)
2220                 {
2221                   end = i - 1;
2222                 }
2223               else if (c == 0)
2224                 {
2225                   while (i > 0 
2226                          && ent->name->num == glist[i - 1]->name->num)
2227                     {
2228                       i--;
2229                     }
2230                   break;
2231                 }
2232               else
2233                 {
2234                   start = i + 1;
2235                 }
2236               if (start > end)
2237                 {
2238                   break;
2239                 }
2240             }
2241           if (c == 0)
2242             {
2243               while (i < glistlen)
2244                 {
2245                   if (ent->name->num != glist[i]->name->num)
2246                     {
2247                       break;
2248                     }
2249                   if (completer_entries_eq (ent, glist[i]))
2250                     {
2251                       return glist[i];
2252                     }
2253                   i++;
2254                 }
2255             }
2256         }
2257       for (; i > 0 && i < glistlen; i--)
2258         {
2259           if (ent->name->num >= glist[i - 1]->name->num)
2260             {
2261               break;
2262             }
2263         }
2264       for (; i < glistlen; i++)
2265         {
2266           if (ent->name->num < glist[i]->name->num)
2267             {
2268               break;
2269             }
2270         }
2271       for (x = glistlen - 1; x >= i; x--)
2272         {
2273           glist[x + 1] = glist[x];
2274         }
2275       glist[i] = ent;
2276       glistlen++;
2277     }
2278   return ent;
2279 }
2280 \f
2281 static int
2282 get_prefix_len (name)
2283      const char *name;
2284 {
2285   char *c;
2286
2287   if (name[0] == '\0')
2288     {
2289       return 0;
2290     }
2291
2292   c = strchr (name, '.');
2293   if (c != NULL)
2294     {
2295       return c - name;
2296     }
2297   else
2298     {
2299       return strlen (name);
2300     }
2301 }
2302 \f
2303 static void
2304 compute_completer_bits (ment, ent)
2305      struct main_entry *ment;
2306      struct completer_entry *ent;
2307 {
2308   while (ent != NULL)
2309     {
2310       compute_completer_bits (ment, ent->addl_entries);
2311
2312       if (ent->is_terminal)
2313         {
2314           ia64_insn mask = 0;
2315           ia64_insn our_bits = ent->bits;
2316           struct completer_entry *p = ent->parent;
2317           ia64_insn p_bits;
2318           int x;
2319
2320           while (p != NULL && ! p->is_terminal)
2321             {
2322               p = p->parent;
2323             }
2324       
2325           if (p != NULL)
2326             {
2327               p_bits = p->bits;
2328             }
2329           else
2330             {
2331               p_bits = ment->opcode->opcode;
2332             }
2333
2334           for (x = 0; x < 64; x++)
2335             {
2336               ia64_insn m = ((ia64_insn) 1) << x;
2337               if ((p_bits & m) != (our_bits & m))
2338                 {
2339                   mask |= m;
2340                 }
2341               else
2342                 {
2343                   our_bits &= ~m;
2344                 }
2345             }
2346           ent->bits = our_bits;
2347           ent->mask = mask;
2348         }
2349       else
2350         {
2351           ent->bits = 0;
2352           ent->mask = 0;
2353         }
2354
2355       ent = ent->alternative;
2356     }
2357 }
2358 \f
2359 /* Find identical completer trees that are used in different
2360    instructions and collapse their entries. */
2361 void
2362 collapse_redundant_completers ()
2363 {
2364   struct main_entry *ptr;
2365   int x;
2366
2367   for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2368     {
2369       if (ptr->completers == NULL)
2370         {
2371           abort ();
2372         }
2373       compute_completer_bits (ptr, ptr->completers);
2374       ptr->completers = insert_gclist (ptr->completers);
2375     }
2376
2377   /* The table has been finalized, now number the indexes.  */
2378   for (x = 0; x < glistlen; x++)
2379     {
2380       glist[x]->num = x;
2381     }
2382 }
2383 \f
2384
2385 /* attach two lists of dependencies to each opcode.
2386    1) all resources which, when already marked in use, conflict with this
2387    opcode (chks) 
2388    2) all resources which must be marked in use when this opcode is used
2389    (regs) 
2390 */
2391 int
2392 insert_opcode_dependencies (opc, cmp)
2393      struct ia64_opcode *opc;
2394      struct completer_entry *cmp;
2395 {
2396   /* note all resources which point to this opcode.  rfi has the most chks
2397      (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2398   int i;
2399   int nregs = 0;
2400   unsigned short regs[256];                  
2401   int nchks = 0;
2402   unsigned short chks[256];
2403   /* flag insns for which no class matched; there should be none */
2404   int no_class_found = 1;
2405
2406   for (i=0;i < rdepslen;i++)
2407     {
2408       struct rdep *rs = rdeps[i];
2409       int j;
2410
2411       if (strcmp (opc->name, "cmp.eq.and") == 0
2412           && strncmp (rs->name, "PR%", 3) == 0
2413           && rs->mode == 1)
2414         no_class_found = 99;
2415
2416       for (j=0; j < rs->nregs;j++)
2417         {
2418           int ic_note = 0;
2419
2420           if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2421             {
2422               /* We can ignore ic_note 11 for non PR resources */
2423               if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2424                 ic_note = 0;
2425
2426               if (ic_note != 0 && rs->regnotes[j] != 0
2427                   && ic_note != rs->regnotes[j]
2428                   && !(ic_note == 11 && rs->regnotes[j] == 1))
2429                 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2430                          " conflicts with resource %s note %d\n", 
2431                          ic_note, opc->name, ics[rs->regs[j]]->name,
2432                          rs->name, rs->regnotes[j]);
2433               /* Instruction class notes override resource notes.
2434                  So far, only note 11 applies to an IC instead of a resource,
2435                  and note 11 implies note 1.
2436                */
2437               if (ic_note)
2438                 regs[nregs++] = RDEP(ic_note, i);
2439               else
2440                 regs[nregs++] = RDEP(rs->regnotes[j], i);
2441               no_class_found = 0;
2442               ++rs->total_regs;
2443             }
2444         }
2445       for (j=0;j < rs->nchks;j++)
2446         {
2447           int ic_note = 0;
2448
2449           if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2450             {
2451               /* We can ignore ic_note 11 for non PR resources */
2452               if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2453                 ic_note = 0;
2454
2455               if (ic_note != 0 && rs->chknotes[j] != 0
2456                   && ic_note != rs->chknotes[j]
2457                   && !(ic_note == 11 && rs->chknotes[j] == 1))
2458                 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2459                          " conflicts with resource %s note %d\n", 
2460                          ic_note, opc->name, ics[rs->chks[j]]->name,
2461                          rs->name, rs->chknotes[j]);
2462               if (ic_note)
2463                 chks[nchks++] = RDEP(ic_note, i);
2464               else
2465                 chks[nchks++] = RDEP(rs->chknotes[j], i);
2466               no_class_found = 0;
2467               ++rs->total_chks;
2468             }
2469         }
2470     }
2471
2472   if (no_class_found)
2473     fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n", 
2474              opc->name, 
2475              opc->operands[0], opc->operands[1], opc->operands[2]);
2476
2477   return insert_dependencies (nchks, chks, nregs, regs);
2478 }
2479 \f
2480 void
2481 insert_completer_entry (opc, tabent, order)
2482      struct ia64_opcode *opc;
2483      struct main_entry *tabent;
2484      int order;
2485 {
2486   struct completer_entry **ptr = &tabent->completers;
2487   struct completer_entry *parent = NULL;
2488   char pcopy[129], *prefix;
2489   int at_end = 0;
2490
2491   if (strlen (opc->name) > 128)
2492     {
2493       abort ();
2494     }
2495   strcpy (pcopy, opc->name);
2496   prefix = pcopy + get_prefix_len (pcopy);
2497   if (prefix[0] != '\0')
2498     {
2499       prefix++;
2500     }
2501
2502   while (! at_end)
2503     {
2504       int need_new_ent = 1;
2505       int plen = get_prefix_len (prefix);
2506       struct string_entry *sent;
2507
2508       at_end = (prefix[plen] == '\0');
2509       prefix[plen] = '\0';
2510       sent = insert_string (prefix);
2511
2512       while (*ptr != NULL)
2513         {
2514           int cmpres = sent->num - (*ptr)->name->num;
2515
2516           if (cmpres == 0)
2517             {
2518               need_new_ent = 0;
2519               break;
2520             }
2521           else
2522             {
2523               ptr = &((*ptr)->alternative);
2524             }
2525         }
2526       if (need_new_ent)
2527         {
2528           struct completer_entry *nent = tmalloc (struct completer_entry);
2529           nent->name = sent;
2530           nent->parent = parent;
2531           nent->addl_entries = NULL;
2532           nent->alternative = *ptr;
2533           *ptr = nent;
2534           nent->is_terminal = 0;
2535           nent->dependencies = -1;
2536         }
2537
2538       if (! at_end)
2539         {
2540           parent = *ptr;
2541           ptr = &((*ptr)->addl_entries);
2542           prefix += plen + 1;
2543         }
2544     }
2545
2546   if ((*ptr)->is_terminal)
2547     {
2548       abort ();
2549     }
2550
2551   (*ptr)->is_terminal = 1;
2552   (*ptr)->mask = (ia64_insn)-1;
2553   (*ptr)->bits = opc->opcode;
2554   (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2555   (*ptr)->order = order;
2556 }
2557 \f
2558 void
2559 print_completer_entry (ent)
2560      struct completer_entry *ent;
2561 {
2562   int moffset = 0;
2563   ia64_insn mask = ent->mask, bits = ent->bits;
2564
2565   if (mask != 0)
2566     {
2567       while (! (mask & 1))
2568         {
2569           moffset++;
2570           mask = mask >> 1;
2571           bits = bits >> 1;
2572         }
2573       if (bits & 0xffffffff00000000LL)
2574         {
2575           abort ();
2576         }
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 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     {
2598       print_completer_entry (glist[x]);
2599     }
2600   printf ("};\n\n");
2601 }
2602 \f
2603 int
2604 opcodes_eq (opc1, opc2)
2605      struct ia64_opcode *opc1;
2606      struct ia64_opcode *opc2;
2607 {
2608   int x;
2609   int plen1, plen2;
2610
2611   if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 
2612       || (opc1->num_outputs != opc2->num_outputs)
2613       || (opc1->flags != opc2->flags))
2614     {
2615       return 0;
2616     }
2617   for (x = 0; x < 5; x++)
2618     {
2619       if (opc1->operands[x] != opc2->operands[x])
2620         {
2621           return 0;
2622         }
2623     }
2624   plen1 = get_prefix_len (opc1->name);
2625   plen2 = get_prefix_len (opc2->name);
2626   if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2627     {
2628       return 1;
2629     }
2630   return 0;
2631 }
2632 \f
2633 void
2634 add_opcode_entry (opc)
2635      struct ia64_opcode *opc;
2636 {
2637   struct main_entry **place;
2638   struct string_entry *name;
2639   char prefix[129];
2640   int found_it = 0;
2641
2642   if (strlen (opc->name) > 128)
2643     {
2644       abort ();
2645     }
2646   place = &maintable;
2647   strcpy (prefix, opc->name);
2648   prefix[get_prefix_len (prefix)] = '\0';
2649   name = insert_string (prefix);
2650
2651   /* Walk the list of opcode table entries.  If it's a new
2652      instruction, allocate and fill in a new entry.  Note 
2653      the main table is alphabetical by opcode name. */
2654
2655   while (*place != NULL)
2656     {
2657       if ((*place)->name->num == name->num
2658           && opcodes_eq ((*place)->opcode, opc))
2659         {
2660           found_it = 1;
2661           break;
2662         }
2663       if ((*place)->name->num > name->num)
2664         {
2665           break;
2666         }
2667       place = &((*place)->next);
2668     }
2669   if (! found_it)
2670     {
2671       struct main_entry *nent = tmalloc (struct main_entry);
2672
2673       nent->name = name;
2674       nent->opcode = opc;
2675       nent->next = *place;
2676       nent->completers = 0;
2677       *place = nent;
2678
2679       if (otlen == ottotlen)
2680         {
2681           ottotlen += 20;
2682           ordered_table = (struct main_entry **)
2683             xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2684         }
2685       ordered_table[otlen++] = nent;
2686     }
2687
2688   insert_completer_entry (opc, *place, opcode_count++);
2689 }
2690 \f
2691 void
2692 print_main_table ()
2693 {
2694   struct main_entry *ptr = maintable;
2695   int index = 0;
2696
2697   printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2698   while (ptr != NULL)
2699     {
2700       printf ("  { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2701               ptr->name->num,
2702               ptr->opcode->type,
2703               ptr->opcode->num_outputs,
2704               ptr->opcode->opcode,
2705               ptr->opcode->mask,
2706               ptr->opcode->operands[0],
2707               ptr->opcode->operands[1],
2708               ptr->opcode->operands[2],
2709               ptr->opcode->operands[3],
2710               ptr->opcode->operands[4],
2711               ptr->opcode->flags,
2712               ptr->completers->num);
2713
2714       ptr->main_index = index++;
2715
2716       ptr = ptr->next;
2717     }
2718   printf ("};\n\n");
2719 }
2720 \f
2721 void
2722 shrink (table)
2723      struct ia64_opcode *table;
2724 {
2725   int curr_opcode;
2726
2727   for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2728     {
2729       add_opcode_entry (table + curr_opcode);
2730     }
2731 }
2732 \f
2733 int
2734 main (int argc, char **argv)
2735 {
2736   if (argc > 1)
2737     {
2738       debug = 1;
2739     }
2740
2741   load_insn_classes();
2742   load_dependencies();
2743
2744   shrink (ia64_opcodes_a);
2745   shrink (ia64_opcodes_b);
2746   shrink (ia64_opcodes_f);
2747   shrink (ia64_opcodes_i);
2748   shrink (ia64_opcodes_m);
2749   shrink (ia64_opcodes_x);
2750   shrink (ia64_opcodes_d);
2751
2752   collapse_redundant_completers ();
2753
2754   printf ("/* This file is automatically generated by ia64-gen.  Do not edit! */\n");
2755   print_string_table ();
2756   print_dependency_table ();
2757   print_completer_table ();
2758   print_main_table ();
2759
2760   generate_disassembler ();
2761
2762   exit (0);
2763 }