file opncls.texi was initially added on branch binutils-2_10-branch.
[binutils.git] / opcodes / ia64-gen.c
blob960540d50ca91aa584ba2dfbb82e4bc2e3ff8068
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>
5 This file is part of GDB, GAS, and the GNU binutils.
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.
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.
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. */
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.
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.
32 The resource table is constructed based on some text dependency tables,
33 which are also easier to maintain than the final representation.
37 #include <stdio.h>
38 #include <ctype.h>
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"
52 int debug = 0;
54 #define tmalloc(X) (X *) xmalloc (sizeof (X))
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). */
59 struct main_entry
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;
71 /* Index in the main table. */
72 int main_index;
73 } *maintable, **ordered_table;
74 int otlen = 0;
75 int ottotlen = 0;
76 int opcode_count = 0;
78 /* The set of possible completers for an opcode. */
79 struct completer_entry
81 /* This entry's index in the ia64_completer_table[] array. */
82 int num;
84 /* The name of the completer. */
85 struct string_entry *name;
87 /* This entry's parent. */
88 struct completer_entry *parent;
90 /* Set if this is a terminal completer (occurs at the end of an
91 opcode). */
92 int is_terminal;
94 /* An alternative completer. */
95 struct completer_entry *alternative;
97 /* Additional completers that can be appended to this one. */
98 struct completer_entry *addl_entries;
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;
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;
112 /* Index into the opcode dependency list, or -1 if none. */
113 int dependencies;
115 /* Remember the order encountered in the opcode tables. */
116 int order;
119 /* One entry in the disassembler name table. */
120 struct disent
122 /* The index into the ia64_name_dis array for this entry. */
123 int ournum;
125 /* The index into the main_table[] array. */
126 int insn;
128 /* The disassmbly priority of this entry. */
129 int priority;
131 /* The completer_index value for this entry. */
132 int completer_index;
134 /* How many other entries share this decode. */
135 int nextcnt;
137 /* The next entry sharing the same decode. */
138 struct disent *nexte;
140 /* The next entry in the name list. */
141 struct disent *next_ent;
142 } *disinsntable = NULL;
144 /* A state machine that will eventually be used to generate the
145 disassembler table. */
146 struct bittree
148 struct disent *disent;
149 struct bittree *bits[3]; /* 0, 1, and X (don't care) */
150 int bits_to_skip;
151 int skip_flag;
152 } *bittree;
154 /* The string table contains all opcodes and completers sorted in
155 alphabetical order. */
157 /* One entry in the string table. */
158 struct string_entry
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;
165 int strtablen = 0;
166 int strtabtotlen = 0;
169 /* resource dependency entries */
170 struct rdep
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 */
188 int waw_special; /* special WAW dependency note */
189 } **rdeps = NULL;
191 static int rdepslen = 0;
192 static int rdepstotlen = 0;
194 /* array of all instruction classes */
195 struct iclass
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;
209 static int iclen = 0;
210 static int ictotlen = 0;
212 /* an opcode dependency (chk/reg pair of dependency lists) */
213 struct opdep
215 int chk; /* index into dlists */
216 int reg; /* index into dlists */
217 } **opdeps;
219 static int opdeplen = 0;
220 static int opdeptotlen = 0;
222 /* a generic list of dependencies w/notes encoded. these may be shared. */
223 struct deplist
225 int len;
226 unsigned short *deps;
227 } **dlists;
229 static int dlistlen = 0;
230 static int dlisttotlen = 0;
232 /* add NAME to the resource table, where TYPE is RAW or WAW */
233 static struct rdep *
234 insert_resource (const char *name, enum ia64_dependency_mode type)
236 if (rdepslen == rdepstotlen)
238 rdepstotlen += 20;
239 rdeps = (struct rdep **)
240 xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
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;
248 return rdeps[rdepslen++];
251 /* are the lists of dependency indexes equivalent? */
252 static int
253 deplist_equals (struct deplist *d1, struct deplist *d2)
255 int i;
257 if (d1->len != d2->len)
258 return 0;
260 for (i=0;i < d1->len;i++)
262 if (d1->deps[i] != d2->deps[i])
263 return 0;
266 return 1;
269 /* add the list of dependencies to the list of dependency lists */
270 static short
271 insert_deplist(int count, unsigned short *deps)
273 /* sort the list, then see if an equivalent list exists already.
274 this results in a much smaller set of dependency lists
276 struct deplist *list;
277 char set[0x10000];
278 int i;
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;
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++)
293 if (set[i])
295 list->deps[count++] = i;
299 /* does this list exist already? */
300 for (i=0;i < dlistlen;i++)
302 if (deplist_equals (list, dlists[i]))
304 free (list->deps);
305 free (list);
306 return i;
310 if (dlistlen == dlisttotlen)
312 dlisttotlen += 20;
313 dlists = (struct deplist **)
314 xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
316 dlists[dlistlen] = list;
318 return dlistlen++;
321 /* add the given pair of dependency lists to the opcode dependency list */
322 static short
323 insert_dependencies (int nchks, unsigned short *chks,
324 int nregs, unsigned short *regs)
326 struct opdep *pair;
327 int i;
328 int regind = -1;
329 int chkind = -1;
331 if (nregs > 0)
332 regind = insert_deplist (nregs, regs);
333 if (nchks > 0)
334 chkind = insert_deplist (nchks, chks);
336 for (i=0;i < opdeplen;i++)
338 if (opdeps[i]->chk == chkind
339 && opdeps[i]->reg == regind)
340 return i;
342 pair = tmalloc(struct opdep);
343 pair->chk = chkind;
344 pair->reg = regind;
346 if (opdeplen == opdeptotlen)
348 opdeptotlen += 20;
349 opdeps = (struct opdep **)
350 xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
352 opdeps[opdeplen] = pair;
354 return opdeplen++;
357 static void
358 mark_used (struct iclass *ic, int clear_terminals)
360 int i;
362 ic->orphan = 0;
363 if (clear_terminals)
364 ic->terminal_resolved = 1;
366 for (i=0;i < ic->nsubs;i++)
368 mark_used (ics[ic->subs[i]], clear_terminals);
370 for (i=0;i < ic->nxsubs;i++)
372 mark_used (ics[ic->xsubs[i]], clear_terminals);
376 /* look up an instruction class; if CREATE make a new one if none found;
377 returns the index into the insn class array */
378 static int
379 fetch_insn_class(const char *full_name, int create)
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;
389 if (strncmp (full_name, "IC:", 3) == 0)
391 name = xstrdup (full_name + 3);
392 is_class = 1;
394 else
395 name = xstrdup (full_name);
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)
403 char *nextnotestr;
404 is_class = 1;
405 note = atoi (notestr + 1);
406 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
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);
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)
420 if (notestr)
421 *notestr = 0;
422 if (comment)
423 *comment = 0;
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;
435 if (!create)
436 return -1;
438 /* doesn't exist, so make a new one */
439 if (iclen == ictotlen)
441 ictotlen += 20;
442 ics = (struct iclass **)
443 xrealloc(ics, (ictotlen)*sizeof(struct iclass *));
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;
452 if (comment)
454 ics[ind]->comment = xstrdup (comment + 1);
455 ics[ind]->comment[strlen(ics[ind]->comment)-1] = 0;
457 if (notestr)
458 ics[ind]->note = note;
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)
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);;
477 while (xsect)
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++;
486 free (name);
488 return ind;
491 /* for sorting a class's sub-class list only; make sure classes appear before
492 terminals */
493 static int
494 sub_compare (const void *e1, const void *e2)
496 struct iclass *ic1 = ics[*(int *)e1];
497 struct iclass *ic2 = ics[*(int *)e2];
499 if (ic1->is_class)
501 if (!ic2->is_class)
502 return -1;
504 else if (ic2->is_class)
505 return 1;
507 return strcmp (ic1->name, ic2->name);
510 static void
511 load_insn_classes()
513 FILE *fp = fopen("ia64-ic.tbl", "r");
514 char buf[2048];
516 if (fp == NULL){
517 fprintf (stderr, "Can't find ia64-ic.tbl for reading\n");
518 exit(1);
521 /* discard first line */
522 fgets (buf, sizeof(buf), fp);
524 while (!feof(fp))
526 int iclass;
527 char *name;
528 char *tmp;
530 if (fgets (buf, sizeof(buf), fp) == NULL)
531 break;
533 while (isspace(buf[strlen(buf)-1]))
534 buf[strlen(buf)-1] = '\0';
536 name = tmp = buf;
537 while (*tmp != ';')
539 ++tmp;
540 if (tmp == buf + sizeof(buf))
541 abort ();
543 *tmp++ = '\0';
545 iclass = fetch_insn_class(name, 1);
546 ics[iclass]->is_class = 1;
548 if (strcmp (name, "none") == 0)
550 ics[iclass]->is_class = 0;
551 ics[iclass]->terminal_resolved = 1;
552 continue;
555 /* for this class, record all sub-classes */
556 while (*tmp)
558 char *subname;
559 int sub;
561 while (*tmp && isspace(*tmp))
563 ++tmp;
564 if (tmp == buf + sizeof(buf))
565 abort();
567 subname = tmp;
568 while (*tmp && *tmp != ',')
570 ++tmp;
571 if (tmp == buf + sizeof(buf))
572 abort();
574 if (*tmp == ',')
575 *tmp++ = '\0';
577 ics[iclass]->subs = (int *)
578 xrealloc((void *)ics[iclass]->subs,
579 (ics[iclass]->nsubs+1)*sizeof(int));
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;
586 /* make sure classes come before terminals */
587 qsort ((void *)ics[iclass]->subs,
588 ics[iclass]->nsubs, sizeof(int), sub_compare);
590 fclose(fp);
592 if (debug)
594 printf ("%d classes\n", iclen);
598 /* extract the insn classes from the given line */
599 static void
600 parse_resource_users(ref, usersp, nusersp, notesp)
601 char *ref;
602 int **usersp;
603 int *nusersp;
604 int **notesp;
606 int c;
607 char *line = xstrdup (ref);
608 char *tmp = line;
609 int *users = *usersp;
610 int count = *nusersp;
611 int *notes = *notesp;
613 c = *tmp;
614 while (c != 0)
616 char *notestr;
617 int note;
618 char *xsect;
619 int iclass;
620 int create = 0;
621 char *name;
623 while (isspace(*tmp))
624 ++tmp;
625 name = tmp;
626 while (*tmp && *tmp != ',')
627 ++tmp;
628 c = *tmp;
629 *tmp++ = '\0';
631 xsect = strchr(name, '\\');
632 if ((notestr = strstr(name, "+")) != NULL)
634 char *nextnotestr;
635 note = atoi (notestr + 1);
636 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
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);
645 if (!xsect)
646 *notestr = '\0';
648 else
649 note = 0;
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).
657 if (strncmp(name, "IC:", 3) != 0 || xsect != NULL)
658 create = 1;
660 iclass = fetch_insn_class(name, create);
661 if (iclass != -1)
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);
671 else
673 if (debug)
674 printf("Class %s not found\n", name);
677 /* update the return values */
678 *usersp = users;
679 *nusersp = count;
680 *notesp = notes;
682 free (line);
685 static int
686 parse_semantics (char *sem)
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;
704 static void
705 add_dep (const char *name, const char *chk, const char *reg,
706 int semantics, int mode, char *extra, int flag)
708 struct rdep *rs;
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;
720 static void
721 load_depfile (const char *filename, enum ia64_dependency_mode mode)
723 FILE *fp = fopen(filename, "r");
724 char buf[1024];
726 if (fp == NULL){
727 fprintf (stderr, "Can't find %s for reading\n", filename);
728 exit(1);
731 fgets(buf, sizeof(buf), fp);
732 while (!feof(fp))
734 char *name, *tmp;
735 int semantics;
736 char *extra;
737 char *regp, *chkp;
739 if (fgets (buf, sizeof(buf), fp) == NULL)
740 break;
742 while (isspace(buf[strlen(buf)-1]))
743 buf[strlen(buf)-1] = '\0';
745 name = tmp = buf;
746 while (*tmp != ';')
747 ++tmp;
748 *tmp++ = '\0';
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;
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)
774 add_dep (name, chkp, regp, semantics, mode, extra, 0);
775 add_dep (name, regp, chkp, semantics, mode, extra, 1);
777 else
779 add_dep (name, chkp, regp, semantics, mode, extra, 0);
782 fclose(fp);
785 static void
786 load_dependencies()
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);
792 if (debug)
793 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
796 /* is the given operand an indirect register file operand? */
797 static int
798 irf_operand (int op, const char *field)
800 if (!field)
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;
807 else
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")));
820 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
821 mov_um insn classes */
822 static int
823 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
824 const char *format, const char *field)
826 int plain_mov = strcmp (idesc->name, "mov") == 0;
828 if (!format)
829 return 0;
831 switch (ic->name[4])
833 default:
834 abort ();
835 case 'a':
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;
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;
858 break;
859 case 'b':
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;
868 break;
869 case 'c':
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;
878 break;
879 case 'i':
880 if (ic->name[5] == 'n')
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;
889 else if (ic->name[5] == 'p')
891 return idesc->operands[1] == IA64_OPND_IP;
893 else
894 abort ();
895 break;
896 case 'p':
897 if (ic->name[5] == 'r')
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;
909 else if (ic->name[5] == 's')
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;
918 else
919 abort ();
920 break;
921 case 'u':
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;
930 break;
932 return 0;
936 /* is the given opcode in the given insn class? */
937 static int
938 in_iclass(struct ia64_opcode *idesc, struct iclass *ic,
939 const char *format, const char *field, int *notep)
941 int i;
942 int resolved = 0;
944 if (ic->comment)
946 if (!strncmp (ic->comment, "Format", 6))
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)
952 if (strlen (ic->comment) < strlen (format))
954 fprintf (stderr, "Warning: most recent format '%s'\n"
955 "appears more restrictive than '%s'\n",
956 ic->comment, format);
957 format = ic->comment;
960 else
961 format = ic->comment;
963 else if (!strncmp (ic->comment, "Field", 5))
965 if (field)
966 fprintf (stderr, "Overlapping field %s->%s\n",
967 ic->comment, field);
968 field = ic->comment;
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)
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);
981 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
982 && (idesc->name[len] == '\0'
983 || idesc->name[len] == '.'));
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;
991 /* assume restrictions in the FORMAT/FIELD negate resolution,
992 unless specifically allowed by clauses in this block */
993 if (resolved && field)
995 /* check Field(sf)==sN against opcode sN */
996 if (strstr(field, "(sf)==") != NULL)
998 char *sf;
999 if ((sf = strstr (idesc->name, ".s")) != 0)
1001 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1004 /* check Field(lftype)==XXX */
1005 else if (strstr (field, "(lftype)") != NULL)
1007 if (strstr (idesc->name, "fault") != NULL)
1008 resolved = strstr (field, "fault") != NULL;
1009 else
1010 resolved = strstr (field, "fault") == NULL;
1012 /* handle Field(ctype)==XXX */
1013 else if (strstr (field, "(ctype)") != NULL)
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;
1033 if (resolved && format)
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;
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)
1067 resolved = 1;
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)
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;
1085 /* probe variations */
1086 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1088 resolved = strcmp (ic->name, "probe") == 0
1089 && !((strstr (idesc->name, "fault") != NULL)
1090 ^ (format && strstr (format, "M40") != NULL));
1092 /* mov variations */
1093 if (!resolved && is_mov)
1095 if (plain_mov)
1097 /* mov alias for fmerge */
1098 if (strcmp (ic->name, "fmerge") == 0)
1100 resolved = idesc->operands[0] == IA64_OPND_F1
1101 && idesc->operands[1] == IA64_OPND_F3;
1103 /* mov alias for adds (r3 or imm14) */
1104 else if (strcmp (ic->name, "adds") == 0)
1106 resolved = (idesc->operands[0] == IA64_OPND_R1
1107 && (idesc->operands[1] == IA64_OPND_R3
1108 || (idesc->operands[1] == IA64_OPND_IMM14)));
1110 /* mov alias for addl */
1111 else if (strcmp (ic->name, "addl") == 0)
1113 resolved = idesc->operands[0] == IA64_OPND_R1
1114 && idesc->operands[1] == IA64_OPND_IMM22;
1117 /* some variants of mov and mov.[im] */
1118 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1120 resolved = in_iclass_mov_x (idesc, ic, format, field);
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)
1128 ic->terminal_resolved = 1;
1131 else for (i=0;i < ic->nsubs;i++)
1133 if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep))
1135 int j;
1136 for (j=0;j < ic->nxsubs;j++)
1138 if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1139 return 0;
1141 if (debug > 1)
1142 printf ("%s is in IC %s\n",
1143 idesc->name, ic->name);
1144 resolved = 1;
1145 break;
1149 /* If it's in this IC, add the IC note (if any) to the insn */
1150 if (resolved)
1152 if (ic->note && notep)
1154 if (*notep && *notep != ic->note)
1156 fprintf (stderr, "Warning: overwriting note %d with note %d"
1157 "(IC:%s)\n",
1158 *notep, ic->note, ic->name);
1160 *notep = ic->note;
1164 return resolved;
1168 static int
1169 lookup_regindex (const char *name, int specifier)
1171 switch (specifier)
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;
1305 return REG_NONE;
1308 static int
1309 lookup_specifier (const char *name)
1311 if (strchr (name, '%'))
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;
1338 fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
1339 name);
1341 else if (strchr (name, '#'))
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;
1360 fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",
1361 name);
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;
1382 return IA64_RS_ANY;
1385 void
1386 print_dependency_table ()
1388 int i, j;
1390 if (debug)
1392 for (i=0;i < iclen;i++)
1394 if (ics[i]->is_class)
1396 if (!ics[i]->nsubs)
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");
1404 else
1406 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
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");
1417 for (i=0;i < iclen;i++)
1419 if (ics[i]->orphan)
1421 mark_used (ics[i], 1);
1422 fprintf (stderr, "Warning: class %s is defined but not used\n",
1423 ics[i]->name);
1427 if (debug > 1) for (i=0;i < rdepslen;i++)
1429 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1430 if (rdeps[i]->total_chks == 0)
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");
1436 else if (rdeps[i]->total_regs == 0)
1438 fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n",
1439 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1444 /* the dependencies themselves */
1445 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1446 for (i=0;i < rdepslen;i++)
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);
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");
1460 printf ("};\n\n");
1462 /* and dependency lists */
1463 for (i=0;i < dlistlen;i++)
1465 int len = 2;
1466 printf ("static const short dep%d[] = {\n ", i);
1467 for (j=0;j < dlists[i]->len; j++)
1469 len += printf ("%d, ", dlists[i]->deps[j]);
1470 if (len > 75)
1472 printf("\n ");
1473 len = 2;
1476 printf ("\n};\n\n");
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++)
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");
1496 printf ("};\n\n");
1500 /* Add STR to the string table. */
1502 static struct string_entry *
1503 insert_string (str)
1504 char *str;
1506 int start = 0, end = strtablen;
1507 int i, x;
1509 if (strtablen == strtabtotlen)
1511 strtabtotlen += 20;
1512 string_table = (struct string_entry **)
1513 xrealloc (string_table,
1514 sizeof (struct string_entry **) * strtabtotlen);
1517 if (strtablen == 0)
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];
1526 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1528 i = end;
1530 else if (strcmp (str, string_table[0]->s) < 0)
1532 i = 0;
1534 else
1536 while (1)
1538 int c;
1540 i = (start + end) / 2;
1541 c = strcmp (str, string_table[i]->s);
1542 if (c < 0)
1544 end = i - 1;
1546 else if (c == 0)
1548 return string_table[i];
1550 else
1552 start = i + 1;
1554 if (start > end)
1556 break;
1560 for (; i > 0 && i < strtablen; i--)
1562 if (strcmp (str, string_table[i - 1]->s) > 0)
1564 break;
1567 for (; i < strtablen; i++)
1569 if (strcmp (str, string_table[i]->s) < 0)
1571 break;
1574 for (x = strtablen - 1; x >= i; x--)
1576 string_table[x + 1] = string_table[x];
1577 string_table[x + 1]->num = x + 1;
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];
1586 struct bittree *
1587 make_bittree_entry ()
1589 struct bittree *res = tmalloc (struct bittree);
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;
1600 struct disent *
1601 add_dis_table_ent (which, insn, order, completer_index)
1602 struct disent *which;
1603 int insn;
1604 int order;
1605 int completer_index;
1607 int ci = 0;
1608 struct disent *ent;
1610 if (which != NULL)
1612 ent = which;
1614 ent->nextcnt++;
1615 while (ent->nexte != NULL)
1617 ent = ent->nexte;
1619 ent = (ent->nexte = tmalloc (struct disent));
1621 else
1623 ent = tmalloc (struct disent);
1624 ent->next_ent = disinsntable;
1625 disinsntable = ent;
1626 which = ent;
1628 ent->nextcnt = 0;
1629 ent->nexte = NULL;
1630 ent->insn = insn;
1631 ent->priority = order;
1633 while (completer_index != 1)
1635 ci = (ci << 1) | (completer_index & 1);
1636 completer_index >>= 1;
1638 ent->completer_index = ci;
1639 return which;
1642 void
1643 finish_distable ()
1645 struct disent *ent = disinsntable;
1646 struct disent *prev = ent;
1648 ent->ournum = 32768;
1649 while ((ent = ent->next_ent) != NULL)
1651 ent->ournum = prev->ournum + prev->nextcnt + 1;
1652 prev = ent;
1656 void
1657 insert_bit_table_ent (curr_ent, bit, opcode, mask,
1658 opcodenum, order, completer_index)
1659 struct bittree *curr_ent;
1660 int bit;
1661 ia64_insn opcode;
1662 ia64_insn mask;
1663 int opcodenum;
1664 int order;
1665 int completer_index;
1667 ia64_insn m;
1668 int b;
1669 struct bittree *next;
1671 if (bit == -1)
1673 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1674 opcodenum, order,
1675 completer_index);
1676 curr_ent->disent = nent;
1677 return;
1680 m = ((ia64_insn) 1) << bit;
1682 if (mask & m)
1684 b = (opcode & m) ? 1 : 0;
1686 else
1688 b = 2;
1690 next = curr_ent->bits[b];
1691 if (next == NULL)
1693 next = make_bittree_entry ();
1694 curr_ent->bits[b] = next;
1696 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1697 completer_index);
1700 void
1701 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1702 struct bittree *first;
1703 ia64_insn opcode;
1704 ia64_insn mask;
1705 int opcodenum;
1706 struct completer_entry *ent;
1707 int completer_index;
1709 if (completer_index & (1 << 20))
1711 abort ();
1713 while (ent != NULL)
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)
1720 insert_bit_table_ent (bittree, 40, newopcode, mask,
1721 opcodenum, opcode_count - ent->order - 1,
1722 (completer_index << 1) | 1);
1724 completer_index <<= 1;
1725 ent = ent->alternative;
1729 /* This optimization pass combines multiple "don't care" nodes. */
1730 void
1731 compact_distree (ent)
1732 struct bittree *ent;
1734 #define IS_SKIP(ent) \
1735 ((ent->bits[2] !=NULL) \
1736 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1738 int bitcnt = 0;
1739 struct bittree *nent = ent;
1740 int x;
1742 while (IS_SKIP (nent))
1744 bitcnt++;
1745 nent = nent->bits[2];
1748 if (bitcnt)
1750 struct bittree *next = ent->bits[2];
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)
1760 struct bittree *b = next;
1761 next = next->bits[2];
1762 free (b);
1764 free (nent);
1767 for (x = 0; x < 3; x++)
1769 struct bittree *i = ent->bits[x];
1770 if (i != NULL)
1772 compact_distree (i);
1777 static unsigned char *insn_list;
1778 static int insn_list_len = 0;
1779 static int tot_insn_list_len = 0;
1781 /* Generate the disassembler state machine corresponding to the tree
1782 in ENT. */
1783 void
1784 gen_dis_table (ent)
1785 struct bittree *ent;
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... */
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)
1800 if (ent->disent == NULL)
1802 abort ();
1804 else
1806 ent->skip_flag = 0;
1810 /* Calculate the amount of space needed for this entry, or at least
1811 a conservatively large approximation. */
1812 if (ent->skip_flag)
1814 totbits += 5;
1816 for (x = 1; x < 3; x++)
1818 if (ent->bits[x] != NULL)
1820 totbits += 16;
1824 if (ent->disent != NULL)
1826 if (ent->bits[2] != NULL)
1828 abort ();
1830 totbits += 16;
1833 /* Now allocate the space. */
1834 needed_bytes = (totbits + 7) / 8;
1835 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1837 tot_insn_list_len += 256;
1838 insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1840 our_offset = insn_list_len;
1841 insn_list_len += needed_bytes;
1842 memset (insn_list + our_offset, 0, needed_bytes);
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)
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);
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)
1857 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1858 state op field. */
1860 if (ent->bits[0] != NULL)
1862 struct bittree *nent = ent->bits[0];
1863 zero_count = 0;
1865 insn_list[our_offset] |= 0x80;
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. */
1872 if (IS_ONLY_IFZERO (ent))
1874 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1876 nent = nent->bits[0];
1877 zero_count++;
1880 insn_list[our_offset + 0] |= zero_count;
1882 zero_dest = insn_list_len;
1883 gen_dis_table (nent);
1886 /* Now store the remaining tests. We also handle a sole "termination
1887 entry" by storing it as an "any bit" test. */
1889 for (x = 1; x < 3; x++)
1891 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1893 struct bittree *i = ent->bits[x];
1894 int idest;
1895 int currbits = 15;
1897 if (i != NULL)
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)
1905 idest = i->disent->ournum;
1906 i = NULL;
1908 else
1910 idest = insn_list_len - our_offset;
1913 else
1915 idest = ent->disent->ournum;
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.
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. */
1928 if (x == 1)
1930 if (idest <= 256)
1932 int start = our_offset + bitsused / 8 + 1;
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--;
1944 else
1946 insn_list[our_offset] |= 0x20;
1949 else
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. */
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))
1962 int start = our_offset + bitsused / 8 + 1;
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;
1975 else
1977 insn_list[our_offset] |= 0x08;
1980 if (debug)
1982 int id = idest;
1984 if (i == NULL)
1986 id |= 32768;
1988 else if (! (id & 32768))
1990 id += our_offset;
1992 if (x == 1)
1994 printf ("%d: if (1) goto %d\n", our_offset, id);
1996 else
1998 printf ("%d: try %d\n", our_offset, id);
2002 /* Store the address of the entry being branched to. */
2003 while (currbits >= 0)
2005 char *byte = insn_list + our_offset + bitsused / 8;
2007 if (idest & (1 << currbits))
2009 *byte |= (1 << (7 - (bitsused % 8)));
2011 bitsused++;
2012 currbits--;
2015 /* Now generate the states for the entry being branched to. */
2016 if (i != NULL)
2018 gen_dis_table (i);
2023 if (debug)
2025 if (ent->skip_flag)
2027 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2030 if (ent->bits[0] != NULL)
2032 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2033 zero_dest);
2036 if (bitsused != totbits)
2038 abort ();
2042 void
2043 print_dis_table ()
2045 int x;
2046 struct disent *cent = disinsntable;
2048 printf ("static const char dis_table[] = {\n");
2049 for (x = 0; x < insn_list_len; x++)
2051 if ((x > 0) && ((x % 12) == 0))
2053 printf ("\n");
2055 printf ("0x%02x, ", insn_list[x]);
2057 printf ("\n};\n\n");
2059 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2060 while (cent != NULL)
2062 struct disent *ent = cent;
2064 while (ent != NULL)
2066 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2067 ent->insn, (ent->nexte != NULL ? 1 : 0),
2068 ent->priority);
2069 ent = ent->nexte;
2071 cent = cent->next_ent;
2073 printf ("};\n\n");
2076 void
2077 generate_disassembler ()
2079 int i;
2081 bittree = make_bittree_entry ();
2083 for (i=0; i < otlen;i++)
2085 struct main_entry *ptr = ordered_table[i];
2087 if (ptr->opcode->type != IA64_TYPE_DYN)
2089 add_dis_entry (bittree,
2090 ptr->opcode->opcode, ptr->opcode->mask,
2091 ptr->main_index,
2092 ptr->completers, 1);
2096 compact_distree (bittree);
2097 finish_distable ();
2098 gen_dis_table (bittree);
2100 print_dis_table ();
2103 void
2104 print_string_table ()
2106 int x;
2107 char lbuf[80], buf[80];
2108 int blen = 0;
2110 printf ("static const char *ia64_strings[] = {\n");
2111 lbuf[0] = '\0';
2112 for (x = 0; x < strtablen; x++)
2114 int len;
2116 if (strlen (string_table[x]->s) > 75)
2118 abort ();
2120 sprintf (buf, " \"%s\",", string_table[x]->s);
2121 len = strlen (buf);
2122 if ((blen + len) > 75)
2124 printf (" %s\n", lbuf);
2125 lbuf[0] = '\0';
2126 blen = 0;
2128 strcat (lbuf, buf);
2129 blen += len;
2131 if (blen > 0)
2133 printf (" %s\n", lbuf);
2135 printf ("};\n\n");
2138 static struct completer_entry **glist;
2139 static int glistlen = 0;
2140 static int glisttotlen = 0;
2142 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2145 completer_entries_eq (ent1, ent2)
2146 struct completer_entry *ent1, *ent2;
2148 while (ent1 != NULL && ent2 != NULL)
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
2154 || ent1->dependencies != ent2->dependencies
2155 || ent1->order != ent2->order)
2157 return 0;
2159 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2161 return 0;
2163 ent1 = ent1->alternative;
2164 ent2 = ent2->alternative;
2166 return ent1 == ent2;
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. */
2172 struct completer_entry *
2173 insert_gclist (ent)
2174 struct completer_entry *ent;
2176 if (ent != NULL)
2178 int i;
2179 int x;
2180 int start = 0, end;
2182 ent->addl_entries = insert_gclist (ent->addl_entries);
2183 ent->alternative = insert_gclist (ent->alternative);
2185 i = glistlen / 2;
2186 end = glistlen;
2188 if (glisttotlen == glistlen)
2190 glisttotlen += 20;
2191 glist = (struct completer_entry **)
2192 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2195 if (glistlen == 0)
2197 glist[0] = ent;
2198 glistlen = 1;
2199 return ent;
2202 if (ent->name->num < glist[0]->name->num)
2204 i = 0;
2206 else if (ent->name->num > glist[end - 1]->name->num)
2208 i = end;
2210 else
2212 int c;
2214 while (1)
2216 i = (start + end) / 2;
2217 c = ent->name->num - glist[i]->name->num;
2218 if (c < 0)
2220 end = i - 1;
2222 else if (c == 0)
2224 while (i > 0
2225 && ent->name->num == glist[i - 1]->name->num)
2227 i--;
2229 break;
2231 else
2233 start = i + 1;
2235 if (start > end)
2237 break;
2240 if (c == 0)
2242 while (i < glistlen)
2244 if (ent->name->num != glist[i]->name->num)
2246 break;
2248 if (completer_entries_eq (ent, glist[i]))
2250 return glist[i];
2252 i++;
2256 for (; i > 0 && i < glistlen; i--)
2258 if (ent->name->num >= glist[i - 1]->name->num)
2260 break;
2263 for (; i < glistlen; i++)
2265 if (ent->name->num < glist[i]->name->num)
2267 break;
2270 for (x = glistlen - 1; x >= i; x--)
2272 glist[x + 1] = glist[x];
2274 glist[i] = ent;
2275 glistlen++;
2277 return ent;
2280 static int
2281 get_prefix_len (name)
2282 const char *name;
2284 char *c;
2286 if (name[0] == '\0')
2288 return 0;
2291 c = strchr (name, '.');
2292 if (c != NULL)
2294 return c - name;
2296 else
2298 return strlen (name);
2302 static void
2303 compute_completer_bits (ment, ent)
2304 struct main_entry *ment;
2305 struct completer_entry *ent;
2307 while (ent != NULL)
2309 compute_completer_bits (ment, ent->addl_entries);
2311 if (ent->is_terminal)
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;
2319 while (p != NULL && ! p->is_terminal)
2321 p = p->parent;
2324 if (p != NULL)
2326 p_bits = p->bits;
2328 else
2330 p_bits = ment->opcode->opcode;
2333 for (x = 0; x < 64; x++)
2335 ia64_insn m = ((ia64_insn) 1) << x;
2336 if ((p_bits & m) != (our_bits & m))
2338 mask |= m;
2340 else
2342 our_bits &= ~m;
2345 ent->bits = our_bits;
2346 ent->mask = mask;
2348 else
2350 ent->bits = 0;
2351 ent->mask = 0;
2354 ent = ent->alternative;
2358 /* Find identical completer trees that are used in different
2359 instructions and collapse their entries. */
2360 void
2361 collapse_redundant_completers ()
2363 struct main_entry *ptr;
2364 int x;
2366 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2368 if (ptr->completers == NULL)
2370 abort ();
2372 compute_completer_bits (ptr, ptr->completers);
2373 ptr->completers = insert_gclist (ptr->completers);
2376 /* The table has been finalized, now number the indexes. */
2377 for (x = 0; x < glistlen; x++)
2379 glist[x]->num = x;
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)
2391 insert_opcode_dependencies (opc, cmp)
2392 struct ia64_opcode *opc;
2393 struct completer_entry *cmp;
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;
2405 for (i=0;i < rdepslen;i++)
2407 struct rdep *rs = rdeps[i];
2408 int j;
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;
2415 for (j=0; j < rs->nregs;j++)
2417 int ic_note = 0;
2419 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
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;
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.
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;
2444 for (j=0;j < rs->nchks;j++)
2446 int ic_note = 0;
2448 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
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;
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;
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]);
2476 return insert_dependencies (nchks, chks, nregs, regs);
2479 void
2480 insert_completer_entry (opc, tabent, order)
2481 struct ia64_opcode *opc;
2482 struct main_entry *tabent;
2483 int order;
2485 struct completer_entry **ptr = &tabent->completers;
2486 struct completer_entry *parent = NULL;
2487 char pcopy[129], *prefix;
2488 int at_end = 0;
2490 if (strlen (opc->name) > 128)
2492 abort ();
2494 strcpy (pcopy, opc->name);
2495 prefix = pcopy + get_prefix_len (pcopy);
2496 if (prefix[0] != '\0')
2498 prefix++;
2501 while (! at_end)
2503 int need_new_ent = 1;
2504 int plen = get_prefix_len (prefix);
2505 struct string_entry *sent;
2507 at_end = (prefix[plen] == '\0');
2508 prefix[plen] = '\0';
2509 sent = insert_string (prefix);
2511 while (*ptr != NULL)
2513 int cmpres = sent->num - (*ptr)->name->num;
2515 if (cmpres == 0)
2517 need_new_ent = 0;
2518 break;
2520 else
2522 ptr = &((*ptr)->alternative);
2525 if (need_new_ent)
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;
2537 if (! at_end)
2539 parent = *ptr;
2540 ptr = &((*ptr)->addl_entries);
2541 prefix += plen + 1;
2545 if ((*ptr)->is_terminal)
2547 abort ();
2550 (*ptr)->is_terminal = 1;
2551 (*ptr)->mask = (ia64_insn)-1;
2552 (*ptr)->bits = opc->opcode;
2554 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2555 (*ptr)->order = order;
2558 void
2559 print_completer_entry (ent)
2560 struct completer_entry *ent;
2562 int moffset = 0;
2563 ia64_insn mask = ent->mask, bits = ent->bits;
2565 if (mask != 0)
2567 while (! (mask & 1))
2569 moffset++;
2570 mask = mask >> 1;
2571 bits = bits >> 1;
2573 if (bits & 0xffffffff00000000LL)
2575 abort ();
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);
2590 void
2591 print_completer_table ()
2593 int x;
2595 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2596 for (x = 0; x < glistlen; x++)
2598 print_completer_entry (glist[x]);
2600 printf ("};\n\n");
2604 opcodes_eq (opc1, opc2)
2605 struct ia64_opcode *opc1;
2606 struct ia64_opcode *opc2;
2608 int x;
2609 int plen1, plen2;
2611 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2612 || (opc1->num_outputs != opc2->num_outputs)
2613 || (opc1->flags != opc2->flags))
2615 return 0;
2617 for (x = 0; x < 5; x++)
2619 if (opc1->operands[x] != opc2->operands[x])
2621 return 0;
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))
2628 return 1;
2630 return 0;
2633 void
2634 add_opcode_entry (opc)
2635 struct ia64_opcode *opc;
2637 struct main_entry **place;
2638 struct string_entry *name;
2639 char prefix[129];
2640 int found_it = 0;
2642 if (strlen (opc->name) > 128)
2644 abort ();
2646 place = &maintable;
2647 strcpy (prefix, opc->name);
2648 prefix[get_prefix_len (prefix)] = '\0';
2649 name = insert_string (prefix);
2651 /* Walk the list of opcode table entries. If it's a new
2652 instruction, allocate and fill in a new entry. Note
2653 the main table is alphabetical by opcode name. */
2655 while (*place != NULL)
2657 if ((*place)->name->num == name->num
2658 && opcodes_eq ((*place)->opcode, opc))
2660 found_it = 1;
2661 break;
2663 if ((*place)->name->num > name->num)
2665 break;
2667 place = &((*place)->next);
2669 if (! found_it)
2671 struct main_entry *nent = tmalloc (struct main_entry);
2673 nent->name = name;
2674 nent->opcode = opc;
2675 nent->next = *place;
2676 nent->completers = 0;
2677 *place = nent;
2679 if (otlen == ottotlen)
2681 ottotlen += 20;
2682 ordered_table = (struct main_entry **)
2683 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2685 ordered_table[otlen++] = nent;
2687 insert_completer_entry (opc, *place, opcode_count++);
2690 void
2691 print_main_table ()
2693 struct main_entry *ptr = maintable;
2694 int index = 0;
2696 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2697 while (ptr != NULL)
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);
2713 ptr->main_index = index++;
2715 ptr = ptr->next;
2717 printf ("};\n\n");
2720 void
2721 shrink (table)
2722 struct ia64_opcode *table;
2724 int curr_opcode;
2726 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2728 add_opcode_entry (table + curr_opcode);
2733 main (int argc, char **argv)
2735 if (argc > 1)
2737 debug = 1;
2740 load_insn_classes();
2741 load_dependencies();
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);
2751 collapse_redundant_completers ();
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 ();
2759 generate_disassembler ();
2761 exit (0);