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