OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [opcodes/] [ia64-gen.c] - Blame information for rev 157

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* ia64-gen.c -- Generate a shrunk set of opcode tables
2
   Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
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 <stdio.h>
38
#include <stdarg.h>
39
#include <errno.h>
40
 
41
#include "ansidecl.h"
42
#include "libiberty.h"
43
#include "safe-ctype.h"
44
#include "sysdep.h"
45
#include "getopt.h"
46
#include "ia64-opc.h"
47
#include "ia64-opc-a.c"
48
#include "ia64-opc-i.c"
49
#include "ia64-opc-m.c"
50
#include "ia64-opc-b.c"
51
#include "ia64-opc-f.c"
52
#include "ia64-opc-x.c"
53
#include "ia64-opc-d.c"
54
 
55
#include <libintl.h>
56
#define _(String) gettext (String)
57
 
58
/* This is a copy of fprintf_vma from bfd/bfd-in2.h.  We have to use this
59
   always, because we might be compiled without BFD64 defined, if configured
60
   for a 32-bit target and --enable-targets=all is used.  This will work for
61
   both 32-bit and 64-bit hosts.  */
62
#define _opcode_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
63
#define _opcode_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
64
#define opcode_fprintf_vma(s,x) \
65
  fprintf ((s), "%08lx%08lx", _opcode_int64_high (x), _opcode_int64_low (x))
66
 
67
const char * program_name = NULL;
68
int debug = 0;
69
 
70
#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
71
#define tmalloc(X) (X *) xmalloc (sizeof (X))
72
 
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
  int 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, int);
295
static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, int);
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, int);
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 (ref, usersp, nusersp, notesp)
698
  const char *ref;
699
  int **usersp;
700
  int *nusersp;
701
  int **notesp;
702
{
703
  int c;
704
  char *line = xstrdup (ref);
705
  char *tmp = line;
706
  int *users = *usersp;
707
  int count = *nusersp;
708
  int *notes = *notesp;
709
 
710
  c = *tmp;
711
  while (c != 0)
712
    {
713
      char *notestr;
714
      int note;
715
      char *xsect;
716
      int iclass;
717
      int create = 0;
718
      char *name;
719
 
720
      while (ISSPACE (*tmp))
721
        ++tmp;
722
      name = tmp;
723
      while (*tmp && *tmp != ',')
724
        ++tmp;
725
      c = *tmp;
726
      *tmp++ = '\0';
727
 
728
      xsect = strchr (name, '\\');
729
      if ((notestr = strstr (name, "+")) != NULL)
730
        {
731
          char *nextnotestr;
732
 
733
          note = atoi (notestr + 1);
734
          if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
735
            {
736
              /* Note 13 always implies note 1.  */
737
              if (strcmp (notestr, "+1+13") == 0)
738
                note = 13;
739
              else if (!xsect || nextnotestr < xsect)
740
                warn (_("multiple note %s not handled\n"), notestr);
741
            }
742
          if (!xsect)
743
            *notestr = '\0';
744
        }
745
      else
746
        note = 0;
747
 
748
      /* All classes are created when the insn class table is parsed;
749
         Individual instructions might not appear until the dependency tables
750
         are read.  Only create new classes if it's *not* an insn class,
751
         or if it's a composite class (which wouldn't necessarily be in the IC
752
         table).  */
753
      if (! CONST_STRNEQ (name, "IC:") || xsect != NULL)
754
        create = 1;
755
 
756
      iclass = fetch_insn_class (name, create);
757
      if (iclass != -1)
758
        {
759
          users = (int *)
760
            xrealloc ((void *) users,(count + 1) * sizeof (int));
761
          notes = (int *)
762
            xrealloc ((void *) notes,(count + 1) * sizeof (int));
763
          notes[count] = note;
764
          users[count++] = iclass;
765
          mark_used (ics[iclass], 0);
766
        }
767
      else if (debug)
768
        printf("Class %s not found\n", name);
769
    }
770
  /* Update the return values.  */
771
  *usersp = users;
772
  *nusersp = count;
773
  *notesp = notes;
774
 
775
  free (line);
776
}
777
 
778
static int
779
parse_semantics (char *sem)
780
{
781
  if (strcmp (sem, "none") == 0)
782
    return IA64_DVS_NONE;
783
  else if (strcmp (sem, "implied") == 0)
784
    return IA64_DVS_IMPLIED;
785
  else if (strcmp (sem, "impliedF") == 0)
786
    return IA64_DVS_IMPLIEDF;
787
  else if (strcmp (sem, "data") == 0)
788
    return IA64_DVS_DATA;
789
  else if (strcmp (sem, "instr") == 0)
790
    return IA64_DVS_INSTR;
791
  else if (strcmp (sem, "specific") == 0)
792
    return IA64_DVS_SPECIFIC;
793
  else if (strcmp (sem, "stop") == 0)
794
    return IA64_DVS_STOP;
795
  else
796
    return IA64_DVS_OTHER;
797
}
798
 
799
static void
800
add_dep (const char *name, const char *chk, const char *reg,
801
         int semantics, int mode, char *extra, int flag)
802
{
803
  struct rdep *rs;
804
 
805
  rs = insert_resource (name, mode);
806
 
807
  parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes);
808
  parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes);
809
 
810
  rs->semantics = semantics;
811
  rs->extra = extra;
812
  rs->waw_special = flag;
813
}
814
 
815
static void
816
load_depfile (const char *filename, enum ia64_dependency_mode mode)
817
{
818
  FILE *fp = fopen (filename, "r");
819
  char buf[1024];
820
 
821
  if (fp == NULL)
822
    fail (_("can't find %s for reading\n"), filename);
823
 
824
  fgets (buf, sizeof(buf), fp);
825
  while (!feof (fp))
826
    {
827
      char *name, *tmp;
828
      int semantics;
829
      char *extra;
830
      char *regp, *chkp;
831
 
832
      if (fgets (buf, sizeof(buf), fp) == NULL)
833
        break;
834
 
835
      while (ISSPACE (buf[strlen (buf) - 1]))
836
        buf[strlen (buf) - 1] = '\0';
837
 
838
      name = tmp = buf;
839
      while (*tmp != ';')
840
        ++tmp;
841
      *tmp++ = '\0';
842
 
843
      while (ISSPACE (*tmp))
844
        ++tmp;
845
      regp = tmp;
846
      tmp = strchr (tmp, ';');
847
      if (!tmp)
848
        abort ();
849
      *tmp++ = 0;
850
      while (ISSPACE (*tmp))
851
        ++tmp;
852
      chkp = tmp;
853
      tmp = strchr (tmp, ';');
854
      if (!tmp)
855
        abort ();
856
      *tmp++ = 0;
857
      while (ISSPACE (*tmp))
858
        ++tmp;
859
      semantics = parse_semantics (tmp);
860
      extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
861
 
862
      /* For WAW entries, if the chks and regs differ, we need to enter the
863
         entries in both positions so that the tables will be parsed properly,
864
         without a lot of extra work.  */
865
      if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
866
        {
867
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
868
          add_dep (name, regp, chkp, semantics, mode, extra, 1);
869
        }
870
      else
871
        {
872
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
873
        }
874
    }
875
  fclose (fp);
876
}
877
 
878
static void
879
load_dependencies (void)
880
{
881
  load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
882
  load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
883
  load_depfile ("ia64-war.tbl", IA64_DV_WAR);
884
 
885
  if (debug)
886
    printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
887
}
888
 
889
/* Is the given operand an indirect register file operand?  */
890
static int
891
irf_operand (int op, const char *field)
892
{
893
  if (!field)
894
    {
895
      return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
896
        || op == IA64_OPND_IBR_R3  || op == IA64_OPND_PKR_R3
897
        || op == IA64_OPND_PMC_R3  || op == IA64_OPND_PMD_R3
898
        || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
899
    }
900
  else
901
    {
902
      return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
903
              || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
904
              || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
905
              || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
906
              || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
907
              || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
908
              || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
909
              || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
910
    }
911
}
912
 
913
/* Handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
914
   mov_um insn classes.  */
915
static int
916
in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
917
                 const char *format, const char *field)
