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