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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [ia64-gen.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* ia64-gen.c -- Generate a shrunk set of opcode tables
2
   Copyright 1999, 2000 Free Software Foundation, Inc.
3
   Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
4
 
5
   This file is part of GDB, GAS, and the GNU binutils.
6
 
7
   GDB, GAS, and the GNU binutils are free software; you can redistribute
8
   them and/or modify them under the terms of the GNU General Public
9
   License as published by the Free Software Foundation; either version
10
   2, or (at your option) any later version.
11
 
12
   GDB, GAS, and the GNU binutils are distributed in the hope that they
13
   will be useful, but WITHOUT ANY WARRANTY; without even the implied
14
   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15
   the GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this file; see the file COPYING.  If not, write to the
19
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20
   02111-1307, USA.  */
21
 
22
/* While the ia64-opc-* set of opcode tables are easy to maintain,
23
   they waste a tremendous amount of space.  ia64-gen rearranges the
24
   instructions into a directed acyclic graph (DAG) of instruction opcodes and
25
   their possible completers, as well as compacting the set of strings used.
26
 
27
   The disassembler table consists of a state machine that does
28
   branching based on the bits of the opcode being disassembled.  The
29
   state encodings have been chosen to minimize the amount of space
30
   required.
31
 
32
   The resource table is constructed based on some text dependency tables,
33
   which are also easier to maintain than the final representation.
34
 
35
*/
36
 
37
#include <stdio.h>
38
#include <ctype.h>
39
 
40
#include "ansidecl.h"
41
#include "libiberty.h"
42
#include "sysdep.h"
43
#include "ia64-opc.h"
44
#include "ia64-opc-a.c"
45
#include "ia64-opc-i.c"
46
#include "ia64-opc-m.c"
47
#include "ia64-opc-b.c"
48
#include "ia64-opc-f.c"
49
#include "ia64-opc-x.c"
50
#include "ia64-opc-d.c"
51
 
52
int debug = 0;
53
 
54
#define tmalloc(X) (X *) xmalloc (sizeof (X))
55
 
56
/* The main opcode table entry.  Each entry is a unique combination of
57
   name and flags (no two entries in the table compare as being equal
58
   via opcodes_eq). */
59
struct main_entry
60
{
61
  /* The base name of this opcode.  The names of its completers are
62
     appended to it to generate the full instruction name. */
63
  struct string_entry *name;
64
  /* The base opcode entry.  Which one to use is a fairly arbitrary choice;
65
     it uses the first one passed to add_opcode_entry. */
66
  struct ia64_opcode *opcode;
67
  /* The list of completers that can be applied to this opcode. */
68
  struct completer_entry *completers;
69
  /* Next entry in the chain. */
70
  struct main_entry *next;
71
  /* Index in the  main table. */
72
  int main_index;
73
} *maintable, **ordered_table;
74
int otlen = 0;
75
int ottotlen = 0;
76
int opcode_count = 0;
77
 
78
/* The set of possible completers for an opcode. */
79
struct completer_entry
80
{
81
  /* This entry's index in the ia64_completer_table[] array. */
82
  int num;
83
 
84
  /* The name of the completer. */
85
  struct string_entry *name;
86
 
87
  /* This entry's parent. */
88
  struct completer_entry *parent;
89
 
90
  /* Set if this is a terminal completer (occurs at the end of an
91
     opcode). */
92
  int is_terminal;
93
 
94
  /* An alternative completer. */
95
  struct completer_entry *alternative;
96
 
97
  /* Additional completers that can be appended to this one.  */
98
  struct completer_entry *addl_entries;
99
 
100
  /* Before compute_completer_bits () is invoked, this contains the actual
101
     instruction opcode for this combination of opcode and completers.
102
     Afterwards, it contains those bits that are different from its
103
     parent opcode. */
104
  ia64_insn bits;
105
 
106
  /* Bits set to 1 correspond to those bits in this completer's opcode
107
     that are different from its parent completer's opcode (or from
108
     the base opcode if the entry is the root of the opcode's completer
109
     list).  This field is filled in by compute_completer_bits (). */
110
  ia64_insn mask;
111
 
112
  /* Index into the opcode dependency list, or -1 if none. */
113
  int dependencies;
114
 
115
  /* Remember the order encountered in the opcode tables.  */
116
  int order;
117
};
118
 
119
/* One entry in the disassembler name table. */
120
struct disent
121
{
122
  /* The index into the ia64_name_dis array for this entry. */
123
  int ournum;
124
 
125
  /* The index into the main_table[] array. */
126
  int insn;
127
 
128
  /* The disassmbly priority of this entry. */
129
  int priority;
130
 
131
  /* The completer_index value for this entry. */
132
  int completer_index;
133
 
134
  /* How many other entries share this decode. */
135
  int nextcnt;
136
 
137
  /* The next entry sharing the same decode. */
138
  struct disent *nexte;
139
 
140
  /* The next entry in the name list. */
141
  struct disent *next_ent;
142
} *disinsntable = NULL;
143
 
144
/* A state machine that will eventually be used to generate the
145
   disassembler table. */
146
struct bittree
147
{
148
  struct disent *disent;
149
  struct bittree *bits[3]; /* 0, 1, and X (don't care) */
150
  int bits_to_skip;
151
  int skip_flag;
152
} *bittree;
153
 
154
/* The string table contains all opcodes and completers sorted in
155
   alphabetical order.  */
156
 
157
/* One entry in the string table. */
158
struct string_entry
159
{
160
  /* The index in the ia64_strings[] array for this entry. */
161
  int num;
162
  /* And the string. */
163
  char *s;
164
} **string_table = NULL;
165
int strtablen = 0;
166
int strtabtotlen = 0;
167
 
168
 
169
/* resource dependency entries */
170
struct rdep
171
{
172
  char *name;                       /* resource name */
173
  unsigned
174
    mode:2,                         /* RAW, WAW, or WAR */
175
    semantics:3;                    /* dependency semantics */
176
  char *extra;                      /* additional semantics info */
177
  int nchks;
178
  int total_chks;                   /* total #of terminal insns */
179
  int *chks;                        /* insn classes which read (RAW), write
180
                                       (WAW), or write (WAR) this rsrc */
181
  int *chknotes;                    /* dependency notes for each class */
182
  int nregs;
183
  int total_regs;                   /* total #of terminal insns */
184
  int *regs;                        /* insn class which write (RAW), write2
185
                                       (WAW), or read (WAR) this rsrc */
186
  int *regnotes;                    /* dependency notes for each class */
187
 
188
  int waw_special;                  /* special WAW dependency note */
189
} **rdeps = NULL;
190
 
191
static int rdepslen = 0;
192
static int rdepstotlen = 0;
193
 
194
/* array of all instruction classes */
195
struct iclass
196
{
197
  char *name;                       /* instruction class name */
198
  int is_class;                     /* is a class, not a terminal */
199
  int nsubs;
200
  int *subs;                        /* other classes within this class */
201
  int nxsubs;
202
  int xsubs[4];                     /* exclusions */
203
  char *comment;                    /* optional comment */
204
  int note;                         /* optional note */
205
  int terminal_resolved;            /* did we match this with anything? */
206
  int orphan;                       /* detect class orphans */
207
} **ics = NULL;
208
 
209
static int iclen = 0;
210
static int ictotlen = 0;
211
 
212
/* an opcode dependency (chk/reg pair of dependency lists) */
213
struct opdep
214
{
215
  int chk;                          /* index into dlists */
216
  int reg;                          /* index into dlists */
217
} **opdeps;
218
 
219
static int opdeplen = 0;
220
static int opdeptotlen = 0;
221
 
222
/* a generic list of dependencies w/notes encoded.  these may be shared. */
223
struct deplist
224
{
225
  int len;
226
  unsigned short *deps;
227
} **dlists;
228
 
229
static int dlistlen = 0;
230
static int dlisttotlen = 0;
231
 
232
/* add NAME to the resource table, where TYPE is RAW or WAW */
233
static struct rdep *
234
insert_resource (const char *name, enum ia64_dependency_mode type)
235
{
236
  if (rdepslen == rdepstotlen)
237
    {
238
      rdepstotlen += 20;
239
      rdeps = (struct rdep **)
240
        xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen);
241
    }
242
  rdeps[rdepslen] = tmalloc(struct rdep);
243
  memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep));
244
  rdeps[rdepslen]->name = xstrdup (name);
245
  rdeps[rdepslen]->mode = type;
246
  rdeps[rdepslen]->waw_special = 0;
247
 
248
  return rdeps[rdepslen++];
249
}
250
 
251
/* are the lists of dependency indexes equivalent? */
252
static int
253
deplist_equals (struct deplist *d1, struct deplist *d2)
254
{
255
  int i;
256
 
257
  if (d1->len != d2->len)
258
    return 0;
259
 
260
  for (i=0;i < d1->len;i++)
261
    {
262
      if (d1->deps[i] != d2->deps[i])
263
        return 0;
264
    }
265
 
266
  return 1;
267
}
268
 
269
/* add the list of dependencies to the list of dependency lists */
270
static short
271
insert_deplist(int count, unsigned short *deps)
272
{
273
  /* sort the list, then see if an equivalent list exists already.
274
     this results in a much smaller set of dependency lists
275
   */
276
  struct deplist *list;
277
  char set[0x10000];
278
  int i;
279
 
280
  memset ((void *)set, 0, sizeof(set));
281
  for (i=0;i < count;i++)
282
    set[deps[i]] = 1;
283
  count = 0;
284
  for (i=0;i < (int)sizeof(set);i++)
285
    if (set[i])
286
      ++count;
287
 
288
  list = tmalloc(struct deplist);
289
  list->len = count;
290
  list->deps = (unsigned short *)malloc (sizeof(unsigned short) * count);
291
  for (i=0, count=0;i < (int)sizeof(set);i++)
292
    {
293
      if (set[i])
294
        {
295
          list->deps[count++] = i;
296
        }
297
    }
298
 
299
  /* does this list exist already? */
300
  for (i=0;i < dlistlen;i++)
301
    {
302
      if (deplist_equals (list, dlists[i]))
303
        {
304
          free (list->deps);
305
          free (list);
306
          return i;
307
        }
308
    }
309
 
310
  if (dlistlen == dlisttotlen)
311
    {
312
      dlisttotlen += 20;
313
      dlists = (struct deplist **)
314
        xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen);
315
    }
316
  dlists[dlistlen] = list;
317
 
318
  return dlistlen++;
319
}
320
 
321
/* add the given pair of dependency lists to the opcode dependency list */
322
static short
323
insert_dependencies (int nchks, unsigned short *chks,
324
                     int nregs, unsigned short *regs)
325
{
326
  struct opdep *pair;
327
  int i;
328
  int regind = -1;
329
  int chkind = -1;
330
 
331
  if (nregs > 0)
332
    regind = insert_deplist (nregs, regs);
333
  if (nchks > 0)
334
    chkind = insert_deplist (nchks, chks);
335
 
336
  for (i=0;i < opdeplen;i++)
337
    {
338
      if (opdeps[i]->chk == chkind
339
          && opdeps[i]->reg == regind)
340
        return i;
341
    }
342
  pair = tmalloc(struct opdep);
343
  pair->chk = chkind;
344
  pair->reg = regind;
345
 
346
  if (opdeplen == opdeptotlen)
347
    {
348
      opdeptotlen += 20;
349
      opdeps = (struct opdep **)
350
        xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen);
351
    }
