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