* config/tc-mn10300.h (tc_fix_adjustable): Define.
[deliverable/binutils-gdb.git] / sim / igen / gen-idecode.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3 Copyright 2002 Free Software Foundation, Inc.
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
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
42 static void
43 lf_print_opcodes (lf *file, gen_entry *table)
44 {
45 if (table !=NULL)
46 {
47 while (1)
48 {
49 ASSERT (table->opcode != NULL);
50 lf_printf (file, "_%d_%d",
51 table->opcode->first, table->opcode->last);
52 if (table->parent == NULL)
53 break;
54 lf_printf (file, "__%d", table->opcode_nr);
55 table = table->parent;
56 }
57 }
58 }
59
60
61
62
63 static void
64 print_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;
70 word_nr < current_nr_prefetched_words; word_nr++)
71 {
72 lf_printf (file,
73 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
74 word_nr, options.insn_bit_size, word_nr);
75
76 }
77 }
78
79
80
81 /****************************************************************/
82
83
84 static void
85 lf_print_table_name (lf *file, gen_entry *table)
86 {
87 lf_printf (file, "idecode_table");
88 lf_print_opcodes (file, table);
89 }
90
91
92
93 static void
94 print_idecode_table (lf *file, gen_entry *entry, const char *result)
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");
105
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");
128
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 {
140 lf_printf (file,
141 "(((idecode_icache*)table_entry->function_or_table)\n");
142 lf_printf (file, " (");
143 print_icache_function_actual (file, 1);
144 lf_printf (file, "));\n");
145 }
146 else
147 {
148 lf_printf (file,
149 "((idecode_semantic*)table_entry->function_or_table)\n");
150 lf_printf (file, " (");
151 print_semantic_function_actual (file, 1);
152 lf_printf (file, ");\n");
153 }
154 }
155 }
156
157
158 static void
159 print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
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
172 static void
173 print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
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 */
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,
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
245 static void
246 print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
247 {
248 ASSERT (depth == 0);
249 if (table->opcode_rule->gen == array_gen)
250 {
251 lf_printf (file, "};\n");
252 }
253 }
254
255 /****************************************************************/
256
257
258 static void
259 print_goto_switch_name (lf *file, gen_entry *entry)
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 {
275 lf_print_table_name (file, entry);
276 }
277 }
278
279 static void
280 print_goto_switch_table_leaf (lf *file,
281 gen_entry *entry, int depth, void *data)
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);
287
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
296 static void
297 print_goto_switch_break (lf *file, gen_entry *entry)
298 {
299 lf_printf (file, "goto break_");
300 lf_print_table_name (file, entry->parent);
301 lf_printf (file, ";\n");
302 }
303
304
305 static void
306 print_goto_switch_table (lf *file, gen_entry *table)
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);
312 gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
313 print_goto_switch_table_leaf, NULL /*end */ ,
314 NULL /*data */ );
315 lf_indent (file, -2);
316 lf_printf (file, "};\n");
317 }
318
319
320 void print_idecode_switch (lf *file, gen_entry *table, const char *result);
321
322 static void
323 print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
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);
330
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 {
372 ASSERT ("bad switch" == NULL);
373 }
374 }
375
376
377 static void
378 print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
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);
387
388 /* skip over any instructions combined into another entry */
389 if (entry->combined_parent != NULL)
390 return;
391
392 if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
393 {
394 /* case: boolean false target */
395 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
396 }
397 else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
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, " (");
449 print_semantic_function_actual (file,
450 entry->insns->semantic->
451 nr_prefetched_words);
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 {
488 print_goto_switch_break (file, entry);
489 }
490 else
491 {
492 ERROR ("bad switch");
493 }
494 }
495 lf_indent (file, -4);
496 lf_printf (file, " }\n");
497 }
498
499
500 static void
501 print_idecode_switch_illegal (lf *file, const char *result)
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
509 static void
510 print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
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);
518
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 {
531 print_sim_engine_abort (file,
532 "Internal error - bad switch generated");
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_");
551 lf_print_table_name (file, table);
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
569 void
570 print_idecode_switch (lf *file, gen_entry *table, const char *result)
571 {
572 gen_entry_traverse_tree (file, table,
573 0,
574 print_idecode_switch_start,
575 print_idecode_switch_leaf,
576 print_idecode_switch_end, (void *) result);
577 }
578
579
580 static void
581 print_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
626 static void
627 idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
628 {
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 */
630 && table->parent->opcode_rule->gen == array_gen)
631 {
632 print_idecode_switch_function_header (file,
633 table,
634 0 /*isnt function definition */ ,
635 0);
636 }
637 }
638
639
640 static void
641 idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
642 {
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 */
644 && table->parent->opcode_rule->gen == array_gen)
645 {
646 print_idecode_switch_function_header (file,
647 table,
648 1 /*is function definition */ ,
649 0);
650 if (options.gen.code == generate_calls)
651 {
652 lf_printf (file, "{\n");
653 lf_indent (file, +2);
654 }
655 print_idecode_switch (file, table, "return");
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
668 void
669 print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
670 {
671 int depth;
672
673 /* output switch function declarations where needed by tables */
674 gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */
675 NULL, NULL, NULL);
676
677 /* output tables where needed */
678 for (depth = gen_entry_depth (table); depth > 0; depth--)
679 {
680 gen_entry_traverse_tree (file, table,
681 1 - depth,
682 print_idecode_table_start,
683 print_idecode_table_leaf,
684 print_idecode_table_end, NULL);
685 }
686
687 /* output switch functions where needed */
688 gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */
689 NULL, NULL, NULL);
690 }
691
692
693 void
694 print_idecode_body (lf *file, gen_entry *table, const char *result)
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
712 static void
713 print_jump (lf *file, int is_tail)
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 }
720
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 }
731
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 }
753
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 }
771
772 }
773 #endif
774
775
776
777 #if 0
778 static void
779 print_jump_insn (lf *file,
780 insn_entry * instruction,
781 insn_bits * expanded_bits,
782 opcode_field *opcodes, cache_entry *cache_rules)
783 {
784
785 /* what we are for the moment */
786 lf_printf (file, "\n");
787 print_my_defines (file, expanded_bits, instruction->name);
788
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,
796 expanded_bits, function_name_prefix_icache);
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");
802 print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
803 print_idecode_validate (file, instruction, opcodes);
804 lf_printf (file, "\n");
805 lf_printf (file, "{\n");
806 lf_indent (file, +2);
807 print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */
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,
813 expanded_bits, function_name_prefix_semantics);
814 lf_printf (file, ";\n");
815 if (options.gen.semantic_icache)
816 {
817 print_semantic_body (file, instruction, expanded_bits, opcodes);
818 print_jump (file, 1 /*is-tail */ );
819 }
820 else
821 {
822 lf_printf (file, "/* goto ");
823 print_function_name (file,
824 instruction->name,
825 expanded_bits, function_name_prefix_semantics);
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 }
833
834 /* print the semantics */
835 lf_printf (file, "\n");
836 lf_indent (file, -1);
837 print_function_name (file,
838 instruction->name,
839 expanded_bits, function_name_prefix_semantics);
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
853 ? get_values_from_icache : do_not_use_icache));
854 print_semantic_body (file, instruction, expanded_bits, opcodes);
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
862 ? get_values_from_icache : do_not_use_icache));
863 print_jump (file, 1 /*is tail */ );
864 lf_indent (file, -2);
865 lf_printf (file, "}\n");
866 }
867 #endif
868
869
870 #if 0
871 static void
872 print_jump_definition (lf *file,
873 gen_entry *entry,
874 insn_entry * insn, int depth, void *data)
875 {
876 cache_entry *cache_rules = (cache_entry *) data;
877 if (options.generate_expanded_instructions)
878 {
879 ASSERT (entry->nr_insns == 1
880 && entry->opcode == NULL
881 && entry->parent != NULL && entry->parent->opcode != NULL);
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,
889 entry->expanded_bits, entry->opcode, cache_rules);
890 }
891 else
892 {
893 print_jump_insn (file,
894 instruction->words[0]->insn, NULL, NULL, cache_rules);
895 }
896 }
897 #endif
898
899 #if 0
900 static void
901 print_jump_internal_function (lf *file,
902 gen_entry *table,
903 function_entry * function, void *data)
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
933 static void
934 print_jump_until_stop_body (lf *file,
935 insn_table *table, cache_table * cache_rules)
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");
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 }
952
953 /* all the switches and tables - they know about jumping */
954 print_idecode_lookups (file, table, cache_rules);
955
956 /* start the simulation up */
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 }
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");
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 }
987
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 }
995
996 print_jump (file, 0 /*is_tail */ );
997
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 }
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");
1008 print_idecode_body (file, table, "/*IGORE*/");
1009
1010 /* print out a table of all the internals functions */
1011 insn_table_traverse_function (table,
1012 file, NULL, print_jump_internal_function);
1013
1014 /* print out a table of all the instructions */
1015 if (generate_expanded_instructions)
1016 insn_table_traverse_tree (table, file, cache_rules, 1, NULL, /* start */
1017 print_jump_definition, /* leaf */
1018 NULL, /* end */
1019 NULL); /* padding */
1020 else
1021 insn_table_traverse_insn (table,
1022 file, cache_rules, print_jump_definition);
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
1037 void
1038 print_idecode_validate (lf *file,
1039 insn_entry * instruction, insn_opcodes *opcode_paths)
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;
1072
1073 /* Only need to validate constant (and reserved)
1074 bits. Skip any others */
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
1080 instruction. See if any have failed to check the
1081 relevant bit */
1082 if (opcode_paths != NULL)
1083 {
1084 insn_opcodes *entry;
1085 for (entry = opcode_paths; entry != NULL; entry = entry->next)
1086 {
1087 opcode_field *opcode;
1088 for (opcode = entry->opcode;
1089 opcode != NULL; opcode = opcode->parent)
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
1103 to check it */
1104 continue;
1105 }
1106
1107 check_mask |= 1;
1108 check_val |= bit->value;
1109 }
1110
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 }
1120 nr_checks++;
1121 if (options.insn_bit_size > 32)
1122 {
1123 lf_printf (file, "if ((instruction_%d\n", word_nr);
1124 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
1125 (unsigned long) (check_mask >> 32),
1126 (unsigned long) (check_mask));
1127 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
1128 (unsigned long) (check_val >> 32),
1129 (unsigned long) (check_val));
1130 }
1131 else
1132 {
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));
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 }
1148 lf_indent_suppress (file);
1149 lf_printf (file, "#endif\n");
1150 }
1151
1152 /* Validate: Floating Point hardware
1153
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");
1164 lf_printf (file,
1165 "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
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);
1193 print_idecode_invalid (file, "return", invalid_fp_unavailable);
1194 lf_indent (file, -2);
1195 lf_printf (file, "}\n");
1196 lf_indent_suppress (file);
1197 lf_printf (file, "#endif\n");
1198 }
1199 }
1200
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");
1213 lf_printf (file,
1214 "/* Validate: Instruction issued in correct slot */\n");
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 }
1224
1225 }
1226
1227
1228 /****************************************************************/
1229
1230
1231 void
1232 print_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,
1243 "INLINE_IDECODE", " ");
1244 break;
1245 case is_function_definition:
1246 lf_print__function_type_function (file, print_semantic_function_type,
1247 "INLINE_IDECODE", "\n");
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,
1258 NULL, function_name_prefix_idecode);
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
1291 void
1292 print_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 }
This page took 0.056859 seconds and 4 git commands to generate.