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
;
701 return IA64_DVS_OTHER
;
705 add_dep (const char *name
, const char *chk
, const char *reg
,
706 int semantics
, int mode
, char *extra
, int flag
)
710 rs
= insert_resource (name
, mode
);
711 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
,
713 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
,
715 rs
->semantics
= semantics
;
717 rs
->waw_special
= flag
;
721 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
723 FILE *fp
= fopen(filename
, "r");
727 fprintf (stderr
, "Can't find %s for reading\n", filename
);
731 fgets(buf
, sizeof(buf
), fp
);
739 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
742 while (isspace(buf
[strlen(buf
)-1]))
743 buf
[strlen(buf
)-1] = '\0';
750 while (isspace (*tmp
))
753 tmp
= strchr (tmp
, ';');
757 while (isspace (*tmp
))
760 tmp
= strchr (tmp
, ';');
764 while (isspace (*tmp
))
766 semantics
= parse_semantics (tmp
);
767 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
769 /* For WAW entries, if the chks and regs differ, we need to enter the
770 entries in both positions so that the tables will be parsed properly,
771 without a lot of extra work */
772 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
774 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
775 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
779 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
788 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
789 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
790 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
793 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
796 /* is the given operand an indirect register file operand? */
798 irf_operand (int op
, const char *field
)
802 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
803 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
804 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
805 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
809 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
810 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
811 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
812 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
813 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
814 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
815 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
816 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
820 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
821 mov_um insn classes */
823 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
824 const char *format
, const char *field
)
826 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
837 int i
= strcmp (idesc
->name
, "mov.i") == 0;
838 int m
= strcmp (idesc
->name
, "mov.m") == 0;
839 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
840 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
841 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
842 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
843 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
844 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
848 return strstr (format
, "I26") || strstr (format
, "I27");
850 return strstr (format
, "I28") != NULL
;
852 return strstr (format
, "M29") || strstr (format
, "M30");
854 return strstr (format
, "M31") != NULL
;
855 if (pseudo0
|| pseudo1
)
861 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
862 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
864 return strstr (format
, "I22") != NULL
;
866 return strstr (format
, "I21") != NULL
;
871 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
872 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
874 return strstr (format
, "M32") != NULL
;
876 return strstr (format
, "M33") != NULL
;
880 if (ic
->name
[5] == 'n')
882 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
883 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
885 return strstr (format
, "M42") != NULL
;
887 return strstr (format
, "M43") != NULL
;
889 else if (ic
->name
[5] == 'p')
891 return idesc
->operands
[1] == IA64_OPND_IP
;
897 if (ic
->name
[5] == 'r')
899 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
900 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
901 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
903 return strstr (format
, "I23") != NULL
;
905 return strstr (format
, "I24") != NULL
;
907 return strstr (format
, "I25") != NULL
;
909 else if (ic
->name
[5] == 's')
911 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
912 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
914 return strstr (format
, "M35") != NULL
;
916 return strstr (format
, "M36") != NULL
;
923 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
924 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
926 return strstr (format
, "M35") != NULL
;
928 return strstr (format
, "M36") != NULL
;
936 /* is the given opcode in the given insn class? */
938 in_iclass(struct ia64_opcode
*idesc
, struct iclass
*ic
,
939 const char *format
, const char *field
, int *notep
)
946 if (!strncmp (ic
->comment
, "Format", 6))
948 /* assume that the first format seen is the most restrictive, and
949 only keep a later one if it looks like it's more restrictive. */
952 if (strlen (ic
->comment
) < strlen (format
))
954 fprintf (stderr
, "Warning: most recent format '%s'\n"
955 "appears more restrictive than '%s'\n",
956 ic
->comment
, format
);
957 format
= ic
->comment
;
961 format
= ic
->comment
;
963 else if (!strncmp (ic
->comment
, "Field", 5))
966 fprintf (stderr
, "Overlapping field %s->%s\n",
972 /* an insn class matches anything that is the same followed by completers,
973 except when the absence and presence of completers constitutes different
975 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
977 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
978 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
979 int len
= strlen(ic
->name
);
981 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
982 && (idesc
->name
[len
] == '\0'
983 || idesc
->name
[len
] == '.'));
985 /* all break and nop variations must match exactly */
987 (strcmp (ic
->name
, "break") == 0
988 || strcmp (ic
->name
, "nop") == 0))
989 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
991 /* assume restrictions in the FORMAT/FIELD negate resolution,
992 unless specifically allowed by clauses in this block */
993 if (resolved
&& field
)
995 /* check Field(sf)==sN against opcode sN */
996 if (strstr(field
, "(sf)==") != NULL
)
999 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1001 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1004 /* check Field(lftype)==XXX */
1005 else if (strstr (field
, "(lftype)") != NULL
)
1007 if (strstr (idesc
->name
, "fault") != NULL
)
1008 resolved
= strstr (field
, "fault") != NULL
;
1010 resolved
= strstr (field
, "fault") == NULL
;
1012 /* handle Field(ctype)==XXX */
1013 else if (strstr (field
, "(ctype)") != NULL
)
1015 if (strstr (idesc
->name
, "or.andcm"))
1016 resolved
= strstr (field
, "or.andcm") != NULL
;
1017 else if (strstr (idesc
->name
, "and.orcm"))
1018 resolved
= strstr (field
, "and.orcm") != NULL
;
1019 else if (strstr (idesc
->name
, "orcm"))
1020 resolved
= strstr (field
, "or orcm") != NULL
;
1021 else if (strstr (idesc
->name
, "or"))
1022 resolved
= strstr (field
, "or orcm") != NULL
;
1023 else if (strstr (idesc
->name
, "andcm"))
1024 resolved
= strstr (field
, "and andcm") != NULL
;
1025 else if (strstr (idesc
->name
, "and"))
1026 resolved
= strstr (field
, "and andcm") != NULL
;
1027 else if (strstr (idesc
->name
, "unc"))
1028 resolved
= strstr (field
, "unc") != NULL
;
1030 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1033 if (resolved
&& format
)
1035 if (strncmp (idesc
->name
, "dep", 3) == 0
1036 && strstr (format
, "I13") != NULL
)
1037 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1038 else if (strncmp (idesc
->name
, "chk", 3) == 0
1039 && strstr (format
, "M21") != NULL
)
1040 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1041 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1042 resolved
= (strstr (format
, "M14 M15") != NULL
1043 && (idesc
->operands
[1] == IA64_OPND_R2
1044 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1045 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1046 && strstr (format
, "B5") != NULL
)
1047 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1048 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1049 && strstr (format
, "B3") != NULL
)
1050 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1051 else if (strncmp (idesc
->name
, "brp", 3) == 0
1052 && strstr (format
, "B7") != NULL
)
1053 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1054 else if (strcmp (ic
->name
, "invala") == 0)
1055 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1060 /* misc brl variations ('.cond' is optional);
1061 plain brl matches brl.cond */
1063 && (strcmp (idesc
->name
, "brl") == 0
1064 || strncmp (idesc
->name
, "brl.", 4) == 0)
1065 && strcmp (ic
->name
, "brl.cond") == 0)
1070 /* misc br variations ('.cond' is optional) */
1072 && (strcmp (idesc
->name
, "br") == 0
1073 || strncmp (idesc
->name
, "br.", 3) == 0)
1074 && strcmp (ic
->name
, "br.cond") == 0)
1077 resolved
= (strstr (format
, "B4") != NULL
1078 && idesc
->operands
[0] == IA64_OPND_B2
)
1079 || (strstr (format
, "B1") != NULL
1080 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1085 /* probe variations */
1086 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1088 resolved
= strcmp (ic
->name
, "probe") == 0
1089 && !((strstr (idesc
->name
, "fault") != NULL
)
1090 ^ (format
&& strstr (format
, "M40") != NULL
));
1092 /* mov variations */
1093 if (!resolved
&& is_mov
)
1097 /* mov alias for fmerge */
1098 if (strcmp (ic
->name
, "fmerge") == 0)
1100 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1101 && idesc
->operands
[1] == IA64_OPND_F3
;
1103 /* mov alias for adds (r3 or imm14) */
1104 else if (strcmp (ic
->name
, "adds") == 0)
1106 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1107 && (idesc
->operands
[1] == IA64_OPND_R3
1108 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1110 /* mov alias for addl */
1111 else if (strcmp (ic
->name
, "addl") == 0)
1113 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1114 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1117 /* some variants of mov and mov.[im] */
1118 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1120 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1124 /* keep track of this so we can flag any insn classes which aren't
1125 mapped onto at least one real insn */
1128 ic
->terminal_resolved
= 1;
1131 else for (i
=0;i
< ic
->nsubs
;i
++)
1133 if (in_iclass(idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1136 for (j
=0;j
< ic
->nxsubs
;j
++)
1138 if (in_iclass(idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1142 printf ("%s is in IC %s\n",
1143 idesc
->name
, ic
->name
);
1149 /* If it's in this IC, add the IC note (if any) to the insn */
1152 if (ic
->note
&& notep
)
1154 if (*notep
&& *notep
!= ic
->note
)
1156 fprintf (stderr
, "Warning: overwriting note %d with note %d"
1158 *notep
, ic
->note
, ic
->name
);
1169 lookup_regindex (const char *name
, int specifier
)
1174 if (strstr (name
, "[RSC]"))
1176 if (strstr (name
, "[BSP]"))
1178 else if (strstr (name
, "[BSPSTORE]"))
1180 else if (strstr (name
, "[RNAT]"))
1182 else if (strstr (name
, "[CCV]"))
1184 else if (strstr (name
, "[ITC]"))
1186 else if (strstr (name
, "[PFS]"))
1188 else if (strstr (name
, "[LC]"))
1190 else if (strstr (name
, "[EC]"))
1194 if (strstr (name
, "[DCR]"))
1196 else if (strstr (name
, "[ITM]"))
1198 else if (strstr (name
, "[IVA]"))
1200 else if (strstr (name
, "[PTA]"))
1202 else if (strstr (name
, "[GPTA]"))
1204 else if (strstr (name
, "[IPSR]"))
1206 else if (strstr (name
, "[ISR]"))
1208 else if (strstr (name
, "[IIP]"))
1210 else if (strstr (name
, "[IFA]"))
1212 else if (strstr (name
, "[ITIR]"))
1214 else if (strstr (name
, "[IIPA]"))
1216 else if (strstr (name
, "[IFS]"))
1218 else if (strstr (name
, "[IIM]"))
1220 else if (strstr (name
, "[IHA]"))
1222 else if (strstr (name
, "[LID]"))
1224 else if (strstr (name
, "[IVR]"))
1226 else if (strstr (name
, "[TPR]"))
1228 else if (strstr (name
, "[EOI]"))
1230 else if (strstr (name
, "[ITV]"))
1232 else if (strstr (name
, "[PMV]"))
1234 else if (strstr (name
, "[CMCV]"))
1238 if (strstr (name
, ".be"))
1240 else if (strstr (name
, ".up"))
1242 else if (strstr (name
, ".ac"))
1244 else if (strstr (name
, ".mfl"))
1246 else if (strstr (name
, ".mfh"))
1248 else if (strstr (name
, ".ic"))
1250 else if (strstr (name
, ".i"))
1252 else if (strstr (name
, ".pk"))
1254 else if (strstr (name
, ".dt"))
1256 else if (strstr (name
, ".dfl"))
1258 else if (strstr (name
, ".dfh"))
1260 else if (strstr (name
, ".sp"))
1262 else if (strstr (name
, ".pp"))
1264 else if (strstr (name
, ".di"))
1266 else if (strstr (name
, ".si"))
1268 else if (strstr (name
, ".db"))
1270 else if (strstr (name
, ".lp"))
1272 else if (strstr (name
, ".tb"))
1274 else if (strstr (name
, ".rt"))
1276 else if (strstr (name
, ".cpl"))
1278 else if (strstr (name
, ".rs"))
1280 else if (strstr (name
, ".mc"))
1282 else if (strstr (name
, ".it"))
1284 else if (strstr (name
, ".id"))
1286 else if (strstr (name
, ".da"))
1288 else if (strstr (name
, ".dd"))
1290 else if (strstr (name
, ".ss"))
1292 else if (strstr (name
, ".ri"))
1294 else if (strstr (name
, ".ed"))
1296 else if (strstr (name
, ".bn"))
1298 else if (strstr (name
, ".ia"))
1309 lookup_specifier (const char *name
)
1311 if (strchr (name
, '%'))
1313 if (strstr (name
, "AR[K%]") != NULL
)
1314 return IA64_RS_AR_K
;
1315 if (strstr (name
, "AR[UNAT]") != NULL
)
1316 return IA64_RS_AR_UNAT
;
1317 if (strstr (name
, "AR%, % in 8") != NULL
)
1319 if (strstr (name
, "AR%, % in 48") != NULL
)
1321 if (strstr (name
, "BR%") != NULL
)
1323 if (strstr (name
, "CR[IRR%]") != NULL
)
1324 return IA64_RS_CR_IRR
;
1325 if (strstr (name
, "CR[LRR%]") != NULL
)
1326 return IA64_RS_CR_LRR
;
1327 if (strstr (name
, "CR%") != NULL
)
1329 if (strstr (name
, "FR%, % in 0") != NULL
)
1331 if (strstr (name
, "FR%, % in 2") != NULL
)
1333 if (strstr (name
, "GR%") != NULL
)
1335 if (strstr (name
, "PR%") != NULL
)
1338 fprintf (stderr
, "Warning! Don't know how to specify %% dependency %s\n",
1341 else if (strchr (name
, '#'))
1343 if (strstr (name
, "CPUID#") != NULL
)
1344 return IA64_RS_CPUID
;
1345 if (strstr (name
, "DBR#") != NULL
)
1347 if (strstr (name
, "IBR#") != NULL
)
1349 if (strstr (name
, "MSR#") != NULL
)
1351 if (strstr (name
, "PKR#") != NULL
)
1353 if (strstr (name
, "PMC#") != NULL
)
1355 if (strstr (name
, "PMD#") != NULL
)
1357 if (strstr (name
, "RR#") != NULL
)
1360 fprintf (stderr
, "Warning! Don't know how to specify # dependency %s\n",
1363 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1364 return IA64_RS_AR_FPSR
;
1365 else if (strncmp (name
, "AR[", 3) == 0)
1367 else if (strncmp (name
, "CR[", 3) == 0)
1369 else if (strncmp (name
, "PSR.", 4) == 0)
1371 else if (strcmp (name
, "InService*") == 0)
1372 return IA64_RS_INSERVICE
;
1373 else if (strcmp (name
, "GR0") == 0)
1375 else if (strcmp (name
, "CFM") == 0)
1377 else if (strcmp (name
, "PR63") == 0)
1378 return IA64_RS_PR63
;
1379 else if (strcmp (name
, "RSE") == 0)
1386 print_dependency_table ()
1392 for (i
=0;i
< iclen
;i
++)
1394 if (ics
[i
]->is_class
)
1398 fprintf (stderr
, "Warning: IC:%s", ics
[i
]->name
);
1399 if (ics
[i
]->comment
)
1400 fprintf (stderr
, "[%s]", ics
[i
]->comment
);
1401 fprintf (stderr
, " has no terminals or sub-classes\n");
1406 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1408 fprintf(stderr
, "Warning: no insns mapped directly to "
1409 "terminal IC %s", ics
[i
]->name
);
1410 if (ics
[i
]->comment
)
1411 fprintf(stderr
, "[%s] ", ics
[i
]->comment
);
1412 fprintf(stderr
, "\n");
1417 for (i
=0;i
< iclen
;i
++)
1421 mark_used (ics
[i
], 1);
1422 fprintf (stderr
, "Warning: class %s is defined but not used\n",
1427 if (debug
> 1) for (i
=0;i
< rdepslen
;i
++)
1429 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1430 if (rdeps
[i
]->total_chks
== 0)
1432 fprintf (stderr
, "Warning: rsrc %s (%s) has no chks%s\n",
1433 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1434 rdeps
[i
]->total_regs
? "" : " or regs");
1436 else if (rdeps
[i
]->total_regs
== 0)
1438 fprintf (stderr
, "Warning: rsrc %s (%s) has no regs\n",
1439 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1444 /* the dependencies themselves */
1445 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1446 for (i
=0;i
< rdepslen
;i
++)
1448 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1450 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1451 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1453 printf (" { \"%s\", %d, %d, %d, %d, ",
1454 rdeps
[i
]->name
, specifier
,
1455 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1456 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1457 printf ("\"%s\", ", rdeps
[i
]->extra
);
1462 /* and dependency lists */
1463 for (i
=0;i
< dlistlen
;i
++)
1466 printf ("static const short dep%d[] = {\n ", i
);
1467 for (j
=0;j
< dlists
[i
]->len
; j
++)
1469 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1476 printf ("\n};\n\n");
1479 /* and opcode dependency list */
1480 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1481 printf ("static const struct ia64_opcode_dependency\n");
1482 printf ("op_dependencies[] = {\n");
1483 for (i
=0;i
< opdeplen
;i
++)
1486 if (opdeps
[i
]->chk
== -1)
1487 printf ("0, NULL, ");
1489 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1490 if (opdeps
[i
]->reg
== -1)
1491 printf ("0, NULL, ");
1493 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1500 /* Add STR to the string table. */
1502 static struct string_entry
*
1506 int start
= 0, end
= strtablen
;
1509 if (strtablen
== strtabtotlen
)
1512 string_table
= (struct string_entry
**)
1513 xrealloc (string_table
,
1514 sizeof (struct string_entry
**) * strtabtotlen
);
1520 string_table
[0] = tmalloc (struct string_entry
);
1521 string_table
[0]->s
= xstrdup (str
);
1522 string_table
[0]->num
= 0;
1523 return string_table
[0];
1526 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1530 else if (strcmp (str
, string_table
[0]->s
) < 0)
1540 i
= (start
+ end
) / 2;
1541 c
= strcmp (str
, string_table
[i
]->s
);
1548 return string_table
[i
];
1560 for (; i
> 0 && i
< strtablen
; i
--)
1562 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1567 for (; i
< strtablen
; i
++)
1569 if (strcmp (str
, string_table
[i
]->s
) < 0)
1574 for (x
= strtablen
- 1; x
>= i
; x
--)
1576 string_table
[x
+ 1] = string_table
[x
];
1577 string_table
[x
+ 1]->num
= x
+ 1;
1579 string_table
[i
] = tmalloc (struct string_entry
);
1580 string_table
[i
]->s
= xstrdup (str
);
1581 string_table
[i
]->num
= i
;
1583 return string_table
[i
];
1587 make_bittree_entry ()
1589 struct bittree
*res
= tmalloc (struct bittree
);
1592 res
->bits
[0] = NULL
;
1593 res
->bits
[1] = NULL
;
1594 res
->bits
[2] = NULL
;
1596 res
->bits_to_skip
= 0;
1601 add_dis_table_ent (which
, insn
, order
, completer_index
)
1602 struct disent
*which
;
1605 int completer_index
;
1615 while (ent
->nexte
!= NULL
)
1619 ent
= (ent
->nexte
= tmalloc (struct disent
));
1623 ent
= tmalloc (struct disent
);
1624 ent
->next_ent
= disinsntable
;
1631 ent
->priority
= order
;
1633 while (completer_index
!= 1)
1635 ci
= (ci
<< 1) | (completer_index
& 1);
1636 completer_index
>>= 1;
1638 ent
->completer_index
= ci
;
1645 struct disent
*ent
= disinsntable
;
1646 struct disent
*prev
= ent
;
1648 ent
->ournum
= 32768;
1649 while ((ent
= ent
->next_ent
) != NULL
)
1651 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1657 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1658 opcodenum
, order
, completer_index
)
1659 struct bittree
*curr_ent
;
1665 int completer_index
;
1669 struct bittree
*next
;
1673 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1676 curr_ent
->disent
= nent
;
1680 m
= ((ia64_insn
) 1) << bit
;
1684 b
= (opcode
& m
) ? 1 : 0;
1690 next
= curr_ent
->bits
[b
];
1693 next
= make_bittree_entry ();
1694 curr_ent
->bits
[b
] = next
;
1696 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1701 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1702 struct bittree
*first
;
1706 struct completer_entry
*ent
;
1707 int completer_index
;
1709 if (completer_index
& (1 << 20))
1715 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1716 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1717 (completer_index
<< 1) | 1);
1718 if (ent
->is_terminal
)
1720 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1721 opcodenum
, opcode_count
- ent
->order
- 1,
1722 (completer_index
<< 1) | 1);
1724 completer_index
<<= 1;
1725 ent
= ent
->alternative
;
1729 /* This optimization pass combines multiple "don't care" nodes. */
1731 compact_distree (ent
)
1732 struct bittree
*ent
;
1734 #define IS_SKIP(ent) \
1735 ((ent->bits[2] !=NULL) \
1736 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1739 struct bittree
*nent
= ent
;
1742 while (IS_SKIP (nent
))
1745 nent
= nent
->bits
[2];
1750 struct bittree
*next
= ent
->bits
[2];
1752 ent
->bits
[0] = nent
->bits
[0];
1753 ent
->bits
[1] = nent
->bits
[1];
1754 ent
->bits
[2] = nent
->bits
[2];
1755 ent
->disent
= nent
->disent
;
1757 ent
->bits_to_skip
= bitcnt
;
1758 while (next
!= nent
)
1760 struct bittree
*b
= next
;
1761 next
= next
->bits
[2];
1767 for (x
= 0; x
< 3; x
++)
1769 struct bittree
*i
= ent
->bits
[x
];
1772 compact_distree (i
);
1777 static unsigned char *insn_list
;
1778 static int insn_list_len
= 0;
1779 static int tot_insn_list_len
= 0;
1781 /* Generate the disassembler state machine corresponding to the tree
1785 struct bittree
*ent
;
1788 int our_offset
= insn_list_len
;
1790 int totbits
= bitsused
;
1793 int zero_dest
= 0; /* initialize this with 0 to keep gcc quiet... */
1795 /* If this is a terminal entry, there's no point in skipping any
1797 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1798 ent
->bits
[2] == NULL
)
1800 if (ent
->disent
== NULL
)
1810 /* Calculate the amount of space needed for this entry, or at least
1811 a conservatively large approximation. */
1816 for (x
= 1; x
< 3; x
++)
1818 if (ent
->bits
[x
] != NULL
)
1824 if (ent
->disent
!= NULL
)
1826 if (ent
->bits
[2] != NULL
)
1833 /* Now allocate the space. */
1834 needed_bytes
= (totbits
+ 7) / 8;
1835 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1837 tot_insn_list_len
+= 256;
1838 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1840 our_offset
= insn_list_len
;
1841 insn_list_len
+= needed_bytes
;
1842 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1844 /* Encode the skip entry by setting bit 6 set in the state op field,
1845 and store the # of bits to skip immediately after. */
1849 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1850 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1853 #define IS_ONLY_IFZERO(ENT) \
1854 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1855 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1857 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1860 if (ent
->bits
[0] != NULL
)
1862 struct bittree
*nent
= ent
->bits
[0];
1865 insn_list
[our_offset
] |= 0x80;
1867 /* We can encode sequences of multiple "if (bit is zero)" tests
1868 by storing the # of zero bits to check in the lower 3 bits of
1869 the instruction. However, this only applies if the state
1870 solely tests for a zero bit. */
1872 if (IS_ONLY_IFZERO (ent
))
1874 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1876 nent
= nent
->bits
[0];
1880 insn_list
[our_offset
+ 0] |= zero_count
;
1882 zero_dest
= insn_list_len
;
1883 gen_dis_table (nent
);
1886 /* Now store the remaining tests. We also handle a sole "termination
1887 entry" by storing it as an "any bit" test. */
1889 for (x
= 1; x
< 3; x
++)
1891 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1893 struct bittree
*i
= ent
->bits
[x
];
1899 /* If the instruction being branched to only consists of
1900 a termination entry, use the termination entry as the
1901 place to branch to instead. */
1902 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1903 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1905 idest
= i
->disent
->ournum
;
1910 idest
= insn_list_len
- our_offset
;
1915 idest
= ent
->disent
->ournum
;
1918 /* If the destination offset for the if (bit is 1) test is less
1919 than 256 bytes away, we can store it as 8-bits instead of 16;
1920 the instruction has bit 5 set for the 16-bit address, and bit
1921 4 for the 8-bit address. Since we've already allocated 16
1922 bits for the address we need to deallocate the space.
1924 Note that branchings within the table are relative, and
1925 there are no branches that branch past our instruction yet
1926 so we do not need to adjust any other offsets. */
1932 int start
= our_offset
+ bitsused
/ 8 + 1;
1934 memmove (insn_list
+ start
,
1935 insn_list
+ start
+ 1,
1936 insn_list_len
- (start
+ 1));
1941 insn_list
[our_offset
] |= 0x10;
1946 insn_list
[our_offset
] |= 0x20;
1951 /* An instruction which solely consists of a termination
1952 marker and whose disassembly name index is < 4096
1953 can be stored in 16 bits. The encoding is slightly
1954 odd; the upper 4 bits of the instruction are 0x3, and
1955 bit 3 loses its normal meaning. */
1957 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
1958 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
1959 && ent
->disent
!= NULL
1960 && ent
->disent
->ournum
< (32768 + 4096))
1962 int start
= our_offset
+ bitsused
/ 8 + 1;
1964 memmove (insn_list
+ start
,
1965 insn_list
+ start
+ 1,
1966 insn_list_len
- (start
+ 1));
1972 insn_list
[our_offset
] |= 0x30;
1977 insn_list
[our_offset
] |= 0x08;
1988 else if (! (id
& 32768))
1994 printf ("%d: if (1) goto %d\n", our_offset
, id
);
1998 printf ("%d: try %d\n", our_offset
, id
);
2002 /* Store the address of the entry being branched to. */
2003 while (currbits
>= 0)
2005 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2007 if (idest
& (1 << currbits
))
2009 *byte
|= (1 << (7 - (bitsused
% 8)));
2015 /* Now generate the states for the entry being branched to. */
2027 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2030 if (ent
->bits
[0] != NULL
)
2032 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2036 if (bitsused
!= totbits
)
2046 struct disent
*cent
= disinsntable
;
2048 printf ("static const char dis_table[] = {\n");
2049 for (x
= 0; x
< insn_list_len
; x
++)
2051 if ((x
> 0) && ((x
% 12) == 0))
2055 printf ("0x%02x, ", insn_list
[x
]);
2057 printf ("\n};\n\n");
2059 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2060 while (cent
!= NULL
)
2062 struct disent
*ent
= cent
;
2066 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2067 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2071 cent
= cent
->next_ent
;
2077 generate_disassembler ()
2081 bittree
= make_bittree_entry ();
2083 for (i
=0; i
< otlen
;i
++)
2085 struct main_entry
*ptr
= ordered_table
[i
];
2087 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2089 add_dis_entry (bittree
,
2090 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2092 ptr
->completers
, 1);
2096 compact_distree (bittree
);
2098 gen_dis_table (bittree
);
2104 print_string_table ()
2107 char lbuf
[80], buf
[80];
2110 printf ("static const char *ia64_strings[] = {\n");
2112 for (x
= 0; x
< strtablen
; x
++)
2116 if (strlen (string_table
[x
]->s
) > 75)
2120 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2122 if ((blen
+ len
) > 75)
2124 printf (" %s\n", lbuf
);
2133 printf (" %s\n", lbuf
);
2138 static struct completer_entry
**glist
;
2139 static int glistlen
= 0;
2140 static int glisttotlen
= 0;
2142 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2145 completer_entries_eq (ent1
, ent2
)
2146 struct completer_entry
*ent1
, *ent2
;
2148 while (ent1
!= NULL
&& ent2
!= NULL
)
2150 if (ent1
->name
->num
!= ent2
->name
->num
2151 || ent1
->bits
!= ent2
->bits
2152 || ent1
->mask
!= ent2
->mask
2153 || ent1
->is_terminal
!= ent2
->is_terminal
2154 || ent1
->dependencies
!= ent2
->dependencies
2155 || ent1
->order
!= ent2
->order
)
2159 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2163 ent1
= ent1
->alternative
;
2164 ent2
= ent2
->alternative
;
2166 return ent1
== ent2
;
2169 /* Insert ENT into the global list of completers and return it. If an
2170 equivalent entry (according to completer_entries_eq) already exists,
2171 it is returned instead. */
2172 struct completer_entry
*
2174 struct completer_entry
*ent
;
2182 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2183 ent
->alternative
= insert_gclist (ent
->alternative
);
2188 if (glisttotlen
== glistlen
)
2191 glist
= (struct completer_entry
**)
2192 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2202 if (ent
->name
->num
< glist
[0]->name
->num
)
2206 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2216 i
= (start
+ end
) / 2;
2217 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2225 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2242 while (i
< glistlen
)
2244 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2248 if (completer_entries_eq (ent
, glist
[i
]))
2256 for (; i
> 0 && i
< glistlen
; i
--)
2258 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2263 for (; i
< glistlen
; i
++)
2265 if (ent
->name
->num
< glist
[i
]->name
->num
)
2270 for (x
= glistlen
- 1; x
>= i
; x
--)
2272 glist
[x
+ 1] = glist
[x
];
2281 get_prefix_len (name
)
2286 if (name
[0] == '\0')
2291 c
= strchr (name
, '.');
2298 return strlen (name
);
2303 compute_completer_bits (ment
, ent
)
2304 struct main_entry
*ment
;
2305 struct completer_entry
*ent
;
2309 compute_completer_bits (ment
, ent
->addl_entries
);
2311 if (ent
->is_terminal
)
2314 ia64_insn our_bits
= ent
->bits
;
2315 struct completer_entry
*p
= ent
->parent
;
2319 while (p
!= NULL
&& ! p
->is_terminal
)
2330 p_bits
= ment
->opcode
->opcode
;
2333 for (x
= 0; x
< 64; x
++)
2335 ia64_insn m
= ((ia64_insn
) 1) << x
;
2336 if ((p_bits
& m
) != (our_bits
& m
))
2345 ent
->bits
= our_bits
;
2354 ent
= ent
->alternative
;
2358 /* Find identical completer trees that are used in different
2359 instructions and collapse their entries. */
2361 collapse_redundant_completers ()
2363 struct main_entry
*ptr
;
2366 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2368 if (ptr
->completers
== NULL
)
2372 compute_completer_bits (ptr
, ptr
->completers
);
2373 ptr
->completers
= insert_gclist (ptr
->completers
);
2376 /* The table has been finalized, now number the indexes. */
2377 for (x
= 0; x
< glistlen
; x
++)
2384 /* attach two lists of dependencies to each opcode.
2385 1) all resources which, when already marked in use, conflict with this
2387 2) all resources which must be marked in use when this opcode is used
2391 insert_opcode_dependencies (opc
, cmp
)
2392 struct ia64_opcode
*opc
;
2393 struct completer_entry
*cmp
;
2395 /* note all resources which point to this opcode. rfi has the most chks
2396 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2399 unsigned short regs
[256];
2401 unsigned short chks
[256];
2402 /* flag insns for which no class matched; there should be none */
2403 int no_class_found
= 1;
2405 for (i
=0;i
< rdepslen
;i
++)
2407 struct rdep
*rs
= rdeps
[i
];
2410 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2411 && strncmp (rs
->name
, "PR%", 3) == 0
2413 no_class_found
= 99;
2415 for (j
=0; j
< rs
->nregs
;j
++)
2419 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2421 /* We can ignore ic_note 11 for non PR resources */
2422 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2425 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2426 && ic_note
!= rs
->regnotes
[j
]
2427 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2428 fprintf (stderr
, "Warning: IC note %d in opcode %s (IC:%s)"
2429 " conflicts with resource %s note %d\n",
2430 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2431 rs
->name
, rs
->regnotes
[j
]);
2432 /* Instruction class notes override resource notes.
2433 So far, only note 11 applies to an IC instead of a resource,
2434 and note 11 implies note 1.
2437 regs
[nregs
++] = RDEP(ic_note
, i
);
2439 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2444 for (j
=0;j
< rs
->nchks
;j
++)
2448 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2450 /* We can ignore ic_note 11 for non PR resources */
2451 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2454 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2455 && ic_note
!= rs
->chknotes
[j
]
2456 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2457 fprintf (stderr
, "Warning: IC note %d for opcode %s (IC:%s)"
2458 " conflicts with resource %s note %d\n",
2459 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2460 rs
->name
, rs
->chknotes
[j
]);
2462 chks
[nchks
++] = RDEP(ic_note
, i
);
2464 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2472 fprintf (stderr
, "Warning: opcode %s has no class (ops %d %d %d)\n",
2474 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2476 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2480 insert_completer_entry (opc
, tabent
, order
)
2481 struct ia64_opcode
*opc
;
2482 struct main_entry
*tabent
;
2485 struct completer_entry
**ptr
= &tabent
->completers
;
2486 struct completer_entry
*parent
= NULL
;
2487 char pcopy
[129], *prefix
;
2490 if (strlen (opc
->name
) > 128)
2494 strcpy (pcopy
, opc
->name
);
2495 prefix
= pcopy
+ get_prefix_len (pcopy
);
2496 if (prefix
[0] != '\0')
2503 int need_new_ent
= 1;
2504 int plen
= get_prefix_len (prefix
);
2505 struct string_entry
*sent
;
2507 at_end
= (prefix
[plen
] == '\0');
2508 prefix
[plen
] = '\0';
2509 sent
= insert_string (prefix
);
2511 while (*ptr
!= NULL
)
2513 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2522 ptr
= &((*ptr
)->alternative
);
2527 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2529 nent
->parent
= parent
;
2530 nent
->addl_entries
= NULL
;
2531 nent
->alternative
= *ptr
;
2533 nent
->is_terminal
= 0;
2534 nent
->dependencies
= -1;
2540 ptr
= &((*ptr
)->addl_entries
);
2545 if ((*ptr
)->is_terminal
)
2550 (*ptr
)->is_terminal
= 1;
2551 (*ptr
)->mask
= (ia64_insn
)-1;
2552 (*ptr
)->bits
= opc
->opcode
;
2554 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2555 (*ptr
)->order
= order
;
2559 print_completer_entry (ent
)
2560 struct completer_entry
*ent
;
2563 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2567 while (! (mask
& 1))
2573 if (bits
& 0xffffffff00000000LL
)
2579 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2583 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2584 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2586 ent
->is_terminal
? 1 : 0,
2591 print_completer_table ()
2595 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2596 for (x
= 0; x
< glistlen
; x
++)
2598 print_completer_entry (glist
[x
]);
2604 opcodes_eq (opc1
, opc2
)
2605 struct ia64_opcode
*opc1
;
2606 struct ia64_opcode
*opc2
;
2611 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2612 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2613 || (opc1
->flags
!= opc2
->flags
))
2617 for (x
= 0; x
< 5; x
++)
2619 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2624 plen1
= get_prefix_len (opc1
->name
);
2625 plen2
= get_prefix_len (opc2
->name
);
2626 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2634 add_opcode_entry (opc
)
2635 struct ia64_opcode
*opc
;
2637 struct main_entry
**place
;
2638 struct string_entry
*name
;
2642 if (strlen (opc
->name
) > 128)
2647 strcpy (prefix
, opc
->name
);
2648 prefix
[get_prefix_len (prefix
)] = '\0';
2649 name
= insert_string (prefix
);
2651 /* Walk the list of opcode table entries. If it's a new
2652 instruction, allocate and fill in a new entry. Note
2653 the main table is alphabetical by opcode name. */
2655 while (*place
!= NULL
)
2657 if ((*place
)->name
->num
== name
->num
2658 && opcodes_eq ((*place
)->opcode
, opc
))
2663 if ((*place
)->name
->num
> name
->num
)
2667 place
= &((*place
)->next
);
2671 struct main_entry
*nent
= tmalloc (struct main_entry
);
2675 nent
->next
= *place
;
2676 nent
->completers
= 0;
2679 if (otlen
== ottotlen
)
2682 ordered_table
= (struct main_entry
**)
2683 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2685 ordered_table
[otlen
++] = nent
;
2687 insert_completer_entry (opc
, *place
, opcode_count
++);
2693 struct main_entry
*ptr
= maintable
;
2696 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2699 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2702 ptr
->opcode
->num_outputs
,
2703 ptr
->opcode
->opcode
,
2705 ptr
->opcode
->operands
[0],
2706 ptr
->opcode
->operands
[1],
2707 ptr
->opcode
->operands
[2],
2708 ptr
->opcode
->operands
[3],
2709 ptr
->opcode
->operands
[4],
2711 ptr
->completers
->num
);
2713 ptr
->main_index
= index
++;
2722 struct ia64_opcode
*table
;
2726 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2728 add_opcode_entry (table
+ curr_opcode
);
2733 main (int argc
, char **argv
)
2740 load_insn_classes();
2741 load_dependencies();
2743 shrink (ia64_opcodes_a
);
2744 shrink (ia64_opcodes_b
);
2745 shrink (ia64_opcodes_f
);
2746 shrink (ia64_opcodes_i
);
2747 shrink (ia64_opcodes_m
);
2748 shrink (ia64_opcodes_x
);
2749 shrink (ia64_opcodes_d
);
2751 collapse_redundant_completers ();
2753 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2754 print_string_table ();
2755 print_dependency_table ();
2756 print_completer_table ();
2757 print_main_table ();
2759 generate_disassembler ();