918
{
919
  int plain_mov = strcmp (idesc->name, "mov") == 0;
920
 
921
  if (!format)
922
    return 0;
923
 
924
  switch (ic->name[4])
925
    {
926
    default:
927
      abort ();
928
    case 'a':
929
      {
930
        int i = strcmp (idesc->name, "mov.i") == 0;
931
        int m = strcmp (idesc->name, "mov.m") == 0;
932
        int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
933
        int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
934
        int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
935
        int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
936
        int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
937
        int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
938
 
939
        /* IC:mov ar */
940
        if (i2627)
941
          return strstr (format, "I26") || strstr (format, "I27");
942
        if (i28)
943
          return strstr (format, "I28") != NULL;
944
        if (m2930)
945
          return strstr (format, "M29") || strstr (format, "M30");
946
        if (m31)
947
          return strstr (format, "M31") != NULL;
948
        if (pseudo0 || pseudo1)
949
          return 1;
950
      }
951
      break;
952
    case 'b':
953
      {
954
        int i21 = idesc->operands[0] == IA64_OPND_B1;
955
        int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
956
        if (i22)
957
          return strstr (format, "I22") != NULL;
958
        if (i21)
959
          return strstr (format, "I21") != NULL;
960
      }
961
      break;
962
    case 'c':
963
      {
964
        int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
965
        int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
966
        if (m32)
967
          return strstr (format, "M32") != NULL;
968
        if (m33)
969
          return strstr (format, "M33") != NULL;
970
      }
971
      break;
972
    case 'i':
973
      if (ic->name[5] == 'n')
974
        {
975
          int m42 = plain_mov && irf_operand (idesc->operands[0], field);
976
          int m43 = plain_mov && irf_operand (idesc->operands[1], field);
977
          if (m42)
978
            return strstr (format, "M42") != NULL;
979
          if (m43)
980
            return strstr (format, "M43") != NULL;
981
        }
982
      else if (ic->name[5] == 'p')
983
        {
984
          return idesc->operands[1] == IA64_OPND_IP;
985
        }
986
      else
987
        abort ();
988
      break;
989
    case 'p':
990
      if (ic->name[5] == 'r')
991
        {
992
          int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
993
          int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
994
          int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
995
          if (i23)
996
            return strstr (format, "I23") != NULL;
997
          if (i24)
998
            return strstr (format, "I24") != NULL;
999
          if (i25)
1000
            return strstr (format, "I25") != NULL;
1001
        }
1002
      else if (ic->name[5] == 's')
1003
        {
1004
          int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
1005
          int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
1006
          if (m35)
1007
            return strstr (format, "M35") != NULL;
1008
          if (m36)
1009
            return strstr (format, "M36") != NULL;
1010
        }
1011
      else
1012
        abort ();
1013
      break;
1014
    case 'u':
1015
      {
1016
        int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
1017
        int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
1018
        if (m35)
1019
          return strstr (format, "M35") != NULL;
1020
        if (m36)
1021
          return strstr (format, "M36") != NULL;
1022
      }
1023
      break;
1024
    }
1025
  return 0;
1026
}
1027
 
1028
/* Is the given opcode in the given insn class?  */
1029
static int
1030
in_iclass (struct ia64_opcode *idesc, struct iclass *ic,
1031
           const char *format, const char *field, int *notep)
1032
{
1033
  int i;
1034
  int resolved = 0;
1035
 
1036
  if (ic->comment)
1037
    {
1038
      if (CONST_STRNEQ (ic->comment, "Format"))
1039
        {
1040
          /* Assume that the first format seen is the most restrictive, and
1041
             only keep a later one if it looks like it's more restrictive.  */
1042
          if (format)
1043
            {
1044
              if (strlen (ic->comment) < strlen (format))
1045
                {
1046
                  warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"),
1047
                        ic->comment, format);
1048
                  format = ic->comment;
1049
                }
1050
            }
1051
          else
1052
            format = ic->comment;
1053
        }
1054
      else if (CONST_STRNEQ (ic->comment, "Field"))
1055
        {
1056
          if (field)
1057
            warn (_("overlapping field %s->%s\n"),
1058
                  ic->comment, field);
1059
          field = ic->comment;
1060
        }
1061
    }
1062
 
1063
  /* An insn class matches anything that is the same followed by completers,
1064
     except when the absence and presence of completers constitutes different
1065
     instructions.  */
1066
  if (ic->nsubs == 0 && ic->nxsubs == 0)
1067
    {
1068
      int is_mov = CONST_STRNEQ (idesc->name, "mov");
1069
      int plain_mov = strcmp (idesc->name, "mov") == 0;
1070
      int len = strlen(ic->name);
1071
 
1072
      resolved = ((strncmp (ic->name, idesc->name, len) == 0)
1073
                  && (idesc->name[len] == '\0'
1074
                      || idesc->name[len] == '.'));
1075
 
1076
      /* All break, nop, and hint variations must match exactly.  */
1077
      if (resolved &&
1078
          (strcmp (ic->name, "break") == 0
1079
           || strcmp (ic->name, "nop") == 0
1080
           || strcmp (ic->name, "hint") == 0))
1081
        resolved = strcmp (ic->name, idesc->name) == 0;
1082
 
1083
      /* Assume restrictions in the FORMAT/FIELD negate resolution,
1084
         unless specifically allowed by clauses in this block.  */
1085
      if (resolved && field)
1086
        {
1087
          /* Check Field(sf)==sN against opcode sN.  */
1088
          if (strstr(field, "(sf)==") != NULL)
1089
            {
1090
              char *sf;
1091
 
1092
              if ((sf = strstr (idesc->name, ".s")) != 0)
1093
                resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1094
            }
1095
          /* Check Field(lftype)==XXX.  */
1096
          else if (strstr (field, "(lftype)") != NULL)
1097
            {
1098
              if (strstr (idesc->name, "fault") != NULL)
1099
                resolved = strstr (field, "fault") != NULL;
1100
              else
1101
                resolved = strstr (field, "fault") == NULL;
1102
            }
1103
          /* Handle Field(ctype)==XXX.  */
1104
          else if (strstr (field, "(ctype)") != NULL)
1105
            {
1106
              if (strstr (idesc->name, "or.andcm"))
1107
                resolved = strstr (field, "or.andcm") != NULL;
1108
              else if (strstr (idesc->name, "and.orcm"))
1109
                resolved = strstr (field, "and.orcm") != NULL;
1110
              else if (strstr (idesc->name, "orcm"))
1111
                resolved = strstr (field, "or orcm") != NULL;
1112
              else if (strstr (idesc->name, "or"))
1113
                resolved = strstr (field, "or orcm") != NULL;
1114
              else if (strstr (idesc->name, "andcm"))
1115
                resolved = strstr (field, "and andcm") != NULL;
1116
              else if (strstr (idesc->name, "and"))
1117
                resolved = strstr (field, "and andcm") != NULL;
1118
              else if (strstr (idesc->name, "unc"))
1119
                resolved = strstr (field, "unc") != NULL;
1120
              else
1121
                resolved = strcmp (field, "Field(ctype)==") == 0;
1122
            }
1123
        }
1124
 
1125
      if (resolved && format)
1126
        {
1127
          if (CONST_STRNEQ (idesc->name, "dep")
1128
                   && strstr (format, "I13") != NULL)
1129
            resolved = idesc->operands[1] == IA64_OPND_IMM8;
1130
          else if (CONST_STRNEQ (idesc->name, "chk")
1131
                   && strstr (format, "M21") != NULL)
1132
            resolved = idesc->operands[0] == IA64_OPND_F2;
1133
          else if (CONST_STRNEQ (idesc->name, "lfetch"))
1134
            resolved = (strstr (format, "M14 M15") != NULL
1135
                        && (idesc->operands[1] == IA64_OPND_R2
1136
                            || idesc->operands[1] == IA64_OPND_IMM9b));
1137
          else if (CONST_STRNEQ (idesc->name, "br.call")
1138
                   && strstr (format, "B5") != NULL)
1139
            resolved = idesc->operands[1] == IA64_OPND_B2;
1140
          else if (CONST_STRNEQ (idesc->name, "br.call")
1141
                   && strstr (format, "B3") != NULL)
1142
            resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1143
          else if (CONST_STRNEQ (idesc->name, "brp")
1144
                   && strstr (format, "B7") != NULL)
1145
            resolved = idesc->operands[0] == IA64_OPND_B2;
1146
          else if (strcmp (ic->name, "invala") == 0)
1147
            resolved = strcmp (idesc->name, ic->name) == 0;
1148
          else if (CONST_STRNEQ (idesc->name, "st")
1149
                   && (strstr (format, "M5") != NULL
1150
                       || strstr (format, "M10") != NULL))
1151
            resolved = idesc->flags & IA64_OPCODE_POSTINC;
1152
          else if (CONST_STRNEQ (idesc->name, "ld")
1153
                   && (strstr (format, "M2 M3") != NULL
1154
                       || strstr (format, "M12") != NULL
1155
                       || strstr (format, "M7 M8") != NULL))
1156
            resolved = idesc->flags & IA64_OPCODE_POSTINC;
1157
          else
1158
            resolved = 0;
1159
        }
1160
 
1161
      /* Misc brl variations ('.cond' is optional);
1162
         plain brl matches brl.cond.  */
1163
      if (!resolved
1164
          && (strcmp (idesc->name, "brl") == 0
1165
              || CONST_STRNEQ (idesc->name, "brl."))
1166
          && strcmp (ic->name, "brl.cond") == 0)
1167
        {
1168
          resolved = 1;
1169
        }
1170
 
1171
      /* Misc br variations ('.cond' is optional).  */
1172
      if (!resolved
1173
          && (strcmp (idesc->name, "br") == 0
1174
              || CONST_STRNEQ (idesc->name, "br."))
1175
          && strcmp (ic->name, "br.cond") == 0)
1176
        {
1177
          if (format)
1178
            resolved = (strstr (format, "B4") != NULL
1179
                        && idesc->operands[0] == IA64_OPND_B2)
1180
              || (strstr (format, "B1") != NULL
1181
                  && idesc->operands[0] == IA64_OPND_TGT25c);
1182
          else
1183
            resolved = 1;
1184
        }
1185
 
1186
      /* probe variations.  */
1187
      if (!resolved && CONST_STRNEQ (idesc->name, "probe"))
1188
        {
1189
          resolved = strcmp (ic->name, "probe") == 0
1190
            && !((strstr (idesc->name, "fault") != NULL)
1191
                 ^ (format && strstr (format, "M40") != NULL));
1192
        }
1193
 
1194
      /* mov variations.  */
1195
      if (!resolved && is_mov)
1196
        {
1197
          if (plain_mov)
1198
            {
1199
              /* mov alias for fmerge.  */
1200
              if (strcmp (ic->name, "fmerge") == 0)
1201
                {
1202
                  resolved = idesc->operands[0] == IA64_OPND_F1
1203
                    && idesc->operands[1] == IA64_OPND_F3;
1204
                }
1205
              /* mov alias for adds (r3 or imm14).  */
1206
              else if (strcmp (ic->name, "adds") == 0)
1207
                {
1208
                  resolved = (idesc->operands[0] == IA64_OPND_R1
1209
                              && (idesc->operands[1] == IA64_OPND_R3
1210
                                  || (idesc->operands[1] == IA64_OPND_IMM14)));
1211
                }
1212
              /* mov alias for addl.  */
1213
              else if (strcmp (ic->name, "addl") == 0)
1214
                {
1215
                  resolved = idesc->operands[0] == IA64_OPND_R1
1216
                    && idesc->operands[1] == IA64_OPND_IMM22;
1217
                }
1218
            }
1219
 
1220
          /* Some variants of mov and mov.[im].  */
1221
          if (!resolved && CONST_STRNEQ (ic->name, "mov_"))
1222
            resolved = in_iclass_mov_x (idesc, ic, format, field);
1223
        }
1224
 
1225
      /* Keep track of this so we can flag any insn classes which aren't
1226
         mapped onto at least one real insn.  */
1227
      if (resolved)
1228
        ic->terminal_resolved = 1;
1229
    }
