aarch64-gen.c 34 KB

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