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