xref: /netbsd-src/external/gpl3/gdb/dist/opcodes/aarch64-gen.c (revision f08ca6a2648c582b262283d26d9571a611813c48)
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.  */
907 struct operand
908 {
909   const char *class;
910   const char *inserter;
911   const char *extractor;
912   const char *str;
913   const char *flags;
914   const char *fields;
915   const char *desc;
916   unsigned processed : 1;
917   unsigned has_inserter : 1;
918   unsigned has_extractor : 1;
919 };
920 
921 typedef struct operand operand;
922 
923 #ifdef X
924 #undef X
925 #endif
926 
927 #ifdef Y
928 #undef Y
929 #endif
930 
931 #ifdef F
932 #undef F
933 #endif
934 
935 /* Get the operand information in strings.  */
936 
937 static operand operands[] =
938 {
939     {"NIL", "0", "0", "", "0", "{0}", "<none>", 0, 0, 0},
940 #define F(...)	#__VA_ARGS__
941 #define X(a,b,c,d,e,f,g)	\
942     {#a, #b, #c, d, #e, "{"f"}", g, 0, 0, 0},
943 #define Y(a,b,d,e,f,g)		\
944     {#a, "ins_"#b, "ext_"#b, d, #e, "{"f"}", g, 0, 0, 0},
945     AARCH64_OPERANDS
946     {"NIL", "0", "0", "", "0", "{0}", "DUMMY", 0, 0, 0},
947 };
948 
949 #undef F
950 #undef X
951 
952 static void
953 process_operand_table (void)
954 {
955   int i;
956   operand *opnd;
957   const int num = sizeof (operands) / sizeof (operand);
958 
959   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
960     {
961       opnd->has_inserter = opnd->inserter[0] != '0';
962       opnd->has_extractor = opnd->extractor[0] != '0';
963     }
964 }
965 
966 /* Generate aarch64_operands in C to the standard output.  */
967 
968 static void
969 print_operand_table (void)
970 {
971   int i;
972   operand *opnd;
973   const int num = sizeof (operands) / sizeof (operand);
974 
975   if (debug)
976     printf ("Enter print_operand_table\n");
977 
978   printf ("\n");
979   printf ("const struct aarch64_operand aarch64_operands[] =\n");
980   printf ("{\n");
981 
982   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
983     {
984       char flags[256];
985       flags[0] = '\0';
986       if (opnd->flags[0] != '0')
987 	sprintf (flags, "%s", opnd->flags);
988       if (opnd->has_inserter)
989 	{
990 	  if (flags[0] != '\0')
991 	    strcat (flags, " | ");
992 	  strcat (flags, "OPD_F_HAS_INSERTER");
993 	}
994       if (opnd->has_extractor)
995 	{
996 	  if (flags[0] != '\0')
997 	    strcat (flags, " | ");
998 	  strcat (flags, "OPD_F_HAS_EXTRACTOR");
999 	}
1000       if (flags[0] == '\0')
1001 	{
1002 	  flags[0] = '0';
1003 	  flags[1] = '\0';
1004 	}
1005     printf ("  {AARCH64_OPND_CLASS_%s, \"%s\", %s, %s, \"%s\"},\n",
1006 	    opnd->class, opnd->str, flags, opnd->fields, opnd->desc);
1007     }
1008   printf ("};\n");
1009 }
1010 
1011 /* Generate aarch64_insert_operand in C to the standard output.  */
1012 
1013 static void
1014 print_operand_inserter (void)
1015 {
1016   int i;
1017   operand *opnd;
1018   const int num = sizeof (operands) / sizeof (operand);
1019 
1020   if (debug)
1021     printf ("Enter print_operand_inserter\n");
1022 
1023   printf ("\n");
1024   printf ("bool\n");
1025   printf ("aarch64_insert_operand (const aarch64_operand *self,\n\
1026 			   const aarch64_opnd_info *info,\n\
1027 			   aarch64_insn *code, const aarch64_inst *inst,\n\
1028 			   aarch64_operand_error *errors)\n");
1029   printf ("{\n");
1030   printf ("  /* Use the index as the key.  */\n");
1031   printf ("  int key = self - aarch64_operands;\n");
1032   printf ("  switch (key)\n");
1033   printf ("    {\n");
1034 
1035   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1036     opnd->processed = 0;
1037 
1038   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1039     {
1040       if (!opnd->processed && opnd->has_inserter)
1041 	{
1042 	  int j = i + 1;
1043 	  const int len = strlen (opnd->inserter);
1044 	  operand *opnd2 = opnd + 1;
1045 	  printf ("    case %u:\n", (unsigned int)(opnd - operands));
1046 	  opnd->processed = 1;
1047 	  for (; j < num; ++j, ++opnd2)
1048 	    {
1049 	      if (!opnd2->processed
1050 		  && opnd2->has_inserter
1051 		  && len == strlen (opnd2->inserter)
1052 		  && strncmp (opnd->inserter, opnd2->inserter, len) == 0)
1053 		{
1054 		  printf ("    case %u:\n", (unsigned int)(opnd2 - operands));
1055 		  opnd2->processed = 1;
1056 		}
1057 	    }
1058 	  printf ("      return aarch64_%s (self, info, code, inst, errors);\n",
1059 		  opnd->inserter);
1060 	}
1061     }
1062 
1063   printf ("    default: assert (0); abort ();\n");
1064   printf ("    }\n");
1065   printf ("}\n");
1066 }
1067 
1068 /* Generate aarch64_extract_operand in C to the standard output.  */
1069 
1070 static void
1071 print_operand_extractor (void)
1072 {
1073   int i;
1074   operand *opnd;
1075   const int num = sizeof (operands) / sizeof (operand);
1076 
1077   if (debug)
1078     printf ("Enter print_operand_extractor\n");
1079 
1080   printf ("\n");
1081   printf ("bool\n");
1082   printf ("aarch64_extract_operand (const aarch64_operand *self,\n\
1083 			   aarch64_opnd_info *info,\n\
1084 			   aarch64_insn code, const aarch64_inst *inst,\n\
1085 			   aarch64_operand_error *errors)\n");
1086   printf ("{\n");
1087   printf ("  /* Use the index as the key.  */\n");
1088   printf ("  int key = self - aarch64_operands;\n");
1089   printf ("  switch (key)\n");
1090   printf ("    {\n");
1091 
1092   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1093     opnd->processed = 0;
1094 
1095   for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1096     {
1097       if (!opnd->processed && opnd->has_extractor)
1098 	{
1099 	  int j = i + 1;
1100 	  const int len = strlen (opnd->extractor);
1101 	  operand *opnd2 = opnd + 1;
1102 	  printf ("    case %u:\n", (unsigned int)(opnd - operands));
1103 	  opnd->processed = 1;
1104 	  for (; j < num; ++j, ++opnd2)
1105 	    {
1106 	      if (!opnd2->processed
1107 		  && opnd2->has_extractor
1108 		  && len == strlen (opnd2->extractor)
1109 		  && strncmp (opnd->extractor, opnd2->extractor, len) == 0)
1110 		{
1111 		  printf ("    case %u:\n", (unsigned int)(opnd2 - operands));
1112 		  opnd2->processed = 1;
1113 		}
1114 	    }
1115 	  printf ("      return aarch64_%s (self, info, code, inst, errors);\n",
1116 		  opnd->extractor);
1117 	}
1118     }
1119 
1120   printf ("    default: assert (0); abort ();\n");
1121   printf ("    }\n");
1122   printf ("}\n");
1123 }
1124 
1125 /* Table indexed by opcode enumerator stores the index of the corresponding
1126    opcode entry in aarch64_opcode_table.  */
1127 static unsigned op_enum_table [OP_TOTAL_NUM];
1128 
1129 /* Print out the routine which, given the opcode enumerator, returns the
1130    corresponding opcode entry pointer.  */
1131 
1132 static void
1133 print_get_opcode (void)
1134 {
1135   int i;
1136   const int num = OP_TOTAL_NUM;
1137   const aarch64_opcode *opcode;
1138 
1139   if (debug)
1140     printf ("Enter print_get_opcode\n");
1141 
1142   /* Fill in the internal table.  */
1143   opcode = aarch64_opcode_table;
1144   while (opcode->name != NULL)
1145     {
1146       if (opcode->op != OP_NIL)
1147 	{
1148 	  /* Assert opcode enumerator be unique, in other words, no shared by
1149 	     different opcodes.  */
1150 	  if (op_enum_table[opcode->op] != 0)
1151 	    {
1152 	      fprintf (stderr, "Opcode %u is shared by different %s and %s.\n",
1153 		       opcode->op,
1154 		       aarch64_opcode_table[op_enum_table[opcode->op]].name,
1155 		       opcode->name);
1156 	      assert (0);
1157 	      abort ();
1158 	    }
1159 	  assert (opcode->op < OP_TOTAL_NUM);
1160 	  op_enum_table[opcode->op] = opcode - aarch64_opcode_table;
1161 	}
1162       ++opcode;
1163     }
1164 
1165   /* Print the table.  */
1166   printf ("\n");
1167   printf ("/* Indexed by an enum aarch64_op enumerator, the value is the offset of\n\
1168    the corresponding aarch64_opcode entry in the aarch64_opcode_table.  */\n\n");
1169   printf ("static const unsigned op_enum_table [] =\n");
1170   printf ("{\n");
1171   for (i = 0; i < num; ++i)
1172     printf ("  %u,\n", op_enum_table[i]);
1173   printf ("};\n");
1174 
1175   /* Print the function.  */
1176   printf ("\n");
1177   printf ("/* Given the opcode enumerator OP, return the pointer to the corresponding\n");
1178   printf ("   opcode entry.  */\n");
1179   printf ("\n");
1180   printf ("const aarch64_opcode *\n");
1181   printf ("aarch64_get_opcode (enum aarch64_op op)\n");
1182   printf ("{\n");
1183   printf ("  return aarch64_opcode_table + op_enum_table[op];\n");
1184   printf ("}\n");
1185 }
1186 
1187 /* Print out the content of an opcode table (not in use).  */
1188 static void ATTRIBUTE_UNUSED
1189 print_table (struct aarch64_opcode* table)
1190 {
1191   struct aarch64_opcode *ent = table;
1192   do
1193     {
1194       printf ("%s\t%08x\t%08x\n", ent->name, (unsigned int)ent->opcode,
1195 	      (unsigned int)ent->mask);
1196     } while ((++ent)->name);
1197 }
1198 
1199 static const char * program_name = NULL;
1200 
1201 /* Program options.  */
1202 struct option long_options[] =
1203 {
1204   {"debug",   no_argument,       NULL, 'd'},
1205   {"version", no_argument,       NULL, 'V'},
1206   {"help",    no_argument,       NULL, 'h'},
1207   {"gen-opc", no_argument,       NULL, 'c'},
1208   {"gen-asm", no_argument,       NULL, 'a'},
1209   {"gen-dis", no_argument,       NULL, 's'},
1210   {0,         no_argument,       NULL, 0}
1211 };
1212 
1213 static void
1214 print_version (void)
1215 {
1216   printf ("%s: version 1.0\n", program_name);
1217   xexit (0);
1218 }
1219 
1220 static void
1221 usage (FILE * stream, int status)
1222 {
1223   fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--help]\n",
1224 	   program_name);
1225   fprintf (stream, "\t[ [-c | --gen-opc] | [-a | --gen-asm] | [-s | --gen-dis] ]\n");
1226   xexit (status);
1227 }
1228 
1229 int
1230 main (int argc, char **argv)
1231 {
1232   extern int chdir (char *);
1233   int c;
1234   int gen_opcode_p = 0;
1235   int gen_assembler_p = 0;
1236   int gen_disassembler_p = 0;
1237 
1238   program_name = *argv;
1239   xmalloc_set_program_name (program_name);
1240 
1241   while ((c = getopt_long (argc, argv, "vVdhacs", long_options, 0)) != EOF)
1242     switch (c)
1243       {
1244       case 'V':
1245       case 'v':
1246 	print_version ();
1247 	break;
1248       case 'd':
1249 	debug = 1;
1250 	break;
1251       case 'h':
1252       case '?':
1253 	usage (stderr, 0);
1254 	break;
1255       case 'c':
1256 	gen_opcode_p = 1;
1257 	break;
1258       case 'a':
1259 	gen_assembler_p = 1;
1260 	break;
1261       case 's':
1262 	gen_disassembler_p = 1;
1263 	break;
1264       default:
1265       case 0:
1266 	break;
1267       }
1268 
1269   if (argc == 1 || optind != argc)
1270     usage (stdout, 1);
1271 
1272   if (gen_opcode_p + gen_assembler_p + gen_disassembler_p > 1)
1273     {
1274       printf ("Please specify only one of the following options\n\
1275 	      [-c | --gen-opc] [-a | --gen-asm] [-s | --gen-dis]\n");
1276       xexit (2);
1277     }
1278 
1279   struct bittree *decoder_tree;
1280 
1281   decoder_tree = initialize_decoder_tree ();
1282   if (debug)
1283     print_divide_result (decoder_tree);
1284 
1285   printf ("/* This file is automatically generated by aarch64-gen.  Do not edit!  */\n");
1286   printf ("/* Copyright (C) 2012-2024 Free Software Foundation, Inc.\n\
1287    Contributed by ARM Ltd.\n\
1288 \n\
1289    This file is part of the GNU opcodes library.\n\
1290 \n\
1291    This library is free software; you can redistribute it and/or modify\n\
1292    it under the terms of the GNU General Public License as published by\n\
1293    the Free Software Foundation; either version 3, or (at your option)\n\
1294    any later version.\n\
1295 \n\
1296    It is distributed in the hope that it will be useful, but WITHOUT\n\
1297    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
1298    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n\
1299    License for more details.\n\
1300 \n\
1301    You should have received a copy of the GNU General Public License\n\
1302    along with this program; see the file COPYING3. If not,\n\
1303    see <http://www.gnu.org/licenses/>.  */\n");
1304 
1305   printf ("\n");
1306   printf ("#include \"sysdep.h\"\n");
1307   if (gen_opcode_p)
1308     printf ("#include \"aarch64-opc.h\"\n");
1309   if (gen_assembler_p)
1310     printf ("#include \"aarch64-asm.h\"\n");
1311   if (gen_disassembler_p)
1312     printf ("#include \"aarch64-dis.h\"\n");
1313   printf ("\n");
1314 
1315   /* Generate opcode entry lookup for the disassembler.  */
1316   if (gen_disassembler_p)
1317     {
1318       print_decision_tree (decoder_tree);
1319       print_find_next_opcode (decoder_tree);
1320       release_resource_decoder_tree (decoder_tree);
1321     }
1322 
1323   /* Generate alias opcode handling for the assembler or the disassembler.  */
1324   if (gen_assembler_p || gen_disassembler_p)
1325     {
1326       int num;
1327       opcode_node *alias_info = create_alias_info (&num);
1328 
1329       if (gen_assembler_p)
1330 	print_find_real_opcode (alias_info, num);
1331 
1332       if (gen_disassembler_p)
1333 	{
1334 	  print_find_alias_opcode (alias_info, num);
1335 	  print_find_next_alias_opcode (alias_info, num);
1336 	}
1337 
1338       release_resource_alias_info (alias_info, num);
1339     }
1340 
1341   /* Generate operand table.  */
1342   process_operand_table ();
1343 
1344   if (gen_assembler_p)
1345     print_operand_inserter ();
1346 
1347   if (gen_disassembler_p)
1348     print_operand_extractor ();
1349 
1350   if (gen_opcode_p)
1351     print_operand_table ();
1352 
1353   /* Generate utility to return aarch64_opcode entry given an enumerator.  */
1354   if (gen_opcode_p)
1355     print_get_opcode ();
1356 
1357   exit (0);
1358 }
1359