1230
  else for (i = 0; i < ic->nsubs; i++)
1231
    {
1232
      if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep))
1233
        {
1234
          int j;
1235
 
1236
          for (j = 0; j < ic->nxsubs; j++)
1237
            if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1238
              return 0;
1239
 
1240
          if (debug > 1)
1241
            printf ("%s is in IC %s\n", idesc->name, ic->name);
1242
 
1243
          resolved = 1;
1244
          break;
1245
        }
1246
    }
1247
 
1248
  /* If it's in this IC, add the IC note (if any) to the insn.  */
1249
  if (resolved)
1250
    {
1251
      if (ic->note && notep)
1252
        {
1253
          if (*notep && *notep != ic->note)
1254
            warn (_("overwriting note %d with note %d (IC:%s)\n"),
1255
                  *notep, ic->note, ic->name);
1256
 
1257
          *notep = ic->note;
1258
        }
1259
    }
1260
 
1261
  return resolved;
1262
}
1263
 
1264
 
1265
static int
1266
lookup_regindex (const char *name, int specifier)
1267
{
1268
  switch (specifier)
1269
    {
1270
    case IA64_RS_ARX:
1271
      if (strstr (name, "[RSC]"))
1272
        return 16;
1273
      if (strstr (name, "[BSP]"))
1274
        return 17;
1275
      else if (strstr (name, "[BSPSTORE]"))
1276
        return 18;
1277
      else if (strstr (name, "[RNAT]"))
1278
        return 19;
1279
      else if (strstr (name, "[FCR]"))
1280
        return 21;
1281
      else if (strstr (name, "[EFLAG]"))
1282
        return 24;
1283
      else if (strstr (name, "[CSD]"))
1284
        return 25;
1285
      else if (strstr (name, "[SSD]"))
1286
        return 26;
1287
      else if (strstr (name, "[CFLG]"))
1288
        return 27;
1289
      else if (strstr (name, "[FSR]"))
1290
        return 28;
1291
      else if (strstr (name, "[FIR]"))
1292
        return 29;
1293
      else if (strstr (name, "[FDR]"))
1294
        return 30;
1295
      else if (strstr (name, "[CCV]"))
1296
        return 32;
1297
      else if (strstr (name, "[ITC]"))
1298
        return 44;
1299
      else if (strstr (name, "[RUC]"))
1300
        return 45;
1301
      else if (strstr (name, "[PFS]"))
1302
        return 64;
1303
      else if (strstr (name, "[LC]"))
1304
        return 65;
1305
      else if (strstr (name, "[EC]"))
1306
        return 66;
1307
      abort ();
1308
    case IA64_RS_CRX:
1309
      if (strstr (name, "[DCR]"))
1310
        return 0;
1311
      else if (strstr (name, "[ITM]"))
1312
        return 1;
1313
      else if (strstr (name, "[IVA]"))
1314
        return 2;
1315
      else if (strstr (name, "[PTA]"))
1316
        return 8;
1317
      else if (strstr (name, "[GPTA]"))
1318
        return 9;
1319
      else if (strstr (name, "[IPSR]"))
1320
        return 16;
1321
      else if (strstr (name, "[ISR]"))
1322
        return 17;
1323
      else if (strstr (name, "[IIP]"))
1324
        return 19;
1325
      else if (strstr (name, "[IFA]"))
1326
        return 20;
1327
      else if (strstr (name, "[ITIR]"))
1328
        return 21;
1329
      else if (strstr (name, "[IIPA]"))
1330
        return 22;
1331
      else if (strstr (name, "[IFS]"))
1332
        return 23;
1333
      else if (strstr (name, "[IIM]"))
1334
        return 24;
1335
      else if (strstr (name, "[IHA]"))
1336
        return 25;
1337
      else if (strstr (name, "[LID]"))
1338
        return 64;
1339
      else if (strstr (name, "[IVR]"))
1340
        return 65;
1341
      else if (strstr (name, "[TPR]"))
1342
        return 66;
1343
      else if (strstr (name, "[EOI]"))
1344
        return 67;
1345
      else if (strstr (name, "[ITV]"))
1346
        return 72;
1347
      else if (strstr (name, "[PMV]"))
1348
        return 73;
1349
      else if (strstr (name, "[CMCV]"))
1350
        return 74;
1351
      abort ();
1352
    case IA64_RS_PSR:
1353
      if (strstr (name, ".be"))
1354
        return 1;
1355
      else if (strstr (name, ".up"))
1356
        return 2;
1357
      else if (strstr (name, ".ac"))
1358
        return 3;
1359
      else if (strstr (name, ".mfl"))
1360
        return 4;
1361
      else if (strstr (name, ".mfh"))
1362
        return 5;
1363
      else if (strstr (name, ".ic"))
1364
        return 13;
1365
      else if (strstr (name, ".i"))
1366
        return 14;
1367
      else if (strstr (name, ".pk"))
1368
        return 15;
1369
      else if (strstr (name, ".dt"))
1370
        return 17;
1371
      else if (strstr (name, ".dfl"))
1372
        return 18;
1373
      else if (strstr (name, ".dfh"))
1374
        return 19;
1375
      else if (strstr (name, ".sp"))
1376
        return 20;
1377
      else if (strstr (name, ".pp"))
1378
        return 21;
1379
      else if (strstr (name, ".di"))
1380
        return 22;
1381
      else if (strstr (name, ".si"))
1382
        return 23;
1383
      else if (strstr (name, ".db"))
1384
        return 24;
1385
      else if (strstr (name, ".lp"))
1386
        return 25;
1387
      else if (strstr (name, ".tb"))
1388
        return 26;
1389
      else if (strstr (name, ".rt"))
1390
        return 27;
1391
      else if (strstr (name, ".cpl"))
1392
        return 32;
1393
      else if (strstr (name, ".rs"))
1394
        return 34;
1395
      else if (strstr (name, ".mc"))
1396
        return 35;
1397
      else if (strstr (name, ".it"))
1398
        return 36;
1399
      else if (strstr (name, ".id"))
1400
        return 37;
1401
      else if (strstr (name, ".da"))
1402
        return 38;
1403
      else if (strstr (name, ".dd"))
1404
        return 39;
1405
      else if (strstr (name, ".ss"))
1406
        return 40;
1407
      else if (strstr (name, ".ri"))
1408
        return 41;
1409
      else if (strstr (name, ".ed"))
1410
        return 43;
1411
      else if (strstr (name, ".bn"))
1412
        return 44;
1413
      else if (strstr (name, ".ia"))
1414
        return 45;
1415
      else if (strstr (name, ".vm"))
1416
        return 46;
1417
      else
1418
        abort ();
1419
    default:
1420
      break;
1421
    }
1422
  return REG_NONE;
1423
}
1424
 
