OSDN Git Service

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