~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/opcodes/ia64-gen.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
5
 
 
6
   This file is part of the GNU opcodes library.
 
7
 
 
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)
 
11
   any later version.
 
12
 
 
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.
 
17
 
 
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
 
21
   02110-1301, USA.  */
 
22
 
 
23
 
 
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.  
 
28
 
 
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
 
32
   required.  
 
33
 
 
34
   The resource table is constructed based on some text dependency tables, 
 
35
   which are also easier to maintain than the final representation.  */
 
36
 
 
37
#include "sysdep.h"
 
38
#include <stdio.h>
 
39
#include <stdarg.h>
 
40
#include <errno.h>
 
41
 
 
42
#include "libiberty.h"
 
43
#include "safe-ctype.h"
 
44
#include "getopt.h"
 
45
#include "ia64-opc.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"
 
53
 
 
54
#include <libintl.h>
 
55
#define _(String) gettext (String)
 
56
 
 
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))
 
65
 
 
66
const char * program_name = NULL;
 
67
int debug = 0;
 
68
 
 
69
#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
 
70
#define tmalloc(X) (X *) xmalloc (sizeof (X))
 
71
 
 
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
 
75
   via opcodes_eq).  */
 
76
struct main_entry
 
77
{
 
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.  */
 
89
  int main_index;
 
90
} *maintable, **ordered_table;
 
91
 
 
92
int otlen = 0;
 
93
int ottotlen = 0;
 
94
int opcode_count = 0;
 
95
 
 
96
/* The set of possible completers for an opcode.  */
 
97
struct completer_entry
 
98
{
 
99
  /* This entry's index in the ia64_completer_table[] array.  */
 
100
  int num;
 
101
 
 
102
  /* The name of the completer.  */
 
103
  struct string_entry *name;
 
104
 
 
105
  /* This entry's parent.  */
 
106
  struct completer_entry *parent;
 
107
 
 
108
  /* Set if this is a terminal completer (occurs at the end of an
 
109
     opcode).  */
 
110
  int is_terminal;
 
111
 
 
112
  /* An alternative completer.  */
 
113
  struct completer_entry *alternative;
 
114
 
 
115
  /* Additional completers that can be appended to this one.  */
 
116
  struct completer_entry *addl_entries;
 
117
 
 
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
 
121
     parent opcode.  */
 
122
  ia64_insn bits;
 
123
 
 
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 ().  */
 
128
  ia64_insn mask;
 
129
 
 
130
  /* Index into the opcode dependency list, or -1 if none.  */
 
131
  int dependencies;
 
132
 
 
133
  /* Remember the order encountered in the opcode tables.  */
 
134
  int order;
 
135
};
 
136
 
 
137
/* One entry in the disassembler name table.  */
 
138
struct disent
 
139
{
 
140
  /* The index into the ia64_name_dis array for this entry.  */
 
141
  int ournum;
 
142
 
 
143
  /* The index into the main_table[] array.  */
 
144
  int insn;
 
145
 
 
146
  /* The disassmbly priority of this entry.  */
 
147
  int priority;
 
148
 
 
149
  /* The completer_index value for this entry.  */
 
150
  ci_t completer_index;
 
151
 
 
152
  /* How many other entries share this decode.  */
 
153
  int nextcnt;
 
154
 
 
155
  /* The next entry sharing the same decode.  */
 
156
  struct disent *nexte;
 
157
 
 
158
  /* The next entry in the name list.  */
 
159
  struct disent *next_ent;
 
160
} *disinsntable = NULL;
 
161
 
 
162
/* A state machine that will eventually be used to generate the
 
163
   disassembler table.  */
 
164
struct bittree
 
165
{
 
166
  struct disent *disent;
 
167
  struct bittree *bits[3]; /* 0, 1, and X (don't care).  */
 
168
  int bits_to_skip;
 
169
  int skip_flag;
 
170
} *bittree;
 
171
 
 
172
/* The string table contains all opcodes and completers sorted in
 
173
   alphabetical order.  */
 
174
 
 
175
/* One entry in the string table.  */
 
176
struct string_entry 
 
177
{
 
178
  /* The index in the ia64_strings[] array for this entry.  */
 
179
  int num;
 
180
  /* And the string.  */
 
181
  char *s;
 
182
} **string_table = NULL;
 
183
 
 
184
int strtablen = 0;
 
185
int strtabtotlen = 0;
 
186
 
 
187
 
 
188
/* Resource dependency entries.  */
 
189
struct rdep
 
190
{
 
191
  char *name;                       /* Resource name.  */
 
192
  unsigned 
 
193
    mode:2,                         /* RAW, WAW, or WAR.  */
 
194
    semantics:3;                    /* Dependency semantics.  */
 
195
  char *extra;                      /* Additional semantics info.  */
 
196
  int nchks;                   
 
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.  */
 
201
  int nregs;
 
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.  */
 
206
 
 
207
  int waw_special;                  /* Special WAW dependency note.  */
 
208
} **rdeps = NULL;
 
209
 
 
210
static int rdepslen = 0;
 
211
static int rdepstotlen = 0;
 
212
 
 
213
/* Array of all instruction classes.  */
 
214
struct iclass
 
215
 
216
  char *name;                       /* Instruction class name.  */
 
217
  int is_class;                     /* Is a class, not a terminal.  */
 
218
  int nsubs;                        
 
219
  int *subs;                        /* Other classes within this class.  */
 
220
  int nxsubs;                       
 
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.  */
 
226
} **ics = NULL;
 
227
 
 
228
static int iclen = 0;
 
229
static int ictotlen = 0;
 
230
 
 
231
/* An opcode dependency (chk/reg pair of dependency lists).  */
 
232
struct opdep
 
233
{
 
234
  int chk;                          /* index into dlists */
 
235
  int reg;                          /* index into dlists */
 
236
} **opdeps;
 
237
 
 
238
static int opdeplen = 0;
 
239
static int opdeptotlen = 0;
 
240
 
 
241
/* A generic list of dependencies w/notes encoded.  These may be shared.  */
 
242
struct deplist
 
243
{
 
244
  int len;
 
245
  unsigned short *deps;
 
246
} **dlists;
 
247
 
 
248
static int dlistlen = 0;
 
249
static int dlisttotlen = 0;
 
250
 
 
251
 
 
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);
 
299
 
 
300
 
 
301
static void
 
302
fail (const char *message, ...)
 
303
{
 
304
  va_list args;
 
305
  
 
306
  va_start (args, message);
 
307
  fprintf (stderr, _("%s: Error: "), program_name);
 
308
  vfprintf (stderr, message, args);
 
309
  va_end (args);
 
310
  xexit (1);
 
311
}
 
312
 
 
313
static void
 
314
warn (const char *message, ...)
 
315
{
 
316
  va_list args;
 
317
 
 
318
  va_start (args, message);
 
319
 
 
320
  fprintf (stderr, _("%s: Warning: "), program_name);
 
321
  vfprintf (stderr, message, args);
 
322
  va_end (args);
 
323
}
 
324
 
 
325
/* Add NAME to the resource table, where TYPE is RAW or WAW.  */
 
326
static struct rdep *
 
327
insert_resource (const char *name, enum ia64_dependency_mode type)
 
328
{
 
329
  if (rdepslen == rdepstotlen)
 
330
    {
 
331
      rdepstotlen += 20;
 
332
      rdeps = (struct rdep **)
 
333
        xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
 
334
    }
 
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;
 
340
  
 
341
  return rdeps[rdepslen++];
 
342
}
 
343
 
 
344
/* Are the lists of dependency indexes equivalent?  */
 
345
static int
 
346
deplist_equals (struct deplist *d1, struct deplist *d2)
 
347
{
 
348
  int i;
 
349
 
 
350
  if (d1->len != d2->len)
 
351
    return 0;
 
352
 
 
353
  for (i = 0; i < d1->len; i++)
 
354
    if (d1->deps[i] != d2->deps[i])
 
355
      return 0;
 
356
 
 
357
  return 1;
 
358
}
 
359
 
 
360
/* Add the list of dependencies to the list of dependency lists.  */
 
361
static short
 
362
insert_deplist (int count, unsigned short *deps)
 
363
{
 
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;
 
367
  char set[0x10000];
 
368
  int i;
 
369
 
 
370
  memset ((void *)set, 0, sizeof (set));
 
371
  for (i = 0; i < count; i++)
 
372
    set[deps[i]] = 1;
 
373
 
 
374
  count = 0;
 
375
  for (i = 0; i < (int) sizeof (set); i++)
 
376
    if (set[i])
 
377
      ++count;
 
378
 
 
379
  list = tmalloc (struct deplist);
 
380
  list->len = count;
 
381
  list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count);
 
382
 
 
383
  for (i = 0, count = 0; i < (int) sizeof (set); i++)
 
384
    if (set[i])
 
385
      list->deps[count++] = i;
 
386
 
 
387
  /* Does this list exist already?  */
 
388
  for (i = 0; i < dlistlen; i++)
 
389
    if (deplist_equals (list, dlists[i]))
 
390
      {
 
391
        free (list->deps);
 
392
        free (list);
 
393
        return i;
 
394
      }
 
395
 
 
396
  if (dlistlen == dlisttotlen)
 
397
    {
 
398
      dlisttotlen += 20;
 
399
      dlists = (struct deplist **)
 
400
        xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
 
401
    }
 
402
  dlists[dlistlen] = list;
 
403
 
 
404
  return dlistlen++;
 
405
}
 
406
 
 
407
/* Add the given pair of dependency lists to the opcode dependency list.  */
 
408
static short
 
409
insert_dependencies (int nchks, unsigned short *chks, 
 
410
                     int nregs, unsigned short *regs)
 
411
{
 
412
  struct opdep *pair;
 
413
  int i;
 
414
  int regind = -1;
 
415
  int chkind = -1;
 
416
 
 
417
  if (nregs > 0)
 
418
    regind = insert_deplist (nregs, regs);
 
419
  if (nchks > 0)
 
420
    chkind = insert_deplist (nchks, chks);
 
421
 
 
422
  for (i = 0; i < opdeplen; i++)
 
423
    if (opdeps[i]->chk == chkind 
 
424
        && opdeps[i]->reg == regind)
 
425
      return i;
 
426
 
 
427
  pair = tmalloc (struct opdep);
 
428
  pair->chk = chkind;
 
429
  pair->reg = regind;
 
430
  
 
431
  if (opdeplen == opdeptotlen)
 
432
    {
 
433
      opdeptotlen += 20;
 
434
      opdeps = (struct opdep **)
 
435
        xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
 
436
    }
 
437
  opdeps[opdeplen] = pair;
 
438
 
 
439
  return opdeplen++;
 
440
}
 
441
 
 
442
static void 
 
443
mark_used (struct iclass *ic, int clear_terminals)
 