1425
static int
1426
lookup_specifier (const char *name)
1427
{
1428
  if (strchr (name, '%'))
1429
    {
1430
      if (strstr (name, "AR[K%]") != NULL)
1431
        return IA64_RS_AR_K;
1432
      if (strstr (name, "AR[UNAT]") != NULL)
1433
        return IA64_RS_AR_UNAT;
1434
      if (strstr (name, "AR%, % in 8") != NULL)
1435
        return IA64_RS_AR;
1436
      if (strstr (name, "AR%, % in 48") != NULL)
1437
        return IA64_RS_ARb;
1438
      if (strstr (name, "BR%") != NULL)
1439
        return IA64_RS_BR;
1440
      if (strstr (name, "CR[IRR%]") != NULL)
1441
        return IA64_RS_CR_IRR;
1442
      if (strstr (name, "CR[LRR%]") != NULL)
1443
        return IA64_RS_CR_LRR;
1444
      if (strstr (name, "CR%") != NULL)
1445
        return IA64_RS_CR;
1446
      if (strstr (name, "FR%, % in 0") != NULL)
1447
        return IA64_RS_FR;
1448
      if (strstr (name, "FR%, % in 2") != NULL)
1449
        return IA64_RS_FRb;
1450
      if (strstr (name, "GR%") != NULL)
1451
        return IA64_RS_GR;
1452
      if (strstr (name, "PR%, % in 1 ") != NULL)
1453
        return IA64_RS_PR;
1454
      if (strstr (name, "PR%, % in 16 ") != NULL)
1455
        return IA64_RS_PRr;
1456
 
1457
      warn (_("don't know how to specify %% dependency %s\n"),
1458
            name);
1459
    }
1460
  else if (strchr (name, '#'))
1461
    {
1462
      if (strstr (name, "CPUID#") != NULL)
1463
        return IA64_RS_CPUID;
1464
      if (strstr (name, "DBR#") != NULL)
1465
        return IA64_RS_DBR;
1466
      if (strstr (name, "IBR#") != NULL)
1467
        return IA64_RS_IBR;
1468
      if (strstr (name, "MSR#") != NULL)
1469
        return IA64_RS_MSR;
1470
      if (strstr (name, "PKR#") != NULL)
1471
        return IA64_RS_PKR;
1472
      if (strstr (name, "PMC#") != NULL)
1473
        return IA64_RS_PMC;
1474
      if (strstr (name, "PMD#") != NULL)
1475
        return IA64_RS_PMD;
1476
      if (strstr (name, "RR#") != NULL)
1477
        return IA64_RS_RR;
1478
 
1479
      warn (_("Don't know how to specify # dependency %s\n"),
1480
            name);
1481
    }
1482
  else if (CONST_STRNEQ (name, "AR[FPSR]"))
1483
    return IA64_RS_AR_FPSR;
1484
  else if (CONST_STRNEQ (name, "AR["))
1485
    return IA64_RS_ARX;
1486
  else if (CONST_STRNEQ (name, "CR["))
1487
    return IA64_RS_CRX;
1488
  else if (CONST_STRNEQ (name, "PSR."))
1489
    return IA64_RS_PSR;
1490
  else if (strcmp (name, "InService*") == 0)
1491
    return IA64_RS_INSERVICE;
1492
  else if (strcmp (name, "GR0") == 0)
1493
    return IA64_RS_GR0;
1494
  else if (strcmp (name, "CFM") == 0)
1495
    return IA64_RS_CFM;
1496
  else if (strcmp (name, "PR63") == 0)
1497
    return IA64_RS_PR63;
1498
  else if (strcmp (name, "RSE") == 0)
1499
    return IA64_RS_RSE;
1500
 
1501
  return IA64_RS_ANY;
1502
}
1503
 
