1
/* ia64-gen.c -- Generate a shrunk set of opcode tables
2
Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2012
3
Free Software Foundation, Inc.
4
Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
6
This file is part of the GNU opcodes library.
8
This library is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
13
It is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16
License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this file; see the file COPYING. If not, write to the
20
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24
/* While the ia64-opc-* set of opcode tables are easy to maintain,
25
they waste a tremendous amount of space. ia64-gen rearranges the
26
instructions into a directed acyclic graph (DAG) of instruction opcodes and
27
their possible completers, as well as compacting the set of strings used.
29
The disassembler table consists of a state machine that does
30
branching based on the bits of the opcode being disassembled. The
31
state encodings have been chosen to minimize the amount of space
34
The resource table is constructed based on some text dependency tables,
35
which are also easier to maintain than the final representation. */
42
#include "libiberty.h"
43
#include "safe-ctype.h"
46
#include "ia64-opc-a.c"
47
#include "ia64-opc-i.c"
48
#include "ia64-opc-m.c"
49
#include "ia64-opc-b.c"
50
#include "ia64-opc-f.c"
51
#include "ia64-opc-x.c"
52
#include "ia64-opc-d.c"
55
#define _(String) gettext (String)
57
/* This is a copy of fprintf_vma from bfd/bfd-in2.h. We have to use this
58
always, because we might be compiled without BFD64 defined, if configured
59
for a 32-bit target and --enable-targets=all is used. This will work for
60
both 32-bit and 64-bit hosts. */
61
#define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
62
#define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
63
#define opcode_fprintf_vma(s,x) \
64
fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
66
const char * program_name = NULL;
69
#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
70
#define tmalloc(X) (X *) xmalloc (sizeof (X))
72
typedef unsigned long long ci_t;
73
/* The main opcode table entry. Each entry is a unique combination of
74
name and flags (no two entries in the table compare as being equal
78
/* The base name of this opcode. The names of its completers are
79
appended to it to generate the full instruction name. */
80
struct string_entry *name;
81
/* The base opcode entry. Which one to use is a fairly arbitrary choice;
82
it uses the first one passed to add_opcode_entry. */
83
struct ia64_opcode *opcode;
84
/* The list of completers that can be applied to this opcode. */
85
struct completer_entry *completers;
86
/* Next entry in the chain. */
87
struct main_entry *next;
88
/* Index in the main table. */
90
} *maintable, **ordered_table;
96
/* The set of possible completers for an opcode. */
97
struct completer_entry
99
/* This entry's index in the ia64_completer_table[] array. */
102
/* The name of the completer. */
103
struct string_entry *name;
105
/* This entry's parent. */
106
struct completer_entry *parent;
108
/* Set if this is a terminal completer (occurs at the end of an
112
/* An alternative completer. */
113
struct completer_entry *alternative;
115
/* Additional completers that can be appended to this one. */
116
struct completer_entry *addl_entries;
118
/* Before compute_completer_bits () is invoked, this contains the actual
119
instruction opcode for this combination of opcode and completers.
120
Afterwards, it contains those bits that are different from its
124
/* Bits set to 1 correspond to those bits in this completer's opcode
125
that are different from its parent completer's opcode (or from
126
the base opcode if the entry is the root of the opcode's completer
127
list). This field is filled in by compute_completer_bits (). */
130
/* Index into the opcode dependency list, or -1 if none. */
133
/* Remember the order encountered in the opcode tables. */
137
/* One entry in the disassembler name table. */
140
/* The index into the ia64_name_dis array for this entry. */
143
/* The index into the main_table[] array. */
146
/* The disassmbly priority of this entry. */
149
/* The completer_index value for this entry. */
150
ci_t completer_index;
152
/* How many other entries share this decode. */
155
/* The next entry sharing the same decode. */
156
struct disent *nexte;
158
/* The next entry in the name list. */
159
struct disent *next_ent;
160
} *disinsntable = NULL;
162
/* A state machine that will eventually be used to generate the
163
disassembler table. */
166
struct disent *disent;
167
struct bittree *bits[3]; /* 0, 1, and X (don't care). */
172
/* The string table contains all opcodes and completers sorted in
173
alphabetical order. */
175
/* One entry in the string table. */
178
/* The index in the ia64_strings[] array for this entry. */
180
/* And the string. */
182
} **string_table = NULL;
185
int strtabtotlen = 0;
188
/* Resource dependency entries. */
191
char *name; /* Resource name. */
193
mode:2, /* RAW, WAW, or WAR. */
194
semantics:3; /* Dependency semantics. */
195
char *extra; /* Additional semantics info. */
197
int total_chks; /* Total #of terminal insns. */
198
int *chks; /* Insn classes which read (RAW), write
199
(WAW), or write (WAR) this rsrc. */
200
int *chknotes; /* Dependency notes for each class. */
202
int total_regs; /* Total #of terminal insns. */
203
int *regs; /* Insn class which write (RAW), write2
204
(WAW), or read (WAR) this rsrc. */
205
int *regnotes; /* Dependency notes for each class. */
207
int waw_special; /* Special WAW dependency note. */
210
static int rdepslen = 0;
211
static int rdepstotlen = 0;
213
/* Array of all instruction classes. */
216
char *name; /* Instruction class name. */
217
int is_class; /* Is a class, not a terminal. */
219
int *subs; /* Other classes within this class. */
221
int xsubs[4]; /* Exclusions. */
222
char *comment; /* Optional comment. */
223
int note; /* Optional note. */
224
int terminal_resolved; /* Did we match this with anything? */
225
int orphan; /* Detect class orphans. */
228
static int iclen = 0;
229
static int ictotlen = 0;
231
/* An opcode dependency (chk/reg pair of dependency lists). */
234
int chk; /* index into dlists */
235
int reg; /* index into dlists */
238
static int opdeplen = 0;
239
static int opdeptotlen = 0;
241
/* A generic list of dependencies w/notes encoded. These may be shared. */
245
unsigned short *deps;
248
static int dlistlen = 0;
249
static int dlisttotlen = 0;
252
static void fail (const char *, ...) ATTRIBUTE_PRINTF_1;
253
static void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
254
static struct rdep * insert_resource (const char *, enum ia64_dependency_mode);
255
static int deplist_equals (struct deplist *, struct deplist *);
256
static short insert_deplist (int, unsigned short *);
257
static short insert_dependencies (int, unsigned short *, int, unsigned short *);
258
static void mark_used (struct iclass *, int);
259
static int fetch_insn_class (const char *, int);
260
static int sub_compare (const void *, const void *);
261
static void load_insn_classes (void);
262
static void parse_resource_users (const char *, int **, int *, int **);
263
static int parse_semantics (char *);
264
static void add_dep (const char *, const char *, const char *, int, int, char *, int);
265
static void load_depfile (const char *, enum ia64_dependency_mode);
266
static void load_dependencies (void);
267
static int irf_operand (int, const char *);
268
static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *);
269
static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *);
270
static int lookup_regindex (const char *, int);
271
static int lookup_specifier (const char *);
272
static void print_dependency_table (void);
273
static struct string_entry * insert_string (char *);
274
static void gen_dis_table (struct bittree *);
275
static void print_dis_table (void);
276
static void generate_disassembler (void);
277
static void print_string_table (void);
278
static int completer_entries_eq (struct completer_entry *, struct completer_entry *);
279
static struct completer_entry * insert_gclist (struct completer_entry *);
280
static int get_prefix_len (const char *);
281
static void compute_completer_bits (struct main_entry *, struct completer_entry *);
282
static void collapse_redundant_completers (void);
283
static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *);
284
static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int);
285
static void print_completer_entry (struct completer_entry *);
286
static void print_completer_table (void);
287
static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *);
288
static void add_opcode_entry (struct ia64_opcode *);
289
static void print_main_table (void);
290
static void shrink (struct ia64_opcode *);
291
static void print_version (void);
292
static void usage (FILE *, int);
293
static void finish_distable (void);
294
static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, ci_t);
295
static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, ci_t);
296
static void compact_distree (struct bittree *);
297
static struct bittree * make_bittree_entry (void);
298
static struct disent * add_dis_table_ent (struct disent *, int, int, ci_t);
302
fail (const char *message, ...)
306
va_start (args, message);
307
fprintf (stderr, _("%s: Error: "), program_name);
308
vfprintf (stderr, message, args);
314
warn (const char *message, ...)
318
va_start (args, message);
320
fprintf (stderr, _("%s: Warning: "), program_name);
321
vfprintf (stderr, message, args);
325
/* Add NAME to the resource table, where TYPE is RAW or WAW. */
327
insert_resource (const char *name, enum ia64_dependency_mode type)
329
if (rdepslen == rdepstotlen)
332
rdeps = (struct rdep **)
333
xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
335
rdeps[rdepslen] = tmalloc(struct rdep);
336
memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep));
337
rdeps[rdepslen]->name = xstrdup (name);
338
rdeps[rdepslen]->mode = type;
339
rdeps[rdepslen]->waw_special = 0;
341
return rdeps[rdepslen++];
344
/* Are the lists of dependency indexes equivalent? */
346
deplist_equals (struct deplist *d1, struct deplist *d2)
350
if (d1->len != d2->len)
353
for (i = 0; i < d1->len; i++)
354
if (d1->deps[i] != d2->deps[i])
360
/* Add the list of dependencies to the list of dependency lists. */
362
insert_deplist (int count, unsigned short *deps)
364
/* Sort the list, then see if an equivalent list exists already.
365
this results in a much smaller set of dependency lists. */
366
struct deplist *list;
370
memset ((void *)set, 0, sizeof (set));
371
for (i = 0; i < count; i++)
375
for (i = 0; i < (int) sizeof (set); i++)
379
list = tmalloc (struct deplist);
381
list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count);
383
for (i = 0, count = 0; i < (int) sizeof (set); i++)
385
list->deps[count++] = i;
387
/* Does this list exist already? */
388
for (i = 0; i < dlistlen; i++)
389
if (deplist_equals (list, dlists[i]))
396
if (dlistlen == dlisttotlen)
399
dlists = (struct deplist **)
400
xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
402
dlists[dlistlen] = list;
407
/* Add the given pair of dependency lists to the opcode dependency list. */
409
insert_dependencies (int nchks, unsigned short *chks,
410
int nregs, unsigned short *regs)
418
regind = insert_deplist (nregs, regs);
420
chkind = insert_deplist (nchks, chks);
422
for (i = 0; i < opdeplen; i++)
423
if (opdeps[i]->chk == chkind
424
&& opdeps[i]->reg == regind)
427
pair = tmalloc (struct opdep);
431
if (opdeplen == opdeptotlen)
434
opdeps = (struct opdep **)
435
xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
437
opdeps[opdeplen] = pair;
443
mark_used (struct iclass *ic, int clear_terminals)
449
ic->terminal_resolved = 1;
451
for (i = 0; i < ic->nsubs; i++)
452
mark_used (ics[ic->subs[i]], clear_terminals);
454
for (i = 0; i < ic->nxsubs; i++)
455
mark_used (ics[ic->xsubs[i]], clear_terminals);
458
/* Look up an instruction class; if CREATE make a new one if none found;
459
returns the index into the insn class array. */
461
fetch_insn_class (const char *full_name, int create)
471
if (CONST_STRNEQ (full_name, "IC:"))
473
name = xstrdup (full_name + 3);
477
name = xstrdup (full_name);
479
if ((xsect = strchr(name, '\\')) != NULL)
481
if ((comment = strchr(name, '[')) != NULL)
483
if ((notestr = strchr(name, '+')) != NULL)
486
/* If it is a composite class, then ignore comments and notes that come after
487
the '\\', since they don't apply to the part we are decoding now. */
500
note = atoi (notestr + 1);
501
if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
503
if (strcmp (notestr, "+1+13") == 0)
505
else if (!xsect || nextnotestr < xsect)
506
warn (_("multiple note %s not handled\n"), notestr);
510
/* If it's a composite class, leave the notes and comments in place so that
511
we have a unique name for the composite class. Otherwise, we remove
521
for (i = 0; i < iclen; i++)
522
if (strcmp (name, ics[i]->name) == 0
523
&& ((comment == NULL && ics[i]->comment == NULL)
524
|| (comment != NULL && ics[i]->comment != NULL
525
&& strncmp (ics[i]->comment, comment,
526
strlen (ics[i]->comment)) == 0))
527
&& note == ics[i]->note)
533
/* Doesn't exist, so make a new one. */
534
if (iclen == ictotlen)
537
ics = (struct iclass **)
538
xrealloc (ics, (ictotlen) * sizeof (struct iclass *));
542
ics[ind] = tmalloc (struct iclass);
543
memset ((void *)ics[ind], 0, sizeof (struct iclass));
544
ics[ind]->name = xstrdup (name);
545
ics[ind]->is_class = is_class;
546
ics[ind]->orphan = 1;
550
ics[ind]->comment = xstrdup (comment + 1);
551
ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0;
555
ics[ind]->note = note;
557
/* If it's a composite class, there's a comment or note, look for an
558
existing class or terminal with the same name. */
559
if ((xsect || comment || notestr) && is_class)
561
/* First, populate with the class we're based on. */
562
char *subname = name;
572
ics[ind]->subs = tmalloc(int);
573
ics[ind]->subs[0] = fetch_insn_class (subname, 1);
578
char *subname = xsect + 1;
580
xsect = strchr (subname, '\\');
583
ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
591
/* For sorting a class's sub-class list only; make sure classes appear before
594
sub_compare (const void *e1, const void *e2)
596
struct iclass *ic1 = ics[*(int *)e1];
597
struct iclass *ic2 = ics[*(int *)e2];
604
else if (ic2->is_class)
607
return strcmp (ic1->name, ic2->name);
611
load_insn_classes (void)
613
FILE *fp = fopen ("ia64-ic.tbl", "r");
617
fail (_("can't find ia64-ic.tbl for reading\n"));
619
/* Discard first line. */
620
fgets (buf, sizeof(buf), fp);
628
if (fgets (buf, sizeof (buf), fp) == NULL)
631
while (ISSPACE (buf[strlen (buf) - 1]))
632
buf[strlen (buf) - 1] = '\0';
638
if (tmp == buf + sizeof (buf))
643
iclass = fetch_insn_class (name, 1);
644
ics[iclass]->is_class = 1;
646
if (strcmp (name, "none") == 0)
648
ics[iclass]->is_class = 0;
649
ics[iclass]->terminal_resolved = 1;
653
/* For this class, record all sub-classes. */
659
while (*tmp && ISSPACE (*tmp))
662
if (tmp == buf + sizeof (buf))
666
while (*tmp && *tmp != ',')
669
if (tmp == buf + sizeof (buf))
675
ics[iclass]->subs = (int *)
676
xrealloc ((void *)ics[iclass]->subs,
677
(ics[iclass]->nsubs + 1) * sizeof (int));
679
sub = fetch_insn_class (subname, 1);
680
ics[iclass]->subs = (int *)
681
xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int));
682
ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
685
/* Make sure classes come before terminals. */
686
qsort ((void *)ics[iclass]->subs,
687
ics[iclass]->nsubs, sizeof(int), sub_compare);
692
printf ("%d classes\n", iclen);
695
/* Extract the insn classes from the given line. */
697
parse_resource_users (const char *ref, int **usersp, int *nusersp,
701
char *line = xstrdup (ref);
703
int *users = *usersp;
704
int count = *nusersp;
705
int *notes = *notesp;
717
while (ISSPACE (*tmp))
720
while (*tmp && *tmp != ',')
725
xsect = strchr (name, '\\');
726
if ((notestr = strstr (name, "+")) != NULL)
730
note = atoi (notestr + 1);
731
if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
733
/* Note 13 always implies note 1. */
734
if (strcmp (notestr, "+1+13") == 0)
736
else if (!xsect || nextnotestr < xsect)
737
warn (_("multiple note %s not handled\n"), notestr);
745
/* All classes are created when the insn class table is parsed;
746
Individual instructions might not appear until the dependency tables
747
are read. Only create new classes if it's *not* an insn class,
748
or if it's a composite class (which wouldn't necessarily be in the IC
750
if (! CONST_STRNEQ (name, "IC:") || xsect != NULL)
753
iclass = fetch_insn_class (name, create);
757
xrealloc ((void *) users,(count + 1) * sizeof (int));
759
xrealloc ((void *) notes,(count + 1) * sizeof (int));
761
users[count++] = iclass;
762
mark_used (ics[iclass], 0);
765
printf("Class %s not found\n", name);
767
/* Update the return values. */
776
parse_semantics (char *sem)
778
if (strcmp (sem, "none") == 0)
779
return IA64_DVS_NONE;
780
else if (strcmp (sem, "implied") == 0)
781
return IA64_DVS_IMPLIED;
782
else if (strcmp (sem, "impliedF") == 0)
783
return IA64_DVS_IMPLIEDF;
784
else if (strcmp (sem, "data") == 0)
785
return IA64_DVS_DATA;
786
else if (strcmp (sem, "instr") == 0)
787
return IA64_DVS_INSTR;
788
else if (strcmp (sem, "specific") == 0)
789
return IA64_DVS_SPECIFIC;
790
else if (strcmp (sem, "stop") == 0)
791
return IA64_DVS_STOP;
793
return IA64_DVS_OTHER;
797
add_dep (const char *name, const char *chk, const char *reg,
798
int semantics, int mode, char *extra, int flag)
802
rs = insert_resource (name, mode);
804
parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
805
parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
807
rs->semantics = semantics;
809
rs->waw_special = flag;
813
load_depfile (const char *filename, enum ia64_dependency_mode mode)
815
FILE *fp = fopen (filename, "r");
819
fail (_("can't find %s for reading\n"), filename);
821
fgets (buf, sizeof(buf), fp);
829
if (fgets (buf, sizeof(buf), fp) == NULL)
832
while (ISSPACE (buf[strlen (buf) - 1]))
833
buf[strlen (buf) - 1] = '\0';
840
while (ISSPACE (*tmp))
843
tmp = strchr (tmp, ';');
847
while (ISSPACE (*tmp))
850
tmp = strchr (tmp, ';');
854
while (ISSPACE (*tmp))
856
semantics = parse_semantics (tmp);
857
extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
859
/* For WAW entries, if the chks and regs differ, we need to enter the
860
entries in both positions so that the tables will be parsed properly,
861
without a lot of extra work. */
862
if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
864
add_dep (name, chkp, regp, semantics, mode, extra, 0);
865
add_dep (name, regp, chkp, semantics, mode, extra, 1);
869
add_dep (name, chkp, regp, semantics, mode, extra, 0);
876
load_dependencies (void)
878
load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
879
load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
880
load_depfile ("ia64-war.tbl", IA64_DV_WAR);
883
printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
886
/* Is the given operand an indirect register file operand? */
888
irf_operand (int op, const char *field)
892
return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
893
|| op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
894
|| op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
895
|| op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
899
return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
900
|| (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
901
|| (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
902
|| (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
903
|| (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
904
|| (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
905
|| (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
906
|| (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid"))
907
|| (op == IA64_OPND_DAHR_R3 && strstr (field, "dahr")));
911
/* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
912
* mov_psr, and mov_um insn classes. */
914
in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
915
const char *format, const char *field)
917
int plain_mov = strcmp (idesc->name, "mov") == 0;
928
int i = strcmp (idesc->name, "mov.i") == 0;
929
int m = strcmp (idesc->name, "mov.m") == 0;
930
int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
931
int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
932
int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
933
int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
934
int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
935
int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
939
return strstr (format, "I26") || strstr (format, "I27");
941
return strstr (format, "I28") != NULL;
943
return strstr (format, "M29") || strstr (format, "M30");
945
return strstr (format, "M31") != NULL;
946
if (pseudo0 || pseudo1)
952
int i21 = idesc->operands[0] == IA64_OPND_B1;
953
int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
955
return strstr (format, "I22") != NULL;
957
return strstr (format, "I21") != NULL;
962
int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
963
int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
965
return strstr (format, "M32") != NULL;
967
return strstr (format, "M33") != NULL;
972
int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3;
974
return strstr (format, "M50") != NULL;
978
if (ic->name[5] == 'n')
980
int m42 = plain_mov && irf_operand (idesc->operands[0], field);
981
int m43 = plain_mov && irf_operand (idesc->operands[1], field);
983
return strstr (format, "M42") != NULL;
985
return strstr (format, "M43") != NULL;
987
else if (ic->name[5] == 'p')
989
return idesc->operands[1] == IA64_OPND_IP;
995
if (ic->name[5] == 'r')
997
int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
998
int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
999
int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
1001
return strstr (format, "I23") != NULL;
1003
return strstr (format, "I24") != NULL;
1005
return strstr (format, "I25") != NULL;
1007
else if (ic->name[5] == 's')
1009
int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
1010
int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
1012
return strstr (format, "M35") != NULL;
1014
return strstr (format, "M36") != NULL;
1021
int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
1022
int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
1024
return strstr (format, "M35") != NULL;
1026
return strstr (format, "M36") != NULL;
1033
/* Is the given opcode in the given insn class? */
1035
in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1036
const char *format, const char *field, int *notep)
1043
if (CONST_STRNEQ (ic->comment, "Format"))
1045
/* Assume that the first format seen is the most restrictive, and
1046
only keep a later one if it looks like it's more restrictive. */
1049
if (strlen (ic->comment) < strlen (format))
1051
warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1052
ic->comment, format);
1053
format = ic->comment;
1057
format = ic->comment;
1059
else if (CONST_STRNEQ (ic->comment, "Field"))
1062
warn (_("overlapping field %s->%s\n"),
1063
ic->comment, field);
1064
field = ic->comment;
1068
/* An insn class matches anything that is the same followed by completers,
1069
except when the absence and presence of completers constitutes different
1071
if (ic->nsubs == 0 && ic->nxsubs == 0)
1073
int is_mov = CONST_STRNEQ (idesc->name, "mov");
1074
int plain_mov = strcmp (idesc->name, "mov") == 0;
1075
int len = strlen(ic->name);
1077
resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1078
&& (idesc->name[len] == '\0'
1079
|| idesc->name[len] == '.'));
1081
/* All break, nop, and hint variations must match exactly. */
1083
(strcmp (ic->name, "break") == 0
1084
|| strcmp (ic->name, "nop") == 0
1085
|| strcmp (ic->name, "hint") == 0))
1086
resolved = strcmp (ic->name, idesc->name) == 0;
1088
/* Assume restrictions in the FORMAT/FIELD negate resolution,
1089
unless specifically allowed by clauses in this block. */
1090
if (resolved && field)
1092
/* Check Field(sf)==sN against opcode sN. */
1093
if (strstr(field, "(sf)==") != NULL)
1097
if ((sf = strstr (idesc->name, ".s")) != 0)
1098
resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1100
/* Check Field(lftype)==XXX. */
1101
else if (strstr (field, "(lftype)") != NULL)
1103
if (strstr (idesc->name, "fault") != NULL)
1104
resolved = strstr (field, "fault") != NULL;
1106
resolved = strstr (field, "fault") == NULL;
1108
/* Handle Field(ctype)==XXX. */
1109
else if (strstr (field, "(ctype)") != NULL)
1111
if (strstr (idesc->name, "or.andcm"))
1112
resolved = strstr (field, "or.andcm") != NULL;
1113
else if (strstr (idesc->name, "and.orcm"))
1114
resolved = strstr (field, "and.orcm") != NULL;
1115
else if (strstr (idesc->name, "orcm"))
1116
resolved = strstr (field, "or orcm") != NULL;
1117
else if (strstr (idesc->name, "or"))
1118
resolved = strstr (field, "or orcm") != NULL;
1119
else if (strstr (idesc->name, "andcm"))
1120
resolved = strstr (field, "and andcm") != NULL;
1121
else if (strstr (idesc->name, "and"))
1122
resolved = strstr (field, "and andcm") != NULL;
1123
else if (strstr (idesc->name, "unc"))
1124
resolved = strstr (field, "unc") != NULL;
1126
resolved = strcmp (field, "Field(ctype)==") == 0;
1130
if (resolved && format)
1132
if (CONST_STRNEQ (idesc->name, "dep")
1133
&& strstr (format, "I13") != NULL)
1134
resolved = idesc->operands[1] == IA64_OPND_IMM8;
1135
else if (CONST_STRNEQ (idesc->name, "chk")
1136
&& strstr (format, "M21") != NULL)
1137
resolved = idesc->operands[0] == IA64_OPND_F2;
1138
else if (CONST_STRNEQ (idesc->name, "lfetch"))
1139
resolved = (strstr (format, "M14 M15") != NULL
1140
&& (idesc->operands[1] == IA64_OPND_R2
1141
|| idesc->operands[1] == IA64_OPND_IMM9b));
1142
else if (CONST_STRNEQ (idesc->name, "br.call")
1143
&& strstr (format, "B5") != NULL)
1144
resolved = idesc->operands[1] == IA64_OPND_B2;
1145
else if (CONST_STRNEQ (idesc->name, "br.call")
1146
&& strstr (format, "B3") != NULL)
1147
resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1148
else if (CONST_STRNEQ (idesc->name, "brp")
1149
&& strstr (format, "B7") != NULL)
1150
resolved = idesc->operands[0] == IA64_OPND_B2;
1151
else if (strcmp (ic->name, "invala") == 0)
1152
resolved = strcmp (idesc->name, ic->name) == 0;
1153
else if (CONST_STRNEQ (idesc->name, "st")
1154
&& (strstr (format, "M5") != NULL
1155
|| strstr (format, "M10") != NULL))
1156
resolved = idesc->flags & IA64_OPCODE_POSTINC;
1157
else if (CONST_STRNEQ (idesc->name, "ld")
1158
&& (strstr (format, "M2 M3") != NULL
1159
|| strstr (format, "M12") != NULL
1160
|| strstr (format, "M7 M8") != NULL))
1161
resolved = idesc->flags & IA64_OPCODE_POSTINC;
1166
/* Misc brl variations ('.cond' is optional);
1167
plain brl matches brl.cond. */
1169
&& (strcmp (idesc->name, "brl") == 0
1170
|| CONST_STRNEQ (idesc->name, "brl."))
1171
&& strcmp (ic->name, "brl.cond") == 0)
1176
/* Misc br variations ('.cond' is optional). */
1178
&& (strcmp (idesc->name, "br") == 0
1179
|| CONST_STRNEQ (idesc->name, "br."))
1180
&& strcmp (ic->name, "br.cond") == 0)
1183
resolved = (strstr (format, "B4") != NULL
1184
&& idesc->operands[0] == IA64_OPND_B2)
1185
|| (strstr (format, "B1") != NULL
1186
&& idesc->operands[0] == IA64_OPND_TGT25c);
1191
/* probe variations. */
1192
if (!resolved && CONST_STRNEQ (idesc->name, "probe"))
1194
resolved = strcmp (ic->name, "probe") == 0
1195
&& !((strstr (idesc->name, "fault") != NULL)
1196
^ (format && strstr (format, "M40") != NULL));
1199
/* mov variations. */
1200
if (!resolved && is_mov)
1204
/* mov alias for fmerge. */
1205
if (strcmp (ic->name, "fmerge") == 0)
1207
resolved = idesc->operands[0] == IA64_OPND_F1
1208
&& idesc->operands[1] == IA64_OPND_F3;
1210
/* mov alias for adds (r3 or imm14). */
1211
else if (strcmp (ic->name, "adds") == 0)
1213
resolved = (idesc->operands[0] == IA64_OPND_R1
1214
&& (idesc->operands[1] == IA64_OPND_R3
1215
|| (idesc->operands[1] == IA64_OPND_IMM14)));
1217
/* mov alias for addl. */
1218
else if (strcmp (ic->name, "addl") == 0)
1220
resolved = idesc->operands[0] == IA64_OPND_R1
1221
&& idesc->operands[1] == IA64_OPND_IMM22;
1225
/* Some variants of mov and mov.[im]. */
1226
if (!resolved && CONST_STRNEQ (ic->name, "mov_"))
1227
resolved = in_iclass_mov_x (idesc, ic, format, field);
1230
/* Keep track of this so we can flag any insn classes which aren't
1231
mapped onto at least one real insn. */
1233
ic->terminal_resolved = 1;
1235
else for (i = 0; i < ic->nsubs; i++)
1237
if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1241
for (j = 0; j < ic->nxsubs; j++)
1242
if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1246
printf ("%s is in IC %s\n", idesc->name, ic->name);
1253
/* If it's in this IC, add the IC note (if any) to the insn. */
1256
if (ic->note && notep)
1258
if (*notep && *notep != ic->note)
1259
warn (_("overwriting note %d with note %d (IC:%s)\n"),
1260
*notep, ic->note, ic->name);
1271
lookup_regindex (const char *name, int specifier)
1276
if (strstr (name, "[RSC]"))
1278
if (strstr (name, "[BSP]"))
1280
else if (strstr (name, "[BSPSTORE]"))
1282
else if (strstr (name, "[RNAT]"))
1284
else if (strstr (name, "[FCR]"))
1286
else if (strstr (name, "[EFLAG]"))
1288
else if (strstr (name, "[CSD]"))
1290
else if (strstr (name, "[SSD]"))
1292
else if (strstr (name, "[CFLG]"))
1294
else if (strstr (name, "[FSR]"))
1296
else if (strstr (name, "[FIR]"))
1298
else if (strstr (name, "[FDR]"))
1300
else if (strstr (name, "[CCV]"))
1302
else if (strstr (name, "[ITC]"))
1304
else if (strstr (name, "[RUC]"))
1306
else if (strstr (name, "[PFS]"))
1308
else if (strstr (name, "[LC]"))
1310
else if (strstr (name, "[EC]"))
1314
if (strstr (name, "[DCR]"))
1316
else if (strstr (name, "[ITM]"))
1318
else if (strstr (name, "[IVA]"))
1320
else if (strstr (name, "[PTA]"))
1322
else if (strstr (name, "[GPTA]"))
1324
else if (strstr (name, "[IPSR]"))
1326
else if (strstr (name, "[ISR]"))
1328
else if (strstr (name, "[IIP]"))
1330
else if (strstr (name, "[IFA]"))
1332
else if (strstr (name, "[ITIR]"))
1334
else if (strstr (name, "[IIPA]"))
1336
else if (strstr (name, "[IFS]"))
1338
else if (strstr (name, "[IIM]"))
1340
else if (strstr (name, "[IHA]"))
1342
else if (strstr (name, "[LID]"))
1344
else if (strstr (name, "[IVR]"))
1346
else if (strstr (name, "[TPR]"))
1348
else if (strstr (name, "[EOI]"))
1350
else if (strstr (name, "[ITV]"))
1352
else if (strstr (name, "[PMV]"))
1354
else if (strstr (name, "[CMCV]"))
1358
if (strstr (name, ".be"))
1360
else if (strstr (name, ".up"))
1362
else if (strstr (name, ".ac"))
1364
else if (strstr (name, ".mfl"))
1366
else if (strstr (name, ".mfh"))
1368
else if (strstr (name, ".ic"))
1370
else if (strstr (name, ".i"))
1372
else if (strstr (name, ".pk"))
1374
else if (strstr (name, ".dt"))
1376
else if (strstr (name, ".dfl"))
1378
else if (strstr (name, ".dfh"))
1380
else if (strstr (name, ".sp"))
1382
else if (strstr (name, ".pp"))
1384
else if (strstr (name, ".di"))
1386
else if (strstr (name, ".si"))
1388
else if (strstr (name, ".db"))
1390
else if (strstr (name, ".lp"))
1392
else if (strstr (name, ".tb"))
1394
else if (strstr (name, ".rt"))
1396
else if (strstr (name, ".cpl"))
1398
else if (strstr (name, ".rs"))
1400
else if (strstr (name, ".mc"))
1402
else if (strstr (name, ".it"))
1404
else if (strstr (name, ".id"))
1406
else if (strstr (name, ".da"))
1408
else if (strstr (name, ".dd"))
1410
else if (strstr (name, ".ss"))
1412
else if (strstr (name, ".ri"))
1414
else if (strstr (name, ".ed"))
1416
else if (strstr (name, ".bn"))
1418
else if (strstr (name, ".ia"))
1420
else if (strstr (name, ".vm"))
1431
lookup_specifier (const char *name)
1433
if (strchr (name, '%'))
1435
if (strstr (name, "AR[K%]") != NULL)
1436
return IA64_RS_AR_K;
1437
if (strstr (name, "AR[UNAT]") != NULL)
1438
return IA64_RS_AR_UNAT;
1439
if (strstr (name, "AR%, % in 8") != NULL)
1441
if (strstr (name, "AR%, % in 48") != NULL)
1443
if (strstr (name, "BR%") != NULL)
1445
if (strstr (name, "CR[IIB%]") != NULL)
1446
return IA64_RS_CR_IIB;
1447
if (strstr (name, "CR[IRR%]") != NULL)
1448
return IA64_RS_CR_IRR;
1449
if (strstr (name, "CR[LRR%]") != NULL)
1450
return IA64_RS_CR_LRR;
1451
if (strstr (name, "CR%") != NULL)
1453
if (strstr (name, "DAHR%, % in 0") != NULL)
1454
return IA64_RS_DAHR;
1455
if (strstr (name, "FR%, % in 0") != NULL)
1457
if (strstr (name, "FR%, % in 2") != NULL)
1459
if (strstr (name, "GR%") != NULL)
1461
if (strstr (name, "PR%, % in 1 ") != NULL)
1463
if (strstr (name, "PR%, % in 16 ") != NULL)
1466
warn (_("don't know how to specify %% dependency %s\n"),
1469
else if (strchr (name, '#'))
1471
if (strstr (name, "CPUID#") != NULL)
1472
return IA64_RS_CPUID;
1473
if (strstr (name, "DBR#") != NULL)
1475
if (strstr (name, "IBR#") != NULL)
1477
if (strstr (name, "MSR#") != NULL)
1479
if (strstr (name, "PKR#") != NULL)
1481
if (strstr (name, "PMC#") != NULL)
1483
if (strstr (name, "PMD#") != NULL)
1485
if (strstr (name, "RR#") != NULL)
1488
warn (_("Don't know how to specify # dependency %s\n"),
1491
else if (CONST_STRNEQ (name, "AR[FPSR]"))
1492
return IA64_RS_AR_FPSR;
1493
else if (CONST_STRNEQ (name, "AR["))
1495
else if (CONST_STRNEQ (name, "CR["))
1497
else if (CONST_STRNEQ (name, "PSR."))
1499
else if (strcmp (name, "InService*") == 0)
1500
return IA64_RS_INSERVICE;
1501
else if (strcmp (name, "GR0") == 0)
1503
else if (strcmp (name, "CFM") == 0)
1505
else if (strcmp (name, "PR63") == 0)
1506
return IA64_RS_PR63;
1507
else if (strcmp (name, "RSE") == 0)
1514
print_dependency_table (void)
1520
for (i=0;i < iclen;i++)
1522
if (ics[i]->is_class)
1526
if (ics[i]->comment)
1527
warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1528
ics[i]->name, ics[i]->comment);
1530
warn (_("IC:%s has no terminals or sub-classes\n"),
1536
if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1538
if (ics[i]->comment)
1539
warn (_("no insns mapped directly to terminal IC %s [%s]"),
1540
ics[i]->name, ics[i]->comment);
1542
warn (_("no insns mapped directly to terminal IC %s\n"),
1548
for (i = 0; i < iclen; i++)
1552
mark_used (ics[i], 1);
1553
warn (_("class %s is defined but not used\n"),
1559
for (i = 0; i < rdepslen; i++)
1561
static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1563
if (rdeps[i]->total_chks == 0)
1565
if (rdeps[i]->total_regs)
1566
warn (_("Warning: rsrc %s (%s) has no chks\n"),
1567
rdeps[i]->name, mode_str[rdeps[i]->mode]);
1569
warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1570
rdeps[i]->name, mode_str[rdeps[i]->mode]);
1572
else if (rdeps[i]->total_regs == 0)
1573
warn (_("rsrc %s (%s) has no regs\n"),
1574
rdeps[i]->name, mode_str[rdeps[i]->mode]);
1578
/* The dependencies themselves. */
1579
printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1580
for (i = 0; i < rdepslen; i++)
1582
/* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1584
int specifier = lookup_specifier (rdeps[i]->name);
1585
int regindex = lookup_regindex (rdeps[i]->name, specifier);
1587
printf (" { \"%s\", %d, %d, %d, %d, ",
1588
rdeps[i]->name, specifier,
1589
(int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1590
if (rdeps[i]->semantics == IA64_DVS_OTHER)
1592
const char *quote, *rest;
1595
rest = rdeps[i]->extra;
1596
quote = strchr (rest, '\"');
1597
while (quote != NULL)
1599
printf ("%.*s\\\"", (int) (quote - rest), rest);
1601
quote = strchr (rest, '\"');
1603
printf ("%s\", ", rest);
1611
/* And dependency lists. */
1612
for (i=0;i < dlistlen;i++)
1615
printf ("static const unsigned short dep%d[] = {\n ", i);
1616
for (j=0;j < dlists[i]->len; j++)
1618
len += printf ("%d, ", dlists[i]->deps[j]);
1625
printf ("\n};\n\n");
1628
/* And opcode dependency list. */
1629
printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1630
printf ("static const struct ia64_opcode_dependency\n");
1631
printf ("op_dependencies[] = {\n");
1632
for (i = 0; i < opdeplen; i++)
1635
if (opdeps[i]->chk == -1)
1636
printf ("0, NULL, ");
1638
printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1639
if (opdeps[i]->reg == -1)
1640
printf ("0, NULL, ");
1642
printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1649
/* Add STR to the string table. */
1650
static struct string_entry *
1651
insert_string (char *str)
1653
int start = 0, end = strtablen;
1656
if (strtablen == strtabtotlen)
1659
string_table = (struct string_entry **)
1660
xrealloc (string_table,
1661
sizeof (struct string_entry **) * strtabtotlen);
1667
string_table[0] = tmalloc (struct string_entry);
1668
string_table[0]->s = xstrdup (str);
1669
string_table[0]->num = 0;
1670
return string_table[0];
1673
if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1675
else if (strcmp (str, string_table[0]->s) < 0)
1683
i = (start + end) / 2;
1684
c = strcmp (str, string_table[i]->s);
1689
return string_table[i];
1698
for (; i > 0 && i < strtablen; i--)
1699
if (strcmp (str, string_table[i - 1]->s) > 0)
1702
for (; i < strtablen; i++)
1703
if (strcmp (str, string_table[i]->s) < 0)
1706
for (x = strtablen - 1; x >= i; x--)
1708
string_table[x + 1] = string_table[x];
1709
string_table[x + 1]->num = x + 1;
1712
string_table[i] = tmalloc (struct string_entry);
1713
string_table[i]->s = xstrdup (str);
1714
string_table[i]->num = i;
1717
return string_table[i];
1720
static struct bittree *
1721
make_bittree_entry (void)
1723
struct bittree *res = tmalloc (struct bittree);
1726
res->bits[0] = NULL;
1727
res->bits[1] = NULL;
1728
res->bits[2] = NULL;
1730
res->bits_to_skip = 0;
1735
static struct disent *
1736
add_dis_table_ent (struct disent *which, int insn, int order,
1737
ci_t completer_index)
1747
while (ent->nexte != NULL)
1750
ent = (ent->nexte = tmalloc (struct disent));
1754
ent = tmalloc (struct disent);
1755
ent->next_ent = disinsntable;
1762
ent->priority = order;
1764
while (completer_index != 1)
1766
ci = (ci << 1) | (completer_index & 1);
1767
completer_index >>= 1;
1769
ent->completer_index = ci;
1774
finish_distable (void)
1776
struct disent *ent = disinsntable;
1777
struct disent *prev = ent;
1779
ent->ournum = 32768;
1780
while ((ent = ent->next_ent) != NULL)
1782
ent->ournum = prev->ournum + prev->nextcnt + 1;
1788
insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode,
1789
ia64_insn mask, int opcodenum, int order,
1790
ci_t completer_index)
1794
struct bittree *next;
1798
struct disent *nent = add_dis_table_ent (curr_ent->disent,
1801
curr_ent->disent = nent;
1805
m = ((ia64_insn) 1) << bit;
1808
b = (opcode & m) ? 1 : 0;
1812
next = curr_ent->bits[b];
1815
next = make_bittree_entry ();
1816
curr_ent->bits[b] = next;
1818
insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1823
add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask,
1824
int opcodenum, struct completer_entry *ent, ci_t completer_index)
1826
if (completer_index & ((ci_t)1 << 32) )
1831
ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1832
add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1833
(completer_index << 1) | 1);
1835
if (ent->is_terminal)
1837
insert_bit_table_ent (bittree, 40, newopcode, mask,
1838
opcodenum, opcode_count - ent->order - 1,
1839
(completer_index << 1) | 1);
1841
completer_index <<= 1;
1842
ent = ent->alternative;
1846
/* This optimization pass combines multiple "don't care" nodes. */
1848
compact_distree (struct bittree *ent)
1850
#define IS_SKIP(ent) \
1851
((ent->bits[2] !=NULL) \
1852
&& (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1855
struct bittree *nent = ent;
1858
while (IS_SKIP (nent))
1861
nent = nent->bits[2];
1866
struct bittree *next = ent->bits[2];
1868
ent->bits[0] = nent->bits[0];
1869
ent->bits[1] = nent->bits[1];
1870
ent->bits[2] = nent->bits[2];
1871
ent->disent = nent->disent;
1873
ent->bits_to_skip = bitcnt;
1874
while (next != nent)
1876
struct bittree *b = next;
1877
next = next->bits[2];
1883
for (x = 0; x < 3; x++)
1885
struct bittree *i = ent->bits[x];
1888
compact_distree (i);
1892
static unsigned char *insn_list;
1893
static int insn_list_len = 0;
1894
static int tot_insn_list_len = 0;
1896
/* Generate the disassembler state machine corresponding to the tree
1899
gen_dis_table (struct bittree *ent)
1902
int our_offset = insn_list_len;
1904
int totbits = bitsused;
1907
int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */
1909
/* If this is a terminal entry, there's no point in skipping any
1911
if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1912
ent->bits[2] == NULL)
1914
if (ent->disent == NULL)
1920
/* Calculate the amount of space needed for this entry, or at least
1921
a conservatively large approximation. */
1925
for (x = 1; x < 3; x++)
1926
if (ent->bits[x] != NULL)
1929
if (ent->disent != NULL)
1931
if (ent->bits[2] != NULL)
1937
/* Now allocate the space. */
1938
needed_bytes = (totbits + 7) / 8;
1939
if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1941
tot_insn_list_len += 256;
1942
insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
1944
our_offset = insn_list_len;
1945
insn_list_len += needed_bytes;
1946
memset (insn_list + our_offset, 0, needed_bytes);
1948
/* Encode the skip entry by setting bit 6 set in the state op field,
1949
and store the # of bits to skip immediately after. */
1953
insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1954
insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1957
#define IS_ONLY_IFZERO(ENT) \
1958
((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1959
&& (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1961
/* Store an "if (bit is zero)" instruction by setting bit 7 in the
1963
if (ent->bits[0] != NULL)
1965
struct bittree *nent = ent->bits[0];
1968
insn_list[our_offset] |= 0x80;
1970
/* We can encode sequences of multiple "if (bit is zero)" tests
1971
by storing the # of zero bits to check in the lower 3 bits of
1972
the instruction. However, this only applies if the state
1973
solely tests for a zero bit. */
1975
if (IS_ONLY_IFZERO (ent))
1977
while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1979
nent = nent->bits[0];
1983
insn_list[our_offset + 0] |= zero_count;
1985
zero_dest = insn_list_len;
1986
gen_dis_table (nent);
1989
/* Now store the remaining tests. We also handle a sole "termination
1990
entry" by storing it as an "any bit" test. */
1992
for (x = 1; x < 3; x++)
1994
if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1996
struct bittree *i = ent->bits[x];
2002
/* If the instruction being branched to only consists of
2003
a termination entry, use the termination entry as the
2004
place to branch to instead. */
2005
if (i->bits[0] == NULL && i->bits[1] == NULL
2006
&& i->bits[2] == NULL && i->disent != NULL)
2008
idest = i->disent->ournum;
2012
idest = insn_list_len - our_offset;
2015
idest = ent->disent->ournum;
2017
/* If the destination offset for the if (bit is 1) test is less
2018
than 256 bytes away, we can store it as 8-bits instead of 16;
2019
the instruction has bit 5 set for the 16-bit address, and bit
2020
4 for the 8-bit address. Since we've already allocated 16
2021
bits for the address we need to deallocate the space.
2023
Note that branchings within the table are relative, and
2024
there are no branches that branch past our instruction yet
2025
so we do not need to adjust any other offsets. */
2030
int start = our_offset + bitsused / 8 + 1;
2032
memmove (insn_list + start,
2033
insn_list + start + 1,
2034
insn_list_len - (start + 1));
2039
insn_list[our_offset] |= 0x10;
2043
insn_list[our_offset] |= 0x20;
2047
/* An instruction which solely consists of a termination
2048
marker and whose disassembly name index is < 4096
2049
can be stored in 16 bits. The encoding is slightly
2050
odd; the upper 4 bits of the instruction are 0x3, and
2051
bit 3 loses its normal meaning. */
2053
if (ent->bits[0] == NULL && ent->bits[1] == NULL
2054
&& ent->bits[2] == NULL && ent->skip_flag == 0
2055
&& ent->disent != NULL
2056
&& ent->disent->ournum < (32768 + 4096))
2058
int start = our_offset + bitsused / 8 + 1;
2060
memmove (insn_list + start,
2061
insn_list + start + 1,
2062
insn_list_len - (start + 1));
2068
insn_list[our_offset] |= 0x30;
2072
insn_list[our_offset] |= 0x08;
2081
else if (! (id & 32768))
2085
printf ("%d: if (1) goto %d\n", our_offset, id);
2087
printf ("%d: try %d\n", our_offset, id);
2090
/* Store the address of the entry being branched to. */
2091
while (currbits >= 0)
2093
unsigned char *byte = insn_list + our_offset + bitsused / 8;
2095
if (idest & (1 << currbits))
2096
*byte |= (1 << (7 - (bitsused % 8)));
2102
/* Now generate the states for the entry being branched to. */
2111
printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2113
if (ent->bits[0] != NULL)
2114
printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2118
if (bitsused != totbits)
2123
print_dis_table (void)
2126
struct disent *cent = disinsntable;
2128
printf ("static const char dis_table[] = {\n");
2129
for (x = 0; x < insn_list_len; x++)
2131
if ((x > 0) && ((x % 12) == 0))
2134
printf ("0x%02x, ", insn_list[x]);
2136
printf ("\n};\n\n");
2138
printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2139
while (cent != NULL)
2141
struct disent *ent = cent;
2145
printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent->completer_index,
2146
ent->insn, (ent->nexte != NULL ? 1 : 0),
2150
cent = cent->next_ent;
2156
generate_disassembler (void)
2160
bittree = make_bittree_entry ();
2162
for (i = 0; i < otlen; i++)
2164
struct main_entry *ptr = ordered_table[i];
2166
if (ptr->opcode->type != IA64_TYPE_DYN)
2167
add_dis_entry (bittree,
2168
ptr->opcode->opcode, ptr->opcode->mask,
2170
ptr->completers, 1);
2173
compact_distree (bittree);
2175
gen_dis_table (bittree);
2181
print_string_table (void)
2184
char lbuf[80], buf[80];
2187
printf ("static const char * const ia64_strings[] = {\n");
2190
for (x = 0; x < strtablen; x++)
2194
if (strlen (string_table[x]->s) > 75)
2197
sprintf (buf, " \"%s\",", string_table[x]->s);
2200
if ((blen + len) > 75)
2202
printf (" %s\n", lbuf);
2211
printf (" %s\n", lbuf);
2216
static struct completer_entry **glist;
2217
static int glistlen = 0;
2218
static int glisttotlen = 0;
2220
/* If the completer trees ENT1 and ENT2 are equal, return 1. */
2223
completer_entries_eq (struct completer_entry *ent1,
2224
struct completer_entry *ent2)
2226
while (ent1 != NULL && ent2 != NULL)
2228
if (ent1->name->num != ent2->name->num
2229
|| ent1->bits != ent2->bits
2230
|| ent1->mask != ent2->mask
2231
|| ent1->is_terminal != ent2->is_terminal
2232
|| ent1->dependencies != ent2->dependencies
2233
|| ent1->order != ent2->order)
2236
if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2239
ent1 = ent1->alternative;
2240
ent2 = ent2->alternative;
2243
return ent1 == ent2;
2246
/* Insert ENT into the global list of completers and return it. If an
2247
equivalent entry (according to completer_entries_eq) already exists,
2248
it is returned instead. */
2249
static struct completer_entry *
2250
insert_gclist (struct completer_entry *ent)
2258
ent->addl_entries = insert_gclist (ent->addl_entries);
2259
ent->alternative = insert_gclist (ent->alternative);
2264
if (glisttotlen == glistlen)
2267
glist = (struct completer_entry **)
2268
xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2278
if (ent->name->num < glist[0]->name->num)
2280
else if (ent->name->num > glist[end - 1]->name->num)
2288
i = (start + end) / 2;
2289
c = ent->name->num - glist[i]->name->num;
2296
&& ent->name->num == glist[i - 1]->name->num)
2310
while (i < glistlen)
2312
if (ent->name->num != glist[i]->name->num)
2315
if (completer_entries_eq (ent, glist[i]))
2323
for (; i > 0 && i < glistlen; i--)
2324
if (ent->name->num >= glist[i - 1]->name->num)
2327
for (; i < glistlen; i++)
2328
if (ent->name->num < glist[i]->name->num)
2331
for (x = glistlen - 1; x >= i; x--)
2332
glist[x + 1] = glist[x];
2341
get_prefix_len (const char *name)
2345
if (name[0] == '\0')
2348
c = strchr (name, '.');
2352
return strlen (name);
2356
compute_completer_bits (struct main_entry *ment, struct completer_entry *ent)
2360
compute_completer_bits (ment, ent->addl_entries);
2362
if (ent->is_terminal)
2365
ia64_insn our_bits = ent->bits;
2366
struct completer_entry *p = ent->parent;
2370
while (p != NULL && ! p->is_terminal)
2376
p_bits = ment->opcode->opcode;
2378
for (x = 0; x < 64; x++)
2380
ia64_insn m = ((ia64_insn) 1) << x;
2382
if ((p_bits & m) != (our_bits & m))
2387
ent->bits = our_bits;
2396
ent = ent->alternative;
2400
/* Find identical completer trees that are used in different
2401
instructions and collapse their entries. */
2403
collapse_redundant_completers (void)
2405
struct main_entry *ptr;
2408
for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2410
if (ptr->completers == NULL)
2413
compute_completer_bits (ptr, ptr->completers);
2414
ptr->completers = insert_gclist (ptr->completers);
2417
/* The table has been finalized, now number the indexes. */
2418
for (x = 0; x < glistlen; x++)
2423
/* Attach two lists of dependencies to each opcode.
2424
1) all resources which, when already marked in use, conflict with this
2426
2) all resources which must be marked in use when this opcode is used
2429
insert_opcode_dependencies (struct ia64_opcode *opc,
2430
struct completer_entry *cmp ATTRIBUTE_UNUSED)
2432
/* Note all resources which point to this opcode. rfi has the most chks
2433
(79) and cmpxchng has the most regs (54) so 100 here should be enough. */
2436
unsigned short regs[256];
2438
unsigned short chks[256];
2439
/* Flag insns for which no class matched; there should be none. */
2440
int no_class_found = 1;
2442
for (i = 0; i < rdepslen; i++)
2444
struct rdep *rs = rdeps[i];
2447
if (strcmp (opc->name, "cmp.eq.and") == 0
2448
&& CONST_STRNEQ (rs->name, "PR%")
2450
no_class_found = 99;
2452
for (j=0; j < rs->nregs;j++)
2456
if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2458
/* We can ignore ic_note 11 for non PR resources. */
2459
if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2462
if (ic_note != 0 && rs->regnotes[j] != 0
2463
&& ic_note != rs->regnotes[j]
2464
&& !(ic_note == 11 && rs->regnotes[j] == 1))
2465
warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2466
ic_note, opc->name, ics[rs->regs[j]]->name,
2467
rs->name, rs->regnotes[j]);
2468
/* Instruction class notes override resource notes.
2469
So far, only note 11 applies to an IC instead of a resource,
2470
and note 11 implies note 1. */
2472
regs[nregs++] = RDEP(ic_note, i);
2474
regs[nregs++] = RDEP(rs->regnotes[j], i);
2480
for (j = 0; j < rs->nchks; j++)
2484
if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2486
/* We can ignore ic_note 11 for non PR resources. */
2487
if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2490
if (ic_note != 0 && rs->chknotes[j] != 0
2491
&& ic_note != rs->chknotes[j]
2492
&& !(ic_note == 11 && rs->chknotes[j] == 1))
2493
warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2494
ic_note, opc->name, ics[rs->chks[j]]->name,
2495
rs->name, rs->chknotes[j]);
2497
chks[nchks++] = RDEP(ic_note, i);
2499
chks[nchks++] = RDEP(rs->chknotes[j], i);
2507
warn (_("opcode %s has no class (ops %d %d %d)\n"),
2509
opc->operands[0], opc->operands[1], opc->operands[2]);
2511
return insert_dependencies (nchks, chks, nregs, regs);
2515
insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent,
2518
struct completer_entry **ptr = &tabent->completers;
2519
struct completer_entry *parent = NULL;
2520
char pcopy[129], *prefix;
2523
if (strlen (opc->name) > 128)
2526
strcpy (pcopy, opc->name);
2527
prefix = pcopy + get_prefix_len (pcopy);
2529
if (prefix[0] != '\0')
2534
int need_new_ent = 1;
2535
int plen = get_prefix_len (prefix);
2536
struct string_entry *sent;
2538
at_end = (prefix[plen] == '\0');
2539
prefix[plen] = '\0';
2540
sent = insert_string (prefix);
2542
while (*ptr != NULL)
2544
int cmpres = sent->num - (*ptr)->name->num;
2552
ptr = &((*ptr)->alternative);
2557
struct completer_entry *nent = tmalloc (struct completer_entry);
2560
nent->parent = parent;
2561
nent->addl_entries = NULL;
2562
nent->alternative = *ptr;
2564
nent->is_terminal = 0;
2565
nent->dependencies = -1;
2571
ptr = &((*ptr)->addl_entries);
2576
if ((*ptr)->is_terminal)
2579
(*ptr)->is_terminal = 1;
2580
(*ptr)->mask = (ia64_insn)-1;
2581
(*ptr)->bits = opc->opcode;
2582
(*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2583
(*ptr)->order = order;
2587
print_completer_entry (struct completer_entry *ent)
2590
ia64_insn mask = ent->mask, bits = ent->bits;
2594
while (! (mask & 1))
2601
if (bits & 0xffffffff00000000LL)
2605
printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2609
ent->alternative != NULL ? ent->alternative->num : -1,
2610
ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2612
ent->is_terminal ? 1 : 0,
2617
print_completer_table (void)
2621
printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2622
for (x = 0; x < glistlen; x++)
2623
print_completer_entry (glist[x]);
2628
opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2)
2633
if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2634
|| (opc1->num_outputs != opc2->num_outputs)
2635
|| (opc1->flags != opc2->flags))
2638
for (x = 0; x < 5; x++)
2639
if (opc1->operands[x] != opc2->operands[x])
2642
plen1 = get_prefix_len (opc1->name);
2643
plen2 = get_prefix_len (opc2->name);
2645
if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2652
add_opcode_entry (struct ia64_opcode *opc)
2654
struct main_entry **place;
2655
struct string_entry *name;
2659
if (strlen (opc->name) > 128)
2663
strcpy (prefix, opc->name);
2664
prefix[get_prefix_len (prefix)] = '\0';
2665
name = insert_string (prefix);
2667
/* Walk the list of opcode table entries. If it's a new
2668
instruction, allocate and fill in a new entry. Note
2669
the main table is alphabetical by opcode name. */
2671
while (*place != NULL)
2673
if ((*place)->name->num == name->num
2674
&& opcodes_eq ((*place)->opcode, opc))
2679
if ((*place)->name->num > name->num)
2682
place = &((*place)->next);
2686
struct main_entry *nent = tmalloc (struct main_entry);
2690
nent->next = *place;
2691
nent->completers = 0;
2694
if (otlen == ottotlen)
2697
ordered_table = (struct main_entry **)
2698
xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2700
ordered_table[otlen++] = nent;
2703
insert_completer_entry (opc, *place, opcode_count++);
2707
print_main_table (void)
2709
struct main_entry *ptr = maintable;
2712
printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2715
printf (" { %d, %d, %d, 0x",
2718
ptr->opcode->num_outputs);
2719
opcode_fprintf_vma (stdout, ptr->opcode->opcode);
2721
opcode_fprintf_vma (stdout, ptr->opcode->mask);
2722
printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2723
ptr->opcode->operands[0],
2724
ptr->opcode->operands[1],
2725
ptr->opcode->operands[2],
2726
ptr->opcode->operands[3],
2727
ptr->opcode->operands[4],
2729
ptr->completers->num);
2731
ptr->main_index = tindex++;
2739
shrink (struct ia64_opcode *table)
2743
for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2745
add_opcode_entry (table + curr_opcode);
2746
if (table[curr_opcode].num_outputs == 2
2747
&& ((table[curr_opcode].operands[0] == IA64_OPND_P1
2748
&& table[curr_opcode].operands[1] == IA64_OPND_P2)
2749
|| (table[curr_opcode].operands[0] == IA64_OPND_P2
2750
&& table[curr_opcode].operands[1] == IA64_OPND_P1)))
2752
struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2755
*alias = table[curr_opcode];
2756
for (i = 2; i < NELEMS (alias->operands); ++i)
2757
alias->operands[i - 1] = alias->operands[i];
2758
alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2759
--alias->num_outputs;
2760
alias->flags |= PSEUDO;
2761
add_opcode_entry (alias);
2767
/* Program options. */
2768
#define OPTION_SRCDIR 200
2770
struct option long_options[] =
2772
{"srcdir", required_argument, NULL, OPTION_SRCDIR},
2773
{"debug", no_argument, NULL, 'd'},
2774
{"version", no_argument, NULL, 'V'},
2775
{"help", no_argument, NULL, 'h'},
2776
{0, no_argument, NULL, 0}
2780
print_version (void)
2782
printf ("%s: version 1.0\n", program_name);
2787
usage (FILE * stream, int status)
2789
fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2795
main (int argc, char **argv)
2797
extern int chdir (char *);
2798
char *srcdir = NULL;
2801
program_name = *argv;
2802
xmalloc_set_program_name (program_name);
2804
while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2829
if (chdir (srcdir) != 0)
2830
fail (_("unable to change directory to \"%s\", errno = %s\n"),
2831
srcdir, strerror (errno));
2833
load_insn_classes ();
2834
load_dependencies ();
2836
shrink (ia64_opcodes_a);
2837
shrink (ia64_opcodes_b);
2838
shrink (ia64_opcodes_f);
2839
shrink (ia64_opcodes_i);
2840
shrink (ia64_opcodes_m);
2841
shrink (ia64_opcodes_x);
2842
shrink (ia64_opcodes_d);
2844
collapse_redundant_completers ();
2846
printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n");
2847
printf ("/* Copyright 2007 Free Software Foundation, Inc.\n\
2849
This file is part of the GNU opcodes library.\n\
2851
This library is free software; you can redistribute it and/or modify\n\
2852
it under the terms of the GNU General Public License as published by\n\
2853
the Free Software Foundation; either version 3, or (at your option)\n\
2854
any later version.\n\
2856
It is distributed in the hope that it will be useful, but WITHOUT\n\
2857
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2858
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
2859
License for more details.\n\
2861
You should have received a copy of the GNU General Public License\n\
2862
along with this program; see the file COPYING. If not, write to the\n\
2863
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2864
02110-1301, USA. */\n");
2866
print_string_table ();
2867
print_dependency_table ();
2868
print_completer_table ();
2869
print_main_table ();
2871
generate_disassembler ();