/* This file is part of the program psim.
- Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+ Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
insn_table *entry,
const char *result)
{
-#if 0
- /* FIXME: I don't think the second part of this is correct! */
- int can_assume_leaf;
- decode_table *opcode_rule;
- /* have a look at the rule table, if all table rules follow all
- switch rules, I can assume that all end points are leaves */
- opcode_rule = entry->opcode_rule;
- while (opcode_rule != NULL
- && (opcode_rule->gen == switch_gen
- || opcode_rule->gen == padded_switch_gen))
- opcode_rule = opcode_rule->next;
- while (opcode_rule != NULL
- && (opcode_rule->gen == switch_gen
- || opcode_rule->gen == padded_switch_gen)
- && opcode_rule->type != normal_decode_rule)
- opcode_rule = opcode_rule->next;
- can_assume_leaf = opcode_rule == NULL;
-#endif
-
+ lf_printf(file, "/* prime the search */\n");
lf_printf(file, "idecode_table_entry *table = ");
lf_print_table_name(file, entry);
lf_printf(file, ";\n");
i2target(hi_bit_nr, entry->opcode->first),
i2target(hi_bit_nr, entry->opcode->last));
lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
+
+ lf_printf(file, "\n");
+ lf_printf(file, "/* iterate until a leaf */\n");
lf_printf(file, "while (1) {\n");
- lf_indent(file, +2);
- {
- lf_printf(file, "/* nonzero mask -> another table */\n");
- lf_printf(file, "while (table_entry->shift >= 0) {\n");
- lf_indent(file, +2);
- {
- lf_printf(file, "table = ((idecode_table_entry*)\n");
- lf_printf(file, " table_entry->function_or_table);\n");
- lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
- lf_printf(file, " >> table_entry->shift);\n");
- lf_printf(file, "table_entry = table + opcode;\n");
- }
- lf_indent(file, -2);
- lf_printf(file, "}\n");
- lf_printf(file, "ASSERT(table_entry->shift < 0);\n");
- lf_printf(file, "/* found the leaf */\n");
- lf_printf(file, "if (table_entry->shift == table_function_entry) {\n");
- lf_indent(file, +2);
- if ((code & generate_jumps)) {
- lf_printf(file, "goto *table_entry->function_or_table;\n");
+ lf_printf(file, " signed shift = table_entry->shift;\n");
+ lf_printf(file, "if (shift == function_entry) break;\n");
+ lf_printf(file, " if (shift >= 0) {\n");
+ lf_printf(file, " table = ((idecode_table_entry*)\n");
+ lf_printf(file, " table_entry->function_or_table);\n");
+ lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
+ lf_printf(file, " >> shift);\n");
+ lf_printf(file, " table_entry = table + opcode;\n");
+ lf_printf(file, " }\n");
+ lf_printf(file, " else {\n");
+ lf_printf(file, " /* must be a boolean */\n");
+ lf_printf(file, " ASSERT(table_entry->shift == boolean_entry);\n");
+ lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
+ lf_printf(file, " != table_entry->value);\n");
+ lf_printf(file, " table = ((idecode_table_entry*)\n");
+ lf_printf(file, " table_entry->function_or_table);\n");
+ lf_printf(file, " table_entry = table + opcode;\n");
+ lf_printf(file, " }\n");
+ lf_printf(file, "}\n");
+
+ lf_printf(file, "\n");
+ lf_printf(file, "/* call the leaf code */\n");
+ if ((code & generate_jumps)) {
+ lf_printf(file, "goto *table_entry->function_or_table;\n");
+ }
+ else {
+ lf_printf(file, "%s ", result);
+ if ((code & generate_with_icache)) {
+ lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");
+ lf_printf(file, " (%s));\n", ICACHE_FUNCTION_ACTUAL);
}
else {
- lf_printf(file, "%s ", result);
- if ((code & generate_with_icache)) {
- lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");
- lf_printf(file, " (%s));\n", ICACHE_FUNCTION_ACTUAL);
- }
- else {
- lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");
- lf_printf(file, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL);
- }
+ lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");
+ lf_printf(file, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL);
}
- lf_printf(file, "break;\n");
- lf_indent(file, -2);
- lf_printf(file, "}\n");
- lf_printf(file, "/* must be a boolean */\n");
- lf_printf(file, "opcode = (((instruction << table_entry->left)\n");
- lf_printf(file, " >> table_entry->right)\n");
- lf_printf(file, " != table_entry->mask);\n");
- lf_printf(file, "table = ((idecode_table_entry*)\n");
- lf_printf(file, " table_entry->function_or_table);\n");
- lf_printf(file, "table_entry = table + opcode;\n");
}
- lf_indent(file, -2);
- lf_printf(file, "}\n");
}
/* add an entry to the table */
if (entry->parent->opcode_rule->gen == array_gen) {
+ lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
if (entry->opcode == NULL) {
/* table leaf entry */
- lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ", entry->opcode_nr);
+ lf_printf(file, "function_entry, 0, 0, ");
if ((code & generate_jumps))
lf_printf(file, "&&");
print_function_name(file,
((code & generate_with_icache)
? function_name_prefix_icache
: function_name_prefix_semantics));
- lf_printf(file, " },\n");
}
else if (entry->opcode_rule->gen == switch_gen
|| entry->opcode_rule->gen == goto_switch_gen
|| entry->opcode_rule->gen == padded_switch_gen) {
/* table calling switch statement */
- lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ",
- entry->opcode_nr);
+ lf_printf(file, "function_entry, 0, 0, ");
if ((code & generate_jumps))
lf_printf(file, "&&");
lf_print_table_name(file, entry);
- lf_printf(file, " },\n");
+ }
+ else if (entry->opcode->is_boolean) {
+ /* table `calling' boolean table */
+ lf_printf(file, "boolean_entry, ");
+ lf_printf(file, "MASK32(%d, %d), ",
+ i2target(hi_bit_nr, entry->opcode->first),
+ i2target(hi_bit_nr, entry->opcode->last));
+ lf_printf(file, "INSERTED32(%d, %d, %d), ",
+ entry->opcode->boolean_constant,
+ i2target(hi_bit_nr, entry->opcode->first),
+ i2target(hi_bit_nr, entry->opcode->last));
+ lf_print_table_name(file, entry);
}
else {
/* table `calling' another table */
- lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
- if (entry->opcode->is_boolean)
- lf_printf(file, "table_boolean_entry, %d, %d, %d, ",
- entry->opcode->first,
- insn_bit_size - entry->opcode->last + entry->opcode->first - 1,
- entry->opcode->boolean_constant);
- else
- lf_printf(file, "%d, 0, 0, MASK32(%d,%d), ",
- insn_bit_size - entry->opcode->last - 1,
- i2target(hi_bit_nr, entry->opcode->first),
- i2target(hi_bit_nr, entry->opcode->last));
+ lf_printf(file, "%d, ", insn_bit_size - entry->opcode->last - 1);
+ lf_printf(file, "MASK32(%d,%d), ",
+ i2target(hi_bit_nr, entry->opcode->first),
+ i2target(hi_bit_nr, entry->opcode->last));
+ lf_printf(file, "0, ");
lf_print_table_name(file, entry);
- lf_printf(file, " },\n");
}
+ lf_printf(file, " },\n");
}
}
{
ASSERT(depth == 0);
if (table->opcode_rule->gen == array_gen) {
- lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ", opcode_nr);
+ lf_printf(file, " /*%d*/ { function_entry, 0, 0, ", opcode_nr);
if ((code & generate_jumps))
lf_printf(file, "&&");
lf_printf(file, "%s_illegal },\n",
static void
print_idecode_body(lf *file,
insn_table *table,
- const char *result,
- const char *indent)
+ const char *result)
{
- lf_indent(file, +strlen(indent));
- lf_putstr(file, "{\n");
- lf_indent(file, +2);
if (table->opcode_rule->gen == switch_gen
|| table->opcode_rule->gen == goto_switch_gen
|| table->opcode_rule->gen == padded_switch_gen)
print_idecode_switch(file, table, result);
else
print_idecode_table(file, table, result);
- lf_indent(file, -2);
- lf_putstr(file, "}\n");
- lf_indent(file, -strlen(indent));
}
lf_indent(file, +2);
lf_putstr(file, "jmp_buf halt;\n");
lf_putstr(file, "jmp_buf restart;\n");
- lf_putstr(file, "cpu *processor = NULL;\n");
- lf_putstr(file, "unsigned_word cia = -1;\n");
- lf_putstr(file, "instruction_word instruction = 0;\n");
- if (generate_smp) {
- lf_putstr(file, "int current_cpu = -1;\n");
+ if (!generate_smp) {
+ lf_putstr(file, "cpu *processor = NULL;\n");
+ lf_putstr(file, "unsigned_word cia = -1;\n");
}
- if ((code & generate_with_icache)) {
- lf_putstr(file, "idecode_cache *cache_entry = NULL;\n");
+ lf_putstr(file, "int last_cpu;\n");
+ if (generate_smp) {
+ lf_putstr(file, "int current_cpu;\n");
}
if ((code & generate_with_icache)) {
+ lf_putstr(file, "int cpu_nr;\n");
lf_putstr(file, "\n");
- lf_putstr(file, "{\n");
- lf_putstr(file, " int cpu_nr;\n");
- lf_putstr(file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
- lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
- lf_putstr(file, "}\n");
+ lf_putstr(file, "/* flush the icache of a possible break insn */\n");
+ lf_putstr(file, "for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
+ lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
}
lf_putstr(file, "\n");
- lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
-
- lf_putstr(file, "\n");
+ lf_putstr(file, "/* set the halt target initially */\n");
+ lf_putstr(file, "psim_set_halt_and_restart(system, &halt, NULL);\n");
lf_putstr(file, "if (setjmp(halt))\n");
lf_putstr(file, " return;\n");
lf_putstr(file, "\n");
- lf_putstr(file, "setjmp(restart);\n");
+ lf_putstr(file, "/* where were we before the halt? */\n");
+ lf_putstr(file, "last_cpu = psim_last_cpu(system);\n");
- if (!generate_smp) {
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* check for need to force event processing first */\n");
+ lf_putstr(file, "if (WITH_EVENTS) {\n");
+ lf_putstr(file, " if (last_cpu == nr_cpus) {\n");
+ lf_putstr(file, " /* halted during event processing */\n");
+ lf_putstr(file, " event_queue_process(events);\n");
+ lf_putstr(file, " last_cpu = -1;\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, " else if (last_cpu == nr_cpus - 1) {\n");
+ lf_putstr(file, " /* last cpu did halt */\n");
+ lf_putstr(file, " if (event_queue_tick(events)) {\n");
+ lf_putstr(file, " event_queue_process(events);\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, " last_cpu = -1;\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, "}\n");
+ lf_putstr(file, "else {\n");
+ lf_putstr(file, " if (last_cpu == nr_cpus - 1)\n");
+ lf_putstr(file, " /* cpu zero is next */\n");
+ lf_putstr(file, " last_cpu = -1;\n");
+ lf_putstr(file, "}\n");
- lf_putstr(file, "
-/* CASE 1: NO SMP (with or with out instruction cache).
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* have ensured that the event queue can not be first */\n");
+ lf_putstr(file, "ASSERT(last_cpu >= -1 && last_cpu < nr_cpus - 1);\n");
- In this case, we can take advantage of the fact that the current
- instruction address does not need to be returned to the cpu object
- after every execution of an instruction. Instead it only needs to
- be saved when either A. the main loop exits or B. A cpu-halt or
- cpu-restart call forces the loop to be re-enered. The later
- functions always save the current cpu instruction address.
+ if (!generate_smp) {
- Two subcases also exist that with and that without an instruction
- cache. */");
+ lf_putstr(file, "\n\
+/* CASE 1: NO SMP (with or with out instruction cache).\n\
+\n\
+ In this case, we can take advantage of the fact that the current\n\
+ instruction address does not need to be returned to the cpu object\n\
+ after every execution of an instruction. Instead it only needs to\n\
+ be saved when either A. the main loop exits or B. A cpu-halt or\n\
+ cpu-restart call forces the loop to be re-enered. The later\n\
+ functions always save the current cpu instruction address.\n\
+\n\
+ Two subcases also exist that with and that without an instruction\n\
+ cache.\n\
+\n\
+ An additional complexity is the need to ensure that a 1:1 ratio\n\
+ is maintained between the execution of an instruction and the\n\
+ incrementing of the simulation clock */");
- lf_putstr(file, "\n\n");
+ lf_putstr(file, "\n");
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* now add restart target as ready to run */\n");
+ lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
+ lf_putstr(file, "if (setjmp(restart)) {\n");
+ lf_putstr(file, " if (WITH_EVENTS) {\n");
+ lf_putstr(file, " /* when restart, cpu must have been last, clock next */\n");
+ lf_putstr(file, " if (event_queue_tick(events)) {\n");
+ lf_putstr(file, " event_queue_process(events);\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, "}\n");
+
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* prime the main loop */\n");
lf_putstr(file, "processor = processors[0];\n");
lf_putstr(file, "cia = cpu_get_program_counter(processor);\n");
+
+ lf_putstr(file, "\n");
lf_putstr(file, "while (1) {\n");
lf_indent(file, +2);
- lf_putstr(file, "if (WITH_EVENTS) {\n");
- lf_putstr(file, " if (event_queue_tick(events)) {\n");
- lf_putstr(file, " cpu_set_program_counter(processor, cia);\n");
- lf_putstr(file, " event_queue_process(events);\n");
- lf_putstr(file, " cia = cpu_get_program_counter(processor);\n");
- lf_putstr(file, " }\n");
- lf_putstr(file, "}\n");
if (!(code & generate_with_icache)) {
- lf_putstr(file, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
- print_idecode_body(file, table, "cia =", "");
- /* tail */
- if (can_stop) {
- lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
- lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
- }
+ lf_putstr(file, "instruction_word instruction =\n");
+ lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
+ lf_putstr(file, "\n");
+ print_idecode_body(file, table, "cia =");;
}
if ((code & generate_with_icache)) {
- lf_putstr(file, "cache_entry = cpu_icache_entry(processor, cia);\n");
+ lf_putstr(file, "idecode_cache *cache_entry =\n");
+ lf_putstr(file, " cpu_icache_entry(processor, cia);\n");
lf_putstr(file, "if (cache_entry->address == cia) {\n");
lf_putstr(file, " /* cache hit */\n");
lf_putstr(file, " idecode_semantic *const semantic = cache_entry->semantic;\n");
lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
}
- lf_putstr(file, " continue;\n");
lf_putstr(file, "}\n");
lf_putstr(file, "else {\n");
lf_putstr(file, " /* cache miss */\n");
lf_putstr(file, "idecode_semantic *semantic;\n");
lf_indent(file, -2);
}
- lf_putstr(file, " instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
+ lf_putstr(file, " instruction_word instruction =\n");
+ lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
lf_putstr(file, " if (WITH_MON != 0)\n");
lf_putstr(file, " mon_event(mon_event_icache_miss, processor, cia);\n");
if ((code & generate_with_semantic_icache)) {
- print_idecode_body(file, table, "cia =", " ");
+ lf_putstr(file, "{\n");
+ lf_indent(file, +2);
+ print_idecode_body(file, table, "cia =");
+ lf_indent(file, -2);
+ lf_putstr(file, "}\n");
}
else {
- print_idecode_body(file, table, "semantic =", " ");
+ print_idecode_body(file, table, "semantic =");
lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
}
- /* tail */
- if (can_stop) {
- lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
- lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
- }
- lf_putstr(file, " continue;\n");
lf_putstr(file, "}\n");
}
+ /* events */
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* process any events */\n");
+ lf_putstr(file, "if (WITH_EVENTS) {\n");
+ lf_putstr(file, " if (event_queue_tick(events)) {\n");
+ lf_putstr(file, " cpu_set_program_counter(processor, cia);\n");
+ lf_putstr(file, " event_queue_process(events);\n");
+ lf_putstr(file, " cia = cpu_get_program_counter(processor);\n");
+ lf_putstr(file, " }\n");
+ lf_putstr(file, "}\n");
+
+ /* tail */
+ if (can_stop) {
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* abort if necessary */\n");
+ lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
+ lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*not important*/);\n");
+ }
+
lf_indent(file, -2);
lf_putstr(file, "}\n");
}
if (generate_smp) {
- lf_putstr(file, "
-/* CASE 2: SMP (With or without ICACHE)
-
- The complexity here comes from needing to correctly restart the
- system when it is aborted. In particular if cpu0 requests a
- restart, the next cpu is still cpu1. Cpu0 being restarted after
+ lf_putstr(file, "\n\
+/* CASE 2: SMP (With or without ICACHE)\n\
+\n\
+ The complexity here comes from needing to correctly restart the\n\
+ system when it is aborted. In particular if cpu0 requests a\n\
+ restart, the next cpu is still cpu1. Cpu0 being restarted after\n\
all the other CPU's and the event queue have been processed */");
- lf_putstr(file, "\n\n");
+ lf_putstr(file, "\n");
- lf_putstr(file, "current_cpu = psim_last_cpu(system);\n");
+ lf_putstr(file, "\n");
+ lf_putstr(file, "/* now establish the restart target */\n");
+ lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
+ lf_putstr(file, "if (setjmp(restart)) {\n");
+ lf_putstr(file, " current_cpu = psim_last_cpu(system);\n");
+ lf_putstr(file, " ASSERT(current_cpu >= 0 && current_cpu < nr_cpus);\n");
+ lf_putstr(file, "}\n");
+ lf_putstr(file, "else {\n");
+ lf_putstr(file, " current_cpu = last_cpu;\n");
+ lf_putstr(file, " ASSERT(current_cpu >= -1 && current_cpu < nr_cpus);\n");
+ lf_putstr(file, "}\n");
+
+
+ lf_putstr(file, "\n");
lf_putstr(file, "while (1) {\n");
lf_indent(file, +2);
+
+ lf_putstr(file, "\n");
lf_putstr(file, "if (WITH_EVENTS) {\n");
lf_putstr(file, " current_cpu += 1;\n");
lf_putstr(file, " if (current_cpu == nr_cpus) {\n");
lf_putstr(file, "else {\n");
lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
lf_putstr(file, "}\n");
- lf_putstr(file, "processor = processors[current_cpu];\n");
- lf_putstr(file, "cia = cpu_get_program_counter(processor);\n");
+
+ lf_putstr(file, "\n");
+ lf_putstr(file, "{\n");
+ lf_indent(file, +2);
+ lf_putstr(file, "cpu *processor = processors[current_cpu];\n");
+ lf_putstr(file, "unsigned_word cia =\n");
+ lf_putstr(file, " cpu_get_program_counter(processor);\n");
if (!(code & generate_with_icache)) {
- lf_putstr(file, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
- print_idecode_body(file, table, "cia =", "");
+ lf_putstr(file, "instruction_word instruction =\n");
+ lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
+ print_idecode_body(file, table, "cia =");
if (can_stop) {
lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
}
lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
- lf_putstr(file, "continue;\n");
}
if ((code & generate_with_icache)) {
- lf_putstr(file, "cache_entry = cpu_icache_entry(processor, cia);\n");
+ lf_putstr(file, "idecode_cache *cache_entry =\n");
+ lf_putstr(file, " cpu_icache_entry(processor, cia);\n");
+ lf_putstr(file, "\n");
lf_putstr(file, "if (cache_entry->address == cia) {\n");
{
lf_indent(file, +2);
+ lf_putstr(file, "\n");
lf_putstr(file, "/* cache hit */\n");
lf_putstr(file, "idecode_semantic *semantic = cache_entry->semantic;\n");
lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
/* tail */
if (can_stop) {
lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
- lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
+ lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
}
lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
- lf_putstr(file, "continue;\n");
+ lf_putstr(file, "\n");
lf_indent(file, -2);
}
lf_putstr(file, "}\n");
lf_putstr(file, "else {\n");
{
lf_indent(file, +2);
+ lf_putstr(file, "\n");
lf_putstr(file, "/* cache miss */\n");
if (!(code & generate_with_semantic_icache)) {
lf_putstr(file, "idecode_semantic *semantic;\n");
}
- lf_putstr(file, "instruction =\n");
+ lf_putstr(file, "instruction_word instruction =\n");
lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
lf_putstr(file, "if (WITH_MON != 0)\n");
lf_putstr(file, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
if ((code & generate_with_semantic_icache)) {
- print_idecode_body(file, table, "cia =", "");
+ lf_putstr(file, "{\n");
+ lf_indent(file, +2);
+ print_idecode_body(file, table, "cia =");
+ lf_indent(file, -2);
+ lf_putstr(file, "}\n");
}
else {
- print_idecode_body(file, table, "semantic = ", " ");
+ print_idecode_body(file, table, "semantic = ");
lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
}
/* tail */
if (can_stop) {
lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
- lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
+ lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
}
lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
- lf_putstr(file, "continue;\n");
+ lf_putstr(file, "\n");
lf_indent(file, -2);
}
lf_putstr(file, "}\n");
}
+ /* close */
+ lf_indent(file, -2);
+ lf_putstr(file, "}\n");
+
/* tail */
lf_indent(file, -2);
lf_putstr(file, "}\n");
lf_putstr(file, "instruction\n");
lf_putstr(file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
lf_putstr(file, " processor, nia);\n");
- print_idecode_body(file, table, "/*IGORE*/", "");
+ print_idecode_body(file, table, "/*IGORE*/");
/* print out a table of all the internals functions */
insn_table_traverse_function(table,
{
int indent;
lf_printf(file, "\n");
- lf_print_function_type(file, "void", "INLINE_IDECODE", (is_definition ? " " : "\n"));
+ lf_print_function_type(file, "void", "PSIM_INLINE_IDECODE", (is_definition ? " " : "\n"));
indent = lf_putstr(file, (can_stop ? "idecode_run_until_stop" : "idecode_run"));
if (is_definition)
lf_putstr(file, "\n");
lf_printf(file, "#include \"idecode.h\"\n");
lf_printf(file, "#include \"semantics.h\"\n");
lf_printf(file, "#include \"icache.h\"\n");
+ lf_printf(file, "#ifdef HAVE_COMMON_FPU\n");
+ lf_printf(file, "#include \"sim-inline.h\"\n");
+ lf_printf(file, "#include \"sim-fpu.h\"\n");
+ lf_printf(file, "#endif\n");
lf_printf(file, "#include \"support.h\"\n");
lf_printf(file, "\n");
lf_printf(file, "#include <setjmp.h>\n");
lf_printf(file, "\n");
- lf_printf(file, "/* encodings for a negative shift field */\n");
lf_printf(file, "enum {\n");
- lf_printf(file, " table_boolean_entry = -2,\n");
- lf_printf(file, " table_function_entry = -1,\n");
+ lf_printf(file, " /* greater or equal to zero => table */\n");
+ lf_printf(file, " function_entry = -1,\n");
+ lf_printf(file, " boolean_entry = -2,\n");
lf_printf(file, "};\n");
lf_printf(file, "\n");
lf_printf(file, "typedef struct _idecode_table_entry {\n");
- lf_printf(file, " signed short shift; /* shift >= 0: t[(i & mask) >> shift] */\n");
- lf_printf(file, " unsigned char left; /* shift == -2: */\n");
- lf_printf(file, " unsigned char right; /* t[((i << left) >> right) != mask] */\n");
- lf_printf(file, " unsigned mask; /* else (shift == -1): function() */\n");
+ lf_printf(file, " int shift;\n");
+ lf_printf(file, " instruction_word mask;\n");
+ lf_printf(file, " instruction_word value;");
lf_printf(file, " void *function_or_table;\n");
lf_printf(file, "} idecode_table_entry;\n");
lf_printf(file, "\n");
error("Something is wrong!\n");
}
}
-
-