352
  opdeps[opdeplen] = pair;
353
 
354
  return opdeplen++;
355
}
356
 
357
static void
358
mark_used (struct iclass *ic, int clear_terminals)
359
{
360
  int i;
361
 
362
  ic->orphan = 0;
363
  if (clear_terminals)
364
    ic->terminal_resolved = 1;
365
 
366
  for (i=0;i < ic->nsubs;i++)
367
    {
368
      mark_used (ics[ic->subs[i]], clear_terminals);
369
    }
370
  for (i=0;i < ic->nxsubs;i++)
371
    {
372
      mark_used (ics[ic->xsubs[i]], clear_terminals);
373
    }
374
}
375
 
376
/* look up an instruction class; if CREATE make a new one if none found;
377
   returns the index into the insn class array */
378
static int
379
fetch_insn_class(const char *full_name, int create)
380
{
381
  char *name;
382
  char *notestr;
383
  char *xsect;
384
  char *comment;
385
  int i, note = 0;
386
  int ind;
387
  int is_class = 0;
388
 
389
  if (strncmp (full_name, "IC:", 3) == 0)
390
    {
391
      name = xstrdup (full_name + 3);
392
      is_class = 1;
393
    }
394
  else
395
    name = xstrdup (full_name);
396
 
397
  if ((xsect = strchr(name, '\\')) != NULL)
398
    is_class = 1;
399
  if ((comment = strchr(name, '[')) != NULL)
400
    is_class = 1;
401
  if ((notestr = strchr(name, '+')) != NULL)
402
    is_class = 1;
403
 
404
  /* If it is a composite class, then ignore comments and notes that come after
405
     the '\\', since they don't apply to the part we are decoding now.  */
406
  if (xsect)
407
    {
408
      if (comment > xsect)
409
        comment = 0;
410
      if (notestr > xsect)
411
        notestr = 0;
412
    }
413
 
414
  if (notestr)
415
    {
416
      char *nextnotestr;
417
      note = atoi (notestr + 1);
418
      if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
419
        {
420
          if (strcmp (notestr, "+1+13") == 0)
421
            note = 13;
422
          else if (!xsect || nextnotestr < xsect)
423
            fprintf (stderr, "Warning: multiple note %s not handled\n",
424
                     notestr);
425
        }
426
    }
427
 
428
  /* If it's a composite class, leave the notes and comments in place so that
429
     we have a unique name for the composite class.  Otherwise, we remove
430
     them.  */
431
  if (!xsect)
432
    {
433
      if (notestr)
434
        *notestr = 0;
435
      if (comment)
436
        *comment = 0;
437
    }
438
 
439
  for (i=0;i < iclen;i++)
440
    if (strcmp(name, ics[i]->name) == 0
441
        && ((comment == NULL && ics[i]->comment == NULL)
442
            || (comment != NULL && ics[i]->comment != NULL
443
                && strncmp (ics[i]->comment, comment,
444
                            strlen (ics[i]->comment)) == 0))
445
        && note == ics[i]->note)
446
      return i;
447
 
448
  if (!create)
449
    return -1;
450
 
451
  /* doesn't exist, so make a new one */
452
  if (iclen == ictotlen)
453
    {
454
      ictotlen += 20;
455
      ics = (struct iclass **)
456
        xrealloc(ics, (ictotlen)*sizeof(struct iclass *));
457
    }
458
  ind = iclen++;
459
  ics[ind] = tmalloc(struct iclass);
460
  memset((void *)ics[ind], 0, sizeof(struct iclass));
461
  ics[ind]->name = xstrdup(name);
462
  ics[ind]->is_class = is_class;
463
  ics[ind]->orphan = 1;
464
 
465
  if (comment)
466
    {
467
      ics[ind]->comment = xstrdup (comment + 1);
468
      ics[ind]->comment[strlen(ics[ind]->comment)-1] = 0;
469
    }
470
  if (notestr)
471
    ics[ind]->note = note;
472
 
473
  /* if it's a composite class, there's a comment or note, look for an
474
     existing class or terminal with the same name. */
475
  if ((xsect || comment || notestr) && is_class)
476
    {
477
      /* First, populate with the class we're based on.  */
478
      char *subname = name;
479
      if (xsect)
480
        *xsect = 0;
481
      else if (comment)
482
        *comment = 0;
483
      else if (notestr)
484
        *notestr = 0;
485
      ics[ind]->nsubs = 1;
486
      ics[ind]->subs = tmalloc(int);
487
      ics[ind]->subs[0] = fetch_insn_class (subname, 1);;
488
    }
489
 
490
  while (xsect)
491
    {
492
      char *subname = xsect + 1;
493
      xsect = strchr (subname, '\\');
494
      if (xsect)
495
        *xsect = 0;
496
      ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1);
497
      ics[ind]->nxsubs++;
498
    }
499
  free (name);
500
 
501
  return ind;
502
}
503
 
504
/* for sorting a class's sub-class list only; make sure classes appear before
505
   terminals  */
506
static int
507
sub_compare (const void *e1, const void *e2)
508
{
509
  struct iclass *ic1 = ics[*(int *)e1];
510
  struct iclass *ic2 = ics[*(int *)e2];
511
 
512
  if (ic1->is_class)
513
    {
514
      if (!ic2->is_class)
515
        return -1;
516
    }
517
  else if (ic2->is_class)
518
    return 1;
519
 
520
  return strcmp (ic1->name, ic2->name);
521
}
522
 
523
static void
524
load_insn_classes()
525
{
526
  FILE *fp = fopen("ia64-ic.tbl", "r");
527
  char buf[2048];
528
 
529
  if (fp == NULL){
530
    fprintf (stderr, "Can't find ia64-ic.tbl for reading\n");
531
    exit(1);
532
  }
533
 
534
  /* discard first line */
535
  fgets (buf, sizeof(buf), fp);
536
 
537
  while (!feof(fp))
538
    {
539
      int iclass;
540
      char *name;
541
      char *tmp;
542
 
543
      if (fgets (buf, sizeof(buf), fp) == NULL)
544
        break;
545
 
546
      while (isspace(buf[strlen(buf)-1]))
547
        buf[strlen(buf)-1] = '\0';
548
 
549
      name = tmp = buf;
550
      while (*tmp != ';')
551
        {
552
          ++tmp;
553
          if (tmp == buf + sizeof(buf))
554
            abort ();
555
        }
556
      *tmp++ = '\0';
557
 
558
      iclass = fetch_insn_class(name, 1);
559
      ics[iclass]->is_class = 1;
560
 
561
      if (strcmp (name, "none") == 0)
562
        {
563
          ics[iclass]->is_class = 0;
564
          ics[iclass]->terminal_resolved = 1;
565
          continue;
566
        }
567
 
568
      /* for this class, record all sub-classes */
569
      while (*tmp)
570
        {
571
          char *subname;
572
          int sub;
573
 
574
          while (*tmp && isspace(*tmp))
575
            {
576
              ++tmp;
577
              if (tmp == buf + sizeof(buf))
578
                abort();
579
            }
580
          subname = tmp;
581
          while (*tmp && *tmp != ',')
582
            {
583
              ++tmp;
584
              if (tmp == buf + sizeof(buf))
585
                abort();
586
            }
587
          if (*tmp == ',')
588
            *tmp++ = '\0';
589
 
590
          ics[iclass]->subs = (int *)
591
            xrealloc((void *)ics[iclass]->subs,
592
                     (ics[iclass]->nsubs+1)*sizeof(int));
593
 
594
          sub = fetch_insn_class(subname, 1);
595
          ics[iclass]->subs = (int *)
596
            xrealloc(ics[iclass]->subs, (ics[iclass]->nsubs+1)*sizeof(int));
597
          ics[iclass]->subs[ics[iclass]->nsubs++] = sub;
598
        }
599
      /* make sure classes come before terminals */
600
      qsort ((void *)ics[iclass]->subs,
601
             ics[iclass]->nsubs, sizeof(int), sub_compare);
602
    }
603
  fclose(fp);
604
 
605
  if (debug)
606
    {
607
      printf ("%d classes\n", iclen);
608
    }
609
}
610
 
611
/* extract the insn classes from the given line */
612
static void
613
parse_resource_users(ref, usersp, nusersp, notesp)
614
  char *ref;
615
  int **usersp;
616
  int *nusersp;
617
  int **notesp;
618
{
619
  int c;
620
  char *line = xstrdup (ref);
621
  char *tmp = line;
622
  int *users = *usersp;
623
  int count = *nusersp;
624
  int *notes = *notesp;
625
 
626
  c = *tmp;
627
  while (c != 0)
628
    {
629
      char *notestr;
630
      int note;
631
      char *xsect;
632
      int iclass;
633
      int create = 0;
634
      char *name;
635
 
636
      while (isspace(*tmp))
637
        ++tmp;
638
      name = tmp;
639
      while (*tmp && *tmp != ',')
640
        ++tmp;
641
      c = *tmp;
642
      *tmp++ = '\0';
643
 
644
      xsect = strchr(name, '\\');
645
      if ((notestr = strstr(name, "+")) != NULL)
646
        {
647
          char *nextnotestr;
648
          note = atoi (notestr + 1);
649
          if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
650
            {
651
              /* note 13 always implies note 1 */
652
              if (strcmp (notestr, "+1+13") == 0)
653
                note = 13;
654
              else if (!xsect || nextnotestr < xsect)
655
                fprintf (stderr, "Warning: multiple note %s not handled\n",
656
                         notestr);
657
            }
658
          if (!xsect)
659
            *notestr = '\0';
660
        }
661
      else
662
        note = 0;
663
 
664
      /* All classes are created when the insn class table is parsed;
665
         Individual instructions might not appear until the dependency tables
666
         are read.  Only create new classes if it's *not* an insn class,
667
         or if it's a composite class (which wouldn't necessarily be in the IC
668
         table).
669
      */
670
      if (strncmp(name, "IC:", 3) != 0 || xsect != NULL)
671
        create = 1;
672
 
673
      iclass = fetch_insn_class(name, create);
674
      if (iclass != -1)
675
        {
676
          users = (int *)
677
            xrealloc ((void *)users,(count+1)*sizeof(int));
678
          notes = (int *)
679
            xrealloc ((void *)notes,(count+1)*sizeof(int));
680
          notes[count] = note;
681
          users[count++] = iclass;
682
          mark_used (ics[iclass], 0);
683
        }
684
      else
685
        {
686
          if (debug)
687
            printf("Class %s not found\n", name);
688
        }
689
    }
690
  /* update the return values */
691
  *usersp = users;
692
  *nusersp = count;
693
  *notesp = notes;
694
 
695
  free (line);
696
}
697
 
698
static int
699
parse_semantics (char *sem)
700
{
701
  if (strcmp (sem, "none") == 0)
702
    return IA64_DVS_NONE;
703
  else if (strcmp (sem, "implied") == 0)
704
    return IA64_DVS_IMPLIED;
705
  else if (strcmp (sem, "impliedF") == 0)
706
    return IA64_DVS_IMPLIEDF;
707
  else if (strcmp (sem, "data") == 0)
708
    return IA64_DVS_DATA;
709
  else if (strcmp (sem, "instr") == 0)
710
    return IA64_DVS_INSTR;
711
  else if (strcmp (sem, "specific") == 0)
712
    return IA64_DVS_SPECIFIC;
713
  else if (strcmp (sem, "stop") == 0)
714
    return IA64_DVS_STOP;
715
  else
716
    return IA64_DVS_OTHER;
717
}
718
 
