* acinclude.m4: Include libtool and gettext macros from the
[binutils.git] / opcodes / ia64-gen.c
bloba1e062ea39899afcd12d6228af2c35537784b51d
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 ();
1714 while (ent != NULL)
1716 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1717 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1718 (completer_index << 1) | 1);
1719 if (ent->is_terminal)
1721 insert_bit_table_ent (bittree, 40, newopcode, mask,
1722 opcodenum, opcode_count - ent->order - 1,
1723 (completer_index << 1) | 1);
1725 completer_index <<= 1;
1726 ent = ent->alternative;
1730 /* This optimization pass combines multiple "don't care" nodes. */
1731 void
1732 compact_distree (ent)
1733 struct bittree *ent;
1735 #define IS_SKIP(ent) \
1736 ((ent->bits[2] !=NULL) \
1737 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1739 int bitcnt = 0;
1740 struct bittree *nent = ent;
1741 int x;
1743 while (IS_SKIP (nent))
1745 bitcnt++;
1746 nent = nent->bits[2];
1749 if (bitcnt)
1751 struct bittree *next = ent->bits[2];
1753 ent->bits[0] = nent->bits[0];
1754 ent->bits[1] = nent->bits[1];
1755 ent->bits[2] = nent->bits[2];
1756 ent->disent = nent->disent;
1757 ent->skip_flag = 1;
1758 ent->bits_to_skip = bitcnt;
1759 while (next != nent)
1761 struct bittree *b = next;
1762 next = next->bits[2];
1763 free (b);
1765 free (nent);
1768 for (x = 0; x < 3; x++)
1770 struct bittree *i = ent->bits[x];
1771 if (i != NULL)
1773 compact_distree (i);
1778 static unsigned char *insn_list;
1779 static int insn_list_len = 0;
1780 static int tot_insn_list_len = 0;
1782 /* Generate the disassembler state machine corresponding to the tree
1783 in ENT. */
1784 void
1785 gen_dis_table (ent)
1786 struct bittree *ent;
1788 int x;
1789 int our_offset = insn_list_len;
1790 int bitsused = 5;
1791 int totbits = bitsused;
1792 int needed_bytes;
1793 int zero_count = 0;
1794 int zero_dest = 0; /* initialize this with 0 to keep gcc quiet... */
1796 /* If this is a terminal entry, there's no point in skipping any
1797 bits. */
1798 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1799 ent->bits[2] == NULL)
1801 if (ent->disent == NULL)
1803 abort ();
1805 else
1807 ent->skip_flag = 0;
1811 /* Calculate the amount of space needed for this entry, or at least
1812 a conservatively large approximation. */
1813 if (ent->skip_flag)
1815 totbits += 5;
1817 for (x = 1; x < 3; x++)
1819 if (ent->bits[x] != NULL)
1821 totbits += 16;
1825 if (ent->disent != NULL)
1827 if (ent->bits[2] != NULL)
1829 abort ();
1831 totbits += 16;
1834 /* Now allocate the space. */
1835 needed_bytes = (totbits + 7) / 8;
1836 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1838 tot_insn_list_len += 256;
1839 insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1841 our_offset = insn_list_len;
1842 insn_list_len += needed_bytes;
1843 memset (insn_list + our_offset, 0, needed_bytes);
1845 /* Encode the skip entry by setting bit 6 set in the state op field,
1846 and store the # of bits to skip immediately after. */
1847 if (ent->skip_flag)
1849 bitsused += 5;
1850 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1851 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1854 #define IS_ONLY_IFZERO(ENT) \
1855 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1856 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1858 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1859 state op field. */
1861 if (ent->bits[0] != NULL)
1863 struct bittree *nent = ent->bits[0];
1864 zero_count = 0;
1866 insn_list[our_offset] |= 0x80;
1868 /* We can encode sequences of multiple "if (bit is zero)" tests
1869 by storing the # of zero bits to check in the lower 3 bits of
1870 the instruction. However, this only applies if the state
1871 solely tests for a zero bit. */
1873 if (IS_ONLY_IFZERO (ent))
1875 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1877 nent = nent->bits[0];
1878 zero_count++;
1881 insn_list[our_offset + 0] |= zero_count;
1883 zero_dest = insn_list_len;
1884 gen_dis_table (nent);
1887 /* Now store the remaining tests. We also handle a sole "termination
1888 entry" by storing it as an "any bit" test. */
1890 for (x = 1; x < 3; x++)
1892 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1894 struct bittree *i = ent->bits[x];
1895 int idest;
1896 int currbits = 15;
1898 if (i != NULL)
1900 /* If the instruction being branched to only consists of
1901 a termination entry, use the termination entry as the
1902 place to branch to instead. */
1903 if (i->bits[0] == NULL && i->bits[1] == NULL
1904 && i->bits[2] == NULL && i->disent != NULL)
1906 idest = i->disent->ournum;
1907 i = NULL;
1909 else
1911 idest = insn_list_len - our_offset;
1914 else
1916 idest = ent->disent->ournum;
1919 /* If the destination offset for the if (bit is 1) test is less
1920 than 256 bytes away, we can store it as 8-bits instead of 16;
1921 the instruction has bit 5 set for the 16-bit address, and bit
1922 4 for the 8-bit address. Since we've already allocated 16
1923 bits for the address we need to deallocate the space.
1925 Note that branchings within the table are relative, and
1926 there are no branches that branch past our instruction yet
1927 so we do not need to adjust any other offsets. */
1929 if (x == 1)
1931 if (idest <= 256)
1933 int start = our_offset + bitsused / 8 + 1;
1935 memmove (insn_list + start,
1936 insn_list + start + 1,
1937 insn_list_len - (start + 1));
1938 currbits = 7;
1939 totbits -= 8;
1940 needed_bytes--;
1941 insn_list_len--;
1942 insn_list[our_offset] |= 0x10;
1943 idest--;
1945 else
1947 insn_list[our_offset] |= 0x20;
1950 else
1952 /* An instruction which solely consists of a termination
1953 marker and whose disassembly name index is < 4096
1954 can be stored in 16 bits. The encoding is slightly
1955 odd; the upper 4 bits of the instruction are 0x3, and
1956 bit 3 loses its normal meaning. */
1958 if (ent->bits[0] == NULL && ent->bits[1] == NULL
1959 && ent->bits[2] == NULL && ent->skip_flag == 0
1960 && ent->disent != NULL
1961 && ent->disent->ournum < (32768 + 4096))
1963 int start = our_offset + bitsused / 8 + 1;
1965 memmove (insn_list + start,
1966 insn_list + start + 1,
1967 insn_list_len - (start + 1));
1968 currbits = 11;
1969 totbits -= 5;
1970 bitsused--;
1971 needed_bytes--;
1972 insn_list_len--;
1973 insn_list[our_offset] |= 0x30;
1974 idest &= ~32768;
1976 else
1978 insn_list[our_offset] |= 0x08;
1981 if (debug)
1983 int id = idest;
1985 if (i == NULL)
1987 id |= 32768;
1989 else if (! (id & 32768))
1991 id += our_offset;
1993 if (x == 1)
1995 printf ("%d: if (1) goto %d\n", our_offset, id);
1997 else
1999 printf ("%d: try %d\n", our_offset, id);
2003 /* Store the address of the entry being branched to. */
2004 while (currbits >= 0)
2006 char *byte = insn_list + our_offset + bitsused / 8;
2008 if (idest & (1 << currbits))
2010 *byte |= (1 << (7 - (bitsused % 8)));
2012 bitsused++;
2013 currbits--;
2016 /* Now generate the states for the entry being branched to. */
2017 if (i != NULL)
2019 gen_dis_table (i);
2024 if (debug)
2026 if (ent->skip_flag)
2028 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2031 if (ent->bits[0] != NULL)
2033 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2034 zero_dest);
2037 if (bitsused != totbits)
2039 abort ();
2043 void
2044 print_dis_table ()
2046 int x;
2047 struct disent *cent = disinsntable;
2049 printf ("static const char dis_table[] = {\n");
2050 for (x = 0; x < insn_list_len; x++)
2052 if ((x > 0) && ((x % 12) == 0))
2054 printf ("\n");
2056 printf ("0x%02x, ", insn_list[x]);
2058 printf ("\n};\n\n");
2060 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2061 while (cent != NULL)
2063 struct disent *ent = cent;
2065 while (ent != NULL)
2067 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2068 ent->insn, (ent->nexte != NULL ? 1 : 0),
2069 ent->priority);
2070 ent = ent->nexte;
2072 cent = cent->next_ent;
2074 printf ("};\n\n");
2077 void
2078 generate_disassembler ()
2080 int i;
2082 bittree = make_bittree_entry ();
2084 for (i=0; i < otlen;i++)
2086 struct main_entry *ptr = ordered_table[i];
2088 if (ptr->opcode->type != IA64_TYPE_DYN)
2090 add_dis_entry (bittree,
2091 ptr->opcode->opcode, ptr->opcode->mask,
2092 ptr->main_index,
2093 ptr->completers, 1);
2097 compact_distree (bittree);
2098 finish_distable ();
2099 gen_dis_table (bittree);
2101 print_dis_table ();
2104 void
2105 print_string_table ()
2107 int x;
2108 char lbuf[80], buf[80];
2109 int blen = 0;
2111 printf ("static const char *ia64_strings[] = {\n");
2112 lbuf[0] = '\0';
2113 for (x = 0; x < strtablen; x++)
2115 int len;
2117 if (strlen (string_table[x]->s) > 75)
2119 abort ();
2121 sprintf (buf, " \"%s\",", string_table[x]->s);
2122 len = strlen (buf);
2123 if ((blen + len) > 75)
2125 printf (" %s\n", lbuf);
2126 lbuf[0] = '\0';
2127 blen = 0;
2129 strcat (lbuf, buf);
2130 blen += len;
2132 if (blen > 0)
2134 printf (" %s\n", lbuf);
2136 printf ("};\n\n");
2139 static struct completer_entry **glist;
2140 static int glistlen = 0;
2141 static int glisttotlen = 0;
2143 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2146 completer_entries_eq (ent1, ent2)
2147 struct completer_entry *ent1, *ent2;
2149 while (ent1 != NULL && ent2 != NULL)
2151 if (ent1->name->num != ent2->name->num
2152 || ent1->bits != ent2->bits
2153 || ent1->mask != ent2->mask
2154 || ent1->is_terminal != ent2->is_terminal
2155 || ent1->dependencies != ent2->dependencies
2156 || ent1->order != ent2->order)
2158 return 0;
2160 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2162 return 0;
2164 ent1 = ent1->alternative;
2165 ent2 = ent2->alternative;
2167 return ent1 == ent2;
2170 /* Insert ENT into the global list of completers and return it. If an
2171 equivalent entry (according to completer_entries_eq) already exists,
2172 it is returned instead. */
2173 struct completer_entry *
2174 insert_gclist (ent)
2175 struct completer_entry *ent;
2177 if (ent != NULL)
2179 int i;
2180 int x;
2181 int start = 0, end;
2183 ent->addl_entries = insert_gclist (ent->addl_entries);
2184 ent->alternative = insert_gclist (ent->alternative);
2186 i = glistlen / 2;
2187 end = glistlen;
2189 if (glisttotlen == glistlen)
2191 glisttotlen += 20;
2192 glist = (struct completer_entry **)
2193 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2196 if (glistlen == 0)
2198 glist[0] = ent;
2199 glistlen = 1;
2200 return ent;
2203 if (ent->name->num < glist[0]->name->num)
2205 i = 0;
2207 else if (ent->name->num > glist[end - 1]->name->num)
2209 i = end;
2211 else
2213 int c;
2215 while (1)
2217 i = (start + end) / 2;
2218 c = ent->name->num - glist[i]->name->num;
2219 if (c < 0)
2221 end = i - 1;
2223 else if (c == 0)
2225 while (i > 0
2226 && ent->name->num == glist[i - 1]->name->num)
2228 i--;
2230 break;
2232 else
2234 start = i + 1;
2236 if (start > end)
2238 break;
2241 if (c == 0)
2243 while (i < glistlen)
2245 if (ent->name->num != glist[i]->name->num)
2247 break;
2249 if (completer_entries_eq (ent, glist[i]))
2251 return glist[i];
2253 i++;
2257 for (; i > 0 && i < glistlen; i--)
2259 if (ent->name->num >= glist[i - 1]->name->num)
2261 break;
2264 for (; i < glistlen; i++)
2266 if (ent->name->num < glist[i]->name->num)
2268 break;
2271 for (x = glistlen - 1; x >= i; x--)
2273 glist[x + 1] = glist[x];
2275 glist[i] = ent;
2276 glistlen++;
2278 return ent;
2281 static int
2282 get_prefix_len (name)
2283 const char *name;
2285 char *c;
2287 if (name[0] == '\0')
2289 return 0;
2292 c = strchr (name, '.');
2293 if (c != NULL)
2295 return c - name;
2297 else
2299 return strlen (name);
2303 static void
2304 compute_completer_bits (ment, ent)
2305 struct main_entry *ment;
2306 struct completer_entry *ent;
2308 while (ent != NULL)
2310 compute_completer_bits (ment, ent->addl_entries);
2312 if (ent->is_terminal)
2314 ia64_insn mask = 0;
2315 ia64_insn our_bits = ent->bits;
2316 struct completer_entry *p = ent->parent;
2317 ia64_insn p_bits;
2318 int x;
2320 while (p != NULL && ! p->is_terminal)
2322 p = p->parent;
2325 if (p != NULL)
2327 p_bits = p->bits;
2329 else
2331 p_bits = ment->opcode->opcode;
2334 for (x = 0; x < 64; x++)
2336 ia64_insn m = ((ia64_insn) 1) << x;
2337 if ((p_bits & m) != (our_bits & m))
2339 mask |= m;
2341 else
2343 our_bits &= ~m;
2346 ent->bits = our_bits;
2347 ent->mask = mask;
2349 else
2351 ent->bits = 0;
2352 ent->mask = 0;
2355 ent = ent->alternative;
2359 /* Find identical completer trees that are used in different
2360 instructions and collapse their entries. */
2361 void
2362 collapse_redundant_completers ()
2364 struct main_entry *ptr;
2365 int x;
2367 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2369 if (ptr->completers == NULL)
2371 abort ();
2373 compute_completer_bits (ptr, ptr->completers);
2374 ptr->completers = insert_gclist (ptr->completers);
2377 /* The table has been finalized, now number the indexes. */
2378 for (x = 0; x < glistlen; x++)
2380 glist[x]->num = x;
2385 /* attach two lists of dependencies to each opcode.
2386 1) all resources which, when already marked in use, conflict with this
2387 opcode (chks)
2388 2) all resources which must be marked in use when this opcode is used
2389 (regs)
2392 insert_opcode_dependencies (opc, cmp)
2393 struct ia64_opcode *opc;
2394 struct completer_entry *cmp;
2396 /* note all resources which point to this opcode. rfi has the most chks
2397 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2398 int i;
2399 int nregs = 0;
2400 unsigned short regs[256];
2401 int nchks = 0;
2402 unsigned short chks[256];
2403 /* flag insns for which no class matched; there should be none */
2404 int no_class_found = 1;
2406 for (i=0;i < rdepslen;i++)
2408 struct rdep *rs = rdeps[i];
2409 int j;
2411 if (strcmp (opc->name, "cmp.eq.and") == 0
2412 && strncmp (rs->name, "PR%", 3) == 0
2413 && rs->mode == 1)
2414 no_class_found = 99;
2416 for (j=0; j < rs->nregs;j++)
2418 int ic_note = 0;
2420 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2422 /* We can ignore ic_note 11 for non PR resources */
2423 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2424 ic_note = 0;
2426 if (ic_note != 0 && rs->regnotes[j] != 0
2427 && ic_note != rs->regnotes[j]
2428 && !(ic_note == 11 && rs->regnotes[j] == 1))
2429 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2430 " conflicts with resource %s note %d\n",
2431 ic_note, opc->name, ics[rs->regs[j]]->name,
2432 rs->name, rs->regnotes[j]);
2433 /* Instruction class notes override resource notes.
2434 So far, only note 11 applies to an IC instead of a resource,
2435 and note 11 implies note 1.
2437 if (ic_note)
2438 regs[nregs++] = RDEP(ic_note, i);
2439 else
2440 regs[nregs++] = RDEP(rs->regnotes[j], i);
2441 no_class_found = 0;
2442 ++rs->total_regs;
2445 for (j=0;j < rs->nchks;j++)
2447 int ic_note = 0;
2449 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2451 /* We can ignore ic_note 11 for non PR resources */
2452 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2453 ic_note = 0;
2455 if (ic_note != 0 && rs->chknotes[j] != 0
2456 && ic_note != rs->chknotes[j]
2457 && !(ic_note == 11 && rs->chknotes[j] == 1))
2458 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2459 " conflicts with resource %s note %d\n",
2460 ic_note, opc->name, ics[rs->chks[j]]->name,
2461 rs->name, rs->chknotes[j]);
2462 if (ic_note)
2463 chks[nchks++] = RDEP(ic_note, i);
2464 else
2465 chks[nchks++] = RDEP(rs->chknotes[j], i);
2466 no_class_found = 0;
2467 ++rs->total_chks;
2472 if (no_class_found)
2473 fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n",
2474 opc->name,
2475 opc->operands[0], opc->operands[1], opc->operands[2]);
2477 return insert_dependencies (nchks, chks, nregs, regs);
2480 void
2481 insert_completer_entry (opc, tabent, order)
2482 struct ia64_opcode *opc;
2483 struct main_entry *tabent;
2484 int order;
2486 struct completer_entry **ptr = &tabent->completers;
2487 struct completer_entry *parent = NULL;
2488 char pcopy[129], *prefix;
2489 int at_end = 0;
2491 if (strlen (opc->name) > 128)
2493 abort ();
2495 strcpy (pcopy, opc->name);
2496 prefix = pcopy + get_prefix_len (pcopy);
2497 if (prefix[0] != '\0')
2499 prefix++;
2502 while (! at_end)
2504 int need_new_ent = 1;
2505 int plen = get_prefix_len (prefix);
2506 struct string_entry *sent;
2508 at_end = (prefix[plen] == '\0');
2509 prefix[plen] = '\0';
2510 sent = insert_string (prefix);
2512 while (*ptr != NULL)
2514 int cmpres = sent->num - (*ptr)->name->num;
2516 if (cmpres == 0)
2518 need_new_ent = 0;
2519 break;
2521 else
2523 ptr = &((*ptr)->alternative);
2526 if (need_new_ent)
2528 struct completer_entry *nent = tmalloc (struct completer_entry);
2529 nent->name = sent;
2530 nent->parent = parent;
2531 nent->addl_entries = NULL;
2532 nent->alternative = *ptr;
2533 *ptr = nent;
2534 nent->is_terminal = 0;
2535 nent->dependencies = -1;
2538 if (! at_end)
2540 parent = *ptr;
2541 ptr = &((*ptr)->addl_entries);
2542 prefix += plen + 1;
2546 if ((*ptr)->is_terminal)
2548 abort ();
2551 (*ptr)->is_terminal = 1;
2552 (*ptr)->mask = (ia64_insn)-1;
2553 (*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;
2688 insert_completer_entry (opc, *place, opcode_count++);
2691 void
2692 print_main_table ()
2694 struct main_entry *ptr = maintable;
2695 int index = 0;
2697 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2698 while (ptr != NULL)
2700 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2701 ptr->name->num,
2702 ptr->opcode->type,
2703 ptr->opcode->num_outputs,
2704 ptr->opcode->opcode,
2705 ptr->opcode->mask,
2706 ptr->opcode->operands[0],
2707 ptr->opcode->operands[1],
2708 ptr->opcode->operands[2],
2709 ptr->opcode->operands[3],
2710 ptr->opcode->operands[4],
2711 ptr->opcode->flags,
2712 ptr->completers->num);
2714 ptr->main_index = index++;
2716 ptr = ptr->next;
2718 printf ("};\n\n");
2721 void
2722 shrink (table)
2723 struct ia64_opcode *table;
2725 int curr_opcode;
2727 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2729 add_opcode_entry (table + curr_opcode);
2734 main (int argc, char **argv)
2736 if (argc > 1)
2738 debug = 1;
2741 load_insn_classes();
2742 load_dependencies();
2744 shrink (ia64_opcodes_a);
2745 shrink (ia64_opcodes_b);
2746 shrink (ia64_opcodes_f);
2747 shrink (ia64_opcodes_i);
2748 shrink (ia64_opcodes_m);
2749 shrink (ia64_opcodes_x);
2750 shrink (ia64_opcodes_d);
2752 collapse_redundant_completers ();
2754 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2755 print_string_table ();
2756 print_dependency_table ();
2757 print_completer_table ();
2758 print_main_table ();
2760 generate_disassembler ();
2762 exit (0);