1 /* ia64-gen.c -- Generate a shrunk set of opcode tables
2 Copyright 1999, 2000, 2001, 2002, 2004, 2005
3 Free Software Foundation, Inc.
4 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
6 This file is part of GDB, GAS, and the GNU binutils.
8 GDB, GAS, and the GNU binutils are free software; you can redistribute
9 them and/or modify them under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version
11 2, or (at your option) any later version.
13 GDB, GAS, and the GNU binutils are distributed in the hope that they
14 will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING. If not, write to the
20 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 /* While the ia64-opc-* set of opcode tables are easy to maintain,
24 they waste a tremendous amount of space. ia64-gen rearranges the
25 instructions into a directed acyclic graph (DAG) of instruction opcodes and
26 their possible completers, as well as compacting the set of strings used.
28 The disassembler table consists of a state machine that does
29 branching based on the bits of the opcode being disassembled. The
30 state encodings have been chosen to minimize the amount of space
33 The resource table is constructed based on some text dependency tables,
34 which are also easier to maintain than the final representation. */
41 #include "libiberty.h"
42 #include "safe-ctype.h"
46 #include "ia64-opc-a.c"
47 #include "ia64-opc-i.c"
48 #include "ia64-opc-m.c"
49 #include "ia64-opc-b.c"
50 #include "ia64-opc-f.c"
51 #include "ia64-opc-x.c"
52 #include "ia64-opc-d.c"
55 #define _(String) gettext (String)
57 const char * program_name
= NULL
;
60 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
61 #define tmalloc(X) (X *) xmalloc (sizeof (X))
63 /* The main opcode table entry. Each entry is a unique combination of
64 name and flags (no two entries in the table compare as being equal
68 /* The base name of this opcode. The names of its completers are
69 appended to it to generate the full instruction name. */
70 struct string_entry
*name
;
71 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
72 it uses the first one passed to add_opcode_entry. */
73 struct ia64_opcode
*opcode
;
74 /* The list of completers that can be applied to this opcode. */
75 struct completer_entry
*completers
;
76 /* Next entry in the chain. */
77 struct main_entry
*next
;
78 /* Index in the main table. */
80 } *maintable
, **ordered_table
;
86 /* The set of possible completers for an opcode. */
87 struct completer_entry
89 /* This entry's index in the ia64_completer_table[] array. */
92 /* The name of the completer. */
93 struct string_entry
*name
;
95 /* This entry's parent. */
96 struct completer_entry
*parent
;
98 /* Set if this is a terminal completer (occurs at the end of an
102 /* An alternative completer. */
103 struct completer_entry
*alternative
;
105 /* Additional completers that can be appended to this one. */
106 struct completer_entry
*addl_entries
;
108 /* Before compute_completer_bits () is invoked, this contains the actual
109 instruction opcode for this combination of opcode and completers.
110 Afterwards, it contains those bits that are different from its
114 /* Bits set to 1 correspond to those bits in this completer's opcode
115 that are different from its parent completer's opcode (or from
116 the base opcode if the entry is the root of the opcode's completer
117 list). This field is filled in by compute_completer_bits (). */
120 /* Index into the opcode dependency list, or -1 if none. */
123 /* Remember the order encountered in the opcode tables. */
127 /* One entry in the disassembler name table. */
130 /* The index into the ia64_name_dis array for this entry. */
133 /* The index into the main_table[] array. */
136 /* The disassmbly priority of this entry. */
139 /* The completer_index value for this entry. */
142 /* How many other entries share this decode. */
145 /* The next entry sharing the same decode. */
146 struct disent
*nexte
;
148 /* The next entry in the name list. */
149 struct disent
*next_ent
;
150 } *disinsntable
= NULL
;
152 /* A state machine that will eventually be used to generate the
153 disassembler table. */
156 struct disent
*disent
;
157 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
162 /* The string table contains all opcodes and completers sorted in
163 alphabetical order. */
165 /* One entry in the string table. */
168 /* The index in the ia64_strings[] array for this entry. */
170 /* And the string. */
172 } **string_table
= NULL
;
175 int strtabtotlen
= 0;
178 /* Resource dependency entries. */
181 char *name
; /* Resource name. */
183 mode
:2, /* RAW, WAW, or WAR. */
184 semantics
:3; /* Dependency semantics. */
185 char *extra
; /* Additional semantics info. */
187 int total_chks
; /* Total #of terminal insns. */
188 int *chks
; /* Insn classes which read (RAW), write
189 (WAW), or write (WAR) this rsrc. */
190 int *chknotes
; /* Dependency notes for each class. */
192 int total_regs
; /* Total #of terminal insns. */
193 int *regs
; /* Insn class which write (RAW), write2
194 (WAW), or read (WAR) this rsrc. */
195 int *regnotes
; /* Dependency notes for each class. */
197 int waw_special
; /* Special WAW dependency note. */
200 static int rdepslen
= 0;
201 static int rdepstotlen
= 0;
203 /* Array of all instruction classes. */
206 char *name
; /* Instruction class name. */
207 int is_class
; /* Is a class, not a terminal. */
209 int *subs
; /* Other classes within this class. */
211 int xsubs
[4]; /* Exclusions. */
212 char *comment
; /* Optional comment. */
213 int note
; /* Optional note. */
214 int terminal_resolved
; /* Did we match this with anything? */
215 int orphan
; /* Detect class orphans. */
218 static int iclen
= 0;
219 static int ictotlen
= 0;
221 /* An opcode dependency (chk/reg pair of dependency lists). */
224 int chk
; /* index into dlists */
225 int reg
; /* index into dlists */
228 static int opdeplen
= 0;
229 static int opdeptotlen
= 0;
231 /* A generic list of dependencies w/notes encoded. These may be shared. */
235 unsigned short *deps
;
238 static int dlistlen
= 0;
239 static int dlisttotlen
= 0;
242 static void fail (const char *, ...);
243 static void warn (const char *, ...);
244 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
245 static int deplist_equals (struct deplist
*, struct deplist
*);
246 static short insert_deplist (int, unsigned short *);
247 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
248 static void mark_used (struct iclass
*, int);
249 static int fetch_insn_class (const char *, int);
250 static int sub_compare (const void *, const void *);
251 static void load_insn_classes (void);
252 static void parse_resource_users (const char *, int **, int *, int **);
253 static int parse_semantics (char *);
254 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
255 static void load_depfile (const char *, enum ia64_dependency_mode
);
256 static void load_dependencies (void);
257 static int irf_operand (int, const char *);
258 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
259 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
260 static int lookup_regindex (const char *, int);
261 static int lookup_specifier (const char *);
262 static void print_dependency_table (void);
263 static struct string_entry
* insert_string (char *);
264 static void gen_dis_table (struct bittree
*);
265 static void print_dis_table (void);
266 static void generate_disassembler (void);
267 static void print_string_table (void);
268 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
269 static struct completer_entry
* insert_gclist (struct completer_entry
*);
270 static int get_prefix_len (const char *);
271 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
272 static void collapse_redundant_completers (void);
273 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
274 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
275 static void print_completer_entry (struct completer_entry
*);
276 static void print_completer_table (void);
277 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
278 static void add_opcode_entry (struct ia64_opcode
*);
279 static void print_main_table (void);
280 static void shrink (struct ia64_opcode
*);
281 static void print_version (void);
282 static void usage (FILE *, int);
283 static void finish_distable (void);
284 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, int);
285 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, int);
286 static void compact_distree (struct bittree
*);
287 static struct bittree
* make_bittree_entry (void);
288 static struct disent
* add_dis_table_ent (struct disent
*, int, int, int);
292 fail (const char *message
, ...)
296 va_start (args
, message
);
297 fprintf (stderr
, _("%s: Error: "), program_name
);
298 vfprintf (stderr
, message
, args
);
304 warn (const char *message
, ...)
308 va_start (args
, message
);
310 fprintf (stderr
, _("%s: Warning: "), program_name
);
311 vfprintf (stderr
, message
, args
);
315 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
317 insert_resource (const char *name
, enum ia64_dependency_mode type
)
319 if (rdepslen
== rdepstotlen
)
322 rdeps
= (struct rdep
**)
323 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
325 rdeps
[rdepslen
] = tmalloc(struct rdep
);
326 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
327 rdeps
[rdepslen
]->name
= xstrdup (name
);
328 rdeps
[rdepslen
]->mode
= type
;
329 rdeps
[rdepslen
]->waw_special
= 0;
331 return rdeps
[rdepslen
++];
334 /* Are the lists of dependency indexes equivalent? */
336 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
340 if (d1
->len
!= d2
->len
)
343 for (i
= 0; i
< d1
->len
; i
++)
344 if (d1
->deps
[i
] != d2
->deps
[i
])
350 /* Add the list of dependencies to the list of dependency lists. */
352 insert_deplist (int count
, unsigned short *deps
)
354 /* Sort the list, then see if an equivalent list exists already.
355 this results in a much smaller set of dependency lists. */
356 struct deplist
*list
;
360 memset ((void *)set
, 0, sizeof (set
));
361 for (i
= 0; i
< count
; i
++)
365 for (i
= 0; i
< (int) sizeof (set
); i
++)
369 list
= tmalloc (struct deplist
);
371 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
373 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
375 list
->deps
[count
++] = i
;
377 /* Does this list exist already? */
378 for (i
= 0; i
< dlistlen
; i
++)
379 if (deplist_equals (list
, dlists
[i
]))
386 if (dlistlen
== dlisttotlen
)
389 dlists
= (struct deplist
**)
390 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
392 dlists
[dlistlen
] = list
;
397 /* Add the given pair of dependency lists to the opcode dependency list. */
399 insert_dependencies (int nchks
, unsigned short *chks
,
400 int nregs
, unsigned short *regs
)
408 regind
= insert_deplist (nregs
, regs
);
410 chkind
= insert_deplist (nchks
, chks
);
412 for (i
= 0; i
< opdeplen
; i
++)
413 if (opdeps
[i
]->chk
== chkind
414 && opdeps
[i
]->reg
== regind
)
417 pair
= tmalloc (struct opdep
);
421 if (opdeplen
== opdeptotlen
)
424 opdeps
= (struct opdep
**)
425 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
427 opdeps
[opdeplen
] = pair
;
433 mark_used (struct iclass
*ic
, int clear_terminals
)
439 ic
->terminal_resolved
= 1;
441 for (i
= 0; i
< ic
->nsubs
; i
++)
442 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
444 for (i
= 0; i
< ic
->nxsubs
; i
++)
445 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
448 /* Look up an instruction class; if CREATE make a new one if none found;
449 returns the index into the insn class array. */
451 fetch_insn_class (const char *full_name
, int create
)
461 if (strncmp (full_name
, "IC:", 3) == 0)
463 name
= xstrdup (full_name
+ 3);
467 name
= xstrdup (full_name
);
469 if ((xsect
= strchr(name
, '\\')) != NULL
)
471 if ((comment
= strchr(name
, '[')) != NULL
)
473 if ((notestr
= strchr(name
, '+')) != NULL
)
476 /* If it is a composite class, then ignore comments and notes that come after
477 the '\\', since they don't apply to the part we are decoding now. */
490 note
= atoi (notestr
+ 1);
491 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
493 if (strcmp (notestr
, "+1+13") == 0)
495 else if (!xsect
|| nextnotestr
< xsect
)
496 warn (_("multiple note %s not handled\n"), notestr
);
500 /* If it's a composite class, leave the notes and comments in place so that
501 we have a unique name for the composite class. Otherwise, we remove
511 for (i
= 0; i
< iclen
; i
++)
512 if (strcmp (name
, ics
[i
]->name
) == 0
513 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
514 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
515 && strncmp (ics
[i
]->comment
, comment
,
516 strlen (ics
[i
]->comment
)) == 0))
517 && note
== ics
[i
]->note
)
523 /* Doesn't exist, so make a new one. */
524 if (iclen
== ictotlen
)
527 ics
= (struct iclass
**)
528 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
532 ics
[ind
] = tmalloc (struct iclass
);
533 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
534 ics
[ind
]->name
= xstrdup (name
);
535 ics
[ind
]->is_class
= is_class
;
536 ics
[ind
]->orphan
= 1;
540 ics
[ind
]->comment
= xstrdup (comment
+ 1);
541 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
545 ics
[ind
]->note
= note
;
547 /* If it's a composite class, there's a comment or note, look for an
548 existing class or terminal with the same name. */
549 if ((xsect
|| comment
|| notestr
) && is_class
)
551 /* First, populate with the class we're based on. */
552 char *subname
= name
;
562 ics
[ind
]->subs
= tmalloc(int);
563 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
568 char *subname
= xsect
+ 1;
570 xsect
= strchr (subname
, '\\');
573 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
581 /* For sorting a class's sub-class list only; make sure classes appear before
584 sub_compare (const void *e1
, const void *e2
)
586 struct iclass
*ic1
= ics
[*(int *)e1
];
587 struct iclass
*ic2
= ics
[*(int *)e2
];
594 else if (ic2
->is_class
)
597 return strcmp (ic1
->name
, ic2
->name
);
601 load_insn_classes (void)
603 FILE *fp
= fopen ("ia64-ic.tbl", "r");
607 fail (_("can't find ia64-ic.tbl for reading\n"));
609 /* Discard first line. */
610 fgets (buf
, sizeof(buf
), fp
);
618 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
621 while (ISSPACE (buf
[strlen (buf
) - 1]))
622 buf
[strlen (buf
) - 1] = '\0';
628 if (tmp
== buf
+ sizeof (buf
))
633 iclass
= fetch_insn_class (name
, 1);
634 ics
[iclass
]->is_class
= 1;
636 if (strcmp (name
, "none") == 0)
638 ics
[iclass
]->is_class
= 0;
639 ics
[iclass
]->terminal_resolved
= 1;
643 /* For this class, record all sub-classes. */
649 while (*tmp
&& ISSPACE (*tmp
))
652 if (tmp
== buf
+ sizeof (buf
))
656 while (*tmp
&& *tmp
!= ',')
659 if (tmp
== buf
+ sizeof (buf
))
665 ics
[iclass
]->subs
= (int *)
666 xrealloc ((void *)ics
[iclass
]->subs
,
667 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
669 sub
= fetch_insn_class (subname
, 1);
670 ics
[iclass
]->subs
= (int *)
671 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
672 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
675 /* Make sure classes come before terminals. */
676 qsort ((void *)ics
[iclass
]->subs
,
677 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
682 printf ("%d classes\n", iclen
);
685 /* Extract the insn classes from the given line. */
687 parse_resource_users (ref
, usersp
, nusersp
, notesp
)
694 char *line
= xstrdup (ref
);
696 int *users
= *usersp
;
697 int count
= *nusersp
;
698 int *notes
= *notesp
;
710 while (ISSPACE (*tmp
))
713 while (*tmp
&& *tmp
!= ',')
718 xsect
= strchr (name
, '\\');
719 if ((notestr
= strstr (name
, "+")) != NULL
)
723 note
= atoi (notestr
+ 1);
724 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
726 /* Note 13 always implies note 1. */
727 if (strcmp (notestr
, "+1+13") == 0)
729 else if (!xsect
|| nextnotestr
< xsect
)
730 warn (_("multiple note %s not handled\n"), notestr
);
738 /* All classes are created when the insn class table is parsed;
739 Individual instructions might not appear until the dependency tables
740 are read. Only create new classes if it's *not* an insn class,
741 or if it's a composite class (which wouldn't necessarily be in the IC
743 if (strncmp (name
, "IC:", 3) != 0 || xsect
!= NULL
)
746 iclass
= fetch_insn_class (name
, create
);
750 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
752 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
754 users
[count
++] = iclass
;
755 mark_used (ics
[iclass
], 0);
758 printf("Class %s not found\n", name
);
760 /* Update the return values. */
769 parse_semantics (char *sem
)
771 if (strcmp (sem
, "none") == 0)
772 return IA64_DVS_NONE
;
773 else if (strcmp (sem
, "implied") == 0)
774 return IA64_DVS_IMPLIED
;
775 else if (strcmp (sem
, "impliedF") == 0)
776 return IA64_DVS_IMPLIEDF
;
777 else if (strcmp (sem
, "data") == 0)
778 return IA64_DVS_DATA
;
779 else if (strcmp (sem
, "instr") == 0)
780 return IA64_DVS_INSTR
;
781 else if (strcmp (sem
, "specific") == 0)
782 return IA64_DVS_SPECIFIC
;
783 else if (strcmp (sem
, "stop") == 0)
784 return IA64_DVS_STOP
;
786 return IA64_DVS_OTHER
;
790 add_dep (const char *name
, const char *chk
, const char *reg
,
791 int semantics
, int mode
, char *extra
, int flag
)
795 rs
= insert_resource (name
, mode
);
797 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
798 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
800 rs
->semantics
= semantics
;
802 rs
->waw_special
= flag
;
806 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
808 FILE *fp
= fopen (filename
, "r");
812 fail (_("can't find %s for reading\n"), filename
);
814 fgets (buf
, sizeof(buf
), fp
);
822 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
825 while (ISSPACE (buf
[strlen (buf
) - 1]))
826 buf
[strlen (buf
) - 1] = '\0';
833 while (ISSPACE (*tmp
))
836 tmp
= strchr (tmp
, ';');
840 while (ISSPACE (*tmp
))
843 tmp
= strchr (tmp
, ';');
847 while (ISSPACE (*tmp
))
849 semantics
= parse_semantics (tmp
);
850 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
852 /* For WAW entries, if the chks and regs differ, we need to enter the
853 entries in both positions so that the tables will be parsed properly,
854 without a lot of extra work. */
855 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
857 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
858 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
862 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
869 load_dependencies (void)
871 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
872 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
873 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
876 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
879 /* Is the given operand an indirect register file operand? */
881 irf_operand (int op
, const char *field
)
885 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
886 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
887 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
888 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
892 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
893 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
894 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
895 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
896 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
897 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
898 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
899 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
903 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
904 mov_um insn classes. */
906 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
907 const char *format
, const char *field
)
909 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
920 int i
= strcmp (idesc
->name
, "mov.i") == 0;
921 int m
= strcmp (idesc
->name
, "mov.m") == 0;
922 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
923 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
924 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
925 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
926 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
927 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
931 return strstr (format
, "I26") || strstr (format
, "I27");
933 return strstr (format
, "I28") != NULL
;
935 return strstr (format
, "M29") || strstr (format
, "M30");
937 return strstr (format
, "M31") != NULL
;
938 if (pseudo0
|| pseudo1
)
944 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
945 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
947 return strstr (format
, "I22") != NULL
;
949 return strstr (format
, "I21") != NULL
;
954 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
955 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
957 return strstr (format
, "M32") != NULL
;
959 return strstr (format
, "M33") != NULL
;
963 if (ic
->name
[5] == 'n')
965 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
966 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
968 return strstr (format
, "M42") != NULL
;
970 return strstr (format
, "M43") != NULL
;
972 else if (ic
->name
[5] == 'p')
974 return idesc
->operands
[1] == IA64_OPND_IP
;
980 if (ic
->name
[5] == 'r')
982 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
983 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
984 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
986 return strstr (format
, "I23") != NULL
;
988 return strstr (format
, "I24") != NULL
;
990 return strstr (format
, "I25") != NULL
;
992 else if (ic
->name
[5] == 's')
994 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
995 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
997 return strstr (format
, "M35") != NULL
;
999 return strstr (format
, "M36") != NULL
;
1006 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1007 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1009 return strstr (format
, "M35") != NULL
;
1011 return strstr (format
, "M36") != NULL
;
1018 /* Is the given opcode in the given insn class? */
1020 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1021 const char *format
, const char *field
, int *notep
)
1028 if (!strncmp (ic
->comment
, "Format", 6))
1030 /* Assume that the first format seen is the most restrictive, and
1031 only keep a later one if it looks like it's more restrictive. */
1034 if (strlen (ic
->comment
) < strlen (format
))
1036 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1037 ic
->comment
, format
);
1038 format
= ic
->comment
;
1042 format
= ic
->comment
;
1044 else if (!strncmp (ic
->comment
, "Field", 5))
1047 warn (_("overlapping field %s->%s\n"),
1048 ic
->comment
, field
);
1049 field
= ic
->comment
;
1053 /* An insn class matches anything that is the same followed by completers,
1054 except when the absence and presence of completers constitutes different
1056 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1058 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
1059 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1060 int len
= strlen(ic
->name
);
1062 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1063 && (idesc
->name
[len
] == '\0'
1064 || idesc
->name
[len
] == '.'));
1066 /* All break, nop, and hint variations must match exactly. */
1068 (strcmp (ic
->name
, "break") == 0
1069 || strcmp (ic
->name
, "nop") == 0
1070 || strcmp (ic
->name
, "hint") == 0))
1071 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1073 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1074 unless specifically allowed by clauses in this block. */
1075 if (resolved
&& field
)
1077 /* Check Field(sf)==sN against opcode sN. */
1078 if (strstr(field
, "(sf)==") != NULL
)
1082 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1083 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1085 /* Check Field(lftype)==XXX. */
1086 else if (strstr (field
, "(lftype)") != NULL
)
1088 if (strstr (idesc
->name
, "fault") != NULL
)
1089 resolved
= strstr (field
, "fault") != NULL
;
1091 resolved
= strstr (field
, "fault") == NULL
;
1093 /* Handle Field(ctype)==XXX. */
1094 else if (strstr (field
, "(ctype)") != NULL
)
1096 if (strstr (idesc
->name
, "or.andcm"))
1097 resolved
= strstr (field
, "or.andcm") != NULL
;
1098 else if (strstr (idesc
->name
, "and.orcm"))
1099 resolved
= strstr (field
, "and.orcm") != NULL
;
1100 else if (strstr (idesc
->name
, "orcm"))
1101 resolved
= strstr (field
, "or orcm") != NULL
;
1102 else if (strstr (idesc
->name
, "or"))
1103 resolved
= strstr (field
, "or orcm") != NULL
;
1104 else if (strstr (idesc
->name
, "andcm"))
1105 resolved
= strstr (field
, "and andcm") != NULL
;
1106 else if (strstr (idesc
->name
, "and"))
1107 resolved
= strstr (field
, "and andcm") != NULL
;
1108 else if (strstr (idesc
->name
, "unc"))
1109 resolved
= strstr (field
, "unc") != NULL
;
1111 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1115 if (resolved
&& format
)
1117 if (strncmp (idesc
->name
, "dep", 3) == 0
1118 && strstr (format
, "I13") != NULL
)
1119 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1120 else if (strncmp (idesc
->name
, "chk", 3) == 0
1121 && strstr (format
, "M21") != NULL
)
1122 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1123 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1124 resolved
= (strstr (format
, "M14 M15") != NULL
1125 && (idesc
->operands
[1] == IA64_OPND_R2
1126 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1127 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1128 && strstr (format
, "B5") != NULL
)
1129 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1130 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1131 && strstr (format
, "B3") != NULL
)
1132 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1133 else if (strncmp (idesc
->name
, "brp", 3) == 0
1134 && strstr (format
, "B7") != NULL
)
1135 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1136 else if (strcmp (ic
->name
, "invala") == 0)
1137 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1138 else if (strncmp (idesc
->name
, "st", 2) == 0
1139 && (strstr (format
, "M5") != NULL
1140 || strstr (format
, "M10") != NULL
))
1141 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1142 else if (strncmp (idesc
->name
, "ld", 2) == 0
1143 && (strstr (format
, "M2 M3") != NULL
1144 || strstr (format
, "M12") != NULL
1145 || strstr (format
, "M7 M8") != NULL
))
1146 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1151 /* Misc brl variations ('.cond' is optional);
1152 plain brl matches brl.cond. */
1154 && (strcmp (idesc
->name
, "brl") == 0
1155 || strncmp (idesc
->name
, "brl.", 4) == 0)
1156 && strcmp (ic
->name
, "brl.cond") == 0)
1161 /* Misc br variations ('.cond' is optional). */
1163 && (strcmp (idesc
->name
, "br") == 0
1164 || strncmp (idesc
->name
, "br.", 3) == 0)
1165 && strcmp (ic
->name
, "br.cond") == 0)
1168 resolved
= (strstr (format
, "B4") != NULL
1169 && idesc
->operands
[0] == IA64_OPND_B2
)
1170 || (strstr (format
, "B1") != NULL
1171 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1176 /* probe variations. */
1177 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1179 resolved
= strcmp (ic
->name
, "probe") == 0
1180 && !((strstr (idesc
->name
, "fault") != NULL
)
1181 ^ (format
&& strstr (format
, "M40") != NULL
));
1184 /* mov variations. */
1185 if (!resolved
&& is_mov
)
1189 /* mov alias for fmerge. */
1190 if (strcmp (ic
->name
, "fmerge") == 0)
1192 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1193 && idesc
->operands
[1] == IA64_OPND_F3
;
1195 /* mov alias for adds (r3 or imm14). */
1196 else if (strcmp (ic
->name
, "adds") == 0)
1198 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1199 && (idesc
->operands
[1] == IA64_OPND_R3
1200 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1202 /* mov alias for addl. */
1203 else if (strcmp (ic
->name
, "addl") == 0)
1205 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1206 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1210 /* Some variants of mov and mov.[im]. */
1211 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1212 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1215 /* Keep track of this so we can flag any insn classes which aren't
1216 mapped onto at least one real insn. */
1218 ic
->terminal_resolved
= 1;
1220 else for (i
= 0; i
< ic
->nsubs
; i
++)
1222 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1226 for (j
= 0; j
< ic
->nxsubs
; j
++)
1227 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1231 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1238 /* If it's in this IC, add the IC note (if any) to the insn. */
1241 if (ic
->note
&& notep
)
1243 if (*notep
&& *notep
!= ic
->note
)
1244 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1245 *notep
, ic
->note
, ic
->name
);
1256 lookup_regindex (const char *name
, int specifier
)
1261 if (strstr (name
, "[RSC]"))
1263 if (strstr (name
, "[BSP]"))
1265 else if (strstr (name
, "[BSPSTORE]"))
1267 else if (strstr (name
, "[RNAT]"))
1269 else if (strstr (name
, "[FCR]"))
1271 else if (strstr (name
, "[EFLAG]"))
1273 else if (strstr (name
, "[CSD]"))
1275 else if (strstr (name
, "[SSD]"))
1277 else if (strstr (name
, "[CFLG]"))
1279 else if (strstr (name
, "[FSR]"))
1281 else if (strstr (name
, "[FIR]"))
1283 else if (strstr (name
, "[FDR]"))
1285 else if (strstr (name
, "[CCV]"))
1287 else if (strstr (name
, "[ITC]"))
1289 else if (strstr (name
, "[PFS]"))
1291 else if (strstr (name
, "[LC]"))
1293 else if (strstr (name
, "[EC]"))
1297 if (strstr (name
, "[DCR]"))
1299 else if (strstr (name
, "[ITM]"))
1301 else if (strstr (name
, "[IVA]"))
1303 else if (strstr (name
, "[PTA]"))
1305 else if (strstr (name
, "[GPTA]"))
1307 else if (strstr (name
, "[IPSR]"))
1309 else if (strstr (name
, "[ISR]"))
1311 else if (strstr (name
, "[IIP]"))
1313 else if (strstr (name
, "[IFA]"))
1315 else if (strstr (name
, "[ITIR]"))
1317 else if (strstr (name
, "[IIPA]"))
1319 else if (strstr (name
, "[IFS]"))
1321 else if (strstr (name
, "[IIM]"))
1323 else if (strstr (name
, "[IHA]"))
1325 else if (strstr (name
, "[LID]"))
1327 else if (strstr (name
, "[IVR]"))
1329 else if (strstr (name
, "[TPR]"))
1331 else if (strstr (name
, "[EOI]"))
1333 else if (strstr (name
, "[ITV]"))
1335 else if (strstr (name
, "[PMV]"))
1337 else if (strstr (name
, "[CMCV]"))
1341 if (strstr (name
, ".be"))
1343 else if (strstr (name
, ".up"))
1345 else if (strstr (name
, ".ac"))
1347 else if (strstr (name
, ".mfl"))
1349 else if (strstr (name
, ".mfh"))
1351 else if (strstr (name
, ".ic"))
1353 else if (strstr (name
, ".i"))
1355 else if (strstr (name
, ".pk"))
1357 else if (strstr (name
, ".dt"))
1359 else if (strstr (name
, ".dfl"))
1361 else if (strstr (name
, ".dfh"))
1363 else if (strstr (name
, ".sp"))
1365 else if (strstr (name
, ".pp"))
1367 else if (strstr (name
, ".di"))
1369 else if (strstr (name
, ".si"))
1371 else if (strstr (name
, ".db"))
1373 else if (strstr (name
, ".lp"))
1375 else if (strstr (name
, ".tb"))
1377 else if (strstr (name
, ".rt"))
1379 else if (strstr (name
, ".cpl"))
1381 else if (strstr (name
, ".rs"))
1383 else if (strstr (name
, ".mc"))
1385 else if (strstr (name
, ".it"))
1387 else if (strstr (name
, ".id"))
1389 else if (strstr (name
, ".da"))
1391 else if (strstr (name
, ".dd"))
1393 else if (strstr (name
, ".ss"))
1395 else if (strstr (name
, ".ri"))
1397 else if (strstr (name
, ".ed"))
1399 else if (strstr (name
, ".bn"))
1401 else if (strstr (name
, ".ia"))
1412 lookup_specifier (const char *name
)
1414 if (strchr (name
, '%'))
1416 if (strstr (name
, "AR[K%]") != NULL
)
1417 return IA64_RS_AR_K
;
1418 if (strstr (name
, "AR[UNAT]") != NULL
)
1419 return IA64_RS_AR_UNAT
;
1420 if (strstr (name
, "AR%, % in 8") != NULL
)
1422 if (strstr (name
, "AR%, % in 48") != NULL
)
1424 if (strstr (name
, "BR%") != NULL
)
1426 if (strstr (name
, "CR[IRR%]") != NULL
)
1427 return IA64_RS_CR_IRR
;
1428 if (strstr (name
, "CR[LRR%]") != NULL
)
1429 return IA64_RS_CR_LRR
;
1430 if (strstr (name
, "CR%") != NULL
)
1432 if (strstr (name
, "FR%, % in 0") != NULL
)
1434 if (strstr (name
, "FR%, % in 2") != NULL
)
1436 if (strstr (name
, "GR%") != NULL
)
1438 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1440 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1443 warn (_("don't know how to specify %% dependency %s\n"),
1446 else if (strchr (name
, '#'))
1448 if (strstr (name
, "CPUID#") != NULL
)
1449 return IA64_RS_CPUID
;
1450 if (strstr (name
, "DBR#") != NULL
)
1452 if (strstr (name
, "IBR#") != NULL
)
1454 if (strstr (name
, "MSR#") != NULL
)
1456 if (strstr (name
, "PKR#") != NULL
)
1458 if (strstr (name
, "PMC#") != NULL
)
1460 if (strstr (name
, "PMD#") != NULL
)
1462 if (strstr (name
, "RR#") != NULL
)
1465 warn (_("Don't know how to specify # dependency %s\n"),
1468 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1469 return IA64_RS_AR_FPSR
;
1470 else if (strncmp (name
, "AR[", 3) == 0)
1472 else if (strncmp (name
, "CR[", 3) == 0)
1474 else if (strncmp (name
, "PSR.", 4) == 0)
1476 else if (strcmp (name
, "InService*") == 0)
1477 return IA64_RS_INSERVICE
;
1478 else if (strcmp (name
, "GR0") == 0)
1480 else if (strcmp (name
, "CFM") == 0)
1482 else if (strcmp (name
, "PR63") == 0)
1483 return IA64_RS_PR63
;
1484 else if (strcmp (name
, "RSE") == 0)
1491 print_dependency_table ()
1497 for (i
=0;i
< iclen
;i
++)
1499 if (ics
[i
]->is_class
)
1503 if (ics
[i
]->comment
)
1504 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1505 ics
[i
]->name
, ics
[i
]->comment
);
1507 warn (_("IC:%s has no terminals or sub-classes\n"),
1513 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1515 if (ics
[i
]->comment
)
1516 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1517 ics
[i
]->name
, ics
[i
]->comment
);
1519 warn (_("no insns mapped directly to terminal IC %s\n"),
1525 for (i
= 0; i
< iclen
; i
++)
1529 mark_used (ics
[i
], 1);
1530 warn (_("class %s is defined but not used\n"),
1536 for (i
= 0; i
< rdepslen
; i
++)
1538 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1540 if (rdeps
[i
]->total_chks
== 0)
1541 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1542 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1543 rdeps
[i
]->total_regs
? "" : " or regs");
1544 else if (rdeps
[i
]->total_regs
== 0)
1545 warn (_("rsrc %s (%s) has no regs\n"),
1546 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1550 /* The dependencies themselves. */
1551 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1552 for (i
= 0; i
< rdepslen
; i
++)
1554 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1556 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1557 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1559 printf (" { \"%s\", %d, %d, %d, %d, ",
1560 rdeps
[i
]->name
, specifier
,
1561 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1562 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1563 printf ("\"%s\", ", rdeps
[i
]->extra
);
1570 /* And dependency lists. */
1571 for (i
=0;i
< dlistlen
;i
++)
1574 printf ("static const unsigned short dep%d[] = {\n ", i
);
1575 for (j
=0;j
< dlists
[i
]->len
; j
++)
1577 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1584 printf ("\n};\n\n");
1587 /* And opcode dependency list. */
1588 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1589 printf ("static const struct ia64_opcode_dependency\n");
1590 printf ("op_dependencies[] = {\n");
1591 for (i
= 0; i
< opdeplen
; i
++)
1594 if (opdeps
[i
]->chk
== -1)
1595 printf ("0, NULL, ");
1597 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1598 if (opdeps
[i
]->reg
== -1)
1599 printf ("0, NULL, ");
1601 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1608 /* Add STR to the string table. */
1609 static struct string_entry
*
1610 insert_string (char *str
)
1612 int start
= 0, end
= strtablen
;
1615 if (strtablen
== strtabtotlen
)
1618 string_table
= (struct string_entry
**)
1619 xrealloc (string_table
,
1620 sizeof (struct string_entry
**) * strtabtotlen
);
1626 string_table
[0] = tmalloc (struct string_entry
);
1627 string_table
[0]->s
= xstrdup (str
);
1628 string_table
[0]->num
= 0;
1629 return string_table
[0];
1632 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1634 else if (strcmp (str
, string_table
[0]->s
) < 0)
1642 i
= (start
+ end
) / 2;
1643 c
= strcmp (str
, string_table
[i
]->s
);
1648 return string_table
[i
];
1657 for (; i
> 0 && i
< strtablen
; i
--)
1658 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1661 for (; i
< strtablen
; i
++)
1662 if (strcmp (str
, string_table
[i
]->s
) < 0)
1665 for (x
= strtablen
- 1; x
>= i
; x
--)
1667 string_table
[x
+ 1] = string_table
[x
];
1668 string_table
[x
+ 1]->num
= x
+ 1;
1671 string_table
[i
] = tmalloc (struct string_entry
);
1672 string_table
[i
]->s
= xstrdup (str
);
1673 string_table
[i
]->num
= i
;
1676 return string_table
[i
];
1679 static struct bittree
*
1680 make_bittree_entry (void)
1682 struct bittree
*res
= tmalloc (struct bittree
);
1685 res
->bits
[0] = NULL
;
1686 res
->bits
[1] = NULL
;
1687 res
->bits
[2] = NULL
;
1689 res
->bits_to_skip
= 0;
1694 static struct disent
*
1695 add_dis_table_ent (which
, insn
, order
, completer_index
)
1696 struct disent
*which
;
1699 int completer_index
;
1709 while (ent
->nexte
!= NULL
)
1712 ent
= (ent
->nexte
= tmalloc (struct disent
));
1716 ent
= tmalloc (struct disent
);
1717 ent
->next_ent
= disinsntable
;
1724 ent
->priority
= order
;
1726 while (completer_index
!= 1)
1728 ci
= (ci
<< 1) | (completer_index
& 1);
1729 completer_index
>>= 1;
1731 ent
->completer_index
= ci
;
1738 struct disent
*ent
= disinsntable
;
1739 struct disent
*prev
= ent
;
1741 ent
->ournum
= 32768;
1742 while ((ent
= ent
->next_ent
) != NULL
)
1744 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1750 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1751 opcodenum
, order
, completer_index
)
1752 struct bittree
*curr_ent
;
1758 int completer_index
;
1762 struct bittree
*next
;
1766 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1769 curr_ent
->disent
= nent
;
1773 m
= ((ia64_insn
) 1) << bit
;
1776 b
= (opcode
& m
) ? 1 : 0;
1780 next
= curr_ent
->bits
[b
];
1783 next
= make_bittree_entry ();
1784 curr_ent
->bits
[b
] = next
;
1786 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1791 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1792 struct bittree
*first
;
1796 struct completer_entry
*ent
;
1797 int completer_index
;
1799 if (completer_index
& (1 << 20))
1804 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1805 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1806 (completer_index
<< 1) | 1);
1808 if (ent
->is_terminal
)
1810 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1811 opcodenum
, opcode_count
- ent
->order
- 1,
1812 (completer_index
<< 1) | 1);
1814 completer_index
<<= 1;
1815 ent
= ent
->alternative
;
1819 /* This optimization pass combines multiple "don't care" nodes. */
1821 compact_distree (ent
)
1822 struct bittree
*ent
;
1824 #define IS_SKIP(ent) \
1825 ((ent->bits[2] !=NULL) \
1826 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1829 struct bittree
*nent
= ent
;
1832 while (IS_SKIP (nent
))
1835 nent
= nent
->bits
[2];
1840 struct bittree
*next
= ent
->bits
[2];
1842 ent
->bits
[0] = nent
->bits
[0];
1843 ent
->bits
[1] = nent
->bits
[1];
1844 ent
->bits
[2] = nent
->bits
[2];
1845 ent
->disent
= nent
->disent
;
1847 ent
->bits_to_skip
= bitcnt
;
1848 while (next
!= nent
)
1850 struct bittree
*b
= next
;
1851 next
= next
->bits
[2];
1857 for (x
= 0; x
< 3; x
++)
1859 struct bittree
*i
= ent
->bits
[x
];
1862 compact_distree (i
);
1866 static unsigned char *insn_list
;
1867 static int insn_list_len
= 0;
1868 static int tot_insn_list_len
= 0;
1870 /* Generate the disassembler state machine corresponding to the tree
1874 struct bittree
*ent
;
1877 int our_offset
= insn_list_len
;
1879 int totbits
= bitsused
;
1882 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1884 /* If this is a terminal entry, there's no point in skipping any
1886 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1887 ent
->bits
[2] == NULL
)
1889 if (ent
->disent
== NULL
)
1895 /* Calculate the amount of space needed for this entry, or at least
1896 a conservatively large approximation. */
1900 for (x
= 1; x
< 3; x
++)
1901 if (ent
->bits
[x
] != NULL
)
1904 if (ent
->disent
!= NULL
)
1906 if (ent
->bits
[2] != NULL
)
1912 /* Now allocate the space. */
1913 needed_bytes
= (totbits
+ 7) / 8;
1914 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1916 tot_insn_list_len
+= 256;
1917 insn_list
= (unsigned char *) xrealloc (insn_list
, tot_insn_list_len
);
1919 our_offset
= insn_list_len
;
1920 insn_list_len
+= needed_bytes
;
1921 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1923 /* Encode the skip entry by setting bit 6 set in the state op field,
1924 and store the # of bits to skip immediately after. */
1928 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1929 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1932 #define IS_ONLY_IFZERO(ENT) \
1933 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1934 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1936 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1938 if (ent
->bits
[0] != NULL
)
1940 struct bittree
*nent
= ent
->bits
[0];
1943 insn_list
[our_offset
] |= 0x80;
1945 /* We can encode sequences of multiple "if (bit is zero)" tests
1946 by storing the # of zero bits to check in the lower 3 bits of
1947 the instruction. However, this only applies if the state
1948 solely tests for a zero bit. */
1950 if (IS_ONLY_IFZERO (ent
))
1952 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1954 nent
= nent
->bits
[0];
1958 insn_list
[our_offset
+ 0] |= zero_count
;
1960 zero_dest
= insn_list_len
;
1961 gen_dis_table (nent
);
1964 /* Now store the remaining tests. We also handle a sole "termination
1965 entry" by storing it as an "any bit" test. */
1967 for (x
= 1; x
< 3; x
++)
1969 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1971 struct bittree
*i
= ent
->bits
[x
];
1977 /* If the instruction being branched to only consists of
1978 a termination entry, use the termination entry as the
1979 place to branch to instead. */
1980 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1981 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1983 idest
= i
->disent
->ournum
;
1987 idest
= insn_list_len
- our_offset
;
1990 idest
= ent
->disent
->ournum
;
1992 /* If the destination offset for the if (bit is 1) test is less
1993 than 256 bytes away, we can store it as 8-bits instead of 16;
1994 the instruction has bit 5 set for the 16-bit address, and bit
1995 4 for the 8-bit address. Since we've already allocated 16
1996 bits for the address we need to deallocate the space.
1998 Note that branchings within the table are relative, and
1999 there are no branches that branch past our instruction yet
2000 so we do not need to adjust any other offsets. */
2005 int start
= our_offset
+ bitsused
/ 8 + 1;
2007 memmove (insn_list
+ start
,
2008 insn_list
+ start
+ 1,
2009 insn_list_len
- (start
+ 1));
2014 insn_list
[our_offset
] |= 0x10;
2018 insn_list
[our_offset
] |= 0x20;
2022 /* An instruction which solely consists of a termination
2023 marker and whose disassembly name index is < 4096
2024 can be stored in 16 bits. The encoding is slightly
2025 odd; the upper 4 bits of the instruction are 0x3, and
2026 bit 3 loses its normal meaning. */
2028 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2029 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2030 && ent
->disent
!= NULL
2031 && ent
->disent
->ournum
< (32768 + 4096))
2033 int start
= our_offset
+ bitsused
/ 8 + 1;
2035 memmove (insn_list
+ start
,
2036 insn_list
+ start
+ 1,
2037 insn_list_len
- (start
+ 1));
2043 insn_list
[our_offset
] |= 0x30;
2047 insn_list
[our_offset
] |= 0x08;
2056 else if (! (id
& 32768))
2060 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2062 printf ("%d: try %d\n", our_offset
, id
);
2065 /* Store the address of the entry being branched to. */
2066 while (currbits
>= 0)
2068 unsigned char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2070 if (idest
& (1 << currbits
))
2071 *byte
|= (1 << (7 - (bitsused
% 8)));
2077 /* Now generate the states for the entry being branched to. */
2086 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2088 if (ent
->bits
[0] != NULL
)
2089 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2093 if (bitsused
!= totbits
)
2098 print_dis_table (void)
2101 struct disent
*cent
= disinsntable
;
2103 printf ("static const char dis_table[] = {\n");
2104 for (x
= 0; x
< insn_list_len
; x
++)
2106 if ((x
> 0) && ((x
% 12) == 0))
2109 printf ("0x%02x, ", insn_list
[x
]);
2111 printf ("\n};\n\n");
2113 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2114 while (cent
!= NULL
)
2116 struct disent
*ent
= cent
;
2120 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2121 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2125 cent
= cent
->next_ent
;
2131 generate_disassembler (void)
2135 bittree
= make_bittree_entry ();
2137 for (i
= 0; i
< otlen
; i
++)
2139 struct main_entry
*ptr
= ordered_table
[i
];
2141 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2142 add_dis_entry (bittree
,
2143 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2145 ptr
->completers
, 1);
2148 compact_distree (bittree
);
2150 gen_dis_table (bittree
);
2156 print_string_table (void)
2159 char lbuf
[80], buf
[80];
2162 printf ("static const char * const ia64_strings[] = {\n");
2165 for (x
= 0; x
< strtablen
; x
++)
2169 if (strlen (string_table
[x
]->s
) > 75)
2172 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2175 if ((blen
+ len
) > 75)
2177 printf (" %s\n", lbuf
);
2186 printf (" %s\n", lbuf
);
2191 static struct completer_entry
**glist
;
2192 static int glistlen
= 0;
2193 static int glisttotlen
= 0;
2195 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2198 completer_entries_eq (ent1
, ent2
)
2199 struct completer_entry
*ent1
, *ent2
;
2201 while (ent1
!= NULL
&& ent2
!= NULL
)
2203 if (ent1
->name
->num
!= ent2
->name
->num
2204 || ent1
->bits
!= ent2
->bits
2205 || ent1
->mask
!= ent2
->mask
2206 || ent1
->is_terminal
!= ent2
->is_terminal
2207 || ent1
->dependencies
!= ent2
->dependencies
2208 || ent1
->order
!= ent2
->order
)
2211 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2214 ent1
= ent1
->alternative
;
2215 ent2
= ent2
->alternative
;
2218 return ent1
== ent2
;
2221 /* Insert ENT into the global list of completers and return it. If an
2222 equivalent entry (according to completer_entries_eq) already exists,
2223 it is returned instead. */
2224 static struct completer_entry
*
2225 insert_gclist (struct completer_entry
*ent
)
2233 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2234 ent
->alternative
= insert_gclist (ent
->alternative
);
2239 if (glisttotlen
== glistlen
)
2242 glist
= (struct completer_entry
**)
2243 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2253 if (ent
->name
->num
< glist
[0]->name
->num
)
2255 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2263 i
= (start
+ end
) / 2;
2264 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2271 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2285 while (i
< glistlen
)
2287 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2290 if (completer_entries_eq (ent
, glist
[i
]))
2298 for (; i
> 0 && i
< glistlen
; i
--)
2299 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2302 for (; i
< glistlen
; i
++)
2303 if (ent
->name
->num
< glist
[i
]->name
->num
)
2306 for (x
= glistlen
- 1; x
>= i
; x
--)
2307 glist
[x
+ 1] = glist
[x
];
2316 get_prefix_len (name
)
2321 if (name
[0] == '\0')
2324 c
= strchr (name
, '.');
2328 return strlen (name
);
2332 compute_completer_bits (ment
, ent
)
2333 struct main_entry
*ment
;
2334 struct completer_entry
*ent
;
2338 compute_completer_bits (ment
, ent
->addl_entries
);
2340 if (ent
->is_terminal
)
2343 ia64_insn our_bits
= ent
->bits
;
2344 struct completer_entry
*p
= ent
->parent
;
2348 while (p
!= NULL
&& ! p
->is_terminal
)
2354 p_bits
= ment
->opcode
->opcode
;
2356 for (x
= 0; x
< 64; x
++)
2358 ia64_insn m
= ((ia64_insn
) 1) << x
;
2360 if ((p_bits
& m
) != (our_bits
& m
))
2365 ent
->bits
= our_bits
;
2374 ent
= ent
->alternative
;
2378 /* Find identical completer trees that are used in different
2379 instructions and collapse their entries. */
2381 collapse_redundant_completers (void)
2383 struct main_entry
*ptr
;
2386 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2388 if (ptr
->completers
== NULL
)
2391 compute_completer_bits (ptr
, ptr
->completers
);
2392 ptr
->completers
= insert_gclist (ptr
->completers
);
2395 /* The table has been finalized, now number the indexes. */
2396 for (x
= 0; x
< glistlen
; x
++)
2401 /* Attach two lists of dependencies to each opcode.
2402 1) all resources which, when already marked in use, conflict with this
2404 2) all resources which must be marked in use when this opcode is used
2407 insert_opcode_dependencies (opc
, cmp
)
2408 struct ia64_opcode
*opc
;
2409 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2411 /* Note all resources which point to this opcode. rfi has the most chks
2412 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2415 unsigned short regs
[256];
2417 unsigned short chks
[256];
2418 /* Flag insns for which no class matched; there should be none. */
2419 int no_class_found
= 1;
2421 for (i
= 0; i
< rdepslen
; i
++)
2423 struct rdep
*rs
= rdeps
[i
];
2426 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2427 && strncmp (rs
->name
, "PR%", 3) == 0
2429 no_class_found
= 99;
2431 for (j
=0; j
< rs
->nregs
;j
++)
2435 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2437 /* We can ignore ic_note 11 for non PR resources. */
2438 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2441 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2442 && ic_note
!= rs
->regnotes
[j
]
2443 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2444 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2445 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2446 rs
->name
, rs
->regnotes
[j
]);
2447 /* Instruction class notes override resource notes.
2448 So far, only note 11 applies to an IC instead of a resource,
2449 and note 11 implies note 1. */
2451 regs
[nregs
++] = RDEP(ic_note
, i
);
2453 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2459 for (j
= 0; j
< rs
->nchks
; j
++)
2463 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2465 /* We can ignore ic_note 11 for non PR resources. */
2466 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2469 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2470 && ic_note
!= rs
->chknotes
[j
]
2471 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2472 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2473 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2474 rs
->name
, rs
->chknotes
[j
]);
2476 chks
[nchks
++] = RDEP(ic_note
, i
);
2478 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2486 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2488 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2490 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2494 insert_completer_entry (opc
, tabent
, order
)
2495 struct ia64_opcode
*opc
;
2496 struct main_entry
*tabent
;
2499 struct completer_entry
**ptr
= &tabent
->completers
;
2500 struct completer_entry
*parent
= NULL
;
2501 char pcopy
[129], *prefix
;
2504 if (strlen (opc
->name
) > 128)
2507 strcpy (pcopy
, opc
->name
);
2508 prefix
= pcopy
+ get_prefix_len (pcopy
);
2510 if (prefix
[0] != '\0')
2515 int need_new_ent
= 1;
2516 int plen
= get_prefix_len (prefix
);
2517 struct string_entry
*sent
;
2519 at_end
= (prefix
[plen
] == '\0');
2520 prefix
[plen
] = '\0';
2521 sent
= insert_string (prefix
);
2523 while (*ptr
!= NULL
)
2525 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2533 ptr
= &((*ptr
)->alternative
);
2538 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2541 nent
->parent
= parent
;
2542 nent
->addl_entries
= NULL
;
2543 nent
->alternative
= *ptr
;
2545 nent
->is_terminal
= 0;
2546 nent
->dependencies
= -1;
2552 ptr
= &((*ptr
)->addl_entries
);
2557 if ((*ptr
)->is_terminal
)
2560 (*ptr
)->is_terminal
= 1;
2561 (*ptr
)->mask
= (ia64_insn
)-1;
2562 (*ptr
)->bits
= opc
->opcode
;
2563 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2564 (*ptr
)->order
= order
;
2568 print_completer_entry (ent
)
2569 struct completer_entry
*ent
;
2572 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2576 while (! (mask
& 1))
2583 if (bits
& 0xffffffff00000000LL
)
2587 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2591 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2592 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2594 ent
->is_terminal
? 1 : 0,
2599 print_completer_table ()
2603 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2604 for (x
= 0; x
< glistlen
; x
++)
2605 print_completer_entry (glist
[x
]);
2610 opcodes_eq (opc1
, opc2
)
2611 struct ia64_opcode
*opc1
;
2612 struct ia64_opcode
*opc2
;
2617 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2618 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2619 || (opc1
->flags
!= opc2
->flags
))
2622 for (x
= 0; x
< 5; x
++)
2623 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2626 plen1
= get_prefix_len (opc1
->name
);
2627 plen2
= get_prefix_len (opc2
->name
);
2629 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2636 add_opcode_entry (opc
)
2637 struct ia64_opcode
*opc
;
2639 struct main_entry
**place
;
2640 struct string_entry
*name
;
2644 if (strlen (opc
->name
) > 128)
2648 strcpy (prefix
, opc
->name
);
2649 prefix
[get_prefix_len (prefix
)] = '\0';
2650 name
= insert_string (prefix
);
2652 /* Walk the list of opcode table entries. If it's a new
2653 instruction, allocate and fill in a new entry. Note
2654 the main table is alphabetical by opcode name. */
2656 while (*place
!= NULL
)
2658 if ((*place
)->name
->num
== name
->num
2659 && opcodes_eq ((*place
)->opcode
, opc
))
2664 if ((*place
)->name
->num
> name
->num
)
2667 place
= &((*place
)->next
);
2671 struct main_entry
*nent
= tmalloc (struct main_entry
);
2675 nent
->next
= *place
;
2676 nent
->completers
= 0;
2679 if (otlen
== ottotlen
)
2682 ordered_table
= (struct main_entry
**)
2683 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2685 ordered_table
[otlen
++] = nent
;
2688 insert_completer_entry (opc
, *place
, opcode_count
++);
2692 print_main_table (void)
2694 struct main_entry
*ptr
= maintable
;
2697 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2700 printf (" { %d, %d, %d, 0x",
2703 ptr
->opcode
->num_outputs
);
2704 fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2706 fprintf_vma (stdout
, ptr
->opcode
->mask
);
2707 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2708 ptr
->opcode
->operands
[0],
2709 ptr
->opcode
->operands
[1],
2710 ptr
->opcode
->operands
[2],
2711 ptr
->opcode
->operands
[3],
2712 ptr
->opcode
->operands
[4],
2714 ptr
->completers
->num
);
2716 ptr
->main_index
= index
++;
2725 struct ia64_opcode
*table
;
2729 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2731 add_opcode_entry (table
+ curr_opcode
);
2732 if (table
[curr_opcode
].num_outputs
== 2
2733 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2734 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2735 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2736 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2738 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2741 *alias
= table
[curr_opcode
];
2742 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2743 alias
->operands
[i
- 1] = alias
->operands
[i
];
2744 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2745 --alias
->num_outputs
;
2746 alias
->flags
|= PSEUDO
;
2747 add_opcode_entry (alias
);
2753 /* Program options. */
2754 #define OPTION_SRCDIR 200
2756 struct option long_options
[] =
2758 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2759 {"debug", no_argument
, NULL
, 'd'},
2760 {"version", no_argument
, NULL
, 'V'},
2761 {"help", no_argument
, NULL
, 'h'},
2762 {0, no_argument
, NULL
, 0}
2766 print_version (void)
2768 printf ("%s: version 1.0\n", program_name
);
2773 usage (FILE * stream
, int status
)
2775 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2781 main (int argc
, char **argv
)
2783 extern int chdir (char *);
2784 char *srcdir
= NULL
;
2787 program_name
= *argv
;
2788 xmalloc_set_program_name (program_name
);
2790 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2815 if (chdir (srcdir
) != 0)
2816 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2817 srcdir
, strerror (errno
));
2819 load_insn_classes ();
2820 load_dependencies ();
2822 shrink (ia64_opcodes_a
);
2823 shrink (ia64_opcodes_b
);
2824 shrink (ia64_opcodes_f
);
2825 shrink (ia64_opcodes_i
);
2826 shrink (ia64_opcodes_m
);
2827 shrink (ia64_opcodes_x
);
2828 shrink (ia64_opcodes_d
);
2830 collapse_redundant_completers ();
2832 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2833 print_string_table ();
2834 print_dependency_table ();
2835 print_completer_table ();
2836 print_main_table ();
2838 generate_disassembler ();