* Makefile.in ($(SIM_MULTI_OBJ)): Depend on sim-main.h
[deliverable/binutils-gdb.git] / sim / igen / gen-idecode.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
7b6bb8da 3 Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
feaee4bd
AC
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
feaee4bd
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
feaee4bd 21
c906108c
SS
22
23#include "misc.h"
24#include "lf.h"
25#include "table.h"
26#include "filter.h"
27#include "igen.h"
28
29#include "ld-insn.h"
30#include "ld-decode.h"
31
32#include "gen.h"
33
34#include "gen-idecode.h"
35#include "gen-icache.h"
36#include "gen-semantics.h"
37
38
39
40static void
4e0bf4c4 41lf_print_opcodes (lf *file, gen_entry *table)
c906108c 42{
4e0bf4c4 43 if (table !=NULL)
c906108c
SS
44 {
45 while (1)
46 {
47 ASSERT (table->opcode != NULL);
48 lf_printf (file, "_%d_%d",
4e0bf4c4
AC
49 table->opcode->first, table->opcode->last);
50 if (table->parent == NULL)
51 break;
c906108c
SS
52 lf_printf (file, "__%d", table->opcode_nr);
53 table = table->parent;
54 }
55 }
56}
57
58
59
60
61static void
62print_idecode_ifetch (lf *file,
63 int previous_nr_prefetched_words,
64 int current_nr_prefetched_words)
65{
66 int word_nr;
67 for (word_nr = previous_nr_prefetched_words;
4e0bf4c4 68 word_nr < current_nr_prefetched_words; word_nr++)
c906108c 69 {
4e0bf4c4
AC
70 lf_printf (file,
71 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
c906108c 72 word_nr, options.insn_bit_size, word_nr);
4e0bf4c4 73
c906108c
SS
74 }
75}
76
77
78
79/****************************************************************/
80
81
82static void
4e0bf4c4 83lf_print_table_name (lf *file, gen_entry *table)
c906108c
SS
84{
85 lf_printf (file, "idecode_table");
86 lf_print_opcodes (file, table);
87}
88
89
90
91static void
4e0bf4c4 92print_idecode_table (lf *file, gen_entry *entry, const char *result)
c906108c
SS
93{
94 lf_printf (file, "/* prime the search */\n");
95 lf_printf (file, "idecode_table_entry *table = ");
96 lf_print_table_name (file, entry);
97 lf_printf (file, ";\n");
98 lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
99 options.insn_bit_size,
100 i2target (options.hi_bit_nr, entry->opcode->first),
101 i2target (options.hi_bit_nr, entry->opcode->last));
102 lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
4e0bf4c4 103
c906108c
SS
104 lf_printf (file, "\n");
105 lf_printf (file, "/* iterate until a leaf */\n");
106 lf_printf (file, "while (1) {\n");
107 lf_printf (file, " signed shift = table_entry->shift;\n");
108 lf_printf (file, "if (shift == function_entry) break;\n");
109 lf_printf (file, " if (shift >= 0) {\n");
110 lf_printf (file, " table = ((idecode_table_entry*)\n");
111 lf_printf (file, " table_entry->function_or_table);\n");
112 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
113 lf_printf (file, " >> shift);\n");
114 lf_printf (file, " table_entry = table + opcode;\n");
115 lf_printf (file, " }\n");
116 lf_printf (file, " else {\n");
117 lf_printf (file, " /* must be a boolean */\n");
118 lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n");
119 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
120 lf_printf (file, " != table_entry->value);\n");
121 lf_printf (file, " table = ((idecode_table_entry*)\n");
122 lf_printf (file, " table_entry->function_or_table);\n");
123 lf_printf (file, " table_entry = table + opcode;\n");
124 lf_printf (file, " }\n");
125 lf_printf (file, "}\n");
4e0bf4c4 126
c906108c
SS
127 lf_printf (file, "\n");
128 lf_printf (file, "/* call the leaf code */\n");
129 if (options.gen.code == generate_jumps)
130 {
131 lf_printf (file, "goto *table_entry->function_or_table;\n");
132 }
133 else
134 {
135 lf_printf (file, "%s ", result);
136 if (options.gen.icache)
137 {
4e0bf4c4
AC
138 lf_printf (file,
139 "(((idecode_icache*)table_entry->function_or_table)\n");
c906108c
SS
140 lf_printf (file, " (");
141 print_icache_function_actual (file, 1);
142 lf_printf (file, "));\n");
143 }
144 else
145 {
4e0bf4c4
AC
146 lf_printf (file,
147 "((idecode_semantic*)table_entry->function_or_table)\n");
c906108c
SS
148 lf_printf (file, " (");
149 print_semantic_function_actual (file, 1);
150 lf_printf (file, ");\n");
151 }
152 }
153}
154
155
156static void
4e0bf4c4 157print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
158{
159 ASSERT (depth == 0);
160 /* start of the table */
161 if (table->opcode_rule->gen == array_gen)
162 {
163 lf_printf (file, "\n");
164 lf_printf (file, "static idecode_table_entry ");
165 lf_print_table_name (file, table);
166 lf_printf (file, "[] = {\n");
167 }
168}
169
170static void
4e0bf4c4 171print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
c906108c
SS
172{
173 gen_entry *master_entry;
174 ASSERT (entry->parent != NULL);
175 ASSERT (depth == 0);
176 if (entry->combined_parent == NULL)
177 master_entry = entry;
178 else
179 master_entry = entry->combined_parent;
180
181 /* add an entry to the table */
182 if (entry->parent->opcode_rule->gen == array_gen)
183 {
184 lf_printf (file, " /*%d*/ { ", entry->opcode_nr);
185 if (entry->opcode == NULL)
186 {
187 ASSERT (entry->nr_insns == 1);
188 /* table leaf entry */
189 lf_printf (file, "function_entry, 0, 0, ");
190 if (options.gen.code == generate_jumps)
191 {
192 lf_printf (file, "&&");
193 }
194 print_function_name (file,
195 entry->insns->insn->name,
196 entry->insns->insn->format_name,
197 NULL,
198 master_entry->expanded_bits,
199 (options.gen.icache
200 ? function_name_prefix_icache
201 : function_name_prefix_semantics));
202 }
203 else if (entry->opcode_rule->gen == switch_gen
204 || entry->opcode_rule->gen == goto_switch_gen
205 || entry->opcode_rule->gen == padded_switch_gen)
206 {
207 /* table calling switch statement */
208 lf_printf (file, "function_entry, 0, 0, ");
209 if (options.gen.code == generate_jumps)
210 {
211 lf_printf (file, "&&");
212 }
213 lf_print_table_name (file, entry);
214 }
215 else if (entry->opcode->is_boolean)
216 {
217 /* table `calling' boolean table */
218 lf_printf (file, "boolean_entry, ");
219 lf_printf (file, "MASK32(%d, %d), ",
220 i2target (options.hi_bit_nr, entry->opcode->first),
221 i2target (options.hi_bit_nr, entry->opcode->last));
222 lf_printf (file, "INSERTED32(%d, %d, %d), ",
223 entry->opcode->boolean_constant,
224 i2target (options.hi_bit_nr, entry->opcode->first),
225 i2target (options.hi_bit_nr, entry->opcode->last));
226 lf_print_table_name (file, entry);
227 }
228 else
229 {
230 /* table `calling' another table */
4e0bf4c4
AC
231 lf_printf (file, "%d, ",
232 options.insn_bit_size - entry->opcode->last - 1);
233 lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
c906108c
SS
234 i2target (options.hi_bit_nr, entry->opcode->first),
235 i2target (options.hi_bit_nr, entry->opcode->last));
236 lf_printf (file, "0, ");
237 lf_print_table_name (file, entry);
238 }
239 lf_printf (file, " },\n");
240 }
241}
242
243static void
4e0bf4c4 244print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
245{
246 ASSERT (depth == 0);
4e0bf4c4
AC
247 if (table->opcode_rule->gen == array_gen)
248 {
249 lf_printf (file, "};\n");
250 }
c906108c
SS
251}
252
253/****************************************************************/
254
255
256static void
4e0bf4c4 257print_goto_switch_name (lf *file, gen_entry *entry)
c906108c
SS
258{
259 lf_printf (file, "case_");
260 if (entry->opcode == NULL)
261 {
262 print_function_name (file,
263 entry->insns->insn->name,
264 entry->insns->insn->format_name,
265 NULL,
266 entry->expanded_bits,
267 (options.gen.icache
268 ? function_name_prefix_icache
269 : function_name_prefix_semantics));
270 }
271 else
272 {
4e0bf4c4 273 lf_print_table_name (file, entry);
c906108c
SS
274 }
275}
276
277static void
278print_goto_switch_table_leaf (lf *file,
4e0bf4c4 279 gen_entry *entry, int depth, void *data)
c906108c
SS
280{
281 ASSERT (entry->parent != NULL);
282 ASSERT (depth == 0);
283 ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
284 ASSERT (entry->parent->opcode);
4e0bf4c4 285
c906108c
SS
286 lf_printf (file, "/* %d */ &&", entry->opcode_nr);
287 if (entry->combined_parent != NULL)
288 print_goto_switch_name (file, entry->combined_parent);
289 else
290 print_goto_switch_name (file, entry);
291 lf_printf (file, ",\n");
292}
293
294static void
4e0bf4c4 295print_goto_switch_break (lf *file, gen_entry *entry)
c906108c
SS
296{
297 lf_printf (file, "goto break_");
298 lf_print_table_name (file, entry->parent);
299 lf_printf (file, ";\n");
300}
301
302
303static void
4e0bf4c4 304print_goto_switch_table (lf *file, gen_entry *table)
c906108c
SS
305{
306 lf_printf (file, "const static void *");
307 lf_print_table_name (file, table);
308 lf_printf (file, "[] = {\n");
309 lf_indent (file, +2);
4e0bf4c4
AC
310 gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
311 print_goto_switch_table_leaf, NULL /*end */ ,
312 NULL /*data */ );
c906108c
SS
313 lf_indent (file, -2);
314 lf_printf (file, "};\n");
315}
316
317
4e0bf4c4 318void print_idecode_switch (lf *file, gen_entry *table, const char *result);
c906108c
SS
319
320static void
4e0bf4c4 321print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
322{
323 /* const char *result = data; */
324 ASSERT (depth == 0);
325 ASSERT (table->opcode_rule->gen == switch_gen
326 || table->opcode_rule->gen == goto_switch_gen
327 || table->opcode_rule->gen == padded_switch_gen);
4e0bf4c4 328
c906108c
SS
329 if (table->opcode->is_boolean
330 || table->opcode_rule->gen == switch_gen
331 || table->opcode_rule->gen == padded_switch_gen)
332 {
333 lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
334 options.insn_bit_size,
335 table->opcode_rule->word_nr,
336 i2target (options.hi_bit_nr, table->opcode->first),
337 i2target (options.hi_bit_nr, table->opcode->last));
338 lf_indent (file, +2);
339 lf_printf (file, "{\n");
340 }
341 else if (table->opcode_rule->gen == goto_switch_gen)
342 {
343 if (table->parent != NULL
344 && (table->parent->opcode_rule->gen == switch_gen
345 || table->parent->opcode_rule->gen == goto_switch_gen
346 || table->parent->opcode_rule->gen == padded_switch_gen))
347 {
348 lf_printf (file, "{\n");
349 lf_indent (file, +2);
350 }
351 print_goto_switch_table (file, table);
352 lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
353 options.insn_bit_size,
354 table->opcode->word_nr,
355 i2target (options.hi_bit_nr, table->opcode->first),
356 i2target (options.hi_bit_nr, table->opcode->last));
357 lf_printf (file, " < (sizeof (");
358 lf_print_table_name (file, table);
359 lf_printf (file, ") / sizeof(void*)));\n");
360 lf_printf (file, "goto *");
361 lf_print_table_name (file, table);
362 lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
363 options.insn_bit_size,
364 table->opcode->word_nr,
365 i2target (options.hi_bit_nr, table->opcode->first),
366 i2target (options.hi_bit_nr, table->opcode->last));
367 }
368 else
369 {
4e0bf4c4 370 ASSERT ("bad switch" == NULL);
c906108c
SS
371 }
372}
373
374
375static void
4e0bf4c4 376print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
c906108c
SS
377{
378 const char *result = data;
379 ASSERT (entry->parent != NULL);
380 ASSERT (depth == 0);
381 ASSERT (entry->parent->opcode_rule->gen == switch_gen
382 || entry->parent->opcode_rule->gen == goto_switch_gen
383 || entry->parent->opcode_rule->gen == padded_switch_gen);
384 ASSERT (entry->parent->opcode);
4e0bf4c4 385
c906108c
SS
386 /* skip over any instructions combined into another entry */
387 if (entry->combined_parent != NULL)
388 return;
389
4e0bf4c4 390 if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
c906108c
SS
391 {
392 /* case: boolean false target */
393 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
394 }
4e0bf4c4 395 else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
c906108c
SS
396 {
397 /* case: boolean true case */
398 lf_printf (file, "default:\n");
399 }
400 else if (entry->parent->opcode_rule->gen == switch_gen
401 || entry->parent->opcode_rule->gen == padded_switch_gen)
402 {
403 /* case: <opcode-nr> - switch */
404 gen_entry *cob;
405 for (cob = entry; cob != NULL; cob = cob->combined_next)
406 lf_printf (file, "case %d:\n", cob->opcode_nr);
407 }
408 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
409 {
410 /* case: <opcode-nr> - goto-switch */
411 print_goto_switch_name (file, entry);
412 lf_printf (file, ":\n");
413 }
414 else
415 {
416 ERROR ("bad switch");
417 }
418 lf_printf (file, " {\n");
419 lf_indent (file, +4);
420 {
421 if (entry->opcode == NULL)
422 {
423 /* switch calling leaf */
424 ASSERT (entry->nr_insns == 1);
425 print_idecode_ifetch (file, entry->nr_prefetched_words,
426 entry->insns->semantic->nr_prefetched_words);
427 switch (options.gen.code)
428 {
429 case generate_jumps:
430 lf_printf (file, "goto ");
431 break;
432 case generate_calls:
433 lf_printf (file, "%s", result);
434 break;
435 }
436 print_function_name (file,
437 entry->insns->insn->name,
438 entry->insns->insn->format_name,
439 NULL,
440 entry->expanded_bits,
441 (options.gen.icache
442 ? function_name_prefix_icache
443 : function_name_prefix_semantics));
444 if (options.gen.code == generate_calls)
445 {
446 lf_printf (file, " (");
4e0bf4c4
AC
447 print_semantic_function_actual (file,
448 entry->insns->semantic->
449 nr_prefetched_words);
c906108c
SS
450 lf_printf (file, ")");
451 }
452 lf_printf (file, ";\n");
453 }
454 else if (entry->opcode_rule->gen == switch_gen
455 || entry->opcode_rule->gen == goto_switch_gen
456 || entry->opcode_rule->gen == padded_switch_gen)
457 {
458 /* switch calling switch */
459 lf_printf (file, "{\n");
460 lf_indent (file, +2);
461 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
462 entry->nr_prefetched_words);
463 print_idecode_switch (file, entry, result);
464 lf_indent (file, -2);
465 lf_printf (file, "}\n");
466 }
467 else
468 {
469 /* switch looking up a table */
470 lf_printf (file, "{\n");
471 lf_indent (file, +2);
472 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
473 entry->nr_prefetched_words);
474 print_idecode_table (file, entry, result);
475 lf_indent (file, -2);
476 lf_printf (file, "}\n");
477 }
478 if (entry->parent->opcode->is_boolean
479 || entry->parent->opcode_rule->gen == switch_gen
480 || entry->parent->opcode_rule->gen == padded_switch_gen)
481 {
482 lf_printf (file, "break;\n");
483 }
484 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
485 {
4e0bf4c4 486 print_goto_switch_break (file, entry);
c906108c
SS
487 }
488 else
489 {
490 ERROR ("bad switch");
491 }
492 }
493 lf_indent (file, -4);
494 lf_printf (file, " }\n");
495}
496
497
498static void
4e0bf4c4 499print_idecode_switch_illegal (lf *file, const char *result)
c906108c
SS
500{
501 lf_indent (file, +2);
502 print_idecode_invalid (file, result, invalid_illegal);
503 lf_printf (file, "break;\n");
504 lf_indent (file, -2);
505}
506
507static void
4e0bf4c4 508print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
509{
510 const char *result = data;
511 ASSERT (depth == 0);
512 ASSERT (table->opcode_rule->gen == switch_gen
513 || table->opcode_rule->gen == goto_switch_gen
514 || table->opcode_rule->gen == padded_switch_gen);
515 ASSERT (table->opcode);
4e0bf4c4 516
c906108c
SS
517 if (table->opcode->is_boolean)
518 {
519 lf_printf (file, "}\n");
520 lf_indent (file, -2);
521 }
522 else if (table->opcode_rule->gen == switch_gen
523 || table->opcode_rule->gen == padded_switch_gen)
524 {
525 lf_printf (file, "default:\n");
526 lf_indent (file, +2);
527 if (table->nr_entries == table->opcode->nr_opcodes)
528 {
4e0bf4c4
AC
529 print_sim_engine_abort (file,
530 "Internal error - bad switch generated");
c906108c
SS
531 lf_printf (file, "%sNULL_CIA;\n", result);
532 lf_printf (file, "break;\n");
533 }
534 else
535 {
536 print_idecode_switch_illegal (file, result);
537 }
538 lf_indent (file, -2);
539 lf_printf (file, "}\n");
540 lf_indent (file, -2);
541 }
542 else if (table->opcode_rule->gen == goto_switch_gen)
543 {
544 lf_printf (file, "illegal_");
545 lf_print_table_name (file, table);
546 lf_printf (file, ":\n");
547 print_idecode_invalid (file, result, invalid_illegal);
548 lf_printf (file, "break_");
4e0bf4c4 549 lf_print_table_name (file, table);
c906108c
SS
550 lf_printf (file, ":;\n");
551 if (table->parent != NULL
552 && (table->parent->opcode_rule->gen == switch_gen
553 || table->parent->opcode_rule->gen == goto_switch_gen
554 || table->parent->opcode_rule->gen == padded_switch_gen))
555 {
556 lf_indent (file, -2);
557 lf_printf (file, "}\n");
558 }
559 }
560 else
561 {
562 ERROR ("bad switch");
563 }
564}
565
566
567void
4e0bf4c4 568print_idecode_switch (lf *file, gen_entry *table, const char *result)
c906108c
SS
569{
570 gen_entry_traverse_tree (file, table,
571 0,
572 print_idecode_switch_start,
573 print_idecode_switch_leaf,
4e0bf4c4 574 print_idecode_switch_end, (void *) result);
c906108c
SS
575}
576
577
578static void
579print_idecode_switch_function_header (lf *file,
580 gen_entry *table,
581 int is_function_definition,
582 int nr_prefetched_words)
583{
584 lf_printf (file, "\n");
585 if (options.gen.code == generate_calls)
586 {
587 lf_printf (file, "static ");
588 if (options.gen.icache)
589 {
590 lf_printf (file, "idecode_semantic *");
591 }
592 else
593 {
594 lf_printf (file, "unsigned_word");
595 }
596 if (is_function_definition)
597 {
598 lf_printf (file, "\n");
599 }
600 else
601 {
602 lf_printf (file, " ");
603 }
604 lf_print_table_name (file, table);
605 lf_printf (file, "\n(");
606 print_icache_function_formal (file, nr_prefetched_words);
607 lf_printf (file, ")");
608 if (!is_function_definition)
609 {
610 lf_printf (file, ";");
611 }
612 lf_printf (file, "\n");
613 }
614 if (options.gen.code == generate_jumps && is_function_definition)
615 {
616 lf_indent (file, -1);
617 lf_print_table_name (file, table);
618 lf_printf (file, ":\n");
619 lf_indent (file, +1);
620 }
621}
622
623
624static void
4e0bf4c4 625idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
c906108c 626{
4e0bf4c4 627 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */
c906108c
SS
628 && table->parent->opcode_rule->gen == array_gen)
629 {
630 print_idecode_switch_function_header (file,
631 table,
4e0bf4c4 632 0 /*isnt function definition */ ,
c906108c
SS
633 0);
634 }
635}
636
637
638static void
4e0bf4c4 639idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
c906108c 640{
4e0bf4c4 641 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */
c906108c
SS
642 && table->parent->opcode_rule->gen == array_gen)
643 {
4e0bf4c4
AC
644 print_idecode_switch_function_header (file,
645 table,
646 1 /*is function definition */ ,
647 0);
c906108c
SS
648 if (options.gen.code == generate_calls)
649 {
650 lf_printf (file, "{\n");
651 lf_indent (file, +2);
652 }
4e0bf4c4 653 print_idecode_switch (file, table, "return");
c906108c
SS
654 if (options.gen.code == generate_calls)
655 {
656 lf_indent (file, -2);
657 lf_printf (file, "}\n");
658 }
659 }
660}
661
662
663/****************************************************************/
664
665
666void
4e0bf4c4 667print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
c906108c
SS
668{
669 int depth;
4e0bf4c4 670
c906108c 671 /* output switch function declarations where needed by tables */
4e0bf4c4
AC
672 gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */
673 NULL, NULL, NULL);
674
c906108c 675 /* output tables where needed */
4e0bf4c4 676 for (depth = gen_entry_depth (table); depth > 0; depth--)
c906108c
SS
677 {
678 gen_entry_traverse_tree (file, table,
4e0bf4c4 679 1 - depth,
c906108c
SS
680 print_idecode_table_start,
681 print_idecode_table_leaf,
4e0bf4c4 682 print_idecode_table_end, NULL);
c906108c 683 }
4e0bf4c4 684
c906108c 685 /* output switch functions where needed */
4e0bf4c4
AC
686 gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */
687 NULL, NULL, NULL);
c906108c
SS
688}
689
690
691void
4e0bf4c4 692print_idecode_body (lf *file, gen_entry *table, const char *result)
c906108c
SS
693{
694 if (table->opcode_rule->gen == switch_gen
695 || table->opcode_rule->gen == goto_switch_gen
696 || table->opcode_rule->gen == padded_switch_gen)
697 {
698 print_idecode_switch (file, table, result);
699 }
700 else
701 {
702 print_idecode_table (file, table, result);
703 }
704}
705
706
707/****************************************************************/
708
c906108c
SS
709/* Output code to do any final checks on the decoded instruction.
710 This includes things like verifying any on decoded fields have the
711 correct value and checking that (for floating point) floating point
712 hardware isn't disabled */
713
714void
715print_idecode_validate (lf *file,
4e0bf4c4 716 insn_entry * instruction, insn_opcodes *opcode_paths)
c906108c
SS
717{
718 /* Validate: unchecked instruction fields
719
720 If any constant fields in the instruction were not checked by the
721 idecode tables, output code to check that they have the correct
722 value here */
723 {
724 int nr_checks = 0;
725 int word_nr;
726 lf_printf (file, "\n");
727 lf_indent_suppress (file);
728 lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
729 lf_printf (file, "/* validate: ");
730 print_insn_words (file, instruction);
731 lf_printf (file, " */\n");
732 for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
733 {
734 insn_uint check_mask = 0;
735 insn_uint check_val = 0;
736 insn_word_entry *word = instruction->word[word_nr];
737 int bit_nr;
738
739 /* form check_mask/check_val containing what needs to be checked
740 in the instruction */
741 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
742 {
743 insn_bit_entry *bit = word->bit[bit_nr];
744 insn_field_entry *field = bit->field;
745
746 /* Make space for the next bit */
747 check_mask <<= 1;
748 check_val <<= 1;
4e0bf4c4 749
c906108c 750 /* Only need to validate constant (and reserved)
4e0bf4c4 751 bits. Skip any others */
c906108c
SS
752 if (field->type != insn_field_int
753 && field->type != insn_field_reserved)
754 continue;
755
756 /* Look through the list of opcode paths that lead to this
4e0bf4c4
AC
757 instruction. See if any have failed to check the
758 relevant bit */
c906108c
SS
759 if (opcode_paths != NULL)
760 {
761 insn_opcodes *entry;
4e0bf4c4 762 for (entry = opcode_paths; entry != NULL; entry = entry->next)
c906108c
SS
763 {
764 opcode_field *opcode;
765 for (opcode = entry->opcode;
4e0bf4c4 766 opcode != NULL; opcode = opcode->parent)
c906108c
SS
767 {
768 if (opcode->word_nr == word_nr
769 && opcode->first <= bit_nr
770 && opcode->last >= bit_nr)
771 /* we've decoded on this bit */
772 break;
773 }
774 if (opcode == NULL)
775 /* the bit wasn't decoded on */
776 break;
777 }
778 if (entry == NULL)
779 /* all the opcode paths decoded on BIT_NR, no need
4e0bf4c4 780 to check it */
c906108c
SS
781 continue;
782 }
4e0bf4c4 783
c906108c
SS
784 check_mask |= 1;
785 check_val |= bit->value;
786 }
4e0bf4c4 787
c906108c
SS
788 /* if any bits not checked by opcode tables, output code to check them */
789 if (check_mask)
790 {
791 if (nr_checks == 0)
792 {
793 lf_printf (file, "if (WITH_RESERVED_BITS)\n");
794 lf_printf (file, " {\n");
795 lf_indent (file, +4);
796 }
4e0bf4c4 797 nr_checks++;
c906108c
SS
798 if (options.insn_bit_size > 32)
799 {
4e0bf4c4 800 lf_printf (file, "if ((instruction_%d\n", word_nr);
c906108c 801 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
4e0bf4c4
AC
802 (unsigned long) (check_mask >> 32),
803 (unsigned long) (check_mask));
c906108c 804 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
4e0bf4c4
AC
805 (unsigned long) (check_val >> 32),
806 (unsigned long) (check_val));
c906108c
SS
807 }
808 else
809 {
4e0bf4c4
AC
810 lf_printf (file,
811 "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
812 word_nr, (unsigned long) (check_mask),
813 (unsigned long) (check_val));
c906108c
SS
814 }
815 lf_indent (file, +2);
816 print_idecode_invalid (file, "return", invalid_illegal);
817 lf_indent (file, -2);
818 }
819 }
820 if (nr_checks > 0)
821 {
822 lf_indent (file, -4);
823 lf_printf (file, " }\n");
824 }
4e0bf4c4 825 lf_indent_suppress (file);
c906108c
SS
826 lf_printf (file, "#endif\n");
827 }
828
829 /* Validate: Floating Point hardware
4e0bf4c4 830
c906108c
SS
831 If the simulator is being built with out floating point hardware
832 (different to it being disabled in the MSR) then floating point
833 instructions are invalid */
834 {
835 if (filter_is_member (instruction->flags, "f"))
836 {
837 lf_printf (file, "\n");
838 lf_indent_suppress (file);
839 lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
840 lf_printf (file, "/* Validate: FP hardware exists */\n");
4e0bf4c4
AC
841 lf_printf (file,
842 "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
c906108c
SS
843 lf_indent (file, +2);
844 print_idecode_invalid (file, "return", invalid_illegal);
845 lf_indent (file, -2);
846 lf_printf (file, "}\n");
847 lf_indent_suppress (file);
848 lf_printf (file, "#endif\n");
849 }
850 }
851
852 /* Validate: Floating Point available
853
854 If floating point is not available, we enter a floating point
855 unavailable interrupt into the cache instead of the instruction
856 proper.
857
858 The PowerPC spec requires a CSI after MSR[FP] is changed and when
859 ever a CSI occures we flush the instruction cache. */
860
861 {
862 if (filter_is_member (instruction->flags, "f"))
863 {
864 lf_printf (file, "\n");
865 lf_indent_suppress (file);
866 lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
867 lf_printf (file, "/* Validate: FP available according to cpu */\n");
868 lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
869 lf_indent (file, +2);
4e0bf4c4 870 print_idecode_invalid (file, "return", invalid_fp_unavailable);
c906108c
SS
871 lf_indent (file, -2);
872 lf_printf (file, "}\n");
873 lf_indent_suppress (file);
874 lf_printf (file, "#endif\n");
875 }
876 }
4e0bf4c4 877
c906108c
SS
878 /* Validate: Validate Instruction in correct slot
879
880 Some architectures place restrictions on the slot that an
881 instruction can be issued in */
882
883 {
884 if (filter_is_member (instruction->options, "s")
885 || options.gen.slot_verification)
886 {
887 lf_printf (file, "\n");
888 lf_indent_suppress (file);
889 lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
4e0bf4c4
AC
890 lf_printf (file,
891 "/* Validate: Instruction issued in correct slot */\n");
c906108c
SS
892 lf_printf (file, "if (IS_WRONG_SLOT) {\n");
893 lf_indent (file, +2);
894 print_idecode_invalid (file, "return", invalid_wrong_slot);
895 lf_indent (file, -2);
896 lf_printf (file, "}\n");
897 lf_indent_suppress (file);
898 lf_printf (file, "#endif\n");
899 }
900 }
4e0bf4c4 901
c906108c
SS
902}
903
904
905/****************************************************************/
906
907
908void
909print_idecode_issue_function_header (lf *file,
910 const char *processor,
911 function_decl_type decl_type,
912 int nr_prefetched_words)
913{
914 int indent;
915 lf_printf (file, "\n");
916 switch (decl_type)
917 {
918 case is_function_declaration:
919 lf_print__function_type_function (file, print_semantic_function_type,
4e0bf4c4 920 "INLINE_IDECODE", " ");
c906108c
SS
921 break;
922 case is_function_definition:
923 lf_print__function_type_function (file, print_semantic_function_type,
4e0bf4c4 924 "INLINE_IDECODE", "\n");
c906108c
SS
925 break;
926 case is_function_variable:
927 print_semantic_function_type (file);
928 lf_printf (file, " (*");
929 break;
930 }
931 indent = print_function_name (file,
932 "issue",
933 NULL,
934 processor,
4e0bf4c4 935 NULL, function_name_prefix_idecode);
c906108c
SS
936 switch (decl_type)
937 {
938 case is_function_definition:
939 indent += lf_printf (file, " (");
940 break;
941 case is_function_declaration:
942 lf_putstr (file, "\n(");
943 indent = 1;
944 break;
945 case is_function_variable:
946 lf_putstr (file, ")\n(");
947 indent = 1;
948 break;
949 }
950 lf_indent (file, +indent);
951 print_semantic_function_formal (file, nr_prefetched_words);
952 lf_putstr (file, ")");
953 lf_indent (file, -indent);
954 switch (decl_type)
955 {
956 case is_function_definition:
957 lf_printf (file, "\n");
958 break;
959 case is_function_declaration:
960 case is_function_variable:
961 lf_putstr (file, ";\n");
962 break;
963 }
964}
965
966
967
968void
969print_idecode_globals (lf *file)
970{
971 lf_printf (file, "enum {\n");
972 lf_printf (file, " /* greater or equal to zero => table */\n");
973 lf_printf (file, " function_entry = -1,\n");
974 lf_printf (file, " boolean_entry = -2,\n");
975 lf_printf (file, "};\n");
976 lf_printf (file, "\n");
977 lf_printf (file, "typedef struct _idecode_table_entry {\n");
978 lf_printf (file, " int shift;\n");
979 lf_printf (file, " unsigned%d mask;\n", options.insn_bit_size);
980 lf_printf (file, " unsigned%d value;\n", options.insn_bit_size);
981 lf_printf (file, " void *function_or_table;\n");
982 lf_printf (file, "} idecode_table_entry;\n");
983}
This page took 0.557975 seconds and 4 git commands to generate.