1504
static void
1505
print_dependency_table ()
1506
{
1507
  int i, j;
1508
 
1509
  if (debug)
1510
    {
1511
      for (i=0;i < iclen;i++)
1512
        {
1513
          if (ics[i]->is_class)
1514
            {
1515
              if (!ics[i]->nsubs)
1516
                {
1517
                  if (ics[i]->comment)
1518
                    warn (_("IC:%s [%s] has no terminals or sub-classes\n"),
1519
                          ics[i]->name, ics[i]->comment);
1520
                  else
1521
                    warn (_("IC:%s has no terminals or sub-classes\n"),
1522
                          ics[i]->name);
1523
                }
1524
            }
1525
          else
1526
            {
1527
              if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1528
                {
1529
                  if (ics[i]->comment)
1530
                    warn (_("no insns mapped directly to terminal IC %s [%s]"),
1531
                          ics[i]->name, ics[i]->comment);
1532
                  else
1533
                    warn (_("no insns mapped directly to terminal IC %s\n"),
1534
                          ics[i]->name);
1535
                }
1536
            }
1537
        }
1538
 
1539
      for (i = 0; i < iclen; i++)
1540
        {
1541
          if (ics[i]->orphan)
1542
            {
1543
              mark_used (ics[i], 1);
1544
              warn (_("class %s is defined but not used\n"),
1545
                    ics[i]->name);
1546
            }
1547
        }
1548
 
1549
      if (debug > 1)
1550
        for (i = 0; i < rdepslen; i++)
1551
          {
1552
            static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1553
 
1554
            if (rdeps[i]->total_chks == 0)
1555
              {
1556
                if (rdeps[i]->total_regs)
1557
                  warn (_("Warning: rsrc %s (%s) has no chks\n"),
1558
                        rdeps[i]->name, mode_str[rdeps[i]->mode]);
1559
                else
1560
                  warn (_("Warning: rsrc %s (%s) has no chks or regs\n"),
1561
                        rdeps[i]->name, mode_str[rdeps[i]->mode]);
1562
              }
1563
            else if (rdeps[i]->total_regs == 0)
1564
              warn (_("rsrc %s (%s) has no regs\n"),
1565
                    rdeps[i]->name, mode_str[rdeps[i]->mode]);
1566
          }
1567
    }
1568
 
1569
  /* The dependencies themselves.  */
1570
  printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1571
  for (i = 0; i < rdepslen; i++)
1572
    {
1573
      /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1574
         resource used.  */
1575
      int specifier = lookup_specifier (rdeps[i]->name);
1576
      int regindex = lookup_regindex (rdeps[i]->name, specifier);
1577
 
1578
      printf ("  { \"%s\", %d, %d, %d, %d, ",
1579
              rdeps[i]->name, specifier,
1580
              (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1581
      if (rdeps[i]->semantics == IA64_DVS_OTHER)
1582
        {
1583
          const char *quote, *rest;
1584
 
1585
          putchar ('\"');
1586
          rest = rdeps[i]->extra;
1587
          quote = strchr (rest, '\"');
1588
          while (quote != NULL)
1589
            {
1590
              printf ("%.*s\\\"", (int) (quote - rest), rest);
1591
              rest = quote + 1;
1592
              quote = strchr (rest, '\"');
1593
            }
1594
          printf ("%s\", ", rest);
1595
        }
1596
      else
1597
        printf ("NULL, ");
1598
      printf("},\n");
1599
    }
1600
  printf ("};\n\n");
1601
 
1602
  /* And dependency lists.  */
1603
  for (i=0;i < dlistlen;i++)
1604
    {
1605
      int len = 2;
1606
      printf ("static const unsigned short dep%d[] = {\n  ", i);
1607
      for (j=0;j < dlists[i]->len; j++)
1608
        {
1609
          len += printf ("%d, ", dlists[i]->deps[j]);
1610
          if (len > 75)
1611
            {
1612
              printf("\n  ");
1613
              len = 2;
1614
            }
1615
        }
1616
      printf ("\n};\n\n");
1617
    }
1618
 
1619
  /* And opcode dependency list.  */
1620
  printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1621
  printf ("static const struct ia64_opcode_dependency\n");
1622
  printf ("op_dependencies[] = {\n");
1623
  for (i = 0; i < opdeplen; i++)
1624
    {
1625
      printf ("  { ");
1626
      if (opdeps[i]->chk == -1)
1627
        printf ("0, NULL, ");
1628
      else
1629
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1630
      if (opdeps[i]->reg == -1)
1631
        printf ("0, NULL, ");
1632
      else
1633
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1634
      printf ("},\n");
1635
    }
1636
  printf ("};\n\n");
1637
}
1638
 
1639
 
1640
/* Add STR to the string table.  */
1641
static struct string_entry *
1642
insert_string (char *str)
1643
{
1644
  int start = 0, end = strtablen;
1645
  int i, x;
1646
 
1647
  if (strtablen == strtabtotlen)
1648
    {
1649
      strtabtotlen += 20;
1650
      string_table = (struct string_entry **)
1651
        xrealloc (string_table,
1652
                  sizeof (struct string_entry **) * strtabtotlen);
1653
    }
1654
 
1655
  if (strtablen == 0)
1656
    {
1657
      strtablen = 1;
1658
      string_table[0] = tmalloc (struct string_entry);
1659
      string_table[0]->s = xstrdup (str);
1660
      string_table[0]->num = 0;
1661
      return string_table[0];
1662
    }
1663
 
1664
  if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1665
    i = end;
1666
  else if (strcmp (str, string_table[0]->s) < 0)
1667
    i = 0;
1668
  else
1669
    {
1670
      while (1)
1671
        {
1672
          int c;
1673
 
1674
          i = (start + end) / 2;
1675
          c = strcmp (str, string_table[i]->s);
1676
 
1677
          if (c < 0)
1678
            end = i - 1;
1679
          else if (c == 0)
1680
            return string_table[i];
1681
          else
1682
            start = i + 1;
1683
 
1684
          if (start > end)
1685
            break;
1686
        }
1687
    }
1688
 
1689
  for (; i > 0 && i < strtablen; i--)
1690
    if (strcmp (str, string_table[i - 1]->s) > 0)
1691
      break;
1692
 
1693
  for (; i < strtablen; i++)
1694
    if (strcmp (str, string_table[i]->s) < 0)
1695
      break;
1696
 
1697
  for (x = strtablen - 1; x >= i; x--)
1698
    {
1699
      string_table[x + 1] = string_table[x];
1700
      string_table[x + 1]->num = x + 1;
1701
    }
1702
 
1703
  string_table[i] = tmalloc (struct string_entry);
1704
  string_table[i]->s = xstrdup (str);
1705
  string_table[i]->num = i;
1706
  strtablen++;
1707
 
1708
  return string_table[i];
1709
}
1710
 
1711
static struct bittree *
1712
make_bittree_entry (void)
1713
{
1714
  struct bittree *res = tmalloc (struct bittree);
1715
 
1716
  res->disent = NULL;
1717
  res->bits[0] = NULL;
1718
  res->bits[1] = NULL;
1719
  res->bits[2] = NULL;
1720
  res->skip_flag = 0;
1721
  res->bits_to_skip = 0;
1722
  return res;
1723
}
1724
 
1725
 
1726
static struct disent *
1727
add_dis_table_ent (which, insn, order, completer_index)
1728
     struct disent *which;
1729
     int insn;
1730
     int order;
1731
     int completer_index;
1732
{
1733
  int ci = 0;
1734
  struct disent *ent;
1735
 
1736
  if (which != NULL)
1737
    {
1738
      ent = which;
1739
 
1740
      ent->nextcnt++;
1741
      while (ent->nexte != NULL)
1742
        ent = ent->nexte;
1743
 
1744
      ent = (ent->nexte = tmalloc (struct disent));
1745
    }
1746
  else
1747
    {
1748
      ent = tmalloc (struct disent);
1749
      ent->next_ent = disinsntable;
1750
      disinsntable = ent;
1751
      which = ent;
1752
    }
1753
  ent->nextcnt = 0;
1754
  ent->nexte = NULL;
1755
  ent->insn = insn;
1756
  ent->priority = order;
1757
 
1758
  while (completer_index != 1)
1759
    {
1760
      ci = (ci << 1) | (completer_index & 1);
1761
      completer_index >>= 1;
1762
    }
1763
  ent->completer_index = ci;
1764
  return which;
1765
}
1766
 
1767
static void
1768
finish_distable ()
1769
{
1770
  struct disent *ent = disinsntable;
1771
  struct disent *prev = ent;
1772
 
1773
  ent->ournum = 32768;
1774
  while ((ent = ent->next_ent) != NULL)
1775
    {
1776
      ent->ournum = prev->ournum + prev->nextcnt + 1;
1777
      prev = ent;
1778
    }
1779
}
1780
 
1781
static void
1782
insert_bit_table_ent (curr_ent, bit, opcode, mask,
1783
                      opcodenum, order, completer_index)
1784
     struct bittree *curr_ent;
1785
     int bit;
1786
     ia64_insn opcode;
1787
     ia64_insn mask;
1788
     int opcodenum;
1789
     int order;
1790
     int 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 (first, opcode, mask, opcodenum, ent, completer_index)
1824
     struct bittree *first;
1825
     ia64_insn opcode;
1826
     ia64_insn mask;
1827
     int opcodenum;
1828
     struct completer_entry *ent;
1829
     int completer_index;
1830
{
1831
  if (completer_index & (1 << 20))
1832
    abort ();
1833
 
1834
  while (ent != NULL)
1835
    {
1836
      ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1837
      add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1838
                     (completer_index << 1) | 1);
1839
 
1840
      if (ent->is_terminal)
1841
        {
1842
          insert_bit_table_ent (bittree, 40, newopcode, mask,
1843
                                opcodenum, opcode_count - ent->order - 1,
1844
                                (completer_index << 1) | 1);
1845
        }
1846
      completer_index <<= 1;
1847
      ent = ent->alternative;
1848
    }
1849
}
1850
 
1851
/* This optimization pass combines multiple "don't care" nodes.  */
1852
static void
1853
compact_distree (ent)
1854
     struct bittree *ent;
1855
{
1856
#define IS_SKIP(ent) \
1857
    ((ent->bits[2] !=NULL) \
1858
     && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1859
 
1860
  int bitcnt = 0;
1861
  struct bittree *nent = ent;
1862
  int x;
1863
 
1864
  while (IS_SKIP (nent))
1865
    {
1866
      bitcnt++;
1867
      nent = nent->bits[2];
1868
    }
1869
 
1870
  if (bitcnt)
1871
    {
1872
      struct bittree *next = ent->bits[2];
1873
 
1874
      ent->bits[0] = nent->bits[0];
1875
      ent->bits[1] = nent->bits[1];
1876
      ent->bits[2] = nent->bits[2];
1877
      ent->disent = nent->disent;
1878
      ent->skip_flag = 1;
1879
      ent->bits_to_skip = bitcnt;
1880
      while (next != nent)
1881
        {
1882
          struct bittree *b = next;
1883
          next = next->bits[2];
1884
          free (b);
1885
        }
1886
      free (nent);
1887
    }
1888
 
1889
  for (x = 0; x < 3; x++)
1890
    {
1891
      struct bittree *i = ent->bits[x];
1892
 
1893
      if (i != NULL)
1894
        compact_distree (i);
1895
    }
1896
}
1897
 
1898
static unsigned char *insn_list;
1899
static int insn_list_len = 0;
1900
static int tot_insn_list_len = 0;
1901
 
1902
/* Generate the disassembler state machine corresponding to the tree
1903
   in ENT.  */
1904
static void
1905
gen_dis_table (ent)
1906
     struct bittree *ent;
1907
{
1908
  int x;
1909
  int our_offset = insn_list_len;
1910
  int bitsused = 5;
1911
  int totbits = bitsused;
1912
  int needed_bytes;
1913
  int zero_count = 0;
1914
  int zero_dest = 0;     /* Initialize this with 0 to keep gcc quiet...  */
1915
 
1916
  /* If this is a terminal entry, there's no point in skipping any
1917
     bits.  */
1918
  if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1919
      ent->bits[2] == NULL)
1920
    {
1921
      if (ent->disent == NULL)
1922
        abort ();
1923
      else
1924
        ent->skip_flag = 0;
1925
    }
1926
 
1927
  /* Calculate the amount of space needed for this entry, or at least
1928
     a conservatively large approximation.  */
1929
  if (ent->skip_flag)
1930
    totbits += 5;
1931
 
1932
  for (x = 1; x < 3; x++)
1933
    if (ent->bits[x] != NULL)
1934
      totbits += 16;
1935
 
1936
  if (ent->disent != NULL)
1937
    {
1938
      if (ent->bits[2] != NULL)
1939
        abort ();
1940
 
1941
      totbits += 16;
1942
    }
1943
 
1944
  /* Now allocate the space.  */
1945
  needed_bytes = (totbits + 7) / 8;
1946
  if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1947
    {
1948
      tot_insn_list_len += 256;
1949
      insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);
1950
    }
1951
  our_offset = insn_list_len;
1952
  insn_list_len += needed_bytes;
1953
  memset (insn_list + our_offset, 0, needed_bytes);
1954
 
1955
  /* Encode the skip entry by setting bit 6 set in the state op field,
1956
     and store the # of bits to skip immediately after.  */
1957
  if (ent->skip_flag)
1958
    {
1959
      bitsused += 5;
1960
      insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1961
      insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1962
    }
1963
 
1964
#define IS_ONLY_IFZERO(ENT) \
1965
  ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1966
   && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1967
 
1968
  /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1969
     state op field.  */
1970
  if (ent->bits[0] != NULL)
1971
    {
1972
      struct bittree *nent = ent->bits[0];
1973
      zero_count = 0;
1974
 
1975
      insn_list[our_offset] |= 0x80;
1976
 
1977
      /* We can encode sequences of multiple "if (bit is zero)" tests
1978
         by storing the # of zero bits to check in the lower 3 bits of
1979
         the instruction.  However, this only applies if the state
1980
         solely tests for a zero bit.  */
1981
 
1982
      if (IS_ONLY_IFZERO (ent))
1983
        {
1984
          while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1985
            {
1986
              nent = nent->bits[0];
1987
              zero_count++;
1988
            }
1989
 
1990
          insn_list[our_offset + 0] |= zero_count;
1991
        }
1992
      zero_dest = insn_list_len;
1993
      gen_dis_table (nent);
1994
    }
1995
 
1996
  /* Now store the remaining tests.  We also handle a sole "termination
1997
     entry" by storing it as an "any bit" test.  */
1998
 
1999
  for (x = 1; x < 3; x++)
2000
    {
2001
      if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
2002
        {
2003
          struct bittree *i = ent->bits[x];
2004
          int idest;
2005
          int currbits = 15;
2006
 
2007
          if (i != NULL)
2008
            {
2009
              /* If the instruction being branched to only consists of
2010
                 a termination entry, use the termination entry as the
2011
                 place to branch to instead.  */
2012
              if (i->bits[0] == NULL && i->bits[1] == NULL
2013
                  && i->bits[2] == NULL && i->disent != NULL)
2014
                {
2015
                  idest = i->disent->ournum;
2016
                  i = NULL;
2017
                }
2018
              else
2019
                idest = insn_list_len - our_offset;
2020
            }
2021
          else
2022
            idest = ent->disent->ournum;
2023
 
2024
          /* If the destination offset for the if (bit is 1) test is less
2025
             than 256 bytes away, we can store it as 8-bits instead of 16;
2026
             the instruction has bit 5 set for the 16-bit address, and bit
2027
             4 for the 8-bit address.  Since we've already allocated 16
2028
             bits for the address we need to deallocate the space.
2029
 
2030
             Note that branchings within the table are relative, and
2031
             there are no branches that branch past our instruction yet
2032
             so we do not need to adjust any other offsets.  */
2033
          if (x == 1)
2034
            {
2035
              if (idest <= 256)
2036
                {
2037
                  int start = our_offset + bitsused / 8 + 1;
2038
 
2039
                  memmove (insn_list + start,
2040
                           insn_list + start + 1,
2041
                           insn_list_len - (start + 1));
2042
                  currbits = 7;
2043
                  totbits -= 8;
2044
                  needed_bytes--;
2045
                  insn_list_len--;
2046
                  insn_list[our_offset] |= 0x10;
2047
                  idest--;
2048
                }
2049
              else
2050
                insn_list[our_offset] |= 0x20;
2051
            }
2052
          else
2053
            {
2054
              /* An instruction which solely consists of a termination
2055
                 marker and whose disassembly name index is < 4096
2056
                 can be stored in 16 bits.  The encoding is slightly
2057
                 odd; the upper 4 bits of the instruction are 0x3, and
2058
                 bit 3 loses its normal meaning.  */
2059
 
2060
              if (ent->bits[0] == NULL && ent->bits[1] == NULL
2061
                  && ent->bits[2] == NULL && ent->skip_flag == 0
2062
                  && ent->disent != NULL
2063
                  && ent->disent->ournum < (32768 + 4096))
2064
                {
2065
                  int start = our_offset + bitsused / 8 + 1;
2066
 
2067
                  memmove (insn_list + start,
2068
                           insn_list + start + 1,
2069
                           insn_list_len - (start + 1));
2070
                  currbits = 11;
2071
                  totbits -= 5;
2072
                  bitsused--;
2073
                  needed_bytes--;
2074
                  insn_list_len--;
2075
                  insn_list[our_offset] |= 0x30;
2076
                  idest &= ~32768;
2077
                }
2078
              else
2079
                insn_list[our_offset] |= 0x08;
2080
            }
2081
 
2082
          if (debug)
2083
            {
2084
              int id = idest;
2085
 
2086
              if (i == NULL)
2087
                id |= 32768;
2088
              else if (! (id & 32768))
2089
                id += our_offset;
2090
 
2091
              if (x == 1)
2092
                printf ("%d: if (1) goto %d\n", our_offset, id);
2093
              else
2094
                printf ("%d: try %d\n", our_offset, id);
2095
            }
2096
 
2097
          /* Store the address of the entry being branched to.  */
2098
          while (currbits >= 0)
2099
            {
2100
              unsigned char *byte = insn_list + our_offset + bitsused / 8;
2101
 
2102
              if (idest & (1 << currbits))
2103
                *byte |= (1 << (7 - (bitsused % 8)));
2104
 
2105
              bitsused++;
2106
              currbits--;
2107
            }
2108
 
2109
          /* Now generate the states for the entry being branched to.  */
2110
          if (i != NULL)
2111
            gen_dis_table (i);
2112
        }
2113
    }
2114
 
2115
  if (debug)
2116
    {
2117
      if (ent->skip_flag)
2118
        printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2119
 
2120
      if (ent->bits[0] != NULL)
2121
        printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2122
                zero_dest);
2123
    }
