1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
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"
47 #include "ia64-opc-a.c"
48 #include "ia64-opc-i.c"
49 #include "ia64-opc-m.c"
50 #include "ia64-opc-b.c"
51 #include "ia64-opc-f.c"
52 #include "ia64-opc-x.c"
53 #include "ia64-opc-d.c"
56 #define _(String) gettext (String)
58 /* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this
59 always, because we might be compiled without BFD64 defined, if configured
60 for a 32-bit target and --enable-targets=all is used. This will work for
61 both 32-bit and 64-bit hosts. */
62 #define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
63 #define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
64 #define opcode_fprintf_vma(s,x) \
65 fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
67 const char * program_name
= NULL
;
70 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
71 #define tmalloc(X) (X *) xmalloc (sizeof (X))
73 /* The main opcode table entry. Each entry is a unique combination of
74 name and flags (no two entries in the table compare as being equal
78 /* The base name of this opcode. The names of its completers are
79 appended to it to generate the full instruction name. */
80 struct string_entry
*name
;
81 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
82 it uses the first one passed to add_opcode_entry. */
83 struct ia64_opcode
*opcode
;
84 /* The list of completers that can be applied to this opcode. */
85 struct completer_entry
*completers
;
86 /* Next entry in the chain. */
87 struct main_entry
*next
;
88 /* Index in the main table. */
90 } *maintable
, **ordered_table
;
96 /* The set of possible completers for an opcode. */
97 struct completer_entry
99 /* This entry's index in the ia64_completer_table[] array. */
102 /* The name of the completer. */
103 struct string_entry
*name
;
105 /* This entry's parent. */
106 struct completer_entry
*parent
;
108 /* Set if this is a terminal completer (occurs at the end of an
112 /* An alternative completer. */
113 struct completer_entry
*alternative
;
115 /* Additional completers that can be appended to this one. */
116 struct completer_entry
*addl_entries
;
118 /* Before compute_completer_bits () is invoked, this contains the actual
119 instruction opcode for this combination of opcode and completers.
120 Afterwards, it contains those bits that are different from its
124 /* Bits set to 1 correspond to those bits in this completer's opcode
125 that are different from its parent completer's opcode (or from
126 the base opcode if the entry is the root of the opcode's completer
127 list). This field is filled in by compute_completer_bits (). */
130 /* Index into the opcode dependency list, or -1 if none. */
133 /* Remember the order encountered in the opcode tables. */
137 /* One entry in the disassembler name table. */
140 /* The index into the ia64_name_dis array for this entry. */
143 /* The index into the main_table[] array. */
146 /* The disassmbly priority of this entry. */
149 /* The completer_index value for this entry. */
152 /* How many other entries share this decode. */
155 /* The next entry sharing the same decode. */
156 struct disent
*nexte
;
158 /* The next entry in the name list. */
159 struct disent
*next_ent
;
160 } *disinsntable
= NULL
;
162 /* A state machine that will eventually be used to generate the
163 disassembler table. */
166 struct disent
*disent
;
167 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
172 /* The string table contains all opcodes and completers sorted in
173 alphabetical order. */
175 /* One entry in the string table. */
178 /* The index in the ia64_strings[] array for this entry. */
180 /* And the string. */
182 } **string_table
= NULL
;
185 int strtabtotlen
= 0;
188 /* Resource dependency entries. */
191 char *name
; /* Resource name. */
193 mode
:2, /* RAW, WAW, or WAR. */
194 semantics
:3; /* Dependency semantics. */
195 char *extra
; /* Additional semantics info. */
197 int total_chks
; /* Total #of terminal insns. */
198 int *chks
; /* Insn classes which read (RAW), write
199 (WAW), or write (WAR) this rsrc. */
200 int *chknotes
; /* Dependency notes for each class. */
202 int total_regs
; /* Total #of terminal insns. */
203 int *regs
; /* Insn class which write (RAW), write2
204 (WAW), or read (WAR) this rsrc. */
205 int *regnotes
; /* Dependency notes for each class. */
207 int waw_special
; /* Special WAW dependency note. */
210 static int rdepslen
= 0;
211 static int rdepstotlen
= 0;
213 /* Array of all instruction classes. */
216 char *name
; /* Instruction class name. */
217 int is_class
; /* Is a class, not a terminal. */
219 int *subs
; /* Other classes within this class. */
221 int xsubs
[4]; /* Exclusions. */
222 char *comment
; /* Optional comment. */
223 int note
; /* Optional note. */
224 int terminal_resolved
; /* Did we match this with anything? */
225 int orphan
; /* Detect class orphans. */
228 static int iclen
= 0;
229 static int ictotlen
= 0;
231 /* An opcode dependency (chk/reg pair of dependency lists). */
234 int chk
; /* index into dlists */
235 int reg
; /* index into dlists */
238 static int opdeplen
= 0;
239 static int opdeptotlen
= 0;
241 /* A generic list of dependencies w/notes encoded. These may be shared. */
245 unsigned short *deps
;
248 static int dlistlen
= 0;
249 static int dlisttotlen
= 0;
252 static void fail (const char *, ...) ATTRIBUTE_PRINTF_1
;
253 static void warn (const char *, ...) ATTRIBUTE_PRINTF_1
;
254 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
255 static int deplist_equals (struct deplist
*, struct deplist
*);
256 static short insert_deplist (int, unsigned short *);
257 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
258 static void mark_used (struct iclass
*, int);
259 static int fetch_insn_class (const char *, int);
260 static int sub_compare (const void *, const void *);
261 static void load_insn_classes (void);
262 static void parse_resource_users (const char *, int **, int *, int **);
263 static int parse_semantics (char *);
264 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
265 static void load_depfile (const char *, enum ia64_dependency_mode
);
266 static void load_dependencies (void);
267 static int irf_operand (int, const char *);
268 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
269 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
270 static int lookup_regindex (const char *, int);
271 static int lookup_specifier (const char *);
272 static void print_dependency_table (void);
273 static struct string_entry
* insert_string (char *);
274 static void gen_dis_table (struct bittree
*);
275 static void print_dis_table (void);
276 static void generate_disassembler (void);
277 static void print_string_table (void);
278 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
279 static struct completer_entry
* insert_gclist (struct completer_entry
*);
280 static int get_prefix_len (const char *);
281 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
282 static void collapse_redundant_completers (void);
283 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
284 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
285 static void print_completer_entry (struct completer_entry
*);
286 static void print_completer_table (void);
287 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
288 static void add_opcode_entry (struct ia64_opcode
*);
289 static void print_main_table (void);
290 static void shrink (struct ia64_opcode
*);
291 static void print_version (void);
292 static void usage (FILE *, int);
293 static void finish_distable (void);
294 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, int);
295 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, int);
296 static void compact_distree (struct bittree
*);
297 static struct bittree
* make_bittree_entry (void);
298 static struct disent
* add_dis_table_ent (struct disent
*, int, int, int);
302 fail (const char *message
, ...)
306 va_start (args
, message
);
307 fprintf (stderr
, _("%s: Error: "), program_name
);
308 vfprintf (stderr
, message
, args
);
314 warn (const char *message
, ...)
318 va_start (args
, message
);
320 fprintf (stderr
, _("%s: Warning: "), program_name
);
321 vfprintf (stderr
, message
, args
);
325 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
327 insert_resource (const char *name
, enum ia64_dependency_mode type
)
329 if (rdepslen
== rdepstotlen
)
332 rdeps
= (struct rdep
**)
333 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
335 rdeps
[rdepslen
] = tmalloc(struct rdep
);
336 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
337 rdeps
[rdepslen
]->name
= xstrdup (name
);
338 rdeps
[rdepslen
]->mode
= type
;
339 rdeps
[rdepslen
]->waw_special
= 0;
341 return rdeps
[rdepslen
++];
344 /* Are the lists of dependency indexes equivalent? */
346 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
350 if (d1
->len
!= d2
->len
)
353 for (i
= 0; i
< d1
->len
; i
++)
354 if (d1
->deps
[i
] != d2
->deps
[i
])
360 /* Add the list of dependencies to the list of dependency lists. */
362 insert_deplist (int count
, unsigned short *deps
)
364 /* Sort the list, then see if an equivalent list exists already.
365 this results in a much smaller set of dependency lists. */
366 struct deplist
*list
;
370 memset ((void *)set
, 0, sizeof (set
));
371 for (i
= 0; i
< count
; i
++)
375 for (i
= 0; i
< (int) sizeof (set
); i
++)
379 list
= tmalloc (struct deplist
);
381 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
383 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
385 list
->deps
[count
++] = i
;
387 /* Does this list exist already? */
388 for (i
= 0; i
< dlistlen
; i
++)
389 if (deplist_equals (list
, dlists
[i
]))
396 if (dlistlen
== dlisttotlen
)
399 dlists
= (struct deplist
**)
400 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
402 dlists
[dlistlen
] = list
;
407 /* Add the given pair of dependency lists to the opcode dependency list. */
409 insert_dependencies (int nchks
, unsigned short *chks
,
410 int nregs
, unsigned short *regs
)
418 regind
= insert_deplist (nregs
, regs
);
420 chkind
= insert_deplist (nchks
, chks
);
422 for (i
= 0; i
< opdeplen
; i
++)
423 if (opdeps
[i
]->chk
== chkind
424 && opdeps
[i
]->reg
== regind
)
427 pair
= tmalloc (struct opdep
);
431 if (opdeplen
== opdeptotlen
)
434 opdeps
= (struct opdep
**)
435 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
437 opdeps
[opdeplen
] = pair
;
443 mark_used (struct iclass
*ic
, int clear_terminals
)
449 ic
->terminal_resolved
= 1;
451 for (i
= 0; i
< ic
->nsubs
; i
++)
452 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
454 for (i
= 0; i
< ic
->nxsubs
; i
++)
455 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
458 /* Look up an instruction class; if CREATE make a new one if none found;
459 returns the index into the insn class array. */
461 fetch_insn_class (const char *full_name
, int create
)
471 if (CONST_STRNEQ (full_name
, "IC:"))
473 name
= xstrdup (full_name
+ 3);
477 name
= xstrdup (full_name
);
479 if ((xsect
= strchr(name
, '\\')) != NULL
)
481 if ((comment
= strchr(name
, '[')) != NULL
)
483 if ((notestr
= strchr(name
, '+')) != NULL
)
486 /* If it is a composite class, then ignore comments and notes that come after
487 the '\\', since they don't apply to the part we are decoding now. */
500 note
= atoi (notestr
+ 1);
501 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
503 if (strcmp (notestr
, "+1+13") == 0)
505 else if (!xsect
|| nextnotestr
< xsect
)
506 warn (_("multiple note %s not handled\n"), notestr
);
510 /* If it's a composite class, leave the notes and comments in place so that
511 we have a unique name for the composite class. Otherwise, we remove
521 for (i
= 0; i
< iclen
; i
++)
522 if (strcmp (name
, ics
[i
]->name
) == 0
523 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
524 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
525 && strncmp (ics
[i
]->comment
, comment
,
526 strlen (ics
[i
]->comment
)) == 0))
527 && note
== ics
[i
]->note
)
533 /* Doesn't exist, so make a new one. */
534 if (iclen
== ictotlen
)
537 ics
= (struct iclass
**)
538 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
542 ics
[ind
] = tmalloc (struct iclass
);
543 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
544 ics
[ind
]->name
= xstrdup (name
);
545 ics
[ind
]->is_class
= is_class
;
546 ics
[ind
]->orphan
= 1;
550 ics
[ind
]->comment
= xstrdup (comment
+ 1);
551 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
555 ics
[ind
]->note
= note
;
557 /* If it's a composite class, there's a comment or note, look for an
558 existing class or terminal with the same name. */
559 if ((xsect
|| comment
|| notestr
) && is_class
)
561 /* First, populate with the class we're based on. */
562 char *subname
= name
;
572 ics
[ind
]->subs
= tmalloc(int);
573 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
578 char *subname
= xsect
+ 1;
580 xsect
= strchr (subname
, '\\');
583 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
591 /* For sorting a class's sub-class list only; make sure classes appear before
594 sub_compare (const void *e1
, const void *e2
)
596 struct iclass
*ic1
= ics
[*(int *)e1
];
597 struct iclass
*ic2
= ics
[*(int *)e2
];
604 else if (ic2
->is_class
)
607 return strcmp (ic1
->name
, ic2
->name
);
611 load_insn_classes (void)
613 FILE *fp
= fopen ("ia64-ic.tbl", "r");
617 fail (_("can't find ia64-ic.tbl for reading\n"));
619 /* Discard first line. */
620 fgets (buf
, sizeof(buf
), fp
);
628 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
631 while (ISSPACE (buf
[strlen (buf
) - 1]))
632 buf
[strlen (buf
) - 1] = '\0';
638 if (tmp
== buf
+ sizeof (buf
))
643 iclass
= fetch_insn_class (name
, 1);
644 ics
[iclass
]->is_class
= 1;
646 if (strcmp (name
, "none") == 0)
648 ics
[iclass
]->is_class
= 0;
649 ics
[iclass
]->terminal_resolved
= 1;
653 /* For this class, record all sub-classes. */
659 while (*tmp
&& ISSPACE (*tmp
))
662 if (tmp
== buf
+ sizeof (buf
))
666 while (*tmp
&& *tmp
!= ',')
669 if (tmp
== buf
+ sizeof (buf
))
675 ics
[iclass
]->subs
= (int *)
676 xrealloc ((void *)ics
[iclass
]->subs
,
677 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
679 sub
= fetch_insn_class (subname
, 1);
680 ics
[iclass
]->subs
= (int *)
681 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
682 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
685 /* Make sure classes come before terminals. */
686 qsort ((void *)ics
[iclass
]->subs
,
687 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
692 printf ("%d classes\n", iclen
);
695 /* Extract the insn classes from the given line. */
697 parse_resource_users (ref
, usersp
, nusersp
, notesp
)
704 char *line
= xstrdup (ref
);
706 int *users
= *usersp
;
707 int count
= *nusersp
;
708 int *notes
= *notesp
;
720 while (ISSPACE (*tmp
))
723 while (*tmp
&& *tmp
!= ',')
728 xsect
= strchr (name
, '\\');
729 if ((notestr
= strstr (name
, "+")) != NULL
)
733 note
= atoi (notestr
+ 1);
734 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
736 /* Note 13 always implies note 1. */
737 if (strcmp (notestr
, "+1+13") == 0)
739 else if (!xsect
|| nextnotestr
< xsect
)
740 warn (_("multiple note %s not handled\n"), notestr
);
748 /* All classes are created when the insn class table is parsed;
749 Individual instructions might not appear until the dependency tables
750 are read. Only create new classes if it's *not* an insn class,
751 or if it's a composite class (which wouldn't necessarily be in the IC
753 if (! CONST_STRNEQ (name
, "IC:") || xsect
!= NULL
)
756 iclass
= fetch_insn_class (name
, create
);
760 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
762 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
764 users
[count
++] = iclass
;
765 mark_used (ics
[iclass
], 0);
768 printf("Class %s not found\n", name
);
770 /* Update the return values. */
779 parse_semantics (char *sem
)
781 if (strcmp (sem
, "none") == 0)
782 return IA64_DVS_NONE
;
783 else if (strcmp (sem
, "implied") == 0)
784 return IA64_DVS_IMPLIED
;
785 else if (strcmp (sem
, "impliedF") == 0)
786 return IA64_DVS_IMPLIEDF
;
787 else if (strcmp (sem
, "data") == 0)
788 return IA64_DVS_DATA
;
789 else if (strcmp (sem
, "instr") == 0)
790 return IA64_DVS_INSTR
;
791 else if (strcmp (sem
, "specific") == 0)
792 return IA64_DVS_SPECIFIC
;
793 else if (strcmp (sem
, "stop") == 0)
794 return IA64_DVS_STOP
;
796 return IA64_DVS_OTHER
;
800 add_dep (const char *name
, const char *chk
, const char *reg
,
801 int semantics
, int mode
, char *extra
, int flag
)
805 rs
= insert_resource (name
, mode
);
807 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
808 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
810 rs
->semantics
= semantics
;
812 rs
->waw_special
= flag
;
816 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
818 FILE *fp
= fopen (filename
, "r");
822 fail (_("can't find %s for reading\n"), filename
);
824 fgets (buf
, sizeof(buf
), fp
);
832 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
835 while (ISSPACE (buf
[strlen (buf
) - 1]))
836 buf
[strlen (buf
) - 1] = '\0';
843 while (ISSPACE (*tmp
))
846 tmp
= strchr (tmp
, ';');
850 while (ISSPACE (*tmp
))
853 tmp
= strchr (tmp
, ';');
857 while (ISSPACE (*tmp
))
859 semantics
= parse_semantics (tmp
);
860 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
862 /* For WAW entries, if the chks and regs differ, we need to enter the
863 entries in both positions so that the tables will be parsed properly,
864 without a lot of extra work. */
865 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
867 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
868 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
872 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
879 load_dependencies (void)
881 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
882 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
883 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
886 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
889 /* Is the given operand an indirect register file operand? */
891 irf_operand (int op
, const char *field
)
895 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
896 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
897 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
898 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
902 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
903 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
904 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
905 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
906 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
907 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
908 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
909 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
913 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
914 mov_um insn classes. */
916 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
917 const char *format
, const char *field
)
919 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
930 int i
= strcmp (idesc
->name
, "mov.i") == 0;
931 int m
= strcmp (idesc
->name
, "mov.m") == 0;
932 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
933 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
934 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
935 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
936 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
937 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
941 return strstr (format
, "I26") || strstr (format
, "I27");
943 return strstr (format
, "I28") != NULL
;
945 return strstr (format
, "M29") || strstr (format
, "M30");
947 return strstr (format
, "M31") != NULL
;
948 if (pseudo0
|| pseudo1
)
954 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
955 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
957 return strstr (format
, "I22") != NULL
;
959 return strstr (format
, "I21") != NULL
;
964 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
965 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
967 return strstr (format
, "M32") != NULL
;
969 return strstr (format
, "M33") != NULL
;
973 if (ic
->name
[5] == 'n')
975 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
976 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
978 return strstr (format
, "M42") != NULL
;
980 return strstr (format
, "M43") != NULL
;
982 else if (ic
->name
[5] == 'p')
984 return idesc
->operands
[1] == IA64_OPND_IP
;
990 if (ic
->name
[5] == 'r')
992 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
993 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
994 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
996 return strstr (format
, "I23") != NULL
;
998 return strstr (format
, "I24") != NULL
;
1000 return strstr (format
, "I25") != NULL
;
1002 else if (ic
->name
[5] == 's')
1004 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1005 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1007 return strstr (format
, "M35") != NULL
;
1009 return strstr (format
, "M36") != NULL
;
1016 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1017 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1019 return strstr (format
, "M35") != NULL
;
1021 return strstr (format
, "M36") != NULL
;
1028 /* Is the given opcode in the given insn class? */
1030 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1031 const char *format
, const char *field
, int *notep
)
1038 if (CONST_STRNEQ (ic
->comment
, "Format"))
1040 /* Assume that the first format seen is the most restrictive, and
1041 only keep a later one if it looks like it's more restrictive. */
1044 if (strlen (ic
->comment
) < strlen (format
))
1046 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1047 ic
->comment
, format
);
1048 format
= ic
->comment
;
1052 format
= ic
->comment
;
1054 else if (CONST_STRNEQ (ic
->comment
, "Field"))
1057 warn (_("overlapping field %s->%s\n"),
1058 ic
->comment
, field
);
1059 field
= ic
->comment
;
1063 /* An insn class matches anything that is the same followed by completers,
1064 except when the absence and presence of completers constitutes different
1066 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1068 int is_mov
= CONST_STRNEQ (idesc
->name
, "mov");
1069 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1070 int len
= strlen(ic
->name
);
1072 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1073 && (idesc
->name
[len
] == '\0'
1074 || idesc
->name
[len
] == '.'));
1076 /* All break, nop, and hint variations must match exactly. */
1078 (strcmp (ic
->name
, "break") == 0
1079 || strcmp (ic
->name
, "nop") == 0
1080 || strcmp (ic
->name
, "hint") == 0))
1081 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1083 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1084 unless specifically allowed by clauses in this block. */
1085 if (resolved
&& field
)
1087 /* Check Field(sf)==sN against opcode sN. */
1088 if (strstr(field
, "(sf)==") != NULL
)
1092 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1093 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1095 /* Check Field(lftype)==XXX. */
1096 else if (strstr (field
, "(lftype)") != NULL
)
1098 if (strstr (idesc
->name
, "fault") != NULL
)
1099 resolved
= strstr (field
, "fault") != NULL
;
1101 resolved
= strstr (field
, "fault") == NULL
;
1103 /* Handle Field(ctype)==XXX. */
1104 else if (strstr (field
, "(ctype)") != NULL
)
1106 if (strstr (idesc
->name
, "or.andcm"))
1107 resolved
= strstr (field
, "or.andcm") != NULL
;
1108 else if (strstr (idesc
->name
, "and.orcm"))
1109 resolved
= strstr (field
, "and.orcm") != NULL
;
1110 else if (strstr (idesc
->name
, "orcm"))
1111 resolved
= strstr (field
, "or orcm") != NULL
;
1112 else if (strstr (idesc
->name
, "or"))
1113 resolved
= strstr (field
, "or orcm") != NULL
;
1114 else if (strstr (idesc
->name
, "andcm"))
1115 resolved
= strstr (field
, "and andcm") != NULL
;
1116 else if (strstr (idesc
->name
, "and"))
1117 resolved
= strstr (field
, "and andcm") != NULL
;
1118 else if (strstr (idesc
->name
, "unc"))
1119 resolved
= strstr (field
, "unc") != NULL
;
1121 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1125 if (resolved
&& format
)
1127 if (CONST_STRNEQ (idesc
->name
, "dep")
1128 && strstr (format
, "I13") != NULL
)
1129 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1130 else if (CONST_STRNEQ (idesc
->name
, "chk")
1131 && strstr (format
, "M21") != NULL
)
1132 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1133 else if (CONST_STRNEQ (idesc
->name
, "lfetch"))
1134 resolved
= (strstr (format
, "M14 M15") != NULL
1135 && (idesc
->operands
[1] == IA64_OPND_R2
1136 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1137 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1138 && strstr (format
, "B5") != NULL
)
1139 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1140 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1141 && strstr (format
, "B3") != NULL
)
1142 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1143 else if (CONST_STRNEQ (idesc
->name
, "brp")
1144 && strstr (format
, "B7") != NULL
)
1145 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1146 else if (strcmp (ic
->name
, "invala") == 0)
1147 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1148 else if (CONST_STRNEQ (idesc
->name
, "st")
1149 && (strstr (format
, "M5") != NULL
1150 || strstr (format
, "M10") != NULL
))
1151 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1152 else if (CONST_STRNEQ (idesc
->name
, "ld")
1153 && (strstr (format
, "M2 M3") != NULL
1154 || strstr (format
, "M12") != NULL
1155 || strstr (format
, "M7 M8") != NULL
))
1156 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1161 /* Misc brl variations ('.cond' is optional);
1162 plain brl matches brl.cond. */
1164 && (strcmp (idesc
->name
, "brl") == 0
1165 || CONST_STRNEQ (idesc
->name
, "brl."))
1166 && strcmp (ic
->name
, "brl.cond") == 0)
1171 /* Misc br variations ('.cond' is optional). */
1173 && (strcmp (idesc
->name
, "br") == 0
1174 || CONST_STRNEQ (idesc
->name
, "br."))
1175 && strcmp (ic
->name
, "br.cond") == 0)
1178 resolved
= (strstr (format
, "B4") != NULL
1179 && idesc
->operands
[0] == IA64_OPND_B2
)
1180 || (strstr (format
, "B1") != NULL
1181 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1186 /* probe variations. */
1187 if (!resolved
&& CONST_STRNEQ (idesc
->name
, "probe"))
1189 resolved
= strcmp (ic
->name
, "probe") == 0
1190 && !((strstr (idesc
->name
, "fault") != NULL
)
1191 ^ (format
&& strstr (format
, "M40") != NULL
));
1194 /* mov variations. */
1195 if (!resolved
&& is_mov
)
1199 /* mov alias for fmerge. */
1200 if (strcmp (ic
->name
, "fmerge") == 0)
1202 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1203 && idesc
->operands
[1] == IA64_OPND_F3
;
1205 /* mov alias for adds (r3 or imm14). */
1206 else if (strcmp (ic
->name
, "adds") == 0)
1208 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1209 && (idesc
->operands
[1] == IA64_OPND_R3
1210 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1212 /* mov alias for addl. */
1213 else if (strcmp (ic
->name
, "addl") == 0)
1215 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1216 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1220 /* Some variants of mov and mov.[im]. */
1221 if (!resolved
&& CONST_STRNEQ (ic
->name
, "mov_"))
1222 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1225 /* Keep track of this so we can flag any insn classes which aren't
1226 mapped onto at least one real insn. */
1228 ic
->terminal_resolved
= 1;
1230 else for (i
= 0; i
< ic
->nsubs
; i
++)
1232 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1236 for (j
= 0; j
< ic
->nxsubs
; j
++)
1237 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1241 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1248 /* If it's in this IC, add the IC note (if any) to the insn. */
1251 if (ic
->note
&& notep
)
1253 if (*notep
&& *notep
!= ic
->note
)
1254 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1255 *notep
, ic
->note
, ic
->name
);
1266 lookup_regindex (const char *name
, int specifier
)
1271 if (strstr (name
, "[RSC]"))
1273 if (strstr (name
, "[BSP]"))
1275 else if (strstr (name
, "[BSPSTORE]"))
1277 else if (strstr (name
, "[RNAT]"))
1279 else if (strstr (name
, "[FCR]"))
1281 else if (strstr (name
, "[EFLAG]"))
1283 else if (strstr (name
, "[CSD]"))
1285 else if (strstr (name
, "[SSD]"))
1287 else if (strstr (name
, "[CFLG]"))
1289 else if (strstr (name
, "[FSR]"))
1291 else if (strstr (name
, "[FIR]"))
1293 else if (strstr (name
, "[FDR]"))
1295 else if (strstr (name
, "[CCV]"))
1297 else if (strstr (name
, "[ITC]"))
1299 else if (strstr (name
, "[RUC]"))
1301 else if (strstr (name
, "[PFS]"))
1303 else if (strstr (name
, "[LC]"))
1305 else if (strstr (name
, "[EC]"))
1309 if (strstr (name
, "[DCR]"))
1311 else if (strstr (name
, "[ITM]"))
1313 else if (strstr (name
, "[IVA]"))
1315 else if (strstr (name
, "[PTA]"))
1317 else if (strstr (name
, "[GPTA]"))
1319 else if (strstr (name
, "[IPSR]"))
1321 else if (strstr (name
, "[ISR]"))
1323 else if (strstr (name
, "[IIP]"))
1325 else if (strstr (name
, "[IFA]"))
1327 else if (strstr (name
, "[ITIR]"))
1329 else if (strstr (name
, "[IIPA]"))
1331 else if (strstr (name
, "[IFS]"))
1333 else if (strstr (name
, "[IIM]"))
1335 else if (strstr (name
, "[IHA]"))
1337 else if (strstr (name
, "[LID]"))
1339 else if (strstr (name
, "[IVR]"))
1341 else if (strstr (name
, "[TPR]"))
1343 else if (strstr (name
, "[EOI]"))
1345 else if (strstr (name
, "[ITV]"))
1347 else if (strstr (name
, "[PMV]"))
1349 else if (strstr (name
, "[CMCV]"))
1353 if (strstr (name
, ".be"))
1355 else if (strstr (name
, ".up"))
1357 else if (strstr (name
, ".ac"))
1359 else if (strstr (name
, ".mfl"))
1361 else if (strstr (name
, ".mfh"))
1363 else if (strstr (name
, ".ic"))
1365 else if (strstr (name
, ".i"))
1367 else if (strstr (name
, ".pk"))
1369 else if (strstr (name
, ".dt"))
1371 else if (strstr (name
, ".dfl"))
1373 else if (strstr (name
, ".dfh"))
1375 else if (strstr (name
, ".sp"))
1377 else if (strstr (name
, ".pp"))
1379 else if (strstr (name
, ".di"))
1381 else if (strstr (name
, ".si"))
1383 else if (strstr (name
, ".db"))
1385 else if (strstr (name
, ".lp"))
1387 else if (strstr (name
, ".tb"))
1389 else if (strstr (name
, ".rt"))
1391 else if (strstr (name
, ".cpl"))
1393 else if (strstr (name
, ".rs"))
1395 else if (strstr (name
, ".mc"))
1397 else if (strstr (name
, ".it"))
1399 else if (strstr (name
, ".id"))
1401 else if (strstr (name
, ".da"))
1403 else if (strstr (name
, ".dd"))
1405 else if (strstr (name
, ".ss"))
1407 else if (strstr (name
, ".ri"))
1409 else if (strstr (name
, ".ed"))
1411 else if (strstr (name
, ".bn"))
1413 else if (strstr (name
, ".ia"))
1415 else if (strstr (name
, ".vm"))
1426 lookup_specifier (const char *name
)
1428 if (strchr (name
, '%'))
1430 if (strstr (name
, "AR[K%]") != NULL
)
1431 return IA64_RS_AR_K
;
1432 if (strstr (name
, "AR[UNAT]") != NULL
)
1433 return IA64_RS_AR_UNAT
;
1434 if (strstr (name
, "AR%, % in 8") != NULL
)
1436 if (strstr (name
, "AR%, % in 48") != NULL
)
1438 if (strstr (name
, "BR%") != NULL
)
1440 if (strstr (name
, "CR[IRR%]") != NULL
)
1441 return IA64_RS_CR_IRR
;
1442 if (strstr (name
, "CR[LRR%]") != NULL
)
1443 return IA64_RS_CR_LRR
;
1444 if (strstr (name
, "CR%") != NULL
)
1446 if (strstr (name
, "FR%, % in 0") != NULL
)
1448 if (strstr (name
, "FR%, % in 2") != NULL
)
1450 if (strstr (name
, "GR%") != NULL
)
1452 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1454 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1457 warn (_("don't know how to specify %% dependency %s\n"),
1460 else if (strchr (name
, '#'))
1462 if (strstr (name
, "CPUID#") != NULL
)
1463 return IA64_RS_CPUID
;
1464 if (strstr (name
, "DBR#") != NULL
)
1466 if (strstr (name
, "IBR#") != NULL
)
1468 if (strstr (name
, "MSR#") != NULL
)
1470 if (strstr (name
, "PKR#") != NULL
)
1472 if (strstr (name
, "PMC#") != NULL
)
1474 if (strstr (name
, "PMD#") != NULL
)
1476 if (strstr (name
, "RR#") != NULL
)
1479 warn (_("Don't know how to specify # dependency %s\n"),
1482 else if (CONST_STRNEQ (name
, "AR[FPSR]"))
1483 return IA64_RS_AR_FPSR
;
1484 else if (CONST_STRNEQ (name
, "AR["))
1486 else if (CONST_STRNEQ (name
, "CR["))
1488 else if (CONST_STRNEQ (name
, "PSR."))
1490 else if (strcmp (name
, "InService*") == 0)
1491 return IA64_RS_INSERVICE
;
1492 else if (strcmp (name
, "GR0") == 0)
1494 else if (strcmp (name
, "CFM") == 0)
1496 else if (strcmp (name
, "PR63") == 0)
1497 return IA64_RS_PR63
;
1498 else if (strcmp (name
, "RSE") == 0)
1505 print_dependency_table ()
1511 for (i
=0;i
< iclen
;i
++)
1513 if (ics
[i
]->is_class
)
1517 if (ics
[i
]->comment
)
1518 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1519 ics
[i
]->name
, ics
[i
]->comment
);
1521 warn (_("IC:%s has no terminals or sub-classes\n"),
1527 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1529 if (ics
[i
]->comment
)
1530 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1531 ics
[i
]->name
, ics
[i
]->comment
);
1533 warn (_("no insns mapped directly to terminal IC %s\n"),
1539 for (i
= 0; i
< iclen
; i
++)
1543 mark_used (ics
[i
], 1);
1544 warn (_("class %s is defined but not used\n"),
1550 for (i
= 0; i
< rdepslen
; i
++)
1552 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1554 if (rdeps
[i
]->total_chks
== 0)
1556 if (rdeps
[i
]->total_regs
)
1557 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1558 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1560 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1561 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1563 else if (rdeps
[i
]->total_regs
== 0)
1564 warn (_("rsrc %s (%s) has no regs\n"),
1565 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1569 /* The dependencies themselves. */
1570 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1571 for (i
= 0; i
< rdepslen
; i
++)
1573 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1575 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1576 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1578 printf (" { \"%s\", %d, %d, %d, %d, ",
1579 rdeps
[i
]->name
, specifier
,
1580 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1581 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1583 const char *quote
, *rest
;
1586 rest
= rdeps
[i
]->extra
;
1587 quote
= strchr (rest
, '\"');
1588 while (quote
!= NULL
)
1590 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1592 quote
= strchr (rest
, '\"');
1594 printf ("%s\", ", rest
);
1602 /* And dependency lists. */
1603 for (i
=0;i
< dlistlen
;i
++)
1606 printf ("static const unsigned short dep%d[] = {\n ", i
);
1607 for (j
=0;j
< dlists
[i
]->len
; j
++)
1609 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1616 printf ("\n};\n\n");
1619 /* And opcode dependency list. */
1620 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1621 printf ("static const struct ia64_opcode_dependency\n");
1622 printf ("op_dependencies[] = {\n");
1623 for (i
= 0; i
< opdeplen
; i
++)
1626 if (opdeps
[i
]->chk
== -1)
1627 printf ("0, NULL, ");
1629 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1630 if (opdeps
[i
]->reg
== -1)
1631 printf ("0, NULL, ");
1633 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1640 /* Add STR to the string table. */
1641 static struct string_entry
*
1642 insert_string (char *str
)
1644 int start
= 0, end
= strtablen
;
1647 if (strtablen
== strtabtotlen
)
1650 string_table
= (struct string_entry
**)
1651 xrealloc (string_table
,
1652 sizeof (struct string_entry
**) * strtabtotlen
);
1658 string_table
[0] = tmalloc (struct string_entry
);
1659 string_table
[0]->s
= xstrdup (str
);
1660 string_table
[0]->num
= 0;
1661 return string_table
[0];
1664 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1666 else if (strcmp (str
, string_table
[0]->s
) < 0)
1674 i
= (start
+ end
) / 2;
1675 c
= strcmp (str
, string_table
[i
]->s
);
1680 return string_table
[i
];
1689 for (; i
> 0 && i
< strtablen
; i
--)
1690 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1693 for (; i
< strtablen
; i
++)
1694 if (strcmp (str
, string_table
[i
]->s
) < 0)
1697 for (x
= strtablen
- 1; x
>= i
; x
--)
1699 string_table
[x
+ 1] = string_table
[x
];
1700 string_table
[x
+ 1]->num
= x
+ 1;
1703 string_table
[i
] = tmalloc (struct string_entry
);
1704 string_table
[i
]->s
= xstrdup (str
);
1705 string_table
[i
]->num
= i
;
1708 return string_table
[i
];
1711 static struct bittree
*
1712 make_bittree_entry (void)
1714 struct bittree
*res
= tmalloc (struct bittree
);
1717 res
->bits
[0] = NULL
;
1718 res
->bits
[1] = NULL
;
1719 res
->bits
[2] = NULL
;
1721 res
->bits_to_skip
= 0;
1726 static struct disent
*
1727 add_dis_table_ent (which
, insn
, order
, completer_index
)
1728 struct disent
*which
;
1731 int completer_index
;
1741 while (ent
->nexte
!= NULL
)
1744 ent
= (ent
->nexte
= tmalloc (struct disent
));
1748 ent
= tmalloc (struct disent
);
1749 ent
->next_ent
= disinsntable
;
1756 ent
->priority
= order
;
1758 while (completer_index
!= 1)
1760 ci
= (ci
<< 1) | (completer_index
& 1);
1761 completer_index
>>= 1;
1763 ent
->completer_index
= ci
;
1770 struct disent
*ent
= disinsntable
;
1771 struct disent
*prev
= ent
;
1773 ent
->ournum
= 32768;
1774 while ((ent
= ent
->next_ent
) != NULL
)
1776 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1782 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1783 opcodenum
, order
, completer_index
)
1784 struct bittree
*curr_ent
;
1790 int completer_index
;
1794 struct bittree
*next
;
1798 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1801 curr_ent
->disent
= nent
;
1805 m
= ((ia64_insn
) 1) << bit
;
1808 b
= (opcode
& m
) ? 1 : 0;
1812 next
= curr_ent
->bits
[b
];
1815 next
= make_bittree_entry ();
1816 curr_ent
->bits
[b
] = next
;
1818 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1823 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1824 struct bittree
*first
;
1828 struct completer_entry
*ent
;
1829 int completer_index
;
1831 if (completer_index
& (1 << 20))
1836 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1837 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1838 (completer_index
<< 1) | 1);
1840 if (ent
->is_terminal
)
1842 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1843 opcodenum
, opcode_count
- ent
->order
- 1,
1844 (completer_index
<< 1) | 1);
1846 completer_index
<<= 1;
1847 ent
= ent
->alternative
;
1851 /* This optimization pass combines multiple "don't care" nodes. */
1853 compact_distree (ent
)
1854 struct bittree
*ent
;
1856 #define IS_SKIP(ent) \
1857 ((ent->bits[2] !=NULL) \
1858 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1861 struct bittree
*nent
= ent
;
1864 while (IS_SKIP (nent
))
1867 nent
= nent
->bits
[2];
1872 struct bittree
*next
= ent
->bits
[2];
1874 ent
->bits
[0] = nent
->bits
[0];
1875 ent
->bits
[1] = nent
->bits
[1];
1876 ent
->bits
[2] = nent
->bits
[2];
1877 ent
->disent
= nent
->disent
;
1879 ent
->bits_to_skip
= bitcnt
;
1880 while (next
!= nent
)
1882 struct bittree
*b
= next
;
1883 next
= next
->bits
[2];
1889 for (x
= 0; x
< 3; x
++)
1891 struct bittree
*i
= ent
->bits
[x
];
1894 compact_distree (i
);
1898 static unsigned char *insn_list
;
1899 static int insn_list_len
= 0;
1900 static int tot_insn_list_len
= 0;
1902 /* Generate the disassembler state machine corresponding to the tree
1906 struct bittree
*ent
;
1909 int our_offset
= insn_list_len
;
1911 int totbits
= bitsused
;
1914 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1916 /* If this is a terminal entry, there's no point in skipping any
1918 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1919 ent
->bits
[2] == NULL
)
1921 if (ent
->disent
== NULL
)
1927 /* Calculate the amount of space needed for this entry, or at least
1928 a conservatively large approximation. */
1932 for (x
= 1; x
< 3; x
++)
1933 if (ent
->bits
[x
] != NULL
)
1936 if (ent
->disent
!= NULL
)
1938 if (ent
->bits
[2] != NULL
)
1944 /* Now allocate the space. */
1945 needed_bytes
= (totbits
+ 7) / 8;
1946 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1948 tot_insn_list_len
+= 256;
1949 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1951 our_offset
= insn_list_len
;
1952 insn_list_len
+= needed_bytes
;
1953 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1955 /* Encode the skip entry by setting bit 6 set in the state op field,
1956 and store the # of bits to skip immediately after. */
1960 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1961 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1964 #define IS_ONLY_IFZERO(ENT) \
1965 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1966 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1968 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1970 if (ent
->bits
[0] != NULL
)
1972 struct bittree
*nent
= ent
->bits
[0];
1975 insn_list
[our_offset
] |= 0x80;
1977 /* We can encode sequences of multiple "if (bit is zero)" tests
1978 by storing the # of zero bits to check in the lower 3 bits of
1979 the instruction. However, this only applies if the state
1980 solely tests for a zero bit. */
1982 if (IS_ONLY_IFZERO (ent
))
1984 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1986 nent
= nent
->bits
[0];
1990 insn_list
[our_offset
+ 0] |= zero_count
;
1992 zero_dest
= insn_list_len
;
1993 gen_dis_table (nent
);
1996 /* Now store the remaining tests. We also handle a sole "termination
1997 entry" by storing it as an "any bit" test. */
1999 for (x
= 1; x
< 3; x
++)
2001 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
2003 struct bittree
*i
= ent
->bits
[x
];
2009 /* If the instruction being branched to only consists of
2010 a termination entry, use the termination entry as the
2011 place to branch to instead. */
2012 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
2013 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
2015 idest
= i
->disent
->ournum
;
2019 idest
= insn_list_len
- our_offset
;
2022 idest
= ent
->disent
->ournum
;
2024 /* If the destination offset for the if (bit is 1) test is less
2025 than 256 bytes away, we can store it as 8-bits instead of 16;
2026 the instruction has bit 5 set for the 16-bit address, and bit
2027 4 for the 8-bit address. Since we've already allocated 16
2028 bits for the address we need to deallocate the space.
2030 Note that branchings within the table are relative, and
2031 there are no branches that branch past our instruction yet
2032 so we do not need to adjust any other offsets. */
2037 int start
= our_offset
+ bitsused
/ 8 + 1;
2039 memmove (insn_list
+ start
,
2040 insn_list
+ start
+ 1,
2041 insn_list_len
- (start
+ 1));
2046 insn_list
[our_offset
] |= 0x10;
2050 insn_list
[our_offset
] |= 0x20;
2054 /* An instruction which solely consists of a termination
2055 marker and whose disassembly name index is < 4096
2056 can be stored in 16 bits. The encoding is slightly
2057 odd; the upper 4 bits of the instruction are 0x3, and
2058 bit 3 loses its normal meaning. */
2060 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2061 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2062 && ent
->disent
!= NULL
2063 && ent
->disent
->ournum
< (32768 + 4096))
2065 int start
= our_offset
+ bitsused
/ 8 + 1;
2067 memmove (insn_list
+ start
,
2068 insn_list
+ start
+ 1,
2069 insn_list_len
- (start
+ 1));
2075 insn_list
[our_offset
] |= 0x30;
2079 insn_list
[our_offset
] |= 0x08;
2088 else if (! (id
& 32768))
2092 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2094 printf ("%d: try %d\n", our_offset
, id
);
2097 /* Store the address of the entry being branched to. */
2098 while (currbits
>= 0)
2100 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2102 if (idest
& (1 << currbits
))
2103 *byte
|= (1 << (7 - (bitsused
% 8)));
2109 /* Now generate the states for the entry being branched to. */
2118 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2120 if (ent
->bits
[0] != NULL
)
2121 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2125 if (bitsused
!= totbits
)
2130 print_dis_table (void)
2133 struct disent
*cent
= disinsntable
;
2135 printf ("static const char dis_table[] = {\n");
2136 for (x
= 0; x
< insn_list_len
; x
++)
2138 if ((x
> 0) && ((x
% 12) == 0))
2141 printf ("0x%02x, ", insn_list
[x
]);
2143 printf ("\n};\n\n");
2145 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2146 while (cent
!= NULL
)
2148 struct disent
*ent
= cent
;
2152 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2153 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2157 cent
= cent
->next_ent
;
2163 generate_disassembler (void)
2167 bittree
= make_bittree_entry ();
2169 for (i
= 0; i
< otlen
; i
++)
2171 struct main_entry
*ptr
= ordered_table
[i
];
2173 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2174 add_dis_entry (bittree
,
2175 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2177 ptr
->completers
, 1);
2180 compact_distree (bittree
);
2182 gen_dis_table (bittree
);
2188 print_string_table (void)
2191 char lbuf
[80], buf
[80];
2194 printf ("static const char * const ia64_strings[] = {\n");
2197 for (x
= 0; x
< strtablen
; x
++)
2201 if (strlen (string_table
[x
]->s
) > 75)
2204 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2207 if ((blen
+ len
) > 75)
2209 printf (" %s\n", lbuf
);
2218 printf (" %s\n", lbuf
);
2223 static struct completer_entry
**glist
;
2224 static int glistlen
= 0;
2225 static int glisttotlen
= 0;
2227 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2230 completer_entries_eq (ent1
, ent2
)
2231 struct completer_entry
*ent1
, *ent2
;
2233 while (ent1
!= NULL
&& ent2
!= NULL
)
2235 if (ent1
->name
->num
!= ent2
->name
->num
2236 || ent1
->bits
!= ent2
->bits
2237 || ent1
->mask
!= ent2
->mask
2238 || ent1
->is_terminal
!= ent2
->is_terminal
2239 || ent1
->dependencies
!= ent2
->dependencies
2240 || ent1
->order
!= ent2
->order
)
2243 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2246 ent1
= ent1
->alternative
;
2247 ent2
= ent2
->alternative
;
2250 return ent1
== ent2
;
2253 /* Insert ENT into the global list of completers and return it. If an
2254 equivalent entry (according to completer_entries_eq) already exists,
2255 it is returned instead. */
2256 static struct completer_entry
*
2257 insert_gclist (struct completer_entry
*ent
)
2265 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2266 ent
->alternative
= insert_gclist (ent
->alternative
);
2271 if (glisttotlen
== glistlen
)
2274 glist
= (struct completer_entry
**)
2275 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2285 if (ent
->name
->num
< glist
[0]->name
->num
)
2287 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2295 i
= (start
+ end
) / 2;
2296 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2303 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2317 while (i
< glistlen
)
2319 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2322 if (completer_entries_eq (ent
, glist
[i
]))
2330 for (; i
> 0 && i
< glistlen
; i
--)
2331 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2334 for (; i
< glistlen
; i
++)
2335 if (ent
->name
->num
< glist
[i
]->name
->num
)
2338 for (x
= glistlen
- 1; x
>= i
; x
--)
2339 glist
[x
+ 1] = glist
[x
];
2348 get_prefix_len (name
)
2353 if (name
[0] == '\0')
2356 c
= strchr (name
, '.');
2360 return strlen (name
);
2364 compute_completer_bits (ment
, ent
)
2365 struct main_entry
*ment
;
2366 struct completer_entry
*ent
;
2370 compute_completer_bits (ment
, ent
->addl_entries
);
2372 if (ent
->is_terminal
)
2375 ia64_insn our_bits
= ent
->bits
;
2376 struct completer_entry
*p
= ent
->parent
;
2380 while (p
!= NULL
&& ! p
->is_terminal
)
2386 p_bits
= ment
->opcode
->opcode
;
2388 for (x
= 0; x
< 64; x
++)
2390 ia64_insn m
= ((ia64_insn
) 1) << x
;
2392 if ((p_bits
& m
) != (our_bits
& m
))
2397 ent
->bits
= our_bits
;
2406 ent
= ent
->alternative
;
2410 /* Find identical completer trees that are used in different
2411 instructions and collapse their entries. */
2413 collapse_redundant_completers (void)
2415 struct main_entry
*ptr
;
2418 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2420 if (ptr
->completers
== NULL
)
2423 compute_completer_bits (ptr
, ptr
->completers
);
2424 ptr
->completers
= insert_gclist (ptr
->completers
);
2427 /* The table has been finalized, now number the indexes. */
2428 for (x
= 0; x
< glistlen
; x
++)
2433 /* Attach two lists of dependencies to each opcode.
2434 1) all resources which, when already marked in use, conflict with this
2436 2) all resources which must be marked in use when this opcode is used
2439 insert_opcode_dependencies (opc
, cmp
)
2440 struct ia64_opcode
*opc
;
2441 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2443 /* Note all resources which point to this opcode. rfi has the most chks
2444 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2447 unsigned short regs
[256];
2449 unsigned short chks
[256];
2450 /* Flag insns for which no class matched; there should be none. */
2451 int no_class_found
= 1;
2453 for (i
= 0; i
< rdepslen
; i
++)
2455 struct rdep
*rs
= rdeps
[i
];
2458 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2459 && CONST_STRNEQ (rs
->name
, "PR%")
2461 no_class_found
= 99;
2463 for (j
=0; j
< rs
->nregs
;j
++)
2467 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2469 /* We can ignore ic_note 11 for non PR resources. */
2470 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2473 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2474 && ic_note
!= rs
->regnotes
[j
]
2475 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2476 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2477 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2478 rs
->name
, rs
->regnotes
[j
]);
2479 /* Instruction class notes override resource notes.
2480 So far, only note 11 applies to an IC instead of a resource,
2481 and note 11 implies note 1. */
2483 regs
[nregs
++] = RDEP(ic_note
, i
);
2485 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2491 for (j
= 0; j
< rs
->nchks
; j
++)
2495 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2497 /* We can ignore ic_note 11 for non PR resources. */
2498 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2501 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2502 && ic_note
!= rs
->chknotes
[j
]
2503 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2504 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2505 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2506 rs
->name
, rs
->chknotes
[j
]);
2508 chks
[nchks
++] = RDEP(ic_note
, i
);
2510 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2518 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2520 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2522 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2526 insert_completer_entry (opc
, tabent
, order
)
2527 struct ia64_opcode
*opc
;
2528 struct main_entry
*tabent
;
2531 struct completer_entry
**ptr
= &tabent
->completers
;
2532 struct completer_entry
*parent
= NULL
;
2533 char pcopy
[129], *prefix
;
2536 if (strlen (opc
->name
) > 128)
2539 strcpy (pcopy
, opc
->name
);
2540 prefix
= pcopy
+ get_prefix_len (pcopy
);
2542 if (prefix
[0] != '\0')
2547 int need_new_ent
= 1;
2548 int plen
= get_prefix_len (prefix
);
2549 struct string_entry
*sent
;
2551 at_end
= (prefix
[plen
] == '\0');
2552 prefix
[plen
] = '\0';
2553 sent
= insert_string (prefix
);
2555 while (*ptr
!= NULL
)
2557 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2565 ptr
= &((*ptr
)->alternative
);
2570 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2573 nent
->parent
= parent
;
2574 nent
->addl_entries
= NULL
;
2575 nent
->alternative
= *ptr
;
2577 nent
->is_terminal
= 0;
2578 nent
->dependencies
= -1;
2584 ptr
= &((*ptr
)->addl_entries
);
2589 if ((*ptr
)->is_terminal
)
2592 (*ptr
)->is_terminal
= 1;
2593 (*ptr
)->mask
= (ia64_insn
)-1;
2594 (*ptr
)->bits
= opc
->opcode
;
2595 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2596 (*ptr
)->order
= order
;
2600 print_completer_entry (ent
)
2601 struct completer_entry
*ent
;
2604 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2608 while (! (mask
& 1))
2615 if (bits
& 0xffffffff00000000LL
)
2619 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2623 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2624 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2626 ent
->is_terminal
? 1 : 0,
2631 print_completer_table ()
2635 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2636 for (x
= 0; x
< glistlen
; x
++)
2637 print_completer_entry (glist
[x
]);
2642 opcodes_eq (opc1
, opc2
)
2643 struct ia64_opcode
*opc1
;
2644 struct ia64_opcode
*opc2
;
2649 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2650 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2651 || (opc1
->flags
!= opc2
->flags
))
2654 for (x
= 0; x
< 5; x
++)
2655 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2658 plen1
= get_prefix_len (opc1
->name
);
2659 plen2
= get_prefix_len (opc2
->name
);
2661 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2668 add_opcode_entry (opc
)
2669 struct ia64_opcode
*opc
;
2671 struct main_entry
**place
;
2672 struct string_entry
*name
;
2676 if (strlen (opc
->name
) > 128)
2680 strcpy (prefix
, opc
->name
);
2681 prefix
[get_prefix_len (prefix
)] = '\0';
2682 name
= insert_string (prefix
);
2684 /* Walk the list of opcode table entries. If it's a new
2685 instruction, allocate and fill in a new entry. Note
2686 the main table is alphabetical by opcode name. */
2688 while (*place
!= NULL
)
2690 if ((*place
)->name
->num
== name
->num
2691 && opcodes_eq ((*place
)->opcode
, opc
))
2696 if ((*place
)->name
->num
> name
->num
)
2699 place
= &((*place
)->next
);
2703 struct main_entry
*nent
= tmalloc (struct main_entry
);
2707 nent
->next
= *place
;
2708 nent
->completers
= 0;
2711 if (otlen
== ottotlen
)
2714 ordered_table
= (struct main_entry
**)
2715 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2717 ordered_table
[otlen
++] = nent
;
2720 insert_completer_entry (opc
, *place
, opcode_count
++);
2724 print_main_table (void)
2726 struct main_entry
*ptr
= maintable
;
2729 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2732 printf (" { %d, %d, %d, 0x",
2735 ptr
->opcode
->num_outputs
);
2736 opcode_fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2738 opcode_fprintf_vma (stdout
, ptr
->opcode
->mask
);
2739 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2740 ptr
->opcode
->operands
[0],
2741 ptr
->opcode
->operands
[1],
2742 ptr
->opcode
->operands
[2],
2743 ptr
->opcode
->operands
[3],
2744 ptr
->opcode
->operands
[4],
2746 ptr
->completers
->num
);
2748 ptr
->main_index
= index
++;
2757 struct ia64_opcode
*table
;
2761 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2763 add_opcode_entry (table
+ curr_opcode
);
2764 if (table
[curr_opcode
].num_outputs
== 2
2765 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2766 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2767 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2768 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2770 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2773 *alias
= table
[curr_opcode
];
2774 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2775 alias
->operands
[i
- 1] = alias
->operands
[i
];
2776 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2777 --alias
->num_outputs
;
2778 alias
->flags
|= PSEUDO
;
2779 add_opcode_entry (alias
);
2785 /* Program options. */
2786 #define OPTION_SRCDIR 200
2788 struct option long_options
[] =
2790 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2791 {"debug", no_argument
, NULL
, 'd'},
2792 {"version", no_argument
, NULL
, 'V'},
2793 {"help", no_argument
, NULL
, 'h'},
2794 {0, no_argument
, NULL
, 0}
2798 print_version (void)
2800 printf ("%s: version 1.0\n", program_name
);
2805 usage (FILE * stream
, int status
)
2807 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2813 main (int argc
, char **argv
)
2815 extern int chdir (char *);
2816 char *srcdir
= NULL
;
2819 program_name
= *argv
;
2820 xmalloc_set_program_name (program_name
);
2822 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2847 if (chdir (srcdir
) != 0)
2848 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2849 srcdir
, strerror (errno
));
2851 load_insn_classes ();
2852 load_dependencies ();
2854 shrink (ia64_opcodes_a
);
2855 shrink (ia64_opcodes_b
);
2856 shrink (ia64_opcodes_f
);
2857 shrink (ia64_opcodes_i
);
2858 shrink (ia64_opcodes_m
);
2859 shrink (ia64_opcodes_x
);
2860 shrink (ia64_opcodes_d
);
2862 collapse_redundant_completers ();
2864 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2865 printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\
2867 This file is part of the GNU opcodes library.\n\
2869 This library is free software; you can redistribute it and/or modify\n\
2870 it under the terms of the GNU General Public License as published by\n\
2871 the Free Software Foundation; either version 3, or (at your option)\n\
2872 any later version.\n\
2874 It is distributed in the hope that it will be useful, but WITHOUT\n\
2875 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2876 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2877 License for more details.\n\
2879 You should have received a copy of the GNU General Public License\n\
2880 along with this program; see the file COPYING. If not, write to the\n\
2881 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2882 02110-1301, USA. */\n");
2884 print_string_table ();
2885 print_dependency_table ();
2886 print_completer_table ();
2887 print_main_table ();
2889 generate_disassembler ();