]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/gen-idecode.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / sim / igen / gen-idecode.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
6aba47ca 3 Copyright 2002, 2007 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
11 the Free Software Foundation; either version 2 of the License, or
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
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
c906108c
SS
24
25#include "misc.h"
26#include "lf.h"
27#include "table.h"
28#include "filter.h"
29#include "igen.h"
30
31#include "ld-insn.h"
32#include "ld-decode.h"
33
34#include "gen.h"
35
36#include "gen-idecode.h"
37#include "gen-icache.h"
38#include "gen-semantics.h"
39
40
41
42static void
4e0bf4c4 43lf_print_opcodes (lf *file, gen_entry *table)
c906108c 44{
4e0bf4c4 45 if (table !=NULL)
c906108c
SS
46 {
47 while (1)
48 {
49 ASSERT (table->opcode != NULL);
50 lf_printf (file, "_%d_%d",
4e0bf4c4
AC
51 table->opcode->first, table->opcode->last);
52 if (table->parent == NULL)
53 break;
c906108c
SS
54 lf_printf (file, "__%d", table->opcode_nr);
55 table = table->parent;
56 }
57 }
58}
59
60
61
62
63static void
64print_idecode_ifetch (lf *file,
65 int previous_nr_prefetched_words,
66 int current_nr_prefetched_words)
67{
68 int word_nr;
69 for (word_nr = previous_nr_prefetched_words;
4e0bf4c4 70 word_nr < current_nr_prefetched_words; word_nr++)
c906108c 71 {
4e0bf4c4
AC
72 lf_printf (file,
73 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
c906108c 74 word_nr, options.insn_bit_size, word_nr);
4e0bf4c4 75
c906108c
SS
76 }
77}
78
79
80
81/****************************************************************/
82
83
84static void
4e0bf4c4 85lf_print_table_name (lf *file, gen_entry *table)
c906108c
SS
86{
87 lf_printf (file, "idecode_table");
88 lf_print_opcodes (file, table);
89}
90
91
92
93static void
4e0bf4c4 94print_idecode_table (lf *file, gen_entry *entry, const char *result)
c906108c
SS
95{
96 lf_printf (file, "/* prime the search */\n");
97 lf_printf (file, "idecode_table_entry *table = ");
98 lf_print_table_name (file, entry);
99 lf_printf (file, ";\n");
100 lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
101 options.insn_bit_size,
102 i2target (options.hi_bit_nr, entry->opcode->first),
103 i2target (options.hi_bit_nr, entry->opcode->last));
104 lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
4e0bf4c4 105
c906108c
SS
106 lf_printf (file, "\n");
107 lf_printf (file, "/* iterate until a leaf */\n");
108 lf_printf (file, "while (1) {\n");
109 lf_printf (file, " signed shift = table_entry->shift;\n");
110 lf_printf (file, "if (shift == function_entry) break;\n");
111 lf_printf (file, " if (shift >= 0) {\n");
112 lf_printf (file, " table = ((idecode_table_entry*)\n");
113 lf_printf (file, " table_entry->function_or_table);\n");
114 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
115 lf_printf (file, " >> shift);\n");
116 lf_printf (file, " table_entry = table + opcode;\n");
117 lf_printf (file, " }\n");
118 lf_printf (file, " else {\n");
119 lf_printf (file, " /* must be a boolean */\n");
120 lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n");
121 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
122 lf_printf (file, " != table_entry->value);\n");
123 lf_printf (file, " table = ((idecode_table_entry*)\n");
124 lf_printf (file, " table_entry->function_or_table);\n");
125 lf_printf (file, " table_entry = table + opcode;\n");
126 lf_printf (file, " }\n");
127 lf_printf (file, "}\n");
4e0bf4c4 128
c906108c
SS
129 lf_printf (file, "\n");
130 lf_printf (file, "/* call the leaf code */\n");
131 if (options.gen.code == generate_jumps)
132 {
133 lf_printf (file, "goto *table_entry->function_or_table;\n");
134 }
135 else
136 {
137 lf_printf (file, "%s ", result);
138 if (options.gen.icache)
139 {
4e0bf4c4
AC
140 lf_printf (file,
141 "(((idecode_icache*)table_entry->function_or_table)\n");
c906108c
SS
142 lf_printf (file, " (");
143 print_icache_function_actual (file, 1);
144 lf_printf (file, "));\n");
145 }
146 else
147 {
4e0bf4c4
AC
148 lf_printf (file,
149 "((idecode_semantic*)table_entry->function_or_table)\n");
c906108c
SS
150 lf_printf (file, " (");
151 print_semantic_function_actual (file, 1);
152 lf_printf (file, ");\n");
153 }
154 }
155}
156
157
158static void
4e0bf4c4 159print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
160{
161 ASSERT (depth == 0);
162 /* start of the table */
163 if (table->opcode_rule->gen == array_gen)
164 {
165 lf_printf (file, "\n");
166 lf_printf (file, "static idecode_table_entry ");
167 lf_print_table_name (file, table);
168 lf_printf (file, "[] = {\n");
169 }
170}
171
172static void
4e0bf4c4 173print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
c906108c
SS
174{
175 gen_entry *master_entry;
176 ASSERT (entry->parent != NULL);
177 ASSERT (depth == 0);
178 if (entry->combined_parent == NULL)
179 master_entry = entry;
180 else
181 master_entry = entry->combined_parent;
182
183 /* add an entry to the table */
184 if (entry->parent->opcode_rule->gen == array_gen)
185 {
186 lf_printf (file, " /*%d*/ { ", entry->opcode_nr);
187 if (entry->opcode == NULL)
188 {
189 ASSERT (entry->nr_insns == 1);
190 /* table leaf entry */
191 lf_printf (file, "function_entry, 0, 0, ");
192 if (options.gen.code == generate_jumps)
193 {
194 lf_printf (file, "&&");
195 }
196 print_function_name (file,
197 entry->insns->insn->name,
198 entry->insns->insn->format_name,
199 NULL,
200 master_entry->expanded_bits,
201 (options.gen.icache
202 ? function_name_prefix_icache
203 : function_name_prefix_semantics));
204 }
205 else if (entry->opcode_rule->gen == switch_gen
206 || entry->opcode_rule->gen == goto_switch_gen
207 || entry->opcode_rule->gen == padded_switch_gen)
208 {
209 /* table calling switch statement */
210 lf_printf (file, "function_entry, 0, 0, ");
211 if (options.gen.code == generate_jumps)
212 {
213 lf_printf (file, "&&");
214 }
215 lf_print_table_name (file, entry);
216 }
217 else if (entry->opcode->is_boolean)
218 {
219 /* table `calling' boolean table */
220 lf_printf (file, "boolean_entry, ");
221 lf_printf (file, "MASK32(%d, %d), ",
222 i2target (options.hi_bit_nr, entry->opcode->first),
223 i2target (options.hi_bit_nr, entry->opcode->last));
224 lf_printf (file, "INSERTED32(%d, %d, %d), ",
225 entry->opcode->boolean_constant,
226 i2target (options.hi_bit_nr, entry->opcode->first),
227 i2target (options.hi_bit_nr, entry->opcode->last));
228 lf_print_table_name (file, entry);
229 }
230 else
231 {
232 /* table `calling' another table */
4e0bf4c4
AC
233 lf_printf (file, "%d, ",
234 options.insn_bit_size - entry->opcode->last - 1);
235 lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
c906108c
SS
236 i2target (options.hi_bit_nr, entry->opcode->first),
237 i2target (options.hi_bit_nr, entry->opcode->last));
238 lf_printf (file, "0, ");
239 lf_print_table_name (file, entry);
240 }
241 lf_printf (file, " },\n");
242 }
243}
244
245static void
4e0bf4c4 246print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
247{
248 ASSERT (depth == 0);
4e0bf4c4
AC
249 if (table->opcode_rule->gen == array_gen)
250 {
251 lf_printf (file, "};\n");
252 }
c906108c
SS
253}
254
255/****************************************************************/
256
257
258static void
4e0bf4c4 259print_goto_switch_name (lf *file, gen_entry *entry)
c906108c
SS
260{
261 lf_printf (file, "case_");
262 if (entry->opcode == NULL)
263 {
264 print_function_name (file,
265 entry->insns->insn->name,
266 entry->insns->insn->format_name,
267 NULL,
268 entry->expanded_bits,
269 (options.gen.icache
270 ? function_name_prefix_icache
271 : function_name_prefix_semantics));
272 }
273 else
274 {
4e0bf4c4 275 lf_print_table_name (file, entry);
c906108c
SS
276 }
277}
278
279static void
280print_goto_switch_table_leaf (lf *file,
4e0bf4c4 281 gen_entry *entry, int depth, void *data)
c906108c
SS
282{
283 ASSERT (entry->parent != NULL);
284 ASSERT (depth == 0);
285 ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
286 ASSERT (entry->parent->opcode);
4e0bf4c4 287
c906108c
SS
288 lf_printf (file, "/* %d */ &&", entry->opcode_nr);
289 if (entry->combined_parent != NULL)
290 print_goto_switch_name (file, entry->combined_parent);
291 else
292 print_goto_switch_name (file, entry);
293 lf_printf (file, ",\n");
294}
295
296static void
4e0bf4c4 297print_goto_switch_break (lf *file, gen_entry *entry)
c906108c
SS
298{
299 lf_printf (file, "goto break_");
300 lf_print_table_name (file, entry->parent);
301 lf_printf (file, ";\n");
302}
303
304
305static void
4e0bf4c4 306print_goto_switch_table (lf *file, gen_entry *table)
c906108c
SS
307{
308 lf_printf (file, "const static void *");
309 lf_print_table_name (file, table);
310 lf_printf (file, "[] = {\n");
311 lf_indent (file, +2);
4e0bf4c4
AC
312 gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
313 print_goto_switch_table_leaf, NULL /*end */ ,
314 NULL /*data */ );
c906108c
SS
315 lf_indent (file, -2);
316 lf_printf (file, "};\n");
317}
318
319
4e0bf4c4 320void print_idecode_switch (lf *file, gen_entry *table, const char *result);
c906108c
SS
321
322static void
4e0bf4c4 323print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
324{
325 /* const char *result = data; */
326 ASSERT (depth == 0);
327 ASSERT (table->opcode_rule->gen == switch_gen
328 || table->opcode_rule->gen == goto_switch_gen
329 || table->opcode_rule->gen == padded_switch_gen);
4e0bf4c4 330
c906108c
SS
331 if (table->opcode->is_boolean
332 || table->opcode_rule->gen == switch_gen
333 || table->opcode_rule->gen == padded_switch_gen)
334 {
335 lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
336 options.insn_bit_size,
337 table->opcode_rule->word_nr,
338 i2target (options.hi_bit_nr, table->opcode->first),
339 i2target (options.hi_bit_nr, table->opcode->last));
340 lf_indent (file, +2);
341 lf_printf (file, "{\n");
342 }
343 else if (table->opcode_rule->gen == goto_switch_gen)
344 {
345 if (table->parent != NULL
346 && (table->parent->opcode_rule->gen == switch_gen
347 || table->parent->opcode_rule->gen == goto_switch_gen
348 || table->parent->opcode_rule->gen == padded_switch_gen))
349 {
350 lf_printf (file, "{\n");
351 lf_indent (file, +2);
352 }
353 print_goto_switch_table (file, table);
354 lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
355 options.insn_bit_size,
356 table->opcode->word_nr,
357 i2target (options.hi_bit_nr, table->opcode->first),
358 i2target (options.hi_bit_nr, table->opcode->last));
359 lf_printf (file, " < (sizeof (");
360 lf_print_table_name (file, table);
361 lf_printf (file, ") / sizeof(void*)));\n");
362 lf_printf (file, "goto *");
363 lf_print_table_name (file, table);
364 lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
365 options.insn_bit_size,
366 table->opcode->word_nr,
367 i2target (options.hi_bit_nr, table->opcode->first),
368 i2target (options.hi_bit_nr, table->opcode->last));
369 }
370 else
371 {
4e0bf4c4 372 ASSERT ("bad switch" == NULL);
c906108c
SS
373 }
374}
375
376
377static void
4e0bf4c4 378print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
c906108c
SS
379{
380 const char *result = data;
381 ASSERT (entry->parent != NULL);
382 ASSERT (depth == 0);
383 ASSERT (entry->parent->opcode_rule->gen == switch_gen
384 || entry->parent->opcode_rule->gen == goto_switch_gen
385 || entry->parent->opcode_rule->gen == padded_switch_gen);
386 ASSERT (entry->parent->opcode);
4e0bf4c4 387
c906108c
SS
388 /* skip over any instructions combined into another entry */
389 if (entry->combined_parent != NULL)
390 return;
391
4e0bf4c4 392 if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
c906108c
SS
393 {
394 /* case: boolean false target */
395 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
396 }
4e0bf4c4 397 else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
c906108c
SS
398 {
399 /* case: boolean true case */
400 lf_printf (file, "default:\n");
401 }
402 else if (entry->parent->opcode_rule->gen == switch_gen
403 || entry->parent->opcode_rule->gen == padded_switch_gen)
404 {
405 /* case: <opcode-nr> - switch */
406 gen_entry *cob;
407 for (cob = entry; cob != NULL; cob = cob->combined_next)
408 lf_printf (file, "case %d:\n", cob->opcode_nr);
409 }
410 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
411 {
412 /* case: <opcode-nr> - goto-switch */
413 print_goto_switch_name (file, entry);
414 lf_printf (file, ":\n");
415 }
416 else
417 {
418 ERROR ("bad switch");
419 }
420 lf_printf (file, " {\n");
421 lf_indent (file, +4);
422 {
423 if (entry->opcode == NULL)
424 {
425 /* switch calling leaf */
426 ASSERT (entry->nr_insns == 1);
427 print_idecode_ifetch (file, entry->nr_prefetched_words,
428 entry->insns->semantic->nr_prefetched_words);
429 switch (options.gen.code)
430 {
431 case generate_jumps:
432 lf_printf (file, "goto ");
433 break;
434 case generate_calls:
435 lf_printf (file, "%s", result);
436 break;
437 }
438 print_function_name (file,
439 entry->insns->insn->name,
440 entry->insns->insn->format_name,
441 NULL,
442 entry->expanded_bits,
443 (options.gen.icache
444 ? function_name_prefix_icache
445 : function_name_prefix_semantics));
446 if (options.gen.code == generate_calls)
447 {
448 lf_printf (file, " (");
4e0bf4c4
AC
449 print_semantic_function_actual (file,
450 entry->insns->semantic->
451 nr_prefetched_words);
c906108c
SS
452 lf_printf (file, ")");
453 }
454 lf_printf (file, ";\n");
455 }
456 else if (entry->opcode_rule->gen == switch_gen
457 || entry->opcode_rule->gen == goto_switch_gen
458 || entry->opcode_rule->gen == padded_switch_gen)
459 {
460 /* switch calling switch */
461 lf_printf (file, "{\n");
462 lf_indent (file, +2);
463 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
464 entry->nr_prefetched_words);
465 print_idecode_switch (file, entry, result);
466 lf_indent (file, -2);
467 lf_printf (file, "}\n");
468 }
469 else
470 {
471 /* switch looking up a table */
472 lf_printf (file, "{\n");
473 lf_indent (file, +2);
474 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
475 entry->nr_prefetched_words);
476 print_idecode_table (file, entry, result);
477 lf_indent (file, -2);
478 lf_printf (file, "}\n");
479 }
480 if (entry->parent->opcode->is_boolean
481 || entry->parent->opcode_rule->gen == switch_gen
482 || entry->parent->opcode_rule->gen == padded_switch_gen)
483 {
484 lf_printf (file, "break;\n");
485 }
486 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
487 {
4e0bf4c4 488 print_goto_switch_break (file, entry);
c906108c
SS
489 }
490 else
491 {
492 ERROR ("bad switch");
493 }
494 }
495 lf_indent (file, -4);
496 lf_printf (file, " }\n");
497}
498
499
500static void
4e0bf4c4 501print_idecode_switch_illegal (lf *file, const char *result)
c906108c
SS
502{
503 lf_indent (file, +2);
504 print_idecode_invalid (file, result, invalid_illegal);
505 lf_printf (file, "break;\n");
506 lf_indent (file, -2);
507}
508
509static void
4e0bf4c4 510print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
c906108c
SS
511{
512 const char *result = data;
513 ASSERT (depth == 0);
514 ASSERT (table->opcode_rule->gen == switch_gen
515 || table->opcode_rule->gen == goto_switch_gen
516 || table->opcode_rule->gen == padded_switch_gen);
517 ASSERT (table->opcode);
4e0bf4c4 518
c906108c
SS
519 if (table->opcode->is_boolean)
520 {
521 lf_printf (file, "}\n");
522 lf_indent (file, -2);
523 }
524 else if (table->opcode_rule->gen == switch_gen
525 || table->opcode_rule->gen == padded_switch_gen)
526 {
527 lf_printf (file, "default:\n");
528 lf_indent (file, +2);
529 if (table->nr_entries == table->opcode->nr_opcodes)
530 {
4e0bf4c4
AC
531 print_sim_engine_abort (file,
532 "Internal error - bad switch generated");
c906108c
SS
533 lf_printf (file, "%sNULL_CIA;\n", result);
534 lf_printf (file, "break;\n");
535 }
536 else
537 {
538 print_idecode_switch_illegal (file, result);
539 }
540 lf_indent (file, -2);
541 lf_printf (file, "}\n");
542 lf_indent (file, -2);
543 }
544 else if (table->opcode_rule->gen == goto_switch_gen)
545 {
546 lf_printf (file, "illegal_");
547 lf_print_table_name (file, table);
548 lf_printf (file, ":\n");
549 print_idecode_invalid (file, result, invalid_illegal);
550 lf_printf (file, "break_");
4e0bf4c4 551 lf_print_table_name (file, table);
c906108c
SS
552 lf_printf (file, ":;\n");
553 if (table->parent != NULL
554 && (table->parent->opcode_rule->gen == switch_gen
555 || table->parent->opcode_rule->gen == goto_switch_gen
556 || table->parent->opcode_rule->gen == padded_switch_gen))
557 {
558 lf_indent (file, -2);
559 lf_printf (file, "}\n");
560 }
561 }
562 else
563 {
564 ERROR ("bad switch");
565 }
566}
567
568
569void
4e0bf4c4 570print_idecode_switch (lf *file, gen_entry *table, const char *result)
c906108c
SS
571{
572 gen_entry_traverse_tree (file, table,
573 0,
574 print_idecode_switch_start,
575 print_idecode_switch_leaf,
4e0bf4c4 576 print_idecode_switch_end, (void *) result);
c906108c
SS
577}
578
579
580static void
581print_idecode_switch_function_header (lf *file,
582 gen_entry *table,
583 int is_function_definition,
584 int nr_prefetched_words)
585{
586 lf_printf (file, "\n");
587 if (options.gen.code == generate_calls)
588 {
589 lf_printf (file, "static ");
590 if (options.gen.icache)
591 {
592 lf_printf (file, "idecode_semantic *");
593 }
594 else
595 {
596 lf_printf (file, "unsigned_word");
597 }
598 if (is_function_definition)
599 {
600 lf_printf (file, "\n");
601 }
602 else
603 {
604 lf_printf (file, " ");
605 }
606 lf_print_table_name (file, table);
607 lf_printf (file, "\n(");
608 print_icache_function_formal (file, nr_prefetched_words);
609 lf_printf (file, ")");
610 if (!is_function_definition)
611 {
612 lf_printf (file, ";");
613 }
614 lf_printf (file, "\n");
615 }
616 if (options.gen.code == generate_jumps && is_function_definition)
617 {
618 lf_indent (file, -1);
619 lf_print_table_name (file, table);
620 lf_printf (file, ":\n");
621 lf_indent (file, +1);
622 }
623}
624
625
626static void
4e0bf4c4 627idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
c906108c 628{
4e0bf4c4 629 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
630 && table->parent->opcode_rule->gen == array_gen)
631 {
632 print_idecode_switch_function_header (file,
633 table,
4e0bf4c4 634 0 /*isnt function definition */ ,
c906108c
SS
635 0);
636 }
637}
638
639
640static void
4e0bf4c4 641idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
c906108c 642{
4e0bf4c4 643 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
644 && table->parent->opcode_rule->gen == array_gen)
645 {
4e0bf4c4
AC
646 print_idecode_switch_function_header (file,
647 table,
648 1 /*is function definition */ ,
649 0);
c906108c
SS
650 if (options.gen.code == generate_calls)
651 {
652 lf_printf (file, "{\n");
653 lf_indent (file, +2);
654 }
4e0bf4c4 655 print_idecode_switch (file, table, "return");
c906108c
SS
656 if (options.gen.code == generate_calls)
657 {
658 lf_indent (file, -2);
659 lf_printf (file, "}\n");
660 }
661 }
662}
663
664
665/****************************************************************/
666
667
668void
4e0bf4c4 669print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
c906108c
SS
670{
671 int depth;
4e0bf4c4 672
c906108c 673 /* output switch function declarations where needed by tables */
4e0bf4c4
AC
674 gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */
675 NULL, NULL, NULL);
676
c906108c 677 /* output tables where needed */
4e0bf4c4 678 for (depth = gen_entry_depth (table); depth > 0; depth--)
c906108c
SS
679 {
680 gen_entry_traverse_tree (file, table,
4e0bf4c4 681 1 - depth,
c906108c
SS
682 print_idecode_table_start,
683 print_idecode_table_leaf,
4e0bf4c4 684 print_idecode_table_end, NULL);
c906108c 685 }
4e0bf4c4 686
c906108c 687 /* output switch functions where needed */
4e0bf4c4
AC
688 gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */
689 NULL, NULL, NULL);
c906108c
SS
690}
691
692
693void
4e0bf4c4 694print_idecode_body (lf *file, gen_entry *table, const char *result)
c906108c
SS
695{
696 if (table->opcode_rule->gen == switch_gen
697 || table->opcode_rule->gen == goto_switch_gen
698 || table->opcode_rule->gen == padded_switch_gen)
699 {
700 print_idecode_switch (file, table, result);
701 }
702 else
703 {
704 print_idecode_table (file, table, result);
705 }
706}
707
708
709/****************************************************************/
710
711#if 0
712static void
4e0bf4c4 713print_jump (lf *file, int is_tail)
c906108c
SS
714{
715 if (is_tail)
716 {
717 lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n");
718 lf_putstr (file, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
719 }
4e0bf4c4 720
c906108c
SS
721 if (!options.generate_smp)
722 {
723 lf_putstr (file, "if (WITH_EVENTS) {\n");
724 lf_putstr (file, " if (event_queue_tick(events)) {\n");
725 lf_putstr (file, " cpu_set_program_counter(cpu, nia);\n");
726 lf_putstr (file, " event_queue_process(events);\n");
727 lf_putstr (file, " nia = cpu_get_program_counter(cpu);\n");
728 lf_putstr (file, " }\n");
729 lf_putstr (file, "}\n");
730 }
4e0bf4c4 731
c906108c
SS
732 if (options.generate_smp)
733 {
734 if (is_tail)
735 {
736 lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n");
737 }
738 lf_putstr (file, "if (WITH_EVENTS) {\n");
739 lf_putstr (file, " current_cpu += 1;\n");
740 lf_putstr (file, " if (current_cpu >= nr_cpus) {\n");
741 lf_putstr (file, " if (event_queue_tick(events)) {\n");
742 lf_putstr (file, " event_queue_process(events);\n");
743 lf_putstr (file, " }\n");
744 lf_putstr (file, " current_cpu = 0;\n");
745 lf_putstr (file, " }\n");
746 lf_putstr (file, "}\n");
747 lf_putstr (file, "else {\n");
748 lf_putstr (file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
749 lf_putstr (file, "}\n");
750 lf_putstr (file, "cpu = cpus[current_cpu];\n");
751 lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
752 }
4e0bf4c4 753
c906108c
SS
754 if (options.gen.icache)
755 {
756 lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n");
757 lf_putstr (file, "if (cache_entry->address == nia) {\n");
758 lf_putstr (file, " /* cache hit */\n");
759 lf_putstr (file, " goto *cache_entry->semantic;\n");
760 lf_putstr (file, "}\n");
761 if (is_tail)
762 {
763 lf_putstr (file, "goto cache_miss;\n");
764 }
765 }
766
767 if (!options.gen.icache && is_tail)
768 {
769 lf_printf (file, "goto idecode;\n");
770 }
4e0bf4c4 771
c906108c
SS
772}
773#endif
774
775
776
777#if 0
778static void
779print_jump_insn (lf *file,
4e0bf4c4
AC
780 insn_entry * instruction,
781 insn_bits * expanded_bits,
782 opcode_field *opcodes, cache_entry *cache_rules)
c906108c 783{
4e0bf4c4 784
c906108c
SS
785 /* what we are for the moment */
786 lf_printf (file, "\n");
787 print_my_defines (file, expanded_bits, instruction->name);
4e0bf4c4 788
c906108c
SS
789 /* output the icache entry */
790 if (options.gen.icache)
791 {
792 lf_printf (file, "\n");
793 lf_indent (file, -1);
794 print_function_name (file,
795 instruction->name,
4e0bf4c4 796 expanded_bits, function_name_prefix_icache);
c906108c
SS
797 lf_printf (file, ":\n");
798 lf_indent (file, +1);
799 lf_printf (file, "{\n");
800 lf_indent (file, +2);
801 lf_putstr (file, "const unsigned_word cia = nia;\n");
4e0bf4c4 802 print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
c906108c
SS
803 print_idecode_validate (file, instruction, opcodes);
804 lf_printf (file, "\n");
805 lf_printf (file, "{\n");
806 lf_indent (file, +2);
4e0bf4c4 807 print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */
c906108c
SS
808 put_values_in_icache);
809 lf_printf (file, "cache_entry->address = nia;\n");
810 lf_printf (file, "cache_entry->semantic = &&");
811 print_function_name (file,
812 instruction->name,
4e0bf4c4 813 expanded_bits, function_name_prefix_semantics);
c906108c
SS
814 lf_printf (file, ";\n");
815 if (options.gen.semantic_icache)
816 {
4e0bf4c4
AC
817 print_semantic_body (file, instruction, expanded_bits, opcodes);
818 print_jump (file, 1 /*is-tail */ );
c906108c
SS
819 }
820 else
821 {
822 lf_printf (file, "/* goto ");
823 print_function_name (file,
824 instruction->name,
4e0bf4c4 825 expanded_bits, function_name_prefix_semantics);
c906108c
SS
826 lf_printf (file, "; */\n");
827 }
828 lf_indent (file, -2);
829 lf_putstr (file, "}\n");
830 lf_indent (file, -2);
831 lf_printf (file, "}\n");
832 }
4e0bf4c4 833
c906108c
SS
834 /* print the semantics */
835 lf_printf (file, "\n");
836 lf_indent (file, -1);
837 print_function_name (file,
838 instruction->name,
4e0bf4c4 839 expanded_bits, function_name_prefix_semantics);
c906108c
SS
840 lf_printf (file, ":\n");
841 lf_indent (file, +1);
842 lf_printf (file, "{\n");
843 lf_indent (file, +2);
844 lf_putstr (file, "const unsigned_word cia = nia;\n");
845 print_icache_body (file,
846 instruction,
847 expanded_bits,
848 cache_rules,
849 (options.gen.direct_access
850 ? define_variables
851 : declare_variables),
852 (options.gen.icache
4e0bf4c4
AC
853 ? get_values_from_icache : do_not_use_icache));
854 print_semantic_body (file, instruction, expanded_bits, opcodes);
c906108c
SS
855 if (options.gen.direct_access)
856 print_icache_body (file,
857 instruction,
858 expanded_bits,
859 cache_rules,
860 undef_variables,
861 (options.gen.icache
4e0bf4c4
AC
862 ? get_values_from_icache : do_not_use_icache));
863 print_jump (file, 1 /*is tail */ );
c906108c
SS
864 lf_indent (file, -2);
865 lf_printf (file, "}\n");
866}
867#endif
868
869
870#if 0
871static void
872print_jump_definition (lf *file,
873 gen_entry *entry,
4e0bf4c4 874 insn_entry * insn, int depth, void *data)
c906108c 875{
4e0bf4c4 876 cache_entry *cache_rules = (cache_entry *) data;
c906108c
SS
877 if (options.generate_expanded_instructions)
878 {
879 ASSERT (entry->nr_insns == 1
880 && entry->opcode == NULL
4e0bf4c4 881 && entry->parent != NULL && entry->parent->opcode != NULL);
c906108c
SS
882 ASSERT (entry->nr_insns == 1
883 && entry->opcode == NULL
884 && entry->parent != NULL
885 && entry->parent->opcode != NULL
886 && entry->parent->opcode_rule != NULL);
887 print_jump_insn (file,
888 entry->insns->words[0]->insn,
4e0bf4c4 889 entry->expanded_bits, entry->opcode, cache_rules);
c906108c
SS
890 }
891 else
892 {
893 print_jump_insn (file,
4e0bf4c4 894 instruction->words[0]->insn, NULL, NULL, cache_rules);
c906108c
SS
895 }
896}
897#endif
898
899#if 0
900static void
901print_jump_internal_function (lf *file,
902 gen_entry *table,
4e0bf4c4 903 function_entry * function, void *data)
c906108c
SS
904{
905 if (function->is_internal)
906 {
907 lf_printf (file, "\n");
908 lf_print__line_ref (file, function->line);
909 lf_indent (file, -1);
910 print_function_name (file,
911 function->name,
912 NULL,
913 (options.gen.icache
914 ? function_name_prefix_icache
915 : function_name_prefix_semantics));
916 lf_printf (file, ":\n");
917 lf_indent (file, +1);
918 lf_printf (file, "{\n");
919 lf_indent (file, +2);
920 lf_printf (file, "const unsigned_word cia = nia;\n");
921 table_print_code (file, function->code);
922 lf_print__internal_ref (file);
923 print_sim_engine_abort (file, "Internal function must longjump");
924 lf_indent (file, -2);
925 lf_printf (file, "}\n");
926 }
927}
928#endif
929
930
931
932#if 0
933static void
4e0bf4c4
AC
934print_jump_until_stop_body (lf *file,
935 insn_table *table, cache_table * cache_rules)
c906108c
SS
936{
937 lf_printf (file, "{\n");
938 lf_indent (file, +2);
939 lf_putstr (file, "jmp_buf halt;\n");
940 lf_putstr (file, "jmp_buf restart;\n");
941 lf_putstr (file, "sim_cpu *cpu = NULL;\n");
942 lf_putstr (file, "unsigned_word nia = -1;\n");
943 lf_putstr (file, "instruction_word instruction = 0;\n");
4e0bf4c4
AC
944 if ((code & generate_with_icache))
945 {
946 lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
947 }
948 if (generate_smp)
949 {
950 lf_putstr (file, "int current_cpu = -1;\n");
951 }
c906108c
SS
952
953 /* all the switches and tables - they know about jumping */
4e0bf4c4
AC
954 print_idecode_lookups (file, table, cache_rules);
955
c906108c 956 /* start the simulation up */
4e0bf4c4
AC
957 if ((code & generate_with_icache))
958 {
959 lf_putstr (file, "\n");
960 lf_putstr (file, "{\n");
961 lf_putstr (file, " int cpu_nr;\n");
962 lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
963 lf_putstr (file, " cpu_flush_icache(cpus[cpu_nr]);\n");
964 lf_putstr (file, "}\n");
965 }
c906108c
SS
966
967 lf_putstr (file, "\n");
968 lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
969
970 lf_putstr (file, "\n");
971 lf_putstr (file, "if (setjmp(halt))\n");
972 lf_putstr (file, " return;\n");
973
974 lf_putstr (file, "\n");
975 lf_putstr (file, "setjmp(restart);\n");
976
977 lf_putstr (file, "\n");
4e0bf4c4
AC
978 if (!generate_smp)
979 {
980 lf_putstr (file, "cpu = cpus[0];\n");
981 lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
982 }
983 else
984 {
985 lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
986 }
c906108c 987
4e0bf4c4
AC
988 if (!(code & generate_with_icache))
989 {
990 lf_printf (file, "\n");
991 lf_indent (file, -1);
992 lf_printf (file, "idecode:\n");
993 lf_indent (file, +1);
994 }
c906108c 995
4e0bf4c4 996 print_jump (file, 0 /*is_tail */ );
c906108c 997
4e0bf4c4
AC
998 if ((code & generate_with_icache))
999 {
1000 lf_indent (file, -1);
1001 lf_printf (file, "cache_miss:\n");
1002 lf_indent (file, +1);
1003 }
c906108c
SS
1004
1005 lf_putstr (file, "instruction\n");
1006 lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
1007 lf_putstr (file, " cpu, nia);\n");
4e0bf4c4 1008 print_idecode_body (file, table, "/*IGORE*/");
c906108c
SS
1009
1010 /* print out a table of all the internals functions */
4e0bf4c4
AC
1011 insn_table_traverse_function (table,
1012 file, NULL, print_jump_internal_function);
c906108c 1013
4e0bf4c4 1014 /* print out a table of all the instructions */
c906108c 1015 if (generate_expanded_instructions)
4e0bf4c4
AC
1016 insn_table_traverse_tree (table, file, cache_rules, 1, NULL, /* start */
1017 print_jump_definition, /* leaf */
1018 NULL, /* end */
1019 NULL); /* padding */
c906108c 1020 else
4e0bf4c4
AC
1021 insn_table_traverse_insn (table,
1022 file, cache_rules, print_jump_definition);
c906108c
SS
1023 lf_indent (file, -2);
1024 lf_printf (file, "}\n");
1025}
1026#endif
1027
1028/****************************************************************/
1029
1030
1031
1032/* Output code to do any final checks on the decoded instruction.
1033 This includes things like verifying any on decoded fields have the
1034 correct value and checking that (for floating point) floating point
1035 hardware isn't disabled */
1036
1037void
1038print_idecode_validate (lf *file,
4e0bf4c4 1039 insn_entry * instruction, insn_opcodes *opcode_paths)
c906108c
SS
1040{
1041 /* Validate: unchecked instruction fields
1042
1043 If any constant fields in the instruction were not checked by the
1044 idecode tables, output code to check that they have the correct
1045 value here */
1046 {
1047 int nr_checks = 0;
1048 int word_nr;
1049 lf_printf (file, "\n");
1050 lf_indent_suppress (file);
1051 lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
1052 lf_printf (file, "/* validate: ");
1053 print_insn_words (file, instruction);
1054 lf_printf (file, " */\n");
1055 for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
1056 {
1057 insn_uint check_mask = 0;
1058 insn_uint check_val = 0;
1059 insn_word_entry *word = instruction->word[word_nr];
1060 int bit_nr;
1061
1062 /* form check_mask/check_val containing what needs to be checked
1063 in the instruction */
1064 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1065 {
1066 insn_bit_entry *bit = word->bit[bit_nr];
1067 insn_field_entry *field = bit->field;
1068
1069 /* Make space for the next bit */
1070 check_mask <<= 1;
1071 check_val <<= 1;
4e0bf4c4 1072
c906108c 1073 /* Only need to validate constant (and reserved)
4e0bf4c4 1074 bits. Skip any others */
c906108c
SS
1075 if (field->type != insn_field_int
1076 && field->type != insn_field_reserved)
1077 continue;
1078
1079 /* Look through the list of opcode paths that lead to this
4e0bf4c4
AC
1080 instruction. See if any have failed to check the
1081 relevant bit */
c906108c
SS
1082 if (opcode_paths != NULL)
1083 {
1084 insn_opcodes *entry;
4e0bf4c4 1085 for (entry = opcode_paths; entry != NULL; entry = entry->next)
c906108c
SS
1086 {
1087 opcode_field *opcode;
1088 for (opcode = entry->opcode;
4e0bf4c4 1089 opcode != NULL; opcode = opcode->parent)
c906108c
SS
1090 {
1091 if (opcode->word_nr == word_nr
1092 && opcode->first <= bit_nr
1093 && opcode->last >= bit_nr)
1094 /* we've decoded on this bit */
1095 break;
1096 }
1097 if (opcode == NULL)
1098 /* the bit wasn't decoded on */
1099 break;
1100 }
1101 if (entry == NULL)
1102 /* all the opcode paths decoded on BIT_NR, no need
4e0bf4c4 1103 to check it */
c906108c
SS
1104 continue;
1105 }
4e0bf4c4 1106
c906108c
SS
1107 check_mask |= 1;
1108 check_val |= bit->value;
1109 }
4e0bf4c4 1110
c906108c
SS
1111 /* if any bits not checked by opcode tables, output code to check them */
1112 if (check_mask)
1113 {
1114 if (nr_checks == 0)
1115 {
1116 lf_printf (file, "if (WITH_RESERVED_BITS)\n");
1117 lf_printf (file, " {\n");
1118 lf_indent (file, +4);
1119 }
4e0bf4c4 1120 nr_checks++;
c906108c
SS
1121 if (options.insn_bit_size > 32)
1122 {
4e0bf4c4 1123 lf_printf (file, "if ((instruction_%d\n", word_nr);
c906108c 1124 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
4e0bf4c4
AC
1125 (unsigned long) (check_mask >> 32),
1126 (unsigned long) (check_mask));
c906108c 1127 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
4e0bf4c4
AC
1128 (unsigned long) (check_val >> 32),
1129 (unsigned long) (check_val));
c906108c
SS
1130 }
1131 else
1132 {
4e0bf4c4
AC
1133 lf_printf (file,
1134 "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
1135 word_nr, (unsigned long) (check_mask),
1136 (unsigned long) (check_val));
c906108c
SS
1137 }
1138 lf_indent (file, +2);
1139 print_idecode_invalid (file, "return", invalid_illegal);
1140 lf_indent (file, -2);
1141 }
1142 }
1143 if (nr_checks > 0)
1144 {
1145 lf_indent (file, -4);
1146 lf_printf (file, " }\n");
1147 }
4e0bf4c4 1148 lf_indent_suppress (file);
c906108c
SS
1149 lf_printf (file, "#endif\n");
1150 }
1151
1152 /* Validate: Floating Point hardware
4e0bf4c4 1153
c906108c
SS
1154 If the simulator is being built with out floating point hardware
1155 (different to it being disabled in the MSR) then floating point
1156 instructions are invalid */
1157 {
1158 if (filter_is_member (instruction->flags, "f"))
1159 {
1160 lf_printf (file, "\n");
1161 lf_indent_suppress (file);
1162 lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
1163 lf_printf (file, "/* Validate: FP hardware exists */\n");
4e0bf4c4
AC
1164 lf_printf (file,
1165 "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
c906108c
SS
1166 lf_indent (file, +2);
1167 print_idecode_invalid (file, "return", invalid_illegal);
1168 lf_indent (file, -2);
1169 lf_printf (file, "}\n");
1170 lf_indent_suppress (file);
1171 lf_printf (file, "#endif\n");
1172 }
1173 }
1174
1175 /* Validate: Floating Point available
1176
1177 If floating point is not available, we enter a floating point
1178 unavailable interrupt into the cache instead of the instruction
1179 proper.
1180
1181 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1182 ever a CSI occures we flush the instruction cache. */
1183
1184 {
1185 if (filter_is_member (instruction->flags, "f"))
1186 {
1187 lf_printf (file, "\n");
1188 lf_indent_suppress (file);
1189 lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
1190 lf_printf (file, "/* Validate: FP available according to cpu */\n");
1191 lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
1192 lf_indent (file, +2);
4e0bf4c4 1193 print_idecode_invalid (file, "return", invalid_fp_unavailable);
c906108c
SS
1194 lf_indent (file, -2);
1195 lf_printf (file, "}\n");
1196 lf_indent_suppress (file);
1197 lf_printf (file, "#endif\n");
1198 }
1199 }
4e0bf4c4 1200
c906108c
SS
1201 /* Validate: Validate Instruction in correct slot
1202
1203 Some architectures place restrictions on the slot that an
1204 instruction can be issued in */
1205
1206 {
1207 if (filter_is_member (instruction->options, "s")
1208 || options.gen.slot_verification)
1209 {
1210 lf_printf (file, "\n");
1211 lf_indent_suppress (file);
1212 lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
4e0bf4c4
AC
1213 lf_printf (file,
1214 "/* Validate: Instruction issued in correct slot */\n");
c906108c
SS
1215 lf_printf (file, "if (IS_WRONG_SLOT) {\n");
1216 lf_indent (file, +2);
1217 print_idecode_invalid (file, "return", invalid_wrong_slot);
1218 lf_indent (file, -2);
1219 lf_printf (file, "}\n");
1220 lf_indent_suppress (file);
1221 lf_printf (file, "#endif\n");
1222 }
1223 }
4e0bf4c4 1224
c906108c
SS
1225}
1226
1227
1228/****************************************************************/
1229
1230
1231void
1232print_idecode_issue_function_header (lf *file,
1233 const char *processor,
1234 function_decl_type decl_type,
1235 int nr_prefetched_words)
1236{
1237 int indent;
1238 lf_printf (file, "\n");
1239 switch (decl_type)
1240 {
1241 case is_function_declaration:
1242 lf_print__function_type_function (file, print_semantic_function_type,
4e0bf4c4 1243 "INLINE_IDECODE", " ");
c906108c
SS
1244 break;
1245 case is_function_definition:
1246 lf_print__function_type_function (file, print_semantic_function_type,
4e0bf4c4 1247 "INLINE_IDECODE", "\n");
c906108c
SS
1248 break;
1249 case is_function_variable:
1250 print_semantic_function_type (file);
1251 lf_printf (file, " (*");
1252 break;
1253 }
1254 indent = print_function_name (file,
1255 "issue",
1256 NULL,
1257 processor,
4e0bf4c4 1258 NULL, function_name_prefix_idecode);
c906108c
SS
1259 switch (decl_type)
1260 {
1261 case is_function_definition:
1262 indent += lf_printf (file, " (");
1263 break;
1264 case is_function_declaration:
1265 lf_putstr (file, "\n(");
1266 indent = 1;
1267 break;
1268 case is_function_variable:
1269 lf_putstr (file, ")\n(");
1270 indent = 1;
1271 break;
1272 }
1273 lf_indent (file, +indent);
1274 print_semantic_function_formal (file, nr_prefetched_words);
1275 lf_putstr (file, ")");
1276 lf_indent (file, -indent);
1277 switch (decl_type)
1278 {
1279 case is_function_definition:
1280 lf_printf (file, "\n");
1281 break;
1282 case is_function_declaration:
1283 case is_function_variable:
1284 lf_putstr (file, ";\n");
1285 break;
1286 }
1287}
1288
1289
1290
1291void
1292print_idecode_globals (lf *file)
1293{
1294 lf_printf (file, "enum {\n");
1295 lf_printf (file, " /* greater or equal to zero => table */\n");
1296 lf_printf (file, " function_entry = -1,\n");
1297 lf_printf (file, " boolean_entry = -2,\n");
1298 lf_printf (file, "};\n");
1299 lf_printf (file, "\n");
1300 lf_printf (file, "typedef struct _idecode_table_entry {\n");
1301 lf_printf (file, " int shift;\n");
1302 lf_printf (file, " unsigned%d mask;\n", options.insn_bit_size);
1303 lf_printf (file, " unsigned%d value;\n", options.insn_bit_size);
1304 lf_printf (file, " void *function_or_table;\n");
1305 lf_printf (file, "} idecode_table_entry;\n");
1306}