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