444
{
 
445
  int i;
 
446
 
 
447
  ic->orphan = 0;
 
448
  if (clear_terminals)
 
449
    ic->terminal_resolved = 1;
 
450
 
 
451
  for (i = 0; i < ic->nsubs; i++)
 
452
    mark_used (ics[ic->subs[i]], clear_terminals);
 
453
 
 
454
  for (i = 0; i < ic->nxsubs; i++)
 
455
    mark_used (ics[ic->xsubs[i]], clear_terminals);
 
456
}
 
457
 
 
458
/* Look up an instruction class; if CREATE make a new one if none found;
 
459
   returns the index into the insn class array.  */
 
460
static int
 
461
fetch_insn_class (const char *full_name, int create)
 
462
{
 
463
  char *name;
 
464
  char *notestr;
 
465
  char *xsect;
 
466
  char *comment;
 
467
  int i, note = 0;
 
468
  int ind;
 
469
  int is_class = 0;
 
470
 
 
471
  if (CONST_STRNEQ (full_name, "IC:"))
 
472
    {
 
473
      name = xstrdup (full_name + 3);
 
474
      is_class = 1;
 
475
    }
 
476
  else
 
477
    name = xstrdup (full_name);
 
478
 
 
479
  if ((xsect = strchr(name, '\\')) != NULL)
 
480
    is_class = 1;
 
481
  if ((comment = strchr(name, '[')) != NULL)
 
482
    is_class = 1;
 
483
  if ((notestr = strchr(name, '+')) != NULL)
 
484
    is_class = 1;
 
485
 
 
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.  */
 
488
  if (xsect)
 
489
    {
 
490
      if (comment > xsect)
 
491
        comment = 0;
 
492
      if (notestr > xsect)
 
493
        notestr = 0;
 
494
    }
 
495
 
 
496
  if (notestr)
 
497
    {
 
498
      char *nextnotestr;
 
499
 
 
500
      note = atoi (notestr + 1);
 
501
      if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
 
502
        {
 
503
          if (strcmp (notestr, "+1+13") == 0)
 
504
            note = 13;
 
505
          else if (!xsect || nextnotestr < xsect)
 
506
            warn (_("multiple note %s not handled\n"), notestr);
 
507
        }
 
508
    }
 
509
 
 
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
 
512
     them.  */
 
513
  if (!xsect)
 
514
    {
 
515
      if (notestr)
 
516
        *notestr = 0;
 
517
      if (comment)
 
518
        *comment = 0;
 
519
    }
 
520
 
 
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)
 
528
      return i;
 
529
 
 
530
  if (!create)
 
531
    return -1;
 
532
 
 
533
  /* Doesn't exist, so make a new one.  */
 
534
  if (iclen == ictotlen)
 
535
    {
 
536
      ictotlen += 20;
 
537
      ics = (struct iclass **)
 
538
        xrealloc (ics, (ictotlen) * sizeof (struct iclass *));
 
539
    }
 
540
 
 
541
  ind = iclen++;
 
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;
 
547
 
 
548
  if (comment)
 
549
    {
 
550
      ics[ind]->comment = xstrdup (comment + 1);
 
551
      ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0;
 
552
    }
 
553
 
 
554
  if (notestr)
 
555
    ics[ind]->note = note;
 
556
 
 
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)
 
560
    {
 
561
      /* First, populate with the class we're based on.  */
 
562
      char *subname = name;
 
563
 
 
564
      if (xsect)
 
565
        *xsect = 0;
 
566
      else if (comment)
 
567
        *comment = 0;
 
568
      else if (notestr)
 
569
        *notestr = 0;
 
570
 
 
571
      ics[ind]->nsubs = 1;
 
572
      ics[ind]->subs = tmalloc(int);
 
573
      ics[ind]->subs[0] = fetch_insn_class (subname, 1);
 
574
    }
 
575
 
 
576
  while (xsect)
 
577
    {
 
578
      char *subname = xsect + 1;
 
579
 
 
580
      xsect = strchr (subname, '\\');
 
581
      if (xsect)
 
582
        *xsect = 0;
 
583
      ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
 
584
      ics[ind]->nxsubs++;
 
585
    }
 
586
  free (name);
 
587
 
 
588
  return ind;
 
589
}
 
590
 
 
591
/* For sorting a class's sub-class list only; make sure classes appear before
 
592
   terminals.  */
 
593
static int
 
594
sub_compare (const void *e1, const void *e2)
 
595
{
 
596
  struct iclass *ic1 = ics[*(int *)e1];
 
597
  struct iclass *ic2 = ics[*(int *)e2];
 
598
 
 
599
  if (ic1->is_class)
 
600
    {
 
601
      if (!ic2->is_class)
 
602
        return -1;
 
603
    }
 
604
  else if (ic2->is_class)
 
605
    return 1;
 
606
 
 
607
  return strcmp (ic1->name, ic2->name);
 
608
}
 
609
 
 
610
static void
 
611
load_insn_classes (void)
 
612
{
 
613
  FILE *fp = fopen ("ia64-ic.tbl", "r");
 
614
  char buf[2048];
 
615
 
 
616
  if (fp == NULL)
 
617
    fail (_("can't find ia64-ic.tbl for reading\n"));
 
618
 
 
619
  /* Discard first line.  */
 
620
  fgets (buf, sizeof(buf), fp);
 
621
 
 
622
  while (!feof (fp))
 
623
    {
 
624
      int iclass;
 
625
      char *name;
 
626
      char *tmp;
 
627
      
 
628
      if (fgets (buf, sizeof (buf), fp) == NULL)
 
629
        break;
 
630
      
 
631
      while (ISSPACE (buf[strlen (buf) - 1]))
 
632
        buf[strlen (buf) - 1] = '\0';
 
633
 
 
634
      name = tmp = buf;
 
635
      while (*tmp != ';')
 
636
        {
 
637
          ++tmp;
 
638
          if (tmp == buf + sizeof (buf))
 
639
            abort ();
 
640
        }
 
641
      *tmp++ = '\0';
 
642
 
 
643
      iclass = fetch_insn_class (name, 1);
 
644
      ics[iclass]->is_class = 1;
 
645
 
 
646
      if (strcmp (name, "none") == 0)
 
647
        {
 
648
          ics[iclass]->is_class = 0;
 
649
          ics[iclass]->terminal_resolved = 1;
 
650
          continue;
 
651
        }
 
652
 
 
653
      /* For this class, record all sub-classes.  */
 
654
      while (*tmp)
 
655
        {
 
656
          char *subname;
 
657
          int sub;
 
658
 
 
659
          while (*tmp && ISSPACE (*tmp))
 
660
            {
 
661
              ++tmp;
 
662
              if (tmp == buf + sizeof (buf))
 
663
                abort ();
 
664
            }
 
665
          subname = tmp;
 
666
          while (*tmp && *tmp != ',')
 
667
            {
 
668
              ++tmp;
 
669
              if (tmp == buf + sizeof (buf))
 
670
                abort ();
 
671
            }
 
672
          if (*tmp == ',')
 
673
            *tmp++ = '\0';
 
674
          
 
675
          ics[iclass]->subs = (int *)
 
676
            xrealloc ((void *)ics[iclass]->subs, 
 
677
                      (ics[iclass]->nsubs + 1) * sizeof (int));
 
678
 
 
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;
 
683
        }
 
684
 
 
685
      /* Make sure classes come before terminals.  */
 
686
      qsort ((void *)ics[iclass]->subs, 
 
687
             ics[iclass]->nsubs, sizeof(int), sub_compare);
 
688
    }
 
689
  fclose (fp);
 
690
 
 
691
  if (debug)
 
692
    printf ("%d classes\n", iclen);
 
693
}
 
694
 
 
695
/* Extract the insn classes from the given line.  */
 
696
static void
 
697
parse_resource_users (const char *ref, int **usersp, int *nusersp,
 
698
                      int **notesp)
 
699
{
 
700
  int c;
 
701
  char *line = xstrdup (ref);
 
702
  char *tmp = line;
 
703
  int *users = *usersp;
 
704
  int count = *nusersp;
 
705
  int *notes = *notesp;
 
706
 
 
707
  c = *tmp;
 
708
  while (c != 0)
 
709
    {
 
710
      char *notestr;
 
711
      int note;
 
712
      char *xsect;
 
713
      int iclass;
 
714
      int create = 0;
 
715
      char *name;
 
716
      
 
717
      while (ISSPACE (*tmp))
 
718
        ++tmp;
 
719
      name = tmp;
 
720
      while (*tmp && *tmp != ',')
 
721
        ++tmp;
 
722
      c = *tmp;
 
723
      *tmp++ = '\0';
 
724
      
 
725
      xsect = strchr (name, '\\');
 
726
      if ((notestr = strstr (name, "+")) != NULL)
 
727
        {
 
728
          char *nextnotestr;
 
729
 
 
730
          note = atoi (notestr + 1);
 
731
          if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
 
732
            {
 
733
              /* Note 13 always implies note 1.  */
 
734
              if (strcmp (notestr, "+1+13") == 0)
 
735
                note = 13;
 
736
              else if (!xsect || nextnotestr < xsect)
 
737
                warn (_("multiple note %s not handled\n"), notestr);
 
738
            }
 
739
          if (!xsect)
 
740
            *notestr = '\0';
 
741
        }
 
742
      else 
 
743
        note = 0;
 
744
 
 
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
 
749
         table).  */
 
750
      if (! CONST_STRNEQ (name, "IC:") || xsect != NULL)
 
751
        create = 1;
 
752
      
 
753
      iclass = fetch_insn_class (name, create);
 
754
      if (iclass != -1)
 
755
        {
 
756
          users = (int *)
 
757
            xrealloc ((void *) users,(count + 1) * sizeof (int));
 
758
          notes = (int *)
 
759
            xrealloc ((void *) notes,(count + 1) * sizeof (int));
 
760
          notes[count] = note;
 
761
          users[count++] = iclass;
 
762
          mark_used (ics[iclass], 0);
 
763
        }
 
764
      else if (debug)
 
765
        printf("Class %s not found\n", name);
 
766
    }
 
767
  /* Update the return values.  */
 
768
  *usersp = users;
 
769
  *nusersp = count;
 
770
  *notesp = notes;
 
771
 
 
772
  free (line);
 
773
}
 
774
 
 
775
static int
 
776
parse_semantics (char *sem)
 
777
{
 
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;
 
792
  else 
 
793
    return IA64_DVS_OTHER;
 
794
}
 
795
 
 
796
static void
 
797
add_dep (const char *name, const char *chk, const char *reg,
 
798
         int semantics, int mode, char *extra, int flag)
 
799
{
 
800
  struct rdep *rs;
 
801
 
 
802
  rs = insert_resource (name, mode);
 
803
 
 
804
  parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
 
805
  parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
 
806
 
 
807
  rs->semantics = semantics;
 
808
  rs->extra = extra;
 
809
  rs->waw_special = flag;
 
810
}
 
811
 
 
812
static void
 
813
load_depfile (const char *filename, enum ia64_dependency_mode mode)
 
