1 /* $MirOS: src/gnu/usr.bin/binutils/opcodes/ia64-gen.c,v 1.4 2005/06/05 21:24:49 tg Exp $ */
2
3 /* ia64-gen.c -- Generate a shrunk set of opcode tables
4 Copyright 1999, 2000, 2001, 2002, 2004, 2005
5 Free Software Foundation, Inc.
6 Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
7
8 This file is part of GDB, GAS, and the GNU binutils.
9
10 GDB, GAS, and the GNU binutils are free software; you can redistribute
11 them and/or modify them under the terms of the GNU General Public
12 License as published by the Free Software Foundation; either version
13 2, or (at your option) any later version.
14
15 GDB, GAS, and the GNU binutils are distributed in the hope that they
16 will be useful, but WITHOUT ANY WARRANTY; without even the implied
17 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 the GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this file; see the file COPYING. If not, write to the
22 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
24
25 /* While the ia64-opc-* set of opcode tables are easy to maintain,
26 they waste a tremendous amount of space. ia64-gen rearranges the
27 instructions into a directed acyclic graph (DAG) of instruction opcodes and
28 their possible completers, as well as compacting the set of strings used.
29
30 The disassembler table consists of a state machine that does
31 branching based on the bits of the opcode being disassembled. The
32 state encodings have been chosen to minimize the amount of space
33 required.
34
35 The resource table is constructed based on some text dependency tables,
36 which are also easier to maintain than the final representation. */
37
38 #include <stdio.h>
39 #include <stdarg.h>
40 #include <errno.h>
41
42 #include "ansidecl.h"
43 #include "libiberty.h"
44 #include "safe-ctype.h"
45 #include "sysdep.h"
46 #include "getopt.h"
47 #include "ia64-opc.h"
48 #include "ia64-opc-a.c"
49 #include "ia64-opc-i.c"
50 #include "ia64-opc-m.c"
51 #include "ia64-opc-b.c"
52 #include "ia64-opc-f.c"
53 #include "ia64-opc-x.c"
54 #include "ia64-opc-d.c"
55
56 __RCSID("$MirOS: src/gnu/usr.bin/binutils/opcodes/ia64-gen.c,v 1.4 2005/06/05 21:24:49 tg Exp $");
57
58 #define _(String) (String)
59
60 const char * program_name = NULL;
61 int debug = 0;
62
63 #define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
64 #define tmalloc(X) (X *) xmalloc (sizeof (X))
65
66 /* The main opcode table entry. Each entry is a unique combination of
67 name and flags (no two entries in the table compare as being equal
68 via opcodes_eq). */
69 struct main_entry
70 {
71 /* The base name of this opcode. The names of its completers are
72 appended to it to generate the full instruction name. */
73 struct string_entry *name;
74 /* The base opcode entry. Which one to use is a fairly arbitrary choice;
75 it uses the first one passed to add_opcode_entry. */
76 struct ia64_opcode *opcode;
77 /* The list of completers that can be applied to this opcode. */
78 struct completer_entry *completers;
79 /* Next entry in the chain. */
80 struct main_entry *next;
81 /* Index in the main table. */
82 int main_index;
83 } *maintable, **ordered_table;
84
85 int otlen = 0;
86 int ottotlen = 0;
87 int opcode_count = 0;
88
89 /* The set of possible completers for an opcode. */
90 struct completer_entry
91 {
92 /* This entry's index in the ia64_completer_table[] array. */
93 int num;
94
95 /* The name of the completer. */
96 struct string_entry *name;
97
98 /* This entry's parent. */
99 struct completer_entry *parent;
100
101 /* Set if this is a terminal completer (occurs at the end of an
102 opcode). */
103 int is_terminal;
104
105 /* An alternative completer. */
106 struct completer_entry *alternative;
107
108 /* Additional completers that can be appended to this one. */
109 struct completer_entry *addl_entries;
110
111 /* Before compute_completer_bits () is invoked, this contains the actual
112 instruction opcode for this combination of opcode and completers.
113 Afterwards, it contains those bits that are different from its
114 parent opcode. */
115 ia64_insn bits;
116
117 /* Bits set to 1 correspond to those bits in this completer's opcode
118 that are different from its parent completer's opcode (or from
119 the base opcode if the entry is the root of the opcode's completer
120 list). This field is filled in by compute_completer_bits (). */
121 ia64_insn mask;
122
123 /* Index into the opcode dependency list, or -1 if none. */
124 int dependencies;
125
126 /* Remember the order encountered in the opcode tables. */
127 int order;
128 };
129
130 /* One entry in the disassembler name table. */
131 struct disent
132 {
133 /* The index into the ia64_name_dis array for this entry. */
134 int ournum;
135
136 /* The index into the main_table[] array. */
137 int insn;
138
139 /* The disassmbly priority of this entry. */
140 int priority;
141
142 /* The completer_index value for this entry. */
143 int completer_index;
144
145 /* How many other entries share this decode. */
146 int nextcnt;
147
148 /* The next entry sharing the same decode. */
149 struct disent *nexte;
150
151 /* The next entry in the name list. */
152 struct disent *next_ent;
153 } *disinsntable = NULL;
154
155 /* A state machine that will eventually be used to generate the
156 disassembler table. */
157 struct bittree
158 {
159 struct disent *disent;
160 struct bittree *bits[3]; /* 0, 1, and X (don't care). */
161 int bits_to_skip;
162 int skip_flag;
163 } *bittree;
164
165 /* The string table contains all opcodes and completers sorted in
166 alphabetical order. */
167
168 /* One entry in the string table. */
169 struct string_entry
170 {
171 /* The index in the ia64_strings[] array for this entry. */
172 int num;
173 /* And the string. */
174 char *s;
175 } **string_table = NULL;
176
177 int strtablen = 0;
178 int strtabtotlen = 0;
179
180
181 /* Resource dependency entries. */
182 struct rdep
183 {
184 char *name; /* Resource name. */
185 unsigned
186 mode:2, /* RAW, WAW, or WAR. */
187 semantics:3; /* Dependency semantics. */
188 char *extra; /* Additional semantics info. */
189 int nchks;
190 int total_chks; /* Total #of terminal insns. */
191 int *chks; /* Insn classes which read (RAW), write
192 (WAW), or write (WAR) this rsrc. */
193 int *chknotes; /* Dependency notes for each class. */
194 int nregs;
195 int total_regs; /* Total #of terminal insns. */
196 int *regs; /* Insn class which write (RAW), write2
197 (WAW), or read (WAR) this rsrc. */
198 int *regnotes; /* Dependency notes for each class. */
199
200 int waw_special; /* Special WAW dependency note. */
201 } **rdeps = NULL;
202
203 static int rdepslen = 0;
204 static int rdepstotlen = 0;
205
206 /* Array of all instruction classes. */
207 struct iclass
208 {
209 char *name; /* Instruction class name. */
210 int is_class; /* Is a class, not a terminal. */
211 int nsubs;
212 int *subs; /* Other classes within this class. */
213 int nxsubs;
214 int xsubs[4]; /* Exclusions. */
215 char *comment; /* Optional comment. */
216 int note; /* Optional note. */
217 int terminal_resolved; /* Did we match this with anything? */
218 int orphan; /* Detect class orphans. */
219 } **ics = NULL;
220
221 static int iclen = 0;
222 static int ictotlen = 0;
223
224 /* An opcode dependency (chk/reg pair of dependency lists). */
225 struct opdep
226 {
227 int chk; /* index into dlists */
228 int reg; /* index into dlists */
229 } **opdeps;
230
231 static int opdeplen = 0;
232 static int opdeptotlen = 0;
233
234 /* A generic list of dependencies w/notes encoded. These may be shared. */
235 struct deplist
236 {
237 int len;
238 unsigned short *deps;
239 } **dlists;
240
241 static int dlistlen = 0;
242 static int dlisttotlen = 0;
243
244
245 static void fail (const char *, ...);
246 static void warn (const char *, ...);
247 static struct rdep * insert_resource (const char *, enum ia64_dependency_mode);
248 static int deplist_equals (struct deplist *, struct deplist *);
249 static short insert_deplist (int, unsigned short *);
250 static short insert_dependencies (int, unsigned short *, int, unsigned short *);
251 static void mark_used (struct iclass *, int);
252 static int fetch_insn_class (const char *, int);
253 static int sub_compare (const void *, const void *);
254 static void load_insn_classes (void);
255 static void parse_resource_users (const char *, int **, int *, int **);
256 static int parse_semantics (char *);
257 static void add_dep (const char *, const char *, const char *, int, int, char *, int);
258 static void load_depfile (const char *, enum ia64_dependency_mode);
259 static void load_dependencies (void);
260 static int irf_operand (int, const char *);
261 static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *);
262 static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *);
263 static int lookup_regindex (const char *, int);
264 static int lookup_specifier (const char *);
265 static void print_dependency_table (void);
266 static struct string_entry * insert_string (char *);
267 static void gen_dis_table (struct bittree *);
268 static void print_dis_table (void);
269 static void generate_disassembler (void);
270 static void print_string_table (void);
271 static int completer_entries_eq (struct completer_entry *, struct completer_entry *);
272 static struct completer_entry * insert_gclist (struct completer_entry *);
273 static int get_prefix_len (const char *);
274 static void compute_completer_bits (struct main_entry *, struct completer_entry *);
275 static void collapse_redundant_completers (void);
276 static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *);
277 static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int);
278 static void print_completer_entry (struct completer_entry *);
279 static void print_completer_table (void);
280 static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *);
281 static void add_opcode_entry (struct ia64_opcode *);
282 static void print_main_table (void);
283 static void shrink (struct ia64_opcode *);
284 static void print_version (void);
285 static void usage (FILE *, int);
286 static void finish_distable (void);
287 static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, int);
288 static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int);
289 static void compact_distree (struct bittree *);
290 static struct bittree * make_bittree_entry (void);
291 static struct disent * add_dis_table_ent (struct disent *, int, int, int);
292
293
294 static void
fail(const char * message,...)295 fail (const char *message, ...)
296 {
297 va_list args;
298
299 va_start (args, message);
300 fprintf (stderr, _("%s: Error: "), program_name);
301 vfprintf (stderr, message, args);
302 va_end (args);
303 xexit (1);
304 }
305
306 static void
warn(const char * message,...)307 warn (const char *message, ...)
308 {
309 va_list args;
310
311 va_start (args, message);
312
313 fprintf (stderr, _("%s: Warning: "), program_name);
314 vfprintf (stderr, message, args);
315 va_end (args);
316 }
317
318 /* Add NAME to the resource table, where TYPE is RAW or WAW. */
319 static struct rdep *
insert_resource(const char * name,enum ia64_dependency_mode type)320 insert_resource (const char *name, enum ia64_dependency_mode type)
321 {
322 if (rdepslen == rdepstotlen)
323 {
324 rdepstotlen += 20;
325 rdeps = (struct rdep **)
326 xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
327 }
328 rdeps[rdepslen] = tmalloc(struct rdep);
329 memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep));
330 rdeps[rdepslen]->name = xstrdup (name);
331 rdeps[rdepslen]->mode = type;
332 rdeps[rdepslen]->waw_special = 0;
333
334 return rdeps[rdepslen++];
335 }
336
337 /* Are the lists of dependency indexes equivalent? */
338 static int
deplist_equals(struct deplist * d1,struct deplist * d2)339 deplist_equals (struct deplist *d1, struct deplist *d2)
340 {
341 int i;
342
343 if (d1->len != d2->len)
344 return 0;
345
346 for (i = 0; i < d1->len; i++)
347 if (d1->deps[i] != d2->deps[i])
348 return 0;
349
350 return 1;
351 }
352
353 /* Add the list of dependencies to the list of dependency lists. */
354 static short
insert_deplist(int count,unsigned short * deps)355 insert_deplist (int count, unsigned short *deps)
356 {
357 /* Sort the list, then see if an equivalent list exists already.
358 this results in a much smaller set of dependency lists. */
359 struct deplist *list;
360 char set[0x10000];
361 int i;
362
363 memset ((void *)set, 0, sizeof (set));
364 for (i = 0; i < count; i++)
365 set[deps[i]] = 1;
366
367 count = 0;
368 for (i = 0; i < (int) sizeof (set); i++)
369 if (set[i])
370 ++count;
371
372 list = tmalloc (struct deplist);
373 list->len = count;
374 list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count);
375
376 for (i = 0, count = 0; i < (int) sizeof (set); i++)
377 if (set[i])
378 list->deps[count++] = i;
379
380 /* Does this list exist already? */
381 for (i = 0; i < dlistlen; i++)
382 if (deplist_equals (list, dlists[i]))
383 {
384 free (list->deps);
385 free (list);
386 return i;
387 }
388
389 if (dlistlen == dlisttotlen)
390 {
391 dlisttotlen += 20;
392 dlists = (struct deplist **)
393 xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
394 }
395 dlists[dlistlen] = list;
396
397 return dlistlen++;
398 }
399
400 /* Add the given pair of dependency lists to the opcode dependency list. */
401 static short
insert_dependencies(int nchks,unsigned short * chks,int nregs,unsigned short * regs)402 insert_dependencies (int nchks, unsigned short *chks,
403 int nregs, unsigned short *regs)
404 {
405 struct opdep *pair;
406 int i;
407 int regind = -1;
408 int chkind = -1;
409
410 if (nregs > 0)
411 regind = insert_deplist (nregs, regs);
412 if (nchks > 0)
413 chkind = insert_deplist (nchks, chks);
414
415 for (i = 0; i < opdeplen; i++)
416 if (opdeps[i]->chk == chkind
417 && opdeps[i]->reg == regind)
418 return i;
419
420 pair = tmalloc (struct opdep);
421 pair->chk = chkind;
422 pair->reg = regind;
423
424 if (opdeplen == opdeptotlen)
425 {
426 opdeptotlen += 20;
427 opdeps = (struct opdep **)
428 xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
429 }
430 opdeps[opdeplen] = pair;
431
432 return opdeplen++;
433 }
434
435 static void
mark_used(struct iclass * ic,int clear_terminals)436 mark_used (struct iclass *ic, int clear_terminals)
437 {
438 int i;
439
440 ic->orphan = 0;
441 if (clear_terminals)
442 ic->terminal_resolved = 1;
443
444 for (i = 0; i < ic->nsubs; i++)
445 mark_used (ics[ic->subs[i]], clear_terminals);
446
447 for (i = 0; i < ic->nxsubs; i++)
448 mark_used (ics[ic->xsubs[i]], clear_terminals);
449 }
450
451 /* Look up an instruction class; if CREATE make a new one if none found;
452 returns the index into the insn class array. */
453 static int
fetch_insn_class(const char * full_name,int create)454 fetch_insn_class (const char *full_name, int create)
455 {
456 char *name;
457 char *notestr;
458 char *xsect;
459 char *comment;
460 int i, note = 0;
461 int ind;
462 int is_class = 0;
463
464 if (strncmp (full_name, "IC:", 3) == 0)
465 {
466 name = xstrdup (full_name + 3);
467 is_class = 1;
468 }
469 else
470 name = xstrdup (full_name);
471
472 if ((xsect = strchr(name, '\\')) != NULL)
473 is_class = 1;
474 if ((comment = strchr(name, '[')) != NULL)
475 is_class = 1;
476 if ((notestr = strchr(name, '+')) != NULL)
477 is_class = 1;
478
479 /* If it is a composite class, then ignore comments and notes that come after
480 the '\\', since they don't apply to the part we are decoding now. */
481 if (xsect)
482 {
483 if (comment > xsect)
484 comment = 0;
485 if (notestr > xsect)
486 notestr = 0;
487 }
488
489 if (notestr)
490 {
491 char *nextnotestr;
492
493 note = atoi (notestr + 1);
494 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
495 {
496 if (strcmp (notestr, "+1+13") == 0)
497 note = 13;
498 else if (!xsect || nextnotestr < xsect)
499 warn (_("multiple note %s not handled\n"), notestr);
500 }
501 }
502
503 /* If it's a composite class, leave the notes and comments in place so that
504 we have a unique name for the composite class. Otherwise, we remove
505 them. */
506 if (!xsect)
507 {
508 if (notestr)
509 *notestr = 0;
510 if (comment)
511 *comment = 0;
512 }
513
514 for (i = 0; i < iclen; i++)
515 if (strcmp (name, ics[i]->name) == 0
516 && ((comment == NULL && ics[i]->comment == NULL)
517 || (comment != NULL && ics[i]->comment != NULL
518 && strncmp (ics[i]->comment, comment,
519 strlen (ics[i]->comment)) == 0))
520 && note == ics[i]->note)
521 return i;
522
523 if (!create)
524 return -1;
525
526 /* Doesn't exist, so make a new one. */
527 if (iclen == ictotlen)
528 {
529 ictotlen += 20;
530 ics = (struct iclass **)
531 xrealloc (ics, (ictotlen) * sizeof (struct iclass *));
532 }
533
534 ind = iclen++;
535 ics[ind] = tmalloc (struct iclass);
536 memset ((void *)ics[ind], 0, sizeof (struct iclass));
537 ics[ind]->name = xstrdup (name);
538 ics[ind]->is_class = is_class;
539 ics[ind]->orphan = 1;
540
541 if (comment)
542 {
543 ics[ind]->comment = xstrdup (comment + 1);
544 ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0;
545 }
546
547 if (notestr)
548 ics[ind]->note = note;
549
550 /* If it's a composite class, there's a comment or note, look for an
551 existing class or terminal with the same name. */
552 if ((xsect || comment || notestr) && is_class)
553 {
554 /* First, populate with the class we're based on. */
555 char *subname = name;
556
557 if (xsect)
558 *xsect = 0;
559 else if (comment)
560 *comment = 0;
561 else if (notestr)
562 *notestr = 0;
563
564 ics[ind]->nsubs = 1;
565 ics[ind]->subs = tmalloc(int);
566 ics[ind]->subs[0] = fetch_insn_class (subname, 1);;
567 }
568
569 while (xsect)
570 {
571 char *subname = xsect + 1;
572
573 xsect = strchr (subname, '\\');
574 if (xsect)
575 *xsect = 0;
576 ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
577 ics[ind]->nxsubs++;
578 }
579 free (name);
580
581 return ind;
582 }
583
584 /* For sorting a class's sub-class list only; make sure classes appear before
585 terminals. */
586 static int
sub_compare(const void * e1,const void * e2)587 sub_compare (const void *e1, const void *e2)
588 {
589 struct iclass *ic1 = ics[*(int *)e1];
590 struct iclass *ic2 = ics[*(int *)e2];
591
592 if (ic1->is_class)
593 {
594 if (!ic2->is_class)
595 return -1;
596 }
597 else if (ic2->is_class)
598 return 1;
599
600 return strcmp (ic1->name, ic2->name);
601 }
602
603 static void
load_insn_classes(void)604 load_insn_classes (void)
605 {
606 FILE *fp = fopen ("ia64-ic.tbl", "r");
607 char buf[2048];
608
609 if (fp == NULL)
610 fail (_("can't find ia64-ic.tbl for reading\n"));
611
612 /* Discard first line. */
613 fgets (buf, sizeof(buf), fp);
614
615 while (!feof (fp))
616 {
617 int iclass;
618 char *name;
619 char *tmp;
620
621 if (fgets (buf, sizeof (buf), fp) == NULL)
622 break;
623
624 while (ISSPACE (buf[strlen (buf) - 1]))
625 buf[strlen (buf) - 1] = '\0';
626
627 name = tmp = buf;
628 while (*tmp != ';')
629 {
630 ++tmp;
631 if (tmp == buf + sizeof (buf))
632 abort ();
633 }
634 *tmp++ = '\0';
635
636 iclass = fetch_insn_class (name, 1);
637 ics[iclass]->is_class = 1;
638
639 if (strcmp (name, "none") == 0)
640 {
641 ics[iclass]->is_class = 0;
642 ics[iclass]->terminal_resolved = 1;
643 continue;
644 }
645
646 /* For this class, record all sub-classes. */
647 while (*tmp)
648 {
649 char *subname;
650 int sub;
651
652 while (*tmp && ISSPACE (*tmp))
653 {
654 ++tmp;
655 if (tmp == buf + sizeof (buf))
656 abort ();
657 }
658 subname = tmp;
659 while (*tmp && *tmp != ',')
660 {
661 ++tmp;
662 if (tmp == buf + sizeof (buf))
663 abort ();
664 }
665 if (*tmp == ',')
666 *tmp++ = '\0';
667
668 ics[iclass]->subs = (int *)
669 xrealloc ((void *)ics[iclass]->subs,
670 (ics[iclass]->nsubs + 1) * sizeof (int));
671
672 sub = fetch_insn_class (subname, 1);
673 ics[iclass]->subs = (int *)
674 xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int));
675 ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
676 }
677
678 /* Make sure classes come before terminals. */
679 qsort ((void *)ics[iclass]->subs,
680 ics[iclass]->nsubs, sizeof(int), sub_compare);
681 }
682 fclose (fp);
683
684 if (debug)
685 printf ("%d classes\n", iclen);
686 }
687
688 /* Extract the insn classes from the given line. */
689 static void
parse_resource_users(ref,usersp,nusersp,notesp)690 parse_resource_users (ref, usersp, nusersp, notesp)
691 const char *ref;
692 int **usersp;
693 int *nusersp;
694 int **notesp;
695 {
696 int c;
697 char *line = xstrdup (ref);
698 char *tmp = line;
699 int *users = *usersp;
700 int count = *nusersp;
701 int *notes = *notesp;
702
703 c = *tmp;
704 while (c != 0)
705 {
706 char *notestr;
707 int note;
708 char *xsect;
709 int iclass;
710 int create = 0;
711 char *name;
712
713 while (ISSPACE (*tmp))
714 ++tmp;
715 name = tmp;
716 while (*tmp && *tmp != ',')
717 ++tmp;
718 c = *tmp;
719 *tmp++ = '\0';
720
721 xsect = strchr (name, '\\');
722 if ((notestr = strstr (name, "+")) != NULL)
723 {
724 char *nextnotestr;
725
726 note = atoi (notestr + 1);
727 if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
728 {
729 /* Note 13 always implies note 1. */
730 if (strcmp (notestr, "+1+13") == 0)
731 note = 13;
732 else if (!xsect || nextnotestr < xsect)
733 warn (_("multiple note %s not handled\n"), notestr);
734 }
735 if (!xsect)
736 *notestr = '\0';
737 }
738 else
739 note = 0;
740
741 /* All classes are created when the insn class table is parsed;
742 Individual instructions might not appear until the dependency tables
743 are read. Only create new classes if it's *not* an insn class,
744 or if it's a composite class (which wouldn't necessarily be in the IC
745 table). */
746 if (strncmp (name, "IC:", 3) != 0 || xsect != NULL)
747 create = 1;
748
749 iclass = fetch_insn_class (name, create);
750 if (iclass != -1)
751 {
752 users = (int *)
753 xrealloc ((void *) users,(count + 1) * sizeof (int));
754 notes = (int *)
755 xrealloc ((void *) notes,(count + 1) * sizeof (int));
756 notes[count] = note;
757 users[count++] = iclass;
758 mark_used (ics[iclass], 0);
759 }
760 else if (debug)
761 printf("Class %s not found\n", name);
762 }
763 /* Update the return values. */
764 *usersp = users;
765 *nusersp = count;
766 *notesp = notes;
767
768 free (line);
769 }
770
771 static int
parse_semantics(char * sem)772 parse_semantics (char *sem)
773 {
774 if (strcmp (sem, "none") == 0)
775 return IA64_DVS_NONE;
776 else if (strcmp (sem, "implied") == 0)
777 return IA64_DVS_IMPLIED;
778 else if (strcmp (sem, "impliedF") == 0)
779 return IA64_DVS_IMPLIEDF;
780 else if (strcmp (sem, "data") == 0)
781 return IA64_DVS_DATA;
782 else if (strcmp (sem, "instr") == 0)
783 return IA64_DVS_INSTR;
784 else if (strcmp (sem, "specific") == 0)
785 return IA64_DVS_SPECIFIC;
786 else if (strcmp (sem, "stop") == 0)
787 return IA64_DVS_STOP;
788 else
789 return IA64_DVS_OTHER;
790 }
791
792 static void
add_dep(const char * name,const char * chk,const char * reg,int semantics,int mode,char * extra,int flag)793 add_dep (const char *name, const char *chk, const char *reg,
794 int semantics, int mode, char *extra, int flag)
795 {
796 struct rdep *rs;
797
798 rs = insert_resource (name, mode);
799
800 parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
801 parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
802
803 rs->semantics = semantics;
804 rs->extra = extra;
805 rs->waw_special = flag;
806 }
807
808 static void
load_depfile(const char * filename,enum ia64_dependency_mode mode)809 load_depfile (const char *filename, enum ia64_dependency_mode mode)
810 {
811 FILE *fp = fopen (filename, "r");
812 char buf[1024];
813
814 if (fp == NULL)
815 fail (_("can't find %s for reading\n"), filename);
816
817 fgets (buf, sizeof(buf), fp);
818 while (!feof (fp))
819 {
820 char *name, *tmp;
821 int semantics;
822 char *extra;
823 char *regp, *chkp;
824
825 if (fgets (buf, sizeof(buf), fp) == NULL)
826 break;
827
828 while (ISSPACE (buf[strlen (buf) - 1]))
829 buf[strlen (buf) - 1] = '\0';
830
831 name = tmp = buf;
832 while (*tmp != ';')
833 ++tmp;
834 *tmp++ = '\0';
835
836 while (ISSPACE (*tmp))
837 ++tmp;
838 regp = tmp;
839 tmp = strchr (tmp, ';');
840 if (!tmp)
841 abort ();
842 *tmp++ = 0;
843 while (ISSPACE (*tmp))
844 ++tmp;
845 chkp = tmp;
846 tmp = strchr (tmp, ';');
847 if (!tmp)
848 abort ();
849 *tmp++ = 0;
850 while (ISSPACE (*tmp))
851 ++tmp;
852 semantics = parse_semantics (tmp);
853 extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
854
855 /* For WAW entries, if the chks and regs differ, we need to enter the
856 entries in both positions so that the tables will be parsed properly,
857 without a lot of extra work. */
858 if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
859 {
860 add_dep (name, chkp, regp, semantics, mode, extra, 0);
861 add_dep (name, regp, chkp, semantics, mode, extra, 1);
862 }
863 else
864 {
865 add_dep (name, chkp, regp, semantics, mode, extra, 0);
866 }
867 }
868 fclose (fp);
869 }
870
871 static void
load_dependencies(void)872 load_dependencies (void)
873 {
874 load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
875 load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
876 load_depfile ("ia64-war.tbl", IA64_DV_WAR);
877
878 if (debug)
879 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
880 }
881
882 /* Is the given operand an indirect register file operand? */
883 static int
irf_operand(int op,const char * field)884 irf_operand (int op, const char *field)
885 {
886 if (!field)
887 {
888 return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
889 || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
890 || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
891 || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
892 }
893 else
894 {
895 return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
896 || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
897 || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
898 || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
899 || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
900 || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
901 || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
902 || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
903 }
904 }
905
906 /* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
907 mov_um insn classes. */
908 static int
in_iclass_mov_x(struct ia64_opcode * idesc,struct iclass * ic,const char * format,const char * field)909 in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
910 const char *format, const char *field)
911 {
912 int plain_mov = strcmp (idesc->name, "mov") == 0;
913
914 if (!format)
915 return 0;
916
917 switch (ic->name[4])
918 {
919 default:
920 abort ();
921 case 'a':
922 {
923 int i = strcmp (idesc->name, "mov.i") == 0;
924 int m = strcmp (idesc->name, "mov.m") == 0;
925 int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
926 int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
927 int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
928 int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
929 int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
930 int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
931
932 /* IC:mov ar */
933 if (i2627)
934 return strstr (format, "I26") || strstr (format, "I27");
935 if (i28)
936 return strstr (format, "I28") != NULL;
937 if (m2930)
938 return strstr (format, "M29") || strstr (format, "M30");
939 if (m31)
940 return strstr (format, "M31") != NULL;
941 if (pseudo0 || pseudo1)
942 return 1;
943 }
944 break;
945 case 'b':
946 {
947 int i21 = idesc->operands[0] == IA64_OPND_B1;
948 int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
949 if (i22)
950 return strstr (format, "I22") != NULL;
951 if (i21)
952 return strstr (format, "I21") != NULL;
953 }
954 break;
955 case 'c':
956 {
957 int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
958 int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
959 if (m32)
960 return strstr (format, "M32") != NULL;
961 if (m33)
962 return strstr (format, "M33") != NULL;
963 }
964 break;
965 case 'i':
966 if (ic->name[5] == 'n')
967 {
968 int m42 = plain_mov && irf_operand (idesc->operands[0], field);
969 int m43 = plain_mov && irf_operand (idesc->operands[1], field);
970 if (m42)
971 return strstr (format, "M42") != NULL;
972 if (m43)
973 return strstr (format, "M43") != NULL;
974 }
975 else if (ic->name[5] == 'p')
976 {
977 return idesc->operands[1] == IA64_OPND_IP;
978 }
979 else
980 abort ();
981 break;
982 case 'p':
983 if (ic->name[5] == 'r')
984 {
985 int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
986 int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
987 int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
988 if (i23)
989 return strstr (format, "I23") != NULL;
990 if (i24)
991 return strstr (format, "I24") != NULL;
992 if (i25)
993 return strstr (format, "I25") != NULL;
994 }
995 else if (ic->name[5] == 's')
996 {
997 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
998 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
999 if (m35)
1000 return strstr (format, "M35") != NULL;
1001 if (m36)
1002 return strstr (format, "M36") != NULL;
1003 }
1004 else
1005 abort ();
1006 break;
1007 case 'u':
1008 {
1009 int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
1010 int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
1011 if (m35)
1012 return strstr (format, "M35") != NULL;
1013 if (m36)
1014 return strstr (format, "M36") != NULL;
1015 }
1016 break;
1017 }
1018 return 0;
1019 }
1020
1021 /* Is the given opcode in the given insn class? */
1022 static int
in_iclass(struct ia64_opcode * idesc,struct iclass * ic,const char * format,const char * field,int * notep)1023 in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1024 const char *format, const char *field, int *notep)
1025 {
1026 int i;
1027 int resolved = 0;
1028
1029 if (ic->comment)
1030 {
1031 if (!strncmp (ic->comment, "Format", 6))
1032 {
1033 /* Assume that the first format seen is the most restrictive, and
1034 only keep a later one if it looks like it's more restrictive. */
1035 if (format)
1036 {
1037 if (strlen (ic->comment) < strlen (format))
1038 {
1039 warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1040 ic->comment, format);
1041 format = ic->comment;
1042 }
1043 }
1044 else
1045 format = ic->comment;
1046 }
1047 else if (!strncmp (ic->comment, "Field", 5))
1048 {
1049 if (field)
1050 warn (_("overlapping field %s->%s\n"),
1051 ic->comment, field);
1052 field = ic->comment;
1053 }
1054 }
1055
1056 /* An insn class matches anything that is the same followed by completers,
1057 except when the absence and presence of completers constitutes different
1058 instructions. */
1059 if (ic->nsubs == 0 && ic->nxsubs == 0)
1060 {
1061 int is_mov = strncmp (idesc->name, "mov", 3) == 0;
1062 int plain_mov = strcmp (idesc->name, "mov") == 0;
1063 int len = strlen(ic->name);
1064
1065 resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1066 && (idesc->name[len] == '\0'
1067 || idesc->name[len] == '.'));
1068
1069 /* All break, nop, and hint variations must match exactly. */
1070 if (resolved &&
1071 (strcmp (ic->name, "break") == 0
1072 || strcmp (ic->name, "nop") == 0
1073 || strcmp (ic->name, "hint") == 0))
1074 resolved = strcmp (ic->name, idesc->name) == 0;
1075
1076 /* Assume restrictions in the FORMAT/FIELD negate resolution,
1077 unless specifically allowed by clauses in this block. */
1078 if (resolved && field)
1079 {
1080 /* Check Field(sf)==sN against opcode sN. */
1081 if (strstr(field, "(sf)==") != NULL)
1082 {
1083 char *sf;
1084
1085 if ((sf = strstr (idesc->name, ".s")) != 0)
1086 resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1087 }
1088 /* Check Field(lftype)==XXX. */
1089 else if (strstr (field, "(lftype)") != NULL)
1090 {
1091 if (strstr (idesc->name, "fault") != NULL)
1092 resolved = strstr (field, "fault") != NULL;
1093 else
1094 resolved = strstr (field, "fault") == NULL;
1095 }
1096 /* Handle Field(ctype)==XXX. */
1097 else if (strstr (field, "(ctype)") != NULL)
1098 {
1099 if (strstr (idesc->name, "or.andcm"))
1100 resolved = strstr (field, "or.andcm") != NULL;
1101 else if (strstr (idesc->name, "and.orcm"))
1102 resolved = strstr (field, "and.orcm") != NULL;
1103 else if (strstr (idesc->name, "orcm"))
1104 resolved = strstr (field, "or orcm") != NULL;
1105 else if (strstr (idesc->name, "or"))
1106 resolved = strstr (field, "or orcm") != NULL;
1107 else if (strstr (idesc->name, "andcm"))
1108 resolved = strstr (field, "and andcm") != NULL;
1109 else if (strstr (idesc->name, "and"))
1110 resolved = strstr (field, "and andcm") != NULL;
1111 else if (strstr (idesc->name, "unc"))
1112 resolved = strstr (field, "unc") != NULL;
1113 else
1114 resolved = strcmp (field, "Field(ctype)==") == 0;
1115 }
1116 }
1117
1118 if (resolved && format)
1119 {
1120 if (strncmp (idesc->name, "dep", 3) == 0
1121 && strstr (format, "I13") != NULL)
1122 resolved = idesc->operands[1] == IA64_OPND_IMM8;
1123 else if (strncmp (idesc->name, "chk", 3) == 0
1124 && strstr (format, "M21") != NULL)
1125 resolved = idesc->operands[0] == IA64_OPND_F2;
1126 else if (strncmp (idesc->name, "lfetch", 6) == 0)
1127 resolved = (strstr (format, "M14 M15") != NULL
1128 && (idesc->operands[1] == IA64_OPND_R2
1129 || idesc->operands[1] == IA64_OPND_IMM9b));
1130 else if (strncmp (idesc->name, "br.call", 7) == 0
1131 && strstr (format, "B5") != NULL)
1132 resolved = idesc->operands[1] == IA64_OPND_B2;
1133 else if (strncmp (idesc->name, "br.call", 7) == 0
1134 && strstr (format, "B3") != NULL)
1135 resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1136 else if (strncmp (idesc->name, "brp", 3) == 0
1137 && strstr (format, "B7") != NULL)
1138 resolved = idesc->operands[0] == IA64_OPND_B2;
1139 else if (strcmp (ic->name, "invala") == 0)
1140 resolved = strcmp (idesc->name, ic->name) == 0;
1141 else if (strncmp (idesc->name, "st", 2) == 0
1142 && (strstr (format, "M5") != NULL
1143 || strstr (format, "M10") != NULL))
1144 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1145 else if (strncmp (idesc->name, "ld", 2) == 0
1146 && (strstr (format, "M2 M3") != NULL
1147 || strstr (format, "M12") != NULL
1148 || strstr (format, "M7 M8") != NULL))
1149 resolved = idesc->flags & IA64_OPCODE_POSTINC;
1150 else
1151 resolved = 0;
1152 }
1153
1154 /* Misc brl variations ('.cond' is optional);
1155 plain brl matches brl.cond. */
1156 if (!resolved
1157 && (strcmp (idesc->name, "brl") == 0
1158 || strncmp (idesc->name, "brl.", 4) == 0)
1159 && strcmp (ic->name, "brl.cond") == 0)
1160 {
1161 resolved = 1;
1162 }
1163
1164 /* Misc br variations ('.cond' is optional). */
1165 if (!resolved
1166 && (strcmp (idesc->name, "br") == 0
1167 || strncmp (idesc->name, "br.", 3) == 0)
1168 && strcmp (ic->name, "br.cond") == 0)
1169 {
1170 if (format)
1171 resolved = (strstr (format, "B4") != NULL
1172 && idesc->operands[0] == IA64_OPND_B2)
1173 || (strstr (format, "B1") != NULL
1174 && idesc->operands[0] == IA64_OPND_TGT25c);
1175 else
1176 resolved = 1;
1177 }
1178
1179 /* probe variations. */
1180 if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1181 {
1182 resolved = strcmp (ic->name, "probe") == 0
1183 && !((strstr (idesc->name, "fault") != NULL)
1184 ^ (format && strstr (format, "M40") != NULL));
1185 }
1186
1187 /* mov variations. */
1188 if (!resolved && is_mov)
1189 {
1190 if (plain_mov)
1191 {
1192 /* mov alias for fmerge. */
1193 if (strcmp (ic->name, "fmerge") == 0)
1194 {
1195 resolved = idesc->operands[0] == IA64_OPND_F1
1196 && idesc->operands[1] == IA64_OPND_F3;
1197 }
1198 /* mov alias for adds (r3 or imm14). */
1199 else if (strcmp (ic->name, "adds") == 0)
1200 {
1201 resolved = (idesc->operands[0] == IA64_OPND_R1
1202 && (idesc->operands[1] == IA64_OPND_R3
1203 || (idesc->operands[1] == IA64_OPND_IMM14)));
1204 }
1205 /* mov alias for addl. */
1206 else if (strcmp (ic->name, "addl") == 0)
1207 {
1208 resolved = idesc->operands[0] == IA64_OPND_R1
1209 && idesc->operands[1] == IA64_OPND_IMM22;
1210 }
1211 }
1212
1213 /* Some variants of mov and mov.[im]. */
1214 if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1215 resolved = in_iclass_mov_x (idesc, ic, format, field);
1216 }
1217
1218 /* Keep track of this so we can flag any insn classes which aren't
1219 mapped onto at least one real insn. */
1220 if (resolved)
1221 ic->terminal_resolved = 1;
1222 }
1223 else for (i = 0; i < ic->nsubs; i++)
1224 {
1225 if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1226 {
1227 int j;
1228
1229 for (j = 0; j < ic->nxsubs; j++)
1230 if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1231 return 0;
1232
1233 if (debug > 1)
1234 printf ("%s is in IC %s\n", idesc->name, ic->name);
1235
1236 resolved = 1;
1237 break;
1238 }
1239 }
1240
1241 /* If it's in this IC, add the IC note (if any) to the insn. */
1242 if (resolved)
1243 {
1244 if (ic->note && notep)
1245 {
1246 if (*notep && *notep != ic->note)
1247 warn (_("overwriting note %d with note %d (IC:%s)\n"),
1248 *notep, ic->note, ic->name);
1249
1250 *notep = ic->note;
1251 }
1252 }
1253
1254 return resolved;
1255 }
1256
1257
1258 static int
lookup_regindex(const char * name,int specifier)1259 lookup_regindex (const char *name, int specifier)
1260 {
1261 switch (specifier)
1262 {
1263 case IA64_RS_ARX:
1264 if (strstr (name, "[RSC]"))
1265 return 16;
1266 if (strstr (name, "[BSP]"))
1267 return 17;
1268 else if (strstr (name, "[BSPSTORE]"))
1269 return 18;
1270 else if (strstr (name, "[RNAT]"))
1271 return 19;
1272 else if (strstr (name, "[FCR]"))
1273 return 21;
1274 else if (strstr (name, "[EFLAG]"))
1275 return 24;
1276 else if (strstr (name, "[CSD]"))
1277 return 25;
1278 else if (strstr (name, "[SSD]"))
1279 return 26;
1280 else if (strstr (name, "[CFLG]"))
1281 return 27;
1282 else if (strstr (name, "[FSR]"))
1283 return 28;
1284 else if (strstr (name, "[FIR]"))
1285 return 29;
1286 else if (strstr (name, "[FDR]"))
1287 return 30;
1288 else if (strstr (name, "[CCV]"))
1289 return 32;
1290 else if (strstr (name, "[ITC]"))
1291 return 44;
1292 else if (strstr (name, "[PFS]"))
1293 return 64;
1294 else if (strstr (name, "[LC]"))
1295 return 65;
1296 else if (strstr (name, "[EC]"))
1297 return 66;
1298 abort ();
1299 case IA64_RS_CRX:
1300 if (strstr (name, "[DCR]"))
1301 return 0;
1302 else if (strstr (name, "[ITM]"))
1303 return 1;
1304 else if (strstr (name, "[IVA]"))
1305 return 2;
1306 else if (strstr (name, "[PTA]"))
1307 return 8;
1308 else if (strstr (name, "[GPTA]"))
1309 return 9;
1310 else if (strstr (name, "[IPSR]"))
1311 return 16;
1312 else if (strstr (name, "[ISR]"))
1313 return 17;
1314 else if (strstr (name, "[IIP]"))
1315 return 19;
1316 else if (strstr (name, "[IFA]"))
1317 return 20;
1318 else if (strstr (name, "[ITIR]"))
1319 return 21;
1320 else if (strstr (name, "[IIPA]"))
1321 return 22;
1322 else if (strstr (name, "[IFS]"))
1323 return 23;
1324 else if (strstr (name, "[IIM]"))
1325 return 24;
1326 else if (strstr (name, "[IHA]"))
1327 return 25;
1328 else if (strstr (name, "[LID]"))
1329 return 64;
1330 else if (strstr (name, "[IVR]"))
1331 return 65;
1332 else if (strstr (name, "[TPR]"))
1333 return 66;
1334 else if (strstr (name, "[EOI]"))
1335 return 67;
1336 else if (strstr (name, "[ITV]"))
1337 return 72;
1338 else if (strstr (name, "[PMV]"))
1339 return 73;
1340 else if (strstr (name, "[CMCV]"))
1341 return 74;
1342 abort ();
1343 case IA64_RS_PSR:
1344 if (strstr (name, ".be"))
1345 return 1;
1346 else if (strstr (name, ".up"))
1347 return 2;
1348 else if (strstr (name, ".ac"))
1349 return 3;
1350 else if (strstr (name, ".mfl"))
1351 return 4;
1352 else if (strstr (name, ".mfh"))
1353 return 5;
1354 else if (strstr (name, ".ic"))
1355 return 13;
1356 else if (strstr (name, ".i"))
1357 return 14;
1358 else if (strstr (name, ".pk"))
1359 return 15;
1360 else if (strstr (name, ".dt"))
1361 return 17;
1362 else if (strstr (name, ".dfl"))
1363 return 18;
1364 else if (strstr (name, ".dfh"))
1365 return 19;
1366 else if (strstr (name, ".sp"))
1367 return 20;
1368 else if (strstr (name, ".pp"))
1369 return 21;
1370 else if (strstr (name, ".di"))
1371 return 22;
1372 else if (strstr (name, ".si"))
1373 return 23;
1374 else if (strstr (name, ".db"))
1375 return 24;
1376 else if (strstr (name, ".lp"))
1377 return 25;
1378 else if (strstr (name, ".tb"))
1379 return 26;
1380 else if (strstr (name, ".rt"))
1381 return 27;
1382 else if (strstr (name, ".cpl"))
1383 return 32;
1384 else if (strstr (name, ".rs"))
1385 return 34;
1386 else if (strstr (name, ".mc"))
1387 return 35;
1388 else if (strstr (name, ".it"))
1389 return 36;
1390 else if (strstr (name, ".id"))
1391 return 37;
1392 else if (strstr (name, ".da"))
1393 return 38;
1394 else if (strstr (name, ".dd"))
1395 return 39;
1396 else if (strstr (name, ".ss"))
1397 return 40;
1398 else if (strstr (name, ".ri"))
1399 return 41;
1400 else if (strstr (name, ".ed"))
1401 return 43;
1402 else if (strstr (name, ".bn"))
1403 return 44;
1404 else if (strstr (name, ".ia"))
1405 return 45;
1406 else
1407 abort ();
1408 default:
1409 break;
1410 }
1411 return REG_NONE;
1412 }
1413
1414 static int
lookup_specifier(const char * name)1415 lookup_specifier (const char *name)
1416 {
1417 if (strchr (name, '%'))
1418 {
1419 if (strstr (name, "AR[K%]") != NULL)
1420 return IA64_RS_AR_K;
1421 if (strstr (name, "AR[UNAT]") != NULL)
1422 return IA64_RS_AR_UNAT;
1423 if (strstr (name, "AR%, % in 8") != NULL)
1424 return IA64_RS_AR;
1425 if (strstr (name, "AR%, % in 48") != NULL)
1426 return IA64_RS_ARb;
1427 if (strstr (name, "BR%") != NULL)
1428 return IA64_RS_BR;
1429 if (strstr (name, "CR[IRR%]") != NULL)
1430 return IA64_RS_CR_IRR;
1431 if (strstr (name, "CR[LRR%]") != NULL)
1432 return IA64_RS_CR_LRR;
1433 if (strstr (name, "CR%") != NULL)
1434 return IA64_RS_CR;
1435 if (strstr (name, "FR%, % in 0") != NULL)
1436 return IA64_RS_FR;
1437 if (strstr (name, "FR%, % in 2") != NULL)
1438 return IA64_RS_FRb;
1439 if (strstr (name, "GR%") != NULL)
1440 return IA64_RS_GR;
1441 if (strstr (name, "PR%, % in 1 ") != NULL)
1442 return IA64_RS_PR;
1443 if (strstr (name, "PR%, % in 16 ") != NULL)
1444 return IA64_RS_PRr;
1445
1446 warn (_("don't know how to specify %% dependency %s\n"),
1447 name);
1448 }
1449 else if (strchr (name, '#'))
1450 {
1451 if (strstr (name, "CPUID#") != NULL)
1452 return IA64_RS_CPUID;
1453 if (strstr (name, "DBR#") != NULL)
1454 return IA64_RS_DBR;
1455 if (strstr (name, "IBR#") != NULL)
1456 return IA64_RS_IBR;
1457 if (strstr (name, "MSR#") != NULL)
1458 return IA64_RS_MSR;
1459 if (strstr (name, "PKR#") != NULL)
1460 return IA64_RS_PKR;
1461 if (strstr (name, "PMC#") != NULL)
1462 return IA64_RS_PMC;
1463 if (strstr (name, "PMD#") != NULL)
1464 return IA64_RS_PMD;
1465 if (strstr (name, "RR#") != NULL)
1466 return IA64_RS_RR;
1467
1468 warn (_("Don't know how to specify # dependency %s\n"),
1469 name);
1470 }
1471 else if (strncmp (name, "AR[FPSR]", 8) == 0)
1472 return IA64_RS_AR_FPSR;
1473 else if (strncmp (name, "AR[", 3) == 0)
1474 return IA64_RS_ARX;
1475 else if (strncmp (name, "CR[", 3) == 0)
1476 return IA64_RS_CRX;
1477 else if (strncmp (name, "PSR.", 4) == 0)
1478 return IA64_RS_PSR;
1479 else if (strcmp (name, "InService*") == 0)
1480 return IA64_RS_INSERVICE;
1481 else if (strcmp (name, "GR0") == 0)
1482 return IA64_RS_GR0;
1483 else if (strcmp (name, "CFM") == 0)
1484 return IA64_RS_CFM;
1485 else if (strcmp (name, "PR63") == 0)
1486 return IA64_RS_PR63;
1487 else if (strcmp (name, "RSE") == 0)
1488 return IA64_RS_RSE;
1489
1490 return IA64_RS_ANY;
1491 }
1492
1493 static void
print_dependency_table()1494 print_dependency_table ()
1495 {
1496 int i, j;
1497
1498 if (debug)
1499 {
1500 for (i=0;i < iclen;i++)
1501 {
1502 if (ics[i]->is_class)
1503 {
1504 if (!ics[i]->nsubs)
1505 {
1506 if (ics[i]->comment)
1507 warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1508 ics[i]->name, ics[i]->comment);
1509 else
1510 warn (_("IC:%s has no terminals or sub-classes\n"),
1511 ics[i]->name);
1512 }
1513 }
1514 else
1515 {
1516 if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1517 {
1518 if (ics[i]->comment)
1519 warn (_("no insns mapped directly to terminal IC %s [%s]"),
1520 ics[i]->name, ics[i]->comment);
1521 else
1522 warn (_("no insns mapped directly to terminal IC %s\n"),
1523 ics[i]->name);
1524 }
1525 }
1526 }
1527
1528 for (i = 0; i < iclen; i++)
1529 {
1530 if (ics[i]->orphan)
1531 {
1532 mark_used (ics[i], 1);
1533 warn (_("class %s is defined but not used\n"),
1534 ics[i]->name);
1535 }
1536 }
1537
1538 if (debug > 1)
1539 for (i = 0; i < rdepslen; i++)
1540 {
1541 static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1542
1543 if (rdeps[i]->total_chks == 0)
1544 warn (_("Warning: rsrc %s (%s) has no chks%s\n"),
1545 rdeps[i]->name, mode_str[rdeps[i]->mode],
1546 rdeps[i]->total_regs ? "" : " or regs");
1547 else if (rdeps[i]->total_regs == 0)
1548 warn (_("rsrc %s (%s) has no regs\n"),
1549 rdeps[i]->name, mode_str[rdeps[i]->mode]);
1550 }
1551 }
1552
1553 /* The dependencies themselves. */
1554 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1555 for (i = 0; i < rdepslen; i++)
1556 {
1557 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1558 resource used. */
1559 int specifier = lookup_specifier (rdeps[i]->name);
1560 int regindex = lookup_regindex (rdeps[i]->name, specifier);
1561
1562 printf (" { \"%s\", %d, %d, %d, %d, ",
1563 rdeps[i]->name, specifier,
1564 (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1565 if (rdeps[i]->semantics == IA64_DVS_OTHER)
1566 printf ("\"%s\", ", rdeps[i]->extra);
1567 else
1568 printf ("NULL, ");
1569 printf("},\n");
1570 }
1571 printf ("};\n\n");
1572
1573 /* And dependency lists. */
1574 for (i=0;i < dlistlen;i++)
1575 {
1576 int len = 2;
1577 printf ("static const unsigned short dep%d[] = {\n ", i);
1578 for (j=0;j < dlists[i]->len; j++)
1579 {
1580 len += printf ("%d, ", dlists[i]->deps[j]);
1581 if (len > 75)
1582 {
1583 printf("\n ");
1584 len = 2;
1585 }
1586 }
1587 printf ("\n};\n\n");
1588 }
1589
1590 /* And opcode dependency list. */
1591 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1592 printf ("static const struct ia64_opcode_dependency\n");
1593 printf ("op_dependencies[] = {\n");
1594 for (i = 0; i < opdeplen; i++)
1595 {
1596 printf (" { ");
1597 if (opdeps[i]->chk == -1)
1598 printf ("0, NULL, ");
1599 else
1600 printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1601 if (opdeps[i]->reg == -1)
1602 printf ("0, NULL, ");
1603 else
1604 printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1605 printf ("},\n");
1606 }
1607 printf ("};\n\n");
1608 }
1609
1610
1611 /* Add STR to the string table. */
1612 static struct string_entry *
insert_string(char * str)1613 insert_string (char *str)
1614 {
1615 int start = 0, end = strtablen;
1616 int i, x;
1617
1618 if (strtablen == strtabtotlen)
1619 {
1620 strtabtotlen += 20;
1621 string_table = (struct string_entry **)
1622 xrealloc (string_table,
1623 sizeof (struct string_entry **) * strtabtotlen);
1624 }
1625
1626 if (strtablen == 0)
1627 {
1628 strtablen = 1;
1629 string_table[0] = tmalloc (struct string_entry);
1630 string_table[0]->s = xstrdup (str);
1631 string_table[0]->num = 0;
1632 return string_table[0];
1633 }
1634
1635 if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1636 i = end;
1637 else if (strcmp (str, string_table[0]->s) < 0)
1638 i = 0;
1639 else
1640 {
1641 while (1)
1642 {
1643 int c;
1644
1645 i = (start + end) / 2;
1646 c = strcmp (str, string_table[i]->s);
1647
1648 if (c < 0)
1649 end = i - 1;
1650 else if (c == 0)
1651 return string_table[i];
1652 else
1653 start = i + 1;
1654
1655 if (start > end)
1656 break;
1657 }
1658 }
1659
1660 for (; i > 0 && i < strtablen; i--)
1661 if (strcmp (str, string_table[i - 1]->s) > 0)
1662 break;
1663
1664 for (; i < strtablen; i++)
1665 if (strcmp (str, string_table[i]->s) < 0)
1666 break;
1667
1668 for (x = strtablen - 1; x >= i; x--)
1669 {
1670 string_table[x + 1] = string_table[x];
1671 string_table[x + 1]->num = x + 1;
1672 }
1673
1674 string_table[i] = tmalloc (struct string_entry);
1675 string_table[i]->s = xstrdup (str);
1676 string_table[i]->num = i;
1677 strtablen++;
1678
1679 return string_table[i];
1680 }
1681
1682 static struct bittree *
make_bittree_entry(void)1683 make_bittree_entry (void)
1684 {
1685 struct bittree *res = tmalloc (struct bittree);
1686
1687 res->disent = NULL;
1688 res->bits[0] = NULL;
1689 res->bits[1] = NULL;
1690 res->bits[2] = NULL;
1691 res->skip_flag = 0;
1692 res->bits_to_skip = 0;
1693 return res;
1694 }
1695
1696
1697 static struct disent *
add_dis_table_ent(which,insn,order,completer_index)1698 add_dis_table_ent (which, insn, order, completer_index)
1699 struct disent *which;
1700 int insn;
1701 int order;
1702 int completer_index;
1703 {
1704 int ci = 0;
1705 struct disent *ent;
1706
1707 if (which != NULL)
1708 {
1709 ent = which;
1710
1711 ent->nextcnt++;
1712 while (ent->nexte != NULL)
1713 ent = ent->nexte;
1714
1715 ent = (ent->nexte = tmalloc (struct disent));
1716 }
1717 else
1718 {
1719 ent = tmalloc (struct disent);
1720 ent->next_ent = disinsntable;
1721 disinsntable = ent;
1722 which = ent;
1723 }
1724 ent->nextcnt = 0;
1725 ent->nexte = NULL;
1726 ent->insn = insn;
1727 ent->priority = order;
1728
1729 while (completer_index != 1)
1730 {
1731 ci = (ci << 1) | (completer_index & 1);
1732 completer_index >>= 1;
1733 }
1734 ent->completer_index = ci;
1735 return which;
1736 }
1737
1738 static void
finish_distable()1739 finish_distable ()
1740 {
1741 struct disent *ent = disinsntable;
1742 struct disent *prev = ent;
1743
1744 ent->ournum = 32768;
1745 while ((ent = ent->next_ent) != NULL)
1746 {
1747 ent->ournum = prev->ournum + prev->nextcnt + 1;
1748 prev = ent;
1749 }
1750 }
1751
1752 static void
insert_bit_table_ent(curr_ent,bit,opcode,mask,opcodenum,order,completer_index)1753 insert_bit_table_ent (curr_ent, bit, opcode, mask,
1754 opcodenum, order, completer_index)
1755 struct bittree *curr_ent;
1756 int bit;
1757 ia64_insn opcode;
1758 ia64_insn mask;
1759 int opcodenum;
1760 int order;
1761 int completer_index;
1762 {
1763 ia64_insn m;
1764 int b;
1765 struct bittree *next;
1766
1767 if (bit == -1)
1768 {
1769 struct disent *nent = add_dis_table_ent (curr_ent->disent,
1770 opcodenum, order,
1771 completer_index);
1772 curr_ent->disent = nent;
1773 return;
1774 }
1775
1776 m = ((ia64_insn) 1) << bit;
1777
1778 if (mask & m)
1779 b = (opcode & m) ? 1 : 0;
1780 else
1781 b = 2;
1782
1783 next = curr_ent->bits[b];
1784 if (next == NULL)
1785 {
1786 next = make_bittree_entry ();
1787 curr_ent->bits[b] = next;
1788 }
1789 insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1790 completer_index);
1791 }
1792
1793 static void
add_dis_entry(first,opcode,mask,opcodenum,ent,completer_index)1794 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1795 struct bittree *first;
1796 ia64_insn opcode;
1797 ia64_insn mask;
1798 int opcodenum;
1799 struct completer_entry *ent;
1800 int completer_index;
1801 {
1802 if (completer_index & (1 << 20))
1803 abort ();
1804
1805 while (ent != NULL)
1806 {
1807 ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1808 add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1809 (completer_index << 1) | 1);
1810
1811 if (ent->is_terminal)
1812 {
1813 insert_bit_table_ent (bittree, 40, newopcode, mask,
1814 opcodenum, opcode_count - ent->order - 1,
1815 (completer_index << 1) | 1);
1816 }
1817 completer_index <<= 1;
1818 ent = ent->alternative;
1819 }
1820 }
1821
1822 /* This optimization pass combines multiple "don't care" nodes. */
1823 static void
compact_distree(ent)1824 compact_distree (ent)
1825 struct bittree *ent;
1826 {
1827 #define IS_SKIP(ent) \
1828 ((ent->bits[2] !=NULL) \
1829 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1830
1831 int bitcnt = 0;
1832 struct bittree *nent = ent;
1833 int x;
1834
1835 while (IS_SKIP (nent))
1836 {
1837 bitcnt++;
1838 nent = nent->bits[2];
1839 }
1840
1841 if (bitcnt)
1842 {
1843 struct bittree *next = ent->bits[2];
1844
1845 ent->bits[0] = nent->bits[0];
1846 ent->bits[1] = nent->bits[1];
1847 ent->bits[2] = nent->bits[2];
1848 ent->disent = nent->disent;
1849 ent->skip_flag = 1;
1850 ent->bits_to_skip = bitcnt;
1851 while (next != nent)
1852 {
1853 struct bittree *b = next;
1854 next = next->bits[2];
1855 free (b);
1856 }
1857 free (nent);
1858 }
1859
1860 for (x = 0; x < 3; x++)
1861 {
1862 struct bittree *i = ent->bits[x];
1863
1864 if (i != NULL)
1865 compact_distree (i);
1866 }
1867 }
1868
1869 static unsigned char *insn_list;
1870 static int insn_list_len = 0;
1871 static int tot_insn_list_len = 0;
1872
1873 /* Generate the disassembler state machine corresponding to the tree
1874 in ENT. */
1875 static void
gen_dis_table(ent)1876 gen_dis_table (ent)
1877 struct bittree *ent;
1878 {
1879 int x;
1880 int our_offset = insn_list_len;
1881 int bitsused = 5;
1882 int totbits = bitsused;
1883 int needed_bytes;
1884 int zero_count = 0;
1885 int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */
1886
1887 /* If this is a terminal entry, there's no point in skipping any
1888 bits. */
1889 if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1890 ent->bits[2] == NULL)
1891 {
1892 if (ent->disent == NULL)
1893 abort ();
1894 else
1895 ent->skip_flag = 0;
1896 }
1897
1898 /* Calculate the amount of space needed for this entry, or at least
1899 a conservatively large approximation. */
1900 if (ent->skip_flag)
1901 totbits += 5;
1902
1903 for (x = 1; x < 3; x++)
1904 if (ent->bits[x] != NULL)
1905 totbits += 16;
1906
1907 if (ent->disent != NULL)
1908 {
1909 if (ent->bits[2] != NULL)
1910 abort ();
1911
1912 totbits += 16;
1913 }
1914
1915 /* Now allocate the space. */
1916 needed_bytes = (totbits + 7) / 8;
1917 if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1918 {
1919 tot_insn_list_len += 256;
1920 insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
1921 }
1922 our_offset = insn_list_len;
1923 insn_list_len += needed_bytes;
1924 memset (insn_list + our_offset, 0, needed_bytes);
1925
1926 /* Encode the skip entry by setting bit 6 set in the state op field,
1927 and store the # of bits to skip immediately after. */
1928 if (ent->skip_flag)
1929 {
1930 bitsused += 5;
1931 insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1932 insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1933 }
1934
1935 #define IS_ONLY_IFZERO(ENT) \
1936 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1937 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1938
1939 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1940 state op field. */
1941 if (ent->bits[0] != NULL)
1942 {
1943 struct bittree *nent = ent->bits[0];
1944 zero_count = 0;
1945
1946 insn_list[our_offset] |= 0x80;
1947
1948 /* We can encode sequences of multiple "if (bit is zero)" tests
1949 by storing the # of zero bits to check in the lower 3 bits of
1950 the instruction. However, this only applies if the state
1951 solely tests for a zero bit. */
1952
1953 if (IS_ONLY_IFZERO (ent))
1954 {
1955 while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1956 {
1957 nent = nent->bits[0];
1958 zero_count++;
1959 }
1960
1961 insn_list[our_offset + 0] |= zero_count;
1962 }
1963 zero_dest = insn_list_len;
1964 gen_dis_table (nent);
1965 }
1966
1967 /* Now store the remaining tests. We also handle a sole "termination
1968 entry" by storing it as an "any bit" test. */
1969
1970 for (x = 1; x < 3; x++)
1971 {
1972 if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1973 {
1974 struct bittree *i = ent->bits[x];
1975 int idest;
1976 int currbits = 15;
1977
1978 if (i != NULL)
1979 {
1980 /* If the instruction being branched to only consists of
1981 a termination entry, use the termination entry as the
1982 place to branch to instead. */
1983 if (i->bits[0] == NULL && i->bits[1] == NULL
1984 && i->bits[2] == NULL && i->disent != NULL)
1985 {
1986 idest = i->disent->ournum;
1987 i = NULL;
1988 }
1989 else
1990 idest = insn_list_len - our_offset;
1991 }
1992 else
1993 idest = ent->disent->ournum;
1994
1995 /* If the destination offset for the if (bit is 1) test is less
1996 than 256 bytes away, we can store it as 8-bits instead of 16;
1997 the instruction has bit 5 set for the 16-bit address, and bit
1998 4 for the 8-bit address. Since we've already allocated 16
1999 bits for the address we need to deallocate the space.
2000
2001 Note that branchings within the table are relative, and
2002 there are no branches that branch past our instruction yet
2003 so we do not need to adjust any other offsets. */
2004 if (x == 1)
2005 {
2006 if (idest <= 256)
2007 {
2008 int start = our_offset + bitsused / 8 + 1;
2009
2010 memmove (insn_list + start,
2011 insn_list + start + 1,
2012 insn_list_len - (start + 1));
2013 currbits = 7;
2014 totbits -= 8;
2015 needed_bytes--;
2016 insn_list_len--;
2017 insn_list[our_offset] |= 0x10;
2018 idest--;
2019 }
2020 else
2021 insn_list[our_offset] |= 0x20;
2022 }
2023 else
2024 {
2025 /* An instruction which solely consists of a termination
2026 marker and whose disassembly name index is < 4096
2027 can be stored in 16 bits. The encoding is slightly
2028 odd; the upper 4 bits of the instruction are 0x3, and
2029 bit 3 loses its normal meaning. */
2030
2031 if (ent->bits[0] == NULL && ent->bits[1] == NULL
2032 && ent->bits[2] == NULL && ent->skip_flag == 0
2033 && ent->disent != NULL
2034 && ent->disent->ournum < (32768 + 4096))
2035 {
2036 int start = our_offset + bitsused / 8 + 1;
2037
2038 memmove (insn_list + start,
2039 insn_list + start + 1,
2040 insn_list_len - (start + 1));
2041 currbits = 11;
2042 totbits -= 5;
2043 bitsused--;
2044 needed_bytes--;
2045 insn_list_len--;
2046 insn_list[our_offset] |= 0x30;
2047 idest &= ~32768;
2048 }
2049 else
2050 insn_list[our_offset] |= 0x08;
2051 }
2052
2053 if (debug)
2054 {
2055 int id = idest;
2056
2057 if (i == NULL)
2058 id |= 32768;
2059 else if (! (id & 32768))
2060 id += our_offset;
2061
2062 if (x == 1)
2063 printf ("%d: if (1) goto %d\n", our_offset, id);
2064 else
2065 printf ("%d: try %d\n", our_offset, id);
2066 }
2067
2068 /* Store the address of the entry being branched to. */
2069 while (currbits >= 0)
2070 {
2071 unsigned char *byte = insn_list + our_offset + bitsused / 8;
2072
2073 if (idest & (1 << currbits))
2074 *byte |= (1 << (7 - (bitsused % 8)));
2075
2076 bitsused++;
2077 currbits--;
2078 }
2079
2080 /* Now generate the states for the entry being branched to. */
2081 if (i != NULL)
2082 gen_dis_table (i);
2083 }
2084 }
2085
2086 if (debug)
2087 {
2088 if (ent->skip_flag)
2089 printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2090
2091 if (ent->bits[0] != NULL)
2092 printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2093 zero_dest);
2094 }
2095
2096 if (bitsused != totbits)
2097 abort ();
2098 }
2099
2100 static void
print_dis_table(void)2101 print_dis_table (void)
2102 {
2103 int x;
2104 struct disent *cent = disinsntable;
2105
2106 printf ("static const char dis_table[] = {\n");
2107 for (x = 0; x < insn_list_len; x++)
2108 {
2109 if ((x > 0) && ((x % 12) == 0))
2110 printf ("\n");
2111
2112 printf ("0x%02x, ", insn_list[x]);
2113 }
2114 printf ("\n};\n\n");
2115
2116 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2117 while (cent != NULL)
2118 {
2119 struct disent *ent = cent;
2120
2121 while (ent != NULL)
2122 {
2123 printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2124 ent->insn, (ent->nexte != NULL ? 1 : 0),
2125 ent->priority);
2126 ent = ent->nexte;
2127 }
2128 cent = cent->next_ent;
2129 }
2130 printf ("};\n\n");
2131 }
2132
2133 static void
generate_disassembler(void)2134 generate_disassembler (void)
2135 {
2136 int i;
2137
2138 bittree = make_bittree_entry ();
2139
2140 for (i = 0; i < otlen; i++)
2141 {
2142 struct main_entry *ptr = ordered_table[i];
2143
2144 if (ptr->opcode->type != IA64_TYPE_DYN)
2145 add_dis_entry (bittree,
2146 ptr->opcode->opcode, ptr->opcode->mask,
2147 ptr->main_index,
2148 ptr->completers, 1);
2149 }
2150
2151 compact_distree (bittree);
2152 finish_distable ();
2153 gen_dis_table (bittree);
2154
2155 print_dis_table ();
2156 }
2157
2158 static void
print_string_table(void)2159 print_string_table (void)
2160 {
2161 int x;
2162 char lbuf[80], buf[80];
2163 int blen = 0;
2164
2165 printf ("static const char * const ia64_strings[] = {\n");
2166 lbuf[0] = '\0';
2167
2168 for (x = 0; x < strtablen; x++)
2169 {
2170 int len;
2171
2172 if (strlen (string_table[x]->s) > 75)
2173 abort ();
2174
2175 sprintf (buf, " \"%s\",", string_table[x]->s);
2176 len = strlen (buf);
2177
2178 if ((blen + len) > 75)
2179 {
2180 printf (" %s\n", lbuf);
2181 lbuf[0] = '\0';
2182 blen = 0;
2183 }
2184 strcat (lbuf, buf);
2185 blen += len;
2186 }
2187
2188 if (blen > 0)
2189 printf (" %s\n", lbuf);
2190
2191 printf ("};\n\n");
2192 }
2193
2194 static struct completer_entry **glist;
2195 static int glistlen = 0;
2196 static int glisttotlen = 0;
2197
2198 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2199
2200 static int
completer_entries_eq(ent1,ent2)2201 completer_entries_eq (ent1, ent2)
2202 struct completer_entry *ent1, *ent2;
2203 {
2204 while (ent1 != NULL && ent2 != NULL)
2205 {
2206 if (ent1->name->num != ent2->name->num
2207 || ent1->bits != ent2->bits
2208 || ent1->mask != ent2->mask
2209 || ent1->is_terminal != ent2->is_terminal
2210 || ent1->dependencies != ent2->dependencies
2211 || ent1->order != ent2->order)
2212 return 0;
2213
2214 if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2215 return 0;
2216
2217 ent1 = ent1->alternative;
2218 ent2 = ent2->alternative;
2219 }
2220
2221 return ent1 == ent2;
2222 }
2223
2224 /* Insert ENT into the global list of completers and return it. If an
2225 equivalent entry (according to completer_entries_eq) already exists,
2226 it is returned instead. */
2227 static struct completer_entry *
insert_gclist(struct completer_entry * ent)2228 insert_gclist (struct completer_entry *ent)
2229 {
2230 if (ent != NULL)
2231 {
2232 int i;
2233 int x;
2234 int start = 0, end;
2235
2236 ent->addl_entries = insert_gclist (ent->addl_entries);
2237 ent->alternative = insert_gclist (ent->alternative);
2238
2239 i = glistlen / 2;
2240 end = glistlen;
2241
2242 if (glisttotlen == glistlen)
2243 {
2244 glisttotlen += 20;
2245 glist = (struct completer_entry **)
2246 xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2247 }
2248
2249 if (glistlen == 0)
2250 {
2251 glist[0] = ent;
2252 glistlen = 1;
2253 return ent;
2254 }
2255
2256 if (ent->name->num < glist[0]->name->num)
2257 i = 0;
2258 else if (ent->name->num > glist[end - 1]->name->num)
2259 i = end;
2260 else
2261 {
2262 int c;
2263
2264 while (1)
2265 {
2266 i = (start + end) / 2;
2267 c = ent->name->num - glist[i]->name->num;
2268
2269 if (c < 0)
2270 end = i - 1;
2271 else if (c == 0)
2272 {
2273 while (i > 0
2274 && ent->name->num == glist[i - 1]->name->num)
2275 i--;
2276
2277 break;
2278 }
2279 else
2280 start = i + 1;
2281
2282 if (start > end)
2283 break;
2284 }
2285
2286 if (c == 0)
2287 {
2288 while (i < glistlen)
2289 {
2290 if (ent->name->num != glist[i]->name->num)
2291 break;
2292
2293 if (completer_entries_eq (ent, glist[i]))
2294 return glist[i];
2295
2296 i++;
2297 }
2298 }
2299 }
2300
2301 for (; i > 0 && i < glistlen; i--)
2302 if (ent->name->num >= glist[i - 1]->name->num)
2303 break;
2304
2305 for (; i < glistlen; i++)
2306 if (ent->name->num < glist[i]->name->num)
2307 break;
2308
2309 for (x = glistlen - 1; x >= i; x--)
2310 glist[x + 1] = glist[x];
2311
2312 glist[i] = ent;
2313 glistlen++;
2314 }
2315 return ent;
2316 }
2317
2318 static int
get_prefix_len(name)2319 get_prefix_len (name)
2320 const char *name;
2321 {
2322 char *c;
2323
2324 if (name[0] == '\0')
2325 return 0;
2326
2327 c = strchr (name, '.');
2328 if (c != NULL)
2329 return c - name;
2330 else
2331 return strlen (name);
2332 }
2333
2334 static void
compute_completer_bits(ment,ent)2335 compute_completer_bits (ment, ent)
2336 struct main_entry *ment;
2337 struct completer_entry *ent;
2338 {
2339 while (ent != NULL)
2340 {
2341 compute_completer_bits (ment, ent->addl_entries);
2342
2343 if (ent->is_terminal)
2344 {
2345 ia64_insn mask = 0;
2346 ia64_insn our_bits = ent->bits;
2347 struct completer_entry *p = ent->parent;
2348 ia64_insn p_bits;
2349 int x;
2350
2351 while (p != NULL && ! p->is_terminal)
2352 p = p->parent;
2353
2354 if (p != NULL)
2355 p_bits = p->bits;
2356 else
2357 p_bits = ment->opcode->opcode;
2358
2359 for (x = 0; x < 64; x++)
2360 {
2361 ia64_insn m = ((ia64_insn) 1) << x;
2362
2363 if ((p_bits & m) != (our_bits & m))
2364 mask |= m;
2365 else
2366 our_bits &= ~m;
2367 }
2368 ent->bits = our_bits;
2369 ent->mask = mask;
2370 }
2371 else
2372 {
2373 ent->bits = 0;
2374 ent->mask = 0;
2375 }
2376
2377 ent = ent->alternative;
2378 }
2379 }
2380
2381 /* Find identical completer trees that are used in different
2382 instructions and collapse their entries. */
2383 static void
collapse_redundant_completers(void)2384 collapse_redundant_completers (void)
2385 {
2386 struct main_entry *ptr;
2387 int x;
2388
2389 for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2390 {
2391 if (ptr->completers == NULL)
2392 abort ();
2393
2394 compute_completer_bits (ptr, ptr->completers);
2395 ptr->completers = insert_gclist (ptr->completers);
2396 }
2397
2398 /* The table has been finalized, now number the indexes. */
2399 for (x = 0; x < glistlen; x++)
2400 glist[x]->num = x;
2401 }
2402
2403
2404 /* Attach two lists of dependencies to each opcode.
2405 1) all resources which, when already marked in use, conflict with this
2406 opcode (chks)
2407 2) all resources which must be marked in use when this opcode is used
2408 (regs). */
2409 static int
insert_opcode_dependencies(opc,cmp)2410 insert_opcode_dependencies (opc, cmp)
2411 struct ia64_opcode *opc;
2412 struct completer_entry *cmp ATTRIBUTE_UNUSED;
2413 {
2414 /* Note all resources which point to this opcode. rfi has the most chks
2415 (79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2416 int i;
2417 int nregs = 0;
2418 unsigned short regs[256];
2419 int nchks = 0;
2420 unsigned short chks[256];
2421 /* Flag insns for which no class matched; there should be none. */
2422 int no_class_found = 1;
2423
2424 for (i = 0; i < rdepslen; i++)
2425 {
2426 struct rdep *rs = rdeps[i];
2427 int j;
2428
2429 if (strcmp (opc->name, "cmp.eq.and") == 0
2430 && strncmp (rs->name, "PR%", 3) == 0
2431 && rs->mode == 1)
2432 no_class_found = 99;
2433
2434 for (j=0; j < rs->nregs;j++)
2435 {
2436 int ic_note = 0;
2437
2438 if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2439 {
2440 /* We can ignore ic_note 11 for non PR resources. */
2441 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2442 ic_note = 0;
2443
2444 if (ic_note != 0 && rs->regnotes[j] != 0
2445 && ic_note != rs->regnotes[j]
2446 && !(ic_note == 11 && rs->regnotes[j] == 1))
2447 warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2448 ic_note, opc->name, ics[rs->regs[j]]->name,
2449 rs->name, rs->regnotes[j]);
2450 /* Instruction class notes override resource notes.
2451 So far, only note 11 applies to an IC instead of a resource,
2452 and note 11 implies note 1. */
2453 if (ic_note)
2454 regs[nregs++] = RDEP(ic_note, i);
2455 else
2456 regs[nregs++] = RDEP(rs->regnotes[j], i);
2457 no_class_found = 0;
2458 ++rs->total_regs;
2459 }
2460 }
2461
2462 for (j = 0; j < rs->nchks; j++)
2463 {
2464 int ic_note = 0;
2465
2466 if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2467 {
2468 /* We can ignore ic_note 11 for non PR resources. */
2469 if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2470 ic_note = 0;
2471
2472 if (ic_note != 0 && rs->chknotes[j] != 0
2473 && ic_note != rs->chknotes[j]
2474 && !(ic_note == 11 && rs->chknotes[j] == 1))
2475 warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2476 ic_note, opc->name, ics[rs->chks[j]]->name,
2477 rs->name, rs->chknotes[j]);
2478 if (ic_note)
2479 chks[nchks++] = RDEP(ic_note, i);
2480 else
2481 chks[nchks++] = RDEP(rs->chknotes[j], i);
2482 no_class_found = 0;
2483 ++rs->total_chks;
2484 }
2485 }
2486 }
2487
2488 if (no_class_found)
2489 warn (_("opcode %s has no class (ops %d %d %d)\n"),
2490 opc->name,
2491 opc->operands[0], opc->operands[1], opc->operands[2]);
2492
2493 return insert_dependencies (nchks, chks, nregs, regs);
2494 }
2495
2496 static void
insert_completer_entry(opc,tabent,order)2497 insert_completer_entry (opc, tabent, order)
2498 struct ia64_opcode *opc;
2499 struct main_entry *tabent;
2500 int order;
2501 {
2502 struct completer_entry **ptr = &tabent->completers;
2503 struct completer_entry *parent = NULL;
2504 char pcopy[129], *prefix;
2505 int at_end = 0;
2506
2507 if (strlen (opc->name) > 128)
2508 abort ();
2509
2510 strcpy (pcopy, opc->name);
2511 prefix = pcopy + get_prefix_len (pcopy);
2512
2513 if (prefix[0] != '\0')
2514 prefix++;
2515
2516 while (! at_end)
2517 {
2518 int need_new_ent = 1;
2519 int plen = get_prefix_len (prefix);
2520 struct string_entry *sent;
2521
2522 at_end = (prefix[plen] == '\0');
2523 prefix[plen] = '\0';
2524 sent = insert_string (prefix);
2525
2526 while (*ptr != NULL)
2527 {
2528 int cmpres = sent->num - (*ptr)->name->num;
2529
2530 if (cmpres == 0)
2531 {
2532 need_new_ent = 0;
2533 break;
2534 }
2535 else
2536 ptr = &((*ptr)->alternative);
2537 }
2538
2539 if (need_new_ent)
2540 {
2541 struct completer_entry *nent = tmalloc (struct completer_entry);
2542
2543 nent->name = sent;
2544 nent->parent = parent;
2545 nent->addl_entries = NULL;
2546 nent->alternative = *ptr;
2547 *ptr = nent;
2548 nent->is_terminal = 0;
2549 nent->dependencies = -1;
2550 }
2551
2552 if (! at_end)
2553 {
2554 parent = *ptr;
2555 ptr = &((*ptr)->addl_entries);
2556 prefix += plen + 1;
2557 }
2558 }
2559
2560 if ((*ptr)->is_terminal)
2561 abort ();
2562
2563 (*ptr)->is_terminal = 1;
2564 (*ptr)->mask = (ia64_insn)-1;
2565 (*ptr)->bits = opc->opcode;
2566 (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2567 (*ptr)->order = order;
2568 }
2569
2570 static void
print_completer_entry(ent)2571 print_completer_entry (ent)
2572 struct completer_entry *ent;
2573 {
2574 int moffset = 0;
2575 ia64_insn mask = ent->mask, bits = ent->bits;
2576
2577 if (mask != 0)
2578 {
2579 while (! (mask & 1))
2580 {
2581 moffset++;
2582 mask = mask >> 1;
2583 bits = bits >> 1;
2584 }
2585
2586 if (bits & 0xffffffff00000000LL)
2587 abort ();
2588 }
2589
2590 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2591 (int)bits,
2592 (int)mask,
2593 ent->name->num,
2594 ent->alternative != NULL ? ent->alternative->num : -1,
2595 ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2596 moffset,
2597 ent->is_terminal ? 1 : 0,
2598 ent->dependencies);
2599 }
2600
2601 static void
print_completer_table()2602 print_completer_table ()
2603 {
2604 int x;
2605
2606 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2607 for (x = 0; x < glistlen; x++)
2608 print_completer_entry (glist[x]);
2609 printf ("};\n\n");
2610 }
2611
2612 static int
opcodes_eq(opc1,opc2)2613 opcodes_eq (opc1, opc2)
2614 struct ia64_opcode *opc1;
2615 struct ia64_opcode *opc2;
2616 {
2617 int x;
2618 int plen1, plen2;
2619
2620 if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2621 || (opc1->num_outputs != opc2->num_outputs)
2622 || (opc1->flags != opc2->flags))
2623 return 0;
2624
2625 for (x = 0; x < 5; x++)
2626 if (opc1->operands[x] != opc2->operands[x])
2627 return 0;
2628
2629 plen1 = get_prefix_len (opc1->name);
2630 plen2 = get_prefix_len (opc2->name);
2631
2632 if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2633 return 1;
2634
2635 return 0;
2636 }
2637
2638 static void
add_opcode_entry(opc)2639 add_opcode_entry (opc)
2640 struct ia64_opcode *opc;
2641 {
2642 struct main_entry **place;
2643 struct string_entry *name;
2644 char prefix[129];
2645 int found_it = 0;
2646
2647 if (strlen (opc->name) > 128)
2648 abort ();
2649
2650 place = &maintable;
2651 strcpy (prefix, opc->name);
2652 prefix[get_prefix_len (prefix)] = '\0';
2653 name = insert_string (prefix);
2654
2655 /* Walk the list of opcode table entries. If it's a new
2656 instruction, allocate and fill in a new entry. Note
2657 the main table is alphabetical by opcode name. */
2658
2659 while (*place != NULL)
2660 {
2661 if ((*place)->name->num == name->num
2662 && opcodes_eq ((*place)->opcode, opc))
2663 {
2664 found_it = 1;
2665 break;
2666 }
2667 if ((*place)->name->num > name->num)
2668 break;
2669
2670 place = &((*place)->next);
2671 }
2672 if (! found_it)
2673 {
2674 struct main_entry *nent = tmalloc (struct main_entry);
2675
2676 nent->name = name;
2677 nent->opcode = opc;
2678 nent->next = *place;
2679 nent->completers = 0;
2680 *place = nent;
2681
2682 if (otlen == ottotlen)
2683 {
2684 ottotlen += 20;
2685 ordered_table = (struct main_entry **)
2686 xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2687 }
2688 ordered_table[otlen++] = nent;
2689 }
2690
2691 insert_completer_entry (opc, *place, opcode_count++);
2692 }
2693
2694 static void
print_main_table(void)2695 print_main_table (void)
2696 {
2697 struct main_entry *ptr = maintable;
2698 int index = 0;
2699
2700 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2701 while (ptr != NULL)
2702 {
2703 printf (" { %d, %d, %d, 0x",
2704 ptr->name->num,
2705 ptr->opcode->type,
2706 ptr->opcode->num_outputs);
2707 fprintf_vma (stdout, ptr->opcode->opcode);
2708 printf ("ull, 0x");
2709 fprintf_vma (stdout, ptr->opcode->mask);
2710 printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2711 ptr->opcode->operands[0],
2712 ptr->opcode->operands[1],
2713 ptr->opcode->operands[2],
2714 ptr->opcode->operands[3],
2715 ptr->opcode->operands[4],
2716 ptr->opcode->flags,
2717 ptr->completers->num);
2718
2719 ptr->main_index = index++;
2720
2721 ptr = ptr->next;
2722 }
2723 printf ("};\n\n");
2724 }
2725
2726 static void
shrink(table)2727 shrink (table)
2728 struct ia64_opcode *table;
2729 {
2730 int curr_opcode;
2731
2732 for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2733 {
2734 add_opcode_entry (table + curr_opcode);
2735 if (table[curr_opcode].num_outputs == 2
2736 && ((table[curr_opcode].operands[0] == IA64_OPND_P1
2737 && table[curr_opcode].operands[1] == IA64_OPND_P2)
2738 || (table[curr_opcode].operands[0] == IA64_OPND_P2
2739 && table[curr_opcode].operands[1] == IA64_OPND_P1)))
2740 {
2741 struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2742 unsigned i;
2743
2744 *alias = table[curr_opcode];
2745 for (i = 2; i < NELEMS (alias->operands); ++i)
2746 alias->operands[i - 1] = alias->operands[i];
2747 alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2748 --alias->num_outputs;
2749 alias->flags |= PSEUDO;
2750 add_opcode_entry (alias);
2751 }
2752 }
2753 }
2754
2755
2756 /* Program options. */
2757 #define OPTION_SRCDIR 200
2758
2759 struct option long_options[] =
2760 {
2761 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
2762 {"debug", no_argument, NULL, 'd'},
2763 {"version", no_argument, NULL, 'V'},
2764 {"help", no_argument, NULL, 'h'},
2765 {0, no_argument, NULL, 0}
2766 };
2767
2768 static void
print_version(void)2769 print_version (void)
2770 {
2771 printf ("%s: version 1.0\n", program_name);
2772 xexit (0);
2773 }
2774
2775 static void
usage(FILE * stream,int status)2776 usage (FILE * stream, int status)
2777 {
2778 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2779 program_name);
2780 xexit (status);
2781 }
2782
2783 int
main(int argc,char ** argv)2784 main (int argc, char **argv)
2785 {
2786 extern int chdir (char *);
2787 char *srcdir = NULL;
2788 int c;
2789
2790 program_name = *argv;
2791 xmalloc_set_program_name (program_name);
2792
2793 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2794 switch (c)
2795 {
2796 case OPTION_SRCDIR:
2797 srcdir = optarg;
2798 break;
2799 case 'V':
2800 case 'v':
2801 print_version ();
2802 break;
2803 case 'd':
2804 debug = 1;
2805 break;
2806 case 'h':
2807 case '?':
2808 usage (stderr, 0);
2809 default:
2810 case 0:
2811 break;
2812 }
2813
2814 if (optind != argc)
2815 usage (stdout, 1);
2816
2817 if (srcdir != NULL)
2818 if (chdir (srcdir) != 0)
2819 fail (_("unable to change directory to \"%s\", errno = %s\n"),
2820 srcdir, strerror (errno));
2821
2822 load_insn_classes ();
2823 load_dependencies ();
2824
2825 shrink (ia64_opcodes_a);
2826 shrink (ia64_opcodes_b);
2827 shrink (ia64_opcodes_f);
2828 shrink (ia64_opcodes_i);
2829 shrink (ia64_opcodes_m);
2830 shrink (ia64_opcodes_x);
2831 shrink (ia64_opcodes_d);
2832
2833 collapse_redundant_completers ();
2834
2835 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2836 print_string_table ();
2837 print_dependency_table ();
2838 print_completer_table ();
2839 print_main_table ();
2840
2841 generate_disassembler ();
2842
2843 exit (0);
2844 }
2845