* ld-insn.c (parse_function_record): When -Wnodiscard, suppress

discarded function warning.
        * igen.c (main): Clarify -Wnodiscard.
        * ld-insn.c (parse_function_record): For functions, allow use of
        instruction style function model records
This commit is contained in:
Andrew Cagney 1998-02-23 08:55:41 +00:00
parent bdd5e0232a
commit 3c1e924307
3 changed files with 256 additions and 78 deletions

View File

@ -1,3 +1,48 @@
Fri Feb 20 16:22:10 1998 Andrew Cagney <cagney@b1.cygnus.com>
* ld-insn.c (parse_function_record): When -Wnodiscard, suppress
discarded function warning.
* igen.c (main): Clarify -Wnodiscard.
* ld-insn.c (parse_function_record): For functions, allow use of
instruction style function model records
* ld-insn.h (nr_function_model_fields): Define.
Tue Feb 17 16:36:27 1998 Andrew Cagney <cagney@b1.cygnus.com>
* igen.c (print_itrace_prefix): Generate call to trace_prefix
instead of trace_one_insn.
(print_itrace): Generate trace_prefix call if any tracing enabled,
(print_itrace): Nest generated call to trace_generic inside
conditional for any tracing enabled.
(print_itrace_prefix): Do not pass PHASE to trace_prefix.
Tue Feb 3 14:00:32 1998 Andrew Cagney <cagney@b1.cygnus.com>
* gen-engine.c (print_run_body): Add bitsize suffix to IMEM macro.
* gen-icache.c (print_icache_body): Ditto.
* gen-idecode.c (print_idecode_ifetch): Ditto.
* gen-icache.c (print_icache_body): Mark successive instruction
words as unused.
* ld-insn.c (parse_insn_word): Only report insn-width problems
when warning enabled.
* igen.h: Add flag for warning about invalid instruction widths.
* igen.c: Parse -Wwidth option.
* gen-support.c (gen_support_h): Map instruction_word onto
<PREFIX>_instruction_word when needed.
(print_support_function_name): Use support prefix.
(gen_support_h): Ditto for <PREFIX>_idecode_issue.
Sun Feb 1 11:08:48 1998 Andrew Cagney <cagney@b1.cygnus.com>
* gen-support.c (gen_support_h): Generate new macro CPU_.
Sat Jan 31 14:50:27 1998 Andrew Cagney <cagney@b1.cygnus.com>
* gen-engine.c (gen_engine_h): Don't assume a model is present.

View File

