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