1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright (C) 1999-2024 Free Software Foundation, Inc.
3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 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, 51 Franklin Street - Fifth Floor, Boston, MA
23 /* While the ia64-opc-* set of opcode tables are easy to maintain,
24 they waste a tremendous amount of space. ia64-gen rearranges the
25 instructions into a directed acyclic graph (DAG) of instruction opcodes and
26 their possible completers, as well as compacting the set of strings used.
28 The disassembler table consists of a state machine that does
29 branching based on the bits of the opcode being disassembled. The
30 state encodings have been chosen to minimize the amount of space
33 The resource table is constructed based on some text dependency tables,
34 which are also easier to maintain than the final representation. */
41 #include "libiberty.h"
42 #include "safe-ctype.h"
45 #include "ia64-opc-a.c"
46 #include "ia64-opc-i.c"
47 #include "ia64-opc-m.c"
48 #include "ia64-opc-b.c"
49 #include "ia64-opc-f.c"
50 #include "ia64-opc-x.c"
51 #include "ia64-opc-d.c"
54 #define _(String) gettext (String)
56 const char * program_name
= NULL
;
59 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
60 #define tmalloc(X) (X *) xmalloc (sizeof (X))
62 typedef unsigned long long ci_t
;
63 /* The main opcode table entry. Each entry is a unique combination of
64 name and flags (no two entries in the table compare as being equal
68 /* The base name of this opcode. The names of its completers are
69 appended to it to generate the full instruction name. */
70 struct string_entry
*name
;
71 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
72 it uses the first one passed to add_opcode_entry. */
73 struct ia64_opcode
*opcode
;
74 /* The list of completers that can be applied to this opcode. */
75 struct completer_entry
*completers
;
76 /* Next entry in the chain. */
77 struct main_entry
*next
;
78 /* Index in the main table. */
80 } *maintable
, **ordered_table
;
86 /* The set of possible completers for an opcode. */
87 struct completer_entry
89 /* This entry's index in the ia64_completer_table[] array. */
92 /* The name of the completer. */
93 struct string_entry
*name
;
95 /* This entry's parent. */
96 struct completer_entry
*parent
;
98 /* Set if this is a terminal completer (occurs at the end of an
102 /* An alternative completer. */
103 struct completer_entry
*alternative
;
105 /* Additional completers that can be appended to this one. */
106 struct completer_entry
*addl_entries
;
108 /* Before compute_completer_bits () is invoked, this contains the actual
109 instruction opcode for this combination of opcode and completers.
110 Afterwards, it contains those bits that are different from its
114 /* Bits set to 1 correspond to those bits in this completer's opcode
115 that are different from its parent completer's opcode (or from
116 the base opcode if the entry is the root of the opcode's completer
117 list). This field is filled in by compute_completer_bits (). */
120 /* Index into the opcode dependency list, or -1 if none. */
123 /* Remember the order encountered in the opcode tables. */
127 /* One entry in the disassembler name table. */
130 /* The index into the ia64_name_dis array for this entry. */
133 /* The index into the main_table[] array. */
136 /* The disassmbly priority of this entry. */
139 /* The completer_index value for this entry. */
140 ci_t completer_index
;
142 /* How many other entries share this decode. */
145 /* The next entry sharing the same decode. */
146 struct disent
*nexte
;
148 /* The next entry in the name list. */
149 struct disent
*next_ent
;
150 } *disinsntable
= NULL
;
152 /* A state machine that will eventually be used to generate the
153 disassembler table. */
156 struct disent
*disent
;
157 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
162 /* The string table contains all opcodes and completers sorted in
163 alphabetical order. */
165 /* One entry in the string table. */
168 /* The index in the ia64_strings[] array for this entry. */
170 /* And the string. */
172 } **string_table
= NULL
;
175 int strtabtotlen
= 0;
178 /* Resource dependency entries. */
181 char *name
; /* Resource name. */
183 mode
:2, /* RAW, WAW, or WAR. */
184 semantics
:3; /* Dependency semantics. */
185 char *extra
; /* Additional semantics info. */
187 int total_chks
; /* Total #of terminal insns. */
188 int *chks
; /* Insn classes which read (RAW), write
189 (WAW), or write (WAR) this rsrc. */
190 int *chknotes
; /* Dependency notes for each class. */
192 int total_regs
; /* Total #of terminal insns. */
193 int *regs
; /* Insn class which write (RAW), write2
194 (WAW), or read (WAR) this rsrc. */
195 int *regnotes
; /* Dependency notes for each class. */
197 int waw_special
; /* Special WAW dependency note. */
200 static int rdepslen
= 0;
201 static int rdepstotlen
= 0;
203 /* Array of all instruction classes. */
206 char *name
; /* Instruction class name. */
207 int is_class
; /* Is a class, not a terminal. */
209 int *subs
; /* Other classes within this class. */
211 int xsubs
[4]; /* Exclusions. */
212 char *comment
; /* Optional comment. */
213 int note
; /* Optional note. */
214 int terminal_resolved
; /* Did we match this with anything? */
215 int orphan
; /* Detect class orphans. */
218 static int iclen
= 0;
219 static int ictotlen
= 0;
221 /* An opcode dependency (chk/reg pair of dependency lists). */
224 int chk
; /* index into dlists */
225 int reg
; /* index into dlists */
228 static int opdeplen
= 0;
229 static int opdeptotlen
= 0;
231 /* A generic list of dependencies w/notes encoded. These may be shared. */
235 unsigned short *deps
;
238 static int dlistlen
= 0;
239 static int dlisttotlen
= 0;
242 static void fail (const char *, ...) ATTRIBUTE_PRINTF_1
;
243 static void warn (const char *, ...) ATTRIBUTE_PRINTF_1
;
244 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
245 static int deplist_equals (struct deplist
*, struct deplist
*);
246 static short insert_deplist (int, unsigned short *);
247 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
248 static void mark_used (struct iclass
*, int);
249 static int fetch_insn_class (const char *, int);
250 static int sub_compare (const void *, const void *);
251 static void load_insn_classes (void);
252 static void parse_resource_users (const char *, int **, int *, int **);
253 static int parse_semantics (char *);
254 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
255 static void load_depfile (const char *, enum ia64_dependency_mode
);
256 static void load_dependencies (void);
257 static int irf_operand (int, const char *);
258 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
259 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
260 static int lookup_regindex (const char *, int);
261 static int lookup_specifier (const char *);
262 static void print_dependency_table (void);
263 static struct string_entry
* insert_string (char *);
264 static void gen_dis_table (struct bittree
*);
265 static void print_dis_table (void);
266 static void generate_disassembler (void);
267 static void print_string_table (void);
268 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
269 static struct completer_entry
* insert_gclist (struct completer_entry
*);
270 static int get_prefix_len (const char *);
271 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
272 static void collapse_redundant_completers (void);
273 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
274 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
275 static void print_completer_entry (struct completer_entry
*);
276 static void print_completer_table (void);
277 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
278 static void add_opcode_entry (struct ia64_opcode
*);
279 static void print_main_table (void);
280 static void shrink (struct ia64_opcode
*);
281 static void print_version (void);
282 static void usage (FILE *, int);
283 static void finish_distable (void);
284 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, ci_t
);
285 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, ci_t
);
286 static void compact_distree (struct bittree
*);
287 static struct bittree
* make_bittree_entry (void);
288 static struct disent
* add_dis_table_ent (struct disent
*, int, int, ci_t
);
292 fail (const char *message
, ...)
296 va_start (args
, message
);
297 fprintf (stderr
, _("%s: Error: "), program_name
);
298 vfprintf (stderr
, message
, args
);
304 warn (const char *message
, ...)
308 va_start (args
, message
);
310 fprintf (stderr
, _("%s: Warning: "), program_name
);
311 vfprintf (stderr
, message
, args
);
315 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
317 insert_resource (const char *name
, enum ia64_dependency_mode type
)
319 if (rdepslen
== rdepstotlen
)
322 rdeps
= (struct rdep
**)
323 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
325 rdeps
[rdepslen
] = tmalloc(struct rdep
);
326 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
327 rdeps
[rdepslen
]->name
= xstrdup (name
);
328 rdeps
[rdepslen
]->mode
= type
;
329 rdeps
[rdepslen
]->waw_special
= 0;
331 return rdeps
[rdepslen
++];
334 /* Are the lists of dependency indexes equivalent? */
336 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
340 if (d1
->len
!= d2
->len
)
343 for (i
= 0; i
< d1
->len
; i
++)
344 if (d1
->deps
[i
] != d2
->deps
[i
])
350 /* Add the list of dependencies to the list of dependency lists. */
352 insert_deplist (int count
, unsigned short *deps
)
354 /* Sort the list, then see if an equivalent list exists already.
355 this results in a much smaller set of dependency lists. */
356 struct deplist
*list
;
360 memset ((void *)set
, 0, sizeof (set
));
361 for (i
= 0; i
< count
; i
++)
365 for (i
= 0; i
< (int) sizeof (set
); i
++)
369 list
= tmalloc (struct deplist
);
371 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
373 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
375 list
->deps
[count
++] = i
;
377 /* Does this list exist already? */
378 for (i
= 0; i
< dlistlen
; i
++)
379 if (deplist_equals (list
, dlists
[i
]))
386 if (dlistlen
== dlisttotlen
)
389 dlists
= (struct deplist
**)
390 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
392 dlists
[dlistlen
] = list
;
397 /* Add the given pair of dependency lists to the opcode dependency list. */
399 insert_dependencies (int nchks
, unsigned short *chks
,
400 int nregs
, unsigned short *regs
)
408 regind
= insert_deplist (nregs
, regs
);
410 chkind
= insert_deplist (nchks
, chks
);
412 for (i
= 0; i
< opdeplen
; i
++)
413 if (opdeps
[i
]->chk
== chkind
414 && opdeps
[i
]->reg
== regind
)
417 pair
= tmalloc (struct opdep
);
421 if (opdeplen
== opdeptotlen
)
424 opdeps
= (struct opdep
**)
425 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
427 opdeps
[opdeplen
] = pair
;
433 mark_used (struct iclass
*ic
, int clear_terminals
)
439 ic
->terminal_resolved
= 1;
441 for (i
= 0; i
< ic
->nsubs
; i
++)
442 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
444 for (i
= 0; i
< ic
->nxsubs
; i
++)
445 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
448 /* Look up an instruction class; if CREATE make a new one if none found;
449 returns the index into the insn class array. */
451 fetch_insn_class (const char *full_name
, int create
)
461 if (startswith (full_name
, "IC:"))
463 name
= xstrdup (full_name
+ 3);
467 name
= xstrdup (full_name
);
469 if ((xsect
= strchr(name
, '\\')) != NULL
)
471 if ((comment
= strchr(name
, '[')) != NULL
)
473 if ((notestr
= strchr(name
, '+')) != NULL
)
476 /* If it is a composite class, then ignore comments and notes that come after
477 the '\\', since they don't apply to the part we are decoding now. */
490 note
= atoi (notestr
+ 1);
491 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
493 if (strcmp (notestr
, "+1+13") == 0)
495 else if (!xsect
|| nextnotestr
< xsect
)
496 warn (_("multiple note %s not handled\n"), notestr
);
500 /* If it's a composite class, leave the notes and comments in place so that
501 we have a unique name for the composite class. Otherwise, we remove
511 for (i
= 0; i
< iclen
; i
++)
512 if (strcmp (name
, ics
[i
]->name
) == 0
513 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
514 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
515 && strncmp (ics
[i
]->comment
, comment
,
516 strlen (ics
[i
]->comment
)) == 0))
517 && note
== ics
[i
]->note
)
523 /* Doesn't exist, so make a new one. */
524 if (iclen
== ictotlen
)
527 ics
= (struct iclass
**)
528 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
532 ics
[ind
] = tmalloc (struct iclass
);
533 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
534 ics
[ind
]->name
= xstrdup (name
);
535 ics
[ind
]->is_class
= is_class
;
536 ics
[ind
]->orphan
= 1;
540 ics
[ind
]->comment
= xstrdup (comment
+ 1);
541 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
545 ics
[ind
]->note
= note
;
547 /* If it's a composite class, there's a comment or note, look for an
548 existing class or terminal with the same name. */
549 if ((xsect
|| comment
|| notestr
) && is_class
)
551 /* First, populate with the class we're based on. */
552 char *subname
= name
;
562 ics
[ind
]->subs
= tmalloc(int);
563 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);
568 char *subname
= xsect
+ 1;
570 xsect
= strchr (subname
, '\\');
573 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
581 /* For sorting a class's sub-class list only; make sure classes appear before
584 sub_compare (const void *e1
, const void *e2
)
586 struct iclass
*ic1
= ics
[*(int *)e1
];
587 struct iclass
*ic2
= ics
[*(int *)e2
];
594 else if (ic2
->is_class
)
597 return strcmp (ic1
->name
, ic2
->name
);
601 load_insn_classes (void)
603 FILE *fp
= fopen ("ia64-ic.tbl", "r");
607 fail (_("can't find ia64-ic.tbl for reading\n"));
609 /* Discard first line. */
610 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
619 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
622 while (ISSPACE (buf
[strlen (buf
) - 1]))
623 buf
[strlen (buf
) - 1] = '\0';
629 if (tmp
== buf
+ sizeof (buf
))
634 iclass
= fetch_insn_class (name
, 1);
635 ics
[iclass
]->is_class
= 1;
637 if (strcmp (name
, "none") == 0)
639 ics
[iclass
]->is_class
= 0;
640 ics
[iclass
]->terminal_resolved
= 1;
644 /* For this class, record all sub-classes. */
650 while (*tmp
&& ISSPACE (*tmp
))
653 if (tmp
== buf
+ sizeof (buf
))
657 while (*tmp
&& *tmp
!= ',')
660 if (tmp
== buf
+ sizeof (buf
))
666 ics
[iclass
]->subs
= (int *)
667 xrealloc ((void *)ics
[iclass
]->subs
,
668 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
670 sub
= fetch_insn_class (subname
, 1);
671 ics
[iclass
]->subs
= (int *)
672 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
673 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
676 /* Make sure classes come before terminals. */
677 qsort ((void *)ics
[iclass
]->subs
,
678 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
683 printf ("%d classes\n", iclen
);
686 /* Extract the insn classes from the given line. */
688 parse_resource_users (const char *ref
, int **usersp
, int *nusersp
,
692 char *line
= xstrdup (ref
);
694 int *users
= *usersp
;
695 int count
= *nusersp
;
696 int *notes
= *notesp
;
708 while (ISSPACE (*tmp
))
711 while (*tmp
&& *tmp
!= ',')
716 xsect
= strchr (name
, '\\');
717 if ((notestr
= strstr (name
, "+")) != NULL
)
721 note
= atoi (notestr
+ 1);
722 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
724 /* Note 13 always implies note 1. */
725 if (strcmp (notestr
, "+1+13") == 0)
727 else if (!xsect
|| nextnotestr
< xsect
)
728 warn (_("multiple note %s not handled\n"), notestr
);
736 /* All classes are created when the insn class table is parsed;
737 Individual instructions might not appear until the dependency tables
738 are read. Only create new classes if it's *not* an insn class,
739 or if it's a composite class (which wouldn't necessarily be in the IC
741 if (! startswith (name
, "IC:") || xsect
!= NULL
)
744 iclass
= fetch_insn_class (name
, create
);
748 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
750 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
752 users
[count
++] = iclass
;
753 mark_used (ics
[iclass
], 0);
756 printf("Class %s not found\n", name
);
758 /* Update the return values. */
767 parse_semantics (char *sem
)
769 if (strcmp (sem
, "none") == 0)
770 return IA64_DVS_NONE
;
771 else if (strcmp (sem
, "implied") == 0)
772 return IA64_DVS_IMPLIED
;
773 else if (strcmp (sem
, "impliedF") == 0)
774 return IA64_DVS_IMPLIEDF
;
775 else if (strcmp (sem
, "data") == 0)
776 return IA64_DVS_DATA
;
777 else if (strcmp (sem
, "instr") == 0)
778 return IA64_DVS_INSTR
;
779 else if (strcmp (sem
, "specific") == 0)
780 return IA64_DVS_SPECIFIC
;
781 else if (strcmp (sem
, "stop") == 0)
782 return IA64_DVS_STOP
;
784 return IA64_DVS_OTHER
;
788 add_dep (const char *name
, const char *chk
, const char *reg
,
789 int semantics
, int mode
, char *extra
, int flag
)
793 rs
= insert_resource (name
, mode
);
795 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
796 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
798 rs
->semantics
= semantics
;
800 rs
->waw_special
= flag
;
804 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
806 FILE *fp
= fopen (filename
, "r");
810 fail (_("can't find %s for reading\n"), filename
);
812 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
821 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
824 while (ISSPACE (buf
[strlen (buf
) - 1]))
825 buf
[strlen (buf
) - 1] = '\0';
832 while (ISSPACE (*tmp
))
835 tmp
= strchr (tmp
, ';');
839 while (ISSPACE (*tmp
))
842 tmp
= strchr (tmp
, ';');
846 while (ISSPACE (*tmp
))
848 semantics
= parse_semantics (tmp
);
849 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
851 /* For WAW entries, if the chks and regs differ, we need to enter the
852 entries in both positions so that the tables will be parsed properly,
853 without a lot of extra work. */
854 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
856 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
857 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
861 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
868 load_dependencies (void)
870 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
871 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
872 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
875 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
878 /* Is the given operand an indirect register file operand? */
880 irf_operand (int op
, const char *field
)
884 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
885 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
886 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
887 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
891 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
892 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
893 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
894 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
895 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
896 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
897 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
898 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid"))
899 || (op
== IA64_OPND_DAHR_R3
&& strstr (field
, "dahr")));
903 /* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
904 * mov_psr, and mov_um insn classes. */
906 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
907 const char *format
, const char *field
)
909 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
920 int i
= strcmp (idesc
->name
, "mov.i") == 0;
921 int m
= strcmp (idesc
->name
, "mov.m") == 0;
922 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
923 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
924 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
925 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
926 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
927 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
931 return strstr (format
, "I26") || strstr (format
, "I27");
933 return strstr (format
, "I28") != NULL
;
935 return strstr (format
, "M29") || strstr (format
, "M30");
937 return strstr (format
, "M31") != NULL
;
938 if (pseudo0
|| pseudo1
)
944 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
945 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
947 return strstr (format
, "I22") != NULL
;
949 return strstr (format
, "I21") != NULL
;
954 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
955 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
957 return strstr (format
, "M32") != NULL
;
959 return strstr (format
, "M33") != NULL
;
964 int m50
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_DAHR3
;
966 return strstr (format
, "M50") != NULL
;
970 if (ic
->name
[5] == 'n')
972 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
973 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
975 return strstr (format
, "M42") != NULL
;
977 return strstr (format
, "M43") != NULL
;
979 else if (ic
->name
[5] == 'p')
981 return idesc
->operands
[1] == IA64_OPND_IP
;
987 if (ic
->name
[5] == 'r')
989 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
990 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
991 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
993 return strstr (format
, "I23") != NULL
;
995 return strstr (format
, "I24") != NULL
;
997 return strstr (format
, "I25") != NULL
;
999 else if (ic
->name
[5] == 's')
1001 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1002 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1004 return strstr (format
, "M35") != NULL
;
1006 return strstr (format
, "M36") != NULL
;
1013 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1014 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1016 return strstr (format
, "M35") != NULL
;
1018 return strstr (format
, "M36") != NULL
;
1025 /* Is the given opcode in the given insn class? */
1027 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1028 const char *format
, const char *field
, int *notep
)
1035 if (startswith (ic
->comment
, "Format"))
1037 /* Assume that the first format seen is the most restrictive, and
1038 only keep a later one if it looks like it's more restrictive. */
1041 if (strlen (ic
->comment
) < strlen (format
))
1043 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1044 ic
->comment
, format
);
1045 format
= ic
->comment
;
1049 format
= ic
->comment
;
1051 else if (startswith (ic
->comment
, "Field"))
1054 warn (_("overlapping field %s->%s\n"),
1055 ic
->comment
, field
);
1056 field
= ic
->comment
;
1060 /* An insn class matches anything that is the same followed by completers,
1061 except when the absence and presence of completers constitutes different
1063 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1065 int is_mov
= startswith (idesc
->name
, "mov");
1066 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1067 int len
= strlen(ic
->name
);
1069 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1070 && (idesc
->name
[len
] == '\0'
1071 || idesc
->name
[len
] == '.'));
1073 /* All break, nop, and hint variations must match exactly. */
1075 (strcmp (ic
->name
, "break") == 0
1076 || strcmp (ic
->name
, "nop") == 0
1077 || strcmp (ic
->name
, "hint") == 0))
1078 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1080 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1081 unless specifically allowed by clauses in this block. */
1082 if (resolved
&& field
)
1084 /* Check Field(sf)==sN against opcode sN. */
1085 if (strstr(field
, "(sf)==") != NULL
)
1089 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1090 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1092 /* Check Field(lftype)==XXX. */
1093 else if (strstr (field
, "(lftype)") != NULL
)
1095 if (strstr (idesc
->name
, "fault") != NULL
)
1096 resolved
= strstr (field
, "fault") != NULL
;
1098 resolved
= strstr (field
, "fault") == NULL
;
1100 /* Handle Field(ctype)==XXX. */
1101 else if (strstr (field
, "(ctype)") != NULL
)
1103 if (strstr (idesc
->name
, "or.andcm"))
1104 resolved
= strstr (field
, "or.andcm") != NULL
;
1105 else if (strstr (idesc
->name
, "and.orcm"))
1106 resolved
= strstr (field
, "and.orcm") != NULL
;
1107 else if (strstr (idesc
->name
, "orcm"))
1108 resolved
= strstr (field
, "or orcm") != NULL
;
1109 else if (strstr (idesc
->name
, "or"))
1110 resolved
= strstr (field
, "or orcm") != NULL
;
1111 else if (strstr (idesc
->name
, "andcm"))
1112 resolved
= strstr (field
, "and andcm") != NULL
;
1113 else if (strstr (idesc
->name
, "and"))
1114 resolved
= strstr (field
, "and andcm") != NULL
;
1115 else if (strstr (idesc
->name
, "unc"))
1116 resolved
= strstr (field
, "unc") != NULL
;
1118 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1122 if (resolved
&& format
)
1124 if (startswith (idesc
->name
, "dep")
1125 && strstr (format
, "I13") != NULL
)
1126 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1127 else if (startswith (idesc
->name
, "chk")
1128 && strstr (format
, "M21") != NULL
)
1129 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1130 else if (startswith (idesc
->name
, "lfetch"))
1131 resolved
= (strstr (format
, "M14 M15") != NULL
1132 && (idesc
->operands
[1] == IA64_OPND_R2
1133 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1134 else if (startswith (idesc
->name
, "br.call")
1135 && strstr (format
, "B5") != NULL
)
1136 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1137 else if (startswith (idesc
->name
, "br.call")
1138 && strstr (format
, "B3") != NULL
)
1139 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1140 else if (startswith (idesc
->name
, "brp")
1141 && strstr (format
, "B7") != NULL
)
1142 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1143 else if (strcmp (ic
->name
, "invala") == 0)
1144 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1145 else if (startswith (idesc
->name
, "st")
1146 && (strstr (format
, "M5") != NULL
1147 || strstr (format
, "M10") != NULL
))
1148 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1149 else if (startswith (idesc
->name
, "ld")
1150 && (strstr (format
, "M2 M3") != NULL
1151 || strstr (format
, "M12") != NULL
1152 || strstr (format
, "M7 M8") != NULL
))
1153 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1158 /* Misc brl variations ('.cond' is optional);
1159 plain brl matches brl.cond. */
1161 && (strcmp (idesc
->name
, "brl") == 0
1162 || startswith (idesc
->name
, "brl."))
1163 && strcmp (ic
->name
, "brl.cond") == 0)
1168 /* Misc br variations ('.cond' is optional). */
1170 && (strcmp (idesc
->name
, "br") == 0
1171 || startswith (idesc
->name
, "br."))
1172 && strcmp (ic
->name
, "br.cond") == 0)
1175 resolved
= (strstr (format
, "B4") != NULL
1176 && idesc
->operands
[0] == IA64_OPND_B2
)
1177 || (strstr (format
, "B1") != NULL
1178 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1183 /* probe variations. */
1184 if (!resolved
&& startswith (idesc
->name
, "probe"))
1186 resolved
= strcmp (ic
->name
, "probe") == 0
1187 && !((strstr (idesc
->name
, "fault") != NULL
)
1188 ^ (format
&& strstr (format
, "M40") != NULL
));
1191 /* mov variations. */
1192 if (!resolved
&& is_mov
)
1196 /* mov alias for fmerge. */
1197 if (strcmp (ic
->name
, "fmerge") == 0)
1199 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1200 && idesc
->operands
[1] == IA64_OPND_F3
;
1202 /* mov alias for adds (r3 or imm14). */
1203 else if (strcmp (ic
->name
, "adds") == 0)
1205 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1206 && (idesc
->operands
[1] == IA64_OPND_R3
1207 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1209 /* mov alias for addl. */
1210 else if (strcmp (ic
->name
, "addl") == 0)
1212 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1213 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1217 /* Some variants of mov and mov.[im]. */
1218 if (!resolved
&& startswith (ic
->name
, "mov_"))
1219 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1222 /* Keep track of this so we can flag any insn classes which aren't
1223 mapped onto at least one real insn. */
1225 ic
->terminal_resolved
= 1;
1227 else for (i
= 0; i
< ic
->nsubs
; i
++)
1229 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1233 for (j
= 0; j
< ic
->nxsubs
; j
++)
1234 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1238 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1245 /* If it's in this IC, add the IC note (if any) to the insn. */
1248 if (ic
->note
&& notep
)
1250 if (*notep
&& *notep
!= ic
->note
)
1251 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1252 *notep
, ic
->note
, ic
->name
);
1263 lookup_regindex (const char *name
, int specifier
)
1268 if (strstr (name
, "[RSC]"))
1270 if (strstr (name
, "[BSP]"))
1272 else if (strstr (name
, "[BSPSTORE]"))
1274 else if (strstr (name
, "[RNAT]"))
1276 else if (strstr (name
, "[FCR]"))
1278 else if (strstr (name
, "[EFLAG]"))
1280 else if (strstr (name
, "[CSD]"))
1282 else if (strstr (name
, "[SSD]"))
1284 else if (strstr (name
, "[CFLG]"))
1286 else if (strstr (name
, "[FSR]"))
1288 else if (strstr (name
, "[FIR]"))
1290 else if (strstr (name
, "[FDR]"))
1292 else if (strstr (name
, "[CCV]"))
1294 else if (strstr (name
, "[ITC]"))
1296 else if (strstr (name
, "[RUC]"))
1298 else if (strstr (name
, "[PFS]"))
1300 else if (strstr (name
, "[LC]"))
1302 else if (strstr (name
, "[EC]"))
1306 if (strstr (name
, "[DCR]"))
1308 else if (strstr (name
, "[ITM]"))
1310 else if (strstr (name
, "[IVA]"))
1312 else if (strstr (name
, "[PTA]"))
1314 else if (strstr (name
, "[GPTA]"))
1316 else if (strstr (name
, "[IPSR]"))
1318 else if (strstr (name
, "[ISR]"))
1320 else if (strstr (name
, "[IIP]"))
1322 else if (strstr (name
, "[IFA]"))
1324 else if (strstr (name
, "[ITIR]"))
1326 else if (strstr (name
, "[IIPA]"))
1328 else if (strstr (name
, "[IFS]"))
1330 else if (strstr (name
, "[IIM]"))
1332 else if (strstr (name
, "[IHA]"))
1334 else if (strstr (name
, "[LID]"))
1336 else if (strstr (name
, "[IVR]"))
1338 else if (strstr (name
, "[TPR]"))
1340 else if (strstr (name
, "[EOI]"))
1342 else if (strstr (name
, "[ITV]"))
1344 else if (strstr (name
, "[PMV]"))
1346 else if (strstr (name
, "[CMCV]"))
1350 if (strstr (name
, ".be"))
1352 else if (strstr (name
, ".up"))
1354 else if (strstr (name
, ".ac"))
1356 else if (strstr (name
, ".mfl"))
1358 else if (strstr (name
, ".mfh"))
1360 else if (strstr (name
, ".ic"))
1362 else if (strstr (name
, ".i"))
1364 else if (strstr (name
, ".pk"))
1366 else if (strstr (name
, ".dt"))
1368 else if (strstr (name
, ".dfl"))
1370 else if (strstr (name
, ".dfh"))
1372 else if (strstr (name
, ".sp"))
1374 else if (strstr (name
, ".pp"))
1376 else if (strstr (name
, ".di"))
1378 else if (strstr (name
, ".si"))
1380 else if (strstr (name
, ".db"))
1382 else if (strstr (name
, ".lp"))
1384 else if (strstr (name
, ".tb"))
1386 else if (strstr (name
, ".rt"))
1388 else if (strstr (name
, ".cpl"))
1390 else if (strstr (name
, ".rs"))
1392 else if (strstr (name
, ".mc"))
1394 else if (strstr (name
, ".it"))
1396 else if (strstr (name
, ".id"))
1398 else if (strstr (name
, ".da"))
1400 else if (strstr (name
, ".dd"))
1402 else if (strstr (name
, ".ss"))
1404 else if (strstr (name
, ".ri"))
1406 else if (strstr (name
, ".ed"))
1408 else if (strstr (name
, ".bn"))
1410 else if (strstr (name
, ".ia"))
1412 else if (strstr (name
, ".vm"))
1423 lookup_specifier (const char *name
)
1425 if (strchr (name
, '%'))
1427 if (strstr (name
, "AR[K%]") != NULL
)
1428 return IA64_RS_AR_K
;
1429 if (strstr (name
, "AR[UNAT]") != NULL
)
1430 return IA64_RS_AR_UNAT
;
1431 if (strstr (name
, "AR%, % in 8") != NULL
)
1433 if (strstr (name
, "AR%, % in 48") != NULL
)
1435 if (strstr (name
, "BR%") != NULL
)
1437 if (strstr (name
, "CR[IIB%]") != NULL
)
1438 return IA64_RS_CR_IIB
;
1439 if (strstr (name
, "CR[IRR%]") != NULL
)
1440 return IA64_RS_CR_IRR
;
1441 if (strstr (name
, "CR[LRR%]") != NULL
)
1442 return IA64_RS_CR_LRR
;
1443 if (strstr (name
, "CR%") != NULL
)
1445 if (strstr (name
, "DAHR%, % in 0") != NULL
)
1446 return IA64_RS_DAHR
;
1447 if (strstr (name
, "FR%, % in 0") != NULL
)
1449 if (strstr (name
, "FR%, % in 2") != NULL
)
1451 if (strstr (name
, "GR%") != NULL
)
1453 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1455 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1458 warn (_("don't know how to specify %% dependency %s\n"),
1461 else if (strchr (name
, '#'))
1463 if (strstr (name
, "CPUID#") != NULL
)
1464 return IA64_RS_CPUID
;
1465 if (strstr (name
, "DBR#") != NULL
)
1467 if (strstr (name
, "IBR#") != NULL
)
1469 if (strstr (name
, "MSR#") != NULL
)
1471 if (strstr (name
, "PKR#") != NULL
)
1473 if (strstr (name
, "PMC#") != NULL
)
1475 if (strstr (name
, "PMD#") != NULL
)
1477 if (strstr (name
, "RR#") != NULL
)
1480 warn (_("Don't know how to specify # dependency %s\n"),
1483 else if (startswith (name
, "AR[FPSR]"))
1484 return IA64_RS_AR_FPSR
;
1485 else if (startswith (name
, "AR["))
1487 else if (startswith (name
, "CR["))
1489 else if (startswith (name
, "PSR."))
1491 else if (strcmp (name
, "InService*") == 0)
1492 return IA64_RS_INSERVICE
;
1493 else if (strcmp (name
, "GR0") == 0)
1495 else if (strcmp (name
, "CFM") == 0)
1497 else if (strcmp (name
, "PR63") == 0)
1498 return IA64_RS_PR63
;
1499 else if (strcmp (name
, "RSE") == 0)
1506 print_dependency_table (void)
1512 for (i
=0;i
< iclen
;i
++)
1514 if (ics
[i
]->is_class
)
1518 if (ics
[i
]->comment
)
1519 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1520 ics
[i
]->name
, ics
[i
]->comment
);
1522 warn (_("IC:%s has no terminals or sub-classes\n"),
1528 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1530 if (ics
[i
]->comment
)
1531 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1532 ics
[i
]->name
, ics
[i
]->comment
);
1534 warn (_("no insns mapped directly to terminal IC %s\n"),
1540 for (i
= 0; i
< iclen
; i
++)
1544 mark_used (ics
[i
], 1);
1545 warn (_("class %s is defined but not used\n"),
1551 for (i
= 0; i
< rdepslen
; i
++)
1553 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1555 if (rdeps
[i
]->total_chks
== 0)
1557 if (rdeps
[i
]->total_regs
)
1558 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1559 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1561 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1562 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1564 else if (rdeps
[i
]->total_regs
== 0)
1565 warn (_("rsrc %s (%s) has no regs\n"),
1566 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1570 /* The dependencies themselves. */
1571 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1572 for (i
= 0; i
< rdepslen
; i
++)
1574 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1576 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1577 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1579 printf (" { \"%s\", %d, %d, %d, %d, ",
1580 rdeps
[i
]->name
, specifier
,
1581 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1582 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1584 const char *quote
, *rest
;
1587 rest
= rdeps
[i
]->extra
;
1588 quote
= strchr (rest
, '\"');
1589 while (quote
!= NULL
)
1591 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1593 quote
= strchr (rest
, '\"');
1595 printf ("%s\", ", rest
);
1603 /* And dependency lists. */
1604 for (i
=0;i
< dlistlen
;i
++)
1606 unsigned int len
= (unsigned) -1;
1607 printf ("static const unsigned short dep%d[] = {", i
);
1608 for (j
=0;j
< dlists
[i
]->len
; j
++)
1615 len
+= printf (" %d,", dlists
[i
]->deps
[j
]);
1617 printf ("\n};\n\n");
1620 /* And opcode dependency list. */
1621 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1622 printf ("static const struct ia64_opcode_dependency\n");
1623 printf ("op_dependencies[] = {\n");
1624 for (i
= 0; i
< opdeplen
; i
++)
1627 if (opdeps
[i
]->chk
== -1)
1628 printf ("0, NULL, ");
1630 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1631 if (opdeps
[i
]->reg
== -1)
1632 printf ("0, NULL, ");
1634 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1641 /* Add STR to the string table. */
1642 static struct string_entry
*
1643 insert_string (char *str
)
1645 int start
= 0, end
= strtablen
;
1648 if (strtablen
== strtabtotlen
)
1651 string_table
= (struct string_entry
**)
1652 xrealloc (string_table
,
1653 sizeof (struct string_entry
**) * strtabtotlen
);
1659 string_table
[0] = tmalloc (struct string_entry
);
1660 string_table
[0]->s
= xstrdup (str
);
1661 string_table
[0]->num
= 0;
1662 return string_table
[0];
1665 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1667 else if (strcmp (str
, string_table
[0]->s
) < 0)
1675 i
= (start
+ end
) / 2;
1676 c
= strcmp (str
, string_table
[i
]->s
);
1681 return string_table
[i
];
1690 for (; i
> 0 && i
< strtablen
; i
--)
1691 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1694 for (; i
< strtablen
; i
++)
1695 if (strcmp (str
, string_table
[i
]->s
) < 0)
1698 for (x
= strtablen
- 1; x
>= i
; x
--)
1700 string_table
[x
+ 1] = string_table
[x
];
1701 string_table
[x
+ 1]->num
= x
+ 1;
1704 string_table
[i
] = tmalloc (struct string_entry
);
1705 string_table
[i
]->s
= xstrdup (str
);
1706 string_table
[i
]->num
= i
;
1709 return string_table
[i
];
1712 static struct bittree
*
1713 make_bittree_entry (void)
1715 struct bittree
*res
= tmalloc (struct bittree
);
1718 res
->bits
[0] = NULL
;
1719 res
->bits
[1] = NULL
;
1720 res
->bits
[2] = NULL
;
1722 res
->bits_to_skip
= 0;
1727 static struct disent
*
1728 add_dis_table_ent (struct disent
*which
, int insn
, int order
,
1729 ci_t completer_index
)
1739 while (ent
->nexte
!= NULL
)
1742 ent
= (ent
->nexte
= tmalloc (struct disent
));
1746 ent
= tmalloc (struct disent
);
1747 ent
->next_ent
= disinsntable
;
1754 ent
->priority
= order
;
1756 while (completer_index
!= 1)
1758 ci
= (ci
<< 1) | (completer_index
& 1);
1759 completer_index
>>= 1;
1761 ent
->completer_index
= ci
;
1766 finish_distable (void)
1768 struct disent
*ent
= disinsntable
;
1769 struct disent
*prev
= ent
;
1771 ent
->ournum
= 32768;
1772 while ((ent
= ent
->next_ent
) != NULL
)
1774 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1780 insert_bit_table_ent (struct bittree
*curr_ent
, int bit
, ia64_insn opcode
,
1781 ia64_insn mask
, int opcodenum
, int order
,
1782 ci_t completer_index
)
1786 struct bittree
*next
;
1790 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1793 curr_ent
->disent
= nent
;
1797 m
= ((ia64_insn
) 1) << bit
;
1800 b
= (opcode
& m
) ? 1 : 0;
1804 next
= curr_ent
->bits
[b
];
1807 next
= make_bittree_entry ();
1808 curr_ent
->bits
[b
] = next
;
1810 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1815 add_dis_entry (struct bittree
*first
, ia64_insn opcode
, ia64_insn mask
,
1816 int opcodenum
, struct completer_entry
*ent
, ci_t completer_index
)
1818 if (completer_index
& ((ci_t
)1 << 32) )
1823 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1824 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1825 (completer_index
<< 1) | 1);
1827 if (ent
->is_terminal
)
1829 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1830 opcodenum
, opcode_count
- ent
->order
- 1,
1831 (completer_index
<< 1) | 1);
1833 completer_index
<<= 1;
1834 ent
= ent
->alternative
;
1838 /* This optimization pass combines multiple "don't care" nodes. */
1840 compact_distree (struct bittree
*ent
)
1842 #define IS_SKIP(ent) \
1843 ((ent->bits[2] !=NULL) \
1844 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1847 struct bittree
*nent
= ent
;
1850 while (IS_SKIP (nent
))
1853 nent
= nent
->bits
[2];
1858 struct bittree
*next
= ent
->bits
[2];
1860 ent
->bits
[0] = nent
->bits
[0];
1861 ent
->bits
[1] = nent
->bits
[1];
1862 ent
->bits
[2] = nent
->bits
[2];
1863 ent
->disent
= nent
->disent
;
1865 ent
->bits_to_skip
= bitcnt
;
1866 while (next
!= nent
)
1868 struct bittree
*b
= next
;
1869 next
= next
->bits
[2];
1875 for (x
= 0; x
< 3; x
++)
1877 struct bittree
*i
= ent
->bits
[x
];
1880 compact_distree (i
);
1884 static unsigned char *insn_list
;
1885 static int insn_list_len
= 0;
1886 static int tot_insn_list_len
= 0;
1888 /* Generate the disassembler state machine corresponding to the tree
1891 gen_dis_table (struct bittree
*ent
)
1894 int our_offset
= insn_list_len
;
1896 int totbits
= bitsused
;
1899 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1901 /* If this is a terminal entry, there's no point in skipping any
1903 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1904 ent
->bits
[2] == NULL
)
1906 if (ent
->disent
== NULL
)
1912 /* Calculate the amount of space needed for this entry, or at least
1913 a conservatively large approximation. */
1917 for (x
= 1; x
< 3; x
++)
1918 if (ent
->bits
[x
] != NULL
)
1921 if (ent
->disent
!= NULL
)
1923 if (ent
->bits
[2] != NULL
)
1929 /* Now allocate the space. */
1930 needed_bytes
= (totbits
+ 7) / 8;
1931 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1933 tot_insn_list_len
+= 256;
1934 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1936 our_offset
= insn_list_len
;
1937 insn_list_len
+= needed_bytes
;
1938 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1940 /* Encode the skip entry by setting bit 6 set in the state op field,
1941 and store the # of bits to skip immediately after. */
1945 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1946 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1949 #define IS_ONLY_IFZERO(ENT) \
1950 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1951 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1953 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1955 if (ent
->bits
[0] != NULL
)
1957 struct bittree
*nent
= ent
->bits
[0];
1960 insn_list
[our_offset
] |= 0x80;
1962 /* We can encode sequences of multiple "if (bit is zero)" tests
1963 by storing the # of zero bits to check in the lower 3 bits of
1964 the instruction. However, this only applies if the state
1965 solely tests for a zero bit. */
1967 if (IS_ONLY_IFZERO (ent
))
1969 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1971 nent
= nent
->bits
[0];
1975 insn_list
[our_offset
+ 0] |= zero_count
;
1977 zero_dest
= insn_list_len
;
1978 gen_dis_table (nent
);
1981 /* Now store the remaining tests. We also handle a sole "termination
1982 entry" by storing it as an "any bit" test. */
1984 for (x
= 1; x
< 3; x
++)
1986 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1988 struct bittree
*i
= ent
->bits
[x
];
1994 /* If the instruction being branched to only consists of
1995 a termination entry, use the termination entry as the
1996 place to branch to instead. */
1997 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1998 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
2000 idest
= i
->disent
->ournum
;
2004 idest
= insn_list_len
- our_offset
;
2007 idest
= ent
->disent
->ournum
;
2009 /* If the destination offset for the if (bit is 1) test is less
2010 than 256 bytes away, we can store it as 8-bits instead of 16;
2011 the instruction has bit 5 set for the 16-bit address, and bit
2012 4 for the 8-bit address. Since we've already allocated 16
2013 bits for the address we need to deallocate the space.
2015 Note that branchings within the table are relative, and
2016 there are no branches that branch past our instruction yet
2017 so we do not need to adjust any other offsets. */
2022 int start
= our_offset
+ bitsused
/ 8 + 1;
2024 memmove (insn_list
+ start
,
2025 insn_list
+ start
+ 1,
2026 insn_list_len
- (start
+ 1));
2031 insn_list
[our_offset
] |= 0x10;
2035 insn_list
[our_offset
] |= 0x20;
2039 /* An instruction which solely consists of a termination
2040 marker and whose disassembly name index is < 4096
2041 can be stored in 16 bits. The encoding is slightly
2042 odd; the upper 4 bits of the instruction are 0x3, and
2043 bit 3 loses its normal meaning. */
2045 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2046 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2047 && ent
->disent
!= NULL
2048 && ent
->disent
->ournum
< (32768 + 4096))
2050 int start
= our_offset
+ bitsused
/ 8 + 1;
2052 memmove (insn_list
+ start
,
2053 insn_list
+ start
+ 1,
2054 insn_list_len
- (start
+ 1));
2060 insn_list
[our_offset
] |= 0x30;
2064 insn_list
[our_offset
] |= 0x08;
2073 else if (! (id
& 32768))
2077 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2079 printf ("%d: try %d\n", our_offset
, id
);
2082 /* Store the address of the entry being branched to. */
2083 while (currbits
>= 0)
2085 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2087 if (idest
& (1 << currbits
))
2088 *byte
|= (1 << (7 - (bitsused
% 8)));
2094 /* Now generate the states for the entry being branched to. */
2103 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2105 if (ent
->bits
[0] != NULL
)
2106 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2110 if (bitsused
!= totbits
)
2115 print_dis_table (void)
2118 struct disent
*cent
= disinsntable
;
2120 printf ("static const char dis_table[] = {");
2121 for (x
= 0; x
< insn_list_len
; x
++)
2126 printf (" 0x%02x,", insn_list
[x
]);
2128 printf ("\n};\n\n");
2130 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2131 while (cent
!= NULL
)
2133 struct disent
*ent
= cent
;
2137 printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent
->completer_index
,
2138 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2142 cent
= cent
->next_ent
;
2148 generate_disassembler (void)
2152 bittree
= make_bittree_entry ();
2154 for (i
= 0; i
< otlen
; i
++)
2156 struct main_entry
*ptr
= ordered_table
[i
];
2158 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2159 add_dis_entry (bittree
,
2160 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2162 ptr
->completers
, 1);
2165 compact_distree (bittree
);
2167 gen_dis_table (bittree
);
2173 print_string_table (void)
2176 char lbuf
[80], buf
[80];
2179 printf ("static const char * const ia64_strings[] = {\n");
2182 for (x
= 0; x
< strtablen
; x
++)
2186 if (strlen (string_table
[x
]->s
) > 75)
2189 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2192 if ((blen
+ len
) > 75)
2194 printf (" %s\n", lbuf
);
2203 printf (" %s\n", lbuf
);
2208 static struct completer_entry
**glist
;
2209 static int glistlen
= 0;
2210 static int glisttotlen
= 0;
2212 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2215 completer_entries_eq (struct completer_entry
*ent1
,
2216 struct completer_entry
*ent2
)
2218 while (ent1
!= NULL
&& ent2
!= NULL
)
2220 if (ent1
->name
->num
!= ent2
->name
->num
2221 || ent1
->bits
!= ent2
->bits
2222 || ent1
->mask
!= ent2
->mask
2223 || ent1
->is_terminal
!= ent2
->is_terminal
2224 || ent1
->dependencies
!= ent2
->dependencies
2225 || ent1
->order
!= ent2
->order
)
2228 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2231 ent1
= ent1
->alternative
;
2232 ent2
= ent2
->alternative
;
2235 return ent1
== ent2
;
2238 /* Insert ENT into the global list of completers and return it. If an
2239 equivalent entry (according to completer_entries_eq) already exists,
2240 it is returned instead. */
2241 static struct completer_entry
*
2242 insert_gclist (struct completer_entry
*ent
)
2250 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2251 ent
->alternative
= insert_gclist (ent
->alternative
);
2256 if (glisttotlen
== glistlen
)
2259 glist
= (struct completer_entry
**)
2260 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2270 if (ent
->name
->num
< glist
[0]->name
->num
)
2272 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2280 i
= (start
+ end
) / 2;
2281 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2288 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2302 while (i
< glistlen
)
2304 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2307 if (completer_entries_eq (ent
, glist
[i
]))
2315 for (; i
> 0 && i
< glistlen
; i
--)
2316 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2319 for (; i
< glistlen
; i
++)
2320 if (ent
->name
->num
< glist
[i
]->name
->num
)
2323 for (x
= glistlen
- 1; x
>= i
; x
--)
2324 glist
[x
+ 1] = glist
[x
];
2333 get_prefix_len (const char *name
)
2337 if (name
[0] == '\0')
2340 c
= strchr (name
, '.');
2344 return strlen (name
);
2348 compute_completer_bits (struct main_entry
*ment
, struct completer_entry
*ent
)
2352 compute_completer_bits (ment
, ent
->addl_entries
);
2354 if (ent
->is_terminal
)
2357 ia64_insn our_bits
= ent
->bits
;
2358 struct completer_entry
*p
= ent
->parent
;
2362 while (p
!= NULL
&& ! p
->is_terminal
)
2368 p_bits
= ment
->opcode
->opcode
;
2370 for (x
= 0; x
< 64; x
++)
2372 ia64_insn m
= ((ia64_insn
) 1) << x
;
2374 if ((p_bits
& m
) != (our_bits
& m
))
2379 ent
->bits
= our_bits
;
2388 ent
= ent
->alternative
;
2392 /* Find identical completer trees that are used in different
2393 instructions and collapse their entries. */
2395 collapse_redundant_completers (void)
2397 struct main_entry
*ptr
;
2400 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2402 if (ptr
->completers
== NULL
)
2405 compute_completer_bits (ptr
, ptr
->completers
);
2406 ptr
->completers
= insert_gclist (ptr
->completers
);
2409 /* The table has been finalized, now number the indexes. */
2410 for (x
= 0; x
< glistlen
; x
++)
2415 /* Attach two lists of dependencies to each opcode.
2416 1) all resources which, when already marked in use, conflict with this
2418 2) all resources which must be marked in use when this opcode is used
2421 insert_opcode_dependencies (struct ia64_opcode
*opc
,
2422 struct completer_entry
*cmp ATTRIBUTE_UNUSED
)
2424 /* Note all resources which point to this opcode. rfi has the most chks
2425 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2428 unsigned short regs
[256];
2430 unsigned short chks
[256];
2431 /* Flag insns for which no class matched; there should be none. */
2432 int no_class_found
= 1;
2434 for (i
= 0; i
< rdepslen
; i
++)
2436 struct rdep
*rs
= rdeps
[i
];
2439 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2440 && startswith (rs
->name
, "PR%")
2442 no_class_found
= 99;
2444 for (j
=0; j
< rs
->nregs
;j
++)
2448 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2450 /* We can ignore ic_note 11 for non PR resources. */
2451 if (ic_note
== 11 && ! startswith (rs
->name
, "PR"))
2454 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2455 && ic_note
!= rs
->regnotes
[j
]
2456 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2457 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2458 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2459 rs
->name
, rs
->regnotes
[j
]);
2460 /* Instruction class notes override resource notes.
2461 So far, only note 11 applies to an IC instead of a resource,
2462 and note 11 implies note 1. */
2464 regs
[nregs
++] = RDEP(ic_note
, i
);
2466 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2472 for (j
= 0; j
< rs
->nchks
; j
++)
2476 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2478 /* We can ignore ic_note 11 for non PR resources. */
2479 if (ic_note
== 11 && ! startswith (rs
->name
, "PR"))
2482 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2483 && ic_note
!= rs
->chknotes
[j
]
2484 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2485 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2486 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2487 rs
->name
, rs
->chknotes
[j
]);
2489 chks
[nchks
++] = RDEP(ic_note
, i
);
2491 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2499 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2501 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2503 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2507 insert_completer_entry (struct ia64_opcode
*opc
, struct main_entry
*tabent
,
2510 struct completer_entry
**ptr
= &tabent
->completers
;
2511 struct completer_entry
*parent
= NULL
;
2512 char pcopy
[129], *prefix
;
2515 if (strlen (opc
->name
) > 128)
2518 strcpy (pcopy
, opc
->name
);
2519 prefix
= pcopy
+ get_prefix_len (pcopy
);
2521 if (prefix
[0] != '\0')
2526 int need_new_ent
= 1;
2527 int plen
= get_prefix_len (prefix
);
2528 struct string_entry
*sent
;
2530 at_end
= (prefix
[plen
] == '\0');
2531 prefix
[plen
] = '\0';
2532 sent
= insert_string (prefix
);
2534 while (*ptr
!= NULL
)
2536 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2544 ptr
= &((*ptr
)->alternative
);
2549 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2552 nent
->parent
= parent
;
2553 nent
->addl_entries
= NULL
;
2554 nent
->alternative
= *ptr
;
2556 nent
->is_terminal
= 0;
2557 nent
->dependencies
= -1;
2563 ptr
= &((*ptr
)->addl_entries
);
2568 if ((*ptr
)->is_terminal
)
2571 (*ptr
)->is_terminal
= 1;
2572 (*ptr
)->mask
= (ia64_insn
)-1;
2573 (*ptr
)->bits
= opc
->opcode
;
2574 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2575 (*ptr
)->order
= order
;
2579 print_completer_entry (struct completer_entry
*ent
)
2582 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2586 while (! (mask
& 1))
2593 if (bits
& 0xffffffff00000000LL
)
2597 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2601 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2602 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2604 ent
->is_terminal
? 1 : 0,
2609 print_completer_table (void)
2613 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2614 for (x
= 0; x
< glistlen
; x
++)
2615 print_completer_entry (glist
[x
]);
2620 opcodes_eq (struct ia64_opcode
*opc1
, struct ia64_opcode
*opc2
)
2625 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2626 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2627 || (opc1
->flags
!= opc2
->flags
))
2630 for (x
= 0; x
< 5; x
++)
2631 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2634 plen1
= get_prefix_len (opc1
->name
);
2635 plen2
= get_prefix_len (opc2
->name
);
2637 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2644 add_opcode_entry (struct ia64_opcode
*opc
)
2646 struct main_entry
**place
;
2647 struct string_entry
*name
;
2651 if (strlen (opc
->name
) > 128)
2655 strcpy (prefix
, opc
->name
);
2656 prefix
[get_prefix_len (prefix
)] = '\0';
2657 name
= insert_string (prefix
);
2659 /* Walk the list of opcode table entries. If it's a new
2660 instruction, allocate and fill in a new entry. Note
2661 the main table is alphabetical by opcode name. */
2663 while (*place
!= NULL
)
2665 if ((*place
)->name
->num
== name
->num
2666 && opcodes_eq ((*place
)->opcode
, opc
))
2671 if ((*place
)->name
->num
> name
->num
)
2674 place
= &((*place
)->next
);
2678 struct main_entry
*nent
= tmalloc (struct main_entry
);
2682 nent
->next
= *place
;
2683 nent
->completers
= 0;
2686 if (otlen
== ottotlen
)
2689 ordered_table
= (struct main_entry
**)
2690 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2692 ordered_table
[otlen
++] = nent
;
2695 insert_completer_entry (opc
, *place
, opcode_count
++);
2699 print_main_table (void)
2701 struct main_entry
*ptr
= maintable
;
2704 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2707 printf (" { %d, %d, %d, 0x%016" PRIx64
"ull, 0x%016" PRIx64
2708 "ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2711 ptr
->opcode
->num_outputs
,
2712 ptr
->opcode
->opcode
,
2714 ptr
->opcode
->operands
[0],
2715 ptr
->opcode
->operands
[1],
2716 ptr
->opcode
->operands
[2],
2717 ptr
->opcode
->operands
[3],
2718 ptr
->opcode
->operands
[4],
2720 ptr
->completers
->num
);
2722 ptr
->main_index
= tindex
++;
2730 shrink (struct ia64_opcode
*table
)
2734 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2736 add_opcode_entry (table
+ curr_opcode
);
2737 if (table
[curr_opcode
].num_outputs
== 2
2738 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2739 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2740 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2741 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2743 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2746 *alias
= table
[curr_opcode
];
2747 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2748 alias
->operands
[i
- 1] = alias
->operands
[i
];
2749 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2750 --alias
->num_outputs
;
2751 alias
->flags
|= PSEUDO
;
2752 add_opcode_entry (alias
);
2758 /* Program options. */
2759 #define OPTION_SRCDIR 200
2761 struct option long_options
[] =
2763 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2764 {"debug", no_argument
, NULL
, 'd'},
2765 {"version", no_argument
, NULL
, 'V'},
2766 {"help", no_argument
, NULL
, 'h'},
2767 {0, no_argument
, NULL
, 0}
2771 print_version (void)
2773 printf ("%s: version 1.0\n", program_name
);
2778 usage (FILE * stream
, int status
)
2780 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2786 main (int argc
, char **argv
)
2788 extern int chdir (char *);
2789 char *srcdir
= NULL
;
2792 program_name
= *argv
;
2793 xmalloc_set_program_name (program_name
);
2795 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2820 if (chdir (srcdir
) != 0)
2821 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2822 srcdir
, strerror (errno
));
2824 load_insn_classes ();
2825 load_dependencies ();
2827 shrink (ia64_opcodes_a
);
2828 shrink (ia64_opcodes_b
);
2829 shrink (ia64_opcodes_f
);
2830 shrink (ia64_opcodes_i
);
2831 shrink (ia64_opcodes_m
);
2832 shrink (ia64_opcodes_x
);
2833 shrink (ia64_opcodes_d
);
2835 collapse_redundant_completers ();
2837 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2838 printf ("/* Copyright (C) 2007-2024 Free Software Foundation, Inc.\n\
2840 This file is part of the GNU opcodes library.\n\
2842 This library is free software; you can redistribute it and/or modify\n\
2843 it under the terms of the GNU General Public License as published by\n\
2844 the Free Software Foundation; either version 3, or (at your option)\n\
2845 any later version.\n\
2847 It is distributed in the hope that it will be useful, but WITHOUT\n\
2848 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2849 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2850 License for more details.\n\
2852 You should have received a copy of the GNU General Public License\n\
2853 along with this program; see the file COPYING. If not, write to the\n\
2854 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2855 02110-1301, USA. */\n");
2857 print_string_table ();
2858 print_dependency_table ();
2859 print_completer_table ();
2860 print_main_table ();
2862 generate_disassembler ();