719
static void
720
add_dep (const char *name, const char *chk, const char *reg,
721
         int semantics, int mode, char *extra, int flag)
722
{
723
  struct rdep *rs;
724
 
725
  rs = insert_resource (name, mode);
726
  parse_resource_users (chk, &rs->chks, &rs->nchks,
727
                        &rs->chknotes);
728
  parse_resource_users (reg, &rs->regs, &rs->nregs,
729
                        &rs->regnotes);
730
  rs->semantics = semantics;
731
  rs->extra = extra;
732
  rs->waw_special = flag;
733
}
734
 
735
static void
736
load_depfile (const char *filename, enum ia64_dependency_mode mode)
737
{
738
  FILE *fp = fopen(filename, "r");
739
  char buf[1024];
740
 
741
  if (fp == NULL){
742
    fprintf (stderr, "Can't find %s for reading\n", filename);
743
    exit(1);
744
  }
745
 
746
  fgets(buf, sizeof(buf), fp);
747
  while (!feof(fp))
748
    {
749
      char *name, *tmp;
750
      int semantics;
751
      char *extra;
752
      char *regp, *chkp;
753
 
754
      if (fgets (buf, sizeof(buf), fp) == NULL)
755
        break;
756
 
757
      while (isspace(buf[strlen(buf)-1]))
758
        buf[strlen(buf)-1] = '\0';
759
 
760
      name = tmp = buf;
761
      while (*tmp != ';')
762
        ++tmp;
763
      *tmp++ = '\0';
764
 
765
      while (isspace (*tmp))
766
        ++tmp;
767
      regp = tmp;
768
      tmp = strchr (tmp, ';');
769
      if (!tmp)
770
        abort ();
771
      *tmp++ = 0;
772
      while (isspace (*tmp))
773
        ++tmp;
774
      chkp = tmp;
775
      tmp = strchr (tmp, ';');
776
      if (!tmp)
777
        abort ();
778
      *tmp++ = 0;
779
      while (isspace (*tmp))
780
        ++tmp;
781
      semantics = parse_semantics (tmp);
782
      extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
783
 
784
      /* For WAW entries, if the chks and regs differ, we need to enter the
785
         entries in both positions so that the tables will be parsed properly,
786
         without a lot of extra work */
787
      if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0)
788
        {
789
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
790
          add_dep (name, regp, chkp, semantics, mode, extra, 1);
791
        }
792
      else
793
        {
794
          add_dep (name, chkp, regp, semantics, mode, extra, 0);
795
        }
796
    }
797
  fclose(fp);
798
}
799
 
800
static void
801
load_dependencies()
802
{
803
  load_depfile ("ia64-raw.tbl", IA64_DV_RAW);
804
  load_depfile ("ia64-waw.tbl", IA64_DV_WAW);
805
  load_depfile ("ia64-war.tbl", IA64_DV_WAR);
806
 
807
  if (debug)
808
      printf ("%d RAW/WAW/WAR dependencies\n", rdepslen);
809
}
810
 
811
/* is the given operand an indirect register file operand? */
812
static int
813
irf_operand (int op, const char *field)
814
{
815
  if (!field)
816
    {
817
      return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
818
        || op == IA64_OPND_IBR_R3  || op == IA64_OPND_PKR_R3
819
        || op == IA64_OPND_PMC_R3  || op == IA64_OPND_PMD_R3
820
        || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
821
    }
822
  else
823
    {
824
      return ((op == IA64_OPND_RR_R3 && strstr (field, "rr"))
825
              || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr"))
826
              || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr"))
827
              || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr"))
828
              || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc"))
829
              || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd"))
830
              || (op == IA64_OPND_MSR_R3 && strstr (field, "msr"))
831
              || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")));
832
    }
833
}
834
 
835
/* handle mov_ar, mov_br, mov_cr, mov_indirect, mov_ip, mov_pr, mov_psr, and
836
   mov_um insn classes */
837
static int
838
in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic,
839
                 const char *format, const char *field)
840
{
841
  int plain_mov = strcmp (idesc->name, "mov") == 0;
842
 
843
  if (!format)
844
    return 0;
845
 
846
  switch (ic->name[4])
847
    {
848
    default:
849
      abort ();
850
    case 'a':
851
      {
852
        int i = strcmp (idesc->name, "mov.i") == 0;
853
        int m = strcmp (idesc->name, "mov.m") == 0;
854
        int i2627 = i && idesc->operands[0] == IA64_OPND_AR3;
855
        int i28 = i && idesc->operands[1] == IA64_OPND_AR3;
856
        int m2930 = m && idesc->operands[0] == IA64_OPND_AR3;
857
        int m31 = m && idesc->operands[1] == IA64_OPND_AR3;
858
        int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3;
859
        int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3;
860
 
861
        /* IC:mov ar */
862
        if (i2627)
863
          return strstr (format, "I26") || strstr (format, "I27");
864
        if (i28)
865
          return strstr (format, "I28") != NULL;
866
        if (m2930)
867
          return strstr (format, "M29") || strstr (format, "M30");
868
        if (m31)
869
          return strstr (format, "M31") != NULL;
870
        if (pseudo0 || pseudo1)
871
          return 1;
872
      }
873
      break;
874
    case 'b':
875
      {
876
        int i21 = idesc->operands[0] == IA64_OPND_B1;
877
        int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2;
878
        if (i22)
879
          return strstr (format, "I22") != NULL;
880
        if (i21)
881
          return strstr (format, "I21") != NULL;
882
      }
883
      break;
884
    case 'c':
885
      {
886
        int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3;
887
        int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3;
888
        if (m32)
889
          return strstr (format, "M32") != NULL;
890
        if (m33)
891
          return strstr (format, "M33") != NULL;
892
      }
893
      break;
894
    case 'i':
895
      if (ic->name[5] == 'n')
896
        {
897
          int m42 = plain_mov && irf_operand (idesc->operands[0], field);
898
          int m43 = plain_mov && irf_operand (idesc->operands[1], field);
899
          if (m42)
900
            return strstr (format, "M42") != NULL;
901
          if (m43)
902
            return strstr (format, "M43") != NULL;
903
        }
904
      else if (ic->name[5] == 'p')
905
        {
906
          return idesc->operands[1] == IA64_OPND_IP;
907
        }
908
      else
909
        abort ();
910
      break;
911
    case 'p':
912
      if (ic->name[5] == 'r')
913
        {
914
          int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR;
915
          int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR;
916
          int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT;
917
          if (i23)
918
            return strstr (format, "I23") != NULL;
919
          if (i24)
920
            return strstr (format, "I24") != NULL;
921
          if (i25)
922
            return strstr (format, "I25") != NULL;
923
        }
924
      else if (ic->name[5] == 's')
925
        {
926
          int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L;
927
          int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR;
928
          if (m35)
929
            return strstr (format, "M35") != NULL;
930
          if (m36)
931
            return strstr (format, "M36") != NULL;
932
        }
933
      else
934
        abort ();
935
      break;
936
    case 'u':
937
      {
938
        int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM;
939
        int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM;
940
        if (m35)
941
          return strstr (format, "M35") != NULL;
942
        if (m36)
943
          return strstr (format, "M36") != NULL;
944
      }
945
      break;
946
    }
947
  return 0;
948
}
949
 
950
 
951
/* is the given opcode in the given insn class? */
952
static int
953
in_iclass(struct ia64_opcode *idesc, struct iclass *ic,
954
          const char *format, const char *field, int *notep)
