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