1 /* aarch64-gen.c -- Generate tables and routines for opcode lookup and
2 instruction encoding and decoding.
3 Copyright (C) 2012-2016 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)
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/>. */
27 #include "libiberty.h"
29 #include "opcode/aarch64.h"
31 #define VERIFIER(x) NULL
32 #include "aarch64-tbl.h"
36 /* Structure used in the decoding tree to group a list of aarch64_opcode
43 /* Index of the entry in the original table; the top 2 bits help
44 determine the table. */
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. */
59 /* 0, 1, and X (don't care). */
60 struct bittree *bits[2];
61 /* List of opcodes; only valid for the leaf node. */
65 /* Allocate and initialize an opcode_node. */
67 new_opcode_node (void)
69 opcode_node* ent = malloc (sizeof (opcode_node));
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 *aarch64_opcode_tables[] =
88 {aarch64_opcode_table};
90 /* Use top 2 bits to indiate which table. */
92 initialize_index (const struct aarch64_opcode* table)
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])
100 if (i == num_of_tables)
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)
123 return &index2table (opcode_node->index)[real_index (opcode_node->index)];
127 read_table (const struct aarch64_opcode* table)
129 const struct aarch64_opcode *ent = table;
130 opcode_node **new_ent;
131 unsigned int index = initialize_index (table);
136 new_ent = &opcode_nodes_head.next;
139 new_ent = &(*new_ent)->next;
143 /* F_PSEUDO needs to be used together with F_ALIAS to indicate an alias
144 opcode is a programmer friendly pseudo instruction available only in
145 the assembly code (thus will not show up in the disassembly). */
146 assert (pseudo_opcode_p (ent) == FALSE || alias_opcode_p (ent) == TRUE);
147 /* Skip alias (inc. pseudo) opcode. */
148 if (alias_opcode_p (ent) == TRUE)
153 *new_ent = new_opcode_node ();
154 (*new_ent)->opcode = ent->opcode;
155 (*new_ent)->mask = ent->mask;
156 (*new_ent)->index = index++;
157 new_ent = &((*new_ent)->next);
158 } while ((++ent)->name);
162 print_one_opcode_node (opcode_node* ent)
164 printf ("%s\t%08x\t%08x\t%d\n", get_aarch64_opcode (ent)->name,
165 get_aarch64_opcode (ent)->opcode, get_aarch64_opcode (ent)->mask,
166 (int)real_index (ent->index));
169 /* As an internal debugging utility, print out the list of nodes pointed
170 by opcode_nodes_head. */
172 print_opcode_nodes (void)
174 opcode_node* ent = opcode_nodes_head.next;
175 printf ("print_opcode_nodes table:\n");
178 print_one_opcode_node (ent);
183 static struct bittree*
184 new_bittree_node (void)
186 struct bittree* node;
187 node = malloc (sizeof (struct bittree));
191 node->bits[0] = NULL;
192 node->bits[1] = NULL;
196 /* The largest number of opcode entries that exist at a leaf node of the
197 decoding decision tree. The reason that there can be more than one
198 opcode entry is because some opcodes have shared field that is partially
199 constrained and thus cannot be fully isolated using the algorithm
201 static int max_num_opcodes_at_leaf_node = 0;
203 /* Given a list of opcodes headed by *OPCODE, try to establish one bit that
204 is shared by all the opcodes in the list as one of base opcode bits. If
205 such a bit is found, divide the list of the opcodes into two based on the
208 Store the bit number in BITTREE->BITNO if the division succeeds. If unable
209 to determine such a bit or there is only one opcode in the list, the list
210 is decided to be undividable and OPCODE will be assigned to BITTREE->LIST.
212 The function recursively call itself until OPCODE is undividable.
214 N.B. the nature of this algrithm determines that given any value in the
215 32-bit space, the computed decision tree will always be able to find one or
216 more opcodes entries for it, regardless whether there is a valid instruction
217 defined for this value or not. In order to detect the undefined values,
218 when the caller obtains the opcode entry/entries, it should at least compare
219 the bit-wise AND result of the value and the mask with the base opcode
220 value; if the two are different, it means that the value is undefined
221 (although the value may be still undefined when the comparison is the same,
222 in which case call aarch64_opcode_decode to carry out further checks). */
225 divide_table_1 (struct bittree *bittree, opcode_node *opcode)
227 aarch64_insn mask_and;
230 aarch64_insn bitmask;
231 opcode_node list0, list1, **ptr0, **ptr1;
232 static int depth = 0;
237 printf ("Enter into depth %d\n", depth);
239 assert (opcode != NULL);
241 /* Succeed when there is only one opcode left. */
246 printf ("opcode isolated:\n");
247 print_one_opcode_node (opcode);
249 goto divide_table_1_finish;
252 divide_table_1_try_again:
257 mask_and &= ent->mask;
262 printf ("mask and result: %08x\n", (unsigned int)mask_and);
264 /* If no more bit to look into, we have to accept the reality then. */
272 printf ("Isolated opcode group:\n");
274 print_one_opcode_node (ptr);
278 /* Count the number of opcodes. */
279 for (i = 0, ptr = opcode; ptr; ++i)
281 if (i > max_num_opcodes_at_leaf_node)
282 max_num_opcodes_at_leaf_node = i;
283 goto divide_table_1_finish;
286 /* Pick up the right most bit that is 1. */
288 while (!(mask_and & (1 << bitno)))
290 bitmask = (1 << bitno);
293 printf ("use bit %d\n", bitno);
295 /* Record in the bittree. */
296 bittree->bitno = bitno;
298 /* Get two new opcode lists; adjust their masks. */
306 if (ent->opcode & bitmask)
308 ent->mask &= (~bitmask);
311 (*ptr1)->next = NULL;
312 ptr1 = &(*ptr1)->next;
316 ent->mask &= (~bitmask);
319 (*ptr0)->next = NULL;
320 ptr0 = &(*ptr0)->next;
324 /* If BITNO can NOT divide the opcode group, try next bit. */
325 if (list0.next == NULL)
328 goto divide_table_1_try_again;
330 else if (list1.next == NULL)
333 goto divide_table_1_try_again;
336 /* Further divide. */
337 bittree->bits[0] = new_bittree_node ();
338 bittree->bits[1] = new_bittree_node ();
339 divide_table_1 (bittree->bits[0], list0.next);
340 divide_table_1 (bittree->bits[1], list1.next);
342 divide_table_1_finish:
344 printf ("Leave from depth %d\n", depth);
347 /* Record the opcode entries on this leaf node. */
348 bittree->list = opcode;
353 /* Call divide_table_1 to divide the all the opcodes and thus create the
354 decoding decision tree. */
355 static struct bittree *
358 struct bittree *bittree = new_bittree_node ();
359 divide_table_1 (bittree, opcode_nodes_head.next);
363 /* Read in all of the tables, create the decoding decision tree and return
365 static struct bittree *
366 initialize_decoder_tree (void)
369 const int num_of_tables = (sizeof (aarch64_opcode_tables)
370 / sizeof (struct aarch64_opcode *));
371 for (i = 0; i < num_of_tables; ++i)
372 read_table (aarch64_opcode_tables [i]);
374 print_opcode_nodes ();
375 return divide_table ();
378 static void __attribute__ ((format (printf, 2, 3)))
379 indented_print (unsigned int indent, const char *format, ...)
381 /* 80 number of spaces pluc a NULL terminator. */
382 static const char spaces[81] =
385 va_start (ap, format);
386 assert (indent <= 80);
387 printf ("%s", &spaces[80 - indent]);
388 vprintf (format, ap);
392 /* N.B. read the comment above divide_table_1 for the reason why the generated
393 decision tree function never returns NULL. */
396 print_decision_tree_1 (unsigned int indent, struct bittree* bittree)
398 /* PATTERN is only used to generate comment in the code. */
399 static char pattern[33] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
400 assert (bittree != NULL);
402 /* Leaf node located. */
403 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
405 assert (bittree->list != NULL);
406 indented_print (indent, "/* 33222222222211111111110000000000\n");
407 indented_print (indent, " 10987654321098765432109876543210\n");
408 indented_print (indent, " %s\n", pattern);
409 indented_print (indent, " %s. */\n",
410 get_aarch64_opcode (bittree->list)->name);
411 indented_print (indent, "return %u;\n",
412 real_index (bittree->list->index));
416 /* Walk down the decoder tree. */
417 indented_print (indent, "if (((word >> %d) & 0x1) == 0)\n", bittree->bitno);
418 indented_print (indent, " {\n");
419 pattern[bittree->bitno] = '0';
420 print_decision_tree_1 (indent + 4, bittree->bits[0]);
421 indented_print (indent, " }\n");
422 indented_print (indent, "else\n");
423 indented_print (indent, " {\n");
424 pattern[bittree->bitno] = '1';
425 print_decision_tree_1 (indent + 4, bittree->bits[1]);
426 indented_print (indent, " }\n");
427 pattern[bittree->bitno] = 'x';
430 /* Generate aarch64_opcode_lookup in C code to the standard output. */
433 print_decision_tree (struct bittree* bittree)
436 printf ("Enter print_decision_tree\n");
438 printf ("/* Called by aarch64_opcode_lookup. */\n\n");
440 printf ("static int\n");
441 printf ("aarch64_opcode_lookup_1 (uint32_t word)\n");
444 print_decision_tree_1 (2, bittree);
449 printf ("/* Lookup opcode WORD in the opcode table. N.B. all alias\n");
450 printf (" opcodes are ignored here. */\n\n");
452 printf ("const aarch64_opcode *\n");
453 printf ("aarch64_opcode_lookup (uint32_t word)\n");
455 printf (" return aarch64_opcode_table + aarch64_opcode_lookup_1 (word);\n");
460 print_find_next_opcode_1 (struct bittree* bittree)
462 assert (bittree != NULL);
464 /* Leaf node located. */
465 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
467 assert (bittree->list != NULL);
468 /* Find multiple opcode entries in one leaf node. */
469 if (bittree->list->next != NULL)
471 opcode_node *list = bittree->list;
474 const aarch64_opcode *curr = get_aarch64_opcode (list);
475 const aarch64_opcode *next = get_aarch64_opcode (list->next);
477 printf (" case %u: ",
478 (unsigned int)(curr - aarch64_opcode_table));
479 if (list->next != NULL)
481 printf ("value = %u; break;\t", real_index (list->next->index));
482 printf ("/* %s --> %s. */\n", curr->name, next->name);
486 printf ("return NULL;\t\t");
487 printf ("/* %s --> NULL. */\n", curr->name);
496 /* Walk down the decoder tree. */
497 print_find_next_opcode_1 (bittree->bits[0]);
498 print_find_next_opcode_1 (bittree->bits[1]);
501 /* Generate aarch64_find_next_opcode in C code to the standard output. */
504 print_find_next_opcode (struct bittree* bittree)
507 printf ("Enter print_find_next_opcode\n");
510 printf ("const aarch64_opcode *\n");
511 printf ("aarch64_find_next_opcode (const aarch64_opcode *opcode)\n");
513 printf (" /* Use the index as the key to locate the next opcode. */\n");
514 printf (" int key = opcode - aarch64_opcode_table;\n");
515 printf (" int value;\n");
516 printf (" switch (key)\n");
519 print_find_next_opcode_1 (bittree);
521 printf (" default: return NULL;\n");
524 printf (" return aarch64_opcode_table + value;\n");
528 /* Release the dynamic memory resource allocated for the generation of the
532 release_resource_decoder_tree (struct bittree* bittree)
534 assert (bittree != NULL);
536 /* Leaf node located. */
537 if (bittree->bits[0] == NULL && bittree->bits[1] == NULL)
539 assert (bittree->list != NULL);
540 /* Free opcode_nodes. */
541 opcode_node *list = bittree->list;
544 opcode_node *next = list->next;
548 /* Free the tree node. */
553 /* Walk down the decoder tree. */
554 release_resource_decoder_tree (bittree->bits[0]);
555 release_resource_decoder_tree (bittree->bits[1]);
557 /* Free the tree node. */
561 /* Generate aarch64_find_real_opcode in C code to the standard output.
562 TABLE points to the alias info table, while NUM indicates the number of
563 entries in the table. */
566 print_find_real_opcode (const opcode_node *table, int num)
571 printf ("Enter print_find_real_opcode\n");
574 printf ("const aarch64_opcode *\n");
575 printf ("aarch64_find_real_opcode (const aarch64_opcode *opcode)\n");
577 printf (" /* Use the index as the key to locate the real opcode. */\n");
578 printf (" int key = opcode - aarch64_opcode_table;\n");
579 printf (" int value;\n");
580 printf (" switch (key)\n");
583 for (i = 0; i < num; ++i)
585 const opcode_node *real = table + i;
586 const opcode_node *alias = real->next;
587 for (; alias; alias = alias->next)
588 printf (" case %u:\t/* %s */\n", real_index (alias->index),
589 get_aarch64_opcode (alias)->name);
590 printf (" value = %u;\t/* --> %s. */\n", real_index (real->index),
591 get_aarch64_opcode (real)->name);
592 printf (" break;\n");
595 printf (" default: return NULL;\n");
598 printf (" return aarch64_opcode_table + value;\n");
602 /* Generate aarch64_find_alias_opcode in C code to the standard output.
603 TABLE points to the alias info table, while NUM indicates the number of
604 entries in the table. */
607 print_find_alias_opcode (const opcode_node *table, int num)
612 printf ("Enter print_find_alias_opcode\n");
615 printf ("const aarch64_opcode *\n");
616 printf ("aarch64_find_alias_opcode (const aarch64_opcode *opcode)\n");
618 printf (" /* Use the index as the key to locate the alias opcode. */\n");
619 printf (" int key = opcode - aarch64_opcode_table;\n");
620 printf (" int value;\n");
621 printf (" switch (key)\n");
624 for (i = 0; i < num; ++i)
626 const opcode_node *node = table + i;
628 printf (" case %u: value = %u; break;", real_index (node->index),
629 real_index (node->next->index));
630 printf ("\t/* %s --> %s. */\n", get_aarch64_opcode (node)->name,
631 get_aarch64_opcode (node->next)->name);
634 printf (" default: return NULL;\n");
637 printf (" return aarch64_opcode_table + value;\n");
641 /* Generate aarch64_find_next_alias_opcode in C code to the standard output.
642 TABLE points to the alias info table, while NUM indicates the number of
643 entries in the table. */
646 print_find_next_alias_opcode (const opcode_node *table, int num)
651 printf ("Enter print_find_next_alias_opcode\n");
654 printf ("const aarch64_opcode *\n");
655 printf ("aarch64_find_next_alias_opcode (const aarch64_opcode *opcode)\n");
657 printf (" /* Use the index as the key to locate the next opcode. */\n");
658 printf (" int key = opcode - aarch64_opcode_table;\n");
659 printf (" int value;\n");
660 printf (" switch (key)\n");
663 for (i = 0; i < num; ++i)
665 const opcode_node *node = table + i;
667 if (node->next->next == NULL)
669 while (node->next->next)
671 printf (" case %u: value = %u; break;", real_index (node->next->index),
672 real_index (node->next->next->index));
673 printf ("\t/* %s --> %s. */\n",
674 get_aarch64_opcode (node->next)->name,
675 get_aarch64_opcode (node->next->next)->name);
680 printf (" default: return NULL;\n");
683 printf (" return aarch64_opcode_table + value;\n");
687 /* Given OPCODE, establish and return a link list of alias nodes in the
691 find_alias_opcode (const aarch64_opcode *opcode)
694 /* Assume maximum of 16 disassemble preference candidates. */
695 const int max_num_aliases = 16;
696 const aarch64_opcode *ent;
697 const aarch64_opcode *preferred[max_num_aliases + 1];
698 opcode_node head, **next;
700 assert (opcode_has_alias (opcode));
703 if (opcode->name != NULL)
704 preferred[i++] = opcode;
705 ent = aarch64_opcode_table;
706 while (ent->name != NULL)
708 /* The mask of an alias opcode must be equal to or a super-set (i.e.
709 more constrained) of that of the aliased opcode; so is the base
711 if (alias_opcode_p (ent) == TRUE
712 && (ent->mask & opcode->mask) == opcode->mask
713 && (opcode->mask & ent->opcode) == (opcode->mask & opcode->opcode))
715 assert (i < max_num_aliases);
716 preferred[i++] = ent;
718 printf ("found %s for %s.", ent->name, opcode->name);
726 printf ("un-orderd list: ");
727 for (m = 0; m < i; ++m)
728 printf ("%s, ", preferred[m]->name);
732 /* There must be at least one alias. */
735 /* Sort preferred array according to the priority (from the lowest to the
740 for (j = 0; j < i - 1; ++j)
742 for (k = 0; k < i - 1 - j; ++k)
744 const aarch64_opcode *t;
746 if (opcode_priority (t) < opcode_priority (preferred [k]))
748 preferred [k+1] = preferred [k];
758 printf ("orderd list: ");
759 for (m = 0; m < i; ++m)
760 printf ("%s, ", preferred[m]->name);
764 /* Create a link-list of opcode_node with disassemble preference from
770 const aarch64_opcode *alias = preferred [i];
771 opcode_node *node = new_opcode_node ();
774 printf ("add %s.\n", alias->name);
776 node->index = alias - aarch64_opcode_table;
787 /* Create and return alias information.
788 Return the address of the created alias info table; return the number
789 of table entries in *NUM_PTR. */
792 create_alias_info (int *num_ptr)
796 const aarch64_opcode *ent;
798 /* Calculate the total number of opcodes that have alias. */
800 ent = aarch64_opcode_table;
801 while (ent->name != NULL)
803 if (opcode_has_alias (ent))
805 /* Assert the alias relationship be flat-structured to keep
806 algorithms simple; not allow F_ALIAS and F_HAS_ALIAS both
808 assert (!alias_opcode_p (ent));
816 /* The array of real opcodes that have alias(es). */
817 ret = malloc (sizeof (opcode_node) * num);
819 /* For each opcode, establish a list of alias nodes in a preferred
821 for (i = 0, ent = aarch64_opcode_table; i < num; ++i, ++ent)
823 opcode_node *node = ret + i;
824 while (ent->name != NULL && !opcode_has_alias (ent))
826 assert (ent->name != NULL);
827 node->index = ent - aarch64_opcode_table;
828 node->next = find_alias_opcode (ent);
836 /* Release the dynamic memory resource allocated for the generation of the
837 alias information. */
840 release_resource_alias_info (opcode_node *alias_info, int num)
843 opcode_node *node = alias_info;
845 /* Free opcode_node list. */
846 for (; i < num; ++i, ++node)
848 opcode_node *list = node->next;
851 opcode_node *next = list->next;
854 } while (list != NULL);
857 /* Free opcode_node array. */
861 /* As a debugging utility, print out the result of the table division, although
862 it is not doing much this moment. */
864 print_divide_result (const struct bittree *bittree ATTRIBUTE_UNUSED)
866 printf ("max_num_opcodes_at_leaf_node: %d\n", max_num_opcodes_at_leaf_node);
870 /* Structure to help generate the operand table. */
874 const char *inserter;
875 const char *extractor;
880 unsigned processed : 1;
881 unsigned has_inserter : 1;
882 unsigned has_extractor : 1;
885 typedef struct operand operand;
899 /* Get the operand information in strings. */
901 static operand operands[] =
903 {"NIL", "0", "0", "", "0", "{0}", "<none>", 0, 0, 0},
904 #define F(...) #__VA_ARGS__
905 #define X(a,b,c,d,e,f,g) \
906 {#a, #b, #c, d, #e, "{"f"}", g, 0, 0, 0},
907 #define Y(a,b,d,e,f,g) \
908 {#a, "ins_"#b, "ext_"#b, d, #e, "{"f"}", g, 0, 0, 0},
910 {"NIL", "0", "0", "", "0", "{0}", "DUMMY", 0, 0, 0},
917 process_operand_table (void)
921 const int num = sizeof (operands) / sizeof (operand);
923 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
925 opnd->has_inserter = opnd->inserter[0] != '0';
926 opnd->has_extractor = opnd->extractor[0] != '0';
930 /* Generate aarch64_operands in C to the standard output. */
933 print_operand_table (void)
937 const int num = sizeof (operands) / sizeof (operand);
940 printf ("Enter print_operand_table\n");
943 printf ("const struct aarch64_operand aarch64_operands[] =\n");
946 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
950 if (opnd->flags[0] != '0')
951 sprintf (flags, "%s", opnd->flags);
952 if (opnd->has_inserter)
954 if (flags[0] != '\0')
955 strcat (flags, " | ");
956 strcat (flags, "OPD_F_HAS_INSERTER");
958 if (opnd->has_extractor)
960 if (flags[0] != '\0')
961 strcat (flags, " | ");
962 strcat (flags, "OPD_F_HAS_EXTRACTOR");
964 if (flags[0] == '\0')
969 printf (" {AARCH64_OPND_CLASS_%s, \"%s\", %s, %s, \"%s\"},\n",
970 opnd->class, opnd->str, flags, opnd->fields, opnd->desc);
975 /* Generate aarch64_insert_operand in C to the standard output. */
978 print_operand_inserter (void)
982 const int num = sizeof (operands) / sizeof (operand);
985 printf ("Enter print_operand_inserter\n");
988 printf ("const char*\n");
989 printf ("aarch64_insert_operand (const aarch64_operand *self,\n\
990 const aarch64_opnd_info *info,\n\
991 aarch64_insn *code, const aarch64_inst *inst)\n");
993 printf (" /* Use the index as the key. */\n");
994 printf (" int key = self - aarch64_operands;\n");
995 printf (" switch (key)\n");
998 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1001 for (i = 0, opnd = operands; i < num; ++i, ++opnd)
1003 if (!opnd->processed && opnd->has_inserter)
1006 const int len = strlen (opnd->inserter);
1007 operand *opnd2 = opnd + 1;
1008 printf (" case %u:\n", (unsigned int)(opnd - operands));
1009 opnd->processed = 1;
1010 for (; j < num; ++j, ++opnd2)
1012 if (!opnd2->processed
1013 && opnd2->has_inserter
1014 && len == strlen (opnd2->inserter)
1015 && strncmp (opnd->inserter, opnd2->inserter, len) == 0)
1017 printf (" case %u:\n", (unsigned int)(opnd2 - operands));
1018 opnd2->processed = 1;
1021 printf (" return aarch64_%s (self, info, code, inst);\n",
1026 printf (" default: assert (0); abort ();\n");
1031 /* Generate aarch64_extract_operand in C to the standard output. */
1034 print_operand_extractor (void)
1038 const int num = sizeof (operands) / sizeof (operand);
1041 printf ("Enter print_operand_extractor\n");
1045 printf ("aarch64_extract_operand (const aarch64_operand *self,\n\
1046 aarch64_opnd_info *info,\n\
1047 aarch64_insn code, const aarch64_inst *inst)\n");
1049 printf (" /* Use the index as the key. */\n");
1050 printf (" int key = self - aarch64_operands;\n");
1051 printf (" switch (key)\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_extractor)
1062 const int len = strlen (opnd->extractor);
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_extractor
1070 && len == strlen (opnd2->extractor)
1071 && strncmp (opnd->extractor, opnd2->extractor, len) == 0)
1073 printf (" case %u:\n", (unsigned int)(opnd2 - operands));
1074 opnd2->processed = 1;
1077 printf (" return aarch64_%s (self, info, code, inst);\n",
1082 printf (" default: assert (0); abort ();\n");
1087 /* Table indexed by opcode enumerator stores the index of the corresponding
1088 opcode entry in aarch64_opcode_table. */
1089 static unsigned op_enum_table [OP_TOTAL_NUM];
1091 /* Print out the routine which, given the opcode enumerator, returns the
1092 corresponding opcode entry pointer. */
1095 print_get_opcode (void)
1098 const int num = OP_TOTAL_NUM;
1099 const aarch64_opcode *opcode;
1102 printf ("Enter print_get_opcode\n");
1104 /* Fill in the internal table. */
1105 opcode = aarch64_opcode_table;
1106 while (opcode->name != NULL)
1108 if (opcode->op != OP_NIL)
1110 /* Assert opcode enumerator be unique, in other words, no shared by
1111 different opcodes. */
1112 if (op_enum_table[opcode->op] != 0)
1114 fprintf (stderr, "Opcode %u is shared by different %s and %s.\n",
1116 aarch64_opcode_table[op_enum_table[opcode->op]].name,
1121 assert (opcode->op < OP_TOTAL_NUM);
1122 op_enum_table[opcode->op] = opcode - aarch64_opcode_table;
1127 /* Print the table. */
1129 printf ("/* Indexed by an enum aarch64_op enumerator, the value is the offset of\n\
1130 the corresponding aarch64_opcode entry in the aarch64_opcode_table. */\n\n");
1131 printf ("static const unsigned op_enum_table [] =\n");
1133 for (i = 0; i < num; ++i)
1134 printf (" %u,\n", op_enum_table[i]);
1137 /* Print the function. */
1139 printf ("/* Given the opcode enumerator OP, return the pointer to the corresponding\n");
1140 printf (" opcode entry. */\n");
1142 printf ("const aarch64_opcode *\n");
1143 printf ("aarch64_get_opcode (enum aarch64_op op)\n");
1145 printf (" return aarch64_opcode_table + op_enum_table[op];\n");
1149 /* Print out the content of an opcode table (not in use). */
1150 static void ATTRIBUTE_UNUSED
1151 print_table (struct aarch64_opcode* table)
1153 struct aarch64_opcode *ent = table;
1156 printf ("%s\t%08x\t%08x\n", ent->name, (unsigned int)ent->opcode,
1157 (unsigned int)ent->mask);
1158 } while ((++ent)->name);
1161 static const char * program_name = NULL;
1163 /* Program options. */
1164 struct option long_options[] =
1166 {"debug", no_argument, NULL, 'd'},
1167 {"version", no_argument, NULL, 'V'},
1168 {"help", no_argument, NULL, 'h'},
1169 {"gen-opc", no_argument, NULL, 'c'},
1170 {"gen-asm", no_argument, NULL, 'a'},
1171 {"gen-dis", no_argument, NULL, 's'},
1172 {0, no_argument, NULL, 0}
1176 print_version (void)
1178 printf ("%s: version 1.0\n", program_name);
1183 usage (FILE * stream, int status)
1185 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--help]\n",
1187 fprintf (stream, "\t[ [-c | --gen-opc] | [-a | --gen-asm] | [-s | --gen-dis] ]\n");
1192 main (int argc, char **argv)
1194 extern int chdir (char *);
1196 int gen_opcode_p = 0;
1197 int gen_assembler_p = 0;
1198 int gen_disassembler_p = 0;
1200 program_name = *argv;
1201 xmalloc_set_program_name (program_name);
1203 while ((c = getopt_long (argc, argv, "vVdhacs", long_options, 0)) != EOF)
1221 gen_assembler_p = 1;
1224 gen_disassembler_p = 1;
1231 if (argc == 1 || optind != argc)
1234 if (gen_opcode_p + gen_assembler_p + gen_disassembler_p > 1)
1236 printf ("Please specify only one of the following options\n\
1237 [-c | --gen-opc] [-a | --gen-asm] [-s | --gen-dis]\n");
1241 struct bittree *decoder_tree;
1243 decoder_tree = initialize_decoder_tree ();
1245 print_divide_result (decoder_tree);
1247 printf ("/* This file is automatically generated by aarch64-gen. Do not edit! */\n");
1248 printf ("/* Copyright (C) 2012-2016 Free Software Foundation, Inc.\n\
1249 Contributed by ARM Ltd.\n\
1251 This file is part of the GNU opcodes library.\n\
1253 This library is free software; you can redistribute it and/or modify\n\
1254 it under the terms of the GNU General Public License as published by\n\
1255 the Free Software Foundation; either version 3, or (at your option)\n\
1256 any later version.\n\
1258 It is distributed in the hope that it will be useful, but WITHOUT\n\
1259 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
1260 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
1261 License for more details.\n\
1263 You should have received a copy of the GNU General Public License\n\
1264 along with this program; see the file COPYING3. If not,\n\
1265 see <http://www.gnu.org/licenses/>. */\n");
1268 printf ("#include \"sysdep.h\"\n");
1270 printf ("#include \"aarch64-opc.h\"\n");
1271 if (gen_assembler_p)
1272 printf ("#include \"aarch64-asm.h\"\n");
1273 if (gen_disassembler_p)
1274 printf ("#include \"aarch64-dis.h\"\n");
1277 /* Generate opcode entry lookup for the disassembler. */
1278 if (gen_disassembler_p)
1280 print_decision_tree (decoder_tree);
1281 print_find_next_opcode (decoder_tree);
1282 release_resource_decoder_tree (decoder_tree);
1285 /* Generate alias opcode handling for the assembler or the disassembler. */
1286 if (gen_assembler_p || gen_disassembler_p)
1289 opcode_node *alias_info = create_alias_info (&num);
1291 if (gen_assembler_p)
1292 print_find_real_opcode (alias_info, num);
1294 if (gen_disassembler_p)
1296 print_find_alias_opcode (alias_info, num);
1297 print_find_next_alias_opcode (alias_info, num);
1300 release_resource_alias_info (alias_info, num);
1303 /* Generate operand table. */
1304 process_operand_table ();
1306 if (gen_assembler_p)
1307 print_operand_inserter ();
1309 if (gen_disassembler_p)
1310 print_operand_extractor ();
1313 print_operand_table ();
1315 /* Generate utility to return aarch64_opcode entry given an enumerator. */
1317 print_get_opcode ();