955
{
956
  int i;
957
  int resolved = 0;
958
 
959
  if (ic->comment)
960
    {
961
      if (!strncmp (ic->comment, "Format", 6))
962
        {
963
          /* assume that the first format seen is the most restrictive, and
964
             only keep a later one if it looks like it's more restrictive. */
965
          if (format)
966
            {
967
              if (strlen (ic->comment) < strlen (format))
968
                {
969
                  fprintf (stderr, "Warning: most recent format '%s'\n"
970
                           "appears more restrictive than '%s'\n",
971
                           ic->comment, format);
972
                  format = ic->comment;
973
                }
974
            }
975
          else
976
            format = ic->comment;
977
        }
978
      else if (!strncmp (ic->comment, "Field", 5))
979
        {
980
          if (field)
981
            fprintf (stderr, "Overlapping field %s->%s\n",
982
                     ic->comment, field);
983
          field = ic->comment;
984
        }
985
    }
986
 
987
  /* an insn class matches anything that is the same followed by completers,
988
     except when the absence and presence of completers constitutes different
989
     instructions */
990
  if (ic->nsubs == 0 && ic->nxsubs == 0)
991
    {
992
      int is_mov = strncmp (idesc->name, "mov", 3) == 0;
993
      int plain_mov = strcmp (idesc->name, "mov") == 0;
994
      int len = strlen(ic->name);
995
 
996
      resolved = ((strncmp (ic->name, idesc->name, len) == 0)
997
                  && (idesc->name[len] == '\0'
998
                      || idesc->name[len] == '.'));
999
 
1000
      /* all break and nop variations must match exactly */
1001
      if (resolved &&
1002
          (strcmp (ic->name, "break") == 0
1003
           || strcmp (ic->name, "nop") == 0))
1004
        resolved = strcmp (ic->name, idesc->name) == 0;
1005
 
1006
      /* assume restrictions in the FORMAT/FIELD negate resolution,
1007
         unless specifically allowed by clauses in this block */
1008
      if (resolved && field)
1009
        {
1010
          /* check Field(sf)==sN against opcode sN */
1011
          if (strstr(field, "(sf)==") != NULL)
1012
            {
1013
              char *sf;
1014
              if ((sf = strstr (idesc->name, ".s")) != 0)
1015
                {
1016
                  resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0;
1017
                }
1018
            }
1019
          /* check Field(lftype)==XXX */
1020
          else if (strstr (field, "(lftype)") != NULL)
1021
            {
1022
              if (strstr (idesc->name, "fault") != NULL)
1023
                resolved = strstr (field, "fault") != NULL;
1024
              else
1025
                resolved = strstr (field, "fault") == NULL;
1026
            }
1027
          /* handle Field(ctype)==XXX */
1028
          else if (strstr (field, "(ctype)") != NULL)
1029
            {
1030
              if (strstr (idesc->name, "or.andcm"))
1031
                resolved = strstr (field, "or.andcm") != NULL;
1032
              else if (strstr (idesc->name, "and.orcm"))
1033
                resolved = strstr (field, "and.orcm") != NULL;
1034
              else if (strstr (idesc->name, "orcm"))
1035
                resolved = strstr (field, "or orcm") != NULL;
1036
              else if (strstr (idesc->name, "or"))
1037
                resolved = strstr (field, "or orcm") != NULL;
1038
              else if (strstr (idesc->name, "andcm"))
1039
                resolved = strstr (field, "and andcm") != NULL;
1040
              else if (strstr (idesc->name, "and"))
1041
                resolved = strstr (field, "and andcm") != NULL;
1042
              else if (strstr (idesc->name, "unc"))
1043
                resolved = strstr (field, "unc") != NULL;
1044
              else
1045
                resolved = strcmp (field, "Field(ctype)==") == 0;
1046
            }
1047
        }
1048
      if (resolved && format)
1049
        {
1050
          if (strncmp (idesc->name, "dep", 3) == 0
1051
                   && strstr (format, "I13") != NULL)
1052
            resolved = idesc->operands[1] == IA64_OPND_IMM8;
1053
          else if (strncmp (idesc->name, "chk", 3) == 0
1054
                   && strstr (format, "M21") != NULL)
1055
            resolved = idesc->operands[0] == IA64_OPND_F2;
1056
          else if (strncmp (idesc->name, "lfetch", 6) == 0)
1057
            resolved = (strstr (format, "M14 M15") != NULL
1058
                        && (idesc->operands[1] == IA64_OPND_R2
1059
                            || idesc->operands[1] == IA64_OPND_IMM9b));
1060
          else if (strncmp (idesc->name, "br.call", 7) == 0
1061
                   && strstr (format, "B5") != NULL)
1062
            resolved = idesc->operands[1] == IA64_OPND_B2;
1063
          else if (strncmp (idesc->name, "br.call", 7) == 0
1064
                   && strstr (format, "B3") != NULL)
1065
            resolved = idesc->operands[1] == IA64_OPND_TGT25c;
1066
          else if (strncmp (idesc->name, "brp", 3) == 0
1067
                   && strstr (format, "B7") != NULL)
1068
            resolved = idesc->operands[0] == IA64_OPND_B2;
1069
          else if (strcmp (ic->name, "invala") == 0)
1070
            resolved = strcmp (idesc->name, ic->name) == 0;
1071
          else if (strncmp (idesc->name, "st", 2) == 0
1072
                   && strstr (format, "M5") != NULL)
1073
            resolved = idesc->flags & IA64_OPCODE_POSTINC;
1074
          else
1075
            resolved = 0;
1076
        }
1077
 
1078
      /* misc brl variations ('.cond' is optional);
1079
         plain brl matches brl.cond */
1080
      if (!resolved
1081
          && (strcmp (idesc->name, "brl") == 0
1082
              || strncmp (idesc->name, "brl.", 4) == 0)
1083
          && strcmp (ic->name, "brl.cond") == 0)
1084
        {
1085
          resolved = 1;
1086
        }
1087
 
1088
      /* misc br variations ('.cond' is optional) */
1089
      if (!resolved
1090
          && (strcmp (idesc->name, "br") == 0
1091
              || strncmp (idesc->name, "br.", 3) == 0)
1092
          && strcmp (ic->name, "br.cond") == 0)
1093
        {
1094
          if (format)
1095
            resolved = (strstr (format, "B4") != NULL
1096
                        && idesc->operands[0] == IA64_OPND_B2)
1097
              || (strstr (format, "B1") != NULL
1098
                  && idesc->operands[0] == IA64_OPND_TGT25c);
1099
          else
1100
            resolved = 1;
1101
        }
1102
 
1103
      /* probe variations */
1104
      if (!resolved && strncmp (idesc->name, "probe", 5) == 0)
1105
        {
1106
          resolved = strcmp (ic->name, "probe") == 0
1107
            && !((strstr (idesc->name, "fault") != NULL)
1108
                 ^ (format && strstr (format, "M40") != NULL));
1109
        }
1110
      /* mov variations */
1111
      if (!resolved && is_mov)
1112
        {
1113
          if (plain_mov)
1114
            {
1115
              /* mov alias for fmerge */
1116
              if (strcmp (ic->name, "fmerge") == 0)
1117
                {
1118
                  resolved = idesc->operands[0] == IA64_OPND_F1
1119
                    && idesc->operands[1] == IA64_OPND_F3;
1120
                }
1121
              /* mov alias for adds (r3 or imm14) */
1122
              else if (strcmp (ic->name, "adds") == 0)
1123
                {
1124
                  resolved = (idesc->operands[0] == IA64_OPND_R1
1125
                              && (idesc->operands[1] == IA64_OPND_R3
1126
                                  || (idesc->operands[1] == IA64_OPND_IMM14)));
1127
                }
1128
              /* mov alias for addl */
1129
              else if (strcmp (ic->name, "addl") == 0)
1130
                {
1131
                  resolved = idesc->operands[0] == IA64_OPND_R1
1132
                    && idesc->operands[1] == IA64_OPND_IMM22;
1133
                }
1134
            }
1135
          /* some variants of mov and mov.[im] */
1136
          if (!resolved && strncmp (ic->name, "mov_", 4) == 0)
1137
            {
1138
              resolved = in_iclass_mov_x (idesc, ic, format, field);
1139
            }
1140
        }
1141
 
1142
      /* keep track of this so we can flag any insn classes which aren't
1143
         mapped onto at least one real insn */
1144
      if (resolved)
1145
        {
1146
          ic->terminal_resolved = 1;
1147
        }
1148
    }
1149
  else for (i=0;i < ic->nsubs;i++)
1150
    {
1151
      if (in_iclass(idesc, ics[ic->subs[i]], format, field, notep))
1152
        {
1153
          int j;
1154
          for (j=0;j < ic->nxsubs;j++)
1155
            {
1156
              if (in_iclass(idesc, ics[ic->xsubs[j]], NULL, NULL, NULL))
1157
                return 0;
1158
            }
1159
          if (debug > 1)
1160
            printf ("%s is in IC %s\n",
1161
                    idesc->name, ic->name);
1162
          resolved = 1;
1163
          break;
1164
        }
1165
    }
1166
 
1167
  /* If it's in this IC, add the IC note (if any) to the insn */
1168
  if (resolved)
1169
    {
1170
      if (ic->note && notep)
1171
        {
1172
          if (*notep && *notep != ic->note)
1173
            {
1174
              fprintf (stderr, "Warning: overwriting note %d with note %d"
1175
                       "(IC:%s)\n",
1176
                       *notep, ic->note, ic->name);
1177
            }
1178
          *notep = ic->note;
1179
        }
1180
    }
1181
 
1182
  return resolved;
1183
}
1184
 
1185
 
1186
static int
1187
lookup_regindex (const char *name, int specifier)
1188
{
1189
  switch (specifier)
1190
    {
1191
    case IA64_RS_ARX:
1192
      if (strstr (name, "[RSC]"))
1193
        return 16;
1194
      if (strstr (name, "[BSP]"))
1195
        return 17;
1196
      else if (strstr (name, "[BSPSTORE]"))
1197
        return 18;
1198
      else if (strstr (name, "[RNAT]"))
1199
        return 19;
1200
      else if (strstr (name, "[CCV]"))
1201
        return 32;
1202
      else if (strstr (name, "[ITC]"))
1203
        return 44;
1204
      else if (strstr (name, "[PFS]"))
1205
        return 64;
1206
      else if (strstr (name, "[LC]"))
1207
        return 65;
1208
      else if (strstr (name, "[EC]"))
1209
        return 66;
1210
      abort ();
1211
    case IA64_RS_CRX:
1212
      if (strstr (name, "[DCR]"))
1213
        return 0;
1214
      else if (strstr (name, "[ITM]"))
1215
        return 1;
1216
      else if (strstr (name, "[IVA]"))
1217
        return 2;
1218
      else if (strstr (name, "[PTA]"))
1219
        return 8;
1220
      else if (strstr (name, "[GPTA]"))
1221
        return 9;
1222
      else if (strstr (name, "[IPSR]"))
1223
        return 16;
1224
      else if (strstr (name, "[ISR]"))
1225
        return 17;
1226
      else if (strstr (name, "[IIP]"))
1227
        return 19;
1228
      else if (strstr (name, "[IFA]"))
1229
        return 20;
1230
      else if (strstr (name, "[ITIR]"))
1231
        return 21;
1232
      else if (strstr (name, "[IIPA]"))
1233
        return 22;
1234
      else if (strstr (name, "[IFS]"))
1235
        return 23;
1236
      else if (strstr (name, "[IIM]"))
1237
        return 24;
1238
      else if (strstr (name, "[IHA]"))
1239
        return 25;
1240
      else if (strstr (name, "[LID]"))
1241
        return 64;
1242
      else if (strstr (name, "[IVR]"))
1243
        return 65;
1244
      else if (strstr (name, "[TPR]"))
1245
        return 66;
1246
      else if (strstr (name, "[EOI]"))
1247
        return 67;
1248
      else if (strstr (name, "[ITV]"))
1249
        return 72;
1250
      else if (strstr (name, "[PMV]"))
1251
        return 73;
1252
      else if (strstr (name, "[CMCV]"))
1253
        return 74;
1254
      abort ();
1255
    case IA64_RS_PSR:
1256
      if (strstr (name, ".be"))
1257
        return 1;
1258
      else if (strstr (name, ".up"))
1259
        return 2;
1260
      else if (strstr (name, ".ac"))
1261
        return 3;
1262
      else if (strstr (name, ".mfl"))
1263
        return 4;
1264
      else if (strstr (name, ".mfh"))
1265
        return 5;
1266
      else if (strstr (name, ".ic"))
1267
        return 13;
1268
      else if (strstr (name, ".i"))
1269
        return 14;
1270
      else if (strstr (name, ".pk"))
1271
        return 15;
1272
      else if (strstr (name, ".dt"))
1273
        return 17;
1274
      else if (strstr (name, ".dfl"))
1275
        return 18;
1276
      else if (strstr (name, ".dfh"))
1277
        return 19;
1278
      else if (strstr (name, ".sp"))
1279
        return 20;
1280
      else if (strstr (name, ".pp"))
1281
        return 21;
1282
      else if (strstr (name, ".di"))
1283
        return 22;
1284
      else if (strstr (name, ".si"))
1285
        return 23;
1286
      else if (strstr (name, ".db"))
1287
        return 24;
1288
      else if (strstr (name, ".lp"))
1289
        return 25;
1290
      else if (strstr (name, ".tb"))
1291
        return 26;
1292
      else if (strstr (name, ".rt"))
1293
        return 27;
1294
      else if (strstr (name, ".cpl"))
1295
        return 32;
1296
      else if (strstr (name, ".rs"))
1297
        return 34;
1298
      else if (strstr (name, ".mc"))
1299
        return 35;
1300
      else if (strstr (name, ".it"))
1301
        return 36;
1302
      else if (strstr (name, ".id"))
1303
        return 37;
1304
      else if (strstr (name, ".da"))
1305
        return 38;
1306
      else if (strstr (name, ".dd"))
1307
        return 39;
1308
      else if (strstr (name, ".ss"))
1309
        return 40;
1310
      else if (strstr (name, ".ri"))
1311
        return 41;
1312
      else if (strstr (name, ".ed"))
1313
        return 43;
1314
      else if (strstr (name, ".bn"))
1315
        return 44;
1316
      else if (strstr (name, ".ia"))
1317
        return 45;
1318
      else
1319
        abort ();
1320
    default:
1321
      break;
1322
    }
1323
  return REG_NONE;
1324
}
1325
 