2124
 
2125
  if (bitsused != totbits)
2126
    abort ();
2127
}
2128
 
2129
static void
2130
print_dis_table (void)
2131
{
2132
  int x;
2133
  struct disent *cent = disinsntable;
2134
 
2135
  printf ("static const char dis_table[] = {\n");
2136
  for (x = 0; x < insn_list_len; x++)
2137
    {
2138
      if ((x > 0) && ((x % 12) == 0))
2139
        printf ("\n");
2140
 
2141
      printf ("0x%02x, ", insn_list[x]);
2142
    }
2143
  printf ("\n};\n\n");
2144
 
2145
  printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2146
  while (cent != NULL)
2147
    {
2148
      struct disent *ent = cent;
2149
 
2150
      while (ent != NULL)
2151
        {
2152
          printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2153
                  ent->insn, (ent->nexte != NULL ? 1 : 0),
2154
                  ent->priority);
2155
          ent = ent->nexte;
2156
        }
2157
      cent = cent->next_ent;
2158
    }
2159
  printf ("};\n\n");
2160
}
2161
 
2162
static void
2163
generate_disassembler (void)
2164
{
2165
  int i;
2166
 
2167
  bittree = make_bittree_entry ();
2168
 
2169
  for (i = 0; i < otlen; i++)
2170
    {
2171
      struct main_entry *ptr = ordered_table[i];
2172
 
2173
      if (ptr->opcode->type != IA64_TYPE_DYN)
2174
        add_dis_entry (bittree,
2175
                       ptr->opcode->opcode, ptr->opcode->mask,
2176
                       ptr->main_index,
2177
                       ptr->completers, 1);
2178
    }
2179
 
2180
  compact_distree (bittree);
2181
  finish_distable ();
2182
  gen_dis_table (bittree);
2183
 
2184
  print_dis_table ();
2185
}
2186
 
2187
static void
2188
print_string_table (void)
2189
{
2190
  int x;
2191
  char lbuf[80], buf[80];
2192
  int blen = 0;
2193
 
2194
  printf ("static const char * const ia64_strings[] = {\n");
2195
  lbuf[0] = '\0';
2196
 
2197
  for (x = 0; x < strtablen; x++)
2198
    {
2199
      int len;
2200
 
2201
      if (strlen (string_table[x]->s) > 75)
2202
        abort ();
2203
 
2204
      sprintf (buf, " \"%s\",", string_table[x]->s);
2205
      len = strlen (buf);
2206
 
2207
      if ((blen + len) > 75)
2208
        {
2209
          printf (" %s\n", lbuf);
2210
          lbuf[0] = '\0';
2211
          blen = 0;
2212
        }
2213
      strcat (lbuf, buf);
2214
      blen += len;
2215
    }
2216
 
2217
  if (blen > 0)
2218
    printf (" %s\n", lbuf);
2219
 
2220
  printf ("};\n\n");
2221
}
2222
 
2223
static struct completer_entry **glist;
2224
static int glistlen = 0;
2225
static int glisttotlen = 0;
2226
 
2227
/* If the completer trees ENT1 and ENT2 are equal, return 1.  */
2228
 
2229
static int
2230
completer_entries_eq (ent1, ent2)
2231
     struct completer_entry *ent1, *ent2;
2232
{
2233
  while (ent1 != NULL && ent2 != NULL)
2234
    {
2235
      if (ent1->name->num != ent2->name->num
2236
          || ent1->bits != ent2->bits
2237
          || ent1->mask != ent2->mask
2238
          || ent1->is_terminal != ent2->is_terminal
2239
          || ent1->dependencies != ent2->dependencies
2240
          || ent1->order != ent2->order)
2241
        return 0;
2242
 
2243
      if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2244
        return 0;
2245
 
2246
      ent1 = ent1->alternative;
2247
      ent2 = ent2->alternative;
2248
    }
2249
 
2250
  return ent1 == ent2;
2251
}
2252
 
2253
/* Insert ENT into the global list of completers and return it.  If an
2254
   equivalent entry (according to completer_entries_eq) already exists,
2255
   it is returned instead.  */
2256
static struct completer_entry *
2257
insert_gclist (struct completer_entry *ent)
2258
{
2259
  if (ent != NULL)
2260
    {
2261
      int i;
2262
      int x;
2263
      int start = 0, end;
2264
 
2265
      ent->addl_entries = insert_gclist (ent->addl_entries);
2266
      ent->alternative = insert_gclist (ent->alternative);
2267
 
2268
      i = glistlen / 2;
2269
      end = glistlen;
2270
 
2271
      if (glisttotlen == glistlen)
2272
        {
2273
          glisttotlen += 20;
2274
          glist = (struct completer_entry **)
2275
            xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2276
        }
2277
 
2278
      if (glistlen == 0)
2279
        {
2280
          glist[0] = ent;
2281
          glistlen = 1;
2282
          return ent;
2283
        }
2284
 
2285
      if (ent->name->num < glist[0]->name->num)
2286
        i = 0;
2287
      else if (ent->name->num > glist[end - 1]->name->num)
2288
        i = end;
2289
      else
2290
        {
2291
          int c;
2292
 
2293
          while (1)
2294
            {
2295
              i = (start + end) / 2;
2296
              c = ent->name->num - glist[i]->name->num;
2297
 
2298
              if (c < 0)
2299
                end = i - 1;
2300
              else if (c == 0)
2301
                {
2302
                  while (i > 0
2303
                         && ent->name->num == glist[i - 1]->name->num)
2304
                    i--;
2305
 
2306
                  break;
2307
                }
2308
              else
2309
                start = i + 1;
2310
 
2311
              if (start > end)
2312
                break;
2313
            }
2314
 
2315
          if (c == 0)
2316
            {
2317
              while (i < glistlen)
2318
                {
2319
                  if (ent->name->num != glist[i]->name->num)
2320
                    break;
2321
 
2322
                  if (completer_entries_eq (ent, glist[i]))
2323
                    return glist[i];
2324
 
2325
                  i++;
2326
                }
2327
            }
2328
        }
2329
 
2330
      for (; i > 0 && i < glistlen; i--)
2331
        if (ent->name->num >= glist[i - 1]->name->num)
2332
          break;
2333
 
2334
      for (; i < glistlen; i++)
2335
        if (ent->name->num < glist[i]->name->num)
2336
          break;
2337
 
2338
      for (x = glistlen - 1; x >= i; x--)
2339
        glist[x + 1] = glist[x];
2340
 
2341
      glist[i] = ent;
2342
      glistlen++;
2343
    }
2344
  return ent;
2345
}
2346
 