814
{
 
815
  FILE *fp = fopen (filename, "r");
 
816
  char buf[1024];
 
817
 
 
818
  if (fp == NULL)
 
819
    fail (_("can't find %s for reading\n"), filename);
 
820
 
 
821
  fgets (buf, sizeof(buf), fp);
 
822
  while (!feof (fp))
 
823
    {
 
824
      char *name, *tmp;
 
825
      int semantics;
 
826
      char *extra;
 
827
      char *regp, *chkp;
 
828
 
 
829
      if (fgets (buf, sizeof(buf), fp) == NULL)
 
830
        break;
 
831
 
 
832
      while (ISSPACE (buf[strlen (buf) - 1]))
 
833
        buf[strlen (buf) - 1] = '\0';
 
834
 
 
835
      name = tmp = buf;
 
836
      while (*tmp != ';')
 
837
        ++tmp;
 
838
      *tmp++ = '\0';
 
839
      
 
840
      while (ISSPACE (*tmp))
 
841
        ++tmp;
 
842
      regp = tmp;
 
843
      tmp = strchr (tmp, ';');
 
844
      if (!tmp)
 
845
        abort ();
 
846
      *tmp++ = 0;
 
847
      while (ISSPACE (*tmp))
 
848
        ++tmp;
 
849
      chkp = tmp;
 
850
      tmp = strchr (tmp, ';');
 
851
      if (!tmp)
 
852
        abort ();
 
853
      *tmp++ = 0;
 
854
      while (ISSPACE (*tmp))
 
855
        ++tmp;
 
856
      semantics = parse_semantics (tmp);
 
857
      extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
 
858
 
 
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)
 
863
        {
 
864
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
 
865
          add_dep (name, regp, chkp, semantics, mode, extra, 1);
 
866
        }
 
867
      else
 
868
        {
 
869
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
 
870
        }
 
871
    }
 
872
  fclose (fp);
 
873
}
 
874
 
 
875
static void
 
876
load_dependencies (void)
 
877
{
 
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);
 
881
 
 
882
  if (debug)
 
883
    printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
 
884
}
 
885
 
 
886
/* Is the given operand an indirect register file operand?  */
 
887
static int 
 
888
irf_operand (int op, const char *field)
 
889
{
 
890
  if (!field)
 
891
    {
 
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;
 
896
    }
 
897
  else
 
898
    {
 
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")));
 
908
    }
 
909
}
 
910
 
 
911
/* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr,
 
912
 * mov_psr, and  mov_um insn classes.  */
 
913
static int
 
914
in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, 
 
915
                 const char *format, const char *field)
 
916
{
 
917
  int plain_mov = strcmp (idesc->name, "mov") == 0;
 
918
 
 
919
  if (!format)
 
920
    return 0;
 
921
 
 
922
  switch (ic->name[4])
 
923
    {
 
924
    default:
 
925
      abort ();
 
926
    case 'a':
 
927
      {
 
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;
 
936
 
 
937
        /* IC:mov ar */
 
938
        if (i2627)
 
939
          return strstr (format, "I26") || strstr (format, "I27");
 
940
        if (i28)
 
941
          return strstr (format, "I28") != NULL;
 
942
        if (m2930)
 
943
          return strstr (format, "M29") || strstr (format, "M30");
 
944
        if (m31)
 
945
          return strstr (format, "M31") != NULL;
 
946
        if (pseudo0 || pseudo1)
 
947
          return 1;
 
948
      }
 
949
      break;
 
950
    case 'b':
 
951
      {
 
952
        int i21 = idesc->operands[0] == IA64_OPND_B1;
 
953
        int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
 
954
        if (i22)
 
955
          return strstr (format, "I22") != NULL;
 
956
        if (i21)
 
957
          return strstr (format, "I21") != NULL;
 
958
      }
 
959
      break;
 
960
    case 'c':
 
961
      {
 
962
        int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
 
963
        int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
 
964
        if (m32)
 
965
          return strstr (format, "M32") != NULL;
 
966
        if (m33)
 
967
          return strstr (format, "M33") != NULL;
 
968
      }
 
969
      break;
 
970
    case 'd':
 
971
      {
 
972
        int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3;
 
973
        if (m50)
 
974
          return strstr (format, "M50") != NULL;
 
975
      }
 
976
      break;
 
977
    case 'i':
 
978
      if (ic->name[5] == 'n')
 
979
        {
 
980
          int m42 = plain_mov && irf_operand (idesc->operands[0], field);
 
981
          int m43 = plain_mov && irf_operand (idesc->operands[1], field);
 
982
          if (m42)
 
983
            return strstr (format, "M42") != NULL;
 
984
          if (m43)
 
985
            return strstr (format, "M43") != NULL;
 
986
        }
 
987
      else if (ic->name[5] == 'p')
 
988
        {
 
989
          return idesc->operands[1] == IA64_OPND_IP;
 
990
        }
 
991
      else
 
992
        abort ();
 
993
      break;
 
994
    case 'p':
 
995
      if (ic->name[5] == 'r')
 
996
        {
 
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;
 
1000
          if (i23)
 
1001
            return strstr (format, "I23") != NULL;
 
1002
          if (i24)
 
1003
            return strstr (format, "I24") != NULL;
 
1004
          if (i25)
 
1005
            return strstr (format, "I25") != NULL;
 
1006
        }
 
1007
      else if (ic->name[5] == 's')
 
1008
        {
 
1009
          int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
 
1010
          int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
 
1011
          if (m35)
 
1012
            return strstr (format, "M35") != NULL;
 
1013
          if (m36)
 
1014
            return strstr (format, "M36") != NULL;
 
1015
        }
 
1016
      else
 
1017
        abort ();
 
1018
      break;
 
1019
    case 'u':
 
1020
      {
 
1021
        int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
 
1022
        int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
 
1023
        if (m35)
 
1024
          return strstr (format, "M35") != NULL;
 
1025
        if (m36)
 
1026
          return strstr (format, "M36") != NULL;
 
1027
      }
 
1028
      break;
 
1029
    }
 
1030
  return 0;
 
1031
}
 
1032
 
 
1033
/* Is the given opcode in the given insn class?  */
 
1034
static int
 
1035
in_iclass (struct ia64_opcode *idesc, struct iclass *ic, 
 
1036
           const char *format, const char *field, int *notep)
 
1037
{
 
1038
  int i;
 
1039
  int resolved = 0;
 
1040
 
 
1041
  if (ic->comment)
 
1042
    {
 
1043
      if (CONST_STRNEQ (ic->comment, "Format"))
 
1044
        {
 
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.  */
 
1047
          if (format)
 
1048
            {
 
1049
              if (strlen (ic->comment) < strlen (format))
 
1050
                {
 
1051
                  warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
 
1052
                        ic->comment, format);
 
1053
                  format = ic->comment; 
 
1054
                }
 
1055
            }
 
1056
          else
 
1057
            format = ic->comment;
 
1058
        }
 
1059
      else if (CONST_STRNEQ (ic->comment, "Field"))
 
1060
        {
 
1061
          if (field)
 
1062
            warn (_("overlapping field %s->%s\n"),
 
1063
                  ic->comment, field);
 
1064
          field = ic->comment;
 
1065
        }
 
1066
    }
 
1067
 
 
1068
  /* An insn class matches anything that is the same followed by completers,
 
1069
     except when the absence and presence of completers constitutes different
 
1070
     instructions.  */
 
1071
  if (ic->nsubs == 0 && ic->nxsubs == 0)
 
1072
    {
 
1073
      int is_mov = CONST_STRNEQ (idesc->name, "mov");
 
1074
      int plain_mov = strcmp (idesc->name, "mov") == 0;
 
1075
      int len = strlen(ic->name);
 
1076
 
 
1077
      resolved = ((strncmp (ic->name, idesc->name, len) == 0)
 
1078
                  && (idesc->name[len] == '\0' 
 
1079
                      || idesc->name[len] == '.'));
 
1080
 
 
1081
      /* All break, nop, and hint variations must match exactly.  */
 
1082
      if (resolved &&
 
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;
 
1087
 
 
1088
      /* Assume restrictions in the FORMAT/FIELD negate resolution,
 
1089
         unless specifically allowed by clauses in this block.  */
 
1090
      if (resolved && field)
 
1091
        {
 
1092
          /* Check Field(sf)==sN against opcode sN.  */
 
1093
          if (strstr(field, "(sf)==") != NULL)
 
1094
            {
 
1095
              char *sf;
 
1096
 
 
1097
              if ((sf = strstr (idesc->name, ".s")) != 0)
 
1098
                resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
 
1099
            }
 
1100
          /* Check Field(lftype)==XXX.  */
 
1101
          else if (strstr (field, "(lftype)") != NULL)
 
1102
            {
 
1103
              if (strstr (idesc->name, "fault") != NULL)
 
1104
                resolved = strstr (field, "fault") != NULL;
 
1105
              else
 
1106
                resolved = strstr (field, "fault") == NULL;
 
1107
            }
 
1108
          /* Handle Field(ctype)==XXX.  */
 
1109
          else if (strstr (field, "(ctype)") != NULL)
 
1110
            {
 
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;
 
1125
              else
 
1126
                resolved = strcmp (field, "Field(ctype)==") == 0;
 
1127
            }
 
1128
        }
 
1129
 
 
1130
      if (resolved && format)
 
1131
        {
 
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;
 
1162
          else
 
1163
            resolved = 0;
 
1164
        }
 
1165
 
 
1166
      /* Misc brl variations ('.cond' is optional); 
 
1167
         plain brl matches brl.cond.  */
 
1168
      if (!resolved
 
1169
          && (strcmp (idesc->name, "brl") == 0
 
1170
              || CONST_STRNEQ (idesc->name, "brl."))
 
1171
          && strcmp (ic->name, "brl.cond") == 0)
 
1172
        {
 
1173
          resolved = 1;
 
1174
        }
 
1175
 
 
1176
      /* Misc br variations ('.cond' is optional).  */
 
1177
      if (!resolved 
 
1178
          && (strcmp (idesc->name, "br") == 0
 
1179
              || CONST_STRNEQ (idesc->name, "br."))
 
1180
          && strcmp (ic->name, "br.cond") == 0)
 
1181
        {
 
1182
          if (format)
 
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);
 
1187
          else
 
1188
            resolved = 1;
 
1189
        }
 
1190
 
 
1191
      /* probe variations.  */
 
1192
      if (!resolved && CONST_STRNEQ (idesc->name, "probe"))
 
1193
        {
 
1194
          resolved = strcmp (ic->name, "probe") == 0 
 
1195
            && !((strstr (idesc->name, "fault") != NULL) 
 
1196
                 ^ (format && strstr (format, "M40") != NULL));
 
1197
        }
 
1198
 
 
1199
      /* mov variations.  */
 
1200
      if (!resolved && is_mov)
 
1201
        {
 
1202
          if (plain_mov)
 
1203
            {
 
1204
              /* mov alias for fmerge.  */
 
1205
              if (strcmp (ic->name, "fmerge") == 0)
 
1206
                {
 
1207
                  resolved = idesc->operands[0] == IA64_OPND_F1
 
1208
                    && idesc->operands[1] == IA64_OPND_F3;
 
1209
                }
 
1210
              /* mov alias for adds (r3 or imm14).  */
 
1211
              else if (strcmp (ic->name, "adds") == 0)
 
1212
                {
 
1213
                  resolved = (idesc->operands[0] == IA64_OPND_R1
 
1214
                              && (idesc->operands[1] == IA64_OPND_R3
 
1215
                                  || (idesc->operands[1] == IA64_OPND_IMM14)));
 
1216
                }
 
1217
              /* mov alias for addl.  */
 
1218
              else if (strcmp (ic->name, "addl") == 0)
 
1219
                {
 
1220
                  resolved = idesc->operands[0] == IA64_OPND_R1
 
1221
                    && idesc->operands[1] == IA64_OPND_IMM22;
 
1222
                }
 
1223
            }
 
1224
 
 
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);
 
1228
        }
 
