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>
5 This file is part of GDB, GAS, and the GNU binutils.
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.
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.
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
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.
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
32 The resource table is constructed based on some text dependency tables,
33 which are also easier to maintain than the final representation.
41 #include "libiberty.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"
54 #define tmalloc(X) (X *) xmalloc (sizeof (X))
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
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
;
73 /* The set of possible completers for an opcode. */
74 struct completer_entry
76 /* This entry's index in the ia64_completer_table[] array. */
79 /* The name of the completer. */
80 struct string_entry
*name
;
82 /* This entry's parent. */
83 struct completer_entry
*parent
;
85 /* Set if this is a terminal completer (occurs at the end of an
89 /* An alternative completer. */
90 struct completer_entry
*alternative
;
92 /* Additional completers that can be appended to this one. */
93 struct completer_entry
*addl_entries
;
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
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 (). */
107 /* Index into the opcode dependency list, or -1 if none */
111 /* One entry in the disassembler name table. */
114 /* The index into the ia64_name_dis array for this entry. */
117 /* The index into the main_table[] array. */
120 /* The completer_index value for this entry. */
123 /* How many other entries share this decode. */
126 /* The next entry sharing the same decode. */
127 struct disent
*nexte
;
129 /* The next entry in the name list. */
130 struct disent
*next_ent
;
131 } *disinsntable
= NULL
;
133 /* A state machine that will eventually be used to generate the
134 disassembler table. */
137 struct disent
*disent
;
138 struct bittree
*bits
[3];
143 /* The string table contains all opcodes and completers sorted in
144 alphabetical order. */
146 /* One entry in the string table. */
149 /* The index in the ia64_strings[] array for this entry. */
151 /* And the string. */
153 } **string_table
= NULL
;
155 int strtabtotlen
= 0;
158 /* resource dependency entries */
161 char *name
; /* resource name */
163 mode
:2, /* RAW, WAW, or WAR */
164 semantics
:3; /* dependency semantics */
165 char *extra
; /* additional semantics info */
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 */
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 */
177 int waw_special
; /* special WAW dependency note */
180 static int rdepslen
= 0;
181 static int rdepstotlen
= 0;
183 /* array of all instruction classes */
186 char *name
; /* instruction class name */
187 int is_class
; /* is a class, not a terminal */
189 int *subs
; /* other classes within this class */
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 */
198 static int iclen
= 0;
199 static int ictotlen
= 0;
201 /* an opcode dependency (chk/reg pair of dependency lists) */
204 int chk
; /* index into dlists */
205 int reg
; /* index into dlists */
208 static int opdeplen
= 0;
209 static int opdeptotlen
= 0;
211 /* a generic list of dependencies w/notes encoded. these may be shared. */
215 unsigned short *deps
;
218 static int dlistlen
= 0;
219 static int dlisttotlen
= 0;
221 /* add NAME to the resource table, where TYPE is RAW or WAW */
223 insert_resource (const char *name
, enum ia64_dependency_mode type
)
225 if (rdepslen
== rdepstotlen
)
228 rdeps
= (struct rdep
**)
229 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
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;
237 return rdeps
[rdepslen
++];
240 /* are the lists of dependency indexes equivalent? */
242 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
246 if (d1
->len
!= d2
->len
)
249 for (i
=0;i
< d1
->len
;i
++)
251 if (d1
->deps
[i
] != d2
->deps
[i
])
258 /* add the list of dependencies to the list of dependency lists */
260 insert_deplist(int count
, unsigned short *deps
)
262 /* sort the list, then see if an equivalent list exists already.
263 this results in a much smaller set of dependency lists
265 struct deplist
*list
;
269 memset ((void *)set
, 0, sizeof(set
));
270 for (i
=0;i
< count
;i
++)
273 for (i
=0;i
< sizeof(set
);i
++)
277 list
= tmalloc(struct deplist
);
279 list
->deps
= (unsigned short *)malloc (sizeof(unsigned short) * count
);
280 for (i
=0, count
=0;i
< sizeof(set
);i
++)
284 list
->deps
[count
++] = i
;
288 /* does this list exist already? */
289 for (i
=0;i
< dlistlen
;i
++)
291 if (deplist_equals (list
, dlists
[i
]))
299 if (dlistlen
== dlisttotlen
)
302 dlists
= (struct deplist
**)
303 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
305 dlists
[dlistlen
] = list
;
310 /* add the given pair of dependency lists to the opcode dependency list */
312 insert_dependencies (int nchks
, unsigned short *chks
,
313 int nregs
, unsigned short *regs
)
321 regind
= insert_deplist (nregs
, regs
);
323 chkind
= insert_deplist (nchks
, chks
);
325 for (i
=0;i
< opdeplen
;i
++)
327 if (opdeps
[i
]->chk
== chkind
328 && opdeps
[i
]->reg
== regind
)
331 pair
= tmalloc(struct opdep
);
335 if (opdeplen
== opdeptotlen
)
338 opdeps
= (struct opdep
**)
339 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
341 opdeps
[opdeplen
] = pair
;
347 mark_used (struct iclass
*ic
, int clear_terminals
)
353 ic
->terminal_resolved
= 1;
355 for (i
=0;i
< ic
->nsubs
;i
++)
357 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
359 for (i
=0;i
< ic
->nxsubs
;i
++)
361 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
365 /* look up an instruction class; if CREATE make a new one if none found;
366 returns the index into the insn class array */
368 fetch_insn_class(const char *full_name
, int create
)
378 if (strncmp (full_name
, "IC:", 3) == 0)
380 name
= xstrdup (full_name
+ 3);
384 name
= xstrdup (full_name
);
386 if ((xsect
= strchr(name
, '\\')) != NULL
)
388 if ((comment
= strchr(name
, '[')) != NULL
)
390 if ((notestr
= strchr(name
, '+')) != NULL
)
394 note
= atoi (notestr
+ 1);
395 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
397 if (strcmp (notestr
, "+1+13") == 0)
399 else if (!xsect
|| nextnotestr
< xsect
)
400 fprintf (stderr
, "Warning: multiple note %s not handled\n",
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 */
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
)
427 /* doesn't exist, so make a new one */
428 if (iclen
== ictotlen
)
431 ics
= (struct iclass
**)
432 xrealloc(ics
, (ictotlen
)*sizeof(struct iclass
*));
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;
443 ics
[ind
]->comment
= xstrdup (comment
+ 1);
444 ics
[ind
]->comment
[strlen(ics
[ind
]->comment
)-1] = 0;
447 ics
[ind
]->note
= note
;
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
)
453 // first, populate with the class we're based on
454 char *subname
= name
;
462 ics
[ind
]->subs
= tmalloc(int);
463 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
468 char *subname
= xsect
+ 1;
469 xsect
= strchr (subname
, '\\');
472 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
480 /* for sorting a class's sub-class list only; make sure classes appear before
483 sub_compare (const void *e1
, const void *e2
)
485 struct iclass
*ic1
= ics
[*(int *)e1
];
486 struct iclass
*ic2
= ics
[*(int *)e2
];
493 else if (ic2
->is_class
)
496 return strcmp (ic1
->name
, ic2
->name
);
502 FILE *fp
= fopen("ia64-ic.tbl", "r");
505 /* discard first line */
506 fgets (buf
, sizeof(buf
), fp
);
514 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
517 while (isspace(buf
[strlen(buf
)-1]))
518 buf
[strlen(buf
)-1] = '\0';
524 if (tmp
== buf
+ sizeof(buf
))
529 iclass
= fetch_insn_class(name
, 1);
530 ics
[iclass
]->is_class
= 1;
532 if (strcmp (name
, "none") == 0)
534 ics
[iclass
]->is_class
= 0;
535 ics
[iclass
]->terminal_resolved
= 1;
539 /* for this class, record all sub-classes */
545 while (*tmp
&& isspace(*tmp
))
548 if (tmp
== buf
+ sizeof(buf
))
552 while (*tmp
&& *tmp
!= ',')
555 if (tmp
== buf
+ sizeof(buf
))
561 ics
[iclass
]->subs
= (int *)
562 xrealloc((void *)ics
[iclass
]->subs
,
563 (ics
[iclass
]->nsubs
+1)*sizeof(int));
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
;
570 /* make sure classes come before terminals */
571 qsort ((void *)ics
[iclass
]->subs
,
572 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
578 printf ("%d classes\n", iclen
);
582 /* extract the insn classes from the given line */
584 parse_resource_users(ref
, usersp
, nusersp
, notesp
)
591 char *line
= xstrdup (ref
);
593 int *users
= *usersp
;
594 int count
= *nusersp
;
595 int *notes
= *notesp
;
607 while (isspace(*tmp
))
610 while (*tmp
&& *tmp
!= ',')
615 xsect
= strchr(name
, '\\');
616 if ((notestr
= strstr(name
, "+")) != NULL
)
619 note
= atoi (notestr
+ 1);
620 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
622 /* note 13 always implies note 1 */
623 if (strcmp (notestr
, "+1+13") == 0)
625 else if (!xsect
|| nextnotestr
< xsect
)
626 fprintf (stderr
, "Warning: multiple note %s not handled\n",
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
641 if (strncmp(name
, "IC:", 3) != 0 || xsect
!= NULL
)
644 iclass
= fetch_insn_class(name
, create
);
648 xrealloc ((void *)users
,(count
+1)*sizeof(int));
650 xrealloc ((void *)notes
,(count
+1)*sizeof(int));
652 users
[count
++] = iclass
;
653 mark_used (ics
[iclass
], 0);
658 printf("Class %s not found\n", name
);
661 /* update the return values */
670 parse_semantics (char *sem
)
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
;
685 return IA64_DVS_OTHER
;
689 add_dep (const char *name
, const char *chk
, const char *reg
,
690 int semantics
, int mode
, char *extra
, int flag
)
694 rs
= insert_resource (name
, mode
);
695 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
,
697 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
,
699 rs
->semantics
= semantics
;
701 rs
->waw_special
= flag
;
705 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
707 FILE *fp
= fopen(filename
, "r");
710 fgets(buf
, sizeof(buf
), fp
);
718 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
721 while (isspace(buf
[strlen(buf
)-1]))
722 buf
[strlen(buf
)-1] = '\0';
729 while (isspace (*tmp
))
732 tmp
= strchr (tmp
, ';');
736 while (isspace (*tmp
))
739 tmp
= strchr (tmp
, ';');
743 while (isspace (*tmp
))
745 semantics
= parse_semantics (tmp
);
746 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
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)
753 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
754 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
758 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
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
);
772 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
775 /* is the given operand an indirect register file operand? */
777 irf_operand (int op
, const char *field
)
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
;
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")));
799 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
800 mov_um insn classes */
802 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
803 const char *format
, const char *field
)
805 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
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
;
827 return strstr (format
, "I26") || strstr (format
, "I27");
829 return strstr (format
, "I28") != NULL
;
831 return strstr (format
, "M29") || strstr (format
, "M30");
833 return strstr (format
, "M31") != NULL
;
834 if (pseudo0
|| pseudo1
)
840 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
841 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
843 return strstr (format
, "I22") != NULL
;
845 return strstr (format
, "I21") != NULL
;
850 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
851 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
853 return strstr (format
, "M32") != NULL
;
855 return strstr (format
, "M33") != NULL
;
859 if (ic
->name
[5] == 'n')
861 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
862 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
864 return strstr (format
, "M42") != NULL
;
866 return strstr (format
, "M43") != NULL
;
868 else if (ic
->name
[5] == 'p')
870 return idesc
->operands
[1] == IA64_OPND_IP
;
876 if (ic
->name
[5] == 'r')
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
;
882 return strstr (format
, "I23") != NULL
;
884 return strstr (format
, "I24") != NULL
;
886 return strstr (format
, "I25") != NULL
;
888 else if (ic
->name
[5] == 's')
890 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
891 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
893 return strstr (format
, "M35") != NULL
;
895 return strstr (format
, "M36") != NULL
;
902 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
903 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
905 return strstr (format
, "M35") != NULL
;
907 return strstr (format
, "M36") != NULL
;
915 /* is the given opcode in the given insn class? */
917 in_iclass(struct ia64_opcode
*idesc
, struct iclass
*ic
,
918 const char *format
, const char *field
, int *notep
)
925 if (!strncmp (ic
->comment
, "Format", 6))
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. */
931 if (strlen (ic
->comment
) < strlen (format
))
933 fprintf (stderr
, "Warning: most recent format '%s'\n"
934 "appears more restrictive than '%s'\n",
935 ic
->comment
, format
);
936 format
= ic
->comment
;
940 format
= ic
->comment
;
942 else if (!strncmp (ic
->comment
, "Field", 5))
945 fprintf (stderr
, "Overlapping field %s->%s\n",
951 /* an insn class matches anything that is the same followed by completers,
952 except when the absence and presence of completers constitutes different
954 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
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
);
960 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
961 && (idesc
->name
[len
] == '\0'
962 || idesc
->name
[len
] == '.'));
964 /* all break and nop variations must match exactly */
966 (strcmp (ic
->name
, "break") == 0
967 || strcmp (ic
->name
, "nop") == 0))
968 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
970 /* assume restrictions in the FORMAT/FIELD negate resolution,
971 unless specifically allowed by clauses in this block */
972 if (resolved
&& field
)
974 /* check Field(sf)==sN against opcode sN */
975 if (strstr(field
, "(sf)==") != NULL
)
978 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
980 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
983 /* check Field(lftype)==XXX */
984 else if (strstr (field
, "(lftype)") != NULL
)
986 if (strstr (idesc
->name
, "fault") != NULL
)
987 resolved
= strstr (field
, "fault") != NULL
;
989 resolved
= strstr (field
, "fault") == NULL
;
991 /* handle Field(ctype)==XXX */
992 else if (strstr (field
, "(ctype)") != NULL
)
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
;
1009 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1012 if (resolved
&& format
)
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;
1039 /* misc brl variations ('.cond' is optional);
1040 plain brl matches brl.cond */
1042 && (strcmp (idesc
->name
, "brl") == 0
1043 || strncmp (idesc
->name
, "brl.", 4) == 0)
1044 && strcmp (ic
->name
, "brl.cond") == 0)
1049 /* misc br variations ('.cond' is optional) */
1051 && (strcmp (idesc
->name
, "br") == 0
1052 || strncmp (idesc
->name
, "br.", 3) == 0)
1053 && strcmp (ic
->name
, "br.cond") == 0)
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
);
1064 /* probe variations */
1065 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1067 resolved
= strcmp (ic
->name
, "probe") == 0
1068 && !((strstr (idesc
->name
, "fault") != NULL
)
1069 ^ (format
&& strstr (format
, "M40") != NULL
));
1071 /* mov variations */
1072 if (!resolved
&& is_mov
)
1076 /* mov alias for fmerge */
1077 if (strcmp (ic
->name
, "fmerge") == 0)
1079 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1080 && idesc
->operands
[1] == IA64_OPND_F3
;
1082 /* mov alias for adds (r3 or imm14) */
1083 else if (strcmp (ic
->name
, "adds") == 0)
1085 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1086 && (idesc
->operands
[1] == IA64_OPND_R3
1087 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1089 /* mov alias for addl */
1090 else if (strcmp (ic
->name
, "addl") == 0)
1092 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1093 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1096 /* some variants of mov and mov.[im] */
1097 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1099 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1103 /* keep track of this so we can flag any insn classes which aren't
1104 mapped onto at least one real insn */
1107 ic
->terminal_resolved
= 1;
1110 else for (i
=0;i
< ic
->nsubs
;i
++)
1112 if (in_iclass(idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1115 for (j
=0;j
< ic
->nxsubs
;j
++)
1117 if (in_iclass(idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1121 printf ("%s is in IC %s\n",
1122 idesc
->name
, ic
->name
);
1128 /* If it's in this IC, add the IC note (if any) to the insn */
1131 if (ic
->note
&& notep
)
1133 if (*notep
&& *notep
!= ic
->note
)
1135 fprintf (stderr
, "Warning: overwriting note %d with note %d"
1137 *notep
, ic
->note
, ic
->name
);
1148 lookup_regindex (const char *name
, int specifier
)
1153 if (strstr (name
, "[RSC]"))
1155 if (strstr (name
, "[BSP]"))
1157 else if (strstr (name
, "[BSPSTORE]"))
1159 else if (strstr (name
, "[RNAT]"))
1161 else if (strstr (name
, "[CCV]"))
1163 else if (strstr (name
, "[ITC]"))
1165 else if (strstr (name
, "[PFS]"))
1167 else if (strstr (name
, "[LC]"))
1169 else if (strstr (name
, "[EC]"))
1173 if (strstr (name
, "[DCR]"))
1175 else if (strstr (name
, "[ITM]"))
1177 else if (strstr (name
, "[IVA]"))
1179 else if (strstr (name
, "[PTA]"))
1181 else if (strstr (name
, "[GPTA]"))
1183 else if (strstr (name
, "[IPSR]"))
1185 else if (strstr (name
, "[ISR]"))
1187 else if (strstr (name
, "[IIP]"))
1189 else if (strstr (name
, "[IFA]"))
1191 else if (strstr (name
, "[ITIR]"))
1193 else if (strstr (name
, "[IIPA]"))
1195 else if (strstr (name
, "[IFS]"))
1197 else if (strstr (name
, "[IIM]"))
1199 else if (strstr (name
, "[IHA]"))
1201 else if (strstr (name
, "[LID]"))
1203 else if (strstr (name
, "[IVR]"))
1205 else if (strstr (name
, "[TPR]"))
1207 else if (strstr (name
, "[EOI]"))
1209 else if (strstr (name
, "[ITV]"))
1211 else if (strstr (name
, "[PMV]"))
1213 else if (strstr (name
, "[CMCV]"))
1217 if (strstr (name
, ".be"))
1219 else if (strstr (name
, ".up"))
1221 else if (strstr (name
, ".ac"))
1223 else if (strstr (name
, ".mfl"))
1225 else if (strstr (name
, ".mfh"))
1227 else if (strstr (name
, ".ic"))
1229 else if (strstr (name
, ".i"))
1231 else if (strstr (name
, ".pk"))
1233 else if (strstr (name
, ".dt"))
1235 else if (strstr (name
, ".dfl"))
1237 else if (strstr (name
, ".dfh"))
1239 else if (strstr (name
, ".sp"))
1241 else if (strstr (name
, ".pp"))
1243 else if (strstr (name
, ".di"))
1245 else if (strstr (name
, ".si"))
1247 else if (strstr (name
, ".db"))
1249 else if (strstr (name
, ".lp"))
1251 else if (strstr (name
, ".tb"))
1253 else if (strstr (name
, ".rt"))
1255 else if (strstr (name
, ".cpl"))
1257 else if (strstr (name
, ".rs"))
1259 else if (strstr (name
, ".mc"))
1261 else if (strstr (name
, ".it"))
1263 else if (strstr (name
, ".id"))
1265 else if (strstr (name
, ".da"))
1267 else if (strstr (name
, ".dd"))
1269 else if (strstr (name
, ".ss"))
1271 else if (strstr (name
, ".ri"))
1273 else if (strstr (name
, ".ed"))
1275 else if (strstr (name
, ".bn"))
1277 else if (strstr (name
, ".ia"))
1288 lookup_specifier (const char *name
)
1290 if (strchr (name
, '%'))
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
)
1298 if (strstr (name
, "AR%, % in 48") != NULL
)
1300 if (strstr (name
, "BR%") != NULL
)
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
)
1308 if (strstr (name
, "FR%, % in 0") != NULL
)
1310 if (strstr (name
, "FR%, % in 2") != NULL
)
1312 if (strstr (name
, "GR%") != NULL
)
1314 if (strstr (name
, "PR%") != NULL
)
1317 fprintf (stderr
, "Warning! Don't know how to specify %% dependency %s\n",
1320 else if (strchr (name
, '#'))
1322 if (strstr (name
, "CPUID#") != NULL
)
1323 return IA64_RS_CPUID
;
1324 if (strstr (name
, "DBR#") != NULL
)
1326 if (strstr (name
, "IBR#") != NULL
)
1328 if (strstr (name
, "MSR#") != NULL
)
1330 if (strstr (name
, "PKR#") != NULL
)
1332 if (strstr (name
, "PMC#") != NULL
)
1334 if (strstr (name
, "PMD#") != NULL
)
1336 if (strstr (name
, "RR#") != NULL
)
1339 fprintf (stderr
, "Warning! Don't know how to specify # dependency %s\n",
1342 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1343 return IA64_RS_AR_FPSR
;
1344 else if (strncmp (name
, "AR[", 3) == 0)
1346 else if (strncmp (name
, "CR[", 3) == 0)
1348 else if (strncmp (name
, "PSR.", 4) == 0)
1350 else if (strcmp (name
, "InService*") == 0)
1351 return IA64_RS_INSERVICE
;
1352 else if (strcmp (name
, "GR0") == 0)
1354 else if (strcmp (name
, "CFM") == 0)
1356 else if (strcmp (name
, "PR63") == 0)
1357 return IA64_RS_PR63
;
1358 else if (strcmp (name
, "RSE") == 0)
1365 print_dependency_table ()
1371 for (i
=0;i
< iclen
;i
++)
1373 if (ics
[i
]->is_class
)
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");
1385 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
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");
1396 for (i
=0;i
< iclen
;i
++)
1400 mark_used (ics
[i
], 1);
1401 fprintf (stderr
, "Warning: class %s is defined but not used\n",
1406 if (debug
> 1) for (i
=0;i
< rdepslen
;i
++)
1408 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1409 if (rdeps
[i
]->total_chks
== 0)
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");
1415 else if (rdeps
[i
]->total_regs
== 0)
1417 fprintf (stderr
, "Warning: rsrc %s (%s) has no regs\n",
1418 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1423 /* the dependencies themselves */
1424 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1425 for (i
=0;i
< rdepslen
;i
++)
1427 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1429 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1430 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
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
);
1441 /* and dependency lists */
1442 for (i
=0;i
< dlistlen
;i
++)
1445 printf ("static const short dep%d[] = {\n ", i
);
1446 for (j
=0;j
< dlists
[i
]->len
; j
++)
1448 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1455 printf ("\n};\n\n");
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
++)
1465 if (opdeps
[i
]->chk
== -1)
1466 printf ("0, NULL, ");
1468 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1469 if (opdeps
[i
]->reg
== -1)
1470 printf ("0, NULL, ");
1472 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1479 /* Add STR to the string table. */
1481 static struct string_entry
*
1485 int start
= 0, end
= strtablen
;
1488 if (strtablen
== strtabtotlen
)
1491 string_table
= (struct string_entry
**)
1492 xrealloc (string_table
,
1493 sizeof (struct string_entry
**) * strtabtotlen
);
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];
1505 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1509 else if (strcmp (str
, string_table
[0]->s
) < 0)
1519 i
= (start
+ end
) / 2;
1520 c
= strcmp (str
, string_table
[i
]->s
);
1527 return string_table
[i
];
1539 for (; i
> 0 && i
< strtablen
; i
--)
1541 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1546 for (; i
< strtablen
; i
++)
1548 if (strcmp (str
, string_table
[i
]->s
) < 0)
1553 for (x
= strtablen
- 1; x
>= i
; x
--)
1555 string_table
[x
+ 1] = string_table
[x
];
1556 string_table
[x
+ 1]->num
= x
+ 1;
1558 string_table
[i
] = tmalloc (struct string_entry
);
1559 string_table
[i
]->s
= xstrdup (str
);
1560 string_table
[i
]->num
= i
;
1562 return string_table
[i
];
1566 make_bittree_entry ()
1568 struct bittree
*res
= tmalloc (struct bittree
);
1571 res
->bits
[0] = NULL
;
1572 res
->bits
[1] = NULL
;
1573 res
->bits
[2] = NULL
;
1575 res
->bits_to_skip
= 0;
1580 add_dis_table_ent (which
, insn
, completer_index
)
1581 struct disent
*which
;
1583 int completer_index
;
1593 while (ent
->nexte
!= NULL
)
1597 ent
= (ent
->nexte
= tmalloc (struct disent
));
1601 ent
= tmalloc (struct disent
);
1602 ent
->next_ent
= disinsntable
;
1609 while (completer_index
!= 1)
1611 ci
= (ci
<< 1) | (completer_index
& 1);
1612 completer_index
>>= 1;
1614 ent
->completer_index
= ci
;
1621 struct disent
*ent
= disinsntable
;
1622 struct disent
*prev
= ent
;
1624 ent
->ournum
= 32768;
1625 while ((ent
= ent
->next_ent
) != NULL
)
1627 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1633 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
, opcodenum
, completer_index
)
1634 struct bittree
*curr_ent
;
1639 int completer_index
;
1643 struct bittree
*next
;
1647 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
, opcodenum
,
1649 curr_ent
->disent
= nent
;
1653 m
= ((ia64_insn
) 1) << bit
;
1657 b
= (opcode
& m
) ? 1 : 0;
1663 next
= curr_ent
->bits
[b
];
1666 next
= make_bittree_entry ();
1667 curr_ent
->bits
[b
] = next
;
1669 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
,
1674 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1679 struct completer_entry
*ent
;
1680 int completer_index
;
1682 if (completer_index
& (1 << 20))
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
)
1693 insert_bit_table_ent (bittree
, 40, newopcode
, mask
, opcodenum
,
1694 (completer_index
<< 1) | 1);
1696 completer_index
<<= 1;
1697 ent
= ent
->alternative
;
1701 /* This optimization pass combines multiple "don't care" nodes. */
1703 compact_distree (ent
)
1704 struct bittree
*ent
;
1706 #define IS_SKIP(ent) \
1707 ((ent->bits[2] !=NULL) \
1708 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1711 struct bittree
*nent
= ent
;
1714 while (IS_SKIP (nent
))
1717 nent
= nent
->bits
[2];
1722 struct bittree
*next
= ent
->bits
[2];
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
;
1729 ent
->bits_to_skip
= bitcnt
;
1730 while (next
!= nent
)
1732 struct bittree
*b
= next
;
1733 next
= next
->bits
[2];
1739 for (x
= 0; x
< 3; x
++)
1741 struct bittree
*i
= ent
->bits
[x
];
1744 compact_distree (i
);
1749 static unsigned char *insn_list
;
1750 static int insn_list_len
= 0;
1751 static int tot_insn_list_len
= 0;
1753 /* Generate the disassembler state machine corresponding to the tree
1757 struct bittree
*ent
;
1760 int our_offset
= insn_list_len
;
1762 int totbits
= bitsused
;
1765 int zero_dest
= 0; /* initialize this with 0 to keep gcc quiet... */
1767 /* If this is a terminal entry, there's no point in skipping any
1769 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1770 ent
->bits
[2] == NULL
)
1772 if (ent
->disent
== NULL
)
1782 /* Calculate the amount of space needed for this entry, or at least
1783 a conservatively large approximation. */
1788 for (x
= 1; x
< 3; x
++)
1790 if (ent
->bits
[x
] != NULL
)
1796 if (ent
->disent
!= NULL
)
1798 if (ent
->bits
[2] != NULL
)
1805 /* Now allocate the space. */
1806 needed_bytes
= (totbits
+ 7) / 8;
1807 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1809 tot_insn_list_len
+= 256;
1810 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1812 our_offset
= insn_list_len
;
1813 insn_list_len
+= needed_bytes
;
1814 memset (insn_list
+ our_offset
, 0, needed_bytes
);
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. */
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);
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)
1829 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1832 if (ent
->bits
[0] != NULL
)
1834 struct bittree
*nent
= ent
->bits
[0];
1837 insn_list
[our_offset
] |= 0x80;
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. */
1844 if (IS_ONLY_IFZERO (ent
))
1846 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1848 nent
= nent
->bits
[0];
1852 insn_list
[our_offset
+ 0] |= zero_count
;
1854 zero_dest
= insn_list_len
;
1855 gen_dis_table (nent
);
1858 /* Now store the remaining tests. We also handle a sole "termination
1859 entry" by storing it as an "any bit" test. */
1861 for (x
= 1; x
< 3; x
++)
1863 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1865 struct bittree
*i
= ent
->bits
[x
];
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
)
1877 idest
= i
->disent
->ournum
;
1882 idest
= insn_list_len
- our_offset
;
1887 idest
= ent
->disent
->ournum
;
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.
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. */
1904 int start
= our_offset
+ bitsused
/ 8 + 1;
1906 memmove (insn_list
+ start
,
1907 insn_list
+ start
+ 1,
1908 insn_list_len
- (start
+ 1));
1913 insn_list
[our_offset
] |= 0x10;
1918 insn_list
[our_offset
] |= 0x20;
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. */
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))
1934 int start
= our_offset
+ bitsused
/ 8 + 1;
1936 memmove (insn_list
+ start
,
1937 insn_list
+ start
+ 1,
1938 insn_list_len
- (start
+ 1));
1944 insn_list
[our_offset
] |= 0x30;
1949 insn_list
[our_offset
] |= 0x08;
1960 else if (! (id
& 32768))
1966 printf ("%d: if (1) goto %d\n", our_offset
, id
);
1970 printf ("%d: try %d\n", our_offset
, id
);
1974 /* Store the address of the entry being branched to. */
1975 while (currbits
>= 0)
1977 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
1979 if (idest
& (1 << currbits
))
1981 *byte
|= (1 << (7 - (bitsused
% 8)));
1987 /* Now generate the states for the entry being branched to. */
1999 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2002 if (ent
->bits
[0] != NULL
)
2004 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2008 if (bitsused
!= totbits
)
2018 struct disent
*cent
= disinsntable
;
2020 printf ("static const char dis_table[] = {\n");
2021 for (x
= 0; x
< insn_list_len
; x
++)
2023 if ((x
> 0) && ((x
% 12) == 0))
2027 printf ("0x%02x, ", insn_list
[x
]);
2029 printf ("\n};\n\n");
2031 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2032 while (cent
!= NULL
)
2034 struct disent
*ent
= cent
;
2038 printf ("{ 0x%x, %d, %d },\n", ent
->completer_index
,
2040 (ent
->nexte
!= NULL
? 1 : 0));
2043 cent
= cent
->next_ent
;
2049 generate_disassembler ()
2052 struct main_entry
*ptr
= maintable
;
2054 bittree
= make_bittree_entry ();
2058 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2060 add_dis_entry (bittree
,
2061 ptr
->opcode
->opcode
, ptr
->opcode
->mask
, mainnum
,
2062 ptr
->completers
, 1);
2068 compact_distree (bittree
);
2070 gen_dis_table (bittree
);
2076 print_string_table ()
2079 char lbuf
[80], buf
[80];
2082 printf ("static const char *ia64_strings[] = {\n");
2084 for (x
= 0; x
< strtablen
; x
++)
2088 if (strlen (string_table
[x
]->s
) > 75)
2092 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2094 if ((blen
+ len
) > 75)
2096 printf (" %s\n", lbuf
);
2105 printf (" %s\n", lbuf
);
2110 static struct completer_entry
**glist
;
2111 static int glistlen
= 0;
2112 static int glisttotlen
= 0;
2114 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2117 completer_entries_eq (ent1
, ent2
)
2118 struct completer_entry
*ent1
, *ent2
;
2120 while (ent1
!= NULL
&& ent2
!= NULL
)
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
)
2130 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2134 ent1
= ent1
->alternative
;
2135 ent2
= ent2
->alternative
;
2137 return ent1
== ent2
;
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
*
2145 struct completer_entry
*ent
;
2153 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2154 ent
->alternative
= insert_gclist (ent
->alternative
);
2159 if (glisttotlen
== glistlen
)
2162 glist
= (struct completer_entry
**)
2163 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2173 if (ent
->name
->num
< glist
[0]->name
->num
)
2177 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2187 i
= (start
+ end
) / 2;
2188 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2196 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2213 while (i
< glistlen
)
2215 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2219 if (completer_entries_eq (ent
, glist
[i
]))
2227 for (; i
> 0 && i
< glistlen
; i
--)
2229 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2234 for (; i
< glistlen
; i
++)
2236 if (ent
->name
->num
< glist
[i
]->name
->num
)
2241 for (x
= glistlen
- 1; x
>= i
; x
--)
2243 glist
[x
+ 1] = glist
[x
];
2252 get_prefix_len (name
)
2257 if (name
[0] == '\0')
2262 c
= strchr (name
, '.');
2269 return strlen (name
);
2274 compute_completer_bits (ment
, ent
)
2275 struct main_entry
*ment
;
2276 struct completer_entry
*ent
;
2280 compute_completer_bits (ment
, ent
->addl_entries
);
2282 if (ent
->is_terminal
)
2285 ia64_insn our_bits
= ent
->bits
;
2286 struct completer_entry
*p
= ent
->parent
;
2290 while (p
!= NULL
&& ! p
->is_terminal
)
2301 p_bits
= ment
->opcode
->opcode
;
2304 for (x
= 0; x
< 64; x
++)
2306 ia64_insn m
= ((ia64_insn
) 1) << x
;
2307 if ((p_bits
& m
) != (our_bits
& m
))
2316 ent
->bits
= our_bits
;
2325 ent
= ent
->alternative
;
2329 /* Find identical completer trees that are used in different
2330 instructions and collapse their entries. */
2332 collapse_redundant_completers ()
2334 struct main_entry
*ptr
;
2337 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2339 if (ptr
->completers
== NULL
)
2343 compute_completer_bits (ptr
, ptr
->completers
);
2344 ptr
->completers
= insert_gclist (ptr
->completers
);
2347 /* The table has been finalized, now number the indexes. */
2348 for (x
= 0; x
< glistlen
; x
++)
2355 /* attach two lists of dependencies to each opcode.
2356 1) all resources which, when already marked in use, conflict with this
2358 2) all resources which must be marked in use when this opcode is used
2362 insert_opcode_dependencies (opc
, cmp
)
2363 struct ia64_opcode
*opc
;
2364 struct completer_entry
*cmp
;
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 */
2370 unsigned short regs
[256];
2372 unsigned short chks
[256];
2373 /* flag insns for which no class matched; there should be none */
2374 int no_class_found
= 1;
2376 for (i
=0;i
< rdepslen
;i
++)
2378 struct rdep
*rs
= rdeps
[i
];
2381 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2382 && strncmp (rs
->name
, "PR%", 3) == 0
2384 no_class_found
= 99;
2386 for (j
=0; j
< rs
->nregs
;j
++)
2390 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2392 /* We can ignore ic_note 11 for non PR resources */
2393 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
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.
2408 regs
[nregs
++] = RDEP(ic_note
, i
);
2410 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2415 for (j
=0;j
< rs
->nchks
;j
++)
2419 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2421 /* We can ignore ic_note 11 for non PR resources */
2422 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
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
]);
2433 chks
[nchks
++] = RDEP(ic_note
, i
);
2435 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2443 fprintf (stderr
, "Warning: opcode %s has no class (ops %d %d %d)\n",
2445 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2447 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2451 insert_completer_entry (opc
, tabent
)
2452 struct ia64_opcode
*opc
;
2453 struct main_entry
*tabent
;
2455 struct completer_entry
**ptr
= &tabent
->completers
;
2456 struct completer_entry
*parent
= NULL
;
2457 char pcopy
[129], *prefix
;
2460 if (strlen (opc
->name
) > 128)
2464 strcpy (pcopy
, opc
->name
);
2465 prefix
= pcopy
+ get_prefix_len (pcopy
);
2466 if (prefix
[0] != '\0')
2473 int need_new_ent
= 1;
2474 int plen
= get_prefix_len (prefix
);
2475 struct string_entry
*sent
;
2477 at_end
= (prefix
[plen
] == '\0');
2478 prefix
[plen
] = '\0';
2479 sent
= insert_string (prefix
);
2481 while (*ptr
!= NULL
)
2483 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2490 else if (cmpres
< 0)
2496 ptr
= &((*ptr
)->alternative
);
2501 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2503 nent
->parent
= parent
;
2504 nent
->addl_entries
= NULL
;
2505 nent
->alternative
= *ptr
;
2507 nent
->is_terminal
= 0;
2508 nent
->dependencies
= -1;
2514 ptr
= &((*ptr
)->addl_entries
);
2519 if ((*ptr
)->is_terminal
)
2524 (*ptr
)->is_terminal
= 1;
2525 (*ptr
)->mask
= (ia64_insn
)-1;
2526 (*ptr
)->bits
= opc
->opcode
;
2528 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2532 print_completer_entry (ent
)
2533 struct completer_entry
*ent
;
2536 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2540 while (! (mask
& 1))
2546 if (bits
& 0xffffffff00000000LL
)
2552 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2556 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2557 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2559 ent
->is_terminal
? 1 : 0,
2564 print_completer_table ()
2568 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2569 for (x
= 0; x
< glistlen
; x
++)
2571 print_completer_entry (glist
[x
]);
2577 opcodes_eq (opc1
, opc2
)
2578 struct ia64_opcode
*opc1
;
2579 struct ia64_opcode
*opc2
;
2584 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2585 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2586 || (opc1
->flags
!= opc2
->flags
))
2590 for (x
= 0; x
< 5; x
++)
2592 if (opc1
->operands
[x
] != opc2
->operands
[x
])
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))
2607 add_opcode_entry (opc
)
2608 struct ia64_opcode
*opc
;
2610 struct main_entry
**place
;
2611 struct string_entry
*name
;
2615 if (strlen (opc
->name
) > 128)
2620 strcpy (prefix
, opc
->name
);
2621 prefix
[get_prefix_len (prefix
)] = '\0';
2622 name
= insert_string (prefix
);
2624 /* Walk the list of opcode table entries. If it's a new
2625 instruction, allocate and fill in a new entry. */
2627 while (*place
!= NULL
)
2629 if ((*place
)->name
->num
== name
->num
2630 && opcodes_eq ((*place
)->opcode
, opc
))
2635 if ((*place
)->name
->num
> name
->num
)
2639 place
= &((*place
)->next
);
2643 struct main_entry
*nent
= tmalloc (struct main_entry
);
2647 nent
->next
= *place
;
2648 nent
->completers
= 0;
2651 insert_completer_entry (opc
, *place
);
2657 struct main_entry
*ptr
= maintable
;
2659 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2662 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2665 ptr
->opcode
->num_outputs
,
2666 ptr
->opcode
->opcode
,
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],
2674 ptr
->completers
->num
);
2683 struct ia64_opcode
*table
;
2687 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2689 add_opcode_entry (table
+ curr_opcode
);
2694 main (int argc
, char **argv
)
2701 load_insn_classes();
2702 load_dependencies();
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
);
2712 collapse_redundant_completers ();
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 ();
2720 generate_disassembler ();