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