2005-09-01 Dmitry Diky <diwil@spec.ru>
[binutils.git] / opcodes / ia64-gen.c
blobe12c145bea142b758f4c9caf8cf6eb2033cc79ab
1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005
3 Free Software Foundation, Inc.
4 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
6 This file is part of GDB, GAS, and the GNU binutils.
8 GDB, GAS, and the GNU binutils are free software; you can redistribute
9 them and/or modify them under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version
11 2, or (at your option) any later version.
13 GDB, GAS, and the GNU binutils are distributed in the hope that they
14 will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 the GNU General Public License for more details.
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
20 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 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 <stdio.h>
37 #include <stdarg.h>
38 #include <errno.h>
40 #include "ansidecl.h"
41 #include "libiberty.h"
42 #include "safe-ctype.h"
43 #include "sysdep.h"
44 #include "getopt.h"
45 #include "ia64-opc.h"
46 #include "ia64-opc-a.c"
47 #include "ia64-opc-i.c"
48 #include "ia64-opc-m.c"
49 #include "ia64-opc-b.c"
50 #include "ia64-opc-f.c"
51 #include "ia64-opc-x.c"
52 #include "ia64-opc-d.c"
54 #include <libintl.h>
55 #define _(String) gettext (String)
57 const char * program_name = NULL;
58 int debug = 0;
60 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
61 #define tmalloc(X) (X *) xmalloc (sizeof (X))
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 int 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, int);
285 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int);
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, int);
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 (strncmp (full_name, "IC:", 3) == 0)
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 fgets (buf, sizeof(buf), fp);
612 while (!feof (fp))
614 int iclass;
615 char *name;
616 char *tmp;
618 if (fgets (buf, sizeof (buf), fp) == NULL)
619 break;
621 while (ISSPACE (buf[strlen (buf) - 1]))
622 buf[strlen (buf) - 1] = '\0';
624 name = tmp = buf;
625 while (*tmp != ';')
627 ++tmp;
628 if (tmp == buf + sizeof (buf))
629 abort ();
631 *tmp++ = '\0';
633 iclass = fetch_insn_class (name, 1);
634 ics[iclass]->is_class = 1;
636 if (strcmp (name, "none") == 0)
638 ics[iclass]->is_class = 0;
639 ics[iclass]->terminal_resolved = 1;
640 continue;
643 /* For this class, record all sub-classes. */
644 while (*tmp)
646 char *subname;
647 int sub;
649 while (*tmp && ISSPACE (*tmp))
651 ++tmp;
652 if (tmp == buf + sizeof (buf))
653 abort ();
655 subname = tmp;
656 while (*tmp && *tmp != ',')
658 ++tmp;
659 if (tmp == buf + sizeof (buf))
660 abort ();
662 if (*tmp == ',')
663 *tmp++ = '\0';
665 ics[iclass]->subs = (int *)
666 xrealloc ((void *)ics[iclass]->subs,
667 (ics[iclass]->nsubs + 1) * sizeof (int));
669 sub = fetch_insn_class (subname, 1);
670 ics[iclass]->subs = (int *)
671 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int));
672 ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
675 /* Make sure classes come before terminals. */
676 qsort ((void *)ics[iclass]->subs,
677 ics[iclass]->nsubs, sizeof(int), sub_compare);
679 fclose (fp);
681 if (debug)
682 printf ("%d classes\n", iclen);
685 /* Extract the insn classes from the given line. */
686 static void
687 parse_resource_users (ref, usersp, nusersp, notesp)
688 const char *ref;
689 int **usersp;
690 int *nusersp;
691 int **notesp;
693 int c;
694 char *line = xstrdup (ref);
695 char *tmp = line;
696 int *users = *usersp;
697 int count = *nusersp;
698 int *notes = *notesp;
700 c = *tmp;
701 while (c != 0)
703 char *notestr;
704 int note;
705 char *xsect;
706 int iclass;
707 int create = 0;
708 char *name;
710 while (ISSPACE (*tmp))
711 ++tmp;
712 name = tmp;
713 while (*tmp && *tmp != ',')
714 ++tmp;
715 c = *tmp;
716 *tmp++ = '\0';
718 xsect = strchr (name, '\\');
719 if ((notestr = strstr (name, "+")) != NULL)
721 char *nextnotestr;
723 note = atoi (notestr + 1);
724 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
726 /* Note 13 always implies note 1. */
727 if (strcmp (notestr, "+1+13") == 0)
728 note = 13;
729 else if (!xsect || nextnotestr < xsect)
730 warn (_("multiple note %s not handled\n"), notestr);
732 if (!xsect)
733 *notestr = '\0';
735 else
736 note = 0;
738 /* All classes are created when the insn class table is parsed;
739 Individual instructions might not appear until the dependency tables
740 are read. Only create new classes if it's *not* an insn class,
741 or if it's a composite class (which wouldn't necessarily be in the IC
742 table). */
743 if (strncmp (name, "IC:", 3) != 0 || xsect != NULL)
744 create = 1;
746 iclass = fetch_insn_class (name, create);
747 if (iclass != -1)
749 users = (int *)
750 xrealloc ((void *) users,(count + 1) * sizeof (int));
751 notes = (int *)
752 xrealloc ((void *) notes,(count + 1) * sizeof (int));
753 notes[count] = note;
754 users[count++] = iclass;
755 mark_used (ics[iclass], 0);
757 else if (debug)
758 printf("Class %s not found\n", name);
760 /* Update the return values. */
761 *usersp = users;
762 *nusersp = count;
763 *notesp = notes;
765 free (line);
768 static int
769 parse_semantics (char *sem)
771 if (strcmp (sem, "none") == 0)
772 return IA64_DVS_NONE;
773 else if (strcmp (sem, "implied") == 0)
774 return IA64_DVS_IMPLIED;
775 else if (strcmp (sem, "impliedF") == 0)
776 return IA64_DVS_IMPLIEDF;
777 else if (strcmp (sem, "data") == 0)
778 return IA64_DVS_DATA;
779 else if (strcmp (sem, "instr") == 0)
780 return IA64_DVS_INSTR;
781 else if (strcmp (sem, "specific") == 0)
782 return IA64_DVS_SPECIFIC;
783 else if (strcmp (sem, "stop") == 0)
784 return IA64_DVS_STOP;
785 else
786 return IA64_DVS_OTHER;
789 static void
790 add_dep (const char *name, const char *chk, const char *reg,
791 int semantics, int mode, char *extra, int flag)
793 struct rdep *rs;
795 rs = insert_resource (name, mode);
797 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
798 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
800 rs->semantics = semantics;
801 rs->extra = extra;
802 rs->waw_special = flag;
805 static void
806 load_depfile (const char *filename, enum ia64_dependency_mode mode)
808 FILE *fp = fopen (filename, "r");
809 char buf[1024];
811 if (fp == NULL)
812 fail (_("can't find %s for reading\n"), filename);
814 fgets (buf, sizeof(buf), fp);
815 while (!feof (fp))
817 char *name, *tmp;
818 int semantics;
819 char *extra;
820 char *regp, *chkp;
822 if (fgets (buf, sizeof(buf), fp) == NULL)
823 break;
825 while (ISSPACE (buf[strlen (buf) - 1]))
826 buf[strlen (buf) - 1] = '\0';
828 name = tmp = buf;
829 while (*tmp != ';')
830 ++tmp;
831 *tmp++ = '\0';
833 while (ISSPACE (*tmp))
834 ++tmp;
835 regp = tmp;
836 tmp = strchr (tmp, ';');
837 if (!tmp)
838 abort ();
839 *tmp++ = 0;
840 while (ISSPACE (*tmp))
841 ++tmp;
842 chkp = tmp;
843 tmp = strchr (tmp, ';');
844 if (!tmp)
845 abort ();
846 *tmp++ = 0;
847 while (ISSPACE (*tmp))
848 ++tmp;
849 semantics = parse_semantics (tmp);
850 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
852 /* For WAW entries, if the chks and regs differ, we need to enter the
853 entries in both positions so that the tables will be parsed properly,
854 without a lot of extra work. */
855 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
857 add_dep (name, chkp, regp, semantics, mode, extra, 0);
858 add_dep (name, regp, chkp, semantics, mode, extra, 1);
860 else
862 add_dep (name, chkp, regp, semantics, mode, extra, 0);
865 fclose (fp);
868 static void
869 load_dependencies (void)
871 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
872 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
873 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
875 if (debug)
876 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
879 /* Is the given operand an indirect register file operand? */
880 static int
881 irf_operand (int op, const char *field)
883 if (!field)
885 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
886 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
887 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
888 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
890 else
892 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
893 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
894 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
895 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
896 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
897 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
898 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
899 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
903 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
904 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 'i':
963 if (ic->name[5] == 'n')
965 int m42 = plain_mov && irf_operand (idesc->operands[0], field);
966 int m43 = plain_mov && irf_operand (idesc->operands[1], field);
967 if (m42)
968 return strstr (format, "M42") != NULL;
969 if (m43)
970 return strstr (format, "M43") != NULL;
972 else if (ic->name[5] == 'p')
974 return idesc->operands[1] == IA64_OPND_IP;
976 else
977 abort ();
978 break;
979 case 'p':
980 if (ic->name[5] == 'r')
982 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
983 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
984 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
985 if (i23)
986 return strstr (format, "I23") != NULL;
987 if (i24)
988 return strstr (format, "I24") != NULL;
989 if (i25)
990 return strstr (format, "I25") != NULL;
992 else if (ic->name[5] == 's')
994 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
995 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
996 if (m35)
997 return strstr (format, "M35") != NULL;
998 if (m36)
999 return strstr (format, "M36") != NULL;
1001 else
1002 abort ();
1003 break;
1004 case 'u':
1006 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
1007 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
1008 if (m35)
1009 return strstr (format, "M35") != NULL;
1010 if (m36)
1011 return strstr (format, "M36") != NULL;
1013 break;
1015 return 0;
1018 /* Is the given opcode in the given insn class? */
1019 static int
1020 in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1021 const char *format, const char *field, int *notep)
1023 int i;
1024 int resolved = 0;
1026 if (ic->comment)
1028 if (!strncmp (ic->comment, "Format", 6))
1030 /* Assume that the first format seen is the most restrictive, and
1031 only keep a later one if it looks like it's more restrictive. */
1032 if (format)
1034 if (strlen (ic->comment) < strlen (format))
1036 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1037 ic->comment, format);
1038 format = ic->comment;
1041 else
1042 format = ic->comment;
1044 else if (!strncmp (ic->comment, "Field", 5))
1046 if (field)
1047 warn (_("overlapping field %s->%s\n"),
1048 ic->comment, field);
1049 field = ic->comment;
1053 /* An insn class matches anything that is the same followed by completers,
1054 except when the absence and presence of completers constitutes different
1055 instructions. */
1056 if (ic->nsubs == 0 && ic->nxsubs == 0)
1058 int is_mov = strncmp (idesc->name, "mov", 3) == 0;
1059 int plain_mov = strcmp (idesc->name, "mov") == 0;
1060 int len = strlen(ic->name);
1062 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1063 && (idesc->name[len] == '\0'
1064 || idesc->name[len] == '.'));
1066 /* All break, nop, and hint variations must match exactly. */
1067 if (resolved &&
1068 (strcmp (ic->name, "break") == 0
1069 || strcmp (ic->name, "nop") == 0
1070 || strcmp (ic->name, "hint") == 0))
1071 resolved = strcmp (ic->name, idesc->name) == 0;
1073 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1074 unless specifically allowed by clauses in this block. */
1075 if (resolved && field)
1077 /* Check Field(sf)==sN against opcode sN. */
1078 if (strstr(field, "(sf)==") != NULL)
1080 char *sf;
1082 if ((sf = strstr (idesc->name, ".s")) != 0)
1083 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1085 /* Check Field(lftype)==XXX. */
1086 else if (strstr (field, "(lftype)") != NULL)
1088 if (strstr (idesc->name, "fault") != NULL)
1089 resolved = strstr (field, "fault") != NULL;
1090 else
1091 resolved = strstr (field, "fault") == NULL;
1093 /* Handle Field(ctype)==XXX. */
1094 else if (strstr (field, "(ctype)") != NULL)
1096 if (strstr (idesc->name, "or.andcm"))
1097 resolved = strstr (field, "or.andcm") != NULL;
1098 else if (strstr (idesc->name, "and.orcm"))
1099 resolved = strstr (field, "and.orcm") != NULL;
1100 else if (strstr (idesc->name, "orcm"))
1101 resolved = strstr (field, "or orcm") != NULL;
1102 else if (strstr (idesc->name, "or"))
1103 resolved = strstr (field, "or orcm") != NULL;
1104 else if (strstr (idesc->name, "andcm"))
1105 resolved = strstr (field, "and andcm") != NULL;
1106 else if (strstr (idesc->name, "and"))
1107 resolved = strstr (field, "and andcm") != NULL;
1108 else if (strstr (idesc->name, "unc"))
1109 resolved = strstr (field, "unc") != NULL;
1110 else
1111 resolved = strcmp (field, "Field(ctype)==") == 0;
1115 if (resolved && format)
1117 if (strncmp (idesc->name, "dep", 3) == 0
1118 && strstr (format, "I13") != NULL)
1119 resolved = idesc->operands[1] == IA64_OPND_IMM8;
1120 else if (strncmp (idesc->name, "chk", 3) == 0
1121 && strstr (format, "M21") != NULL)
1122 resolved = idesc->operands[0] == IA64_OPND_F2;
1123 else if (strncmp (idesc->name, "lfetch", 6) == 0)
1124 resolved = (strstr (format, "M14 M15") != NULL
1125 && (idesc->operands[1] == IA64_OPND_R2
1126 || idesc->operands[1] == IA64_OPND_IMM9b));
1127 else if (strncmp (idesc->name, "br.call", 7) == 0
1128 && strstr (format, "B5") != NULL)
1129 resolved = idesc->operands[1] == IA64_OPND_B2;
1130 else if (strncmp (idesc->name, "br.call", 7) == 0
1131 && strstr (format, "B3") != NULL)
1132 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1133 else if (strncmp (idesc->name, "brp", 3) == 0
1134 && strstr (format, "B7") != NULL)
1135 resolved = idesc->operands[0] == IA64_OPND_B2;
1136 else if (strcmp (ic->name, "invala") == 0)
1137 resolved = strcmp (idesc->name, ic->name) == 0;
1138 else if (strncmp (idesc->name, "st", 2) == 0
1139 && (strstr (format, "M5") != NULL
1140 || strstr (format, "M10") != NULL))
1141 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1142 else if (strncmp (idesc->name, "ld", 2) == 0
1143 && (strstr (format, "M2 M3") != NULL
1144 || strstr (format, "M12") != NULL
1145 || strstr (format, "M7 M8") != NULL))
1146 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1147 else
1148 resolved = 0;
1151 /* Misc brl variations ('.cond' is optional);
1152 plain brl matches brl.cond. */
1153 if (!resolved
1154 && (strcmp (idesc->name, "brl") == 0
1155 || strncmp (idesc->name, "brl.", 4) == 0)
1156 && strcmp (ic->name, "brl.cond") == 0)
1158 resolved = 1;
1161 /* Misc br variations ('.cond' is optional). */
1162 if (!resolved
1163 && (strcmp (idesc->name, "br") == 0
1164 || strncmp (idesc->name, "br.", 3) == 0)
1165 && strcmp (ic->name, "br.cond") == 0)
1167 if (format)
1168 resolved = (strstr (format, "B4") != NULL
1169 && idesc->operands[0] == IA64_OPND_B2)
1170 || (strstr (format, "B1") != NULL
1171 && idesc->operands[0] == IA64_OPND_TGT25c);
1172 else
1173 resolved = 1;
1176 /* probe variations. */
1177 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1179 resolved = strcmp (ic->name, "probe") == 0
1180 && !((strstr (idesc->name, "fault") != NULL)
1181 ^ (format && strstr (format, "M40") != NULL));
1184 /* mov variations. */
1185 if (!resolved && is_mov)
1187 if (plain_mov)
1189 /* mov alias for fmerge. */
1190 if (strcmp (ic->name, "fmerge") == 0)
1192 resolved = idesc->operands[0] == IA64_OPND_F1
1193 && idesc->operands[1] == IA64_OPND_F3;
1195 /* mov alias for adds (r3 or imm14). */
1196 else if (strcmp (ic->name, "adds") == 0)
1198 resolved = (idesc->operands[0] == IA64_OPND_R1
1199 && (idesc->operands[1] == IA64_OPND_R3
1200 || (idesc->operands[1] == IA64_OPND_IMM14)));
1202 /* mov alias for addl. */
1203 else if (strcmp (ic->name, "addl") == 0)
1205 resolved = idesc->operands[0] == IA64_OPND_R1
1206 && idesc->operands[1] == IA64_OPND_IMM22;
1210 /* Some variants of mov and mov.[im]. */
1211 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1212 resolved = in_iclass_mov_x (idesc, ic, format, field);
1215 /* Keep track of this so we can flag any insn classes which aren't
1216 mapped onto at least one real insn. */
1217 if (resolved)
1218 ic->terminal_resolved = 1;
1220 else for (i = 0; i < ic->nsubs; i++)
1222 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1224 int j;
1226 for (j = 0; j < ic->nxsubs; j++)
1227 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1228 return 0;
1230 if (debug > 1)
1231 printf ("%s is in IC %s\n", idesc->name, ic->name);
1233 resolved = 1;
1234 break;
1238 /* If it's in this IC, add the IC note (if any) to the insn. */
1239 if (resolved)
1241 if (ic->note && notep)
1243 if (*notep && *notep != ic->note)
1244 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1245 *notep, ic->note, ic->name);
1247 *notep = ic->note;
1251 return resolved;
1255 static int
1256 lookup_regindex (const char *name, int specifier)
1258 switch (specifier)
1260 case IA64_RS_ARX:
1261 if (strstr (name, "[RSC]"))
1262 return 16;
1263 if (strstr (name, "[BSP]"))
1264 return 17;
1265 else if (strstr (name, "[BSPSTORE]"))
1266 return 18;
1267 else if (strstr (name, "[RNAT]"))
1268 return 19;
1269 else if (strstr (name, "[FCR]"))
1270 return 21;
1271 else if (strstr (name, "[EFLAG]"))
1272 return 24;
1273 else if (strstr (name, "[CSD]"))
1274 return 25;
1275 else if (strstr (name, "[SSD]"))
1276 return 26;
1277 else if (strstr (name, "[CFLG]"))
1278 return 27;
1279 else if (strstr (name, "[FSR]"))
1280 return 28;
1281 else if (strstr (name, "[FIR]"))
1282 return 29;
1283 else if (strstr (name, "[FDR]"))
1284 return 30;
1285 else if (strstr (name, "[CCV]"))
1286 return 32;
1287 else if (strstr (name, "[ITC]"))
1288 return 44;
1289 else if (strstr (name, "[PFS]"))
1290 return 64;
1291 else if (strstr (name, "[LC]"))
1292 return 65;
1293 else if (strstr (name, "[EC]"))
1294 return 66;
1295 abort ();
1296 case IA64_RS_CRX:
1297 if (strstr (name, "[DCR]"))
1298 return 0;
1299 else if (strstr (name, "[ITM]"))
1300 return 1;
1301 else if (strstr (name, "[IVA]"))
1302 return 2;
1303 else if (strstr (name, "[PTA]"))
1304 return 8;
1305 else if (strstr (name, "[GPTA]"))
1306 return 9;
1307 else if (strstr (name, "[IPSR]"))
1308 return 16;
1309 else if (strstr (name, "[ISR]"))
1310 return 17;
1311 else if (strstr (name, "[IIP]"))
1312 return 19;
1313 else if (strstr (name, "[IFA]"))
1314 return 20;
1315 else if (strstr (name, "[ITIR]"))
1316 return 21;
1317 else if (strstr (name, "[IIPA]"))
1318 return 22;
1319 else if (strstr (name, "[IFS]"))
1320 return 23;
1321 else if (strstr (name, "[IIM]"))
1322 return 24;
1323 else if (strstr (name, "[IHA]"))
1324 return 25;
1325 else if (strstr (name, "[LID]"))
1326 return 64;
1327 else if (strstr (name, "[IVR]"))
1328 return 65;
1329 else if (strstr (name, "[TPR]"))
1330 return 66;
1331 else if (strstr (name, "[EOI]"))
1332 return 67;
1333 else if (strstr (name, "[ITV]"))
1334 return 72;
1335 else if (strstr (name, "[PMV]"))
1336 return 73;
1337 else if (strstr (name, "[CMCV]"))
1338 return 74;
1339 abort ();
1340 case IA64_RS_PSR:
1341 if (strstr (name, ".be"))
1342 return 1;
1343 else if (strstr (name, ".up"))
1344 return 2;
1345 else if (strstr (name, ".ac"))
1346 return 3;
1347 else if (strstr (name, ".mfl"))
1348 return 4;
1349 else if (strstr (name, ".mfh"))
1350 return 5;
1351 else if (strstr (name, ".ic"))
1352 return 13;
1353 else if (strstr (name, ".i"))
1354 return 14;
1355 else if (strstr (name, ".pk"))
1356 return 15;
1357 else if (strstr (name, ".dt"))
1358 return 17;
1359 else if (strstr (name, ".dfl"))
1360 return 18;
1361 else if (strstr (name, ".dfh"))
1362 return 19;
1363 else if (strstr (name, ".sp"))
1364 return 20;
1365 else if (strstr (name, ".pp"))
1366 return 21;
1367 else if (strstr (name, ".di"))
1368 return 22;
1369 else if (strstr (name, ".si"))
1370 return 23;
1371 else if (strstr (name, ".db"))
1372 return 24;
1373 else if (strstr (name, ".lp"))
1374 return 25;
1375 else if (strstr (name, ".tb"))
1376 return 26;
1377 else if (strstr (name, ".rt"))
1378 return 27;
1379 else if (strstr (name, ".cpl"))
1380 return 32;
1381 else if (strstr (name, ".rs"))
1382 return 34;
1383 else if (strstr (name, ".mc"))
1384 return 35;
1385 else if (strstr (name, ".it"))
1386 return 36;
1387 else if (strstr (name, ".id"))
1388 return 37;
1389 else if (strstr (name, ".da"))
1390 return 38;
1391 else if (strstr (name, ".dd"))
1392 return 39;
1393 else if (strstr (name, ".ss"))
1394 return 40;
1395 else if (strstr (name, ".ri"))
1396 return 41;
1397 else if (strstr (name, ".ed"))
1398 return 43;
1399 else if (strstr (name, ".bn"))
1400 return 44;
1401 else if (strstr (name, ".ia"))
1402 return 45;
1403 else
1404 abort ();
1405 default:
1406 break;
1408 return REG_NONE;
1411 static int
1412 lookup_specifier (const char *name)
1414 if (strchr (name, '%'))
1416 if (strstr (name, "AR[K%]") != NULL)
1417 return IA64_RS_AR_K;
1418 if (strstr (name, "AR[UNAT]") != NULL)
1419 return IA64_RS_AR_UNAT;
1420 if (strstr (name, "AR%, % in 8") != NULL)
1421 return IA64_RS_AR;
1422 if (strstr (name, "AR%, % in 48") != NULL)
1423 return IA64_RS_ARb;
1424 if (strstr (name, "BR%") != NULL)
1425 return IA64_RS_BR;
1426 if (strstr (name, "CR[IRR%]") != NULL)
1427 return IA64_RS_CR_IRR;
1428 if (strstr (name, "CR[LRR%]") != NULL)
1429 return IA64_RS_CR_LRR;
1430 if (strstr (name, "CR%") != NULL)
1431 return IA64_RS_CR;
1432 if (strstr (name, "FR%, % in 0") != NULL)
1433 return IA64_RS_FR;
1434 if (strstr (name, "FR%, % in 2") != NULL)
1435 return IA64_RS_FRb;
1436 if (strstr (name, "GR%") != NULL)
1437 return IA64_RS_GR;
1438 if (strstr (name, "PR%, % in 1 ") != NULL)
1439 return IA64_RS_PR;
1440 if (strstr (name, "PR%, % in 16 ") != NULL)
1441 return IA64_RS_PRr;
1443 warn (_("don't know how to specify %% dependency %s\n"),
1444 name);
1446 else if (strchr (name, '#'))
1448 if (strstr (name, "CPUID#") != NULL)
1449 return IA64_RS_CPUID;
1450 if (strstr (name, "DBR#") != NULL)
1451 return IA64_RS_DBR;
1452 if (strstr (name, "IBR#") != NULL)
1453 return IA64_RS_IBR;
1454 if (strstr (name, "MSR#") != NULL)
1455 return IA64_RS_MSR;
1456 if (strstr (name, "PKR#") != NULL)
1457 return IA64_RS_PKR;
1458 if (strstr (name, "PMC#") != NULL)
1459 return IA64_RS_PMC;
1460 if (strstr (name, "PMD#") != NULL)
1461 return IA64_RS_PMD;
1462 if (strstr (name, "RR#") != NULL)
1463 return IA64_RS_RR;
1465 warn (_("Don't know how to specify # dependency %s\n"),
1466 name);
1468 else if (strncmp (name, "AR[FPSR]", 8) == 0)
1469 return IA64_RS_AR_FPSR;
1470 else if (strncmp (name, "AR[", 3) == 0)
1471 return IA64_RS_ARX;
1472 else if (strncmp (name, "CR[", 3) == 0)
1473 return IA64_RS_CRX;
1474 else if (strncmp (name, "PSR.", 4) == 0)
1475 return IA64_RS_PSR;
1476 else if (strcmp (name, "InService*") == 0)
1477 return IA64_RS_INSERVICE;
1478 else if (strcmp (name, "GR0") == 0)
1479 return IA64_RS_GR0;
1480 else if (strcmp (name, "CFM") == 0)
1481 return IA64_RS_CFM;
1482 else if (strcmp (name, "PR63") == 0)
1483 return IA64_RS_PR63;
1484 else if (strcmp (name, "RSE") == 0)
1485 return IA64_RS_RSE;
1487 return IA64_RS_ANY;
1490 static void
1491 print_dependency_table ()
1493 int i, j;
1495 if (debug)
1497 for (i=0;i < iclen;i++)
1499 if (ics[i]->is_class)
1501 if (!ics[i]->nsubs)
1503 if (ics[i]->comment)
1504 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1505 ics[i]->name, ics[i]->comment);
1506 else
1507 warn (_("IC:%s has no terminals or sub-classes\n"),
1508 ics[i]->name);
1511 else
1513 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1515 if (ics[i]->comment)
1516 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1517 ics[i]->name, ics[i]->comment);
1518 else
1519 warn (_("no insns mapped directly to terminal IC %s\n"),
1520 ics[i]->name);
1525 for (i = 0; i < iclen; i++)
1527 if (ics[i]->orphan)
1529 mark_used (ics[i], 1);
1530 warn (_("class %s is defined but not used\n"),
1531 ics[i]->name);
1535 if (debug > 1)
1536 for (i = 0; i < rdepslen; i++)
1538 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1540 if (rdeps[i]->total_chks == 0)
1541 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1542 rdeps[i]->name, mode_str[rdeps[i]->mode],
1543 rdeps[i]->total_regs ? "" : " or regs");
1544 else if (rdeps[i]->total_regs == 0)
1545 warn (_("rsrc %s (%s) has no regs\n"),
1546 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1550 /* The dependencies themselves. */
1551 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1552 for (i = 0; i < rdepslen; i++)
1554 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1555 resource used. */
1556 int specifier = lookup_specifier (rdeps[i]->name);
1557 int regindex = lookup_regindex (rdeps[i]->name, specifier);
1559 printf (" { \"%s\", %d, %d, %d, %d, ",
1560 rdeps[i]->name, specifier,
1561 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1562 if (rdeps[i]->semantics == IA64_DVS_OTHER)
1563 printf ("\"%s\", ", rdeps[i]->extra);
1564 else
1565 printf ("NULL, ");
1566 printf("},\n");
1568 printf ("};\n\n");
1570 /* And dependency lists. */
1571 for (i=0;i < dlistlen;i++)
1573 int len = 2;
1574 printf ("static const unsigned short dep%d[] = {\n ", i);
1575 for (j=0;j < dlists[i]->len; j++)
1577 len += printf ("%d, ", dlists[i]->deps[j]);
1578 if (len > 75)
1580 printf("\n ");
1581 len = 2;
1584 printf ("\n};\n\n");
1587 /* And opcode dependency list. */
1588 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1589 printf ("static const struct ia64_opcode_dependency\n");
1590 printf ("op_dependencies[] = {\n");
1591 for (i = 0; i < opdeplen; i++)
1593 printf (" { ");
1594 if (opdeps[i]->chk == -1)
1595 printf ("0, NULL, ");
1596 else
1597 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1598 if (opdeps[i]->reg == -1)
1599 printf ("0, NULL, ");
1600 else
1601 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1602 printf ("},\n");
1604 printf ("};\n\n");
1608 /* Add STR to the string table. */
1609 static struct string_entry *
1610 insert_string (char *str)
1612 int start = 0, end = strtablen;
1613 int i, x;
1615 if (strtablen == strtabtotlen)
1617 strtabtotlen += 20;
1618 string_table = (struct string_entry **)
1619 xrealloc (string_table,
1620 sizeof (struct string_entry **) * strtabtotlen);
1623 if (strtablen == 0)
1625 strtablen = 1;
1626 string_table[0] = tmalloc (struct string_entry);
1627 string_table[0]->s = xstrdup (str);
1628 string_table[0]->num = 0;
1629 return string_table[0];
1632 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1633 i = end;
1634 else if (strcmp (str, string_table[0]->s) < 0)
1635 i = 0;
1636 else
1638 while (1)
1640 int c;
1642 i = (start + end) / 2;
1643 c = strcmp (str, string_table[i]->s);
1645 if (c < 0)
1646 end = i - 1;
1647 else if (c == 0)
1648 return string_table[i];
1649 else
1650 start = i + 1;
1652 if (start > end)
1653 break;
1657 for (; i > 0 && i < strtablen; i--)
1658 if (strcmp (str, string_table[i - 1]->s) > 0)
1659 break;
1661 for (; i < strtablen; i++)
1662 if (strcmp (str, string_table[i]->s) < 0)
1663 break;
1665 for (x = strtablen - 1; x >= i; x--)
1667 string_table[x + 1] = string_table[x];
1668 string_table[x + 1]->num = x + 1;
1671 string_table[i] = tmalloc (struct string_entry);
1672 string_table[i]->s = xstrdup (str);
1673 string_table[i]->num = i;
1674 strtablen++;
1676 return string_table[i];
1679 static struct bittree *
1680 make_bittree_entry (void)
1682 struct bittree *res = tmalloc (struct bittree);
1684 res->disent = NULL;
1685 res->bits[0] = NULL;
1686 res->bits[1] = NULL;
1687 res->bits[2] = NULL;
1688 res->skip_flag = 0;
1689 res->bits_to_skip = 0;
1690 return res;
1694 static struct disent *
1695 add_dis_table_ent (which, insn, order, completer_index)
1696 struct disent *which;
1697 int insn;
1698 int order;
1699 int completer_index;
1701 int ci = 0;
1702 struct disent *ent;
1704 if (which != NULL)
1706 ent = which;
1708 ent->nextcnt++;
1709 while (ent->nexte != NULL)
1710 ent = ent->nexte;
1712 ent = (ent->nexte = tmalloc (struct disent));
1714 else
1716 ent = tmalloc (struct disent);
1717 ent->next_ent = disinsntable;
1718 disinsntable = ent;
1719 which = ent;
1721 ent->nextcnt = 0;
1722 ent->nexte = NULL;
1723 ent->insn = insn;
1724 ent->priority = order;
1726 while (completer_index != 1)
1728 ci = (ci << 1) | (completer_index & 1);
1729 completer_index >>= 1;
1731 ent->completer_index = ci;
1732 return which;
1735 static void
1736 finish_distable ()
1738 struct disent *ent = disinsntable;
1739 struct disent *prev = ent;
1741 ent->ournum = 32768;
1742 while ((ent = ent->next_ent) != NULL)
1744 ent->ournum = prev->ournum + prev->nextcnt + 1;
1745 prev = ent;
1749 static void
1750 insert_bit_table_ent (curr_ent, bit, opcode, mask,
1751 opcodenum, order, completer_index)
1752 struct bittree *curr_ent;
1753 int bit;
1754 ia64_insn opcode;
1755 ia64_insn mask;
1756 int opcodenum;
1757 int order;
1758 int completer_index;
1760 ia64_insn m;
1761 int b;
1762 struct bittree *next;
1764 if (bit == -1)
1766 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1767 opcodenum, order,
1768 completer_index);
1769 curr_ent->disent = nent;
1770 return;
1773 m = ((ia64_insn) 1) << bit;
1775 if (mask & m)
1776 b = (opcode & m) ? 1 : 0;
1777 else
1778 b = 2;
1780 next = curr_ent->bits[b];
1781 if (next == NULL)
1783 next = make_bittree_entry ();
1784 curr_ent->bits[b] = next;
1786 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1787 completer_index);
1790 static void
1791 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1792 struct bittree *first;
1793 ia64_insn opcode;
1794 ia64_insn mask;
1795 int opcodenum;
1796 struct completer_entry *ent;
1797 int completer_index;
1799 if (completer_index & (1 << 20))
1800 abort ();
1802 while (ent != NULL)
1804 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1805 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1806 (completer_index << 1) | 1);
1808 if (ent->is_terminal)
1810 insert_bit_table_ent (bittree, 40, newopcode, mask,
1811 opcodenum, opcode_count - ent->order - 1,
1812 (completer_index << 1) | 1);
1814 completer_index <<= 1;
1815 ent = ent->alternative;
1819 /* This optimization pass combines multiple "don't care" nodes. */
1820 static void
1821 compact_distree (ent)
1822 struct bittree *ent;
1824 #define IS_SKIP(ent) \
1825 ((ent->bits[2] !=NULL) \
1826 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1828 int bitcnt = 0;
1829 struct bittree *nent = ent;
1830 int x;
1832 while (IS_SKIP (nent))
1834 bitcnt++;
1835 nent = nent->bits[2];
1838 if (bitcnt)
1840 struct bittree *next = ent->bits[2];
1842 ent->bits[0] = nent->bits[0];
1843 ent->bits[1] = nent->bits[1];
1844 ent->bits[2] = nent->bits[2];
1845 ent->disent = nent->disent;
1846 ent->skip_flag = 1;
1847 ent->bits_to_skip = bitcnt;
1848 while (next != nent)
1850 struct bittree *b = next;
1851 next = next->bits[2];
1852 free (b);
1854 free (nent);
1857 for (x = 0; x < 3; x++)
1859 struct bittree *i = ent->bits[x];
1861 if (i != NULL)
1862 compact_distree (i);
1866 static unsigned char *insn_list;
1867 static int insn_list_len = 0;
1868 static int tot_insn_list_len = 0;
1870 /* Generate the disassembler state machine corresponding to the tree
1871 in ENT. */
1872 static void
1873 gen_dis_table (ent)
1874 struct bittree *ent;
1876 int x;
1877 int our_offset = insn_list_len;
1878 int bitsused = 5;
1879 int totbits = bitsused;
1880 int needed_bytes;
1881 int zero_count = 0;
1882 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */
1884 /* If this is a terminal entry, there's no point in skipping any
1885 bits. */
1886 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1887 ent->bits[2] == NULL)
1889 if (ent->disent == NULL)
1890 abort ();
1891 else
1892 ent->skip_flag = 0;
1895 /* Calculate the amount of space needed for this entry, or at least
1896 a conservatively large approximation. */
1897 if (ent->skip_flag)
1898 totbits += 5;
1900 for (x = 1; x < 3; x++)
1901 if (ent->bits[x] != NULL)
1902 totbits += 16;
1904 if (ent->disent != NULL)
1906 if (ent->bits[2] != NULL)
1907 abort ();
1909 totbits += 16;
1912 /* Now allocate the space. */
1913 needed_bytes = (totbits + 7) / 8;
1914 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1916 tot_insn_list_len += 256;
1917 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
1919 our_offset = insn_list_len;
1920 insn_list_len += needed_bytes;
1921 memset (insn_list + our_offset, 0, needed_bytes);
1923 /* Encode the skip entry by setting bit 6 set in the state op field,
1924 and store the # of bits to skip immediately after. */
1925 if (ent->skip_flag)
1927 bitsused += 5;
1928 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1929 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1932 #define IS_ONLY_IFZERO(ENT) \
1933 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1934 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1936 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1937 state op field. */
1938 if (ent->bits[0] != NULL)
1940 struct bittree *nent = ent->bits[0];
1941 zero_count = 0;
1943 insn_list[our_offset] |= 0x80;
1945 /* We can encode sequences of multiple "if (bit is zero)" tests
1946 by storing the # of zero bits to check in the lower 3 bits of
1947 the instruction. However, this only applies if the state
1948 solely tests for a zero bit. */
1950 if (IS_ONLY_IFZERO (ent))
1952 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1954 nent = nent->bits[0];
1955 zero_count++;
1958 insn_list[our_offset + 0] |= zero_count;
1960 zero_dest = insn_list_len;
1961 gen_dis_table (nent);
1964 /* Now store the remaining tests. We also handle a sole "termination
1965 entry" by storing it as an "any bit" test. */
1967 for (x = 1; x < 3; x++)
1969 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1971 struct bittree *i = ent->bits[x];
1972 int idest;
1973 int currbits = 15;
1975 if (i != NULL)
1977 /* If the instruction being branched to only consists of
1978 a termination entry, use the termination entry as the
1979 place to branch to instead. */
1980 if (i->bits[0] == NULL && i->bits[1] == NULL
1981 && i->bits[2] == NULL && i->disent != NULL)
1983 idest = i->disent->ournum;
1984 i = NULL;
1986 else
1987 idest = insn_list_len - our_offset;
1989 else
1990 idest = ent->disent->ournum;
1992 /* If the destination offset for the if (bit is 1) test is less
1993 than 256 bytes away, we can store it as 8-bits instead of 16;
1994 the instruction has bit 5 set for the 16-bit address, and bit
1995 4 for the 8-bit address. Since we've already allocated 16
1996 bits for the address we need to deallocate the space.
1998 Note that branchings within the table are relative, and
1999 there are no branches that branch past our instruction yet
2000 so we do not need to adjust any other offsets. */
2001 if (x == 1)
2003 if (idest <= 256)
2005 int start = our_offset + bitsused / 8 + 1;
2007 memmove (insn_list + start,
2008 insn_list + start + 1,
2009 insn_list_len - (start + 1));
2010 currbits = 7;
2011 totbits -= 8;
2012 needed_bytes--;
2013 insn_list_len--;
2014 insn_list[our_offset] |= 0x10;
2015 idest--;
2017 else
2018 insn_list[our_offset] |= 0x20;
2020 else
2022 /* An instruction which solely consists of a termination
2023 marker and whose disassembly name index is < 4096
2024 can be stored in 16 bits. The encoding is slightly
2025 odd; the upper 4 bits of the instruction are 0x3, and
2026 bit 3 loses its normal meaning. */
2028 if (ent->bits[0] == NULL && ent->bits[1] == NULL
2029 && ent->bits[2] == NULL && ent->skip_flag == 0
2030 && ent->disent != NULL
2031 && ent->disent->ournum < (32768 + 4096))
2033 int start = our_offset + bitsused / 8 + 1;
2035 memmove (insn_list + start,
2036 insn_list + start + 1,
2037 insn_list_len - (start + 1));
2038 currbits = 11;
2039 totbits -= 5;
2040 bitsused--;
2041 needed_bytes--;
2042 insn_list_len--;
2043 insn_list[our_offset] |= 0x30;
2044 idest &= ~32768;
2046 else
2047 insn_list[our_offset] |= 0x08;
2050 if (debug)
2052 int id = idest;
2054 if (i == NULL)
2055 id |= 32768;
2056 else if (! (id & 32768))
2057 id += our_offset;
2059 if (x == 1)
2060 printf ("%d: if (1) goto %d\n", our_offset, id);
2061 else
2062 printf ("%d: try %d\n", our_offset, id);
2065 /* Store the address of the entry being branched to. */
2066 while (currbits >= 0)
2068 unsigned char *byte = insn_list + our_offset + bitsused / 8;
2070 if (idest & (1 << currbits))
2071 *byte |= (1 << (7 - (bitsused % 8)));
2073 bitsused++;
2074 currbits--;
2077 /* Now generate the states for the entry being branched to. */
2078 if (i != NULL)
2079 gen_dis_table (i);
2083 if (debug)
2085 if (ent->skip_flag)
2086 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2088 if (ent->bits[0] != NULL)
2089 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2090 zero_dest);
2093 if (bitsused != totbits)
2094 abort ();
2097 static void
2098 print_dis_table (void)
2100 int x;
2101 struct disent *cent = disinsntable;
2103 printf ("static const char dis_table[] = {\n");
2104 for (x = 0; x < insn_list_len; x++)
2106 if ((x > 0) && ((x % 12) == 0))
2107 printf ("\n");
2109 printf ("0x%02x, ", insn_list[x]);
2111 printf ("\n};\n\n");
2113 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2114 while (cent != NULL)
2116 struct disent *ent = cent;
2118 while (ent != NULL)
2120 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2121 ent->insn, (ent->nexte != NULL ? 1 : 0),
2122 ent->priority);
2123 ent = ent->nexte;
2125 cent = cent->next_ent;
2127 printf ("};\n\n");
2130 static void
2131 generate_disassembler (void)
2133 int i;
2135 bittree = make_bittree_entry ();
2137 for (i = 0; i < otlen; i++)
2139 struct main_entry *ptr = ordered_table[i];
2141 if (ptr->opcode->type != IA64_TYPE_DYN)
2142 add_dis_entry (bittree,
2143 ptr->opcode->opcode, ptr->opcode->mask,
2144 ptr->main_index,
2145 ptr->completers, 1);
2148 compact_distree (bittree);
2149 finish_distable ();
2150 gen_dis_table (bittree);
2152 print_dis_table ();
2155 static void
2156 print_string_table (void)
2158 int x;
2159 char lbuf[80], buf[80];
2160 int blen = 0;
2162 printf ("static const char * const ia64_strings[] = {\n");
2163 lbuf[0] = '\0';
2165 for (x = 0; x < strtablen; x++)
2167 int len;
2169 if (strlen (string_table[x]->s) > 75)
2170 abort ();
2172 sprintf (buf, " \"%s\",", string_table[x]->s);
2173 len = strlen (buf);
2175 if ((blen + len) > 75)
2177 printf (" %s\n", lbuf);
2178 lbuf[0] = '\0';
2179 blen = 0;
2181 strcat (lbuf, buf);
2182 blen += len;
2185 if (blen > 0)
2186 printf (" %s\n", lbuf);
2188 printf ("};\n\n");
2191 static struct completer_entry **glist;
2192 static int glistlen = 0;
2193 static int glisttotlen = 0;
2195 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2197 static int
2198 completer_entries_eq (ent1, ent2)
2199 struct completer_entry *ent1, *ent2;
2201 while (ent1 != NULL && ent2 != NULL)
2203 if (ent1->name->num != ent2->name->num
2204 || ent1->bits != ent2->bits
2205 || ent1->mask != ent2->mask
2206 || ent1->is_terminal != ent2->is_terminal
2207 || ent1->dependencies != ent2->dependencies
2208 || ent1->order != ent2->order)
2209 return 0;
2211 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2212 return 0;
2214 ent1 = ent1->alternative;
2215 ent2 = ent2->alternative;
2218 return ent1 == ent2;
2221 /* Insert ENT into the global list of completers and return it. If an
2222 equivalent entry (according to completer_entries_eq) already exists,
2223 it is returned instead. */
2224 static struct completer_entry *
2225 insert_gclist (struct completer_entry *ent)
2227 if (ent != NULL)
2229 int i;
2230 int x;
2231 int start = 0, end;
2233 ent->addl_entries = insert_gclist (ent->addl_entries);
2234 ent->alternative = insert_gclist (ent->alternative);
2236 i = glistlen / 2;
2237 end = glistlen;
2239 if (glisttotlen == glistlen)
2241 glisttotlen += 20;
2242 glist = (struct completer_entry **)
2243 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2246 if (glistlen == 0)
2248 glist[0] = ent;
2249 glistlen = 1;
2250 return ent;
2253 if (ent->name->num < glist[0]->name->num)
2254 i = 0;
2255 else if (ent->name->num > glist[end - 1]->name->num)
2256 i = end;
2257 else
2259 int c;
2261 while (1)
2263 i = (start + end) / 2;
2264 c = ent->name->num - glist[i]->name->num;
2266 if (c < 0)
2267 end = i - 1;
2268 else if (c == 0)
2270 while (i > 0
2271 && ent->name->num == glist[i - 1]->name->num)
2272 i--;
2274 break;
2276 else
2277 start = i + 1;
2279 if (start > end)
2280 break;
2283 if (c == 0)
2285 while (i < glistlen)
2287 if (ent->name->num != glist[i]->name->num)
2288 break;
2290 if (completer_entries_eq (ent, glist[i]))
2291 return glist[i];
2293 i++;
2298 for (; i > 0 && i < glistlen; i--)
2299 if (ent->name->num >= glist[i - 1]->name->num)
2300 break;
2302 for (; i < glistlen; i++)
2303 if (ent->name->num < glist[i]->name->num)
2304 break;
2306 for (x = glistlen - 1; x >= i; x--)
2307 glist[x + 1] = glist[x];
2309 glist[i] = ent;
2310 glistlen++;
2312 return ent;
2315 static int
2316 get_prefix_len (name)
2317 const char *name;
2319 char *c;
2321 if (name[0] == '\0')
2322 return 0;
2324 c = strchr (name, '.');
2325 if (c != NULL)
2326 return c - name;
2327 else
2328 return strlen (name);
2331 static void
2332 compute_completer_bits (ment, ent)
2333 struct main_entry *ment;
2334 struct completer_entry *ent;
2336 while (ent != NULL)
2338 compute_completer_bits (ment, ent->addl_entries);
2340 if (ent->is_terminal)
2342 ia64_insn mask = 0;
2343 ia64_insn our_bits = ent->bits;
2344 struct completer_entry *p = ent->parent;
2345 ia64_insn p_bits;
2346 int x;
2348 while (p != NULL && ! p->is_terminal)
2349 p = p->parent;
2351 if (p != NULL)
2352 p_bits = p->bits;
2353 else
2354 p_bits = ment->opcode->opcode;
2356 for (x = 0; x < 64; x++)
2358 ia64_insn m = ((ia64_insn) 1) << x;
2360 if ((p_bits & m) != (our_bits & m))
2361 mask |= m;
2362 else
2363 our_bits &= ~m;
2365 ent->bits = our_bits;
2366 ent->mask = mask;
2368 else
2370 ent->bits = 0;
2371 ent->mask = 0;
2374 ent = ent->alternative;
2378 /* Find identical completer trees that are used in different
2379 instructions and collapse their entries. */
2380 static void
2381 collapse_redundant_completers (void)
2383 struct main_entry *ptr;
2384 int x;
2386 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2388 if (ptr->completers == NULL)
2389 abort ();
2391 compute_completer_bits (ptr, ptr->completers);
2392 ptr->completers = insert_gclist (ptr->completers);
2395 /* The table has been finalized, now number the indexes. */
2396 for (x = 0; x < glistlen; x++)
2397 glist[x]->num = x;
2401 /* Attach two lists of dependencies to each opcode.
2402 1) all resources which, when already marked in use, conflict with this
2403 opcode (chks)
2404 2) all resources which must be marked in use when this opcode is used
2405 (regs). */
2406 static int
2407 insert_opcode_dependencies (opc, cmp)
2408 struct ia64_opcode *opc;
2409 struct completer_entry *cmp ATTRIBUTE_UNUSED;
2411 /* Note all resources which point to this opcode. rfi has the most chks
2412 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2413 int i;
2414 int nregs = 0;
2415 unsigned short regs[256];
2416 int nchks = 0;
2417 unsigned short chks[256];
2418 /* Flag insns for which no class matched; there should be none. */
2419 int no_class_found = 1;
2421 for (i = 0; i < rdepslen; i++)
2423 struct rdep *rs = rdeps[i];
2424 int j;
2426 if (strcmp (opc->name, "cmp.eq.and") == 0
2427 && strncmp (rs->name, "PR%", 3) == 0
2428 && rs->mode == 1)
2429 no_class_found = 99;
2431 for (j=0; j < rs->nregs;j++)
2433 int ic_note = 0;
2435 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2437 /* We can ignore ic_note 11 for non PR resources. */
2438 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2439 ic_note = 0;
2441 if (ic_note != 0 && rs->regnotes[j] != 0
2442 && ic_note != rs->regnotes[j]
2443 && !(ic_note == 11 && rs->regnotes[j] == 1))
2444 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2445 ic_note, opc->name, ics[rs->regs[j]]->name,
2446 rs->name, rs->regnotes[j]);
2447 /* Instruction class notes override resource notes.
2448 So far, only note 11 applies to an IC instead of a resource,
2449 and note 11 implies note 1. */
2450 if (ic_note)
2451 regs[nregs++] = RDEP(ic_note, i);
2452 else
2453 regs[nregs++] = RDEP(rs->regnotes[j], i);
2454 no_class_found = 0;
2455 ++rs->total_regs;
2459 for (j = 0; j < rs->nchks; j++)
2461 int ic_note = 0;
2463 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2465 /* We can ignore ic_note 11 for non PR resources. */
2466 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2467 ic_note = 0;
2469 if (ic_note != 0 && rs->chknotes[j] != 0
2470 && ic_note != rs->chknotes[j]
2471 && !(ic_note == 11 && rs->chknotes[j] == 1))
2472 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2473 ic_note, opc->name, ics[rs->chks[j]]->name,
2474 rs->name, rs->chknotes[j]);
2475 if (ic_note)
2476 chks[nchks++] = RDEP(ic_note, i);
2477 else
2478 chks[nchks++] = RDEP(rs->chknotes[j], i);
2479 no_class_found = 0;
2480 ++rs->total_chks;
2485 if (no_class_found)
2486 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2487 opc->name,
2488 opc->operands[0], opc->operands[1], opc->operands[2]);
2490 return insert_dependencies (nchks, chks, nregs, regs);
2493 static void
2494 insert_completer_entry (opc, tabent, order)
2495 struct ia64_opcode *opc;
2496 struct main_entry *tabent;
2497 int order;
2499 struct completer_entry **ptr = &tabent->completers;
2500 struct completer_entry *parent = NULL;
2501 char pcopy[129], *prefix;
2502 int at_end = 0;
2504 if (strlen (opc->name) > 128)
2505 abort ();
2507 strcpy (pcopy, opc->name);
2508 prefix = pcopy + get_prefix_len (pcopy);
2510 if (prefix[0] != '\0')
2511 prefix++;
2513 while (! at_end)
2515 int need_new_ent = 1;
2516 int plen = get_prefix_len (prefix);
2517 struct string_entry *sent;
2519 at_end = (prefix[plen] == '\0');
2520 prefix[plen] = '\0';
2521 sent = insert_string (prefix);
2523 while (*ptr != NULL)
2525 int cmpres = sent->num - (*ptr)->name->num;
2527 if (cmpres == 0)
2529 need_new_ent = 0;
2530 break;
2532 else
2533 ptr = &((*ptr)->alternative);
2536 if (need_new_ent)
2538 struct completer_entry *nent = tmalloc (struct completer_entry);
2540 nent->name = sent;
2541 nent->parent = parent;
2542 nent->addl_entries = NULL;
2543 nent->alternative = *ptr;
2544 *ptr = nent;
2545 nent->is_terminal = 0;
2546 nent->dependencies = -1;
2549 if (! at_end)
2551 parent = *ptr;
2552 ptr = &((*ptr)->addl_entries);
2553 prefix += plen + 1;
2557 if ((*ptr)->is_terminal)
2558 abort ();
2560 (*ptr)->is_terminal = 1;
2561 (*ptr)->mask = (ia64_insn)-1;
2562 (*ptr)->bits = opc->opcode;
2563 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2564 (*ptr)->order = order;
2567 static void
2568 print_completer_entry (ent)
2569 struct completer_entry *ent;
2571 int moffset = 0;
2572 ia64_insn mask = ent->mask, bits = ent->bits;
2574 if (mask != 0)
2576 while (! (mask & 1))
2578 moffset++;
2579 mask = mask >> 1;
2580 bits = bits >> 1;
2583 if (bits & 0xffffffff00000000LL)
2584 abort ();
2587 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2588 (int)bits,
2589 (int)mask,
2590 ent->name->num,
2591 ent->alternative != NULL ? ent->alternative->num : -1,
2592 ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2593 moffset,
2594 ent->is_terminal ? 1 : 0,
2595 ent->dependencies);
2598 static void
2599 print_completer_table ()
2601 int x;
2603 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2604 for (x = 0; x < glistlen; x++)
2605 print_completer_entry (glist[x]);
2606 printf ("};\n\n");
2609 static int
2610 opcodes_eq (opc1, opc2)
2611 struct ia64_opcode *opc1;
2612 struct ia64_opcode *opc2;
2614 int x;
2615 int plen1, plen2;
2617 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2618 || (opc1->num_outputs != opc2->num_outputs)
2619 || (opc1->flags != opc2->flags))
2620 return 0;
2622 for (x = 0; x < 5; x++)
2623 if (opc1->operands[x] != opc2->operands[x])
2624 return 0;
2626 plen1 = get_prefix_len (opc1->name);
2627 plen2 = get_prefix_len (opc2->name);
2629 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2630 return 1;
2632 return 0;
2635 static void
2636 add_opcode_entry (opc)
2637 struct ia64_opcode *opc;
2639 struct main_entry **place;
2640 struct string_entry *name;
2641 char prefix[129];
2642 int found_it = 0;
2644 if (strlen (opc->name) > 128)
2645 abort ();
2647 place = &maintable;
2648 strcpy (prefix, opc->name);
2649 prefix[get_prefix_len (prefix)] = '\0';
2650 name = insert_string (prefix);
2652 /* Walk the list of opcode table entries. If it's a new
2653 instruction, allocate and fill in a new entry. Note
2654 the main table is alphabetical by opcode name. */
2656 while (*place != NULL)
2658 if ((*place)->name->num == name->num
2659 && opcodes_eq ((*place)->opcode, opc))
2661 found_it = 1;
2662 break;
2664 if ((*place)->name->num > name->num)
2665 break;
2667 place = &((*place)->next);
2669 if (! found_it)
2671 struct main_entry *nent = tmalloc (struct main_entry);
2673 nent->name = name;
2674 nent->opcode = opc;
2675 nent->next = *place;
2676 nent->completers = 0;
2677 *place = nent;
2679 if (otlen == ottotlen)
2681 ottotlen += 20;
2682 ordered_table = (struct main_entry **)
2683 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2685 ordered_table[otlen++] = nent;
2688 insert_completer_entry (opc, *place, opcode_count++);
2691 static void
2692 print_main_table (void)
2694 struct main_entry *ptr = maintable;
2695 int index = 0;
2697 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2698 while (ptr != NULL)
2700 printf (" { %d, %d, %d, 0x",
2701 ptr->name->num,
2702 ptr->opcode->type,
2703 ptr->opcode->num_outputs);
2704 fprintf_vma (stdout, ptr->opcode->opcode);
2705 printf ("ull, 0x");
2706 fprintf_vma (stdout, ptr->opcode->mask);
2707 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2708 ptr->opcode->operands[0],
2709 ptr->opcode->operands[1],
2710 ptr->opcode->operands[2],
2711 ptr->opcode->operands[3],
2712 ptr->opcode->operands[4],
2713 ptr->opcode->flags,
2714 ptr->completers->num);
2716 ptr->main_index = index++;
2718 ptr = ptr->next;
2720 printf ("};\n\n");
2723 static void
2724 shrink (table)
2725 struct ia64_opcode *table;
2727 int curr_opcode;
2729 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2731 add_opcode_entry (table + curr_opcode);
2732 if (table[curr_opcode].num_outputs == 2
2733 && ((table[curr_opcode].operands[0] == IA64_OPND_P1
2734 && table[curr_opcode].operands[1] == IA64_OPND_P2)
2735 || (table[curr_opcode].operands[0] == IA64_OPND_P2
2736 && table[curr_opcode].operands[1] == IA64_OPND_P1)))
2738 struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2739 unsigned i;
2741 *alias = table[curr_opcode];
2742 for (i = 2; i < NELEMS (alias->operands); ++i)
2743 alias->operands[i - 1] = alias->operands[i];
2744 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2745 --alias->num_outputs;
2746 alias->flags |= PSEUDO;
2747 add_opcode_entry (alias);
2753 /* Program options. */
2754 #define OPTION_SRCDIR 200
2756 struct option long_options[] =
2758 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2759 {"debug", no_argument, NULL, 'd'},
2760 {"version", no_argument, NULL, 'V'},
2761 {"help", no_argument, NULL, 'h'},
2762 {0, no_argument, NULL, 0}
2765 static void
2766 print_version (void)
2768 printf ("%s: version 1.0\n", program_name);
2769 xexit (0);
2772 static void
2773 usage (FILE * stream, int status)
2775 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2776 program_name);
2777 xexit (status);
2781 main (int argc, char **argv)
2783 extern int chdir (char *);
2784 char *srcdir = NULL;
2785 int c;
2787 program_name = *argv;
2788 xmalloc_set_program_name (program_name);
2790 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2791 switch (c)
2793 case OPTION_SRCDIR:
2794 srcdir = optarg;
2795 break;
2796 case 'V':
2797 case 'v':
2798 print_version ();
2799 break;
2800 case 'd':
2801 debug = 1;
2802 break;
2803 case 'h':
2804 case '?':
2805 usage (stderr, 0);
2806 default:
2807 case 0:
2808 break;
2811 if (optind != argc)
2812 usage (stdout, 1);
2814 if (srcdir != NULL)
2815 if (chdir (srcdir) != 0)
2816 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2817 srcdir, strerror (errno));
2819 load_insn_classes ();
2820 load_dependencies ();
2822 shrink (ia64_opcodes_a);
2823 shrink (ia64_opcodes_b);
2824 shrink (ia64_opcodes_f);
2825 shrink (ia64_opcodes_i);
2826 shrink (ia64_opcodes_m);
2827 shrink (ia64_opcodes_x);
2828 shrink (ia64_opcodes_d);
2830 collapse_redundant_completers ();
2832 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2833 print_string_table ();
2834 print_dependency_table ();
2835 print_completer_table ();
2836 print_main_table ();
2838 generate_disassembler ();
2840 exit (0);