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 NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
60 #define tmalloc(X) (X *) xmalloc (sizeof (X))
62 /* The main opcode table entry. Each entry is a unique combination of
63 name and flags (no two entries in the table compare as being equal
67 /* The base name of this opcode. The names of its completers are
68 appended to it to generate the full instruction name. */
69 struct string_entry
*name
;
70 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
71 it uses the first one passed to add_opcode_entry. */
72 struct ia64_opcode
*opcode
;
73 /* The list of completers that can be applied to this opcode. */
74 struct completer_entry
*completers
;
75 /* Next entry in the chain. */
76 struct main_entry
*next
;
77 /* Index in the main table. */
79 } *maintable
, **ordered_table
;
85 /* The set of possible completers for an opcode. */
86 struct completer_entry
88 /* This entry's index in the ia64_completer_table[] array. */
91 /* The name of the completer. */
92 struct string_entry
*name
;
94 /* This entry's parent. */
95 struct completer_entry
*parent
;
97 /* Set if this is a terminal completer (occurs at the end of an
101 /* An alternative completer. */
102 struct completer_entry
*alternative
;
104 /* Additional completers that can be appended to this one. */
105 struct completer_entry
*addl_entries
;
107 /* Before compute_completer_bits () is invoked, this contains the actual
108 instruction opcode for this combination of opcode and completers.
109 Afterwards, it contains those bits that are different from its
113 /* Bits set to 1 correspond to those bits in this completer's opcode
114 that are different from its parent completer's opcode (or from
115 the base opcode if the entry is the root of the opcode's completer
116 list). This field is filled in by compute_completer_bits (). */
119 /* Index into the opcode dependency list, or -1 if none. */
122 /* Remember the order encountered in the opcode tables. */
126 /* One entry in the disassembler name table. */
129 /* The index into the ia64_name_dis array for this entry. */
132 /* The index into the main_table[] array. */
135 /* The disassmbly priority of this entry. */
138 /* The completer_index value for this entry. */
141 /* How many other entries share this decode. */
144 /* The next entry sharing the same decode. */
145 struct disent
*nexte
;
147 /* The next entry in the name list. */
148 struct disent
*next_ent
;
149 } *disinsntable
= NULL
;
151 /* A state machine that will eventually be used to generate the
152 disassembler table. */
155 struct disent
*disent
;
156 struct bittree
*bits
[3]; /* 0, 1, and X (don't care). */
161 /* The string table contains all opcodes and completers sorted in
162 alphabetical order. */
164 /* One entry in the string table. */
167 /* The index in the ia64_strings[] array for this entry. */
169 /* And the string. */
171 } **string_table
= NULL
;
174 int strtabtotlen
= 0;
177 /* Resource dependency entries. */
180 char *name
; /* Resource name. */
182 mode
:2, /* RAW, WAW, or WAR. */
183 semantics
:3; /* Dependency semantics. */
184 char *extra
; /* Additional semantics info. */
186 int total_chks
; /* Total #of terminal insns. */
187 int *chks
; /* Insn classes which read (RAW), write
188 (WAW), or write (WAR) this rsrc. */
189 int *chknotes
; /* Dependency notes for each class. */
191 int total_regs
; /* Total #of terminal insns. */
192 int *regs
; /* Insn class which write (RAW), write2
193 (WAW), or read (WAR) this rsrc. */
194 int *regnotes
; /* Dependency notes for each class. */
196 int waw_special
; /* Special WAW dependency note. */
199 static int rdepslen
= 0;
200 static int rdepstotlen
= 0;
202 /* Array of all instruction classes. */
205 char *name
; /* Instruction class name. */
206 int is_class
; /* Is a class, not a terminal. */
208 int *subs
; /* Other classes within this class. */
210 int xsubs
[4]; /* Exclusions. */
211 char *comment
; /* Optional comment. */
212 int note
; /* Optional note. */
213 int terminal_resolved
; /* Did we match this with anything? */
214 int orphan
; /* Detect class orphans. */
217 static int iclen
= 0;
218 static int ictotlen
= 0;
220 /* An opcode dependency (chk/reg pair of dependency lists). */
223 int chk
; /* index into dlists */
224 int reg
; /* index into dlists */
227 static int opdeplen
= 0;
228 static int opdeptotlen
= 0;
230 /* A generic list of dependencies w/notes encoded. These may be shared. */
234 unsigned short *deps
;
237 static int dlistlen
= 0;
238 static int dlisttotlen
= 0;
241 static void fail (const char *, ...);
242 static void warn (const char *, ...);
243 static struct rdep
* insert_resource (const char *, enum ia64_dependency_mode
);
244 static int deplist_equals (struct deplist
*, struct deplist
*);
245 static short insert_deplist (int, unsigned short *);
246 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
247 static void mark_used (struct iclass
*, int);
248 static int fetch_insn_class (const char *, int);
249 static int sub_compare (const void *, const void *);
250 static void load_insn_classes (void);
251 static void parse_resource_users (const char *, int **, int *, int **);
252 static int parse_semantics (char *);
253 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
254 static void load_depfile (const char *, enum ia64_dependency_mode
);
255 static void load_dependencies (void);
256 static int irf_operand (int, const char *);
257 static int in_iclass_mov_x (struct ia64_opcode
*, struct iclass
*, const char *, const char *);
258 static int in_iclass (struct ia64_opcode
*, struct iclass
*, const char *, const char *, int *);
259 static int lookup_regindex (const char *, int);
260 static int lookup_specifier (const char *);
261 static void print_dependency_table (void);
262 static struct string_entry
* insert_string (char *);
263 static void gen_dis_table (struct bittree
*);
264 static void print_dis_table (void);
265 static void generate_disassembler (void);
266 static void print_string_table (void);
267 static int completer_entries_eq (struct completer_entry
*, struct completer_entry
*);
268 static struct completer_entry
* insert_gclist (struct completer_entry
*);
269 static int get_prefix_len (const char *);
270 static void compute_completer_bits (struct main_entry
*, struct completer_entry
*);
271 static void collapse_redundant_completers (void);
272 static int insert_opcode_dependencies (struct ia64_opcode
*, struct completer_entry
*);
273 static void insert_completer_entry (struct ia64_opcode
*, struct main_entry
*, int);
274 static void print_completer_entry (struct completer_entry
*);
275 static void print_completer_table (void);
276 static int opcodes_eq (struct ia64_opcode
*, struct ia64_opcode
*);
277 static void add_opcode_entry (struct ia64_opcode
*);
278 static void print_main_table (void);
279 static void shrink (struct ia64_opcode
*);
280 static void print_version (void);
281 static void usage (FILE *, int);
282 static void finish_distable (void);
283 static void insert_bit_table_ent (struct bittree
*, int, ia64_insn
, ia64_insn
, int, int, int);
284 static void add_dis_entry (struct bittree
*, ia64_insn
, ia64_insn
, int, struct completer_entry
*, int);
285 static void compact_distree (struct bittree
*);
286 static struct bittree
* make_bittree_entry (void);
287 static struct disent
* add_dis_table_ent (struct disent
*, int, int, int);
291 fail (const char *message
, ...)
295 va_start (args
, message
);
296 fprintf (stderr
, _("%s: Error: "), program_name
);
297 vfprintf (stderr
, message
, args
);
303 warn (const char *message
, ...)
307 va_start (args
, message
);
309 fprintf (stderr
, _("%s: Warning: "), program_name
);
310 vfprintf (stderr
, message
, args
);
314 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
316 insert_resource (const char *name
, enum ia64_dependency_mode type
)
318 if (rdepslen
== rdepstotlen
)
321 rdeps
= (struct rdep
**)
322 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
324 rdeps
[rdepslen
] = tmalloc(struct rdep
);
325 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
326 rdeps
[rdepslen
]->name
= xstrdup (name
);
327 rdeps
[rdepslen
]->mode
= type
;
328 rdeps
[rdepslen
]->waw_special
= 0;
330 return rdeps
[rdepslen
++];
333 /* Are the lists of dependency indexes equivalent? */
335 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
339 if (d1
->len
!= d2
->len
)
342 for (i
= 0; i
< d1
->len
; i
++)
343 if (d1
->deps
[i
] != d2
->deps
[i
])
349 /* Add the list of dependencies to the list of dependency lists. */
351 insert_deplist (int count
, unsigned short *deps
)
353 /* Sort the list, then see if an equivalent list exists already.
354 this results in a much smaller set of dependency lists. */
355 struct deplist
*list
;
359 memset ((void *)set
, 0, sizeof (set
));
360 for (i
= 0; i
< count
; i
++)
364 for (i
= 0; i
< (int) sizeof (set
); i
++)
368 list
= tmalloc (struct deplist
);
370 list
->deps
= (unsigned short *) malloc (sizeof (unsigned short) * count
);
372 for (i
= 0, count
= 0; i
< (int) sizeof (set
); i
++)
374 list
->deps
[count
++] = i
;
376 /* Does this list exist already? */
377 for (i
= 0; i
< dlistlen
; i
++)
378 if (deplist_equals (list
, dlists
[i
]))
385 if (dlistlen
== dlisttotlen
)
388 dlists
= (struct deplist
**)
389 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
391 dlists
[dlistlen
] = list
;
396 /* Add the given pair of dependency lists to the opcode dependency list. */
398 insert_dependencies (int nchks
, unsigned short *chks
,
399 int nregs
, unsigned short *regs
)
407 regind
= insert_deplist (nregs
, regs
);
409 chkind
= insert_deplist (nchks
, chks
);
411 for (i
= 0; i
< opdeplen
; i
++)
412 if (opdeps
[i
]->chk
== chkind
413 && opdeps
[i
]->reg
== regind
)
416 pair
= tmalloc (struct opdep
);
420 if (opdeplen
== opdeptotlen
)
423 opdeps
= (struct opdep
**)
424 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
426 opdeps
[opdeplen
] = pair
;
432 mark_used (struct iclass
*ic
, int clear_terminals
)
438 ic
->terminal_resolved
= 1;
440 for (i
= 0; i
< ic
->nsubs
; i
++)
441 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
443 for (i
= 0; i
< ic
->nxsubs
; i
++)
444 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
447 /* Look up an instruction class; if CREATE make a new one if none found;
448 returns the index into the insn class array. */
450 fetch_insn_class (const char *full_name
, int create
)
460 if (strncmp (full_name
, "IC:", 3) == 0)
462 name
= xstrdup (full_name
+ 3);
466 name
= xstrdup (full_name
);
468 if ((xsect
= strchr(name
, '\\')) != NULL
)
470 if ((comment
= strchr(name
, '[')) != NULL
)
472 if ((notestr
= strchr(name
, '+')) != NULL
)
475 /* If it is a composite class, then ignore comments and notes that come after
476 the '\\', since they don't apply to the part we are decoding now. */
489 note
= atoi (notestr
+ 1);
490 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
492 if (strcmp (notestr
, "+1+13") == 0)
494 else if (!xsect
|| nextnotestr
< xsect
)
495 warn (_("multiple note %s not handled\n"), notestr
);
499 /* If it's a composite class, leave the notes and comments in place so that
500 we have a unique name for the composite class. Otherwise, we remove
510 for (i
= 0; i
< iclen
; i
++)
511 if (strcmp (name
, ics
[i
]->name
) == 0
512 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
513 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
514 && strncmp (ics
[i
]->comment
, comment
,
515 strlen (ics
[i
]->comment
)) == 0))
516 && note
== ics
[i
]->note
)
522 /* Doesn't exist, so make a new one. */
523 if (iclen
== ictotlen
)
526 ics
= (struct iclass
**)
527 xrealloc (ics
, (ictotlen
) * sizeof (struct iclass
*));
531 ics
[ind
] = tmalloc (struct iclass
);
532 memset ((void *)ics
[ind
], 0, sizeof (struct iclass
));
533 ics
[ind
]->name
= xstrdup (name
);
534 ics
[ind
]->is_class
= is_class
;
535 ics
[ind
]->orphan
= 1;
539 ics
[ind
]->comment
= xstrdup (comment
+ 1);
540 ics
[ind
]->comment
[strlen (ics
[ind
]->comment
)-1] = 0;
544 ics
[ind
]->note
= note
;
546 /* If it's a composite class, there's a comment or note, look for an
547 existing class or terminal with the same name. */
548 if ((xsect
|| comment
|| notestr
) && is_class
)
550 /* First, populate with the class we're based on. */
551 char *subname
= name
;
561 ics
[ind
]->subs
= tmalloc(int);
562 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
567 char *subname
= xsect
+ 1;
569 xsect
= strchr (subname
, '\\');
572 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
580 /* For sorting a class's sub-class list only; make sure classes appear before
583 sub_compare (const void *e1
, const void *e2
)
585 struct iclass
*ic1
= ics
[*(int *)e1
];
586 struct iclass
*ic2
= ics
[*(int *)e2
];
593 else if (ic2
->is_class
)
596 return strcmp (ic1
->name
, ic2
->name
);
600 load_insn_classes (void)
602 FILE *fp
= fopen ("ia64-ic.tbl", "r");
606 fail (_("can't find ia64-ic.tbl for reading\n"));
608 /* Discard first line. */
609 fgets (buf
, sizeof(buf
), fp
);
617 if (fgets (buf
, sizeof (buf
), fp
) == NULL
)
620 while (ISSPACE (buf
[strlen (buf
) - 1]))
621 buf
[strlen (buf
) - 1] = '\0';
627 if (tmp
== buf
+ sizeof (buf
))
632 iclass
= fetch_insn_class (name
, 1);
633 ics
[iclass
]->is_class
= 1;
635 if (strcmp (name
, "none") == 0)
637 ics
[iclass
]->is_class
= 0;
638 ics
[iclass
]->terminal_resolved
= 1;
642 /* For this class, record all sub-classes. */
648 while (*tmp
&& ISSPACE (*tmp
))
651 if (tmp
== buf
+ sizeof (buf
))
655 while (*tmp
&& *tmp
!= ',')
658 if (tmp
== buf
+ sizeof (buf
))
664 ics
[iclass
]->subs
= (int *)
665 xrealloc ((void *)ics
[iclass
]->subs
,
666 (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
668 sub
= fetch_insn_class (subname
, 1);
669 ics
[iclass
]->subs
= (int *)
670 xrealloc (ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+ 1) * sizeof (int));
671 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
674 /* Make sure classes come before terminals. */
675 qsort ((void *)ics
[iclass
]->subs
,
676 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
681 printf ("%d classes\n", iclen
);
684 /* Extract the insn classes from the given line. */
686 parse_resource_users (ref
, usersp
, nusersp
, notesp
)
693 char *line
= xstrdup (ref
);
695 int *users
= *usersp
;
696 int count
= *nusersp
;
697 int *notes
= *notesp
;
709 while (ISSPACE (*tmp
))
712 while (*tmp
&& *tmp
!= ',')
717 xsect
= strchr (name
, '\\');
718 if ((notestr
= strstr (name
, "+")) != NULL
)
722 note
= atoi (notestr
+ 1);
723 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
725 /* Note 13 always implies note 1. */
726 if (strcmp (notestr
, "+1+13") == 0)
728 else if (!xsect
|| nextnotestr
< xsect
)
729 warn (_("multiple note %s not handled\n"), notestr
);
737 /* All classes are created when the insn class table is parsed;
738 Individual instructions might not appear until the dependency tables
739 are read. Only create new classes if it's *not* an insn class,
740 or if it's a composite class (which wouldn't necessarily be in the IC
742 if (strncmp (name
, "IC:", 3) != 0 || xsect
!= NULL
)
745 iclass
= fetch_insn_class (name
, create
);
749 xrealloc ((void *) users
,(count
+ 1) * sizeof (int));
751 xrealloc ((void *) notes
,(count
+ 1) * sizeof (int));
753 users
[count
++] = iclass
;
754 mark_used (ics
[iclass
], 0);
757 printf("Class %s not found\n", name
);
759 /* Update the return values. */
768 parse_semantics (char *sem
)
770 if (strcmp (sem
, "none") == 0)
771 return IA64_DVS_NONE
;
772 else if (strcmp (sem
, "implied") == 0)
773 return IA64_DVS_IMPLIED
;
774 else if (strcmp (sem
, "impliedF") == 0)
775 return IA64_DVS_IMPLIEDF
;
776 else if (strcmp (sem
, "data") == 0)
777 return IA64_DVS_DATA
;
778 else if (strcmp (sem
, "instr") == 0)
779 return IA64_DVS_INSTR
;
780 else if (strcmp (sem
, "specific") == 0)
781 return IA64_DVS_SPECIFIC
;
782 else if (strcmp (sem
, "stop") == 0)
783 return IA64_DVS_STOP
;
785 return IA64_DVS_OTHER
;
789 add_dep (const char *name
, const char *chk
, const char *reg
,
790 int semantics
, int mode
, char *extra
, int flag
)
794 rs
= insert_resource (name
, mode
);
796 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
, &rs
->chknotes
);
797 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
, &rs
->regnotes
);
799 rs
->semantics
= semantics
;
801 rs
->waw_special
= flag
;
805 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
807 FILE *fp
= fopen (filename
, "r");
811 fail (_("can't find %s for reading\n"), filename
);
813 fgets (buf
, sizeof(buf
), fp
);
821 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
824 while (ISSPACE (buf
[strlen (buf
) - 1]))
825 buf
[strlen (buf
) - 1] = '\0';
832 while (ISSPACE (*tmp
))
835 tmp
= strchr (tmp
, ';');
839 while (ISSPACE (*tmp
))
842 tmp
= strchr (tmp
, ';');
846 while (ISSPACE (*tmp
))
848 semantics
= parse_semantics (tmp
);
849 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
851 /* For WAW entries, if the chks and regs differ, we need to enter the
852 entries in both positions so that the tables will be parsed properly,
853 without a lot of extra work. */
854 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
856 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
857 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
861 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
868 load_dependencies (void)
870 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
871 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
872 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
875 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
878 /* Is the given operand an indirect register file operand? */
880 irf_operand (int op
, const char *field
)
884 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
885 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
886 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
887 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
891 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
892 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
893 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
894 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
895 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
896 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
897 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
898 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
902 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
903 mov_um insn classes. */
905 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
906 const char *format
, const char *field
)
908 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
919 int i
= strcmp (idesc
->name
, "mov.i") == 0;
920 int m
= strcmp (idesc
->name
, "mov.m") == 0;
921 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
922 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
923 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
924 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
925 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
926 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
930 return strstr (format
, "I26") || strstr (format
, "I27");
932 return strstr (format
, "I28") != NULL
;
934 return strstr (format
, "M29") || strstr (format
, "M30");
936 return strstr (format
, "M31") != NULL
;
937 if (pseudo0
|| pseudo1
)
943 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
944 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
946 return strstr (format
, "I22") != NULL
;
948 return strstr (format
, "I21") != NULL
;
953 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
954 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
956 return strstr (format
, "M32") != NULL
;
958 return strstr (format
, "M33") != NULL
;
962 if (ic
->name
[5] == 'n')
964 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
965 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
967 return strstr (format
, "M42") != NULL
;
969 return strstr (format
, "M43") != NULL
;
971 else if (ic
->name
[5] == 'p')
973 return idesc
->operands
[1] == IA64_OPND_IP
;
979 if (ic
->name
[5] == 'r')
981 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
982 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
983 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
985 return strstr (format
, "I23") != NULL
;
987 return strstr (format
, "I24") != NULL
;
989 return strstr (format
, "I25") != NULL
;
991 else if (ic
->name
[5] == 's')
993 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
994 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
996 return strstr (format
, "M35") != NULL
;
998 return strstr (format
, "M36") != NULL
;
1005 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
1006 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
1008 return strstr (format
, "M35") != NULL
;
1010 return strstr (format
, "M36") != NULL
;
1017 /* Is the given opcode in the given insn class? */
1019 in_iclass (struct ia64_opcode
*idesc
, struct iclass
*ic
,
1020 const char *format
, const char *field
, int *notep
)
1027 if (!strncmp (ic
->comment
, "Format", 6))
1029 /* Assume that the first format seen is the most restrictive, and
1030 only keep a later one if it looks like it's more restrictive. */
1033 if (strlen (ic
->comment
) < strlen (format
))
1035 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1036 ic
->comment
, format
);
1037 format
= ic
->comment
;
1041 format
= ic
->comment
;
1043 else if (!strncmp (ic
->comment
, "Field", 5))
1046 warn (_("overlapping field %s->%s\n"),
1047 ic
->comment
, field
);
1048 field
= ic
->comment
;
1052 /* An insn class matches anything that is the same followed by completers,
1053 except when the absence and presence of completers constitutes different
1055 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
1057 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
1058 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
1059 int len
= strlen(ic
->name
);
1061 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
1062 && (idesc
->name
[len
] == '\0'
1063 || idesc
->name
[len
] == '.'));
1065 /* All break, nop, and hint variations must match exactly. */
1067 (strcmp (ic
->name
, "break") == 0
1068 || strcmp (ic
->name
, "nop") == 0
1069 || strcmp (ic
->name
, "hint") == 0))
1070 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
1072 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1073 unless specifically allowed by clauses in this block. */
1074 if (resolved
&& field
)
1076 /* Check Field(sf)==sN against opcode sN. */
1077 if (strstr(field
, "(sf)==") != NULL
)
1081 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1082 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1084 /* Check Field(lftype)==XXX. */
1085 else if (strstr (field
, "(lftype)") != NULL
)
1087 if (strstr (idesc
->name
, "fault") != NULL
)
1088 resolved
= strstr (field
, "fault") != NULL
;
1090 resolved
= strstr (field
, "fault") == NULL
;
1092 /* Handle Field(ctype)==XXX. */
1093 else if (strstr (field
, "(ctype)") != NULL
)
1095 if (strstr (idesc
->name
, "or.andcm"))
1096 resolved
= strstr (field
, "or.andcm") != NULL
;
1097 else if (strstr (idesc
->name
, "and.orcm"))
1098 resolved
= strstr (field
, "and.orcm") != NULL
;
1099 else if (strstr (idesc
->name
, "orcm"))
1100 resolved
= strstr (field
, "or orcm") != NULL
;
1101 else if (strstr (idesc
->name
, "or"))
1102 resolved
= strstr (field
, "or orcm") != NULL
;
1103 else if (strstr (idesc
->name
, "andcm"))
1104 resolved
= strstr (field
, "and andcm") != NULL
;
1105 else if (strstr (idesc
->name
, "and"))
1106 resolved
= strstr (field
, "and andcm") != NULL
;
1107 else if (strstr (idesc
->name
, "unc"))
1108 resolved
= strstr (field
, "unc") != NULL
;
1110 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1114 if (resolved
&& format
)
1116 if (strncmp (idesc
->name
, "dep", 3) == 0
1117 && strstr (format
, "I13") != NULL
)
1118 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1119 else if (strncmp (idesc
->name
, "chk", 3) == 0
1120 && strstr (format
, "M21") != NULL
)
1121 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1122 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1123 resolved
= (strstr (format
, "M14 M15") != NULL
1124 && (idesc
->operands
[1] == IA64_OPND_R2
1125 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1126 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1127 && strstr (format
, "B5") != NULL
)
1128 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1129 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1130 && strstr (format
, "B3") != NULL
)
1131 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1132 else if (strncmp (idesc
->name
, "brp", 3) == 0
1133 && strstr (format
, "B7") != NULL
)
1134 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1135 else if (strcmp (ic
->name
, "invala") == 0)
1136 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1137 else if (strncmp (idesc
->name
, "st", 2) == 0
1138 && (strstr (format
, "M5") != NULL
1139 || strstr (format
, "M10") != NULL
))
1140 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1141 else if (strncmp (idesc
->name
, "ld", 2) == 0
1142 && (strstr (format
, "M2 M3") != NULL
1143 || strstr (format
, "M12") != NULL
1144 || strstr (format
, "M7 M8") != NULL
))
1145 resolved
= idesc
->flags
& IA64_OPCODE_POSTINC
;
1150 /* Misc brl variations ('.cond' is optional);
1151 plain brl matches brl.cond. */
1153 && (strcmp (idesc
->name
, "brl") == 0
1154 || strncmp (idesc
->name
, "brl.", 4) == 0)
1155 && strcmp (ic
->name
, "brl.cond") == 0)
1160 /* Misc br variations ('.cond' is optional). */
1162 && (strcmp (idesc
->name
, "br") == 0
1163 || strncmp (idesc
->name
, "br.", 3) == 0)
1164 && strcmp (ic
->name
, "br.cond") == 0)
1167 resolved
= (strstr (format
, "B4") != NULL
1168 && idesc
->operands
[0] == IA64_OPND_B2
)
1169 || (strstr (format
, "B1") != NULL
1170 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1175 /* probe variations. */
1176 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1178 resolved
= strcmp (ic
->name
, "probe") == 0
1179 && !((strstr (idesc
->name
, "fault") != NULL
)
1180 ^ (format
&& strstr (format
, "M40") != NULL
));
1183 /* mov variations. */
1184 if (!resolved
&& is_mov
)
1188 /* mov alias for fmerge. */
1189 if (strcmp (ic
->name
, "fmerge") == 0)
1191 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1192 && idesc
->operands
[1] == IA64_OPND_F3
;
1194 /* mov alias for adds (r3 or imm14). */
1195 else if (strcmp (ic
->name
, "adds") == 0)
1197 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1198 && (idesc
->operands
[1] == IA64_OPND_R3
1199 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1201 /* mov alias for addl. */
1202 else if (strcmp (ic
->name
, "addl") == 0)
1204 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1205 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1209 /* Some variants of mov and mov.[im]. */
1210 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1211 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1214 /* Keep track of this so we can flag any insn classes which aren't
1215 mapped onto at least one real insn. */
1217 ic
->terminal_resolved
= 1;
1219 else for (i
= 0; i
< ic
->nsubs
; i
++)
1221 if (in_iclass (idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1225 for (j
= 0; j
< ic
->nxsubs
; j
++)
1226 if (in_iclass (idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1230 printf ("%s is in IC %s\n", idesc
->name
, ic
->name
);
1237 /* If it's in this IC, add the IC note (if any) to the insn. */
1240 if (ic
->note
&& notep
)
1242 if (*notep
&& *notep
!= ic
->note
)
1243 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1244 *notep
, ic
->note
, ic
->name
);
1255 lookup_regindex (const char *name
, int specifier
)
1260 if (strstr (name
, "[RSC]"))
1262 if (strstr (name
, "[BSP]"))
1264 else if (strstr (name
, "[BSPSTORE]"))
1266 else if (strstr (name
, "[RNAT]"))
1268 else if (strstr (name
, "[FCR]"))
1270 else if (strstr (name
, "[EFLAG]"))
1272 else if (strstr (name
, "[CSD]"))
1274 else if (strstr (name
, "[SSD]"))
1276 else if (strstr (name
, "[CFLG]"))
1278 else if (strstr (name
, "[FSR]"))
1280 else if (strstr (name
, "[FIR]"))
1282 else if (strstr (name
, "[FDR]"))
1284 else if (strstr (name
, "[CCV]"))
1286 else if (strstr (name
, "[ITC]"))
1288 else if (strstr (name
, "[PFS]"))
1290 else if (strstr (name
, "[LC]"))
1292 else if (strstr (name
, "[EC]"))
1296 if (strstr (name
, "[DCR]"))
1298 else if (strstr (name
, "[ITM]"))
1300 else if (strstr (name
, "[IVA]"))
1302 else if (strstr (name
, "[PTA]"))
1304 else if (strstr (name
, "[GPTA]"))
1306 else if (strstr (name
, "[IPSR]"))
1308 else if (strstr (name
, "[ISR]"))
1310 else if (strstr (name
, "[IIP]"))
1312 else if (strstr (name
, "[IFA]"))
1314 else if (strstr (name
, "[ITIR]"))
1316 else if (strstr (name
, "[IIPA]"))
1318 else if (strstr (name
, "[IFS]"))
1320 else if (strstr (name
, "[IIM]"))
1322 else if (strstr (name
, "[IHA]"))
1324 else if (strstr (name
, "[LID]"))
1326 else if (strstr (name
, "[IVR]"))
1328 else if (strstr (name
, "[TPR]"))
1330 else if (strstr (name
, "[EOI]"))
1332 else if (strstr (name
, "[ITV]"))
1334 else if (strstr (name
, "[PMV]"))
1336 else if (strstr (name
, "[CMCV]"))
1340 if (strstr (name
, ".be"))
1342 else if (strstr (name
, ".up"))
1344 else if (strstr (name
, ".ac"))
1346 else if (strstr (name
, ".mfl"))
1348 else if (strstr (name
, ".mfh"))
1350 else if (strstr (name
, ".ic"))
1352 else if (strstr (name
, ".i"))
1354 else if (strstr (name
, ".pk"))
1356 else if (strstr (name
, ".dt"))
1358 else if (strstr (name
, ".dfl"))
1360 else if (strstr (name
, ".dfh"))
1362 else if (strstr (name
, ".sp"))
1364 else if (strstr (name
, ".pp"))
1366 else if (strstr (name
, ".di"))
1368 else if (strstr (name
, ".si"))
1370 else if (strstr (name
, ".db"))
1372 else if (strstr (name
, ".lp"))
1374 else if (strstr (name
, ".tb"))
1376 else if (strstr (name
, ".rt"))
1378 else if (strstr (name
, ".cpl"))
1380 else if (strstr (name
, ".rs"))
1382 else if (strstr (name
, ".mc"))
1384 else if (strstr (name
, ".it"))
1386 else if (strstr (name
, ".id"))
1388 else if (strstr (name
, ".da"))
1390 else if (strstr (name
, ".dd"))
1392 else if (strstr (name
, ".ss"))
1394 else if (strstr (name
, ".ri"))
1396 else if (strstr (name
, ".ed"))
1398 else if (strstr (name
, ".bn"))
1400 else if (strstr (name
, ".ia"))
1411 lookup_specifier (const char *name
)
1413 if (strchr (name
, '%'))
1415 if (strstr (name
, "AR[K%]") != NULL
)
1416 return IA64_RS_AR_K
;
1417 if (strstr (name
, "AR[UNAT]") != NULL
)
1418 return IA64_RS_AR_UNAT
;
1419 if (strstr (name
, "AR%, % in 8") != NULL
)
1421 if (strstr (name
, "AR%, % in 48") != NULL
)
1423 if (strstr (name
, "BR%") != NULL
)
1425 if (strstr (name
, "CR[IRR%]") != NULL
)
1426 return IA64_RS_CR_IRR
;
1427 if (strstr (name
, "CR[LRR%]") != NULL
)
1428 return IA64_RS_CR_LRR
;
1429 if (strstr (name
, "CR%") != NULL
)
1431 if (strstr (name
, "FR%, % in 0") != NULL
)
1433 if (strstr (name
, "FR%, % in 2") != NULL
)
1435 if (strstr (name
, "GR%") != NULL
)
1437 if (strstr (name
, "PR%, % in 1 ") != NULL
)
1439 if (strstr (name
, "PR%, % in 16 ") != NULL
)
1442 warn (_("don't know how to specify %% dependency %s\n"),
1445 else if (strchr (name
, '#'))
1447 if (strstr (name
, "CPUID#") != NULL
)
1448 return IA64_RS_CPUID
;
1449 if (strstr (name
, "DBR#") != NULL
)
1451 if (strstr (name
, "IBR#") != NULL
)
1453 if (strstr (name
, "MSR#") != NULL
)
1455 if (strstr (name
, "PKR#") != NULL
)
1457 if (strstr (name
, "PMC#") != NULL
)
1459 if (strstr (name
, "PMD#") != NULL
)
1461 if (strstr (name
, "RR#") != NULL
)
1464 warn (_("Don't know how to specify # dependency %s\n"),
1467 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1468 return IA64_RS_AR_FPSR
;
1469 else if (strncmp (name
, "AR[", 3) == 0)
1471 else if (strncmp (name
, "CR[", 3) == 0)
1473 else if (strncmp (name
, "PSR.", 4) == 0)
1475 else if (strcmp (name
, "InService*") == 0)
1476 return IA64_RS_INSERVICE
;
1477 else if (strcmp (name
, "GR0") == 0)
1479 else if (strcmp (name
, "CFM") == 0)
1481 else if (strcmp (name
, "PR63") == 0)
1482 return IA64_RS_PR63
;
1483 else if (strcmp (name
, "RSE") == 0)
1490 print_dependency_table ()
1496 for (i
=0;i
< iclen
;i
++)
1498 if (ics
[i
]->is_class
)
1502 if (ics
[i
]->comment
)
1503 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1504 ics
[i
]->name
, ics
[i
]->comment
);
1506 warn (_("IC:%s has no terminals or sub-classes\n"),
1512 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1514 if (ics
[i
]->comment
)
1515 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1516 ics
[i
]->name
, ics
[i
]->comment
);
1518 warn (_("no insns mapped directly to terminal IC %s\n"),
1524 for (i
= 0; i
< iclen
; i
++)
1528 mark_used (ics
[i
], 1);
1529 warn (_("class %s is defined but not used\n"),
1535 for (i
= 0; i
< rdepslen
; i
++)
1537 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1539 if (rdeps
[i
]->total_chks
== 0)
1540 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1541 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1542 rdeps
[i
]->total_regs
? "" : " or regs");
1543 else if (rdeps
[i
]->total_regs
== 0)
1544 warn (_("rsrc %s (%s) has no regs\n"),
1545 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1549 /* The dependencies themselves. */
1550 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1551 for (i
= 0; i
< rdepslen
; i
++)
1553 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1555 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1556 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1558 printf (" { \"%s\", %d, %d, %d, %d, ",
1559 rdeps
[i
]->name
, specifier
,
1560 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1561 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1562 printf ("\"%s\", ", rdeps
[i
]->extra
);
1569 /* And dependency lists. */
1570 for (i
=0;i
< dlistlen
;i
++)
1573 printf ("static const short dep%d[] = {\n ", i
);
1574 for (j
=0;j
< dlists
[i
]->len
; j
++)
1576 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1583 printf ("\n};\n\n");
1586 /* And opcode dependency list. */
1587 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1588 printf ("static const struct ia64_opcode_dependency\n");
1589 printf ("op_dependencies[] = {\n");
1590 for (i
= 0; i
< opdeplen
; i
++)
1593 if (opdeps
[i
]->chk
== -1)
1594 printf ("0, NULL, ");
1596 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1597 if (opdeps
[i
]->reg
== -1)
1598 printf ("0, NULL, ");
1600 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1607 /* Add STR to the string table. */
1608 static struct string_entry
*
1609 insert_string (char *str
)
1611 int start
= 0, end
= strtablen
;
1614 if (strtablen
== strtabtotlen
)
1617 string_table
= (struct string_entry
**)
1618 xrealloc (string_table
,
1619 sizeof (struct string_entry
**) * strtabtotlen
);
1625 string_table
[0] = tmalloc (struct string_entry
);
1626 string_table
[0]->s
= xstrdup (str
);
1627 string_table
[0]->num
= 0;
1628 return string_table
[0];
1631 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1633 else if (strcmp (str
, string_table
[0]->s
) < 0)
1641 i
= (start
+ end
) / 2;
1642 c
= strcmp (str
, string_table
[i
]->s
);
1647 return string_table
[i
];
1656 for (; i
> 0 && i
< strtablen
; i
--)
1657 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1660 for (; i
< strtablen
; i
++)
1661 if (strcmp (str
, string_table
[i
]->s
) < 0)
1664 for (x
= strtablen
- 1; x
>= i
; x
--)
1666 string_table
[x
+ 1] = string_table
[x
];
1667 string_table
[x
+ 1]->num
= x
+ 1;
1670 string_table
[i
] = tmalloc (struct string_entry
);
1671 string_table
[i
]->s
= xstrdup (str
);
1672 string_table
[i
]->num
= i
;
1675 return string_table
[i
];
1678 static struct bittree
*
1679 make_bittree_entry (void)
1681 struct bittree
*res
= tmalloc (struct bittree
);
1684 res
->bits
[0] = NULL
;
1685 res
->bits
[1] = NULL
;
1686 res
->bits
[2] = NULL
;
1688 res
->bits_to_skip
= 0;
1693 static struct disent
*
1694 add_dis_table_ent (which
, insn
, order
, completer_index
)
1695 struct disent
*which
;
1698 int completer_index
;
1708 while (ent
->nexte
!= NULL
)
1711 ent
= (ent
->nexte
= tmalloc (struct disent
));
1715 ent
= tmalloc (struct disent
);
1716 ent
->next_ent
= disinsntable
;
1723 ent
->priority
= order
;
1725 while (completer_index
!= 1)
1727 ci
= (ci
<< 1) | (completer_index
& 1);
1728 completer_index
>>= 1;
1730 ent
->completer_index
= ci
;
1737 struct disent
*ent
= disinsntable
;
1738 struct disent
*prev
= ent
;
1740 ent
->ournum
= 32768;
1741 while ((ent
= ent
->next_ent
) != NULL
)
1743 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1749 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1750 opcodenum
, order
, completer_index
)
1751 struct bittree
*curr_ent
;
1757 int completer_index
;
1761 struct bittree
*next
;
1765 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1768 curr_ent
->disent
= nent
;
1772 m
= ((ia64_insn
) 1) << bit
;
1775 b
= (opcode
& m
) ? 1 : 0;
1779 next
= curr_ent
->bits
[b
];
1782 next
= make_bittree_entry ();
1783 curr_ent
->bits
[b
] = next
;
1785 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1790 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1791 struct bittree
*first
;
1795 struct completer_entry
*ent
;
1796 int completer_index
;
1798 if (completer_index
& (1 << 20))
1803 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1804 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1805 (completer_index
<< 1) | 1);
1807 if (ent
->is_terminal
)
1809 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1810 opcodenum
, opcode_count
- ent
->order
- 1,
1811 (completer_index
<< 1) | 1);
1813 completer_index
<<= 1;
1814 ent
= ent
->alternative
;
1818 /* This optimization pass combines multiple "don't care" nodes. */
1820 compact_distree (ent
)
1821 struct bittree
*ent
;
1823 #define IS_SKIP(ent) \
1824 ((ent->bits[2] !=NULL) \
1825 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1828 struct bittree
*nent
= ent
;
1831 while (IS_SKIP (nent
))
1834 nent
= nent
->bits
[2];
1839 struct bittree
*next
= ent
->bits
[2];
1841 ent
->bits
[0] = nent
->bits
[0];
1842 ent
->bits
[1] = nent
->bits
[1];
1843 ent
->bits
[2] = nent
->bits
[2];
1844 ent
->disent
= nent
->disent
;
1846 ent
->bits_to_skip
= bitcnt
;
1847 while (next
!= nent
)
1849 struct bittree
*b
= next
;
1850 next
= next
->bits
[2];
1856 for (x
= 0; x
< 3; x
++)
1858 struct bittree
*i
= ent
->bits
[x
];
1861 compact_distree (i
);
1865 static unsigned char *insn_list
;
1866 static int insn_list_len
= 0;
1867 static int tot_insn_list_len
= 0;
1869 /* Generate the disassembler state machine corresponding to the tree
1873 struct bittree
*ent
;
1876 int our_offset
= insn_list_len
;
1878 int totbits
= bitsused
;
1881 int zero_dest
= 0; /* Initialize this with 0 to keep gcc quiet... */
1883 /* If this is a terminal entry, there's no point in skipping any
1885 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1886 ent
->bits
[2] == NULL
)
1888 if (ent
->disent
== NULL
)
1894 /* Calculate the amount of space needed for this entry, or at least
1895 a conservatively large approximation. */
1899 for (x
= 1; x
< 3; x
++)
1900 if (ent
->bits
[x
] != NULL
)
1903 if (ent
->disent
!= NULL
)
1905 if (ent
->bits
[2] != NULL
)
1911 /* Now allocate the space. */
1912 needed_bytes
= (totbits
+ 7) / 8;
1913 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1915 tot_insn_list_len
+= 256;
1916 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1918 our_offset
= insn_list_len
;
1919 insn_list_len
+= needed_bytes
;
1920 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1922 /* Encode the skip entry by setting bit 6 set in the state op field,
1923 and store the # of bits to skip immediately after. */
1927 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1928 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1931 #define IS_ONLY_IFZERO(ENT) \
1932 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1933 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1935 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1937 if (ent
->bits
[0] != NULL
)
1939 struct bittree
*nent
= ent
->bits
[0];
1942 insn_list
[our_offset
] |= 0x80;
1944 /* We can encode sequences of multiple "if (bit is zero)" tests
1945 by storing the # of zero bits to check in the lower 3 bits of
1946 the instruction. However, this only applies if the state
1947 solely tests for a zero bit. */
1949 if (IS_ONLY_IFZERO (ent
))
1951 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1953 nent
= nent
->bits
[0];
1957 insn_list
[our_offset
+ 0] |= zero_count
;
1959 zero_dest
= insn_list_len
;
1960 gen_dis_table (nent
);
1963 /* Now store the remaining tests. We also handle a sole "termination
1964 entry" by storing it as an "any bit" test. */
1966 for (x
= 1; x
< 3; x
++)
1968 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1970 struct bittree
*i
= ent
->bits
[x
];
1976 /* If the instruction being branched to only consists of
1977 a termination entry, use the termination entry as the
1978 place to branch to instead. */
1979 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1980 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1982 idest
= i
->disent
->ournum
;
1986 idest
= insn_list_len
- our_offset
;
1989 idest
= ent
->disent
->ournum
;
1991 /* If the destination offset for the if (bit is 1) test is less
1992 than 256 bytes away, we can store it as 8-bits instead of 16;
1993 the instruction has bit 5 set for the 16-bit address, and bit
1994 4 for the 8-bit address. Since we've already allocated 16
1995 bits for the address we need to deallocate the space.
1997 Note that branchings within the table are relative, and
1998 there are no branches that branch past our instruction yet
1999 so we do not need to adjust any other offsets. */
2004 int start
= our_offset
+ bitsused
/ 8 + 1;
2006 memmove (insn_list
+ start
,
2007 insn_list
+ start
+ 1,
2008 insn_list_len
- (start
+ 1));
2013 insn_list
[our_offset
] |= 0x10;
2017 insn_list
[our_offset
] |= 0x20;
2021 /* An instruction which solely consists of a termination
2022 marker and whose disassembly name index is < 4096
2023 can be stored in 16 bits. The encoding is slightly
2024 odd; the upper 4 bits of the instruction are 0x3, and
2025 bit 3 loses its normal meaning. */
2027 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
2028 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
2029 && ent
->disent
!= NULL
2030 && ent
->disent
->ournum
< (32768 + 4096))
2032 int start
= our_offset
+ bitsused
/ 8 + 1;
2034 memmove (insn_list
+ start
,
2035 insn_list
+ start
+ 1,
2036 insn_list_len
- (start
+ 1));
2042 insn_list
[our_offset
] |= 0x30;
2046 insn_list
[our_offset
] |= 0x08;
2055 else if (! (id
& 32768))
2059 printf ("%d: if (1) goto %d\n", our_offset
, id
);
2061 printf ("%d: try %d\n", our_offset
, id
);
2064 /* Store the address of the entry being branched to. */
2065 while (currbits
>= 0)
2067 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2069 if (idest
& (1 << currbits
))
2070 *byte
|= (1 << (7 - (bitsused
% 8)));
2076 /* Now generate the states for the entry being branched to. */
2085 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2087 if (ent
->bits
[0] != NULL
)
2088 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2092 if (bitsused
!= totbits
)
2097 print_dis_table (void)
2100 struct disent
*cent
= disinsntable
;
2102 printf ("static const char dis_table[] = {\n");
2103 for (x
= 0; x
< insn_list_len
; x
++)
2105 if ((x
> 0) && ((x
% 12) == 0))
2108 printf ("0x%02x, ", insn_list
[x
]);
2110 printf ("\n};\n\n");
2112 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2113 while (cent
!= NULL
)
2115 struct disent
*ent
= cent
;
2119 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2120 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2124 cent
= cent
->next_ent
;
2130 generate_disassembler (void)
2134 bittree
= make_bittree_entry ();
2136 for (i
= 0; i
< otlen
; i
++)
2138 struct main_entry
*ptr
= ordered_table
[i
];
2140 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2141 add_dis_entry (bittree
,
2142 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2144 ptr
->completers
, 1);
2147 compact_distree (bittree
);
2149 gen_dis_table (bittree
);
2155 print_string_table (void)
2158 char lbuf
[80], buf
[80];
2161 printf ("static const char * const ia64_strings[] = {\n");
2164 for (x
= 0; x
< strtablen
; x
++)
2168 if (strlen (string_table
[x
]->s
) > 75)
2171 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2174 if ((blen
+ len
) > 75)
2176 printf (" %s\n", lbuf
);
2185 printf (" %s\n", lbuf
);
2190 static struct completer_entry
**glist
;
2191 static int glistlen
= 0;
2192 static int glisttotlen
= 0;
2194 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2197 completer_entries_eq (ent1
, ent2
)
2198 struct completer_entry
*ent1
, *ent2
;
2200 while (ent1
!= NULL
&& ent2
!= NULL
)
2202 if (ent1
->name
->num
!= ent2
->name
->num
2203 || ent1
->bits
!= ent2
->bits
2204 || ent1
->mask
!= ent2
->mask
2205 || ent1
->is_terminal
!= ent2
->is_terminal
2206 || ent1
->dependencies
!= ent2
->dependencies
2207 || ent1
->order
!= ent2
->order
)
2210 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2213 ent1
= ent1
->alternative
;
2214 ent2
= ent2
->alternative
;
2217 return ent1
== ent2
;
2220 /* Insert ENT into the global list of completers and return it. If an
2221 equivalent entry (according to completer_entries_eq) already exists,
2222 it is returned instead. */
2223 static struct completer_entry
*
2224 insert_gclist (struct completer_entry
*ent
)
2232 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2233 ent
->alternative
= insert_gclist (ent
->alternative
);
2238 if (glisttotlen
== glistlen
)
2241 glist
= (struct completer_entry
**)
2242 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2252 if (ent
->name
->num
< glist
[0]->name
->num
)
2254 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2262 i
= (start
+ end
) / 2;
2263 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2270 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2284 while (i
< glistlen
)
2286 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2289 if (completer_entries_eq (ent
, glist
[i
]))
2297 for (; i
> 0 && i
< glistlen
; i
--)
2298 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2301 for (; i
< glistlen
; i
++)
2302 if (ent
->name
->num
< glist
[i
]->name
->num
)
2305 for (x
= glistlen
- 1; x
>= i
; x
--)
2306 glist
[x
+ 1] = glist
[x
];
2315 get_prefix_len (name
)
2320 if (name
[0] == '\0')
2323 c
= strchr (name
, '.');
2327 return strlen (name
);
2331 compute_completer_bits (ment
, ent
)
2332 struct main_entry
*ment
;
2333 struct completer_entry
*ent
;
2337 compute_completer_bits (ment
, ent
->addl_entries
);
2339 if (ent
->is_terminal
)
2342 ia64_insn our_bits
= ent
->bits
;
2343 struct completer_entry
*p
= ent
->parent
;
2347 while (p
!= NULL
&& ! p
->is_terminal
)
2353 p_bits
= ment
->opcode
->opcode
;
2355 for (x
= 0; x
< 64; x
++)
2357 ia64_insn m
= ((ia64_insn
) 1) << x
;
2359 if ((p_bits
& m
) != (our_bits
& m
))
2364 ent
->bits
= our_bits
;
2373 ent
= ent
->alternative
;
2377 /* Find identical completer trees that are used in different
2378 instructions and collapse their entries. */
2380 collapse_redundant_completers (void)
2382 struct main_entry
*ptr
;
2385 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2387 if (ptr
->completers
== NULL
)
2390 compute_completer_bits (ptr
, ptr
->completers
);
2391 ptr
->completers
= insert_gclist (ptr
->completers
);
2394 /* The table has been finalized, now number the indexes. */
2395 for (x
= 0; x
< glistlen
; x
++)
2400 /* Attach two lists of dependencies to each opcode.
2401 1) all resources which, when already marked in use, conflict with this
2403 2) all resources which must be marked in use when this opcode is used
2406 insert_opcode_dependencies (opc
, cmp
)
2407 struct ia64_opcode
*opc
;
2408 struct completer_entry
*cmp ATTRIBUTE_UNUSED
;
2410 /* Note all resources which point to this opcode. rfi has the most chks
2411 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2414 unsigned short regs
[256];
2416 unsigned short chks
[256];
2417 /* Flag insns for which no class matched; there should be none. */
2418 int no_class_found
= 1;
2420 for (i
= 0; i
< rdepslen
; i
++)
2422 struct rdep
*rs
= rdeps
[i
];
2425 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2426 && strncmp (rs
->name
, "PR%", 3) == 0
2428 no_class_found
= 99;
2430 for (j
=0; j
< rs
->nregs
;j
++)
2434 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2436 /* We can ignore ic_note 11 for non PR resources. */
2437 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2440 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2441 && ic_note
!= rs
->regnotes
[j
]
2442 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2443 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2444 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2445 rs
->name
, rs
->regnotes
[j
]);
2446 /* Instruction class notes override resource notes.
2447 So far, only note 11 applies to an IC instead of a resource,
2448 and note 11 implies note 1. */
2450 regs
[nregs
++] = RDEP(ic_note
, i
);
2452 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2458 for (j
= 0; j
< rs
->nchks
; j
++)
2462 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2464 /* We can ignore ic_note 11 for non PR resources. */
2465 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2468 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2469 && ic_note
!= rs
->chknotes
[j
]
2470 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2471 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2472 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2473 rs
->name
, rs
->chknotes
[j
]);
2475 chks
[nchks
++] = RDEP(ic_note
, i
);
2477 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2485 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2487 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2489 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2493 insert_completer_entry (opc
, tabent
, order
)
2494 struct ia64_opcode
*opc
;
2495 struct main_entry
*tabent
;
2498 struct completer_entry
**ptr
= &tabent
->completers
;
2499 struct completer_entry
*parent
= NULL
;
2500 char pcopy
[129], *prefix
;
2503 if (strlen (opc
->name
) > 128)
2506 strcpy (pcopy
, opc
->name
);
2507 prefix
= pcopy
+ get_prefix_len (pcopy
);
2509 if (prefix
[0] != '\0')
2514 int need_new_ent
= 1;
2515 int plen
= get_prefix_len (prefix
);
2516 struct string_entry
*sent
;
2518 at_end
= (prefix
[plen
] == '\0');
2519 prefix
[plen
] = '\0';
2520 sent
= insert_string (prefix
);
2522 while (*ptr
!= NULL
)
2524 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2532 ptr
= &((*ptr
)->alternative
);
2537 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2540 nent
->parent
= parent
;
2541 nent
->addl_entries
= NULL
;
2542 nent
->alternative
= *ptr
;
2544 nent
->is_terminal
= 0;
2545 nent
->dependencies
= -1;
2551 ptr
= &((*ptr
)->addl_entries
);
2556 if ((*ptr
)->is_terminal
)
2559 (*ptr
)->is_terminal
= 1;
2560 (*ptr
)->mask
= (ia64_insn
)-1;
2561 (*ptr
)->bits
= opc
->opcode
;
2562 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2563 (*ptr
)->order
= order
;
2567 print_completer_entry (ent
)
2568 struct completer_entry
*ent
;
2571 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2575 while (! (mask
& 1))
2582 if (bits
& 0xffffffff00000000LL
)
2586 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2590 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2591 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2593 ent
->is_terminal
? 1 : 0,
2598 print_completer_table ()
2602 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2603 for (x
= 0; x
< glistlen
; x
++)
2604 print_completer_entry (glist
[x
]);
2609 opcodes_eq (opc1
, opc2
)
2610 struct ia64_opcode
*opc1
;
2611 struct ia64_opcode
*opc2
;
2616 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2617 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2618 || (opc1
->flags
!= opc2
->flags
))
2621 for (x
= 0; x
< 5; x
++)
2622 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2625 plen1
= get_prefix_len (opc1
->name
);
2626 plen2
= get_prefix_len (opc2
->name
);
2628 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2635 add_opcode_entry (opc
)
2636 struct ia64_opcode
*opc
;
2638 struct main_entry
**place
;
2639 struct string_entry
*name
;
2643 if (strlen (opc
->name
) > 128)
2647 strcpy (prefix
, opc
->name
);
2648 prefix
[get_prefix_len (prefix
)] = '\0';
2649 name
= insert_string (prefix
);
2651 /* Walk the list of opcode table entries. If it's a new
2652 instruction, allocate and fill in a new entry. Note
2653 the main table is alphabetical by opcode name. */
2655 while (*place
!= NULL
)
2657 if ((*place
)->name
->num
== name
->num
2658 && opcodes_eq ((*place
)->opcode
, opc
))
2663 if ((*place
)->name
->num
> name
->num
)
2666 place
= &((*place
)->next
);
2670 struct main_entry
*nent
= tmalloc (struct main_entry
);
2674 nent
->next
= *place
;
2675 nent
->completers
= 0;
2678 if (otlen
== ottotlen
)
2681 ordered_table
= (struct main_entry
**)
2682 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2684 ordered_table
[otlen
++] = nent
;
2687 insert_completer_entry (opc
, *place
, opcode_count
++);
2691 print_main_table (void)
2693 struct main_entry
*ptr
= maintable
;
2696 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2699 printf (" { %d, %d, %d, 0x",
2702 ptr
->opcode
->num_outputs
);
2703 fprintf_vma (stdout
, ptr
->opcode
->opcode
);
2705 fprintf_vma (stdout
, ptr
->opcode
->mask
);
2706 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2707 ptr
->opcode
->operands
[0],
2708 ptr
->opcode
->operands
[1],
2709 ptr
->opcode
->operands
[2],
2710 ptr
->opcode
->operands
[3],
2711 ptr
->opcode
->operands
[4],
2713 ptr
->completers
->num
);
2715 ptr
->main_index
= index
++;
2724 struct ia64_opcode
*table
;
2728 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2730 add_opcode_entry (table
+ curr_opcode
);
2731 if (table
[curr_opcode
].num_outputs
== 2
2732 && ((table
[curr_opcode
].operands
[0] == IA64_OPND_P1
2733 && table
[curr_opcode
].operands
[1] == IA64_OPND_P2
)
2734 || (table
[curr_opcode
].operands
[0] == IA64_OPND_P2
2735 && table
[curr_opcode
].operands
[1] == IA64_OPND_P1
)))
2737 struct ia64_opcode
*alias
= tmalloc(struct ia64_opcode
);
2740 *alias
= table
[curr_opcode
];
2741 for (i
= 2; i
< NELEMS (alias
->operands
); ++i
)
2742 alias
->operands
[i
- 1] = alias
->operands
[i
];
2743 alias
->operands
[NELEMS (alias
->operands
) - 1] = IA64_OPND_NIL
;
2744 --alias
->num_outputs
;
2745 alias
->flags
|= PSEUDO
;
2746 add_opcode_entry (alias
);
2752 /* Program options. */
2753 #define OPTION_SRCDIR 200
2755 struct option long_options
[] =
2757 {"srcdir", required_argument
, NULL
, OPTION_SRCDIR
},
2758 {"debug", no_argument
, NULL
, 'd'},
2759 {"version", no_argument
, NULL
, 'V'},
2760 {"help", no_argument
, NULL
, 'h'},
2761 {0, no_argument
, NULL
, 0}
2765 print_version (void)
2767 printf ("%s: version 1.0\n", program_name
);
2772 usage (FILE * stream
, int status
)
2774 fprintf (stream
, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2780 main (int argc
, char **argv
)
2782 extern int chdir (char *);
2783 char *srcdir
= NULL
;
2786 program_name
= *argv
;
2787 xmalloc_set_program_name (program_name
);
2789 while ((c
= getopt_long (argc
, argv
, "vVdh", long_options
, 0)) != EOF
)
2814 if (chdir (srcdir
) != 0)
2815 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2816 srcdir
, strerror (errno
));
2818 load_insn_classes ();
2819 load_dependencies ();
2821 shrink (ia64_opcodes_a
);
2822 shrink (ia64_opcodes_b
);
2823 shrink (ia64_opcodes_f
);
2824 shrink (ia64_opcodes_i
);
2825 shrink (ia64_opcodes_m
);
2826 shrink (ia64_opcodes_x
);
2827 shrink (ia64_opcodes_d
);
2829 collapse_redundant_completers ();
2831 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2832 print_string_table ();
2833 print_dependency_table ();
2834 print_completer_table ();
2835 print_main_table ();
2837 generate_disassembler ();