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

Subversion Repositories openrisc_me

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

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

powered by: WebSVN 2.1.0

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