* alpha-opc.c (unop): Encode with RB as $sp.
[deliverable/binutils-gdb.git] / opcodes / ia64-gen.c
index 093d6860ff1089ff064f20bc87e1402f28e93389..6443c7c4b250f9f7009be8052acc4997c121aa15 100644 (file)
@@ -1,5 +1,5 @@
 /* ia64-gen.c -- Generate a shrunk set of opcode tables
-   Copyright (c) 1999 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
    Written by Bob Manson, Cygnus Solutions, <manson@cygnus.com>
 
    This file is part of GDB, GAS, and the GNU binutils.
 */
 
 #include <stdio.h>
-#include <ctype.h>
 
 #include "ansidecl.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "sysdep.h"
 #include "ia64-opc.h"
 #include "ia64-opc-a.c"
@@ -68,7 +68,12 @@ struct main_entry
   struct completer_entry *completers;
   /* Next entry in the chain. */
   struct main_entry *next;
-} *maintable;
+  /* Index in the  main table. */
+  int main_index;
+} *maintable, **ordered_table;
+int otlen = 0;
+int ottotlen = 0;
+int opcode_count = 0;
 
 /* The set of possible completers for an opcode. */
 struct completer_entry
@@ -104,8 +109,11 @@ struct completer_entry
      list).  This field is filled in by compute_completer_bits (). */
   ia64_insn mask;
 
-  /* Index into the opcode dependency list, or -1 if none */
+  /* Index into the opcode dependency list, or -1 if none. */
   int dependencies;
+
+  /* Remember the order encountered in the opcode tables.  */
+  int order;
 };
 
 /* One entry in the disassembler name table. */
@@ -117,6 +125,9 @@ struct disent
   /* The index into the main_table[] array. */
   int insn;
 
+  /* The disassmbly priority of this entry. */
+  int priority;
+
   /* The completer_index value for this entry. */
   int completer_index;
 
@@ -135,7 +146,7 @@ struct disent
 struct bittree
 {
   struct disent *disent;
-  struct bittree *bits[3];
+  struct bittree *bits[3]; /* 0, 1, and X (don't care) */
   int bits_to_skip;
   int skip_flag;
 } *bittree;
@@ -166,7 +177,7 @@ struct rdep
   int nchks;                   
   int total_chks;                   /* total #of terminal insns */
   int *chks;                        /* insn classes which read (RAW), write
-                                       (WAW), or write (WAR) this rsrc */ // 
+                                       (WAW), or write (WAR) this rsrc */
   int *chknotes;                    /* dependency notes for each class */
   int nregs;
   int total_regs;                   /* total #of terminal insns */
@@ -270,14 +281,14 @@ insert_deplist(int count, unsigned short *deps)
   for (i=0;i < count;i++)
     set[deps[i]] = 1;
   count = 0;
-  for (i=0;i < sizeof(set);i++)
+  for (i=0;i < (int)sizeof(set);i++)
     if (set[i])
       ++count;
 
   list = tmalloc(struct deplist);
   list->len = count;
   list->deps = (unsigned short *)malloc (sizeof(unsigned short) * count);
