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 and nop variations must match exactly. */
1066 (strcmp (ic
->name
, "break") == 0
1067 || strcmp (ic
->name
, "nop") == 0))
1068 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1070 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1071 unless specifically allowed by clauses in this block. */
1072 if (resolved
&& field
)
1074 /* Check Field(sf)==sN against opcode sN. */
1075 if (strstr(field
, "(sf)==") != NULL
)
1079 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1080 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1082 /* Check Field(lftype)==XXX. */
1083 else if (strstr (field
, "(lftype)") != NULL
)
1085 if (strstr (idesc
->name
, "fault") != NULL
)
1086 resolved
= strstr (field
, "fault") != NULL
;
1088 resolved
= strstr (field
, "fault") == NULL
;
1090 /* Handle Field(ctype)==XXX. */
1091 else if (strstr (field
, "(ctype)") != NULL
)
1093 if (strstr (idesc
->name
, "or.andcm"))
1094 resolved
= strstr (field
, "or.andcm") != NULL
;
1095 else if (strstr (idesc
->name
, "and.orcm"))
1096 resolved
= strstr (field
, "and.orcm") != NULL
;
1097 else if (strstr (idesc
->name
, "orcm"))
1098 resolved
= strstr (field
, "or orcm") != NULL
;
1099 else if (strstr (idesc
->name
, "or"))
1100 resolved
= strstr (field
, "or orcm") != NULL
;
1101 else if (strstr (idesc
->name
, "andcm"))
1102 resolved
= strstr (field
, "and andcm") != NULL
;
1103 else if (strstr (idesc
->name
, "and"))
1104 resolved
= strstr (field
, "and andcm") != NULL
;
1105 else if (strstr (idesc
->name
, "unc"))
1106 resolved
= strstr (field
, "unc") != NULL
;
1108 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1112 if (resolved
&& format
)
1114 if (strncmp (idesc
->name
, "dep", 3) == 0
1115 && strstr (format
, "I13") != NULL
)
1116 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1117 else if (strncmp (idesc
->name
, "chk", 3) == 0
1118 && strstr (format
, "M21") != NULL
)
1119 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1120 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1121 resolved
= (strstr (format
, "M14 M15") != NULL
1122 && (idesc
->operands
[1] == IA64_OPND_R2
1123 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1124 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1125 && strstr (format
, "B5") != NULL
)
1126 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1127 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1128 && strstr (format
, "B3") != NULL
)
1129 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1130 else if (strncmp (idesc
->name
, "brp", 3) == 0
1131 && strstr (format
, "B7") != NULL
)
1132 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1133 else if (strcmp (ic
->name
, "invala") == 0)
1134 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1135 else if (strncmp (idesc
->name
, "st", 2) == 0
1136 && strstr (format
, "M5") != NULL
)
1137 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1142 /* Misc brl variations ('.cond' is optional);
1143 plain brl matches brl.cond. */
1145 && (strcmp (idesc
->name
, "brl") == 0
1146 || strncmp (idesc
->name
, "brl.", 4) == 0)
1147 && strcmp (ic
->name
, "brl.cond") == 0)
1152 /* Misc br variations ('.cond' is optional). */
1154 && (strcmp (idesc
->name
, "br") == 0
1155 || strncmp (idesc
->name
, "br.", 3) == 0)
1156 && strcmp (ic
->name
, "br.cond") == 0)
1159 resolved
= (strstr (format
, "B4") != NULL
1160 && idesc
->operands
[0] == IA64_OPND_B2
)
1161 || (strstr (format
, "B1") != NULL
1162 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1167 /* probe variations. */
1168 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1170 resolved
= strcmp (ic
->name
, "probe") == 0
1171 && !((strstr (idesc
->name
, "fault") != NULL
)
1172 ^ (format
&& strstr (format
, "M40") != NULL
));
1175 /* mov variations. */
1176 if (!resolved
&& is_mov
)
1180 /* mov alias for fmerge. */
1181 if (strcmp (ic
->name
, "fmerge") == 0)
1183 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1184 && idesc
->operands
[1] == IA64_OPND_F3
;
1186 /* mov alias for adds (r3 or imm14). */
1187 else if (strcmp (ic
->name
, "adds") == 0)
1189 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1190 && (idesc
->operands
[1] == IA64_OPND_R3
1191 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1193 /* mov alias for addl. */
1194 else if (strcmp (ic
->name
, "addl") == 0)
1196 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1197 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1201 /* Some variants of mov and mov.[im]. */
1202 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1203 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1206 /* Keep track of this so we can flag any insn classes which aren't
1207 mapped onto at least one real insn. */
1209 ic
->terminal_resolved
= 1;
1211 else for (i
= 0; i
< ic
->nsubs
; i
++)
1213 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1217 for (j
= 0; j
< ic
->nxsubs
; j
++)
1218 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1222 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1229 /* If it's in this IC, add the IC note (if any) to the insn. */
1232 if (ic
->note
&& notep
)
1234 if (*notep
&& *notep
!= ic
->note
)
1235 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1236 *notep
, ic
->note
, ic
->name
);
1247 lookup_regindex (const char *name
, int specifier
)
1252 if (strstr (name
, "[RSC]"))
1254 if (strstr (name
, "[BSP]"))
1256 else if (strstr (name
, "[BSPSTORE]"))
1258 else if (strstr (name
, "[RNAT]"))
1260 else if (strstr (name
, "[CCV]"))
1262 else if (strstr (name
, "[ITC]"))
1264 else if (strstr (name
, "[PFS]"))
1266 else if (strstr (name
, "[LC]"))
1268 else if (strstr (name
, "[EC]"))
1272 if (strstr (name
, "[DCR]"))
1274 else if (strstr (name
, "[ITM]"))
1276 else if (strstr (name
, "[IVA]"))
1278 else if (strstr (name
, "[PTA]"))
1280 else if (strstr (name
, "[GPTA]"))
1282 else if (strstr (name
, "[IPSR]"))
1284 else if (strstr (name
, "[ISR]"))
1286 else if (strstr (name
, "[IIP]"))
1288 else if (strstr (name
, "[IFA]"))
1290 else if (strstr (name
, "[ITIR]"))
1292 else if (strstr (name
, "[IIPA]"))
1294 else if (strstr (name
, "[IFS]"))
1296 else if (strstr (name
, "[IIM]"))
1298 else if (strstr (name
, "[IHA]"))
1300 else if (strstr (name
, "[LID]"))
1302 else if (strstr (name
, "[IVR]"))
1304 else if (strstr (name
, "[TPR]"))
1306 else if (strstr (name
, "[EOI]"))
1308 else if (strstr (name
, "[ITV]"))
1310 else if (strstr (name
, "[PMV]"))
1312 else if (strstr (name
, "[CMCV]"))
1316 if (strstr (name
, ".be"))
1318 else if (strstr (name
, ".up"))
1320 else if (strstr (name
, ".ac"))
1322 else if (strstr (name
, ".mfl"))
1324 else if (strstr (name
, ".mfh"))
1326 else if (strstr (name
, ".ic"))
1328 else if (strstr (name
, ".i"))
1330 else if (strstr (name
, ".pk"))
1332 else if (strstr (name
, ".dt"))
1334 else if (strstr (name
, ".dfl"))
1336 else if (strstr (name
, ".dfh"))
1338 else if (strstr (name
, ".sp"))
1340 else if (strstr (name
, ".pp"))
1342 else if (strstr (name
, ".di"))
1344 else if (strstr (name
, ".si"))
1346 else if (strstr (name
, ".db"))
1348 else if (strstr (name
, ".lp"))
1350 else if (strstr (name
, ".tb"))
1352 else if (strstr (name
, ".rt"))
1354 else if (strstr (name
, ".cpl"))
1356 else if (strstr (name
, ".rs"))
1358 else if (strstr (name
, ".mc"))
1360 else if (strstr (name
, ".it"))
1362 else if (strstr (name
, ".id"))
1364 else if (strstr (name
, ".da"))
1366 else if (strstr (name
, ".dd"))
1368 else if (strstr (name
, ".ss"))
1370 else if (strstr (name
, ".ri"))
1372 else if (strstr (name
, ".ed"))
1374 else if (strstr (name
, ".bn"))
1376 else if (strstr (name
, ".ia"))
1387 lookup_specifier (const char *name
)
1389 if (strchr (name
, '%'))
1391 if (strstr (name
, "AR[K%]") != NULL
)
1392 return IA64_RS_AR_K
;
1393 if (strstr (name
, "AR[UNAT]") != NULL
)
1394 return IA64_RS_AR_UNAT
;
1395 if (strstr (name
, "AR%, % in 8") != NULL
)
1397 if (strstr (name
, "AR%, % in 48") != NULL
)
1399 if (strstr (name
, "BR%") != NULL
)
1401 if (strstr (name
, "CR[IRR%]") != NULL
)
1402 return IA64_RS_CR_IRR
;
1403 if (strstr (name
, "CR[LRR%]") != NULL
)
1404 return IA64_RS_CR_LRR
;
1405 if (strstr (name
, "CR%") != NULL
)
1407 if (strstr (name
, "FR%, % in 0") != NULL
)
1409 if (strstr (name
, "FR%, % in 2") != NULL
)
1411 if (strstr (name
, "GR%") != NULL
)
1413 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1415 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1418 warn (_("don't know how to specify %% dependency %s\n"),
1421 else if (strchr (name
, '#'))
1423 if (strstr (name
, "CPUID#") != NULL
)
1424 return IA64_RS_CPUID
;
1425 if (strstr (name
, "DBR#") != NULL
)
1427 if (strstr (name
, "IBR#") != NULL
)
1429 if (strstr (name
, "MSR#") != NULL
)
1431 if (strstr (name
, "PKR#") != NULL
)
1433 if (strstr (name
, "PMC#") != NULL
)
1435 if (strstr (name
, "PMD#") != NULL
)
1437 if (strstr (name
, "RR#") != NULL
)
1440 warn (_("Don't know how to specify # dependency %s\n"),
1443 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1444 return IA64_RS_AR_FPSR
;
1445 else if (strncmp (name
, "AR[", 3) == 0)
1447 else if (strncmp (name
, "CR[", 3) == 0)
1449 else if (strncmp (name
, "PSR.", 4) == 0)
1451 else if (strcmp (name
, "InService*") == 0)
1452 return IA64_RS_INSERVICE
;
1453 else if (strcmp (name
, "GR0") == 0)
1455 else if (strcmp (name
, "CFM") == 0)
1457 else if (strcmp (name
, "PR63") == 0)
1458 return IA64_RS_PR63
;
1459 else if (strcmp (name
, "RSE") == 0)
1466 print_dependency_table ()
1472 for (i
=0;i
< iclen
;i
++)
1474 if (ics
[i
]->is_class
)
1478 if (ics
[i
]->comment
)
1479 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1480 ics
[i
]->name
, ics
[i
]->comment
);
1482 warn (_("IC:%s has no terminals or sub-classes\n"),
1488 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1490 if (ics
[i
]->comment
)
1491 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1492 ics
[i
]->name
, ics
[i
]->comment
);
1494 warn (_("no insns mapped directly to terminal IC %s\n"),
1500 for (i
= 0; i
< iclen
; i
++)
1504 mark_used (ics
[i
], 1);
1505 warn (_("class %s is defined but not used\n"),
1511 for (i
= 0; i
< rdepslen
; i
++)
1513 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1515 if (rdeps
[i
]->total_chks
== 0)
1516 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1517 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1518 rdeps
[i
]->total_regs
? "" : " or regs");
1519 else if (rdeps
[i
]->total_regs
== 0)
1520 warn (_("rsrc %s (%s) has no regs\n"),
1521 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1525 /* The dependencies themselves. */
1526 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1527 for (i
= 0; i
< rdepslen
; i
++)
1529 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1531 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1532 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1534 printf (" { \"%s\", %d, %d, %d, %d, ",
1535 rdeps
[i
]->name
, specifier
,
1536 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1537 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1538 printf ("\"%s\", ", rdeps
[i
]->extra
);
1545 /* And dependency lists. */
1546 for (i
=0;i
< dlistlen
;i
++)
1549 printf ("static const short dep%d[] = {\n ", i
);
1550 for (j
=0;j
< dlists
[i
]->len
; j
++)
1552 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1559 printf ("\n};\n\n");
1562 /* And opcode dependency list. */
1563 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1564 printf ("static const struct ia64_opcode_dependency\n");
1565 printf ("op_dependencies[] = {\n");
1566 for (i
= 0; i
< opdeplen
; i
++)
1569 if (opdeps
[i
]->chk
== -1)
1570 printf ("0, NULL, ");
1572 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1573 if (opdeps
[i
]->reg
== -1)
1574 printf ("0, NULL, ");
1576 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1583 /* Add STR to the string table. */
1584 static struct string_entry
*
1585 insert_string (char *str
)
1587 int start
= 0, end
= strtablen
;
1590 if (strtablen
== strtabtotlen
)
1593 string_table
= (struct string_entry
**)
1594 xrealloc (string_table
,
1595 sizeof (struct string_entry
**) * strtabtotlen
);
1601 string_table
[0] = tmalloc (struct string_entry
);
1602 string_table
[0]->s
= xstrdup (str
);
1603 string_table
[0]->num
= 0;
1604 return string_table
[0];
1607 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1609 else if (strcmp (str
, string_table
[0]->s
) < 0)
1617 i
= (start
+ end
) / 2;
1618 c
= strcmp (str
, string_table
[i
]->s
);
1623 return string_table
[i
];
1632 for (; i
> 0 && i
< strtablen
; i
--)
1633 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1636 for (; i
< strtablen
; i
++)
1637 if (strcmp (str
, string_table
[i
]->s
) < 0)
1640 for (x
= strtablen
- 1; x
>= i
; x
--)
1642 string_table
[x
+ 1] = string_table
[x
];
1643 string_table
[x
+ 1]->num
= x
+ 1;
1646 string_table
[i
] = tmalloc (struct string_entry
);
1647 string_table
[i
]->s
= xstrdup (str
);
1648 string_table
[i
]->num
= i
;
1651 return string_table
[i
];
1654 static struct bittree
*
1655 make_bittree_entry (void)
1657 struct bittree
*res
= tmalloc (struct bittree
);
1660 res
->bits
[0] = NULL
;
1661 res
->bits
[1] = NULL
;
1662 res
->bits
[2] = NULL
;
1664 res
->bits_to_skip
= 0;
1669 static struct disent
*
1670 add_dis_table_ent (which
, insn
, order
, completer_index
)
1671 struct disent
*which
;
1674 int completer_index
;
1684 while (ent
->nexte
!= NULL
)
1687 ent
= (ent
->nexte
= tmalloc (struct disent
));
1691 ent
= tmalloc (struct disent
);
1692 ent
->next_ent
= disinsntable
;
1699 ent
->priority
= order
;
1701 while (completer_index
!= 1)
1703 ci
= (ci
<< 1) | (completer_index
& 1);
1704 completer_index
>>= 1;
1706 ent
->completer_index
= ci
;
1713 struct disent
*ent
= disinsntable
;
1714 struct disent
*prev
= ent
;
1716 ent
->ournum
= 32768;
1717 while ((ent
= ent
->next_ent
) != NULL
)
1719 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1725 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1726 opcodenum
, order
, completer_index
)
1727 struct bittree
*curr_ent
;
1733 int completer_index
;
1737 struct bittree
*next
;
1741 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1744 curr_ent
->disent
= nent
;
1748 m
= ((ia64_insn
) 1) << bit
;
1751 b
= (opcode
& m
) ? 1 : 0;
1755 next
= curr_ent
->bits
[b
];
1758 next
= make_bittree_entry ();
1759 curr_ent
->bits
[b
] = next
;
1761 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1766 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1767 struct bittree
*first
;
1771 struct completer_entry
*ent
;
1772 int completer_index
;
1774 if (completer_index
& (1 << 20))
1779 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1780 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1781 (completer_index
<< 1) | 1);
1783 if (ent
->is_terminal
)
1785 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1786 opcodenum
, opcode_count
- ent
->order
- 1,
1787 (completer_index
<< 1) | 1);
1789 completer_index
<<= 1;
1790 ent
= ent
->alternative
;
1794 /* This optimization pass combines multiple "don't care" nodes. */
1796 compact_distree (ent
)
1797 struct bittree
*ent
;
1799 #define IS_SKIP(ent) \
1800 ((ent->bits[2] !=NULL) \
1801 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1804 struct bittree
*nent
= ent
;
1807 while (IS_SKIP (nent
))
1810 nent
= nent
->bits
[2];
1815 struct bittree
*next
= ent
->bits
[2];
1817 ent
->bits
[0] = nent
->bits
[0];
1818 ent
->bits
[1] = nent
->bits
[1];
1819 ent
->bits
[2] = nent
->bits
[2];
1820 ent
->disent
= nent
->disent
;
1822 ent
->bits_to_skip
= bitcnt
;
1823 while (next
!= nent
)
1825 struct bittree
*b
= next
;
1826 next
= next
->bits
[2];
1832 for (x
= 0; x
< 3; x
++)
1834 struct bittree
*i
= ent
->bits
[x
];
1837 compact_distree (i
);
1841 static unsigned char *insn_list
;
1842 static int insn_list_len
= 0;
1843 static int tot_insn_list_len
= 0;
1845 /* Generate the disassembler state machine corresponding to the tree
1849 struct bittree
*ent
;
1852 int our_offset
= insn_list_len
;
1854 int totbits
= bitsused
;
1857 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1859 /* If this is a terminal entry, there's no point in skipping any
1861 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1862 ent
->bits
[2] == NULL
)
1864 if (ent
->disent
== NULL
)
1870 /* Calculate the amount of space needed for this entry, or at least
1871 a conservatively large approximation. */
1875 for (x
= 1; x
< 3; x
++)
1876 if (ent
->bits
[x
] != NULL
)
1879 if (ent
->disent
!= NULL
)
1881 if (ent
->bits
[2] != NULL
)
1887 /* Now allocate the space. */
1888 needed_bytes
= (totbits
+ 7) / 8;
1889 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1891 tot_insn_list_len
+= 256;
1892 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1894 our_offset
= insn_list_len
;
1895 insn_list_len
+= needed_bytes
;
1896 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1898 /* Encode the skip entry by setting bit 6 set in the state op field,
1899 and store the # of bits to skip immediately after. */
1903 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1904 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1907 #define IS_ONLY_IFZERO(ENT) \
1908 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1909 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1911 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1913 if (ent
->bits
[0] != NULL
)
1915 struct bittree
*nent
= ent
->bits
[0];
1918 insn_list
[our_offset
] |= 0x80;
1920 /* We can encode sequences of multiple "if (bit is zero)" tests
1921 by storing the # of zero bits to check in the lower 3 bits of
1922 the instruction. However, this only applies if the state
1923 solely tests for a zero bit. */
1925 if (IS_ONLY_IFZERO (ent
))
1927 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1929 nent
= nent
->bits
[0];
1933 insn_list
[our_offset
+ 0] |= zero_count
;
1935 zero_dest
= insn_list_len
;
1936 gen_dis_table (nent
);
1939 /* Now store the remaining tests. We also handle a sole "termination
1940 entry" by storing it as an "any bit" test. */
1942 for (x
= 1; x
< 3; x
++)
1944 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1946 struct bittree
*i
= ent
->bits
[x
];
1952 /* If the instruction being branched to only consists of
1953 a termination entry, use the termination entry as the
1954 place to branch to instead. */
1955 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1956 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1958 idest
= i
->disent
->ournum
;
1962 idest
= insn_list_len
- our_offset
;
1965 idest
= ent
->disent
->ournum
;
1967 /* If the destination offset for the if (bit is 1) test is less
1968 than 256 bytes away, we can store it as 8-bits instead of 16;
1969 the instruction has bit 5 set for the 16-bit address, and bit
1970 4 for the 8-bit address. Since we've already allocated 16
1971 bits for the address we need to deallocate the space.
1973 Note that branchings within the table are relative, and
1974 there are no branches that branch past our instruction yet
1975 so we do not need to adjust any other offsets. */
1980 int start
= our_offset
+ bitsused
/ 8 + 1;
1982 memmove (insn_list
+ start
,
1983 insn_list
+ start
+ 1,
1984 insn_list_len
- (start
+ 1));
1989 insn_list
[our_offset
] |= 0x10;
1993 insn_list
[our_offset
] |= 0x20;
1997 /* An instruction which solely consists of a termination
1998 marker and whose disassembly name index is < 4096
1999 can be stored in 16 bits. The encoding is slightly
2000 odd; the upper 4 bits of the instruction are 0x3, and
2001 bit 3 loses its normal meaning. */
2003 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2004 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2005 && ent
->disent
!= NULL
2006 && ent
->disent
->ournum
< (32768 + 4096))
2008 int start
= our_offset
+ bitsused
/ 8 + 1;
2010 memmove (insn_list
+ start
,
2011 insn_list
+ start
+ 1,
2012 insn_list_len
- (start
+ 1));
2018 insn_list
[our_offset
] |= 0x30;
2022 insn_list
[our_offset
] |= 0x08;
2031 else if (! (id
& 32768))
2035 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2037 printf ("%d: try %d\n", our_offset
, id
);
2040 /* Store the address of the entry being branched to. */
2041 while (currbits
>= 0)
2043 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2045 if (idest
& (1 << currbits
))
2046 *byte
|= (1 << (7 - (bitsused
% 8)));
2052 /* Now generate the states for the entry being branched to. */
2061 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2063 if (ent
->bits
[0] != NULL
)
2064 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2068 if (bitsused
!= totbits
)
2073 print_dis_table (void)
2076 struct disent
*cent
= disinsntable
;
2078 printf ("static const char dis_table[] = {\n");
2079 for (x
= 0; x
< insn_list_len
; x
++)
2081 if ((x
> 0) && ((x
% 12) == 0))
2084 printf ("0x%02x, ", insn_list
[x
]);
2086 printf ("\n};\n\n");
2088 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2089 while (cent
!= NULL
)
2091 struct disent
*ent
= cent
;
2095 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2096 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2100 cent
= cent
->next_ent
;
2106 generate_disassembler (void)
2110 bittree
= make_bittree_entry ();
2112 for (i
= 0; i
< otlen
; i
++)
2114 struct main_entry
*ptr
= ordered_table
[i
];
2116 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2117 add_dis_entry (bittree
,
2118 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2120 ptr
->completers
, 1);
2123 compact_distree (bittree
);
2125 gen_dis_table (bittree
);
2131 print_string_table (void)
2134 char lbuf
[80], buf
[80];
2137 printf ("static const char * const ia64_strings[] = {\n");
2140 for (x
= 0; x
< strtablen
; x
++)
2144 if (strlen (string_table
[x
]->s
) > 75)
2147 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2150 if ((blen
+ len
) > 75)
2152 printf (" %s\n", lbuf
);
2161 printf (" %s\n", lbuf
);
2166 static struct completer_entry
**glist
;
2167 static int glistlen
= 0;
2168 static int glisttotlen
= 0;
2170 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2173 completer_entries_eq (ent1
, ent2
)
2174 struct completer_entry
*ent1
, *ent2
;
2176 while (ent1
!= NULL
&& ent2
!= NULL
)
2178 if (ent1
->name
->num
!= ent2
->name
->num
2179 || ent1
->bits
!= ent2
->bits
2180 || ent1
->mask
!= ent2
->mask
2181 || ent1
->is_terminal
!= ent2
->is_terminal
2182 || ent1
->dependencies
!= ent2
->dependencies
2183 || ent1
->order
!= ent2
->order
)
2186 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2189 ent1
= ent1
->alternative
;
2190 ent2
= ent2
->alternative
;
2193 return ent1
== ent2
;
2196 /* Insert ENT into the global list of completers and return it. If an
2197 equivalent entry (according to completer_entries_eq) already exists,
2198 it is returned instead. */
2199 static struct completer_entry
*
2200 insert_gclist (struct completer_entry
*ent
)
2208 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2209 ent
->alternative
= insert_gclist (ent
->alternative
);
2214 if (glisttotlen
== glistlen
)
2217 glist
= (struct completer_entry
**)
2218 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2228 if (ent
->name
->num
< glist
[0]->name
->num
)
2230 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2238 i
= (start
+ end
) / 2;
2239 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2246 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2260 while (i
< glistlen
)
2262 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2265 if (completer_entries_eq (ent
, glist
[i
]))
2273 for (; i
> 0 && i
< glistlen
; i
--)
2274 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2277 for (; i
< glistlen
; i
++)
2278 if (ent
->name
->num
< glist
[i
]->name
->num
)
2281 for (x
= glistlen
- 1; x
>= i
; x
--)
2282 glist
[x
+ 1] = glist
[x
];
2291 get_prefix_len (name
)
2296 if (name
[0] == '\0')
2299 c
= strchr (name
, '.');
2303 return strlen (name
);
2307 compute_completer_bits (ment
, ent
)
2308 struct main_entry
*ment
;
2309 struct completer_entry
*ent
;
2313 compute_completer_bits (ment
, ent
->addl_entries
);
2315 if (ent
->is_terminal
)
2318 ia64_insn our_bits
= ent
->bits
;
2319 struct completer_entry
*p
= ent
->parent
;
2323 while (p
!= NULL
&& ! p
->is_terminal
)
2329 p_bits
= ment
->opcode
->opcode
;
2331 for (x
= 0; x
< 64; x
++)
2333 ia64_insn m
= ((ia64_insn
) 1) << x
;
2335 if ((p_bits
& m
) != (our_bits
& m
))
2340 ent
->bits
= our_bits
;
2349 ent
= ent
->alternative
;
2353 /* Find identical completer trees that are used in different
2354 instructions and collapse their entries. */
2356 collapse_redundant_completers (void)
2358 struct main_entry
*ptr
;
2361 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2363 if (ptr
->completers
== NULL
)
2366 compute_completer_bits (ptr
, ptr
->completers
);
2367 ptr
->completers
= insert_gclist (ptr
->completers
);
2370 /* The table has been finalized, now number the indexes. */
2371 for (x
= 0; x
< glistlen
; x
++)
2376 /* Attach two lists of dependencies to each opcode.
2377 1) all resources which, when already marked in use, conflict with this
2379 2) all resources which must be marked in use when this opcode is used
2382 insert_opcode_dependencies (opc
, cmp
)
2383 struct ia64_opcode
*opc
;
2384 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2386 /* Note all resources which point to this opcode. rfi has the most chks
2387 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2390 unsigned short regs
[256];
2392 unsigned short chks
[256];
2393 /* Flag insns for which no class matched; there should be none. */
2394 int no_class_found
= 1;
2396 for (i
= 0; i
< rdepslen
; i
++)
2398 struct rdep
*rs
= rdeps
[i
];
2401 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2402 && strncmp (rs
->name
, "PR%", 3) == 0
2404 no_class_found
= 99;
2406 for (j
=0; j
< rs
->nregs
;j
++)
2410 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2412 /* We can ignore ic_note 11 for non PR resources. */
2413 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2416 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2417 && ic_note
!= rs
->regnotes
[j
]
2418 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2419 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2420 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2421 rs
->name
, rs
->regnotes
[j
]);
2422 /* Instruction class notes override resource notes.
2423 So far, only note 11 applies to an IC instead of a resource,
2424 and note 11 implies note 1. */
2426 regs
[nregs
++] = RDEP(ic_note
, i
);
2428 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2434 for (j
= 0; j
< rs
->nchks
; j
++)
2438 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2440 /* We can ignore ic_note 11 for non PR resources. */
2441 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2444 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2445 && ic_note
!= rs
->chknotes
[j
]
2446 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2447 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2448 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2449 rs
->name
, rs
->chknotes
[j
]);
2451 chks
[nchks
++] = RDEP(ic_note
, i
);
2453 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2461 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2463 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2465 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2469 insert_completer_entry (opc
, tabent
, order
)
2470 struct ia64_opcode
*opc
;
2471 struct main_entry
*tabent
;
2474 struct completer_entry
**ptr
= &tabent
->completers
;
2475 struct completer_entry
*parent
= NULL
;
2476 char pcopy
[129], *prefix
;
2479 if (strlen (opc
->name
) > 128)
2482 strcpy (pcopy
, opc
->name
);
2483 prefix
= pcopy
+ get_prefix_len (pcopy
);
2485 if (prefix
[0] != '\0')
2490 int need_new_ent
= 1;
2491 int plen
= get_prefix_len (prefix
);
2492 struct string_entry
*sent
;
2494 at_end
= (prefix
[plen
] == '\0');
2495 prefix
[plen
] = '\0';
2496 sent
= insert_string (prefix
);
2498 while (*ptr
!= NULL
)
2500 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2508 ptr
= &((*ptr
)->alternative
);
2513 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2516 nent
->parent
= parent
;
2517 nent
->addl_entries
= NULL
;
2518 nent
->alternative
= *ptr
;
2520 nent
->is_terminal
= 0;
2521 nent
->dependencies
= -1;
2527 ptr
= &((*ptr
)->addl_entries
);
2532 if ((*ptr
)->is_terminal
)
2535 (*ptr
)->is_terminal
= 1;
2536 (*ptr
)->mask
= (ia64_insn
)-1;
2537 (*ptr
)->bits
= opc
->opcode
;
2538 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2539 (*ptr
)->order
= order
;
2543 print_completer_entry (ent
)
2544 struct completer_entry
*ent
;
2547 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2551 while (! (mask
& 1))
2558 if (bits
& 0xffffffff00000000LL
)
2562 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2566 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2567 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2569 ent
->is_terminal
? 1 : 0,
2574 print_completer_table ()
2578 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2579 for (x
= 0; x
< glistlen
; x
++)
2580 print_completer_entry (glist
[x
]);
2585 opcodes_eq (opc1
, opc2
)
2586 struct ia64_opcode
*opc1
;
2587 struct ia64_opcode
*opc2
;
2592 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2593 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2594 || (opc1
->flags
!= opc2
->flags
))
2597 for (x
= 0; x
< 5; x
++)
2598 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2601 plen1
= get_prefix_len (opc1
->name
);
2602 plen2
= get_prefix_len (opc2
->name
);
2604 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2611 add_opcode_entry (opc
)
2612 struct ia64_opcode
*opc
;
2614 struct main_entry
**place
;
2615 struct string_entry
*name
;
2619 if (strlen (opc
->name
) > 128)
2623 strcpy (prefix
, opc
->name
);
2624 prefix
[get_prefix_len (prefix
)] = '\0';
2625 name
= insert_string (prefix
);
2627 /* Walk the list of opcode table entries. If it's a new
2628 instruction, allocate and fill in a new entry. Note
2629 the main table is alphabetical by opcode name. */
2631 while (*place
!= NULL
)
2633 if ((*place
)->name
->num
== name
->num
2634 && opcodes_eq ((*place
)->opcode
, opc
))
2639 if ((*place
)->name
->num
> name
->num
)
2642 place
= &((*place
)->next
);
2646 struct main_entry
*nent
= tmalloc (struct main_entry
);
2650 nent
->next
= *place
;
2651 nent
->completers
= 0;
2654 if (otlen
== ottotlen
)
2657 ordered_table
= (struct main_entry
**)
2658 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2660 ordered_table
[otlen
++] = nent
;
2663 insert_completer_entry (opc
, *place
, opcode_count
++);
2667 print_main_table (void)
2669 struct main_entry
*ptr
= maintable
;
2672 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2675 printf (" { %d, %d, %d, 0x",
2678 ptr
->opcode
->num_outputs
);
2679 fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2681 fprintf_vma (stdout
, ptr
->opcode
->mask
);
2682 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2683 ptr
->opcode
->operands
[0],
2684 ptr
->opcode
->operands
[1],
2685 ptr
->opcode
->operands
[2],
2686 ptr
->opcode
->operands
[3],
2687 ptr
->opcode
->operands
[4],
2689 ptr
->completers
->num
);
2691 ptr
->main_index
= index
++;
2700 struct ia64_opcode
*table
;
2704 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2705 add_opcode_entry (table
+ curr_opcode
);
2709 /* Program options. */
2710 #define OPTION_SRCDIR 200
2712 struct option long_options
[] =
2714 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2715 {"debug", no_argument
, NULL
, 'd'},
2716 {"version", no_argument
, NULL
, 'V'},
2717 {"help", no_argument
, NULL
, 'h'},
2718 {0, no_argument
, NULL
, 0}
2722 print_version (void)
2724 printf ("%s: version 1.0\n", program_name
);
2729 usage (FILE * stream
, int status
)
2731 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2737 main (int argc
, char **argv
)
2739 extern int chdir (char *);
2740 char *srcdir
= NULL
;
2743 program_name
= *argv
;
2744 xmalloc_set_program_name (program_name
);
2746 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2771 if (chdir (srcdir
) != 0)
2772 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2773 srcdir
, strerror (errno
));
2775 load_insn_classes ();
2776 load_dependencies ();
2778 shrink (ia64_opcodes_a
);
2779 shrink (ia64_opcodes_b
);
2780 shrink (ia64_opcodes_f
);
2781 shrink (ia64_opcodes_i
);
2782 shrink (ia64_opcodes_m
);
2783 shrink (ia64_opcodes_x
);
2784 shrink (ia64_opcodes_d
);
2786 collapse_redundant_completers ();
2788 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2789 print_string_table ();
2790 print_dependency_table ();
2791 print_completer_table ();
2792 print_main_table ();
2794 generate_disassembler ();