1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright (C) 1999-2014 Free Software Foundation, Inc.
3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this file; see the file COPYING. If not, write to the
19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 /* While the ia64-opc-* set of opcode tables are easy to maintain,
24 they waste a tremendous amount of space. ia64-gen rearranges the
25 instructions into a directed acyclic graph (DAG) of instruction opcodes and
26 their possible completers, as well as compacting the set of strings used.
28 The disassembler table consists of a state machine that does
29 branching based on the bits of the opcode being disassembled. The
30 state encodings have been chosen to minimize the amount of space
33 The resource table is constructed based on some text dependency tables,
34 which are also easier to maintain than the final representation. */
41 #include "libiberty.h"
42 #include "safe-ctype.h"
45 #include "ia64-opc-a.c"
46 #include "ia64-opc-i.c"
47 #include "ia64-opc-m.c"
48 #include "ia64-opc-b.c"
49 #include "ia64-opc-f.c"
50 #include "ia64-opc-x.c"
51 #include "ia64-opc-d.c"
54 #define _(String) gettext (String)
56 /* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this
57 always, because we might be compiled without BFD64 defined, if configured
58 for a 32-bit target and --enable-targets=all is used. This will work for
59 both 32-bit and 64-bit hosts. */
60 #define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
61 #define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
62 #define opcode_fprintf_vma(s,x) \
63 fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
65 const char * program_name
= NULL
;
68 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
69 #define tmalloc(X) (X *) xmalloc (sizeof (X))
71 typedef unsigned long long ci_t
;
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. */
149 ci_t completer_index
;
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, ci_t
);
294 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, ci_t
);
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, ci_t
);
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"))
906 || (op
== IA64_OPND_DAHR_R3
&& strstr (field
, "dahr")));
910 /* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
911 * mov_psr, and mov_um insn classes. */
913 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
914 const char *format
, const char *field
)
916 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
927 int i
= strcmp (idesc
->name
, "mov.i") == 0;
928 int m
= strcmp (idesc
->name
, "mov.m") == 0;
929 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
930 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
931 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
932 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
933 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
934 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
938 return strstr (format
, "I26") || strstr (format
, "I27");
940 return strstr (format
, "I28") != NULL
;
942 return strstr (format
, "M29") || strstr (format
, "M30");
944 return strstr (format
, "M31") != NULL
;
945 if (pseudo0
|| pseudo1
)
951 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
952 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
954 return strstr (format
, "I22") != NULL
;
956 return strstr (format
, "I21") != NULL
;
961 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
962 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
964 return strstr (format
, "M32") != NULL
;
966 return strstr (format
, "M33") != NULL
;
971 int m50
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_DAHR3
;
973 return strstr (format
, "M50") != NULL
;
977 if (ic
->name
[5] == 'n')
979 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
980 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
982 return strstr (format
, "M42") != NULL
;
984 return strstr (format
, "M43") != NULL
;
986 else if (ic
->name
[5] == 'p')
988 return idesc
->operands
[1] == IA64_OPND_IP
;
994 if (ic
->name
[5] == 'r')
996 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
997 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
998 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
1000 return strstr (format
, "I23") != NULL
;
1002 return strstr (format
, "I24") != NULL
;
1004 return strstr (format
, "I25") != NULL
;
1006 else if (ic
->name
[5] == 's')
1008 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1009 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1011 return strstr (format
, "M35") != NULL
;
1013 return strstr (format
, "M36") != NULL
;
1020 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1021 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1023 return strstr (format
, "M35") != NULL
;
1025 return strstr (format
, "M36") != NULL
;
1032 /* Is the given opcode in the given insn class? */
1034 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1035 const char *format
, const char *field
, int *notep
)
1042 if (CONST_STRNEQ (ic
->comment
, "Format"))
1044 /* Assume that the first format seen is the most restrictive, and
1045 only keep a later one if it looks like it's more restrictive. */
1048 if (strlen (ic
->comment
) < strlen (format
))
1050 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1051 ic
->comment
, format
);
1052 format
= ic
->comment
;
1056 format
= ic
->comment
;
1058 else if (CONST_STRNEQ (ic
->comment
, "Field"))
1061 warn (_("overlapping field %s->%s\n"),
1062 ic
->comment
, field
);
1063 field
= ic
->comment
;
1067 /* An insn class matches anything that is the same followed by completers,
1068 except when the absence and presence of completers constitutes different
1070 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1072 int is_mov
= CONST_STRNEQ (idesc
->name
, "mov");
1073 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1074 int len
= strlen(ic
->name
);
1076 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1077 && (idesc
->name
[len
] == '\0'
1078 || idesc
->name
[len
] == '.'));
1080 /* All break, nop, and hint variations must match exactly. */
1082 (strcmp (ic
->name
, "break") == 0
1083 || strcmp (ic
->name
, "nop") == 0
1084 || strcmp (ic
->name
, "hint") == 0))
1085 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1087 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1088 unless specifically allowed by clauses in this block. */
1089 if (resolved
&& field
)
1091 /* Check Field(sf)==sN against opcode sN. */
1092 if (strstr(field
, "(sf)==") != NULL
)
1096 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1097 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1099 /* Check Field(lftype)==XXX. */
1100 else if (strstr (field
, "(lftype)") != NULL
)
1102 if (strstr (idesc
->name
, "fault") != NULL
)
1103 resolved
= strstr (field
, "fault") != NULL
;
1105 resolved
= strstr (field
, "fault") == NULL
;
1107 /* Handle Field(ctype)==XXX. */
1108 else if (strstr (field
, "(ctype)") != NULL
)
1110 if (strstr (idesc
->name
, "or.andcm"))
1111 resolved
= strstr (field
, "or.andcm") != NULL
;
1112 else if (strstr (idesc
->name
, "and.orcm"))
1113 resolved
= strstr (field
, "and.orcm") != NULL
;
1114 else if (strstr (idesc
->name
, "orcm"))
1115 resolved
= strstr (field
, "or orcm") != NULL
;
1116 else if (strstr (idesc
->name
, "or"))
1117 resolved
= strstr (field
, "or orcm") != NULL
;
1118 else if (strstr (idesc
->name
, "andcm"))
1119 resolved
= strstr (field
, "and andcm") != NULL
;
1120 else if (strstr (idesc
->name
, "and"))
1121 resolved
= strstr (field
, "and andcm") != NULL
;
1122 else if (strstr (idesc
->name
, "unc"))
1123 resolved
= strstr (field
, "unc") != NULL
;
1125 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1129 if (resolved
&& format
)
1131 if (CONST_STRNEQ (idesc
->name
, "dep")
1132 && strstr (format
, "I13") != NULL
)
1133 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1134 else if (CONST_STRNEQ (idesc
->name
, "chk")
1135 && strstr (format
, "M21") != NULL
)
1136 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1137 else if (CONST_STRNEQ (idesc
->name
, "lfetch"))
1138 resolved
= (strstr (format
, "M14 M15") != NULL
1139 && (idesc
->operands
[1] == IA64_OPND_R2
1140 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1141 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1142 && strstr (format
, "B5") != NULL
)
1143 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1144 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1145 && strstr (format
, "B3") != NULL
)
1146 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1147 else if (CONST_STRNEQ (idesc
->name
, "brp")
1148 && strstr (format
, "B7") != NULL
)
1149 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1150 else if (strcmp (ic
->name
, "invala") == 0)
1151 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1152 else if (CONST_STRNEQ (idesc
->name
, "st")
1153 && (strstr (format
, "M5") != NULL
1154 || strstr (format
, "M10") != NULL
))
1155 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1156 else if (CONST_STRNEQ (idesc
->name
, "ld")
1157 && (strstr (format
, "M2 M3") != NULL
1158 || strstr (format
, "M12") != NULL
1159 || strstr (format
, "M7 M8") != NULL
))
1160 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1165 /* Misc brl variations ('.cond' is optional);
1166 plain brl matches brl.cond. */
1168 && (strcmp (idesc
->name
, "brl") == 0
1169 || CONST_STRNEQ (idesc
->name
, "brl."))
1170 && strcmp (ic
->name
, "brl.cond") == 0)
1175 /* Misc br variations ('.cond' is optional). */
1177 && (strcmp (idesc
->name
, "br") == 0
1178 || CONST_STRNEQ (idesc
->name
, "br."))
1179 && strcmp (ic
->name
, "br.cond") == 0)
1182 resolved
= (strstr (format
, "B4") != NULL
1183 && idesc
->operands
[0] == IA64_OPND_B2
)
1184 || (strstr (format
, "B1") != NULL
1185 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1190 /* probe variations. */
1191 if (!resolved
&& CONST_STRNEQ (idesc
->name
, "probe"))
1193 resolved
= strcmp (ic
->name
, "probe") == 0
1194 && !((strstr (idesc
->name
, "fault") != NULL
)
1195 ^ (format
&& strstr (format
, "M40") != NULL
));
1198 /* mov variations. */
1199 if (!resolved
&& is_mov
)
1203 /* mov alias for fmerge. */
1204 if (strcmp (ic
->name
, "fmerge") == 0)
1206 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1207 && idesc
->operands
[1] == IA64_OPND_F3
;
1209 /* mov alias for adds (r3 or imm14). */
1210 else if (strcmp (ic
->name
, "adds") == 0)
1212 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1213 && (idesc
->operands
[1] == IA64_OPND_R3
1214 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1216 /* mov alias for addl. */
1217 else if (strcmp (ic
->name
, "addl") == 0)
1219 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1220 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1224 /* Some variants of mov and mov.[im]. */
1225 if (!resolved
&& CONST_STRNEQ (ic
->name
, "mov_"))
1226 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1229 /* Keep track of this so we can flag any insn classes which aren't
1230 mapped onto at least one real insn. */
1232 ic
->terminal_resolved
= 1;
1234 else for (i
= 0; i
< ic
->nsubs
; i
++)
1236 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1240 for (j
= 0; j
< ic
->nxsubs
; j
++)
1241 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1245 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1252 /* If it's in this IC, add the IC note (if any) to the insn. */
1255 if (ic
->note
&& notep
)
1257 if (*notep
&& *notep
!= ic
->note
)
1258 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1259 *notep
, ic
->note
, ic
->name
);
1270 lookup_regindex (const char *name
, int specifier
)
1275 if (strstr (name
, "[RSC]"))
1277 if (strstr (name
, "[BSP]"))
1279 else if (strstr (name
, "[BSPSTORE]"))
1281 else if (strstr (name
, "[RNAT]"))
1283 else if (strstr (name
, "[FCR]"))
1285 else if (strstr (name
, "[EFLAG]"))
1287 else if (strstr (name
, "[CSD]"))
1289 else if (strstr (name
, "[SSD]"))
1291 else if (strstr (name
, "[CFLG]"))
1293 else if (strstr (name
, "[FSR]"))
1295 else if (strstr (name
, "[FIR]"))
1297 else if (strstr (name
, "[FDR]"))
1299 else if (strstr (name
, "[CCV]"))
1301 else if (strstr (name
, "[ITC]"))
1303 else if (strstr (name
, "[RUC]"))
1305 else if (strstr (name
, "[PFS]"))
1307 else if (strstr (name
, "[LC]"))
1309 else if (strstr (name
, "[EC]"))
1313 if (strstr (name
, "[DCR]"))
1315 else if (strstr (name
, "[ITM]"))
1317 else if (strstr (name
, "[IVA]"))
1319 else if (strstr (name
, "[PTA]"))
1321 else if (strstr (name
, "[GPTA]"))
1323 else if (strstr (name
, "[IPSR]"))
1325 else if (strstr (name
, "[ISR]"))
1327 else if (strstr (name
, "[IIP]"))
1329 else if (strstr (name
, "[IFA]"))
1331 else if (strstr (name
, "[ITIR]"))
1333 else if (strstr (name
, "[IIPA]"))
1335 else if (strstr (name
, "[IFS]"))
1337 else if (strstr (name
, "[IIM]"))
1339 else if (strstr (name
, "[IHA]"))
1341 else if (strstr (name
, "[LID]"))
1343 else if (strstr (name
, "[IVR]"))
1345 else if (strstr (name
, "[TPR]"))
1347 else if (strstr (name
, "[EOI]"))
1349 else if (strstr (name
, "[ITV]"))
1351 else if (strstr (name
, "[PMV]"))
1353 else if (strstr (name
, "[CMCV]"))
1357 if (strstr (name
, ".be"))
1359 else if (strstr (name
, ".up"))
1361 else if (strstr (name
, ".ac"))
1363 else if (strstr (name
, ".mfl"))
1365 else if (strstr (name
, ".mfh"))
1367 else if (strstr (name
, ".ic"))
1369 else if (strstr (name
, ".i"))
1371 else if (strstr (name
, ".pk"))
1373 else if (strstr (name
, ".dt"))
1375 else if (strstr (name
, ".dfl"))
1377 else if (strstr (name
, ".dfh"))
1379 else if (strstr (name
, ".sp"))
1381 else if (strstr (name
, ".pp"))
1383 else if (strstr (name
, ".di"))
1385 else if (strstr (name
, ".si"))
1387 else if (strstr (name
, ".db"))
1389 else if (strstr (name
, ".lp"))
1391 else if (strstr (name
, ".tb"))
1393 else if (strstr (name
, ".rt"))
1395 else if (strstr (name
, ".cpl"))
1397 else if (strstr (name
, ".rs"))
1399 else if (strstr (name
, ".mc"))
1401 else if (strstr (name
, ".it"))
1403 else if (strstr (name
, ".id"))
1405 else if (strstr (name
, ".da"))
1407 else if (strstr (name
, ".dd"))
1409 else if (strstr (name
, ".ss"))
1411 else if (strstr (name
, ".ri"))
1413 else if (strstr (name
, ".ed"))
1415 else if (strstr (name
, ".bn"))
1417 else if (strstr (name
, ".ia"))
1419 else if (strstr (name
, ".vm"))
1430 lookup_specifier (const char *name
)
1432 if (strchr (name
, '%'))
1434 if (strstr (name
, "AR[K%]") != NULL
)
1435 return IA64_RS_AR_K
;
1436 if (strstr (name
, "AR[UNAT]") != NULL
)
1437 return IA64_RS_AR_UNAT
;
1438 if (strstr (name
, "AR%, % in 8") != NULL
)
1440 if (strstr (name
, "AR%, % in 48") != NULL
)
1442 if (strstr (name
, "BR%") != NULL
)
1444 if (strstr (name
, "CR[IIB%]") != NULL
)
1445 return IA64_RS_CR_IIB
;
1446 if (strstr (name
, "CR[IRR%]") != NULL
)
1447 return IA64_RS_CR_IRR
;
1448 if (strstr (name
, "CR[LRR%]") != NULL
)
1449 return IA64_RS_CR_LRR
;
1450 if (strstr (name
, "CR%") != NULL
)
1452 if (strstr (name
, "DAHR%, % in 0") != NULL
)
1453 return IA64_RS_DAHR
;
1454 if (strstr (name
, "FR%, % in 0") != NULL
)
1456 if (strstr (name
, "FR%, % in 2") != NULL
)
1458 if (strstr (name
, "GR%") != NULL
)
1460 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1462 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1465 warn (_("don't know how to specify %% dependency %s\n"),
1468 else if (strchr (name
, '#'))
1470 if (strstr (name
, "CPUID#") != NULL
)
1471 return IA64_RS_CPUID
;
1472 if (strstr (name
, "DBR#") != NULL
)
1474 if (strstr (name
, "IBR#") != NULL
)
1476 if (strstr (name
, "MSR#") != NULL
)
1478 if (strstr (name
, "PKR#") != NULL
)
1480 if (strstr (name
, "PMC#") != NULL
)
1482 if (strstr (name
, "PMD#") != NULL
)
1484 if (strstr (name
, "RR#") != NULL
)
1487 warn (_("Don't know how to specify # dependency %s\n"),
1490 else if (CONST_STRNEQ (name
, "AR[FPSR]"))
1491 return IA64_RS_AR_FPSR
;
1492 else if (CONST_STRNEQ (name
, "AR["))
1494 else if (CONST_STRNEQ (name
, "CR["))
1496 else if (CONST_STRNEQ (name
, "PSR."))
1498 else if (strcmp (name
, "InService*") == 0)
1499 return IA64_RS_INSERVICE
;
1500 else if (strcmp (name
, "GR0") == 0)
1502 else if (strcmp (name
, "CFM") == 0)
1504 else if (strcmp (name
, "PR63") == 0)
1505 return IA64_RS_PR63
;
1506 else if (strcmp (name
, "RSE") == 0)
1513 print_dependency_table (void)
1519 for (i
=0;i
< iclen
;i
++)
1521 if (ics
[i
]->is_class
)
1525 if (ics
[i
]->comment
)
1526 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1527 ics
[i
]->name
, ics
[i
]->comment
);
1529 warn (_("IC:%s has no terminals or sub-classes\n"),
1535 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1537 if (ics
[i
]->comment
)
1538 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1539 ics
[i
]->name
, ics
[i
]->comment
);
1541 warn (_("no insns mapped directly to terminal IC %s\n"),
1547 for (i
= 0; i
< iclen
; i
++)
1551 mark_used (ics
[i
], 1);
1552 warn (_("class %s is defined but not used\n"),
1558 for (i
= 0; i
< rdepslen
; i
++)
1560 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1562 if (rdeps
[i
]->total_chks
== 0)
1564 if (rdeps
[i
]->total_regs
)
1565 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1566 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1568 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1569 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1571 else if (rdeps
[i
]->total_regs
== 0)
1572 warn (_("rsrc %s (%s) has no regs\n"),
1573 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1577 /* The dependencies themselves. */
1578 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1579 for (i
= 0; i
< rdepslen
; i
++)
1581 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1583 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1584 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1586 printf (" { \"%s\", %d, %d, %d, %d, ",
1587 rdeps
[i
]->name
, specifier
,
1588 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1589 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1591 const char *quote
, *rest
;
1594 rest
= rdeps
[i
]->extra
;
1595 quote
= strchr (rest
, '\"');
1596 while (quote
!= NULL
)
1598 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1600 quote
= strchr (rest
, '\"');
1602 printf ("%s\", ", rest
);
1610 /* And dependency lists. */
1611 for (i
=0;i
< dlistlen
;i
++)
1614 printf ("static const unsigned short dep%d[] = {\n ", i
);
1615 for (j
=0;j
< dlists
[i
]->len
; j
++)
1617 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1624 printf ("\n};\n\n");
1627 /* And opcode dependency list. */
1628 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1629 printf ("static const struct ia64_opcode_dependency\n");
1630 printf ("op_dependencies[] = {\n");
1631 for (i
= 0; i
< opdeplen
; i
++)
1634 if (opdeps
[i
]->chk
== -1)
1635 printf ("0, NULL, ");
1637 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1638 if (opdeps
[i
]->reg
== -1)
1639 printf ("0, NULL, ");
1641 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1648 /* Add STR to the string table. */
1649 static struct string_entry
*
1650 insert_string (char *str
)
1652 int start
= 0, end
= strtablen
;
1655 if (strtablen
== strtabtotlen
)
1658 string_table
= (struct string_entry
**)
1659 xrealloc (string_table
,
1660 sizeof (struct string_entry
**) * strtabtotlen
);
1666 string_table
[0] = tmalloc (struct string_entry
);
1667 string_table
[0]->s
= xstrdup (str
);
1668 string_table
[0]->num
= 0;
1669 return string_table
[0];
1672 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1674 else if (strcmp (str
, string_table
[0]->s
) < 0)
1682 i
= (start
+ end
) / 2;
1683 c
= strcmp (str
, string_table
[i
]->s
);
1688 return string_table
[i
];
1697 for (; i
> 0 && i
< strtablen
; i
--)
1698 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1701 for (; i
< strtablen
; i
++)
1702 if (strcmp (str
, string_table
[i
]->s
) < 0)
1705 for (x
= strtablen
- 1; x
>= i
; x
--)
1707 string_table
[x
+ 1] = string_table
[x
];
1708 string_table
[x
+ 1]->num
= x
+ 1;
1711 string_table
[i
] = tmalloc (struct string_entry
);
1712 string_table
[i
]->s
= xstrdup (str
);
1713 string_table
[i
]->num
= i
;
1716 return string_table
[i
];
1719 static struct bittree
*
1720 make_bittree_entry (void)
1722 struct bittree
*res
= tmalloc (struct bittree
);
1725 res
->bits
[0] = NULL
;
1726 res
->bits
[1] = NULL
;
1727 res
->bits
[2] = NULL
;
1729 res
->bits_to_skip
= 0;
1734 static struct disent
*
1735 add_dis_table_ent (struct disent
*which
, int insn
, int order
,
1736 ci_t completer_index
)
1746 while (ent
->nexte
!= NULL
)
1749 ent
= (ent
->nexte
= tmalloc (struct disent
));
1753 ent
= tmalloc (struct disent
);
1754 ent
->next_ent
= disinsntable
;
1761 ent
->priority
= order
;
1763 while (completer_index
!= 1)
1765 ci
= (ci
<< 1) | (completer_index
& 1);
1766 completer_index
>>= 1;
1768 ent
->completer_index
= ci
;
1773 finish_distable (void)
1775 struct disent
*ent
= disinsntable
;
1776 struct disent
*prev
= ent
;
1778 ent
->ournum
= 32768;
1779 while ((ent
= ent
->next_ent
) != NULL
)
1781 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1787 insert_bit_table_ent (struct bittree
*curr_ent
, int bit
, ia64_insn opcode
,
1788 ia64_insn mask
, int opcodenum
, int order
,
1789 ci_t completer_index
)
1793 struct bittree
*next
;
1797 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1800 curr_ent
->disent
= nent
;
1804 m
= ((ia64_insn
) 1) << bit
;
1807 b
= (opcode
& m
) ? 1 : 0;
1811 next
= curr_ent
->bits
[b
];
1814 next
= make_bittree_entry ();
1815 curr_ent
->bits
[b
] = next
;
1817 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1822 add_dis_entry (struct bittree
*first
, ia64_insn opcode
, ia64_insn mask
,
1823 int opcodenum
, struct completer_entry
*ent
, ci_t completer_index
)
1825 if (completer_index
& ((ci_t
)1 << 32) )
1830 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1831 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1832 (completer_index
<< 1) | 1);
1834 if (ent
->is_terminal
)
1836 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1837 opcodenum
, opcode_count
- ent
->order
- 1,
1838 (completer_index
<< 1) | 1);
1840 completer_index
<<= 1;
1841 ent
= ent
->alternative
;
1845 /* This optimization pass combines multiple "don't care" nodes. */
1847 compact_distree (struct bittree
*ent
)
1849 #define IS_SKIP(ent) \
1850 ((ent->bits[2] !=NULL) \
1851 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1854 struct bittree
*nent
= ent
;
1857 while (IS_SKIP (nent
))
1860 nent
= nent
->bits
[2];
1865 struct bittree
*next
= ent
->bits
[2];
1867 ent
->bits
[0] = nent
->bits
[0];
1868 ent
->bits
[1] = nent
->bits
[1];
1869 ent
->bits
[2] = nent
->bits
[2];
1870 ent
->disent
= nent
->disent
;
1872 ent
->bits_to_skip
= bitcnt
;
1873 while (next
!= nent
)
1875 struct bittree
*b
= next
;
1876 next
= next
->bits
[2];
1882 for (x
= 0; x
< 3; x
++)
1884 struct bittree
*i
= ent
->bits
[x
];
1887 compact_distree (i
);
1891 static unsigned char *insn_list
;
1892 static int insn_list_len
= 0;
1893 static int tot_insn_list_len
= 0;
1895 /* Generate the disassembler state machine corresponding to the tree
1898 gen_dis_table (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%lx, %d, %d, %d },\n", ( long ) 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 (struct completer_entry
*ent1
,
2223 struct completer_entry
*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 (const char *name
)
2344 if (name
[0] == '\0')
2347 c
= strchr (name
, '.');
2351 return strlen (name
);
2355 compute_completer_bits (struct main_entry
*ment
, struct completer_entry
*ent
)
2359 compute_completer_bits (ment
, ent
->addl_entries
);
2361 if (ent
->is_terminal
)
2364 ia64_insn our_bits
= ent
->bits
;
2365 struct completer_entry
*p
= ent
->parent
;
2369 while (p
!= NULL
&& ! p
->is_terminal
)
2375 p_bits
= ment
->opcode
->opcode
;
2377 for (x
= 0; x
< 64; x
++)
2379 ia64_insn m
= ((ia64_insn
) 1) << x
;
2381 if ((p_bits
& m
) != (our_bits
& m
))
2386 ent
->bits
= our_bits
;
2395 ent
= ent
->alternative
;
2399 /* Find identical completer trees that are used in different
2400 instructions and collapse their entries. */
2402 collapse_redundant_completers (void)
2404 struct main_entry
*ptr
;
2407 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2409 if (ptr
->completers
== NULL
)
2412 compute_completer_bits (ptr
, ptr
->completers
);
2413 ptr
->completers
= insert_gclist (ptr
->completers
);
2416 /* The table has been finalized, now number the indexes. */
2417 for (x
= 0; x
< glistlen
; x
++)
2422 /* Attach two lists of dependencies to each opcode.
2423 1) all resources which, when already marked in use, conflict with this
2425 2) all resources which must be marked in use when this opcode is used
2428 insert_opcode_dependencies (struct ia64_opcode
*opc
,
2429 struct completer_entry
*cmp ATTRIBUTE_UNUSED
)
2431 /* Note all resources which point to this opcode. rfi has the most chks
2432 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2435 unsigned short regs
[256];
2437 unsigned short chks
[256];
2438 /* Flag insns for which no class matched; there should be none. */
2439 int no_class_found
= 1;
2441 for (i
= 0; i
< rdepslen
; i
++)
2443 struct rdep
*rs
= rdeps
[i
];
2446 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2447 && CONST_STRNEQ (rs
->name
, "PR%")
2449 no_class_found
= 99;
2451 for (j
=0; j
< rs
->nregs
;j
++)
2455 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2457 /* We can ignore ic_note 11 for non PR resources. */
2458 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2461 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2462 && ic_note
!= rs
->regnotes
[j
]
2463 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2464 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2465 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2466 rs
->name
, rs
->regnotes
[j
]);
2467 /* Instruction class notes override resource notes.
2468 So far, only note 11 applies to an IC instead of a resource,
2469 and note 11 implies note 1. */
2471 regs
[nregs
++] = RDEP(ic_note
, i
);
2473 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2479 for (j
= 0; j
< rs
->nchks
; j
++)
2483 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2485 /* We can ignore ic_note 11 for non PR resources. */
2486 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2489 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2490 && ic_note
!= rs
->chknotes
[j
]
2491 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2492 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2493 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2494 rs
->name
, rs
->chknotes
[j
]);
2496 chks
[nchks
++] = RDEP(ic_note
, i
);
2498 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2506 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2508 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2510 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2514 insert_completer_entry (struct ia64_opcode
*opc
, struct main_entry
*tabent
,
2517 struct completer_entry
**ptr
= &tabent
->completers
;
2518 struct completer_entry
*parent
= NULL
;
2519 char pcopy
[129], *prefix
;
2522 if (strlen (opc
->name
) > 128)
2525 strcpy (pcopy
, opc
->name
);
2526 prefix
= pcopy
+ get_prefix_len (pcopy
);
2528 if (prefix
[0] != '\0')
2533 int need_new_ent
= 1;
2534 int plen
= get_prefix_len (prefix
);
2535 struct string_entry
*sent
;
2537 at_end
= (prefix
[plen
] == '\0');
2538 prefix
[plen
] = '\0';
2539 sent
= insert_string (prefix
);
2541 while (*ptr
!= NULL
)
2543 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2551 ptr
= &((*ptr
)->alternative
);
2556 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2559 nent
->parent
= parent
;
2560 nent
->addl_entries
= NULL
;
2561 nent
->alternative
= *ptr
;
2563 nent
->is_terminal
= 0;
2564 nent
->dependencies
= -1;
2570 ptr
= &((*ptr
)->addl_entries
);
2575 if ((*ptr
)->is_terminal
)
2578 (*ptr
)->is_terminal
= 1;
2579 (*ptr
)->mask
= (ia64_insn
)-1;
2580 (*ptr
)->bits
= opc
->opcode
;
2581 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2582 (*ptr
)->order
= order
;
2586 print_completer_entry (struct completer_entry
*ent
)
2589 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2593 while (! (mask
& 1))
2600 if (bits
& 0xffffffff00000000LL
)
2604 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2608 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2609 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2611 ent
->is_terminal
? 1 : 0,
2616 print_completer_table (void)
2620 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2621 for (x
= 0; x
< glistlen
; x
++)
2622 print_completer_entry (glist
[x
]);
2627 opcodes_eq (struct ia64_opcode
*opc1
, struct ia64_opcode
*opc2
)
2632 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2633 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2634 || (opc1
->flags
!= opc2
->flags
))
2637 for (x
= 0; x
< 5; x
++)
2638 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2641 plen1
= get_prefix_len (opc1
->name
);
2642 plen2
= get_prefix_len (opc2
->name
);
2644 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2651 add_opcode_entry (struct ia64_opcode
*opc
)
2653 struct main_entry
**place
;
2654 struct string_entry
*name
;
2658 if (strlen (opc
->name
) > 128)
2662 strcpy (prefix
, opc
->name
);
2663 prefix
[get_prefix_len (prefix
)] = '\0';
2664 name
= insert_string (prefix
);
2666 /* Walk the list of opcode table entries. If it's a new
2667 instruction, allocate and fill in a new entry. Note
2668 the main table is alphabetical by opcode name. */
2670 while (*place
!= NULL
)
2672 if ((*place
)->name
->num
== name
->num
2673 && opcodes_eq ((*place
)->opcode
, opc
))
2678 if ((*place
)->name
->num
> name
->num
)
2681 place
= &((*place
)->next
);
2685 struct main_entry
*nent
= tmalloc (struct main_entry
);
2689 nent
->next
= *place
;
2690 nent
->completers
= 0;
2693 if (otlen
== ottotlen
)
2696 ordered_table
= (struct main_entry
**)
2697 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2699 ordered_table
[otlen
++] = nent
;
2702 insert_completer_entry (opc
, *place
, opcode_count
++);
2706 print_main_table (void)
2708 struct main_entry
*ptr
= maintable
;
2711 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2714 printf (" { %d, %d, %d, 0x",
2717 ptr
->opcode
->num_outputs
);
2718 opcode_fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2720 opcode_fprintf_vma (stdout
, ptr
->opcode
->mask
);
2721 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2722 ptr
->opcode
->operands
[0],
2723 ptr
->opcode
->operands
[1],
2724 ptr
->opcode
->operands
[2],
2725 ptr
->opcode
->operands
[3],
2726 ptr
->opcode
->operands
[4],
2728 ptr
->completers
->num
);
2730 ptr
->main_index
= tindex
++;
2738 shrink (struct ia64_opcode
*table
)
2742 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2744 add_opcode_entry (table
+ curr_opcode
);
2745 if (table
[curr_opcode
].num_outputs
== 2
2746 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2747 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2748 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2749 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2751 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2754 *alias
= table
[curr_opcode
];
2755 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2756 alias
->operands
[i
- 1] = alias
->operands
[i
];
2757 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2758 --alias
->num_outputs
;
2759 alias
->flags
|= PSEUDO
;
2760 add_opcode_entry (alias
);
2766 /* Program options. */
2767 #define OPTION_SRCDIR 200
2769 struct option long_options
[] =
2771 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2772 {"debug", no_argument
, NULL
, 'd'},
2773 {"version", no_argument
, NULL
, 'V'},
2774 {"help", no_argument
, NULL
, 'h'},
2775 {0, no_argument
, NULL
, 0}
2779 print_version (void)
2781 printf ("%s: version 1.0\n", program_name
);
2786 usage (FILE * stream
, int status
)
2788 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2794 main (int argc
, char **argv
)
2796 extern int chdir (char *);
2797 char *srcdir
= NULL
;
2800 program_name
= *argv
;
2801 xmalloc_set_program_name (program_name
);
2803 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2828 if (chdir (srcdir
) != 0)
2829 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2830 srcdir
, strerror (errno
));
2832 load_insn_classes ();
2833 load_dependencies ();
2835 shrink (ia64_opcodes_a
);
2836 shrink (ia64_opcodes_b
);
2837 shrink (ia64_opcodes_f
);
2838 shrink (ia64_opcodes_i
);
2839 shrink (ia64_opcodes_m
);
2840 shrink (ia64_opcodes_x
);
2841 shrink (ia64_opcodes_d
);
2843 collapse_redundant_completers ();
2845 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2846 printf ("/* Copyright (C) 2007-2014 Free Software Foundation, Inc.\n\
2848 This file is part of the GNU opcodes library.\n\
2850 This library is free software; you can redistribute it and/or modify\n\
2851 it under the terms of the GNU General Public License as published by\n\
2852 the Free Software Foundation; either version 3, or (at your option)\n\
2853 any later version.\n\
2855 It is distributed in the hope that it will be useful, but WITHOUT\n\
2856 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2857 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2858 License for more details.\n\
2860 You should have received a copy of the GNU General Public License\n\
2861 along with this program; see the file COPYING. If not, write to the\n\
2862 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2863 02110-1301, USA. */\n");
2865 print_string_table ();
2866 print_dependency_table ();
2867 print_completer_table ();
2868 print_main_table ();
2870 generate_disassembler ();