1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
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 (const char *ref
, int **usersp
, int *nusersp
,
701 char *line
= xstrdup (ref
);
703 int *users
= *usersp
;
704 int count
= *nusersp
;
705 int *notes
= *notesp
;
717 while (ISSPACE (*tmp
))
720 while (*tmp
&& *tmp
!= ',')
725 xsect
= strchr (name
, '\\');
726 if ((notestr
= strstr (name
, "+")) != NULL
)
730 note
= atoi (notestr
+ 1);
731 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
733 /* Note 13 always implies note 1. */
734 if (strcmp (notestr
, "+1+13") == 0)
736 else if (!xsect
|| nextnotestr
< xsect
)
737 warn (_("multiple note %s not handled\n"), notestr
);
745 /* All classes are created when the insn class table is parsed;
746 Individual instructions might not appear until the dependency tables
747 are read. Only create new classes if it's *not* an insn class,
748 or if it's a composite class (which wouldn't necessarily be in the IC
750 if (! CONST_STRNEQ (name
, "IC:") || xsect
!= NULL
)
753 iclass
= fetch_insn_class (name
, create
);
757 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
759 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
761 users
[count
++] = iclass
;
762 mark_used (ics
[iclass
], 0);
765 printf("Class %s not found\n", name
);
767 /* Update the return values. */
776 parse_semantics (char *sem
)
778 if (strcmp (sem
, "none") == 0)
779 return IA64_DVS_NONE
;
780 else if (strcmp (sem
, "implied") == 0)
781 return IA64_DVS_IMPLIED
;
782 else if (strcmp (sem
, "impliedF") == 0)
783 return IA64_DVS_IMPLIEDF
;
784 else if (strcmp (sem
, "data") == 0)
785 return IA64_DVS_DATA
;
786 else if (strcmp (sem
, "instr") == 0)
787 return IA64_DVS_INSTR
;
788 else if (strcmp (sem
, "specific") == 0)
789 return IA64_DVS_SPECIFIC
;
790 else if (strcmp (sem
, "stop") == 0)
791 return IA64_DVS_STOP
;
793 return IA64_DVS_OTHER
;
797 add_dep (const char *name
, const char *chk
, const char *reg
,
798 int semantics
, int mode
, char *extra
, int flag
)
802 rs
= insert_resource (name
, mode
);
804 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
805 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
807 rs
->semantics
= semantics
;
809 rs
->waw_special
= flag
;
813 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
815 FILE *fp
= fopen (filename
, "r");
819 fail (_("can't find %s for reading\n"), filename
);
821 fgets (buf
, sizeof(buf
), fp
);
829 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
832 while (ISSPACE (buf
[strlen (buf
) - 1]))
833 buf
[strlen (buf
) - 1] = '\0';
840 while (ISSPACE (*tmp
))
843 tmp
= strchr (tmp
, ';');
847 while (ISSPACE (*tmp
))
850 tmp
= strchr (tmp
, ';');
854 while (ISSPACE (*tmp
))
856 semantics
= parse_semantics (tmp
);
857 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
859 /* For WAW entries, if the chks and regs differ, we need to enter the
860 entries in both positions so that the tables will be parsed properly,
861 without a lot of extra work. */
862 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
864 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
865 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
869 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
876 load_dependencies (void)
878 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
879 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
880 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
883 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
886 /* Is the given operand an indirect register file operand? */
888 irf_operand (int op
, const char *field
)
892 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
893 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
894 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
895 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
899 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
900 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
901 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
902 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
903 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
904 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
905 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
906 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
910 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
911 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
;
970 if (ic
->name
[5] == 'n')
972 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
973 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
975 return strstr (format
, "M42") != NULL
;
977 return strstr (format
, "M43") != NULL
;
979 else if (ic
->name
[5] == 'p')
981 return idesc
->operands
[1] == IA64_OPND_IP
;
987 if (ic
->name
[5] == 'r')
989 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
990 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
991 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
993 return strstr (format
, "I23") != NULL
;
995 return strstr (format
, "I24") != NULL
;
997 return strstr (format
, "I25") != NULL
;
999 else if (ic
->name
[5] == 's')
1001 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
1002 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
1004 return strstr (format
, "M35") != NULL
;
1006 return strstr (format
, "M36") != NULL
;
1013 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1014 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1016 return strstr (format
, "M35") != NULL
;
1018 return strstr (format
, "M36") != NULL
;
1025 /* Is the given opcode in the given insn class? */
1027 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1028 const char *format
, const char *field
, int *notep
)
1035 if (CONST_STRNEQ (ic
->comment
, "Format"))
1037 /* Assume that the first format seen is the most restrictive, and
1038 only keep a later one if it looks like it's more restrictive. */
1041 if (strlen (ic
->comment
) < strlen (format
))
1043 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1044 ic
->comment
, format
);
1045 format
= ic
->comment
;
1049 format
= ic
->comment
;
1051 else if (CONST_STRNEQ (ic
->comment
, "Field"))
1054 warn (_("overlapping field %s->%s\n"),
1055 ic
->comment
, field
);
1056 field
= ic
->comment
;
1060 /* An insn class matches anything that is the same followed by completers,
1061 except when the absence and presence of completers constitutes different
1063 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1065 int is_mov
= CONST_STRNEQ (idesc
->name
, "mov");
1066 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1067 int len
= strlen(ic
->name
);
1069 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1070 && (idesc
->name
[len
] == '\0'
1071 || idesc
->name
[len
] == '.'));
1073 /* All break, nop, and hint variations must match exactly. */
1075 (strcmp (ic
->name
, "break") == 0
1076 || strcmp (ic
->name
, "nop") == 0
1077 || strcmp (ic
->name
, "hint") == 0))
1078 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1080 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1081 unless specifically allowed by clauses in this block. */
1082 if (resolved
&& field
)
1084 /* Check Field(sf)==sN against opcode sN. */
1085 if (strstr(field
, "(sf)==") != NULL
)
1089 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1090 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1092 /* Check Field(lftype)==XXX. */
1093 else if (strstr (field
, "(lftype)") != NULL
)
1095 if (strstr (idesc
->name
, "fault") != NULL
)
1096 resolved
= strstr (field
, "fault") != NULL
;
1098 resolved
= strstr (field
, "fault") == NULL
;
1100 /* Handle Field(ctype)==XXX. */
1101 else if (strstr (field
, "(ctype)") != NULL
)
1103 if (strstr (idesc
->name
, "or.andcm"))
1104 resolved
= strstr (field
, "or.andcm") != NULL
;
1105 else if (strstr (idesc
->name
, "and.orcm"))
1106 resolved
= strstr (field
, "and.orcm") != NULL
;
1107 else if (strstr (idesc
->name
, "orcm"))
1108 resolved
= strstr (field
, "or orcm") != NULL
;
1109 else if (strstr (idesc
->name
, "or"))
1110 resolved
= strstr (field
, "or orcm") != NULL
;
1111 else if (strstr (idesc
->name
, "andcm"))
1112 resolved
= strstr (field
, "and andcm") != NULL
;
1113 else if (strstr (idesc
->name
, "and"))
1114 resolved
= strstr (field
, "and andcm") != NULL
;
1115 else if (strstr (idesc
->name
, "unc"))
1116 resolved
= strstr (field
, "unc") != NULL
;
1118 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1122 if (resolved
&& format
)
1124 if (CONST_STRNEQ (idesc
->name
, "dep")
1125 && strstr (format
, "I13") != NULL
)
1126 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1127 else if (CONST_STRNEQ (idesc
->name
, "chk")
1128 && strstr (format
, "M21") != NULL
)
1129 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1130 else if (CONST_STRNEQ (idesc
->name
, "lfetch"))
1131 resolved
= (strstr (format
, "M14 M15") != NULL
1132 && (idesc
->operands
[1] == IA64_OPND_R2
1133 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1134 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1135 && strstr (format
, "B5") != NULL
)
1136 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1137 else if (CONST_STRNEQ (idesc
->name
, "br.call")
1138 && strstr (format
, "B3") != NULL
)
1139 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1140 else if (CONST_STRNEQ (idesc
->name
, "brp")
1141 && strstr (format
, "B7") != NULL
)
1142 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1143 else if (strcmp (ic
->name
, "invala") == 0)
1144 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1145 else if (CONST_STRNEQ (idesc
->name
, "st")
1146 && (strstr (format
, "M5") != NULL
1147 || strstr (format
, "M10") != NULL
))
1148 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1149 else if (CONST_STRNEQ (idesc
->name
, "ld")
1150 && (strstr (format
, "M2 M3") != NULL
1151 || strstr (format
, "M12") != NULL
1152 || strstr (format
, "M7 M8") != NULL
))
1153 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1158 /* Misc brl variations ('.cond' is optional);
1159 plain brl matches brl.cond. */
1161 && (strcmp (idesc
->name
, "brl") == 0
1162 || CONST_STRNEQ (idesc
->name
, "brl."))
1163 && strcmp (ic
->name
, "brl.cond") == 0)
1168 /* Misc br variations ('.cond' is optional). */
1170 && (strcmp (idesc
->name
, "br") == 0
1171 || CONST_STRNEQ (idesc
->name
, "br."))
1172 && strcmp (ic
->name
, "br.cond") == 0)
1175 resolved
= (strstr (format
, "B4") != NULL
1176 && idesc
->operands
[0] == IA64_OPND_B2
)
1177 || (strstr (format
, "B1") != NULL
1178 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1183 /* probe variations. */
1184 if (!resolved
&& CONST_STRNEQ (idesc
->name
, "probe"))
1186 resolved
= strcmp (ic
->name
, "probe") == 0
1187 && !((strstr (idesc
->name
, "fault") != NULL
)
1188 ^ (format
&& strstr (format
, "M40") != NULL
));
1191 /* mov variations. */
1192 if (!resolved
&& is_mov
)
1196 /* mov alias for fmerge. */
1197 if (strcmp (ic
->name
, "fmerge") == 0)
1199 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1200 && idesc
->operands
[1] == IA64_OPND_F3
;
1202 /* mov alias for adds (r3 or imm14). */
1203 else if (strcmp (ic
->name
, "adds") == 0)
1205 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1206 && (idesc
->operands
[1] == IA64_OPND_R3
1207 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1209 /* mov alias for addl. */
1210 else if (strcmp (ic
->name
, "addl") == 0)
1212 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1213 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1217 /* Some variants of mov and mov.[im]. */
1218 if (!resolved
&& CONST_STRNEQ (ic
->name
, "mov_"))
1219 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1222 /* Keep track of this so we can flag any insn classes which aren't
1223 mapped onto at least one real insn. */
1225 ic
->terminal_resolved
= 1;
1227 else for (i
= 0; i
< ic
->nsubs
; i
++)
1229 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1233 for (j
= 0; j
< ic
->nxsubs
; j
++)
1234 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1238 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1245 /* If it's in this IC, add the IC note (if any) to the insn. */
1248 if (ic
->note
&& notep
)
1250 if (*notep
&& *notep
!= ic
->note
)
1251 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1252 *notep
, ic
->note
, ic
->name
);
1263 lookup_regindex (const char *name
, int specifier
)
1268 if (strstr (name
, "[RSC]"))
1270 if (strstr (name
, "[BSP]"))
1272 else if (strstr (name
, "[BSPSTORE]"))
1274 else if (strstr (name
, "[RNAT]"))
1276 else if (strstr (name
, "[FCR]"))
1278 else if (strstr (name
, "[EFLAG]"))
1280 else if (strstr (name
, "[CSD]"))
1282 else if (strstr (name
, "[SSD]"))
1284 else if (strstr (name
, "[CFLG]"))
1286 else if (strstr (name
, "[FSR]"))
1288 else if (strstr (name
, "[FIR]"))
1290 else if (strstr (name
, "[FDR]"))
1292 else if (strstr (name
, "[CCV]"))
1294 else if (strstr (name
, "[ITC]"))
1296 else if (strstr (name
, "[RUC]"))
1298 else if (strstr (name
, "[PFS]"))
1300 else if (strstr (name
, "[LC]"))
1302 else if (strstr (name
, "[EC]"))
1306 if (strstr (name
, "[DCR]"))
1308 else if (strstr (name
, "[ITM]"))
1310 else if (strstr (name
, "[IVA]"))
1312 else if (strstr (name
, "[PTA]"))
1314 else if (strstr (name
, "[GPTA]"))
1316 else if (strstr (name
, "[IPSR]"))
1318 else if (strstr (name
, "[ISR]"))
1320 else if (strstr (name
, "[IIP]"))
1322 else if (strstr (name
, "[IFA]"))
1324 else if (strstr (name
, "[ITIR]"))
1326 else if (strstr (name
, "[IIPA]"))
1328 else if (strstr (name
, "[IFS]"))
1330 else if (strstr (name
, "[IIM]"))
1332 else if (strstr (name
, "[IHA]"))
1334 else if (strstr (name
, "[LID]"))
1336 else if (strstr (name
, "[IVR]"))
1338 else if (strstr (name
, "[TPR]"))
1340 else if (strstr (name
, "[EOI]"))
1342 else if (strstr (name
, "[ITV]"))
1344 else if (strstr (name
, "[PMV]"))
1346 else if (strstr (name
, "[CMCV]"))
1350 if (strstr (name
, ".be"))
1352 else if (strstr (name
, ".up"))
1354 else if (strstr (name
, ".ac"))
1356 else if (strstr (name
, ".mfl"))
1358 else if (strstr (name
, ".mfh"))
1360 else if (strstr (name
, ".ic"))
1362 else if (strstr (name
, ".i"))
1364 else if (strstr (name
, ".pk"))
1366 else if (strstr (name
, ".dt"))
1368 else if (strstr (name
, ".dfl"))
1370 else if (strstr (name
, ".dfh"))
1372 else if (strstr (name
, ".sp"))
1374 else if (strstr (name
, ".pp"))
1376 else if (strstr (name
, ".di"))
1378 else if (strstr (name
, ".si"))
1380 else if (strstr (name
, ".db"))
1382 else if (strstr (name
, ".lp"))
1384 else if (strstr (name
, ".tb"))
1386 else if (strstr (name
, ".rt"))
1388 else if (strstr (name
, ".cpl"))
1390 else if (strstr (name
, ".rs"))
1392 else if (strstr (name
, ".mc"))
1394 else if (strstr (name
, ".it"))
1396 else if (strstr (name
, ".id"))
1398 else if (strstr (name
, ".da"))
1400 else if (strstr (name
, ".dd"))
1402 else if (strstr (name
, ".ss"))
1404 else if (strstr (name
, ".ri"))
1406 else if (strstr (name
, ".ed"))
1408 else if (strstr (name
, ".bn"))
1410 else if (strstr (name
, ".ia"))
1412 else if (strstr (name
, ".vm"))
1423 lookup_specifier (const char *name
)
1425 if (strchr (name
, '%'))
1427 if (strstr (name
, "AR[K%]") != NULL
)
1428 return IA64_RS_AR_K
;
1429 if (strstr (name
, "AR[UNAT]") != NULL
)
1430 return IA64_RS_AR_UNAT
;
1431 if (strstr (name
, "AR%, % in 8") != NULL
)
1433 if (strstr (name
, "AR%, % in 48") != NULL
)
1435 if (strstr (name
, "BR%") != NULL
)
1437 if (strstr (name
, "CR[IIB%]") != NULL
)
1438 return IA64_RS_CR_IIB
;
1439 if (strstr (name
, "CR[IRR%]") != NULL
)
1440 return IA64_RS_CR_IRR
;
1441 if (strstr (name
, "CR[LRR%]") != NULL
)
1442 return IA64_RS_CR_LRR
;
1443 if (strstr (name
, "CR%") != NULL
)
1445 if (strstr (name
, "FR%, % in 0") != NULL
)
1447 if (strstr (name
, "FR%, % in 2") != NULL
)
1449 if (strstr (name
, "GR%") != NULL
)
1451 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1453 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1456 warn (_("don't know how to specify %% dependency %s\n"),
1459 else if (strchr (name
, '#'))
1461 if (strstr (name
, "CPUID#") != NULL
)
1462 return IA64_RS_CPUID
;
1463 if (strstr (name
, "DBR#") != NULL
)
1465 if (strstr (name
, "IBR#") != NULL
)
1467 if (strstr (name
, "MSR#") != NULL
)
1469 if (strstr (name
, "PKR#") != NULL
)
1471 if (strstr (name
, "PMC#") != NULL
)
1473 if (strstr (name
, "PMD#") != NULL
)
1475 if (strstr (name
, "RR#") != NULL
)
1478 warn (_("Don't know how to specify # dependency %s\n"),
1481 else if (CONST_STRNEQ (name
, "AR[FPSR]"))
1482 return IA64_RS_AR_FPSR
;
1483 else if (CONST_STRNEQ (name
, "AR["))
1485 else if (CONST_STRNEQ (name
, "CR["))
1487 else if (CONST_STRNEQ (name
, "PSR."))
1489 else if (strcmp (name
, "InService*") == 0)
1490 return IA64_RS_INSERVICE
;
1491 else if (strcmp (name
, "GR0") == 0)
1493 else if (strcmp (name
, "CFM") == 0)
1495 else if (strcmp (name
, "PR63") == 0)
1496 return IA64_RS_PR63
;
1497 else if (strcmp (name
, "RSE") == 0)
1504 print_dependency_table (void)
1510 for (i
=0;i
< iclen
;i
++)
1512 if (ics
[i
]->is_class
)
1516 if (ics
[i
]->comment
)
1517 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1518 ics
[i
]->name
, ics
[i
]->comment
);
1520 warn (_("IC:%s has no terminals or sub-classes\n"),
1526 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1528 if (ics
[i
]->comment
)
1529 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1530 ics
[i
]->name
, ics
[i
]->comment
);
1532 warn (_("no insns mapped directly to terminal IC %s\n"),
1538 for (i
= 0; i
< iclen
; i
++)
1542 mark_used (ics
[i
], 1);
1543 warn (_("class %s is defined but not used\n"),
1549 for (i
= 0; i
< rdepslen
; i
++)
1551 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1553 if (rdeps
[i
]->total_chks
== 0)
1555 if (rdeps
[i
]->total_regs
)
1556 warn (_("Warning: rsrc %s (%s) has no chks\n"),
1557 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1559 warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1560 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1562 else if (rdeps
[i
]->total_regs
== 0)
1563 warn (_("rsrc %s (%s) has no regs\n"),
1564 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1568 /* The dependencies themselves. */
1569 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1570 for (i
= 0; i
< rdepslen
; i
++)
1572 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1574 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1575 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1577 printf (" { \"%s\", %d, %d, %d, %d, ",
1578 rdeps
[i
]->name
, specifier
,
1579 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1580 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1582 const char *quote
, *rest
;
1585 rest
= rdeps
[i
]->extra
;
1586 quote
= strchr (rest
, '\"');
1587 while (quote
!= NULL
)
1589 printf ("%.*s\\\"", (int) (quote
- rest
), rest
);
1591 quote
= strchr (rest
, '\"');
1593 printf ("%s\", ", rest
);
1601 /* And dependency lists. */
1602 for (i
=0;i
< dlistlen
;i
++)
1605 printf ("static const unsigned short dep%d[] = {\n ", i
);
1606 for (j
=0;j
< dlists
[i
]->len
; j
++)
1608 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1615 printf ("\n};\n\n");
1618 /* And opcode dependency list. */
1619 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1620 printf ("static const struct ia64_opcode_dependency\n");
1621 printf ("op_dependencies[] = {\n");
1622 for (i
= 0; i
< opdeplen
; i
++)
1625 if (opdeps
[i
]->chk
== -1)
1626 printf ("0, NULL, ");
1628 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1629 if (opdeps
[i
]->reg
== -1)
1630 printf ("0, NULL, ");
1632 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1639 /* Add STR to the string table. */
1640 static struct string_entry
*
1641 insert_string (char *str
)
1643 int start
= 0, end
= strtablen
;
1646 if (strtablen
== strtabtotlen
)
1649 string_table
= (struct string_entry
**)
1650 xrealloc (string_table
,
1651 sizeof (struct string_entry
**) * strtabtotlen
);
1657 string_table
[0] = tmalloc (struct string_entry
);
1658 string_table
[0]->s
= xstrdup (str
);
1659 string_table
[0]->num
= 0;
1660 return string_table
[0];
1663 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1665 else if (strcmp (str
, string_table
[0]->s
) < 0)
1673 i
= (start
+ end
) / 2;
1674 c
= strcmp (str
, string_table
[i
]->s
);
1679 return string_table
[i
];
1688 for (; i
> 0 && i
< strtablen
; i
--)
1689 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1692 for (; i
< strtablen
; i
++)
1693 if (strcmp (str
, string_table
[i
]->s
) < 0)
1696 for (x
= strtablen
- 1; x
>= i
; x
--)
1698 string_table
[x
+ 1] = string_table
[x
];
1699 string_table
[x
+ 1]->num
= x
+ 1;
1702 string_table
[i
] = tmalloc (struct string_entry
);
1703 string_table
[i
]->s
= xstrdup (str
);
1704 string_table
[i
]->num
= i
;
1707 return string_table
[i
];
1710 static struct bittree
*
1711 make_bittree_entry (void)
1713 struct bittree
*res
= tmalloc (struct bittree
);
1716 res
->bits
[0] = NULL
;
1717 res
->bits
[1] = NULL
;
1718 res
->bits
[2] = NULL
;
1720 res
->bits_to_skip
= 0;
1725 static struct disent
*
1726 add_dis_table_ent (struct disent
*which
, int insn
, int order
,
1727 int completer_index
)
1737 while (ent
->nexte
!= NULL
)
1740 ent
= (ent
->nexte
= tmalloc (struct disent
));
1744 ent
= tmalloc (struct disent
);
1745 ent
->next_ent
= disinsntable
;
1752 ent
->priority
= order
;
1754 while (completer_index
!= 1)
1756 ci
= (ci
<< 1) | (completer_index
& 1);
1757 completer_index
>>= 1;
1759 ent
->completer_index
= ci
;
1764 finish_distable (void)
1766 struct disent
*ent
= disinsntable
;
1767 struct disent
*prev
= ent
;
1769 ent
->ournum
= 32768;
1770 while ((ent
= ent
->next_ent
) != NULL
)
1772 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1778 insert_bit_table_ent (struct bittree
*curr_ent
, int bit
, ia64_insn opcode
,
1779 ia64_insn mask
, int opcodenum
, int order
,
1780 int completer_index
)
1784 struct bittree
*next
;
1788 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1791 curr_ent
->disent
= nent
;
1795 m
= ((ia64_insn
) 1) << bit
;
1798 b
= (opcode
& m
) ? 1 : 0;
1802 next
= curr_ent
->bits
[b
];
1805 next
= make_bittree_entry ();
1806 curr_ent
->bits
[b
] = next
;
1808 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1813 add_dis_entry (struct bittree
*first
, ia64_insn opcode
, ia64_insn mask
,
1814 int opcodenum
, struct completer_entry
*ent
, int completer_index
)
1816 if (completer_index
& (1 << 20))
1821 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1822 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1823 (completer_index
<< 1) | 1);
1825 if (ent
->is_terminal
)
1827 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1828 opcodenum
, opcode_count
- ent
->order
- 1,
1829 (completer_index
<< 1) | 1);
1831 completer_index
<<= 1;
1832 ent
= ent
->alternative
;
1836 /* This optimization pass combines multiple "don't care" nodes. */
1838 compact_distree (struct bittree
*ent
)
1840 #define IS_SKIP(ent) \
1841 ((ent->bits[2] !=NULL) \
1842 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1845 struct bittree
*nent
= ent
;
1848 while (IS_SKIP (nent
))
1851 nent
= nent
->bits
[2];
1856 struct bittree
*next
= ent
->bits
[2];
1858 ent
->bits
[0] = nent
->bits
[0];
1859 ent
->bits
[1] = nent
->bits
[1];
1860 ent
->bits
[2] = nent
->bits
[2];
1861 ent
->disent
= nent
->disent
;
1863 ent
->bits_to_skip
= bitcnt
;
1864 while (next
!= nent
)
1866 struct bittree
*b
= next
;
1867 next
= next
->bits
[2];
1873 for (x
= 0; x
< 3; x
++)
1875 struct bittree
*i
= ent
->bits
[x
];
1878 compact_distree (i
);
1882 static unsigned char *insn_list
;
1883 static int insn_list_len
= 0;
1884 static int tot_insn_list_len
= 0;
1886 /* Generate the disassembler state machine corresponding to the tree
1889 gen_dis_table (struct bittree
*ent
)
1892 int our_offset
= insn_list_len
;
1894 int totbits
= bitsused
;
1897 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1899 /* If this is a terminal entry, there's no point in skipping any
1901 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1902 ent
->bits
[2] == NULL
)
1904 if (ent
->disent
== NULL
)
1910 /* Calculate the amount of space needed for this entry, or at least
1911 a conservatively large approximation. */
1915 for (x
= 1; x
< 3; x
++)
1916 if (ent
->bits
[x
] != NULL
)
1919 if (ent
->disent
!= NULL
)
1921 if (ent
->bits
[2] != NULL
)
1927 /* Now allocate the space. */
1928 needed_bytes
= (totbits
+ 7) / 8;
1929 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1931 tot_insn_list_len
+= 256;
1932 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1934 our_offset
= insn_list_len
;
1935 insn_list_len
+= needed_bytes
;
1936 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1938 /* Encode the skip entry by setting bit 6 set in the state op field,
1939 and store the # of bits to skip immediately after. */
1943 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1944 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1947 #define IS_ONLY_IFZERO(ENT) \
1948 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1949 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1951 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1953 if (ent
->bits
[0] != NULL
)
1955 struct bittree
*nent
= ent
->bits
[0];
1958 insn_list
[our_offset
] |= 0x80;
1960 /* We can encode sequences of multiple "if (bit is zero)" tests
1961 by storing the # of zero bits to check in the lower 3 bits of
1962 the instruction. However, this only applies if the state
1963 solely tests for a zero bit. */
1965 if (IS_ONLY_IFZERO (ent
))
1967 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1969 nent
= nent
->bits
[0];
1973 insn_list
[our_offset
+ 0] |= zero_count
;
1975 zero_dest
= insn_list_len
;
1976 gen_dis_table (nent
);
1979 /* Now store the remaining tests. We also handle a sole "termination
1980 entry" by storing it as an "any bit" test. */
1982 for (x
= 1; x
< 3; x
++)
1984 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1986 struct bittree
*i
= ent
->bits
[x
];
1992 /* If the instruction being branched to only consists of
1993 a termination entry, use the termination entry as the
1994 place to branch to instead. */
1995 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1996 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1998 idest
= i
->disent
->ournum
;
2002 idest
= insn_list_len
- our_offset
;
2005 idest
= ent
->disent
->ournum
;
2007 /* If the destination offset for the if (bit is 1) test is less
2008 than 256 bytes away, we can store it as 8-bits instead of 16;
2009 the instruction has bit 5 set for the 16-bit address, and bit
2010 4 for the 8-bit address. Since we've already allocated 16
2011 bits for the address we need to deallocate the space.
2013 Note that branchings within the table are relative, and
2014 there are no branches that branch past our instruction yet
2015 so we do not need to adjust any other offsets. */
2020 int start
= our_offset
+ bitsused
/ 8 + 1;
2022 memmove (insn_list
+ start
,
2023 insn_list
+ start
+ 1,
2024 insn_list_len
- (start
+ 1));
2029 insn_list
[our_offset
] |= 0x10;
2033 insn_list
[our_offset
] |= 0x20;
2037 /* An instruction which solely consists of a termination
2038 marker and whose disassembly name index is < 4096
2039 can be stored in 16 bits. The encoding is slightly
2040 odd; the upper 4 bits of the instruction are 0x3, and
2041 bit 3 loses its normal meaning. */
2043 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2044 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2045 && ent
->disent
!= NULL
2046 && ent
->disent
->ournum
< (32768 + 4096))
2048 int start
= our_offset
+ bitsused
/ 8 + 1;
2050 memmove (insn_list
+ start
,
2051 insn_list
+ start
+ 1,
2052 insn_list_len
- (start
+ 1));
2058 insn_list
[our_offset
] |= 0x30;
2062 insn_list
[our_offset
] |= 0x08;
2071 else if (! (id
& 32768))
2075 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2077 printf ("%d: try %d\n", our_offset
, id
);
2080 /* Store the address of the entry being branched to. */
2081 while (currbits
>= 0)
2083 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2085 if (idest
& (1 << currbits
))
2086 *byte
|= (1 << (7 - (bitsused
% 8)));
2092 /* Now generate the states for the entry being branched to. */
2101 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2103 if (ent
->bits
[0] != NULL
)
2104 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2108 if (bitsused
!= totbits
)
2113 print_dis_table (void)
2116 struct disent
*cent
= disinsntable
;
2118 printf ("static const char dis_table[] = {\n");
2119 for (x
= 0; x
< insn_list_len
; x
++)
2121 if ((x
> 0) && ((x
% 12) == 0))
2124 printf ("0x%02x, ", insn_list
[x
]);
2126 printf ("\n};\n\n");
2128 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2129 while (cent
!= NULL
)
2131 struct disent
*ent
= cent
;
2135 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2136 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2140 cent
= cent
->next_ent
;
2146 generate_disassembler (void)
2150 bittree
= make_bittree_entry ();
2152 for (i
= 0; i
< otlen
; i
++)
2154 struct main_entry
*ptr
= ordered_table
[i
];
2156 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2157 add_dis_entry (bittree
,
2158 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2160 ptr
->completers
, 1);
2163 compact_distree (bittree
);
2165 gen_dis_table (bittree
);
2171 print_string_table (void)
2174 char lbuf
[80], buf
[80];
2177 printf ("static const char * const ia64_strings[] = {\n");
2180 for (x
= 0; x
< strtablen
; x
++)
2184 if (strlen (string_table
[x
]->s
) > 75)
2187 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2190 if ((blen
+ len
) > 75)
2192 printf (" %s\n", lbuf
);
2201 printf (" %s\n", lbuf
);
2206 static struct completer_entry
**glist
;
2207 static int glistlen
= 0;
2208 static int glisttotlen
= 0;
2210 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2213 completer_entries_eq (struct completer_entry
*ent1
,
2214 struct completer_entry
*ent2
)
2216 while (ent1
!= NULL
&& ent2
!= NULL
)
2218 if (ent1
->name
->num
!= ent2
->name
->num
2219 || ent1
->bits
!= ent2
->bits
2220 || ent1
->mask
!= ent2
->mask
2221 || ent1
->is_terminal
!= ent2
->is_terminal
2222 || ent1
->dependencies
!= ent2
->dependencies
2223 || ent1
->order
!= ent2
->order
)
2226 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2229 ent1
= ent1
->alternative
;
2230 ent2
= ent2
->alternative
;
2233 return ent1
== ent2
;
2236 /* Insert ENT into the global list of completers and return it. If an
2237 equivalent entry (according to completer_entries_eq) already exists,
2238 it is returned instead. */
2239 static struct completer_entry
*
2240 insert_gclist (struct completer_entry
*ent
)
2248 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2249 ent
->alternative
= insert_gclist (ent
->alternative
);
2254 if (glisttotlen
== glistlen
)
2257 glist
= (struct completer_entry
**)
2258 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2268 if (ent
->name
->num
< glist
[0]->name
->num
)
2270 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2278 i
= (start
+ end
) / 2;
2279 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2286 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2300 while (i
< glistlen
)
2302 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2305 if (completer_entries_eq (ent
, glist
[i
]))
2313 for (; i
> 0 && i
< glistlen
; i
--)
2314 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2317 for (; i
< glistlen
; i
++)
2318 if (ent
->name
->num
< glist
[i
]->name
->num
)
2321 for (x
= glistlen
- 1; x
>= i
; x
--)
2322 glist
[x
+ 1] = glist
[x
];
2331 get_prefix_len (const char *name
)
2335 if (name
[0] == '\0')
2338 c
= strchr (name
, '.');
2342 return strlen (name
);
2346 compute_completer_bits (struct main_entry
*ment
, struct completer_entry
*ent
)
2350 compute_completer_bits (ment
, ent
->addl_entries
);
2352 if (ent
->is_terminal
)
2355 ia64_insn our_bits
= ent
->bits
;
2356 struct completer_entry
*p
= ent
->parent
;
2360 while (p
!= NULL
&& ! p
->is_terminal
)
2366 p_bits
= ment
->opcode
->opcode
;
2368 for (x
= 0; x
< 64; x
++)
2370 ia64_insn m
= ((ia64_insn
) 1) << x
;
2372 if ((p_bits
& m
) != (our_bits
& m
))
2377 ent
->bits
= our_bits
;
2386 ent
= ent
->alternative
;
2390 /* Find identical completer trees that are used in different
2391 instructions and collapse their entries. */
2393 collapse_redundant_completers (void)
2395 struct main_entry
*ptr
;
2398 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2400 if (ptr
->completers
== NULL
)
2403 compute_completer_bits (ptr
, ptr
->completers
);
2404 ptr
->completers
= insert_gclist (ptr
->completers
);
2407 /* The table has been finalized, now number the indexes. */
2408 for (x
= 0; x
< glistlen
; x
++)
2413 /* Attach two lists of dependencies to each opcode.
2414 1) all resources which, when already marked in use, conflict with this
2416 2) all resources which must be marked in use when this opcode is used
2419 insert_opcode_dependencies (struct ia64_opcode
*opc
,
2420 struct completer_entry
*cmp ATTRIBUTE_UNUSED
)
2422 /* Note all resources which point to this opcode. rfi has the most chks
2423 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2426 unsigned short regs
[256];
2428 unsigned short chks
[256];
2429 /* Flag insns for which no class matched; there should be none. */
2430 int no_class_found
= 1;
2432 for (i
= 0; i
< rdepslen
; i
++)
2434 struct rdep
*rs
= rdeps
[i
];
2437 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2438 && CONST_STRNEQ (rs
->name
, "PR%")
2440 no_class_found
= 99;
2442 for (j
=0; j
< rs
->nregs
;j
++)
2446 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2448 /* We can ignore ic_note 11 for non PR resources. */
2449 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2452 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2453 && ic_note
!= rs
->regnotes
[j
]
2454 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2455 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2456 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2457 rs
->name
, rs
->regnotes
[j
]);
2458 /* Instruction class notes override resource notes.
2459 So far, only note 11 applies to an IC instead of a resource,
2460 and note 11 implies note 1. */
2462 regs
[nregs
++] = RDEP(ic_note
, i
);
2464 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2470 for (j
= 0; j
< rs
->nchks
; j
++)
2474 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2476 /* We can ignore ic_note 11 for non PR resources. */
2477 if (ic_note
== 11 && ! CONST_STRNEQ (rs
->name
, "PR"))
2480 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2481 && ic_note
!= rs
->chknotes
[j
]
2482 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2483 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2484 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2485 rs
->name
, rs
->chknotes
[j
]);
2487 chks
[nchks
++] = RDEP(ic_note
, i
);
2489 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2497 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2499 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2501 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2505 insert_completer_entry (struct ia64_opcode
*opc
, struct main_entry
*tabent
,
2508 struct completer_entry
**ptr
= &tabent
->completers
;
2509 struct completer_entry
*parent
= NULL
;
2510 char pcopy
[129], *prefix
;
2513 if (strlen (opc
->name
) > 128)
2516 strcpy (pcopy
, opc
->name
);
2517 prefix
= pcopy
+ get_prefix_len (pcopy
);
2519 if (prefix
[0] != '\0')
2524 int need_new_ent
= 1;
2525 int plen
= get_prefix_len (prefix
);
2526 struct string_entry
*sent
;
2528 at_end
= (prefix
[plen
] == '\0');
2529 prefix
[plen
] = '\0';
2530 sent
= insert_string (prefix
);
2532 while (*ptr
!= NULL
)
2534 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2542 ptr
= &((*ptr
)->alternative
);
2547 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2550 nent
->parent
= parent
;
2551 nent
->addl_entries
= NULL
;
2552 nent
->alternative
= *ptr
;
2554 nent
->is_terminal
= 0;
2555 nent
->dependencies
= -1;
2561 ptr
= &((*ptr
)->addl_entries
);
2566 if ((*ptr
)->is_terminal
)
2569 (*ptr
)->is_terminal
= 1;
2570 (*ptr
)->mask
= (ia64_insn
)-1;
2571 (*ptr
)->bits
= opc
->opcode
;
2572 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2573 (*ptr
)->order
= order
;
2577 print_completer_entry (struct completer_entry
*ent
)
2580 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2584 while (! (mask
& 1))
2591 if (bits
& 0xffffffff00000000LL
)
2595 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2599 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2600 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2602 ent
->is_terminal
? 1 : 0,
2607 print_completer_table (void)
2611 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2612 for (x
= 0; x
< glistlen
; x
++)
2613 print_completer_entry (glist
[x
]);
2618 opcodes_eq (struct ia64_opcode
*opc1
, struct ia64_opcode
*opc2
)
2623 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2624 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2625 || (opc1
->flags
!= opc2
->flags
))
2628 for (x
= 0; x
< 5; x
++)
2629 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2632 plen1
= get_prefix_len (opc1
->name
);
2633 plen2
= get_prefix_len (opc2
->name
);
2635 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2642 add_opcode_entry (struct ia64_opcode
*opc
)
2644 struct main_entry
**place
;
2645 struct string_entry
*name
;
2649 if (strlen (opc
->name
) > 128)
2653 strcpy (prefix
, opc
->name
);
2654 prefix
[get_prefix_len (prefix
)] = '\0';
2655 name
= insert_string (prefix
);
2657 /* Walk the list of opcode table entries. If it's a new
2658 instruction, allocate and fill in a new entry. Note
2659 the main table is alphabetical by opcode name. */
2661 while (*place
!= NULL
)
2663 if ((*place
)->name
->num
== name
->num
2664 && opcodes_eq ((*place
)->opcode
, opc
))
2669 if ((*place
)->name
->num
> name
->num
)
2672 place
= &((*place
)->next
);
2676 struct main_entry
*nent
= tmalloc (struct main_entry
);
2680 nent
->next
= *place
;
2681 nent
->completers
= 0;
2684 if (otlen
== ottotlen
)
2687 ordered_table
= (struct main_entry
**)
2688 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2690 ordered_table
[otlen
++] = nent
;
2693 insert_completer_entry (opc
, *place
, opcode_count
++);
2697 print_main_table (void)
2699 struct main_entry
*ptr
= maintable
;
2702 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2705 printf (" { %d, %d, %d, 0x",
2708 ptr
->opcode
->num_outputs
);
2709 opcode_fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2711 opcode_fprintf_vma (stdout
, ptr
->opcode
->mask
);
2712 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2713 ptr
->opcode
->operands
[0],
2714 ptr
->opcode
->operands
[1],
2715 ptr
->opcode
->operands
[2],
2716 ptr
->opcode
->operands
[3],
2717 ptr
->opcode
->operands
[4],
2719 ptr
->completers
->num
);
2721 ptr
->main_index
= index
++;
2729 shrink (struct ia64_opcode
*table
)
2733 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2735 add_opcode_entry (table
+ curr_opcode
);
2736 if (table
[curr_opcode
].num_outputs
== 2
2737 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2738 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2739 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2740 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2742 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2745 *alias
= table
[curr_opcode
];
2746 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2747 alias
->operands
[i
- 1] = alias
->operands
[i
];
2748 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2749 --alias
->num_outputs
;
2750 alias
->flags
|= PSEUDO
;
2751 add_opcode_entry (alias
);
2757 /* Program options. */
2758 #define OPTION_SRCDIR 200
2760 struct option long_options
[] =
2762 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2763 {"debug", no_argument
, NULL
, 'd'},
2764 {"version", no_argument
, NULL
, 'V'},
2765 {"help", no_argument
, NULL
, 'h'},
2766 {0, no_argument
, NULL
, 0}
2770 print_version (void)
2772 printf ("%s: version 1.0\n", program_name
);
2777 usage (FILE * stream
, int status
)
2779 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2785 main (int argc
, char **argv
)
2787 extern int chdir (char *);
2788 char *srcdir
= NULL
;
2791 program_name
= *argv
;
2792 xmalloc_set_program_name (program_name
);
2794 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2819 if (chdir (srcdir
) != 0)
2820 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2821 srcdir
, strerror (errno
));
2823 load_insn_classes ();
2824 load_dependencies ();
2826 shrink (ia64_opcodes_a
);
2827 shrink (ia64_opcodes_b
);
2828 shrink (ia64_opcodes_f
);
2829 shrink (ia64_opcodes_i
);
2830 shrink (ia64_opcodes_m
);
2831 shrink (ia64_opcodes_x
);
2832 shrink (ia64_opcodes_d
);
2834 collapse_redundant_completers ();
2836 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2837 printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\
2839 This file is part of the GNU opcodes library.\n\
2841 This library is free software; you can redistribute it and/or modify\n\
2842 it under the terms of the GNU General Public License as published by\n\
2843 the Free Software Foundation; either version 3, or (at your option)\n\
2844 any later version.\n\
2846 It is distributed in the hope that it will be useful, but WITHOUT\n\
2847 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2848 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2849 License for more details.\n\
2851 You should have received a copy of the GNU General Public License\n\
2852 along with this program; see the file COPYING. If not, write to the\n\
2853 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2854 02110-1301, USA. */\n");
2856 print_string_table ();
2857 print_dependency_table ();
2858 print_completer_table ();
2859 print_main_table ();
2861 generate_disassembler ();