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
< 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
< 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
);
1466 /* and dependency lists */
1467 for (i
=0;i
< dlistlen
;i
++)
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
]);
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
++)
1490 if (opdeps
[i
]->chk
== -1)
1491 printf ("0, NULL, ");
1493 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1494 if (opdeps
[i
]->reg
== -1)
1495 printf ("0, NULL, ");
1497 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1504 /* Add STR to the string table. */
1506 static struct string_entry
*
1510 int start
= 0, end
= strtablen
;
1513 if (strtablen
== strtabtotlen
)
1516 string_table
= (struct string_entry
**)
1517 xrealloc (string_table
,
1518 sizeof (struct string_entry
**) * strtabtotlen
);
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)
1534 else if (strcmp (str
, string_table
[0]->s
) < 0)
1544 i
= (start
+ end
) / 2;
1545 c
= strcmp (str
, string_table
[i
]->s
);
1552 return string_table
[i
];
1564 for (; i
> 0 && i
< strtablen
; i
--)
1566 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1571 for (; i
< strtablen
; i
++)
1573 if (strcmp (str
, string_table
[i
]->s
) < 0)
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
;
1587 return string_table
[i
];
1591 make_bittree_entry ()
1593 struct bittree
*res
= tmalloc (struct bittree
);
1596 res
->bits
[0] = NULL
;
1597 res
->bits
[1] = NULL
;
1598 res
->bits
[2] = NULL
;
1600 res
->bits_to_skip
= 0;
1605 add_dis_table_ent (which
, insn
, order
, completer_index
)
1606 struct disent
*which
;
1609 int completer_index
;
1619 while (ent
->nexte
!= NULL
)
1623 ent
= (ent
->nexte
= tmalloc (struct disent
));
1627 ent
= tmalloc (struct disent
);
1628 ent
->next_ent
= disinsntable
;
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
;
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;
1661 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1662 opcodenum
, order
, completer_index
)
1663 struct bittree
*curr_ent
;
1669 int completer_index
;
1673 struct bittree
*next
;
1677 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1680 curr_ent
->disent
= nent
;
1684 m
= ((ia64_insn
) 1) << bit
;
1688 b
= (opcode
& m
) ? 1 : 0;
1694 next
= curr_ent
->bits
[b
];
1697 next
= make_bittree_entry ();
1698 curr_ent
->bits
[b
] = next
;
1700 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1705 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1706 struct bittree
*first
;
1710 struct completer_entry
*ent
;
1711 int completer_index
;
1713 if (completer_index
& (1 << 20))
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. */
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))
1744 struct bittree
*nent
= ent
;
1747 while (IS_SKIP (nent
))
1750 nent
= nent
->bits
[2];
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
;
1762 ent
->bits_to_skip
= bitcnt
;
1763 while (next
!= nent
)
1765 struct bittree
*b
= next
;
1766 next
= next
->bits
[2];
1772 for (x
= 0; x
< 3; x
++)
1774 struct bittree
*i
= ent
->bits
[x
];
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
1790 struct bittree
*ent
;
1793 int our_offset
= insn_list_len
;
1795 int totbits
= bitsused
;
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
1802 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1803 ent
->bits
[2] == NULL
)
1805 if (ent
->disent
== NULL
)
1815 /* Calculate the amount of space needed for this entry, or at least
1816 a conservatively large approximation. */
1821 for (x
= 1; x
< 3; x
++)
1823 if (ent
->bits
[x
] != NULL
)
1829 if (ent
->disent
!= NULL
)
1831 if (ent
->bits
[2] != NULL
)
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. */
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
1865 if (ent
->bits
[0] != NULL
)
1867 struct bittree
*nent
= ent
->bits
[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];
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
];
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
;
1915 idest
= insn_list_len
- our_offset
;
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. */
1937 int start
= our_offset
+ bitsused
/ 8 + 1;
1939 memmove (insn_list
+ start
,
1940 insn_list
+ start
+ 1,
1941 insn_list_len
- (start
+ 1));
1946 insn_list
[our_offset
] |= 0x10;
1951 insn_list
[our_offset
] |= 0x20;
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));
1977 insn_list
[our_offset
] |= 0x30;
1982 insn_list
[our_offset
] |= 0x08;
1993 else if (! (id
& 32768))
1999 printf ("%d: if (1) goto %d\n", our_offset
, id
);
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)));
2020 /* Now generate the states for the entry being branched to. */
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,
2041 if (bitsused
!= totbits
)
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))
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
;
2071 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2072 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2076 cent
= cent
->next_ent
;
2082 generate_disassembler ()
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
,
2097 ptr
->completers
, 1);
2101 compact_distree (bittree
);
2103 gen_dis_table (bittree
);
2109 print_string_table ()
2112 char lbuf
[80], buf
[80];
2115 printf ("static const char *ia64_strings[] = {\n");
2117 for (x
= 0; x
< strtablen
; x
++)
2121 if (strlen (string_table
[x
]->s
) > 75)
2125 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2127 if ((blen
+ len
) > 75)
2129 printf (" %s\n", lbuf
);
2138 printf (" %s\n", lbuf
);
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
)
2164 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
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
*
2179 struct completer_entry
*ent
;
2187 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2188 ent
->alternative
= insert_gclist (ent
->alternative
);
2193 if (glisttotlen
== glistlen
)
2196 glist
= (struct completer_entry
**)
2197 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2207 if (ent
->name
->num
< glist
[0]->name
->num
)
2211 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2221 i
= (start
+ end
) / 2;
2222 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2230 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2247 while (i
< glistlen
)
2249 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2253 if (completer_entries_eq (ent
, glist
[i
]))
2261 for (; i
> 0 && i
< glistlen
; i
--)
2263 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2268 for (; i
< glistlen
; i
++)
2270 if (ent
->name
->num
< glist
[i
]->name
->num
)
2275 for (x
= glistlen
- 1; x
>= i
; x
--)
2277 glist
[x
+ 1] = glist
[x
];
2286 get_prefix_len (name
)
2291 if (name
[0] == '\0')
2296 c
= strchr (name
, '.');
2303 return strlen (name
);
2308 compute_completer_bits (ment
, ent
)
2309 struct main_entry
*ment
;
2310 struct completer_entry
*ent
;
2314 compute_completer_bits (ment
, ent
->addl_entries
);
2316 if (ent
->is_terminal
)
2319 ia64_insn our_bits
= ent
->bits
;
2320 struct completer_entry
*p
= ent
->parent
;
2324 while (p
!= NULL
&& ! p
->is_terminal
)
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
))
2350 ent
->bits
= our_bits
;
2359 ent
= ent
->alternative
;
2363 /* Find identical completer trees that are used in different
2364 instructions and collapse their entries. */
2366 collapse_redundant_completers ()
2368 struct main_entry
*ptr
;
2371 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2373 if (ptr
->completers
== NULL
)
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
++)
2389 /* attach two lists of dependencies to each opcode.
2390 1) all resources which, when already marked in use, conflict with this
2392 2) all resources which must be marked in use when this opcode is used
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 */
2404 unsigned short regs
[256];
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
];
2415 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2416 && strncmp (rs
->name
, "PR%", 3) == 0
2418 no_class_found
= 99;
2420 for (j
=0; j
< rs
->nregs
;j
++)
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)
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.
2442 regs
[nregs
++] = RDEP(ic_note
, i
);
2444 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2449 for (j
=0;j
< rs
->nchks
;j
++)
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)
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
]);
2467 chks
[nchks
++] = RDEP(ic_note
, i
);
2469 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2477 fprintf (stderr
, "Warning: opcode %s has no class (ops %d %d %d)\n",
2479 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2481 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2485 insert_completer_entry (opc
, tabent
, order
)
2486 struct ia64_opcode
*opc
;
2487 struct main_entry
*tabent
;
2490 struct completer_entry
**ptr
= &tabent
->completers
;
2491 struct completer_entry
*parent
= NULL
;
2492 char pcopy
[129], *prefix
;
2495 if (strlen (opc
->name
) > 128)
2499 strcpy (pcopy
, opc
->name
);
2500 prefix
= pcopy
+ get_prefix_len (pcopy
);
2501 if (prefix
[0] != '\0')
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
;
2527 ptr
= &((*ptr
)->alternative
);
2532 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2534 nent
->parent
= parent
;
2535 nent
->addl_entries
= NULL
;
2536 nent
->alternative
= *ptr
;
2538 nent
->is_terminal
= 0;
2539 nent
->dependencies
= -1;
2545 ptr
= &((*ptr
)->addl_entries
);
2550 if ((*ptr
)->is_terminal
)
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
;
2563 print_completer_entry (ent
)
2564 struct completer_entry
*ent
;
2567 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2571 while (! (mask
& 1))
2577 if (bits
& 0xffffffff00000000LL
)
2583 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2587 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2588 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2590 ent
->is_terminal
? 1 : 0,
2595 print_completer_table ()
2599 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2600 for (x
= 0; x
< glistlen
; x
++)
2602 print_completer_entry (glist
[x
]);
2608 opcodes_eq (opc1
, opc2
)
2609 struct ia64_opcode
*opc1
;
2610 struct ia64_opcode
*opc2
;
2615 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2616 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2617 || (opc1
->flags
!= opc2
->flags
))
2621 for (x
= 0; x
< 5; x
++)
2623 if (opc1
->operands
[x
] != opc2
->operands
[x
])
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))
2638 add_opcode_entry (opc
)
2639 struct ia64_opcode
*opc
;
2641 struct main_entry
**place
;
2642 struct string_entry
*name
;
2646 if (strlen (opc
->name
) > 128)
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
))
2667 if ((*place
)->name
->num
> name
->num
)
2671 place
= &((*place
)->next
);
2675 struct main_entry
*nent
= tmalloc (struct main_entry
);
2679 nent
->next
= *place
;
2680 nent
->completers
= 0;
2683 if (otlen
== ottotlen
)
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
++);
2698 struct main_entry
*ptr
= maintable
;
2701 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2704 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2707 ptr
->opcode
->num_outputs
,
2708 ptr
->opcode
->opcode
,
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],
2716 ptr
->completers
->num
);
2718 ptr
->main_index
= index
++;
2727 struct ia64_opcode
*table
;
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
)
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 ();