Automatic date update in version.in
[binutils-gdb.git] / opcodes / aarch64-gen.c
blob6ca0932aa6ee955e7711bffef92a750c0e9a430a
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.
6 This file is part of the GNU opcodes library.
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.
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.
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/>. */
22 #include "sysdep.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
27 #include "libiberty.h"
28 #include "getopt.h"
29 #include "opcode/aarch64.h"
31 #define VERIFIER(x) NULL
32 #include "aarch64-tbl.h"
34 static int debug = 0;
36 /* Structure used in the decoding tree to group a list of aarch64_opcode
37 entries. */
39 struct opcode_node
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;
49 typedef struct opcode_node opcode_node;
51 /* Head of the list of the opcode_node after read_table. */
52 static opcode_node opcode_nodes_head;
54 /* Node in the decoding tree. */
56 struct bittree
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;
65 /* Allocate and initialize an opcode_node. */
66 static opcode_node*
67 new_opcode_node (void)
69 opcode_node* ent = malloc (sizeof (opcode_node));
71 if (!ent)
72 abort ();
74 ent->opcode = 0;
75 ent->mask = 0;
76 ent->index = -1;
77 ent->next = NULL;
79 return ent;
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};
90 /* Use top 2 bits to indiate which table. */
91 static unsigned int
92 initialize_index (const struct aarch64_opcode* table)
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;
105 static inline const struct aarch64_opcode *
106 index2table (unsigned int index)
108 return aarch64_opcode_tables[(index >> 30) & 0x3];
111 static inline unsigned int
112 real_index (unsigned int index)
114 return index & ((1 << 30) - 1);
117 /* Given OPCODE_NODE, return the corresponding aarch64_opcode*. */
118 static const aarch64_opcode*
119 get_aarch64_opcode (const opcode_node *opcode_node)
121 if (opcode_node == NULL)
122 return NULL;
123 return &index2table (opcode_node->index)[real_index (opcode_node->index)];
126 static bool iclass_has_subclasses_p[last_iclass];
128 static void
129 read_table (const struct aarch64_opcode* table)
131 const struct aarch64_opcode *ent = table;
132 opcode_node **new_ent;
133 unsigned int index = initialize_index (table);
134 unsigned int errors = 0;
136 if (!ent->name)
137 return;
139 new_ent = &opcode_nodes_head.next;
141 while (*new_ent)
142 new_ent = &(*new_ent)->next;
146 bool match = false;
148 /* F_PSEUDO needs to be used together with F_ALIAS to indicate an alias
149 opcode is a programmer friendly pseudo instruction available only in
150 the assembly code (thus will not show up in the disassembly). */
151 assert (!pseudo_opcode_p (ent) || alias_opcode_p (ent));
152 /* Skip alias (inc. pseudo) opcode. */
153 if (alias_opcode_p (ent))
155 index++;
156 continue;
159 /* Check tied_operand against operands[]. */
160 for (unsigned int i = 1; i < ARRAY_SIZE (ent->operands); ++i)
162 if (ent->operands[i] == AARCH64_OPND_NIL)
163 break;
165 if (ent->operands[i] != ent->operands[0])
166 continue;
167 match = true;
169 if (i != ent->tied_operand)
171 fprintf (stderr,
172 "%s (%08x,%08x): operands 1 and %u match, but tied=%u\n",
173 ent->name, ent->opcode, ent->mask, i + 1, ent->tied_operand);
174 ++errors;
177 if (!match && ent->tied_operand
178 /* SME LDR/STR (array vector) tie together inner immediates only. */
179 && ent->iclass != sme_ldr && ent->iclass != sme_str)
181 fprintf (stderr, "%s: no operands match, but tied=%u\n",
182 ent->name, ent->tied_operand);
183 ++errors;
186 if (ent->flags & F_SUBCLASS)
187 iclass_has_subclasses_p[ent->iclass] = true;
189 *new_ent = new_opcode_node ();
190 (*new_ent)->opcode = ent->opcode;
191 (*new_ent)->mask = ent->mask;
192 (*new_ent)->index = index++;
193 new_ent = &((*new_ent)->next);
194 } while ((++ent)->name);
196 ent = table;
199 /* If a subclass is set for one insn of an iclass, every insn of that
200 iclass must have non-zero subclass field. */
201 if ((iclass_has_subclasses_p[ent->iclass] && !(ent->flags & F_SUBCLASS))
202 || (!iclass_has_subclasses_p[ent->iclass] && (ent->flags & F_SUBCLASS)))
204 fprintf (stderr, "%s: unexpected subclass\n", ent->name);
205 ++errors;
207 ent++;
208 } while (ent->name);
210 if (errors)
212 fprintf (stderr, "%u errors, exiting\n", errors);
213 xexit (3);
217 static inline void
218 print_one_opcode_node (opcode_node* ent)
220 printf ("%s\t%08x\t%08x\t%d\n", get_aarch64_opcode (ent)->name,
221 get_aarch64_opcode (ent)->opcode, get_aarch64_opcode (ent)->mask,
222 (int)real_index (ent->index));
225 /* As an internal debugging utility, print out the list of nodes pointed
226 by opcode_nodes_head. */
227 static void
228 print_opcode_nodes (void)
230 opcode_node* ent = opcode_nodes_head.next;
231 printf ("print_opcode_nodes table:\n");
232 while (ent)
234 print_one_opcode_node (ent);
235 ent = ent->next;
239 static struct bittree*
240 new_bittree_node (void)
242 struct bittree* node;
243 node = malloc (sizeof (struct bittree));
244 if (!node)
245 abort ();
246 node->bitno = -1;
247 node->bits[0] = NULL;
248 node->bits[1] = NULL;
249 return node;
252 /* The largest number of opcode entries that exist at a leaf node of the
253 decoding decision tree. The reason that there can be more than one
254 opcode entry is because some opcodes have shared field that is partially
255 constrained and thus cannot be fully isolated using the algorithm
256 here. */
257 static int max_num_opcodes_at_leaf_node = 0;
259 /* Given a list of opcodes headed by *OPCODE, try to establish one bit that
260 is shared by all the opcodes in the list as one of base opcode bits. If
261 such a bit is found, divide the list of the opcodes into two based on the
262 value of the bit.
264 Store the bit number in BITTREE->BITNO if the division succeeds. If unable
265 to determine such a bit or there is only one opcode in the list, the list
266 is decided to be undividable and OPCODE will be assigned to BITTREE->LIST.
268 The function recursively call itself until OPCODE is undividable.
270 N.B. the nature of this algrithm determines that given any value in the
271 32-bit space, the computed decision tree will always be able to find one or
272 more opcodes entries for it, regardless whether there is a valid instruction
273 defined for this value or not. In order to detect the undefined values,
274 when the caller obtains the opcode entry/entries, it should at least compare
275 the bit-wise AND result of the value and the mask with the base opcode
276 value; if the two are different, it means that the value is undefined
277 (although the value may be still undefined when the comparison is the same,
278 in which case call aarch64_opcode_decode to carry out further checks). */
280 static void
281 divide_table_1 (struct bittree *bittree, opcode_node *opcode)
283 aarch64_insn mask_and;
284 opcode_node *ent;
285 unsigned int bitno;
286 aarch64_insn bitmask;
287 opcode_node list0, list1, **ptr0, **ptr1;
288 static int depth = 0;
290 ++depth;
292 if (debug)
293 printf ("Enter into depth %d\n", depth);
295 assert (opcode != NULL);
297 /* Succeed when there is only one opcode left. */
298 if (!opcode->next)
300 if (debug)
302 printf ("opcode isolated:\n");
303 print_one_opcode_node (opcode);
305 goto divide_table_1_finish;
308 divide_table_1_try_again:
309 mask_and = -1;
310 ent = opcode;
311 while (ent)
313 mask_and &= ent->mask;
314 ent = ent->next;
317 if (debug)
318 printf ("mask and result: %08x\n", (unsigned int)mask_and);
320 /* If no more bit to look into, we have to accept the reality then. */
321 if (!mask_and)
323 int i;
324 opcode_node *ptr;
325 if (debug)
327 ptr = opcode;
328 printf ("Isolated opcode group:\n");
329 do {
330 print_one_opcode_node (ptr);
331 ptr = ptr->next;
332 } while (ptr);
334 /* Count the number of opcodes. */
335 for (i = 0, ptr = opcode; ptr; ++i)
336 ptr = ptr->next;
337 if (i > max_num_opcodes_at_leaf_node)
338 max_num_opcodes_at_leaf_node = i;
339 goto divide_table_1_finish;
342 /* Pick up the right most bit that is 1. */
343 bitno = 0;
344 while (!(mask_and & (1 << bitno)))
345 ++bitno;
346 bitmask = (1 << bitno);
348 if (debug)
349 printf ("use bit %d\n", bitno);
351 /* Record in the bittree. */
352 bittree->bitno = bitno;
354 /* Get two new opcode lists; adjust their masks. */
355 list0.next = NULL;
356 list1.next = NULL;
357 ptr0 = &list0.next;
358 ptr1 = &list1.next;
359 ent = opcode;
360 while (ent)
362 if (ent->opcode & bitmask)
364 ent->mask &= (~bitmask);
365 *ptr1 = ent;
366 ent = ent->next;
367 (*ptr1)->next = NULL;
368 ptr1 = &(*ptr1)->next;
370 else
372 ent->mask &= (~bitmask);
373 *ptr0 = ent;
374 ent = ent->next;
375 (*ptr0)->next = NULL;
376 ptr0 = &(*ptr0)->next;
380 /* If BITNO can NOT divide the opcode group, try next bit. */
381 if (list0.next == NULL)
383 opcode = list1.next;
384 goto divide_table_1_try_again;
386 else if (list1.next == NULL)
388 opcode = list0.next;
389 goto divide_table_1_try_again;
392 /* Further divide. */
393 bittree->bits[0] = new_bittree_node ();
394 bittree->bits[1] = new_bittree_node ();
395 divide_table_1 (bittree->bits[0], list0.next);
396 divide_table_1 (bittree->bits[1], list1.next);
398 divide_table_1_finish:
399 if (debug)
400 printf ("Leave from depth %d\n", depth);
401 --depth;
403 /* Record the opcode entries on this leaf node. */
404 bittree->list = opcode;
406 return;
409 /* Call divide_table_1 to divide the all the opcodes and thus create the
410 decoding decision tree. */
411 static struct bittree *
412 divide_table (void)
414 struct bittree *bittree = new_bittree_node ();
415 divide_table_1 (bittree, opcode_nodes_head.next);
416 return bittree;
419 /* Read in all of the tables, create the decoding decision tree and return
420 the tree root. */
421 static struct bittree *
422 initialize_decoder_tree (void)
424 int i;
425 const int num_of_tables = (sizeof (aarch64_opcode_tables)
426 / sizeof (struct aarch64_opcode *));
427 for (i = 0; i < num_of_tables; ++i)
428 read_table (aarch64_opcode_tables [i]);
429 if (debug)
430 print_opcode_nodes ();
431 return divide_table ();
434 static void __attribute__ ((format (printf, 2, 3)))
435 indented_print (unsigned int indent, const char *format, ...)
437 va_list ap;
438 va_start (ap, format);
439 printf ("%*s", (int) indent, "");
440 vprintf (format, ap);
441 va_end (ap);
444 /* N.B. read the comment above divide_table_1 for the reason why the generated
445 decision tree function never returns NULL. */
447 static void
448 print_decision_tree_1 (unsigned int indent, struct bittree* bittree)
450 /* PATTERN is only used to generate comment in the code. */
451 static char pattern[33] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
452 /* Low bits in PATTERN will be printed first which then look as the high
453 bits in comment. We need to reverse the index to get correct print. */
454 unsigned int msb = sizeof (pattern) - 2;
455 assert (bittree != NULL);
457 /* Leaf node located. */
458 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
460 assert (bittree->list != NULL);
461 indented_print (indent, "/* 33222222222211111111110000000000\n");
462 indented_print (indent, " 10987654321098765432109876543210\n");
463 indented_print (indent, " %s\n", pattern);
464 indented_print (indent, " %s. */\n",
465 get_aarch64_opcode (bittree->list)->name);
466 indented_print (indent, "return %u;\n",
467 real_index (bittree->list->index));
468 return;
471 /* Walk down the decoder tree. */
472 indented_print (indent, "if (((word >> %d) & 0x1) == 0)\n", bittree->bitno);
473 indented_print (indent, " {\n");
474 pattern[msb - bittree->bitno] = '0';
475 print_decision_tree_1 (indent + 4, bittree->bits[0]);
476 indented_print (indent, " }\n");
477 indented_print (indent, "else\n");
478 indented_print (indent, " {\n");
479 pattern[msb - bittree->bitno] = '1';
480 print_decision_tree_1 (indent + 4, bittree->bits[1]);
481 indented_print (indent, " }\n");
482 pattern[msb - bittree->bitno] = 'x';
485 /* Generate aarch64_opcode_lookup in C code to the standard output. */
487 static void
488 print_decision_tree (struct bittree* bittree)
490 if (debug)
491 printf ("Enter print_decision_tree\n");
493 printf ("/* Called by aarch64_opcode_lookup. */\n\n");
495 printf ("static int\n");
496 printf ("aarch64_opcode_lookup_1 (uint32_t word)\n");
497 printf ("{\n");
499 print_decision_tree_1 (2, bittree);
501 printf ("}\n\n");
504 printf ("/* Lookup opcode WORD in the opcode table. N.B. all alias\n");
505 printf (" opcodes are ignored here. */\n\n");
507 printf ("const aarch64_opcode *\n");
508 printf ("aarch64_opcode_lookup (uint32_t word)\n");
509 printf ("{\n");
510 printf (" return aarch64_opcode_table + aarch64_opcode_lookup_1 (word);\n");
511 printf ("}\n");
514 static void
515 print_find_next_opcode_1 (struct bittree* bittree)
517 assert (bittree != NULL);
519 /* Leaf node located. */
520 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
522 assert (bittree->list != NULL);
523 /* Find multiple opcode entries in one leaf node. */
524 if (bittree->list->next != NULL)
526 opcode_node *list = bittree->list;
527 while (list != NULL)
529 const aarch64_opcode *curr = get_aarch64_opcode (list);
530 const aarch64_opcode *next = get_aarch64_opcode (list->next);
532 printf (" case %u: ",
533 (unsigned int)(curr - aarch64_opcode_table));
534 if (list->next != NULL)
536 printf ("value = %u; break;\t", real_index (list->next->index));
537 printf ("/* %s --> %s. */\n", curr->name, next->name);
539 else
541 printf ("return NULL;\t\t");
542 printf ("/* %s --> NULL. */\n", curr->name);
545 list = list->next;
548 return;
551 /* Walk down the decoder tree. */
552 print_find_next_opcode_1 (bittree->bits[0]);
553 print_find_next_opcode_1 (bittree->bits[1]);
556 /* Generate aarch64_find_next_opcode in C code to the standard output. */
558 static void
559 print_find_next_opcode (struct bittree* bittree)
561 if (debug)
562 printf ("Enter print_find_next_opcode\n");
564 printf ("\n");
565 printf ("const aarch64_opcode *\n");
566 printf ("aarch64_find_next_opcode (const aarch64_opcode *opcode)\n");
567 printf ("{\n");
568 printf (" /* Use the index as the key to locate the next opcode. */\n");
569 printf (" int key = opcode - aarch64_opcode_table;\n");
570 printf (" int value;\n");
571 printf (" switch (key)\n");
572 printf (" {\n");
574 print_find_next_opcode_1 (bittree);
576 printf (" default: return NULL;\n");
577 printf (" }\n\n");
579 printf (" return aarch64_opcode_table + value;\n");
580 printf ("}\n");
583 /* Release the dynamic memory resource allocated for the generation of the
584 decoder tree. */
586 static void
587 release_resource_decoder_tree (struct bittree* bittree)
589 assert (bittree != NULL);
591 /* Leaf node located. */
592 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
594 assert (bittree->list != NULL);
595 /* Free opcode_nodes. */
596 opcode_node *list = bittree->list;
597 while (list != NULL)
599 opcode_node *next = list->next;
600 free (list);
601 list = next;
603 /* Free the tree node. */
604 free (bittree);
605 return;
608 /* Walk down the decoder tree. */
609 release_resource_decoder_tree (bittree->bits[0]);
610 release_resource_decoder_tree (bittree->bits[1]);
612 /* Free the tree node. */
613 free (bittree);
616 /* Generate aarch64_find_real_opcode in C code to the standard output.
617 TABLE points to the alias info table, while NUM indicates the number of
618 entries in the table. */
620 static void
621 print_find_real_opcode (const opcode_node *table, int num)
623 int i;
625 if (debug)
626 printf ("Enter print_find_real_opcode\n");
628 printf ("\n");
629 printf ("const aarch64_opcode *\n");
630 printf ("aarch64_find_real_opcode (const aarch64_opcode *opcode)\n");
631 printf ("{\n");
632 printf (" /* Use the index as the key to locate the real opcode. */\n");
633 printf (" int key = opcode - aarch64_opcode_table;\n");
634 printf (" int value;\n");
635 printf (" switch (key)\n");
636 printf (" {\n");
638 for (i = 0; i < num; ++i)
640 const opcode_node *real = table + i;
641 const opcode_node *alias = real->next;
642 for (; alias; alias = alias->next)
643 printf (" case %u:\t/* %s */\n", real_index (alias->index),
644 get_aarch64_opcode (alias)->name);
645 printf (" value = %u;\t/* --> %s. */\n", real_index (real->index),
646 get_aarch64_opcode (real)->name);
647 printf (" break;\n");
650 printf (" default: return NULL;\n");
651 printf (" }\n\n");
653 printf (" return aarch64_opcode_table + value;\n");
654 printf ("}\n");
657 /* Generate aarch64_find_alias_opcode in C code to the standard output.
658 TABLE points to the alias info table, while NUM indicates the number of
659 entries in the table. */
661 static void
662 print_find_alias_opcode (const opcode_node *table, int num)
664 int i;
666 if (debug)
667 printf ("Enter print_find_alias_opcode\n");
669 printf ("\n");
670 printf ("const aarch64_opcode *\n");
671 printf ("aarch64_find_alias_opcode (const aarch64_opcode *opcode)\n");
672 printf ("{\n");
673 printf (" /* Use the index as the key to locate the alias opcode. */\n");
674 printf (" int key = opcode - aarch64_opcode_table;\n");
675 printf (" int value;\n");
676 printf (" switch (key)\n");
677 printf (" {\n");
679 for (i = 0; i < num; ++i)
681 const opcode_node *node = table + i;
682 assert (node->next);
683 printf (" case %u: value = %u; break;", real_index (node->index),
684 real_index (node->next->index));
685 printf ("\t/* %s --> %s. */\n", get_aarch64_opcode (node)->name,
686 get_aarch64_opcode (node->next)->name);
689 printf (" default: return NULL;\n");
690 printf (" }\n\n");
692 printf (" return aarch64_opcode_table + value;\n");
693 printf ("}\n");
696 /* Generate aarch64_find_next_alias_opcode in C code to the standard output.
697 TABLE points to the alias info table, while NUM indicates the number of
698 entries in the table. */
700 static void
701 print_find_next_alias_opcode (const opcode_node *table, int num)
703 int i;
705 if (debug)
706 printf ("Enter print_find_next_alias_opcode\n");
708 printf ("\n");
709 printf ("const aarch64_opcode *\n");
710 printf ("aarch64_find_next_alias_opcode (const aarch64_opcode *opcode)\n");
711 printf ("{\n");
712 printf (" /* Use the index as the key to locate the next opcode. */\n");
713 printf (" int key = opcode - aarch64_opcode_table;\n");
714 printf (" int value;\n");
715 printf (" switch (key)\n");
716 printf (" {\n");
718 for (i = 0; i < num; ++i)
720 const opcode_node *node = table + i;
721 assert (node->next);
722 if (node->next->next == NULL)
723 continue;
724 while (node->next->next)
726 printf (" case %u: value = %u; break;", real_index (node->next->index),
727 real_index (node->next->next->index));
728 printf ("\t/* %s --> %s. */\n",
729 get_aarch64_opcode (node->next)->name,
730 get_aarch64_opcode (node->next->next)->name);
731 node = node->next;
735 printf (" default: return NULL;\n");
736 printf (" }\n\n");
738 printf (" return aarch64_opcode_table + value;\n");
739 printf ("}\n");
742 /* Given OPCODE, establish and return a link list of alias nodes in the
743 preferred order. */
745 opcode_node *
746 find_alias_opcode (const aarch64_opcode *opcode)
748 int i;
749 /* Assume maximum of 32 disassemble preference candidates. */
750 const int max_num_aliases = 32;
751 const aarch64_opcode *ent;
752 const aarch64_opcode *preferred[max_num_aliases + 1];
753 opcode_node head, **next;
755 assert (opcode_has_alias (opcode));
757 i = 0;
758 if (opcode->name != NULL)
759 preferred[i++] = opcode;
760 ent = aarch64_opcode_table;
761 while (ent->name != NULL)
763 /* The mask of an alias opcode must be equal to or a super-set (i.e.
764 more constrained) of that of the aliased opcode; so is the base
765 opcode value. */
766 if (alias_opcode_p (ent)
767 && (ent->mask & opcode->mask) == opcode->mask
768 && (opcode->mask & ent->opcode) == (opcode->mask & opcode->opcode))
770 assert (i < max_num_aliases);
771 preferred[i++] = ent;
772 if (debug)
773 printf ("found %s for %s.", ent->name, opcode->name);
775 ++ent;
778 if (debug)
780 int m;
781 printf ("un-orderd list: ");
782 for (m = 0; m < i; ++m)
783 printf ("%s, ", preferred[m]->name);
784 printf ("\n");
787 /* There must be at least one alias. */
788 assert (i >= 1);
790 /* Sort preferred array according to the priority (from the lowest to the
791 highest. */
792 if (i > 1)
794 int j, k;
795 for (j = 0; j < i - 1; ++j)
797 for (k = 0; k < i - 1 - j; ++k)
799 const aarch64_opcode *t;
800 t = preferred [k+1];
801 if (opcode_priority (t) < opcode_priority (preferred [k]))
803 preferred [k+1] = preferred [k];
804 preferred [k] = t;
810 if (debug)
812 int m;
813 printf ("orderd list: ");
814 for (m = 0; m < i; ++m)
815 printf ("%s, ", preferred[m]->name);
816 printf ("\n");
819 /* Create a link-list of opcode_node with disassemble preference from
820 higher to lower. */
821 next = &head.next;
822 --i;
823 while (i >= 0)
825 const aarch64_opcode *alias = preferred [i];
826 opcode_node *node = new_opcode_node ();
828 if (debug)
829 printf ("add %s.\n", alias->name);
831 node->index = alias - aarch64_opcode_table;
832 *next = node;
833 next = &node->next;
835 --i;
837 *next = NULL;
839 return head.next;
842 /* Create and return alias information.
843 Return the address of the created alias info table; return the number
844 of table entries in *NUM_PTR. */
846 opcode_node *
847 create_alias_info (int *num_ptr)
849 int i, num;
850 opcode_node *ret;
851 const aarch64_opcode *ent;
853 /* Calculate the total number of opcodes that have alias. */
854 num = 0;
855 ent = aarch64_opcode_table;
856 while (ent->name != NULL)
858 if (opcode_has_alias (ent))
860 /* Assert the alias relationship be flat-structured to keep
861 algorithms simple; not allow F_ALIAS and F_HAS_ALIAS both
862 specified. */
863 assert (!alias_opcode_p (ent));
864 ++num;
866 ++ent;
868 assert (num_ptr);
869 *num_ptr = num;
871 /* The array of real opcodes that have alias(es). */
872 ret = malloc (sizeof (opcode_node) * num);
874 /* For each opcode, establish a list of alias nodes in a preferred
875 order. */
876 for (i = 0, ent = aarch64_opcode_table; i < num; ++i, ++ent)
878 opcode_node *node = ret + i;
879 while (ent->name != NULL && !opcode_has_alias (ent))
880 ++ent;
881 assert (ent->name != NULL);
882 node->index = ent - aarch64_opcode_table;
883 node->next = find_alias_opcode (ent);
884 assert (node->next);
886 assert (i == num);
888 return ret;
891 /* Release the dynamic memory resource allocated for the generation of the
892 alias information. */
894 void
895 release_resource_alias_info (opcode_node *alias_info, int num)
897 int i = 0;
898 opcode_node *node = alias_info;
900 /* Free opcode_node list. */
901 for (; i < num; ++i, ++node)
903 opcode_node *list = node->next;
906 opcode_node *next = list->next;
907 free (list);
908 list = next;
909 } while (list != NULL);
912 /* Free opcode_node array. */
913 free (alias_info);
916 /* As a debugging utility, print out the result of the table division, although
917 it is not doing much this moment. */
918 static void
919 print_divide_result (const struct bittree *bittree ATTRIBUTE_UNUSED)
921 printf ("max_num_opcodes_at_leaf_node: %d\n", max_num_opcodes_at_leaf_node);
922 return;
925 /* Structure to help generate the operand table. */
926 struct operand
928 const char *class;
929 const char *inserter;
930 const char *extractor;
931 const char *str;
932 const char *flags;
933 const char *fields;
934 const char *desc;
935 unsigned processed : 1;
936 unsigned has_inserter : 1;
937 unsigned has_extractor : 1;
940 typedef struct operand operand;
942 #ifdef X
943 #undef X
944 #endif
946 #ifdef Y
947 #undef Y
948 #endif
950 #ifdef F
951 #undef F
952 #endif
954 /* Get the operand information in strings. */
956 static operand operands[] =
958 {"NIL", "0", "0", "", "0", "{0}", "<none>", 0, 0, 0},
959 #define F(...) #__VA_ARGS__
960 #define X(a,b,c,d,e,f,g) \
961 {#a, #b, #c, d, #e, "{"f"}", g, 0, 0, 0},
962 #define Y(a,b,d,e,f,g) \
963 {#a, "ins_"#b, "ext_"#b, d, #e, "{"f"}", g, 0, 0, 0},
964 AARCH64_OPERANDS
965 {"NIL", "0", "0", "", "0", "{0}", "DUMMY", 0, 0, 0},
968 #undef F
969 #undef X
971 static void
972 process_operand_table (void)
974 int i;
975 operand *opnd;
976 const int num = sizeof (operands) / sizeof (operand);
978 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
980 opnd->has_inserter = opnd->inserter[0] != '0';
981 opnd->has_extractor = opnd->extractor[0] != '0';
985 /* Generate aarch64_operands in C to the standard output. */
987 static void
988 print_operand_table (void)
990 int i;
991 operand *opnd;
992 const int num = sizeof (operands) / sizeof (operand);
994 if (debug)
995 printf ("Enter print_operand_table\n");
997 printf ("\n");
998 printf ("const struct aarch64_operand aarch64_operands[] =\n");
999 printf ("{\n");
1001 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1003 char flags[256];
1004 flags[0] = '\0';
1005 if (opnd->flags[0] != '0')
1006 sprintf (flags, "%s", opnd->flags);
1007 if (opnd->has_inserter)
1009 if (flags[0] != '\0')
1010 strcat (flags, " | ");
1011 strcat (flags, "OPD_F_HAS_INSERTER");
1013 if (opnd->has_extractor)
1015 if (flags[0] != '\0')
1016 strcat (flags, " | ");
1017 strcat (flags, "OPD_F_HAS_EXTRACTOR");
1019 if (flags[0] == '\0')
1021 flags[0] = '0';
1022 flags[1] = '\0';
1024 printf (" {AARCH64_OPND_CLASS_%s, \"%s\", %s, %s, \"%s\"},\n",
1025 opnd->class, opnd->str, flags, opnd->fields, opnd->desc);
1027 printf ("};\n");
1030 /* Generate aarch64_insert_operand in C to the standard output. */
1032 static void
1033 print_operand_inserter (void)
1035 int i;
1036 operand *opnd;
1037 const int num = sizeof (operands) / sizeof (operand);
1039 if (debug)
1040 printf ("Enter print_operand_inserter\n");
1042 printf ("\n");
1043 printf ("bool\n");
1044 printf ("aarch64_insert_operand (const aarch64_operand *self,\n\
1045 const aarch64_opnd_info *info,\n\
1046 aarch64_insn *code, const aarch64_inst *inst,\n\
1047 aarch64_operand_error *errors)\n");
1048 printf ("{\n");
1049 printf (" /* Use the index as the key. */\n");
1050 printf (" int key = self - aarch64_operands;\n");
1051 printf (" switch (key)\n");
1052 printf (" {\n");
1054 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1055 opnd->processed = 0;
1057 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1059 if (!opnd->processed && opnd->has_inserter)
1061 int j = i + 1;
1062 const int len = strlen (opnd->inserter);
1063 operand *opnd2 = opnd + 1;
1064 printf (" case %u:\n", (unsigned int)(opnd - operands));
1065 opnd->processed = 1;
1066 for (; j < num; ++j, ++opnd2)
1068 if (!opnd2->processed
1069 && opnd2->has_inserter
1070 && len == strlen (opnd2->inserter)
1071 && strncmp (opnd->inserter, opnd2->inserter, len) == 0)
1073 printf (" case %u:\n", (unsigned int)(opnd2 - operands));
1074 opnd2->processed = 1;
1077 printf (" return aarch64_%s (self, info, code, inst, errors);\n",
1078 opnd->inserter);
1082 printf (" default: assert (0); abort ();\n");
1083 printf (" }\n");
1084 printf ("}\n");
1087 /* Generate aarch64_extract_operand in C to the standard output. */
1089 static void
1090 print_operand_extractor (void)
1092 int i;
1093 operand *opnd;
1094 const int num = sizeof (operands) / sizeof (operand);
1096 if (debug)
1097 printf ("Enter print_operand_extractor\n");
1099 printf ("\n");
1100 printf ("bool\n");
1101 printf ("aarch64_extract_operand (const aarch64_operand *self,\n\
1102 aarch64_opnd_info *info,\n\
1103 aarch64_insn code, const aarch64_inst *inst,\n\
1104 aarch64_operand_error *errors)\n");
1105 printf ("{\n");
1106 printf (" /* Use the index as the key. */\n");
1107 printf (" int key = self - aarch64_operands;\n");
1108 printf (" switch (key)\n");
1109 printf (" {\n");
1111 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1112 opnd->processed = 0;
1114 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1116 if (!opnd->processed && opnd->has_extractor)
1118 int j = i + 1;
1119 const int len = strlen (opnd->extractor);
1120 operand *opnd2 = opnd + 1;
1121 printf (" case %u:\n", (unsigned int)(opnd - operands));
1122 opnd->processed = 1;
1123 for (; j < num; ++j, ++opnd2)
1125 if (!opnd2->processed
1126 && opnd2->has_extractor
1127 && len == strlen (opnd2->extractor)
1128 && strncmp (opnd->extractor, opnd2->extractor, len) == 0)
1130 printf (" case %u:\n", (unsigned int)(opnd2 - operands));
1131 opnd2->processed = 1;
1134 printf (" return aarch64_%s (self, info, code, inst, errors);\n",
1135 opnd->extractor);
1139 printf (" default: assert (0); abort ();\n");
1140 printf (" }\n");
1141 printf ("}\n");
1144 /* Table indexed by opcode enumerator stores the index of the corresponding
1145 opcode entry in aarch64_opcode_table. */
1146 static unsigned op_enum_table [OP_TOTAL_NUM];
1148 /* Print out the routine which, given the opcode enumerator, returns the
1149 corresponding opcode entry pointer. */
1151 static void
1152 print_get_opcode (void)
1154 int i;
1155 const int num = OP_TOTAL_NUM;
1156 const aarch64_opcode *opcode;
1158 if (debug)
1159 printf ("Enter print_get_opcode\n");
1161 /* Fill in the internal table. */
1162 opcode = aarch64_opcode_table;
1163 while (opcode->name != NULL)
1165 if (opcode->op != OP_NIL)
1167 /* Assert opcode enumerator be unique, in other words, no shared by
1168 different opcodes. */
1169 if (op_enum_table[opcode->op] != 0)
1171 fprintf (stderr, "Opcode %u is shared by different %s and %s.\n",
1172 opcode->op,
1173 aarch64_opcode_table[op_enum_table[opcode->op]].name,
1174 opcode->name);
1175 assert (0);
1176 abort ();
1178 assert (opcode->op < OP_TOTAL_NUM);
1179 op_enum_table[opcode->op] = opcode - aarch64_opcode_table;
1181 ++opcode;
1184 /* Print the table. */
1185 printf ("\n");
1186 printf ("/* Indexed by an enum aarch64_op enumerator, the value is the offset of\n\
1187 the corresponding aarch64_opcode entry in the aarch64_opcode_table. */\n\n");
1188 printf ("static const unsigned op_enum_table [] =\n");
1189 printf ("{\n");
1190 for (i = 0; i < num; ++i)
1191 printf (" %u,\n", op_enum_table[i]);
1192 printf ("};\n");
1194 /* Print the function. */
1195 printf ("\n");
1196 printf ("/* Given the opcode enumerator OP, return the pointer to the corresponding\n");
1197 printf (" opcode entry. */\n");
1198 printf ("\n");
1199 printf ("const aarch64_opcode *\n");
1200 printf ("aarch64_get_opcode (enum aarch64_op op)\n");
1201 printf ("{\n");
1202 printf (" return aarch64_opcode_table + op_enum_table[op];\n");
1203 printf ("}\n");
1206 /* Print out the content of an opcode table (not in use). */
1207 static void ATTRIBUTE_UNUSED
1208 print_table (struct aarch64_opcode* table)
1210 struct aarch64_opcode *ent = table;
1213 printf ("%s\t%08x\t%08x\n", ent->name, (unsigned int)ent->opcode,
1214 (unsigned int)ent->mask);
1215 } while ((++ent)->name);
1218 static const char * program_name = NULL;
1220 /* Program options. */
1221 struct option long_options[] =
1223 {"debug", no_argument, NULL, 'd'},
1224 {"version", no_argument, NULL, 'V'},
1225 {"help", no_argument, NULL, 'h'},
1226 {"gen-opc", no_argument, NULL, 'c'},
1227 {"gen-asm", no_argument, NULL, 'a'},
1228 {"gen-dis", no_argument, NULL, 's'},
1229 {0, no_argument, NULL, 0}
1232 static void
1233 print_version (void)
1235 printf ("%s: version 1.0\n", program_name);
1236 xexit (0);
1239 static void
1240 usage (FILE * stream, int status)
1242 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--help]\n",
1243 program_name);
1244 fprintf (stream, "\t[ [-c | --gen-opc] | [-a | --gen-asm] | [-s | --gen-dis] ]\n");
1245 xexit (status);
1249 main (int argc, char **argv)
1251 extern int chdir (char *);
1252 int c;
1253 int gen_opcode_p = 0;
1254 int gen_assembler_p = 0;
1255 int gen_disassembler_p = 0;
1257 program_name = *argv;
1258 xmalloc_set_program_name (program_name);
1260 while ((c = getopt_long (argc, argv, "vVdhacs", long_options, 0)) != EOF)
1261 switch (c)
1263 case 'V':
1264 case 'v':
1265 print_version ();
1266 break;
1267 case 'd':
1268 debug = 1;
1269 break;
1270 case 'h':
1271 case '?':
1272 usage (stderr, 0);
1273 break;
1274 case 'c':
1275 gen_opcode_p = 1;
1276 break;
1277 case 'a':
1278 gen_assembler_p = 1;
1279 break;
1280 case 's':
1281 gen_disassembler_p = 1;
1282 break;
1283 default:
1284 case 0:
1285 break;
1288 if (argc == 1 || optind != argc)
1289 usage (stdout, 1);
1291 if (gen_opcode_p + gen_assembler_p + gen_disassembler_p > 1)
1293 printf ("Please specify only one of the following options\n\
1294 [-c | --gen-opc] [-a | --gen-asm] [-s | --gen-dis]\n");
1295 xexit (2);
1298 struct bittree *decoder_tree;
1300 decoder_tree = initialize_decoder_tree ();
1301 if (debug)
1302 print_divide_result (decoder_tree);
1304 printf ("/* This file is automatically generated by aarch64-gen. Do not edit! */\n");
1305 printf ("/* Copyright (C) 2012-2024 Free Software Foundation, Inc.\n\
1306 Contributed by ARM Ltd.\n\
1308 This file is part of the GNU opcodes library.\n\
1310 This library is free software; you can redistribute it and/or modify\n\
1311 it under the terms of the GNU General Public License as published by\n\
1312 the Free Software Foundation; either version 3, or (at your option)\n\
1313 any later version.\n\
1315 It is distributed in the hope that it will be useful, but WITHOUT\n\
1316 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
1317 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
1318 License for more details.\n\
1320 You should have received a copy of the GNU General Public License\n\
1321 along with this program; see the file COPYING3. If not,\n\
1322 see <http://www.gnu.org/licenses/>. */\n");
1324 printf ("\n");
1325 printf ("#include \"sysdep.h\"\n");
1326 if (gen_opcode_p)
1327 printf ("#include \"aarch64-opc.h\"\n");
1328 if (gen_assembler_p)
1329 printf ("#include \"aarch64-asm.h\"\n");
1330 if (gen_disassembler_p)
1331 printf ("#include \"aarch64-dis.h\"\n");
1332 printf ("\n");
1334 /* Generate opcode entry lookup for the disassembler. */
1335 if (gen_disassembler_p)
1337 print_decision_tree (decoder_tree);
1338 print_find_next_opcode (decoder_tree);
1339 release_resource_decoder_tree (decoder_tree);
1342 /* Generate alias opcode handling for the assembler or the disassembler. */
1343 if (gen_assembler_p || gen_disassembler_p)
1345 int num;
1346 opcode_node *alias_info = create_alias_info (&num);
1348 if (gen_assembler_p)
1349 print_find_real_opcode (alias_info, num);
1351 if (gen_disassembler_p)
1353 print_find_alias_opcode (alias_info, num);
1354 print_find_next_alias_opcode (alias_info, num);
1357 release_resource_alias_info (alias_info, num);
1360 /* Generate operand table. */
1361 process_operand_table ();
1363 if (gen_assembler_p)
1364 print_operand_inserter ();
1366 if (gen_disassembler_p)
1367 print_operand_extractor ();
1369 if (gen_opcode_p)
1370 print_operand_table ();
1372 /* Generate utility to return aarch64_opcode entry given an enumerator. */
1373 if (gen_opcode_p)
1374 print_get_opcode ();
1376 exit (0);