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
;
71 /* Index in the main table. */
73 } *maintable
, **ordered_table
;
78 /* The set of possible completers for an opcode. */
79 struct completer_entry
81 /* This entry's index in the ia64_completer_table[] array. */
84 /* The name of the completer. */
85 struct string_entry
*name
;
87 /* This entry's parent. */
88 struct completer_entry
*parent
;
90 /* Set if this is a terminal completer (occurs at the end of an
94 /* An alternative completer. */
95 struct completer_entry
*alternative
;
97 /* Additional completers that can be appended to this one. */
98 struct completer_entry
*addl_entries
;
100 /* Before compute_completer_bits () is invoked, this contains the actual
101 instruction opcode for this combination of opcode and completers.
102 Afterwards, it contains those bits that are different from its
106 /* Bits set to 1 correspond to those bits in this completer's opcode
107 that are different from its parent completer's opcode (or from
108 the base opcode if the entry is the root of the opcode's completer
109 list). This field is filled in by compute_completer_bits (). */
112 /* Index into the opcode dependency list, or -1 if none. */
115 /* Remember the order encountered in the opcode tables. */
119 /* One entry in the disassembler name table. */
122 /* The index into the ia64_name_dis array for this entry. */
125 /* The index into the main_table[] array. */
128 /* The disassmbly priority of this entry. */
131 /* The completer_index value for this entry. */
134 /* How many other entries share this decode. */
137 /* The next entry sharing the same decode. */
138 struct disent
*nexte
;
140 /* The next entry in the name list. */
141 struct disent
*next_ent
;
142 } *disinsntable
= NULL
;
144 /* A state machine that will eventually be used to generate the
145 disassembler table. */
148 struct disent
*disent
;
149 struct bittree
*bits
[3]; /* 0, 1, and X (don't care) */
154 /* The string table contains all opcodes and completers sorted in
155 alphabetical order. */
157 /* One entry in the string table. */
160 /* The index in the ia64_strings[] array for this entry. */
162 /* And the string. */
164 } **string_table
= NULL
;
166 int strtabtotlen
= 0;
169 /* resource dependency entries */
172 char *name
; /* resource name */
174 mode
:2, /* RAW, WAW, or WAR */
175 semantics
:3; /* dependency semantics */
176 char *extra
; /* additional semantics info */
178 int total_chks
; /* total #of terminal insns */
179 int *chks
; /* insn classes which read (RAW), write
180 (WAW), or write (WAR) this rsrc */ //
181 int *chknotes
; /* dependency notes for each class */
183 int total_regs
; /* total #of terminal insns */
184 int *regs
; /* insn class which write (RAW), write2
185 (WAW), or read (WAR) this rsrc */
186 int *regnotes
; /* dependency notes for each class */
188 int waw_special
; /* special WAW dependency note */
191 static int rdepslen
= 0;
192 static int rdepstotlen
= 0;
194 /* array of all instruction classes */
197 char *name
; /* instruction class name */
198 int is_class
; /* is a class, not a terminal */
200 int *subs
; /* other classes within this class */
202 int xsubs
[4]; /* exclusions */
203 char *comment
; /* optional comment */
204 int note
; /* optional note */
205 int terminal_resolved
; /* did we match this with anything? */
206 int orphan
; /* detect class orphans */
209 static int iclen
= 0;
210 static int ictotlen
= 0;
212 /* an opcode dependency (chk/reg pair of dependency lists) */
215 int chk
; /* index into dlists */
216 int reg
; /* index into dlists */
219 static int opdeplen
= 0;
220 static int opdeptotlen
= 0;
222 /* a generic list of dependencies w/notes encoded. these may be shared. */
226 unsigned short *deps
;
229 static int dlistlen
= 0;
230 static int dlisttotlen
= 0;
232 /* add NAME to the resource table, where TYPE is RAW or WAW */
234 insert_resource (const char *name
, enum ia64_dependency_mode type
)
236 if (rdepslen
== rdepstotlen
)
239 rdeps
= (struct rdep
**)
240 xrealloc (rdeps
, sizeof(struct rdep
**) * rdepstotlen
);
242 rdeps
[rdepslen
] = tmalloc(struct rdep
);
243 memset((void *)rdeps
[rdepslen
], 0, sizeof(struct rdep
));
244 rdeps
[rdepslen
]->name
= xstrdup (name
);
245 rdeps
[rdepslen
]->mode
= type
;
246 rdeps
[rdepslen
]->waw_special
= 0;
248 return rdeps
[rdepslen
++];
251 /* are the lists of dependency indexes equivalent? */
253 deplist_equals (struct deplist
*d1
, struct deplist
*d2
)
257 if (d1
->len
!= d2
->len
)
260 for (i
=0;i
< d1
->len
;i
++)
262 if (d1
->deps
[i
] != d2
->deps
[i
])
269 /* add the list of dependencies to the list of dependency lists */
271 insert_deplist(int count
, unsigned short *deps
)
273 /* sort the list, then see if an equivalent list exists already.
274 this results in a much smaller set of dependency lists
276 struct deplist
*list
;
280 memset ((void *)set
, 0, sizeof(set
));
281 for (i
=0;i
< count
;i
++)
284 for (i
=0;i
< sizeof(set
);i
++)
288 list
= tmalloc(struct deplist
);
290 list
->deps
= (unsigned short *)malloc (sizeof(unsigned short) * count
);
291 for (i
=0, count
=0;i
< sizeof(set
);i
++)
295 list
->deps
[count
++] = i
;
299 /* does this list exist already? */
300 for (i
=0;i
< dlistlen
;i
++)
302 if (deplist_equals (list
, dlists
[i
]))
310 if (dlistlen
== dlisttotlen
)
313 dlists
= (struct deplist
**)
314 xrealloc (dlists
, sizeof(struct deplist
**) * dlisttotlen
);
316 dlists
[dlistlen
] = list
;
321 /* add the given pair of dependency lists to the opcode dependency list */
323 insert_dependencies (int nchks
, unsigned short *chks
,
324 int nregs
, unsigned short *regs
)
332 regind
= insert_deplist (nregs
, regs
);
334 chkind
= insert_deplist (nchks
, chks
);
336 for (i
=0;i
< opdeplen
;i
++)
338 if (opdeps
[i
]->chk
== chkind
339 && opdeps
[i
]->reg
== regind
)
342 pair
= tmalloc(struct opdep
);
346 if (opdeplen
== opdeptotlen
)
349 opdeps
= (struct opdep
**)
350 xrealloc (opdeps
, sizeof(struct opdep
**) * opdeptotlen
);
352 opdeps
[opdeplen
] = pair
;
358 mark_used (struct iclass
*ic
, int clear_terminals
)
364 ic
->terminal_resolved
= 1;
366 for (i
=0;i
< ic
->nsubs
;i
++)
368 mark_used (ics
[ic
->subs
[i
]], clear_terminals
);
370 for (i
=0;i
< ic
->nxsubs
;i
++)
372 mark_used (ics
[ic
->xsubs
[i
]], clear_terminals
);
376 /* look up an instruction class; if CREATE make a new one if none found;
377 returns the index into the insn class array */
379 fetch_insn_class(const char *full_name
, int create
)
389 if (strncmp (full_name
, "IC:", 3) == 0)
391 name
= xstrdup (full_name
+ 3);
395 name
= xstrdup (full_name
);
397 if ((xsect
= strchr(name
, '\\')) != NULL
)
399 if ((comment
= strchr(name
, '[')) != NULL
)
401 if ((notestr
= strchr(name
, '+')) != NULL
)
405 note
= atoi (notestr
+ 1);
406 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
408 if (strcmp (notestr
, "+1+13") == 0)
410 else if (!xsect
|| nextnotestr
< xsect
)
411 fprintf (stderr
, "Warning: multiple note %s not handled\n",
416 /* if it's a composite class, leave the notes and comments in place so that
417 we have a unique name for the composite class */
426 for (i
=0;i
< iclen
;i
++)
427 if (strcmp(name
, ics
[i
]->name
) == 0
428 && ((comment
== NULL
&& ics
[i
]->comment
== NULL
)
429 || (comment
!= NULL
&& ics
[i
]->comment
!= NULL
430 && strncmp (ics
[i
]->comment
, comment
,
431 strlen (ics
[i
]->comment
)) == 0))
432 && note
== ics
[i
]->note
)
438 /* doesn't exist, so make a new one */
439 if (iclen
== ictotlen
)
442 ics
= (struct iclass
**)
443 xrealloc(ics
, (ictotlen
)*sizeof(struct iclass
*));
446 ics
[ind
] = tmalloc(struct iclass
);
447 memset((void *)ics
[ind
], 0, sizeof(struct iclass
));
448 ics
[ind
]->name
= xstrdup(name
);
449 ics
[ind
]->is_class
= is_class
;
450 ics
[ind
]->orphan
= 1;
454 ics
[ind
]->comment
= xstrdup (comment
+ 1);
455 ics
[ind
]->comment
[strlen(ics
[ind
]->comment
)-1] = 0;
458 ics
[ind
]->note
= note
;
460 /* if it's a composite class, there's a comment or note, look for an
461 existing class or terminal with the same name. */
462 if ((xsect
|| comment
|| notestr
) && is_class
)
464 // first, populate with the class we're based on
465 char *subname
= name
;
473 ics
[ind
]->subs
= tmalloc(int);
474 ics
[ind
]->subs
[0] = fetch_insn_class (subname
, 1);;
479 char *subname
= xsect
+ 1;
480 xsect
= strchr (subname
, '\\');
483 ics
[ind
]->xsubs
[ics
[ind
]->nxsubs
] = fetch_insn_class (subname
,1);
491 /* for sorting a class's sub-class list only; make sure classes appear before
494 sub_compare (const void *e1
, const void *e2
)
496 struct iclass
*ic1
= ics
[*(int *)e1
];
497 struct iclass
*ic2
= ics
[*(int *)e2
];
504 else if (ic2
->is_class
)
507 return strcmp (ic1
->name
, ic2
->name
);
513 FILE *fp
= fopen("ia64-ic.tbl", "r");
517 fprintf (stderr
, "Can't find ia64-ic.tbl for reading\n");
521 /* discard first line */
522 fgets (buf
, sizeof(buf
), fp
);
530 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
533 while (isspace(buf
[strlen(buf
)-1]))
534 buf
[strlen(buf
)-1] = '\0';
540 if (tmp
== buf
+ sizeof(buf
))
545 iclass
= fetch_insn_class(name
, 1);
546 ics
[iclass
]->is_class
= 1;
548 if (strcmp (name
, "none") == 0)
550 ics
[iclass
]->is_class
= 0;
551 ics
[iclass
]->terminal_resolved
= 1;
555 /* for this class, record all sub-classes */
561 while (*tmp
&& isspace(*tmp
))
564 if (tmp
== buf
+ sizeof(buf
))
568 while (*tmp
&& *tmp
!= ',')
571 if (tmp
== buf
+ sizeof(buf
))
577 ics
[iclass
]->subs
= (int *)
578 xrealloc((void *)ics
[iclass
]->subs
,
579 (ics
[iclass
]->nsubs
+1)*sizeof(int));
581 sub
= fetch_insn_class(subname
, 1);
582 ics
[iclass
]->subs
= (int *)
583 xrealloc(ics
[iclass
]->subs
, (ics
[iclass
]->nsubs
+1)*sizeof(int));
584 ics
[iclass
]->subs
[ics
[iclass
]->nsubs
++] = sub
;
586 /* make sure classes come before terminals */
587 qsort ((void *)ics
[iclass
]->subs
,
588 ics
[iclass
]->nsubs
, sizeof(int), sub_compare
);
594 printf ("%d classes\n", iclen
);
598 /* extract the insn classes from the given line */
600 parse_resource_users(ref
, usersp
, nusersp
, notesp
)
607 char *line
= xstrdup (ref
);
609 int *users
= *usersp
;
610 int count
= *nusersp
;
611 int *notes
= *notesp
;
623 while (isspace(*tmp
))
626 while (*tmp
&& *tmp
!= ',')
631 xsect
= strchr(name
, '\\');
632 if ((notestr
= strstr(name
, "+")) != NULL
)
635 note
= atoi (notestr
+ 1);
636 if ((nextnotestr
= strchr (notestr
+ 1, '+')) != NULL
)
638 /* note 13 always implies note 1 */
639 if (strcmp (notestr
, "+1+13") == 0)
641 else if (!xsect
|| nextnotestr
< xsect
)
642 fprintf (stderr
, "Warning: multiple note %s not handled\n",
651 /* All classes are created when the insn class table is parsed;
652 Individual instructions might not appear until the dependency tables
653 are read. Only create new classes if it's *not* an insn class,
654 or if it's a composite class (which wouldn't necessarily be in the IC
657 if (strncmp(name
, "IC:", 3) != 0 || xsect
!= NULL
)
660 iclass
= fetch_insn_class(name
, create
);
664 xrealloc ((void *)users
,(count
+1)*sizeof(int));
666 xrealloc ((void *)notes
,(count
+1)*sizeof(int));
668 users
[count
++] = iclass
;
669 mark_used (ics
[iclass
], 0);
674 printf("Class %s not found\n", name
);
677 /* update the return values */
686 parse_semantics (char *sem
)
688 if (strcmp (sem
, "none") == 0)
689 return IA64_DVS_NONE
;
690 else if (strcmp (sem
, "implied") == 0)
691 return IA64_DVS_IMPLIED
;
692 else if (strcmp (sem
, "impliedF") == 0)
693 return IA64_DVS_IMPLIEDF
;
694 else if (strcmp (sem
, "data") == 0)
695 return IA64_DVS_DATA
;
696 else if (strcmp (sem
, "instr") == 0)
697 return IA64_DVS_INSTR
;
698 else if (strcmp (sem
, "specific") == 0)
699 return IA64_DVS_SPECIFIC
;
701 return IA64_DVS_OTHER
;
705 add_dep (const char *name
, const char *chk
, const char *reg
,
706 int semantics
, int mode
, char *extra
, int flag
)
710 rs
= insert_resource (name
, mode
);
711 parse_resource_users (chk
, &rs
->chks
, &rs
->nchks
,
713 parse_resource_users (reg
, &rs
->regs
, &rs
->nregs
,
715 rs
->semantics
= semantics
;
717 rs
->waw_special
= flag
;
721 load_depfile (const char *filename
, enum ia64_dependency_mode mode
)
723 FILE *fp
= fopen(filename
, "r");
727 fprintf (stderr
, "Can't find %s for reading\n", filename
);
731 fgets(buf
, sizeof(buf
), fp
);
739 if (fgets (buf
, sizeof(buf
), fp
) == NULL
)
742 while (isspace(buf
[strlen(buf
)-1]))
743 buf
[strlen(buf
)-1] = '\0';
750 while (isspace (*tmp
))
753 tmp
= strchr (tmp
, ';');
757 while (isspace (*tmp
))
760 tmp
= strchr (tmp
, ';');
764 while (isspace (*tmp
))
766 semantics
= parse_semantics (tmp
);
767 extra
= semantics
== IA64_DVS_OTHER
? xstrdup (tmp
) : NULL
;
769 /* For WAW entries, if the chks and regs differ, we need to enter the
770 entries in both positions so that the tables will be parsed properly,
771 without a lot of extra work */
772 if (mode
== IA64_DV_WAW
&& strcmp (regp
, chkp
) != 0)
774 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
775 add_dep (name
, regp
, chkp
, semantics
, mode
, extra
, 1);
779 add_dep (name
, chkp
, regp
, semantics
, mode
, extra
, 0);
788 load_depfile ("ia64-raw.tbl", IA64_DV_RAW
);
789 load_depfile ("ia64-waw.tbl", IA64_DV_WAW
);
790 load_depfile ("ia64-war.tbl", IA64_DV_WAR
);
793 printf ("%d RAW/WAW/WAR dependencies\n", rdepslen
);
796 /* is the given operand an indirect register file operand? */
798 irf_operand (int op
, const char *field
)
802 return op
== IA64_OPND_RR_R3
|| op
== IA64_OPND_DBR_R3
803 || op
== IA64_OPND_IBR_R3
|| op
== IA64_OPND_PKR_R3
804 || op
== IA64_OPND_PMC_R3
|| op
== IA64_OPND_PMD_R3
805 || op
== IA64_OPND_MSR_R3
|| op
== IA64_OPND_CPUID_R3
;
809 return ((op
== IA64_OPND_RR_R3
&& strstr (field
, "rr"))
810 || (op
== IA64_OPND_DBR_R3
&& strstr (field
, "dbr"))
811 || (op
== IA64_OPND_IBR_R3
&& strstr (field
, "ibr"))
812 || (op
== IA64_OPND_PKR_R3
&& strstr (field
, "pkr"))
813 || (op
== IA64_OPND_PMC_R3
&& strstr (field
, "pmc"))
814 || (op
== IA64_OPND_PMD_R3
&& strstr (field
, "pmd"))
815 || (op
== IA64_OPND_MSR_R3
&& strstr (field
, "msr"))
816 || (op
== IA64_OPND_CPUID_R3
&& strstr (field
, "cpuid")));
820 /* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
821 mov_um insn classes */
823 in_iclass_mov_x (struct ia64_opcode
*idesc
, struct iclass
*ic
,
824 const char *format
, const char *field
)
826 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
837 int i
= strcmp (idesc
->name
, "mov.i") == 0;
838 int m
= strcmp (idesc
->name
, "mov.m") == 0;
839 int i2627
= i
&& idesc
->operands
[0] == IA64_OPND_AR3
;
840 int i28
= i
&& idesc
->operands
[1] == IA64_OPND_AR3
;
841 int m2930
= m
&& idesc
->operands
[0] == IA64_OPND_AR3
;
842 int m31
= m
&& idesc
->operands
[1] == IA64_OPND_AR3
;
843 int pseudo0
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_AR3
;
844 int pseudo1
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_AR3
;
848 return strstr (format
, "I26") || strstr (format
, "I27");
850 return strstr (format
, "I28") != NULL
;
852 return strstr (format
, "M29") || strstr (format
, "M30");
854 return strstr (format
, "M31") != NULL
;
855 if (pseudo0
|| pseudo1
)
861 int i21
= idesc
->operands
[0] == IA64_OPND_B1
;
862 int i22
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_B2
;
864 return strstr (format
, "I22") != NULL
;
866 return strstr (format
, "I21") != NULL
;
871 int m32
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_CR3
;
872 int m33
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_CR3
;
874 return strstr (format
, "M32") != NULL
;
876 return strstr (format
, "M33") != NULL
;
880 if (ic
->name
[5] == 'n')
882 int m42
= plain_mov
&& irf_operand (idesc
->operands
[0], field
);
883 int m43
= plain_mov
&& irf_operand (idesc
->operands
[1], field
);
885 return strstr (format
, "M42") != NULL
;
887 return strstr (format
, "M43") != NULL
;
889 else if (ic
->name
[5] == 'p')
891 return idesc
->operands
[1] == IA64_OPND_IP
;
897 if (ic
->name
[5] == 'r')
899 int i25
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PR
;
900 int i23
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR
;
901 int i24
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PR_ROT
;
903 return strstr (format
, "I23") != NULL
;
905 return strstr (format
, "I24") != NULL
;
907 return strstr (format
, "I25") != NULL
;
909 else if (ic
->name
[5] == 's')
911 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_L
;
912 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR
;
914 return strstr (format
, "M35") != NULL
;
916 return strstr (format
, "M36") != NULL
;
923 int m35
= plain_mov
&& idesc
->operands
[0] == IA64_OPND_PSR_UM
;
924 int m36
= plain_mov
&& idesc
->operands
[1] == IA64_OPND_PSR_UM
;
926 return strstr (format
, "M35") != NULL
;
928 return strstr (format
, "M36") != NULL
;
936 /* is the given opcode in the given insn class? */
938 in_iclass(struct ia64_opcode
*idesc
, struct iclass
*ic
,
939 const char *format
, const char *field
, int *notep
)
946 if (!strncmp (ic
->comment
, "Format", 6))
948 /* assume that the first format seen is the most restrictive, and
949 only keep a later one if it looks like it's more restrictive. */
952 if (strlen (ic
->comment
) < strlen (format
))
954 fprintf (stderr
, "Warning: most recent format '%s'\n"
955 "appears more restrictive than '%s'\n",
956 ic
->comment
, format
);
957 format
= ic
->comment
;
961 format
= ic
->comment
;
963 else if (!strncmp (ic
->comment
, "Field", 5))
966 fprintf (stderr
, "Overlapping field %s->%s\n",
972 /* an insn class matches anything that is the same followed by completers,
973 except when the absence and presence of completers constitutes different
975 if (ic
->nsubs
== 0 && ic
->nxsubs
== 0)
977 int is_mov
= strncmp (idesc
->name
, "mov", 3) == 0;
978 int plain_mov
= strcmp (idesc
->name
, "mov") == 0;
979 int len
= strlen(ic
->name
);
981 resolved
= ((strncmp (ic
->name
, idesc
->name
, len
) == 0)
982 && (idesc
->name
[len
] == '\0'
983 || idesc
->name
[len
] == '.'));
985 /* all break and nop variations must match exactly */
987 (strcmp (ic
->name
, "break") == 0
988 || strcmp (ic
->name
, "nop") == 0))
989 resolved
= strcmp (ic
->name
, idesc
->name
) == 0;
991 /* assume restrictions in the FORMAT/FIELD negate resolution,
992 unless specifically allowed by clauses in this block */
993 if (resolved
&& field
)
995 /* check Field(sf)==sN against opcode sN */
996 if (strstr(field
, "(sf)==") != NULL
)
999 if ((sf
= strstr (idesc
->name
, ".s")) != 0)
1001 resolved
= strcmp (sf
+ 1, strstr (field
, "==") + 2) == 0;
1004 /* check Field(lftype)==XXX */
1005 else if (strstr (field
, "(lftype)") != NULL
)
1007 if (strstr (idesc
->name
, "fault") != NULL
)
1008 resolved
= strstr (field
, "fault") != NULL
;
1010 resolved
= strstr (field
, "fault") == NULL
;
1012 /* handle Field(ctype)==XXX */
1013 else if (strstr (field
, "(ctype)") != NULL
)
1015 if (strstr (idesc
->name
, "or.andcm"))
1016 resolved
= strstr (field
, "or.andcm") != NULL
;
1017 else if (strstr (idesc
->name
, "and.orcm"))
1018 resolved
= strstr (field
, "and.orcm") != NULL
;
1019 else if (strstr (idesc
->name
, "orcm"))
1020 resolved
= strstr (field
, "or orcm") != NULL
;
1021 else if (strstr (idesc
->name
, "or"))
1022 resolved
= strstr (field
, "or orcm") != NULL
;
1023 else if (strstr (idesc
->name
, "andcm"))
1024 resolved
= strstr (field
, "and andcm") != NULL
;
1025 else if (strstr (idesc
->name
, "and"))
1026 resolved
= strstr (field
, "and andcm") != NULL
;
1027 else if (strstr (idesc
->name
, "unc"))
1028 resolved
= strstr (field
, "unc") != NULL
;
1030 resolved
= strcmp (field
, "Field(ctype)==") == 0;
1033 if (resolved
&& format
)
1035 if (strncmp (idesc
->name
, "dep", 3) == 0
1036 && strstr (format
, "I13") != NULL
)
1037 resolved
= idesc
->operands
[1] == IA64_OPND_IMM8
;
1038 else if (strncmp (idesc
->name
, "chk", 3) == 0
1039 && strstr (format
, "M21") != NULL
)
1040 resolved
= idesc
->operands
[0] == IA64_OPND_F2
;
1041 else if (strncmp (idesc
->name
, "lfetch", 6) == 0)
1042 resolved
= (strstr (format
, "M14 M15") != NULL
1043 && (idesc
->operands
[1] == IA64_OPND_R2
1044 || idesc
->operands
[1] == IA64_OPND_IMM9b
));
1045 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1046 && strstr (format
, "B5") != NULL
)
1047 resolved
= idesc
->operands
[1] == IA64_OPND_B2
;
1048 else if (strncmp (idesc
->name
, "br.call", 7) == 0
1049 && strstr (format
, "B3") != NULL
)
1050 resolved
= idesc
->operands
[1] == IA64_OPND_TGT25c
;
1051 else if (strncmp (idesc
->name
, "brp", 3) == 0
1052 && strstr (format
, "B7") != NULL
)
1053 resolved
= idesc
->operands
[0] == IA64_OPND_B2
;
1054 else if (strcmp (ic
->name
, "invala") == 0)
1055 resolved
= strcmp (idesc
->name
, ic
->name
) == 0;
1060 /* misc brl variations ('.cond' is optional);
1061 plain brl matches brl.cond */
1063 && (strcmp (idesc
->name
, "brl") == 0
1064 || strncmp (idesc
->name
, "brl.", 4) == 0)
1065 && strcmp (ic
->name
, "brl.cond") == 0)
1070 /* misc br variations ('.cond' is optional) */
1072 && (strcmp (idesc
->name
, "br") == 0
1073 || strncmp (idesc
->name
, "br.", 3) == 0)
1074 && strcmp (ic
->name
, "br.cond") == 0)
1077 resolved
= (strstr (format
, "B4") != NULL
1078 && idesc
->operands
[0] == IA64_OPND_B2
)
1079 || (strstr (format
, "B1") != NULL
1080 && idesc
->operands
[0] == IA64_OPND_TGT25c
);
1085 /* probe variations */
1086 if (!resolved
&& strncmp (idesc
->name
, "probe", 5) == 0)
1088 resolved
= strcmp (ic
->name
, "probe") == 0
1089 && !((strstr (idesc
->name
, "fault") != NULL
)
1090 ^ (format
&& strstr (format
, "M40") != NULL
));
1092 /* mov variations */
1093 if (!resolved
&& is_mov
)
1097 /* mov alias for fmerge */
1098 if (strcmp (ic
->name
, "fmerge") == 0)
1100 resolved
= idesc
->operands
[0] == IA64_OPND_F1
1101 && idesc
->operands
[1] == IA64_OPND_F3
;
1103 /* mov alias for adds (r3 or imm14) */
1104 else if (strcmp (ic
->name
, "adds") == 0)
1106 resolved
= (idesc
->operands
[0] == IA64_OPND_R1
1107 && (idesc
->operands
[1] == IA64_OPND_R3
1108 || (idesc
->operands
[1] == IA64_OPND_IMM14
)));
1110 /* mov alias for addl */
1111 else if (strcmp (ic
->name
, "addl") == 0)
1113 resolved
= idesc
->operands
[0] == IA64_OPND_R1
1114 && idesc
->operands
[1] == IA64_OPND_IMM22
;
1117 /* some variants of mov and mov.[im] */
1118 if (!resolved
&& strncmp (ic
->name
, "mov_", 4) == 0)
1120 resolved
= in_iclass_mov_x (idesc
, ic
, format
, field
);
1124 /* keep track of this so we can flag any insn classes which aren't
1125 mapped onto at least one real insn */
1128 ic
->terminal_resolved
= 1;
1131 else for (i
=0;i
< ic
->nsubs
;i
++)
1133 if (in_iclass(idesc
, ics
[ic
->subs
[i
]], format
, field
, notep
))
1136 for (j
=0;j
< ic
->nxsubs
;j
++)
1138 if (in_iclass(idesc
, ics
[ic
->xsubs
[j
]], NULL
, NULL
, NULL
))
1142 printf ("%s is in IC %s\n",
1143 idesc
->name
, ic
->name
);
1149 /* If it's in this IC, add the IC note (if any) to the insn */
1152 if (ic
->note
&& notep
)
1154 if (*notep
&& *notep
!= ic
->note
)
1156 fprintf (stderr
, "Warning: overwriting note %d with note %d"
1158 *notep
, ic
->note
, ic
->name
);
1169 lookup_regindex (const char *name
, int specifier
)
1174 if (strstr (name
, "[RSC]"))
1176 if (strstr (name
, "[BSP]"))
1178 else if (strstr (name
, "[BSPSTORE]"))
1180 else if (strstr (name
, "[RNAT]"))
1182 else if (strstr (name
, "[CCV]"))
1184 else if (strstr (name
, "[ITC]"))
1186 else if (strstr (name
, "[PFS]"))
1188 else if (strstr (name
, "[LC]"))
1190 else if (strstr (name
, "[EC]"))
1194 if (strstr (name
, "[DCR]"))
1196 else if (strstr (name
, "[ITM]"))
1198 else if (strstr (name
, "[IVA]"))
1200 else if (strstr (name
, "[PTA]"))
1202 else if (strstr (name
, "[GPTA]"))
1204 else if (strstr (name
, "[IPSR]"))
1206 else if (strstr (name
, "[ISR]"))
1208 else if (strstr (name
, "[IIP]"))
1210 else if (strstr (name
, "[IFA]"))
1212 else if (strstr (name
, "[ITIR]"))
1214 else if (strstr (name
, "[IIPA]"))
1216 else if (strstr (name
, "[IFS]"))
1218 else if (strstr (name
, "[IIM]"))
1220 else if (strstr (name
, "[IHA]"))
1222 else if (strstr (name
, "[LID]"))
1224 else if (strstr (name
, "[IVR]"))
1226 else if (strstr (name
, "[TPR]"))
1228 else if (strstr (name
, "[EOI]"))
1230 else if (strstr (name
, "[ITV]"))
1232 else if (strstr (name
, "[PMV]"))
1234 else if (strstr (name
, "[CMCV]"))
1238 if (strstr (name
, ".be"))
1240 else if (strstr (name
, ".up"))
1242 else if (strstr (name
, ".ac"))
1244 else if (strstr (name
, ".mfl"))
1246 else if (strstr (name
, ".mfh"))
1248 else if (strstr (name
, ".ic"))
1250 else if (strstr (name
, ".i"))
1252 else if (strstr (name
, ".pk"))
1254 else if (strstr (name
, ".dt"))
1256 else if (strstr (name
, ".dfl"))
1258 else if (strstr (name
, ".dfh"))
1260 else if (strstr (name
, ".sp"))
1262 else if (strstr (name
, ".pp"))
1264 else if (strstr (name
, ".di"))
1266 else if (strstr (name
, ".si"))
1268 else if (strstr (name
, ".db"))
1270 else if (strstr (name
, ".lp"))
1272 else if (strstr (name
, ".tb"))
1274 else if (strstr (name
, ".rt"))
1276 else if (strstr (name
, ".cpl"))
1278 else if (strstr (name
, ".rs"))
1280 else if (strstr (name
, ".mc"))
1282 else if (strstr (name
, ".it"))
1284 else if (strstr (name
, ".id"))
1286 else if (strstr (name
, ".da"))
1288 else if (strstr (name
, ".dd"))
1290 else if (strstr (name
, ".ss"))
1292 else if (strstr (name
, ".ri"))
1294 else if (strstr (name
, ".ed"))
1296 else if (strstr (name
, ".bn"))
1298 else if (strstr (name
, ".ia"))
1309 lookup_specifier (const char *name
)
1311 if (strchr (name
, '%'))
1313 if (strstr (name
, "AR[K%]") != NULL
)
1314 return IA64_RS_AR_K
;
1315 if (strstr (name
, "AR[UNAT]") != NULL
)
1316 return IA64_RS_AR_UNAT
;
1317 if (strstr (name
, "AR%, % in 8") != NULL
)
1319 if (strstr (name
, "AR%, % in 48") != NULL
)
1321 if (strstr (name
, "BR%") != NULL
)
1323 if (strstr (name
, "CR[IRR%]") != NULL
)
1324 return IA64_RS_CR_IRR
;
1325 if (strstr (name
, "CR[LRR%]") != NULL
)
1326 return IA64_RS_CR_LRR
;
1327 if (strstr (name
, "CR%") != NULL
)
1329 if (strstr (name
, "FR%, % in 0") != NULL
)
1331 if (strstr (name
, "FR%, % in 2") != NULL
)
1333 if (strstr (name
, "GR%") != NULL
)
1335 if (strstr (name
, "PR%") != NULL
)
1338 fprintf (stderr
, "Warning! Don't know how to specify %% dependency %s\n",
1341 else if (strchr (name
, '#'))
1343 if (strstr (name
, "CPUID#") != NULL
)
1344 return IA64_RS_CPUID
;
1345 if (strstr (name
, "DBR#") != NULL
)
1347 if (strstr (name
, "IBR#") != NULL
)
1349 if (strstr (name
, "MSR#") != NULL
)
1351 if (strstr (name
, "PKR#") != NULL
)
1353 if (strstr (name
, "PMC#") != NULL
)
1355 if (strstr (name
, "PMD#") != NULL
)
1357 if (strstr (name
, "RR#") != NULL
)
1360 fprintf (stderr
, "Warning! Don't know how to specify # dependency %s\n",
1363 else if (strncmp (name
, "AR[FPSR]", 8) == 0)
1364 return IA64_RS_AR_FPSR
;
1365 else if (strncmp (name
, "AR[", 3) == 0)
1367 else if (strncmp (name
, "CR[", 3) == 0)
1369 else if (strncmp (name
, "PSR.", 4) == 0)
1371 else if (strcmp (name
, "InService*") == 0)
1372 return IA64_RS_INSERVICE
;
1373 else if (strcmp (name
, "GR0") == 0)
1375 else if (strcmp (name
, "CFM") == 0)
1377 else if (strcmp (name
, "PR63") == 0)
1378 return IA64_RS_PR63
;
1379 else if (strcmp (name
, "RSE") == 0)
1386 print_dependency_table ()
1392 for (i
=0;i
< iclen
;i
++)
1394 if (ics
[i
]->is_class
)
1398 fprintf (stderr
, "Warning: IC:%s", ics
[i
]->name
);
1399 if (ics
[i
]->comment
)
1400 fprintf (stderr
, "[%s]", ics
[i
]->comment
);
1401 fprintf (stderr
, " has no terminals or sub-classes\n");
1406 if (!ics
[i
]->terminal_resolved
&& !ics
[i
]->orphan
)
1408 fprintf(stderr
, "Warning: no insns mapped directly to "
1409 "terminal IC %s", ics
[i
]->name
);
1410 if (ics
[i
]->comment
)
1411 fprintf(stderr
, "[%s] ", ics
[i
]->comment
);
1412 fprintf(stderr
, "\n");
1417 for (i
=0;i
< iclen
;i
++)
1421 mark_used (ics
[i
], 1);
1422 fprintf (stderr
, "Warning: class %s is defined but not used\n",
1427 if (debug
> 1) for (i
=0;i
< rdepslen
;i
++)
1429 static const char *mode_str
[] = { "RAW", "WAW", "WAR" };
1430 if (rdeps
[i
]->total_chks
== 0)
1432 fprintf (stderr
, "Warning: rsrc %s (%s) has no chks%s\n",
1433 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
],
1434 rdeps
[i
]->total_regs
? "" : " or regs");
1436 else if (rdeps
[i
]->total_regs
== 0)
1438 fprintf (stderr
, "Warning: rsrc %s (%s) has no regs\n",
1439 rdeps
[i
]->name
, mode_str
[rdeps
[i
]->mode
]);
1444 /* the dependencies themselves */
1445 printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1446 for (i
=0;i
< rdepslen
;i
++)
1448 /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1450 int specifier
= lookup_specifier (rdeps
[i
]->name
);
1451 int regindex
= lookup_regindex (rdeps
[i
]->name
, specifier
);
1453 printf (" { \"%s\", %d, %d, %d, %d, ",
1454 rdeps
[i
]->name
, specifier
,
1455 (int)rdeps
[i
]->mode
, (int)rdeps
[i
]->semantics
, regindex
);
1456 if (rdeps
[i
]->semantics
== IA64_DVS_OTHER
)
1457 printf ("\"%s\", ", rdeps
[i
]->extra
);
1462 /* and dependency lists */
1463 for (i
=0;i
< dlistlen
;i
++)
1466 printf ("static const short dep%d[] = {\n ", i
);
1467 for (j
=0;j
< dlists
[i
]->len
; j
++)
1469 len
+= printf ("%d, ", dlists
[i
]->deps
[j
]);
1476 printf ("\n};\n\n");
1479 /* and opcode dependency list */
1480 printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1481 printf ("static const struct ia64_opcode_dependency\n");
1482 printf ("op_dependencies[] = {\n");
1483 for (i
=0;i
< opdeplen
;i
++)
1486 if (opdeps
[i
]->chk
== -1)
1487 printf ("0, NULL, ");
1489 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->chk
, opdeps
[i
]->chk
);
1490 if (opdeps
[i
]->reg
== -1)
1491 printf ("0, NULL, ");
1493 printf ("NELS(dep%d), dep%d, ", opdeps
[i
]->reg
, opdeps
[i
]->reg
);
1500 /* Add STR to the string table. */
1502 static struct string_entry
*
1506 int start
= 0, end
= strtablen
;
1509 if (strtablen
== strtabtotlen
)
1512 string_table
= (struct string_entry
**)
1513 xrealloc (string_table
,
1514 sizeof (struct string_entry
**) * strtabtotlen
);
1520 string_table
[0] = tmalloc (struct string_entry
);
1521 string_table
[0]->s
= xstrdup (str
);
1522 string_table
[0]->num
= 0;
1523 return string_table
[0];
1526 if (strcmp (str
, string_table
[strtablen
- 1]->s
) > 0)
1530 else if (strcmp (str
, string_table
[0]->s
) < 0)
1540 i
= (start
+ end
) / 2;
1541 c
= strcmp (str
, string_table
[i
]->s
);
1548 return string_table
[i
];
1560 for (; i
> 0 && i
< strtablen
; i
--)
1562 if (strcmp (str
, string_table
[i
- 1]->s
) > 0)
1567 for (; i
< strtablen
; i
++)
1569 if (strcmp (str
, string_table
[i
]->s
) < 0)
1574 for (x
= strtablen
- 1; x
>= i
; x
--)
1576 string_table
[x
+ 1] = string_table
[x
];
1577 string_table
[x
+ 1]->num
= x
+ 1;
1579 string_table
[i
] = tmalloc (struct string_entry
);
1580 string_table
[i
]->s
= xstrdup (str
);
1581 string_table
[i
]->num
= i
;
1583 return string_table
[i
];
1587 make_bittree_entry ()
1589 struct bittree
*res
= tmalloc (struct bittree
);
1592 res
->bits
[0] = NULL
;
1593 res
->bits
[1] = NULL
;
1594 res
->bits
[2] = NULL
;
1596 res
->bits_to_skip
= 0;
1601 add_dis_table_ent (which
, insn
, order
, completer_index
)
1602 struct disent
*which
;
1605 int completer_index
;
1615 while (ent
->nexte
!= NULL
)
1619 ent
= (ent
->nexte
= tmalloc (struct disent
));
1623 ent
= tmalloc (struct disent
);
1624 ent
->next_ent
= disinsntable
;
1631 ent
->priority
= order
;
1633 while (completer_index
!= 1)
1635 ci
= (ci
<< 1) | (completer_index
& 1);
1636 completer_index
>>= 1;
1638 ent
->completer_index
= ci
;
1645 struct disent
*ent
= disinsntable
;
1646 struct disent
*prev
= ent
;
1648 ent
->ournum
= 32768;
1649 while ((ent
= ent
->next_ent
) != NULL
)
1651 ent
->ournum
= prev
->ournum
+ prev
->nextcnt
+ 1;
1657 insert_bit_table_ent (curr_ent
, bit
, opcode
, mask
,
1658 opcodenum
, order
, completer_index
)
1659 struct bittree
*curr_ent
;
1665 int completer_index
;
1669 struct bittree
*next
;
1673 struct disent
*nent
= add_dis_table_ent (curr_ent
->disent
,
1676 curr_ent
->disent
= nent
;
1680 m
= ((ia64_insn
) 1) << bit
;
1684 b
= (opcode
& m
) ? 1 : 0;
1690 next
= curr_ent
->bits
[b
];
1693 next
= make_bittree_entry ();
1694 curr_ent
->bits
[b
] = next
;
1696 insert_bit_table_ent (next
, bit
- 1, opcode
, mask
, opcodenum
, order
,
1701 add_dis_entry (first
, opcode
, mask
, opcodenum
, ent
, completer_index
)
1702 struct bittree
*first
;
1706 struct completer_entry
*ent
;
1707 int completer_index
;
1709 if (completer_index
& (1 << 20))
1716 ia64_insn newopcode
= (opcode
& (~ ent
->mask
)) | ent
->bits
;
1717 add_dis_entry (first
, newopcode
, mask
, opcodenum
, ent
->addl_entries
,
1718 (completer_index
<< 1) | 1);
1719 if (ent
->is_terminal
)
1721 insert_bit_table_ent (bittree
, 40, newopcode
, mask
,
1722 opcodenum
, opcode_count
- ent
->order
- 1,
1723 (completer_index
<< 1) | 1);
1725 completer_index
<<= 1;
1726 ent
= ent
->alternative
;
1730 /* This optimization pass combines multiple "don't care" nodes. */
1732 compact_distree (ent
)
1733 struct bittree
*ent
;
1735 #define IS_SKIP(ent) \
1736 ((ent->bits[2] !=NULL) \
1737 && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1740 struct bittree
*nent
= ent
;
1743 while (IS_SKIP (nent
))
1746 nent
= nent
->bits
[2];
1751 struct bittree
*next
= ent
->bits
[2];
1753 ent
->bits
[0] = nent
->bits
[0];
1754 ent
->bits
[1] = nent
->bits
[1];
1755 ent
->bits
[2] = nent
->bits
[2];
1756 ent
->disent
= nent
->disent
;
1758 ent
->bits_to_skip
= bitcnt
;
1759 while (next
!= nent
)
1761 struct bittree
*b
= next
;
1762 next
= next
->bits
[2];
1768 for (x
= 0; x
< 3; x
++)
1770 struct bittree
*i
= ent
->bits
[x
];
1773 compact_distree (i
);
1778 static unsigned char *insn_list
;
1779 static int insn_list_len
= 0;
1780 static int tot_insn_list_len
= 0;
1782 /* Generate the disassembler state machine corresponding to the tree
1786 struct bittree
*ent
;
1789 int our_offset
= insn_list_len
;
1791 int totbits
= bitsused
;
1794 int zero_dest
= 0; /* initialize this with 0 to keep gcc quiet... */
1796 /* If this is a terminal entry, there's no point in skipping any
1798 if (ent
->skip_flag
&& ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
&&
1799 ent
->bits
[2] == NULL
)
1801 if (ent
->disent
== NULL
)
1811 /* Calculate the amount of space needed for this entry, or at least
1812 a conservatively large approximation. */
1817 for (x
= 1; x
< 3; x
++)
1819 if (ent
->bits
[x
] != NULL
)
1825 if (ent
->disent
!= NULL
)
1827 if (ent
->bits
[2] != NULL
)
1834 /* Now allocate the space. */
1835 needed_bytes
= (totbits
+ 7) / 8;
1836 if ((needed_bytes
+ insn_list_len
) > tot_insn_list_len
)
1838 tot_insn_list_len
+= 256;
1839 insn_list
= (char *) xrealloc (insn_list
, tot_insn_list_len
);
1841 our_offset
= insn_list_len
;
1842 insn_list_len
+= needed_bytes
;
1843 memset (insn_list
+ our_offset
, 0, needed_bytes
);
1845 /* Encode the skip entry by setting bit 6 set in the state op field,
1846 and store the # of bits to skip immediately after. */
1850 insn_list
[our_offset
+ 0] |= 0x40 | ((ent
->bits_to_skip
>> 2) & 0xf);
1851 insn_list
[our_offset
+ 1] |= ((ent
->bits_to_skip
& 3) << 6);
1854 #define IS_ONLY_IFZERO(ENT) \
1855 ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1856 && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1858 /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1861 if (ent
->bits
[0] != NULL
)
1863 struct bittree
*nent
= ent
->bits
[0];
1866 insn_list
[our_offset
] |= 0x80;
1868 /* We can encode sequences of multiple "if (bit is zero)" tests
1869 by storing the # of zero bits to check in the lower 3 bits of
1870 the instruction. However, this only applies if the state
1871 solely tests for a zero bit. */
1873 if (IS_ONLY_IFZERO (ent
))
1875 while (IS_ONLY_IFZERO (nent
) && zero_count
< 7)
1877 nent
= nent
->bits
[0];
1881 insn_list
[our_offset
+ 0] |= zero_count
;
1883 zero_dest
= insn_list_len
;
1884 gen_dis_table (nent
);
1887 /* Now store the remaining tests. We also handle a sole "termination
1888 entry" by storing it as an "any bit" test. */
1890 for (x
= 1; x
< 3; x
++)
1892 if (ent
->bits
[x
] != NULL
|| (x
== 2 && ent
->disent
!= NULL
))
1894 struct bittree
*i
= ent
->bits
[x
];
1900 /* If the instruction being branched to only consists of
1901 a termination entry, use the termination entry as the
1902 place to branch to instead. */
1903 if (i
->bits
[0] == NULL
&& i
->bits
[1] == NULL
1904 && i
->bits
[2] == NULL
&& i
->disent
!= NULL
)
1906 idest
= i
->disent
->ournum
;
1911 idest
= insn_list_len
- our_offset
;
1916 idest
= ent
->disent
->ournum
;
1919 /* If the destination offset for the if (bit is 1) test is less
1920 than 256 bytes away, we can store it as 8-bits instead of 16;
1921 the instruction has bit 5 set for the 16-bit address, and bit
1922 4 for the 8-bit address. Since we've already allocated 16
1923 bits for the address we need to deallocate the space.
1925 Note that branchings within the table are relative, and
1926 there are no branches that branch past our instruction yet
1927 so we do not need to adjust any other offsets. */
1933 int start
= our_offset
+ bitsused
/ 8 + 1;
1935 memmove (insn_list
+ start
,
1936 insn_list
+ start
+ 1,
1937 insn_list_len
- (start
+ 1));
1942 insn_list
[our_offset
] |= 0x10;
1947 insn_list
[our_offset
] |= 0x20;
1952 /* An instruction which solely consists of a termination
1953 marker and whose disassembly name index is < 4096
1954 can be stored in 16 bits. The encoding is slightly
1955 odd; the upper 4 bits of the instruction are 0x3, and
1956 bit 3 loses its normal meaning. */
1958 if (ent
->bits
[0] == NULL
&& ent
->bits
[1] == NULL
1959 && ent
->bits
[2] == NULL
&& ent
->skip_flag
== 0
1960 && ent
->disent
!= NULL
1961 && ent
->disent
->ournum
< (32768 + 4096))
1963 int start
= our_offset
+ bitsused
/ 8 + 1;
1965 memmove (insn_list
+ start
,
1966 insn_list
+ start
+ 1,
1967 insn_list_len
- (start
+ 1));
1973 insn_list
[our_offset
] |= 0x30;
1978 insn_list
[our_offset
] |= 0x08;
1989 else if (! (id
& 32768))
1995 printf ("%d: if (1) goto %d\n", our_offset
, id
);
1999 printf ("%d: try %d\n", our_offset
, id
);
2003 /* Store the address of the entry being branched to. */
2004 while (currbits
>= 0)
2006 char *byte
= insn_list
+ our_offset
+ bitsused
/ 8;
2008 if (idest
& (1 << currbits
))
2010 *byte
|= (1 << (7 - (bitsused
% 8)));
2016 /* Now generate the states for the entry being branched to. */
2028 printf ("%d: skipping %d\n", our_offset
, ent
->bits_to_skip
);
2031 if (ent
->bits
[0] != NULL
)
2033 printf ("%d: if (0:%d) goto %d\n", our_offset
, zero_count
+ 1,
2037 if (bitsused
!= totbits
)
2047 struct disent
*cent
= disinsntable
;
2049 printf ("static const char dis_table[] = {\n");
2050 for (x
= 0; x
< insn_list_len
; x
++)
2052 if ((x
> 0) && ((x
% 12) == 0))
2056 printf ("0x%02x, ", insn_list
[x
]);
2058 printf ("\n};\n\n");
2060 printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2061 while (cent
!= NULL
)
2063 struct disent
*ent
= cent
;
2067 printf ("{ 0x%x, %d, %d, %d },\n", ent
->completer_index
,
2068 ent
->insn
, (ent
->nexte
!= NULL
? 1 : 0),
2072 cent
= cent
->next_ent
;
2078 generate_disassembler ()
2082 bittree
= make_bittree_entry ();
2084 for (i
=0; i
< otlen
;i
++)
2086 struct main_entry
*ptr
= ordered_table
[i
];
2088 if (ptr
->opcode
->type
!= IA64_TYPE_DYN
)
2090 add_dis_entry (bittree
,
2091 ptr
->opcode
->opcode
, ptr
->opcode
->mask
,
2093 ptr
->completers
, 1);
2097 compact_distree (bittree
);
2099 gen_dis_table (bittree
);
2105 print_string_table ()
2108 char lbuf
[80], buf
[80];
2111 printf ("static const char *ia64_strings[] = {\n");
2113 for (x
= 0; x
< strtablen
; x
++)
2117 if (strlen (string_table
[x
]->s
) > 75)
2121 sprintf (buf
, " \"%s\",", string_table
[x
]->s
);
2123 if ((blen
+ len
) > 75)
2125 printf (" %s\n", lbuf
);
2134 printf (" %s\n", lbuf
);
2139 static struct completer_entry
**glist
;
2140 static int glistlen
= 0;
2141 static int glisttotlen
= 0;
2143 /* If the completer trees ENT1 and ENT2 are equal, return 1. */
2146 completer_entries_eq (ent1
, ent2
)
2147 struct completer_entry
*ent1
, *ent2
;
2149 while (ent1
!= NULL
&& ent2
!= NULL
)
2151 if (ent1
->name
->num
!= ent2
->name
->num
2152 || ent1
->bits
!= ent2
->bits
2153 || ent1
->mask
!= ent2
->mask
2154 || ent1
->is_terminal
!= ent2
->is_terminal
2155 || ent1
->dependencies
!= ent2
->dependencies
2156 || ent1
->order
!= ent2
->order
)
2160 if (! completer_entries_eq (ent1
->addl_entries
, ent2
->addl_entries
))
2164 ent1
= ent1
->alternative
;
2165 ent2
= ent2
->alternative
;
2167 return ent1
== ent2
;
2170 /* Insert ENT into the global list of completers and return it. If an
2171 equivalent entry (according to completer_entries_eq) already exists,
2172 it is returned instead. */
2173 struct completer_entry
*
2175 struct completer_entry
*ent
;
2183 ent
->addl_entries
= insert_gclist (ent
->addl_entries
);
2184 ent
->alternative
= insert_gclist (ent
->alternative
);
2189 if (glisttotlen
== glistlen
)
2192 glist
= (struct completer_entry
**)
2193 xrealloc (glist
, sizeof (struct completer_entry
*) * glisttotlen
);
2203 if (ent
->name
->num
< glist
[0]->name
->num
)
2207 else if (ent
->name
->num
> glist
[end
- 1]->name
->num
)
2217 i
= (start
+ end
) / 2;
2218 c
= ent
->name
->num
- glist
[i
]->name
->num
;
2226 && ent
->name
->num
== glist
[i
- 1]->name
->num
)
2243 while (i
< glistlen
)
2245 if (ent
->name
->num
!= glist
[i
]->name
->num
)
2249 if (completer_entries_eq (ent
, glist
[i
]))
2257 for (; i
> 0 && i
< glistlen
; i
--)
2259 if (ent
->name
->num
>= glist
[i
- 1]->name
->num
)
2264 for (; i
< glistlen
; i
++)
2266 if (ent
->name
->num
< glist
[i
]->name
->num
)
2271 for (x
= glistlen
- 1; x
>= i
; x
--)
2273 glist
[x
+ 1] = glist
[x
];
2282 get_prefix_len (name
)
2287 if (name
[0] == '\0')
2292 c
= strchr (name
, '.');
2299 return strlen (name
);
2304 compute_completer_bits (ment
, ent
)
2305 struct main_entry
*ment
;
2306 struct completer_entry
*ent
;
2310 compute_completer_bits (ment
, ent
->addl_entries
);
2312 if (ent
->is_terminal
)
2315 ia64_insn our_bits
= ent
->bits
;
2316 struct completer_entry
*p
= ent
->parent
;
2320 while (p
!= NULL
&& ! p
->is_terminal
)
2331 p_bits
= ment
->opcode
->opcode
;
2334 for (x
= 0; x
< 64; x
++)
2336 ia64_insn m
= ((ia64_insn
) 1) << x
;
2337 if ((p_bits
& m
) != (our_bits
& m
))
2346 ent
->bits
= our_bits
;
2355 ent
= ent
->alternative
;
2359 /* Find identical completer trees that are used in different
2360 instructions and collapse their entries. */
2362 collapse_redundant_completers ()
2364 struct main_entry
*ptr
;
2367 for (ptr
= maintable
; ptr
!= NULL
; ptr
= ptr
->next
)
2369 if (ptr
->completers
== NULL
)
2373 compute_completer_bits (ptr
, ptr
->completers
);
2374 ptr
->completers
= insert_gclist (ptr
->completers
);
2377 /* The table has been finalized, now number the indexes. */
2378 for (x
= 0; x
< glistlen
; x
++)
2385 /* attach two lists of dependencies to each opcode.
2386 1) all resources which, when already marked in use, conflict with this
2388 2) all resources which must be marked in use when this opcode is used
2392 insert_opcode_dependencies (opc
, cmp
)
2393 struct ia64_opcode
*opc
;
2394 struct completer_entry
*cmp
;
2396 /* note all resources which point to this opcode. rfi has the most chks
2397 (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2400 unsigned short regs
[256];
2402 unsigned short chks
[256];
2403 /* flag insns for which no class matched; there should be none */
2404 int no_class_found
= 1;
2406 for (i
=0;i
< rdepslen
;i
++)
2408 struct rdep
*rs
= rdeps
[i
];
2411 if (strcmp (opc
->name
, "cmp.eq.and") == 0
2412 && strncmp (rs
->name
, "PR%", 3) == 0
2414 no_class_found
= 99;
2416 for (j
=0; j
< rs
->nregs
;j
++)
2420 if (in_iclass (opc
, ics
[rs
->regs
[j
]], NULL
, NULL
, &ic_note
))
2422 /* We can ignore ic_note 11 for non PR resources */
2423 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2426 if (ic_note
!= 0 && rs
->regnotes
[j
] != 0
2427 && ic_note
!= rs
->regnotes
[j
]
2428 && !(ic_note
== 11 && rs
->regnotes
[j
] == 1))
2429 fprintf (stderr
, "Warning: IC note %d in opcode %s (IC:%s)"
2430 " conflicts with resource %s note %d\n",
2431 ic_note
, opc
->name
, ics
[rs
->regs
[j
]]->name
,
2432 rs
->name
, rs
->regnotes
[j
]);
2433 /* Instruction class notes override resource notes.
2434 So far, only note 11 applies to an IC instead of a resource,
2435 and note 11 implies note 1.
2438 regs
[nregs
++] = RDEP(ic_note
, i
);
2440 regs
[nregs
++] = RDEP(rs
->regnotes
[j
], i
);
2445 for (j
=0;j
< rs
->nchks
;j
++)
2449 if (in_iclass (opc
, ics
[rs
->chks
[j
]], NULL
, NULL
, &ic_note
))
2451 /* We can ignore ic_note 11 for non PR resources */
2452 if (ic_note
== 11 && strncmp (rs
->name
, "PR", 2) != 0)
2455 if (ic_note
!= 0 && rs
->chknotes
[j
] != 0
2456 && ic_note
!= rs
->chknotes
[j
]
2457 && !(ic_note
== 11 && rs
->chknotes
[j
] == 1))
2458 fprintf (stderr
, "Warning: IC note %d for opcode %s (IC:%s)"
2459 " conflicts with resource %s note %d\n",
2460 ic_note
, opc
->name
, ics
[rs
->chks
[j
]]->name
,
2461 rs
->name
, rs
->chknotes
[j
]);
2463 chks
[nchks
++] = RDEP(ic_note
, i
);
2465 chks
[nchks
++] = RDEP(rs
->chknotes
[j
], i
);
2473 fprintf (stderr
, "Warning: opcode %s has no class (ops %d %d %d)\n",
2475 opc
->operands
[0], opc
->operands
[1], opc
->operands
[2]);
2477 return insert_dependencies (nchks
, chks
, nregs
, regs
);
2481 insert_completer_entry (opc
, tabent
, order
)
2482 struct ia64_opcode
*opc
;
2483 struct main_entry
*tabent
;
2486 struct completer_entry
**ptr
= &tabent
->completers
;
2487 struct completer_entry
*parent
= NULL
;
2488 char pcopy
[129], *prefix
;
2491 if (strlen (opc
->name
) > 128)
2495 strcpy (pcopy
, opc
->name
);
2496 prefix
= pcopy
+ get_prefix_len (pcopy
);
2497 if (prefix
[0] != '\0')
2504 int need_new_ent
= 1;
2505 int plen
= get_prefix_len (prefix
);
2506 struct string_entry
*sent
;
2508 at_end
= (prefix
[plen
] == '\0');
2509 prefix
[plen
] = '\0';
2510 sent
= insert_string (prefix
);
2512 while (*ptr
!= NULL
)
2514 int cmpres
= sent
->num
- (*ptr
)->name
->num
;
2523 ptr
= &((*ptr
)->alternative
);
2528 struct completer_entry
*nent
= tmalloc (struct completer_entry
);
2530 nent
->parent
= parent
;
2531 nent
->addl_entries
= NULL
;
2532 nent
->alternative
= *ptr
;
2534 nent
->is_terminal
= 0;
2535 nent
->dependencies
= -1;
2541 ptr
= &((*ptr
)->addl_entries
);
2546 if ((*ptr
)->is_terminal
)
2551 (*ptr
)->is_terminal
= 1;
2552 (*ptr
)->mask
= (ia64_insn
)-1;
2553 (*ptr
)->bits
= opc
->opcode
;
2554 (*ptr
)->dependencies
= insert_opcode_dependencies (opc
, *ptr
);
2555 (*ptr
)->order
= order
;
2559 print_completer_entry (ent
)
2560 struct completer_entry
*ent
;
2563 ia64_insn mask
= ent
->mask
, bits
= ent
->bits
;
2567 while (! (mask
& 1))
2573 if (bits
& 0xffffffff00000000LL
)
2579 printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2583 ent
->alternative
!= NULL
? ent
->alternative
->num
: -1,
2584 ent
->addl_entries
!= NULL
? ent
->addl_entries
->num
: -1,
2586 ent
->is_terminal
? 1 : 0,
2591 print_completer_table ()
2595 printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2596 for (x
= 0; x
< glistlen
; x
++)
2598 print_completer_entry (glist
[x
]);
2604 opcodes_eq (opc1
, opc2
)
2605 struct ia64_opcode
*opc1
;
2606 struct ia64_opcode
*opc2
;
2611 if ((opc1
->mask
!= opc2
->mask
) || (opc1
->type
!= opc2
->type
)
2612 || (opc1
->num_outputs
!= opc2
->num_outputs
)
2613 || (opc1
->flags
!= opc2
->flags
))
2617 for (x
= 0; x
< 5; x
++)
2619 if (opc1
->operands
[x
] != opc2
->operands
[x
])
2624 plen1
= get_prefix_len (opc1
->name
);
2625 plen2
= get_prefix_len (opc2
->name
);
2626 if (plen1
== plen2
&& (memcmp (opc1
->name
, opc2
->name
, plen1
) == 0))
2634 add_opcode_entry (opc
)
2635 struct ia64_opcode
*opc
;
2637 struct main_entry
**place
;
2638 struct string_entry
*name
;
2642 if (strlen (opc
->name
) > 128)
2647 strcpy (prefix
, opc
->name
);
2648 prefix
[get_prefix_len (prefix
)] = '\0';
2649 name
= insert_string (prefix
);
2651 /* Walk the list of opcode table entries. If it's a new
2652 instruction, allocate and fill in a new entry. Note
2653 the main table is alphabetical by opcode name. */
2655 while (*place
!= NULL
)
2657 if ((*place
)->name
->num
== name
->num
2658 && opcodes_eq ((*place
)->opcode
, opc
))
2663 if ((*place
)->name
->num
> name
->num
)
2667 place
= &((*place
)->next
);
2671 struct main_entry
*nent
= tmalloc (struct main_entry
);
2675 nent
->next
= *place
;
2676 nent
->completers
= 0;
2679 if (otlen
== ottotlen
)
2682 ordered_table
= (struct main_entry
**)
2683 xrealloc (ordered_table
, sizeof (struct main_entry
*) * ottotlen
);
2685 ordered_table
[otlen
++] = nent
;
2688 insert_completer_entry (opc
, *place
, opcode_count
++);
2694 struct main_entry
*ptr
= maintable
;
2697 printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2700 printf (" { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2703 ptr
->opcode
->num_outputs
,
2704 ptr
->opcode
->opcode
,
2706 ptr
->opcode
->operands
[0],
2707 ptr
->opcode
->operands
[1],
2708 ptr
->opcode
->operands
[2],
2709 ptr
->opcode
->operands
[3],
2710 ptr
->opcode
->operands
[4],
2712 ptr
->completers
->num
);
2714 ptr
->main_index
= index
++;
2723 struct ia64_opcode
*table
;
2727 for (curr_opcode
= 0; table
[curr_opcode
].name
!= NULL
; curr_opcode
++)
2729 add_opcode_entry (table
+ curr_opcode
);
2734 main (int argc
, char **argv
)
2741 load_insn_classes();
2742 load_dependencies();
2744 shrink (ia64_opcodes_a
);
2745 shrink (ia64_opcodes_b
);
2746 shrink (ia64_opcodes_f
);
2747 shrink (ia64_opcodes_i
);
2748 shrink (ia64_opcodes_m
);
2749 shrink (ia64_opcodes_x
);
2750 shrink (ia64_opcodes_d
);
2752 collapse_redundant_completers ();
2754 printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2755 print_string_table ();
2756 print_dependency_table ();
2757 print_completer_table ();
2758 print_main_table ();
2760 generate_disassembler ();