* configure.in: Disable language-specific target libraries for
[binutils.git] / opcodes / ia64-gen.c
blobf0451cea6a41ddd2a631dd59495da10eb0affa71
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 if (strcmp (sem, "stop") == 0)
701 return IA64_DVS_STOP;
702 else
703 return IA64_DVS_OTHER;
706 static void
707 add_dep (const char *name, const char *chk, const char *reg,
708 int semantics, int mode, char *extra, int flag)
710 struct rdep *rs;
712 rs = insert_resource (name, mode);
713 parse_resource_users (chk, &rs->chks, &rs->nchks,
714 &rs->chknotes);
715 parse_resource_users (reg, &rs->regs, &rs->nregs,
716 &rs->regnotes);
717 rs->semantics = semantics;
718 rs->extra = extra;
719 rs->waw_special = flag;
722 static void
723 load_depfile (const char *filename, enum ia64_dependency_mode mode)
725 FILE *fp = fopen(filename, "r");
726 char buf[1024];
728 if (fp == NULL){
729 fprintf (stderr, "Can't find %s for reading\n", filename);
730 exit(1);
733 fgets(buf, sizeof(buf), fp);
734 while (!feof(fp))
736 char *name, *tmp;
737 int semantics;
738 char *extra;
739 char *regp, *chkp;
741 if (fgets (buf, sizeof(buf), fp) == NULL)
742 break;
744 while (isspace(buf[strlen(buf)-1]))
745 buf[strlen(buf)-1] = '\0';
747 name = tmp = buf;
748 while (*tmp != ';')
749 ++tmp;
750 *tmp++ = '\0';
752 while (isspace (*tmp))
753 ++tmp;
754 regp = tmp;
755 tmp = strchr (tmp, ';');
756 if (!tmp)
757 abort ();
758 *tmp++ = 0;
759 while (isspace (*tmp))
760 ++tmp;
761 chkp = tmp;
762 tmp = strchr (tmp, ';');
763 if (!tmp)
764 abort ();
765 *tmp++ = 0;
766 while (isspace (*tmp))
767 ++tmp;
768 semantics = parse_semantics (tmp);
769 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
771 /* For WAW entries, if the chks and regs differ, we need to enter the
772 entries in both positions so that the tables will be parsed properly,
773 without a lot of extra work */
774 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
776 add_dep (name, chkp, regp, semantics, mode, extra, 0);
777 add_dep (name, regp, chkp, semantics, mode, extra, 1);
779 else
781 add_dep (name, chkp, regp, semantics, mode, extra, 0);
784 fclose(fp);
787 static void
788 load_dependencies()
790 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
791 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
792 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
794 if (debug)
795 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
798 /* is the given operand an indirect register file operand? */
799 static int
800 irf_operand (int op, const char *field)
802 if (!field)
804 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
805 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
806 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
807 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
809 else
811 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
812 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
813 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
814 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
815 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
816 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
817 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
818 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
822 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
823 mov_um insn classes */
824 static int
825 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
826 const char *format, const char *field)
828 int plain_mov = strcmp (idesc->name, "mov") == 0;
830 if (!format)
831 return 0;
833 switch (ic->name[4])
835 default:
836 abort ();
837 case 'a':
839 int i = strcmp (idesc->name, "mov.i") == 0;
840 int m = strcmp (idesc->name, "mov.m") == 0;
841 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
842 int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
843 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
844 int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
845 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
846 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
848 /* IC:mov ar */
849 if (i2627)
850 return strstr (format, "I26") || strstr (format, "I27");
851 if (i28)
852 return strstr (format, "I28") != NULL;
853 if (m2930)
854 return strstr (format, "M29") || strstr (format, "M30");
855 if (m31)
856 return strstr (format, "M31") != NULL;
857 if (pseudo0 || pseudo1)
858 return 1;
860 break;
861 case 'b':
863 int i21 = idesc->operands[0] == IA64_OPND_B1;
864 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
865 if (i22)
866 return strstr (format, "I22") != NULL;
867 if (i21)
868 return strstr (format, "I21") != NULL;
870 break;
871 case 'c':
873 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
874 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
875 if (m32)
876 return strstr (format, "M32") != NULL;
877 if (m33)
878 return strstr (format, "M33") != NULL;
880 break;
881 case 'i':
882 if (ic->name[5] == 'n')
884 int m42 = plain_mov && irf_operand (idesc->operands[0], field);
885 int m43 = plain_mov && irf_operand (idesc->operands[1], field);
886 if (m42)
887 return strstr (format, "M42") != NULL;
888 if (m43)
889 return strstr (format, "M43") != NULL;
891 else if (ic->name[5] == 'p')
893 return idesc->operands[1] == IA64_OPND_IP;
895 else
896 abort ();
897 break;
898 case 'p':
899 if (ic->name[5] == 'r')
901 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
902 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
903 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
904 if (i23)
905 return strstr (format, "I23") != NULL;
906 if (i24)
907 return strstr (format, "I24") != NULL;
908 if (i25)
909 return strstr (format, "I25") != NULL;
911 else if (ic->name[5] == 's')
913 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
914 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
915 if (m35)
916 return strstr (format, "M35") != NULL;
917 if (m36)
918 return strstr (format, "M36") != NULL;
920 else
921 abort ();
922 break;
923 case 'u':
925 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
926 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
927 if (m35)
928 return strstr (format, "M35") != NULL;
929 if (m36)
930 return strstr (format, "M36") != NULL;
932 break;
934 return 0;
938 /* is the given opcode in the given insn class? */
939 static int
940 in_iclass(struct ia64_opcode *idesc, struct iclass *ic,
941 const char *format, const char *field, int *notep)
943 int i;
944 int resolved = 0;
946 if (ic->comment)
948 if (!strncmp (ic->comment, "Format", 6))
950 /* assume that the first format seen is the most restrictive, and
951 only keep a later one if it looks like it's more restrictive. */
952 if (format)
954 if (strlen (ic->comment) < strlen (format))
956 fprintf (stderr, "Warning: most recent format '%s'\n"
957 "appears more restrictive than '%s'\n",
958 ic->comment, format);
959 format = ic->comment;
962 else
963 format = ic->comment;
965 else if (!strncmp (ic->comment, "Field", 5))
967 if (field)
968 fprintf (stderr, "Overlapping field %s->%s\n",
969 ic->comment, field);
970 field = ic->comment;
974 /* an insn class matches anything that is the same followed by completers,
975 except when the absence and presence of completers constitutes different
976 instructions */
977 if (ic->nsubs == 0 && ic->nxsubs == 0)
979 int is_mov = strncmp (idesc->name, "mov", 3) == 0;
980 int plain_mov = strcmp (idesc->name, "mov") == 0;
981 int len = strlen(ic->name);
983 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
984 && (idesc->name[len] == '\0'
985 || idesc->name[len] == '.'));
987 /* all break and nop variations must match exactly */
988 if (resolved &&
989 (strcmp (ic->name, "break") == 0
990 || strcmp (ic->name, "nop") == 0))
991 resolved = strcmp (ic->name, idesc->name) == 0;
993 /* assume restrictions in the FORMAT/FIELD negate resolution,
994 unless specifically allowed by clauses in this block */
995 if (resolved && field)
997 /* check Field(sf)==sN against opcode sN */
998 if (strstr(field, "(sf)==") != NULL)
1000 char *sf;
1001 if ((sf = strstr (idesc->name, ".s")) != 0)
1003 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1006 /* check Field(lftype)==XXX */
1007 else if (strstr (field, "(lftype)") != NULL)
1009 if (strstr (idesc->name, "fault") != NULL)
1010 resolved = strstr (field, "fault") != NULL;
1011 else
1012 resolved = strstr (field, "fault") == NULL;
1014 /* handle Field(ctype)==XXX */
1015 else if (strstr (field, "(ctype)") != NULL)
1017 if (strstr (idesc->name, "or.andcm"))
1018 resolved = strstr (field, "or.andcm") != NULL;
1019 else if (strstr (idesc->name, "and.orcm"))
1020 resolved = strstr (field, "and.orcm") != NULL;
1021 else if (strstr (idesc->name, "orcm"))
1022 resolved = strstr (field, "or orcm") != NULL;
1023 else if (strstr (idesc->name, "or"))
1024 resolved = strstr (field, "or orcm") != NULL;
1025 else if (strstr (idesc->name, "andcm"))
1026 resolved = strstr (field, "and andcm") != NULL;
1027 else if (strstr (idesc->name, "and"))
1028 resolved = strstr (field, "and andcm") != NULL;
1029 else if (strstr (idesc->name, "unc"))
1030 resolved = strstr (field, "unc") != NULL;
1031 else
1032 resolved = strcmp (field, "Field(ctype)==") == 0;
1035 if (resolved && format)
1037 if (strncmp (idesc->name, "dep", 3) == 0
1038 && strstr (format, "I13") != NULL)
1039 resolved = idesc->operands[1] == IA64_OPND_IMM8;
1040 else if (strncmp (idesc->name, "chk", 3) == 0
1041 && strstr (format, "M21") != NULL)
1042 resolved = idesc->operands[0] == IA64_OPND_F2;
1043 else if (strncmp (idesc->name, "lfetch", 6) == 0)
1044 resolved = (strstr (format, "M14 M15") != NULL
1045 && (idesc->operands[1] == IA64_OPND_R2
1046 || idesc->operands[1] == IA64_OPND_IMM9b));
1047 else if (strncmp (idesc->name, "br.call", 7) == 0
1048 && strstr (format, "B5") != NULL)
1049 resolved = idesc->operands[1] == IA64_OPND_B2;
1050 else if (strncmp (idesc->name, "br.call", 7) == 0
1051 && strstr (format, "B3") != NULL)
1052 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1053 else if (strncmp (idesc->name, "brp", 3) == 0
1054 && strstr (format, "B7") != NULL)
1055 resolved = idesc->operands[0] == IA64_OPND_B2;
1056 else if (strcmp (ic->name, "invala") == 0)
1057 resolved = strcmp (idesc->name, ic->name) == 0;
1058 else
1059 resolved = 0;
1062 /* misc brl variations ('.cond' is optional);
1063 plain brl matches brl.cond */
1064 if (!resolved
1065 && (strcmp (idesc->name, "brl") == 0
1066 || strncmp (idesc->name, "brl.", 4) == 0)
1067 && strcmp (ic->name, "brl.cond") == 0)
1069 resolved = 1;
1072 /* misc br variations ('.cond' is optional) */
1073 if (!resolved
1074 && (strcmp (idesc->name, "br") == 0
1075 || strncmp (idesc->name, "br.", 3) == 0)
1076 && strcmp (ic->name, "br.cond") == 0)
1078 if (format)
1079 resolved = (strstr (format, "B4") != NULL
1080 && idesc->operands[0] == IA64_OPND_B2)
1081 || (strstr (format, "B1") != NULL
1082 && idesc->operands[0] == IA64_OPND_TGT25c);
1083 else
1084 resolved = 1;
1087 /* probe variations */
1088 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1090 resolved = strcmp (ic->name, "probe") == 0
1091 && !((strstr (idesc->name, "fault") != NULL)
1092 ^ (format && strstr (format, "M40") != NULL));
1094 /* mov variations */
1095 if (!resolved && is_mov)
1097 if (plain_mov)
1099 /* mov alias for fmerge */
1100 if (strcmp (ic->name, "fmerge") == 0)
1102 resolved = idesc->operands[0] == IA64_OPND_F1
1103 && idesc->operands[1] == IA64_OPND_F3;
1105 /* mov alias for adds (r3 or imm14) */
1106 else if (strcmp (ic->name, "adds") == 0)
1108 resolved = (idesc->operands[0] == IA64_OPND_R1
1109 && (idesc->operands[1] == IA64_OPND_R3
1110 || (idesc->operands[1] == IA64_OPND_IMM14)));
1112 /* mov alias for addl */
1113 else if (strcmp (ic->name, "addl") == 0)
1115 resolved = idesc->operands[0] == IA64_OPND_R1
1116 && idesc->operands[1] == IA64_OPND_IMM22;
1119 /* some variants of mov and mov.[im] */
1120 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1122 resolved = in_iclass_mov_x (idesc, ic, format, field);
1126 /* keep track of this so we can flag any insn classes which aren't
1127 mapped onto at least one real insn */
1128 if (resolved)
1130 ic->terminal_resolved = 1;
1133 else for (i=0;i < ic->nsubs;i++)
1135 if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep))
1137 int j;
1138 for (j=0;j < ic->nxsubs;j++)
1140 if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1141 return 0;
1143 if (debug > 1)
1144 printf ("%s is in IC %s\n",
1145 idesc->name, ic->name);
1146 resolved = 1;
1147 break;
1151 /* If it's in this IC, add the IC note (if any) to the insn */
1152 if (resolved)
1154 if (ic->note && notep)
1156 if (*notep && *notep != ic->note)
1158 fprintf (stderr, "Warning: overwriting note %d with note %d"
1159 "(IC:%s)\n",
1160 *notep, ic->note, ic->name);
1162 *notep = ic->note;
1166 return resolved;
1170 static int
1171 lookup_regindex (const char *name, int specifier)
1173 switch (specifier)
1175 case IA64_RS_ARX:
1176 if (strstr (name, "[RSC]"))
1177 return 16;
1178 if (strstr (name, "[BSP]"))
1179 return 17;
1180 else if (strstr (name, "[BSPSTORE]"))
1181 return 18;
1182 else if (strstr (name, "[RNAT]"))
1183 return 19;
1184 else if (strstr (name, "[CCV]"))
1185 return 32;
1186 else if (strstr (name, "[ITC]"))
1187 return 44;
1188 else if (strstr (name, "[PFS]"))
1189 return 64;
1190 else if (strstr (name, "[LC]"))
1191 return 65;
1192 else if (strstr (name, "[EC]"))
1193 return 66;
1194 abort ();
1195 case IA64_RS_CRX:
1196 if (strstr (name, "[DCR]"))
1197 return 0;
1198 else if (strstr (name, "[ITM]"))
1199 return 1;
1200 else if (strstr (name, "[IVA]"))
1201 return 2;
1202 else if (strstr (name, "[PTA]"))
1203 return 8;
1204 else if (strstr (name, "[GPTA]"))
1205 return 9;
1206 else if (strstr (name, "[IPSR]"))
1207 return 16;
1208 else if (strstr (name, "[ISR]"))
1209 return 17;
1210 else if (strstr (name, "[IIP]"))
1211 return 19;
1212 else if (strstr (name, "[IFA]"))
1213 return 20;
1214 else if (strstr (name, "[ITIR]"))
1215 return 21;
1216 else if (strstr (name, "[IIPA]"))
1217 return 22;
1218 else if (strstr (name, "[IFS]"))
1219 return 23;
1220 else if (strstr (name, "[IIM]"))
1221 return 24;
1222 else if (strstr (name, "[IHA]"))
1223 return 25;
1224 else if (strstr (name, "[LID]"))
1225 return 64;
1226 else if (strstr (name, "[IVR]"))
1227 return 65;
1228 else if (strstr (name, "[TPR]"))
1229 return 66;
1230 else if (strstr (name, "[EOI]"))
1231 return 67;
1232 else if (strstr (name, "[ITV]"))
1233 return 72;
1234 else if (strstr (name, "[PMV]"))
1235 return 73;
1236 else if (strstr (name, "[CMCV]"))
1237 return 74;
1238 abort ();
1239 case IA64_RS_PSR:
1240 if (strstr (name, ".be"))
1241 return 1;
1242 else if (strstr (name, ".up"))
1243 return 2;
1244 else if (strstr (name, ".ac"))
1245 return 3;
1246 else if (strstr (name, ".mfl"))
1247 return 4;
1248 else if (strstr (name, ".mfh"))
1249 return 5;
1250 else if (strstr (name, ".ic"))
1251 return 13;
1252 else if (strstr (name, ".i"))
1253 return 14;
1254 else if (strstr (name, ".pk"))
1255 return 15;
1256 else if (strstr (name, ".dt"))
1257 return 17;
1258 else if (strstr (name, ".dfl"))
1259 return 18;
1260 else if (strstr (name, ".dfh"))
1261 return 19;
1262 else if (strstr (name, ".sp"))
1263 return 20;
1264 else if (strstr (name, ".pp"))
1265 return 21;
1266 else if (strstr (name, ".di"))
1267 return 22;
1268 else if (strstr (name, ".si"))
1269 return 23;
1270 else if (strstr (name, ".db"))
1271 return 24;
1272 else if (strstr (name, ".lp"))
1273 return 25;
1274 else if (strstr (name, ".tb"))
1275 return 26;
1276 else if (strstr (name, ".rt"))
1277 return 27;
1278 else if (strstr (name, ".cpl"))
1279 return 32;
1280 else if (strstr (name, ".rs"))
1281 return 34;
1282 else if (strstr (name, ".mc"))
1283 return 35;
1284 else if (strstr (name, ".it"))
1285 return 36;
1286 else if (strstr (name, ".id"))
1287 return 37;
1288 else if (strstr (name, ".da"))
1289 return 38;
1290 else if (strstr (name, ".dd"))
1291 return 39;
1292 else if (strstr (name, ".ss"))
1293 return 40;
1294 else if (strstr (name, ".ri"))
1295 return 41;
1296 else if (strstr (name, ".ed"))
1297 return 43;
1298 else if (strstr (name, ".bn"))
1299 return 44;
1300 else if (strstr (name, ".ia"))
1301 return 45;
1302 else
1303 abort ();
1304 default:
1305 break;
1307 return REG_NONE;
1310 static int
1311 lookup_specifier (const char *name)
1313 if (strchr (name, '%'))
1315 if (strstr (name, "AR[K%]") != NULL)
1316 return IA64_RS_AR_K;
1317 if (strstr (name, "AR[UNAT]") != NULL)
1318 return IA64_RS_AR_UNAT;
1319 if (strstr (name, "AR%, % in 8") != NULL)
1320 return IA64_RS_AR;
1321 if (strstr (name, "AR%, % in 48") != NULL)
1322 return IA64_RS_ARb;
1323 if (strstr (name, "BR%") != NULL)
1324 return IA64_RS_BR;
1325 if (strstr (name, "CR[IRR%]") != NULL)
1326 return IA64_RS_CR_IRR;
1327 if (strstr (name, "CR[LRR%]") != NULL)
1328 return IA64_RS_CR_LRR;
1329 if (strstr (name, "CR%") != NULL)
1330 return IA64_RS_CR;
1331 if (strstr (name, "FR%, % in 0") != NULL)
1332 return IA64_RS_FR;
1333 if (strstr (name, "FR%, % in 2") != NULL)
1334 return IA64_RS_FRb;
1335 if (strstr (name, "GR%") != NULL)
1336 return IA64_RS_GR;
1337 if (strstr (name, "PR%, % in 1 ") != NULL)
1338 return IA64_RS_PR;
1339 if (strstr (name, "PR%, % in 16 ") != NULL)
1340 return IA64_RS_PRr;
1342 fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
1343 name);
1345 else if (strchr (name, '#'))
1347 if (strstr (name, "CPUID#") != NULL)
1348 return IA64_RS_CPUID;
1349 if (strstr (name, "DBR#") != NULL)
1350 return IA64_RS_DBR;
1351 if (strstr (name, "IBR#") != NULL)
1352 return IA64_RS_IBR;
1353 if (strstr (name, "MSR#") != NULL)
1354 return IA64_RS_MSR;
1355 if (strstr (name, "PKR#") != NULL)
1356 return IA64_RS_PKR;
1357 if (strstr (name, "PMC#") != NULL)
1358 return IA64_RS_PMC;
1359 if (strstr (name, "PMD#") != NULL)
1360 return IA64_RS_PMD;
1361 if (strstr (name, "RR#") != NULL)
1362 return IA64_RS_RR;
1364 fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",
1365 name);
1367 else if (strncmp (name, "AR[FPSR]", 8) == 0)
1368 return IA64_RS_AR_FPSR;
1369 else if (strncmp (name, "AR[", 3) == 0)
1370 return IA64_RS_ARX;
1371 else if (strncmp (name, "CR[", 3) == 0)
1372 return IA64_RS_CRX;
1373 else if (strncmp (name, "PSR.", 4) == 0)
1374 return IA64_RS_PSR;
1375 else if (strcmp (name, "InService*") == 0)
1376 return IA64_RS_INSERVICE;
1377 else if (strcmp (name, "GR0") == 0)
1378 return IA64_RS_GR0;
1379 else if (strcmp (name, "CFM") == 0)
1380 return IA64_RS_CFM;
1381 else if (strcmp (name, "PR63") == 0)
1382 return IA64_RS_PR63;
1383 else if (strcmp (name, "RSE") == 0)
1384 return IA64_RS_RSE;
1386 return IA64_RS_ANY;
1389 void
1390 print_dependency_table ()
1392 int i, j;
1394 if (debug)
1396 for (i=0;i < iclen;i++)
1398 if (ics[i]->is_class)
1400 if (!ics[i]->nsubs)
1402 fprintf (stderr, "Warning: IC:%s", ics[i]->name);
1403 if (ics[i]->comment)
1404 fprintf (stderr, "[%s]", ics[i]->comment);
1405 fprintf (stderr, " has no terminals or sub-classes\n");
1408 else
1410 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1412 fprintf(stderr, "Warning: no insns mapped directly to "
1413 "terminal IC %s", ics[i]->name);
1414 if (ics[i]->comment)
1415 fprintf(stderr, "[%s] ", ics[i]->comment);
1416 fprintf(stderr, "\n");
1421 for (i=0;i < iclen;i++)
1423 if (ics[i]->orphan)
1425 mark_used (ics[i], 1);
1426 fprintf (stderr, "Warning: class %s is defined but not used\n",
1427 ics[i]->name);
1431 if (debug > 1) for (i=0;i < rdepslen;i++)
1433 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1434 if (rdeps[i]->total_chks == 0)
1436 fprintf (stderr, "Warning: rsrc %s (%s) has no chks%s\n",
1437 rdeps[i]->name, mode_str[rdeps[i]->mode],
1438 rdeps[i]->total_regs ? "" : " or regs");
1440 else if (rdeps[i]->total_regs == 0)
1442 fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n",
1443 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1448 /* the dependencies themselves */
1449 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1450 for (i=0;i < rdepslen;i++)
1452 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1453 resource used */
1454 int specifier = lookup_specifier (rdeps[i]->name);
1455 int regindex = lookup_regindex (rdeps[i]->name, specifier);
1457 printf (" { \"%s\", %d, %d, %d, %d, ",
1458 rdeps[i]->name, specifier,
1459 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1460 if (rdeps[i]->semantics == IA64_DVS_OTHER)
1461 printf ("\"%s\", ", rdeps[i]->extra);
1462 printf("},\n");
1464 printf ("};\n\n");
1466 /* and dependency lists */
1467 for (i=0;i < dlistlen;i++)
1469 int len = 2;
1470 printf ("static const short dep%d[] = {\n ", i);
1471 for (j=0;j < dlists[i]->len; j++)
1473 len += printf ("%d, ", dlists[i]->deps[j]);
1474 if (len > 75)
1476 printf("\n ");
1477 len = 2;
1480 printf ("\n};\n\n");
1483 /* and opcode dependency list */
1484 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1485 printf ("static const struct ia64_opcode_dependency\n");
1486 printf ("op_dependencies[] = {\n");
1487 for (i=0;i < opdeplen;i++)
1489 printf (" { ");
1490 if (opdeps[i]->chk == -1)
1491 printf ("0, NULL, ");
1492 else
1493 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1494 if (opdeps[i]->reg == -1)
1495 printf ("0, NULL, ");
1496 else
1497 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1498 printf ("},\n");
1500 printf ("};\n\n");
1504 /* Add STR to the string table. */
1506 static struct string_entry *
1507 insert_string (str)
1508 char *str;
1510 int start = 0, end = strtablen;
1511 int i, x;
1513 if (strtablen == strtabtotlen)
1515 strtabtotlen += 20;
1516 string_table = (struct string_entry **)
1517 xrealloc (string_table,
1518 sizeof (struct string_entry **) * strtabtotlen);
1521 if (strtablen == 0)
1523 strtablen = 1;
1524 string_table[0] = tmalloc (struct string_entry);
1525 string_table[0]->s = xstrdup (str);
1526 string_table[0]->num = 0;
1527 return string_table[0];
1530 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1532 i = end;
1534 else if (strcmp (str, string_table[0]->s) < 0)
1536 i = 0;
1538 else
1540 while (1)
1542 int c;
1544 i = (start + end) / 2;
1545 c = strcmp (str, string_table[i]->s);
1546 if (c < 0)
1548 end = i - 1;
1550 else if (c == 0)
1552 return string_table[i];
1554 else
1556 start = i + 1;
1558 if (start > end)
1560 break;
1564 for (; i > 0 && i < strtablen; i--)
1566 if (strcmp (str, string_table[i - 1]->s) > 0)
1568 break;
1571 for (; i < strtablen; i++)
1573 if (strcmp (str, string_table[i]->s) < 0)
1575 break;
1578 for (x = strtablen - 1; x >= i; x--)
1580 string_table[x + 1] = string_table[x];
1581 string_table[x + 1]->num = x + 1;
1583 string_table[i] = tmalloc (struct string_entry);
1584 string_table[i]->s = xstrdup (str);
1585 string_table[i]->num = i;
1586 strtablen++;
1587 return string_table[i];
1590 struct bittree *
1591 make_bittree_entry ()
1593 struct bittree *res = tmalloc (struct bittree);
1595 res->disent = NULL;
1596 res->bits[0] = NULL;
1597 res->bits[1] = NULL;
1598 res->bits[2] = NULL;
1599 res->skip_flag = 0;
1600 res->bits_to_skip = 0;
1601 return res;
1604 struct disent *
1605 add_dis_table_ent (which, insn, order, completer_index)
1606 struct disent *which;
1607 int insn;
1608 int order;
1609 int completer_index;
1611 int ci = 0;
1612 struct disent *ent;
1614 if (which != NULL)
1616 ent = which;
1618 ent->nextcnt++;
1619 while (ent->nexte != NULL)
1621 ent = ent->nexte;
1623 ent = (ent->nexte = tmalloc (struct disent));
1625 else
1627 ent = tmalloc (struct disent);
1628 ent->next_ent = disinsntable;
1629 disinsntable = ent;
1630 which = ent;
1632 ent->nextcnt = 0;
1633 ent->nexte = NULL;
1634 ent->insn = insn;
1635 ent->priority = order;
1637 while (completer_index != 1)
1639 ci = (ci << 1) | (completer_index & 1);
1640 completer_index >>= 1;
1642 ent->completer_index = ci;
1643 return which;
1646 void
1647 finish_distable ()
1649 struct disent *ent = disinsntable;
1650 struct disent *prev = ent;
1652 ent->ournum = 32768;
1653 while ((ent = ent->next_ent) != NULL)
1655 ent->ournum = prev->ournum + prev->nextcnt + 1;
1656 prev = ent;
1660 void
1661 insert_bit_table_ent (curr_ent, bit, opcode, mask,
1662 opcodenum, order, completer_index)
1663 struct bittree *curr_ent;
1664 int bit;
1665 ia64_insn opcode;
1666 ia64_insn mask;
1667 int opcodenum;
1668 int order;
1669 int completer_index;
1671 ia64_insn m;
1672 int b;
1673 struct bittree *next;
1675 if (bit == -1)
1677 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1678 opcodenum, order,
1679 completer_index);
1680 curr_ent->disent = nent;
1681 return;
1684 m = ((ia64_insn) 1) << bit;
1686 if (mask & m)
1688 b = (opcode & m) ? 1 : 0;
1690 else
1692 b = 2;
1694 next = curr_ent->bits[b];
1695 if (next == NULL)
1697 next = make_bittree_entry ();
1698 curr_ent->bits[b] = next;
1700 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1701 completer_index);
1704 void
1705 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1706 struct bittree *first;
1707 ia64_insn opcode;
1708 ia64_insn mask;
1709 int opcodenum;
1710 struct completer_entry *ent;
1711 int completer_index;
1713 if (completer_index & (1 << 20))
1715 abort ();
1718 while (ent != NULL)
1720 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1721 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1722 (completer_index << 1) | 1);
1723 if (ent->is_terminal)
1725 insert_bit_table_ent (bittree, 40, newopcode, mask,
1726 opcodenum, opcode_count - ent->order - 1,
1727 (completer_index << 1) | 1);
1729 completer_index <<= 1;
1730 ent = ent->alternative;
1734 /* This optimization pass combines multiple "don't care" nodes. */
1735 void
1736 compact_distree (ent)
1737 struct bittree *ent;
1739 #define IS_SKIP(ent) \
1740 ((ent->bits[2] !=NULL) \
1741 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1743 int bitcnt = 0;
1744 struct bittree *nent = ent;
1745 int x;
1747 while (IS_SKIP (nent))
1749 bitcnt++;
1750 nent = nent->bits[2];
1753 if (bitcnt)
1755 struct bittree *next = ent->bits[2];
1757 ent->bits[0] = nent->bits[0];
1758 ent->bits[1] = nent->bits[1];
1759 ent->bits[2] = nent->bits[2];
1760 ent->disent = nent->disent;
1761 ent->skip_flag = 1;
1762 ent->bits_to_skip = bitcnt;
1763 while (next != nent)
1765 struct bittree *b = next;
1766 next = next->bits[2];
1767 free (b);
1769 free (nent);
1772 for (x = 0; x < 3; x++)
1774 struct bittree *i = ent->bits[x];
1775 if (i != NULL)
1777 compact_distree (i);
1782 static unsigned char *insn_list;
1783 static int insn_list_len = 0;
1784 static int tot_insn_list_len = 0;
1786 /* Generate the disassembler state machine corresponding to the tree
1787 in ENT. */
1788 void
1789 gen_dis_table (ent)
1790 struct bittree *ent;
1792 int x;
1793 int our_offset = insn_list_len;
1794 int bitsused = 5;
1795 int totbits = bitsused;
1796 int needed_bytes;
1797 int zero_count = 0;
1798 int zero_dest = 0; /* initialize this with 0 to keep gcc quiet... */
1800 /* If this is a terminal entry, there's no point in skipping any
1801 bits. */
1802 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1803 ent->bits[2] == NULL)
1805 if (ent->disent == NULL)
1807 abort ();
1809 else
1811 ent->skip_flag = 0;
1815 /* Calculate the amount of space needed for this entry, or at least
1816 a conservatively large approximation. */
1817 if (ent->skip_flag)
1819 totbits += 5;
1821 for (x = 1; x < 3; x++)
1823 if (ent->bits[x] != NULL)
1825 totbits += 16;
1829 if (ent->disent != NULL)
1831 if (ent->bits[2] != NULL)
1833 abort ();
1835 totbits += 16;
1838 /* Now allocate the space. */
1839 needed_bytes = (totbits + 7) / 8;
1840 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1842 tot_insn_list_len += 256;
1843 insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1845 our_offset = insn_list_len;
1846 insn_list_len += needed_bytes;
1847 memset (insn_list + our_offset, 0, needed_bytes);
1849 /* Encode the skip entry by setting bit 6 set in the state op field,
1850 and store the # of bits to skip immediately after. */
1851 if (ent->skip_flag)
1853 bitsused += 5;
1854 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1855 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1858 #define IS_ONLY_IFZERO(ENT) \
1859 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1860 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1862 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1863 state op field. */
1865 if (ent->bits[0] != NULL)
1867 struct bittree *nent = ent->bits[0];
1868 zero_count = 0;
1870 insn_list[our_offset] |= 0x80;
1872 /* We can encode sequences of multiple "if (bit is zero)" tests
1873 by storing the # of zero bits to check in the lower 3 bits of
1874 the instruction. However, this only applies if the state
1875 solely tests for a zero bit. */
1877 if (IS_ONLY_IFZERO (ent))
1879 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1881 nent = nent->bits[0];
1882 zero_count++;
1885 insn_list[our_offset + 0] |= zero_count;
1887 zero_dest = insn_list_len;
1888 gen_dis_table (nent);
1891 /* Now store the remaining tests. We also handle a sole "termination
1892 entry" by storing it as an "any bit" test. */
1894 for (x = 1; x < 3; x++)
1896 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1898 struct bittree *i = ent->bits[x];
1899 int idest;
1900 int currbits = 15;
1902 if (i != NULL)
1904 /* If the instruction being branched to only consists of
1905 a termination entry, use the termination entry as the
1906 place to branch to instead. */
1907 if (i->bits[0] == NULL && i->bits[1] == NULL
1908 && i->bits[2] == NULL && i->disent != NULL)
1910 idest = i->disent->ournum;
1911 i = NULL;
1913 else
1915 idest = insn_list_len - our_offset;
1918 else
1920 idest = ent->disent->ournum;
1923 /* If the destination offset for the if (bit is 1) test is less
1924 than 256 bytes away, we can store it as 8-bits instead of 16;
1925 the instruction has bit 5 set for the 16-bit address, and bit
1926 4 for the 8-bit address. Since we've already allocated 16
1927 bits for the address we need to deallocate the space.
1929 Note that branchings within the table are relative, and
1930 there are no branches that branch past our instruction yet
1931 so we do not need to adjust any other offsets. */
1933 if (x == 1)
1935 if (idest <= 256)
1937 int start = our_offset + bitsused / 8 + 1;
1939 memmove (insn_list + start,
1940 insn_list + start + 1,
1941 insn_list_len - (start + 1));
1942 currbits = 7;
1943 totbits -= 8;
1944 needed_bytes--;
1945 insn_list_len--;
1946 insn_list[our_offset] |= 0x10;
1947 idest--;
1949 else
1951 insn_list[our_offset] |= 0x20;
1954 else
1956 /* An instruction which solely consists of a termination
1957 marker and whose disassembly name index is < 4096
1958 can be stored in 16 bits. The encoding is slightly
1959 odd; the upper 4 bits of the instruction are 0x3, and
1960 bit 3 loses its normal meaning. */
1962 if (ent->bits[0] == NULL && ent->bits[1] == NULL
1963 && ent->bits[2] == NULL && ent->skip_flag == 0
1964 && ent->disent != NULL
1965 && ent->disent->ournum < (32768 + 4096))
1967 int start = our_offset + bitsused / 8 + 1;
1969 memmove (insn_list + start,
1970 insn_list + start + 1,
1971 insn_list_len - (start + 1));
1972 currbits = 11;
1973 totbits -= 5;
1974 bitsused--;
1975 needed_bytes--;
1976 insn_list_len--;
1977 insn_list[our_offset] |= 0x30;
1978 idest &= ~32768;
1980 else
1982 insn_list[our_offset] |= 0x08;
1985 if (debug)
1987 int id = idest;
1989 if (i == NULL)
1991 id |= 32768;
1993 else if (! (id & 32768))
1995 id += our_offset;
1997 if (x == 1)
1999 printf ("%d: if (1) goto %d\n", our_offset, id);
2001 else
2003 printf ("%d: try %d\n", our_offset, id);
2007 /* Store the address of the entry being branched to. */
2008 while (currbits >= 0)
2010 char *byte = insn_list + our_offset + bitsused / 8;
2012 if (idest & (1 << currbits))
2014 *byte |= (1 << (7 - (bitsused % 8)));
2016 bitsused++;
2017 currbits--;
2020 /* Now generate the states for the entry being branched to. */
2021 if (i != NULL)
2023 gen_dis_table (i);
2028 if (debug)
2030 if (ent->skip_flag)
2032 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2035 if (ent->bits[0] != NULL)
2037 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2038 zero_dest);
2041 if (bitsused != totbits)
2043 abort ();
2047 void
2048 print_dis_table ()
2050 int x;
2051 struct disent *cent = disinsntable;
2053 printf ("static const char dis_table[] = {\n");
2054 for (x = 0; x < insn_list_len; x++)
2056 if ((x > 0) && ((x % 12) == 0))
2058 printf ("\n");
2060 printf ("0x%02x, ", insn_list[x]);
2062 printf ("\n};\n\n");
2064 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2065 while (cent != NULL)
2067 struct disent *ent = cent;
2069 while (ent != NULL)
2071 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2072 ent->insn, (ent->nexte != NULL ? 1 : 0),
2073 ent->priority);
2074 ent = ent->nexte;
2076 cent = cent->next_ent;
2078 printf ("};\n\n");
2081 void
2082 generate_disassembler ()
2084 int i;
2086 bittree = make_bittree_entry ();
2088 for (i=0; i < otlen;i++)
2090 struct main_entry *ptr = ordered_table[i];
2092 if (ptr->opcode->type != IA64_TYPE_DYN)
2094 add_dis_entry (bittree,
2095 ptr->opcode->opcode, ptr->opcode->mask,
2096 ptr->main_index,
2097 ptr->completers, 1);
2101 compact_distree (bittree);
2102 finish_distable ();
2103 gen_dis_table (bittree);
2105 print_dis_table ();
2108 void
2109 print_string_table ()
2111 int x;
2112 char lbuf[80], buf[80];
2113 int blen = 0;
2115 printf ("static const char *ia64_strings[] = {\n");
2116 lbuf[0] = '\0';
2117 for (x = 0; x < strtablen; x++)
2119 int len;
2121 if (strlen (string_table[x]->s) > 75)
2123 abort ();
2125 sprintf (buf, " \"%s\",", string_table[x]->s);
2126 len = strlen (buf);
2127 if ((blen + len) > 75)
2129 printf (" %s\n", lbuf);
2130 lbuf[0] = '\0';
2131 blen = 0;
2133 strcat (lbuf, buf);
2134 blen += len;
2136 if (blen > 0)
2138 printf (" %s\n", lbuf);
2140 printf ("};\n\n");
2143 static struct completer_entry **glist;
2144 static int glistlen = 0;
2145 static int glisttotlen = 0;
2147 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2150 completer_entries_eq (ent1, ent2)
2151 struct completer_entry *ent1, *ent2;
2153 while (ent1 != NULL && ent2 != NULL)
2155 if (ent1->name->num != ent2->name->num
2156 || ent1->bits != ent2->bits
2157 || ent1->mask != ent2->mask
2158 || ent1->is_terminal != ent2->is_terminal
2159 || ent1->dependencies != ent2->dependencies
2160 || ent1->order != ent2->order)
2162 return 0;
2164 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2166 return 0;
2168 ent1 = ent1->alternative;
2169 ent2 = ent2->alternative;
2171 return ent1 == ent2;
2174 /* Insert ENT into the global list of completers and return it. If an
2175 equivalent entry (according to completer_entries_eq) already exists,
2176 it is returned instead. */
2177 struct completer_entry *
2178 insert_gclist (ent)
2179 struct completer_entry *ent;
2181 if (ent != NULL)
2183 int i;
2184 int x;
2185 int start = 0, end;
2187 ent->addl_entries = insert_gclist (ent->addl_entries);
2188 ent->alternative = insert_gclist (ent->alternative);
2190 i = glistlen / 2;
2191 end = glistlen;
2193 if (glisttotlen == glistlen)
2195 glisttotlen += 20;
2196 glist = (struct completer_entry **)
2197 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2200 if (glistlen == 0)
2202 glist[0] = ent;
2203 glistlen = 1;
2204 return ent;
2207 if (ent->name->num < glist[0]->name->num)
2209 i = 0;
2211 else if (ent->name->num > glist[end - 1]->name->num)
2213 i = end;
2215 else
2217 int c;
2219 while (1)
2221 i = (start + end) / 2;
2222 c = ent->name->num - glist[i]->name->num;
2223 if (c < 0)
2225 end = i - 1;
2227 else if (c == 0)
2229 while (i > 0
2230 && ent->name->num == glist[i - 1]->name->num)
2232 i--;
2234 break;
2236 else
2238 start = i + 1;
2240 if (start > end)
2242 break;
2245 if (c == 0)
2247 while (i < glistlen)
2249 if (ent->name->num != glist[i]->name->num)
2251 break;
2253 if (completer_entries_eq (ent, glist[i]))
2255 return glist[i];
2257 i++;
2261 for (; i > 0 && i < glistlen; i--)
2263 if (ent->name->num >= glist[i - 1]->name->num)
2265 break;
2268 for (; i < glistlen; i++)
2270 if (ent->name->num < glist[i]->name->num)
2272 break;
2275 for (x = glistlen - 1; x >= i; x--)
2277 glist[x + 1] = glist[x];
2279 glist[i] = ent;
2280 glistlen++;
2282 return ent;
2285 static int
2286 get_prefix_len (name)
2287 const char *name;
2289 char *c;
2291 if (name[0] == '\0')
2293 return 0;
2296 c = strchr (name, '.');
2297 if (c != NULL)
2299 return c - name;
2301 else
2303 return strlen (name);
2307 static void
2308 compute_completer_bits (ment, ent)
2309 struct main_entry *ment;
2310 struct completer_entry *ent;
2312 while (ent != NULL)
2314 compute_completer_bits (ment, ent->addl_entries);
2316 if (ent->is_terminal)
2318 ia64_insn mask = 0;
2319 ia64_insn our_bits = ent->bits;
2320 struct completer_entry *p = ent->parent;
2321 ia64_insn p_bits;
2322 int x;
2324 while (p != NULL && ! p->is_terminal)
2326 p = p->parent;
2329 if (p != NULL)
2331 p_bits = p->bits;
2333 else
2335 p_bits = ment->opcode->opcode;
2338 for (x = 0; x < 64; x++)
2340 ia64_insn m = ((ia64_insn) 1) << x;
2341 if ((p_bits & m) != (our_bits & m))
2343 mask |= m;
2345 else
2347 our_bits &= ~m;
2350 ent->bits = our_bits;
2351 ent->mask = mask;
2353 else
2355 ent->bits = 0;
2356 ent->mask = 0;
2359 ent = ent->alternative;
2363 /* Find identical completer trees that are used in different
2364 instructions and collapse their entries. */
2365 void
2366 collapse_redundant_completers ()
2368 struct main_entry *ptr;
2369 int x;
2371 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2373 if (ptr->completers == NULL)
2375 abort ();
2377 compute_completer_bits (ptr, ptr->completers);
2378 ptr->completers = insert_gclist (ptr->completers);
2381 /* The table has been finalized, now number the indexes. */
2382 for (x = 0; x < glistlen; x++)
2384 glist[x]->num = x;
2389 /* attach two lists of dependencies to each opcode.
2390 1) all resources which, when already marked in use, conflict with this
2391 opcode (chks)
2392 2) all resources which must be marked in use when this opcode is used
2393 (regs)
2396 insert_opcode_dependencies (opc, cmp)
2397 struct ia64_opcode *opc;
2398 struct completer_entry *cmp;
2400 /* note all resources which point to this opcode. rfi has the most chks
2401 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2402 int i;
2403 int nregs = 0;
2404 unsigned short regs[256];
2405 int nchks = 0;
2406 unsigned short chks[256];
2407 /* flag insns for which no class matched; there should be none */
2408 int no_class_found = 1;
2410 for (i=0;i < rdepslen;i++)
2412 struct rdep *rs = rdeps[i];
2413 int j;
2415 if (strcmp (opc->name, "cmp.eq.and") == 0
2416 && strncmp (rs->name, "PR%", 3) == 0
2417 && rs->mode == 1)
2418 no_class_found = 99;
2420 for (j=0; j < rs->nregs;j++)
2422 int ic_note = 0;
2424 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2426 /* We can ignore ic_note 11 for non PR resources */
2427 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2428 ic_note = 0;
2430 if (ic_note != 0 && rs->regnotes[j] != 0
2431 && ic_note != rs->regnotes[j]
2432 && !(ic_note == 11 && rs->regnotes[j] == 1))
2433 fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2434 " conflicts with resource %s note %d\n",
2435 ic_note, opc->name, ics[rs->regs[j]]->name,
2436 rs->name, rs->regnotes[j]);
2437 /* Instruction class notes override resource notes.
2438 So far, only note 11 applies to an IC instead of a resource,
2439 and note 11 implies note 1.
2441 if (ic_note)
2442 regs[nregs++] = RDEP(ic_note, i);
2443 else
2444 regs[nregs++] = RDEP(rs->regnotes[j], i);
2445 no_class_found = 0;
2446 ++rs->total_regs;
2449 for (j=0;j < rs->nchks;j++)
2451 int ic_note = 0;
2453 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2455 /* We can ignore ic_note 11 for non PR resources */
2456 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2457 ic_note = 0;
2459 if (ic_note != 0 && rs->chknotes[j] != 0
2460 && ic_note != rs->chknotes[j]
2461 && !(ic_note == 11 && rs->chknotes[j] == 1))
2462 fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2463 " conflicts with resource %s note %d\n",
2464 ic_note, opc->name, ics[rs->chks[j]]->name,
2465 rs->name, rs->chknotes[j]);
2466 if (ic_note)
2467 chks[nchks++] = RDEP(ic_note, i);
2468 else
2469 chks[nchks++] = RDEP(rs->chknotes[j], i);
2470 no_class_found = 0;
2471 ++rs->total_chks;
2476 if (no_class_found)
2477 fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n",
2478 opc->name,
2479 opc->operands[0], opc->operands[1], opc->operands[2]);
2481 return insert_dependencies (nchks, chks, nregs, regs);
2484 void
2485 insert_completer_entry (opc, tabent, order)
2486 struct ia64_opcode *opc;
2487 struct main_entry *tabent;
2488 int order;
2490 struct completer_entry **ptr = &tabent->completers;
2491 struct completer_entry *parent = NULL;
2492 char pcopy[129], *prefix;
2493 int at_end = 0;
2495 if (strlen (opc->name) > 128)
2497 abort ();
2499 strcpy (pcopy, opc->name);
2500 prefix = pcopy + get_prefix_len (pcopy);
2501 if (prefix[0] != '\0')
2503 prefix++;
2506 while (! at_end)
2508 int need_new_ent = 1;
2509 int plen = get_prefix_len (prefix);
2510 struct string_entry *sent;
2512 at_end = (prefix[plen] == '\0');
2513 prefix[plen] = '\0';
2514 sent = insert_string (prefix);
2516 while (*ptr != NULL)
2518 int cmpres = sent->num - (*ptr)->name->num;
2520 if (cmpres == 0)
2522 need_new_ent = 0;
2523 break;
2525 else
2527 ptr = &((*ptr)->alternative);
2530 if (need_new_ent)
2532 struct completer_entry *nent = tmalloc (struct completer_entry);
2533 nent->name = sent;
2534 nent->parent = parent;
2535 nent->addl_entries = NULL;
2536 nent->alternative = *ptr;
2537 *ptr = nent;
2538 nent->is_terminal = 0;
2539 nent->dependencies = -1;
2542 if (! at_end)
2544 parent = *ptr;
2545 ptr = &((*ptr)->addl_entries);
2546 prefix += plen + 1;
2550 if ((*ptr)->is_terminal)
2552 abort ();
2555 (*ptr)->is_terminal = 1;
2556 (*ptr)->mask = (ia64_insn)-1;
2557 (*ptr)->bits = opc->opcode;
2558 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2559 (*ptr)->order = order;
2562 void
2563 print_completer_entry (ent)
2564 struct completer_entry *ent;
2566 int moffset = 0;
2567 ia64_insn mask = ent->mask, bits = ent->bits;
2569 if (mask != 0)
2571 while (! (mask & 1))
2573 moffset++;
2574 mask = mask >> 1;
2575 bits = bits >> 1;
2577 if (bits & 0xffffffff00000000LL)
2579 abort ();
2583 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2584 (int)bits,
2585 (int)mask,
2586 ent->name->num,
2587 ent->alternative != NULL ? ent->alternative->num : -1,
2588 ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2589 moffset,
2590 ent->is_terminal ? 1 : 0,
2591 ent->dependencies);
2594 void
2595 print_completer_table ()
2597 int x;
2599 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2600 for (x = 0; x < glistlen; x++)
2602 print_completer_entry (glist[x]);
2604 printf ("};\n\n");
2608 opcodes_eq (opc1, opc2)
2609 struct ia64_opcode *opc1;
2610 struct ia64_opcode *opc2;
2612 int x;
2613 int plen1, plen2;
2615 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2616 || (opc1->num_outputs != opc2->num_outputs)
2617 || (opc1->flags != opc2->flags))
2619 return 0;
2621 for (x = 0; x < 5; x++)
2623 if (opc1->operands[x] != opc2->operands[x])
2625 return 0;
2628 plen1 = get_prefix_len (opc1->name);
2629 plen2 = get_prefix_len (opc2->name);
2630 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2632 return 1;
2634 return 0;
2637 void
2638 add_opcode_entry (opc)
2639 struct ia64_opcode *opc;
2641 struct main_entry **place;
2642 struct string_entry *name;
2643 char prefix[129];
2644 int found_it = 0;
2646 if (strlen (opc->name) > 128)
2648 abort ();
2650 place = &maintable;
2651 strcpy (prefix, opc->name);
2652 prefix[get_prefix_len (prefix)] = '\0';
2653 name = insert_string (prefix);
2655 /* Walk the list of opcode table entries. If it's a new
2656 instruction, allocate and fill in a new entry. Note
2657 the main table is alphabetical by opcode name. */
2659 while (*place != NULL)
2661 if ((*place)->name->num == name->num
2662 && opcodes_eq ((*place)->opcode, opc))
2664 found_it = 1;
2665 break;
2667 if ((*place)->name->num > name->num)
2669 break;
2671 place = &((*place)->next);
2673 if (! found_it)
2675 struct main_entry *nent = tmalloc (struct main_entry);
2677 nent->name = name;
2678 nent->opcode = opc;
2679 nent->next = *place;
2680 nent->completers = 0;
2681 *place = nent;
2683 if (otlen == ottotlen)
2685 ottotlen += 20;
2686 ordered_table = (struct main_entry **)
2687 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2689 ordered_table[otlen++] = nent;
2692 insert_completer_entry (opc, *place, opcode_count++);
2695 void
2696 print_main_table ()
2698 struct main_entry *ptr = maintable;
2699 int index = 0;
2701 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2702 while (ptr != NULL)
2704 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2705 ptr->name->num,
2706 ptr->opcode->type,
2707 ptr->opcode->num_outputs,
2708 ptr->opcode->opcode,
2709 ptr->opcode->mask,
2710 ptr->opcode->operands[0],
2711 ptr->opcode->operands[1],
2712 ptr->opcode->operands[2],
2713 ptr->opcode->operands[3],
2714 ptr->opcode->operands[4],
2715 ptr->opcode->flags,
2716 ptr->completers->num);
2718 ptr->main_index = index++;
2720 ptr = ptr->next;
2722 printf ("};\n\n");
2725 void
2726 shrink (table)
2727 struct ia64_opcode *table;
2729 int curr_opcode;
2731 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2733 add_opcode_entry (table + curr_opcode);
2738 main (int argc, char **argv)
2740 if (argc > 1)
2742 debug = 1;
2745 load_insn_classes();
2746 load_dependencies();
2748 shrink (ia64_opcodes_a);
2749 shrink (ia64_opcodes_b);
2750 shrink (ia64_opcodes_f);
2751 shrink (ia64_opcodes_i);
2752 shrink (ia64_opcodes_m);
2753 shrink (ia64_opcodes_x);
2754 shrink (ia64_opcodes_d);
2756 collapse_redundant_completers ();
2758 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2759 print_string_table ();
2760 print_dependency_table ();
2761 print_completer_table ();
2762 print_main_table ();
2764 generate_disassembler ();
2766 exit (0);