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