Automatic date update in version.in
[binutils-gdb.git] / opcodes / ia64-gen.c
blobf19e505bf7caaf01d6ec9f3acdcfa466a439f6cf
1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright (C) 1999-2024 Free Software Foundation, Inc.
3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this file; see the file COPYING. If not, write to the
19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
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.
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.
33 The resource table is constructed based on some text dependency tables,
34 which are also easier to maintain than the final representation. */
36 #include "sysdep.h"
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <errno.h>
41 #include "libiberty.h"
42 #include "safe-ctype.h"
43 #include "getopt.h"
44 #include "ia64-opc.h"
45 #include "ia64-opc-a.c"
46 #include "ia64-opc-i.c"
47 #include "ia64-opc-m.c"
48 #include "ia64-opc-b.c"
49 #include "ia64-opc-f.c"
50 #include "ia64-opc-x.c"
51 #include "ia64-opc-d.c"
53 #include <libintl.h>
54 #define _(String) gettext (String)
56 const char * program_name = NULL;
57 int debug = 0;
59 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
60 #define tmalloc(X) (X *) xmalloc (sizeof (X))
62 typedef unsigned long long ci_t;
63 /* The main opcode table entry. Each entry is a unique combination of
64 name and flags (no two entries in the table compare as being equal
65 via opcodes_eq). */
66 struct main_entry
68 /* The base name of this opcode. The names of its completers are
69 appended to it to generate the full instruction name. */
70 struct string_entry *name;
71 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
72 it uses the first one passed to add_opcode_entry. */
73 struct ia64_opcode *opcode;
74 /* The list of completers that can be applied to this opcode. */
75 struct completer_entry *completers;
76 /* Next entry in the chain. */
77 struct main_entry *next;
78 /* Index in the main table. */
79 int main_index;
80 } *maintable, **ordered_table;
82 int otlen = 0;
83 int ottotlen = 0;
84 int opcode_count = 0;
86 /* The set of possible completers for an opcode. */
87 struct completer_entry
89 /* This entry's index in the ia64_completer_table[] array. */
90 int num;
92 /* The name of the completer. */
93 struct string_entry *name;
95 /* This entry's parent. */
96 struct completer_entry *parent;
98 /* Set if this is a terminal completer (occurs at the end of an
99 opcode). */
100 int is_terminal;
102 /* An alternative completer. */
103 struct completer_entry *alternative;
105 /* Additional completers that can be appended to this one. */
106 struct completer_entry *addl_entries;
108 /* Before compute_completer_bits () is invoked, this contains the actual
109 instruction opcode for this combination of opcode and completers.
110 Afterwards, it contains those bits that are different from its
111 parent opcode. */
112 ia64_insn bits;
114 /* Bits set to 1 correspond to those bits in this completer's opcode
115 that are different from its parent completer's opcode (or from
116 the base opcode if the entry is the root of the opcode's completer
117 list). This field is filled in by compute_completer_bits (). */
118 ia64_insn mask;
120 /* Index into the opcode dependency list, or -1 if none. */
121 int dependencies;
123 /* Remember the order encountered in the opcode tables. */
124 int order;
127 /* One entry in the disassembler name table. */
128 struct disent
130 /* The index into the ia64_name_dis array for this entry. */
131 int ournum;
133 /* The index into the main_table[] array. */
134 int insn;
136 /* The disassmbly priority of this entry. */
137 int priority;
139 /* The completer_index value for this entry. */
140 ci_t completer_index;
142 /* How many other entries share this decode. */
143 int nextcnt;
145 /* The next entry sharing the same decode. */
146 struct disent *nexte;
148 /* The next entry in the name list. */
149 struct disent *next_ent;
150 } *disinsntable = NULL;
152 /* A state machine that will eventually be used to generate the
153 disassembler table. */
154 struct bittree
156 struct disent *disent;
157 struct bittree *bits[3]; /* 0, 1, and X (don't care). */
158 int bits_to_skip;
159 int skip_flag;
160 } *bittree;
162 /* The string table contains all opcodes and completers sorted in
163 alphabetical order. */
165 /* One entry in the string table. */
166 struct string_entry
168 /* The index in the ia64_strings[] array for this entry. */
169 int num;
170 /* And the string. */
171 char *s;
172 } **string_table = NULL;
174 int strtablen = 0;
175 int strtabtotlen = 0;
178 /* Resource dependency entries. */
179 struct rdep
181 char *name; /* Resource name. */
182 unsigned
183 mode:2, /* RAW, WAW, or WAR. */
184 semantics:3; /* Dependency semantics. */
185 char *extra; /* Additional semantics info. */
186 int nchks;
187 int total_chks; /* Total #of terminal insns. */
188 int *chks; /* Insn classes which read (RAW), write
189 (WAW), or write (WAR) this rsrc. */
190 int *chknotes; /* Dependency notes for each class. */
191 int nregs;
192 int total_regs; /* Total #of terminal insns. */
193 int *regs; /* Insn class which write (RAW), write2
194 (WAW), or read (WAR) this rsrc. */
195 int *regnotes; /* Dependency notes for each class. */
197 int waw_special; /* Special WAW dependency note. */
198 } **rdeps = NULL;
200 static int rdepslen = 0;
201 static int rdepstotlen = 0;
203 /* Array of all instruction classes. */
204 struct iclass
206 char *name; /* Instruction class name. */
207 int is_class; /* Is a class, not a terminal. */
208 int nsubs;
209 int *subs; /* Other classes within this class. */
210 int nxsubs;
211 int xsubs[4]; /* Exclusions. */
212 char *comment; /* Optional comment. */
213 int note; /* Optional note. */
214 int terminal_resolved; /* Did we match this with anything? */
215 int orphan; /* Detect class orphans. */
216 } **ics = NULL;
218 static int iclen = 0;
219 static int ictotlen = 0;
221 /* An opcode dependency (chk/reg pair of dependency lists). */
222 struct opdep
224 int chk; /* index into dlists */
225 int reg; /* index into dlists */
226 } **opdeps;
228 static int opdeplen = 0;
229 static int opdeptotlen = 0;
231 /* A generic list of dependencies w/notes encoded. These may be shared. */
232 struct deplist
234 int len;
235 unsigned short *deps;
236 } **dlists;
238 static int dlistlen = 0;
239 static int dlisttotlen = 0;
242 static void fail (const char *, ...) ATTRIBUTE_PRINTF_1;
243 static void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
244 static struct rdep * insert_resource (const char *, enum ia64_dependency_mode);
245 static int deplist_equals (struct deplist *, struct deplist *);
246 static short insert_deplist (int, unsigned short *);
247 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
248 static void mark_used (struct iclass *, int);
249 static int fetch_insn_class (const char *, int);
250 static int sub_compare (const void *, const void *);
251 static void load_insn_classes (void);
252 static void parse_resource_users (const char *, int **, int *, int **);
253 static int parse_semantics (char *);
254 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
255 static void load_depfile (const char *, enum ia64_dependency_mode);
256 static void load_dependencies (void);
257 static int irf_operand (int, const char *);
258 static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *);
259 static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *);
260 static int lookup_regindex (const char *, int);
261 static int lookup_specifier (const char *);
262 static void print_dependency_table (void);
263 static struct string_entry * insert_string (char *);
264 static void gen_dis_table (struct bittree *);
265 static void print_dis_table (void);
266 static void generate_disassembler (void);
267 static void print_string_table (void);
268 static int completer_entries_eq (struct completer_entry *, struct completer_entry *);
269 static struct completer_entry * insert_gclist (struct completer_entry *);
270 static int get_prefix_len (const char *);
271 static void compute_completer_bits (struct main_entry *, struct completer_entry *);
272 static void collapse_redundant_completers (void);
273 static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *);
274 static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int);
275 static void print_completer_entry (struct completer_entry *);
276 static void print_completer_table (void);
277 static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *);
278 static void add_opcode_entry (struct ia64_opcode *);
279 static void print_main_table (void);
280 static void shrink (struct ia64_opcode *);
281 static void print_version (void);
282 static void usage (FILE *, int);
283 static void finish_distable (void);
284 static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, ci_t);
285 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, ci_t);
286 static void compact_distree (struct bittree *);
287 static struct bittree * make_bittree_entry (void);
288 static struct disent * add_dis_table_ent (struct disent *, int, int, ci_t);
291 static void
292 fail (const char *message, ...)
294 va_list args;
296 va_start (args, message);
297 fprintf (stderr, _("%s: Error: "), program_name);
298 vfprintf (stderr, message, args);
299 va_end (args);
300 xexit (1);
303 static void
304 warn (const char *message, ...)
306 va_list args;
308 va_start (args, message);
310 fprintf (stderr, _("%s: Warning: "), program_name);
311 vfprintf (stderr, message, args);
312 va_end (args);
315 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
316 static struct rdep *
317 insert_resource (const char *name, enum ia64_dependency_mode type)
319 if (rdepslen == rdepstotlen)
321 rdepstotlen += 20;
322 rdeps = (struct rdep **)
323 xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
325 rdeps[rdepslen] = tmalloc(struct rdep);
326 memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep));
327 rdeps[rdepslen]->name = xstrdup (name);
328 rdeps[rdepslen]->mode = type;
329 rdeps[rdepslen]->waw_special = 0;
331 return rdeps[rdepslen++];
334 /* Are the lists of dependency indexes equivalent? */
335 static int
336 deplist_equals (struct deplist *d1, struct deplist *d2)
338 int i;
340 if (d1->len != d2->len)
341 return 0;
343 for (i = 0; i < d1->len; i++)
344 if (d1->deps[i] != d2->deps[i])
345 return 0;
347 return 1;
350 /* Add the list of dependencies to the list of dependency lists. */
351 static short
352 insert_deplist (int count, unsigned short *deps)
354 /* Sort the list, then see if an equivalent list exists already.
355 this results in a much smaller set of dependency lists. */
356 struct deplist *list;
357 char set[0x10000];
358 int i;
360 memset ((void *)set, 0, sizeof (set));
361 for (i = 0; i < count; i++)
362 set[deps[i]] = 1;
364 count = 0;
365 for (i = 0; i < (int) sizeof (set); i++)
366 if (set[i])
367 ++count;
369 list = tmalloc (struct deplist);
370 list->len = count;
371 list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count);
373 for (i = 0, count = 0; i < (int) sizeof (set); i++)
374 if (set[i])
375 list->deps[count++] = i;
377 /* Does this list exist already? */
378 for (i = 0; i < dlistlen; i++)
379 if (deplist_equals (list, dlists[i]))
381 free (list->deps);
382 free (list);
383 return i;
386 if (dlistlen == dlisttotlen)
388 dlisttotlen += 20;
389 dlists = (struct deplist **)
390 xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
392 dlists[dlistlen] = list;
394 return dlistlen++;
397 /* Add the given pair of dependency lists to the opcode dependency list. */
398 static short
399 insert_dependencies (int nchks, unsigned short *chks,
400 int nregs, unsigned short *regs)
402 struct opdep *pair;
403 int i;
404 int regind = -1;
405 int chkind = -1;
407 if (nregs > 0)
408 regind = insert_deplist (nregs, regs);
409 if (nchks > 0)
410 chkind = insert_deplist (nchks, chks);
412 for (i = 0; i < opdeplen; i++)
413 if (opdeps[i]->chk == chkind
414 && opdeps[i]->reg == regind)
415 return i;
417 pair = tmalloc (struct opdep);
418 pair->chk = chkind;
419 pair->reg = regind;
421 if (opdeplen == opdeptotlen)
423 opdeptotlen += 20;
424 opdeps = (struct opdep **)
425 xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
427 opdeps[opdeplen] = pair;
429 return opdeplen++;
432 static void
433 mark_used (struct iclass *ic, int clear_terminals)
435 int i;
437 ic->orphan = 0;
438 if (clear_terminals)
439 ic->terminal_resolved = 1;
441 for (i = 0; i < ic->nsubs; i++)
442 mark_used (ics[ic->subs[i]], clear_terminals);
444 for (i = 0; i < ic->nxsubs; i++)
445 mark_used (ics[ic->xsubs[i]], clear_terminals);
448 /* Look up an instruction class; if CREATE make a new one if none found;
449 returns the index into the insn class array. */
450 static int
451 fetch_insn_class (const char *full_name, int create)
453 char *name;
454 char *notestr;
455 char *xsect;
456 char *comment;
457 int i, note = 0;
458 int ind;
459 int is_class = 0;
461 if (startswith (full_name, "IC:"))
463 name = xstrdup (full_name + 3);
464 is_class = 1;
466 else
467 name = xstrdup (full_name);
469 if ((xsect = strchr(name, '\\')) != NULL)
470 is_class = 1;
471 if ((comment = strchr(name, '[')) != NULL)
472 is_class = 1;
473 if ((notestr = strchr(name, '+')) != NULL)
474 is_class = 1;
476 /* If it is a composite class, then ignore comments and notes that come after
477 the '\\', since they don't apply to the part we are decoding now. */
478 if (xsect)
480 if (comment > xsect)
481 comment = 0;
482 if (notestr > xsect)
483 notestr = 0;
486 if (notestr)
488 char *nextnotestr;
490 note = atoi (notestr + 1);
491 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
493 if (strcmp (notestr, "+1+13") == 0)
494 note = 13;
495 else if (!xsect || nextnotestr < xsect)
496 warn (_("multiple note %s not handled\n"), notestr);
500 /* If it's a composite class, leave the notes and comments in place so that
501 we have a unique name for the composite class. Otherwise, we remove
502 them. */
503 if (!xsect)
505 if (notestr)
506 *notestr = 0;
507 if (comment)
508 *comment = 0;
511 for (i = 0; i < iclen; i++)
512 if (strcmp (name, ics[i]->name) == 0
513 && ((comment == NULL && ics[i]->comment == NULL)
514 || (comment != NULL && ics[i]->comment != NULL
515 && strncmp (ics[i]->comment, comment,
516 strlen (ics[i]->comment)) == 0))
517 && note == ics[i]->note)
518 return i;
520 if (!create)
521 return -1;
523 /* Doesn't exist, so make a new one. */
524 if (iclen == ictotlen)
526 ictotlen += 20;
527 ics = (struct iclass **)
528 xrealloc (ics, (ictotlen) * sizeof (struct iclass *));
531 ind = iclen++;
532 ics[ind] = tmalloc (struct iclass);
533 memset ((void *)ics[ind], 0, sizeof (struct iclass));
534 ics[ind]->name = xstrdup (name);
535 ics[ind]->is_class = is_class;
536 ics[ind]->orphan = 1;
538 if (comment)
540 ics[ind]->comment = xstrdup (comment + 1);
541 ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0;
544 if (notestr)
545 ics[ind]->note = note;
547 /* If it's a composite class, there's a comment or note, look for an
548 existing class or terminal with the same name. */
549 if ((xsect || comment || notestr) && is_class)
551 /* First, populate with the class we're based on. */
552 char *subname = name;
554 if (xsect)
555 *xsect = 0;
556 else if (comment)
557 *comment = 0;
558 else if (notestr)
559 *notestr = 0;
561 ics[ind]->nsubs = 1;
562 ics[ind]->subs = tmalloc(int);
563 ics[ind]->subs[0] = fetch_insn_class (subname, 1);
566 while (xsect)
568 char *subname = xsect + 1;
570 xsect = strchr (subname, '\\');
571 if (xsect)
572 *xsect = 0;
573 ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
574 ics[ind]->nxsubs++;
576 free (name);
578 return ind;
581 /* For sorting a class's sub-class list only; make sure classes appear before
582 terminals. */
583 static int
584 sub_compare (const void *e1, const void *e2)
586 struct iclass *ic1 = ics[*(int *)e1];
587 struct iclass *ic2 = ics[*(int *)e2];
589 if (ic1->is_class)
591 if (!ic2->is_class)
592 return -1;
594 else if (ic2->is_class)
595 return 1;
597 return strcmp (ic1->name, ic2->name);
600 static void
601 load_insn_classes (void)
603 FILE *fp = fopen ("ia64-ic.tbl", "r");
604 char buf[2048];
606 if (fp == NULL)
607 fail (_("can't find ia64-ic.tbl for reading\n"));
609 /* Discard first line. */
610 if (fgets (buf, sizeof(buf), fp) == NULL)
611 return;
613 while (!feof (fp))
615 int iclass;
616 char *name;
617 char *tmp;
619 if (fgets (buf, sizeof (buf), fp) == NULL)
620 break;
622 while (ISSPACE (buf[strlen (buf) - 1]))
623 buf[strlen (buf) - 1] = '\0';
625 name = tmp = buf;
626 while (*tmp != ';')
628 ++tmp;
629 if (tmp == buf + sizeof (buf))
630 abort ();
632 *tmp++ = '\0';
634 iclass = fetch_insn_class (name, 1);
635 ics[iclass]->is_class = 1;
637 if (strcmp (name, "none") == 0)
639 ics[iclass]->is_class = 0;
640 ics[iclass]->terminal_resolved = 1;
641 continue;
644 /* For this class, record all sub-classes. */
645 while (*tmp)
647 char *subname;
648 int sub;
650 while (*tmp && ISSPACE (*tmp))
652 ++tmp;
653 if (tmp == buf + sizeof (buf))
654 abort ();
656 subname = tmp;
657 while (*tmp && *tmp != ',')
659 ++tmp;
660 if (tmp == buf + sizeof (buf))
661 abort ();
663 if (*tmp == ',')
664 *tmp++ = '\0';
666 ics[iclass]->subs = (int *)
667 xrealloc ((void *)ics[iclass]->subs,
668 (ics[iclass]->nsubs + 1) * sizeof (int));
670 sub = fetch_insn_class (subname, 1);
671 ics[iclass]->subs = (int *)
672 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int));
673 ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
676 /* Make sure classes come before terminals. */
677 qsort ((void *)ics[iclass]->subs,
678 ics[iclass]->nsubs, sizeof(int), sub_compare);
680 fclose (fp);
682 if (debug)
683 printf ("%d classes\n", iclen);
686 /* Extract the insn classes from the given line. */
687 static void
688 parse_resource_users (const char *ref, int **usersp, int *nusersp,
689 int **notesp)
691 int c;
692 char *line = xstrdup (ref);
693 char *tmp = line;
694 int *users = *usersp;
695 int count = *nusersp;
696 int *notes = *notesp;
698 c = *tmp;
699 while (c != 0)
701 char *notestr;
702 int note;
703 char *xsect;
704 int iclass;
705 int create = 0;
706 char *name;
708 while (ISSPACE (*tmp))
709 ++tmp;
710 name = tmp;
711 while (*tmp && *tmp != ',')
712 ++tmp;
713 c = *tmp;
714 *tmp++ = '\0';
716 xsect = strchr (name, '\\');
717 if ((notestr = strstr (name, "+")) != NULL)
719 char *nextnotestr;
721 note = atoi (notestr + 1);
722 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
724 /* Note 13 always implies note 1. */
725 if (strcmp (notestr, "+1+13") == 0)
726 note = 13;
727 else if (!xsect || nextnotestr < xsect)
728 warn (_("multiple note %s not handled\n"), notestr);
730 if (!xsect)
731 *notestr = '\0';
733 else
734 note = 0;
736 /* All classes are created when the insn class table is parsed;
737 Individual instructions might not appear until the dependency tables
738 are read. Only create new classes if it's *not* an insn class,
739 or if it's a composite class (which wouldn't necessarily be in the IC
740 table). */
741 if (! startswith (name, "IC:") || xsect != NULL)
742 create = 1;
744 iclass = fetch_insn_class (name, create);
745 if (iclass != -1)
747 users = (int *)
748 xrealloc ((void *) users,(count + 1) * sizeof (int));
749 notes = (int *)
750 xrealloc ((void *) notes,(count + 1) * sizeof (int));
751 notes[count] = note;
752 users[count++] = iclass;
753 mark_used (ics[iclass], 0);
755 else if (debug)
756 printf("Class %s not found\n", name);
758 /* Update the return values. */
759 *usersp = users;
760 *nusersp = count;
761 *notesp = notes;
763 free (line);
766 static int
767 parse_semantics (char *sem)
769 if (strcmp (sem, "none") == 0)
770 return IA64_DVS_NONE;
771 else if (strcmp (sem, "implied") == 0)
772 return IA64_DVS_IMPLIED;
773 else if (strcmp (sem, "impliedF") == 0)
774 return IA64_DVS_IMPLIEDF;
775 else if (strcmp (sem, "data") == 0)
776 return IA64_DVS_DATA;
777 else if (strcmp (sem, "instr") == 0)
778 return IA64_DVS_INSTR;
779 else if (strcmp (sem, "specific") == 0)
780 return IA64_DVS_SPECIFIC;
781 else if (strcmp (sem, "stop") == 0)
782 return IA64_DVS_STOP;
783 else
784 return IA64_DVS_OTHER;
787 static void
788 add_dep (const char *name, const char *chk, const char *reg,
789 int semantics, int mode, char *extra, int flag)
791 struct rdep *rs;
793 rs = insert_resource (name, mode);
795 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
796 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
798 rs->semantics = semantics;
799 rs->extra = extra;
800 rs->waw_special = flag;
803 static void
804 load_depfile (const char *filename, enum ia64_dependency_mode mode)
806 FILE *fp = fopen (filename, "r");
807 char buf[1024];
809 if (fp == NULL)
810 fail (_("can't find %s for reading\n"), filename);
812 if (fgets (buf, sizeof(buf), fp) == NULL)
813 return;
814 while (!feof (fp))
816 char *name, *tmp;
817 int semantics;
818 char *extra;
819 char *regp, *chkp;
821 if (fgets (buf, sizeof(buf), fp) == NULL)
822 break;
824 while (ISSPACE (buf[strlen (buf) - 1]))
825 buf[strlen (buf) - 1] = '\0';
827 name = tmp = buf;
828 while (*tmp != ';')
829 ++tmp;
830 *tmp++ = '\0';
832 while (ISSPACE (*tmp))
833 ++tmp;
834 regp = tmp;
835 tmp = strchr (tmp, ';');
836 if (!tmp)
837 abort ();
838 *tmp++ = 0;
839 while (ISSPACE (*tmp))
840 ++tmp;
841 chkp = tmp;
842 tmp = strchr (tmp, ';');
843 if (!tmp)
844 abort ();
845 *tmp++ = 0;
846 while (ISSPACE (*tmp))
847 ++tmp;
848 semantics = parse_semantics (tmp);
849 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
851 /* For WAW entries, if the chks and regs differ, we need to enter the
852 entries in both positions so that the tables will be parsed properly,
853 without a lot of extra work. */
854 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
856 add_dep (name, chkp, regp, semantics, mode, extra, 0);
857 add_dep (name, regp, chkp, semantics, mode, extra, 1);
859 else
861 add_dep (name, chkp, regp, semantics, mode, extra, 0);
864 fclose (fp);
867 static void
868 load_dependencies (void)
870 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
871 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
872 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
874 if (debug)
875 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
878 /* Is the given operand an indirect register file operand? */
879 static int
880 irf_operand (int op, const char *field)
882 if (!field)
884 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
885 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
886 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
887 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
889 else
891 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
892 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
893 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
894 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
895 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
896 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
897 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
898 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid"))
899 || (op == IA64_OPND_DAHR_R3 && strstr (field, "dahr")));
903 /* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
904 * mov_psr, and mov_um insn classes. */
905 static int
906 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
907 const char *format, const char *field)
909 int plain_mov = strcmp (idesc->name, "mov") == 0;
911 if (!format)
912 return 0;
914 switch (ic->name[4])
916 default:
917 abort ();
918 case 'a':
920 int i = strcmp (idesc->name, "mov.i") == 0;
921 int m = strcmp (idesc->name, "mov.m") == 0;
922 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
923 int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
924 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
925 int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
926 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
927 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
929 /* IC:mov ar */
930 if (i2627)
931 return strstr (format, "I26") || strstr (format, "I27");
932 if (i28)
933 return strstr (format, "I28") != NULL;
934 if (m2930)
935 return strstr (format, "M29") || strstr (format, "M30");
936 if (m31)
937 return strstr (format, "M31") != NULL;
938 if (pseudo0 || pseudo1)
939 return 1;
941 break;
942 case 'b':
944 int i21 = idesc->operands[0] == IA64_OPND_B1;
945 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
946 if (i22)
947 return strstr (format, "I22") != NULL;
948 if (i21)
949 return strstr (format, "I21") != NULL;
951 break;
952 case 'c':
954 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
955 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
956 if (m32)
957 return strstr (format, "M32") != NULL;
958 if (m33)
959 return strstr (format, "M33") != NULL;
961 break;
962 case 'd':
964 int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3;
965 if (m50)
966 return strstr (format, "M50") != NULL;
968 break;
969 case 'i':
970 if (ic->name[5] == 'n')
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;
979 else if (ic->name[5] == 'p')
981 return idesc->operands[1] == IA64_OPND_IP;
983 else
984 abort ();
985 break;
986 case 'p':
987 if (ic->name[5] == 'r')
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;
999 else if (ic->name[5] == 's')
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;
1008 else
1009 abort ();
1010 break;
1011 case 'u':
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;
1020 break;
1022 return 0;
1025 /* Is the given opcode in the given insn class? */
1026 static int
1027 in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1028 const char *format, const char *field, int *notep)
1030 int i;
1031 int resolved = 0;
1033 if (ic->comment)
1035 if (startswith (ic->comment, "Format"))
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. */
1039 if (format)
1041 if (strlen (ic->comment) < strlen (format))
1043 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1044 ic->comment, format);
1045 format = ic->comment;
1048 else
1049 format = ic->comment;
1051 else if (startswith (ic->comment, "Field"))
1053 if (field)
1054 warn (_("overlapping field %s->%s\n"),
1055 ic->comment, field);
1056 field = ic->comment;
1060 /* An insn class matches anything that is the same followed by completers,
1061 except when the absence and presence of completers constitutes different
1062 instructions. */
1063 if (ic->nsubs == 0 && ic->nxsubs == 0)
1065 int is_mov = startswith (idesc->name, "mov");
1066 int plain_mov = strcmp (idesc->name, "mov") == 0;
1067 int len = strlen(ic->name);
1069 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1070 && (idesc->name[len] == '\0'
1071 || idesc->name[len] == '.'));
1073 /* All break, nop, and hint variations must match exactly. */
1074 if (resolved &&
1075 (strcmp (ic->name, "break") == 0
1076 || strcmp (ic->name, "nop") == 0
1077 || strcmp (ic->name, "hint") == 0))
1078 resolved = strcmp (ic->name, idesc->name) == 0;
1080 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1081 unless specifically allowed by clauses in this block. */
1082 if (resolved && field)
1084 /* Check Field(sf)==sN against opcode sN. */
1085 if (strstr(field, "(sf)==") != NULL)
1087 char *sf;
1089 if ((sf = strstr (idesc->name, ".s")) != 0)
1090 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1092 /* Check Field(lftype)==XXX. */
1093 else if (strstr (field, "(lftype)") != NULL)
1095 if (strstr (idesc->name, "fault") != NULL)
1096 resolved = strstr (field, "fault") != NULL;
1097 else
1098 resolved = strstr (field, "fault") == NULL;
1100 /* Handle Field(ctype)==XXX. */
1101 else if (strstr (field, "(ctype)") != NULL)
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;
1122 if (resolved && format)
1124 if (startswith (idesc->name, "dep")
1125 && strstr (format, "I13") != NULL)
1126 resolved = idesc->operands[1] == IA64_OPND_IMM8;
1127 else if (startswith (idesc->name, "chk")
1128 && strstr (format, "M21") != NULL)
1129 resolved = idesc->operands[0] == IA64_OPND_F2;
1130 else if (startswith (idesc->name, "lfetch"))
1131 resolved = (strstr (format, "M14 M15") != NULL
1132 && (idesc->operands[1] == IA64_OPND_R2
1133 || idesc->operands[1] == IA64_OPND_IMM9b));
1134 else if (startswith (idesc->name, "br.call")
1135 && strstr (format, "B5") != NULL)
1136 resolved = idesc->operands[1] == IA64_OPND_B2;
1137 else if (startswith (idesc->name, "br.call")
1138 && strstr (format, "B3") != NULL)
1139 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1140 else if (startswith (idesc->name, "brp")
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;
1145 else if (startswith (idesc->name, "st")
1146 && (strstr (format, "M5") != NULL
1147 || strstr (format, "M10") != NULL))
1148 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1149 else if (startswith (idesc->name, "ld")
1150 && (strstr (format, "M2 M3") != NULL
1151 || strstr (format, "M12") != NULL
1152 || strstr (format, "M7 M8") != NULL))
1153 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1154 else
1155 resolved = 0;
1158 /* Misc brl variations ('.cond' is optional);
1159 plain brl matches brl.cond. */
1160 if (!resolved
1161 && (strcmp (idesc->name, "brl") == 0
1162 || startswith (idesc->name, "brl."))
1163 && strcmp (ic->name, "brl.cond") == 0)
1165 resolved = 1;
1168 /* Misc br variations ('.cond' is optional). */
1169 if (!resolved
1170 && (strcmp (idesc->name, "br") == 0
1171 || startswith (idesc->name, "br."))
1172 && strcmp (ic->name, "br.cond") == 0)
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;
1183 /* probe variations. */
1184 if (!resolved && startswith (idesc->name, "probe"))
1186 resolved = strcmp (ic->name, "probe") == 0
1187 && !((strstr (idesc->name, "fault") != NULL)
1188 ^ (format && strstr (format, "M40") != NULL));
1191 /* mov variations. */
1192 if (!resolved && is_mov)
1194 if (plain_mov)
1196 /* mov alias for fmerge. */
1197 if (strcmp (ic->name, "fmerge") == 0)
1199 resolved = idesc->operands[0] == IA64_OPND_F1
1200 && idesc->operands[1] == IA64_OPND_F3;
1202 /* mov alias for adds (r3 or imm14). */
1203 else if (strcmp (ic->name, "adds") == 0)
1205 resolved = (idesc->operands[0] == IA64_OPND_R1
1206 && (idesc->operands[1] == IA64_OPND_R3
1207 || (idesc->operands[1] == IA64_OPND_IMM14)));
1209 /* mov alias for addl. */
1210 else if (strcmp (ic->name, "addl") == 0)
1212 resolved = idesc->operands[0] == IA64_OPND_R1
1213 && idesc->operands[1] == IA64_OPND_IMM22;
1217 /* Some variants of mov and mov.[im]. */
1218 if (!resolved && startswith (ic->name, "mov_"))
1219 resolved = in_iclass_mov_x (idesc, ic, format, field);
1222 /* Keep track of this so we can flag any insn classes which aren't
1223 mapped onto at least one real insn. */
1224 if (resolved)
1225 ic->terminal_resolved = 1;
1227 else for (i = 0; i < ic->nsubs; i++)
1229 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1231 int j;
1233 for (j = 0; j < ic->nxsubs; j++)
1234 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1235 return 0;
1237 if (debug > 1)
1238 printf ("%s is in IC %s\n", idesc->name, ic->name);
1240 resolved = 1;
1241 break;
1245 /* If it's in this IC, add the IC note (if any) to the insn. */
1246 if (resolved)
1248 if (ic->note && notep)
1250 if (*notep && *notep != ic->note)
1251 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1252 *notep, ic->note, ic->name);
1254 *notep = ic->note;
1258 return resolved;
1262 static int
1263 lookup_regindex (const char *name, int specifier)
1265 switch (specifier)
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;
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;
1292 else if (strstr (name, "[CCV]"))
1293 return 32;
1294 else if (strstr (name, "[ITC]"))
1295 return 44;
1296 else if (strstr (name, "[RUC]"))
1297 return 45;
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 if (strstr (name, ".vm"))
1413 return 46;
1414 else
1415 abort ();
1416 default:
1417 break;
1419 return REG_NONE;
1422 static int
1423 lookup_specifier (const char *name)
1425 if (strchr (name, '%'))
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;
1437 if (strstr (name, "CR[IIB%]") != NULL)
1438 return IA64_RS_CR_IIB;
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, "DAHR%, % in 0") != NULL)
1446 return IA64_RS_DAHR;
1447 if (strstr (name, "FR%, % in 0") != NULL)
1448 return IA64_RS_FR;
1449 if (strstr (name, "FR%, % in 2") != NULL)
1450 return IA64_RS_FRb;
1451 if (strstr (name, "GR%") != NULL)
1452 return IA64_RS_GR;
1453 if (strstr (name, "PR%, % in 1 ") != NULL)
1454 return IA64_RS_PR;
1455 if (strstr (name, "PR%, % in 16 ") != NULL)
1456 return IA64_RS_PRr;
1458 warn (_("don't know how to specify %% dependency %s\n"),
1459 name);
1461 else if (strchr (name, '#'))
1463 if (strstr (name, "CPUID#") != NULL)
1464 return IA64_RS_CPUID;
1465 if (strstr (name, "DBR#") != NULL)
1466 return IA64_RS_DBR;
1467 if (strstr (name, "IBR#") != NULL)
1468 return IA64_RS_IBR;
1469 if (strstr (name, "MSR#") != NULL)
1470 return IA64_RS_MSR;
1471 if (strstr (name, "PKR#") != NULL)
1472 return IA64_RS_PKR;
1473 if (strstr (name, "PMC#") != NULL)
1474 return IA64_RS_PMC;
1475 if (strstr (name, "PMD#") != NULL)
1476 return IA64_RS_PMD;
1477 if (strstr (name, "RR#") != NULL)
1478 return IA64_RS_RR;
1480 warn (_("Don't know how to specify # dependency %s\n"),
1481 name);
1483 else if (startswith (name, "AR[FPSR]"))
1484 return IA64_RS_AR_FPSR;
1485 else if (startswith (name, "AR["))
1486 return IA64_RS_ARX;
1487 else if (startswith (name, "CR["))
1488 return IA64_RS_CRX;
1489 else if (startswith (name, "PSR."))
1490 return IA64_RS_PSR;
1491 else if (strcmp (name, "InService*") == 0)
1492 return IA64_RS_INSERVICE;
1493 else if (strcmp (name, "GR0") == 0)
1494 return IA64_RS_GR0;
1495 else if (strcmp (name, "CFM") == 0)
1496 return IA64_RS_CFM;
1497 else if (strcmp (name, "PR63") == 0)
1498 return IA64_RS_PR63;
1499 else if (strcmp (name, "RSE") == 0)
1500 return IA64_RS_RSE;
1502 return IA64_RS_ANY;
1505 static void
1506 print_dependency_table (void)
1508 int i, j;
1510 if (debug)
1512 for (i=0;i < iclen;i++)
1514 if (ics[i]->is_class)
1516 if (!ics[i]->nsubs)
1518 if (ics[i]->comment)
1519 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1520 ics[i]->name, ics[i]->comment);
1521 else
1522 warn (_("IC:%s has no terminals or sub-classes\n"),
1523 ics[i]->name);
1526 else
1528 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1530 if (ics[i]->comment)
1531 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1532 ics[i]->name, ics[i]->comment);
1533 else
1534 warn (_("no insns mapped directly to terminal IC %s\n"),
1535 ics[i]->name);
1540 for (i = 0; i < iclen; i++)
1542 if (ics[i]->orphan)
1544 mark_used (ics[i], 1);
1545 warn (_("class %s is defined but not used\n"),
1546 ics[i]->name);
1550 if (debug > 1)
1551 for (i = 0; i < rdepslen; i++)
1553 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1555 if (rdeps[i]->total_chks == 0)
1557 if (rdeps[i]->total_regs)
1558 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1559 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1560 else
1561 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1562 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1564 else if (rdeps[i]->total_regs == 0)
1565 warn (_("rsrc %s (%s) has no regs\n"),
1566 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1570 /* The dependencies themselves. */
1571 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1572 for (i = 0; i < rdepslen; i++)
1574 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1575 resource used. */
1576 int specifier = lookup_specifier (rdeps[i]->name);
1577 int regindex = lookup_regindex (rdeps[i]->name, specifier);
1579 printf (" { \"%s\", %d, %d, %d, %d, ",
1580 rdeps[i]->name, specifier,
1581 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1582 if (rdeps[i]->semantics == IA64_DVS_OTHER)
1584 const char *quote, *rest;
1586 putchar ('\"');
1587 rest = rdeps[i]->extra;
1588 quote = strchr (rest, '\"');
1589 while (quote != NULL)
1591 printf ("%.*s\\\"", (int) (quote - rest), rest);
1592 rest = quote + 1;
1593 quote = strchr (rest, '\"');
1595 printf ("%s\", ", rest);
1597 else
1598 printf ("NULL, ");
1599 printf("},\n");
1601 printf ("};\n\n");
1603 /* And dependency lists. */
1604 for (i=0;i < dlistlen;i++)
1606 unsigned int len = (unsigned) -1;
1607 printf ("static const unsigned short dep%d[] = {", i);
1608 for (j=0;j < dlists[i]->len; j++)
1610 if (len > 74)
1612 printf("\n ");
1613 len = 1;
1615 len += printf (" %d,", dlists[i]->deps[j]);
1617 printf ("\n};\n\n");
1620 /* And opcode dependency list. */
1621 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1622 printf ("static const struct ia64_opcode_dependency\n");
1623 printf ("op_dependencies[] = {\n");
1624 for (i = 0; i < opdeplen; i++)
1626 printf (" { ");
1627 if (opdeps[i]->chk == -1)
1628 printf ("0, NULL, ");
1629 else
1630 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1631 if (opdeps[i]->reg == -1)
1632 printf ("0, NULL, ");
1633 else
1634 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1635 printf ("},\n");
1637 printf ("};\n\n");
1641 /* Add STR to the string table. */
1642 static struct string_entry *
1643 insert_string (char *str)
1645 int start = 0, end = strtablen;
1646 int i, x;
1648 if (strtablen == strtabtotlen)
1650 strtabtotlen += 20;
1651 string_table = (struct string_entry **)
1652 xrealloc (string_table,
1653 sizeof (struct string_entry **) * strtabtotlen);
1656 if (strtablen == 0)
1658 strtablen = 1;
1659 string_table[0] = tmalloc (struct string_entry);
1660 string_table[0]->s = xstrdup (str);
1661 string_table[0]->num = 0;
1662 return string_table[0];
1665 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1666 i = end;
1667 else if (strcmp (str, string_table[0]->s) < 0)
1668 i = 0;
1669 else
1671 while (1)
1673 int c;
1675 i = (start + end) / 2;
1676 c = strcmp (str, string_table[i]->s);
1678 if (c < 0)
1679 end = i - 1;
1680 else if (c == 0)
1681 return string_table[i];
1682 else
1683 start = i + 1;
1685 if (start > end)
1686 break;
1690 for (; i > 0 && i < strtablen; i--)
1691 if (strcmp (str, string_table[i - 1]->s) > 0)
1692 break;
1694 for (; i < strtablen; i++)
1695 if (strcmp (str, string_table[i]->s) < 0)
1696 break;
1698 for (x = strtablen - 1; x >= i; x--)
1700 string_table[x + 1] = string_table[x];
1701 string_table[x + 1]->num = x + 1;
1704 string_table[i] = tmalloc (struct string_entry);
1705 string_table[i]->s = xstrdup (str);
1706 string_table[i]->num = i;
1707 strtablen++;
1709 return string_table[i];
1712 static struct bittree *
1713 make_bittree_entry (void)
1715 struct bittree *res = tmalloc (struct bittree);
1717 res->disent = NULL;
1718 res->bits[0] = NULL;
1719 res->bits[1] = NULL;
1720 res->bits[2] = NULL;
1721 res->skip_flag = 0;
1722 res->bits_to_skip = 0;
1723 return res;
1727 static struct disent *
1728 add_dis_table_ent (struct disent *which, int insn, int order,
1729 ci_t completer_index)
1731 int ci = 0;
1732 struct disent *ent;
1734 if (which != NULL)
1736 ent = which;
1738 ent->nextcnt++;
1739 while (ent->nexte != NULL)
1740 ent = ent->nexte;
1742 ent = (ent->nexte = tmalloc (struct disent));
1744 else
1746 ent = tmalloc (struct disent);
1747 ent->next_ent = disinsntable;
1748 disinsntable = ent;
1749 which = ent;
1751 ent->nextcnt = 0;
1752 ent->nexte = NULL;
1753 ent->insn = insn;
1754 ent->priority = order;
1756 while (completer_index != 1)
1758 ci = (ci << 1) | (completer_index & 1);
1759 completer_index >>= 1;
1761 ent->completer_index = ci;
1762 return which;
1765 static void
1766 finish_distable (void)
1768 struct disent *ent = disinsntable;
1769 struct disent *prev = ent;
1771 ent->ournum = 32768;
1772 while ((ent = ent->next_ent) != NULL)
1774 ent->ournum = prev->ournum + prev->nextcnt + 1;
1775 prev = ent;
1779 static void
1780 insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode,
1781 ia64_insn mask, int opcodenum, int order,
1782 ci_t completer_index)
1784 ia64_insn m;
1785 int b;
1786 struct bittree *next;
1788 if (bit == -1)
1790 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1791 opcodenum, order,
1792 completer_index);
1793 curr_ent->disent = nent;
1794 return;
1797 m = ((ia64_insn) 1) << bit;
1799 if (mask & m)
1800 b = (opcode & m) ? 1 : 0;
1801 else
1802 b = 2;
1804 next = curr_ent->bits[b];
1805 if (next == NULL)
1807 next = make_bittree_entry ();
1808 curr_ent->bits[b] = next;
1810 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1811 completer_index);
1814 static void
1815 add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask,
1816 int opcodenum, struct completer_entry *ent, ci_t completer_index)
1818 if (completer_index & ((ci_t)1 << 32) )
1819 abort ();
1821 while (ent != NULL)
1823 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1824 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1825 (completer_index << 1) | 1);
1827 if (ent->is_terminal)
1829 insert_bit_table_ent (bittree, 40, newopcode, mask,
1830 opcodenum, opcode_count - ent->order - 1,
1831 (completer_index << 1) | 1);
1833 completer_index <<= 1;
1834 ent = ent->alternative;
1838 /* This optimization pass combines multiple "don't care" nodes. */
1839 static void
1840 compact_distree (struct bittree *ent)
1842 #define IS_SKIP(ent) \
1843 ((ent->bits[2] !=NULL) \
1844 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1846 int bitcnt = 0;
1847 struct bittree *nent = ent;
1848 int x;
1850 while (IS_SKIP (nent))
1852 bitcnt++;
1853 nent = nent->bits[2];
1856 if (bitcnt)
1858 struct bittree *next = ent->bits[2];
1860 ent->bits[0] = nent->bits[0];
1861 ent->bits[1] = nent->bits[1];
1862 ent->bits[2] = nent->bits[2];
1863 ent->disent = nent->disent;
1864 ent->skip_flag = 1;
1865 ent->bits_to_skip = bitcnt;
1866 while (next != nent)
1868 struct bittree *b = next;
1869 next = next->bits[2];
1870 free (b);
1872 free (nent);
1875 for (x = 0; x < 3; x++)
1877 struct bittree *i = ent->bits[x];
1879 if (i != NULL)
1880 compact_distree (i);
1884 static unsigned char *insn_list;
1885 static int insn_list_len = 0;
1886 static int tot_insn_list_len = 0;
1888 /* Generate the disassembler state machine corresponding to the tree
1889 in ENT. */
1890 static void
1891 gen_dis_table (struct bittree *ent)
1893 int x;
1894 int our_offset = insn_list_len;
1895 int bitsused = 5;
1896 int totbits = bitsused;
1897 int needed_bytes;
1898 int zero_count = 0;
1899 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */
1901 /* If this is a terminal entry, there's no point in skipping any
1902 bits. */
1903 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1904 ent->bits[2] == NULL)
1906 if (ent->disent == NULL)
1907 abort ();
1908 else
1909 ent->skip_flag = 0;
1912 /* Calculate the amount of space needed for this entry, or at least
1913 a conservatively large approximation. */
1914 if (ent->skip_flag)
1915 totbits += 5;
1917 for (x = 1; x < 3; x++)
1918 if (ent->bits[x] != NULL)
1919 totbits += 16;
1921 if (ent->disent != NULL)
1923 if (ent->bits[2] != NULL)
1924 abort ();
1926 totbits += 16;
1929 /* Now allocate the space. */
1930 needed_bytes = (totbits + 7) / 8;
1931 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1933 tot_insn_list_len += 256;
1934 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
1936 our_offset = insn_list_len;
1937 insn_list_len += needed_bytes;
1938 memset (insn_list + our_offset, 0, needed_bytes);
1940 /* Encode the skip entry by setting bit 6 set in the state op field,
1941 and store the # of bits to skip immediately after. */
1942 if (ent->skip_flag)
1944 bitsused += 5;
1945 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1946 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1949 #define IS_ONLY_IFZERO(ENT) \
1950 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1951 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1953 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1954 state op field. */
1955 if (ent->bits[0] != NULL)
1957 struct bittree *nent = ent->bits[0];
1958 zero_count = 0;
1960 insn_list[our_offset] |= 0x80;
1962 /* We can encode sequences of multiple "if (bit is zero)" tests
1963 by storing the # of zero bits to check in the lower 3 bits of
1964 the instruction. However, this only applies if the state
1965 solely tests for a zero bit. */
1967 if (IS_ONLY_IFZERO (ent))
1969 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1971 nent = nent->bits[0];
1972 zero_count++;
1975 insn_list[our_offset + 0] |= zero_count;
1977 zero_dest = insn_list_len;
1978 gen_dis_table (nent);
1981 /* Now store the remaining tests. We also handle a sole "termination
1982 entry" by storing it as an "any bit" test. */
1984 for (x = 1; x < 3; x++)
1986 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1988 struct bittree *i = ent->bits[x];
1989 int idest;
1990 int currbits = 15;
1992 if (i != NULL)
1994 /* If the instruction being branched to only consists of
1995 a termination entry, use the termination entry as the
1996 place to branch to instead. */
1997 if (i->bits[0] == NULL && i->bits[1] == NULL
1998 && i->bits[2] == NULL && i->disent != NULL)
2000 idest = i->disent->ournum;
2001 i = NULL;
2003 else
2004 idest = insn_list_len - our_offset;
2006 else
2007 idest = ent->disent->ournum;
2009 /* If the destination offset for the if (bit is 1) test is less
2010 than 256 bytes away, we can store it as 8-bits instead of 16;
2011 the instruction has bit 5 set for the 16-bit address, and bit
2012 4 for the 8-bit address. Since we've already allocated 16
2013 bits for the address we need to deallocate the space.
2015 Note that branchings within the table are relative, and
2016 there are no branches that branch past our instruction yet
2017 so we do not need to adjust any other offsets. */
2018 if (x == 1)
2020 if (idest <= 256)
2022 int start = our_offset + bitsused / 8 + 1;
2024 memmove (insn_list + start,
2025 insn_list + start + 1,
2026 insn_list_len - (start + 1));
2027 currbits = 7;
2028 totbits -= 8;
2029 needed_bytes--;
2030 insn_list_len--;
2031 insn_list[our_offset] |= 0x10;
2032 idest--;
2034 else
2035 insn_list[our_offset] |= 0x20;
2037 else
2039 /* An instruction which solely consists of a termination
2040 marker and whose disassembly name index is < 4096
2041 can be stored in 16 bits. The encoding is slightly
2042 odd; the upper 4 bits of the instruction are 0x3, and
2043 bit 3 loses its normal meaning. */
2045 if (ent->bits[0] == NULL && ent->bits[1] == NULL
2046 && ent->bits[2] == NULL && ent->skip_flag == 0
2047 && ent->disent != NULL
2048 && ent->disent->ournum < (32768 + 4096))
2050 int start = our_offset + bitsused / 8 + 1;
2052 memmove (insn_list + start,
2053 insn_list + start + 1,
2054 insn_list_len - (start + 1));
2055 currbits = 11;
2056 totbits -= 5;
2057 bitsused--;
2058 needed_bytes--;
2059 insn_list_len--;
2060 insn_list[our_offset] |= 0x30;
2061 idest &= ~32768;
2063 else
2064 insn_list[our_offset] |= 0x08;
2067 if (debug)
2069 int id = idest;
2071 if (i == NULL)
2072 id |= 32768;
2073 else if (! (id & 32768))
2074 id += our_offset;
2076 if (x == 1)
2077 printf ("%d: if (1) goto %d\n", our_offset, id);
2078 else
2079 printf ("%d: try %d\n", our_offset, id);
2082 /* Store the address of the entry being branched to. */
2083 while (currbits >= 0)
2085 unsigned char *byte = insn_list + our_offset + bitsused / 8;
2087 if (idest & (1 << currbits))
2088 *byte |= (1 << (7 - (bitsused % 8)));
2090 bitsused++;
2091 currbits--;
2094 /* Now generate the states for the entry being branched to. */
2095 if (i != NULL)
2096 gen_dis_table (i);
2100 if (debug)
2102 if (ent->skip_flag)
2103 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2105 if (ent->bits[0] != NULL)
2106 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2107 zero_dest);
2110 if (bitsused != totbits)
2111 abort ();
2114 static void
2115 print_dis_table (void)
2117 int x;
2118 struct disent *cent = disinsntable;
2120 printf ("static const char dis_table[] = {");
2121 for (x = 0; x < insn_list_len; x++)
2123 if (x % 12 == 0)
2124 printf ("\n ");
2126 printf (" 0x%02x,", insn_list[x]);
2128 printf ("\n};\n\n");
2130 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2131 while (cent != NULL)
2133 struct disent *ent = cent;
2135 while (ent != NULL)
2137 printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent->completer_index,
2138 ent->insn, (ent->nexte != NULL ? 1 : 0),
2139 ent->priority);
2140 ent = ent->nexte;
2142 cent = cent->next_ent;
2144 printf ("};\n\n");
2147 static void
2148 generate_disassembler (void)
2150 int i;
2152 bittree = make_bittree_entry ();
2154 for (i = 0; i < otlen; i++)
2156 struct main_entry *ptr = ordered_table[i];
2158 if (ptr->opcode->type != IA64_TYPE_DYN)
2159 add_dis_entry (bittree,
2160 ptr->opcode->opcode, ptr->opcode->mask,
2161 ptr->main_index,
2162 ptr->completers, 1);
2165 compact_distree (bittree);
2166 finish_distable ();
2167 gen_dis_table (bittree);
2169 print_dis_table ();
2172 static void
2173 print_string_table (void)
2175 int x;
2176 char lbuf[80], buf[80];
2177 int blen = 0;
2179 printf ("static const char * const ia64_strings[] = {\n");
2180 lbuf[0] = '\0';
2182 for (x = 0; x < strtablen; x++)
2184 int len;
2186 if (strlen (string_table[x]->s) > 75)
2187 abort ();
2189 sprintf (buf, " \"%s\",", string_table[x]->s);
2190 len = strlen (buf);
2192 if ((blen + len) > 75)
2194 printf (" %s\n", lbuf);
2195 lbuf[0] = '\0';
2196 blen = 0;
2198 strcat (lbuf, buf);
2199 blen += len;
2202 if (blen > 0)
2203 printf (" %s\n", lbuf);
2205 printf ("};\n\n");
2208 static struct completer_entry **glist;
2209 static int glistlen = 0;
2210 static int glisttotlen = 0;
2212 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2214 static int
2215 completer_entries_eq (struct completer_entry *ent1,
2216 struct completer_entry *ent2)
2218 while (ent1 != NULL && ent2 != NULL)
2220 if (ent1->name->num != ent2->name->num
2221 || ent1->bits != ent2->bits
2222 || ent1->mask != ent2->mask
2223 || ent1->is_terminal != ent2->is_terminal
2224 || ent1->dependencies != ent2->dependencies
2225 || ent1->order != ent2->order)
2226 return 0;
2228 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2229 return 0;
2231 ent1 = ent1->alternative;
2232 ent2 = ent2->alternative;
2235 return ent1 == ent2;
2238 /* Insert ENT into the global list of completers and return it. If an
2239 equivalent entry (according to completer_entries_eq) already exists,
2240 it is returned instead. */
2241 static struct completer_entry *
2242 insert_gclist (struct completer_entry *ent)
2244 if (ent != NULL)
2246 int i;
2247 int x;
2248 int start = 0, end;
2250 ent->addl_entries = insert_gclist (ent->addl_entries);
2251 ent->alternative = insert_gclist (ent->alternative);
2253 i = glistlen / 2;
2254 end = glistlen;
2256 if (glisttotlen == glistlen)
2258 glisttotlen += 20;
2259 glist = (struct completer_entry **)
2260 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2263 if (glistlen == 0)
2265 glist[0] = ent;
2266 glistlen = 1;
2267 return ent;
2270 if (ent->name->num < glist[0]->name->num)
2271 i = 0;
2272 else if (ent->name->num > glist[end - 1]->name->num)
2273 i = end;
2274 else
2276 int c;
2278 while (1)
2280 i = (start + end) / 2;
2281 c = ent->name->num - glist[i]->name->num;
2283 if (c < 0)
2284 end = i - 1;
2285 else if (c == 0)
2287 while (i > 0
2288 && ent->name->num == glist[i - 1]->name->num)
2289 i--;
2291 break;
2293 else
2294 start = i + 1;
2296 if (start > end)
2297 break;
2300 if (c == 0)
2302 while (i < glistlen)
2304 if (ent->name->num != glist[i]->name->num)
2305 break;
2307 if (completer_entries_eq (ent, glist[i]))
2308 return glist[i];
2310 i++;
2315 for (; i > 0 && i < glistlen; i--)
2316 if (ent->name->num >= glist[i - 1]->name->num)
2317 break;
2319 for (; i < glistlen; i++)
2320 if (ent->name->num < glist[i]->name->num)
2321 break;
2323 for (x = glistlen - 1; x >= i; x--)
2324 glist[x + 1] = glist[x];
2326 glist[i] = ent;
2327 glistlen++;
2329 return ent;
2332 static int
2333 get_prefix_len (const char *name)
2335 char *c;
2337 if (name[0] == '\0')
2338 return 0;
2340 c = strchr (name, '.');
2341 if (c != NULL)
2342 return c - name;
2343 else
2344 return strlen (name);
2347 static void
2348 compute_completer_bits (struct main_entry *ment, struct completer_entry *ent)
2350 while (ent != NULL)
2352 compute_completer_bits (ment, ent->addl_entries);
2354 if (ent->is_terminal)
2356 ia64_insn mask = 0;
2357 ia64_insn our_bits = ent->bits;
2358 struct completer_entry *p = ent->parent;
2359 ia64_insn p_bits;
2360 int x;
2362 while (p != NULL && ! p->is_terminal)
2363 p = p->parent;
2365 if (p != NULL)
2366 p_bits = p->bits;
2367 else
2368 p_bits = ment->opcode->opcode;
2370 for (x = 0; x < 64; x++)
2372 ia64_insn m = ((ia64_insn) 1) << x;
2374 if ((p_bits & m) != (our_bits & m))
2375 mask |= m;
2376 else
2377 our_bits &= ~m;
2379 ent->bits = our_bits;
2380 ent->mask = mask;
2382 else
2384 ent->bits = 0;
2385 ent->mask = 0;
2388 ent = ent->alternative;
2392 /* Find identical completer trees that are used in different
2393 instructions and collapse their entries. */
2394 static void
2395 collapse_redundant_completers (void)
2397 struct main_entry *ptr;
2398 int x;
2400 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2402 if (ptr->completers == NULL)
2403 abort ();
2405 compute_completer_bits (ptr, ptr->completers);
2406 ptr->completers = insert_gclist (ptr->completers);
2409 /* The table has been finalized, now number the indexes. */
2410 for (x = 0; x < glistlen; x++)
2411 glist[x]->num = x;
2415 /* Attach two lists of dependencies to each opcode.
2416 1) all resources which, when already marked in use, conflict with this
2417 opcode (chks)
2418 2) all resources which must be marked in use when this opcode is used
2419 (regs). */
2420 static int
2421 insert_opcode_dependencies (struct ia64_opcode *opc,
2422 struct completer_entry *cmp ATTRIBUTE_UNUSED)
2424 /* Note all resources which point to this opcode. rfi has the most chks
2425 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2426 int i;
2427 int nregs = 0;
2428 unsigned short regs[256];
2429 int nchks = 0;
2430 unsigned short chks[256];
2431 /* Flag insns for which no class matched; there should be none. */
2432 int no_class_found = 1;
2434 for (i = 0; i < rdepslen; i++)
2436 struct rdep *rs = rdeps[i];
2437 int j;
2439 if (strcmp (opc->name, "cmp.eq.and") == 0
2440 && startswith (rs->name, "PR%")
2441 && rs->mode == 1)
2442 no_class_found = 99;
2444 for (j=0; j < rs->nregs;j++)
2446 int ic_note = 0;
2448 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2450 /* We can ignore ic_note 11 for non PR resources. */
2451 if (ic_note == 11 && ! startswith (rs->name, "PR"))
2452 ic_note = 0;
2454 if (ic_note != 0 && rs->regnotes[j] != 0
2455 && ic_note != rs->regnotes[j]
2456 && !(ic_note == 11 && rs->regnotes[j] == 1))
2457 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2458 ic_note, opc->name, ics[rs->regs[j]]->name,
2459 rs->name, rs->regnotes[j]);
2460 /* Instruction class notes override resource notes.
2461 So far, only note 11 applies to an IC instead of a resource,
2462 and note 11 implies note 1. */
2463 if (ic_note)
2464 regs[nregs++] = RDEP(ic_note, i);
2465 else
2466 regs[nregs++] = RDEP(rs->regnotes[j], i);
2467 no_class_found = 0;
2468 ++rs->total_regs;
2472 for (j = 0; j < rs->nchks; j++)
2474 int ic_note = 0;
2476 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2478 /* We can ignore ic_note 11 for non PR resources. */
2479 if (ic_note == 11 && ! startswith (rs->name, "PR"))
2480 ic_note = 0;
2482 if (ic_note != 0 && rs->chknotes[j] != 0
2483 && ic_note != rs->chknotes[j]
2484 && !(ic_note == 11 && rs->chknotes[j] == 1))
2485 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2486 ic_note, opc->name, ics[rs->chks[j]]->name,
2487 rs->name, rs->chknotes[j]);
2488 if (ic_note)
2489 chks[nchks++] = RDEP(ic_note, i);
2490 else
2491 chks[nchks++] = RDEP(rs->chknotes[j], i);
2492 no_class_found = 0;
2493 ++rs->total_chks;
2498 if (no_class_found)
2499 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2500 opc->name,
2501 opc->operands[0], opc->operands[1], opc->operands[2]);
2503 return insert_dependencies (nchks, chks, nregs, regs);
2506 static void
2507 insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent,
2508 int order)
2510 struct completer_entry **ptr = &tabent->completers;
2511 struct completer_entry *parent = NULL;
2512 char pcopy[129], *prefix;
2513 int at_end = 0;
2515 if (strlen (opc->name) > 128)
2516 abort ();
2518 strcpy (pcopy, opc->name);
2519 prefix = pcopy + get_prefix_len (pcopy);
2521 if (prefix[0] != '\0')
2522 prefix++;
2524 while (! at_end)
2526 int need_new_ent = 1;
2527 int plen = get_prefix_len (prefix);
2528 struct string_entry *sent;
2530 at_end = (prefix[plen] == '\0');
2531 prefix[plen] = '\0';
2532 sent = insert_string (prefix);
2534 while (*ptr != NULL)
2536 int cmpres = sent->num - (*ptr)->name->num;
2538 if (cmpres == 0)
2540 need_new_ent = 0;
2541 break;
2543 else
2544 ptr = &((*ptr)->alternative);
2547 if (need_new_ent)
2549 struct completer_entry *nent = tmalloc (struct completer_entry);
2551 nent->name = sent;
2552 nent->parent = parent;
2553 nent->addl_entries = NULL;
2554 nent->alternative = *ptr;
2555 *ptr = nent;
2556 nent->is_terminal = 0;
2557 nent->dependencies = -1;
2560 if (! at_end)
2562 parent = *ptr;
2563 ptr = &((*ptr)->addl_entries);
2564 prefix += plen + 1;
2568 if ((*ptr)->is_terminal)
2569 abort ();
2571 (*ptr)->is_terminal = 1;
2572 (*ptr)->mask = (ia64_insn)-1;
2573 (*ptr)->bits = opc->opcode;
2574 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2575 (*ptr)->order = order;
2578 static void
2579 print_completer_entry (struct completer_entry *ent)
2581 int moffset = 0;
2582 ia64_insn mask = ent->mask, bits = ent->bits;
2584 if (mask != 0)
2586 while (! (mask & 1))
2588 moffset++;
2589 mask = mask >> 1;
2590 bits = bits >> 1;
2593 if (bits & 0xffffffff00000000LL)
2594 abort ();
2597 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2598 (int)bits,
2599 (int)mask,
2600 ent->name->num,
2601 ent->alternative != NULL ? ent->alternative->num : -1,
2602 ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2603 moffset,
2604 ent->is_terminal ? 1 : 0,
2605 ent->dependencies);
2608 static void
2609 print_completer_table (void)
2611 int x;
2613 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2614 for (x = 0; x < glistlen; x++)
2615 print_completer_entry (glist[x]);
2616 printf ("};\n\n");
2619 static int
2620 opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2)
2622 int x;
2623 int plen1, plen2;
2625 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2626 || (opc1->num_outputs != opc2->num_outputs)
2627 || (opc1->flags != opc2->flags))
2628 return 0;
2630 for (x = 0; x < 5; x++)
2631 if (opc1->operands[x] != opc2->operands[x])
2632 return 0;
2634 plen1 = get_prefix_len (opc1->name);
2635 plen2 = get_prefix_len (opc2->name);
2637 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2638 return 1;
2640 return 0;
2643 static void
2644 add_opcode_entry (struct ia64_opcode *opc)
2646 struct main_entry **place;
2647 struct string_entry *name;
2648 char prefix[129];
2649 int found_it = 0;
2651 if (strlen (opc->name) > 128)
2652 abort ();
2654 place = &maintable;
2655 strcpy (prefix, opc->name);
2656 prefix[get_prefix_len (prefix)] = '\0';
2657 name = insert_string (prefix);
2659 /* Walk the list of opcode table entries. If it's a new
2660 instruction, allocate and fill in a new entry. Note
2661 the main table is alphabetical by opcode name. */
2663 while (*place != NULL)
2665 if ((*place)->name->num == name->num
2666 && opcodes_eq ((*place)->opcode, opc))
2668 found_it = 1;
2669 break;
2671 if ((*place)->name->num > name->num)
2672 break;
2674 place = &((*place)->next);
2676 if (! found_it)
2678 struct main_entry *nent = tmalloc (struct main_entry);
2680 nent->name = name;
2681 nent->opcode = opc;
2682 nent->next = *place;
2683 nent->completers = 0;
2684 *place = nent;
2686 if (otlen == ottotlen)
2688 ottotlen += 20;
2689 ordered_table = (struct main_entry **)
2690 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2692 ordered_table[otlen++] = nent;
2695 insert_completer_entry (opc, *place, opcode_count++);
2698 static void
2699 print_main_table (void)
2701 struct main_entry *ptr = maintable;
2702 int tindex = 0;
2704 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2705 while (ptr != NULL)
2707 printf (" { %d, %d, %d, 0x%016" PRIx64 "ull, 0x%016" PRIx64
2708 "ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2709 ptr->name->num,
2710 ptr->opcode->type,
2711 ptr->opcode->num_outputs,
2712 ptr->opcode->opcode,
2713 ptr->opcode->mask,
2714 ptr->opcode->operands[0],
2715 ptr->opcode->operands[1],
2716 ptr->opcode->operands[2],
2717 ptr->opcode->operands[3],
2718 ptr->opcode->operands[4],
2719 ptr->opcode->flags,
2720 ptr->completers->num);
2722 ptr->main_index = tindex++;
2724 ptr = ptr->next;
2726 printf ("};\n\n");
2729 static void
2730 shrink (struct ia64_opcode *table)
2732 int curr_opcode;
2734 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2736 add_opcode_entry (table + curr_opcode);
2737 if (table[curr_opcode].num_outputs == 2
2738 && ((table[curr_opcode].operands[0] == IA64_OPND_P1
2739 && table[curr_opcode].operands[1] == IA64_OPND_P2)
2740 || (table[curr_opcode].operands[0] == IA64_OPND_P2
2741 && table[curr_opcode].operands[1] == IA64_OPND_P1)))
2743 struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2744 unsigned i;
2746 *alias = table[curr_opcode];
2747 for (i = 2; i < NELEMS (alias->operands); ++i)
2748 alias->operands[i - 1] = alias->operands[i];
2749 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2750 --alias->num_outputs;
2751 alias->flags |= PSEUDO;
2752 add_opcode_entry (alias);
2758 /* Program options. */
2759 #define OPTION_SRCDIR 200
2761 struct option long_options[] =
2763 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2764 {"debug", no_argument, NULL, 'd'},
2765 {"version", no_argument, NULL, 'V'},
2766 {"help", no_argument, NULL, 'h'},
2767 {0, no_argument, NULL, 0}
2770 static void
2771 print_version (void)
2773 printf ("%s: version 1.0\n", program_name);
2774 xexit (0);
2777 static void
2778 usage (FILE * stream, int status)
2780 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2781 program_name);
2782 xexit (status);
2786 main (int argc, char **argv)
2788 extern int chdir (char *);
2789 char *srcdir = NULL;
2790 int c;
2792 program_name = *argv;
2793 xmalloc_set_program_name (program_name);
2795 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2796 switch (c)
2798 case OPTION_SRCDIR:
2799 srcdir = optarg;
2800 break;
2801 case 'V':
2802 case 'v':
2803 print_version ();
2804 break;
2805 case 'd':
2806 debug = 1;
2807 break;
2808 case 'h':
2809 case '?':
2810 usage (stderr, 0);
2811 default:
2812 case 0:
2813 break;
2816 if (optind != argc)
2817 usage (stdout, 1);
2819 if (srcdir != NULL)
2820 if (chdir (srcdir) != 0)
2821 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2822 srcdir, strerror (errno));
2824 load_insn_classes ();
2825 load_dependencies ();
2827 shrink (ia64_opcodes_a);
2828 shrink (ia64_opcodes_b);
2829 shrink (ia64_opcodes_f);
2830 shrink (ia64_opcodes_i);
2831 shrink (ia64_opcodes_m);
2832 shrink (ia64_opcodes_x);
2833 shrink (ia64_opcodes_d);
2835 collapse_redundant_completers ();
2837 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2838 printf ("/* Copyright (C) 2007-2024 Free Software Foundation, Inc.\n\
2840 This file is part of the GNU opcodes library.\n\
2842 This library is free software; you can redistribute it and/or modify\n\
2843 it under the terms of the GNU General Public License as published by\n\
2844 the Free Software Foundation; either version 3, or (at your option)\n\
2845 any later version.\n\
2847 It is distributed in the hope that it will be useful, but WITHOUT\n\
2848 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2849 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2850 License for more details.\n\
2852 You should have received a copy of the GNU General Public License\n\
2853 along with this program; see the file COPYING. If not, write to the\n\
2854 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2855 02110-1301, USA. */\n");
2857 print_string_table ();
2858 print_dependency_table ();
2859 print_completer_table ();
2860 print_main_table ();
2862 generate_disassembler ();
2864 exit (0);