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