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