1326
static int
1327
lookup_specifier (const char *name)
1328
{
1329
  if (strchr (name, '%'))
1330
    {
1331
      if (strstr (name, "AR[K%]") != NULL)
1332
        return IA64_RS_AR_K;
1333
      if (strstr (name, "AR[UNAT]") != NULL)
1334
        return IA64_RS_AR_UNAT;
1335
      if (strstr (name, "AR%, % in 8") != NULL)
1336
        return IA64_RS_AR;
1337
      if (strstr (name, "AR%, % in 48") != NULL)
1338
        return IA64_RS_ARb;
1339
      if (strstr (name, "BR%") != NULL)
1340
        return IA64_RS_BR;
1341
      if (strstr (name, "CR[IRR%]") != NULL)
1342
        return IA64_RS_CR_IRR;
1343
      if (strstr (name, "CR[LRR%]") != NULL)
1344
        return IA64_RS_CR_LRR;
1345
      if (strstr (name, "CR%") != NULL)
1346
        return IA64_RS_CR;
1347
      if (strstr (name, "FR%, % in 0") != NULL)
1348
        return IA64_RS_FR;
1349
      if (strstr (name, "FR%, % in 2") != NULL)
1350
        return IA64_RS_FRb;
1351
      if (strstr (name, "GR%") != NULL)
1352
        return IA64_RS_GR;
1353
      if (strstr (name, "PR%, % in 1 ") != NULL)
1354
        return IA64_RS_PR;
1355
      if (strstr (name, "PR%, % in 16 ") != NULL)
1356
        return IA64_RS_PRr;
1357
 
1358
      fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
1359
               name);
1360
    }
1361
  else if (strchr (name, '#'))
1362
    {
1363
      if (strstr (name, "CPUID#") != NULL)
1364
        return IA64_RS_CPUID;
1365
      if (strstr (name, "DBR#") != NULL)
1366
        return IA64_RS_DBR;
1367
      if (strstr (name, "IBR#") != NULL)
1368
        return IA64_RS_IBR;
1369
      if (strstr (name, "MSR#") != NULL)
1370
        return IA64_RS_MSR;
1371
      if (strstr (name, "PKR#") != NULL)
1372
        return IA64_RS_PKR;
1373
      if (strstr (name, "PMC#") != NULL)
1374
        return IA64_RS_PMC;
1375
      if (strstr (name, "PMD#") != NULL)
1376
        return IA64_RS_PMD;
1377
      if (strstr (name, "RR#") != NULL)
1378
        return IA64_RS_RR;
1379
 
1380
      fprintf (stderr, "Warning! Don't know how to specify # dependency %s\n",
1381
               name);
1382
    }
1383
  else if (strncmp (name, "AR[FPSR]", 8) == 0)
1384
    return IA64_RS_AR_FPSR;
1385
  else if (strncmp (name, "AR[", 3) == 0)
1386
    return IA64_RS_ARX;
1387
  else if (strncmp (name, "CR[", 3) == 0)
1388
    return IA64_RS_CRX;
1389
  else if (strncmp (name, "PSR.", 4) == 0)
1390
    return IA64_RS_PSR;
1391
  else if (strcmp (name, "InService*") == 0)
1392
    return IA64_RS_INSERVICE;
1393
  else if (strcmp (name, "GR0") == 0)
1394
    return IA64_RS_GR0;
1395
  else if (strcmp (name, "CFM") == 0)
1396
    return IA64_RS_CFM;
1397
  else if (strcmp (name, "PR63") == 0)
1398
    return IA64_RS_PR63;
1399
  else if (strcmp (name, "RSE") == 0)
1400
    return IA64_RS_RSE;
1401
 
1402
  return IA64_RS_ANY;
1403
}
1404
 
1405
void
1406
print_dependency_table ()
1407
{
1408
  int i, j;
1409
 
1410
  if (debug)
1411
    {
1412
      for (i=0;i < iclen;i++)
1413
        {
1414
          if (ics[i]->is_class)
1415
            {
1416
              if (!ics[i]->nsubs)
1417
                {
1418
                  fprintf (stderr, "Warning: IC:%s", ics[i]->name);
1419
                  if (ics[i]->comment)
1420
                    fprintf (stderr, "[%s]", ics[i]->comment);
1421
                  fprintf (stderr, " has no terminals or sub-classes\n");
1422
                }
1423
            }
1424
          else
1425
            {
1426
              if (!ics[i]->terminal_resolved && !ics[i]->orphan)
1427
                {
1428
                  fprintf(stderr, "Warning: no insns mapped directly to "
1429
                          "terminal IC %s", ics[i]->name);
1430
                  if (ics[i]->comment)
1431
                    fprintf(stderr, "[%s] ", ics[i]->comment);
1432
                  fprintf(stderr, "\n");
1433
                }
1434
            }
1435
        }
1436
 
1437
      for (i=0;i < iclen;i++)
1438
        {
1439
          if (ics[i]->orphan)
1440
            {
1441
              mark_used (ics[i], 1);
1442
              fprintf (stderr, "Warning: class %s is defined but not used\n",
1443
                       ics[i]->name);
1444
            }
1445
        }
1446
 
1447
      if (debug > 1) for (i=0;i < rdepslen;i++)
1448
        {
1449
          static const char *mode_str[] = { "RAW", "WAW", "WAR" };
1450
          if (rdeps[i]->total_chks == 0)
1451
            {
1452
              fprintf (stderr, "Warning: rsrc %s (%s) has no chks%s\n",
1453
                       rdeps[i]->name, mode_str[rdeps[i]->mode],
1454
                       rdeps[i]->total_regs ? "" : " or regs");
1455
            }
1456
          else if (rdeps[i]->total_regs == 0)
1457
            {
1458
              fprintf (stderr, "Warning: rsrc %s (%s) has no regs\n",
1459
                       rdeps[i]->name, mode_str[rdeps[i]->mode]);
1460
            }
1461
        }
1462
    }
1463
 
1464
  /* the dependencies themselves */
1465
  printf ("static const struct ia64_dependency\ndependencies[] = {\n");
1466
  for (i=0;i < rdepslen;i++)
1467
    {
1468
      /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual
1469
         resource used */
1470
      int specifier = lookup_specifier (rdeps[i]->name);
1471
      int regindex = lookup_regindex (rdeps[i]->name, specifier);
1472
 
1473
      printf ("  { \"%s\", %d, %d, %d, %d, ",
1474
              rdeps[i]->name, specifier,
1475
              (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
1476
      if (rdeps[i]->semantics == IA64_DVS_OTHER)
1477
        printf ("\"%s\", ", rdeps[i]->extra);
1478
      else
1479
        printf ("NULL, ");
1480
      printf("},\n");
1481
    }
1482
  printf ("};\n\n");
1483
 
1484
  /* and dependency lists */
1485
  for (i=0;i < dlistlen;i++)
1486
    {
1487
      int len = 2;
1488
      printf ("static const short dep%d[] = {\n  ", i);
1489
      for (j=0;j < dlists[i]->len; j++)
1490
        {
1491
          len += printf ("%d, ", dlists[i]->deps[j]);
1492
          if (len > 75)
1493
            {
1494
              printf("\n  ");
1495
              len = 2;
1496
            }
1497
        }
1498
      printf ("\n};\n\n");
1499
    }
1500
 
1501
  /* and opcode dependency list */
1502
  printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n");
1503
  printf ("static const struct ia64_opcode_dependency\n");
1504
  printf ("op_dependencies[] = {\n");
1505
  for (i=0;i < opdeplen;i++)
1506
    {
1507
      printf ("  { ");
1508
      if (opdeps[i]->chk == -1)
1509
        printf ("0, NULL, ");
1510
      else
1511
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk);
1512
      if (opdeps[i]->reg == -1)
1513
        printf ("0, NULL, ");
1514
      else
1515
        printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg);
1516
      printf ("},\n");
1517
    }
1518
  printf ("};\n\n");
1519
}
1520
 
1521
 
1522
/* Add STR to the string table. */
1523
 
1524
static struct string_entry *
1525
insert_string (str)
1526
     char *str;
1527
{
1528
  int start = 0, end = strtablen;
1529
  int i, x;
1530
 
1531
  if (strtablen == strtabtotlen)
1532
    {
1533
      strtabtotlen += 20;
1534
      string_table = (struct string_entry **)
1535
        xrealloc (string_table,
1536
                  sizeof (struct string_entry **) * strtabtotlen);
1537
    }
1538
 
1539
  if (strtablen == 0)
1540
    {
1541
      strtablen = 1;
1542
      string_table[0] = tmalloc (struct string_entry);
1543
      string_table[0]->s = xstrdup (str);
1544
      string_table[0]->num = 0;
1545
      return string_table[0];
1546
    }
1547
 
1548
  if (strcmp (str, string_table[strtablen - 1]->s) > 0)
1549
    {
1550
      i = end;
1551
    }
1552
  else if (strcmp (str, string_table[0]->s) < 0)
1553
    {
1554
      i = 0;
1555
    }
1556
  else
1557
    {
1558
      while (1)
1559
        {
1560
          int c;
1561
 
1562
          i = (start + end) / 2;
1563
          c = strcmp (str, string_table[i]->s);
1564
          if (c < 0)
1565
            {
1566
              end = i - 1;
1567
            }
1568
          else if (c == 0)
1569
            {
1570
              return string_table[i];
1571
            }
1572
          else
1573
            {
1574
              start = i + 1;
1575
            }
1576
          if (start > end)
1577
            {
1578
              break;
1579
            }
1580
        }
1581
    }
1582
  for (; i > 0 && i < strtablen; i--)
1583
    {
1584
      if (strcmp (str, string_table[i - 1]->s) > 0)
1585
        {
1586
          break;
1587
        }
1588
    }
1589
  for (; i < strtablen; i++)
1590
    {
1591
      if (strcmp (str, string_table[i]->s) < 0)
1592
        {
1593
          break;
1594
        }
1595
    }
1596
  for (x = strtablen - 1; x >= i; x--)
1597
    {
1598
      string_table[x + 1] = string_table[x];
1599
      string_table[x + 1]->num = x + 1;
1600
    }
1601
  string_table[i] = tmalloc (struct string_entry);
1602
  string_table[i]->s = xstrdup (str);
1603
  string_table[i]->num = i;
1604
  strtablen++;
1605
  return string_table[i];
1606
}
1607
 
1608
struct bittree *
1609
make_bittree_entry ()
1610
{
1611
  struct bittree *res = tmalloc (struct bittree);
1612
 
1613
  res->disent = NULL;
1614
  res->bits[0] = NULL;
1615
  res->bits[1] = NULL;
1616
  res->bits[2] = NULL;
1617
  res->skip_flag = 0;
1618
  res->bits_to_skip = 0;
1619
  return res;
1620
}
1621
 
1622
struct disent *
1623
add_dis_table_ent (which, insn, order, completer_index)
1624
     struct disent *which;
1625
     int insn;
1626
     int order;
1627
     int completer_index;
1628
{
1629
  int ci = 0;
1630
  struct disent *ent;
1631
 
1632
  if (which != NULL)
1633
    {
1634
      ent = which;
1635
 
1636
      ent->nextcnt++;
1637
      while (ent->nexte != NULL)
1638
        {
1639
          ent = ent->nexte;
1640
        }
1641
      ent = (ent->nexte = tmalloc (struct disent));
1642
    }
1643
  else
1644
    {
1645
      ent = tmalloc (struct disent);
1646
      ent->next_ent = disinsntable;
1647
      disinsntable = ent;
1648
      which = ent;
1649
    }
1650
  ent->nextcnt = 0;
1651
  ent->nexte = NULL;
1652
  ent->insn = insn;
1653
  ent->priority = order;
1654
 
1655
  while (completer_index != 1)
1656
    {
1657
      ci = (ci << 1) | (completer_index & 1);
1658
      completer_index >>= 1;
1659
    }
1660
  ent->completer_index = ci;
1661
  return which;
1662
}
1663
 