@ -1,6 +1,6 @@
/* This file is part of the program psim.
Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
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
@ -260,8 +260,9 @@ parse_insn_word (line_ref *line,
/* check that the last field goes all the way to the last bit */
if (word->last->last != options.insn_bit_size - 1)
{
options.warning (line, "Instruction format is not %d bits wide\n",
options.insn_bit_size);
if (options.warn.width)
options.warning (line, "Instruction format is not %d bits wide\n",
options.insn_bit_size);
word->last->last = options.insn_bit_size - 1;
}
@ -488,10 +489,16 @@ parse_model_data_record (insn_table *isa,
model_record->field[record_filter_flags_field]);
new_data->entry = model_record;
new_data->code = code_record;
/* append it */
while (*list != NULL)
list = &(*list)->next;
*list = new_data;
/* append it if not filtered out */
if (!is_filtered_out (options.flags_filter,
model_record->field[record_filter_flags_field])
&& !is_filtered_out (options.model_filter,
model_record->field[record_filter_models_field]))
{
while (*list != NULL)
list = &(*list)->next;
*list = new_data;
}
return record;
}
@ -520,6 +527,28 @@ static const name_map option_map[] = {
{ NULL, unknown_option },
};
static table_entry *
parse_include_record (table *file,
table_entry *record)
{
/* parse the include record */
if (record->nr_fields < nr_include_fields)
error (record->line, "Incorrect nr fields for include record\n");
/* process it */
if (!is_filtered_out (options.flags_filter,
record->field[record_filter_flags_field])
&& !is_filtered_out (options.model_filter,
record->field[record_filter_models_field]))
{
table_push (file, record->line, options.include,
record->field[include_filename_field]);
}
/* nb: can't read next record until after the file has been pushed */
record = table_read (file);
return record;
}
static table_entry *
parse_option_record (table *file,
table_entry *record)
@ -532,7 +561,9 @@ parse_option_record (table *file,
record = table_read (file);
/* process it */
if (!is_filtered_out (options.flags_filter,
option_record->field[record_filter_flags_field]))
option_record->field[record_filter_flags_field])
&& !is_filtered_out (options.model_filter,
option_record->field[record_filter_models_field]))
{
char *name = option_record->field[option_name_field];
option_names option = name2i (name, option_map);
@ -598,6 +629,7 @@ parse_option_record (table *file,
return record;
}
static table_entry *
parse_function_record (table *file,
table_entry *record,
@ -606,35 +638,66 @@ parse_function_record (table *file,
int is_internal)
{
function_entry *new_function;
if (record->nr_fields < nr_function_fields)
error (record->line, "Missing fields from function record\n");
/* look for a body to the function */
new_function = ZALLOC (function_entry);
/* parse the function header */
new_function->line = record->line;
filter_parse (&new_function->flags,
record->field[record_filter_flags_field]);
if (record_is_old (record))
new_function->type = record->field[old_function_typedef_field];
else
new_function->type = record->field[function_typedef_field];
new_function->name = record->field[function_name_field];
if (record->nr_fields > function_param_field)
new_function->param = record->field[function_param_field];
new_function->is_internal = is_internal;
/* parse the function body */
/* parse the function header */
if (record_is_old (record))
{
if (record->nr_fields < nr_old_function_fields)
error (record->line, "Missing fields from (old) function record\n");
new_function->type = record->field[old_function_typedef_field];
new_function->type = record->field[old_function_typedef_field];
if (record->nr_fields > old_function_param_field)
new_function->param = record->field[old_function_param_field];
new_function->name = record->field[old_function_name_field];
}
else
{
if (record->nr_fields < nr_function_fields)
error (record->line, "Missing fields from function record\n");
filter_parse (&new_function->flags,
record->field[record_filter_flags_field]);
filter_parse (&new_function->models,
record->field[record_filter_models_field]);
new_function->type = record->field[function_typedef_field];
new_function->param = record->field[function_param_field];
new_function->name = record->field[function_name_field];
}
record = table_read (file);
/* parse any function-model records */
while (record != NULL
&& record_prefix_is (record, '*', nr_function_model_fields))
{
filter_parse (&new_function->models,
record->field[function_model_name_field] + 1 /*skip `*'*/);
record = table_read (file);
}
/* parse the function body */
if (record->type == table_code_entry)
{
new_function->code = record;
record = table_read (file);
}
/* insert it */
while (*list != NULL)
list = &(*list)->next;
*list = new_function;
if (list_entry != NULL)
*list_entry = new_function;
if (!filter_is_subset (options.flags_filter, new_function->flags))
{
if (options.warn.discard)
notify (new_function->line, "Discarding function entry - filter flags\n");
}
else if (!filter_is_subset (options.model_filter, new_function->models))
{
if (options.warn.discard)
notify (new_function->line, "Discarding function entry - filter models\n");
}
else
{
while (*list != NULL)
list = &(*list)->next;
*list = new_function;
if (list_entry != NULL)
*list_entry = new_function;
}
/* done */
return record;
}
@ -649,16 +712,16 @@ parse_insn_model_record (table *file,
insn_model_entry *new_insn_model = ZALLOC (insn_model_entry);
/* parse it */
new_insn_model->line = record->line;
if (record->nr_fields > insn_model_name_field)
new_insn_model->name = record->field[insn_model_name_field];
if (record->nr_fields > insn_model_unit_data_field)
new_insn_model->unit_data = record->field[insn_model_unit_data_field];
new_insn_model->insn = insn;
/* strip "\*[ ]*" from name */
new_insn_model->name = skip_spaces (new_insn_model->name + 1);
if (strlen (new_insn_model->name) == 0)
/* parse the model names, verify that all were defined */
new_insn_model->names = NULL;
filter_parse (&new_insn_model->names,
record->field[insn_model_name_field] + 1 /*skip `*'*/);
if (new_insn_model->names == NULL)
{
/* No processor name - a generic model entry, enter it into all
/* No processor names - a generic model entry, enter it into all
the non-empty fields */
int index;
for (index = 0; index < model->nr_models; index++)
@ -671,20 +734,33 @@ parse_insn_model_record (table *file,
}
else
{
/* Find the corresponding master model record so it can be
linked in correctly */
/* Find the corresponding master model record for each name so
that they can be linked in. */
int index;
index = filter_is_member (model->processors, new_insn_model->name) - 1;
if (index < 0)
char *name = "";
while (1)
{
error (record->line, "machine model `%s' undefined\n",
new_insn_model->name);
name = filter_next (new_insn_model->names, name);
if (name == NULL) break;
index = filter_is_member (model->processors, name) - 1;
if (index < 0)
{
error (new_insn_model->line,
"machine model `%s' undefined\n", name);
}
/* store it in the corresponding model array entry */
if (insn->model[index] != NULL
&& insn->model[index]->names != NULL)
{
warning (new_insn_model->line,
"machine model `%s' previously defined\n", name);
error (insn->model[index]->line, "earlier definition\n");
}
insn->model[index] = new_insn_model;
/* also add the name to the instructions processor set as an
alternative lookup mechanism */
filter_parse (&insn->processors, name);
}
/* store it in the corresponding model array entry */
insn->model[index] = new_insn_model;
/* also add the name to the instructions processor set as an
alternative lookup mechanism */
filter_parse (&insn->processors, new_insn_model->name);
}
#if 0
/* for some reason record the max length of any
@ -748,12 +824,7 @@ load_insn_table (char *file_name,
case include_record:
{
if (record->nr_fields < nr_include_record_fields)
error (record->line,
"Incorrect nr of fields for include record\n");
table_push (file, record->line, options.include,
record->field[include_record_filename_field]);
record = table_read (file);
record = parse_include_record (file, record);
break;
}
@ -767,20 +838,23 @@ load_insn_table (char *file_name,
case string_function_record:
{
/* convert a string function field into an internal function field */
char *name;
if (record->nr_fields < nr_function_fields)
error (record->line, "Incorrect nr of fields for %%s record\n");
name = NZALLOC (char,
(strlen ("str_")
+ strlen (record->field[function_name_field])
+ 1));
strcat (name, "str_");
strcat (name, record->field[function_name_field]);
record->field[record_type_field] = "function";
record->field[function_typedef_field] = "const char *";
record->field[function_name_field] = name;
/* HACK - comes round back as a function/internal record */
function_entry *function = NULL;
record = parse_function_record (file, record,
&isa->functions,
&function,
0/*is-internal*/);
/* convert a string function record into an internal function */
if (function != NULL)
{
char *name = NZALLOC (char,
(strlen ("str_")
+ strlen (function->name)
+ 1));
strcat (name, "str_");
strcat (name, function->name);
function->name = name;
function->type = "const char *";
}
break;
}
@ -844,7 +918,9 @@ load_insn_table (char *file_name,
new_cache->line = record->line;
filter_parse (&new_cache->flags,
record->field[record_filter_flags_field]);
new_cache->type = record->field[cache_type_field];
filter_parse (&new_cache->models,
record->field[record_filter_models_field]);
new_cache->type = record->field[cache_typedef_field];
new_cache->name = record->field[cache_name_field];
filter_parse (&new_cache->original_fields,
record->field[cache_original_fields_field]);
@ -852,7 +928,13 @@ load_insn_table (char *file_name,
/* insert it but only if not filtered out */
if (!filter_is_subset (options.flags_filter, new_cache->flags))
{
notify (new_cache->line, "Discarding cache entry %s\n",
notify (new_cache->line, "Discarding cache entry %s - filter flags\n",
new_cache->name);
}
else if (is_filtered_out (options.model_filter,
record->field[record_filter_models_field]))
{
notify (new_cache->line, "Discarding cache entry %s - filter models\n",
new_cache->name);
}
else
@ -887,7 +969,13 @@ load_insn_table (char *file_name,
/* only insert it if not filtered out */
if (!filter_is_subset (options.flags_filter, new_model->flags))
{
notify (new_model->line, "Discarding processor model %s\n",
notify (new_model->line, "Discarding processor model %s - filter flags\n",
new_model->name);
}
else if (is_filtered_out (options.model_filter,
record->field[record_filter_models_field]))
{
notify (new_model->line, "Discarding processor model %s - filter models\n",
new_model->name);
}
else if (filter_is_member (model->processors, new_model->name))
@ -1409,7 +1497,7 @@ dump_insn_model_entry (lf *file,
{
lf_indent (file, +1);
dump_line_ref (file, "\n(line ", model->line, ")");
lf_printf (file, "\n(name \"%s\")", model->name);
dump_filter (file, "\n(names ", model->names, ")");
lf_printf (file, "\n(full_name \"%s\")", model->full_name);
lf_printf (file, "\n(unit_data \"%s\")", model->unit_data);
lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn);

View File

@ -1,6 +1,6 @@
/* This file is part of the program psim.
Copyright (C) 1994,1995,1996,1997 Andrew Cagney <cagney@highland.com.au>
Copyright (C) 1994-1998 Andrew Cagney <cagney@highland.com.au>
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
@ -123,6 +123,9 @@ enum {
/* Functions and internal routins:
NB: <filter-models> and <function-models> are the equivalent.
<function> ::=
":" "function"
<function-spec>
@ -138,6 +141,12 @@ enum {
<function-spec>
;
<function-model> ::=
"*" [ <processor-list> ]
":"
<nl>
;
<function-spec> ::=
":" <filter-flags>
":" <filter-models>
@ -145,6 +154,7 @@ enum {
":" <name>
[ ":" <parameter-list> ]
<nl>
[ <function-model> ]
<code-block>
;
@ -157,6 +167,11 @@ enum {
nr_function_fields,
};
enum {
function_model_name_field = 0,
nr_function_model_fields = 1,
};
enum {
old_function_typedef_field = 0,
old_function_type_field = 2,
@ -262,7 +277,7 @@ struct _cache_entry {
":" <filter-flags>
":" <filter-models>
":" <processor>
":" <long-processor>
":" <BFD-processor>
":" <function-unit-data>
<nl>
;
@ -368,8 +383,8 @@ struct _model_table {
;
<field> ::=
"*" +
| "/" +
{ "*" }+
| { "/" }+
| <field-name>
| "0x" <hex-value>
| "0b" <binary-value>
@ -436,16 +451,21 @@ struct _insn_word_entry {
/* Instruction model:
Provides scheduling data for the code modeling the instruction unit.
Provides scheduling and other data for the code modeling the
instruction unit.
<insn-model> ::=
"*" [ <processor> ]
":" <function-unit-data>
"*" [ <processor-list> ]
":" [ <function-unit-data> ]
<nl>
;
If <processor> is NULL, the model is made the default for this
instruction.
<processor-list> ::=
<processor> { "," <processor>" }
;
If the <processor-list> is empty, the model is made the default for
this instruction.
*/
@ -459,7 +479,7 @@ typedef struct _insn_model_entry insn_model_entry;
struct _insn_model_entry {
line_ref *line;
insn_entry *insn;
char *name;
filter *names;
char *full_name;
char *unit_data;
insn_model_entry *next;
@ -477,6 +497,31 @@ struct _insn_model_entry {
<nl>
;
An assembler mnemonic string has the syntax:
<assembler-mnemonic> ::=
( [ "%" <format-spec> ] "<" <func> [ "#" <param-list> ] ">"
| "%%"
| <other-letter>
)+
Where, for instance, the text is translated into a printf format
and argument pair:
"<FUNC>" : "%ld", (long) FUNC
"%<FUNC>..." : "%...", FUNC
"%s<FUNC>" : "%s", <%s>FUNC (SD_, FUNC)
"%s<FUNC#P1,P2>" : "%s", <%s>FUNC (SD_, P1,P2)
"%lx<FUNC>" : "%lx", (unsigned long) FUNC
"%08lx<FUNC>" : "%08lx", (unsigned long) FUNC
And "<%s>FUNC" denotes a function declared using the "%s" record
specifier.
;
*/
enum {