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