1229
 
 
1230
      /* Keep track of this so we can flag any insn classes which aren't 
 
1231
         mapped onto at least one real insn.  */
 
1232
      if (resolved)
 
1233
        ic->terminal_resolved = 1;
 
1234
    }
 
1235
  else for (i = 0; i < ic->nsubs; i++)
 
1236
    {
 
1237
      if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
 
1238
        {
 
1239
          int j;
 
1240
 
 
1241
          for (j = 0; j < ic->nxsubs; j++)
 
1242
            if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
 
1243
              return 0;
 
1244
 
 
1245
          if (debug > 1)
 
1246
            printf ("%s is in IC %s\n", idesc->name, ic->name);
 
1247
 
 
1248
          resolved = 1;
 
1249
          break;
 
1250
        }
 
1251
    }
 
1252
  
 
1253
  /* If it's in this IC, add the IC note (if any) to the insn.  */
 
1254
  if (resolved)
 
1255
    {
 
1256
      if (ic->note && notep)
 
1257
        {
 
1258
          if (*notep && *notep != ic->note)
 
1259
            warn (_("overwriting note %d with note %d (IC:%s)\n"),
 
1260
                  *notep, ic->note, ic->name);
 
1261
 
 
1262
          *notep = ic->note;
 
1263
        }
 
1264
    }
 
1265
 
 
1266
  return resolved;
 
1267
}
 
1268
 
 
1269
 
 
1270
static int
 
1271
lookup_regindex (const char *name, int specifier)
 
1272
{
 
1273
  switch (specifier)
 
1274
    {
 
1275
    case IA64_RS_ARX:
 
1276
      if (strstr (name, "[RSC]"))
 
1277
        return 16;
 
1278
      if (strstr (name, "[BSP]"))
 
1279
        return 17;
 
1280
      else if (strstr (name, "[BSPSTORE]"))
 
1281
        return 18;
 
1282
      else if (strstr (name, "[RNAT]"))
 
1283
        return 19;
 
1284
      else if (strstr (name, "[FCR]"))
 
1285
        return 21;
 
1286
      else if (strstr (name, "[EFLAG]"))
 
1287
        return 24;
 
1288
      else if (strstr (name, "[CSD]"))
 
1289
        return 25;
 
1290
      else if (strstr (name, "[SSD]"))
 
1291
        return 26;
 
1292
      else if (strstr (name, "[CFLG]"))
 
1293
        return 27;
 
1294
      else if (strstr (name, "[FSR]"))
 
1295
        return 28;
 
1296
      else if (strstr (name, "[FIR]"))
 
1297
        return 29;
 
1298
      else if (strstr (name, "[FDR]"))
 
1299
        return 30;
 
1300
      else if (strstr (name, "[CCV]"))
 
1301
        return 32;
 
1302
      else if (strstr (name, "[ITC]"))
 
1303
        return 44;
 
1304
      else if (strstr (name, "[RUC]"))
 
1305
        return 45;
 
1306
      else if (strstr (name, "[PFS]"))
 
1307
        return 64;
 
1308
      else if (strstr (name, "[LC]"))
 
1309
        return 65;
 
1310
      else if (strstr (name, "[EC]"))
 
1311
        return 66;
 
1312
      abort ();
 
1313
    case IA64_RS_CRX:
 
1314
      if (strstr (name, "[DCR]"))
 
1315
        return 0;
 
1316
      else if (strstr (name, "[ITM]"))
 
1317
        return 1;
 
1318
      else if (strstr (name, "[IVA]"))
 
1319
        return 2;
 
1320
      else if (strstr (name, "[PTA]"))
 
1321
        return 8;
 
1322
      else if (strstr (name, "[GPTA]"))
 
1323
        return 9;
 
1324
      else if (strstr (name, "[IPSR]"))
 
1325
        return 16;
 
1326
      else if (strstr (name, "[ISR]"))
 
1327
        return 17;
 
1328
      else if (strstr (name, "[IIP]"))
 
1329
        return 19;
 
1330
      else if (strstr (name, "[IFA]"))
 
1331
        return 20;
 
1332
      else if (strstr (name, "[ITIR]"))
 
1333
        return 21;
 
1334
      else if (strstr (name, "[IIPA]"))
 
1335
        return 22;
 
1336
      else if (strstr (name, "[IFS]"))
 
1337
        return 23;
 
1338
      else if (strstr (name, "[IIM]"))
 
1339
        return 24;
 
1340
      else if (strstr (name, "[IHA]"))
 
1341
        return 25;
 
1342
      else if (strstr (name, "[LID]"))
 
1343
        return 64;
 
1344
      else if (strstr (name, "[IVR]"))
 
1345
        return 65;
 
1346
      else if (strstr (name, "[TPR]"))
 
1347
        return 66;
 
1348
      else if (strstr (name, "[EOI]"))
 
1349
        return 67;
 
1350
      else if (strstr (name, "[ITV]"))
 
1351
        return 72;
 
1352
      else if (strstr (name, "[PMV]"))
 
1353
        return 73;
 
1354
      else if (strstr (name, "[CMCV]"))
 
1355
        return 74;
 
1356
      abort ();
 
1357
    case IA64_RS_PSR:
 
1358
      if (strstr (name, ".be"))
 
1359
        return 1;
 
1360
      else if (strstr (name, ".up"))
 
1361
        return 2;
 
1362
      else if (strstr (name, ".ac"))
 
1363
        return 3;
 
1364
      else if (strstr (name, ".mfl"))
 
1365
        return 4;
 
1366
      else if (strstr (name, ".mfh"))
 
1367
        return 5;
 
1368
      else if (strstr (name, ".ic"))
 
1369
        return 13;
 
1370
      else if (strstr (name, ".i"))
 
1371
        return 14;
 
1372
      else if (strstr (name, ".pk"))
 
1373
        return 15;
 
1374
      else if (strstr (name, ".dt"))
 
1375
        return 17;
 
1376
      else if (strstr (name, ".dfl"))
 
1377
        return 18;
 
1378
      else if (strstr (name, ".dfh"))
 
1379
        return 19;
 
1380
      else if (strstr (name, ".sp"))
 
1381
        return 20;
 
1382
      else if (strstr (name, ".pp"))
 
1383
        return 21;
 
1384
      else if (strstr (name, ".di"))
 
1385
        return 22;
 
1386
      else if (strstr (name, ".si"))
 
1387
        return 23;
 
1388
      else if (strstr (name, ".db"))
 
1389
        return 24;
 
1390
      else if (strstr (name, ".lp"))
 
1391
        return 25;
 
1392
      else if (strstr (name, ".tb"))
 
1393
        return 26;
 
1394
      else if (strstr (name, ".rt"))
 
1395
        return 27;
 
1396
      else if (strstr (name, ".cpl"))
 
1397
        return 32;
 
1398
      else if (strstr (name, ".rs"))
 
1399
        return 34;
 
1400
      else if (strstr (name, ".mc"))
 
1401
        return 35;
 
1402
      else if (strstr (name, ".it"))
 
1403
        return 36;
 
1404
      else if (strstr (name, ".id"))
 
1405
        return 37;
 
1406
      else if (strstr (name, ".da"))
 
1407
        return 38;
 
1408
      else if (strstr (name, ".dd"))
 
1409
        return 39;
 
1410
      else if (strstr (name, ".ss"))
 
1411
        return 40;
 
1412
      else if (strstr (name, ".ri"))
 
1413
        return 41;
 
1414
      else if (strstr (name, ".ed"))
 
1415
        return 43;
 
1416
      else if (strstr (name, ".bn"))
 
1417
        return 44;
 
1418
      else if (strstr (name, ".ia"))
 
1419
        return 45;
 
1420
      else if (strstr (name, ".vm"))
 
1421
        return 46;
 
1422
      else
 
1423
        abort ();
 
1424
    default:
 
1425
      break;
 
1426
    }
 
1427
  return REG_NONE;
 
1428
}
 
1429
 
 
1430
static int
 
1431
lookup_specifier (const char *name)
 
1432
{
 
1433
  if (strchr (name, '%'))
 
1434
    {
 
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)
 
1440
        return IA64_RS_AR;
 
1441
      if (strstr (name, "AR%, % in 48") != NULL)
 
1442
        return IA64_RS_ARb;
 
1443
      if (strstr (name, "BR%") != NULL)
 
1444
        return IA64_RS_BR;
 
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)
 
1452
        return IA64_RS_CR;
 
1453
      if (strstr (name, "DAHR%, % in 0") != NULL)
 
1454
        return IA64_RS_DAHR;
 
1455
      if (strstr (name, "FR%, % in 0") != NULL)
 
1456
        return IA64_RS_FR;
 
1457
      if (strstr (name, "FR%, % in 2") != NULL)
 
1458
        return IA64_RS_FRb;
 
1459
      if (strstr (name, "GR%") != NULL)
 
1460
        return IA64_RS_GR;
 
1461
      if (strstr (name, "PR%, % in 1 ") != NULL)
 
1462
        return IA64_RS_PR;
 
1463
      if (strstr (name, "PR%, % in 16 ") != NULL)
 
1464
        return IA64_RS_PRr;
 
1465
 
 
1466
      warn (_("don't know how to specify %% dependency %s\n"),
 
1467
            name);
 
1468
    }
 
1469
  else if (strchr (name, '#'))
 
1470
    {
 
1471
      if (strstr (name, "CPUID#") != NULL)
 
1472
        return IA64_RS_CPUID;
 
1473
      if (strstr (name, "DBR#") != NULL)
 
1474
        return IA64_RS_DBR;
 
1475
      if (strstr (name, "IBR#") != NULL)
 
1476
        return IA64_RS_IBR;
 
1477
      if (strstr (name, "MSR#") != NULL)
 
1478
        return IA64_RS_MSR;
 
1479
      if (strstr (name, "PKR#") != NULL)
 
1480
        return IA64_RS_PKR;
 
1481
      if (strstr (name, "PMC#") != NULL)
 
1482
        return IA64_RS_PMC;
 
1483
      if (strstr (name, "PMD#") != NULL)
 
1484
        return IA64_RS_PMD;
 
1485
      if (strstr (name, "RR#") != NULL)
 
1486
        return IA64_RS_RR;
 
1487
      
 
1488
      warn (_("Don't know how to specify # dependency %s\n"),
 
1489
            name);
 
1490
    }
 
