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