Home | History | Annotate | Line # | Download | only in opcodes
aarch64-gen.c revision 1.1.1.2
      1 /* aarch64-gen.c -- Generate tables and routines for opcode lookup and
      2    instruction encoding and decoding.
      3    Copyright (C) 2012-2015 Free Software Foundation, Inc.
      4    Contributed by ARM Ltd.
      5 
      6    This file is part of the GNU opcodes library.
      7 
      8    This library is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3, or (at your option)
     11    any later version.
     12 
     13    It is distributed in the hope that it will be useful, but WITHOUT
     14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16    License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; see the file COPYING3. If not,
     20    see <http://www.gnu.org/licenses/>.  */
     21 
     22 #include "sysdep.h"
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <stdarg.h>
     26 
     27 #include "libiberty.h"
     28 #include "getopt.h"
     29 #include "opcode/aarch64.h"
     30 
     31 #include "aarch64-tbl.h"
     32 
     33 static int debug = 0;
     34 
     35 /* Structure used in the decoding tree to group a list of aarch64_opcode
     36    entries.  */
     37 
     38 struct opcode_node
     39 {
     40   aarch64_insn opcode;
     41   aarch64_insn mask;
     42   /* Index of the entry in the original table; the top 2 bits help
     43      determine the table.  */
     44   unsigned int index;
     45   struct opcode_node *next;
     46 };
     47 
     48 typedef struct opcode_node opcode_node;
     49 
     50 /* Head of the list of the opcode_node after read_table.  */
     51 static opcode_node opcode_nodes_head;
     52 
     53 /* Node in the decoding tree.  */
     54 
     55 struct bittree
     56 {
     57   unsigned int bitno;
     58   /* 0, 1, and X (don't care).  */
     59   struct bittree *bits[2];
     60   /* List of opcodes; only valid for the leaf node.  */
     61   opcode_node *list;
     62 };
     63 
     64 /* Allocate and initialize an opcode_node.  */
     65 static opcode_node*
     66 new_opcode_node (void)
     67 {
     68   opcode_node* ent = malloc (sizeof (opcode_node));
     69 
     70   if (!ent)
     71     abort ();
     72 
     73   ent->opcode = 0;
     74   ent->mask = 0;
     75   ent->index = -1;
     76   ent->next = NULL;
     77 
     78   return ent;
     79 }
     80 
     81 /* Multiple tables are supported, although currently only one table is
     82    in use.  N.B. there are still some functions have the table name
     83    'aarch64_opcode_table' hard-coded in, e.g. print_find_next_opcode;
     84    therefore some amount of work needs to be done if the full support
     85    for multiple tables needs to be enabled.  */
     86 static const struct aarch64_opcode *aarch64_opcode_tables[] =
     87 {aarch64_opcode_table};
     88 
     89 /* Use top 2 bits to indiate which table.  */
     90 static unsigned int
     91 initialize_index (const struct aarch64_opcode* table)
     92 {
     93   int i;
     94   const int num_of_tables = sizeof (aarch64_opcode_tables)
     95     / sizeof (struct aarch64_opcode *);
     96   for (i = 0; i < num_of_tables; ++i)
     97     if (table == aarch64_opcode_tables [i])
     98       break;
     99   if (i == num_of_tables)
    100     abort ();
    101   return (unsigned int)i << 30;
    102 }
    103 
    104 static inline const struct aarch64_opcode *
    105 index2table (unsigned int index)
    106 {
    107   return aarch64_opcode_tables[(index >> 30) & 0x3];
    108 }
    109 
    110 static inline unsigned int
    111 real_index (unsigned int index)
    112 {
    113   return index & ((1 << 30) - 1);
    114 }
    115 
    116 /* Given OPCODE_NODE, return the corresponding aarch64_opcode*.  */
    117 static const aarch64_opcode*
    118 get_aarch64_opcode (const opcode_node *opcode_node)
    119 {
    120   if (opcode_node == NULL)
    121     return NULL;
    122   return &index2table (opcode_node->index)[real_index (opcode_node->index)];
    123 }
    124 
    125 static void
    126 read_table (const struct aarch64_opcode* table)
    127 {
    128   const struct aarch64_opcode *ent = table;
    129   opcode_node **new_ent;
    130   unsigned int index = initialize_index (table);
    131 
    132   if (!ent->name)
    133     return;
    134 
    135   new_ent = &opcode_nodes_head.next;
    136 
    137   while (*new_ent)
    138     new_ent = &(*new_ent)->next;
    139 
    140   do
    141     {
    142       /* F_PSEUDO needs to be used together with F_ALIAS to indicate an alias
    143 	 opcode is a programmer friendly pseudo instruction available only in
    144 	 the assembly code (thus will not show up in the disassembly).  */
    145       assert (pseudo_opcode_p (ent) == FALSE || alias_opcode_p (ent) == TRUE);
    146       /* Skip alias (inc. pseudo) opcode.  */
    147       if (alias_opcode_p (ent) == TRUE)
    148 	{
    149 	  index++;
    150 	  continue;
    151 	}
    152       *new_ent = new_opcode_node ();
    153       (*new_ent)->opcode = ent->opcode;
    154       (*new_ent)->mask = ent->mask;
    155       (*new_ent)->index = index++;
    156       new_ent = &((*new_ent)->next);
    157     } while ((++ent)->name);
    158 }
    159 
    160 static inline void
    161 print_one_opcode_node (opcode_node* ent)
    162 {
    163   printf ("%s\t%08x\t%08x\t%d\n", get_aarch64_opcode (ent)->name,
    164 	  get_aarch64_opcode (ent)->opcode, get_aarch64_opcode (ent)->mask,
    165 	  (int)real_index (ent->index));
    166 }
    167 
    168 /* As an internal debugging utility, print out the list of nodes pointed
    169    by opcode_nodes_head.  */
    170 static void
    171 print_opcode_nodes (void)
    172 {
    173   opcode_node* ent = opcode_nodes_head.next;
    174   printf ("print_opcode_nodes table:\n");
    175   while (ent)
    176     {
    177       print_one_opcode_node (ent);
    178       ent = ent->next;
    179     }
    180 }
    181 
    182 static struct bittree*
    183 new_bittree_node (void)
    184 {
    185   struct bittree* node;
    186   node = malloc (sizeof (struct bittree));
    187   if (!node)
    188     abort ();
    189   node->bitno = -1;
    190   node->bits[0] = NULL;
    191   node->bits[1] = NULL;
    192   return node;
    193 }
    194 
    195 /* The largest number of opcode entries that exist at a leaf node of the
    196    decoding decision tree.  The reason that there can be more than one
    197    opcode entry is because some opcodes have shared field that is partially
    198    constrained and thus cannot be fully isolated using the algorithm
    199    here.  */
    200 static int max_num_opcodes_at_leaf_node = 0;
    201 
    202 /* Given a list of opcodes headed by *OPCODE, try to establish one bit that
    203    is shared by all the opcodes in the list as one of base opcode bits.  If
    204    such a bit is found, divide the list of the opcodes into two based on the
    205    value of the bit.
    206 
    207    Store the bit number in BITTREE->BITNO if the division succeeds.  If unable
    208    to determine such a bit or there is only one opcode in the list, the list
    209    is decided to be undividable and OPCODE will be assigned to BITTREE->LIST.
    210 
    211    The function recursively call itself until OPCODE is undividable.
    212 
    213    N.B. the nature of this algrithm determines that given any value in the
    214    32-bit space, the computed decision tree will always be able to find one or
    215    more opcodes entries for it, regardless whether there is a valid instruction
    216    defined for this value or not.  In order to detect the undefined values,
    217    when the caller obtains the opcode entry/entries, it should at least compare
    218    the bit-wise AND result of the value and the mask with the base opcode
    219    value; if the two are different, it means that the value is undefined
    220    (although the value may be still undefined when the comparison is the same,
    221    in which case call aarch64_opcode_decode to carry out further checks).  */
    222 
    223 static void
    224 divide_table_1 (struct bittree *bittree, opcode_node *opcode)
    225 {
    226   aarch64_insn mask_and;
    227   opcode_node *ent;
    228   unsigned int bitno;
    229   aarch64_insn bitmask;
    230   opcode_node list0, list1, **ptr0, **ptr1;
    231   static int depth = 0;
    232 
    233   ++depth;
    234 
    235   if (debug)
    236     printf ("Enter into depth %d\n", depth);
    237 
    238   assert (opcode != NULL);
    239 
    240   /* Succeed when there is only one opcode left.  */
    241   if (!opcode->next)
    242     {
    243       if (debug)
    244 	{
    245 	  printf ("opcode isolated:\n");
    246 	  print_one_opcode_node (opcode);
    247 	}
    248       goto divide_table_1_finish;
    249     }
    250 
    251 divide_table_1_try_again:
    252   mask_and = -1;
    253   ent = opcode;
    254   while (ent)
    255     {
    256       mask_and &= ent->mask;
    257       ent = ent->next;
    258     }
    259 
    260   if (debug)
    261     printf ("mask and result: %08x\n", (unsigned int)mask_and);
    262 
    263   /* If no more bit to look into, we have to accept the reality then.  */
    264   if (!mask_and)
    265     {
    266       int i;
    267       opcode_node *ptr;
    268       if (debug)
    269 	{
    270 	  ptr = opcode;
    271 	  printf ("Isolated opcode group:\n");
    272 	  do {
    273 	      print_one_opcode_node (ptr);
    274 	      ptr = ptr->next;
    275 	  } while (ptr);
    276 	}
    277       /* Count the number of opcodes.  */
    278       for (i = 0, ptr = opcode; ptr; ++i)
    279 	ptr = ptr->next;
    280       if (i > max_num_opcodes_at_leaf_node)
    281 	max_num_opcodes_at_leaf_node = i;
    282       goto divide_table_1_finish;
    283     }
    284 
    285   /* Pick up the right most bit that is 1.  */
    286   bitno = 0;
    287   while (!(mask_and & (1 << bitno)))
    288     ++bitno;
    289   bitmask = (1 << bitno);
    290 
    291   if (debug)
    292     printf ("use bit %d\n", bitno);
    293 
    294   /* Record in the bittree.  */
    295   bittree->bitno = bitno;
    296 
    297   /* Get two new opcode lists; adjust their masks.  */
    298   list0.next = NULL;
    299   list1.next = NULL;
    300   ptr0 = &list0.next;
    301   ptr1 = &list1.next;
    302   ent = opcode;
    303   while (ent)
    304     {
    305       if (ent->opcode & bitmask)
    306 	{
    307 	  ent->mask &= (~bitmask);
    308 	  *ptr1 = ent;
    309 	  ent = ent->next;
    310 	  (*ptr1)->next = NULL;
    311 	  ptr1 = &(*ptr1)->next;
    312 	}
    313       else
    314 	{
    315 	  ent->mask &= (~bitmask);
    316 	  *ptr0 = ent;
    317 	  ent = ent->next;
    318 	  (*ptr0)->next = NULL;
    319 	  ptr0 = &(*ptr0)->next;
    320 	}
    321     }
    322 
    323   /* If BITNO can NOT divide the opcode group, try next bit.  */
    324   if (list0.next == NULL)
    325     {
    326       opcode = list1.next;
    327       goto divide_table_1_try_again;
    328     }
    329   else if (list1.next == NULL)
    330     {
    331       opcode = list0.next;
    332       goto divide_table_1_try_again;
    333     }
    334 
    335   /* Further divide.  */
    336   bittree->bits[0] = new_bittree_node ();
    337   bittree->bits[1] = new_bittree_node ();
    338   divide_table_1 (bittree->bits[0], list0.next);
    339   divide_table_1 (bittree->bits[1], list1.next);
    340 
    341 divide_table_1_finish:
    342   if (debug)
    343     printf ("Leave from depth %d\n", depth);
    344   --depth;
    345 
    346   /* Record the opcode entries on this leaf node.  */
    347   bittree->list = opcode;
    348 
    349   return;
    350 }
    351 
    352 /* Call divide_table_1 to divide the all the opcodes and thus create the
    353    decoding decision tree.  */
    354 static struct bittree *
    355 divide_table (void)
    356 {
    357   struct bittree *bittree = new_bittree_node ();
    358   divide_table_1 (bittree, opcode_nodes_head.next);
    359   return bittree;
    360 }
    361 
    362 /* Read in all of the tables, create the decoding decision tree and return
    363    the tree root.  */
    364 static struct bittree *
    365 initialize_decoder_tree (void)
    366 {
    367   int i;
    368   const int num_of_tables = (sizeof (aarch64_opcode_tables)
    369 			     / sizeof (struct aarch64_opcode *));
    370   for (i = 0; i < num_of_tables; ++i)
    371     read_table (aarch64_opcode_tables [i]);
    372   if (debug)
    373     print_opcode_nodes ();
    374   return divide_table ();
    375 }
    376 
    377 static void __attribute__ ((format (printf, 2, 3)))
    378 indented_print (unsigned int indent, const char *format, ...)
    379 {
    380   /* 80 number of spaces pluc a NULL terminator.  */
    381   static const char spaces[81] =
    382     "                                                                                ";
    383   va_list ap;
    384   va_start (ap, format);
    385   assert (indent <= 80);
    386   printf ("%s", &spaces[80 - indent]);
    387   vprintf (format, ap);
    388   va_end (ap);
    389 }
    390 
    391 /* N.B. read the comment above divide_table_1 for the reason why the generated
    392    decision tree function never returns NULL.  */
    393 
    394 static void
    395 print_decision_tree_1 (unsigned int indent, struct bittree* bittree)
    396 {
    397   /* PATTERN is only used to generate comment in the code.  */
    398   static char pattern[33] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    399   assert (bittree != NULL);
    400 
    401   /* Leaf node located.  */
    402   if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
    403     {
    404       assert (bittree->list != NULL);
    405       indented_print (indent, "/* 33222222222211111111110000000000\n");
    406       indented_print (indent, "   10987654321098765432109876543210\n");
    407       indented_print (indent, "   %s\n", pattern);
    408       indented_print (indent, "   %s.  */\n",
    409 		      get_aarch64_opcode (bittree->list)->name);
    410       indented_print (indent, "return %u;\n",
    411 		      real_index (bittree->list->index));
    412       return;
    413     }
    414 
    415   /* Walk down the decoder tree.  */
    416   indented_print (indent, "if (((word >> %d) & 0x1) == 0)\n", bittree->bitno);
    417   indented_print (indent, "  {\n");
    418   pattern[bittree->bitno] = '0';
    419   print_decision_tree_1 (indent + 4, bittree->bits[0]);
    420   indented_print (indent, "  }\n");
    421   indented_print (indent, "else\n");
    422   indented_print (indent, "  {\n");
    423   pattern[bittree->bitno] = '1';
    424   print_decision_tree_1 (indent + 4, bittree->bits[1]);
    425   indented_print (indent, "  }\n");
    426   pattern[bittree->bitno] = 'x';
    427 }
    428 
    429 /* Generate aarch64_opcode_lookup in C code to the standard output.  */
    430 
    431 static void
    432 print_decision_tree (struct bittree* bittree)
    433 {
    434   if (debug)
    435     printf ("Enter print_decision_tree\n");
    436 
    437   printf ("/* Called by aarch64_opcode_lookup.  */\n\n");
    438 
    439   printf ("static int\n");
    440   printf ("aarch64_opcode_lookup_1 (uint32_t word)\n");
    441   printf ("{\n");
    442 
    443   print_decision_tree_1 (2, bittree);
    444 
    445   printf ("}\n\n");
    446 
    447 
    448   printf ("/* Lookup opcode WORD in the opcode table.  N.B. all alias\n");
    449   printf ("   opcodes are ignored here.  */\n\n");
    450 
    451   printf ("const aarch64_opcode *\n");
    452   printf ("aarch64_opcode_lookup (uint32_t word)\n");
    453   printf ("{\n");
    454   printf ("  return aarch64_opcode_table + aarch64_opcode_lookup_1 (word);\n");
    455   printf ("}\n");
    456 }
    457 
    458 static void
    459 print_find_next_opcode_1 (struct bittree* bittree)
    460 {
    461   assert (bittree != NULL);
    462 
    463   /* Leaf node located.  */
    464   if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
    465     {
    466       assert (bittree->list != NULL);
    467       /* Find multiple opcode entries in one leaf node.  */
    468       if (bittree->list->next != NULL)
    469 	{
    470 	  opcode_node *list = bittree->list;
    471 	  while (list != NULL)
    472 	    {
    473 	      const aarch64_opcode *curr = get_aarch64_opcode (list);
    474 	      const aarch64_opcode *next = get_aarch64_opcode (list->next);
    475 
    476 	      printf ("    case %u: ",
    477 		      (unsigned int)(curr - aarch64_opcode_table));
    478 	      if (list->next != NULL)
    479 		{
    480 		  printf ("value = %u; break;\t", real_index (list->next->index));
    481 		  printf ("/* %s --> %s.  */\n", curr->name, next->name);
    482 		}
    483 	      else
    484 		{
    485 		  printf ("return NULL;\t\t");
    486 		  printf ("/* %s --> NULL.  */\n", curr->name);
    487 		}
    488 
    489 	      list = list->next;
    490 	    }
    491 	}
    492       return;
    493     }
    494 
    495   /* Walk down the decoder tree.  */
    496   print_find_next_opcode_1 (bittree->bits[0]);
    497   print_find_next_opcode_1 (bittree->bits[1]);
    498 }
    499 
    500 /* Generate aarch64_find_next_opcode in C code to the standard output.  */
    501 
    502 static void
    503 print_find_next_opcode (struct bittree* bittree)
    504 {
    505   if (debug)
    506     printf ("Enter print_find_next_opcode\n");
    507 
    508   printf ("\n");
    509   printf ("const aarch64_opcode *\n");
    510   printf ("aarch64_find_next_opcode (const aarch64_opcode *opcode)\n");
    511   printf ("{\n");
    512   printf ("  /* Use the index as the key to locate the next opcode.  */\n");
    513   printf ("  int key = opcode - aarch64_opcode_table;\n");
    514   printf ("  int value;\n");
    515   printf ("  switch (key)\n");
    516   printf ("    {\n");
    517 
    518   print_find_next_opcode_1 (bittree);
    519 
    520   printf ("    default: return NULL;\n");
    521   printf ("    }\n\n");
    522 
    523   printf ("  return aarch64_opcode_table + value;\n");
    524   printf ("}\n");
    525 }
    526 
    527 /* Release the dynamic memory resource allocated for the generation of the
    528    decoder tree.  */
    529 
    530 static void
    531 release_resource_decoder_tree (struct bittree* bittree)
    532 {
    533   assert (bittree != NULL);
    534 
    535   /* Leaf node located.  */
    536   if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
    537     {
    538       assert (bittree->list != NULL);
    539       /* Free opcode_nodes.  */
    540       opcode_node *list = bittree->list;
    541       while (list != NULL)
    542 	{
    543 	  opcode_node *next = list->next;
    544 	  free (list);
    545 	  list = next;
    546 	}
    547       /* Free the tree node.  */
    548       free (bittree);
    549       return;
    550     }
    551 
    552   /* Walk down the decoder tree.  */
    553   release_resource_decoder_tree (bittree->bits[0]);
    554   release_resource_decoder_tree (bittree->bits[1]);
    555 
    556   /* Free the tree node.  */
    557   free (bittree);
    558 }
    559 
    560 /* Generate aarch64_find_real_opcode in C code to the standard output.
    561    TABLE points to the alias info table, while NUM indicates the number of
    562    entries in the table.  */
    563 
    564 static void
    565 print_find_real_opcode (const opcode_node *table, int num)
    566 {
    567   int i;
    568 
    569   if (debug)
    570     printf ("Enter print_find_real_opcode\n");
    571 
    572   printf ("\n");
    573   printf ("const aarch64_opcode *\n");
    574   printf ("aarch64_find_real_opcode (const aarch64_opcode *opcode)\n");
    575   printf ("{\n");
    576   printf ("  /* Use the index as the key to locate the real opcode.  */\n");
    577   printf ("  int key = opcode - aarch64_opcode_table;\n");
    578   printf ("  int value;\n");
    579   printf ("  switch (key)\n");
    580   printf ("    {\n");
    581 
    582   for (i = 0; i < num; ++i)
    583     {
    584       const opcode_node *real = table + i;
    585       const opcode_node *alias = real->next;
    586       for (; alias; alias = alias->next)
    587 	printf ("    case %u:\t/* %s */\n", real_index (alias->index),
    588 		get_aarch64_opcode (alias)->name);
    589       printf ("      value = %u;\t/* --> %s.  */\n", real_index (real->index),
    590 	      get_aarch64_opcode (real)->name);
    591       printf ("      break;\n");
    592     }
    593 
    594   printf ("    default: return NULL;\n");
    595   printf ("    }\n\n");
    596 
    597   printf ("  return aarch64_opcode_table + value;\n");
    598   printf ("}\n");
    599 }
    600 
    601 /* Generate aarch64_find_alias_opcode in C code to the standard output.
    602    TABLE points to the alias info table, while NUM indicates the number of
    603    entries in the table.  */
    604 
    605 static void
    606 print_find_alias_opcode (const opcode_node *table, int num)
    607 {
    608   int i;
    609 
    610   if (debug)
    611     printf ("Enter print_find_alias_opcode\n");
    612 
    613   printf ("\n");
    614   printf ("const aarch64_opcode *\n");
    615   printf ("aarch64_find_alias_opcode (const aarch64_opcode *opcode)\n");
    616   printf ("{\n");
    617   printf ("  /* Use the index as the key to locate the alias opcode.  */\n");
    618   printf ("  int key = opcode - aarch64_opcode_table;\n");
    619   printf ("  int value;\n");
    620   printf ("  switch (key)\n");
    621   printf ("    {\n");
    622 
    623   for (i = 0; i < num; ++i)
    624     {
    625       const opcode_node *node = table + i;
    626       assert (node->next);
    627       printf ("    case %u: value = %u; break;", real_index (node->index),
    628 	      real_index (node->next->index));
    629       printf ("\t/* %s --> %s.  */\n", get_aarch64_opcode (node)->name,
    630 	      get_aarch64_opcode (node->next)->name);
    631     }
    632 
    633   printf ("    default: return NULL;\n");
    634   printf ("    }\n\n");
    635 
    636   printf ("  return aarch64_opcode_table + value;\n");
    637   printf ("}\n");
    638 }
    639 
    640 /* Generate aarch64_find_next_alias_opcode in C code to the standard output.
    641    TABLE points to the alias info table, while NUM indicates the number of
    642    entries in the table.  */
    643 
    644 static void
    645 print_find_next_alias_opcode (const opcode_node *table, int num)
    646 {
    647   int i;
    648 
    649   if (debug)
    650     printf ("Enter print_find_next_alias_opcode\n");
    651 
    652   printf ("\n");
    653   printf ("const aarch64_opcode *\n");
    654   printf ("aarch64_find_next_alias_opcode (const aarch64_opcode *opcode)\n");
    655   printf ("{\n");
    656   printf ("  /* Use the index as the key to locate the next opcode.  */\n");
    657   printf ("  int key = opcode - aarch64_opcode_table;\n");
    658   printf ("  int value;\n");
    659   printf ("  switch (key)\n");
    660   printf ("    {\n");
    661 
    662   for (i = 0; i < num; ++i)
    663     {
    664       const opcode_node *node = table + i;
    665       assert (node->next);
    666       if (node->next->next == NULL)
    667 	continue;
    668       while (node->next->next)
    669 	{
    670 	  printf ("    case %u: value = %u; break;", real_index (node->next->index),
    671 		 real_index (node->next->next->index));
    672 	  printf ("\t/* %s --> %s.  */\n",
    673 		  get_aarch64_opcode (node->next)->name,
    674 		  get_aarch64_opcode (node->next->next)->name);
    675 	  node = node->next;
    676 	}
    677     }
    678 
    679   printf ("    default: return NULL;\n");
    680   printf ("    }\n\n");
    681 
    682   printf ("  return aarch64_opcode_table + value;\n");
    683   printf ("}\n");
    684 }
    685 
    686 /* Given OPCODE, establish and return a link list of alias nodes in the
    687    preferred order.  */
    688 
    689 opcode_node *
    690 find_alias_opcode (const aarch64_opcode *opcode)
    691 {
    692   int i;
    693   /* Assume maximum of 8 disassemble preference candidates.  */
    694   const int max_num_aliases = 8;
    695   const aarch64_opcode *ent;
    696   const aarch64_opcode *preferred[max_num_aliases];
    697   opcode_node head, **next;
    698 
    699   assert (opcode_has_alias (opcode));
    700 
    701   i = 0;
    702   ent = aarch64_opcode_table;
    703   while (ent->name != NULL)
    704     {
    705       /* The mask of an alias opcode must be equal to or a super-set (i.e.
    706 	 more constrained) of that of the aliased opcode; so is the base
    707 	 opcode value.  */
    708       if (alias_opcode_p (ent) == TRUE
    709 	  && (ent->mask & opcode->mask) == opcode->mask
    710 	  && (opcode->mask & ent->opcode) == (opcode->mask & opcode->opcode))
    711 	{
    712 	  assert (i < max_num_aliases);
    713 	  preferred[i++] = ent;
    714 	  if (debug)
    715 	    printf ("found %s for %s.", ent->name, opcode->name);
    716 	}
    717       ++ent;
    718     }
    719 
    720   if (debug)
    721     {
    722       int m;
    723       printf ("un-orderd list: ");
    724       for (m = 0; m < i; ++m)
    725 	printf ("%s, ", preferred[m]->name);
    726       printf ("\n");
    727     }
    728 
    729   /* There must be at least one alias.  */
    730   assert (i >= 1);
    731 
    732   /* Sort preferred array according to the priority (from the lowest to the
    733      highest.  */
    734   if (i > 1)
    735     {
    736       int j, k;
    737       for (j = 0; j < i - 1; ++j)
    738 	{
    739 	  for (k = 0; k < i - 1 - j; ++k)
    740 	    {
    741 	      const aarch64_opcode *t;
    742 	      t = preferred [k+1];
    743 	      if (opcode_priority (t) < opcode_priority (preferred [k]))
    744 		{
    745 		  preferred [k+1] = preferred [k];
    746 		  preferred [k] = t;
    747 		}
    748 	    }
    749 	}
    750     }
    751 
    752   if (debug)
    753     {
    754       int m;
    755       printf ("orderd list: ");
    756       for (m = 0; m < i; ++m)
    757 	printf ("%s, ", preferred[m]->name);
    758       printf ("\n");
    759     }
    760 
    761   /* Create a link-list of opcode_node with disassemble preference from
    762      higher to lower.  */
    763   next = &head.next;
    764   --i;
    765   while (i >= 0)
    766     {
    767       const aarch64_opcode *alias = preferred [i];
    768       opcode_node *node = new_opcode_node ();
    769 
    770       if (debug)
    771 	printf ("add %s.\n", alias->name);
    772 
    773       node->index = alias - aarch64_opcode_table;
    774       *next = node;
    775       next = &node->next;
    776 
    777       --i;
    778     }
    779   *next = NULL;
    780 
    781   return head.next;
    782 }
    783 
    784 /* Create and return alias information.
    785    Return the address of the created alias info table; return the number
    786    of table entries in *NUM_PTR.  */
    787 
    788 opcode_node *
    789 create_alias_info (int *num_ptr)
    790 {
    791   int i, num;
    792   opcode_node *ret;
    793   const aarch64_opcode *ent;
    794 
    795   /* Calculate the total number of opcodes that have alias.  */
    796   num = 0;
    797   ent = aarch64_opcode_table;
    798   while (ent->name != NULL)
    799     {
    800       if (opcode_has_alias (ent))
    801 	{
    802 	  /* Assert the alias relationship be flat-structured to keep
    803 	     algorithms simple; not allow F_ALIAS and F_HAS_ALIAS both
    804 	     specified.  */
    805 	  assert (!alias_opcode_p (ent));
    806 	  ++num;
    807 	}
    808       ++ent;
    809     }
    810   assert (num_ptr);
    811   *num_ptr = num;
    812 
    813   /* The array of real opcodes that have alias(es).  */
    814   ret = malloc (sizeof (opcode_node) * num);
    815 
    816   /* For each opcode, establish a list of alias nodes in a preferred
    817      order.  */
    818   for (i = 0, ent = aarch64_opcode_table; i < num; ++i, ++ent)
    819     {
    820       opcode_node *node = ret + i;
    821       while (ent->name != NULL && !opcode_has_alias (ent))
    822 	++ent;
    823       assert (ent->name != NULL);
    824       node->index = ent - aarch64_opcode_table;
    825       node->next = find_alias_opcode (ent);
    826       assert (node->next);
    827     }
    828   assert (i == num);
    829 
    830   return ret;
    831 }
    832 
    833 /* Release the dynamic memory resource allocated for the generation of the
    834    alias information.  */
    835 
    836 void
    837 release_resource_alias_info (opcode_node *alias_info, int num)
    838 {
    839   int i = 0;
    840   opcode_node *node = alias_info;
    841 
    842   /* Free opcode_node list.  */
    843   for (; i < num; ++i, ++node)
    844     {
    845       opcode_node *list = node->next;
    846       do
    847 	{
    848 	  opcode_node *next = list->next;
    849 	  free (list);
    850 	  list = next;
    851 	} while (list != NULL);
    852     }
    853 
    854   /* Free opcode_node array.  */
    855   free (alias_info);
    856 }
    857 
    858 /* As a debugging utility, print out the result of the table division, although
    859    it is not doing much this moment.  */
    860 static void
    861 print_divide_result (const struct bittree *bittree ATTRIBUTE_UNUSED)
    862 {
    863   printf ("max_num_opcodes_at_leaf_node: %d\n", max_num_opcodes_at_leaf_node);
    864   return;
    865 }
    866 
    867 /* Structure to help generate the operand table.  */
    869 struct operand
    870 {
    871   const char *class;
    872   const char *inserter;
    873   const char *extractor;
    874   const char *str;
    875   const char *flags;
    876   const char *fields;
    877   const char *desc;
    878   unsigned processed : 1;
    879   unsigned has_inserter : 1;
    880   unsigned has_extractor : 1;
    881 };
    882 
    883 typedef struct operand operand;
    884 
    885 #ifdef X
    886 #undef X
    887 #endif
    888 
    889 #ifdef Y
    890 #undef Y
    891 #endif
    892 
    893 #ifdef F
    894 #undef F
    895 #endif
    896 
    897 /* Get the operand information in strings.  */
    898 
    899 static operand operands[] =
    900 {
    901     {"NIL", "0", "0", "", "0", "{0}", "<none>", 0, 0, 0},
    902 #define F(...)	#__VA_ARGS__
    903 #define X(a,b,c,d,e,f,g)	\
    904     {#a, #b, #c, d, #e, "{"f"}", g, 0, 0, 0},
    905 #define Y(a,b,d,e,f,g)		\
    906     {#a, "ins_"#b, "ext_"#b, d, #e, "{"f"}", g, 0, 0, 0},
    907     AARCH64_OPERANDS
    908     {"NIL", "0", "0", "", "0", "{0}", "DUMMY", 0, 0, 0},
    909 };
    910 
    911 #undef F
    912 #undef X
    913 
    914 static void
    915 process_operand_table (void)
    916 {
    917   int i;
    918   operand *opnd;
    919   const int num = sizeof (operands) / sizeof (operand);
    920 
    921   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
    922     {
    923       opnd->has_inserter = opnd->inserter[0] != '0';
    924       opnd->has_extractor = opnd->extractor[0] != '0';
    925     }
    926 }
    927 
    928 /* Generate aarch64_operands in C to the standard output.  */
    929 
    930 static void
    931 print_operand_table (void)
    932 {
    933   int i;
    934   operand *opnd;
    935   const int num = sizeof (operands) / sizeof (operand);
    936 
    937   if (debug)
    938     printf ("Enter print_operand_table\n");
    939 
    940   printf ("\n");
    941   printf ("const struct aarch64_operand aarch64_operands[] =\n");
    942   printf ("{\n");
    943 
    944   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
    945     {
    946       char flags[256];
    947       flags[0] = '\0';
    948       if (opnd->flags[0] != '0')
    949 	sprintf (flags, "%s", opnd->flags);
    950       if (opnd->has_inserter)
    951 	{
    952 	  if (flags[0] != '\0')
    953 	    strcat (flags, " | ");
    954 	  strcat (flags, "OPD_F_HAS_INSERTER");
    955 	}
    956       if (opnd->has_extractor)
    957 	{
    958 	  if (flags[0] != '\0')
    959 	    strcat (flags, " | ");
    960 	  strcat (flags, "OPD_F_HAS_EXTRACTOR");
    961 	}
    962       if (flags[0] == '\0')
    963 	{
    964 	  flags[0] = '0';
    965 	  flags[1] = '\0';
    966 	}
    967     printf ("  {AARCH64_OPND_CLASS_%s, \"%s\", %s, %s, \"%s\"},\n",
    968 	    opnd->class, opnd->str, flags, opnd->fields, opnd->desc);
    969     }
    970   printf ("};\n");
    971 }
    972 
    973 /* Generate aarch64_insert_operand in C to the standard output.  */
    974 
    975 static void
    976 print_operand_inserter (void)
    977 {
    978   int i;
    979   operand *opnd;
    980   const int num = sizeof (operands) / sizeof (operand);
    981 
    982   if (debug)
    983     printf ("Enter print_operand_inserter\n");
    984 
    985   printf ("\n");
    986   printf ("const char*\n");
    987   printf ("aarch64_insert_operand (const aarch64_operand *self,\n\
    988 			   const aarch64_opnd_info *info,\n\
    989 			   aarch64_insn *code, const aarch64_inst *inst)\n");
    990   printf ("{\n");
    991   printf ("  /* Use the index as the key.  */\n");
    992   printf ("  int key = self - aarch64_operands;\n");
    993   printf ("  switch (key)\n");
    994   printf ("    {\n");
    995 
    996   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
    997     opnd->processed = 0;
    998 
    999   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
   1000     {
   1001       if (!opnd->processed && opnd->has_inserter)
   1002 	{
   1003 	  int j = i + 1;
   1004 	  const int len = strlen (opnd->inserter);
   1005 	  operand *opnd2 = opnd + 1;
   1006 	  printf ("    case %u:\n", (unsigned int)(opnd - operands));
   1007 	  opnd->processed = 1;
   1008 	  for (; j < num; ++j, ++opnd2)
   1009 	    {
   1010 	      if (!opnd2->processed
   1011 		  && opnd2->has_inserter
   1012 		  && len == strlen (opnd2->inserter)
   1013 		  && strncmp (opnd->inserter, opnd2->inserter, len) == 0)
   1014 		{
   1015 		  printf ("    case %u:\n", (unsigned int)(opnd2 - operands));
   1016 		  opnd2->processed = 1;
   1017 		}
   1018 	    }
   1019 	  printf ("      return aarch64_%s (self, info, code, inst);\n",
   1020 		  opnd->inserter);
   1021 	}
   1022     }
   1023 
   1024   printf ("    default: assert (0); abort ();\n");
   1025   printf ("    }\n");
   1026   printf ("}\n");
   1027 }
   1028 
   1029 /* Generate aarch64_extract_operand in C to the standard output.  */
   1030 
   1031 static void
   1032 print_operand_extractor (void)
   1033 {
   1034   int i;
   1035   operand *opnd;
   1036   const int num = sizeof (operands) / sizeof (operand);
   1037 
   1038   if (debug)
   1039     printf ("Enter print_operand_extractor\n");
   1040 
   1041   printf ("\n");
   1042   printf ("int\n");
   1043   printf ("aarch64_extract_operand (const aarch64_operand *self,\n\
   1044 			   aarch64_opnd_info *info,\n\
   1045 			   aarch64_insn code, const aarch64_inst *inst)\n");
   1046   printf ("{\n");
   1047   printf ("  /* Use the index as the key.  */\n");
   1048   printf ("  int key = self - aarch64_operands;\n");
   1049   printf ("  switch (key)\n");
   1050   printf ("    {\n");
   1051 
   1052   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
   1053     opnd->processed = 0;
   1054 
   1055   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
   1056     {
   1057       if (!opnd->processed && opnd->has_extractor)
   1058 	{
   1059 	  int j = i + 1;
   1060 	  const int len = strlen (opnd->extractor);
   1061 	  operand *opnd2 = opnd + 1;
   1062 	  printf ("    case %u:\n", (unsigned int)(opnd - operands));
   1063 	  opnd->processed = 1;
   1064 	  for (; j < num; ++j, ++opnd2)
   1065 	    {
   1066 	      if (!opnd2->processed
   1067 		  && opnd2->has_extractor
   1068 		  && len == strlen (opnd2->extractor)
   1069 		  && strncmp (opnd->extractor, opnd2->extractor, len) == 0)
   1070 		{
   1071 		  printf ("    case %u:\n", (unsigned int)(opnd2 - operands));
   1072 		  opnd2->processed = 1;
   1073 		}
   1074 	    }
   1075 	  printf ("      return aarch64_%s (self, info, code, inst);\n",
   1076 		  opnd->extractor);
   1077 	}
   1078     }
   1079 
   1080   printf ("    default: assert (0); abort ();\n");
   1081   printf ("    }\n");
   1082   printf ("}\n");
   1083 }
   1084 
   1085 /* Table indexed by opcode enumerator stores the index of the corresponding
   1087    opcode entry in aarch64_opcode_table.  */
   1088 static unsigned op_enum_table [OP_TOTAL_NUM];
   1089 
   1090 /* Print out the routine which, given the opcode enumerator, returns the
   1091    corresponding opcode entry pointer.  */
   1092 
   1093 static void
   1094 print_get_opcode (void)
   1095 {
   1096   int i;
   1097   const int num = OP_TOTAL_NUM;
   1098   const aarch64_opcode *opcode;
   1099 
   1100   if (debug)
   1101     printf ("Enter print_get_opcode\n");
   1102 
   1103   /* Fill in the internal table.  */
   1104   opcode = aarch64_opcode_table;
   1105   while (opcode->name != NULL)
   1106     {
   1107       if (opcode->op != OP_NIL)
   1108 	{
   1109 	  /* Assert opcode enumerator be unique, in other words, no shared by
   1110 	     different opcodes.  */
   1111 	  if (op_enum_table[opcode->op] != 0)
   1112 	    {
   1113 	      fprintf (stderr, "Opcode %u is shared by different %s and %s.\n",
   1114 		       opcode->op,
   1115 		       aarch64_opcode_table[op_enum_table[opcode->op]].name,
   1116 		       opcode->name);
   1117 	      assert (0);
   1118 	      abort ();
   1119 	    }
   1120 	  assert (opcode->op < OP_TOTAL_NUM);
   1121 	  op_enum_table[opcode->op] = opcode - aarch64_opcode_table;
   1122 	}
   1123       ++opcode;
   1124     }
   1125 
   1126   /* Print the table.  */
   1127   printf ("\n");
   1128   printf ("/* Indexed by an enum aarch64_op enumerator, the value is the offset of\n\
   1129    the corresponding aarch64_opcode entry in the aarch64_opcode_table.  */\n\n");
   1130   printf ("static const unsigned op_enum_table [] =\n");
   1131   printf ("{\n");
   1132   for (i = 0; i < num; ++i)
   1133     printf ("  %u,\n", op_enum_table[i]);
   1134   printf ("};\n");
   1135 
   1136   /* Print the function.  */
   1137   printf ("\n");
   1138   printf ("/* Given the opcode enumerator OP, return the pointer to the corresponding\n");
   1139   printf ("   opcode entry.  */\n");
   1140   printf ("\n");
   1141   printf ("const aarch64_opcode *\n");
   1142   printf ("aarch64_get_opcode (enum aarch64_op op)\n");
   1143   printf ("{\n");
   1144   printf ("  return aarch64_opcode_table + op_enum_table[op];\n");
   1145   printf ("}\n");
   1146 }
   1147 
   1148 /* Print out the content of an opcode table (not in use).  */
   1149 static void ATTRIBUTE_UNUSED
   1150 print_table (struct aarch64_opcode* table)
   1151 {
   1152   struct aarch64_opcode *ent = table;
   1153   do
   1154     {
   1155       printf ("%s\t%08x\t%08x\n", ent->name, (unsigned int)ent->opcode,
   1156 	      (unsigned int)ent->mask);
   1157     } while ((++ent)->name);
   1158 }
   1159 
   1160 static const char * program_name = NULL;
   1162 
   1163 /* Program options.  */
   1164 struct option long_options[] =
   1165 {
   1166   {"debug",   no_argument,       NULL, 'd'},
   1167   {"version", no_argument,       NULL, 'V'},
   1168   {"help",    no_argument,       NULL, 'h'},
   1169   {"gen-opc", no_argument,       NULL, 'c'},
   1170   {"gen-asm", no_argument,       NULL, 'a'},
   1171   {"gen-dis", no_argument,       NULL, 's'},
   1172   {0,         no_argument,       NULL, 0}
   1173 };
   1174 
   1175 static void
   1176 print_version (void)
   1177 {
   1178   printf ("%s: version 1.0\n", program_name);
   1179   xexit (0);
   1180 }
   1181 
   1182 static void
   1183 usage (FILE * stream, int status)
   1184 {
   1185   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--help]\n",
   1186 	   program_name);
   1187   fprintf (stream, "\t[ [-c | --gen-opc] | [-a | --gen-asm] | [-s | --gen-dis] ]\n");
   1188   xexit (status);
   1189 }
   1190 
   1191 int
   1192 main (int argc, char **argv)
   1193 {
   1194   extern int chdir (char *);
   1195   int c;
   1196   int gen_opcode_p = 0;
   1197   int gen_assembler_p = 0;
   1198   int gen_disassembler_p = 0;
   1199 
   1200   program_name = *argv;
   1201   xmalloc_set_program_name (program_name);
   1202 
   1203   while ((c = getopt_long (argc, argv, "vVdhacs", long_options, 0)) != EOF)
   1204     switch (c)
   1205       {
   1206       case 'V':
   1207       case 'v':
   1208 	print_version ();
   1209 	break;
   1210       case 'd':
   1211 	debug = 1;
   1212 	break;
   1213       case 'h':
   1214       case '?':
   1215 	usage (stderr, 0);
   1216 	break;
   1217       case 'c':
   1218 	gen_opcode_p = 1;
   1219 	break;
   1220       case 'a':
   1221 	gen_assembler_p = 1;
   1222 	break;
   1223       case 's':
   1224 	gen_disassembler_p = 1;
   1225 	break;
   1226       default:
   1227       case 0:
   1228 	break;
   1229       }
   1230 
   1231   if (argc == 1 || optind != argc)
   1232     usage (stdout, 1);
   1233 
   1234   if (gen_opcode_p + gen_assembler_p + gen_disassembler_p > 1)
   1235     {
   1236       printf ("Please specify only one of the following options\n\
   1237 	      [-c | --gen-opc] [-a | --gen-asm] [-s | --gen-dis]\n");
   1238       xexit (2);
   1239     }
   1240 
   1241   struct bittree *decoder_tree;
   1242 
   1243   decoder_tree = initialize_decoder_tree ();
   1244   if (debug)
   1245     print_divide_result (decoder_tree);
   1246 
   1247   printf ("/* This file is automatically generated by aarch64-gen.  Do not edit!  */\n");
   1248   printf ("/* Copyright (C) 2012-2015 Free Software Foundation, Inc.\n\
   1249    Contributed by ARM Ltd.\n\
   1250 \n\
   1251    This file is part of the GNU opcodes library.\n\
   1252 \n\
   1253    This library is free software; you can redistribute it and/or modify\n\
   1254    it under the terms of the GNU General Public License as published by\n\
   1255    the Free Software Foundation; either version 3, or (at your option)\n\
   1256    any later version.\n\
   1257 \n\
   1258    It is distributed in the hope that it will be useful, but WITHOUT\n\
   1259    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
   1260    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
   1261    License for more details.\n\
   1262 \n\
   1263    You should have received a copy of the GNU General Public License\n\
   1264    along with this program; see the file COPYING3. If not,\n\
   1265    see <http://www.gnu.org/licenses/>.  */\n");
   1266 
   1267   printf ("\n");
   1268   printf ("#include \"sysdep.h\"\n");
   1269   if (gen_opcode_p)
   1270     printf ("#include \"aarch64-opc.h\"\n");
   1271   if (gen_assembler_p)
   1272     printf ("#include \"aarch64-asm.h\"\n");
   1273   if (gen_disassembler_p)
   1274     printf ("#include \"aarch64-dis.h\"\n");
   1275   printf ("\n");
   1276 
   1277   /* Generate opcode entry lookup for the disassembler.  */
   1278   if (gen_disassembler_p)
   1279     {
   1280       print_decision_tree (decoder_tree);
   1281       print_find_next_opcode (decoder_tree);
   1282       release_resource_decoder_tree (decoder_tree);
   1283     }
   1284 
   1285   /* Generate alias opcode handling for the assembler or the disassembler.  */
   1286   if (gen_assembler_p || gen_disassembler_p)
   1287     {
   1288       int num;
   1289       opcode_node *alias_info = create_alias_info (&num);
   1290 
   1291       if (gen_assembler_p)
   1292 	print_find_real_opcode (alias_info, num);
   1293 
   1294       if (gen_disassembler_p)
   1295 	{
   1296 	  print_find_alias_opcode (alias_info, num);
   1297 	  print_find_next_alias_opcode (alias_info, num);
   1298 	}
   1299 
   1300       release_resource_alias_info (alias_info, num);
   1301     }
   1302 
   1303   /* Generate operand table.  */
   1304   process_operand_table ();
   1305 
   1306   if (gen_assembler_p)
   1307     print_operand_inserter ();
   1308 
   1309   if (gen_disassembler_p)
   1310     print_operand_extractor ();
   1311 
   1312   if (gen_opcode_p)
   1313     print_operand_table ();
   1314 
   1315   /* Generate utility to return aarch64_opcode entry given an enumerator.  */
   1316   if (gen_opcode_p)
   1317     print_get_opcode ();
   1318 
   1319   exit (0);
   1320 }
   1321