1491
  else if (CONST_STRNEQ (name, "AR[FPSR]"))
 
1492
    return IA64_RS_AR_FPSR;
 
1493
  else if (CONST_STRNEQ (name, "AR["))
 
1494
    return IA64_RS_ARX;
 
1495
  else if (CONST_STRNEQ (name, "CR["))
 
1496
    return IA64_RS_CRX;
 
1497
  else if (CONST_STRNEQ (name, "PSR."))
 
1498
    return IA64_RS_PSR;
 
1499
  else if (strcmp (name, "InService*") == 0)
 
1500
    return IA64_RS_INSERVICE;
 
1501
  else if (strcmp (name, "GR0") == 0)
 
1502
    return IA64_RS_GR0;
 
1503
  else if (strcmp (name, "CFM") == 0)
 
1504
    return IA64_RS_CFM;
 
1505
  else if (strcmp (name, "PR63") == 0)
 
1506
    return IA64_RS_PR63;
 
1507
  else if (strcmp (name, "RSE") == 0)
 
1508
    return IA64_RS_RSE;
 
1509
 
 
1510
  return IA64_RS_ANY;
 
1511
}
 
1512
 
 
1513
static void
 
1514
print_dependency_table (void)
 
1515
{
 
1516
  int i, j;
 
1517
 
 
1518
  if (debug) 
 
1519
    {
 
1520
      for (i=0;i < iclen;i++)
 
1521
        {
 
1522
          if (ics[i]->is_class)
 
1523
            {
 
1524
              if (!ics[i]->nsubs)
 
1525
                {
 
1526
                  if (ics[i]->comment)
 
1527
                    warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
 
1528
                          ics[i]->name, ics[i]->comment);
 
1529
                  else
 
1530
                    warn (_("IC:%s has no terminals or sub-classes\n"),
 
1531
                          ics[i]->name);
 
1532
                }
 
1533
            }
 
1534
          else 
 
1535
            {
 
1536
              if (!ics[i]->terminal_resolved && !ics[i]->orphan)
 
1537
                {
 
1538
                  if (ics[i]->comment)
 
1539
                    warn (_("no insns mapped directly to terminal IC %s [%s]"),
 
1540
                          ics[i]->name, ics[i]->comment);
 
1541
                  else
 
1542
                    warn (_("no insns mapped directly to terminal IC %s\n"),
 
1543
                          ics[i]->name);
 
1544
                }
 
1545
            }
 
1546
        }
 
1547
 
 
1548
      for (i = 0; i < iclen; i++)
 
1549
        {
 
1550
          if (ics[i]->orphan)
 
1551
            {
 
1552
              mark_used (ics[i], 1);
 
1553
              warn (_("class %s is defined but not used\n"),
 
1554
                    ics[i]->name);
 
1555
            }
 
1556
        }
 
1557
 
 
1558
      if (debug > 1)
 
1559
        for (i = 0; i < rdepslen; i++)
 
1560
          {  
 
1561
            static const char *mode_str[] = { "RAW", "WAW", "WAR" };
 
1562
 
 
1563
            if (rdeps[i]->total_chks == 0)
 
1564
              {
 
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]);
 
1568
                else
 
1569
                  warn (_("Warning: rsrc %s (%s) has no chks or regs\n"), 
 
1570
                        rdeps[i]->name, mode_str[rdeps[i]->mode]);
 
1571
              }
 
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]);
 
1575
          }
 
1576
    }
 
1577
 
 
1578
  /* The dependencies themselves.  */
 
1579
  printf ("static const struct ia64_dependency\ndependencies[] = {\n");
 
1580
  for (i = 0; i < rdepslen; i++)
 
1581
    {
 
1582
      /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
 
1583
         resource used.  */ 
 
1584
      int specifier = lookup_specifier (rdeps[i]->name);
 
1585
      int regindex = lookup_regindex (rdeps[i]->name, specifier);
 
1586
 
 
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)
 
1591
        {
 
1592
          const char *quote, *rest;
 
1593
 
 
1594
          putchar ('\"');
 
1595
          rest = rdeps[i]->extra;
 
1596
          quote = strchr (rest, '\"');
 
1597
          while (quote != NULL)
 
1598
            {
 
1599
              printf ("%.*s\\\"", (int) (quote - rest), rest);
 
1600
              rest = quote + 1;
 
1601
              quote = strchr (rest, '\"');
 
1602
            }
 
1603
          printf ("%s\", ", rest);
 
1604
        }
 
1605
      else
 
1606
        printf ("NULL, ");
 
1607
      printf("},\n");
 
1608
    }
 
1609
  printf ("};\n\n");
 
1610
 
 
1611
  /* And dependency lists.  */
 
1612
  for (i=0;i < dlistlen;i++)
 
1613
    {
 
1614
      int len = 2;
 
1615
      printf ("static const unsigned short dep%d[] = {\n  ", i);
 
1616
      for (j=0;j < dlists[i]->len; j++)
 
1617
        {
 
1618
          len += printf ("%d, ", dlists[i]->deps[j]);
 
1619
          if (len > 75)
 
1620
            {
 
1621
              printf("\n  ");
 
1622
              len = 2;
 
1623
            }
 
1624
        }
 
1625
      printf ("\n};\n\n");
 
1626
    }
 
1627
 
 
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++)
 
1633
    {
 
1634
      printf ("  { ");
 
1635
      if (opdeps[i]->chk == -1)
 
1636
        printf ("0, NULL, ");
 
1637
      else 
 
1638
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
 
1639
      if (opdeps[i]->reg == -1)
 
1640
        printf ("0, NULL, ");
 
1641
      else 
 
1642
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
 
1643
      printf ("},\n");
 
1644
    }
 
1645
  printf ("};\n\n");
 
1646
}
 
1647
 
 
1648
 
 
1649
/* Add STR to the string table.  */
 
1650
static struct string_entry *
 
1651
insert_string (char *str)
 
1652
{
 
1653
  int start = 0, end = strtablen;
 
1654
  int i, x;
 
1655
 
 
1656
  if (strtablen == strtabtotlen)
 
1657
    {
 
1658
      strtabtotlen += 20;
 
1659
      string_table = (struct string_entry **)
 
1660
        xrealloc (string_table, 
 
1661
                  sizeof (struct string_entry **) * strtabtotlen);
 
1662
    }
 
1663
 
 
1664
  if (strtablen == 0)
 
1665
    {
 
1666
      strtablen = 1;
 
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];
 
1671
    }
 
1672
 
 
1673
  if (strcmp (str, string_table[strtablen - 1]->s) > 0)
 
1674
    i = end;
 
1675
  else if (strcmp (str, string_table[0]->s) < 0)
 
1676
    i = 0;
 
1677
  else
 
1678
    {
 
1679
      while (1)
 
1680
        {
 
1681
          int c;
 
1682
 
 
1683
          i = (start + end) / 2;
 
1684
          c = strcmp (str, string_table[i]->s);
 
1685
 
 
1686
          if (c < 0)
 
1687
            end = i - 1;
 
1688
          else if (c == 0)
 
1689
            return string_table[i];
 
1690
          else
 
1691
            start = i + 1;
 
1692
 
 
1693
          if (start > end)
 
1694
            break;
 
1695
        }
 
1696
    }
 
1697
 
 
1698
  for (; i > 0 && i < strtablen; i--)
 
1699
    if (strcmp (str, string_table[i - 1]->s) > 0)
 
1700
      break;
 
1701
 
 
1702
  for (; i < strtablen; i++)
 
1703
    if (strcmp (str, string_table[i]->s) < 0)
 
1704
      break;
 
1705
 
 
1706
  for (x = strtablen - 1; x >= i; x--)
 
1707
    {
 
1708
      string_table[x + 1] = string_table[x];
 
1709
      string_table[x + 1]->num = x + 1;
 
1710
    }
 
1711
 
 
1712
  string_table[i] = tmalloc (struct string_entry);
 
1713
  string_table[i]->s = xstrdup (str);
 
1714
  string_table[i]->num = i;
 
1715
  strtablen++;
 
1716
 
 
1717
  return string_table[i];
 
1718
}
 
1719
 
 
1720
static struct bittree *
 
1721
make_bittree_entry (void)
 
1722
{
 
1723
  struct bittree *res = tmalloc (struct bittree);
 
1724
 
 
1725
  res->disent = NULL;
 
1726
  res->bits[0] = NULL;
 
1727
  res->bits[1] = NULL;
 
1728
  res->bits[2] = NULL;
 
1729
  res->skip_flag = 0;
 
1730
  res->bits_to_skip = 0;
 
1731
  return res;
 
1732
}
 
1733
 
 
1734
 
 
1735
static struct disent *
 
1736
add_dis_table_ent (struct disent *which, int insn, int order,
 
1737
                   ci_t completer_index)
 
1738
{
 
1739
  int ci = 0;
 
1740
  struct disent *ent;
 
1741
 
 
1742
  if (which != NULL)
 
1743
    {
 
1744
      ent = which;
 
1745
 
 
1746
      ent->nextcnt++;
 
1747
      while (ent->nexte != NULL)
 
1748
        ent = ent->nexte;
 
1749
 
 
1750
      ent = (ent->nexte = tmalloc (struct disent));
 
1751
    }
 
1752
  else
 
1753
    {
 
1754
      ent = tmalloc (struct disent);
 
1755
      ent->next_ent = disinsntable;
 
1756
      disinsntable = ent;
 
1757
      which = ent;
 
1758
    }
 
1759
  ent->nextcnt = 0;
 
1760
  ent->nexte = NULL;
 
1761
  ent->insn = insn;
 
1762
  ent->priority = order;
 
1763
 
 
1764
  while (completer_index != 1)
 
1765
    {
 
1766
      ci = (ci << 1) | (completer_index & 1);
 
1767
      completer_index >>= 1;
 
1768
    }
 
1769
  ent->completer_index = ci;
 
1770
  return which;
 
1771
}
 
1772
 
 
1773
static void
 
1774
finish_distable (void)
 
1775
{
 
1776
  struct disent *ent = disinsntable;
 
1777
  struct disent *prev = ent;
 
1778
 
 
1779
  ent->ournum = 32768;
 
1780
  while ((ent = ent->next_ent) != NULL)
 
1781
    {
 
1782
      ent->ournum = prev->ournum + prev->nextcnt + 1;
 
1783
      prev = ent;
 
1784
    }
 
1785
}
 
1786
 
 
1787
static void
 
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)
 