1664
void
1665
finish_distable ()
1666
{
1667
  struct disent *ent = disinsntable;
1668
  struct disent *prev = ent;
1669
 
1670
  ent->ournum = 32768;
1671
  while ((ent = ent->next_ent) != NULL)
1672
    {
1673
      ent->ournum = prev->ournum + prev->nextcnt + 1;
1674
      prev = ent;
1675
    }
1676
}
1677
 
1678
void
1679
insert_bit_table_ent (curr_ent, bit, opcode, mask,
1680
                      opcodenum, order, completer_index)
1681
     struct bittree *curr_ent;
1682
     int bit;
1683
     ia64_insn opcode;
1684
     ia64_insn mask;
1685
     int opcodenum;
1686
     int order;
1687
     int completer_index;
1688
{
1689
  ia64_insn m;
1690
  int b;
1691
  struct bittree *next;
1692
 
1693
  if (bit == -1)
1694
    {
1695
      struct disent *nent = add_dis_table_ent (curr_ent->disent,
1696
                                               opcodenum, order,
1697
                                               completer_index);
1698
      curr_ent->disent = nent;
1699
      return;
1700
    }
1701
 
1702
  m = ((ia64_insn) 1) << bit;
1703
 
1704
  if (mask & m)
1705
    {
1706
      b = (opcode & m) ? 1 : 0;
1707
    }
1708
  else
1709
    {
1710
      b = 2;
1711
    }
1712
  next = curr_ent->bits[b];
1713
  if (next == NULL)
1714
    {
1715
      next = make_bittree_entry ();
1716
      curr_ent->bits[b] = next;
1717
    }
1718
  insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
1719
                        completer_index);
1720
}
1721
 
1722
void
1723
add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
1724
     struct bittree *first;
1725
     ia64_insn opcode;
1726
     ia64_insn mask;
1727
     int opcodenum;
1728
     struct completer_entry *ent;
1729
     int completer_index;
1730
{
1731
  if (completer_index & (1 << 20))
1732
    {
1733
      abort ();
1734
    }
1735
 
1736
  while (ent != NULL)
1737
    {
1738
      ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
1739
      add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries,
1740
                     (completer_index << 1) | 1);
1741
      if (ent->is_terminal)
1742
        {
1743
          insert_bit_table_ent (bittree, 40, newopcode, mask,
1744
                                opcodenum, opcode_count - ent->order - 1,
1745
                                (completer_index << 1) | 1);
1746
        }
1747
      completer_index <<= 1;
1748
      ent = ent->alternative;
1749
    }
1750
}
1751
 
1752
/* This optimization pass combines multiple "don't care" nodes. */
1753
void
1754
compact_distree (ent)
1755
     struct bittree *ent;
1756
{
1757
#define IS_SKIP(ent) \
1758
    ((ent->bits[2] !=NULL) \
1759
     && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0))
1760
 
1761
  int bitcnt = 0;
1762
  struct bittree *nent = ent;
1763
  int x;
1764
 
1765
  while (IS_SKIP (nent))
1766
    {
1767
      bitcnt++;
1768
      nent = nent->bits[2];
1769
    }
1770
 
1771
  if (bitcnt)
1772
    {
1773
      struct bittree *next = ent->bits[2];
1774
 
1775
      ent->bits[0] = nent->bits[0];
1776
      ent->bits[1] = nent->bits[1];
1777
      ent->bits[2] = nent->bits[2];
1778
      ent->disent = nent->disent;
1779
      ent->skip_flag = 1;
1780
      ent->bits_to_skip = bitcnt;
1781
      while (next != nent)
1782
        {
1783
          struct bittree *b = next;
1784
          next = next->bits[2];
1785
          free (b);
1786
        }
1787
      free (nent);
1788
    }
1789
 
1790
  for (x = 0; x < 3; x++)
1791
    {
1792
      struct bittree *i = ent->bits[x];
1793
      if (i != NULL)
1794
        {
1795
          compact_distree (i);
1796
        }
1797
    }
1798
}
1799
 
1800
static unsigned char *insn_list;
1801
static int insn_list_len = 0;
1802
static int tot_insn_list_len = 0;
1803
 
1804
/* Generate the disassembler state machine corresponding to the tree
1805
   in ENT.  */
1806
void
1807
gen_dis_table (ent)
1808
     struct bittree *ent;
1809
{
1810
  int x;
1811
  int our_offset = insn_list_len;
1812
  int bitsused = 5;
1813
  int totbits = bitsused;
1814
  int needed_bytes;
1815
  int zero_count = 0;
1816
  int zero_dest = 0;     /* initialize this with 0 to keep gcc quiet... */
1817
 
1818
  /* If this is a terminal entry, there's no point in skipping any
1819
     bits. */
1820
  if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL &&
1821
      ent->bits[2] == NULL)
1822
    {
1823
      if (ent->disent == NULL)
1824
        {
1825
          abort ();
1826
        }
1827
      else
1828
        {
1829
          ent->skip_flag = 0;
1830
        }
1831
    }
1832
 
1833
  /* Calculate the amount of space needed for this entry, or at least
1834
     a conservatively large approximation. */
1835
  if (ent->skip_flag)
1836
    {
1837
      totbits += 5;
1838
    }
1839
  for (x = 1; x < 3; x++)
1840
    {
1841
      if (ent->bits[x] != NULL)
1842
        {
1843
          totbits += 16;
1844
        }
1845
    }
1846
 
1847
  if (ent->disent != NULL)
1848
    {
1849
      if (ent->bits[2] != NULL)
1850
        {
1851
          abort ();
1852
        }
1853
      totbits += 16;
1854
    }
1855
 
1856
  /* Now allocate the space. */
1857
  needed_bytes = (totbits + 7) / 8;
1858
  if ((needed_bytes + insn_list_len) > tot_insn_list_len)
1859
    {
1860
      tot_insn_list_len += 256;
1861
      insn_list = (char *) xrealloc (insn_list, tot_insn_list_len);
1862
    }
1863
  our_offset = insn_list_len;
1864
  insn_list_len += needed_bytes;
1865
  memset (insn_list + our_offset, 0, needed_bytes);
1866
 
1867
  /* Encode the skip entry by setting bit 6 set in the state op field,
1868
     and store the # of bits to skip immediately after. */
1869
  if (ent->skip_flag)
1870
    {
1871
      bitsused += 5;
1872
      insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);
1873
      insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);
1874
    }
1875
 
1876
#define IS_ONLY_IFZERO(ENT) \
1877
  ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \
1878
   && (ENT)->disent == NULL && (ENT)->skip_flag == 0)
1879
 
1880
  /* Store an "if (bit is zero)" instruction by setting bit 7 in the
1881
     state op field. */
1882
 
1883
  if (ent->bits[0] != NULL)
1884
    {
1885
      struct bittree *nent = ent->bits[0];
1886
      zero_count = 0;
1887
 
1888
      insn_list[our_offset] |= 0x80;
1889
 
1890
      /* We can encode sequences of multiple "if (bit is zero)" tests
1891
         by storing the # of zero bits to check in the lower 3 bits of
1892
         the instruction.  However, this only applies if the state
1893
         solely tests for a zero bit.  */
1894
 
1895
      if (IS_ONLY_IFZERO (ent))
1896
        {
1897
          while (IS_ONLY_IFZERO (nent) && zero_count < 7)
1898
            {
1899
              nent = nent->bits[0];
1900
              zero_count++;
1901
            }
1902
 
1903
          insn_list[our_offset + 0] |= zero_count;
1904
        }
1905
      zero_dest = insn_list_len;
1906
      gen_dis_table (nent);
1907
    }
1908
 
1909
  /* Now store the remaining tests.  We also handle a sole "termination
1910
     entry" by storing it as an "any bit" test.  */
1911
 
1912
  for (x = 1; x < 3; x++)
1913
    {
1914
      if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))
1915
        {
1916
          struct bittree *i = ent->bits[x];
1917
          int idest;
1918
          int currbits = 15;
1919
 
1920
          if (i != NULL)
1921
            {
1922
              /* If the instruction being branched to only consists of
1923
                 a termination entry, use the termination entry as the
1924
                 place to branch to instead.  */
1925
              if (i->bits[0] == NULL && i->bits[1] == NULL
1926
                  && i->bits[2] == NULL && i->disent != NULL)
1927
                {
1928
                  idest = i->disent->ournum;
1929
                  i = NULL;
1930
                }
1931
              else
1932
                {
1933
                  idest = insn_list_len - our_offset;
1934
                }
1935
            }
1936
          else
1937
            {
1938
              idest = ent->disent->ournum;
1939
            }
1940
 
1941
          /* If the destination offset for the if (bit is 1) test is less
1942
             than 256 bytes away, we can store it as 8-bits instead of 16;
1943
             the instruction has bit 5 set for the 16-bit address, and bit
1944
             4 for the 8-bit address.  Since we've already allocated 16
1945
             bits for the address we need to deallocate the space.
1946
 
1947
             Note that branchings within the table are relative, and
1948
             there are no branches that branch past our instruction yet
1949
             so we do not need to adjust any other offsets. */
1950
 
1951
          if (x == 1)
1952
            {
1953
              if (idest <= 256)
1954
                {
1955
                  int start = our_offset + bitsused / 8 + 1;
1956
 
1957
                  memmove (insn_list + start,
1958
                           insn_list + start + 1,
1959
                           insn_list_len - (start + 1));
1960
                  currbits = 7;
1961
                  totbits -= 8;
1962
                  needed_bytes--;
1963
                  insn_list_len--;
1964
                  insn_list[our_offset] |= 0x10;
1965
                  idest--;
1966
                }
1967
              else
1968
                {
1969
                  insn_list[our_offset] |= 0x20;
1970
                }
1971
            }
1972
          else
1973
            {
1974
              /* An instruction which solely consists of a termination
1975
                 marker and whose disassembly name index is < 4096
1976
                 can be stored in 16 bits.  The encoding is slightly
1977
                 odd; the upper 4 bits of the instruction are 0x3, and
1978
                 bit 3 loses its normal meaning.  */
1979
 
1980
              if (ent->bits[0] == NULL && ent->bits[1] == NULL
1981
                  && ent->bits[2] == NULL && ent->skip_flag == 0
1982
                  && ent->disent != NULL
1983
                  && ent->disent->ournum < (32768 + 4096))
1984
                {
1985
                  int start = our_offset + bitsused / 8 + 1;
1986
 
1987
                  memmove (insn_list + start,
1988
                           insn_list + start + 1,
1989
                           insn_list_len - (start + 1));
1990
                  currbits = 11;
1991
                  totbits -= 5;
1992
                  bitsused--;
1993
                  needed_bytes--;
1994
                  insn_list_len--;
1995
                  insn_list[our_offset] |= 0x30;
1996
                  idest &= ~32768;
1997
                }
1998
              else
1999
                {
2000
                  insn_list[our_offset] |= 0x08;
2001
                }
2002
            }
2003
          if (debug)
2004
            {
2005
              int id = idest;
2006
 
2007
              if (i == NULL)
2008
                {
2009
                  id |= 32768;
2010
                }
2011
              else if (! (id & 32768))
2012
                {
2013
                  id += our_offset;
2014
                }
2015
              if (x == 1)
2016
                {
2017
                  printf ("%d: if (1) goto %d\n", our_offset, id);
2018
                }
2019
              else
2020
                {
2021
                  printf ("%d: try %d\n", our_offset, id);
2022
                }
2023
            }
2024
 
2025
          /* Store the address of the entry being branched to. */
2026
          while (currbits >= 0)
2027
            {
2028
              char *byte = insn_list + our_offset + bitsused / 8;
2029
 
2030
              if (idest & (1 << currbits))
2031
                {
2032
                  *byte |= (1 << (7 - (bitsused % 8)));
2033
                }
2034
              bitsused++;
2035
              currbits--;
2036
            }
2037
 
2038
          /* Now generate the states for the entry being branched to. */
2039
          if (i != NULL)
2040
            {
2041
              gen_dis_table (i);
2042
            }
2043
 
2044
        }