-  for (i=0, count=0;i < sizeof(set);i++)
+  for (i=0, count=0;i < (int)sizeof(set);i++)
     {
       if (set[i])
         {
@@ -388,9 +399,21 @@ fetch_insn_class(const char *full_name, int create)
   if ((comment = strchr(name, '[')) != NULL)
     is_class = 1;
   if ((notestr = strchr(name, '+')) != NULL)
+    is_class = 1;
+
+  /* If it is a composite class, then ignore comments and notes that come after
+     the '\\', since they don't apply to the part we are decoding now.  */
+  if (xsect)
+    {
+      if (comment > xsect)
+       comment = 0;
+      if (notestr > xsect)
+       notestr = 0;
+    }
+
+  if (notestr)
     {
       char *nextnotestr;
-      is_class = 1;
       note = atoi (notestr + 1);
       if ((nextnotestr = strchr (notestr + 1, '+')) != NULL)
         {
@@ -402,8 +425,9 @@ fetch_insn_class(const char *full_name, int create)
         }
     }
 
-  /* if it's a composite class, leave the notes and comments in place so that
-     we have a unique name for the composite class */
+  /* If it's a composite class, leave the notes and comments in place so that
+     we have a unique name for the composite class.  Otherwise, we remove
+     them.  */
   if (!xsect)
     {
       if (notestr)
@@ -450,7 +474,7 @@ fetch_insn_class(const char *full_name, int create)
      existing class or terminal with the same name. */ 
   if ((xsect || comment || notestr) && is_class)
     {
-      // first, populate with the class we're based on
+      /* First, populate with the class we're based on.  */
       char *subname = name;
       if (xsect)
         *xsect = 0;
@@ -502,6 +526,11 @@ load_insn_classes()
   FILE *fp = fopen("ia64-ic.tbl", "r");
   char buf[2048];
 
+  if (fp == NULL){
+    fprintf (stderr, "Can't find ia64-ic.tbl for reading\n");
+    exit(1);
+  }
+
   /* discard first line */
   fgets (buf, sizeof(buf), fp);
 
@@ -514,7 +543,7 @@ load_insn_classes()
       if (fgets (buf, sizeof(buf), fp) == NULL)
         break;
       
-      while (isspace(buf[strlen(buf)-1]))
+      while (ISSPACE (buf[strlen(buf)-1]))
         buf[strlen(buf)-1] = '\0';
 
       name = tmp = buf;
@@ -542,7 +571,7 @@ load_insn_classes()
           char *subname;
           int sub;
 
-          while (*tmp && isspace(*tmp))
+          while (*tmp && ISSPACE (*tmp))
             {
               ++tmp;
               if (tmp == buf + sizeof(buf))
@@ -604,7 +633,7 @@ parse_resource_users(ref, usersp, nusersp, notesp)
       int create = 0;
       char *name;
       
-      while (isspace(*tmp))
+      while (ISSPACE (*tmp))
         ++tmp;
       name = tmp;
       while (*tmp && *tmp != ',')
@@ -681,6 +710,8 @@ parse_semantics (char *sem)
     return IA64_DVS_INSTR;
   else if (strcmp (sem, "specific") == 0)
     return IA64_DVS_SPECIFIC;
+  else if (strcmp (sem, "stop") == 0)
+    return IA64_DVS_STOP;
   else 
     return IA64_DVS_OTHER;
 }
@@ -707,6 +738,11 @@ load_depfile (const char *filename, enum ia64_dependency_mode mode)
   FILE *fp = fopen(filename, "r");
   char buf[1024];
 
+  if (fp == NULL){
+    fprintf (stderr, "Can't find %s for reading\n", filename);
+    exit(1);
+  }
+
   fgets(buf, sizeof(buf), fp);
   while (!feof(fp))
     {
@@ -718,7 +754,7 @@ load_depfile (const char *filename, enum ia64_dependency_mode mode)
       if (fgets (buf, sizeof(buf), fp) == NULL)
         break;
 
-      while (isspace(buf[strlen(buf)-1]))
+      while (ISSPACE (buf[strlen(buf)-1]))
         buf[strlen(buf)-1] = '\0';
 
       name = tmp = buf;
@@ -726,21 +762,21 @@ load_depfile (const char *filename, enum ia64_dependency_mode mode)
         ++tmp;
       *tmp++ = '\0';
       
-      while (isspace (*tmp))
+      while (ISSPACE (*tmp))
         ++tmp;
       regp = tmp;
       tmp = strchr (tmp, ';');
       if (!tmp)
         abort ();
       *tmp++ = 0;
-      while (isspace (*tmp))
+      while (ISSPACE (*tmp))
         ++tmp;
       chkp = tmp;
       tmp = strchr (tmp, ';');
       if (!tmp)
         abort ();
       *tmp++ = 0;
-      while (isspace (*tmp))
+      while (ISSPACE (*tmp))
         ++tmp;
       semantics = parse_semantics (tmp);
       extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL;
@@ -779,8 +815,8 @@ irf_operand (int op, const char *field)
   if (!field)
     {
       return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3
-        || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3
-        || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3
+        || op == IA64_OPND_IBR_R3  || op == IA64_OPND_PKR_R3
+       || op == IA64_OPND_PMC_R3  || op == IA64_OPND_PMD_R3
        || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3;
     }
   else
@@ -1032,6 +1068,9 @@ in_iclass(struct ia64_opcode *idesc, struct iclass *ic,
             resolved = idesc->operands[0] == IA64_OPND_B2;
           else if (strcmp (ic->name, "invala") == 0)
             resolved = strcmp (idesc->name, ic->name) == 0;
+         else if (strncmp (idesc->name, "st", 2) == 0
+                  && strstr (format, "M5") != NULL)
+           resolved = idesc->flags & IA64_OPCODE_POSTINC;
           else
             resolved = 0;
         }
@@ -1311,8 +1350,10 @@ lookup_specifier (const char *name)
         return IA64_RS_FRb;
       if (strstr (name, "GR%") != NULL)
         return IA64_RS_GR;
-      if (strstr (name, "PR%") != NULL)
+      if (strstr (name, "PR%, % in 1 ") != NULL)
         return IA64_RS_PR;
+      if (strstr (name, "PR%, % in 16 ") != NULL)
+       return IA64_RS_PRr;
 
       fprintf (stderr, "Warning! Don't know how to specify %% dependency %s\n",
                name);
@@ -1434,6 +1475,8 @@ print_dependency_table ()
               (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex);
       if (rdeps[i]->semantics == IA64_DVS_OTHER)
         printf ("\"%s\", ", rdeps[i]->extra);
+      else
+       printf ("NULL, ");
       printf("},\n");
     }
   printf ("};\n\n");
@@ -1577,9 +1620,10 @@ make_bittree_entry ()
 }
 \f
 struct disent *
-add_dis_table_ent (which, insn, completer_index)
+add_dis_table_ent (which, insn, order, completer_index)
      struct disent *which;
      int insn;
+     int order;
      int completer_index;
 {
   int ci = 0;
@@ -1606,6 +1650,8 @@ add_dis_table_ent (which, insn, completer_index)
   ent->nextcnt = 0;
   ent->nexte = NULL;
   ent->insn = insn;
+  ent->priority = order;
+
   while (completer_index != 1)
     {
       ci = (ci << 1) | (completer_index & 1);
@@ -1630,12 +1676,14 @@ finish_distable ()
 }
 \f
 void
-insert_bit_table_ent (curr_ent, bit, opcode, mask, opcodenum, completer_index)
+insert_bit_table_ent (curr_ent, bit, opcode, mask, 
+                      opcodenum, order, completer_index)
      struct bittree *curr_ent;
      int bit;
      ia64_insn opcode; 
      ia64_insn mask;
      int opcodenum;
+     int order;
      int completer_index;
 {
   ia64_insn m;
@@ -1644,7 +1692,8 @@ insert_bit_table_ent (curr_ent, bit, opcode, mask, opcodenum, completer_index)
 
   if (bit == -1)
     {
-      struct disent *nent = add_dis_table_ent (curr_ent->disent, opcodenum,
+      struct disent *nent = add_dis_table_ent (curr_ent->disent, 
+                                               opcodenum, order,
                                               completer_index);
       curr_ent->disent = nent;
       return;
@@ -1666,13 +1715,13 @@ insert_bit_table_ent (curr_ent, bit, opcode, mask, opcodenum, completer_index)
       next = make_bittree_entry ();
       curr_ent->bits[b] = next;
     }
-  insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum,
+  insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order,
                        completer_index);
 }
 \f
 void
 add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
-     int first;
+     struct bittree *first;
      ia64_insn opcode;
      ia64_insn mask;
      int opcodenum;
@@ -1683,6 +1732,7 @@ add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
     {
       abort ();
     }
+
   while (ent != NULL)
     {
       ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits;
@@ -1690,7 +1740,8 @@ add_dis_entry (first, opcode, mask, opcodenum, ent, completer_index)
                     (completer_index << 1) | 1);
       if (ent->is_terminal)
        {
-         insert_bit_table_ent (bittree, 40, newopcode, mask, opcodenum, 
+         insert_bit_table_ent (bittree, 40, newopcode, mask, 
+                                opcodenum, opcode_count - ent->order - 1, 
                                (completer_index << 1) | 1);
        }
       completer_index <<= 1;
@@ -2035,9 +2086,9 @@ print_dis_table ()
 
       while (ent != NULL)
        {
-         printf ("{ 0x%x, %d, %d },\n", ent->completer_index,
-                 ent->insn,
-                 (ent->nexte != NULL ? 1 : 0));
+         printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,
+                 ent->insn, (ent->nexte != NULL ? 1 : 0),
+                  ent->priority);
          ent = ent->nexte;
        }
       cent = cent->next_ent;
@@ -2048,21 +2099,21 @@ print_dis_table ()
 void
 generate_disassembler ()
 {
-  int mainnum = 0;
-  struct main_entry *ptr = maintable;
+  int i;
 
   bittree = make_bittree_entry ();
 
-  while (ptr != NULL)
+  for (i=0; i < otlen;i++)
     {
+      struct main_entry *ptr = ordered_table[i];
+
       if (ptr->opcode->type != IA64_TYPE_DYN)
        {
          add_dis_entry (bittree,
-                        ptr->opcode->opcode, ptr->opcode->mask, mainnum,
+                        ptr->opcode->opcode, ptr->opcode->mask, 
+                         ptr->main_index,
                         ptr->completers, 1);
        }
-      mainnum++;
-      ptr = ptr->next;
     }
 
   compact_distree (bittree);
@@ -2123,7 +2174,8 @@ completer_entries_eq (ent1, ent2)
          || ent1->bits != ent2->bits
          || ent1->mask != ent2->mask
          || ent1->is_terminal != ent2->is_terminal
-          || ent1->dependencies != ent2->dependencies)
+          || ent1->dependencies != ent2->dependencies
+          || ent1->order != ent2->order)
        {
          return 0;
        }
@@ -2361,7 +2413,7 @@ collapse_redundant_completers ()
 int
 insert_opcode_dependencies (opc, cmp)
      struct ia64_opcode *opc;
-     struct completer_entry *cmp;
+     struct completer_entry *cmp ATTRIBUTE_UNUSED;
 {
   /* note all resources which point to this opcode.  rfi has the most chks
      (79) and cmpxchng has the most regs (54) so 100 here should be enough */
@@ -2448,9 +2500,10 @@ insert_opcode_dependencies (opc, cmp)
 }
 \f
 void
-insert_completer_entry (opc, tabent)
+insert_completer_entry (opc, tabent, order)
      struct ia64_opcode *opc;
      struct main_entry *tabent;
+     int order;
 {
   struct completer_entry **ptr = &tabent->completers;
   struct completer_entry *parent = NULL;
@@ -2487,10 +2540,6 @@ insert_completer_entry (opc, tabent)
              need_new_ent = 0;
              break;
            }
-         else if (cmpres < 0)
-           {
-             break;
-           }
          else
            {
              ptr = &((*ptr)->alternative);
@@ -2524,8 +2573,8 @@ insert_completer_entry (opc, tabent)
   (*ptr)->is_terminal = 1;
   (*ptr)->mask = (ia64_insn)-1;
   (*ptr)->bits = opc->opcode;
-
   (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr);
+  (*ptr)->order = order;
 }
 \f
 void
@@ -2622,7 +2671,8 @@ add_opcode_entry (opc)
   name = insert_string (prefix);
 
   /* Walk the list of opcode table entries.  If it's a new
-     instruction, allocate and fill in a new entry.  */
+     instruction, allocate and fill in a new entry.  Note 
+     the main table is alphabetical by opcode name. */
 
   while (*place != NULL)
     {
@@ -2647,24 +2697,36 @@ add_opcode_entry (opc)
       nent->next = *place;
       nent->completers = 0;
       *place = nent;
+
+      if (otlen == ottotlen)
+        {
+          ottotlen += 20;
+          ordered_table = (struct main_entry **)
+            xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen);
+        }
+      ordered_table[otlen++] = nent;
     }
-  insert_completer_entry (opc, *place);
+
+  insert_completer_entry (opc, *place, opcode_count++);
 }
 \f
 void
 print_main_table ()
 {
   struct main_entry *ptr = maintable;
+  int index = 0;
 
   printf ("static const struct ia64_main_table\nmain_table[] = {\n");
   while (ptr != NULL)
     {
-      printf ("  { %d, %d, %d, 0x%llxull, 0x%llxull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
+      printf ("  { %d, %d, %d, 0x",
              ptr->name->num,
              ptr->opcode->type,
-             ptr->opcode->num_outputs,
-             ptr->opcode->opcode,
-             ptr->opcode->mask,
+             ptr->opcode->num_outputs);
+      fprintf_vma (stdout, ptr->opcode->opcode);
+      printf ("ull, 0x");
+      fprintf_vma (stdout, ptr->opcode->mask);
+      printf ("ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n",
              ptr->opcode->operands[0],
              ptr->opcode->operands[1],
              ptr->opcode->operands[2],
@@ -2673,6 +2735,8 @@ print_main_table ()
              ptr->opcode->flags,
              ptr->completers->num);
 
+      ptr->main_index = index++;
+
       ptr = ptr->next;
     }
   printf ("};\n\n");
@@ -2691,7 +2755,9 @@ shrink (table)
 }
 \f
 int
-main (int argc, char **argv)
+main (argc, argv)
+     int argc;
+     char **argv ATTRIBUTE_UNUSED;
 {
   if (argc > 1)
     {
This page took 0.036186 seconds and 4 git commands to generate.