1791
{
 
1792
  ia64_insn m;
 
1793
  int b;
 
1794
  struct bittree *next;
 
1795
 
 
1796
  if (bit == -1)
 
1797
    {
 
1798
      struct disent *nent = add_dis_table_ent (curr_ent->disent, 
 
1799
                                               opcodenum, order,
 
1800
                                               completer_index);
 
1801
      curr_ent->disent = nent;
 
1802
      return;
 
1803
    }
 
1804
 
 
1805
  m = ((ia64_insn) 1) << bit;
 
1806
 
 
1807
  if (mask & m)
 
1808
    b = (opcode & m) ? 1 : 0;
 
1809
  else
 
1810
    b = 2;
 
1811
 
 
1812
  next = curr_ent->bits[b];
 
1813
  if (next == NULL)
 
1814
    {
 
1815
      next = make_bittree_entry ();
 
1816
      curr_ent->bits[b] = next;
 
1817
    }
 
1818
  insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
 
1819
                        completer_index);
 
1820
}
 
1821
 
 
1822
static void
 
1823
add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask,
 
1824
               int opcodenum, struct completer_entry *ent, ci_t completer_index)
 
1825
{
 
1826
  if (completer_index & ((ci_t)1 << 32) )
 
1827
    abort ();
 
1828
 
 
1829
  while (ent != NULL)
 
1830
    {
 
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);
 
1834
 
 
1835
      if (ent->is_terminal)
 
1836
        {
 
1837
          insert_bit_table_ent (bittree, 40, newopcode, mask, 
 
1838
                                opcodenum, opcode_count - ent->order - 1, 
 
1839
                                (completer_index << 1) | 1);
 
1840
        }
 
1841
      completer_index <<= 1;
 
1842
      ent = ent->alternative;
 
1843
    }
 
1844
}
 
1845
 
 
1846
/* This optimization pass combines multiple "don't care" nodes.  */
 
1847
static void
 
1848
compact_distree (struct bittree *ent)
 
1849
{
 
1850
#define IS_SKIP(ent) \
 
1851
    ((ent->bits[2] !=NULL) \
 
1852
     && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
 
1853
 
 
1854
  int bitcnt = 0;
 
1855
  struct bittree *nent = ent;
 
1856
  int x;
 
1857
 
 
1858
  while (IS_SKIP (nent))
 
1859
    {
 
1860
      bitcnt++;
 
1861
      nent = nent->bits[2];
 
1862
    }
 
1863
 
 
1864
  if (bitcnt)
 
1865
    {
 
1866
      struct bittree *next = ent->bits[2];
 
1867
 
 
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;
 
1872
      ent->skip_flag = 1;
 
1873
      ent->bits_to_skip = bitcnt;
 
1874
      while (next != nent)
 
1875
        {
 
1876
          struct bittree *b = next;
 
1877
          next = next->bits[2];
 
1878
          free (b);
 
1879
        }
 
1880
      free (nent);
 
1881
    }
 
1882
 
 
1883
  for (x = 0; x < 3; x++)
 
1884
    {
 
1885
      struct bittree *i = ent->bits[x];
 
1886
 
 
1887
      if (i != NULL)
 
1888
        compact_distree (i);
 
1889
    }
 
1890
}
 
1891
 
 
1892
static unsigned char *insn_list;
 
1893
static int insn_list_len = 0;
 
1894
static int tot_insn_list_len = 0;
 
1895
 
 
1896
/* Generate the disassembler state machine corresponding to the tree
 
1897
   in ENT.  */
 
1898
static void
 
1899
gen_dis_table (struct bittree *ent)
 
1900
{
 
1901
  int x;
 
1902
  int our_offset = insn_list_len;
 
1903
  int bitsused = 5;
 
1904
  int totbits = bitsused;
 
1905
  int needed_bytes;
 
1906
  int zero_count = 0;
 
1907
  int zero_dest = 0;    /* Initialize this with 0 to keep gcc quiet...  */
 
1908
 
 
1909
  /* If this is a terminal entry, there's no point in skipping any
 
1910
     bits.  */
 
1911
  if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
 
1912
      ent->bits[2] == NULL)
 
1913
    {
 
1914
      if (ent->disent == NULL)
 
1915
        abort ();
 
1916
      else
 
1917
        ent->skip_flag = 0;
 
1918
    }
 
1919
 
 
1920
  /* Calculate the amount of space needed for this entry, or at least
 
1921
     a conservatively large approximation.  */
 
1922
  if (ent->skip_flag)
 
1923
    totbits += 5;
 
1924
 
 
1925
  for (x = 1; x < 3; x++)
 
1926
    if (ent->bits[x] != NULL)
 
1927
      totbits += 16;
 
1928
 
 
1929
  if (ent->disent != NULL)
 
1930
    {
 
1931
      if (ent->bits[2] != NULL)
 
1932
        abort ();
 
1933
 
 
1934
      totbits += 16;
 
1935
    }
 
1936
 
 
1937
  /* Now allocate the space.  */
 
1938
  needed_bytes = (totbits + 7) / 8;
 
1939
  if ((needed_bytes + insn_list_len) > tot_insn_list_len)
 
1940
    {
 
1941
      tot_insn_list_len += 256;
 
1942
      insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
 
1943
    }
 
1944
  our_offset = insn_list_len;
 
1945
  insn_list_len += needed_bytes;
 
1946
  memset (insn_list + our_offset, 0, needed_bytes);
 
1947
 
 
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.  */
 
1950
  if (ent->skip_flag)
 
1951
    {
 
1952
      bitsused += 5;
 
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);
 
1955
    }
 
1956
 
 
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)
 
1960
 
 
1961
  /* Store an "if (bit is zero)" instruction by setting bit 7 in the
 
1962
     state op field.  */
 
1963
  if (ent->bits[0] != NULL)
 
1964
    {
 
1965
      struct bittree *nent = ent->bits[0];
 
1966
      zero_count = 0;
 
1967
 
 
1968
      insn_list[our_offset] |= 0x80;
 
1969
 
 
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.  */
 
1974
 
 
1975
      if (IS_ONLY_IFZERO (ent))
 
1976
        {
 
1977
          while (IS_ONLY_IFZERO (nent) && zero_count < 7)
 
1978
            {
 
1979
              nent = nent->bits[0];
 
1980
              zero_count++;
 
1981
            }
 
1982
 
 
1983
          insn_list[our_offset + 0] |= zero_count;
 
1984
        }
 
1985
      zero_dest = insn_list_len;
 
1986
      gen_dis_table (nent);
 
1987
    }
 
1988
 
 
1989
  /* Now store the remaining tests.  We also handle a sole "termination
 
1990
     entry" by storing it as an "any bit" test.  */
 
1991
 
 
1992
  for (x = 1; x < 3; x++)
 
1993
    {
 
1994
      if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
 
1995
        {
 
1996
          struct bittree *i = ent->bits[x];
 
1997
          int idest;
 
1998
          int currbits = 15;
 
1999
 
 
2000
          if (i != NULL)
 
2001
            {
 
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)
 
2007
                {
 
2008
                  idest = i->disent->ournum;
 
2009
                  i = NULL;
 
2010
                }
 
2011
              else
 
2012
                idest = insn_list_len - our_offset;
 
2013
            }
 
2014
          else
 
2015
            idest = ent->disent->ournum;
 
2016
 
 
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.
 
2022
 
 
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.  */
 
2026
          if (x == 1)
 
2027
            {
 
2028
              if (idest <= 256)
 
2029
                {
 
2030
                  int start = our_offset + bitsused / 8 + 1;
 
2031
 
 
2032
                  memmove (insn_list + start,
 
2033
                           insn_list + start + 1,
 
2034
                           insn_list_len - (start + 1));
 
2035
                  currbits = 7;
 
2036
                  totbits -= 8;
 
2037
                  needed_bytes--;
 
2038
                  insn_list_len--;
 
2039
                  insn_list[our_offset] |= 0x10;
 
2040
                  idest--;
 
2041
                }
 
2042
              else
 
2043
                insn_list[our_offset] |= 0x20;
 
2044
            }
 
2045
          else
 
2046
            {
 
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.  */
 
2052
 
 
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))
 
2057
                {
 
2058
                  int start = our_offset + bitsused / 8 + 1;
 
2059
 
 
2060
                  memmove (insn_list + start,
 
2061
                           insn_list + start + 1,
 
2062
                           insn_list_len - (start + 1));
 
2063
                  currbits = 11;
 
2064
                  totbits -= 5;
 
2065
                  bitsused--;
 
2066
                  needed_bytes--;
 
2067
                  insn_list_len--;
 
2068
                  insn_list[our_offset] |= 0x30;
 
2069
                  idest &= ~32768;
 
2070
                }
 
2071
              else
 
2072
                insn_list[our_offset] |= 0x08;
 
2073
            }
 
2074
 
 
2075
          if (debug)
 
2076
            {
 
2077
              int id = idest;
 
2078
 
 
2079
              if (i == NULL)
 
2080
                id |= 32768;
 
2081
              else if (! (id & 32768))
 
2082
                id += our_offset;
 
2083
 
 
2084
              if (x == 1)
 
2085
                printf ("%d: if (1) goto %d\n", our_offset, id);
 
2086
              else
 
2087
                printf ("%d: try %d\n", our_offset, id);
 
2088
            }
 
2089
 
 
2090
          /* Store the address of the entry being branched to.  */
 
2091
          while (currbits >= 0)
 
2092
            {
 
2093
              unsigned char *byte = insn_list + our_offset + bitsused / 8;
 
2094
 
 
2095
              if (idest & (1 << currbits))
 
2096
                *byte |= (1 << (7 - (bitsused % 8)));
 
2097
 
 
2098
              bitsused++;
 
2099
              currbits--;
 
2100
            }
 
2101
 
 
2102
          /* Now generate the states for the entry being branched to.  */
 
2103
          if (i != NULL)
 
2104
            gen_dis_table (i);
 
2105
        }
 
2106
    }
 
2107
 
 
2108
  if (debug)
 
2109
    {
 
2110
      if (ent->skip_flag)
 
2111
        printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
 
2112
  
 
2113
      if (ent->bits[0] != NULL)
 
2114
        printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
 
2115
                zero_dest);
 
2116
    }
 
2117
 
 
2118
  if (bitsused != totbits)
 
2119
    abort ();
 
2120
}
 
2121
 
 
2122
static void
 
2123
print_dis_table (void)
 
2124
{
 
2125
  int x;
 
2126
  struct disent *cent = disinsntable;
 
2127
 
 
2128
  printf ("static const char dis_table[] = {\n");
 
2129
  for (x = 0; x < insn_list_len; x++)
 
2130
    {
 
2131
      if ((x > 0) && ((x % 12) == 0))
 
2132
        printf ("\n");
 
2133
 
 
2134
      printf ("0x%02x, ", insn_list[x]);
 
2135
    }
 
2136
  printf ("\n};\n\n");
 
2137
 
 
2138
  printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
 
2139
  while (cent != NULL)
 
2140
    {
 
2141
      struct disent *ent = cent;
 
2142
 
 
2143
      while (ent != NULL)
 
2144
        {
 
2145
          printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent->completer_index,
 
2146
                  ent->insn, (ent->nexte != NULL ? 1 : 0),
 
2147
                  ent->priority);
 
2148
          ent = ent->nexte;
 
2149
        }
 
2150
      cent = cent->next_ent;
 
2151
    }
 
2152
  printf ("};\n\n");
 
