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