/* The IGEN simulator generator for GDB, the GNU Debugger.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002-2013 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"
#include "ld-insn.h"
static insn_word_entry *
-parse_insn_word (line_ref *line,
- char *string,
- int word_nr)
+parse_insn_word (line_ref *line, char *string, int word_nr)
{
char *chp;
insn_word_entry *word = ZALLOC (insn_word_entry);
/* now work through the formats */
chp = skip_spaces (string);
- while (*chp != '\0') {
- char *start_pos;
- int strlen_pos;
- char *start_val;
- int strlen_val;
- insn_field_entry *new_field;
-
- /* create / link in the new field */
- new_field = ZALLOC (insn_field_entry);
- new_field->next = word->last;
- new_field->prev = word->last->prev;
- new_field->next->prev = new_field;
- new_field->prev->next = new_field;
- new_field->word_nr = word_nr;
-
- /* break out the first field (if present) */
- start_pos = chp;
- chp = skip_to_separator (chp, ".,!");
- strlen_pos = back_spaces (start_pos, chp) - start_pos;
-
- /* break out the second field (if present) */
- if (*chp != '.')
- {
- /* assume what was specified was the value (and not the start
- position). Assume the value length implicitly specifies
- the number of bits */
- start_val = start_pos;
- strlen_val = strlen_pos;
- start_pos = "";
- strlen_pos = 0;
- }
- else
- {
- chp++; /* skip `.' */
- chp = skip_spaces (chp);
- start_val = chp;
- if (*chp == '/' || *chp == '*')
- {
- do
- {
- chp++;
- }
- while (*chp == '/' || *chp == '*');
- }
- else if (isalpha(*start_val))
- {
- do
- {
- chp++;
- }
- while (isalnum(*chp) || *chp == '_');
- }
- else if (isdigit(*start_val))
- {
- do {
- chp++;
+ while (*chp != '\0')
+ {
+ char *start_pos;
+ int strlen_pos;
+ char *start_val;
+ int strlen_val;
+ insn_field_entry *new_field;
+
+ /* create / link in the new field */
+ new_field = ZALLOC (insn_field_entry);
+ new_field->next = word->last;
+ new_field->prev = word->last->prev;
+ new_field->next->prev = new_field;
+ new_field->prev->next = new_field;
+ new_field->word_nr = word_nr;
+
+ /* break out the first field (if present) */
+ start_pos = chp;
+ chp = skip_to_separator (chp, ".,!");
+ strlen_pos = back_spaces (start_pos, chp) - start_pos;
+
+ /* break out the second field (if present) */
+ if (*chp != '.')
+ {
+ /* assume what was specified was the value (and not the start
+ position). Assume the value length implicitly specifies
+ the number of bits */
+ start_val = start_pos;
+ strlen_val = strlen_pos;
+ start_pos = "";
+ strlen_pos = 0;
+ }
+ else
+ {
+ chp++; /* skip `.' */
+ chp = skip_spaces (chp);
+ start_val = chp;
+ if (*chp == '/' || *chp == '*')
+ {
+ do
+ {
+ chp++;
+ }
+ while (*chp == '/' || *chp == '*');
}
- while (isalnum(*chp));
- }
- strlen_val = chp - start_val;
- chp = skip_spaces (chp);
- }
- if (strlen_val == 0)
- error (line, "Empty value field\n");
-
- /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
- while (*chp == '!' || *chp == '=')
- {
- char *start;
- char *end;
- int len;
- insn_field_cond *new_cond = ZALLOC (insn_field_cond);
-
- /* determine the conditional test */
- switch (*chp)
- {
- case '=':
- new_cond->test = insn_field_cond_eq;
- break;
- case '!':
- new_cond->test = insn_field_cond_ne;
- break;
- default:
- ASSERT (0);
- }
-
- /* save the value */
- chp++;
- chp = skip_spaces (chp);
- start = chp;
- chp = skip_to_separator (chp, "+,:!=");
- end = back_spaces (start, chp);
- len = end - start;
- if (len == 0)
- error (line, "Missing or invalid conditional value\n");
- new_cond->string = NZALLOC (char, len + 1);
- strncpy (new_cond->string, start, len);
-
- /* determine the conditional type */
- if (isdigit (*start))
- {
- /* [ "!" | "=" ] <value> */
- new_cond->type = insn_field_cond_value;
- new_cond->value = a2i (new_cond->string);
- }
- else
+ else if (isalpha (*start_val))
+ {
+ do
+ {
+ chp++;
+ }
+ while (isalnum (*chp) || *chp == '_');
+ }
+ else if (isdigit (*start_val))
+ {
+ do
+ {
+ chp++;
+ }
+ while (isalnum (*chp));
+ }
+ strlen_val = chp - start_val;
+ chp = skip_spaces (chp);
+ }
+ if (strlen_val == 0)
+ error (line, "Empty value field\n");
+
+ /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
+ while (*chp == '!' || *chp == '=')
+ {
+ char *start;
+ char *end;
+ int len;
+ insn_field_cond *new_cond = ZALLOC (insn_field_cond);
+
+ /* determine the conditional test */
+ switch (*chp)
+ {
+ case '=':
+ new_cond->test = insn_field_cond_eq;
+ break;
+ case '!':
+ new_cond->test = insn_field_cond_ne;
+ break;
+ default:
+ ASSERT (0);
+ }
+
+ /* save the value */
+ chp++;
+ chp = skip_spaces (chp);
+ start = chp;
+ chp = skip_to_separator (chp, "+,:!=");
+ end = back_spaces (start, chp);
+ len = end - start;
+ if (len == 0)
+ error (line, "Missing or invalid conditional value\n");
+ new_cond->string = NZALLOC (char, len + 1);
+ strncpy (new_cond->string, start, len);
+
+ /* determine the conditional type */
+ if (isdigit (*start))
+ {
+ /* [ "!" | "=" ] <value> */
+ new_cond->type = insn_field_cond_value;
+ new_cond->value = a2i (new_cond->string);
+ }
+ else
+ {
+ /* [ "!" | "=" ] <field> - check field valid */
+ new_cond->type = insn_field_cond_field;
+ /* new_cond->field is determined in later */
+ }
+
+ /* Only a single `=' is permitted. */
+ if ((new_cond->test == insn_field_cond_eq
+ && new_field->conditions != NULL)
+ || (new_field->conditions != NULL
+ && new_field->conditions->test == insn_field_cond_eq))
+ error (line, "Only single conditional when `=' allowed\n");
+
+ /* insert it */
{
- /* [ "!" | "=" ] <field> - check field valid */
- new_cond->type = insn_field_cond_field;
- /* new_cond->field is determined in later */
+ insn_field_cond **last = &new_field->conditions;
+ while (*last != NULL)
+ last = &(*last)->next;
+ *last = new_cond;
}
-
- /* Only a single `=' is permitted. */
- if ((new_cond->test == insn_field_cond_eq
- && new_field->conditions != NULL)
- || (new_field->conditions != NULL
- && new_field->conditions->test == insn_field_cond_eq))
- error (line, "Only single conditional when `=' allowed\n");
-
- /* insert it */
+ }
+
+ /* NOW verify that the field was finished */
+ if (*chp == ',')
{
- insn_field_cond **last = &new_field->conditions;
- while (*last != NULL)
- last = &(*last)->next;
- *last = new_cond;
+ chp = skip_spaces (chp + 1);
+ if (*chp == '\0')
+ error (line, "empty field\n");
+ }
+ else if (*chp != '\0')
+ {
+ error (line, "Missing field separator\n");
}
- }
- /* NOW verify that the field was finished */
- if (*chp == ',')
- {
- chp = skip_spaces (chp + 1);
- if (*chp == '\0')
- error (line, "empty field\n");
- }
- else if (*chp != '\0')
- {
- error (line, "Missing field separator\n");
- }
+ /* copy the value */
+ new_field->val_string = NZALLOC (char, strlen_val + 1);
+ strncpy (new_field->val_string, start_val, strlen_val);
+ if (isdigit (new_field->val_string[0]))
+ {
+ if (strlen_pos == 0)
+ {
+ /* when the length/pos field is omited, an integer field
+ is always binary */
+ unsigned64 val = 0;
+ int i;
+ for (i = 0; i < strlen_val; i++)
+ {
+ if (new_field->val_string[i] != '0'
+ && new_field->val_string[i] != '1')
+ error (line, "invalid binary field %s\n",
+ new_field->val_string);
+ val = (val << 1) + (new_field->val_string[i] == '1');
+ }
+ new_field->val_int = val;
+ new_field->type = insn_field_int;
+ }
+ else
+ {
+ new_field->val_int = a2i (new_field->val_string);
+ new_field->type = insn_field_int;
+ }
+ }
+ else if (new_field->val_string[0] == '/')
+ {
+ new_field->type = insn_field_reserved;
+ }
+ else if (new_field->val_string[0] == '*')
+ {
+ new_field->type = insn_field_wild;
+ }
+ else
+ {
+ new_field->type = insn_field_string;
+ if (filter_is_member (word->field_names, new_field->val_string))
+ error (line, "Field name %s is duplicated\n",
+ new_field->val_string);
+ filter_parse (&word->field_names, new_field->val_string);
+ }
+ if (new_field->type != insn_field_string
+ && new_field->conditions != NULL)
+ error (line, "Conditionals can only be applied to named fields\n");
- /* copy the value */
- new_field->val_string = NZALLOC (char, strlen_val+1);
- strncpy (new_field->val_string, start_val, strlen_val);
- if (isdigit (new_field->val_string[0]))
- {
- if (strlen_pos == 0)
- {
- /* when the length/pos field is omited, an integer field
- is always binary */
- unsigned64 val = 0;
- int i;
- for (i = 0; i < strlen_val; i++)
- {
- if (new_field->val_string[i] != '0'
- && new_field->val_string[i] != '1')
- error (line, "invalid binary field %s\n",
- new_field->val_string);
- val = (val << 1) + (new_field->val_string[i] == '1');
- }
- new_field->val_int = val;
- new_field->type = insn_field_int;
- }
- else
- {
- new_field->val_int = a2i (new_field->val_string);
- new_field->type = insn_field_int;
- }
- }
- else if (new_field->val_string[0] == '/')
- {
- new_field->type = insn_field_reserved;
- }
- else if (new_field->val_string[0] == '*')
- {
- new_field->type = insn_field_wild;
- }
- else
- {
- new_field->type = insn_field_string;
- if (filter_is_member (word->field_names, new_field->val_string))
- error (line, "Field name %s is duplicated\n", new_field->val_string);
- filter_parse (&word->field_names, new_field->val_string);
- }
- if (new_field->type != insn_field_string
- && new_field->conditions != NULL)
- error (line, "Conditionals can only be applied to named fields\n");
-
- /* the copy the position */
- new_field->pos_string = NZALLOC (char, strlen_pos + 1);
- strncpy (new_field->pos_string, start_pos, strlen_pos);
- if (strlen_pos == 0)
- {
- new_field->first = new_field->prev->last + 1;
- if (new_field->first == 0 /* first field */
- && *chp == '\0' /* no further fields */
- && new_field->type == insn_field_string)
- {
- /* A single string without any position, assume that it
- represents the entire instruction word */
- new_field->width = options.insn_bit_size;
- }
- else
- {
- /* No explicit width/position, assume value implicitly
- supplies the width */
- new_field->width = strlen_val;
- }
- new_field->last = new_field->first + new_field->width - 1;
- if (new_field->last >= options.insn_bit_size)
- error (line, "Bit position %d exceed instruction bit size (%d)\n",
- new_field->last, options.insn_bit_size);
- }
- else if (options.insn_specifying_widths)
- {
- new_field->first = new_field->prev->last + 1;
- new_field->width = a2i(new_field->pos_string);
- new_field->last = new_field->first + new_field->width - 1;
- if (new_field->last >= options.insn_bit_size)
- error (line, "Bit position %d exceed instruction bit size (%d)\n",
- new_field->last, options.insn_bit_size);
- }
- else
- {
- new_field->first = target_a2i(options.hi_bit_nr,
- new_field->pos_string);
- new_field->last = new_field->next->first - 1; /* guess */
- new_field->width = new_field->last - new_field->first + 1; /* guess */
- new_field->prev->last = new_field->first - 1; /*fix*/
- new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
- }
- }
+ /* the copy the position */
+ new_field->pos_string = NZALLOC (char, strlen_pos + 1);
+ strncpy (new_field->pos_string, start_pos, strlen_pos);
+ if (strlen_pos == 0)
+ {
+ new_field->first = new_field->prev->last + 1;
+ if (new_field->first == 0 /* first field */
+ && *chp == '\0' /* no further fields */
+ && new_field->type == insn_field_string)
+ {
+ /* A single string without any position, assume that it
+ represents the entire instruction word */
+ new_field->width = options.insn_bit_size;
+ }
+ else
+ {
+ /* No explicit width/position, assume value implicitly
+ supplies the width */
+ new_field->width = strlen_val;
+ }
+ new_field->last = new_field->first + new_field->width - 1;
+ if (new_field->last >= options.insn_bit_size)
+ error (line, "Bit position %d exceed instruction bit size (%d)\n",
+ new_field->last, options.insn_bit_size);
+ }
+ else if (options.insn_specifying_widths)
+ {
+ new_field->first = new_field->prev->last + 1;
+ new_field->width = a2i (new_field->pos_string);
+ new_field->last = new_field->first + new_field->width - 1;
+ if (new_field->last >= options.insn_bit_size)
+ error (line, "Bit position %d exceed instruction bit size (%d)\n",
+ new_field->last, options.insn_bit_size);
+ }
+ else
+ {
+ new_field->first = target_a2i (options.hi_bit_nr,
+ new_field->pos_string);
+ new_field->last = new_field->next->first - 1; /* guess */
+ new_field->width = new_field->last - new_field->first + 1; /* guess */
+ new_field->prev->last = new_field->first - 1; /*fix */
+ new_field->prev->width = new_field->first - new_field->prev->first; /*fix */
+ }
+ }
/* fiddle first/last so that the sentinals disapear */
- ASSERT(word->first->last < 0);
- ASSERT(word->last->first >= options.insn_bit_size);
+ ASSERT (word->first->last < 0);
+ ASSERT (word->last->first >= options.insn_bit_size);
word->first = word->first->next;
word->last = word->last->prev;
{
insn_field_entry *field;
for (field = word->first;
- field->last < options.insn_bit_size;
- field = field->next)
+ field->last < options.insn_bit_size; field = field->next)
{
int i;
for (i = field->first; i <= field->last; i++)
case insn_field_int:
word->bit[i]->mask = 1;
word->bit[i]->value = ((field->val_int
- & ((insn_uint)1 << (field->last - i)))
- != 0);
+ & ((insn_uint) 1 <<
+ (field->last - i))) != 0);
case insn_field_reserved:
case insn_field_wild:
case insn_field_string:
/* if we encounter a constant conditional, encode
- their bit value. */
+ their bit value. */
if (field->conditions != NULL
&& field->conditions->test == insn_field_cond_eq
&& field->conditions->type == insn_field_cond_value)
{
word->bit[i]->mask = 1;
word->bit[i]->value = ((field->conditions->value
- & ((insn_uint)1 << (field->last - i)))
- != 0);
+ & ((insn_uint) 1 <<
+ (field->last - i))) != 0);
}
break;
}
static void
-parse_insn_words (insn_entry *insn,
- char *formats)
+parse_insn_words (insn_entry * insn, char *formats)
{
insn_word_entry **last_word = &insn->words;
char *chp;
insn_word_entry *word;
insn->word = NZALLOC (insn_word_entry *, insn->nr_words + 1);
for (i = 0, word = insn->words;
- i < insn->nr_words;
- i++, word = word->next)
+ i < insn->nr_words; i++, word = word->next)
insn->word[i] = word;
}
{
insn_word_entry *word = insn->word[i];
insn_field_entry *f;
- for (f = word->first;
- f->last < options.insn_bit_size;
- f = f->next)
+ for (f = word->first; f->last < options.insn_bit_size; f = f->next)
{
insn_field_cond *cond;
- for (cond = f->conditions;
- cond != NULL;
- cond = cond->next)
+ for (cond = f->conditions; cond != NULL; cond = cond->next)
{
if (cond->type == insn_field_cond_field)
{
refered_field = refered_field->next)
{
if (refered_field->type == insn_field_string
- && strcmp (refered_field->val_string, cond->string) == 0)
+ && strcmp (refered_field->val_string,
+ cond->string) == 0)
{
/* found field being refered to by conditonal */
cond->field = refered_field;
if (f->width != refered_field->width)
error (insn->line,
"Conditional `%s' of field `%s' should be of size %s\n",
- cond->string, f->val_string, refered_field->width);
+ cond->string, f->val_string,
+ refered_field->width);
}
}
}
}
}
}
-
+
}
-typedef enum {
+typedef enum
+{
unknown_record = 0,
- insn_record, /* default */
+ insn_record, /* default */
code_record,
cache_record,
compute_record,
model_static_record,
model_function_record,
model_internal_record,
-} insn_record_type;
+}
+insn_record_type;
static const name_map insn_type_map[] = {
- { "option", option_record },
- { "cache", cache_record },
- { "compute", compute_record },
- { "scratch", scratch_record },
- { "define", define_record },
- { "include", include_record },
- { "%s", string_function_record },
- { "function", function_record },
- { "internal", internal_record },
- { "model", model_processor_record },
- { "model-macro", model_macro_record },
- { "model-data", model_data_record },
- { "model-static", model_static_record },
- { "model-internal", model_internal_record },
- { "model-function", model_function_record },
- { NULL, insn_record },
+ {"option", option_record},
+ {"cache", cache_record},
+ {"compute", compute_record},
+ {"scratch", scratch_record},
+ {"define", define_record},
+ {"include", include_record},
+ {"%s", string_function_record},
+ {"function", function_record},
+ {"internal", internal_record},
+ {"model", model_processor_record},
+ {"model-macro", model_macro_record},
+ {"model-data", model_data_record},
+ {"model-static", model_static_record},
+ {"model-internal", model_internal_record},
+ {"model-function", model_function_record},
+ {NULL, insn_record},
};
return i;
}
else
- return insn_record; /* default */
+ return insn_record; /* default */
}
return unknown_record;
}
static int
-record_prefix_is (table_entry *entry,
- char ch,
- int nr_fields)
+record_prefix_is (table_entry *entry, char ch, int nr_fields)
{
if (entry->type != table_colon_entry)
return 0;
parse_model_data_record (insn_table *isa,
table *file,
table_entry *record,
- int nr_fields,
- model_data **list)
+ int nr_fields, model_data **list)
{
table_entry *model_record = record;
table_entry *code_record = NULL;
}
-typedef enum {
+typedef enum
+{
insn_bit_size_option = 1,
insn_specifying_widths_option,
hi_bit_nr_option,
format_names_option,
gen_delayed_branch,
unknown_option,
-} option_names;
+}
+option_names;
static const name_map option_map[] = {
- { "insn-bit-size", insn_bit_size_option },
- { "insn-specifying-widths", insn_specifying_widths_option },
- { "hi-bit-nr", hi_bit_nr_option },
- { "flags-filter", flags_filter_option },
- { "model-filter", model_filter_option },
- { "multi-sim", multi_sim_option },
- { "format-names", format_names_option },
- { "gen-delayed-branch", gen_delayed_branch },
- { NULL, unknown_option },
+ {"insn-bit-size", insn_bit_size_option},
+ {"insn-specifying-widths", insn_specifying_widths_option},
+ {"hi-bit-nr", hi_bit_nr_option},
+ {"flags-filter", flags_filter_option},
+ {"model-filter", model_filter_option},
+ {"multi-sim", multi_sim_option},
+ {"format-names", format_names_option},
+ {"gen-delayed-branch", gen_delayed_branch},
+ {NULL, unknown_option},
};
static table_entry *
-parse_include_record (table *file,
- table_entry *record)
+parse_include_record (table *file, table_entry *record)
{
/* parse the include record */
if (record->nr_fields < nr_include_fields)
{
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)
+parse_option_record (table *file, table_entry *record)
{
table_entry *option_record;
/* parse the option record */
options.insn_bit_size = a2i (value);
if (options.insn_bit_size < 0
|| options.insn_bit_size > max_insn_bit_size)
- error (option_record->line, "Instruction bit size out of range\n");
+ error (option_record->line,
+ "Instruction bit size out of range\n");
if (options.hi_bit_nr != options.insn_bit_size - 1
&& options.hi_bit_nr != 0)
- error (option_record->line, "insn-bit-size / hi-bit-nr conflict\n");
+ error (option_record->line,
+ "insn-bit-size / hi-bit-nr conflict\n");
break;
}
case insn_specifying_widths_option:
options.hi_bit_nr = a2i (value);
if (options.hi_bit_nr != 0
&& options.hi_bit_nr != options.insn_bit_size - 1)
- error (option_record->line, "hi-bit-nr / insn-bit-size conflict\n");
+ error (option_record->line,
+ "hi-bit-nr / insn-bit-size conflict\n");
break;
}
case flags_filter_option:
break;
}
}
- }
+ }
return record;
}
static table_entry *
parse_function_record (table *file,
table_entry *record,
- function_entry **list,
- function_entry **list_entry,
- int is_internal,
- model_table *model)
+ function_entry ** list,
+ function_entry ** list_entry,
+ int is_internal, model_table *model)
{
function_entry *new_function;
new_function = ZALLOC (function_entry);
while (record != NULL
&& record_prefix_is (record, '*', nr_function_model_fields))
{
- char *model_name = record->field[function_model_name_field] + 1; /*skip `*'*/
+ char *model_name = record->field[function_model_name_field] + 1; /*skip `*' */
filter_parse (&new_function->models, model_name);
if (!filter_is_subset (model->processors, new_function->models))
{
&& !filter_is_common (options.model_filter, new_function->models))
{
if (options.warn.discard)
- notify (new_function->line, "Discarding function %s - filter models\n",
+ notify (new_function->line,
+ "Discarding function %s - filter models\n",
new_function->name);
}
else
static void
parse_insn_model_record (table *file,
table_entry *record,
- insn_entry *insn,
- model_table *model)
+ insn_entry * insn, model_table *model)
{
insn_model_entry **last_insn_model;
insn_model_entry *new_insn_model = ZALLOC (insn_model_entry);
/* 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 `*'*/);
+ record->field[insn_model_name_field] + 1 /*skip `*' */ );
if (new_insn_model->names == NULL)
{
/* No processor names - a generic model entry, enter it into all
- the non-empty fields */
+ the non-empty fields */
int index;
for (index = 0; index < model->nr_models; index++)
if (insn->model[index] == 0)
while (1)
{
name = filter_next (new_insn_model->names, name);
- if (name == NULL) break;
+ if (name == NULL)
+ break;
index = filter_is_member (model->processors, name) - 1;
if (index < 0)
{
"machine model `%s' undefined\n", name);
}
/* store it in the corresponding model array entry */
- if (insn->model[index] != NULL
- && insn->model[index]->names != NULL)
+ if (insn->model[index] != NULL && insn->model[index]->names != NULL)
{
warning (new_insn_model->line,
"machine model `%s' previously defined\n", name);
filter_parse (&insn->processors, name);
}
}
-#if 0
- /* for some reason record the max length of any
- function unit field */
- int len = strlen (insn_model_ptr->field[insn_model_fields]);
- if (model->max_model_fields_len < len)
- model->max_model_fields_len = len;
-#endif
/* link it in */
last_insn_model = &insn->models;
while ((*last_insn_model) != NULL)
static void
parse_insn_mnemonic_record (table *file,
- table_entry *record,
- insn_entry *insn)
+ table_entry *record, insn_entry * insn)
{
insn_mnemonic_entry **last_insn_mnemonic;
insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry);
ASSERT (record->nr_fields > insn_mnemonic_format_field);
new_insn_mnemonic->format = record->field[insn_mnemonic_format_field];
ASSERT (new_insn_mnemonic->format[0] == '"');
- if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != '"')
- error (new_insn_mnemonic->line, "Missing closing double quote in mnemonic field\n");
+ if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] !=
+ '"')
+ error (new_insn_mnemonic->line,
+ "Missing closing double quote in mnemonic field\n");
if (record->nr_fields > insn_mnemonic_condition_field)
- new_insn_mnemonic->condition = record->field[insn_mnemonic_condition_field];
+ new_insn_mnemonic->condition =
+ record->field[insn_mnemonic_condition_field];
new_insn_mnemonic->insn = insn;
/* insert it */
last_insn_mnemonic = &insn->mnemonics;
static table_entry *
-parse_macro_record (table *file,
- table_entry *record)
+parse_macro_record (table *file, table_entry *record)
{
#if 1
error (record->line, "Macros are not implemented");
record->field[macro_name_field],
record->field[macro_args_field],
record->field[macro_expr_field]);
- }
+ }
record = table_read (file);
#endif
return record;
insn_table *
-load_insn_table (char *file_name,
- cache_entry *cache)
+load_insn_table (char *file_name, cache_entry *cache)
{
table *file = table_open (file_name);
table_entry *record = table_read (file);
insn_table *isa = ZALLOC (insn_table);
model_table *model = ZALLOC (model_table);
-
+
isa->model = model;
isa->caches = cache;
record = parse_option_record (file, record);
break;
}
-
+
case string_function_record:
{
function_entry *function = NULL;
record = parse_function_record (file, record,
&isa->functions,
- &function,
- 0/*is-internal*/,
+ &function, 0 /*is-internal */ ,
model);
/* convert a string function record into an internal function */
if (function != NULL)
{
char *name = NZALLOC (char,
(strlen ("str_")
- + strlen (function->name)
- + 1));
+ + strlen (function->name) + 1));
strcat (name, "str_");
strcat (name, function->name);
function->name = name;
}
break;
}
-
- case function_record: /* function record */
+
+ case function_record: /* function record */
{
record = parse_function_record (file, record,
&isa->functions,
- NULL,
- 0/*is-internal*/,
+ NULL, 0 /*is-internal */ ,
model);
break;
}
function_entry *function = NULL;
record = parse_function_record (file, record,
&isa->functions,
- &function,
- 1/*is-internal*/,
+ &function, 1 /*is-internal */ ,
model);
/* check what was inserted to see if a pseudo-instruction
- entry also needs to be created */
+ entry also needs to be created */
if (function != NULL)
{
insn_entry **insn = NULL;
}
break;
}
-
- case scratch_record: /* cache macro records */
+
+ case scratch_record: /* cache macro records */
case cache_record:
case compute_record:
{
/* 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 - filter flags\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]))
+ record->
+ field[record_filter_models_field]))
{
- notify (new_cache->line, "Discarding cache entry %s - filter models\n",
+ notify (new_cache->line,
+ "Discarding cache entry %s - filter models\n",
new_cache->name);
}
else
record = table_read (file);
break;
}
-
- /* model records */
+
+ /* model records */
case model_processor_record:
{
model_entry *new_model;
/* parse the model */
if (record->nr_fields < nr_model_processor_fields)
- error (record->line, "Incorrect nr of fields for model record\n");
+ error (record->line,
+ "Incorrect nr of fields for model record\n");
if (isa->insns != NULL)
error (record->line, "Model appears after first instruction\n");
new_model = ZALLOC (model_entry);
/* 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 - filter flags\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]))
+ record->
+ field[record_filter_models_field]))
{
- notify (new_model->line, "Discarding processor model %s - filter models\n",
+ notify (new_model->line,
+ "Discarding processor model %s - filter models\n",
new_model->name);
}
else if (filter_is_member (model->processors, new_model->name))
last = &(*last)->next;
*last = new_model;
/* count it */
- model->nr_models ++;
+ model->nr_models++;
filter_parse (&model->processors, new_model->name);
}
/* advance things */
record = table_read (file);
}
break;
-
+
case model_macro_record:
record = parse_model_data_record (isa, file, record,
nr_model_macro_fields,
&model->macros);
break;
-
+
case model_data_record:
record = parse_model_data_record (isa, file, record,
nr_model_data_fields,
&model->data);
break;
-
+
case model_static_record:
record = parse_function_record (file, record,
&model->statics,
- NULL,
- 0/*is internal*/,
+ NULL, 0 /*is internal */ ,
model);
break;
-
+
case model_internal_record:
record = parse_function_record (file, record,
&model->internals,
- NULL,
- 1/*is internal*/,
+ NULL, 1 /*is internal */ ,
model);
break;
-
+
case model_function_record:
record = parse_function_record (file, record,
&model->functions,
- NULL,
- 0/*is internal*/,
+ NULL, 0 /*is internal */ ,
model);
break;
-
- case insn_record: /* instruction records */
+
+ case insn_record: /* instruction records */
{
insn_entry *new_insn;
char *format;
/* parse the instruction */
if (record->nr_fields < nr_insn_fields)
- error (record->line, "Incorrect nr of fields for insn record\n");
+ error (record->line,
+ "Incorrect nr of fields for insn record\n");
new_insn = ZALLOC (insn_entry);
new_insn->line = record->line;
filter_parse (&new_insn->flags,
record->field[record_filter_flags_field]);
/* save the format field. Can't parse it until after the
- filter-out checks. Could be filtered out because the
- format is invalid */
+ filter-out checks. Could be filtered out because the
+ format is invalid */
format = record->field[insn_word_field];
new_insn->format_name = record->field[insn_format_name_field];
if (options.format_name_filter != NULL
&& !filter_is_member (options.format_name_filter,
new_insn->format_name))
- error (new_insn->line, "Unreconized instruction format name `%s'\n",
+ error (new_insn->line,
+ "Unreconized instruction format name `%s'\n",
new_insn->format_name);
filter_parse (&new_insn->options,
record->field[insn_options_field]);
record = table_read (file);
/* Parse any model/assember records */
new_insn->nr_models = model->nr_models;
- new_insn->model = NZALLOC (insn_model_entry*, model->nr_models + 1);
+ new_insn->model =
+ NZALLOC (insn_model_entry *, model->nr_models + 1);
while (record != NULL)
{
if (record_prefix_is (record, '*', nr_insn_model_fields))
parse_insn_model_record (file, record, new_insn, model);
- else if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
+ else
+ if (record_prefix_is (record, '"', nr_insn_mnemonic_fields))
parse_insn_mnemonic_record (file, record, new_insn);
else
break;
new_insn->processors))
{
/* only discard an instruction based in the processor
- model when both the instruction and the options are
- nonempty */
+ model when both the instruction and the options are
+ nonempty */
if (options.warn.discard)
notify (new_insn->line,
"Discarding instruction %s (processor-model)\n",
last = &(*last)->next;
*last = new_insn;
/* update global isa counters */
- isa->nr_insns ++;
+ isa->nr_insns++;
if (isa->max_nr_words < new_insn->nr_words)
isa->max_nr_words = new_insn->nr_words;
filter_add (&isa->flags, new_insn->flags);
}
break;
}
-
+
case define_record:
record = parse_macro_record (file, record);
break;
void
-print_insn_words (lf *file,
- insn_entry *insn)
+print_insn_words (lf *file, insn_entry * insn)
{
insn_word_entry *word = insn->words;
if (word != NULL)
insn_field_entry *field = word->first;
while (1)
{
+ insn_field_cond *cond;
+
if (options.insn_specifying_widths)
lf_printf (file, "%d.", field->width);
else
- lf_printf (file, "%d.", i2target (options.hi_bit_nr, field->first));
+ lf_printf (file, "%d.",
+ i2target (options.hi_bit_nr, field->first));
switch (field->type)
{
case insn_field_invalid:
break;
case insn_field_string:
lf_printf (file, "%s", field->val_string);
+
+ if (field->conditions == NULL)
+ break;
+
+ if (field->conditions->test == insn_field_cond_eq)
+ {
+ if (field->conditions->type == insn_field_cond_value)
+ lf_printf (file, "=%ld",
+ (long) field->conditions->value);
+ else
+ lf_printf (file, "=%s", field->conditions->string);
+
+ /* There can be only one equality condition. */
+ ASSERT (field->conditions->next == NULL);
+ break;
+ }
+
+ for (cond = field->conditions;
+ cond != NULL;
+ cond = cond->next)
+ {
+ ASSERT (cond->test == insn_field_cond_ne);
+
+ if (cond->type == insn_field_cond_value)
+ lf_printf (file, "!%ld", (long) cond->value);
+ else
+ lf_printf (file, "!%s", cond->string);
+ }
break;
}
if (field == word->last)
}
}
}
+\f
-\f
void
function_entry_traverse (lf *file,
- function_entry *functions,
- function_entry_handler *handler,
- void *data)
+ function_entry * functions,
+ function_entry_handler * handler, void *data)
{
function_entry *function;
for (function = functions; function != NULL; function = function->next)
void
insn_table_traverse_insn (lf *file,
insn_table *isa,
- insn_entry_handler *handler,
- void *data)
+ insn_entry_handler * handler, void *data)
{
insn_entry *insn;
for (insn = isa->insns; insn != NULL; insn = insn->next)
handler (file, isa, insn, data);
}
}
-
\f
+
static void
dump_function_entry (lf *file,
- char *prefix,
- function_entry *entry,
- char *suffix)
+ char *prefix, function_entry * entry, char *suffix)
{
lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
static void
dump_function_entries (lf *file,
- char *prefix,
- function_entry *entry,
- char *suffix)
+ char *prefix, function_entry * entry, char *suffix)
{
lf_printf (file, "%s", prefix);
lf_indent (file, +1);
{
switch (type)
{
- case scratch_value: return "scratch";
- case cache_value: return "cache";
- case compute_value: return "compute";
+ case scratch_value:
+ return "scratch";
+ case cache_value:
+ return "cache";
+ case compute_value:
+ return "compute";
}
ERROR ("Bad switch");
return 0;
}
static void
-dump_cache_entry (lf *file,
- char *prefix,
- cache_entry *entry,
- char *suffix)
+dump_cache_entry (lf *file, char *prefix, cache_entry *entry, char *suffix)
{
lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
{
dump_line_ref (file, "\n(line ", entry->line, ")");
dump_filter (file, "\n(flags ", entry->flags, ")");
- lf_printf (file, "\n(entry_type \"%s\")", cache_entry_type_to_str (entry->entry_type));
+ lf_printf (file, "\n(entry_type \"%s\")",
+ cache_entry_type_to_str (entry->entry_type));
lf_printf (file, "\n(name \"%s\")", entry->name);
dump_filter (file, "\n(original_fields ", entry->original_fields, ")");
lf_printf (file, "\n(type \"%s\")", entry->type);
}
void
-dump_cache_entries (lf *file,
- char *prefix,
- cache_entry *entry,
- char *suffix)
+dump_cache_entries (lf *file, char *prefix, cache_entry *entry, char *suffix)
{
lf_printf (file, "%s", prefix);
lf_indent (file, +1);
}
static void
-dump_model_data (lf *file,
- char *prefix,
- model_data *entry,
- char *suffix)
+dump_model_data (lf *file, char *prefix, model_data *entry, char *suffix)
{
lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
}
static void
-dump_model_datas (lf *file,
- char *prefix,
- model_data *entry,
- char *suffix)
+dump_model_datas (lf *file, char *prefix, model_data *entry, char *suffix)
{
lf_printf (file, "%s", prefix);
lf_indent (file, +1);
}
static void
-dump_model_entry (lf *file,
- char *prefix,
- model_entry *entry,
- char *suffix)
+dump_model_entry (lf *file, char *prefix, model_entry *entry, char *suffix)
{
lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
}
static void
-dump_model_entries (lf *file,
- char *prefix,
- model_entry *entry,
- char *suffix)
+dump_model_entries (lf *file, char *prefix, model_entry *entry, char *suffix)
{
lf_printf (file, "%s", prefix);
lf_indent (file, +1);
static void
-dump_model_table (lf *file,
- char *prefix,
- model_table *entry,
- char *suffix)
+dump_model_table (lf *file, char *prefix, model_table *entry, char *suffix)
{
lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
{
switch (type)
{
- case insn_field_invalid: ASSERT (0); return "(invalid)";
- case insn_field_int: return "int";
- case insn_field_reserved: return "reserved";
- case insn_field_wild: return "wild";
- case insn_field_string: return "string";
+ case insn_field_invalid:
+ ASSERT (0);
+ return "(invalid)";
+ case insn_field_int:
+ return "int";
+ case insn_field_reserved:
+ return "reserved";
+ case insn_field_wild:
+ return "wild";
+ case insn_field_string:
+ return "string";
}
ERROR ("bad switch");
return 0;
void
dump_insn_field (lf *file,
- char *prefix,
- insn_field_entry *field,
- char *suffix)
+ char *prefix, insn_field_entry *field, char *suffix)
{
char *sep = " ";
lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field);
lf_printf (file, "%s(first %d)", sep, field->first);
lf_printf (file, "%s(last %d)", sep, field->last);
lf_printf (file, "%s(width %d)", sep, field->width);
- lf_printf (file, "%s(type %s)", sep, insn_field_type_to_str (field->type));
+ lf_printf (file, "%s(type %s)", sep,
+ insn_field_type_to_str (field->type));
switch (field->type)
{
case insn_field_invalid:
void
dump_insn_word_entry (lf *file,
- char *prefix,
- insn_word_entry *word,
- char *suffix)
+ char *prefix, insn_word_entry *word, char *suffix)
{
lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word);
if (word != NULL)
lf_printf (file, "\n(bit");
for (i = 0; i < options.insn_bit_size; i++)
lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))",
- word->bit[i]->value, word->bit[i]->mask, (long) word->bit[i]->field);
+ word->bit[i]->value, word->bit[i]->mask,
+ (long) word->bit[i]->field);
lf_printf (file, ")");
for (field = word->first; field != NULL; field = field->next)
dump_insn_field (file, "\n(", field, ")");
static void
dump_insn_word_entries (lf *file,
- char *prefix,
- insn_word_entry *word,
- char *suffix)
+ char *prefix, insn_word_entry *word, char *suffix)
{
lf_printf (file, "%s", prefix);
while (word != NULL)
static void
dump_insn_model_entry (lf *file,
- char *prefix,
- insn_model_entry *model,
- char *suffix)
+ char *prefix, insn_model_entry *model, char *suffix)
{
lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model);
if (model != NULL)
static void
dump_insn_model_entries (lf *file,
- char *prefix,
- insn_model_entry *model,
- char *suffix)
+ char *prefix, insn_model_entry *model, char *suffix)
{
lf_printf (file, "%s", prefix);
while (model != NULL)
static void
dump_insn_mnemonic_entry (lf *file,
char *prefix,
- insn_mnemonic_entry *mnemonic,
- char *suffix)
+ insn_mnemonic_entry *mnemonic, char *suffix)
{
- lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix, (long) mnemonic);
+ lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix,
+ (long) mnemonic);
if (mnemonic != NULL)
{
lf_indent (file, +1);
static void
dump_insn_mnemonic_entries (lf *file,
char *prefix,
- insn_mnemonic_entry *mnemonic,
- char *suffix)
+ insn_mnemonic_entry *mnemonic, char *suffix)
{
lf_printf (file, "%s", prefix);
while (mnemonic != NULL)
}
void
-dump_insn_entry (lf *file,
- char *prefix,
- insn_entry *entry,
- char *suffix)
+dump_insn_entry (lf *file, char *prefix, insn_entry * entry, char *suffix)
{
lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry);
if (entry != NULL)
lf_printf (file, " 0x%lx", (long) entry->model[i]);
lf_printf (file, ")");
dump_filter (file, "\n(processors ", entry->processors, ")");
- dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics, ")");
+ dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics,
+ ")");
dump_table_entry (file, "\n(code ", entry->code, ")");
lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
lf_indent (file, -1);
- }
+ }
lf_printf (file, "%s", suffix);
}
static void
-dump_insn_entries (lf *file,
- char *prefix,
- insn_entry *entry,
- char *suffix)
+dump_insn_entries (lf *file, char *prefix, insn_entry * entry, char *suffix)
{
lf_printf (file, "%s", prefix);
lf_indent (file, +1);
void
-dump_insn_table (lf *file,
- char *prefix,
- insn_table *isa,
- char *suffix)
+dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix)
{
lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa);
if (isa != NULL)