Add support for v4 SystemMode.
[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;
700 else
701 return IA64_DVS_OTHER;
702}
703
704static void
705add_dep (const char *name, const char *chk, const char *reg,
706 int semantics, int mode, char *extra, int flag)
707{
708 struct rdep *rs;
709
710 rs = insert_resource (name, mode);
711 parse_resource_users (chk, &rs->chks, &rs->nchks,
712 &rs->chknotes);
713 parse_resource_users (reg, &rs->regs, &rs->nregs,
714 &rs->regnotes);
715 rs->semantics = semantics;
716 rs->extra = extra;
717 rs->waw_special = flag;
718}
719
720static void
721load_depfile (const char *filename, enum ia64_dependency_mode mode)
722{
723 FILE *fp = fopen(filename, "r");
724 char buf[1024];
725
aa170a07
TW
726 if (fp == NULL){
727 fprintf (stderr, "Can't find %s for reading\n", filename);
728 exit(1);
729 }
730
800eeca4
JW
731 fgets(buf, sizeof(buf), fp);
732 while (!feof(fp))
733 {
734 char *name, *tmp;
735 int semantics;
736 char *extra;
737 char *regp, *chkp;
738
739 if (fgets (buf, sizeof(buf), fp) == NULL)
740 break;
741
742 while (isspace(buf[strlen(buf)-1]))
743 buf[strlen(buf)-1] = '\0';
744
745 name = tmp = buf;
746 while (*tmp != ';')
747 ++tmp;
748 *tmp++ = '\0';
749
750 while (isspace (*tmp))
751 ++tmp;
752 regp = tmp;
753 tmp = strchr (tmp, ';');
754 if (!tmp)
755 abort ();
756 *tmp++ = 0;
757 while (isspace (*tmp))
758 ++tmp;
759 chkp = tmp;
760 tmp = strchr (tmp, ';');
761 if (!tmp)
762 abort ();
763 *tmp++ = 0;
764 while (isspace (*tmp))
765 ++tmp;
766 semantics = parse_semantics (tmp);
767 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
768
769 /* For WAW entries, if the chks and regs differ, we need to enter the
770 entries in both positions so that the tables will be parsed properly,
771 without a lot of extra work */
772 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
773 {
774 add_dep (name, chkp, regp, semantics, mode, extra, 0);
775 add_dep (name, regp, chkp, semantics, mode, extra, 1);
776 }
777 else
778 {
779 add_dep (name, chkp, regp, semantics, mode, extra, 0);
780 }
781 }
782 fclose(fp);
783}
784
785static void
786load_dependencies()
787{
788 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
789 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
790 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
791
792 if (debug)
793 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
794}
795
796/* is the given operand an indirect register file operand? */
797static int
798irf_operand (int op, const char *field)
799{
800 if (!field)
801 {
802 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
803 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
804 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
805 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
806 }
807 else
808 {
809 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
810 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
811 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
812 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
813 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
814 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
815 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
816 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
817 }
818}
819
820/* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
821 mov_um insn classes */
822static int
823in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
824 const char *format, const char *field)
825{
826 int plain_mov = strcmp (idesc->name, "mov") == 0;
827
828 if (!format)
829 return 0;
830
831 switch (ic->name[4])
832 {
833 default:
834 abort ();
835 case 'a':
836 {
837 int i = strcmp (idesc->name, "mov.i") == 0;
838 int m = strcmp (idesc->name, "mov.m") == 0;
839 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
840 int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
841 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
842 int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
843 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
844 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
845
846 /* IC:mov ar */
847 if (i2627)
848 return strstr (format, "I26") || strstr (format, "I27");
849 if (i28)
850 return strstr (format, "I28") != NULL;
851 if (m2930)
852 return strstr (format, "M29") || strstr (format, "M30");
853 if (m31)
854 return strstr (format, "M31") != NULL;
855 if (pseudo0 || pseudo1)
856 return 1;
857 }
858 break;
859 case 'b':
860 {
861 int i21 = idesc->operands[0] == IA64_OPND_B1;
862 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
863 if (i22)
864 return strstr (format, "I22") != NULL;
865 if (i21)
866 return strstr (format, "I21") != NULL;
867 }
868 break;
869 case 'c':
870 {
871 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
872 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
873 if (m32)
874 return strstr (format, "M32") != NULL;
875 if (m33)
876 return strstr (format, "M33") != NULL;
877 }
878 break;
879 case 'i':
880 if (ic->name[5] == 'n')
881 {
882 int m42 = plain_mov && irf_operand (idesc->operands[0], field);
883 int m43 = plain_mov && irf_operand (idesc->operands[1], field);
884 if (m42)
885 return strstr (format, "M42") != NULL;
886 if (m43)
887 return strstr (format, "M43") != NULL;
888 }
889 else if (ic->name[5] == 'p')
890 {
891 return idesc->operands[1] == IA64_OPND_IP;
892 }
893 else
894 abort ();
895 break;
896 case 'p':
897 if (ic->name[5] == 'r')
898 {
899 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
900 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
901 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
902 if (i23)
903 return strstr (format, "I23") != NULL;
904 if (i24)
905 return strstr (format, "I24") != NULL;
906 if (i25)
907 return strstr (format, "I25") != NULL;
908 }
909 else if (ic->name[5] == 's')
910 {
911 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
912 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
913 if (m35)
914 return strstr (format, "M35") != NULL;
915 if (m36)
916 return strstr (format, "M36") != NULL;
917 }
918 else
919 abort ();
920 break;
921 case 'u':
922 {
923 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
924 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
925 if (m35)
926 return strstr (format, "M35") != NULL;
927 if (m36)
928 return strstr (format, "M36") != NULL;
929 }
930 break;
931 }
932 return 0;
933}
934
935
936/* is the given opcode in the given insn class? */
937static int
938in_iclass(struct ia64_opcode *idesc, struct iclass *ic,
939 const char *format, const char *field, int *notep)
940{
941 int i;
942 int resolved = 0;
943
944 if (ic->comment)
945 {
946 if (!strncmp (ic->comment, "Format", 6))
947 {
948 /* assume that the first format seen is the most restrictive, and
949 only keep a later one if it looks like it's more restrictive. */
950 if (format)
951 {
952 if (strlen (ic->comment) < strlen (format))
953 {
954 fprintf (stderr, "Warning: most recent format '%s'\n"
955 "appears more restrictive than '%s'\n",
956 ic->comment, format);
957 format = ic->comment;
958 }
959 }
960 else
961 format = ic->comment;
962 }
963 else if (!strncmp (ic->comment, "Field", 5))
964 {
965 if (field)
966 fprintf (stderr, "Overlapping field %s->%s\n",
967 ic->comment, field);
968 field = ic->comment;
969 }
970 }
971
972 /* an insn class matches anything that is the same followed by completers,
973 except when the absence and presence of completers constitutes different
974 instructions */
975 if (ic->nsubs == 0 && ic->nxsubs == 0)
976 {
977 int is_mov = strncmp (idesc->name, "mov", 3) == 0;
978 int plain_mov = strcmp (idesc->name, "mov") == 0;
979 int len = strlen(ic->name);
980
981 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
982 && (idesc->name[len] == '\0'
983 || idesc->name[len] == '.'));
984
985 /* all break and nop variations must match exactly */
986 if (resolved &&
987 (strcmp (ic->name, "break") == 0
988 || strcmp (ic->name, "nop") == 0))
989 resolved = strcmp (ic->name, idesc->name) == 0;
990
991 /* assume restrictions in the FORMAT/FIELD negate resolution,
992 unless specifically allowed by clauses in this block */
993 if (resolved && field)
994 {
995 /* check Field(sf)==sN against opcode sN */
996 if (strstr(field, "(sf)==") != NULL)
997 {
998 char *sf;
999 if ((sf = strstr (idesc->name, ".s")) != 0)
1000 {
1001 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1002 }
1003 }
1004 /* check Field(lftype)==XXX */
1005 else if (strstr (field, "(lftype)") != NULL)
1006 {
1007 if (strstr (idesc->name, "fault") != NULL)
1008 resolved = strstr (field, "fault") != NULL;
1009 else
1010 resolved = strstr (field, "fault") == NULL;
1011 }
1012 /* handle Field(ctype)==XXX */
1013 else if (strstr (field, "(ctype)") != NULL)
1014 {
1015 if (strstr (idesc->name, "or.andcm"))
1016 resolved = strstr (field, "or.andcm") != NULL;
1017 else if (strstr (idesc->name, "and.orcm"))
1018 resolved = strstr (field, "and.orcm") != NULL;
1019 else if (strstr (idesc->name, "orcm"))
1020 resolved = strstr (field, "or orcm") != NULL;
1021 else if (strstr (idesc->name, "or"))
1022 resolved = strstr (field, "or orcm") != NULL;
1023 else if (strstr (idesc->name, "andcm"))
1024 resolved = strstr (field, "and andcm") != NULL;
1025 else if (strstr (idesc->name, "and"))
1026 resolved = strstr (field, "and andcm") != NULL;
1027 else if (strstr (idesc->name, "unc"))
1028 resolved = strstr (field, "unc") != NULL;
1029 else
1030 resolved = strcmp (field, "Field(ctype)==") == 0;
1031 }
1032 }
1033 if (resolved && format)
1034 {
1035 if (strncmp (idesc->name, "dep", 3) == 0
1036 && strstr (format, "I13") != NULL)
1037 resolved = idesc->operands[1] == IA64_OPND_IMM8;
1038 else if (strncmp (idesc->name, "chk", 3) == 0
1039 && strstr (format, "M21") != NULL)
1040 resolved = idesc->operands[0] == IA64_OPND_F2;
1041 else if (strncmp (idesc->name, "lfetch", 6) == 0)
1042 resolved = (strstr (format, "M14 M15") != NULL
1043 && (idesc->operands[1] == IA64_OPND_R2
1044 || idesc->operands[1] == IA64_OPND_IMM9b));
1045 else if (strncmp (idesc->name, "br.call", 7) == 0
1046 && strstr (format, "B5") != NULL)
1047 resolved = idesc->operands[1] == IA64_OPND_B2;
1048 else if (strncmp (idesc->name, "br.call", 7) == 0
1049 && strstr (format, "B3") != NULL)
1050 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1051 else if (strncmp (idesc->name, "brp", 3) == 0
1052 && strstr (format, "B7") != NULL)
1053 resolved = idesc->operands[0] == IA64_OPND_B2;
1054 else if (strcmp (ic->name, "invala") == 0)
1055 resolved = strcmp (idesc->name, ic->name) == 0;
1056 else
1057 resolved = 0;
1058 }
1059
1060 /* misc brl variations ('.cond' is optional);
1061 plain brl matches brl.cond */
1062 if (!resolved
1063 && (strcmp (idesc->name, "brl") == 0
1064 || strncmp (idesc->name, "brl.", 4) == 0)
1065 && strcmp (ic->name, "brl.cond") == 0)
1066 {
1067 resolved = 1;
1068 }
1069
1070 /* misc br variations ('.cond' is optional) */
1071 if (!resolved
1072 && (strcmp (idesc->name, "br") == 0
1073 || strncmp (idesc->name, "br.", 3) == 0)
1074 && strcmp (ic->name, "br.cond") == 0)
1075 {
1076 if (format)
1077 resolved = (strstr (format, "B4") != NULL
1078 && idesc->operands[0] == IA64_OPND_B2)
1079 || (strstr (format, "B1") != NULL
1080 && idesc->operands[0] == IA64_OPND_TGT25c);
1081 else
1082 resolved = 1;
1083 }
1084
1085 /* probe variations */
1086 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1087 {
1088 resolved = strcmp (ic->name, "probe") == 0
1089 && !((strstr (idesc->name, "fault") != NULL)
1090 ^ (format && strstr (format, "M40") != NULL));
1091 }
1092 /* mov variations */
1093 if (!resolved && is_mov)
1094 {
1095 if (plain_mov)
1096 {
1097 /* mov alias for fmerge */
1098 if (strcmp (ic->name, "fmerge") == 0)
1099 {
1100 resolved = idesc->operands[0] == IA64_OPND_F1
1101 && idesc->operands[1] == IA64_OPND_F3;
1102 }
1103 /* mov alias for adds (r3 or imm14) */
1104 else if (strcmp (ic->name, "adds") == 0)
1105 {
1106 resolved = (idesc->operands[0] == IA64_OPND_R1
1107 && (idesc->operands[1] == IA64_OPND_R3
1108 || (idesc->operands[1] == IA64_OPND_IMM14)));
1109 }
1110 /* mov alias for addl */
1111 else if (strcmp (ic->name, "addl") == 0)
1112 {
1113 resolved = idesc->operands[0] == IA64_OPND_R1
1114 && idesc->operands[1] == IA64_OPND_IMM22;
1115 }
1116 }
1117 /* some variants of mov and mov.[im] */
1118 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1119 {
1120 resolved = in_iclass_mov_x (idesc, ic, format, field);
1121 }
1122 }
1123
1124 /* keep track of this so we can flag any insn classes which aren't
1125 mapped onto at least one real insn */
1126 if (resolved)
1127 {
1128 ic->terminal_resolved = 1;
1129 }
1130 }
1131 else for (i=0;i < ic->nsubs;i++)
1132 {
1133 if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep))
1134 {
1135 int j;
1136 for (j=0;j < ic->nxsubs;j++)
1137 {
1138 if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1139 return 0;
1140 }
1141 if (debug > 1)
1142 printf ("%s is in IC %s\n",
1143 idesc->name, ic->name);
1144 resolved = 1;
1145 break;
1146 }
1147 }
1148
1149 /* If it's in this IC, add the IC note (if any) to the insn */
1150 if (resolved)
1151 {
1152 if (ic->note && notep)
1153 {
1154 if (*notep && *notep != ic->note)
1155 {
1156 fprintf (stderr, "Warning: overwriting note %d with note %d"
1157 "(IC:%s)\n",
1158 *notep, ic->note, ic->name);
1159 }
1160 *notep = ic->note;
1161 }
1162 }
1163
1164 return resolved;
1165}
1166
1167\f
1168static int
1169lookup_regindex (const char *name, int specifier)
1170{
1171 switch (specifier)
1172 {
1173 case IA64_RS_ARX:
1174 if (strstr (name, "[RSC]"))
1175 return 16;
1176 if (strstr (name, "[BSP]"))
1177 return 17;
1178 else if (strstr (name, "[BSPSTORE]"))
1179 return 18;
1180 else if (strstr (name, "[RNAT]"))
1181 return 19;
1182 else if (strstr (name, "[CCV]"))
1183 return 32;
1184 else if (strstr (name, "[ITC]"))
1185 return 44;
1186 else if (strstr (name, "[PFS]"))
1187 return 64;
1188 else if (strstr (name, "[LC]"))
1189 return 65;
1190 else if (strstr (name, "[EC]"))
1191 return 66;
1192 abort ();
1193 case IA64_RS_CRX:
1194 if (strstr (name, "[DCR]"))
1195 return 0;
1196 else if (strstr (name, "[ITM]"))
1197 return 1;
1198 else if (strstr (name, "[IVA]"))
1199 return 2;
1200 else if (strstr (name, "[PTA]"))
1201 return 8;
1202 else if (strstr (name, "[GPTA]"))
1203 return 9;
1204 else if (strstr (name, "[IPSR]"))
1205 return 16;
1206 else if (strstr (name, "[ISR]"))
1207 return 17;
1208 else if (strstr (name, "[IIP]"))
1209 return 19;
1210 else if (strstr (name, "[IFA]"))
1211 return 20;
1212 else if (strstr (name, "[ITIR]"))
1213 return 21;
1214 else if (strstr (name, "[IIPA]"))
1215 return 22;
1216 else if (strstr (name, "[IFS]"))
1217 return 23;
1218 else if (strstr (name, "[IIM]"))
1219 return 24;
1220 else if (strstr (name, "[IHA]"))
1221 return 25;
1222 else if (strstr (name, "[LID]"))
1223 return 64;
1224 else if (strstr (name, "[IVR]"))
1225 return 65;
1226 else if (strstr (name, "[TPR]"))
1227 return 66;
1228 else if (strstr (name, "[EOI]"))
1229 return 67;
1230 else if (strstr (name, "[ITV]"))
1231 return 72;
1232 else if (strstr (name, "[PMV]"))
1233 return 73;
1234 else if (strstr (name, "[CMCV]"))
1235 return 74;
1236 abort ();
1237 case IA64_RS_PSR:
1238 if (strstr (name, ".be"))
1239 return 1;
1240 else if (strstr (name, ".up"))
1241 return 2;
1242 else if (strstr (name, ".ac"))
1243 return 3;
1244 else if (strstr (name, ".mfl"))
1245 return 4;
1246 else if (strstr (name, ".mfh"))
1247 return 5;
1248 else if (strstr (name, ".ic"))
1249 return 13;
1250 else if (strstr (name, ".i"))
1251 return 14;
1252 else if (strstr (name, ".pk"))
1253 return 15;
1254 else if (strstr (name, ".dt"))
1255 return 17;
1256 else if (strstr (name, ".dfl"))
1257 return 18;
1258 else if (strstr (name, ".dfh"))
1259 return 19;
1260 else if (strstr (name, ".sp"))
1261 return 20;
1262 else if (strstr (name, ".pp"))
1263 return 21;
1264 else if (strstr (name, ".di"))
1265 return 22;
1266 else if (strstr (name, ".si"))
1267 return 23;
1268 else if (strstr (name, ".db"))
1269 return 24;
1270 else if (strstr (name, ".lp"))
1271 return 25;
1272 else if (strstr (name, ".tb"))
1273 return 26;
1274 else if (strstr (name, ".rt"))
1275 return 27;
1276 else if (strstr (name, ".cpl"))
1277 return 32;
1278 else if (strstr (name, ".rs"))
1279 return 34;
1280 else if (strstr (name, ".mc"))
1281 return 35;
1282 else if (strstr (name, ".it"))
1283 return 36;
1284 else if (strstr (name, ".id"))
1285 return 37;
1286 else if (strstr (name, ".da"))
1287 return 38;
1288 else if (strstr (name, ".dd"))
1289 return 39;
1290 else if (strstr (name, ".ss"))
1291 return 40;
1292 else if (strstr (name, ".ri"))
1293 return 41;
1294 else if (strstr (name, ".ed"))
1295 return 43;
1296 else if (strstr (name, ".bn"))
1297 return 44;
1298 else if (strstr (name, ".ia"))
1299 return 45;
1300 else
1301 abort ();
1302 default:
1303 break;
1304 }
1305 return REG_NONE;
1306}
1307
1308static int
1309lookup_specifier (const char *name)
1310{
1311 if (strchr (name, '%'))
1312 {
1313 if (strstr (name, "AR[K%]") != NULL)
1314 return IA64_RS_AR_K;
1315 if (strstr (name, "AR[UNAT]") != NULL)
1316 return IA64_RS_AR_UNAT;
1317 if (strstr (name, "AR%, % in 8") != NULL)
1318 return IA64_RS_AR;
1319 if (strstr (name, "AR%, % in 48") != NULL)
1320 return IA64_RS_ARb;
1321 if (strstr (name, "BR%") != NULL)
1322 return IA64_RS_BR;
1323 if (strstr (name, "CR[IRR%]") != NULL)
1324 return IA64_RS_CR_IRR;
1325 if (strstr (name, "CR[LRR%]") != NULL)
1326 return IA64_RS_CR_LRR;
1327 if (strstr (name, "CR%") != NULL)
1328 return IA64_RS_CR;
1329 if (strstr (name, "FR%, % in 0") != NULL)
1330 return IA64_RS_FR;
1331 if (strstr (name, "FR%, % in 2") != NULL)
1332 return IA64_RS_FRb;
1333 if (strstr (name, "GR%") != NULL)
1334 return IA64_RS_GR;
1335 if (strstr (name, "PR%") != NULL)
1336 return IA64_RS_PR;
1337
1338 fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
1339 name);
1340 }
1341 else if (strchr (name, '#'))
1342 {
1343 if (strstr (name, "CPUID#") != NULL)
1344 return IA64_RS_CPUID;
1345 if (strstr (name, "DBR#") != NULL)
1346 return IA64_RS_DBR;
1347 if (strstr (name, "IBR#") != NULL)
1348 return IA64_RS_IBR;
1349 if (strstr (name, "MSR#") != NULL)
1350 return IA64_RS_MSR;
1351 if (strstr (name, "PKR#") != NULL)
1352 return IA64_RS_PKR;
1353 if (strstr (name, "PMC#") != NULL)
1354 return IA64_RS_PMC;
1355 if (strstr (name, "PMD#") != NULL)
1356 return IA64_RS_PMD;
1357 if (strstr (name, "RR#") != NULL)
1358 return IA64_RS_RR;
1359
1360 fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",
1361 name);
1362 }
1363 else if (strncmp (name, "AR[FPSR]", 8) == 0)
1364 return IA64_RS_AR_FPSR;
1365 else if (strncmp (name, "AR[", 3) == 0)
1366 return IA64_RS_ARX;
1367 else if (strncmp (name, "CR[", 3) == 0)
1368 return IA64_RS_CRX;
1369 else if (strncmp (name, "PSR.", 4) == 0)
1370 return IA64_RS_PSR;
1371 else if (strcmp (name, "InService*") == 0)
1372 return IA64_RS_INSERVICE;
1373 else if (strcmp (name, "GR0") == 0)
1374 return IA64_RS_GR0;
1375 else if (strcmp (name, "CFM") == 0)
1376 return IA64_RS_CFM;
1377 else if (strcmp (name, "PR63") == 0)
1378 return IA64_RS_PR63;
1379 else if (strcmp (name, "RSE") == 0)
1380 return IA64_RS_RSE;
1381
1382 return IA64_RS_ANY;
1383}
1384
1385void
1386print_dependency_table ()
1387{
1388 int i, j;
1389
1390 if (debug)
1391 {
1392 for (i=0;i < iclen;i++)
1393 {
1394 if (ics[i]->is_class)
1395 {
1396 if (!ics[i]->nsubs)
1397 {
1398 fprintf (stderr, "Warning: IC:%s", ics[i]->name);
1399 if (ics[i]->comment)
1400 fprintf (stderr, "[%s]", ics[i]->comment);
1401 fprintf (stderr, " has no terminals or sub-classes\n");
1402 }
1403 }
1404 else
1405 {
1406 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1407 {
1408 fprintf(stderr, "Warning: no insns mapped directly to "
1409 "terminal IC %s", ics[i]->name);
1410 if (ics[i]->comment)
1411 fprintf(stderr, "[%s] ", ics[i]->comment);
1412 fprintf(stderr, "\n");
1413 }
1414 }
1415 }
1416
1417 for (i=0;i < iclen;i++)
1418 {
1419 if (ics[i]->orphan)
1420 {
1421 mark_used (ics[i], 1);
1422 fprintf (stderr, "Warning: class %s is defined but not used\n",
1423 ics[i]->name);
1424 }
1425 }
1426
1427 if (debug > 1) for (i=0;i < rdepslen;i++)
1428 {
1429 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1430 if (rdeps[i]->total_chks == 0)
1431 {
1432 fprintf (stderr, "Warning: rsrc %s (%s) has no chks%s\n",
1433 rdeps[i]->name, mode_str[rdeps[i]->mode],
1434 rdeps[i]->total_regs ? "" : " or regs");
1435 }
1436 else if (rdeps[i]->total_regs == 0)
1437 {
1438 fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n",
1439 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1440 }
1441 }
1442 }
1443
1444 /* the dependencies themselves */
1445 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1446 for (i=0;i < rdepslen;i++)
1447 {
1448 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1449 resource used */
1450 int specifier = lookup_specifier (rdeps[i]->name);
1451 int regindex = lookup_regindex (rdeps[i]->name, specifier);
1452
1453 printf (" { \"%s\", %d, %d, %d, %d, ",
1454 rdeps[i]->name, specifier,
1455 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1456 if (rdeps[i]->semantics == IA64_DVS_OTHER)
1457 printf ("\"%s\", ", rdeps[i]->extra);
1458 printf("},\n");
1459 }
1460 printf ("};\n\n");
1461
1462 /* and dependency lists */
1463 for (i=0;i < dlistlen;i++)
1464 {
1465 int len = 2;
1466 printf ("static const short dep%d[] = {\n ", i);
1467 for (j=0;j < dlists[i]->len; j++)
1468 {
1469 len += printf ("%d, ", dlists[i]->deps[j]);
1470 if (len > 75)
1471 {
1472 printf("\n ");
1473 len = 2;
1474 }
1475 }
1476 printf ("\n};\n\n");
1477 }
1478
1479 /* and opcode dependency list */
1480 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1481 printf ("static const struct ia64_opcode_dependency\n");
1482 printf ("op_dependencies[] = {\n");
1483 for (i=0;i < opdeplen;i++)
1484 {
1485 printf (" { ");
1486 if (opdeps[i]->chk == -1)
1487 printf ("0, NULL, ");
1488 else
1489 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1490 if (opdeps[i]->reg == -1)
1491 printf ("0, NULL, ");
1492 else
1493 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1494 printf ("},\n");
1495 }
1496 printf ("};\n\n");
1497}
1498
1499\f
1500/* Add STR to the string table. */
1501
1502static struct string_entry *
1503insert_string (str)
1504 char *str;
1505{
1506 int start = 0, end = strtablen;
1507 int i, x;
1508
1509 if (strtablen == strtabtotlen)
1510 {
1511 strtabtotlen += 20;
1512 string_table = (struct string_entry **)
1513 xrealloc (string_table,
1514 sizeof (struct string_entry **) * strtabtotlen);
1515 }
1516
1517 if (strtablen == 0)
1518 {
1519 strtablen = 1;
1520 string_table[0] = tmalloc (struct string_entry);
1521 string_table[0]->s = xstrdup (str);
1522 string_table[0]->num = 0;
1523 return string_table[0];
1524 }
1525
1526 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1527 {
1528 i = end;
1529 }
1530 else if (strcmp (str, string_table[0]->s) < 0)
1531 {
1532 i = 0;
1533 }
1534 else
1535 {
1536 while (1)
1537 {
1538 int c;
1539
1540 i = (start + end) / 2;
1541 c = strcmp (str, string_table[i]->s);
1542 if (c < 0)
1543 {
1544 end = i - 1;
1545 }
1546 else if (c == 0)
1547 {
1548 return string_table[i];
1549 }
1550 else
1551 {
1552 start = i + 1;
1553 }
1554 if (start > end)
1555 {
1556 break;
1557 }
1558 }
1559 }
1560 for (; i > 0 && i < strtablen; i--)
1561 {
1562 if (strcmp (str, string_table[i - 1]->s) > 0)
1563 {
1564 break;
1565 }
1566 }
1567 for (; i < strtablen; i++)
1568 {
1569 if (strcmp (str, string_table[i]->s) < 0)
1570 {
1571 break;
1572 }
1573 }
1574 for (x = strtablen - 1; x >= i; x--)
1575 {
1576 string_table[x + 1] = string_table[x];
1577 string_table[x + 1]->num = x + 1;
1578 }
1579 string_table[i] = tmalloc (struct string_entry);
1580 string_table[i]->s = xstrdup (str);
1581 string_table[i]->num = i;
1582 strtablen++;
1583 return string_table[i];
1584}
1585\f
1586struct bittree *
1587make_bittree_entry ()
1588{
1589 struct bittree *res = tmalloc (struct bittree);
1590
1591 res->disent = NULL;
1592 res->bits[0] = NULL;
1593 res->bits[1] = NULL;
1594 res->bits[2] = NULL;
1595 res->skip_flag = 0;
1596 res->bits_to_skip = 0;
1597 return res;
1598}
1599\f
1600struct disent *
aa170a07 1601add_dis_table_ent (which, insn, order, completer_index)
800eeca4
JW
1602 struct disent *which;
1603 int insn;
aa170a07 1604 int order;
800eeca4
JW
1605 int completer_index;
1606{
1607 int ci = 0;
1608 struct disent *ent;
1609
1610 if (which != NULL)
1611 {
1612 ent = which;
1613
1614 ent->nextcnt++;
1615 while (ent->nexte != NULL)
1616 {
1617 ent = ent->nexte;
1618 }
1619 ent = (ent->nexte = tmalloc (struct disent));
1620 }
1621 else
1622 {
1623 ent = tmalloc (struct disent);
1624 ent->next_ent = disinsntable;
1625 disinsntable = ent;
1626 which = ent;
1627 }
1628 ent->nextcnt = 0;
1629 ent->nexte = NULL;
1630 ent->insn = insn;
aa170a07
TW
1631 ent->priority = order;
1632
800eeca4
JW
1633 while (completer_index != 1)
1634 {
1635 ci = (ci << 1) | (completer_index & 1);
1636 completer_index >>= 1;
1637 }
1638 ent->completer_index = ci;
1639 return which;
1640}
1641\f
1642void
1643finish_distable ()
1644{
1645 struct disent *ent = disinsntable;
1646 struct disent *prev = ent;
1647
1648 ent->ournum = 32768;
1649 while ((ent = ent->next_ent) != NULL)
1650 {
1651 ent->ournum = prev->ournum + prev->nextcnt + 1;
1652 prev = ent;
1653 }
1654}
1655\f
1656void
aa170a07
TW
1657insert_bit_table_ent (curr_ent, bit, opcode, mask,
1658 opcodenum, order, completer_index)
800eeca4
JW
1659 struct bittree *curr_ent;
1660 int bit;
1661 ia64_insn opcode;
1662 ia64_insn mask;
1663 int opcodenum;
aa170a07 1664 int order;
800eeca4
JW
1665 int completer_index;
1666{
1667 ia64_insn m;
1668 int b;
1669 struct bittree *next;
1670
1671 if (bit == -1)
1672 {
aa170a07
TW
1673 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1674 opcodenum, order,
800eeca4
JW
1675 completer_index);
1676 curr_ent->disent = nent;
1677 return;
1678 }
1679
1680 m = ((ia64_insn) 1) << bit;
1681
1682 if (mask & m)
1683 {
1684 b = (opcode & m) ? 1 : 0;
1685 }
1686 else
1687 {
1688 b = 2;
1689 }
1690 next = curr_ent->bits[b];
1691 if (next == NULL)
1692 {
1693 next = make_bittree_entry ();
1694 curr_ent->bits[b] = next;
1695 }
aa170a07 1696 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
800eeca4
JW
1697 completer_index);
1698}
1699\f
1700void
1701add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
aa170a07 1702 struct bittree *first;
800eeca4
JW
1703 ia64_insn opcode;
1704 ia64_insn mask;
1705 int opcodenum;
1706 struct completer_entry *ent;
1707 int completer_index;
1708{
1709 if (completer_index & (1 << 20))
1710 {
1711 abort ();
1712 }
1713 while (ent != NULL)
1714 {
1715 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1716 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1717 (completer_index << 1) | 1);
1718 if (ent->is_terminal)
1719 {
aa170a07
TW
1720 insert_bit_table_ent (bittree, 40, newopcode, mask,
1721 opcodenum, opcode_count - ent->order - 1,
800eeca4
JW
1722 (completer_index << 1) | 1);
1723 }
1724 completer_index <<= 1;
1725 ent = ent->alternative;
1726 }
1727}
1728\f
1729/* This optimization pass combines multiple "don't care" nodes. */
1730void
1731compact_distree (ent)
1732 struct bittree *ent;
1733{
1734#define IS_SKIP(ent) \
1735 ((ent->bits[2] !=NULL) \
1736 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1737
1738 int bitcnt = 0;
1739 struct bittree *nent = ent;
1740 int x;
1741
1742 while (IS_SKIP (nent))
1743 {
1744 bitcnt++;
1745 nent = nent->bits[2];
1746 }
1747
1748 if (bitcnt)
1749 {
1750 struct bittree *next = ent->bits[2];
1751
1752 ent->bits[0] = nent->bits[0];
1753 ent->bits[1] = nent->bits[1];
1754 ent->bits[2] = nent->bits[2];
1755 ent->disent = nent->disent;
1756 ent->skip_flag = 1;
1757 ent->bits_to_skip = bitcnt;
1758 while (next != nent)
1759 {
1760 struct bittree *b = next;
1761 next = next->bits[2];
1762 free (b);
1763 }
1764 free (nent);
1765 }
1766
1767 for (x = 0; x < 3; x++)
1768 {
1769 struct bittree *i = ent->bits[x];
1770 if (i != NULL)
1771 {
1772 compact_distree (i);
1773 }
1774 }
1775}
1776\f
1777static unsigned char *insn_list;
1778static int insn_list_len = 0;
1779static int tot_insn_list_len = 0;
1780
1781/* Generate the disassembler state machine corresponding to the tree
1782 in ENT. */
1783void
1784gen_dis_table (ent)
1785 struct bittree *ent;
1786{
1787 int x;
1788 int our_offset = insn_list_len;
1789 int bitsused = 5;
1790 int totbits = bitsused;
1791 int needed_bytes;
1792 int zero_count = 0;
1793 int zero_dest = 0; /* initialize this with 0 to keep gcc quiet... */
1794
1795 /* If this is a terminal entry, there's no point in skipping any
1796 bits. */
1797 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1798 ent->bits[2] == NULL)
1799 {
1800 if (ent->disent == NULL)
1801 {
1802 abort ();
1803 }
1804 else
1805 {
1806 ent->skip_flag = 0;
1807 }
1808 }
1809
1810 /* Calculate the amount of space needed for this entry, or at least
1811 a conservatively large approximation. */
1812 if (ent->skip_flag)
1813 {
1814 totbits += 5;
1815 }
1816 for (x = 1; x < 3; x++)
1817 {
1818 if (ent->bits[x] != NULL)
1819 {
1820 totbits += 16;
1821 }
1822 }
1823
1824 if (ent->disent != NULL)
1825 {
1826 if (ent->bits[2] != NULL)
1827 {
1828 abort ();
1829 }
1830 totbits += 16;
1831 }
1832
1833 /* Now allocate the space. */
1834 needed_bytes = (totbits + 7) / 8;
1835 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1836 {
1837 tot_insn_list_len += 256;
1838 insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1839 }
1840 our_offset = insn_list_len;
1841 insn_list_len += needed_bytes;
1842 memset (insn_list + our_offset, 0, needed_bytes);
1843
1844 /* Encode the skip entry by setting bit 6 set in the state op field,
1845 and store the # of bits to skip immediately after. */
1846 if (ent->skip_flag)
1847 {
1848 bitsused += 5;
1849 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1850 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1851 }
1852
1853#define IS_ONLY_IFZERO(ENT) \
1854 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1855 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1856
1857 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1858 state op field. */
1859
1860 if (ent->bits[0] != NULL)
1861 {
1862 struct bittree *nent = ent->bits[0];
1863 zero_count = 0;
1864
1865 insn_list[our_offset] |= 0x80;
1866
1867 /* We can encode sequences of multiple "if (bit is zero)" tests
1868 by storing the # of zero bits to check in the lower 3 bits of
1869 the instruction. However, this only applies if the state
1870 solely tests for a zero bit. */
1871
1872 if (IS_ONLY_IFZERO (ent))
1873 {
1874 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1875 {
1876 nent = nent->bits[0];
1877 zero_count++;
1878 }
1879
1880 insn_list[our_offset + 0] |= zero_count;
1881 }
1882 zero_dest = insn_list_len;
1883 gen_dis_table (nent);
1884 }
1885
1886 /* Now store the remaining tests. We also handle a sole "termination
1887 entry" by storing it as an "any bit" test. */
1888
1889 for (x = 1; x < 3; x++)
1890 {
1891 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1892 {
1893 struct bittree *i = ent->bits[x];
1894 int idest;
1895 int currbits = 15;
1896
1897 if (i != NULL)
1898 {
1899 /* If the instruction being branched to only consists of
1900 a termination entry, use the termination entry as the
1901 place to branch to instead. */
1902 if (i->bits[0] == NULL && i->bits[1] == NULL
1903 && i->bits[2] == NULL && i->disent != NULL)
1904 {
1905 idest = i->disent->ournum;
1906 i = NULL;
1907 }
1908 else
1909 {
1910 idest = insn_list_len - our_offset;
1911 }
1912 }
1913 else
1914 {
1915 idest = ent->disent->ournum;
1916 }
1917
1918 /* If the destination offset for the if (bit is 1) test is less
1919 than 256 bytes away, we can store it as 8-bits instead of 16;
1920 the instruction has bit 5 set for the 16-bit address, and bit
1921 4 for the 8-bit address. Since we've already allocated 16
1922 bits for the address we need to deallocate the space.
1923
1924 Note that branchings within the table are relative, and
1925 there are no branches that branch past our instruction yet
1926 so we do not need to adjust any other offsets. */
1927
1928 if (x == 1)
1929 {
1930 if (idest <= 256)
1931 {
1932 int start = our_offset + bitsused / 8 + 1;
1933
1934 memmove (insn_list + start,
1935 insn_list + start + 1,
1936 insn_list_len - (start + 1));
1937 currbits = 7;
1938 totbits -= 8;
1939 needed_bytes--;
1940 insn_list_len--;
1941 insn_list[our_offset] |= 0x10;
1942 idest--;
1943 }
1944 else
1945 {
1946 insn_list[our_offset] |= 0x20;
1947 }
1948 }
1949 else
1950 {
1951 /* An instruction which solely consists of a termination
1952 marker and whose disassembly name index is < 4096
1953 can be stored in 16 bits. The encoding is slightly
1954 odd; the upper 4 bits of the instruction are 0x3, and
1955 bit 3 loses its normal meaning. */
1956
1957 if (ent->bits[0] == NULL && ent->bits[1] == NULL
1958 && ent->bits[2] == NULL && ent->skip_flag == 0
1959 && ent->disent != NULL
1960 && ent->disent->ournum < (32768 + 4096))
1961 {
1962 int start = our_offset + bitsused / 8 + 1;
1963
1964 memmove (insn_list + start,
1965 insn_list + start + 1,
1966 insn_list_len - (start + 1));
1967 currbits = 11;
1968 totbits -= 5;
1969 bitsused--;
1970 needed_bytes--;
1971 insn_list_len--;
1972 insn_list[our_offset] |= 0x30;
1973 idest &= ~32768;
1974 }
1975 else
1976 {
1977 insn_list[our_offset] |= 0x08;
1978 }
1979 }
1980 if (debug)
1981 {
1982 int id = idest;
1983
1984 if (i == NULL)
1985 {
1986 id |= 32768;
1987 }
1988 else if (! (id & 32768))
1989 {
1990 id += our_offset;
1991 }
1992 if (x == 1)
1993 {
1994 printf ("%d: if (1) goto %d\n", our_offset, id);
1995 }
1996 else
1997 {
1998 printf ("%d: try %d\n", our_offset, id);
1999 }
2000 }
2001
2002 /* Store the address of the entry being branched to. */
2003 while (currbits >= 0)
2004 {
2005 char *byte = insn_list + our_offset + bitsused / 8;
2006
2007 if (idest & (1 << currbits))
2008 {
2009 *byte |= (1 << (7 - (bitsused % 8)));
2010 }
2011 bitsused++;
2012 currbits--;
2013 }
2014
2015 /* Now generate the states for the entry being branched to. */
2016 if (i != NULL)
2017 {
2018 gen_dis_table (i);
2019 }
2020
2021 }
2022 }
2023 if (debug)
2024 {
2025 if (ent->skip_flag)
2026 {
2027 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2028 }
2029
2030 if (ent->bits[0] != NULL)
2031 {
2032 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2033 zero_dest);
2034 }
2035 }
2036 if (bitsused != totbits)
2037 {
2038 abort ();
2039 }
2040}
2041\f
2042void
2043print_dis_table ()
2044{
2045 int x;
2046 struct disent *cent = disinsntable;
2047
2048 printf ("static const char dis_table[] = {\n");
2049 for (x = 0; x < insn_list_len; x++)
2050 {
2051 if ((x > 0) && ((x % 12) == 0))
2052 {
2053 printf ("\n");
2054 }
2055 printf ("0x%02x, ", insn_list[x]);
2056 }
2057 printf ("\n};\n\n");
2058
2059 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2060 while (cent != NULL)
2061 {
2062 struct disent *ent = cent;
2063
2064 while (ent != NULL)
2065 {
aa170a07
TW
2066 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2067 ent->insn, (ent->nexte != NULL ? 1 : 0),
2068 ent->priority);
800eeca4
JW
2069 ent = ent->nexte;
2070 }
2071 cent = cent->next_ent;
2072 }
2073 printf ("};\n\n");
2074}
2075\f
2076void
2077generate_disassembler ()
2078{
aa170a07 2079 int i;
800eeca4
JW
2080
2081 bittree = make_bittree_entry ();
2082
aa170a07 2083 for (i=0; i < otlen;i++)
800eeca4 2084 {
aa170a07
TW
2085 struct main_entry *ptr = ordered_table[i];
2086
800eeca4
JW
2087 if (ptr->opcode->type != IA64_TYPE_DYN)
2088 {
2089 add_dis_entry (bittree,
aa170a07
TW
2090 ptr->opcode->opcode, ptr->opcode->mask,
2091 ptr->main_index,
800eeca4
JW
2092 ptr->completers, 1);
2093 }
800eeca4
JW
2094 }
2095
2096 compact_distree (bittree);
2097 finish_distable ();
2098 gen_dis_table (bittree);
2099
2100 print_dis_table ();
2101}
2102\f
2103void
2104print_string_table ()
2105{
2106 int x;
2107 char lbuf[80], buf[80];
2108 int blen = 0;
2109
2110 printf ("static const char *ia64_strings[] = {\n");
2111 lbuf[0] = '\0';
2112 for (x = 0; x < strtablen; x++)
2113 {
2114 int len;
2115
2116 if (strlen (string_table[x]->s) > 75)
2117 {
2118 abort ();
2119 }
2120 sprintf (buf, " \"%s\",", string_table[x]->s);
2121 len = strlen (buf);
2122 if ((blen + len) > 75)
2123 {
2124 printf (" %s\n", lbuf);
2125 lbuf[0] = '\0';
2126 blen = 0;
2127 }
2128 strcat (lbuf, buf);
2129 blen += len;
2130 }
2131 if (blen > 0)
2132 {
2133 printf (" %s\n", lbuf);
2134 }
2135 printf ("};\n\n");
2136}
2137\f
2138static struct completer_entry **glist;
2139static int glistlen = 0;
2140static int glisttotlen = 0;
2141
2142/* If the completer trees ENT1 and ENT2 are equal, return 1. */
2143
2144int
2145completer_entries_eq (ent1, ent2)
2146 struct completer_entry *ent1, *ent2;
2147{
2148 while (ent1 != NULL && ent2 != NULL)
2149 {
2150 if (ent1->name->num != ent2->name->num
2151 || ent1->bits != ent2->bits
2152 || ent1->mask != ent2->mask
2153 || ent1->is_terminal != ent2->is_terminal
aa170a07
TW
2154 || ent1->dependencies != ent2->dependencies
2155 || ent1->order != ent2->order)
800eeca4
JW
2156 {
2157 return 0;
2158 }
2159 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2160 {
2161 return 0;
2162 }
2163 ent1 = ent1->alternative;
2164 ent2 = ent2->alternative;
2165 }
2166 return ent1 == ent2;
2167}
2168\f
2169/* Insert ENT into the global list of completers and return it. If an
2170 equivalent entry (according to completer_entries_eq) already exists,
2171 it is returned instead. */
2172struct completer_entry *
2173insert_gclist (ent)
2174 struct completer_entry *ent;
2175{
2176 if (ent != NULL)
2177 {
2178 int i;
2179 int x;
2180 int start = 0, end;
2181
2182 ent->addl_entries = insert_gclist (ent->addl_entries);
2183 ent->alternative = insert_gclist (ent->alternative);
2184
2185 i = glistlen / 2;
2186 end = glistlen;
2187
2188 if (glisttotlen == glistlen)
2189 {
2190 glisttotlen += 20;
2191 glist = (struct completer_entry **)
2192 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2193 }
2194
2195 if (glistlen == 0)
2196 {
2197 glist[0] = ent;
2198 glistlen = 1;
2199 return ent;
2200 }
2201
2202 if (ent->name->num < glist[0]->name->num)
2203 {
2204 i = 0;
2205 }
2206 else if (ent->name->num > glist[end - 1]->name->num)
2207 {
2208 i = end;
2209 }
2210 else
2211 {
2212 int c;
2213
2214 while (1)
2215 {
2216 i = (start + end) / 2;
2217 c = ent->name->num - glist[i]->name->num;
2218 if (c < 0)
2219 {
2220 end = i - 1;
2221 }
2222 else if (c == 0)
2223 {
2224 while (i > 0
2225 && ent->name->num == glist[i - 1]->name->num)
2226 {
2227 i--;
2228 }
2229 break;
2230 }
2231 else
2232 {
2233 start = i + 1;
2234 }
2235 if (start > end)
2236 {
2237 break;
2238 }
2239 }
2240 if (c == 0)
2241 {
2242 while (i < glistlen)
2243 {
2244 if (ent->name->num != glist[i]->name->num)
2245 {
2246 break;
2247 }
2248 if (completer_entries_eq (ent, glist[i]))
2249 {
2250 return glist[i];
2251 }
2252 i++;
2253 }
2254 }
2255 }
2256 for (; i > 0 && i < glistlen; i--)
2257 {
2258 if (ent->name->num >= glist[i - 1]->name->num)
2259 {
2260 break;
2261 }
2262 }
2263 for (; i < glistlen; i++)
2264 {
2265 if (ent->name->num < glist[i]->name->num)
2266 {
2267 break;
2268 }
2269 }
2270 for (x = glistlen - 1; x >= i; x--)
2271 {
2272 glist[x + 1] = glist[x];
2273 }
2274 glist[i] = ent;
2275 glistlen++;
2276 }
2277 return ent;
2278}
2279\f
2280static int
2281get_prefix_len (name)
2282 const char *name;
2283{
2284 char *c;
2285
2286 if (name[0] == '\0')
2287 {
2288 return 0;
2289 }
2290
2291 c = strchr (name, '.');
2292 if (c != NULL)
2293 {
2294 return c - name;
2295 }
2296 else
2297 {
2298 return strlen (name);
2299 }
2300}
2301\f
2302static void
2303compute_completer_bits (ment, ent)
2304 struct main_entry *ment;
2305 struct completer_entry *ent;
2306{
2307 while (ent != NULL)
2308 {
2309 compute_completer_bits (ment, ent->addl_entries);
2310
2311 if (ent->is_terminal)
2312 {
2313 ia64_insn mask = 0;
2314 ia64_insn our_bits = ent->bits;
2315 struct completer_entry *p = ent->parent;
2316 ia64_insn p_bits;
2317 int x;
2318
2319 while (p != NULL && ! p->is_terminal)
2320 {
2321 p = p->parent;
2322 }
2323
2324 if (p != NULL)
2325 {
2326 p_bits = p->bits;
2327 }
2328 else
2329 {
2330 p_bits = ment->opcode->opcode;
2331 }
2332
2333 for (x = 0; x < 64; x++)
2334 {
2335 ia64_insn m = ((ia64_insn) 1) << x;
2336 if ((p_bits & m) != (our_bits & m))
2337 {
2338 mask |= m;
2339 }
2340 else
2341 {
2342 our_bits &= ~m;
2343 }
2344 }
2345 ent->bits = our_bits;
2346 ent->mask = mask;
2347 }
2348 else
2349 {
2350 ent->bits = 0;
2351 ent->mask = 0;
2352 }
2353
2354 ent = ent->alternative;
2355 }
2356}
2357\f
2358/* Find identical completer trees that are used in different
2359 instructions and collapse their entries. */
2360void
2361collapse_redundant_completers ()
2362{
2363 struct main_entry *ptr;
2364 int x;
2365
2366 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2367 {
2368 if (ptr->completers == NULL)
2369 {
2370 abort ();
2371 }
2372 compute_completer_bits (ptr, ptr->completers);
2373 ptr->completers = insert_gclist (ptr->completers);
2374 }
2375
2376 /* The table has been finalized, now number the indexes. */
2377 for (x = 0; x < glistlen; x++)
2378 {
2379 glist[x]->num = x;
2380 }
2381}
2382\f
2383
2384/* attach two lists of dependencies to each opcode.
2385 1) all resources which, when already marked in use, conflict with this
2386 opcode (chks)
2387 2) all resources which must be marked in use when this opcode is used
2388 (regs)
2389*/
2390int
2391insert_opcode_dependencies (opc, cmp)
2392 struct ia64_opcode *opc;
2393 struct completer_entry *cmp;
2394{
2395 /* note all resources which point to this opcode. rfi has the most chks
2396 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2397 int i;
2398 int nregs = 0;
2399 unsigned short regs[256];
2400 int nchks = 0;
2401 unsigned short chks[256];
2402 /* flag insns for which no class matched; there should be none */
2403 int no_class_found = 1;
2404
2405 for (i=0;i < rdepslen;i++)
2406 {
2407 struct rdep *rs = rdeps[i];
2408 int j;
2409
2410 if (strcmp (opc->name, "cmp.eq.and") == 0
2411 && strncmp (rs->name, "PR%", 3) == 0
2412 && rs->mode == 1)
2413 no_class_found = 99;
2414
2415 for (j=0; j < rs->nregs;j++)
2416 {
2417 int ic_note = 0;
2418
2419 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2420 {
2421 /* We can ignore ic_note 11 for non PR resources */
2422 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2423 ic_note = 0;
2424
2425 if (ic_note != 0 && rs->regnotes[j] != 0
2426 && ic_note != rs->regnotes[j]
2427 && !(ic_note == 11 && rs->regnotes[j] == 1))
2428 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2429 " conflicts with resource %s note %d\n",
2430 ic_note, opc->name, ics[rs->regs[j]]->name,
2431 rs->name, rs->regnotes[j]);
2432 /* Instruction class notes override resource notes.
2433 So far, only note 11 applies to an IC instead of a resource,
2434 and note 11 implies note 1.
2435 */
2436 if (ic_note)
2437 regs[nregs++] = RDEP(ic_note, i);
2438 else
2439 regs[nregs++] = RDEP(rs->regnotes[j], i);
2440 no_class_found = 0;
2441 ++rs->total_regs;
2442 }
2443 }
2444 for (j=0;j < rs->nchks;j++)
2445 {
2446 int ic_note = 0;
2447
2448 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2449 {
2450 /* We can ignore ic_note 11 for non PR resources */
2451 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2452 ic_note = 0;
2453
2454 if (ic_note != 0 && rs->chknotes[j] != 0
2455 && ic_note != rs->chknotes[j]
2456 && !(ic_note == 11 && rs->chknotes[j] == 1))
2457 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2458 " conflicts with resource %s note %d\n",
2459 ic_note, opc->name, ics[rs->chks[j]]->name,
2460 rs->name, rs->chknotes[j]);
2461 if (ic_note)
2462 chks[nchks++] = RDEP(ic_note, i);
2463 else
2464 chks[nchks++] = RDEP(rs->chknotes[j], i);
2465 no_class_found = 0;
2466 ++rs->total_chks;
2467 }
2468 }
2469 }
2470
2471 if (no_class_found)
2472 fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n",
2473 opc->name,
2474 opc->operands[0], opc->operands[1], opc->operands[2]);
2475
2476 return insert_dependencies (nchks, chks, nregs, regs);
2477}
2478\f
2479void
aa170a07 2480insert_completer_entry (opc, tabent, order)
800eeca4
JW
2481 struct ia64_opcode *opc;
2482 struct main_entry *tabent;
aa170a07 2483 int order;
800eeca4
JW
2484{
2485 struct completer_entry **ptr = &tabent->completers;
2486 struct completer_entry *parent = NULL;
2487 char pcopy[129], *prefix;
2488 int at_end = 0;
2489
2490 if (strlen (opc->name) > 128)
2491 {
2492 abort ();
2493 }
2494 strcpy (pcopy, opc->name);
2495 prefix = pcopy + get_prefix_len (pcopy);
2496 if (prefix[0] != '\0')
2497 {
2498 prefix++;
2499 }
2500
2501 while (! at_end)
2502 {
2503 int need_new_ent = 1;
2504 int plen = get_prefix_len (prefix);
2505 struct string_entry *sent;
2506
2507 at_end = (prefix[plen] == '\0');
2508 prefix[plen] = '\0';
2509 sent = insert_string (prefix);
2510
2511 while (*ptr != NULL)
2512 {
2513 int cmpres = sent->num - (*ptr)->name->num;
2514
2515 if (cmpres == 0)
2516 {
2517 need_new_ent = 0;
2518 break;
2519 }
800eeca4
JW
2520 else
2521 {
2522 ptr = &((*ptr)->alternative);
2523 }
2524 }
2525 if (need_new_ent)
2526 {
2527 struct completer_entry *nent = tmalloc (struct completer_entry);
2528 nent->name = sent;
2529 nent->parent = parent;
2530 nent->addl_entries = NULL;
2531 nent->alternative = *ptr;
2532 *ptr = nent;
2533 nent->is_terminal = 0;
2534 nent->dependencies = -1;
2535 }
2536
2537 if (! at_end)
2538 {
2539 parent = *ptr;
2540 ptr = &((*ptr)->addl_entries);
2541 prefix += plen + 1;
2542 }
2543 }
2544
2545 if ((*ptr)->is_terminal)
2546 {
2547 abort ();
2548 }
2549
2550 (*ptr)->is_terminal = 1;
2551 (*ptr)->mask = (ia64_insn)-1;
2552 (*ptr)->bits = opc->opcode;
2553
2554 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
aa170a07 2555 (*ptr)->order = order;
800eeca4
JW
2556}
2557\f
2558void
2559print_completer_entry (ent)
2560 struct completer_entry *ent;
2561{
2562 int moffset = 0;
2563 ia64_insn mask = ent->mask, bits = ent->bits;
2564
2565 if (mask != 0)
2566 {
2567 while (! (mask & 1))
2568 {
2569 moffset++;
2570 mask = mask >> 1;
2571 bits = bits >> 1;
2572 }
2573 if (bits & 0xffffffff00000000LL)
2574 {
2575 abort ();
2576 }
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
2590void
2591print_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 {
2598 print_completer_entry (glist[x]);
2599 }
2600 printf ("};\n\n");
2601}
2602\f
2603int
2604opcodes_eq (opc1, opc2)
2605 struct ia64_opcode *opc1;
2606 struct ia64_opcode *opc2;
2607{
2608 int x;
2609 int plen1, plen2;
2610
2611 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2612 || (opc1->num_outputs != opc2->num_outputs)
2613 || (opc1->flags != opc2->flags))
2614 {
2615 return 0;
2616 }
2617 for (x = 0; x < 5; x++)
2618 {
2619 if (opc1->operands[x] != opc2->operands[x])
2620 {
2621 return 0;
2622 }
2623 }
2624 plen1 = get_prefix_len (opc1->name);
2625 plen2 = get_prefix_len (opc2->name);
2626 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2627 {
2628 return 1;
2629 }
2630 return 0;
2631}
2632\f
2633void
2634add_opcode_entry (opc)
2635 struct ia64_opcode *opc;
2636{
2637 struct main_entry **place;
2638 struct string_entry *name;
2639 char prefix[129];
2640 int found_it = 0;
2641
2642 if (strlen (opc->name) > 128)
2643 {
2644 abort ();
2645 }
2646 place = &maintable;
2647 strcpy (prefix, opc->name);
2648 prefix[get_prefix_len (prefix)] = '\0';
2649 name = insert_string (prefix);
2650
2651 /* Walk the list of opcode table entries. If it's a new
aa170a07
TW
2652 instruction, allocate and fill in a new entry. Note
2653 the main table is alphabetical by opcode name. */
800eeca4
JW
2654
2655 while (*place != NULL)
2656 {
2657 if ((*place)->name->num == name->num
2658 && opcodes_eq ((*place)->opcode, opc))
2659 {
2660 found_it = 1;
2661 break;
2662 }
2663 if ((*place)->name->num > name->num)
2664 {
2665 break;
2666 }
2667 place = &((*place)->next);
2668 }
2669 if (! found_it)
2670 {
2671 struct main_entry *nent = tmalloc (struct main_entry);
2672
2673 nent->name = name;
2674 nent->opcode = opc;
2675 nent->next = *place;
2676 nent->completers = 0;
2677 *place = nent;
aa170a07
TW
2678
2679 if (otlen == ottotlen)
2680 {
2681 ottotlen += 20;
2682 ordered_table = (struct main_entry **)
2683 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2684 }
2685 ordered_table[otlen++] = nent;
800eeca4 2686 }
aa170a07 2687 insert_completer_entry (opc, *place, opcode_count++);
800eeca4
JW
2688}
2689\f
2690void
2691print_main_table ()
2692{
2693 struct main_entry *ptr = maintable;
aa170a07 2694 int index = 0;
800eeca4
JW
2695
2696 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2697 while (ptr != NULL)
2698 {
2699 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2700 ptr->name->num,
2701 ptr->opcode->type,
2702 ptr->opcode->num_outputs,
2703 ptr->opcode->opcode,
2704 ptr->opcode->mask,
2705 ptr->opcode->operands[0],
2706 ptr->opcode->operands[1],
2707 ptr->opcode->operands[2],
2708 ptr->opcode->operands[3],
2709 ptr->opcode->operands[4],
2710 ptr->opcode->flags,
2711 ptr->completers->num);
2712
aa170a07
TW
2713 ptr->main_index = index++;
2714
800eeca4
JW
2715 ptr = ptr->next;
2716 }
2717 printf ("};\n\n");
2718}
2719\f
2720void
2721shrink (table)
2722 struct ia64_opcode *table;
2723{
2724 int curr_opcode;
2725
2726 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2727 {
2728 add_opcode_entry (table + curr_opcode);
2729 }
2730}
2731\f
2732int
2733main (int argc, char **argv)
2734{
2735 if (argc > 1)
2736 {
2737 debug = 1;
2738 }
2739
2740 load_insn_classes();
2741 load_dependencies();
2742
2743 shrink (ia64_opcodes_a);
2744 shrink (ia64_opcodes_b);
2745 shrink (ia64_opcodes_f);
2746 shrink (ia64_opcodes_i);
2747 shrink (ia64_opcodes_m);
2748 shrink (ia64_opcodes_x);
2749 shrink (ia64_opcodes_d);
2750
2751 collapse_redundant_completers ();
2752
2753 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2754 print_string_table ();
2755 print_dependency_table ();
2756 print_completer_table ();
2757 print_main_table ();
2758
2759 generate_disassembler ();
2760
2761 exit (0);
2762}
This page took 0.132142 seconds and 4 git commands to generate.