2153
}
 
2154
 
 
2155
static void
 
2156
generate_disassembler (void)
 
2157
{
 
2158
  int i;
 
2159
 
 
2160
  bittree = make_bittree_entry ();
 
2161
 
 
2162
  for (i = 0; i < otlen; i++)
 
2163
    {
 
2164
      struct main_entry *ptr = ordered_table[i];
 
2165
 
 
2166
      if (ptr->opcode->type != IA64_TYPE_DYN)
 
2167
        add_dis_entry (bittree,
 
2168
                       ptr->opcode->opcode, ptr->opcode->mask, 
 
2169
                       ptr->main_index,
 
2170
                       ptr->completers, 1);
 
2171
    }
 
2172
 
 
2173
  compact_distree (bittree);
 
2174
  finish_distable ();
 
2175
  gen_dis_table (bittree);
 
2176
 
 
2177
  print_dis_table ();
 
2178
}
 
2179
 
 
2180
static void
 
2181
print_string_table (void)
 
2182
{
 
2183
  int x;
 
2184
  char lbuf[80], buf[80];
 
2185
  int blen = 0;
 
2186
 
 
2187
  printf ("static const char * const ia64_strings[] = {\n");
 
2188
  lbuf[0] = '\0';
 
2189
 
 
2190
  for (x = 0; x < strtablen; x++)
 
2191
    {
 
2192
      int len;
 
2193
      
 
2194
      if (strlen (string_table[x]->s) > 75)
 
2195
        abort ();
 
2196
 
 
2197
      sprintf (buf, " \"%s\",", string_table[x]->s);
 
2198
      len = strlen (buf);
 
2199
 
 
2200
      if ((blen + len) > 75)
 
2201
        {
 
2202
          printf (" %s\n", lbuf);
 
2203
          lbuf[0] = '\0';
 
2204
          blen = 0;
 
2205
        }
 
2206
      strcat (lbuf, buf);
 
2207
      blen += len;
 
2208
    }
 
2209
 
 
2210
  if (blen > 0)
 
2211
    printf (" %s\n", lbuf);
 
2212
 
 
2213
  printf ("};\n\n");
 
2214
}
 
2215
 
 
2216
static struct completer_entry **glist;
 
2217
static int glistlen = 0;
 
2218
static int glisttotlen = 0;
 
2219
 
 
2220
/* If the completer trees ENT1 and ENT2 are equal, return 1.  */
 
2221
 
 
2222
static int
 
2223
completer_entries_eq (struct completer_entry *ent1,
 
2224
                      struct completer_entry *ent2)
 
2225
{
 
2226
  while (ent1 != NULL && ent2 != NULL)
 
2227
    {
 
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)
 
2234
        return 0;
 
2235
 
 
2236
      if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
 
2237
        return 0;
 
2238
 
 
2239
      ent1 = ent1->alternative;
 
2240
      ent2 = ent2->alternative;
 
2241
    }
 
2242
 
 
2243
  return ent1 == ent2;
 
2244
}
 
2245
 
 
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)
 
2251
{
 
2252
  if (ent != NULL)
 
2253
    {
 
2254
      int i;
 
2255
      int x;
 
2256
      int start = 0, end;
 
2257
 
 
2258
      ent->addl_entries = insert_gclist (ent->addl_entries);
 
2259
      ent->alternative = insert_gclist (ent->alternative);
 
2260
 
 
2261
      i = glistlen / 2;
 
2262
      end = glistlen;
 
2263
 
 
2264
      if (glisttotlen == glistlen)
 
2265
        {
 
2266
          glisttotlen += 20;
 
2267
          glist = (struct completer_entry **)
 
2268
            xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
 
2269
        }
 
2270
 
 
2271
      if (glistlen == 0)
 
2272
        {
 
2273
          glist[0] = ent;
 
2274
          glistlen = 1;
 
2275
          return ent;
 
2276
        }
 
2277
 
 
2278
      if (ent->name->num < glist[0]->name->num)
 
2279
        i = 0;
 
2280
      else if (ent->name->num > glist[end - 1]->name->num)
 
2281
        i = end;
 
2282
      else
 
2283
        {
 
2284
          int c;
 
2285
 
 
2286
          while (1)
 
2287
            {
 
2288
              i = (start + end) / 2;
 
2289
              c = ent->name->num - glist[i]->name->num;
 
2290
 
 
2291
              if (c < 0)
 
2292
                end = i - 1;
 
2293
              else if (c == 0)
 
2294
                {
 
2295
                  while (i > 0 
 
2296
                         && ent->name->num == glist[i - 1]->name->num)
 
2297
                    i--;
 
2298
 
 
2299
                  break;
 
2300
                }
 
2301
              else
 
2302
                start = i + 1;
 
2303
 
 
2304
              if (start > end)
 
2305
                break;
 
2306
            }
 
2307
 
 
2308
          if (c == 0)
 
2309
            {
 
2310
              while (i < glistlen)
 
2311
                {
 
2312
                  if (ent->name->num != glist[i]->name->num)
 
2313
                    break;
 
2314
 
 
2315
                  if (completer_entries_eq (ent, glist[i]))
 
2316
                    return glist[i];
 
2317
 
 
2318
                  i++;
 
2319
                }
 
2320
            }
 
2321
        }
 
2322
 
 
2323
      for (; i > 0 && i < glistlen; i--)
 
2324
        if (ent->name->num >= glist[i - 1]->name->num)
 
2325
          break;
 
2326
 
 
2327
      for (; i < glistlen; i++)
 
2328
        if (ent->name->num < glist[i]->name->num)
 
2329
          break;
 
2330
 
 
2331
      for (x = glistlen - 1; x >= i; x--)
 
2332
        glist[x + 1] = glist[x];
 
2333
 
 
2334
      glist[i] = ent;
 
2335
      glistlen++;
 
2336
    }
 
2337
  return ent;
 
2338
}
 
2339
 
 
2340
static int
 
2341
get_prefix_len (const char *name)
 
2342
{
 
2343
  char *c;
 
2344
 
 
2345
  if (name[0] == '\0')
 
2346
    return 0;
 
2347
 
 
2348
  c = strchr (name, '.');
 
2349
  if (c != NULL)
 
2350
    return c - name;
 
2351
  else
 
2352
    return strlen (name);
 
2353
}
 
2354
 
 
2355
static void
 
2356
compute_completer_bits (struct main_entry *ment, struct completer_entry *ent)
 
2357
{
 
2358
  while (ent != NULL)
 
2359
    {
 
2360
      compute_completer_bits (ment, ent->addl_entries);
 
2361
 
 
2362
      if (ent->is_terminal)
 
2363
        {
 
2364
          ia64_insn mask = 0;
 
2365
          ia64_insn our_bits = ent->bits;
 
2366
          struct completer_entry *p = ent->parent;
 
2367
          ia64_insn p_bits;
 
2368
          int x;
 
2369
 
 
2370
          while (p != NULL && ! p->is_terminal)
 
2371
            p = p->parent;
 
2372
      
 
2373
          if (p != NULL)
 
2374
            p_bits = p->bits;
 
2375
          else
 
2376
            p_bits = ment->opcode->opcode;
 
2377
 
 
2378
          for (x = 0; x < 64; x++)
 
2379
            {
 
2380
              ia64_insn m = ((ia64_insn) 1) << x;
 
2381
 
 
2382
              if ((p_bits & m) != (our_bits & m))
 
2383
                mask |= m;
 
2384
              else
 
2385
                our_bits &= ~m;
 
2386
            }
 
2387
          ent->bits = our_bits;
 
2388
          ent->mask = mask;
 
2389
        }
 
2390
      else
 
2391
        {
 
2392
          ent->bits = 0;
 
2393
          ent->mask = 0;
 
2394
        }
 
2395
 
 
2396
      ent = ent->alternative;
 
2397
    }
 
2398
}
 
2399
 
 
2400
/* Find identical completer trees that are used in different
 
2401
   instructions and collapse their entries.  */
 
2402
static void
 
2403
collapse_redundant_completers (void)
 
2404
{
 
2405
  struct main_entry *ptr;
 
2406
  int x;
 
2407
 
 
2408
  for (ptr = maintable; ptr != NULL; ptr = ptr->next)
 
2409
    {
 
2410
      if (ptr->completers == NULL)
 
2411
        abort ();
 
2412
 
 
2413
      compute_completer_bits (ptr, ptr->completers);
 
2414
      ptr->completers = insert_gclist (ptr->completers);
 
2415
    }
 
2416
 
 
2417
  /* The table has been finalized, now number the indexes.  */
 
2418
  for (x = 0; x < glistlen; x++)
 
2419
    glist[x]->num = x;
 
2420
}
 
2421
 
 
2422
 
 
2423
/* Attach two lists of dependencies to each opcode.
 
2424
   1) all resources which, when already marked in use, conflict with this
 
2425
   opcode (chks) 
 
2426
   2) all resources which must be marked in use when this opcode is used
 
2427
   (regs).  */
 
2428
static int
 
2429
insert_opcode_dependencies (struct ia64_opcode *opc,
 
2430
                            struct completer_entry *cmp ATTRIBUTE_UNUSED)
 
2431
{
 
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.  */
 
2434
  int i;
 
2435
  int nregs = 0;
 
2436
  unsigned short regs[256];                  
 
2437
  int nchks = 0;
 
2438
  unsigned short chks[256];
 
2439
  /* Flag insns for which no class matched; there should be none.  */
 
2440
  int no_class_found = 1;
 
2441
 
 
2442
  for (i = 0; i < rdepslen; i++)
 
2443
    {
 
2444
      struct rdep *rs = rdeps[i];
 
2445
      int j;
 
2446
 
 
2447
      if (strcmp (opc->name, "cmp.eq.and") == 0
 
2448
          && CONST_STRNEQ (rs->name, "PR%")
 
2449
          && rs->mode == 1)
 
2450
        no_class_found = 99;
 
2451
 
 
2452
      for (j=0; j < rs->nregs;j++)
 
2453
        {
 
2454
          int ic_note = 0;
 
2455
 
 
2456
          if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
 
2457
            {
 
2458
              /* We can ignore ic_note 11 for non PR resources.  */
 
2459
              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
 
2460
                ic_note = 0;
 
2461
 
 
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.  */
 
2471
              if (ic_note)
 
2472
                regs[nregs++] = RDEP(ic_note, i);
 
2473
              else
 
2474
                regs[nregs++] = RDEP(rs->regnotes[j], i);
 
2475
              no_class_found = 0;
 
2476
              ++rs->total_regs;
 
2477
            }
 
2478
        }
 
2479
 
 
2480
      for (j = 0; j < rs->nchks; j++)
 
2481
        {
 
2482
          int ic_note = 0;
 
2483
 
 
2484
          if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
 
2485
            {
 
2486
              /* We can ignore ic_note 11 for non PR resources.  */
 
2487
              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
 
2488
                ic_note = 0;
 
2489
 
 
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]);
 
2496
              if (ic_note)
 
2497
                chks[nchks++] = RDEP(ic_note, i);
 
2498
              else
 
2499
                chks[nchks++] = RDEP(rs->chknotes[j], i);
 
2500
              no_class_found = 0;
 
2501
              ++rs->total_chks;
 
2502
            }
 
2503
        }
 