2347
static int
2348
get_prefix_len (name)
2349
     const char *name;
2350
{
2351
  char *c;
2352
 
2353
  if (name[0] == '\0')
2354
    return 0;
2355
 
2356
  c = strchr (name, '.');
2357
  if (c != NULL)
2358
    return c - name;
2359
  else
2360
    return strlen (name);
2361
}
2362
 
2363
static void
2364
compute_completer_bits (ment, ent)
2365
     struct main_entry *ment;
2366
     struct completer_entry *ent;
2367
{
2368
  while (ent != NULL)
2369
    {
2370
      compute_completer_bits (ment, ent->addl_entries);
2371
 
2372
      if (ent->is_terminal)
2373
        {
2374
          ia64_insn mask = 0;
2375
          ia64_insn our_bits = ent->bits;
2376
          struct completer_entry *p = ent->parent;
2377
          ia64_insn p_bits;
2378
          int x;
2379
 
2380
          while (p != NULL && ! p->is_terminal)
2381
            p = p->parent;
2382
 
2383
          if (p != NULL)
2384
            p_bits = p->bits;
2385
          else
2386
            p_bits = ment->opcode->opcode;
2387
 
2388
          for (x = 0; x < 64; x++)
2389
            {
2390
              ia64_insn m = ((ia64_insn) 1) << x;
2391
 
2392
              if ((p_bits & m) != (our_bits & m))
2393
                mask |= m;
2394
              else
2395
                our_bits &= ~m;
2396
            }
2397
          ent->bits = our_bits;
2398
          ent->mask = mask;
2399
        }
2400
      else
2401
        {
2402
          ent->bits = 0;
2403
          ent->mask = 0;
2404
        }
2405
 
2406
      ent = ent->alternative;
2407
    }
2408
}
2409
 
2410
/* Find identical completer trees that are used in different
2411
   instructions and collapse their entries.  */
2412
static void
2413
collapse_redundant_completers (void)
2414
{
2415
  struct main_entry *ptr;
2416
  int x;
2417
 
2418
  for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2419
    {
2420
      if (ptr->completers == NULL)
2421
        abort ();
2422
 
2423
      compute_completer_bits (ptr, ptr->completers);
2424
      ptr->completers = insert_gclist (ptr->completers);
2425
    }
2426
 
2427
  /* The table has been finalized, now number the indexes.  */
2428
  for (x = 0; x < glistlen; x++)
2429
    glist[x]->num = x;
2430
}
2431
 
2432
 
2433
/* Attach two lists of dependencies to each opcode.
2434
   1) all resources which, when already marked in use, conflict with this
2435
   opcode (chks)
2436
   2) all resources which must be marked in use when this opcode is used
2437
   (regs).  */
2438
static int
2439
insert_opcode_dependencies (opc, cmp)
2440
     struct ia64_opcode *opc;
2441
     struct completer_entry *cmp ATTRIBUTE_UNUSED;
2442
{
2443
  /* Note all resources which point to this opcode.  rfi has the most chks
2444
     (79) and cmpxchng has the most regs (54) so 100 here should be enough.  */
2445
  int i;
2446
  int nregs = 0;
2447
  unsigned short regs[256];
2448
  int nchks = 0;
2449
  unsigned short chks[256];
2450
  /* Flag insns for which no class matched; there should be none.  */
2451
  int no_class_found = 1;
2452
 
2453
  for (i = 0; i < rdepslen; i++)
2454
    {
2455
      struct rdep *rs = rdeps[i];
2456
      int j;
2457
 
2458
      if (strcmp (opc->name, "cmp.eq.and") == 0
2459
          && CONST_STRNEQ (rs->name, "PR%")
2460
          && rs->mode == 1)
2461
        no_class_found = 99;
2462
 
2463
      for (j=0; j < rs->nregs;j++)
2464
        {
2465
          int ic_note = 0;
2466
 
2467
          if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2468
            {
2469
              /* We can ignore ic_note 11 for non PR resources.  */
2470
              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2471
                ic_note = 0;
2472
 
2473
              if (ic_note != 0 && rs->regnotes[j] != 0
2474
                  && ic_note != rs->regnotes[j]
2475
                  && !(ic_note == 11 && rs->regnotes[j] == 1))
2476
                warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2477
                      ic_note, opc->name, ics[rs->regs[j]]->name,
2478
                      rs->name, rs->regnotes[j]);
2479
              /* Instruction class notes override resource notes.
2480
                 So far, only note 11 applies to an IC instead of a resource,
2481
                 and note 11 implies note 1.  */
2482
              if (ic_note)
2483
                regs[nregs++] = RDEP(ic_note, i);
2484
              else
2485
                regs[nregs++] = RDEP(rs->regnotes[j], i);
2486
              no_class_found = 0;
2487
              ++rs->total_regs;
2488
            }
2489
        }
2490
 
2491
      for (j = 0; j < rs->nchks; j++)
2492
        {
2493
          int ic_note = 0;
2494
 
2495
          if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2496
            {
2497
              /* We can ignore ic_note 11 for non PR resources.  */
2498
              if (ic_note == 11 && ! CONST_STRNEQ (rs->name, "PR"))
2499
                ic_note = 0;
2500
 
2501
              if (ic_note != 0 && rs->chknotes[j] != 0
2502
                  && ic_note != rs->chknotes[j]
2503
                  && !(ic_note == 11 && rs->chknotes[j] == 1))
2504
                warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"),
2505
                      ic_note, opc->name, ics[rs->chks[j]]->name,
2506
                      rs->name, rs->chknotes[j]);
2507
              if (ic_note)
2508
                chks[nchks++] = RDEP(ic_note, i);
2509
              else
2510
                chks[nchks++] = RDEP(rs->chknotes[j], i);
2511
              no_class_found = 0;
2512
              ++rs->total_chks;
2513
            }
2514
        }
2515
    }
2516
 
2517
  if (no_class_found)
2518
    warn (_("opcode %s has no class (ops %d %d %d)\n"),
2519
          opc->name,
2520
          opc->operands[0], opc->operands[1], opc->operands[2]);
2521
 
2522
  return insert_dependencies (nchks, chks, nregs, regs);
2523
}
2524
 
2525
static void
2526
insert_completer_entry (opc, tabent, order)
2527
     struct ia64_opcode *opc;
2528
     struct main_entry *tabent;
2529
     int order;
2530
{
2531
  struct completer_entry **ptr = &tabent->completers;
2532
  struct completer_entry *parent = NULL;
2533
  char pcopy[129], *prefix;
2534
  int at_end = 0;
2535
 
2536
  if (strlen (opc->name) > 128)
2537
    abort ();
2538
 
2539
  strcpy (pcopy, opc->name);
2540
  prefix = pcopy + get_prefix_len (pcopy);
2541
 
2542
  if (prefix[0] != '\0')
2543
    prefix++;
2544
 
2545
  while (! at_end)
2546
    {
2547
      int need_new_ent = 1;
2548
      int plen = get_prefix_len (prefix);
2549
      struct string_entry *sent;
2550
 
2551
      at_end = (prefix[plen] == '\0');
2552
      prefix[plen] = '\0';
2553
      sent = insert_string (prefix);
2554
 
2555
      while (*ptr != NULL)
2556
        {
2557
          int cmpres = sent->num - (*ptr)->name->num;
2558
 
2559
          if (cmpres == 0)
2560
            {
2561
              need_new_ent = 0;
2562
              break;
2563
            }
2564
          else
2565
            ptr = &((*ptr)->alternative);
2566
        }
2567
 
2568
      if (need_new_ent)
2569
        {
2570
          struct completer_entry *nent = tmalloc (struct completer_entry);
2571
 
2572
          nent->name = sent;
2573
          nent->parent = parent;
2574
          nent->addl_entries = NULL;
2575
          nent->alternative = *ptr;
2576
          *ptr = nent;
2577
          nent->is_terminal = 0;
2578
          nent->dependencies = -1;
2579
        }
2580
 
2581
      if (! at_end)
2582
        {
2583
          parent = *ptr;
2584
          ptr = &((*ptr)->addl_entries);
2585
          prefix += plen + 1;
2586
        }
2587
    }
2588
 
2589
  if ((*ptr)->is_terminal)
2590
    abort ();
2591
 
2592
  (*ptr)->is_terminal = 1;
2593
  (*ptr)->mask = (ia64_insn)-1;
2594
  (*ptr)->bits = opc->opcode;
2595
  (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2596
  (*ptr)->order = order;
2597
}
2598
 
2599
static void
2600
print_completer_entry (ent)
2601
     struct completer_entry *ent;
2602
{
2603
  int moffset = 0;
2604
  ia64_insn mask = ent->mask, bits = ent->bits;
2605
 
2606
  if (mask != 0)
2607
    {
2608
      while (! (mask & 1))
2609
        {
2610
          moffset++;
2611
          mask = mask >> 1;
2612
          bits = bits >> 1;
2613
        }
2614
 
2615
      if (bits & 0xffffffff00000000LL)
2616
        abort ();
2617
    }
2618
 
2619
  printf ("  { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2620
          (int)bits,
2621
          (int)mask,
2622
          ent->name->num,
2623
          ent->alternative != NULL ? ent->alternative->num : -1,
2624
          ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2625
          moffset,
2626
          ent->is_terminal ? 1 : 0,
2627
          ent->dependencies);
2628
}
2629
 
2630
static void
2631
print_completer_table ()
2632
{
2633
  int x;
2634
 
2635
  printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2636
  for (x = 0; x < glistlen; x++)
2637
    print_completer_entry (glist[x]);
2638
  printf ("};\n\n");
2639
}
2640
 
2641
static int
2642
opcodes_eq (opc1, opc2)
2643
     struct ia64_opcode *opc1;
2644
     struct ia64_opcode *opc2;
2645
{
2646
  int x;
2647
  int plen1, plen2;
2648
 
2649
  if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2650
      || (opc1->num_outputs != opc2->num_outputs)
2651
      || (opc1->flags != opc2->flags))
2652
    return 0;
2653
 
2654
  for (x = 0; x < 5; x++)
2655
    if (opc1->operands[x] != opc2->operands[x])
2656
      return 0;
2657
 
2658
  plen1 = get_prefix_len (opc1->name);
2659
  plen2 = get_prefix_len (opc2->name);
2660
 
2661
  if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2662
    return 1;
2663
 
2664
  return 0;
2665
}
2666
 
