1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
6 This file is part of GDB, GAS, and the GNU binutils.
8 GDB, GAS, and the GNU binutils are free software; you can redistribute
9 them and/or modify them under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version
11 2, or (at your option) any later version.
13 GDB, GAS, and the GNU binutils are distributed in the hope that they
14 will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING. If not, write to the
20 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"
46 #include "ia64-opc-a.c"
47 #include "ia64-opc-i.c"
48 #include "ia64-opc-m.c"
49 #include "ia64-opc-b.c"
50 #include "ia64-opc-f.c"
51 #include "ia64-opc-x.c"
52 #include "ia64-opc-d.c"
55 #define _(String) gettext (String)
57 /* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this
58 always, because we might be compiled without BFD64 defined, if configured
59 for a 32-bit target and --enable-targets=all is used. This will work for
60 both 32-bit and 64-bit hosts. */
61 #define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
62 #define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
63 #define opcode_fprintf_vma(s,x) \
64 fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
66 const char * program_name
= NULL
;
69 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
70 #define tmalloc(X) (X *) xmalloc (sizeof (X))
72 /* The main opcode table entry. Each entry is a unique combination of
73 name and flags (no two entries in the table compare as being equal
77 /* The base name of this opcode. The names of its completers are
78 appended to it to generate the full instruction name. */
79 struct string_entry
*name
;
80 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
81 it uses the first one passed to add_opcode_entry. */
82 struct ia64_opcode
*opcode
;
83 /* The list of completers that can be applied to this opcode. */
84 struct completer_entry
*completers
;
85 /* Next entry in the chain. */
86 struct main_entry
*next
;
87 /* Index in the main table. */
89 } *maintable
, **ordered_table
;
95 /* The set of possible completers for an opcode. */
96 struct completer_entry
98 /* This entry's index in the ia64_completer_table[] array. */
101 /* The name of the completer. */
102 struct string_entry
*name
;
104 /* This entry's parent. */
105 struct completer_entry
*parent
;
107 /* Set if this is a terminal completer (occurs at the end of an
111 /* An alternative completer. */
112 struct completer_entry
*alternative
;
114 /* Additional completers that can be appended to this one. */
115 struct completer_entry
*addl_entries
;
117 /* Before compute_completer_bits () is invoked, this contains the actual
118 instruction opcode for this combination of opcode and completers.
119 Afterwards, it contains those bits that are different from its
123 /* Bits set to 1 correspond to those bits in this completer's opcode
124 that are different from its parent completer's opcode (or from
125 the base opcode if the entry is the root of the opcode's completer
126 list). This field is filled in by compute_completer_bits (). */
129 /* Index into the opcode dependency list, or -1 if none. */
132 /* Remember the order encountered in the opcode tables. */
136 /* One entry in the disassembler name table. */
139 /* The index into the ia64_name_dis array for this entry. */
142 /* The index into the main_table[] array. */
145 /* The disassmbly priority of this entry. */
148 /* The completer_index value for this entry. */
151 /* How many other entries share this decode. */
154 /* The next entry sharing the same decode. */
155 struct disent
*nexte
;
157 /* The next entry in the name list. */
158 struct disent
*next_ent
;
159 } *disinsntable
= NULL
;
161 /* A state machine that will eventually be used to generate the
162 disassembler table. */
165 struct disent
*disent
;
166 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
171 /* The string table contains all opcodes and completers sorted in
172 alphabetical order. */
174 /* One entry in the string table. */
177 /* The index in the ia64_strings[] array for this entry. */
179 /* And the string. */
181 } **string_table
= NULL
;
184 int strtabtotlen
= 0;
187 /* Resource dependency entries. */
190 char *name
; /* Resource name. */
192 mode
:2, /* RAW, WAW, or WAR. */
193 semantics
:3; /* Dependency semantics. */
194 char *extra
; /* Additional semantics info. */
196 int total_chks
; /* Total #of terminal insns. */
197 int *chks
; /* Insn classes which read (RAW), write
198 (WAW), or write (WAR) this rsrc. */
199 int *chknotes
; /* Dependency notes for each class. */
201 int total_regs
; /* Total #of terminal insns. */
202 int *regs
; /* Insn class which write (RAW), write2
203 (WAW), or read (WAR) this rsrc. */
204 int *regnotes
; /* Dependency notes for each class. */
206 int waw_special
; /* Special WAW dependency note. */
209 static int rdepslen
= 0;
210 static int rdepstotlen
= 0;
212 /* Array of all instruction classes. */
215 char *name
; /* Instruction class name. */
216 int is_class
; /* Is a class, not a terminal. */
218 int *subs
; /* Other classes within this class. */
220 int xsubs
[4]; /* Exclusions. */
221 char *comment
; /* Optional comment. */
222 int note
; /* Optional note. */
223 int terminal_resolved
; /* Did we match this with anything? */
224 int orphan
; /* Detect class orphans. */
227 static int iclen
= 0;
228 static int ictotlen
= 0;
230 /* An opcode dependency (chk/reg pair of dependency lists). */
233 int chk
; /* index into dlists */
234 int reg
; /* index into dlists */
237 static int opdeplen
= 0;
238 static int opdeptotlen
= 0;
240 /* A generic list of dependencies w/notes encoded. These may be shared. */
244 unsigned short *deps
;
247 static int dlistlen
= 0;
248 static int dlisttotlen
= 0;
251 static void fail (const char *, ...) ATTRIBUTE_PRINTF_1
;
252 static void warn (const char *, ...) ATTRIBUTE_PRINTF_1
;
253 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
254 static int deplist_equals (struct deplist
*, struct deplist
*);
255 static short insert_deplist (int, unsigned short *);
256 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
257 static void mark_used (struct iclass
*, int);
258 static int fetch_insn_class (const char *, int);
259 static int sub_compare (const void *, const void *);
260 static void load_insn_classes (void);
261 static void parse_resource_users (const char *, int **, int *, int **);
262 static int parse_semantics (char *);
263 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
264 static void load_depfile (const char *, enum ia64_dependency_mode
);
265 static void load_dependencies (void);
266 static int irf_operand (int, const char *);
267 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
268 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
269 static int lookup_regindex (const char *, int);
270 static int lookup_specifier (const char *);
271 static void print_dependency_table (void);
272 static struct string_entry
* insert_string (char *);
273 static void gen_dis_table (struct bittree
*);
274 static void print_dis_table (void);
275 static void generate_disassembler (void);
276 static void print_string_table (void);
277 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
278 static struct completer_entry
* insert_gclist (struct completer_entry
*);
279 static int get_prefix_len (const char *);
280 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
281 static void collapse_redundant_completers (void);
282 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
283 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
284 static void print_completer_entry (struct completer_entry
*);
285 static void print_completer_table (void);
286 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
287 static void add_opcode_entry (struct ia64_opcode
*);
288 static void print_main_table (void);
289 static void shrink (struct ia64_opcode
*);
290 static void print_version (void);
291 static void usage (FILE *, int);
292 static void finish_distable (void);
293 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, int);
294 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, int);
295 static void compact_distree (struct bittree
*);
296 static struct bittree
* make_bittree_entry (void);
297 static struct disent
* add_dis_table_ent (struct disent
*, int, int, int);
301 fail (const char *message
, ...)
305 va_start (args
, message
);
306 fprintf (stderr
, _("%s: Error: "), program_name
);
307 vfprintf (stderr
, message
, args
);
313 warn (const char *message
, ...)
317 va_start (args
, message
);
319 fprintf (stderr
, _("%s: Warning: "), program_name
);
320 vfprintf (stderr
, message
, args
);
324 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
326 insert_resource (const char *name
, enum ia64_dependency_mode type
)
328 if (rdepslen
== rdepstotlen
)
331 rdeps
= (struct rdep
**)
332 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
334 rdeps
[rdepslen
] = tmalloc(struct rdep
);
335 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
336 rdeps
[rdepslen
]->name
= xstrdup (name
);
337 rdeps
[rdepslen
]->mode
= type
;
338 rdeps
[rdepslen
]->waw_special
= 0;
340 return rdeps
[rdepslen
++];
343 /* Are the lists of dependency indexes equivalent? */
345 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
349 if (d1
->len
!= d2
->len
)
352 for (i
= 0; i
< d1
->len
; i
++)
353 if (d1
->deps
[i
] != d2
->deps
[i
])
359 /* Add the list of dependencies to the list of dependency lists. */
361 insert_deplist (int count
, unsigned short *deps
)
363 /* Sort the list, then see if an equivalent list exists already.
364 this results in a much smaller set of dependency lists. */
365 struct deplist
*list
;
369 memset ((void *)set
, 0, sizeof (set
));
370 for (i
= 0; i
< count
; i
++)
374 for (i
= 0; i
< (int) sizeof (set
); i
++)
378 list
= tmalloc (struct deplist
);
380 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
382 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
384 list
->deps
[count
++] = i
;
386 /* Does this list exist already? */
387 for (i
= 0; i
< dlistlen
; i
++)
388 if (deplist_equals (list
, dlists
[i
]))
395 if (dlistlen
== dlisttotlen
)
398 dlists
= (struct deplist
**)
399 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
401 dlists
[dlistlen
] = list
;
406 /* Add the given pair of dependency lists to the opcode dependency list. */
408 insert_dependencies (int nchks
, unsigned short *chks
,
409 int nregs
, unsigned short *regs
)
417 regind
= insert_deplist (nregs
, regs
);
419 chkind
= insert_deplist (nchks
, chks
);
421 for (i
= 0; i
< opdeplen
; i
++)
422 if (opdeps
[i
]->chk
== chkind
423 && opdeps
[i
]->reg
== regind
)
426 pair
= tmalloc (struct opdep
);
430 if (opdeplen
== opdeptotlen
)
433 opdeps
= (struct opdep
**)
434 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
436 opdeps
[opdeplen
] = pair
;
442 mark_used (struct iclass
*ic
, int clear_terminals
)
448 ic
->terminal_resolved
= 1;
450 for (i
= 0; i
< ic
->nsubs
; i
++)
451 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
453 for (i
= 0; i
< ic
->nxsubs
; i
++)
454 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
457 /* Look up an instruction class; if CREATE make a new one if none found;
458 returns the index into the insn class array. */
460 fetch_insn_class (const char *full_name
, int create
)
470 if (strncmp (full_name
, "IC:", 3) == 0)
472 name
= xstrdup (full_name
+ 3);
476 name
= xstrdup (full_name
);
478 if ((xsect
= strchr(name
, '\\')) != NULL
)
480 if ((comment
= strchr(name
, '[')) != NULL
)
482 if ((notestr
= strchr(name
, '+')) != NULL
)
485 /* If it is a composite class, then ignore comments and notes that come after
486 the '\\', since they don't apply to the part we are decoding now. */
499 note
= atoi (notestr
+ 1);
500 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
502 if (strcmp (notestr
, "+1+13") == 0)
504 else if (!xsect
|| nextnotestr
< xsect
)
505 warn (_("multiple note %s not handled\n"), notestr
);
509 /* If it's a composite class, leave the notes and comments in place so that
510 we have a unique name for the composite class. Otherwise, we remove
520 for (i
= 0; i
< iclen
; i
++)
521 if (strcmp (name
, ics
[i
]->name
) == 0
522 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
523 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
524 && strncmp (ics
[i
]->comment
, comment
,
525 strlen (ics
[i
]->comment
)) == 0))
526 && note
== ics
[i
]->note
)
532 /* Doesn't exist, so make a new one. */
533 if (iclen
== ictotlen
)
536 ics
= (struct iclass
**)
537 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
541 ics
[ind
] = tmalloc (struct iclass
);
542 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
543 ics
[ind
]->name
= xstrdup (name
);
544 ics
[ind
]->is_class
= is_class
;
545 ics
[ind
]->orphan
= 1;
549 ics
[ind
]->comment
= xstrdup (comment
+ 1);
550 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
554 ics
[ind
]->note
= note
;
556 /* If it's a composite class, there's a comment or note, look for an
557 existing class or terminal with the same name. */
558 if ((xsect
|| comment
|| notestr
) && is_class
)
560 /* First, populate with the class we're based on. */
561 char *subname
= name
;
571 ics
[ind
]->subs
= tmalloc(int);
572 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
577 char *subname
= xsect
+ 1;
579 xsect
= strchr (subname
, '\\');
582 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
590 /* For sorting a class's sub-class list only; make sure classes appear before
593 sub_compare (const void *e1
, const void *e2
)
595 struct iclass
*ic1
= ics
[*(int *)e1
];
596 struct iclass
*ic2
= ics
[*(int *)e2
];
603 else if (ic2
->is_class
)
606 return strcmp (ic1
->name
, ic2
->name
);
610 load_insn_classes (void)
612 FILE *fp
= fopen ("ia64-ic.tbl", "r");
616 fail (_("can't find ia64-ic.tbl for reading\n"));
618 /* Discard first line. */
619 fgets (buf
, sizeof(buf
), fp
);
627 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
630 while (ISSPACE (buf
[strlen (buf
) - 1]))
631 buf
[strlen (buf
) - 1] = '\0';
637 if (tmp
== buf
+ sizeof (buf
))
642 iclass
= fetch_insn_class (name
, 1);
643 ics
[iclass
]->is_class
= 1;
645 if (strcmp (name
, "none") == 0)
647 ics
[iclass
]->is_class
= 0;
648 ics
[iclass
]->terminal_resolved
= 1;
652 /* For this class, record all sub-classes. */
658 while (*tmp
&& ISSPACE (*tmp
))
661 if (tmp
== buf
+ sizeof (buf
))
665 while (*tmp
&& *tmp
!= ',')
668 if (tmp
== buf
+ sizeof (buf
))
674 ics
[iclass
]->subs
= (int *)
675 xrealloc ((void *)ics
[iclass
]->subs
,
676 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
678 sub
= fetch_insn_class (subname
, 1);
679 ics
[iclass
]->subs
= (int *)
680 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
681 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
684 /* Make sure classes come before terminals. */
685 qsort ((void *)ics
[iclass
]->subs
,
686 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
691 printf ("%d classes\n", iclen
);
694 /* Extract the insn classes from the given line. */
696 parse_resource_users (ref
, usersp
, nusersp
, notesp
)
703 char *line
= xstrdup (ref
);
705 int *users
= *usersp
;
706 int count
= *nusersp
;
707 int *notes
= *notesp
;
719 while (ISSPACE (*tmp
))
722 while (*tmp
&& *tmp
!= ',')
727 xsect
= strchr (name
, '\\');
728 if ((notestr
= strstr (name
, "+")) != NULL
)
732 note
= atoi (notestr
+ 1);
733 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
735 /* Note 13 always implies note 1. */
736 if (strcmp (notestr
, "+1+13") == 0)
738 else if (!xsect
|| nextnotestr
< xsect
)
739 warn (_("multiple note %s not handled\n"), notestr
);
747 /* All classes are created when the insn class table is parsed;
748 Individual instructions might not appear until the dependency tables
749 are read. Only create new classes if it's *not* an insn class,
750 or if it's a composite class (which wouldn't necessarily be in the IC
752 if (strncmp (name
, "IC:", 3) != 0 || xsect
!= NULL
)
755 iclass
= fetch_insn_class (name
, create
);
759 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
761 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
763 users
[count
++] = iclass
;
764 mark_used (ics
[iclass
], 0);
767 printf("Class %s not found\n", name
);
769 /* Update the return values. */
778 parse_semantics (char *sem
)
780 if (strcmp (sem
, "none") == 0)
781 return IA64_DVS_NONE
;
782 else if (strcmp (sem
, "implied") == 0)
783 return IA64_DVS_IMPLIED
;
784 else if (strcmp (sem
, "impliedF") == 0)
785 return IA64_DVS_IMPLIEDF
;
786 else if (strcmp (sem
, "data") == 0)
787 return IA64_DVS_DATA
;
788 else if (strcmp (sem
, "instr") == 0)
789 return IA64_DVS_INSTR
;
790 else if (strcmp (sem
, "specific") == 0)
791 return IA64_DVS_SPECIFIC
;
792 else if (strcmp (sem
, "stop") == 0)
793 return IA64_DVS_STOP
;
795 return IA64_DVS_OTHER
;
799 add_dep (const char *name
, const char *chk
, const char *reg
,
800 int semantics
, int mode
, char *extra
, int flag
)
804 rs
= insert_resource (name
, mode
);
806 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
807 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
809 rs
->semantics
= semantics
;
811 rs
->waw_special
= flag
;
815 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
817 FILE *fp
= fopen (filename
, "r");
821 fail (_("can't find %s for reading\n"), filename
);
823 fgets (buf
, sizeof(buf
), fp
);
831 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
834 while (ISSPACE (buf
[strlen (buf
) - 1]))
835 buf
[strlen (buf
) - 1] = '\0';
842 while (ISSPACE (*tmp
))
845 tmp
= strchr (tmp
, ';');
849 while (ISSPACE (*tmp
))
852 tmp
= strchr (tmp
, ';');
856 while (ISSPACE (*tmp
))
858 semantics
= parse_semantics (tmp
);
859 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
861 /* For WAW entries, if the chks and regs differ, we need to enter the
862 entries in both positions so that the tables will be parsed properly,
863 without a lot of extra work. */
864 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
866 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
867 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
871 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
878 load_dependencies (void)
880 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
881 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
882 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
885 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
888 /* Is the given operand an indirect register file operand? */
890 irf_operand (int op
, const char *field
)
894 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
895 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
896 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
897 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
901 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
902 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
903 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
904 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
905 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
906 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
907 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
908 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
912 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
913 mov_um insn classes. */
915 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
916 const char *format
, const char *field
)
918 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
929 int i
= strcmp (idesc
->name
, "mov.i") == 0;
930 int m
= strcmp (idesc
->name
, "mov.m") == 0;
931 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
932 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
933 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
934 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
935 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
936 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
940 return strstr (format
, "I26") || strstr (format
, "I27");
942 return strstr (format
, "I28") != NULL
;
944 return strstr (format
, "M29") || strstr (format
, "M30");
946 return strstr (format
, "M31") != NULL
;
947 if (pseudo0
|| pseudo1
)
953 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
954 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
956 return strstr (format
, "I22") != NULL
;
958 return strstr (format
, "I21") != NULL
;
963 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
964 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
966 return strstr (format
, "M32") != NULL
;
968 return strstr (format
, "M33") != NULL
;
972 if (ic
->name
[5] == 'n')
974 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
975 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
977 return strstr (format
, "M42") != NULL
;
979 return strstr (format
, "M43") != NULL
;
981 else if (ic
->name
[5] == 'p')
983 return idesc
->operands
[1] == IA64_OPND_IP
;
989 if (ic
->name
[5] == 'r')
991 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
992 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
993 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
995 return strstr (format
, "I23") != NULL
;
997 return strstr (format
, "I24") != NULL
;
999 return strstr (format
, "I25") != NULL
;
1001 else if (ic
->name
[5] == 's')
1003 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1004 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1006 return strstr (format
, "M35") != NULL
;
1008 return strstr (format
, "M36") != NULL
;
1015 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1016 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1018 return strstr (format
, "M35") != NULL
;
1020 return strstr (format
, "M36") != NULL
;
1027 /* Is the given opcode in the given insn class? */
1029 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1030 const char *format
, const char *field
, int *notep
)
1037 if (!strncmp (ic
->comment
, "Format", 6))
1039 /* Assume that the first format seen is the most restrictive, and
1040 only keep a later one if it looks like it's more restrictive. */
1043 if (strlen (ic
->comment
) < strlen (format
))
1045 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1046 ic
->comment
, format
);
1047 format
= ic
->comment
;
1051 format
= ic
->comment
;
1053 else if (!strncmp (ic
->comment
, "Field", 5))
1056 warn (_("overlapping field %s->%s\n"),
1057 ic
->comment
, field
);
1058 field
= ic
->comment
;
1062 /* An insn class matches anything that is the same followed by completers,
1063 except when the absence and presence of completers constitutes different
1065 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1067 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
1068 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1069 int len
= strlen(ic
->name
);
1071 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1072 && (idesc
->name
[len
] == '\0'
1073 || idesc
->name
[len
] == '.'));
1075 /* All break, nop, and hint variations must match exactly. */
1077 (strcmp (ic
->name
, "break") == 0
1078 || strcmp (ic
->name
, "nop") == 0
1079 || strcmp (ic
->name
, "hint") == 0))
1080 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1082 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1083 unless specifically allowed by clauses in this block. */
1084 if (resolved
&& field
)
1086 /* Check Field(sf)==sN against opcode sN. */
1087 if (strstr(field
, "(sf)==") != NULL
)
1091 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1092 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1094 /* Check Field(lftype)==XXX. */
1095 else if (strstr (field
, "(lftype)") != NULL
)
1097 if (strstr (idesc
->name
, "fault") != NULL
)
1098 resolved
= strstr (field
, "fault") != NULL
;
1100 resolved
= strstr (field
, "fault") == NULL
;
1102 /* Handle Field(ctype)==XXX. */
1103 else if (strstr (field
, "(ctype)") != NULL
)
1105 if (strstr (idesc
->name
, "or.andcm"))
1106 resolved
= strstr (field
, "or.andcm") != NULL
;
1107 else if (strstr (idesc
->name
, "and.orcm"))
1108 resolved
= strstr (field
, "and.orcm") != NULL
;
1109 else if (strstr (idesc
->name
, "orcm"))
1110 resolved
= strstr (field
, "or orcm") != NULL
;
1111 else if (strstr (idesc
->name
, "or"))
1112 resolved
= strstr (field
, "or orcm") != NULL
;
1113 else if (strstr (idesc
->name
, "andcm"))
1114 resolved
= strstr (field
, "and andcm") != NULL
;
1115 else if (strstr (idesc
->name
, "and"))
1116 resolved
= strstr (field
, "and andcm") != NULL
;
1117 else if (strstr (idesc
->name
, "unc"))
1118 resolved
= strstr (field
, "unc") != NULL
;
1120 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1124 if (resolved
&& format
)
1126 if (strncmp (idesc
->name
, "dep", 3) == 0
1127 && strstr (format
, "I13") != NULL
)
1128 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1129 else if (strncmp (idesc
->name
, "chk", 3) == 0
1130 && strstr (format
, "M21") != NULL
)
1131 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1132 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1133 resolved
= (strstr (format
, "M14 M15") != NULL
1134 && (idesc
->operands
[1] == IA64_OPND_R2
1135 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1136 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1137 && strstr (format
, "B5") != NULL
)
1138 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1139 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1140 && strstr (format
, "B3") != NULL
)
1141 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1142 else if (strncmp (idesc
->name
, "brp", 3) == 0
1143 && strstr (format
, "B7") != NULL
)
1144 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1145 else if (strcmp (ic
->name
, "invala") == 0)
1146 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1147 else if (strncmp (idesc
->name
, "st", 2) == 0
1148 && (strstr (format
, "M5") != NULL
1149 || strstr (format
, "M10") != NULL
))
1150 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1151 else if (strncmp (idesc
->name
, "ld", 2) == 0
1152 && (strstr (format
, "M2 M3") != NULL
1153 || strstr (format
, "M12") != NULL
1154 || strstr (format
, "M7 M8") != NULL
))
1155 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1160 /* Misc brl variations ('.cond' is optional);
1161 plain brl matches brl.cond. */
1163 && (strcmp (idesc
->name
, "brl") == 0
1164 || strncmp (idesc
->name
, "brl.", 4) == 0)
1165 && strcmp (ic
->name
, "brl.cond") == 0)
1170 /* Misc br variations ('.cond' is optional). */
1172 && (strcmp (idesc
->name
, "br") == 0
1173 || strncmp (idesc
->name
, "br.", 3) == 0)
1174 && strcmp (ic
->name
, "br.cond") == 0)
1177 resolved
= (strstr (format
, "B4") != NULL
1178 && idesc
->operands
[0] == IA64_OPND_B2
)
1179 || (strstr (format
, "B1") != NULL
1180 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1185 /* probe variations. */
1186 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1188 resolved
= strcmp (ic
->name
, "probe") == 0
1189 && !((strstr (idesc
->name
, "fault") != NULL
)
1190 ^ (format
&& strstr (format
, "M40") != NULL
));
1193 /* mov variations. */
1194 if (!resolved
&& is_mov
)
1198 /* mov alias for fmerge. */
1199 if (strcmp (ic
->name
, "fmerge") == 0)
1201 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1202 && idesc
->operands
[1] == IA64_OPND_F3
;
1204 /* mov alias for adds (r3 or imm14). */
1205 else if (strcmp (ic
->name
, "adds") == 0)
1207 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1208 && (idesc
->operands
[1] == IA64_OPND_R3
1209 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1211 /* mov alias for addl. */
1212 else if (strcmp (ic
->name
, "addl") == 0)
1214 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1215 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1219 /* Some variants of mov and mov.[im]. */
1220 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1221 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1224 /* Keep track of this so we can flag any insn classes which aren't
1225 mapped onto at least one real insn. */
1227 ic
->terminal_resolved
= 1;
1229 else for (i
= 0; i
< ic
->nsubs
; i
++)
1231 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1235 for (j
= 0; j
< ic
->nxsubs
; j
++)
1236 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1240 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1247 /* If it's in this IC, add the IC note (if any) to the insn. */
1250 if (ic
->note
&& notep
)
1252 if (*notep
&& *notep
!= ic
->note
)
1253 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1254 *notep
, ic
->note
, ic
->name
);
1265 lookup_regindex (const char *name
, int specifier
)
1270 if (strstr (name
, "[RSC]"))
1272 if (strstr (name
, "[BSP]"))
1274 else if (strstr (name
, "[BSPSTORE]"))
1276 else if (strstr (name
, "[RNAT]"))
1278 else if (strstr (name
, "[FCR]"))
1280 else if (strstr (name
, "[EFLAG]"))
1282 else if (strstr (name
, "[CSD]"))
1284 else if (strstr (name
, "[SSD]"))
1286 else if (strstr (name
, "[CFLG]"))
1288 else if (strstr (name
, "[FSR]"))
1290 else if (strstr (name
, "[FIR]"))
1292 else if (strstr (name
, "[FDR]"))
1294 else if (strstr (name
, "[CCV]"))
1296 else if (strstr (name
, "[ITC]"))
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[IRR%]") != NULL
)
1438 return IA64_RS_CR_IRR
;
1439 if (strstr (name
, "CR[LRR%]") != NULL
)
1440 return IA64_RS_CR_LRR
;
1441 if (strstr (name
, "CR%") != NULL
)
1443 if (strstr (name
, "FR%, % in 0") != NULL
)
1445 if (strstr (name
, "FR%, % in 2") != NULL
)
1447 if (strstr (name
, "GR%") != NULL
)
1449 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1451 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1454 warn (_("don't know how to specify %% dependency %s\n"),
1457 else if (strchr (name
, '#'))
1459 if (strstr (name
, "CPUID#") != NULL
)
1460 return IA64_RS_CPUID
;
1461 if (strstr (name
, "DBR#") != NULL
)
1463 if (strstr (name
, "IBR#") != NULL
)
1465 if (strstr (name
, "MSR#") != NULL
)
1467 if (strstr (name
, "PKR#") != NULL
)
1469 if (strstr (name
, "PMC#") != NULL
)
1471 if (strstr (name
, "PMD#") != NULL
)
1473 if (strstr (name
, "RR#") != NULL
)
1476 warn (_("Don't know how to specify # dependency %s\n"),
1479 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1480 return IA64_RS_AR_FPSR
;
1481 else if (strncmp (name
, "AR[", 3) == 0)
1483 else if (strncmp (name
, "CR[", 3) == 0)
1485 else if (strncmp (name
, "PSR.", 4) == 0)
1487 else if (strcmp (name
, "InService*") == 0)
1488 return IA64_RS_INSERVICE
;
1489 else if (strcmp (name
, "GR0") == 0)
1491 else if (strcmp (name
, "CFM") == 0)
1493 else if (strcmp (name
, "PR63") == 0)
1494 return IA64_RS_PR63
;
1495 else if (strcmp (name
, "RSE") == 0)
1502 print_dependency_table ()
1508 for (i
=0;i
< iclen
;i
++)
1510 if (ics
[i
]->is_class
)
1514 if (ics
[i
]->comment
)
1515 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1516 ics
[i
]->name
, ics
[i
]->comment
);
1518 warn (_("IC:%s has no terminals or sub-classes\n"),
1524 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1526 if (ics
[i
]->comment
)
1527 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1528 ics
[i
]->name
, ics
[i
]->comment
);
1530 warn (_("no insns mapped directly to terminal IC %s\n"),
1536 for (i
= 0; i
< iclen
; i
++)
1540 mark_used (ics
[i
], 1);
1541 warn (_("class %s is defined but not used\n"),
1547 for (i
= 0; i
< rdepslen
; i
++)
1549 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1551 if (rdeps
[i
]->total_chks
== 0)
1552 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1553 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1554 rdeps
[i
]->total_regs
? "" : " or regs");
1555 else if (rdeps
[i
]->total_regs
== 0)
1556 warn (_("rsrc %s (%s) has no regs\n"),
1557 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1561 /* The dependencies themselves. */
1562 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1563 for (i
= 0; i
< rdepslen
; i
++)
1565 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1567 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1568 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1570 printf (" { \"%s\", %d, %d, %d, %d, ",
1571 rdeps
[i
]->name
, specifier
,
1572 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1573 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1575 const char *quote
, *rest
;
1578 rest
= rdeps
[i
]->extra
;
1579 quote
= strchr (rest
, '\"');
1580 while (quote
!= NULL
)
1582 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1584 quote
= strchr (rest
, '\"');
1586 printf ("%s\", ", rest
);
1594 /* And dependency lists. */
1595 for (i
=0;i
< dlistlen
;i
++)
1598 printf ("static const unsigned short dep%d[] = {\n ", i
);
1599 for (j
=0;j
< dlists
[i
]->len
; j
++)
1601 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1608 printf ("\n};\n\n");
1611 /* And opcode dependency list. */
1612 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1613 printf ("static const struct ia64_opcode_dependency\n");
1614 printf ("op_dependencies[] = {\n");
1615 for (i
= 0; i
< opdeplen
; i
++)
1618 if (opdeps
[i
]->chk
== -1)
1619 printf ("0, NULL, ");
1621 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1622 if (opdeps
[i
]->reg
== -1)
1623 printf ("0, NULL, ");
1625 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1632 /* Add STR to the string table. */
1633 static struct string_entry
*
1634 insert_string (char *str
)
1636 int start
= 0, end
= strtablen
;
1639 if (strtablen
== strtabtotlen
)
1642 string_table
= (struct string_entry
**)
1643 xrealloc (string_table
,
1644 sizeof (struct string_entry
**) * strtabtotlen
);
1650 string_table
[0] = tmalloc (struct string_entry
);
1651 string_table
[0]->s
= xstrdup (str
);
1652 string_table
[0]->num
= 0;
1653 return string_table
[0];
1656 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1658 else if (strcmp (str
, string_table
[0]->s
) < 0)
1666 i
= (start
+ end
) / 2;
1667 c
= strcmp (str
, string_table
[i
]->s
);
1672 return string_table
[i
];
1681 for (; i
> 0 && i
< strtablen
; i
--)
1682 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1685 for (; i
< strtablen
; i
++)
1686 if (strcmp (str
, string_table
[i
]->s
) < 0)
1689 for (x
= strtablen
- 1; x
>= i
; x
--)
1691 string_table
[x
+ 1] = string_table
[x
];
1692 string_table
[x
+ 1]->num
= x
+ 1;
1695 string_table
[i
] = tmalloc (struct string_entry
);
1696 string_table
[i
]->s
= xstrdup (str
);
1697 string_table
[i
]->num
= i
;
1700 return string_table
[i
];
1703 static struct bittree
*
1704 make_bittree_entry (void)
1706 struct bittree
*res
= tmalloc (struct bittree
);
1709 res
->bits
[0] = NULL
;
1710 res
->bits
[1] = NULL
;
1711 res
->bits
[2] = NULL
;
1713 res
->bits_to_skip
= 0;
1718 static struct disent
*
1719 add_dis_table_ent (which
, insn
, order
, completer_index
)
1720 struct disent
*which
;
1723 int completer_index
;
1733 while (ent
->nexte
!= NULL
)
1736 ent
= (ent
->nexte
= tmalloc (struct disent
));
1740 ent
= tmalloc (struct disent
);
1741 ent
->next_ent
= disinsntable
;
1748 ent
->priority
= order
;
1750 while (completer_index
!= 1)
1752 ci
= (ci
<< 1) | (completer_index
& 1);
1753 completer_index
>>= 1;
1755 ent
->completer_index
= ci
;
1762 struct disent
*ent
= disinsntable
;
1763 struct disent
*prev
= ent
;
1765 ent
->ournum
= 32768;
1766 while ((ent
= ent
->next_ent
) != NULL
)
1768 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1774 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1775 opcodenum
, order
, completer_index
)
1776 struct bittree
*curr_ent
;
1782 int 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 (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1816 struct bittree
*first
;
1820 struct completer_entry
*ent
;
1821 int completer_index
;
1823 if (completer_index
& (1 << 20))
1828 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1829 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1830 (completer_index
<< 1) | 1);
1832 if (ent
->is_terminal
)
1834 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1835 opcodenum
, opcode_count
- ent
->order
- 1,
1836 (completer_index
<< 1) | 1);
1838 completer_index
<<= 1;
1839 ent
= ent
->alternative
;
1843 /* This optimization pass combines multiple "don't care" nodes. */
1845 compact_distree (ent
)
1846 struct bittree
*ent
;
1848 #define IS_SKIP(ent) \
1849 ((ent->bits[2] !=NULL) \
1850 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1853 struct bittree
*nent
= ent
;
1856 while (IS_SKIP (nent
))
1859 nent
= nent
->bits
[2];
1864 struct bittree
*next
= ent
->bits
[2];
1866 ent
->bits
[0] = nent
->bits
[0];
1867 ent
->bits
[1] = nent
->bits
[1];
1868 ent
->bits
[2] = nent
->bits
[2];
1869 ent
->disent
= nent
->disent
;
1871 ent
->bits_to_skip
= bitcnt
;
1872 while (next
!= nent
)
1874 struct bittree
*b
= next
;
1875 next
= next
->bits
[2];
1881 for (x
= 0; x
< 3; x
++)
1883 struct bittree
*i
= ent
->bits
[x
];
1886 compact_distree (i
);
1890 static unsigned char *insn_list
;
1891 static int insn_list_len
= 0;
1892 static int tot_insn_list_len
= 0;
1894 /* Generate the disassembler state machine corresponding to the tree
1898 struct bittree
*ent
;
1901 int our_offset
= insn_list_len
;
1903 int totbits
= bitsused
;
1906 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1908 /* If this is a terminal entry, there's no point in skipping any
1910 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1911 ent
->bits
[2] == NULL
)
1913 if (ent
->disent
== NULL
)
1919 /* Calculate the amount of space needed for this entry, or at least
1920 a conservatively large approximation. */
1924 for (x
= 1; x
< 3; x
++)
1925 if (ent
->bits
[x
] != NULL
)
1928 if (ent
->disent
!= NULL
)
1930 if (ent
->bits
[2] != NULL
)
1936 /* Now allocate the space. */
1937 needed_bytes
= (totbits
+ 7) / 8;
1938 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1940 tot_insn_list_len
+= 256;
1941 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1943 our_offset
= insn_list_len
;
1944 insn_list_len
+= needed_bytes
;
1945 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1947 /* Encode the skip entry by setting bit 6 set in the state op field,
1948 and store the # of bits to skip immediately after. */
1952 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1953 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1956 #define IS_ONLY_IFZERO(ENT) \
1957 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1958 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1960 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1962 if (ent
->bits
[0] != NULL
)
1964 struct bittree
*nent
= ent
->bits
[0];
1967 insn_list
[our_offset
] |= 0x80;
1969 /* We can encode sequences of multiple "if (bit is zero)" tests
1970 by storing the # of zero bits to check in the lower 3 bits of
1971 the instruction. However, this only applies if the state
1972 solely tests for a zero bit. */
1974 if (IS_ONLY_IFZERO (ent
))
1976 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1978 nent
= nent
->bits
[0];
1982 insn_list
[our_offset
+ 0] |= zero_count
;
1984 zero_dest
= insn_list_len
;
1985 gen_dis_table (nent
);
1988 /* Now store the remaining tests. We also handle a sole "termination
1989 entry" by storing it as an "any bit" test. */
1991 for (x
= 1; x
< 3; x
++)
1993 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1995 struct bittree
*i
= ent
->bits
[x
];
2001 /* If the instruction being branched to only consists of
2002 a termination entry, use the termination entry as the
2003 place to branch to instead. */
2004 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
2005 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
2007 idest
= i
->disent
->ournum
;
2011 idest
= insn_list_len
- our_offset
;
2014 idest
= ent
->disent
->ournum
;
2016 /* If the destination offset for the if (bit is 1) test is less
2017 than 256 bytes away, we can store it as 8-bits instead of 16;
2018 the instruction has bit 5 set for the 16-bit address, and bit
2019 4 for the 8-bit address. Since we've already allocated 16
2020 bits for the address we need to deallocate the space.
2022 Note that branchings within the table are relative, and
2023 there are no branches that branch past our instruction yet
2024 so we do not need to adjust any other offsets. */
2029 int start
= our_offset
+ bitsused
/ 8 + 1;
2031 memmove (insn_list
+ start
,
2032 insn_list
+ start
+ 1,
2033 insn_list_len
- (start
+ 1));
2038 insn_list
[our_offset
] |= 0x10;
2042 insn_list
[our_offset
] |= 0x20;
2046 /* An instruction which solely consists of a termination
2047 marker and whose disassembly name index is < 4096
2048 can be stored in 16 bits. The encoding is slightly
2049 odd; the upper 4 bits of the instruction are 0x3, and
2050 bit 3 loses its normal meaning. */
2052 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2053 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2054 && ent
->disent
!= NULL
2055 && ent
->disent
->ournum
< (32768 + 4096))
2057 int start
= our_offset
+ bitsused
/ 8 + 1;
2059 memmove (insn_list
+ start
,
2060 insn_list
+ start
+ 1,
2061 insn_list_len
- (start
+ 1));
2067 insn_list
[our_offset
] |= 0x30;
2071 insn_list
[our_offset
] |= 0x08;
2080 else if (! (id
& 32768))
2084 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2086 printf ("%d: try %d\n", our_offset
, id
);
2089 /* Store the address of the entry being branched to. */
2090 while (currbits
>= 0)
2092 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2094 if (idest
& (1 << currbits
))
2095 *byte
|= (1 << (7 - (bitsused
% 8)));
2101 /* Now generate the states for the entry being branched to. */
2110 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2112 if (ent
->bits
[0] != NULL
)
2113 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2117 if (bitsused
!= totbits
)
2122 print_dis_table (void)
2125 struct disent
*cent
= disinsntable
;
2127 printf ("static const char dis_table[] = {\n");
2128 for (x
= 0; x
< insn_list_len
; x
++)
2130 if ((x
> 0) && ((x
% 12) == 0))
2133 printf ("0x%02x, ", insn_list
[x
]);
2135 printf ("\n};\n\n");
2137 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2138 while (cent
!= NULL
)
2140 struct disent
*ent
= cent
;
2144 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2145 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2149 cent
= cent
->next_ent
;
2155 generate_disassembler (void)
2159 bittree
= make_bittree_entry ();
2161 for (i
= 0; i
< otlen
; i
++)
2163 struct main_entry
*ptr
= ordered_table
[i
];
2165 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2166 add_dis_entry (bittree
,
2167 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2169 ptr
->completers
, 1);
2172 compact_distree (bittree
);
2174 gen_dis_table (bittree
);
2180 print_string_table (void)
2183 char lbuf
[80], buf
[80];
2186 printf ("static const char * const ia64_strings[] = {\n");
2189 for (x
= 0; x
< strtablen
; x
++)
2193 if (strlen (string_table
[x
]->s
) > 75)
2196 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2199 if ((blen
+ len
) > 75)
2201 printf (" %s\n", lbuf
);
2210 printf (" %s\n", lbuf
);
2215 static struct completer_entry
**glist
;
2216 static int glistlen
= 0;
2217 static int glisttotlen
= 0;
2219 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2222 completer_entries_eq (ent1
, ent2
)
2223 struct completer_entry
*ent1
, *ent2
;
2225 while (ent1
!= NULL
&& ent2
!= NULL
)
2227 if (ent1
->name
->num
!= ent2
->name
->num
2228 || ent1
->bits
!= ent2
->bits
2229 || ent1
->mask
!= ent2
->mask
2230 || ent1
->is_terminal
!= ent2
->is_terminal
2231 || ent1
->dependencies
!= ent2
->dependencies
2232 || ent1
->order
!= ent2
->order
)
2235 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2238 ent1
= ent1
->alternative
;
2239 ent2
= ent2
->alternative
;
2242 return ent1
== ent2
;
2245 /* Insert ENT into the global list of completers and return it. If an
2246 equivalent entry (according to completer_entries_eq) already exists,
2247 it is returned instead. */
2248 static struct completer_entry
*
2249 insert_gclist (struct completer_entry
*ent
)
2257 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2258 ent
->alternative
= insert_gclist (ent
->alternative
);
2263 if (glisttotlen
== glistlen
)
2266 glist
= (struct completer_entry
**)
2267 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2277 if (ent
->name
->num
< glist
[0]->name
->num
)
2279 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2287 i
= (start
+ end
) / 2;
2288 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2295 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2309 while (i
< glistlen
)
2311 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2314 if (completer_entries_eq (ent
, glist
[i
]))
2322 for (; i
> 0 && i
< glistlen
; i
--)
2323 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2326 for (; i
< glistlen
; i
++)
2327 if (ent
->name
->num
< glist
[i
]->name
->num
)
2330 for (x
= glistlen
- 1; x
>= i
; x
--)
2331 glist
[x
+ 1] = glist
[x
];
2340 get_prefix_len (name
)
2345 if (name
[0] == '\0')
2348 c
= strchr (name
, '.');
2352 return strlen (name
);
2356 compute_completer_bits (ment
, ent
)
2357 struct main_entry
*ment
;
2358 struct completer_entry
*ent
;
2362 compute_completer_bits (ment
, ent
->addl_entries
);
2364 if (ent
->is_terminal
)
2367 ia64_insn our_bits
= ent
->bits
;
2368 struct completer_entry
*p
= ent
->parent
;
2372 while (p
!= NULL
&& ! p
->is_terminal
)
2378 p_bits
= ment
->opcode
->opcode
;
2380 for (x
= 0; x
< 64; x
++)
2382 ia64_insn m
= ((ia64_insn
) 1) << x
;
2384 if ((p_bits
& m
) != (our_bits
& m
))
2389 ent
->bits
= our_bits
;
2398 ent
= ent
->alternative
;
2402 /* Find identical completer trees that are used in different
2403 instructions and collapse their entries. */
2405 collapse_redundant_completers (void)
2407 struct main_entry
*ptr
;
2410 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2412 if (ptr
->completers
== NULL
)
2415 compute_completer_bits (ptr
, ptr
->completers
);
2416 ptr
->completers
= insert_gclist (ptr
->completers
);
2419 /* The table has been finalized, now number the indexes. */
2420 for (x
= 0; x
< glistlen
; x
++)
2425 /* Attach two lists of dependencies to each opcode.
2426 1) all resources which, when already marked in use, conflict with this
2428 2) all resources which must be marked in use when this opcode is used
2431 insert_opcode_dependencies (opc
, cmp
)
2432 struct ia64_opcode
*opc
;
2433 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2435 /* Note all resources which point to this opcode. rfi has the most chks
2436 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2439 unsigned short regs
[256];
2441 unsigned short chks
[256];
2442 /* Flag insns for which no class matched; there should be none. */
2443 int no_class_found
= 1;
2445 for (i
= 0; i
< rdepslen
; i
++)
2447 struct rdep
*rs
= rdeps
[i
];
2450 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2451 && strncmp (rs
->name
, "PR%", 3) == 0
2453 no_class_found
= 99;
2455 for (j
=0; j
< rs
->nregs
;j
++)
2459 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2461 /* We can ignore ic_note 11 for non PR resources. */
2462 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2465 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2466 && ic_note
!= rs
->regnotes
[j
]
2467 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2468 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2469 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2470 rs
->name
, rs
->regnotes
[j
]);
2471 /* Instruction class notes override resource notes.
2472 So far, only note 11 applies to an IC instead of a resource,
2473 and note 11 implies note 1. */
2475 regs
[nregs
++] = RDEP(ic_note
, i
);
2477 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2483 for (j
= 0; j
< rs
->nchks
; j
++)
2487 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2489 /* We can ignore ic_note 11 for non PR resources. */
2490 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2493 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2494 && ic_note
!= rs
->chknotes
[j
]
2495 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2496 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2497 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2498 rs
->name
, rs
->chknotes
[j
]);
2500 chks
[nchks
++] = RDEP(ic_note
, i
);
2502 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2510 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2512 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2514 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2518 insert_completer_entry (opc
, tabent
, order
)
2519 struct ia64_opcode
*opc
;
2520 struct main_entry
*tabent
;
2523 struct completer_entry
**ptr
= &tabent
->completers
;
2524 struct completer_entry
*parent
= NULL
;
2525 char pcopy
[129], *prefix
;
2528 if (strlen (opc
->name
) > 128)
2531 strcpy (pcopy
, opc
->name
);
2532 prefix
= pcopy
+ get_prefix_len (pcopy
);
2534 if (prefix
[0] != '\0')
2539 int need_new_ent
= 1;
2540 int plen
= get_prefix_len (prefix
);
2541 struct string_entry
*sent
;
2543 at_end
= (prefix
[plen
] == '\0');
2544 prefix
[plen
] = '\0';
2545 sent
= insert_string (prefix
);
2547 while (*ptr
!= NULL
)
2549 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2557 ptr
= &((*ptr
)->alternative
);
2562 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2565 nent
->parent
= parent
;
2566 nent
->addl_entries
= NULL
;
2567 nent
->alternative
= *ptr
;
2569 nent
->is_terminal
= 0;
2570 nent
->dependencies
= -1;
2576 ptr
= &((*ptr
)->addl_entries
);
2581 if ((*ptr
)->is_terminal
)
2584 (*ptr
)->is_terminal
= 1;
2585 (*ptr
)->mask
= (ia64_insn
)-1;
2586 (*ptr
)->bits
= opc
->opcode
;
2587 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2588 (*ptr
)->order
= order
;
2592 print_completer_entry (ent
)
2593 struct completer_entry
*ent
;
2596 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2600 while (! (mask
& 1))
2607 if (bits
& 0xffffffff00000000LL
)
2611 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2615 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2616 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2618 ent
->is_terminal
? 1 : 0,
2623 print_completer_table ()
2627 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2628 for (x
= 0; x
< glistlen
; x
++)
2629 print_completer_entry (glist
[x
]);
2634 opcodes_eq (opc1
, opc2
)
2635 struct ia64_opcode
*opc1
;
2636 struct ia64_opcode
*opc2
;
2641 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2642 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2643 || (opc1
->flags
!= opc2
->flags
))
2646 for (x
= 0; x
< 5; x
++)
2647 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2650 plen1
= get_prefix_len (opc1
->name
);
2651 plen2
= get_prefix_len (opc2
->name
);
2653 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2660 add_opcode_entry (opc
)
2661 struct ia64_opcode
*opc
;
2663 struct main_entry
**place
;
2664 struct string_entry
*name
;
2668 if (strlen (opc
->name
) > 128)
2672 strcpy (prefix
, opc
->name
);
2673 prefix
[get_prefix_len (prefix
)] = '\0';
2674 name
= insert_string (prefix
);
2676 /* Walk the list of opcode table entries. If it's a new
2677 instruction, allocate and fill in a new entry. Note
2678 the main table is alphabetical by opcode name. */
2680 while (*place
!= NULL
)
2682 if ((*place
)->name
->num
== name
->num
2683 && opcodes_eq ((*place
)->opcode
, opc
))
2688 if ((*place
)->name
->num
> name
->num
)
2691 place
= &((*place
)->next
);
2695 struct main_entry
*nent
= tmalloc (struct main_entry
);
2699 nent
->next
= *place
;
2700 nent
->completers
= 0;
2703 if (otlen
== ottotlen
)
2706 ordered_table
= (struct main_entry
**)
2707 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2709 ordered_table
[otlen
++] = nent
;
2712 insert_completer_entry (opc
, *place
, opcode_count
++);
2716 print_main_table (void)
2718 struct main_entry
*ptr
= maintable
;
2721 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2724 printf (" { %d, %d, %d, 0x",
2727 ptr
->opcode
->num_outputs
);
2728 opcode_fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2730 opcode_fprintf_vma (stdout
, ptr
->opcode
->mask
);
2731 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2732 ptr
->opcode
->operands
[0],
2733 ptr
->opcode
->operands
[1],
2734 ptr
->opcode
->operands
[2],
2735 ptr
->opcode
->operands
[3],
2736 ptr
->opcode
->operands
[4],
2738 ptr
->completers
->num
);
2740 ptr
->main_index
= index
++;
2749 struct ia64_opcode
*table
;
2753 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2755 add_opcode_entry (table
+ curr_opcode
);
2756 if (table
[curr_opcode
].num_outputs
== 2
2757 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2758 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2759 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2760 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2762 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2765 *alias
= table
[curr_opcode
];
2766 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2767 alias
->operands
[i
- 1] = alias
->operands
[i
];
2768 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2769 --alias
->num_outputs
;
2770 alias
->flags
|= PSEUDO
;
2771 add_opcode_entry (alias
);
2777 /* Program options. */
2778 #define OPTION_SRCDIR 200
2780 struct option long_options
[] =
2782 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2783 {"debug", no_argument
, NULL
, 'd'},
2784 {"version", no_argument
, NULL
, 'V'},
2785 {"help", no_argument
, NULL
, 'h'},
2786 {0, no_argument
, NULL
, 0}
2790 print_version (void)
2792 printf ("%s: version 1.0\n", program_name
);
2797 usage (FILE * stream
, int status
)
2799 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2805 main (int argc
, char **argv
)
2807 extern int chdir (char *);
2808 char *srcdir
= NULL
;
2811 program_name
= *argv
;
2812 xmalloc_set_program_name (program_name
);
2814 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2839 if (chdir (srcdir
) != 0)
2840 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2841 srcdir
, strerror (errno
));
2843 load_insn_classes ();
2844 load_dependencies ();
2846 shrink (ia64_opcodes_a
);
2847 shrink (ia64_opcodes_b
);
2848 shrink (ia64_opcodes_f
);
2849 shrink (ia64_opcodes_i
);
2850 shrink (ia64_opcodes_m
);
2851 shrink (ia64_opcodes_x
);
2852 shrink (ia64_opcodes_d
);
2854 collapse_redundant_completers ();
2856 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2857 print_string_table ();
2858 print_dependency_table ();
2859 print_completer_table ();
2860 print_main_table ();
2862 generate_disassembler ();