2045
    }
2046
  if (debug)
2047
    {
2048
      if (ent->skip_flag)
2049
        {
2050
          printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);
2051
        }
2052
 
2053
      if (ent->bits[0] != NULL)
2054
        {
2055
          printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,
2056
                  zero_dest);
2057
        }
2058
    }
2059
  if (bitsused != totbits)
2060
    {
2061
      abort ();
2062
    }
2063
}
2064
 
2065
void
2066
print_dis_table ()
2067
{
2068
  int x;
2069
  struct disent *cent = disinsntable;
2070
 
2071
  printf ("static const char dis_table[] = {\n");
2072
  for (x = 0; x < insn_list_len; x++)
2073
    {
2074
      if ((x > 0) && ((x % 12) == 0))
2075
        {
2076
          printf ("\n");
2077
        }
2078
      printf ("0x%02x, ", insn_list[x]);
2079
    }
2080
  printf ("\n};\n\n");
2081
 
2082
  printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");
2083
  while (cent != NULL)
2084
    {
2085
      struct disent *ent = cent;
2086
 
2087
      while (ent != NULL)
2088
        {
2089
          printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
2090
                  ent->insn, (ent->nexte != NULL ? 1 : 0),
2091
                  ent->priority);
2092
          ent = ent->nexte;
2093
        }
2094
      cent = cent->next_ent;
2095
    }
2096
  printf ("};\n\n");
2097
}
2098
 
2099
void
2100
generate_disassembler ()
2101
{
2102
  int i;
2103
 
2104
  bittree = make_bittree_entry ();
2105
 
2106
  for (i=0; i < otlen;i++)
2107
    {
2108
      struct main_entry *ptr = ordered_table[i];
2109
 
2110
      if (ptr->opcode->type != IA64_TYPE_DYN)
2111
        {
2112
          add_dis_entry (bittree,
2113
                         ptr->opcode->opcode, ptr->opcode->mask,
2114
                         ptr->main_index,
2115
                         ptr->completers, 1);
2116
        }
2117
    }
2118
 
2119
  compact_distree (bittree);
2120
  finish_distable ();
2121
  gen_dis_table (bittree);
2122
 
2123
  print_dis_table ();
2124
}
2125
 
2126
void
2127
print_string_table ()
2128
{
2129
  int x;
2130
  char lbuf[80], buf[80];
2131
  int blen = 0;
2132
 
2133
  printf ("static const char *ia64_strings[] = {\n");
2134
  lbuf[0] = '\0';
2135
  for (x = 0; x < strtablen; x++)
2136
    {
2137
      int len;
2138
 
2139
      if (strlen (string_table[x]->s) > 75)
2140
        {
2141
          abort ();
2142
        }
2143
      sprintf (buf, " \"%s\",", string_table[x]->s);
2144
      len = strlen (buf);
2145
      if ((blen + len) > 75)
2146
        {
2147
          printf (" %s\n", lbuf);
2148
          lbuf[0] = '\0';
2149
          blen = 0;
2150
        }
2151
      strcat (lbuf, buf);
2152
      blen += len;
2153
    }
2154
  if (blen > 0)
2155
    {
2156
      printf (" %s\n", lbuf);
2157
    }
2158
  printf ("};\n\n");
2159
}
2160
 
2161
static struct completer_entry **glist;
2162
static int glistlen = 0;
2163
static int glisttotlen = 0;
2164
 
2165
/* If the completer trees ENT1 and ENT2 are equal, return 1. */
2166
 
2167
int
2168
completer_entries_eq (ent1, ent2)
2169
     struct completer_entry *ent1, *ent2;
2170
{
2171
  while (ent1 != NULL && ent2 != NULL)
2172
    {
2173
      if (ent1->name->num != ent2->name->num
2174
          || ent1->bits != ent2->bits
2175
          || ent1->mask != ent2->mask
2176
          || ent1->is_terminal != ent2->is_terminal
2177
          || ent1->dependencies != ent2->dependencies
2178
          || ent1->order != ent2->order)
2179
        {
2180
          return 0;
2181
        }
2182
      if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))
2183
        {
2184
          return 0;
2185
        }
2186
      ent1 = ent1->alternative;
2187
      ent2 = ent2->alternative;
2188
    }
2189
  return ent1 == ent2;
2190
}
2191
 
2192
/* Insert ENT into the global list of completers and return it.  If an
2193
   equivalent entry (according to completer_entries_eq) already exists,
2194
   it is returned instead. */
2195
struct completer_entry *
2196
insert_gclist (ent)
2197
     struct completer_entry *ent;
2198
{
2199
  if (ent != NULL)
2200
    {
2201
      int i;
2202
      int x;
2203
      int start = 0, end;
2204
 
2205
      ent->addl_entries = insert_gclist (ent->addl_entries);
2206
      ent->alternative = insert_gclist (ent->alternative);
2207
 
2208
      i = glistlen / 2;
2209
      end = glistlen;
2210
 
2211
      if (glisttotlen == glistlen)
2212
        {
2213
          glisttotlen += 20;
2214
          glist = (struct completer_entry **)
2215
            xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);
2216
        }
2217
 
2218
      if (glistlen == 0)
2219
        {
2220
          glist[0] = ent;
2221
          glistlen = 1;
2222
          return ent;
2223
        }
2224
 
2225
      if (ent->name->num < glist[0]->name->num)
2226
        {
2227
          i = 0;
2228
        }
2229
      else if (ent->name->num > glist[end - 1]->name->num)
2230
        {
2231
          i = end;
2232
        }
2233
      else
2234
        {
2235
          int c;
2236
 
2237
          while (1)
2238
            {
2239
              i = (start + end) / 2;
2240
              c = ent->name->num - glist[i]->name->num;
2241
              if (c < 0)
2242
                {
2243
                  end = i - 1;
2244
                }
2245
              else if (c == 0)
2246
                {
2247
                  while (i > 0
2248
                         && ent->name->num == glist[i - 1]->name->num)
2249
                    {
2250
                      i--;
2251
                    }
2252
                  break;
2253
                }
2254
              else
2255
                {
2256
                  start = i + 1;
2257
                }
2258
              if (start > end)
2259
                {
2260
                  break;
2261
                }
2262
            }
2263
          if (c == 0)
2264
            {
2265
              while (i < glistlen)
2266
                {
2267
                  if (ent->name->num != glist[i]->name->num)
2268
                    {
2269
                      break;
2270
                    }
2271
                  if (completer_entries_eq (ent, glist[i]))
2272
                    {
2273
                      return glist[i];
2274
                    }
2275
                  i++;
2276
                }
2277
            }
2278
        }
2279
      for (; i > 0 && i < glistlen; i--)
2280
        {
2281
          if (ent->name->num >= glist[i - 1]->name->num)
2282
            {
2283
              break;
2284
            }
2285
        }
2286
      for (; i < glistlen; i++)
2287
        {
2288
          if (ent->name->num < glist[i]->name->num)
2289
            {
2290
              break;
2291
            }
2292
        }
2293
      for (x = glistlen - 1; x >= i; x--)
2294
        {
2295
          glist[x + 1] = glist[x];
2296
        }
2297
      glist[i] = ent;
2298
      glistlen++;
2299
    }
2300
  return ent;
2301
}
2302
 
2303
static int
2304
get_prefix_len (name)
2305
     const char *name;
2306
{
2307
  char *c;
2308
 
2309
  if (name[0] == '\0')
2310
    {
2311
      return 0;
2312
    }
2313
 
2314
  c = strchr (name, '.');
2315
  if (c != NULL)
2316
    {
2317
      return c - name;
2318
    }
2319
  else
2320
    {
2321
      return strlen (name);
2322
    }
2323
}
2324
 
2325
static void
2326
compute_completer_bits (ment, ent)
2327
     struct main_entry *ment;
2328
     struct completer_entry *ent;
2329
{
2330
  while (ent != NULL)
2331
    {
2332
      compute_completer_bits (ment, ent->addl_entries);
2333
 
2334
      if (ent->is_terminal)
2335
        {
2336
          ia64_insn mask = 0;
2337
          ia64_insn our_bits = ent->bits;
2338
          struct completer_entry *p = ent->parent;
2339
          ia64_insn p_bits;
2340
          int x;
2341
 
2342
          while (p != NULL && ! p->is_terminal)
2343
            {
2344
              p = p->parent;
2345
            }
2346
 
2347
          if (p != NULL)
2348
            {
2349
              p_bits = p->bits;
2350
            }
2351
          else
2352
            {
2353
              p_bits = ment->opcode->opcode;
2354
            }
2355
 
2356
          for (x = 0; x < 64; x++)
2357
            {
2358
              ia64_insn m = ((ia64_insn) 1) << x;
2359
              if ((p_bits & m) != (our_bits & m))
2360
                {
2361
                  mask |= m;
2362
                }
2363
              else
2364
                {
2365
                  our_bits &= ~m;
2366
                }
2367
            }
2368
          ent->bits = our_bits;
2369
          ent->mask = mask;
2370
        }
2371
      else
2372
        {
2373
          ent->bits = 0;
2374
          ent->mask = 0;
2375
        }
2376
 
2377
      ent = ent->alternative;
2378
    }
2379
}
2380
 
2381
/* Find identical completer trees that are used in different
2382
   instructions and collapse their entries. */
2383
void
2384
collapse_redundant_completers ()
2385
{
2386
  struct main_entry *ptr;
2387
  int x;
2388
 
2389
  for (ptr = maintable; ptr != NULL; ptr = ptr->next)
2390
    {
2391
      if (ptr->completers == NULL)
2392
        {
2393
          abort ();
2394
        }
2395
      compute_completer_bits (ptr, ptr->completers);
2396
      ptr->completers = insert_gclist (ptr->completers);
2397
    }
2398
 
2399
  /* The table has been finalized, now number the indexes.  */
2400
  for (x = 0; x < glistlen; x++)
2401
    {
2402
      glist[x]->num = x;
2403
    }
2404
}
2405
 
2406
 
2407
/* attach two lists of dependencies to each opcode.
2408
   1) all resources which, when already marked in use, conflict with this
2409
   opcode (chks)
2410
   2) all resources which must be marked in use when this opcode is used
2411
   (regs)
2412
*/
2413
int
2414
insert_opcode_dependencies (opc, cmp)
2415
     struct ia64_opcode *opc;
2416
     struct completer_entry *cmp ATTRIBUTE_UNUSED;
