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
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
32 The resource table is constructed based on some text dependency tables,
33 which are also easier to maintain than the final representation.
41 #include "libiberty.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"
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
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. */
73 } *maintable
, **ordered_table
;
78 /* The set of possible completers for an opcode. */
79 struct completer_entry
81 /* This entry's index in the ia64_completer_table[] array. */
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
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
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 (). */
112 /* Index into the opcode dependency list, or -1 if none. */
115 /* Remember the order encountered in the opcode tables. */
119 /* One entry in the disassembler name table. */
122 /* The index into the ia64_name_dis array for this entry. */
125 /* The index into the main_table[] array. */
128 /* The disassmbly priority of this entry. */
131 /* The completer_index value for this entry. */
134 /* How many other entries share this decode. */
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. */
148 struct disent
*disent
;
149 struct bittree
*bits
[3]; /* 0, 1, and X (don't care) */
154 /* The string table contains all opcodes and completers sorted in
155 alphabetical order. */
157 /* One entry in the string table. */
160 /* The index in the ia64_strings[] array for this entry. */
162 /* And the string. */
164 } **string_table
= NULL
;
166 int strtabtotlen
= 0;
169 /* resource dependency entries */
172 char *name
; /* resource name */
174 mode
:2, /* RAW, WAW, or WAR */
175 semantics
:3; /* dependency semantics */
176 char *extra
; /* additional semantics info */
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 */
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 */
191 static int rdepslen
= 0;
192 static int rdepstotlen
= 0;
194 /* array of all instruction classes */
197 char *name
; /* instruction class name */
198 int is_class
; /* is a class, not a terminal */
200 int *subs
; /* other classes within this class */
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 */
209 static int iclen
= 0;
210 static int ictotlen
= 0;
212 /* an opcode dependency (chk/reg pair of dependency lists) */
215 int chk
; /* index into dlists */
216 int reg
; /* index into dlists */
219 static int opdeplen
= 0;
220 static int opdeptotlen
= 0;
222 /* a generic list of dependencies w/notes encoded. these may be shared. */
226 unsigned short *deps
;
229 static int dlistlen
= 0;
230 static int dlisttotlen
= 0;
232 /* add NAME to the resource table, where TYPE is RAW or WAW */
234 insert_resource (const char *name
, enum ia64_dependency_mode type
)
236 if (rdepslen
== rdepstotlen
)
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? */
253 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
257 if (d1
->len
!= d2
->len
)
260 for (i
=0;i
< d1
->len
;i
++)
262 if (d1
->deps
[i
] != d2
->deps
[i
])
269 /* add the list of dependencies to the list of dependency lists */
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
;
280 memset ((void *)set
, 0, sizeof(set
));
281 for (i
=0;i
< count
;i
++)
284 for (i
=0;i
< (int)sizeof(set
);i
++)
288 list
= tmalloc(struct deplist
);
290 list
->deps
= (unsigned short *)malloc (sizeof(unsigned short) * count
);
291 for (i
=0, count
=0;i
< (int)sizeof(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
]))
310 if (dlistlen
== dlisttotlen
)
313 dlists
= (struct deplist
**)
314 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
316 dlists
[dlistlen
] = list
;
321 /* add the given pair of dependency lists to the opcode dependency list */
323 insert_dependencies (int nchks
, unsigned short *chks
,
324 int nregs
, unsigned short *regs
)
332 regind
= insert_deplist (nregs
, regs
);
334 chkind
= insert_deplist (nchks
, chks
);
336 for (i
=0;i
< opdeplen
;i
++)
338 if (opdeps
[i
]->chk
== chkind
339 && opdeps
[i
]->reg
== regind
)
342 pair
= tmalloc(struct opdep
);
346 if (opdeplen
== opdeptotlen
)
349 opdeps
= (struct opdep
**)
350 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
352 opdeps
[opdeplen
] = pair
;
358 mark_used (struct iclass
*ic
, int 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 */
379 fetch_insn_class(const char *full_name
, int create
)
389 if (strncmp (full_name
, "IC:", 3) == 0)
391 name
= xstrdup (full_name
+ 3);
395 name
= xstrdup (full_name
);
397 if ((xsect
= strchr(name
, '\\')) != NULL
)
399 if ((comment
= strchr(name
, '[')) != NULL
)
401 if ((notestr
= strchr(name
, '+')) != NULL
)
405 note
= atoi (notestr
+ 1);
406 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
408 if (strcmp (notestr
, "+1+13") == 0)
410 else if (!xsect
|| nextnotestr
< xsect
)
411 fprintf (stderr
, "Warning: multiple note %s not handled\n",
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 */
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
)
438 /* doesn't exist, so make a new one */
439 if (iclen
== ictotlen
)
442 ics
= (struct iclass
**)
443 xrealloc(ics
, (ictotlen
)*sizeof(struct iclass
*));
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;
454 ics
[ind
]->comment
= xstrdup (comment
+ 1);
455 ics
[ind
]->comment
[strlen(ics
[ind
]->comment
)-1] = 0;
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
;
473 ics
[ind
]->subs
= tmalloc(int);
474 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
479 char *subname
= xsect
+ 1;
480 xsect
= strchr (subname
, '\\');
483 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
491 /* for sorting a class's sub-class list only; make sure classes appear before
494 sub_compare (const void *e1
, const void *e2
)
496 struct iclass
*ic1
= ics
[*(int *)e1
];
497 struct iclass
*ic2
= ics
[*(int *)e2
];
504 else if (ic2
->is_class
)
507 return strcmp (ic1
->name
, ic2
->name
);
513 FILE *fp
= fopen("ia64-ic.tbl", "r");
517 fprintf (stderr
, "Can't find ia64-ic.tbl for reading\n");
521 /* discard first line */
522 fgets (buf
, sizeof(buf
), fp
);
530 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
533 while (isspace(buf
[strlen(buf
)-1]))
534 buf
[strlen(buf
)-1] = '\0';
540 if (tmp
== buf
+ sizeof(buf
))
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;
555 /* for this class, record all sub-classes */
561 while (*tmp
&& isspace(*tmp
))
564 if (tmp
== buf
+ sizeof(buf
))
568 while (*tmp
&& *tmp
!= ',')
571 if (tmp
== buf
+ sizeof(buf
))
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
);
594 printf ("%d classes\n", iclen
);
598 /* extract the insn classes from the given line */
600 parse_resource_users(ref
, usersp
, nusersp
, notesp
)
607 char *line
= xstrdup (ref
);
609 int *users
= *usersp
;
610 int count
= *nusersp
;
611 int *notes
= *notesp
;
623 while (isspace(*tmp
))
626 while (*tmp
&& *tmp
!= ',')
631 xsect
= strchr(name
, '\\');
632 if ((notestr
= strstr(name
, "+")) != NULL
)
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)
641 else if (!xsect
|| nextnotestr
< xsect
)
642 fprintf (stderr
, "Warning: multiple note %s not handled\n",
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
657 if (strncmp(name
, "IC:", 3) != 0 || xsect
!= NULL
)
660 iclass
= fetch_insn_class(name
, create
);
664 xrealloc ((void *)users
,(count
+1)*sizeof(int));
666 xrealloc ((void *)notes
,(count
+1)*sizeof(int));
668 users
[count
++] = iclass
;
669 mark_used (ics
[iclass
], 0);
674 printf("Class %s not found\n", name
);
677 /* update the return values */
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
;
703 return IA64_DVS_OTHER
;
707 add_dep (const char *name
, const char *chk
, const char *reg
,
708 int semantics
, int mode
, char *extra
, int flag
)
712 rs
= insert_resource (name
, mode
);
713 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
,
715 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
,
717 rs
->semantics
= semantics
;
719 rs
->waw_special
= flag
;
723 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
725 FILE *fp
= fopen(filename
, "r");
729 fprintf (stderr
, "Can't find %s for reading\n", filename
);
733 fgets(buf
, sizeof(buf
), fp
);
741 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
744 while (isspace(buf
[strlen(buf
)-1]))
745 buf
[strlen(buf
)-1] = '\0';
752 while (isspace (*tmp
))
755 tmp
= strchr (tmp
, ';');
759 while (isspace (*tmp
))
762 tmp
= strchr (tmp
, ';');
766 while (isspace (*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);
781 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
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
);
795 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
798 /* is the given operand an indirect register file operand? */
800 irf_operand (int op
, const char *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
;
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 */
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;
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
;
850 return strstr (format
, "I26") || strstr (format
, "I27");
852 return strstr (format
, "I28") != NULL
;
854 return strstr (format
, "M29") || strstr (format
, "M30");
856 return strstr (format
, "M31") != NULL
;
857 if (pseudo0
|| pseudo1
)
863 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
864 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
866 return strstr (format
, "I22") != NULL
;
868 return strstr (format
, "I21") != NULL
;
873 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
874 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
876 return strstr (format
, "M32") != NULL
;
878 return strstr (format
, "M33") != NULL
;
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
);
887 return strstr (format
, "M42") != NULL
;
889 return strstr (format
, "M43") != NULL
;
891 else if (ic
->name
[5] == 'p')
893 return idesc
->operands
[1] == IA64_OPND_IP
;
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
;
905 return strstr (format
, "I23") != NULL
;
907 return strstr (format
, "I24") != NULL
;
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
;
916 return strstr (format
, "M35") != NULL
;
918 return strstr (format
, "M36") != NULL
;
925 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
926 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
928 return strstr (format
, "M35") != NULL
;
930 return strstr (format
, "M36") != NULL
;
938 /* is the given opcode in the given insn class? */
940 in_iclass(struct ia64_opcode
*idesc
, struct iclass
*ic
,
941 const char *format
, const char *field
, int *notep
)
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. */
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
;
963 format
= ic
->comment
;
965 else if (!strncmp (ic
->comment
, "Field", 5))
968 fprintf (stderr
, "Overlapping field %s->%s\n",
974 /* an insn class matches anything that is the same followed by completers,
975 except when the absence and presence of completers constitutes different
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 */
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
)
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
;
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
;
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;
1062 /* misc brl variations ('.cond' is optional);
1063 plain brl matches brl.cond */
1065 && (strcmp (idesc
->name
, "brl") == 0
1066 || strncmp (idesc
->name
, "brl.", 4) == 0)
1067 && strcmp (ic
->name
, "brl.cond") == 0)
1072 /* misc br variations ('.cond' is optional) */
1074 && (strcmp (idesc
->name
, "br") == 0
1075 || strncmp (idesc
->name
, "br.", 3) == 0)
1076 && strcmp (ic
->name
, "br.cond") == 0)
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
);
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
)
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 */
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
))
1138 for (j
=0;j
< ic
->nxsubs
;j
++)
1140 if (in_iclass(idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1144 printf ("%s is in IC %s\n",
1145 idesc
->name
, ic
->name
);
1151 /* If it's in this IC, add the IC note (if any) to the insn */
1154 if (ic
->note
&& notep
)
1156 if (*notep
&& *notep
!= ic
->note
)
1158 fprintf (stderr
, "Warning: overwriting note %d with note %d"
1160 *notep
, ic
->note
, ic
->name
);
1171 lookup_regindex (const char *name
, int specifier
)
1176 if (strstr (name
, "[RSC]"))
1178 if (strstr (name
, "[BSP]"))
1180 else if (strstr (name
, "[BSPSTORE]"))
1182 else if (strstr (name
, "[RNAT]"))
1184 else if (strstr (name
, "[CCV]"))
1186 else if (strstr (name
, "[ITC]"))
1188 else if (strstr (name
, "[PFS]"))
1190 else if (strstr (name
, "[LC]"))
1192 else if (strstr (name
, "[EC]"))
1196 if (strstr (name
, "[DCR]"))
1198 else if (strstr (name
, "[ITM]"))
1200 else if (strstr (name
, "[IVA]"))
1202 else if (strstr (name
, "[PTA]"))
1204 else if (strstr (name
, "[GPTA]"))
1206 else if (strstr (name
, "[IPSR]"))
1208 else if (strstr (name
, "[ISR]"))
1210 else if (strstr (name
, "[IIP]"))
1212 else if (strstr (name
, "[IFA]"))
1214 else if (strstr (name
, "[ITIR]"))
1216 else if (strstr (name
, "[IIPA]"))
1218 else if (strstr (name
, "[IFS]"))
1220 else if (strstr (name
, "[IIM]"))
1222 else if (strstr (name
, "[IHA]"))
1224 else if (strstr (name
, "[LID]"))
1226 else if (strstr (name
, "[IVR]"))
1228 else if (strstr (name
, "[TPR]"))
1230 else if (strstr (name
, "[EOI]"))
1232 else if (strstr (name
, "[ITV]"))
1234 else if (strstr (name
, "[PMV]"))
1236 else if (strstr (name
, "[CMCV]"))
1240 if (strstr (name
, ".be"))
1242 else if (strstr (name
, ".up"))
1244 else if (strstr (name
, ".ac"))
1246 else if (strstr (name
, ".mfl"))
1248 else if (strstr (name
, ".mfh"))
1250 else if (strstr (name
, ".ic"))
1252 else if (strstr (name
, ".i"))
1254 else if (strstr (name
, ".pk"))
1256 else if (strstr (name
, ".dt"))
1258 else if (strstr (name
, ".dfl"))
1260 else if (strstr (name
, ".dfh"))
1262 else if (strstr (name
, ".sp"))
1264 else if (strstr (name
, ".pp"))
1266 else if (strstr (name
, ".di"))
1268 else if (strstr (name
, ".si"))
1270 else if (strstr (name
, ".db"))
1272 else if (strstr (name
, ".lp"))
1274 else if (strstr (name
, ".tb"))
1276 else if (strstr (name
, ".rt"))
1278 else if (strstr (name
, ".cpl"))
1280 else if (strstr (name
, ".rs"))
1282 else if (strstr (name
, ".mc"))
1284 else if (strstr (name
, ".it"))
1286 else if (strstr (name
, ".id"))
1288 else if (strstr (name
, ".da"))
1290 else if (strstr (name
, ".dd"))
1292 else if (strstr (name
, ".ss"))
1294 else if (strstr (name
, ".ri"))
1296 else if (strstr (name
, ".ed"))
1298 else if (strstr (name
, ".bn"))
1300 else if (strstr (name
, ".ia"))
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
)
1321 if (strstr (name
, "AR%, % in 48") != NULL
)
1323 if (strstr (name
, "BR%") != NULL
)
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
)
1331 if (strstr (name
, "FR%, % in 0") != NULL
)
1333 if (strstr (name
, "FR%, % in 2") != NULL
)
1335 if (strstr (name
, "GR%") != NULL
)
1337 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1339 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1342 fprintf (stderr
, "Warning! Don't know how to specify %% dependency %s\n",
1345 else if (strchr (name
, '#'))
1347 if (strstr (name
, "CPUID#") != NULL
)
1348 return IA64_RS_CPUID
;
1349 if (strstr (name
, "DBR#") != NULL
)
1351 if (strstr (name
, "IBR#") != NULL
)
1353 if (strstr (name
, "MSR#") != NULL
)
1355 if (strstr (name
, "PKR#") != NULL
)
1357 if (strstr (name
, "PMC#") != NULL
)
1359 if (strstr (name
, "PMD#") != NULL
)
1361 if (strstr (name
, "RR#") != NULL
)
1364 fprintf (stderr
, "Warning! Don't know how to specify # dependency %s\n",
1367 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1368 return IA64_RS_AR_FPSR
;
1369 else if (strncmp (name
, "AR[", 3) == 0)
1371 else if (strncmp (name
, "CR[", 3) == 0)
1373 else if (strncmp (name
, "PSR.", 4) == 0)
1375 else if (strcmp (name
, "InService*") == 0)
1376 return IA64_RS_INSERVICE
;
1377 else if (strcmp (name
, "GR0") == 0)
1379 else if (strcmp (name
, "CFM") == 0)
1381 else if (strcmp (name
, "PR63") == 0)
1382 return IA64_RS_PR63
;
1383 else if (strcmp (name
, "RSE") == 0)
1390 print_dependency_table ()
1396 for (i
=0;i
< iclen
;i
++)
1398 if (ics
[i
]->is_class
)
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");
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
++)
1425 mark_used (ics
[i
], 1);
1426 fprintf (stderr
, "Warning: class %s is defined but not used\n",
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
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
);
1468 /* and dependency lists */
1469 for (i
=0;i
< dlistlen
;i
++)
1472 printf ("static const short dep%d[] = {\n ", i
);
1473 for (j
=0;j
< dlists
[i
]->len
; j
++)
1475 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1482 printf ("\n};\n\n");
1485 /* and opcode dependency list */
1486 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1487 printf ("static const struct ia64_opcode_dependency\n");
1488 printf ("op_dependencies[] = {\n");
1489 for (i
=0;i
< opdeplen
;i
++)
1492 if (opdeps
[i
]->chk
== -1)
1493 printf ("0, NULL, ");
1495 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1496 if (opdeps
[i
]->reg
== -1)
1497 printf ("0, NULL, ");
1499 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1506 /* Add STR to the string table. */
1508 static struct string_entry
*
1512 int start
= 0, end
= strtablen
;
1515 if (strtablen
== strtabtotlen
)
1518 string_table
= (struct string_entry
**)
1519 xrealloc (string_table
,
1520 sizeof (struct string_entry
**) * strtabtotlen
);
1526 string_table
[0] = tmalloc (struct string_entry
);
1527 string_table
[0]->s
= xstrdup (str
);
1528 string_table
[0]->num
= 0;
1529 return string_table
[0];
1532 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1536 else if (strcmp (str
, string_table
[0]->s
) < 0)
1546 i
= (start
+ end
) / 2;
1547 c
= strcmp (str
, string_table
[i
]->s
);
1554 return string_table
[i
];
1566 for (; i
> 0 && i
< strtablen
; i
--)
1568 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1573 for (; i
< strtablen
; i
++)
1575 if (strcmp (str
, string_table
[i
]->s
) < 0)
1580 for (x
= strtablen
- 1; x
>= i
; x
--)
1582 string_table
[x
+ 1] = string_table
[x
];
1583 string_table
[x
+ 1]->num
= x
+ 1;
1585 string_table
[i
] = tmalloc (struct string_entry
);
1586 string_table
[i
]->s
= xstrdup (str
);
1587 string_table
[i
]->num
= i
;
1589 return string_table
[i
];
1593 make_bittree_entry ()
1595 struct bittree
*res
= tmalloc (struct bittree
);
1598 res
->bits
[0] = NULL
;
1599 res
->bits
[1] = NULL
;
1600 res
->bits
[2] = NULL
;
1602 res
->bits_to_skip
= 0;
1607 add_dis_table_ent (which
, insn
, order
, completer_index
)
1608 struct disent
*which
;
1611 int completer_index
;
1621 while (ent
->nexte
!= NULL
)
1625 ent
= (ent
->nexte
= tmalloc (struct disent
));
1629 ent
= tmalloc (struct disent
);
1630 ent
->next_ent
= disinsntable
;
1637 ent
->priority
= order
;
1639 while (completer_index
!= 1)
1641 ci
= (ci
<< 1) | (completer_index
& 1);
1642 completer_index
>>= 1;
1644 ent
->completer_index
= ci
;
1651 struct disent
*ent
= disinsntable
;
1652 struct disent
*prev
= ent
;
1654 ent
->ournum
= 32768;
1655 while ((ent
= ent
->next_ent
) != NULL
)
1657 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1663 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1664 opcodenum
, order
, completer_index
)
1665 struct bittree
*curr_ent
;
1671 int completer_index
;
1675 struct bittree
*next
;
1679 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1682 curr_ent
->disent
= nent
;
1686 m
= ((ia64_insn
) 1) << bit
;
1690 b
= (opcode
& m
) ? 1 : 0;
1696 next
= curr_ent
->bits
[b
];
1699 next
= make_bittree_entry ();
1700 curr_ent
->bits
[b
] = next
;
1702 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1707 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1708 struct bittree
*first
;
1712 struct completer_entry
*ent
;
1713 int completer_index
;
1715 if (completer_index
& (1 << 20))
1722 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1723 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1724 (completer_index
<< 1) | 1);
1725 if (ent
->is_terminal
)
1727 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1728 opcodenum
, opcode_count
- ent
->order
- 1,
1729 (completer_index
<< 1) | 1);
1731 completer_index
<<= 1;
1732 ent
= ent
->alternative
;
1736 /* This optimization pass combines multiple "don't care" nodes. */
1738 compact_distree (ent
)
1739 struct bittree
*ent
;
1741 #define IS_SKIP(ent) \
1742 ((ent->bits[2] !=NULL) \
1743 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1746 struct bittree
*nent
= ent
;
1749 while (IS_SKIP (nent
))
1752 nent
= nent
->bits
[2];
1757 struct bittree
*next
= ent
->bits
[2];
1759 ent
->bits
[0] = nent
->bits
[0];
1760 ent
->bits
[1] = nent
->bits
[1];
1761 ent
->bits
[2] = nent
->bits
[2];
1762 ent
->disent
= nent
->disent
;
1764 ent
->bits_to_skip
= bitcnt
;
1765 while (next
!= nent
)
1767 struct bittree
*b
= next
;
1768 next
= next
->bits
[2];
1774 for (x
= 0; x
< 3; x
++)
1776 struct bittree
*i
= ent
->bits
[x
];
1779 compact_distree (i
);
1784 static unsigned char *insn_list
;
1785 static int insn_list_len
= 0;
1786 static int tot_insn_list_len
= 0;
1788 /* Generate the disassembler state machine corresponding to the tree
1792 struct bittree
*ent
;
1795 int our_offset
= insn_list_len
;
1797 int totbits
= bitsused
;
1800 int zero_dest
= 0; /* initialize this with 0 to keep gcc quiet... */
1802 /* If this is a terminal entry, there's no point in skipping any
1804 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1805 ent
->bits
[2] == NULL
)
1807 if (ent
->disent
== NULL
)
1817 /* Calculate the amount of space needed for this entry, or at least
1818 a conservatively large approximation. */
1823 for (x
= 1; x
< 3; x
++)
1825 if (ent
->bits
[x
] != NULL
)
1831 if (ent
->disent
!= NULL
)
1833 if (ent
->bits
[2] != NULL
)
1840 /* Now allocate the space. */
1841 needed_bytes
= (totbits
+ 7) / 8;
1842 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1844 tot_insn_list_len
+= 256;
1845 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1847 our_offset
= insn_list_len
;
1848 insn_list_len
+= needed_bytes
;
1849 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1851 /* Encode the skip entry by setting bit 6 set in the state op field,
1852 and store the # of bits to skip immediately after. */
1856 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1857 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1860 #define IS_ONLY_IFZERO(ENT) \
1861 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1862 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1864 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1867 if (ent
->bits
[0] != NULL
)
1869 struct bittree
*nent
= ent
->bits
[0];
1872 insn_list
[our_offset
] |= 0x80;
1874 /* We can encode sequences of multiple "if (bit is zero)" tests
1875 by storing the # of zero bits to check in the lower 3 bits of
1876 the instruction. However, this only applies if the state
1877 solely tests for a zero bit. */
1879 if (IS_ONLY_IFZERO (ent
))
1881 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1883 nent
= nent
->bits
[0];
1887 insn_list
[our_offset
+ 0] |= zero_count
;
1889 zero_dest
= insn_list_len
;
1890 gen_dis_table (nent
);
1893 /* Now store the remaining tests. We also handle a sole "termination
1894 entry" by storing it as an "any bit" test. */
1896 for (x
= 1; x
< 3; x
++)
1898 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1900 struct bittree
*i
= ent
->bits
[x
];
1906 /* If the instruction being branched to only consists of
1907 a termination entry, use the termination entry as the
1908 place to branch to instead. */
1909 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1910 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1912 idest
= i
->disent
->ournum
;
1917 idest
= insn_list_len
- our_offset
;
1922 idest
= ent
->disent
->ournum
;
1925 /* If the destination offset for the if (bit is 1) test is less
1926 than 256 bytes away, we can store it as 8-bits instead of 16;
1927 the instruction has bit 5 set for the 16-bit address, and bit
1928 4 for the 8-bit address. Since we've already allocated 16
1929 bits for the address we need to deallocate the space.
1931 Note that branchings within the table are relative, and
1932 there are no branches that branch past our instruction yet
1933 so we do not need to adjust any other offsets. */
1939 int start
= our_offset
+ bitsused
/ 8 + 1;
1941 memmove (insn_list
+ start
,
1942 insn_list
+ start
+ 1,
1943 insn_list_len
- (start
+ 1));
1948 insn_list
[our_offset
] |= 0x10;
1953 insn_list
[our_offset
] |= 0x20;
1958 /* An instruction which solely consists of a termination
1959 marker and whose disassembly name index is < 4096
1960 can be stored in 16 bits. The encoding is slightly
1961 odd; the upper 4 bits of the instruction are 0x3, and
1962 bit 3 loses its normal meaning. */
1964 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
1965 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
1966 && ent
->disent
!= NULL
1967 && ent
->disent
->ournum
< (32768 + 4096))
1969 int start
= our_offset
+ bitsused
/ 8 + 1;
1971 memmove (insn_list
+ start
,
1972 insn_list
+ start
+ 1,
1973 insn_list_len
- (start
+ 1));
1979 insn_list
[our_offset
] |= 0x30;
1984 insn_list
[our_offset
] |= 0x08;
1995 else if (! (id
& 32768))
2001 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2005 printf ("%d: try %d\n", our_offset
, id
);
2009 /* Store the address of the entry being branched to. */
2010 while (currbits
>= 0)
2012 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2014 if (idest
& (1 << currbits
))
2016 *byte
|= (1 << (7 - (bitsused
% 8)));
2022 /* Now generate the states for the entry being branched to. */
2034 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2037 if (ent
->bits
[0] != NULL
)
2039 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2043 if (bitsused
!= totbits
)
2053 struct disent
*cent
= disinsntable
;
2055 printf ("static const char dis_table[] = {\n");
2056 for (x
= 0; x
< insn_list_len
; x
++)
2058 if ((x
> 0) && ((x
% 12) == 0))
2062 printf ("0x%02x, ", insn_list
[x
]);
2064 printf ("\n};\n\n");
2066 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2067 while (cent
!= NULL
)
2069 struct disent
*ent
= cent
;
2073 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2074 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2078 cent
= cent
->next_ent
;
2084 generate_disassembler ()
2088 bittree
= make_bittree_entry ();
2090 for (i
=0; i
< otlen
;i
++)
2092 struct main_entry
*ptr
= ordered_table
[i
];
2094 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2096 add_dis_entry (bittree
,
2097 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2099 ptr
->completers
, 1);
2103 compact_distree (bittree
);
2105 gen_dis_table (bittree
);
2111 print_string_table ()
2114 char lbuf
[80], buf
[80];
2117 printf ("static const char *ia64_strings[] = {\n");
2119 for (x
= 0; x
< strtablen
; x
++)
2123 if (strlen (string_table
[x
]->s
) > 75)
2127 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2129 if ((blen
+ len
) > 75)
2131 printf (" %s\n", lbuf
);
2140 printf (" %s\n", lbuf
);
2145 static struct completer_entry
**glist
;
2146 static int glistlen
= 0;
2147 static int glisttotlen
= 0;
2149 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2152 completer_entries_eq (ent1
, ent2
)
2153 struct completer_entry
*ent1
, *ent2
;
2155 while (ent1
!= NULL
&& ent2
!= NULL
)
2157 if (ent1
->name
->num
!= ent2
->name
->num
2158 || ent1
->bits
!= ent2
->bits
2159 || ent1
->mask
!= ent2
->mask
2160 || ent1
->is_terminal
!= ent2
->is_terminal
2161 || ent1
->dependencies
!= ent2
->dependencies
2162 || ent1
->order
!= ent2
->order
)
2166 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2170 ent1
= ent1
->alternative
;
2171 ent2
= ent2
->alternative
;
2173 return ent1
== ent2
;
2176 /* Insert ENT into the global list of completers and return it. If an
2177 equivalent entry (according to completer_entries_eq) already exists,
2178 it is returned instead. */
2179 struct completer_entry
*
2181 struct completer_entry
*ent
;
2189 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2190 ent
->alternative
= insert_gclist (ent
->alternative
);
2195 if (glisttotlen
== glistlen
)
2198 glist
= (struct completer_entry
**)
2199 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2209 if (ent
->name
->num
< glist
[0]->name
->num
)
2213 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2223 i
= (start
+ end
) / 2;
2224 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2232 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2249 while (i
< glistlen
)
2251 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2255 if (completer_entries_eq (ent
, glist
[i
]))
2263 for (; i
> 0 && i
< glistlen
; i
--)
2265 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2270 for (; i
< glistlen
; i
++)
2272 if (ent
->name
->num
< glist
[i
]->name
->num
)
2277 for (x
= glistlen
- 1; x
>= i
; x
--)
2279 glist
[x
+ 1] = glist
[x
];
2288 get_prefix_len (name
)
2293 if (name
[0] == '\0')
2298 c
= strchr (name
, '.');
2305 return strlen (name
);
2310 compute_completer_bits (ment
, ent
)
2311 struct main_entry
*ment
;
2312 struct completer_entry
*ent
;
2316 compute_completer_bits (ment
, ent
->addl_entries
);
2318 if (ent
->is_terminal
)
2321 ia64_insn our_bits
= ent
->bits
;
2322 struct completer_entry
*p
= ent
->parent
;
2326 while (p
!= NULL
&& ! p
->is_terminal
)
2337 p_bits
= ment
->opcode
->opcode
;
2340 for (x
= 0; x
< 64; x
++)
2342 ia64_insn m
= ((ia64_insn
) 1) << x
;
2343 if ((p_bits
& m
) != (our_bits
& m
))
2352 ent
->bits
= our_bits
;
2361 ent
= ent
->alternative
;
2365 /* Find identical completer trees that are used in different
2366 instructions and collapse their entries. */
2368 collapse_redundant_completers ()
2370 struct main_entry
*ptr
;
2373 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2375 if (ptr
->completers
== NULL
)
2379 compute_completer_bits (ptr
, ptr
->completers
);
2380 ptr
->completers
= insert_gclist (ptr
->completers
);
2383 /* The table has been finalized, now number the indexes. */
2384 for (x
= 0; x
< glistlen
; x
++)
2391 /* attach two lists of dependencies to each opcode.
2392 1) all resources which, when already marked in use, conflict with this
2394 2) all resources which must be marked in use when this opcode is used
2398 insert_opcode_dependencies (opc
, cmp
)
2399 struct ia64_opcode
*opc
;
2400 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2402 /* note all resources which point to this opcode. rfi has the most chks
2403 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2406 unsigned short regs
[256];
2408 unsigned short chks
[256];
2409 /* flag insns for which no class matched; there should be none */
2410 int no_class_found
= 1;
2412 for (i
=0;i
< rdepslen
;i
++)
2414 struct rdep
*rs
= rdeps
[i
];
2417 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2418 && strncmp (rs
->name
, "PR%", 3) == 0
2420 no_class_found
= 99;
2422 for (j
=0; j
< rs
->nregs
;j
++)
2426 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2428 /* We can ignore ic_note 11 for non PR resources */
2429 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2432 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2433 && ic_note
!= rs
->regnotes
[j
]
2434 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2435 fprintf (stderr
, "Warning: IC note %d in opcode %s (IC:%s)"
2436 " conflicts with resource %s note %d\n",
2437 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2438 rs
->name
, rs
->regnotes
[j
]);
2439 /* Instruction class notes override resource notes.
2440 So far, only note 11 applies to an IC instead of a resource,
2441 and note 11 implies note 1.
2444 regs
[nregs
++] = RDEP(ic_note
, i
);
2446 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2451 for (j
=0;j
< rs
->nchks
;j
++)
2455 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2457 /* We can ignore ic_note 11 for non PR resources */
2458 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2461 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2462 && ic_note
!= rs
->chknotes
[j
]
2463 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2464 fprintf (stderr
, "Warning: IC note %d for opcode %s (IC:%s)"
2465 " conflicts with resource %s note %d\n",
2466 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2467 rs
->name
, rs
->chknotes
[j
]);
2469 chks
[nchks
++] = RDEP(ic_note
, i
);
2471 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2479 fprintf (stderr
, "Warning: opcode %s has no class (ops %d %d %d)\n",
2481 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2483 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2487 insert_completer_entry (opc
, tabent
, order
)
2488 struct ia64_opcode
*opc
;
2489 struct main_entry
*tabent
;
2492 struct completer_entry
**ptr
= &tabent
->completers
;
2493 struct completer_entry
*parent
= NULL
;
2494 char pcopy
[129], *prefix
;
2497 if (strlen (opc
->name
) > 128)
2501 strcpy (pcopy
, opc
->name
);
2502 prefix
= pcopy
+ get_prefix_len (pcopy
);
2503 if (prefix
[0] != '\0')
2510 int need_new_ent
= 1;
2511 int plen
= get_prefix_len (prefix
);
2512 struct string_entry
*sent
;
2514 at_end
= (prefix
[plen
] == '\0');
2515 prefix
[plen
] = '\0';
2516 sent
= insert_string (prefix
);
2518 while (*ptr
!= NULL
)
2520 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2529 ptr
= &((*ptr
)->alternative
);
2534 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2536 nent
->parent
= parent
;
2537 nent
->addl_entries
= NULL
;
2538 nent
->alternative
= *ptr
;
2540 nent
->is_terminal
= 0;
2541 nent
->dependencies
= -1;
2547 ptr
= &((*ptr
)->addl_entries
);
2552 if ((*ptr
)->is_terminal
)
2557 (*ptr
)->is_terminal
= 1;
2558 (*ptr
)->mask
= (ia64_insn
)-1;
2559 (*ptr
)->bits
= opc
->opcode
;
2560 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2561 (*ptr
)->order
= order
;
2565 print_completer_entry (ent
)
2566 struct completer_entry
*ent
;
2569 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2573 while (! (mask
& 1))
2579 if (bits
& 0xffffffff00000000LL
)
2585 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2589 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2590 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2592 ent
->is_terminal
? 1 : 0,
2597 print_completer_table ()
2601 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2602 for (x
= 0; x
< glistlen
; x
++)
2604 print_completer_entry (glist
[x
]);
2610 opcodes_eq (opc1
, opc2
)
2611 struct ia64_opcode
*opc1
;
2612 struct ia64_opcode
*opc2
;
2617 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2618 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2619 || (opc1
->flags
!= opc2
->flags
))
2623 for (x
= 0; x
< 5; x
++)
2625 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2630 plen1
= get_prefix_len (opc1
->name
);
2631 plen2
= get_prefix_len (opc2
->name
);
2632 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2640 add_opcode_entry (opc
)
2641 struct ia64_opcode
*opc
;
2643 struct main_entry
**place
;
2644 struct string_entry
*name
;
2648 if (strlen (opc
->name
) > 128)
2653 strcpy (prefix
, opc
->name
);
2654 prefix
[get_prefix_len (prefix
)] = '\0';
2655 name
= insert_string (prefix
);
2657 /* Walk the list of opcode table entries. If it's a new
2658 instruction, allocate and fill in a new entry. Note
2659 the main table is alphabetical by opcode name. */
2661 while (*place
!= NULL
)
2663 if ((*place
)->name
->num
== name
->num
2664 && opcodes_eq ((*place
)->opcode
, opc
))
2669 if ((*place
)->name
->num
> name
->num
)
2673 place
= &((*place
)->next
);
2677 struct main_entry
*nent
= tmalloc (struct main_entry
);
2681 nent
->next
= *place
;
2682 nent
->completers
= 0;
2685 if (otlen
== ottotlen
)
2688 ordered_table
= (struct main_entry
**)
2689 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2691 ordered_table
[otlen
++] = nent
;
2694 insert_completer_entry (opc
, *place
, opcode_count
++);
2700 struct main_entry
*ptr
= maintable
;
2703 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2706 printf (" { %d, %d, %d, 0x",
2709 ptr
->opcode
->num_outputs
);
2710 fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2712 fprintf_vma (stdout
, ptr
->opcode
->mask
);
2713 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2714 ptr
->opcode
->operands
[0],
2715 ptr
->opcode
->operands
[1],
2716 ptr
->opcode
->operands
[2],
2717 ptr
->opcode
->operands
[3],
2718 ptr
->opcode
->operands
[4],
2720 ptr
->completers
->num
);
2722 ptr
->main_index
= index
++;
2731 struct ia64_opcode
*table
;
2735 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2737 add_opcode_entry (table
+ curr_opcode
);
2744 char **argv ATTRIBUTE_UNUSED
;
2751 load_insn_classes();
2752 load_dependencies();
2754 shrink (ia64_opcodes_a
);
2755 shrink (ia64_opcodes_b
);
2756 shrink (ia64_opcodes_f
);
2757 shrink (ia64_opcodes_i
);
2758 shrink (ia64_opcodes_m
);
2759 shrink (ia64_opcodes_x
);
2760 shrink (ia64_opcodes_d
);
2762 collapse_redundant_completers ();
2764 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2765 print_string_table ();
2766 print_dependency_table ();
2767 print_completer_table ();
2768 print_main_table ();
2770 generate_disassembler ();