1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
5 This file is part of GDB, GAS, and the GNU binutils.
7 GDB, GAS, and the GNU binutils are free software; you can redistribute
8 them and/or modify them under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either version
10 2, or (at your option) any later version.
12 GDB, GAS, and the GNU binutils are distributed in the hope that they
13 will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this file; see the file COPYING. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* While the ia64-opc-* set of opcode tables are easy to maintain,
23 they waste a tremendous amount of space. ia64-gen rearranges the
24 instructions into a directed acyclic graph (DAG) of instruction opcodes and
25 their possible completers, as well as compacting the set of strings used.
27 The disassembler table consists of a state machine that does
28 branching based on the bits of the opcode being disassembled. The
29 state encodings have been chosen to minimize the amount of space
32 The resource table is constructed based on some text dependency tables,
33 which are also easier to maintain than the final representation. */
40 #include "libiberty.h"
41 #include "safe-ctype.h"
45 #include "ia64-opc-a.c"
46 #include "ia64-opc-i.c"
47 #include "ia64-opc-m.c"
48 #include "ia64-opc-b.c"
49 #include "ia64-opc-f.c"
50 #include "ia64-opc-x.c"
51 #include "ia64-opc-d.c"
54 #define _(String) gettext (String)
56 const char * program_name
= NULL
;
59 #define tmalloc(X) (X *) xmalloc (sizeof (X))
61 /* The main opcode table entry. Each entry is a unique combination of
62 name and flags (no two entries in the table compare as being equal
66 /* The base name of this opcode. The names of its completers are
67 appended to it to generate the full instruction name. */
68 struct string_entry
*name
;
69 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
70 it uses the first one passed to add_opcode_entry. */
71 struct ia64_opcode
*opcode
;
72 /* The list of completers that can be applied to this opcode. */
73 struct completer_entry
*completers
;
74 /* Next entry in the chain. */
75 struct main_entry
*next
;
76 /* Index in the main table. */
78 } *maintable
, **ordered_table
;
84 /* The set of possible completers for an opcode. */
85 struct completer_entry
87 /* This entry's index in the ia64_completer_table[] array. */
90 /* The name of the completer. */
91 struct string_entry
*name
;
93 /* This entry's parent. */
94 struct completer_entry
*parent
;
96 /* Set if this is a terminal completer (occurs at the end of an
100 /* An alternative completer. */
101 struct completer_entry
*alternative
;
103 /* Additional completers that can be appended to this one. */
104 struct completer_entry
*addl_entries
;
106 /* Before compute_completer_bits () is invoked, this contains the actual
107 instruction opcode for this combination of opcode and completers.
108 Afterwards, it contains those bits that are different from its
112 /* Bits set to 1 correspond to those bits in this completer's opcode
113 that are different from its parent completer's opcode (or from
114 the base opcode if the entry is the root of the opcode's completer
115 list). This field is filled in by compute_completer_bits (). */
118 /* Index into the opcode dependency list, or -1 if none. */
121 /* Remember the order encountered in the opcode tables. */
125 /* One entry in the disassembler name table. */
128 /* The index into the ia64_name_dis array for this entry. */
131 /* The index into the main_table[] array. */
134 /* The disassmbly priority of this entry. */
137 /* The completer_index value for this entry. */
140 /* How many other entries share this decode. */
143 /* The next entry sharing the same decode. */
144 struct disent
*nexte
;
146 /* The next entry in the name list. */
147 struct disent
*next_ent
;
148 } *disinsntable
= NULL
;
150 /* A state machine that will eventually be used to generate the
151 disassembler table. */
154 struct disent
*disent
;
155 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
160 /* The string table contains all opcodes and completers sorted in
161 alphabetical order. */
163 /* One entry in the string table. */
166 /* The index in the ia64_strings[] array for this entry. */
168 /* And the string. */
170 } **string_table
= NULL
;
173 int strtabtotlen
= 0;
176 /* Resource dependency entries. */
179 char *name
; /* Resource name. */
181 mode
:2, /* RAW, WAW, or WAR. */
182 semantics
:3; /* Dependency semantics. */
183 char *extra
; /* Additional semantics info. */
185 int total_chks
; /* Total #of terminal insns. */
186 int *chks
; /* Insn classes which read (RAW), write
187 (WAW), or write (WAR) this rsrc. */
188 int *chknotes
; /* Dependency notes for each class. */
190 int total_regs
; /* Total #of terminal insns. */
191 int *regs
; /* Insn class which write (RAW), write2
192 (WAW), or read (WAR) this rsrc. */
193 int *regnotes
; /* Dependency notes for each class. */
195 int waw_special
; /* Special WAW dependency note. */
198 static int rdepslen
= 0;
199 static int rdepstotlen
= 0;
201 /* Array of all instruction classes. */
204 char *name
; /* Instruction class name. */
205 int is_class
; /* Is a class, not a terminal. */
207 int *subs
; /* Other classes within this class. */
209 int xsubs
[4]; /* Exclusions. */
210 char *comment
; /* Optional comment. */
211 int note
; /* Optional note. */
212 int terminal_resolved
; /* Did we match this with anything? */
213 int orphan
; /* Detect class orphans. */
216 static int iclen
= 0;
217 static int ictotlen
= 0;
219 /* An opcode dependency (chk/reg pair of dependency lists). */
222 int chk
; /* index into dlists */
223 int reg
; /* index into dlists */
226 static int opdeplen
= 0;
227 static int opdeptotlen
= 0;
229 /* A generic list of dependencies w/notes encoded. These may be shared. */
233 unsigned short *deps
;
236 static int dlistlen
= 0;
237 static int dlisttotlen
= 0;
240 static void fail (const char *, ...);
241 static void warn (const char *, ...);
242 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
243 static int deplist_equals (struct deplist
*, struct deplist
*);
244 static short insert_deplist (int, unsigned short *);
245 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
246 static void mark_used (struct iclass
*, int);
247 static int fetch_insn_class (const char *, int);
248 static int sub_compare (const void *, const void *);
249 static void load_insn_classes (void);
250 static void parse_resource_users (const char *, int **, int *, int **);
251 static int parse_semantics (char *);
252 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
253 static void load_depfile (const char *, enum ia64_dependency_mode
);
254 static void load_dependencies (void);
255 static int irf_operand (int, const char *);
256 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
257 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
258 static int lookup_regindex (const char *, int);
259 static int lookup_specifier (const char *);
260 static void print_dependency_table (void);
261 static struct string_entry
* insert_string (char *);
262 static void gen_dis_table (struct bittree
*);
263 static void print_dis_table (void);
264 static void generate_disassembler (void);
265 static void print_string_table (void);
266 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
267 static struct completer_entry
* insert_gclist (struct completer_entry
*);
268 static int get_prefix_len (const char *);
269 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
270 static void collapse_redundant_completers (void);
271 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
272 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
273 static void print_completer_entry (struct completer_entry
*);
274 static void print_completer_table (void);
275 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
276 static void add_opcode_entry (struct ia64_opcode
*);
277 static void print_main_table (void);
278 static void shrink (struct ia64_opcode
*);
279 static void print_version (void);
280 static void usage (FILE *, int);
281 static void finish_distable (void);
282 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, int);
283 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, int);
284 static void compact_distree (struct bittree
*);
285 static struct bittree
* make_bittree_entry (void);
286 static struct disent
* add_dis_table_ent (struct disent
*, int, int, int);
290 fail (const char *message
, ...)
294 va_start (args
, message
);
295 fprintf (stderr
, _("%s: Error: "), program_name
);
296 vfprintf (stderr
, message
, args
);
302 warn (const char *message
, ...)
306 va_start (args
, message
);
308 fprintf (stderr
, _("%s: Warning: "), program_name
);
309 vfprintf (stderr
, message
, args
);
313 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
315 insert_resource (const char *name
, enum ia64_dependency_mode type
)
317 if (rdepslen
== rdepstotlen
)
320 rdeps
= (struct rdep
**)
321 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
323 rdeps
[rdepslen
] = tmalloc(struct rdep
);
324 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
325 rdeps
[rdepslen
]->name
= xstrdup (name
);
326 rdeps
[rdepslen
]->mode
= type
;
327 rdeps
[rdepslen
]->waw_special
= 0;
329 return rdeps
[rdepslen
++];
332 /* Are the lists of dependency indexes equivalent? */
334 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
338 if (d1
->len
!= d2
->len
)
341 for (i
= 0; i
< d1
->len
; i
++)
342 if (d1
->deps
[i
] != d2
->deps
[i
])
348 /* Add the list of dependencies to the list of dependency lists. */
350 insert_deplist (int count
, unsigned short *deps
)
352 /* Sort the list, then see if an equivalent list exists already.
353 this results in a much smaller set of dependency lists. */
354 struct deplist
*list
;
358 memset ((void *)set
, 0, sizeof (set
));
359 for (i
= 0; i
< count
; i
++)
363 for (i
= 0; i
< (int) sizeof (set
); i
++)
367 list
= tmalloc (struct deplist
);
369 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
371 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
373 list
->deps
[count
++] = i
;
375 /* Does this list exist already? */
376 for (i
= 0; i
< dlistlen
; i
++)
377 if (deplist_equals (list
, dlists
[i
]))
384 if (dlistlen
== dlisttotlen
)
387 dlists
= (struct deplist
**)
388 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
390 dlists
[dlistlen
] = list
;
395 /* Add the given pair of dependency lists to the opcode dependency list. */
397 insert_dependencies (int nchks
, unsigned short *chks
,
398 int nregs
, unsigned short *regs
)
406 regind
= insert_deplist (nregs
, regs
);
408 chkind
= insert_deplist (nchks
, chks
);
410 for (i
= 0; i
< opdeplen
; i
++)
411 if (opdeps
[i
]->chk
== chkind
412 && opdeps
[i
]->reg
== regind
)
415 pair
= tmalloc (struct opdep
);
419 if (opdeplen
== opdeptotlen
)
422 opdeps
= (struct opdep
**)
423 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
425 opdeps
[opdeplen
] = pair
;
431 mark_used (struct iclass
*ic
, int clear_terminals
)
437 ic
->terminal_resolved
= 1;
439 for (i
= 0; i
< ic
->nsubs
; i
++)
440 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
442 for (i
= 0; i
< ic
->nxsubs
; i
++)
443 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
446 /* Look up an instruction class; if CREATE make a new one if none found;
447 returns the index into the insn class array. */
449 fetch_insn_class (const char *full_name
, int create
)
459 if (strncmp (full_name
, "IC:", 3) == 0)
461 name
= xstrdup (full_name
+ 3);
465 name
= xstrdup (full_name
);
467 if ((xsect
= strchr(name
, '\\')) != NULL
)
469 if ((comment
= strchr(name
, '[')) != NULL
)
471 if ((notestr
= strchr(name
, '+')) != NULL
)
474 /* If it is a composite class, then ignore comments and notes that come after
475 the '\\', since they don't apply to the part we are decoding now. */
488 note
= atoi (notestr
+ 1);
489 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
491 if (strcmp (notestr
, "+1+13") == 0)
493 else if (!xsect
|| nextnotestr
< xsect
)
494 warn (_("multiple note %s not handled\n"), notestr
);
498 /* If it's a composite class, leave the notes and comments in place so that
499 we have a unique name for the composite class. Otherwise, we remove
509 for (i
= 0; i
< iclen
; i
++)
510 if (strcmp (name
, ics
[i
]->name
) == 0
511 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
512 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
513 && strncmp (ics
[i
]->comment
, comment
,
514 strlen (ics
[i
]->comment
)) == 0))
515 && note
== ics
[i
]->note
)
521 /* Doesn't exist, so make a new one. */
522 if (iclen
== ictotlen
)
525 ics
= (struct iclass
**)
526 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
530 ics
[ind
] = tmalloc (struct iclass
);
531 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
532 ics
[ind
]->name
= xstrdup (name
);
533 ics
[ind
]->is_class
= is_class
;
534 ics
[ind
]->orphan
= 1;
538 ics
[ind
]->comment
= xstrdup (comment
+ 1);
539 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
543 ics
[ind
]->note
= note
;
545 /* If it's a composite class, there's a comment or note, look for an
546 existing class or terminal with the same name. */
547 if ((xsect
|| comment
|| notestr
) && is_class
)
549 /* First, populate with the class we're based on. */
550 char *subname
= name
;
560 ics
[ind
]->subs
= tmalloc(int);
561 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
566 char *subname
= xsect
+ 1;
568 xsect
= strchr (subname
, '\\');
571 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
579 /* For sorting a class's sub-class list only; make sure classes appear before
582 sub_compare (const void *e1
, const void *e2
)
584 struct iclass
*ic1
= ics
[*(int *)e1
];
585 struct iclass
*ic2
= ics
[*(int *)e2
];
592 else if (ic2
->is_class
)
595 return strcmp (ic1
->name
, ic2
->name
);
599 load_insn_classes (void)
601 FILE *fp
= fopen ("ia64-ic.tbl", "r");
605 fail (_("can't find ia64-ic.tbl for reading\n"));
607 /* Discard first line. */
608 fgets (buf
, sizeof(buf
), fp
);
616 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
619 while (ISSPACE (buf
[strlen (buf
) - 1]))
620 buf
[strlen (buf
) - 1] = '\0';
626 if (tmp
== buf
+ sizeof (buf
))
631 iclass
= fetch_insn_class (name
, 1);
632 ics
[iclass
]->is_class
= 1;
634 if (strcmp (name
, "none") == 0)
636 ics
[iclass
]->is_class
= 0;
637 ics
[iclass
]->terminal_resolved
= 1;
641 /* For this class, record all sub-classes. */
647 while (*tmp
&& ISSPACE (*tmp
))
650 if (tmp
== buf
+ sizeof (buf
))
654 while (*tmp
&& *tmp
!= ',')
657 if (tmp
== buf
+ sizeof (buf
))
663 ics
[iclass
]->subs
= (int *)
664 xrealloc ((void *)ics
[iclass
]->subs
,
665 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
667 sub
= fetch_insn_class (subname
, 1);
668 ics
[iclass
]->subs
= (int *)
669 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
670 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
673 /* Make sure classes come before terminals. */
674 qsort ((void *)ics
[iclass
]->subs
,
675 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
680 printf ("%d classes\n", iclen
);
683 /* Extract the insn classes from the given line. */
685 parse_resource_users (ref
, usersp
, nusersp
, notesp
)
692 char *line
= xstrdup (ref
);
694 int *users
= *usersp
;
695 int count
= *nusersp
;
696 int *notes
= *notesp
;
708 while (ISSPACE (*tmp
))
711 while (*tmp
&& *tmp
!= ',')
716 xsect
= strchr (name
, '\\');
717 if ((notestr
= strstr (name
, "+")) != NULL
)
721 note
= atoi (notestr
+ 1);
722 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
724 /* Note 13 always implies note 1. */
725 if (strcmp (notestr
, "+1+13") == 0)
727 else if (!xsect
|| nextnotestr
< xsect
)
728 warn (_("multiple note %s not handled\n"), notestr
);
736 /* All classes are created when the insn class table is parsed;
737 Individual instructions might not appear until the dependency tables
738 are read. Only create new classes if it's *not* an insn class,
739 or if it's a composite class (which wouldn't necessarily be in the IC
741 if (strncmp (name
, "IC:", 3) != 0 || xsect
!= NULL
)
744 iclass
= fetch_insn_class (name
, create
);
748 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
750 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
752 users
[count
++] = iclass
;
753 mark_used (ics
[iclass
], 0);
756 printf("Class %s not found\n", name
);
758 /* Update the return values. */
767 parse_semantics (char *sem
)
769 if (strcmp (sem
, "none") == 0)
770 return IA64_DVS_NONE
;
771 else if (strcmp (sem
, "implied") == 0)
772 return IA64_DVS_IMPLIED
;
773 else if (strcmp (sem
, "impliedF") == 0)
774 return IA64_DVS_IMPLIEDF
;
775 else if (strcmp (sem
, "data") == 0)
776 return IA64_DVS_DATA
;
777 else if (strcmp (sem
, "instr") == 0)
778 return IA64_DVS_INSTR
;
779 else if (strcmp (sem
, "specific") == 0)
780 return IA64_DVS_SPECIFIC
;
781 else if (strcmp (sem
, "stop") == 0)
782 return IA64_DVS_STOP
;
784 return IA64_DVS_OTHER
;
788 add_dep (const char *name
, const char *chk
, const char *reg
,
789 int semantics
, int mode
, char *extra
, int flag
)
793 rs
= insert_resource (name
, mode
);
795 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
796 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
798 rs
->semantics
= semantics
;
800 rs
->waw_special
= flag
;
804 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
806 FILE *fp
= fopen (filename
, "r");
810 fail (_("can't find %s for reading\n"), filename
);
812 fgets (buf
, sizeof(buf
), fp
);
820 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
823 while (ISSPACE (buf
[strlen (buf
) - 1]))
824 buf
[strlen (buf
) - 1] = '\0';
831 while (ISSPACE (*tmp
))
834 tmp
= strchr (tmp
, ';');
838 while (ISSPACE (*tmp
))
841 tmp
= strchr (tmp
, ';');
845 while (ISSPACE (*tmp
))
847 semantics
= parse_semantics (tmp
);
848 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
850 /* For WAW entries, if the chks and regs differ, we need to enter the
851 entries in both positions so that the tables will be parsed properly,
852 without a lot of extra work. */
853 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
855 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
856 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
860 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
867 load_dependencies (void)
869 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
870 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
871 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
874 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
877 /* Is the given operand an indirect register file operand? */
879 irf_operand (int op
, const char *field
)
883 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
884 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
885 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
886 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
890 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
891 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
892 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
893 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
894 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
895 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
896 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
897 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
901 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
902 mov_um insn classes. */
904 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
905 const char *format
, const char *field
)
907 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
918 int i
= strcmp (idesc
->name
, "mov.i") == 0;
919 int m
= strcmp (idesc
->name
, "mov.m") == 0;
920 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
921 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
922 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
923 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
924 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
925 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
929 return strstr (format
, "I26") || strstr (format
, "I27");
931 return strstr (format
, "I28") != NULL
;
933 return strstr (format
, "M29") || strstr (format
, "M30");
935 return strstr (format
, "M31") != NULL
;
936 if (pseudo0
|| pseudo1
)
942 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
943 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
945 return strstr (format
, "I22") != NULL
;
947 return strstr (format
, "I21") != NULL
;
952 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
953 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
955 return strstr (format
, "M32") != NULL
;
957 return strstr (format
, "M33") != NULL
;
961 if (ic
->name
[5] == 'n')
963 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
964 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
966 return strstr (format
, "M42") != NULL
;
968 return strstr (format
, "M43") != NULL
;
970 else if (ic
->name
[5] == 'p')
972 return idesc
->operands
[1] == IA64_OPND_IP
;
978 if (ic
->name
[5] == 'r')
980 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
981 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
982 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
984 return strstr (format
, "I23") != NULL
;
986 return strstr (format
, "I24") != NULL
;
988 return strstr (format
, "I25") != NULL
;
990 else if (ic
->name
[5] == 's')
992 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
993 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
995 return strstr (format
, "M35") != NULL
;
997 return strstr (format
, "M36") != NULL
;
1004 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1005 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1007 return strstr (format
, "M35") != NULL
;
1009 return strstr (format
, "M36") != NULL
;
1016 /* Is the given opcode in the given insn class? */
1018 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1019 const char *format
, const char *field
, int *notep
)
1026 if (!strncmp (ic
->comment
, "Format", 6))
1028 /* Assume that the first format seen is the most restrictive, and
1029 only keep a later one if it looks like it's more restrictive. */
1032 if (strlen (ic
->comment
) < strlen (format
))
1034 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1035 ic
->comment
, format
);
1036 format
= ic
->comment
;
1040 format
= ic
->comment
;
1042 else if (!strncmp (ic
->comment
, "Field", 5))
1045 warn (_("overlapping field %s->%s\n"),
1046 ic
->comment
, field
);
1047 field
= ic
->comment
;
1051 /* An insn class matches anything that is the same followed by completers,
1052 except when the absence and presence of completers constitutes different
1054 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1056 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
1057 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1058 int len
= strlen(ic
->name
);
1060 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1061 && (idesc
->name
[len
] == '\0'
1062 || idesc
->name
[len
] == '.'));
1064 /* All break, nop, and hint variations must match exactly. */
1066 (strcmp (ic
->name
, "break") == 0
1067 || strcmp (ic
->name
, "nop") == 0
1068 || strcmp (ic
->name
, "hint") == 0))
1069 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1071 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1072 unless specifically allowed by clauses in this block. */
1073 if (resolved
&& field
)
1075 /* Check Field(sf)==sN against opcode sN. */
1076 if (strstr(field
, "(sf)==") != NULL
)
1080 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1081 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1083 /* Check Field(lftype)==XXX. */
1084 else if (strstr (field
, "(lftype)") != NULL
)
1086 if (strstr (idesc
->name
, "fault") != NULL
)
1087 resolved
= strstr (field
, "fault") != NULL
;
1089 resolved
= strstr (field
, "fault") == NULL
;
1091 /* Handle Field(ctype)==XXX. */
1092 else if (strstr (field
, "(ctype)") != NULL
)
1094 if (strstr (idesc
->name
, "or.andcm"))
1095 resolved
= strstr (field
, "or.andcm") != NULL
;
1096 else if (strstr (idesc
->name
, "and.orcm"))
1097 resolved
= strstr (field
, "and.orcm") != NULL
;
1098 else if (strstr (idesc
->name
, "orcm"))
1099 resolved
= strstr (field
, "or orcm") != NULL
;
1100 else if (strstr (idesc
->name
, "or"))
1101 resolved
= strstr (field
, "or orcm") != NULL
;
1102 else if (strstr (idesc
->name
, "andcm"))
1103 resolved
= strstr (field
, "and andcm") != NULL
;
1104 else if (strstr (idesc
->name
, "and"))
1105 resolved
= strstr (field
, "and andcm") != NULL
;
1106 else if (strstr (idesc
->name
, "unc"))
1107 resolved
= strstr (field
, "unc") != NULL
;
1109 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1113 if (resolved
&& format
)
1115 if (strncmp (idesc
->name
, "dep", 3) == 0
1116 && strstr (format
, "I13") != NULL
)
1117 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1118 else if (strncmp (idesc
->name
, "chk", 3) == 0
1119 && strstr (format
, "M21") != NULL
)
1120 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1121 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1122 resolved
= (strstr (format
, "M14 M15") != NULL
1123 && (idesc
->operands
[1] == IA64_OPND_R2
1124 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1125 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1126 && strstr (format
, "B5") != NULL
)
1127 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1128 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1129 && strstr (format
, "B3") != NULL
)
1130 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1131 else if (strncmp (idesc
->name
, "brp", 3) == 0
1132 && strstr (format
, "B7") != NULL
)
1133 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1134 else if (strcmp (ic
->name
, "invala") == 0)
1135 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1136 else if (strncmp (idesc
->name
, "st", 2) == 0
1137 && (strstr (format
, "M5") != NULL
1138 || strstr (format
, "M10") != NULL
))
1139 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1140 else if (strncmp (idesc
->name
, "ld", 2) == 0
1141 && (strstr (format
, "M2 M3") != NULL
1142 || strstr (format
, "M12") != NULL
1143 || strstr (format
, "M7 M8") != NULL
))
1144 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1149 /* Misc brl variations ('.cond' is optional);
1150 plain brl matches brl.cond. */
1152 && (strcmp (idesc
->name
, "brl") == 0
1153 || strncmp (idesc
->name
, "brl.", 4) == 0)
1154 && strcmp (ic
->name
, "brl.cond") == 0)
1159 /* Misc br variations ('.cond' is optional). */
1161 && (strcmp (idesc
->name
, "br") == 0
1162 || strncmp (idesc
->name
, "br.", 3) == 0)
1163 && strcmp (ic
->name
, "br.cond") == 0)
1166 resolved
= (strstr (format
, "B4") != NULL
1167 && idesc
->operands
[0] == IA64_OPND_B2
)
1168 || (strstr (format
, "B1") != NULL
1169 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1174 /* probe variations. */
1175 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1177 resolved
= strcmp (ic
->name
, "probe") == 0
1178 && !((strstr (idesc
->name
, "fault") != NULL
)
1179 ^ (format
&& strstr (format
, "M40") != NULL
));
1182 /* mov variations. */
1183 if (!resolved
&& is_mov
)
1187 /* mov alias for fmerge. */
1188 if (strcmp (ic
->name
, "fmerge") == 0)
1190 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1191 && idesc
->operands
[1] == IA64_OPND_F3
;
1193 /* mov alias for adds (r3 or imm14). */
1194 else if (strcmp (ic
->name
, "adds") == 0)
1196 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1197 && (idesc
->operands
[1] == IA64_OPND_R3
1198 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1200 /* mov alias for addl. */
1201 else if (strcmp (ic
->name
, "addl") == 0)
1203 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1204 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1208 /* Some variants of mov and mov.[im]. */
1209 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1210 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1213 /* Keep track of this so we can flag any insn classes which aren't
1214 mapped onto at least one real insn. */
1216 ic
->terminal_resolved
= 1;
1218 else for (i
= 0; i
< ic
->nsubs
; i
++)
1220 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1224 for (j
= 0; j
< ic
->nxsubs
; j
++)
1225 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1229 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1236 /* If it's in this IC, add the IC note (if any) to the insn. */
1239 if (ic
->note
&& notep
)
1241 if (*notep
&& *notep
!= ic
->note
)
1242 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1243 *notep
, ic
->note
, ic
->name
);
1254 lookup_regindex (const char *name
, int specifier
)
1259 if (strstr (name
, "[RSC]"))
1261 if (strstr (name
, "[BSP]"))
1263 else if (strstr (name
, "[BSPSTORE]"))
1265 else if (strstr (name
, "[RNAT]"))
1267 else if (strstr (name
, "[FCR]"))
1269 else if (strstr (name
, "[EFLAG]"))
1271 else if (strstr (name
, "[CSD]"))
1273 else if (strstr (name
, "[SSD]"))
1275 else if (strstr (name
, "[CFLG]"))
1277 else if (strstr (name
, "[FSR]"))
1279 else if (strstr (name
, "[FIR]"))
1281 else if (strstr (name
, "[FDR]"))
1283 else if (strstr (name
, "[CCV]"))
1285 else if (strstr (name
, "[ITC]"))
1287 else if (strstr (name
, "[PFS]"))
1289 else if (strstr (name
, "[LC]"))
1291 else if (strstr (name
, "[EC]"))
1295 if (strstr (name
, "[DCR]"))
1297 else if (strstr (name
, "[ITM]"))
1299 else if (strstr (name
, "[IVA]"))
1301 else if (strstr (name
, "[PTA]"))
1303 else if (strstr (name
, "[GPTA]"))
1305 else if (strstr (name
, "[IPSR]"))
1307 else if (strstr (name
, "[ISR]"))
1309 else if (strstr (name
, "[IIP]"))
1311 else if (strstr (name
, "[IFA]"))
1313 else if (strstr (name
, "[ITIR]"))
1315 else if (strstr (name
, "[IIPA]"))
1317 else if (strstr (name
, "[IFS]"))
1319 else if (strstr (name
, "[IIM]"))
1321 else if (strstr (name
, "[IHA]"))
1323 else if (strstr (name
, "[LID]"))
1325 else if (strstr (name
, "[IVR]"))
1327 else if (strstr (name
, "[TPR]"))
1329 else if (strstr (name
, "[EOI]"))
1331 else if (strstr (name
, "[ITV]"))
1333 else if (strstr (name
, "[PMV]"))
1335 else if (strstr (name
, "[CMCV]"))
1339 if (strstr (name
, ".be"))
1341 else if (strstr (name
, ".up"))
1343 else if (strstr (name
, ".ac"))
1345 else if (strstr (name
, ".mfl"))
1347 else if (strstr (name
, ".mfh"))
1349 else if (strstr (name
, ".ic"))
1351 else if (strstr (name
, ".i"))
1353 else if (strstr (name
, ".pk"))
1355 else if (strstr (name
, ".dt"))
1357 else if (strstr (name
, ".dfl"))
1359 else if (strstr (name
, ".dfh"))
1361 else if (strstr (name
, ".sp"))
1363 else if (strstr (name
, ".pp"))
1365 else if (strstr (name
, ".di"))
1367 else if (strstr (name
, ".si"))
1369 else if (strstr (name
, ".db"))
1371 else if (strstr (name
, ".lp"))
1373 else if (strstr (name
, ".tb"))
1375 else if (strstr (name
, ".rt"))
1377 else if (strstr (name
, ".cpl"))
1379 else if (strstr (name
, ".rs"))
1381 else if (strstr (name
, ".mc"))
1383 else if (strstr (name
, ".it"))
1385 else if (strstr (name
, ".id"))
1387 else if (strstr (name
, ".da"))
1389 else if (strstr (name
, ".dd"))
1391 else if (strstr (name
, ".ss"))
1393 else if (strstr (name
, ".ri"))
1395 else if (strstr (name
, ".ed"))
1397 else if (strstr (name
, ".bn"))
1399 else if (strstr (name
, ".ia"))
1410 lookup_specifier (const char *name
)
1412 if (strchr (name
, '%'))
1414 if (strstr (name
, "AR[K%]") != NULL
)
1415 return IA64_RS_AR_K
;
1416 if (strstr (name
, "AR[UNAT]") != NULL
)
1417 return IA64_RS_AR_UNAT
;
1418 if (strstr (name
, "AR%, % in 8") != NULL
)
1420 if (strstr (name
, "AR%, % in 48") != NULL
)
1422 if (strstr (name
, "BR%") != NULL
)
1424 if (strstr (name
, "CR[IRR%]") != NULL
)
1425 return IA64_RS_CR_IRR
;
1426 if (strstr (name
, "CR[LRR%]") != NULL
)
1427 return IA64_RS_CR_LRR
;
1428 if (strstr (name
, "CR%") != NULL
)
1430 if (strstr (name
, "FR%, % in 0") != NULL
)
1432 if (strstr (name
, "FR%, % in 2") != NULL
)
1434 if (strstr (name
, "GR%") != NULL
)
1436 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1438 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1441 warn (_("don't know how to specify %% dependency %s\n"),
1444 else if (strchr (name
, '#'))
1446 if (strstr (name
, "CPUID#") != NULL
)
1447 return IA64_RS_CPUID
;
1448 if (strstr (name
, "DBR#") != NULL
)
1450 if (strstr (name
, "IBR#") != NULL
)
1452 if (strstr (name
, "MSR#") != NULL
)
1454 if (strstr (name
, "PKR#") != NULL
)
1456 if (strstr (name
, "PMC#") != NULL
)
1458 if (strstr (name
, "PMD#") != NULL
)
1460 if (strstr (name
, "RR#") != NULL
)
1463 warn (_("Don't know how to specify # dependency %s\n"),
1466 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1467 return IA64_RS_AR_FPSR
;
1468 else if (strncmp (name
, "AR[", 3) == 0)
1470 else if (strncmp (name
, "CR[", 3) == 0)
1472 else if (strncmp (name
, "PSR.", 4) == 0)
1474 else if (strcmp (name
, "InService*") == 0)
1475 return IA64_RS_INSERVICE
;
1476 else if (strcmp (name
, "GR0") == 0)
1478 else if (strcmp (name
, "CFM") == 0)
1480 else if (strcmp (name
, "PR63") == 0)
1481 return IA64_RS_PR63
;
1482 else if (strcmp (name
, "RSE") == 0)
1489 print_dependency_table ()
1495 for (i
=0;i
< iclen
;i
++)
1497 if (ics
[i
]->is_class
)
1501 if (ics
[i
]->comment
)
1502 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1503 ics
[i
]->name
, ics
[i
]->comment
);
1505 warn (_("IC:%s has no terminals or sub-classes\n"),
1511 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1513 if (ics
[i
]->comment
)
1514 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1515 ics
[i
]->name
, ics
[i
]->comment
);
1517 warn (_("no insns mapped directly to terminal IC %s\n"),
1523 for (i
= 0; i
< iclen
; i
++)
1527 mark_used (ics
[i
], 1);
1528 warn (_("class %s is defined but not used\n"),
1534 for (i
= 0; i
< rdepslen
; i
++)
1536 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1538 if (rdeps
[i
]->total_chks
== 0)
1539 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1540 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1541 rdeps
[i
]->total_regs
? "" : " or regs");
1542 else if (rdeps
[i
]->total_regs
== 0)
1543 warn (_("rsrc %s (%s) has no regs\n"),
1544 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1548 /* The dependencies themselves. */
1549 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1550 for (i
= 0; i
< rdepslen
; i
++)
1552 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1554 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1555 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1557 printf (" { \"%s\", %d, %d, %d, %d, ",
1558 rdeps
[i
]->name
, specifier
,
1559 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1560 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1561 printf ("\"%s\", ", rdeps
[i
]->extra
);
1568 /* And dependency lists. */
1569 for (i
=0;i
< dlistlen
;i
++)
1572 printf ("static const short dep%d[] = {\n ", i
);
1573 for (j
=0;j
< dlists
[i
]->len
; j
++)
1575 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1582 printf ("\n};\n\n");
1585 /* And opcode dependency list. */
1586 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1587 printf ("static const struct ia64_opcode_dependency\n");
1588 printf ("op_dependencies[] = {\n");
1589 for (i
= 0; i
< opdeplen
; i
++)
1592 if (opdeps
[i
]->chk
== -1)
1593 printf ("0, NULL, ");
1595 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1596 if (opdeps
[i
]->reg
== -1)
1597 printf ("0, NULL, ");
1599 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1606 /* Add STR to the string table. */
1607 static struct string_entry
*
1608 insert_string (char *str
)
1610 int start
= 0, end
= strtablen
;
1613 if (strtablen
== strtabtotlen
)
1616 string_table
= (struct string_entry
**)
1617 xrealloc (string_table
,
1618 sizeof (struct string_entry
**) * strtabtotlen
);
1624 string_table
[0] = tmalloc (struct string_entry
);
1625 string_table
[0]->s
= xstrdup (str
);
1626 string_table
[0]->num
= 0;
1627 return string_table
[0];
1630 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1632 else if (strcmp (str
, string_table
[0]->s
) < 0)
1640 i
= (start
+ end
) / 2;
1641 c
= strcmp (str
, string_table
[i
]->s
);
1646 return string_table
[i
];
1655 for (; i
> 0 && i
< strtablen
; i
--)
1656 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1659 for (; i
< strtablen
; i
++)
1660 if (strcmp (str
, string_table
[i
]->s
) < 0)
1663 for (x
= strtablen
- 1; x
>= i
; x
--)
1665 string_table
[x
+ 1] = string_table
[x
];
1666 string_table
[x
+ 1]->num
= x
+ 1;
1669 string_table
[i
] = tmalloc (struct string_entry
);
1670 string_table
[i
]->s
= xstrdup (str
);
1671 string_table
[i
]->num
= i
;
1674 return string_table
[i
];
1677 static struct bittree
*
1678 make_bittree_entry (void)
1680 struct bittree
*res
= tmalloc (struct bittree
);
1683 res
->bits
[0] = NULL
;
1684 res
->bits
[1] = NULL
;
1685 res
->bits
[2] = NULL
;
1687 res
->bits_to_skip
= 0;
1692 static struct disent
*
1693 add_dis_table_ent (which
, insn
, order
, completer_index
)
1694 struct disent
*which
;
1697 int completer_index
;
1707 while (ent
->nexte
!= NULL
)
1710 ent
= (ent
->nexte
= tmalloc (struct disent
));
1714 ent
= tmalloc (struct disent
);
1715 ent
->next_ent
= disinsntable
;
1722 ent
->priority
= order
;
1724 while (completer_index
!= 1)
1726 ci
= (ci
<< 1) | (completer_index
& 1);
1727 completer_index
>>= 1;
1729 ent
->completer_index
= ci
;
1736 struct disent
*ent
= disinsntable
;
1737 struct disent
*prev
= ent
;
1739 ent
->ournum
= 32768;
1740 while ((ent
= ent
->next_ent
) != NULL
)
1742 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1748 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1749 opcodenum
, order
, completer_index
)
1750 struct bittree
*curr_ent
;
1756 int completer_index
;
1760 struct bittree
*next
;
1764 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1767 curr_ent
->disent
= nent
;
1771 m
= ((ia64_insn
) 1) << bit
;
1774 b
= (opcode
& m
) ? 1 : 0;
1778 next
= curr_ent
->bits
[b
];
1781 next
= make_bittree_entry ();
1782 curr_ent
->bits
[b
] = next
;
1784 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1789 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1790 struct bittree
*first
;
1794 struct completer_entry
*ent
;
1795 int completer_index
;
1797 if (completer_index
& (1 << 20))
1802 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1803 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1804 (completer_index
<< 1) | 1);
1806 if (ent
->is_terminal
)
1808 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1809 opcodenum
, opcode_count
- ent
->order
- 1,
1810 (completer_index
<< 1) | 1);
1812 completer_index
<<= 1;
1813 ent
= ent
->alternative
;
1817 /* This optimization pass combines multiple "don't care" nodes. */
1819 compact_distree (ent
)
1820 struct bittree
*ent
;
1822 #define IS_SKIP(ent) \
1823 ((ent->bits[2] !=NULL) \
1824 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1827 struct bittree
*nent
= ent
;
1830 while (IS_SKIP (nent
))
1833 nent
= nent
->bits
[2];
1838 struct bittree
*next
= ent
->bits
[2];
1840 ent
->bits
[0] = nent
->bits
[0];
1841 ent
->bits
[1] = nent
->bits
[1];
1842 ent
->bits
[2] = nent
->bits
[2];
1843 ent
->disent
= nent
->disent
;
1845 ent
->bits_to_skip
= bitcnt
;
1846 while (next
!= nent
)
1848 struct bittree
*b
= next
;
1849 next
= next
->bits
[2];
1855 for (x
= 0; x
< 3; x
++)
1857 struct bittree
*i
= ent
->bits
[x
];
1860 compact_distree (i
);
1864 static unsigned char *insn_list
;
1865 static int insn_list_len
= 0;
1866 static int tot_insn_list_len
= 0;
1868 /* Generate the disassembler state machine corresponding to the tree
1872 struct bittree
*ent
;
1875 int our_offset
= insn_list_len
;
1877 int totbits
= bitsused
;
1880 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1882 /* If this is a terminal entry, there's no point in skipping any
1884 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1885 ent
->bits
[2] == NULL
)
1887 if (ent
->disent
== NULL
)
1893 /* Calculate the amount of space needed for this entry, or at least
1894 a conservatively large approximation. */
1898 for (x
= 1; x
< 3; x
++)
1899 if (ent
->bits
[x
] != NULL
)
1902 if (ent
->disent
!= NULL
)
1904 if (ent
->bits
[2] != NULL
)
1910 /* Now allocate the space. */
1911 needed_bytes
= (totbits
+ 7) / 8;
1912 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1914 tot_insn_list_len
+= 256;
1915 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1917 our_offset
= insn_list_len
;
1918 insn_list_len
+= needed_bytes
;
1919 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1921 /* Encode the skip entry by setting bit 6 set in the state op field,
1922 and store the # of bits to skip immediately after. */
1926 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1927 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1930 #define IS_ONLY_IFZERO(ENT) \
1931 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1932 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1934 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1936 if (ent
->bits
[0] != NULL
)
1938 struct bittree
*nent
= ent
->bits
[0];
1941 insn_list
[our_offset
] |= 0x80;
1943 /* We can encode sequences of multiple "if (bit is zero)" tests
1944 by storing the # of zero bits to check in the lower 3 bits of
1945 the instruction. However, this only applies if the state
1946 solely tests for a zero bit. */
1948 if (IS_ONLY_IFZERO (ent
))
1950 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1952 nent
= nent
->bits
[0];
1956 insn_list
[our_offset
+ 0] |= zero_count
;
1958 zero_dest
= insn_list_len
;
1959 gen_dis_table (nent
);
1962 /* Now store the remaining tests. We also handle a sole "termination
1963 entry" by storing it as an "any bit" test. */
1965 for (x
= 1; x
< 3; x
++)
1967 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1969 struct bittree
*i
= ent
->bits
[x
];
1975 /* If the instruction being branched to only consists of
1976 a termination entry, use the termination entry as the
1977 place to branch to instead. */
1978 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1979 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1981 idest
= i
->disent
->ournum
;
1985 idest
= insn_list_len
- our_offset
;
1988 idest
= ent
->disent
->ournum
;
1990 /* If the destination offset for the if (bit is 1) test is less
1991 than 256 bytes away, we can store it as 8-bits instead of 16;
1992 the instruction has bit 5 set for the 16-bit address, and bit
1993 4 for the 8-bit address. Since we've already allocated 16
1994 bits for the address we need to deallocate the space.
1996 Note that branchings within the table are relative, and
1997 there are no branches that branch past our instruction yet
1998 so we do not need to adjust any other offsets. */
2003 int start
= our_offset
+ bitsused
/ 8 + 1;
2005 memmove (insn_list
+ start
,
2006 insn_list
+ start
+ 1,
2007 insn_list_len
- (start
+ 1));
2012 insn_list
[our_offset
] |= 0x10;
2016 insn_list
[our_offset
] |= 0x20;
2020 /* An instruction which solely consists of a termination
2021 marker and whose disassembly name index is < 4096
2022 can be stored in 16 bits. The encoding is slightly
2023 odd; the upper 4 bits of the instruction are 0x3, and
2024 bit 3 loses its normal meaning. */
2026 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2027 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2028 && ent
->disent
!= NULL
2029 && ent
->disent
->ournum
< (32768 + 4096))
2031 int start
= our_offset
+ bitsused
/ 8 + 1;
2033 memmove (insn_list
+ start
,
2034 insn_list
+ start
+ 1,
2035 insn_list_len
- (start
+ 1));
2041 insn_list
[our_offset
] |= 0x30;
2045 insn_list
[our_offset
] |= 0x08;
2054 else if (! (id
& 32768))
2058 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2060 printf ("%d: try %d\n", our_offset
, id
);
2063 /* Store the address of the entry being branched to. */
2064 while (currbits
>= 0)
2066 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2068 if (idest
& (1 << currbits
))
2069 *byte
|= (1 << (7 - (bitsused
% 8)));
2075 /* Now generate the states for the entry being branched to. */
2084 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2086 if (ent
->bits
[0] != NULL
)
2087 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2091 if (bitsused
!= totbits
)
2096 print_dis_table (void)
2099 struct disent
*cent
= disinsntable
;
2101 printf ("static const char dis_table[] = {\n");
2102 for (x
= 0; x
< insn_list_len
; x
++)
2104 if ((x
> 0) && ((x
% 12) == 0))
2107 printf ("0x%02x, ", insn_list
[x
]);
2109 printf ("\n};\n\n");
2111 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2112 while (cent
!= NULL
)
2114 struct disent
*ent
= cent
;
2118 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2119 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2123 cent
= cent
->next_ent
;
2129 generate_disassembler (void)
2133 bittree
= make_bittree_entry ();
2135 for (i
= 0; i
< otlen
; i
++)
2137 struct main_entry
*ptr
= ordered_table
[i
];
2139 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2140 add_dis_entry (bittree
,
2141 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2143 ptr
->completers
, 1);
2146 compact_distree (bittree
);
2148 gen_dis_table (bittree
);
2154 print_string_table (void)
2157 char lbuf
[80], buf
[80];
2160 printf ("static const char * const ia64_strings[] = {\n");
2163 for (x
= 0; x
< strtablen
; x
++)
2167 if (strlen (string_table
[x
]->s
) > 75)
2170 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2173 if ((blen
+ len
) > 75)
2175 printf (" %s\n", lbuf
);
2184 printf (" %s\n", lbuf
);
2189 static struct completer_entry
**glist
;
2190 static int glistlen
= 0;
2191 static int glisttotlen
= 0;
2193 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2196 completer_entries_eq (ent1
, ent2
)
2197 struct completer_entry
*ent1
, *ent2
;
2199 while (ent1
!= NULL
&& ent2
!= NULL
)
2201 if (ent1
->name
->num
!= ent2
->name
->num
2202 || ent1
->bits
!= ent2
->bits
2203 || ent1
->mask
!= ent2
->mask
2204 || ent1
->is_terminal
!= ent2
->is_terminal
2205 || ent1
->dependencies
!= ent2
->dependencies
2206 || ent1
->order
!= ent2
->order
)
2209 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2212 ent1
= ent1
->alternative
;
2213 ent2
= ent2
->alternative
;
2216 return ent1
== ent2
;
2219 /* Insert ENT into the global list of completers and return it. If an
2220 equivalent entry (according to completer_entries_eq) already exists,
2221 it is returned instead. */
2222 static struct completer_entry
*
2223 insert_gclist (struct completer_entry
*ent
)
2231 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2232 ent
->alternative
= insert_gclist (ent
->alternative
);
2237 if (glisttotlen
== glistlen
)
2240 glist
= (struct completer_entry
**)
2241 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2251 if (ent
->name
->num
< glist
[0]->name
->num
)
2253 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2261 i
= (start
+ end
) / 2;
2262 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2269 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2283 while (i
< glistlen
)
2285 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2288 if (completer_entries_eq (ent
, glist
[i
]))
2296 for (; i
> 0 && i
< glistlen
; i
--)
2297 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2300 for (; i
< glistlen
; i
++)
2301 if (ent
->name
->num
< glist
[i
]->name
->num
)
2304 for (x
= glistlen
- 1; x
>= i
; x
--)
2305 glist
[x
+ 1] = glist
[x
];
2314 get_prefix_len (name
)
2319 if (name
[0] == '\0')
2322 c
= strchr (name
, '.');
2326 return strlen (name
);
2330 compute_completer_bits (ment
, ent
)
2331 struct main_entry
*ment
;
2332 struct completer_entry
*ent
;
2336 compute_completer_bits (ment
, ent
->addl_entries
);
2338 if (ent
->is_terminal
)
2341 ia64_insn our_bits
= ent
->bits
;
2342 struct completer_entry
*p
= ent
->parent
;
2346 while (p
!= NULL
&& ! p
->is_terminal
)
2352 p_bits
= ment
->opcode
->opcode
;
2354 for (x
= 0; x
< 64; x
++)
2356 ia64_insn m
= ((ia64_insn
) 1) << x
;
2358 if ((p_bits
& m
) != (our_bits
& m
))
2363 ent
->bits
= our_bits
;
2372 ent
= ent
->alternative
;
2376 /* Find identical completer trees that are used in different
2377 instructions and collapse their entries. */
2379 collapse_redundant_completers (void)
2381 struct main_entry
*ptr
;
2384 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2386 if (ptr
->completers
== NULL
)
2389 compute_completer_bits (ptr
, ptr
->completers
);
2390 ptr
->completers
= insert_gclist (ptr
->completers
);
2393 /* The table has been finalized, now number the indexes. */
2394 for (x
= 0; x
< glistlen
; x
++)
2399 /* Attach two lists of dependencies to each opcode.
2400 1) all resources which, when already marked in use, conflict with this
2402 2) all resources which must be marked in use when this opcode is used
2405 insert_opcode_dependencies (opc
, cmp
)
2406 struct ia64_opcode
*opc
;
2407 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2409 /* Note all resources which point to this opcode. rfi has the most chks
2410 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2413 unsigned short regs
[256];
2415 unsigned short chks
[256];
2416 /* Flag insns for which no class matched; there should be none. */
2417 int no_class_found
= 1;
2419 for (i
= 0; i
< rdepslen
; i
++)
2421 struct rdep
*rs
= rdeps
[i
];
2424 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2425 && strncmp (rs
->name
, "PR%", 3) == 0
2427 no_class_found
= 99;
2429 for (j
=0; j
< rs
->nregs
;j
++)
2433 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2435 /* We can ignore ic_note 11 for non PR resources. */
2436 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2439 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2440 && ic_note
!= rs
->regnotes
[j
]
2441 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2442 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2443 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2444 rs
->name
, rs
->regnotes
[j
]);
2445 /* Instruction class notes override resource notes.
2446 So far, only note 11 applies to an IC instead of a resource,
2447 and note 11 implies note 1. */
2449 regs
[nregs
++] = RDEP(ic_note
, i
);
2451 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2457 for (j
= 0; j
< rs
->nchks
; j
++)
2461 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2463 /* We can ignore ic_note 11 for non PR resources. */
2464 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2467 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2468 && ic_note
!= rs
->chknotes
[j
]
2469 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2470 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2471 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2472 rs
->name
, rs
->chknotes
[j
]);
2474 chks
[nchks
++] = RDEP(ic_note
, i
);
2476 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2484 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2486 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2488 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2492 insert_completer_entry (opc
, tabent
, order
)
2493 struct ia64_opcode
*opc
;
2494 struct main_entry
*tabent
;
2497 struct completer_entry
**ptr
= &tabent
->completers
;
2498 struct completer_entry
*parent
= NULL
;
2499 char pcopy
[129], *prefix
;
2502 if (strlen (opc
->name
) > 128)
2505 strcpy (pcopy
, opc
->name
);
2506 prefix
= pcopy
+ get_prefix_len (pcopy
);
2508 if (prefix
[0] != '\0')
2513 int need_new_ent
= 1;
2514 int plen
= get_prefix_len (prefix
);
2515 struct string_entry
*sent
;
2517 at_end
= (prefix
[plen
] == '\0');
2518 prefix
[plen
] = '\0';
2519 sent
= insert_string (prefix
);
2521 while (*ptr
!= NULL
)
2523 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2531 ptr
= &((*ptr
)->alternative
);
2536 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2539 nent
->parent
= parent
;
2540 nent
->addl_entries
= NULL
;
2541 nent
->alternative
= *ptr
;
2543 nent
->is_terminal
= 0;
2544 nent
->dependencies
= -1;
2550 ptr
= &((*ptr
)->addl_entries
);
2555 if ((*ptr
)->is_terminal
)
2558 (*ptr
)->is_terminal
= 1;
2559 (*ptr
)->mask
= (ia64_insn
)-1;
2560 (*ptr
)->bits
= opc
->opcode
;
2561 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2562 (*ptr
)->order
= order
;
2566 print_completer_entry (ent
)
2567 struct completer_entry
*ent
;
2570 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2574 while (! (mask
& 1))
2581 if (bits
& 0xffffffff00000000LL
)
2585 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2589 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2590 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2592 ent
->is_terminal
? 1 : 0,
2597 print_completer_table ()
2601 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2602 for (x
= 0; x
< glistlen
; x
++)
2603 print_completer_entry (glist
[x
]);
2608 opcodes_eq (opc1
, opc2
)
2609 struct ia64_opcode
*opc1
;
2610 struct ia64_opcode
*opc2
;
2615 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2616 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2617 || (opc1
->flags
!= opc2
->flags
))
2620 for (x
= 0; x
< 5; x
++)
2621 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2624 plen1
= get_prefix_len (opc1
->name
);
2625 plen2
= get_prefix_len (opc2
->name
);
2627 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2634 add_opcode_entry (opc
)
2635 struct ia64_opcode
*opc
;
2637 struct main_entry
**place
;
2638 struct string_entry
*name
;
2642 if (strlen (opc
->name
) > 128)
2646 strcpy (prefix
, opc
->name
);
2647 prefix
[get_prefix_len (prefix
)] = '\0';
2648 name
= insert_string (prefix
);
2650 /* Walk the list of opcode table entries. If it's a new
2651 instruction, allocate and fill in a new entry. Note
2652 the main table is alphabetical by opcode name. */
2654 while (*place
!= NULL
)
2656 if ((*place
)->name
->num
== name
->num
2657 && opcodes_eq ((*place
)->opcode
, opc
))
2662 if ((*place
)->name
->num
> name
->num
)
2665 place
= &((*place
)->next
);
2669 struct main_entry
*nent
= tmalloc (struct main_entry
);
2673 nent
->next
= *place
;
2674 nent
->completers
= 0;
2677 if (otlen
== ottotlen
)
2680 ordered_table
= (struct main_entry
**)
2681 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2683 ordered_table
[otlen
++] = nent
;
2686 insert_completer_entry (opc
, *place
, opcode_count
++);
2690 print_main_table (void)
2692 struct main_entry
*ptr
= maintable
;
2695 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2698 printf (" { %d, %d, %d, 0x",
2701 ptr
->opcode
->num_outputs
);
2702 fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2704 fprintf_vma (stdout
, ptr
->opcode
->mask
);
2705 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2706 ptr
->opcode
->operands
[0],
2707 ptr
->opcode
->operands
[1],
2708 ptr
->opcode
->operands
[2],
2709 ptr
->opcode
->operands
[3],
2710 ptr
->opcode
->operands
[4],
2712 ptr
->completers
->num
);
2714 ptr
->main_index
= index
++;
2723 struct ia64_opcode
*table
;
2727 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2728 add_opcode_entry (table
+ curr_opcode
);
2732 /* Program options. */
2733 #define OPTION_SRCDIR 200
2735 struct option long_options
[] =
2737 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2738 {"debug", no_argument
, NULL
, 'd'},
2739 {"version", no_argument
, NULL
, 'V'},
2740 {"help", no_argument
, NULL
, 'h'},
2741 {0, no_argument
, NULL
, 0}
2745 print_version (void)
2747 printf ("%s: version 1.0\n", program_name
);
2752 usage (FILE * stream
, int status
)
2754 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2760 main (int argc
, char **argv
)
2762 extern int chdir (char *);
2763 char *srcdir
= NULL
;
2766 program_name
= *argv
;
2767 xmalloc_set_program_name (program_name
);
2769 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2794 if (chdir (srcdir
) != 0)
2795 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2796 srcdir
, strerror (errno
));
2798 load_insn_classes ();
2799 load_dependencies ();
2801 shrink (ia64_opcodes_a
);
2802 shrink (ia64_opcodes_b
);
2803 shrink (ia64_opcodes_f
);
2804 shrink (ia64_opcodes_i
);
2805 shrink (ia64_opcodes_m
);
2806 shrink (ia64_opcodes_x
);
2807 shrink (ia64_opcodes_d
);
2809 collapse_redundant_completers ();
2811 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2812 print_string_table ();
2813 print_dependency_table ();
2814 print_completer_table ();
2815 print_main_table ();
2817 generate_disassembler ();