2417
{
2418
  /* note all resources which point to this opcode.  rfi has the most chks
2419
     (79) and cmpxchng has the most regs (54) so 100 here should be enough */
2420
  int i;
2421
  int nregs = 0;
2422
  unsigned short regs[256];
2423
  int nchks = 0;
2424
  unsigned short chks[256];
2425
  /* flag insns for which no class matched; there should be none */
2426
  int no_class_found = 1;
2427
 
2428
  for (i=0;i < rdepslen;i++)
2429
    {
2430
      struct rdep *rs = rdeps[i];
2431
      int j;
2432
 
2433
      if (strcmp (opc->name, "cmp.eq.and") == 0
2434
          && strncmp (rs->name, "PR%", 3) == 0
2435
          && rs->mode == 1)
2436
        no_class_found = 99;
2437
 
2438
      for (j=0; j < rs->nregs;j++)
2439
        {
2440
          int ic_note = 0;
2441
 
2442
          if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note))
2443
            {
2444
              /* We can ignore ic_note 11 for non PR resources */
2445
              if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2446
                ic_note = 0;
2447
 
2448
              if (ic_note != 0 && rs->regnotes[j] != 0
2449
                  && ic_note != rs->regnotes[j]
2450
                  && !(ic_note == 11 && rs->regnotes[j] == 1))
2451
                fprintf (stderr, "Warning: IC note %d in opcode %s (IC:%s)"
2452
                         " conflicts with resource %s note %d\n",
2453
                         ic_note, opc->name, ics[rs->regs[j]]->name,
2454
                         rs->name, rs->regnotes[j]);
2455
              /* Instruction class notes override resource notes.
2456
                 So far, only note 11 applies to an IC instead of a resource,
2457
                 and note 11 implies note 1.
2458
               */
2459
              if (ic_note)
2460
                regs[nregs++] = RDEP(ic_note, i);
2461
              else
2462
                regs[nregs++] = RDEP(rs->regnotes[j], i);
2463
              no_class_found = 0;
2464
              ++rs->total_regs;
2465
            }
2466
        }
2467
      for (j=0;j < rs->nchks;j++)
2468
        {
2469
          int ic_note = 0;
2470
 
2471
          if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note))
2472
            {
2473
              /* We can ignore ic_note 11 for non PR resources */
2474
              if (ic_note == 11 && strncmp (rs->name, "PR", 2) != 0)
2475
                ic_note = 0;
2476
 
2477
              if (ic_note != 0 && rs->chknotes[j] != 0
2478
                  && ic_note != rs->chknotes[j]
2479
                  && !(ic_note == 11 && rs->chknotes[j] == 1))
2480
                fprintf (stderr, "Warning: IC note %d for opcode %s (IC:%s)"
2481
                         " conflicts with resource %s note %d\n",
2482
                         ic_note, opc->name, ics[rs->chks[j]]->name,
2483
                         rs->name, rs->chknotes[j]);
2484
              if (ic_note)
2485
                chks[nchks++] = RDEP(ic_note, i);
2486
              else
2487
                chks[nchks++] = RDEP(rs->chknotes[j], i);
2488
              no_class_found = 0;
2489
              ++rs->total_chks;
2490
            }
2491
        }
2492
    }
2493
 
2494
  if (no_class_found)
2495
    fprintf (stderr, "Warning: opcode %s has no class (ops %d %d %d)\n",
2496
             opc->name,
2497
             opc->operands[0], opc->operands[1], opc->operands[2]);
2498
 
2499
  return insert_dependencies (nchks, chks, nregs, regs);
2500
}
2501
 
2502
void
2503
insert_completer_entry (opc, tabent, order)
2504
     struct ia64_opcode *opc;
2505
     struct main_entry *tabent;
2506
     int order;
2507
{
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
    {
2515
      abort ();
2516
    }
2517
  strcpy (pcopy, opc->name);
2518
  prefix = pcopy + get_prefix_len (pcopy);
2519
  if (prefix[0] != '\0')
2520
    {
2521
      prefix++;
2522
    }
2523
 
2524
  while (! at_end)
2525
    {
2526
      int need_new_ent = 1;
2527
      int plen = get_prefix_len (prefix);
2528
      struct string_entry *sent;
2529
 
2530
      at_end = (prefix[plen] == '\0');
2531
      prefix[plen] = '\0';
2532
      sent = insert_string (prefix);
2533
 
2534
      while (*ptr != NULL)
2535
        {
2536
          int cmpres = sent->num - (*ptr)->name->num;
2537
 
2538
          if (cmpres == 0)
2539
            {
2540
              need_new_ent = 0;
2541
              break;
2542
            }
2543
          else
2544
            {
2545
              ptr = &((*ptr)->alternative);
2546
            }
2547
        }
2548
      if (need_new_ent)
2549
        {
2550
          struct completer_entry *nent = tmalloc (struct completer_entry);
2551
          nent->name = sent;
2552
          nent->parent = parent;
2553
          nent->addl_entries = NULL;
2554
          nent->alternative = *ptr;
2555
          *ptr = nent;
2556
          nent->is_terminal = 0;
2557
          nent->dependencies = -1;
2558
        }
2559
 
2560
      if (! at_end)
2561
        {
2562
          parent = *ptr;
2563
          ptr = &((*ptr)->addl_entries);
2564
          prefix += plen + 1;
2565
        }
2566
    }
2567
 
2568
  if ((*ptr)->is_terminal)
2569
    {
2570
      abort ();
2571
    }
2572
 
2573
  (*ptr)->is_terminal = 1;
2574
  (*ptr)->mask = (ia64_insn)-1;
2575
  (*ptr)->bits = opc->opcode;
2576
  (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
2577
  (*ptr)->order = order;
2578
}
2579
 
2580
void
2581
print_completer_entry (ent)
2582
     struct completer_entry *ent;
2583
{
2584
  int moffset = 0;
2585
  ia64_insn mask = ent->mask, bits = ent->bits;
2586
 
2587
  if (mask != 0)
2588
    {
2589
      while (! (mask & 1))
2590
        {
2591
          moffset++;
2592
          mask = mask >> 1;
2593
          bits = bits >> 1;
2594
        }
2595
      if (bits & 0xffffffff00000000LL)
2596
        {
2597
          abort ();
2598
        }
2599
    }
2600
 
2601
  printf ("  { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n",
2602
          (int)bits,
2603
          (int)mask,
2604
          ent->name->num,
2605
          ent->alternative != NULL ? ent->alternative->num : -1,
2606
          ent->addl_entries != NULL ? ent->addl_entries->num : -1,
2607
          moffset,
2608
          ent->is_terminal ? 1 : 0,
2609
          ent->dependencies);
2610
}
2611
 
2612
void
2613
print_completer_table ()
2614
{
2615
  int x;
2616
 
2617
  printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n");
2618
  for (x = 0; x < glistlen; x++)
2619
    {
2620
      print_completer_entry (glist[x]);
2621
    }
2622
  printf ("};\n\n");
2623
}
2624
 
2625
int
2626
opcodes_eq (opc1, opc2)
2627
     struct ia64_opcode *opc1;
2628
     struct ia64_opcode *opc2;
2629
{
2630
  int x;
2631
  int plen1, plen2;
2632
 
2633
  if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type)
2634
      || (opc1->num_outputs != opc2->num_outputs)
2635
      || (opc1->flags != opc2->flags))
2636
    {
2637
      return 0;
2638
    }
2639
  for (x = 0; x < 5; x++)
2640
    {
2641
      if (opc1->operands[x] != opc2->operands[x])
2642
        {
2643
          return 0;
2644
        }
2645
    }
2646
  plen1 = get_prefix_len (opc1->name);
2647
  plen2 = get_prefix_len (opc2->name);
2648
  if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0))
2649
    {
2650
      return 1;
2651
    }
2652
  return 0;
2653
}
2654
 
2655
void
2656
add_opcode_entry (opc)
2657
     struct ia64_opcode *opc;
2658
{
2659
  struct main_entry **place;
2660
  struct string_entry *name;
2661
  char prefix[129];
2662
  int found_it = 0;
2663
 
2664
  if (strlen (opc->name) > 128)
2665
    {
2666
      abort ();
2667
    }
2668
  place = &maintable;
2669
  strcpy (prefix, opc->name);
2670
  prefix[get_prefix_len (prefix)] = '\0';
2671
  name = insert_string (prefix);
2672
 
2673
  /* Walk the list of opcode table entries.  If it's a new
2674
     instruction, allocate and fill in a new entry.  Note
2675
     the main table is alphabetical by opcode name. */
2676
 
2677
  while (*place != NULL)
2678
    {
2679
      if ((*place)->name->num == name->num
2680
          && opcodes_eq ((*place)->opcode, opc))
2681
        {
2682
          found_it = 1;
2683
          break;
2684
        }
2685
      if ((*place)->name->num > name->num)
2686
        {
2687
          break;
2688
        }
2689
      place = &((*place)->next);
2690
    }
2691
  if (! found_it)
2692
    {
2693
      struct main_entry *nent = tmalloc (struct main_entry);
2694
 
2695
      nent->name = name;
2696
      nent->opcode = opc;
2697
      nent->next = *place;
2698
      nent->completers = 0;
2699
      *place = nent;
2700
 
2701
      if (otlen == ottotlen)
2702
        {
2703
          ottotlen += 20;
2704
          ordered_table = (struct main_entry **)
2705
            xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
2706
        }
2707
      ordered_table[otlen++] = nent;
2708
    }
2709
 
2710
  insert_completer_entry (opc, *place, opcode_count++);
2711
}
2712
 
2713
void
2714
print_main_table ()
2715
{
2716
  struct main_entry *ptr = maintable;
2717
  int index = 0;
2718
 
2719
  printf ("static const struct ia64_main_table\nmain_table[] = {\n");
2720
  while (ptr != NULL)
2721
    {
2722
      printf ("  { %d, %d, %d, 0x",
2723
              ptr->name->num,
2724
              ptr->opcode->type,
2725
              ptr->opcode->num_outputs);
2726
      fprintf_vma (stdout, ptr->opcode->opcode);
2727
      printf ("ull, 0x");
2728
      fprintf_vma (stdout, ptr->opcode->mask);
2729
      printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
2730
              ptr->opcode->operands[0],
2731
              ptr->opcode->operands[1],
2732
              ptr->opcode->operands[2],
2733
              ptr->opcode->operands[3],
2734
              ptr->opcode->operands[4],
2735
              ptr->opcode->flags,
2736
              ptr->completers->num);
2737
 
2738
      ptr->main_index = index++;
2739
 
2740
      ptr = ptr->next;
2741
    }
2742
  printf ("};\n\n");
2743
}
2744
 
2745
void
2746
shrink (table)
2747
     struct ia64_opcode *table;
2748
{
2749
  int curr_opcode;
2750
 
2751
  for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++)
2752
    {
2753
      add_opcode_entry (table + curr_opcode);
2754
    }
2755
}
2756
 
2757
int
2758
main (argc, argv)
2759
     int argc;
2760
     char **argv ATTRIBUTE_UNUSED;
2761
{
2762
  if (argc > 1)
2763
    {
2764
      debug = 1;
2765
    }
2766
 
2767
  load_insn_classes();
2768
  load_dependencies();
2769
 
2770
  shrink (ia64_opcodes_a);
2771
  shrink (ia64_opcodes_b);
2772
  shrink (ia64_opcodes_f);
2773
  shrink (ia64_opcodes_i);
2774
  shrink (ia64_opcodes_m);
2775
  shrink (ia64_opcodes_x);
2776
  shrink (ia64_opcodes_d);
2777
 
2778
  collapse_redundant_completers ();
2779
 
2780
  printf ("/* This file is automatically generated by ia64-gen.  Do not edit! */\n");
2781
  print_string_table ();
2782
  print_dependency_table ();
2783
  print_completer_table ();
2784
  print_main_table ();
2785
 
2786
  generate_disassembler ();
2787
 
2788
  exit (0);
2789
}

powered by: WebSVN 2.1.0

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