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