1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2012
3 Free Software Foundation, Inc.
4 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
6 This file is part of the GNU opcodes library.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 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
24 /* While the ia64-opc-* set of opcode tables are easy to maintain,
25 they waste a tremendous amount of space. ia64-gen rearranges the
26 instructions into a directed acyclic graph (DAG) of instruction opcodes and
27 their possible completers, as well as compacting the set of strings used.
29 The disassembler table consists of a state machine that does
30 branching based on the bits of the opcode being disassembled. The
31 state encodings have been chosen to minimize the amount of space
34 The resource table is constructed based on some text dependency tables,
35 which are also easier to maintain than the final representation. */
42 #include "libiberty.h"
43 #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 (CONST_STRNEQ (full_name
, "IC:"))
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 (const char *ref
, int **usersp
, int *nusersp
,
700 char *line
= xstrdup (ref
);
702 int *users
= *usersp
;
703 int count
= *nusersp
;
704 int *notes
= *notesp
;
716 while (ISSPACE (*tmp
))
719 while (*tmp
&& *tmp
!= ',')
724 xsect
= strchr (name
, '\\');
725 if ((notestr
= strstr (name
, "+")) != NULL
)
729 note
= atoi (notestr
+ 1);
730 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
732 /* Note 13 always implies note 1. */
733 if (strcmp (notestr
, "+1+13") == 0)
735 else if (!xsect
|| nextnotestr
< xsect
)
736 warn (_("multiple note %s not handled\n"), notestr
);
744 /* All classes are created when the insn class table is parsed;
745 Individual instructions might not appear until the dependency tables
746 are read. Only create new classes if it's *not* an insn class,
747 or if it's a composite class (which wouldn't necessarily be in the IC
749 if (! CONST_STRNEQ (name
, "IC:") || xsect
!= NULL
)
752 iclass
= fetch_insn_class (name
, create
);
756 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
758 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
760 users
[count
++] = iclass
;
761 mark_used (ics
[iclass
], 0);
764 printf("Class %s not found\n", name
);
766 /* Update the return values. */
775 parse_semantics (char *sem
)
777 if (strcmp (sem
, "none") == 0)
778 return IA64_DVS_NONE
;
779 else if (strcmp (sem
, "implied") == 0)
780 return IA64_DVS_IMPLIED
;
781 else if (strcmp (sem
, "impliedF") == 0)
782 return IA64_DVS_IMPLIEDF
;
783 else if (strcmp (sem
, "data") == 0)
784 return IA64_DVS_DATA
;
785 else if (strcmp (sem
, "instr") == 0)
786 return IA64_DVS_INSTR
;
787 else if (strcmp (sem
, "specific") == 0)
788 return IA64_DVS_SPECIFIC
;
789 else if (strcmp (sem
, "stop") == 0)
790 return IA64_DVS_STOP
;
792 return IA64_DVS_OTHER
;
796 add_dep (const char *name
, const char *chk
, const char *reg
,
797 int semantics
, int mode
, char *extra
, int flag
)
801 rs
= insert_resource (name
, mode
);
803 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
804 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
806 rs
->semantics
= semantics
;
808 rs
->waw_special
= flag
;
812 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
814 FILE *fp
= fopen (filename
, "r");
818 fail (_("can't find %s for reading\n"), filename
);
820 fgets (buf
, sizeof(buf
), fp
);
828 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
831 while (ISSPACE (buf
[strlen (buf
) - 1]))
832 buf
[strlen (buf
) - 1] = '\0';
839 while (ISSPACE (*tmp
))
842 tmp
= strchr (tmp
, ';');
846 while (ISSPACE (*tmp
))
849 tmp
= strchr (tmp
, ';');
853 while (ISSPACE (*tmp
))
855 semantics
= parse_semantics (tmp
);
856 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
858 /* For WAW entries, if the chks and regs differ, we need to enter the
859 entries in both positions so that the tables will be parsed properly,
860 without a lot of extra work. */
861 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
863 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
864 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
868 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
875 load_dependencies (void)
877 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
878 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
879 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
882 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
885 /* Is the given operand an indirect register file operand? */
887 irf_operand (int op
, const char *field
)
891 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
892 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
893 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
894 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
898 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
899 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
900 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
901 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
902 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
903 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
904 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
905 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
909 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
910 mov_um insn classes. */
912 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
913 const char *format
, const char *field
)
915 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
926 int i
= strcmp (idesc
->name
, "mov.i") == 0;
927 int m
= strcmp (idesc
->name
, "mov.m") == 0;
928 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
929 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
930 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
931 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
932 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
933 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
937 return strstr (format
, "I26") || strstr (format
, "I27");
939 return strstr (format
, "I28") != NULL
;
941 return strstr (format
, "M29") || strstr (format
, "M30");
943 return strstr (format
, "M31") != NULL
;
944 if (pseudo0
|| pseudo1
)
950 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
951 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
953 return strstr (format
, "I22") != NULL
;
955 return strstr (format
, "I21") != NULL
;
960 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
961 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
963 return strstr (format
, "M32") != NULL
;
965 return strstr (format
, "M33") != NULL
;
969 if (ic
->name
[5] == 'n')
971 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
972 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
974 return strstr (format
, "M42") != NULL
;
976 return strstr (format
, "M43") != NULL
;
978 else if (ic
->name
[5] == 'p')
980 return idesc
->operands
[1] == IA64_OPND_IP
;
986 if (ic
->name
[5] == 'r')
988 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
989 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
990 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
992 return strstr (format
, "I23") != NULL
;
994 return strstr (format
, "I24") != NULL
;
996 return strstr (format
, "I25") != NULL
;
998 else if (ic
->name
[5] == 's')
1000 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1001 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1003 return strstr (format
, "M35") != NULL
;
1005 return strstr (format
, "M36") != NULL
;
1012 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1013 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1015 return strstr (format
, "M35") != NULL
;
1017 return strstr (format
, "M36") != NULL
;
1024 /* Is the given opcode in the given insn class? */
1026 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1027 const char *format
, const char *field
, int *notep
)
1034 if (CONST_STRNEQ (ic
->comment
, "Format"))
1036 /* Assume that the first format seen is the most restrictive, and
1037 only keep a later one if it looks like it's more restrictive. */
1040 if (strlen (ic
->comment
) < strlen (format
))
1042 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1043 ic
->comment
, format
);
1044 format
= ic
->comment
;
1048 format
= ic
->comment
;
1050 else if (CONST_STRNEQ (ic
->comment
, "Field"))
1053 warn (_("overlapping field %s->%s\n"),
1054 ic
->comment
, field
);
1055 field
= ic
->comment
;
1059 /* An insn class matches anything that is the same followed by completers,
1060 except when the absence and presence of completers constitutes different
1062 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1064 int is_mov
= CONST_STRNEQ (idesc
->name
, "mov");
1065 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1066 int len
= strlen(ic
->name
);
1068 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1069 && (idesc
->name
[len
] == '\0'
1070 || idesc
->name
[len
] == '.'));
1072 /* All break, nop, and hint variations must match exactly. */
1074 (strcmp (ic
->name
, "break") == 0
1075 || strcmp (ic
->name
, "nop") == 0
1076 || strcmp (ic
->name
, "hint") == 0))
1077 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1079 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1080 unless specifically allowed by clauses in this block. */
1081 if (resolved
&& field
)
1083 /* Check Field(sf)==sN against opcode sN. */
1084 if (strstr(field
, "(sf)==") != NULL
)
1088 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1089 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1091 /* Check Field(lftype)==XXX. */
1092 else if (strstr (field
, "(lftype)") != NULL
)
1094 if (strstr (idesc
->name
, "fault") != NULL
)
1095 resolved
= strstr (field
, "fault") != NULL
;
1097 resolved
= strstr (field
, "fault") == NULL
;
1099 /* Handle Field(ctype)==XXX. */
1100 else if (strstr (field
, "(ctype)") != NULL
)
1102 if (strstr (idesc
->name
, "or.andcm"))
1103 resolved
= strstr (field
, "or.andcm") != NULL
;
1104 else if (strstr (idesc
->name
, "and.orcm"))
1105 resolved
= strstr (field
, "and.orcm") != NULL
;
1106 else if (strstr (idesc
->name
, "orcm"))
1107 resolved
= strstr (field
, "or orcm") != NULL
;
1108 else if (strstr (idesc
->name
, "or"))
1109 resolved
= strstr (field
, "or orcm") != NULL
;
1110 else if (strstr (idesc
->name
, "andcm"))
1111 resolved
= strstr (field
, "and andcm") != NULL
;
1112 else if (strstr (idesc
->name
, "and"))
1113 resolved
= strstr (field
, "and andcm") != NULL
;
1114 else if (strstr (idesc
->name
, "unc"))
1115 resolved
= strstr (field
, "unc") != NULL
;
1117 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1121 if (resolved
&& format
)
1123 if (CONST_STRNEQ (idesc
->name
, "dep")
1124 && strstr (format
, "I13") != NULL
)
1125 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1126 else if (CONST_STRNEQ (idesc
->name
, "chk")
1127 && strstr (format
, "M21") != NULL
)
1128 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1129 else if (CONST_STRNEQ (idesc
->name
, "lfetch"))
1130 resolved
= (strstr (format
, "M14 M15") != NULL
1131 && (idesc
->operands
[1] == IA64_OPND_R2
1132 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1133 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1134 && strstr (format
, "B5") != NULL
)
1135 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1136 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1137 && strstr (format
, "B3") != NULL
)
1138 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1139 else if (CONST_STRNEQ (idesc
->name
, "brp")
1140 && strstr (format
, "B7") != NULL
)
1141 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1142 else if (strcmp (ic
->name
, "invala") == 0)
1143 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1144 else if (CONST_STRNEQ (idesc
->name
, "st")
1145 && (strstr (format
, "M5") != NULL
1146 || strstr (format
, "M10") != NULL
))
1147 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1148 else if (CONST_STRNEQ (idesc
->name
, "ld")
1149 && (strstr (format
, "M2 M3") != NULL
1150 || strstr (format
, "M12") != NULL
1151 || strstr (format
, "M7 M8") != NULL
))
1152 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1157 /* Misc brl variations ('.cond' is optional);
1158 plain brl matches brl.cond. */
1160 && (strcmp (idesc
->name
, "brl") == 0
1161 || CONST_STRNEQ (idesc
->name
, "brl."))
1162 && strcmp (ic
->name
, "brl.cond") == 0)
1167 /* Misc br variations ('.cond' is optional). */
1169 && (strcmp (idesc
->name
, "br") == 0
1170 || CONST_STRNEQ (idesc
->name
, "br."))
1171 && strcmp (ic
->name
, "br.cond") == 0)
1174 resolved
= (strstr (format
, "B4") != NULL
1175 && idesc
->operands
[0] == IA64_OPND_B2
)
1176 || (strstr (format
, "B1") != NULL
1177 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1182 /* probe variations. */
1183 if (!resolved
&& CONST_STRNEQ (idesc
->name
, "probe"))
1185 resolved
= strcmp (ic
->name
, "probe") == 0
1186 && !((strstr (idesc
->name
, "fault") != NULL
)
1187 ^ (format
&& strstr (format
, "M40") != NULL
));
1190 /* mov variations. */
1191 if (!resolved
&& is_mov
)
1195 /* mov alias for fmerge. */
1196 if (strcmp (ic
->name
, "fmerge") == 0)
1198 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1199 && idesc
->operands
[1] == IA64_OPND_F3
;
1201 /* mov alias for adds (r3 or imm14). */
1202 else if (strcmp (ic
->name
, "adds") == 0)
1204 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1205 && (idesc
->operands
[1] == IA64_OPND_R3
1206 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1208 /* mov alias for addl. */
1209 else if (strcmp (ic
->name
, "addl") == 0)
1211 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1212 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1216 /* Some variants of mov and mov.[im]. */
1217 if (!resolved
&& CONST_STRNEQ (ic
->name
, "mov_"))
1218 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1221 /* Keep track of this so we can flag any insn classes which aren't
1222 mapped onto at least one real insn. */
1224 ic
->terminal_resolved
= 1;
1226 else for (i
= 0; i
< ic
->nsubs
; i
++)
1228 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1232 for (j
= 0; j
< ic
->nxsubs
; j
++)
1233 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1237 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1244 /* If it's in this IC, add the IC note (if any) to the insn. */
1247 if (ic
->note
&& notep
)
1249 if (*notep
&& *notep
!= ic
->note
)
1250 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1251 *notep
, ic
->note
, ic
->name
);
1262 lookup_regindex (const char *name
, int specifier
)
1267 if (strstr (name
, "[RSC]"))
1269 if (strstr (name
, "[BSP]"))
1271 else if (strstr (name
, "[BSPSTORE]"))
1273 else if (strstr (name
, "[RNAT]"))
1275 else if (strstr (name
, "[FCR]"))
1277 else if (strstr (name
, "[EFLAG]"))
1279 else if (strstr (name
, "[CSD]"))
1281 else if (strstr (name
, "[SSD]"))
1283 else if (strstr (name
, "[CFLG]"))
1285 else if (strstr (name
, "[FSR]"))
1287 else if (strstr (name
, "[FIR]"))
1289 else if (strstr (name
, "[FDR]"))
1291 else if (strstr (name
, "[CCV]"))
1293 else if (strstr (name
, "[ITC]"))
1295 else if (strstr (name
, "[RUC]"))
1297 else if (strstr (name
, "[PFS]"))
1299 else if (strstr (name
, "[LC]"))
1301 else if (strstr (name
, "[EC]"))
1305 if (strstr (name
, "[DCR]"))
1307 else if (strstr (name
, "[ITM]"))
1309 else if (strstr (name
, "[IVA]"))
1311 else if (strstr (name
, "[PTA]"))
1313 else if (strstr (name
, "[GPTA]"))
1315 else if (strstr (name
, "[IPSR]"))
1317 else if (strstr (name
, "[ISR]"))
1319 else if (strstr (name
, "[IIP]"))
1321 else if (strstr (name
, "[IFA]"))
1323 else if (strstr (name
, "[ITIR]"))
1325 else if (strstr (name
, "[IIPA]"))
1327 else if (strstr (name
, "[IFS]"))
1329 else if (strstr (name
, "[IIM]"))
1331 else if (strstr (name
, "[IHA]"))
1333 else if (strstr (name
, "[LID]"))
1335 else if (strstr (name
, "[IVR]"))
1337 else if (strstr (name
, "[TPR]"))
1339 else if (strstr (name
, "[EOI]"))
1341 else if (strstr (name
, "[ITV]"))
1343 else if (strstr (name
, "[PMV]"))
1345 else if (strstr (name
, "[CMCV]"))
1349 if (strstr (name
, ".be"))
1351 else if (strstr (name
, ".up"))
1353 else if (strstr (name
, ".ac"))
1355 else if (strstr (name
, ".mfl"))
1357 else if (strstr (name
, ".mfh"))
1359 else if (strstr (name
, ".ic"))
1361 else if (strstr (name
, ".i"))
1363 else if (strstr (name
, ".pk"))
1365 else if (strstr (name
, ".dt"))
1367 else if (strstr (name
, ".dfl"))
1369 else if (strstr (name
, ".dfh"))
1371 else if (strstr (name
, ".sp"))
1373 else if (strstr (name
, ".pp"))
1375 else if (strstr (name
, ".di"))
1377 else if (strstr (name
, ".si"))
1379 else if (strstr (name
, ".db"))
1381 else if (strstr (name
, ".lp"))
1383 else if (strstr (name
, ".tb"))
1385 else if (strstr (name
, ".rt"))
1387 else if (strstr (name
, ".cpl"))
1389 else if (strstr (name
, ".rs"))
1391 else if (strstr (name
, ".mc"))
1393 else if (strstr (name
, ".it"))
1395 else if (strstr (name
, ".id"))
1397 else if (strstr (name
, ".da"))
1399 else if (strstr (name
, ".dd"))
1401 else if (strstr (name
, ".ss"))
1403 else if (strstr (name
, ".ri"))
1405 else if (strstr (name
, ".ed"))
1407 else if (strstr (name
, ".bn"))
1409 else if (strstr (name
, ".ia"))
1411 else if (strstr (name
, ".vm"))
1422 lookup_specifier (const char *name
)
1424 if (strchr (name
, '%'))
1426 if (strstr (name
, "AR[K%]") != NULL
)
1427 return IA64_RS_AR_K
;
1428 if (strstr (name
, "AR[UNAT]") != NULL
)
1429 return IA64_RS_AR_UNAT
;
1430 if (strstr (name
, "AR%, % in 8") != NULL
)
1432 if (strstr (name
, "AR%, % in 48") != NULL
)
1434 if (strstr (name
, "BR%") != NULL
)
1436 if (strstr (name
, "CR[IIB%]") != NULL
)
1437 return IA64_RS_CR_IIB
;
1438 if (strstr (name
, "CR[IRR%]") != NULL
)
1439 return IA64_RS_CR_IRR
;
1440 if (strstr (name
, "CR[LRR%]") != NULL
)
1441 return IA64_RS_CR_LRR
;
1442 if (strstr (name
, "CR%") != NULL
)
1444 if (strstr (name
, "FR%, % in 0") != NULL
)
1446 if (strstr (name
, "FR%, % in 2") != NULL
)
1448 if (strstr (name
, "GR%") != NULL
)
1450 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1452 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1455 warn (_("don't know how to specify %% dependency %s\n"),
1458 else if (strchr (name
, '#'))
1460 if (strstr (name
, "CPUID#") != NULL
)
1461 return IA64_RS_CPUID
;
1462 if (strstr (name
, "DBR#") != NULL
)
1464 if (strstr (name
, "IBR#") != NULL
)
1466 if (strstr (name
, "MSR#") != NULL
)
1468 if (strstr (name
, "PKR#") != NULL
)
1470 if (strstr (name
, "PMC#") != NULL
)
1472 if (strstr (name
, "PMD#") != NULL
)
1474 if (strstr (name
, "RR#") != NULL
)
1477 warn (_("Don't know how to specify # dependency %s\n"),
1480 else if (CONST_STRNEQ (name
, "AR[FPSR]"))
1481 return IA64_RS_AR_FPSR
;
1482 else if (CONST_STRNEQ (name
, "AR["))
1484 else if (CONST_STRNEQ (name
, "CR["))
1486 else if (CONST_STRNEQ (name
, "PSR."))
1488 else if (strcmp (name
, "InService*") == 0)
1489 return IA64_RS_INSERVICE
;
1490 else if (strcmp (name
, "GR0") == 0)
1492 else if (strcmp (name
, "CFM") == 0)
1494 else if (strcmp (name
, "PR63") == 0)
1495 return IA64_RS_PR63
;
1496 else if (strcmp (name
, "RSE") == 0)
1503 print_dependency_table (void)
1509 for (i
=0;i
< iclen
;i
++)
1511 if (ics
[i
]->is_class
)
1515 if (ics
[i
]->comment
)
1516 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1517 ics
[i
]->name
, ics
[i
]->comment
);
1519 warn (_("IC:%s has no terminals or sub-classes\n"),
1525 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1527 if (ics
[i
]->comment
)
1528 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1529 ics
[i
]->name
, ics
[i
]->comment
);
1531 warn (_("no insns mapped directly to terminal IC %s\n"),
1537 for (i
= 0; i
< iclen
; i
++)
1541 mark_used (ics
[i
], 1);
1542 warn (_("class %s is defined but not used\n"),
1548 for (i
= 0; i
< rdepslen
; i
++)
1550 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1552 if (rdeps
[i
]->total_chks
== 0)
1554 if (rdeps
[i
]->total_regs
)
1555 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1556 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1558 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1559 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1561 else if (rdeps
[i
]->total_regs
== 0)
1562 warn (_("rsrc %s (%s) has no regs\n"),
1563 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1567 /* The dependencies themselves. */
1568 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1569 for (i
= 0; i
< rdepslen
; i
++)
1571 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1573 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1574 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1576 printf (" { \"%s\", %d, %d, %d, %d, ",
1577 rdeps
[i
]->name
, specifier
,
1578 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1579 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1581 const char *quote
, *rest
;
1584 rest
= rdeps
[i
]->extra
;
1585 quote
= strchr (rest
, '\"');
1586 while (quote
!= NULL
)
1588 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1590 quote
= strchr (rest
, '\"');
1592 printf ("%s\", ", rest
);
1600 /* And dependency lists. */
1601 for (i
=0;i
< dlistlen
;i
++)
1604 printf ("static const unsigned short dep%d[] = {\n ", i
);
1605 for (j
=0;j
< dlists
[i
]->len
; j
++)
1607 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1614 printf ("\n};\n\n");
1617 /* And opcode dependency list. */
1618 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1619 printf ("static const struct ia64_opcode_dependency\n");
1620 printf ("op_dependencies[] = {\n");
1621 for (i
= 0; i
< opdeplen
; i
++)
1624 if (opdeps
[i
]->chk
== -1)
1625 printf ("0, NULL, ");
1627 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1628 if (opdeps
[i
]->reg
== -1)
1629 printf ("0, NULL, ");
1631 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1638 /* Add STR to the string table. */
1639 static struct string_entry
*
1640 insert_string (char *str
)
1642 int start
= 0, end
= strtablen
;
1645 if (strtablen
== strtabtotlen
)
1648 string_table
= (struct string_entry
**)
1649 xrealloc (string_table
,
1650 sizeof (struct string_entry
**) * strtabtotlen
);
1656 string_table
[0] = tmalloc (struct string_entry
);
1657 string_table
[0]->s
= xstrdup (str
);
1658 string_table
[0]->num
= 0;
1659 return string_table
[0];
1662 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1664 else if (strcmp (str
, string_table
[0]->s
) < 0)
1672 i
= (start
+ end
) / 2;
1673 c
= strcmp (str
, string_table
[i
]->s
);
1678 return string_table
[i
];
1687 for (; i
> 0 && i
< strtablen
; i
--)
1688 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1691 for (; i
< strtablen
; i
++)
1692 if (strcmp (str
, string_table
[i
]->s
) < 0)
1695 for (x
= strtablen
- 1; x
>= i
; x
--)
1697 string_table
[x
+ 1] = string_table
[x
];
1698 string_table
[x
+ 1]->num
= x
+ 1;
1701 string_table
[i
] = tmalloc (struct string_entry
);
1702 string_table
[i
]->s
= xstrdup (str
);
1703 string_table
[i
]->num
= i
;
1706 return string_table
[i
];
1709 static struct bittree
*
1710 make_bittree_entry (void)
1712 struct bittree
*res
= tmalloc (struct bittree
);
1715 res
->bits
[0] = NULL
;
1716 res
->bits
[1] = NULL
;
1717 res
->bits
[2] = NULL
;
1719 res
->bits_to_skip
= 0;
1724 static struct disent
*
1725 add_dis_table_ent (struct disent
*which
, int insn
, int order
,
1726 int completer_index
)
1736 while (ent
->nexte
!= NULL
)
1739 ent
= (ent
->nexte
= tmalloc (struct disent
));
1743 ent
= tmalloc (struct disent
);
1744 ent
->next_ent
= disinsntable
;
1751 ent
->priority
= order
;
1753 while (completer_index
!= 1)
1755 ci
= (ci
<< 1) | (completer_index
& 1);
1756 completer_index
>>= 1;
1758 ent
->completer_index
= ci
;
1763 finish_distable (void)
1765 struct disent
*ent
= disinsntable
;
1766 struct disent
*prev
= ent
;
1768 ent
->ournum
= 32768;
1769 while ((ent
= ent
->next_ent
) != NULL
)
1771 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1777 insert_bit_table_ent (struct bittree
*curr_ent
, int bit
, ia64_insn opcode
,
1778 ia64_insn mask
, int opcodenum
, int order
,
1779 int completer_index
)
1783 struct bittree
*next
;
1787 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1790 curr_ent
->disent
= nent
;
1794 m
= ((ia64_insn
) 1) << bit
;
1797 b
= (opcode
& m
) ? 1 : 0;
1801 next
= curr_ent
->bits
[b
];
1804 next
= make_bittree_entry ();
1805 curr_ent
->bits
[b
] = next
;
1807 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1812 add_dis_entry (struct bittree
*first
, ia64_insn opcode
, ia64_insn mask
,
1813 int opcodenum
, struct completer_entry
*ent
, int completer_index
)
1815 if (completer_index
& (1 << 20))
1820 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1821 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1822 (completer_index
<< 1) | 1);
1824 if (ent
->is_terminal
)
1826 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1827 opcodenum
, opcode_count
- ent
->order
- 1,
1828 (completer_index
<< 1) | 1);
1830 completer_index
<<= 1;
1831 ent
= ent
->alternative
;
1835 /* This optimization pass combines multiple "don't care" nodes. */
1837 compact_distree (struct bittree
*ent
)
1839 #define IS_SKIP(ent) \
1840 ((ent->bits[2] !=NULL) \
1841 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1844 struct bittree
*nent
= ent
;
1847 while (IS_SKIP (nent
))
1850 nent
= nent
->bits
[2];
1855 struct bittree
*next
= ent
->bits
[2];
1857 ent
->bits
[0] = nent
->bits
[0];
1858 ent
->bits
[1] = nent
->bits
[1];
1859 ent
->bits
[2] = nent
->bits
[2];
1860 ent
->disent
= nent
->disent
;
1862 ent
->bits_to_skip
= bitcnt
;
1863 while (next
!= nent
)
1865 struct bittree
*b
= next
;
1866 next
= next
->bits
[2];
1872 for (x
= 0; x
< 3; x
++)
1874 struct bittree
*i
= ent
->bits
[x
];
1877 compact_distree (i
);
1881 static unsigned char *insn_list
;
1882 static int insn_list_len
= 0;
1883 static int tot_insn_list_len
= 0;
1885 /* Generate the disassembler state machine corresponding to the tree
1888 gen_dis_table (struct bittree
*ent
)
1891 int our_offset
= insn_list_len
;
1893 int totbits
= bitsused
;
1896 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1898 /* If this is a terminal entry, there's no point in skipping any
1900 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1901 ent
->bits
[2] == NULL
)
1903 if (ent
->disent
== NULL
)
1909 /* Calculate the amount of space needed for this entry, or at least
1910 a conservatively large approximation. */
1914 for (x
= 1; x
< 3; x
++)
1915 if (ent
->bits
[x
] != NULL
)
1918 if (ent
->disent
!= NULL
)
1920 if (ent
->bits
[2] != NULL
)
1926 /* Now allocate the space. */
1927 needed_bytes
= (totbits
+ 7) / 8;
1928 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1930 tot_insn_list_len
+= 256;
1931 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1933 our_offset
= insn_list_len
;
1934 insn_list_len
+= needed_bytes
;
1935 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1937 /* Encode the skip entry by setting bit 6 set in the state op field,
1938 and store the # of bits to skip immediately after. */
1942 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1943 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1946 #define IS_ONLY_IFZERO(ENT) \
1947 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1948 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1950 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1952 if (ent
->bits
[0] != NULL
)
1954 struct bittree
*nent
= ent
->bits
[0];
1957 insn_list
[our_offset
] |= 0x80;
1959 /* We can encode sequences of multiple "if (bit is zero)" tests
1960 by storing the # of zero bits to check in the lower 3 bits of
1961 the instruction. However, this only applies if the state
1962 solely tests for a zero bit. */
1964 if (IS_ONLY_IFZERO (ent
))
1966 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1968 nent
= nent
->bits
[0];
1972 insn_list
[our_offset
+ 0] |= zero_count
;
1974 zero_dest
= insn_list_len
;
1975 gen_dis_table (nent
);
1978 /* Now store the remaining tests. We also handle a sole "termination
1979 entry" by storing it as an "any bit" test. */
1981 for (x
= 1; x
< 3; x
++)
1983 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1985 struct bittree
*i
= ent
->bits
[x
];
1991 /* If the instruction being branched to only consists of
1992 a termination entry, use the termination entry as the
1993 place to branch to instead. */
1994 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1995 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1997 idest
= i
->disent
->ournum
;
2001 idest
= insn_list_len
- our_offset
;
2004 idest
= ent
->disent
->ournum
;
2006 /* If the destination offset for the if (bit is 1) test is less
2007 than 256 bytes away, we can store it as 8-bits instead of 16;
2008 the instruction has bit 5 set for the 16-bit address, and bit
2009 4 for the 8-bit address. Since we've already allocated 16
2010 bits for the address we need to deallocate the space.
2012 Note that branchings within the table are relative, and
2013 there are no branches that branch past our instruction yet
2014 so we do not need to adjust any other offsets. */
2019 int start
= our_offset
+ bitsused
/ 8 + 1;
2021 memmove (insn_list
+ start
,
2022 insn_list
+ start
+ 1,
2023 insn_list_len
- (start
+ 1));
2028 insn_list
[our_offset
] |= 0x10;
2032 insn_list
[our_offset
] |= 0x20;
2036 /* An instruction which solely consists of a termination
2037 marker and whose disassembly name index is < 4096
2038 can be stored in 16 bits. The encoding is slightly
2039 odd; the upper 4 bits of the instruction are 0x3, and
2040 bit 3 loses its normal meaning. */
2042 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2043 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2044 && ent
->disent
!= NULL
2045 && ent
->disent
->ournum
< (32768 + 4096))
2047 int start
= our_offset
+ bitsused
/ 8 + 1;
2049 memmove (insn_list
+ start
,
2050 insn_list
+ start
+ 1,
2051 insn_list_len
- (start
+ 1));
2057 insn_list
[our_offset
] |= 0x30;
2061 insn_list
[our_offset
] |= 0x08;
2070 else if (! (id
& 32768))
2074 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2076 printf ("%d: try %d\n", our_offset
, id
);
2079 /* Store the address of the entry being branched to. */
2080 while (currbits
>= 0)
2082 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2084 if (idest
& (1 << currbits
))
2085 *byte
|= (1 << (7 - (bitsused
% 8)));
2091 /* Now generate the states for the entry being branched to. */
2100 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2102 if (ent
->bits
[0] != NULL
)
2103 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2107 if (bitsused
!= totbits
)
2112 print_dis_table (void)
2115 struct disent
*cent
= disinsntable
;
2117 printf ("static const char dis_table[] = {\n");
2118 for (x
= 0; x
< insn_list_len
; x
++)
2120 if ((x
> 0) && ((x
% 12) == 0))
2123 printf ("0x%02x, ", insn_list
[x
]);
2125 printf ("\n};\n\n");
2127 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2128 while (cent
!= NULL
)
2130 struct disent
*ent
= cent
;
2134 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2135 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2139 cent
= cent
->next_ent
;
2145 generate_disassembler (void)
2149 bittree
= make_bittree_entry ();
2151 for (i
= 0; i
< otlen
; i
++)
2153 struct main_entry
*ptr
= ordered_table
[i
];
2155 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2156 add_dis_entry (bittree
,
2157 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2159 ptr
->completers
, 1);
2162 compact_distree (bittree
);
2164 gen_dis_table (bittree
);
2170 print_string_table (void)
2173 char lbuf
[80], buf
[80];
2176 printf ("static const char * const ia64_strings[] = {\n");
2179 for (x
= 0; x
< strtablen
; x
++)
2183 if (strlen (string_table
[x
]->s
) > 75)
2186 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2189 if ((blen
+ len
) > 75)
2191 printf (" %s\n", lbuf
);
2200 printf (" %s\n", lbuf
);
2205 static struct completer_entry
**glist
;
2206 static int glistlen
= 0;
2207 static int glisttotlen
= 0;
2209 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2212 completer_entries_eq (struct completer_entry
*ent1
,
2213 struct completer_entry
*ent2
)
2215 while (ent1
!= NULL
&& ent2
!= NULL
)
2217 if (ent1
->name
->num
!= ent2
->name
->num
2218 || ent1
->bits
!= ent2
->bits
2219 || ent1
->mask
!= ent2
->mask
2220 || ent1
->is_terminal
!= ent2
->is_terminal
2221 || ent1
->dependencies
!= ent2
->dependencies
2222 || ent1
->order
!= ent2
->order
)
2225 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2228 ent1
= ent1
->alternative
;
2229 ent2
= ent2
->alternative
;
2232 return ent1
== ent2
;
2235 /* Insert ENT into the global list of completers and return it. If an
2236 equivalent entry (according to completer_entries_eq) already exists,
2237 it is returned instead. */
2238 static struct completer_entry
*
2239 insert_gclist (struct completer_entry
*ent
)
2247 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2248 ent
->alternative
= insert_gclist (ent
->alternative
);
2253 if (glisttotlen
== glistlen
)
2256 glist
= (struct completer_entry
**)
2257 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2267 if (ent
->name
->num
< glist
[0]->name
->num
)
2269 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2277 i
= (start
+ end
) / 2;
2278 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2285 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2299 while (i
< glistlen
)
2301 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2304 if (completer_entries_eq (ent
, glist
[i
]))
2312 for (; i
> 0 && i
< glistlen
; i
--)
2313 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2316 for (; i
< glistlen
; i
++)
2317 if (ent
->name
->num
< glist
[i
]->name
->num
)
2320 for (x
= glistlen
- 1; x
>= i
; x
--)
2321 glist
[x
+ 1] = glist
[x
];
2330 get_prefix_len (const char *name
)
2334 if (name
[0] == '\0')
2337 c
= strchr (name
, '.');
2341 return strlen (name
);
2345 compute_completer_bits (struct main_entry
*ment
, struct completer_entry
*ent
)
2349 compute_completer_bits (ment
, ent
->addl_entries
);
2351 if (ent
->is_terminal
)
2354 ia64_insn our_bits
= ent
->bits
;
2355 struct completer_entry
*p
= ent
->parent
;
2359 while (p
!= NULL
&& ! p
->is_terminal
)
2365 p_bits
= ment
->opcode
->opcode
;
2367 for (x
= 0; x
< 64; x
++)
2369 ia64_insn m
= ((ia64_insn
) 1) << x
;
2371 if ((p_bits
& m
) != (our_bits
& m
))
2376 ent
->bits
= our_bits
;
2385 ent
= ent
->alternative
;
2389 /* Find identical completer trees that are used in different
2390 instructions and collapse their entries. */
2392 collapse_redundant_completers (void)
2394 struct main_entry
*ptr
;
2397 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2399 if (ptr
->completers
== NULL
)
2402 compute_completer_bits (ptr
, ptr
->completers
);
2403 ptr
->completers
= insert_gclist (ptr
->completers
);
2406 /* The table has been finalized, now number the indexes. */
2407 for (x
= 0; x
< glistlen
; x
++)
2412 /* Attach two lists of dependencies to each opcode.
2413 1) all resources which, when already marked in use, conflict with this
2415 2) all resources which must be marked in use when this opcode is used
2418 insert_opcode_dependencies (struct ia64_opcode
*opc
,
2419 struct completer_entry
*cmp ATTRIBUTE_UNUSED
)
2421 /* Note all resources which point to this opcode. rfi has the most chks
2422 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2425 unsigned short regs
[256];
2427 unsigned short chks
[256];
2428 /* Flag insns for which no class matched; there should be none. */
2429 int no_class_found
= 1;
2431 for (i
= 0; i
< rdepslen
; i
++)
2433 struct rdep
*rs
= rdeps
[i
];
2436 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2437 && CONST_STRNEQ (rs
->name
, "PR%")
2439 no_class_found
= 99;
2441 for (j
=0; j
< rs
->nregs
;j
++)
2445 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2447 /* We can ignore ic_note 11 for non PR resources. */
2448 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2451 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2452 && ic_note
!= rs
->regnotes
[j
]
2453 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2454 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2455 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2456 rs
->name
, rs
->regnotes
[j
]);
2457 /* Instruction class notes override resource notes.
2458 So far, only note 11 applies to an IC instead of a resource,
2459 and note 11 implies note 1. */
2461 regs
[nregs
++] = RDEP(ic_note
, i
);
2463 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2469 for (j
= 0; j
< rs
->nchks
; j
++)
2473 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2475 /* We can ignore ic_note 11 for non PR resources. */
2476 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2479 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2480 && ic_note
!= rs
->chknotes
[j
]
2481 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2482 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2483 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2484 rs
->name
, rs
->chknotes
[j
]);
2486 chks
[nchks
++] = RDEP(ic_note
, i
);
2488 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2496 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2498 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2500 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2504 insert_completer_entry (struct ia64_opcode
*opc
, struct main_entry
*tabent
,
2507 struct completer_entry
**ptr
= &tabent
->completers
;
2508 struct completer_entry
*parent
= NULL
;
2509 char pcopy
[129], *prefix
;
2512 if (strlen (opc
->name
) > 128)
2515 strcpy (pcopy
, opc
->name
);
2516 prefix
= pcopy
+ get_prefix_len (pcopy
);
2518 if (prefix
[0] != '\0')
2523 int need_new_ent
= 1;
2524 int plen
= get_prefix_len (prefix
);
2525 struct string_entry
*sent
;
2527 at_end
= (prefix
[plen
] == '\0');
2528 prefix
[plen
] = '\0';
2529 sent
= insert_string (prefix
);
2531 while (*ptr
!= NULL
)
2533 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2541 ptr
= &((*ptr
)->alternative
);
2546 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2549 nent
->parent
= parent
;
2550 nent
->addl_entries
= NULL
;
2551 nent
->alternative
= *ptr
;
2553 nent
->is_terminal
= 0;
2554 nent
->dependencies
= -1;
2560 ptr
= &((*ptr
)->addl_entries
);
2565 if ((*ptr
)->is_terminal
)
2568 (*ptr
)->is_terminal
= 1;
2569 (*ptr
)->mask
= (ia64_insn
)-1;
2570 (*ptr
)->bits
= opc
->opcode
;
2571 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2572 (*ptr
)->order
= order
;
2576 print_completer_entry (struct completer_entry
*ent
)
2579 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2583 while (! (mask
& 1))
2590 if (bits
& 0xffffffff00000000LL
)
2594 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2598 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2599 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2601 ent
->is_terminal
? 1 : 0,
2606 print_completer_table (void)
2610 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2611 for (x
= 0; x
< glistlen
; x
++)
2612 print_completer_entry (glist
[x
]);
2617 opcodes_eq (struct ia64_opcode
*opc1
, struct ia64_opcode
*opc2
)
2622 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2623 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2624 || (opc1
->flags
!= opc2
->flags
))
2627 for (x
= 0; x
< 5; x
++)
2628 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2631 plen1
= get_prefix_len (opc1
->name
);
2632 plen2
= get_prefix_len (opc2
->name
);
2634 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2641 add_opcode_entry (struct ia64_opcode
*opc
)
2643 struct main_entry
**place
;
2644 struct string_entry
*name
;
2648 if (strlen (opc
->name
) > 128)
2652 strcpy (prefix
, opc
->name
);
2653 prefix
[get_prefix_len (prefix
)] = '\0';
2654 name
= insert_string (prefix
);
2656 /* Walk the list of opcode table entries. If it's a new
2657 instruction, allocate and fill in a new entry. Note
2658 the main table is alphabetical by opcode name. */
2660 while (*place
!= NULL
)
2662 if ((*place
)->name
->num
== name
->num
2663 && opcodes_eq ((*place
)->opcode
, opc
))
2668 if ((*place
)->name
->num
> name
->num
)
2671 place
= &((*place
)->next
);
2675 struct main_entry
*nent
= tmalloc (struct main_entry
);
2679 nent
->next
= *place
;
2680 nent
->completers
= 0;
2683 if (otlen
== ottotlen
)
2686 ordered_table
= (struct main_entry
**)
2687 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2689 ordered_table
[otlen
++] = nent
;
2692 insert_completer_entry (opc
, *place
, opcode_count
++);
2696 print_main_table (void)
2698 struct main_entry
*ptr
= maintable
;
2701 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2704 printf (" { %d, %d, %d, 0x",
2707 ptr
->opcode
->num_outputs
);
2708 opcode_fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2710 opcode_fprintf_vma (stdout
, ptr
->opcode
->mask
);
2711 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2712 ptr
->opcode
->operands
[0],
2713 ptr
->opcode
->operands
[1],
2714 ptr
->opcode
->operands
[2],
2715 ptr
->opcode
->operands
[3],
2716 ptr
->opcode
->operands
[4],
2718 ptr
->completers
->num
);
2720 ptr
->main_index
= tindex
++;
2728 shrink (struct ia64_opcode
*table
)
2732 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2734 add_opcode_entry (table
+ curr_opcode
);
2735 if (table
[curr_opcode
].num_outputs
== 2
2736 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2737 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2738 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2739 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2741 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2744 *alias
= table
[curr_opcode
];
2745 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2746 alias
->operands
[i
- 1] = alias
->operands
[i
];
2747 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2748 --alias
->num_outputs
;
2749 alias
->flags
|= PSEUDO
;
2750 add_opcode_entry (alias
);
2756 /* Program options. */
2757 #define OPTION_SRCDIR 200
2759 struct option long_options
[] =
2761 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2762 {"debug", no_argument
, NULL
, 'd'},
2763 {"version", no_argument
, NULL
, 'V'},
2764 {"help", no_argument
, NULL
, 'h'},
2765 {0, no_argument
, NULL
, 0}
2769 print_version (void)
2771 printf ("%s: version 1.0\n", program_name
);
2776 usage (FILE * stream
, int status
)
2778 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2784 main (int argc
, char **argv
)
2786 extern int chdir (char *);
2787 char *srcdir
= NULL
;
2790 program_name
= *argv
;
2791 xmalloc_set_program_name (program_name
);
2793 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2818 if (chdir (srcdir
) != 0)
2819 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2820 srcdir
, strerror (errno
));
2822 load_insn_classes ();
2823 load_dependencies ();
2825 shrink (ia64_opcodes_a
);
2826 shrink (ia64_opcodes_b
);
2827 shrink (ia64_opcodes_f
);
2828 shrink (ia64_opcodes_i
);
2829 shrink (ia64_opcodes_m
);
2830 shrink (ia64_opcodes_x
);
2831 shrink (ia64_opcodes_d
);
2833 collapse_redundant_completers ();
2835 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2836 printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\
2838 This file is part of the GNU opcodes library.\n\
2840 This library is free software; you can redistribute it and/or modify\n\
2841 it under the terms of the GNU General Public License as published by\n\
2842 the Free Software Foundation; either version 3, or (at your option)\n\
2843 any later version.\n\
2845 It is distributed in the hope that it will be useful, but WITHOUT\n\
2846 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2847 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2848 License for more details.\n\
2850 You should have received a copy of the GNU General Public License\n\
2851 along with this program; see the file COPYING. If not, write to the\n\
2852 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2853 02110-1301, USA. */\n");
2855 print_string_table ();
2856 print_dependency_table ();
2857 print_completer_table ();
2858 print_main_table ();
2860 generate_disassembler ();