2667
static void
2668
add_opcode_entry (opc)
2669
     struct ia64_opcode *opc;
2670
{
2671
  struct main_entry **place;
2672
  struct string_entry *name;
2673
  char prefix[129];
2674
  int found_it = 0;
2675
 
2676
  if (strlen (opc->name) > 128)
2677
    abort ();
2678
 
2679
  place = &maintable;
2680
  strcpy (prefix, opc->name);
2681
  prefix[get_prefix_len (prefix)] = '\0';
2682
  name = insert_string (prefix);
2683
 
2684
  /* Walk the list of opcode table entries.  If it's a new
2685
     instruction, allocate and fill in a new entry.  Note
2686
     the main table is alphabetical by opcode name.  */
2687
 
2688
  while (*place != NULL)
2689
    {
2690
      if ((*place)->name->num == name->num
2691
          && opcodes_eq ((*place)->opcode, opc))
2692
        {
2693
          found_it = 1;
2694
          break;
2695
        }
2696
      if ((*place)->name->num > name->num)
2697
        break;
2698
 
2699
      place = &((*place)->next);
2700
    }
2701
  if (! found_it)
2702
    {
2703
      struct main_entry *nent = tmalloc (struct main_entry);
2704
 
2705
      nent->name = name;
2706
      nent->opcode = opc;
2707
      nent->next = *place;
2708
      nent->completers = 0;
2709
      *place = nent;
2710
 
2711
      if (otlen == ottotlen)
2712
        {
2713
          ottotlen += 20;
2714
          ordered_table = (struct main_entry **)
2715
            xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2716
        }
2717
      ordered_table[otlen++] = nent;
2718
    }
2719
 
2720
  insert_completer_entry (opc, *place, opcode_count++);
2721
}
2722
 
2723
static void
2724
print_main_table (void)
2725
{
2726
  struct main_entry *ptr = maintable;
2727
  int index = 0;
2728
 
2729
  printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2730
  while (ptr != NULL)
2731
    {
2732
      printf ("  { %d, %d, %d, 0x",
2733
              ptr->name->num,
2734
              ptr->opcode->type,
2735
              ptr->opcode->num_outputs);
2736
      opcode_fprintf_vma (stdout, ptr->opcode->opcode);
2737
      printf ("ull, 0x");
2738
      opcode_fprintf_vma (stdout, ptr->opcode->mask);
2739
      printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2740
              ptr->opcode->operands[0],
2741
              ptr->opcode->operands[1],
2742
              ptr->opcode->operands[2],
2743
              ptr->opcode->operands[3],
2744
              ptr->opcode->operands[4],
2745
              ptr->opcode->flags,
2746
              ptr->completers->num);
2747
 
2748
      ptr->main_index = index++;
2749
 
2750
      ptr = ptr->next;
2751
    }
2752
  printf ("};\n\n");
2753
}
2754
 
2755
static void
2756
shrink (table)
2757
     struct ia64_opcode *table;
2758
{
2759
  int curr_opcode;
2760
 
2761
  for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2762
    {
2763
      add_opcode_entry (table + curr_opcode);
2764
      if (table[curr_opcode].num_outputs == 2
2765
          && ((table[curr_opcode].operands[0] == IA64_OPND_P1
2766
               && table[curr_opcode].operands[1] == IA64_OPND_P2)
2767
              || (table[curr_opcode].operands[0] == IA64_OPND_P2
2768
                  && table[curr_opcode].operands[1] == IA64_OPND_P1)))
2769
        {
2770
          struct ia64_opcode *alias = tmalloc(struct ia64_opcode);
2771
          unsigned i;
2772
 
2773
          *alias = table[curr_opcode];
2774
          for (i = 2; i < NELEMS (alias->operands); ++i)
2775
            alias->operands[i - 1] = alias->operands[i];
2776
          alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL;
2777
          --alias->num_outputs;
2778
          alias->flags |= PSEUDO;
2779
          add_opcode_entry (alias);
2780
        }
2781
    }
2782
}
2783
 
2784
 
2785
/* Program options.  */
2786
#define OPTION_SRCDIR   200
2787
 
2788
struct option long_options[] =
2789
{
2790
  {"srcdir",  required_argument, NULL, OPTION_SRCDIR},
2791
  {"debug",   no_argument,       NULL, 'd'},
2792
  {"version", no_argument,       NULL, 'V'},
2793
  {"help",    no_argument,       NULL, 'h'},
2794
  {0,         no_argument,       NULL, 0}
2795
};
2796
 
2797
static void
2798
print_version (void)
2799
{
2800
  printf ("%s: version 1.0\n", program_name);
2801
  xexit (0);
2802
}
2803
 
2804
static void
2805
usage (FILE * stream, int status)
2806
{
2807
  fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
2808
           program_name);
2809
  xexit (status);
2810
}
2811
 
2812
int
2813
main (int argc, char **argv)
2814
{
2815
  extern int chdir (char *);
2816
  char *srcdir = NULL;
2817
  int c;
2818
 
2819
  program_name = *argv;
2820
  xmalloc_set_program_name (program_name);
2821
 
2822
  while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
2823
    switch (c)
2824
      {
2825
      case OPTION_SRCDIR:
2826
        srcdir = optarg;
2827
        break;
2828
      case 'V':
2829
      case 'v':
2830
        print_version ();
2831
        break;
2832
      case 'd':
2833
        debug = 1;
2834
        break;
2835
      case 'h':
2836
      case '?':
2837
        usage (stderr, 0);
2838
      default:
2839
      case 0:
2840
        break;
2841
      }
2842
 
2843
  if (optind != argc)
2844
    usage (stdout, 1);
2845
 
2846
  if (srcdir != NULL)
2847
    if (chdir (srcdir) != 0)
2848
      fail (_("unable to change directory to \"%s\", errno = %s\n"),
2849
            srcdir, strerror (errno));
2850
 
2851
  load_insn_classes ();
2852
  load_dependencies ();
2853
 
2854
  shrink (ia64_opcodes_a);
2855
  shrink (ia64_opcodes_b);
2856
  shrink (ia64_opcodes_f);
2857
  shrink (ia64_opcodes_i);
2858
  shrink (ia64_opcodes_m);
2859
  shrink (ia64_opcodes_x);
2860
  shrink (ia64_opcodes_d);
2861
 
2862
  collapse_redundant_completers ();
2863
 
2864
  printf ("/* This file is automatically generated by ia64-gen.  Do not edit!  */\n");
2865
  printf ("/* Copyright 2007  Free Software Foundation, Inc.\n\
2866
\n\
2867
   This file is part of the GNU opcodes library.\n\
2868
\n\
2869
   This library is free software; you can redistribute it and/or modify\n\
2870
   it under the terms of the GNU General Public License as published by\n\
2871
   the Free Software Foundation; either version 3, or (at your option)\n\
2872
   any later version.\n\
2873
\n\
2874
   It is distributed in the hope that it will be useful, but WITHOUT\n\
2875
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
2876
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
2877
   License for more details.\n\
2878
\n\
2879
   You should have received a copy of the GNU General Public License\n\
2880
   along with this program; see the file COPYING.  If not, write to the\n\
2881
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\
2882
   02110-1301, USA.  */\n");
2883
 
2884
  print_string_table ();
2885
  print_dependency_table ();
2886
  print_completer_table ();
2887
  print_main_table ();
2888
 
2889
  generate_disassembler ();
2890
 
2891
  exit (0);
2892
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.