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