source: trunk/src/binutils/opcodes/ia64-gen.c@ 1113

Last change on this file since 1113 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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