2504
    }
 
2505
 
 
2506
  if (no_class_found)
 
2507
    warn (_("opcode %s has no class (ops %d %d %d)\n"),
 
2508
          opc->name, 
 
2509
          opc->operands[0], opc->operands[1], opc->operands[2]);
 
2510
 
 
2511
  return insert_dependencies (nchks, chks, nregs, regs);
 
2512
}
 
2513
 
 
2514
static void
 
2515
insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent,
 
2516
                        int order)
 
2517
{
 
2518
  struct completer_entry **ptr = &tabent->completers;
 
2519
  struct completer_entry *parent = NULL;
 
2520
  char pcopy[129], *prefix;
 
2521
  int at_end = 0;
 
2522
 
 
2523
  if (strlen (opc->name) > 128)
 
2524
    abort ();
 
2525
 
 
2526
  strcpy (pcopy, opc->name);
 
2527
  prefix = pcopy + get_prefix_len (pcopy);
 
2528
 
 
2529
  if (prefix[0] != '\0')
 
2530
    prefix++;
 
2531
 
 
2532
  while (! at_end)
 
2533
    {
 
2534
      int need_new_ent = 1;
 
2535
      int plen = get_prefix_len (prefix);
 
2536
      struct string_entry *sent;
 
2537
 
 
2538
      at_end = (prefix[plen] == '\0');
 
2539
      prefix[plen] = '\0';
 
2540
      sent = insert_string (prefix);
 
2541
 
 
2542
      while (*ptr != NULL)
 
2543
        {
 
2544
          int cmpres = sent->num - (*ptr)->name->num;
 
2545
 
 
2546
          if (cmpres == 0)
 
2547
            {
 
2548
              need_new_ent = 0;
 
2549
              break;
 
2550
            }
 
2551
          else
 
2552
            ptr = &((*ptr)->alternative);
 
2553
        }
 
2554
 
 
2555
      if (need_new_ent)
 
2556
        {
 
2557
          struct completer_entry *nent = tmalloc (struct completer_entry);
 
2558
 
 
2559
          nent->name = sent;
 
2560
          nent->parent = parent;
 
2561
          nent->addl_entries = NULL;
 
2562
          nent->alternative = *ptr;
 
2563
          *ptr = nent;
 
2564
          nent->is_terminal = 0;
 
2565
          nent->dependencies = -1;
 
2566
        }
 
2567
 
 
2568
      if (! at_end)
 
2569
        {
 
2570
          parent = *ptr;
 
2571
          ptr = &((*ptr)->addl_entries);
 
2572
          prefix += plen + 1;
 
2573
        }
 
2574
    }
 
2575
 
 
2576
  if ((*ptr)->is_terminal)
 
2577
    abort ();
 
2578
 
 
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;
 
2584
}
 
2585
 
 
2586
static void
 
2587
print_completer_entry (struct completer_entry *ent)
 
2588
{
 
2589
  int moffset = 0;
 
2590
  ia64_insn mask = ent->mask, bits = ent->bits;
 
2591
 
 
2592
  if (mask != 0)
 
2593
    {
 
2594
      while (! (mask & 1))
 
2595
        {
 
2596
          moffset++;
 
2597
          mask = mask >> 1;
 
2598
          bits = bits >> 1;
 
2599
        }
 
2600
 
 
2601
      if (bits & 0xffffffff00000000LL)
 
2602
        abort ();
 
2603
    }
 
2604
  
 
2605
  printf ("  { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
 
2606
          (int)bits,
 
2607
          (int)mask,
 
2608
          ent->name->num,
 
2609
          ent->alternative != NULL ? ent->alternative->num : -1,
 
2610
          ent->addl_entries != NULL ? ent->addl_entries->num : -1,
 
2611
          moffset,
 
2612
          ent->is_terminal ? 1 : 0,
 
2613
          ent->dependencies);
 
2614
}
 
2615
 
 
2616
static void
 
2617
print_completer_table (void)
 
2618
{
 
2619
  int x;
 
2620
 
 
2621
  printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
 
2622
  for (x = 0; x < glistlen; x++)
 
2623
    print_completer_entry (glist[x]);
 
2624
  printf ("};\n\n");
 
2625
}
 
2626
 
 
2627
static int
 
2628
opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2)
 
2629
{
 
2630
  int x;
 
2631
  int plen1, plen2;
 
2632
 
 
2633
  if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 
 
2634
      || (opc1->num_outputs != opc2->num_outputs)
 
2635
      || (opc1->flags != opc2->flags))
 
2636
    return 0;
 
2637
 
 
2638
  for (x = 0; x < 5; x++)
 
2639
    if (opc1->operands[x] != opc2->operands[x])
 
2640
      return 0;
 
2641
 
 
2642
  plen1 = get_prefix_len (opc1->name);
 
2643
  plen2 = get_prefix_len (opc2->name);
 
2644
 
 
2645
  if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
 
2646
    return 1;
 
2647
 
 
2648
  return 0;
 
2649
}
 
2650
 
 
2651
static void
 
2652
add_opcode_entry (struct ia64_opcode *opc)
 
2653
{
 
2654
  struct main_entry **place;
 
2655
  struct string_entry *name;
 
2656
  char prefix[129];
 
2657
  int found_it = 0;
 
2658
 
 
2659
  if (strlen (opc->name) > 128)
 
2660
    abort ();
 
2661
 
 
2662
  place = &maintable;
 
2663
  strcpy (prefix, opc->name);
 
2664
  prefix[get_prefix_len (prefix)] = '\0';
 
2665
  name = insert_string (prefix);
 
2666
 
 
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.  */
 
2670
 
 
2671
  while (*place != NULL)
 
2672
    {
 
2673
      if ((*place)->name->num == name->num
 
2674
          && opcodes_eq ((*place)->opcode, opc))
 
2675
        {
 
2676
          found_it = 1;
 
2677
          break;
 
2678
        }
 
2679
      if ((*place)->name->num > name->num)
 
2680
        break;
 
2681
 
 
2682
      place = &((*place)->next);
 
2683
    }
 
2684
  if (! found_it)
 
2685
    {
 
2686
      struct main_entry *nent = tmalloc (struct main_entry);
 
2687
 
 
2688
      nent->name = name;
 
2689
      nent->opcode = opc;
 
2690
      nent->next = *place;
 
2691
      nent->completers = 0;
 
2692
      *place = nent;
 
2693
 
 
2694
      if (otlen == ottotlen)
 
2695
        {
 
2696
          ottotlen += 20;
 
2697
          ordered_table = (struct main_entry **)
 
2698
            xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
 
2699
        }
 
2700
      ordered_table[otlen++] = nent;
 
2701
    }
 
2702
 
 
2703
  insert_completer_entry (opc, *place, opcode_count++);
 
2704
}
 
2705
 
 
2706
static void
 
2707
print_main_table (void)
 
2708
{
 
2709
  struct main_entry *ptr = maintable;
 
2710
  int tindex = 0;
 
2711
 
 
2712
  printf ("static const struct ia64_main_table\nmain_table[] = {\n");
 
2713
  while (ptr != NULL)
 
2714
    {
 
2715
      printf ("  { %d, %d, %d, 0x",
 
2716
              ptr->name->num,
 
2717
              ptr->opcode->type,
 
2718
              ptr->opcode->num_outputs);
 
2719
      opcode_fprintf_vma (stdout, ptr->opcode->opcode);
 
2720
      printf ("ull, 0x");
 
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],
 
2728
              ptr->opcode->flags,
 
2729
              ptr->completers->num);
 
2730
 
 
2731
      ptr->main_index = tindex++;
 
2732
 
 
2733
      ptr = ptr->next;
 
2734
    }
 
2735
  printf ("};\n\n");
 
2736
}
 
2737
 
 
2738
static void
 
2739
shrink (struct ia64_opcode *table)
 
2740
{
 
2741
  int curr_opcode;
 
2742
 
 
2743
  for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
 
2744
    {
 
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)))
 
2751
        {
 
2752
          struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
 
2753
          unsigned i;
 
2754
 
 
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);
 
2762
        }
 
2763
    }
 
2764
}
 
2765
 
 
2766
 
 
2767
/* Program options.  */
 
2768
#define OPTION_SRCDIR   200
 
2769
 
 
2770
struct option long_options[] = 
 
2771
{
 
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}
 
2777
};
 
2778
 
 
2779
static void
 
2780
print_version (void)
 
2781
{
 
2782
  printf ("%s: version 1.0\n", program_name);
 
2783
  xexit (0);
 
2784
}
 
2785
 
 
2786
static void
 
2787
usage (FILE * stream, int status)
 
2788
{
 
2789
  fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
 
2790
           program_name);
 
2791
  xexit (status);
 
2792
}
 
2793
 
 
2794
int
 
2795
main (int argc, char **argv)
 
2796
{
 
2797
  extern int chdir (char *);
 
2798
  char *srcdir = NULL;
 
2799
  int c;
 
2800
  
 
2801
  program_name = *argv;
 
2802
  xmalloc_set_program_name (program_name);
 
2803
 
 
2804
  while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
 
2805
    switch (c)
 
2806
      {
 
2807
      case OPTION_SRCDIR:
 
2808
        srcdir = optarg;
 
2809
        break;
 
2810
      case 'V':
 
2811
      case 'v':
 
2812
        print_version ();
 
2813
        break;
 
2814
      case 'd':
 
2815
        debug = 1;
 
2816
        break;
 
2817
      case 'h':
 
2818
      case '?':
 
2819
        usage (stderr, 0);
 
2820
      default:
 
2821
      case 0:
 
2822
        break;
 
2823
      }
 
2824
 
 
2825
  if (optind != argc)
 
2826
    usage (stdout, 1);
 
2827
 
 
2828
  if (srcdir != NULL) 
 
2829
    if (chdir (srcdir) != 0)
 
2830
      fail (_("unable to change directory to \"%s\", errno = %s\n"),
 
2831
            srcdir, strerror (errno));
 
2832
 
 
2833
  load_insn_classes ();
 
2834
  load_dependencies ();
 
2835
 
 
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);
 
2843
 
 
2844
  collapse_redundant_completers ();
 
2845
 
 
2846
  printf ("/* This file is automatically generated by ia64-gen.  Do not edit!  */\n");
 
2847
  printf ("/* Copyright 2007  Free Software Foundation, Inc.\n\
 
2848
\n\
 
2849
   This file is part of the GNU opcodes library.\n\
 
2850
\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\
 
2855
\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\
 
2860
\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");
 
2865
 
 
2866
  print_string_table ();
 
2867
  print_dependency_table ();
 
2868
  print_completer_table ();
 
2869
  print_main_table ();
 
2870
 
 
2871
  generate_disassembler ();
 
2872
 
 
2873
  exit (0);
 
2874
}