OSDN Git Service

Fix typos in ChangeLogs; fix dates in copyright notices
[pf3gnuchains/pf3gnuchains3x.git] / opcodes / ia64-gen.c
1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2    Copyright 1999, 2000 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 < (int)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 < (int)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       else
1463         printf ("NULL, ");
1464       printf("},\n");
1465     }
1466   printf ("};\n\n");
1467
1468   /* and dependency lists */
1469   for (i=0;i < dlistlen;i++)
1470     {
1471       int len = 2;
1472       printf ("static const short dep%d[] = {\n  ", i);
1473       for (j=0;j < dlists[i]->len; j++)
1474         {
1475           len += printf ("%d, ", dlists[i]->deps[j]);
1476           if (len > 75)
1477             {
1478               printf("\n  ");
1479               len = 2;
1480             }
1481         }
1482       printf ("\n};\n\n");
1483     }
1484
1485   /* and opcode dependency list */
1486   printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1487   printf ("static const struct ia64_opcode_dependency\n");
1488   printf ("op_dependencies[] = {\n");
1489   for (i=0;i < opdeplen;i++)
1490     {
1491       printf ("  { ");
1492       if (opdeps[i]->chk == -1)
1493         printf ("0, NULL, ");
1494       else 
1495         printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1496       if (opdeps[i]->reg == -1)
1497         printf ("0, NULL, ");
1498       else 
1499         printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1500       printf ("},\n");
1501     }
1502   printf ("};\n\n");
1503 }
1504
1505 \f
1506 /* Add STR to the string table. */
1507
1508 static struct string_entry *
1509 insert_string (str)
1510      char *str;
1511 {
1512   int start = 0, end = strtablen;
1513   int i, x;
1514
1515   if (strtablen == strtabtotlen)
1516     {
1517       strtabtotlen += 20;
1518       string_table = (struct string_entry **)
1519         xrealloc (string_table, 
1520                   sizeof (struct string_entry **) * strtabtotlen);
1521     }
1522
1523   if (strtablen == 0)
1524     {
1525       strtablen = 1;
1526       string_table[0] = tmalloc (struct string_entry);
1527       string_table[0]->s = xstrdup (str);
1528       string_table[0]->num = 0;
1529       return string_table[0];
1530     }
1531
1532   if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1533     {
1534       i = end;
1535     }
1536   else if (strcmp (str, string_table[0]->s) < 0)
1537     {
1538       i = 0;
1539     }
1540   else
1541     {
1542       while (1)
1543         {
1544           int c;
1545
1546           i = (start + end) / 2;
1547           c = strcmp (str, string_table[i]->s);
1548           if (c < 0)
1549             {
1550               end = i - 1;
1551             }
1552           else if (c == 0)
1553             {
1554               return string_table[i];
1555             }
1556           else
1557             {
1558               start = i + 1;
1559             }
1560           if (start > end)
1561             {
1562               break;
1563             }
1564         }
1565     }
1566   for (; i > 0 && i < strtablen; i--)
1567     {
1568       if (strcmp (str, string_table[i - 1]->s) > 0)
1569         {
1570           break;
1571         }
1572     }
1573   for (; i < strtablen; i++)
1574     {
1575       if (strcmp (str, string_table[i]->s) < 0)
1576         {
1577           break;
1578         }
1579     }
1580   for (x = strtablen - 1; x >= i; x--)
1581     {
1582       string_table[x + 1] = string_table[x];
1583       string_table[x + 1]->num = x + 1;
1584     }
1585   string_table[i] = tmalloc (struct string_entry);
1586   string_table[i]->s = xstrdup (str);
1587   string_table[i]->num = i;
1588   strtablen++;
1589   return string_table[i];
1590 }
1591 \f
1592 struct bittree *
1593 make_bittree_entry ()
1594 {
1595   struct bittree *res = tmalloc (struct bittree);
1596
1597   res->disent = NULL;
1598   res->bits[0] = NULL;
1599   res->bits[1] = NULL;
1600   res->bits[2] = NULL;
1601   res->skip_flag = 0;
1602   res->bits_to_skip = 0;
1603   return res;
1604 }
1605 \f
1606 struct disent *
1607 add_dis_table_ent (which, insn, order, completer_index)
1608      struct disent *which;
1609      int insn;
1610      int order;
1611      int completer_index;
1612 {
1613   int ci = 0;
1614   struct disent *ent;
1615
1616   if (which != NULL)
1617     {
1618       ent = which;
1619
1620       ent->nextcnt++;
1621       while (ent->nexte != NULL)
1622         {
1623           ent = ent->nexte;
1624         }
1625       ent = (ent->nexte = tmalloc (struct disent));
1626     }
1627   else
1628     {
1629       ent = tmalloc (struct disent);
1630       ent->next_ent = disinsntable;
1631       disinsntable = ent;
1632       which = ent;
1633     }
1634   ent->nextcnt = 0;
1635   ent->nexte = NULL;
1636   ent->insn = insn;
1637   ent->priority = order;
1638
1639   while (completer_index != 1)
1640     {
1641       ci = (ci << 1) | (completer_index & 1);
1642       completer_index >>= 1;
1643     }
1644   ent->completer_index = ci;
1645   return which;
1646 }
1647 \f
1648 void
1649 finish_distable ()
1650 {
1651   struct disent *ent = disinsntable;
1652   struct disent *prev = ent;
1653
1654   ent->ournum = 32768;
1655   while ((ent = ent->next_ent) != NULL)
1656     {
1657       ent->ournum = prev->ournum + prev->nextcnt + 1;
1658       prev = ent;
1659     }
1660 }
1661 \f
1662 void
1663 insert_bit_table_ent (curr_ent, bit, opcode, mask, 
1664                       opcodenum, order, completer_index)
1665      struct bittree *curr_ent;
1666      int bit;
1667      ia64_insn opcode; 
1668      ia64_insn mask;
1669      int opcodenum;
1670      int order;
1671      int completer_index;
1672 {
1673   ia64_insn m;
1674   int b;
1675   struct bittree *next;
1676
1677   if (bit == -1)
1678     {
1679       struct disent *nent = add_dis_table_ent (curr_ent->disent, 
1680                                                opcodenum, order,
1681                                                completer_index);
1682       curr_ent->disent = nent;
1683       return;
1684     }
1685
1686   m = ((ia64_insn) 1) << bit;
1687
1688   if (mask & m)
1689     {
1690       b = (opcode & m) ? 1 : 0;
1691     }
1692   else
1693     {
1694       b = 2;
1695     }
1696   next = curr_ent->bits[b];
1697   if (next == NULL)
1698     {
1699       next = make_bittree_entry ();
1700       curr_ent->bits[b] = next;
1701     }
1702   insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1703                         completer_index);
1704 }
1705 \f
1706 void
1707 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1708      struct bittree *first;
1709      ia64_insn opcode;
1710      ia64_insn mask;
1711      int opcodenum;
1712      struct completer_entry *ent;
1713      int completer_index;
1714 {
1715   if (completer_index & (1 << 20))
1716     {
1717       abort ();
1718     }
1719
1720   while (ent != NULL)
1721     {
1722       ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1723       add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1724                      (completer_index << 1) | 1);
1725       if (ent->is_terminal)
1726         {
1727           insert_bit_table_ent (bittree, 40, newopcode, mask, 
1728                                 opcodenum, opcode_count - ent->order - 1, 
1729                                 (completer_index << 1) | 1);
1730         }
1731       completer_index <<= 1;
1732       ent = ent->alternative;
1733     }
1734 }
1735 \f
1736 /* This optimization pass combines multiple "don't care" nodes. */
1737 void
1738 compact_distree (ent)
1739      struct bittree *ent;
1740 {
1741 #define IS_SKIP(ent) \
1742     ((ent->bits[2] !=NULL) \
1743      && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1744
1745   int bitcnt = 0;
1746   struct bittree *nent = ent;
1747   int x;
1748
1749   while (IS_SKIP (nent))
1750     {
1751       bitcnt++;
1752       nent = nent->bits[2];
1753     }
1754
1755   if (bitcnt)
1756     {
1757       struct bittree *next = ent->bits[2];
1758
1759       ent->bits[0] = nent->bits[0];
1760       ent->bits[1] = nent->bits[1];
1761       ent->bits[2] = nent->bits[2];
1762       ent->disent = nent->disent;
1763       ent->skip_flag = 1;
1764       ent->bits_to_skip = bitcnt;
1765       while (next != nent)
1766         {
1767           struct bittree *b = next;
1768           next = next->bits[2];
1769           free (b);
1770         }
1771       free (nent);
1772     }
1773
1774   for (x = 0; x < 3; x++)
1775     {
1776       struct bittree *i = ent->bits[x];
1777       if (i != NULL)
1778         {
1779           compact_distree (i);
1780         }
1781     }
1782 }
1783 \f
1784 static unsigned char *insn_list;
1785 static int insn_list_len = 0;
1786 static int tot_insn_list_len = 0;
1787
1788 /* Generate the disassembler state machine corresponding to the tree
1789    in ENT.  */
1790 void
1791 gen_dis_table (ent)
1792      struct bittree *ent;
1793 {
1794   int x;
1795   int our_offset = insn_list_len;
1796   int bitsused = 5;
1797   int totbits = bitsused;
1798   int needed_bytes;
1799   int zero_count = 0;
1800   int zero_dest = 0;    /* initialize this with 0 to keep gcc quiet... */
1801
1802   /* If this is a terminal entry, there's no point in skipping any
1803      bits. */
1804   if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1805       ent->bits[2] == NULL)
1806     {
1807       if (ent->disent == NULL)
1808         {
1809           abort ();
1810         }
1811       else
1812         {
1813           ent->skip_flag = 0;
1814         }
1815     }
1816
1817   /* Calculate the amount of space needed for this entry, or at least
1818      a conservatively large approximation. */
1819   if (ent->skip_flag)
1820     {
1821       totbits += 5;
1822     }
1823   for (x = 1; x < 3; x++)
1824     {
1825       if (ent->bits[x] != NULL)
1826         {
1827           totbits += 16;
1828         }
1829     }
1830
1831   if (ent->disent != NULL)
1832     {
1833       if (ent->bits[2] != NULL)
1834         {
1835           abort ();
1836         }
1837       totbits += 16;
1838     }
1839
1840   /* Now allocate the space. */
1841   needed_bytes = (totbits + 7) / 8;
1842   if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1843     {
1844       tot_insn_list_len += 256;
1845       insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1846     }
1847   our_offset = insn_list_len;
1848   insn_list_len += needed_bytes;
1849   memset (insn_list + our_offset, 0, needed_bytes);
1850
1851   /* Encode the skip entry by setting bit 6 set in the state op field,
1852      and store the # of bits to skip immediately after. */
1853   if (ent->skip_flag)
1854     {
1855       bitsused += 5;
1856       insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1857       insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1858     }
1859
1860 #define IS_ONLY_IFZERO(ENT) \
1861   ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1862    && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1863
1864   /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1865      state op field. */
1866
1867   if (ent->bits[0] != NULL)
1868     {
1869       struct bittree *nent = ent->bits[0];
1870       zero_count = 0;
1871
1872       insn_list[our_offset] |= 0x80;
1873
1874       /* We can encode sequences of multiple "if (bit is zero)" tests
1875          by storing the # of zero bits to check in the lower 3 bits of
1876          the instruction.  However, this only applies if the state
1877          solely tests for a zero bit.  */
1878
1879       if (IS_ONLY_IFZERO (ent))
1880         {
1881           while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1882             {
1883               nent = nent->bits[0];
1884               zero_count++;
1885             }
1886
1887           insn_list[our_offset + 0] |= zero_count;
1888         }
1889       zero_dest = insn_list_len;
1890       gen_dis_table (nent);
1891     }
1892
1893   /* Now store the remaining tests.  We also handle a sole "termination
1894      entry" by storing it as an "any bit" test.  */
1895
1896   for (x = 1; x < 3; x++)
1897     {
1898       if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1899         {
1900           struct bittree *i = ent->bits[x];
1901           int idest;
1902           int currbits = 15;
1903
1904           if (i != NULL)
1905             {
1906               /* If the instruction being branched to only consists of
1907                  a termination entry, use the termination entry as the
1908                  place to branch to instead.  */
1909               if (i->bits[0] == NULL && i->bits[1] == NULL
1910                   && i->bits[2] == NULL && i->disent != NULL)
1911                 {
1912                   idest = i->disent->ournum;
1913                   i = NULL;
1914                 }
1915               else
1916                 {
1917                   idest = insn_list_len - our_offset;
1918                 }
1919             }
1920           else
1921             {
1922               idest = ent->disent->ournum;
1923             }
1924
1925           /* If the destination offset for the if (bit is 1) test is less 
1926              than 256 bytes away, we can store it as 8-bits instead of 16;
1927              the instruction has bit 5 set for the 16-bit address, and bit
1928              4 for the 8-bit address.  Since we've already allocated 16
1929              bits for the address we need to deallocate the space.
1930
1931              Note that branchings within the table are relative, and
1932              there are no branches that branch past our instruction yet
1933              so we do not need to adjust any other offsets. */
1934
1935           if (x == 1)
1936             {
1937               if (idest <= 256)
1938                 {
1939                   int start = our_offset + bitsused / 8 + 1;
1940
1941                   memmove (insn_list + start,
1942                            insn_list + start + 1,
1943                            insn_list_len - (start + 1));
1944                   currbits = 7;
1945                   totbits -= 8;
1946                   needed_bytes--;
1947                   insn_list_len--;
1948                   insn_list[our_offset] |= 0x10;
1949                   idest--;
1950                 }
1951               else
1952                 {
1953                   insn_list[our_offset] |= 0x20;
1954                 }
1955             }
1956           else
1957             {
1958               /* An instruction which solely consists of a termination
1959                  marker and whose disassembly name index is < 4096
1960                  can be stored in 16 bits.  The encoding is slightly
1961                  odd; the upper 4 bits of the instruction are 0x3, and
1962                  bit 3 loses its normal meaning.  */
1963
1964               if (ent->bits[0] == NULL && ent->bits[1] == NULL
1965                   && ent->bits[2] == NULL && ent->skip_flag == 0
1966                   && ent->disent != NULL
1967                   && ent->disent->ournum < (32768 + 4096))
1968                 {
1969                   int start = our_offset + bitsused / 8 + 1;
1970
1971                   memmove (insn_list + start,
1972                            insn_list + start + 1,
1973                            insn_list_len - (start + 1));
1974                   currbits = 11;
1975                   totbits -= 5;
1976                   bitsused--;
1977                   needed_bytes--;
1978                   insn_list_len--;
1979                   insn_list[our_offset] |= 0x30;
1980                   idest &= ~32768;
1981                 }
1982               else
1983                 {
1984                   insn_list[our_offset] |= 0x08;
1985                 }
1986             }
1987           if (debug)
1988             {
1989               int id = idest;
1990
1991               if (i == NULL)
1992                 {
1993                   id |= 32768;
1994                 }
1995               else if (! (id & 32768))
1996                 {
1997                   id += our_offset;
1998                 }
1999               if (x == 1)
2000                 {
2001                   printf ("%d: if (1) goto %d\n", our_offset, id);
2002                 }
2003               else
2004                 {
2005                   printf ("%d: try %d\n", our_offset, id);
2006                 }
2007             }
2008
2009           /* Store the address of the entry being branched to. */
2010           while (currbits >= 0)
2011             {
2012               char *byte = insn_list + our_offset + bitsused / 8;
2013
2014               if (idest & (1 << currbits))
2015                 {
2016                   *byte |= (1 << (7 - (bitsused % 8)));
2017                 }
2018               bitsused++;
2019               currbits--;
2020             }
2021
2022           /* Now generate the states for the entry being branched to. */
2023           if (i != NULL)
2024             {
2025               gen_dis_table (i);
2026             }
2027
2028         }
2029     }
2030   if (debug)
2031     {
2032       if (ent->skip_flag)
2033         {
2034           printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2035         }
2036   
2037       if (ent->bits[0] != NULL)
2038         {
2039           printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2040                   zero_dest);
2041         }
2042     }
2043   if (bitsused != totbits)
2044     {
2045       abort ();
2046     }
2047 }
2048 \f
2049 void
2050 print_dis_table ()
2051 {
2052   int x;
2053   struct disent *cent = disinsntable;
2054
2055   printf ("static const char dis_table[] = {\n");
2056   for (x = 0; x < insn_list_len; x++)
2057     {
2058       if ((x > 0) && ((x % 12) == 0))
2059         {
2060           printf ("\n");
2061         }
2062       printf ("0x%02x, ", insn_list[x]);
2063     }
2064   printf ("\n};\n\n");
2065
2066   printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2067   while (cent != NULL)
2068     {
2069       struct disent *ent = cent;
2070
2071       while (ent != NULL)
2072         {
2073           printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2074                   ent->insn, (ent->nexte != NULL ? 1 : 0),
2075                   ent->priority);
2076           ent = ent->nexte;
2077         }
2078       cent = cent->next_ent;
2079     }
2080   printf ("};\n\n");
2081 }
2082 \f
2083 void
2084 generate_disassembler ()
2085 {
2086   int i;
2087
2088   bittree = make_bittree_entry ();
2089
2090   for (i=0; i < otlen;i++)
2091     {
2092       struct main_entry *ptr = ordered_table[i];
2093
2094       if (ptr->opcode->type != IA64_TYPE_DYN)
2095         {
2096           add_dis_entry (bittree,
2097                          ptr->opcode->opcode, ptr->opcode->mask, 
2098                          ptr->main_index,
2099                          ptr->completers, 1);
2100         }
2101     }
2102
2103   compact_distree (bittree);
2104   finish_distable ();
2105   gen_dis_table (bittree);
2106
2107   print_dis_table ();
2108 }
2109 \f
2110 void
2111 print_string_table ()
2112 {
2113   int x;
2114   char lbuf[80], buf[80];
2115   int blen = 0;
2116
2117   printf ("static const char *ia64_strings[] = {\n");
2118   lbuf[0] = '\0';
2119   for (x = 0; x < strtablen; x++)
2120     {
2121       int len;
2122       
2123       if (strlen (string_table[x]->s) > 75)
2124         {
2125           abort ();
2126         }
2127       sprintf (buf, " \"%s\",", string_table[x]->s);
2128       len = strlen (buf);
2129       if ((blen + len) > 75)
2130         {
2131           printf (" %s\n", lbuf);
2132           lbuf[0] = '\0';
2133           blen = 0;
2134         }
2135       strcat (lbuf, buf);
2136       blen += len;
2137     }
2138   if (blen > 0)
2139     {
2140       printf (" %s\n", lbuf);
2141     }
2142   printf ("};\n\n");
2143 }
2144 \f
2145 static struct completer_entry **glist;
2146 static int glistlen = 0;
2147 static int glisttotlen = 0;
2148
2149 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2150
2151 int
2152 completer_entries_eq (ent1, ent2)
2153      struct completer_entry *ent1, *ent2;
2154 {
2155   while (ent1 != NULL && ent2 != NULL)
2156     {
2157       if (ent1->name->num != ent2->name->num
2158           || ent1->bits != ent2->bits
2159           || ent1->mask != ent2->mask
2160           || ent1->is_terminal != ent2->is_terminal
2161           || ent1->dependencies != ent2->dependencies
2162           || ent1->order != ent2->order)
2163         {
2164           return 0;
2165         }
2166       if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2167         {
2168           return 0;
2169         }
2170       ent1 = ent1->alternative;
2171       ent2 = ent2->alternative;
2172     }
2173   return ent1 == ent2;
2174 }
2175 \f
2176 /* Insert ENT into the global list of completers and return it.  If an
2177    equivalent entry (according to completer_entries_eq) already exists,
2178    it is returned instead. */
2179 struct completer_entry *
2180 insert_gclist (ent)
2181      struct completer_entry *ent;
2182 {
2183   if (ent != NULL)
2184     {
2185       int i;
2186       int x;
2187       int start = 0, end;
2188
2189       ent->addl_entries = insert_gclist (ent->addl_entries);
2190       ent->alternative = insert_gclist (ent->alternative);
2191
2192       i = glistlen / 2;
2193       end = glistlen;
2194
2195       if (glisttotlen == glistlen)
2196         {
2197           glisttotlen += 20;
2198           glist = (struct completer_entry **)
2199             xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2200         }
2201
2202       if (glistlen == 0)
2203         {
2204           glist[0] = ent;
2205           glistlen = 1;
2206           return ent;
2207         }
2208
2209       if (ent->name->num < glist[0]->name->num)
2210         {
2211           i = 0;
2212         }
2213       else if (ent->name->num > glist[end - 1]->name->num)
2214         {
2215           i = end;
2216         }
2217       else
2218         {
2219           int c;
2220
2221           while (1)
2222             {
2223               i = (start + end) / 2;
2224               c = ent->name->num - glist[i]->name->num;
2225               if (c < 0)
2226                 {
2227                   end = i - 1;
2228                 }
2229               else if (c == 0)
2230                 {
2231                   while (i > 0 
2232                          && ent->name->num == glist[i - 1]->name->num)
2233                     {
2234                       i--;
2235                     }
2236                   break;
2237                 }
2238               else
2239                 {
2240                   start = i + 1;
2241                 }
2242               if (start > end)
2243                 {
2244                   break;
2245                 }
2246             }
2247           if (c == 0)
2248             {
2249               while (i < glistlen)
2250                 {
2251                   if (ent->name->num != glist[i]->name->num)
2252                     {
2253                       break;
2254                     }
2255                   if (completer_entries_eq (ent, glist[i]))
2256                     {
2257                       return glist[i];
2258                     }
2259                   i++;
2260                 }
2261             }
2262         }
2263       for (; i > 0 && i < glistlen; i--)
2264         {
2265           if (ent->name->num >= glist[i - 1]->name->num)
2266             {
2267               break;
2268             }
2269         }
2270       for (; i < glistlen; i++)
2271         {
2272           if (ent->name->num < glist[i]->name->num)
2273             {
2274               break;
2275             }
2276         }
2277       for (x = glistlen - 1; x >= i; x--)
2278         {
2279           glist[x + 1] = glist[x];
2280         }
2281       glist[i] = ent;
2282       glistlen++;
2283     }
2284   return ent;
2285 }
2286 \f
2287 static int
2288 get_prefix_len (name)
2289      const char *name;
2290 {
2291   char *c;
2292
2293   if (name[0] == '\0')
2294     {
2295       return 0;
2296     }
2297
2298   c = strchr (name, '.');
2299   if (c != NULL)
2300     {
2301       return c - name;
2302     }
2303   else
2304     {
2305       return strlen (name);
2306     }
2307 }
2308 \f
2309 static void
2310 compute_completer_bits (ment, ent)
2311      struct main_entry *ment;
2312      struct completer_entry *ent;
2313 {
2314   while (ent != NULL)
2315     {
2316       compute_completer_bits (ment, ent->addl_entries);
2317
2318       if (ent->is_terminal)
2319         {
2320           ia64_insn mask = 0;
2321           ia64_insn our_bits = ent->bits;
2322           struct completer_entry *p = ent->parent;
2323           ia64_insn p_bits;
2324           int x;
2325
2326           while (p != NULL && ! p->is_terminal)
2327             {
2328               p = p->parent;
2329             }
2330       
2331           if (p != NULL)
2332             {
2333               p_bits = p->bits;
2334             }
2335           else
2336             {
2337               p_bits = ment->opcode->opcode;
2338             }
2339
2340           for (x = 0; x < 64; x++)
2341             {
2342               ia64_insn m = ((ia64_insn) 1) << x;
2343               if ((p_bits & m) != (our_bits & m))
2344                 {
2345                   mask |= m;
2346                 }
2347               else
2348                 {
2349                   our_bits &= ~m;
2350                 }
2351             }
2352           ent->bits = our_bits;
2353           ent->mask = mask;
2354         }
2355       else
2356         {
2357           ent->bits = 0;
2358           ent->mask = 0;
2359         }
2360
2361       ent = ent->alternative;
2362     }
2363 }
2364 \f
2365 /* Find identical completer trees that are used in different
2366    instructions and collapse their entries. */
2367 void
2368 collapse_redundant_completers ()
2369 {
2370   struct main_entry *ptr;
2371   int x;
2372
2373   for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2374     {
2375       if (ptr->completers == NULL)
2376         {
2377           abort ();
2378         }
2379       compute_completer_bits (ptr, ptr->completers);
2380       ptr->completers = insert_gclist (ptr->completers);
2381     }
2382
2383   /* The table has been finalized, now number the indexes.  */
2384   for (x = 0; x < glistlen; x++)
2385     {
2386       glist[x]->num = x;
2387     }
2388 }
2389 \f
2390
2391 /* attach two lists of dependencies to each opcode.
2392    1) all resources which, when already marked in use, conflict with this
2393    opcode (chks) 
2394    2) all resources which must be marked in use when this opcode is used
2395    (regs) 
2396 */
2397 int
2398 insert_opcode_dependencies (opc, cmp)
2399      struct ia64_opcode *opc;
2400      struct completer_entry *cmp ATTRIBUTE_UNUSED;
2401 {
2402   /* note all resources which point to this opcode.  rfi has the most chks
2403      (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2404   int i;
2405   int nregs = 0;
2406   unsigned short regs[256];                  
2407   int nchks = 0;
2408   unsigned short chks[256];
2409   /* flag insns for which no class matched; there should be none */
2410   int no_class_found = 1;
2411
2412   for (i=0;i < rdepslen;i++)
2413     {
2414       struct rdep *rs = rdeps[i];
2415       int j;
2416
2417       if (strcmp (opc->name, "cmp.eq.and") == 0
2418           && strncmp (rs->name, "PR%", 3) == 0
2419           && rs->mode == 1)
2420         no_class_found = 99;
2421
2422       for (j=0; j < rs->nregs;j++)
2423         {
2424           int ic_note = 0;
2425
2426           if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2427             {
2428               /* We can ignore ic_note 11 for non PR resources */
2429               if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2430                 ic_note = 0;
2431
2432               if (ic_note != 0 && rs->regnotes[j] != 0
2433                   && ic_note != rs->regnotes[j]
2434                   && !(ic_note == 11 && rs->regnotes[j] == 1))
2435                 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2436                          " conflicts with resource %s note %d\n", 
2437                          ic_note, opc->name, ics[rs->regs[j]]->name,
2438                          rs->name, rs->regnotes[j]);
2439               /* Instruction class notes override resource notes.
2440                  So far, only note 11 applies to an IC instead of a resource,
2441                  and note 11 implies note 1.
2442                */
2443               if (ic_note)
2444                 regs[nregs++] = RDEP(ic_note, i);
2445               else
2446                 regs[nregs++] = RDEP(rs->regnotes[j], i);
2447               no_class_found = 0;
2448               ++rs->total_regs;
2449             }
2450         }
2451       for (j=0;j < rs->nchks;j++)
2452         {
2453           int ic_note = 0;
2454
2455           if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2456             {
2457               /* We can ignore ic_note 11 for non PR resources */
2458               if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2459                 ic_note = 0;
2460
2461               if (ic_note != 0 && rs->chknotes[j] != 0
2462                   && ic_note != rs->chknotes[j]
2463                   && !(ic_note == 11 && rs->chknotes[j] == 1))
2464                 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2465                          " conflicts with resource %s note %d\n", 
2466                          ic_note, opc->name, ics[rs->chks[j]]->name,
2467                          rs->name, rs->chknotes[j]);
2468               if (ic_note)
2469                 chks[nchks++] = RDEP(ic_note, i);
2470               else
2471                 chks[nchks++] = RDEP(rs->chknotes[j], i);
2472               no_class_found = 0;
2473               ++rs->total_chks;
2474             }
2475         }
2476     }
2477
2478   if (no_class_found)
2479     fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n", 
2480              opc->name, 
2481              opc->operands[0], opc->operands[1], opc->operands[2]);
2482
2483   return insert_dependencies (nchks, chks, nregs, regs);
2484 }
2485 \f
2486 void
2487 insert_completer_entry (opc, tabent, order)
2488      struct ia64_opcode *opc;
2489      struct main_entry *tabent;
2490      int order;
2491 {
2492   struct completer_entry **ptr = &tabent->completers;
2493   struct completer_entry *parent = NULL;
2494   char pcopy[129], *prefix;
2495   int at_end = 0;
2496
2497   if (strlen (opc->name) > 128)
2498     {
2499       abort ();
2500     }
2501   strcpy (pcopy, opc->name);
2502   prefix = pcopy + get_prefix_len (pcopy);
2503   if (prefix[0] != '\0')
2504     {
2505       prefix++;
2506     }
2507
2508   while (! at_end)
2509     {
2510       int need_new_ent = 1;
2511       int plen = get_prefix_len (prefix);
2512       struct string_entry *sent;
2513
2514       at_end = (prefix[plen] == '\0');
2515       prefix[plen] = '\0';
2516       sent = insert_string (prefix);
2517
2518       while (*ptr != NULL)
2519         {
2520           int cmpres = sent->num - (*ptr)->name->num;
2521
2522           if (cmpres == 0)
2523             {
2524               need_new_ent = 0;
2525               break;
2526             }
2527           else
2528             {
2529               ptr = &((*ptr)->alternative);
2530             }
2531         }
2532       if (need_new_ent)
2533         {
2534           struct completer_entry *nent = tmalloc (struct completer_entry);
2535           nent->name = sent;
2536           nent->parent = parent;
2537           nent->addl_entries = NULL;
2538           nent->alternative = *ptr;
2539           *ptr = nent;
2540           nent->is_terminal = 0;
2541           nent->dependencies = -1;
2542         }
2543
2544       if (! at_end)
2545         {
2546           parent = *ptr;
2547           ptr = &((*ptr)->addl_entries);
2548           prefix += plen + 1;
2549         }
2550     }
2551
2552   if ((*ptr)->is_terminal)
2553     {
2554       abort ();
2555     }
2556
2557   (*ptr)->is_terminal = 1;
2558   (*ptr)->mask = (ia64_insn)-1;
2559   (*ptr)->bits = opc->opcode;
2560   (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2561   (*ptr)->order = order;
2562 }
2563 \f
2564 void
2565 print_completer_entry (ent)
2566      struct completer_entry *ent;
2567 {
2568   int moffset = 0;
2569   ia64_insn mask = ent->mask, bits = ent->bits;
2570
2571   if (mask != 0)
2572     {
2573       while (! (mask & 1))
2574         {
2575           moffset++;
2576           mask = mask >> 1;
2577           bits = bits >> 1;
2578         }
2579       if (bits & 0xffffffff00000000LL)
2580         {
2581           abort ();
2582         }
2583     }
2584   
2585   printf ("  { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2586           (int)bits,
2587           (int)mask,
2588           ent->name->num,
2589           ent->alternative != NULL ? ent->alternative->num : -1,
2590           ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2591           moffset,
2592           ent->is_terminal ? 1 : 0,
2593           ent->dependencies);
2594 }
2595 \f
2596 void
2597 print_completer_table ()
2598 {
2599   int x;
2600
2601   printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2602   for (x = 0; x < glistlen; x++)
2603     {
2604       print_completer_entry (glist[x]);
2605     }
2606   printf ("};\n\n");
2607 }
2608 \f
2609 int
2610 opcodes_eq (opc1, opc2)
2611      struct ia64_opcode *opc1;
2612      struct ia64_opcode *opc2;
2613 {
2614   int x;
2615   int plen1, plen2;
2616
2617   if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 
2618       || (opc1->num_outputs != opc2->num_outputs)
2619       || (opc1->flags != opc2->flags))
2620     {
2621       return 0;
2622     }
2623   for (x = 0; x < 5; x++)
2624     {
2625       if (opc1->operands[x] != opc2->operands[x])
2626         {
2627           return 0;
2628         }
2629     }
2630   plen1 = get_prefix_len (opc1->name);
2631   plen2 = get_prefix_len (opc2->name);
2632   if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2633     {
2634       return 1;
2635     }
2636   return 0;
2637 }
2638 \f
2639 void
2640 add_opcode_entry (opc)
2641      struct ia64_opcode *opc;
2642 {
2643   struct main_entry **place;
2644   struct string_entry *name;
2645   char prefix[129];
2646   int found_it = 0;
2647
2648   if (strlen (opc->name) > 128)
2649     {
2650       abort ();
2651     }
2652   place = &maintable;
2653   strcpy (prefix, opc->name);
2654   prefix[get_prefix_len (prefix)] = '\0';
2655   name = insert_string (prefix);
2656
2657   /* Walk the list of opcode table entries.  If it's a new
2658      instruction, allocate and fill in a new entry.  Note 
2659      the main table is alphabetical by opcode name. */
2660
2661   while (*place != NULL)
2662     {
2663       if ((*place)->name->num == name->num
2664           && opcodes_eq ((*place)->opcode, opc))
2665         {
2666           found_it = 1;
2667           break;
2668         }
2669       if ((*place)->name->num > name->num)
2670         {
2671           break;
2672         }
2673       place = &((*place)->next);
2674     }
2675   if (! found_it)
2676     {
2677       struct main_entry *nent = tmalloc (struct main_entry);
2678
2679       nent->name = name;
2680       nent->opcode = opc;
2681       nent->next = *place;
2682       nent->completers = 0;
2683       *place = nent;
2684
2685       if (otlen == ottotlen)
2686         {
2687           ottotlen += 20;
2688           ordered_table = (struct main_entry **)
2689             xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2690         }
2691       ordered_table[otlen++] = nent;
2692     }
2693
2694   insert_completer_entry (opc, *place, opcode_count++);
2695 }
2696 \f
2697 void
2698 print_main_table ()
2699 {
2700   struct main_entry *ptr = maintable;
2701   int index = 0;
2702
2703   printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2704   while (ptr != NULL)
2705     {
2706       printf ("  { %d, %d, %d, 0x",
2707               ptr->name->num,
2708               ptr->opcode->type,
2709               ptr->opcode->num_outputs);
2710       fprintf_vma (stdout, ptr->opcode->opcode);
2711       printf ("ull, 0x");
2712       fprintf_vma (stdout, ptr->opcode->mask);
2713       printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2714               ptr->opcode->operands[0],
2715               ptr->opcode->operands[1],
2716               ptr->opcode->operands[2],
2717               ptr->opcode->operands[3],
2718               ptr->opcode->operands[4],
2719               ptr->opcode->flags,
2720               ptr->completers->num);
2721
2722       ptr->main_index = index++;
2723
2724       ptr = ptr->next;
2725     }
2726   printf ("};\n\n");
2727 }
2728 \f
2729 void
2730 shrink (table)
2731      struct ia64_opcode *table;
2732 {
2733   int curr_opcode;
2734
2735   for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2736     {
2737       add_opcode_entry (table + curr_opcode);
2738     }
2739 }
2740 \f
2741 int
2742 main (argc, argv)
2743      int argc;
2744      char **argv ATTRIBUTE_UNUSED;
2745 {
2746   if (argc > 1)
2747     {
2748       debug = 1;
2749     }
2750
2751   load_insn_classes();
2752   load_dependencies();
2753
2754   shrink (ia64_opcodes_a);
2755   shrink (ia64_opcodes_b);
2756   shrink (ia64_opcodes_f);
2757   shrink (ia64_opcodes_i);
2758   shrink (ia64_opcodes_m);
2759   shrink (ia64_opcodes_x);
2760   shrink (ia64_opcodes_d);
2761
2762   collapse_redundant_completers ();
2763
2764   printf ("/* This file is automatically generated by ia64-gen.  Do not edit! */\n");
2765   print_string_table ();
2766   print_dependency_table ();
2767   print_completer_table ();
2768   print_main_table ();
2769
2770   generate_disassembler ();
2771
2772   exit (0);
2773 }