OSDN Git Service

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