/* The IGEN simulator generator for GDB, the GNU Debugger.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002-2020 Free Software Foundation, Inc.
Contributed by 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/>. */
#include "misc.h"
int is_function_definition,
int nr_prefetched_words)
{
- lf_printf(file, "\n");
+ lf_printf (file, "\n");
lf_print__function_type_function (file, print_icache_function_type,
"EXTERN_ICACHE", " ");
print_function_name (file,
basename, format_name, NULL,
- expanded_bits,
- function_name_prefix_icache);
+ expanded_bits, function_name_prefix_icache);
lf_printf (file, "\n(");
print_icache_function_formal (file, nr_prefetched_words);
lf_printf (file, ")");
void
print_icache_declaration (lf *file,
- insn_entry *insn,
+ insn_entry * insn,
opcode_bits *expanded_bits,
- insn_opcodes *opcodes,
- int nr_prefetched_words)
+ insn_opcodes *opcodes, int nr_prefetched_words)
{
print_icache_function_header (file,
insn->name,
insn->format_name,
expanded_bits,
- 0/* is not function definition */,
+ 0 /* is not function definition */ ,
nr_prefetched_words);
}
char *reason;
ASSERT (format_name != NULL);
ASSERT (entry_name != NULL);
-
+
/* figure out exactly what should be going on here */
switch (cache_type)
{
{
reason = "cache";
what_to_declare = ((what_to_do & put_values_in_icache)
- ? declare_variables
- : what_to_declare);
+ ? declare_variables : what_to_declare);
}
else
return;
break;
default:
- abort (); /* Bad switch. */
+ abort (); /* Bad switch. */
}
-
+
/* For the type, default to a simple unsigned */
if (entry_type == NULL || strlen (entry_type) == 0)
entry_type = "unsigned";
-
+
/* look through the set of expanded sub fields to see if this field
has been given a constant value */
- for (bits = expanded_bits;
- bits != NULL;
- bits = bits->next)
+ for (bits = expanded_bits; bits != NULL; bits = bits->next)
{
if (bits->field == cur_field)
break;
}
-
+
/* Define a storage area for the cache element */
switch (what_to_declare)
{
lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
break;
}
-
-
+
+
/* define a value for that storage area as determined by what is in
the cache */
if (bits != NULL
{
/* The cache rule is specifying what to do with a simple
instruction field.
-
- Because of instruction expansion, the field is either a
- constant value or equal to the specified constant (boolean
- comparison). (The latter indicated by bits->value == 0).
-
+
+ Because of instruction expansion, the field is either a
+ constant value or equal to the specified constant (boolean
+ comparison). (The latter indicated by bits->value == 0).
+
The case of a field not being equal to the specified boolean
value is handled later. */
expression = "constant field";
"_is_",
strlen ("_is_")) == 0
&& ((bits->opcode->is_boolean
- && ((unsigned) atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
- == bits->opcode->boolean_constant))
+ && ((unsigned)
+ atol (entry_name + strlen (single_insn_field) +
+ strlen ("_is_")) == bits->opcode->boolean_constant))
|| (!bits->opcode->is_boolean)))
{
/* The cache rule defines an entry for the comparison between a
- single instruction field and a constant. The value of the
- comparison in someway matches that of the opcode field that
- was made constant through expansion. */
+ single instruction field and a constant. The value of the
+ comparison in someway matches that of the opcode field that
+ was made constant through expansion. */
expression = "constant compare";
if (bits->opcode->is_boolean)
{
lf_printf (file, "%d /* %s == %d */",
bits->value == 0,
- single_insn_field,
- bits->opcode->boolean_constant);
+ single_insn_field, bits->opcode->boolean_constant);
}
else if (bits->opcode->last < bits->field->last)
{
lf_printf (file, "%d /* %s == %d */",
- (atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
- == (bits->value << (bits->field->last - bits->opcode->last))),
+ (atol
+ (entry_name + strlen (single_insn_field) +
+ strlen ("_is_")) ==
+ (bits->
+ value << (bits->field->last - bits->opcode->last))),
single_insn_field,
- (bits->value << (bits->field->last - bits->opcode->last)));
+ (bits->
+ value << (bits->field->last - bits->opcode->last)));
}
else
{
lf_printf (file, "%d /* %s == %d */",
- (atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
- == bits->value),
- single_insn_field,
+ (atol
+ (entry_name + strlen (single_insn_field) +
+ strlen ("_is_")) == bits->value), single_insn_field,
bits->value);
}
}
else
{
/* put the field in the local variable, possibly also enter it
- into the cache */
+ into the cache */
expression = "extraction";
/* handle the cache */
if ((what_to_do & get_values_from_icache)
|| (what_to_do & put_values_in_icache))
{
lf_printf (file, "cache_entry->crack.%s.%s",
- format_name,
- entry_name);
- if (what_to_do & put_values_in_icache) /* also put it in the cache? */
+ format_name, entry_name);
+ if (what_to_do & put_values_in_icache) /* also put it in the cache? */
{
lf_printf (file, " = ");
}
if (cur_field != NULL)
{
if (entry_expression != NULL && strlen (entry_expression) > 0)
- error (line, "Instruction field entry with nonempty expression\n");
- if (cur_field->first == 0 && cur_field->last == options.insn_bit_size - 1)
- lf_printf (file, "(instruction_%d)",
- cur_field->word_nr);
+ error (line,
+ "Instruction field entry with nonempty expression\n");
+ if (cur_field->first == 0
+ && cur_field->last == options.insn_bit_size - 1)
+ lf_printf (file, "(instruction_%d)", cur_field->word_nr);
else if (cur_field->last == options.insn_bit_size - 1)
lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
options.insn_bit_size,
}
}
}
-
+
switch (what_to_declare)
{
case define_variables:
void
print_icache_body (lf *file,
- insn_entry *instruction,
+ insn_entry * instruction,
opcode_bits *expanded_bits,
cache_entry *cache_rules,
icache_decl_type what_to_declare,
- icache_body_type what_to_do,
- int nr_prefetched_words)
+ icache_body_type what_to_do, int nr_prefetched_words)
{
/* extract instruction fields */
lf_printf (file, "/* Extraction: %s\n", instruction->name);
}
lf_printf (file, "\n ");
print_insn_words (file, instruction);
- lf_printf(file, " */\n");
-
+ lf_printf (file, " */\n");
+
/* pass zero - fetch from memory any missing instructions.
Some of the instructions will have already been fetched (in the
case define_variables:
case declare_variables:
for (word_nr = nr_prefetched_words;
- word_nr < instruction->nr_words;
- word_nr++)
+ word_nr < instruction->nr_words; word_nr++)
{
/* FIXME - should be using print_icache_extraction? */
- lf_printf (file, "%sinstruction_word instruction_%d UNUSED = ",
- options.module.global.prefix.l,
- word_nr);
+ lf_printf (file,
+ "%sinstruction_word instruction_%d UNUSED = ",
+ options.module.global.prefix.l, word_nr);
lf_printf (file, "IMEM%d_IMMED (cia, %d)",
options.insn_bit_size, word_nr);
lf_printf (file, ";\n");
/* if putting the instruction words in the cache, define references
for them */
- if (options.gen.insn_in_icache) {
- /* FIXME: is the instruction_word type correct? */
- print_icache_extraction (file,
- instruction->format_name,
- cache_value,
- "insn", /* name */
- "instruction_word", /* type */
- "instruction", /* expression */
- NULL, /* origin */
- NULL, /* line */
- NULL, NULL,
- what_to_declare,
- what_to_do);
- }
- lf_printf(file, "\n");
+ if (options.gen.insn_in_icache)
+ {
+ /* FIXME: is the instruction_word type correct? */
+ print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */
+ "instruction_word", /* type */
+ "instruction", /* expression */
+ NULL, /* origin */
+ NULL, /* line */
+ NULL, NULL, what_to_declare, what_to_do);
+ }
+ lf_printf (file, "\n");
/* pass one - process instruction fields.
the cache */
{
insn_word_entry *word;
- for (word = instruction->words;
- word != NULL;
- word = word->next)
+ for (word = instruction->words; word != NULL; word = word->next)
{
insn_field_entry *cur_field;
for (cur_field = word->first;
cur_field->first < options.insn_bit_size;
cur_field = cur_field->next)
{
+ /* Always expand named fields (even if constant), so
+ references are valid. */
if (cur_field->type == insn_field_string)
{
cache_entry *cache_rule;
overriding the default cache action for an
instruction field */
for (cache_rule = cache_rules;
- cache_rule != NULL;
- cache_rule = cache_rule->next)
+ cache_rule != NULL; cache_rule = cache_rule->next)
{
if (filter_is_subset (instruction->field_names,
cache_rule->original_fields)
- && strcmp (cache_rule->name, cur_field->val_string) == 0)
+ && strcmp (cache_rule->name,
+ cur_field->val_string) == 0)
{
value_type = cache_rule->entry_type;
value_line = cache_rule->line;
}
}
/* Define an entry for the field within the
- instruction */
- print_icache_extraction (file,
- instruction->format_name,
- value_type,
- cur_field->val_string, /* name */
- NULL, /* type */
- NULL, /* expression */
- cur_field->val_string, /* insn field */
+ instruction */
+ print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */
+ NULL, /* type */
+ NULL, /* expression */
+ cur_field->val_string, /* insn field */
value_line,
cur_field,
expanded_bits,
- what_to_declare,
- what_to_do);
+ what_to_declare, what_to_do);
}
}
}
{
cache_entry *cache_rule;
for (cache_rule = cache_rules;
- cache_rule != NULL;
- cache_rule = cache_rule->next)
+ cache_rule != NULL; cache_rule = cache_rule->next)
{
if (filter_is_subset (instruction->field_names,
cache_rule->original_fields)
- && !filter_is_member (instruction->field_names,
- cache_rule->name))
+ && !filter_is_member (instruction->field_names, cache_rule->name))
{
- char *single_field = filter_next (cache_rule->original_fields, "");
- if (filter_next (cache_rule->original_fields, single_field) != NULL)
+ char *single_field =
+ filter_next (cache_rule->original_fields, "");
+ if (filter_next (cache_rule->original_fields, single_field) !=
+ NULL)
single_field = NULL;
- print_icache_extraction (file,
- instruction->format_name,
- cache_rule->entry_type,
- cache_rule->name,
- cache_rule->type,
- cache_rule->expression,
- single_field,
- cache_rule->line,
- NULL, /* cur_field */
+ print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL, /* cur_field */
expanded_bits,
- what_to_declare,
- what_to_do);
+ what_to_declare, what_to_do);
}
}
}
typedef struct _form_fields form_fields;
-struct _form_fields {
+struct _form_fields
+{
char *name;
filter *fields;
form_fields *next;
{
form_fields *forms = NULL;
insn_entry *insn;
- for (insn = isa->insns;
- insn != NULL;
- insn = insn->next) {
- form_fields **form = &forms;
- while (1)
- {
- if (*form == NULL)
- {
- /* new format name, add it */
- form_fields *new_form = ZALLOC (form_fields);
- new_form->name = insn->format_name;
- filter_add (&new_form->fields, insn->field_names);
- *form = new_form;
- break;
- }
- else if (strcmp ((*form)->name, insn->format_name) == 0)
- {
- /* already present, add field names to the existing list */
- filter_add (&(*form)->fields, insn->field_names);
- break;
- }
- form = &(*form)->next;
- }
- }
+ for (insn = isa->insns; insn != NULL; insn = insn->next)
+ {
+ form_fields **form = &forms;
+ while (1)
+ {
+ if (*form == NULL)
+ {
+ /* new format name, add it */
+ form_fields *new_form = ZALLOC (form_fields);
+ new_form->name = insn->format_name;
+ filter_add (&new_form->fields, insn->field_names);
+ *form = new_form;
+ break;
+ }
+ else if (strcmp ((*form)->name, insn->format_name) == 0)
+ {
+ /* already present, add field names to the existing list */
+ filter_add (&(*form)->fields, insn->field_names);
+ break;
+ }
+ form = &(*form)->next;
+ }
+ }
return forms;
}
extern void
-print_icache_struct (lf *file,
- insn_table *isa,
- cache_entry *cache_rules)
+print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
{
/* Create a list of all the different instruction formats with their
corresponding field names. */
form_fields *formats = insn_table_cache_fields (isa);
-
+
lf_printf (file, "\n");
lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
options.module.global.prefix.u,
(options.gen.icache ? options.gen.icache_size : 0));
lf_printf (file, "\n");
-
+
/* create an instruction cache if being used */
- if (options.gen.icache) {
- lf_printf (file, "typedef struct _%sidecode_cache {\n",
- options.module.global.prefix.l);
- lf_indent (file, +2);
+ if (options.gen.icache)
{
- form_fields *format;
- lf_printf (file, "unsigned_word address;\n");
- lf_printf (file, "void *semantic;\n");
- lf_printf (file, "union {\n");
+ lf_printf (file, "typedef struct _%sidecode_cache {\n",
+ options.module.global.prefix.l);
lf_indent (file, +2);
- for (format = formats;
- format != NULL;
- format = format->next)
- {
- lf_printf (file, "struct {\n");
- lf_indent (file, +2);
+ {
+ form_fields *format;
+ lf_printf (file, "unsigned_word address;\n");
+ lf_printf (file, "void *semantic;\n");
+ lf_printf (file, "union {\n");
+ lf_indent (file, +2);
+ for (format = formats; format != NULL; format = format->next)
{
- cache_entry *cache_rule;
- char *field;
- /* space for any instruction words */
- if (options.gen.insn_in_icache)
- lf_printf (file, "instruction_word insn[%d];\n", isa->max_nr_words);
- /* define an entry for any applicable cache rules */
- for (cache_rule = cache_rules;
- cache_rule != NULL;
- cache_rule = cache_rule->next)
- {
- /* nb - sort of correct - should really check against
- individual instructions */
- if (filter_is_subset (format->fields, cache_rule->original_fields))
- {
- char *memb;
- lf_printf (file, "%s %s;",
- (cache_rule->type == NULL
- ? "unsigned"
- : cache_rule->type),
- cache_rule->name);
- lf_printf (file, " /*");
- for (memb = filter_next (cache_rule->original_fields, "");
- memb != NULL;
- memb = filter_next (cache_rule->original_fields, memb))
- {
- lf_printf (file, " %s", memb);
- }
- lf_printf (file, " */\n");
- }
- }
- /* define an entry for any fields not covered by a cache rule */
- for (field = filter_next (format->fields, "");
- field != NULL;
- field = filter_next (format->fields, field))
- {
- cache_entry *cache_rule;
- int found_rule = 0;
- for (cache_rule = cache_rules;
- cache_rule != NULL;
- cache_rule = cache_rule->next)
- {
- if (strcmp (cache_rule->name, field) == 0)
- {
- found_rule = 1;
- break;
- }
- }
- if (!found_rule)
- lf_printf (file, "unsigned %s; /* default */\n", field);
- }
+ lf_printf (file, "struct {\n");
+ lf_indent (file, +2);
+ {
+ cache_entry *cache_rule;
+ char *field;
+ /* space for any instruction words */
+ if (options.gen.insn_in_icache)
+ lf_printf (file, "instruction_word insn[%d];\n",
+ isa->max_nr_words);
+ /* define an entry for any applicable cache rules */
+ for (cache_rule = cache_rules;
+ cache_rule != NULL; cache_rule = cache_rule->next)
+ {
+ /* nb - sort of correct - should really check against
+ individual instructions */
+ if (filter_is_subset
+ (format->fields, cache_rule->original_fields))
+ {
+ char *memb;
+ lf_printf (file, "%s %s;",
+ (cache_rule->type == NULL
+ ? "unsigned"
+ : cache_rule->type), cache_rule->name);
+ lf_printf (file, " /*");
+ for (memb =
+ filter_next (cache_rule->original_fields, "");
+ memb != NULL;
+ memb =
+ filter_next (cache_rule->original_fields, memb))
+ {
+ lf_printf (file, " %s", memb);
+ }
+ lf_printf (file, " */\n");
+ }
+ }
+ /* define an entry for any fields not covered by a cache rule */
+ for (field = filter_next (format->fields, "");
+ field != NULL; field = filter_next (format->fields, field))
+ {
+ cache_entry *cache_rule;
+ int found_rule = 0;
+ for (cache_rule = cache_rules;
+ cache_rule != NULL; cache_rule = cache_rule->next)
+ {
+ if (strcmp (cache_rule->name, field) == 0)
+ {
+ found_rule = 1;
+ break;
+ }
+ }
+ if (!found_rule)
+ lf_printf (file, "unsigned %s; /* default */\n", field);
+ }
+ }
+ lf_indent (file, -2);
+ lf_printf (file, "} %s;\n", format->name);
}
- lf_indent (file, -2);
- lf_printf (file, "} %s;\n", format->name);
- }
+ lf_indent (file, -2);
+ lf_printf (file, "} crack;\n");
+ }
lf_indent (file, -2);
- lf_printf (file, "} crack;\n");
+ lf_printf (file, "} %sidecode_cache;\n",
+ options.module.global.prefix.l);
}
- lf_indent (file, -2);
- lf_printf (file, "} %sidecode_cache;\n", options.module.global.prefix.l);
- }
else
{
/* alernativly, since no cache, emit a dummy definition for
- idecode_cache so that code refering to the type can still compile */
- lf_printf(file, "typedef void %sidecode_cache;\n",
- options.module.global.prefix.l);
+ idecode_cache so that code refering to the type can still compile */
+ lf_printf (file, "typedef void %sidecode_cache;\n",
+ options.module.global.prefix.l);
}
lf_printf (file, "\n");
}
static void
print_icache_function (lf *file,
- insn_entry *instruction,
+ insn_entry * instruction,
opcode_bits *expanded_bits,
insn_opcodes *opcodes,
- cache_entry *cache_rules,
- int nr_prefetched_words)
+ cache_entry *cache_rules, int nr_prefetched_words)
{
int indent;
/* generate code to enter decoded instruction into the icache */
- lf_printf(file, "\n");
+ lf_printf (file, "\n");
lf_print__function_type_function (file, print_icache_function_type,
"EXTERN_ICACHE", "\n");
indent = print_function_name (file,
instruction->name,
instruction->format_name,
NULL,
- expanded_bits,
- function_name_prefix_icache);
+ expanded_bits, function_name_prefix_icache);
indent += lf_printf (file, " ");
lf_indent (file, +indent);
lf_printf (file, "(");
print_icache_function_formal (file, nr_prefetched_words);
lf_printf (file, ")\n");
lf_indent (file, -indent);
-
+
/* function header */
lf_printf (file, "{\n");
lf_indent (file, +2);
-
+
print_my_defines (file,
instruction->name,
- instruction->format_name,
- expanded_bits);
- print_itrace (file, instruction, 1/*putting-value-in-cache*/);
-
+ instruction->format_name, expanded_bits);
+ print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
+
print_idecode_validate (file, instruction, opcodes);
-
+
lf_printf (file, "\n");
lf_printf (file, "{\n");
lf_indent (file, +2);
: declare_variables),
(options.gen.semantic_icache
? both_values_and_icache
- : put_values_in_icache),
- nr_prefetched_words);
-
+ : put_values_in_icache), nr_prefetched_words);
+
lf_printf (file, "\n");
lf_printf (file, "cache_entry->address = cia;\n");
lf_printf (file, "cache_entry->semantic = ");
print_function_name (file,
instruction->name,
instruction->format_name,
- NULL,
- expanded_bits,
- function_name_prefix_semantics);
+ NULL, expanded_bits, function_name_prefix_semantics);
lf_printf (file, ";\n");
lf_printf (file, "\n");
- if (options.gen.semantic_icache) {
- lf_printf (file, "/* semantic routine */\n");
- print_semantic_body (file,
- instruction,
- expanded_bits,
- opcodes);
- lf_printf (file, "return nia;\n");
- }
-
+ if (options.gen.semantic_icache)
+ {
+ lf_printf (file, "/* semantic routine */\n");
+ print_semantic_body (file, instruction, expanded_bits, opcodes);
+ lf_printf (file, "return nia;\n");
+ }
+
if (!options.gen.semantic_icache)
{
lf_printf (file, "/* return the function proper */\n");
instruction->name,
instruction->format_name,
NULL,
- expanded_bits,
- function_name_prefix_semantics);
+ expanded_bits, function_name_prefix_semantics);
lf_printf (file, ";\n");
}
-
+
if (options.gen.direct_access)
{
print_icache_body (file,
undef_variables,
(options.gen.semantic_icache
? both_values_and_icache
- : put_values_in_icache),
- nr_prefetched_words);
+ : put_values_in_icache), nr_prefetched_words);
}
-
+
lf_indent (file, -2);
lf_printf (file, "}\n");
lf_indent (file, -2);
void
print_icache_definition (lf *file,
- insn_entry *insn,
+ insn_entry * insn,
opcode_bits *expanded_bits,
insn_opcodes *opcodes,
- cache_entry *cache_rules,
- int nr_prefetched_words)
+ cache_entry *cache_rules, int nr_prefetched_words)
{
print_icache_function (file,
insn,
expanded_bits,
- opcodes,
- cache_rules,
- nr_prefetched_words);
+ opcodes, cache_rules, nr_prefetched_words);
}
void
print_icache_internal_function_declaration (lf *file,
- function_entry *function,
+ function_entry * function,
void *data)
{
ASSERT (options.gen.icache);
"INLINE_ICACHE", "\n");
print_function_name (file,
function->name,
- NULL,
- NULL,
- NULL,
- function_name_prefix_icache);
+ NULL, NULL, NULL, function_name_prefix_icache);
lf_printf (file, "\n(");
print_icache_function_formal (file, 0);
lf_printf (file, ");\n");
void
print_icache_internal_function_definition (lf *file,
- function_entry *function,
+ function_entry * function,
void *data)
{
ASSERT (options.gen.icache);
"INLINE_ICACHE", "\n");
print_function_name (file,
function->name,
- NULL,
- NULL,
- NULL,
- function_name_prefix_icache);
+ NULL, NULL, NULL, function_name_prefix_icache);
lf_printf (file, "\n(");
print_icache_function_formal (file, 0);
lf_printf (file, ")\n");
{
lf_print__line_ref (file, function->code->line);
table_print_code (file, function->code);
- lf_printf (file, "error (\"Internal function must longjump\\n\");\n");
+ lf_printf (file,
+ "error (\"Internal function must longjump\\n\");\n");
lf_printf (file, "return 0;\n");
}
else
print_function_name (file,
function->name,
NULL,
- NULL,
- NULL,
- function_name_prefix_semantics);
+ NULL, NULL, function_name_prefix_semantics);
lf_printf (file, ";\n");
}
-
+
lf_print__internal_ref (file);
lf_indent (file, -2);
lf_printf (file, "}\n");