gen-icache.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /* The IGEN simulator generator for GDB, the GNU Debugger.
  2. Copyright 2002-2022 Free Software Foundation, Inc.
  3. Contributed by Andrew Cagney.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include <stdlib.h>
  16. #include "misc.h"
  17. #include "lf.h"
  18. #include "table.h"
  19. #include "filter.h"
  20. #include "igen.h"
  21. #include "ld-insn.h"
  22. #include "ld-decode.h"
  23. #include "gen.h"
  24. #include "gen-semantics.h"
  25. #include "gen-idecode.h"
  26. #include "gen-icache.h"
  27. static void
  28. print_icache_function_header (lf *file,
  29. const char *basename,
  30. const char *format_name,
  31. opcode_bits *expanded_bits,
  32. int is_function_definition,
  33. int nr_prefetched_words)
  34. {
  35. lf_printf (file, "\n");
  36. lf_print__function_type_function (file, print_icache_function_type,
  37. "EXTERN_ICACHE", " ");
  38. print_function_name (file,
  39. basename, format_name, NULL,
  40. expanded_bits, function_name_prefix_icache);
  41. lf_printf (file, "\n(");
  42. print_icache_function_formal (file, nr_prefetched_words);
  43. lf_printf (file, ")");
  44. if (!is_function_definition)
  45. lf_printf (file, ";");
  46. lf_printf (file, "\n");
  47. }
  48. void
  49. print_icache_declaration (lf *file,
  50. insn_entry * insn,
  51. opcode_bits *expanded_bits,
  52. insn_opcodes *opcodes, int nr_prefetched_words)
  53. {
  54. print_icache_function_header (file,
  55. insn->name,
  56. insn->format_name,
  57. expanded_bits,
  58. 0 /* is not function definition */ ,
  59. nr_prefetched_words);
  60. }
  61. static void
  62. print_icache_extraction (lf *file,
  63. const char *format_name,
  64. cache_entry_type cache_type,
  65. const char *entry_name,
  66. const char *entry_type,
  67. const char *entry_expression,
  68. char *single_insn_field,
  69. line_ref *line,
  70. insn_field_entry *cur_field,
  71. opcode_bits *expanded_bits,
  72. icache_decl_type what_to_declare,
  73. icache_body_type what_to_do)
  74. {
  75. const char *expression;
  76. opcode_bits *bits;
  77. char *reason;
  78. ASSERT (format_name != NULL);
  79. ASSERT (entry_name != NULL);
  80. /* figure out exactly what should be going on here */
  81. switch (cache_type)
  82. {
  83. case scratch_value:
  84. if ((what_to_do & put_values_in_icache)
  85. || what_to_do == do_not_use_icache)
  86. {
  87. reason = "scratch";
  88. what_to_do = do_not_use_icache;
  89. }
  90. else
  91. return;
  92. break;
  93. case compute_value:
  94. if ((what_to_do & get_values_from_icache)
  95. || what_to_do == do_not_use_icache)
  96. {
  97. reason = "compute";
  98. what_to_do = do_not_use_icache;
  99. }
  100. else
  101. return;
  102. break;
  103. case cache_value:
  104. if ((what_to_declare != undef_variables)
  105. || !(what_to_do & put_values_in_icache))
  106. {
  107. reason = "cache";
  108. what_to_declare = ((what_to_do & put_values_in_icache)
  109. ? declare_variables : what_to_declare);
  110. }
  111. else
  112. return;
  113. break;
  114. default:
  115. abort (); /* Bad switch. */
  116. }
  117. /* For the type, default to a simple unsigned */
  118. if (entry_type == NULL || strlen (entry_type) == 0)
  119. entry_type = "unsigned";
  120. /* look through the set of expanded sub fields to see if this field
  121. has been given a constant value */
  122. for (bits = expanded_bits; bits != NULL; bits = bits->next)
  123. {
  124. if (bits->field == cur_field)
  125. break;
  126. }
  127. /* Define a storage area for the cache element */
  128. switch (what_to_declare)
  129. {
  130. case undef_variables:
  131. /* We've finished with the #define value - destory it */
  132. lf_indent_suppress (file);
  133. lf_printf (file, "#undef %s\n", entry_name);
  134. return;
  135. case define_variables:
  136. /* Using direct access for this entry, clear any prior
  137. definition, then define it */
  138. lf_indent_suppress (file);
  139. lf_printf (file, "#undef %s\n", entry_name);
  140. /* Don't type cast pointer types! */
  141. lf_indent_suppress (file);
  142. if (strchr (entry_type, '*') != NULL)
  143. lf_printf (file, "#define %s (", entry_name);
  144. else
  145. lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
  146. break;
  147. case declare_variables:
  148. /* using variables to define the value */
  149. if (line != NULL)
  150. lf_print__line_ref (file, line);
  151. lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
  152. break;
  153. }
  154. /* define a value for that storage area as determined by what is in
  155. the cache */
  156. if (bits != NULL
  157. && single_insn_field != NULL
  158. && strcmp (entry_name, single_insn_field) == 0
  159. && strcmp (entry_name, cur_field->val_string) == 0
  160. && ((bits->opcode->is_boolean && bits->value == 0)
  161. || (!bits->opcode->is_boolean)))
  162. {
  163. /* The cache rule is specifying what to do with a simple
  164. instruction field.
  165. Because of instruction expansion, the field is either a
  166. constant value or equal to the specified constant (boolean
  167. comparison). (The latter indicated by bits->value == 0).
  168. The case of a field not being equal to the specified boolean
  169. value is handled later. */
  170. expression = "constant field";
  171. ASSERT (bits->field == cur_field);
  172. if (bits->opcode->is_boolean)
  173. {
  174. ASSERT (bits->value == 0);
  175. lf_printf (file, "%d", bits->opcode->boolean_constant);
  176. }
  177. else if (bits->opcode->last < bits->field->last)
  178. {
  179. lf_printf (file, "%d",
  180. bits->value << (bits->field->last - bits->opcode->last));
  181. }
  182. else
  183. {
  184. lf_printf (file, "%d", bits->value);
  185. }
  186. }
  187. else if (bits != NULL
  188. && single_insn_field != NULL
  189. && strncmp (entry_name,
  190. single_insn_field,
  191. strlen (single_insn_field)) == 0
  192. && strncmp (entry_name + strlen (single_insn_field),
  193. "_is_",
  194. strlen ("_is_")) == 0
  195. && ((bits->opcode->is_boolean
  196. && ((unsigned)
  197. atol (entry_name + strlen (single_insn_field) +
  198. strlen ("_is_")) == bits->opcode->boolean_constant))
  199. || (!bits->opcode->is_boolean)))
  200. {
  201. /* The cache rule defines an entry for the comparison between a
  202. single instruction field and a constant. The value of the
  203. comparison in someway matches that of the opcode field that
  204. was made constant through expansion. */
  205. expression = "constant compare";
  206. if (bits->opcode->is_boolean)
  207. {
  208. lf_printf (file, "%d /* %s == %d */",
  209. bits->value == 0,
  210. single_insn_field, bits->opcode->boolean_constant);
  211. }
  212. else if (bits->opcode->last < bits->field->last)
  213. {
  214. lf_printf (file, "%d /* %s == %d */",
  215. (atol
  216. (entry_name + strlen (single_insn_field) +
  217. strlen ("_is_")) ==
  218. (bits->
  219. value << (bits->field->last - bits->opcode->last))),
  220. single_insn_field,
  221. (bits->
  222. value << (bits->field->last - bits->opcode->last)));
  223. }
  224. else
  225. {
  226. lf_printf (file, "%d /* %s == %d */",
  227. (atol
  228. (entry_name + strlen (single_insn_field) +
  229. strlen ("_is_")) == bits->value), single_insn_field,
  230. bits->value);
  231. }
  232. }
  233. else
  234. {
  235. /* put the field in the local variable, possibly also enter it
  236. into the cache */
  237. expression = "extraction";
  238. /* handle the cache */
  239. if ((what_to_do & get_values_from_icache)
  240. || (what_to_do & put_values_in_icache))
  241. {
  242. lf_printf (file, "cache_entry->crack.%s.%s",
  243. format_name, entry_name);
  244. if (what_to_do & put_values_in_icache) /* also put it in the cache? */
  245. {
  246. lf_printf (file, " = ");
  247. }
  248. }
  249. if ((what_to_do & put_values_in_icache)
  250. || what_to_do == do_not_use_icache)
  251. {
  252. if (cur_field != NULL)
  253. {
  254. if (entry_expression != NULL && strlen (entry_expression) > 0)
  255. error (line,
  256. "Instruction field entry with nonempty expression\n");
  257. if (cur_field->first == 0
  258. && cur_field->last == options.insn_bit_size - 1)
  259. lf_printf (file, "(instruction_%d)", cur_field->word_nr);
  260. else if (cur_field->last == options.insn_bit_size - 1)
  261. lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
  262. options.insn_bit_size,
  263. cur_field->word_nr,
  264. i2target (options.hi_bit_nr, cur_field->first),
  265. i2target (options.hi_bit_nr, cur_field->last));
  266. else
  267. lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",
  268. options.insn_bit_size,
  269. cur_field->word_nr,
  270. i2target (options.hi_bit_nr, cur_field->first),
  271. i2target (options.hi_bit_nr, cur_field->last));
  272. }
  273. else
  274. {
  275. lf_printf (file, "%s", entry_expression);
  276. }
  277. }
  278. }
  279. switch (what_to_declare)
  280. {
  281. case define_variables:
  282. lf_printf (file, ")");
  283. break;
  284. case undef_variables:
  285. break;
  286. case declare_variables:
  287. lf_printf (file, ";");
  288. break;
  289. }
  290. ASSERT (reason != NULL && expression != NULL);
  291. lf_printf (file, " /* %s - %s */\n", reason, expression);
  292. }
  293. void
  294. print_icache_body (lf *file,
  295. insn_entry * instruction,
  296. opcode_bits *expanded_bits,
  297. cache_entry *cache_rules,
  298. icache_decl_type what_to_declare,
  299. icache_body_type what_to_do, int nr_prefetched_words)
  300. {
  301. /* extract instruction fields */
  302. lf_printf (file, "/* Extraction: %s\n", instruction->name);
  303. lf_printf (file, " ");
  304. switch (what_to_declare)
  305. {
  306. case define_variables:
  307. lf_printf (file, "#define");
  308. break;
  309. case declare_variables:
  310. lf_printf (file, "declare");
  311. break;
  312. case undef_variables:
  313. lf_printf (file, "#undef");
  314. break;
  315. }
  316. lf_printf (file, " ");
  317. switch (what_to_do)
  318. {
  319. case get_values_from_icache:
  320. lf_printf (file, "get-values-from-icache");
  321. break;
  322. case put_values_in_icache:
  323. lf_printf (file, "put-values-in-icache");
  324. break;
  325. case both_values_and_icache:
  326. lf_printf (file, "get-values-from-icache|put-values-in-icache");
  327. break;
  328. case do_not_use_icache:
  329. lf_printf (file, "do-not-use-icache");
  330. break;
  331. }
  332. lf_printf (file, "\n ");
  333. print_insn_words (file, instruction);
  334. lf_printf (file, " */\n");
  335. /* pass zero - fetch from memory any missing instructions.
  336. Some of the instructions will have already been fetched (in the
  337. instruction array), others will still need fetching. */
  338. switch (what_to_do)
  339. {
  340. case get_values_from_icache:
  341. break;
  342. case put_values_in_icache:
  343. case both_values_and_icache:
  344. case do_not_use_icache:
  345. {
  346. int word_nr;
  347. switch (what_to_declare)
  348. {
  349. case undef_variables:
  350. break;
  351. case define_variables:
  352. case declare_variables:
  353. for (word_nr = nr_prefetched_words;
  354. word_nr < instruction->nr_words; word_nr++)
  355. {
  356. /* FIXME - should be using print_icache_extraction? */
  357. lf_printf (file,
  358. "%sinstruction_word instruction_%d UNUSED = ",
  359. options.module.global.prefix.l, word_nr);
  360. lf_printf (file, "IMEM%d_IMMED (cia, %d)",
  361. options.insn_bit_size, word_nr);
  362. lf_printf (file, ";\n");
  363. }
  364. }
  365. }
  366. }
  367. /* if putting the instruction words in the cache, define references
  368. for them */
  369. if (options.gen.insn_in_icache)
  370. {
  371. /* FIXME: is the instruction_word type correct? */
  372. print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */
  373. "instruction_word", /* type */
  374. "instruction", /* expression */
  375. NULL, /* origin */
  376. NULL, /* line */
  377. NULL, NULL, what_to_declare, what_to_do);
  378. }
  379. lf_printf (file, "\n");
  380. /* pass one - process instruction fields.
  381. If there is no cache rule, the default is to enter the field into
  382. the cache */
  383. {
  384. insn_word_entry *word;
  385. for (word = instruction->words; word != NULL; word = word->next)
  386. {
  387. insn_field_entry *cur_field;
  388. for (cur_field = word->first;
  389. cur_field->first < options.insn_bit_size;
  390. cur_field = cur_field->next)
  391. {
  392. /* Always expand named fields (even if constant), so
  393. references are valid. */
  394. if (cur_field->type == insn_field_string)
  395. {
  396. cache_entry *cache_rule;
  397. cache_entry_type value_type = cache_value;
  398. line_ref *value_line = instruction->line;
  399. /* check the cache table to see if it contains a rule
  400. overriding the default cache action for an
  401. instruction field */
  402. for (cache_rule = cache_rules;
  403. cache_rule != NULL; cache_rule = cache_rule->next)
  404. {
  405. if (filter_is_subset (instruction->field_names,
  406. cache_rule->original_fields)
  407. && strcmp (cache_rule->name,
  408. cur_field->val_string) == 0)
  409. {
  410. value_type = cache_rule->entry_type;
  411. value_line = cache_rule->line;
  412. if (value_type == compute_value)
  413. {
  414. options.warning (cache_rule->line,
  415. "instruction field of type `compute' changed to `cache'\n");
  416. cache_rule->entry_type = cache_value;
  417. }
  418. break;
  419. }
  420. }
  421. /* Define an entry for the field within the
  422. instruction */
  423. print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */
  424. NULL, /* type */
  425. NULL, /* expression */
  426. cur_field->val_string, /* insn field */
  427. value_line,
  428. cur_field,
  429. expanded_bits,
  430. what_to_declare, what_to_do);
  431. }
  432. }
  433. }
  434. }
  435. /* pass two - any cache fields not processed above */
  436. {
  437. cache_entry *cache_rule;
  438. for (cache_rule = cache_rules;
  439. cache_rule != NULL; cache_rule = cache_rule->next)
  440. {
  441. if (filter_is_subset (instruction->field_names,
  442. cache_rule->original_fields)
  443. && !filter_is_member (instruction->field_names, cache_rule->name))
  444. {
  445. char *single_field =
  446. filter_next (cache_rule->original_fields, "");
  447. if (filter_next (cache_rule->original_fields, single_field) !=
  448. NULL)
  449. single_field = NULL;
  450. print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL, /* cur_field */
  451. expanded_bits,
  452. what_to_declare, what_to_do);
  453. }
  454. }
  455. }
  456. lf_print__internal_ref (file);
  457. }
  458. typedef struct _form_fields form_fields;
  459. struct _form_fields
  460. {
  461. char *name;
  462. filter *fields;
  463. form_fields *next;
  464. };
  465. static form_fields *
  466. insn_table_cache_fields (insn_table *isa)
  467. {
  468. form_fields *forms = NULL;
  469. insn_entry *insn;
  470. for (insn = isa->insns; insn != NULL; insn = insn->next)
  471. {
  472. form_fields **form = &forms;
  473. while (1)
  474. {
  475. if (*form == NULL)
  476. {
  477. /* new format name, add it */
  478. form_fields *new_form = ZALLOC (form_fields);
  479. new_form->name = insn->format_name;
  480. filter_add (&new_form->fields, insn->field_names);
  481. *form = new_form;
  482. break;
  483. }
  484. else if (strcmp ((*form)->name, insn->format_name) == 0)
  485. {
  486. /* already present, add field names to the existing list */
  487. filter_add (&(*form)->fields, insn->field_names);
  488. break;
  489. }
  490. form = &(*form)->next;
  491. }
  492. }
  493. return forms;
  494. }
  495. extern void
  496. print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
  497. {
  498. /* Create a list of all the different instruction formats with their
  499. corresponding field names. */
  500. form_fields *formats = insn_table_cache_fields (isa);
  501. lf_printf (file, "\n");
  502. lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
  503. options.module.global.prefix.u,
  504. (options.gen.icache ? options.gen.icache_size : 0));
  505. lf_printf (file, "\n");
  506. /* create an instruction cache if being used */
  507. if (options.gen.icache)
  508. {
  509. lf_printf (file, "typedef struct _%sidecode_cache {\n",
  510. options.module.global.prefix.l);
  511. lf_indent (file, +2);
  512. {
  513. form_fields *format;
  514. lf_printf (file, "unsigned_word address;\n");
  515. lf_printf (file, "void *semantic;\n");
  516. lf_printf (file, "union {\n");
  517. lf_indent (file, +2);
  518. for (format = formats; format != NULL; format = format->next)
  519. {
  520. lf_printf (file, "struct {\n");
  521. lf_indent (file, +2);
  522. {
  523. cache_entry *cache_rule;
  524. char *field;
  525. /* space for any instruction words */
  526. if (options.gen.insn_in_icache)
  527. lf_printf (file, "instruction_word insn[%d];\n",
  528. isa->max_nr_words);
  529. /* define an entry for any applicable cache rules */
  530. for (cache_rule = cache_rules;
  531. cache_rule != NULL; cache_rule = cache_rule->next)
  532. {
  533. /* nb - sort of correct - should really check against
  534. individual instructions */
  535. if (filter_is_subset
  536. (format->fields, cache_rule->original_fields))
  537. {
  538. char *memb;
  539. lf_printf (file, "%s %s;",
  540. (cache_rule->type == NULL
  541. ? "unsigned"
  542. : cache_rule->type), cache_rule->name);
  543. lf_printf (file, " /*");
  544. for (memb =
  545. filter_next (cache_rule->original_fields, "");
  546. memb != NULL;
  547. memb =
  548. filter_next (cache_rule->original_fields, memb))
  549. {
  550. lf_printf (file, " %s", memb);
  551. }
  552. lf_printf (file, " */\n");
  553. }
  554. }
  555. /* define an entry for any fields not covered by a cache rule */
  556. for (field = filter_next (format->fields, "");
  557. field != NULL; field = filter_next (format->fields, field))
  558. {
  559. cache_entry *cache_rule;
  560. int found_rule = 0;
  561. for (cache_rule = cache_rules;
  562. cache_rule != NULL; cache_rule = cache_rule->next)
  563. {
  564. if (strcmp (cache_rule->name, field) == 0)
  565. {
  566. found_rule = 1;
  567. break;
  568. }
  569. }
  570. if (!found_rule)
  571. lf_printf (file, "unsigned %s; /* default */\n", field);
  572. }
  573. }
  574. lf_indent (file, -2);
  575. lf_printf (file, "} %s;\n", format->name);
  576. }
  577. lf_indent (file, -2);
  578. lf_printf (file, "} crack;\n");
  579. }
  580. lf_indent (file, -2);
  581. lf_printf (file, "} %sidecode_cache;\n",
  582. options.module.global.prefix.l);
  583. }
  584. else
  585. {
  586. /* alernativly, since no cache, emit a dummy definition for
  587. idecode_cache so that code refering to the type can still compile */
  588. lf_printf (file, "typedef void %sidecode_cache;\n",
  589. options.module.global.prefix.l);
  590. }
  591. lf_printf (file, "\n");
  592. }
  593. static void
  594. print_icache_function (lf *file,
  595. insn_entry * instruction,
  596. opcode_bits *expanded_bits,
  597. insn_opcodes *opcodes,
  598. cache_entry *cache_rules, int nr_prefetched_words)
  599. {
  600. int indent;
  601. /* generate code to enter decoded instruction into the icache */
  602. lf_printf (file, "\n");
  603. lf_print__function_type_function (file, print_icache_function_type,
  604. "EXTERN_ICACHE", "\n");
  605. indent = print_function_name (file,
  606. instruction->name,
  607. instruction->format_name,
  608. NULL,
  609. expanded_bits, function_name_prefix_icache);
  610. indent += lf_printf (file, " ");
  611. lf_indent (file, +indent);
  612. lf_printf (file, "(");
  613. print_icache_function_formal (file, nr_prefetched_words);
  614. lf_printf (file, ")\n");
  615. lf_indent (file, -indent);
  616. /* function header */
  617. lf_printf (file, "{\n");
  618. lf_indent (file, +2);
  619. print_my_defines (file,
  620. instruction->name,
  621. instruction->format_name, expanded_bits);
  622. print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
  623. print_idecode_validate (file, instruction, opcodes);
  624. lf_printf (file, "\n");
  625. lf_printf (file, "{\n");
  626. lf_indent (file, +2);
  627. if (options.gen.semantic_icache)
  628. lf_printf (file, "unsigned_word nia;\n");
  629. print_icache_body (file,
  630. instruction,
  631. expanded_bits,
  632. cache_rules,
  633. (options.gen.direct_access
  634. ? define_variables
  635. : declare_variables),
  636. (options.gen.semantic_icache
  637. ? both_values_and_icache
  638. : put_values_in_icache), nr_prefetched_words);
  639. lf_printf (file, "\n");
  640. lf_printf (file, "cache_entry->address = cia;\n");
  641. lf_printf (file, "cache_entry->semantic = ");
  642. print_function_name (file,
  643. instruction->name,
  644. instruction->format_name,
  645. NULL, expanded_bits, function_name_prefix_semantics);
  646. lf_printf (file, ";\n");
  647. lf_printf (file, "\n");
  648. if (options.gen.semantic_icache)
  649. {
  650. lf_printf (file, "/* semantic routine */\n");
  651. print_semantic_body (file, instruction, expanded_bits, opcodes);
  652. lf_printf (file, "return nia;\n");
  653. }
  654. if (!options.gen.semantic_icache)
  655. {
  656. lf_printf (file, "/* return the function proper */\n");
  657. lf_printf (file, "return ");
  658. print_function_name (file,
  659. instruction->name,
  660. instruction->format_name,
  661. NULL,
  662. expanded_bits, function_name_prefix_semantics);
  663. lf_printf (file, ";\n");
  664. }
  665. if (options.gen.direct_access)
  666. {
  667. print_icache_body (file,
  668. instruction,
  669. expanded_bits,
  670. cache_rules,
  671. undef_variables,
  672. (options.gen.semantic_icache
  673. ? both_values_and_icache
  674. : put_values_in_icache), nr_prefetched_words);
  675. }
  676. lf_indent (file, -2);
  677. lf_printf (file, "}\n");
  678. lf_indent (file, -2);
  679. lf_printf (file, "}\n");
  680. }
  681. void
  682. print_icache_definition (lf *file,
  683. insn_entry * insn,
  684. opcode_bits *expanded_bits,
  685. insn_opcodes *opcodes,
  686. cache_entry *cache_rules, int nr_prefetched_words)
  687. {
  688. print_icache_function (file,
  689. insn,
  690. expanded_bits,
  691. opcodes, cache_rules, nr_prefetched_words);
  692. }
  693. void
  694. print_icache_internal_function_declaration (lf *file,
  695. function_entry * function,
  696. void *data)
  697. {
  698. ASSERT (options.gen.icache);
  699. if (function->is_internal)
  700. {
  701. lf_printf (file, "\n");
  702. lf_print__function_type_function (file, print_icache_function_type,
  703. "INLINE_ICACHE", "\n");
  704. print_function_name (file,
  705. function->name,
  706. NULL, NULL, NULL, function_name_prefix_icache);
  707. lf_printf (file, "\n(");
  708. print_icache_function_formal (file, 0);
  709. lf_printf (file, ");\n");
  710. }
  711. }
  712. void
  713. print_icache_internal_function_definition (lf *file,
  714. function_entry * function,
  715. void *data)
  716. {
  717. ASSERT (options.gen.icache);
  718. if (function->is_internal)
  719. {
  720. lf_printf (file, "\n");
  721. lf_print__function_type_function (file, print_icache_function_type,
  722. "INLINE_ICACHE", "\n");
  723. print_function_name (file,
  724. function->name,
  725. NULL, NULL, NULL, function_name_prefix_icache);
  726. lf_printf (file, "\n(");
  727. print_icache_function_formal (file, 0);
  728. lf_printf (file, ")\n");
  729. lf_printf (file, "{\n");
  730. lf_indent (file, +2);
  731. lf_printf (file, "/* semantic routine */\n");
  732. if (options.gen.semantic_icache)
  733. {
  734. lf_print__line_ref (file, function->code->line);
  735. table_print_code (file, function->code);
  736. lf_printf (file,
  737. "error (\"Internal function must longjump\\n\");\n");
  738. lf_printf (file, "return 0;\n");
  739. }
  740. else
  741. {
  742. lf_printf (file, "return ");
  743. print_function_name (file,
  744. function->name,
  745. NULL,
  746. NULL, NULL, function_name_prefix_semantics);
  747. lf_printf (file, ";\n");
  748. }
  749. lf_print__internal_ref (file);
  750. lf_indent (file, -2);
  751. lf_printf (file, "}\n");
  752. }
  753. }