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