diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
commit | 071ea11e85eb9d529cc5eb3d35f6247466a21b99 (patch) | |
tree | 5deda65b8d7b04d1f4cbc534c3206d328e1267ec /sim/igen/ld-insn.c | |
parent | 1730ec6b1848f0f32154277f788fb29f88d8475b (diff) | |
download | gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.zip gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.gz gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.bz2 |
Initial creation of sourceware repository
Diffstat (limited to 'sim/igen/ld-insn.c')
-rw-r--r-- | sim/igen/ld-insn.c | 1803 |
1 files changed, 0 insertions, 1803 deletions
diff --git a/sim/igen/ld-insn.c b/sim/igen/ld-insn.c deleted file mode 100644 index 7fc0e37..0000000 --- a/sim/igen/ld-insn.c +++ /dev/null @@ -1,1803 +0,0 @@ -/* This file is part of the program psim. - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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. - - */ - - -#include "misc.h" -#include "lf.h" -#include "table.h" -#include "filter.h" -#include "igen.h" -#include "ld-insn.h" - -static insn_word_entry * -parse_insn_word (line_ref *line, - char *string, - int word_nr) -{ - char *chp; - insn_word_entry *word = ZALLOC (insn_word_entry); - - /* create a leading sentinal */ - word->first = ZALLOC (insn_field_entry); - word->first->first = -1; - word->first->last = -1; - word->first->width = 0; - - /* and a trailing sentinal */ - word->last = ZALLOC (insn_field_entry); - word->last->first = options.insn_bit_size; - word->last->last = options.insn_bit_size; - word->last->width = 0; - - /* link them together */ - word->first->next = word->last; - word->last->prev = word->first; - - /* 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 (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 */ - { - insn_field_cond **last = &new_field->conditions; - while (*last != NULL) - last = &(*last)->next; - *last = new_cond; - } - } - - /* 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"); - - /* 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); - word->first = word->first->next; - word->last = word->last->prev; - - /* check that the last field goes all the way to the last bit */ - if (word->last->last != options.insn_bit_size - 1) - { - 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; - } - - /* now go over this again, pointing each bit position at a field - record */ - { - insn_field_entry *field; - for (field = word->first; - field->last < options.insn_bit_size; - field = field->next) - { - int i; - for (i = field->first; i <= field->last; i++) - { - word->bit[i] = ZALLOC (insn_bit_entry); - word->bit[i]->field = field; - switch (field->type) - { - case insn_field_invalid: - ASSERT (0); - break; - case insn_field_int: - word->bit[i]->mask = 1; - word->bit[i]->value = ((field->val_int - & ((insn_uint)1 << (field->last - i))) - != 0); - case insn_field_reserved: - case insn_field_wild: - case insn_field_string: - break; - } - } - } - } - - /* go over all fields that have conditionals refering to other - fields. Link the fields up. Verify that the two fields have the - same size. Verify that the two fields are different */ - { - insn_field_entry *f; - 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) - { - if (cond->type == insn_field_cond_field) - { - insn_field_entry *field; - if (strcmp (cond->string, f->val_string) == 0) - error (line, "Conditional of field `%s' refers to its self\n", - f->val_string); - for (field = word->first; - field != NULL; - field = field->next) - { - if (field->type == insn_field_string - && strcmp (field->val_string, cond->string) == 0) - { - /* found field being refered to by conditonal */ - cond->field = field; - /* check refered to and this field are the - same size */ - if (f->width != field->width) - error (line, "Conditional `%s' of field `%s' has different size\n", - field->width, f->width); - break; - } - } - if (cond->field == NULL) - error (line, "Condition field refers to non-existant field `%s'\n", - cond->string); - } - } - } - } - - return word; -} - - -static void -parse_insn_words (insn_entry *insn, - char *formats) -{ - insn_word_entry **last_word = &insn->words; - char *chp; - - /* now work through the formats */ - insn->nr_words = 0; - chp = formats; - - while (1) - { - char *start_pos; - char *end_pos; - int strlen_pos; - char *format; - insn_word_entry *new_word; - - /* skip leading spaces */ - chp = skip_spaces (chp); - - /* break out the format */ - start_pos = chp; - chp = skip_to_separator (chp, "+"); - end_pos = back_spaces (start_pos, chp); - strlen_pos = end_pos - start_pos; - - /* check that something was there */ - if (strlen_pos == 0) - error (insn->line, "missing or empty instruction format\n"); - - /* parse the field */ - format = NZALLOC (char, strlen_pos + 1); - strncpy (format, start_pos, strlen_pos); - new_word = parse_insn_word (insn->line, format, insn->nr_words); - insn->nr_words++; - if (filter_is_common (insn->field_names, new_word->field_names)) - error (insn->line, "Field name duplicated between two words\n"); - filter_add (&insn->field_names, new_word->field_names); - - /* insert it */ - *last_word = new_word; - last_word = &new_word->next; - - /* last format? */ - if (*chp == '\0') - break; - ASSERT (*chp == '+'); - chp++; - } - - /* now create a quick access array of the same structure */ - { - int i; - 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) - insn->word[i] = word; - } -} - -typedef enum { - unknown_record = 0, - insn_record, /* default */ - code_record, - cache_record, - compute_record, - scratch_record, - option_record, - string_function_record, - function_record, - internal_record, - define_record, - include_record, - model_processor_record, - model_macro_record, - model_data_record, - model_static_record, - model_function_record, - model_internal_record, -} 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 }, -}; - - -static int -record_is_old (table_entry *entry) -{ - if (entry->nr_fields > record_type_field - && strlen (entry->field[record_type_field]) == 0) - return 1; - return 0; -} - -static insn_record_type -record_type (table_entry *entry) -{ - switch (entry->type) - { - case table_code_entry: - return code_record; - - case table_colon_entry: - if (record_is_old (entry)) - { - /* old-format? */ - if (entry->nr_fields > old_record_type_field) - { - int i = name2i (entry->field[old_record_type_field], - insn_type_map); - return i; - } - else - { - return unknown_record; - } - } - else if (entry->nr_fields > record_type_field - && entry->field[0][0] == '\0') - { - /* new-format? */ - int i = name2i (entry->field[record_type_field], - insn_type_map); - return i; - } - else - return insn_record; /* default */ - } - return unknown_record; -} - -static int -record_prefix_is (table_entry *entry, - char ch, - int nr_fields) -{ - if (entry->type != table_colon_entry) - return 0; - if (entry->nr_fields < nr_fields) - return 0; - if (entry->field[0][0] != ch && ch != '\0') - return 0; - return 1; -} - -static table_entry * -parse_model_data_record (insn_table *isa, - table *file, - table_entry *record, - int nr_fields, - model_data **list) -{ - table_entry *model_record = record; - table_entry *code_record = NULL; - model_data *new_data; - if (record->nr_fields < nr_fields) - error (record->line, "Incorrect number of fields\n"); - record = table_read (file); - if (record->type == table_code_entry) - { - code_record = record; - record = table_read (file); - } - /* create the new data record */ - new_data = ZALLOC (model_data); - new_data->line = model_record->line; - filter_parse (&new_data->flags, - model_record->field[record_filter_flags_field]); - new_data->entry = model_record; - new_data->code = code_record; - /* 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; -} - - -typedef enum { - insn_bit_size_option = 1, - insn_specifying_widths_option, - hi_bit_nr_option, - flags_filter_option, - model_filter_option, - multi_sim_option, - format_names_option, - gen_delayed_branch, - unknown_option, -} 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 }, -}; - -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) -{ - table_entry *option_record; - /* parse the option record */ - option_record = record; - if (record->nr_fields < nr_option_fields) - error (record->line, "Incorrect nr of fields for option record\n"); - record = table_read (file); - /* process it */ - if (!is_filtered_out (options.flags_filter, - 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); - char *value = option_record->field[option_value_field]; - switch (option) - { - case insn_bit_size_option: - { - 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"); - 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"); - break; - } - case insn_specifying_widths_option: - { - options.insn_specifying_widths = a2i (value); - break; - } - case hi_bit_nr_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"); - break; - } - case flags_filter_option: - { - filter_parse (&options.flags_filter, value); - break; - } - case model_filter_option: - { - filter_parse (&options.model_filter, value); - break; - } - case multi_sim_option: - { - options.gen.multi_sim = a2i (value); - break; - } - case format_names_option: - { - filter_parse (&options.format_name_filter, value); - break; - } - case gen_delayed_branch: - { - options.gen.delayed_branch = a2i (value); - break; - } - case unknown_option: - { - error (option_record->line, "Unknown option - %s\n", name); - 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 *new_function; - new_function = ZALLOC (function_entry); - new_function->line = record->line; - new_function->is_internal = is_internal; - /* 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)) - { - 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)) - { - error (record->line, "machine model `%s' undefined\n", model_name); - } - record = table_read (file); - } - /* parse the function body */ - if (record->type == table_code_entry) - { - new_function->code = record; - record = table_read (file); - } - /* insert it */ - if (!filter_is_subset (options.flags_filter, new_function->flags)) - { - if (options.warn.discard) - notify (new_function->line, "Discarding function %s - filter flags\n", - new_function->name); - } - else if (new_function->models != NULL - && !filter_is_common (options.model_filter, new_function->models)) - { - if (options.warn.discard) - notify (new_function->line, "Discarding function %s - filter models\n", - new_function->name); - } - else - { - while (*list != NULL) - list = &(*list)->next; - *list = new_function; - if (list_entry != NULL) - *list_entry = new_function; - } - /* done */ - return record; -} - -static void -parse_insn_model_record (table *file, - table_entry *record, - insn_entry *insn, - model_table *model) -{ - insn_model_entry **last_insn_model; - insn_model_entry *new_insn_model = ZALLOC (insn_model_entry); - /* parse it */ - new_insn_model->line = record->line; - 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; - /* 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 names - a generic model entry, enter it into all - the non-empty fields */ - int index; - for (index = 0; index < model->nr_models; index++) - if (insn->model[index] == 0) - { - insn->model[index] = new_insn_model; - } - /* also add the complete processor set to this processor's set */ - filter_add (&insn->processors, model->processors); - } - else - { - /* Find the corresponding master model record for each name so - that they can be linked in. */ - int index; - char *name = ""; - while (1) - { - 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); - } - } -#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) - last_insn_model = &(*last_insn_model)->next; - *last_insn_model = new_insn_model; -} - - -static void -parse_insn_mnemonic_record (table *file, - table_entry *record, - insn_entry *insn) -{ - insn_mnemonic_entry **last_insn_mnemonic; - insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry); - /* parse it */ - new_insn_mnemonic->line = record->line; - 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 (record->nr_fields > 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; - while ((*last_insn_mnemonic) != NULL) - last_insn_mnemonic = &(*last_insn_mnemonic)->next; - insn->nr_mnemonics++; - *last_insn_mnemonic = new_insn_mnemonic; -} - - -static table_entry * -parse_macro_record (table *file, - table_entry *record) -{ -#if 1 - error (record->line, "Macros are not implemented"); -#else - /* parse the define record */ - if (record->nr_fields < nr_define_fields) - error (record->line, "Incorrect nr fields for define 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_define (file, - record->line, - 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) -{ - 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; - - while (record != NULL) - { - - switch (record_type (record)) - { - - case include_record: - { - record = parse_include_record (file, record); - break; - } - - case option_record: - { - if (isa->insns != NULL) - error (record->line, "Option after first instruction\n"); - 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*/, - model); - /* 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; - } - - case function_record: /* function record */ - { - record = parse_function_record (file, record, - &isa->functions, - NULL, - 0/*is-internal*/, - model); - break; - } - - case internal_record: - { - /* only insert it into the function list if it is unknown */ - function_entry *function = NULL; - record = parse_function_record (file, record, - &isa->functions, - &function, - 1/*is-internal*/, - model); - /* check what was inserted to see if a pseudo-instruction - entry also needs to be created */ - if (function != NULL) - { - insn_entry **insn = NULL; - if (strcmp (function->name, "illegal") == 0) - { - /* illegal function save it away */ - if (isa->illegal_insn != NULL) - { - warning (function->line, - "Multiple illegal instruction definitions\n"); - error (isa->illegal_insn->line, - "Location of first illegal instruction\n"); - } - else - insn = &isa->illegal_insn; - } - if (insn != NULL) - { - *insn = ZALLOC (insn_entry); - (*insn)->line = function->line; - (*insn)->name = function->name; - (*insn)->code = function->code; - } - } - break; - } - - case scratch_record: /* cache macro records */ - case cache_record: - case compute_record: - { - cache_entry *new_cache; - /* parse the cache record */ - if (record->nr_fields < nr_cache_fields) - error (record->line, - "Incorrect nr of fields for scratch/cache/compute record\n"); - /* create it */ - new_cache = ZALLOC (cache_entry); - new_cache->line = record->line; - filter_parse (&new_cache->flags, - record->field[record_filter_flags_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]); - new_cache->expression = record->field[cache_expression_field]; - /* 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", - 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 - { - cache_entry **last; - last = &isa->caches; - while (*last != NULL) - last = &(*last)->next; - *last = new_cache; - } - /* advance things */ - record = table_read (file); - break; - } - - /* 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"); - if (isa->insns != NULL) - error (record->line, "Model appears after first instruction\n"); - new_model = ZALLOC (model_entry); - filter_parse (&new_model->flags, - record->field[record_filter_flags_field]); - new_model->line = record->line; - new_model->name = record->field[model_name_field]; - new_model->full_name = record->field[model_full_name_field]; - new_model->unit_data = record->field[model_unit_data_field]; - /* 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", - 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)) - { - error (new_model->line, "Duplicate processor model %s\n", - new_model->name); - } - else - { - model_entry **last; - last = &model->models; - while (*last != NULL) - last = &(*last)->next; - *last = new_model; - /* count it */ - 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*/, - model); - break; - - case model_internal_record: - record = parse_function_record (file, record, - &model->internals, - NULL, - 1/*is internal*/, - model); - break; - - case model_function_record: - record = parse_function_record (file, record, - &model->functions, - NULL, - 0/*is internal*/, - model); - break; - - 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"); - 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 */ - 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", - new_insn->format_name); - filter_parse (&new_insn->options, - record->field[insn_options_field]); - new_insn->name = record->field[insn_name_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); - 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)) - parse_insn_mnemonic_record (file, record, new_insn); - else - break; - /* advance */ - record = table_read (file); - } - /* Parse the code record */ - if (record != NULL && record->type == table_code_entry) - { - new_insn->code = record; - record = table_read (file); - } - /* insert it */ - if (!filter_is_subset (options.flags_filter, new_insn->flags)) - { - if (options.warn.discard) - notify (new_insn->line, - "Discarding instruction %s (flags-filter)\n", - new_insn->name); - } - else if (new_insn->processors != NULL - && options.model_filter != NULL - && !filter_is_common (options.model_filter, - new_insn->processors)) - { - /* only discard an instruction based in the processor - model when both the instruction and the options are - nonempty */ - if (options.warn.discard) - notify (new_insn->line, - "Discarding instruction %s (processor-model)\n", - new_insn->name); - } - else - { - insn_entry **last; - /* finish the parsing */ - parse_insn_words (new_insn, format); - /* append it */ - last = &isa->insns; - while (*last) - last = &(*last)->next; - *last = new_insn; - /* update global isa counters */ - 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); - filter_add (&isa->options, new_insn->options); - } - break; - } - - case define_record: - record = parse_macro_record (file, record); - break; - - case unknown_record: - case code_record: - error (record->line, "Unknown or unexpected entry\n"); - - - } - } - return isa; -} - - -void -print_insn_words (lf *file, - insn_entry *insn) -{ - insn_word_entry *word = insn->words; - if (word != NULL) - { - while (1) - { - insn_field_entry *field = word->first; - while (1) - { - if (options.insn_specifying_widths) - lf_printf (file, "%d.", field->width); - else - lf_printf (file, "%d.", i2target (options.hi_bit_nr, field->first)); - switch (field->type) - { - case insn_field_invalid: - ASSERT (0); - break; - case insn_field_int: - lf_printf (file, "0x%lx", (long) field->val_int); - break; - case insn_field_reserved: - lf_printf (file, "/"); - break; - case insn_field_wild: - lf_printf (file, "*"); - break; - case insn_field_string: - lf_printf (file, "%s", field->val_string); - break; - } - if (field == word->last) - break; - field = field->next; - lf_printf (file, ","); - } - word = word->next; - if (word == NULL) - break; - lf_printf (file, "+"); - } - } -} - - - -void -function_entry_traverse (lf *file, - function_entry *functions, - function_entry_handler *handler, - void *data) -{ - function_entry *function; - for (function = functions; function != NULL; function = function->next) - { - handler (file, function, data); - } -} - -void -insn_table_traverse_insn (lf *file, - insn_table *isa, - insn_entry_handler *handler, - void *data) -{ - insn_entry *insn; - for (insn = isa->insns; insn != NULL; insn = insn->next) - { - handler (file, isa, insn, data); - } -} - - -static void -dump_function_entry (lf *file, - char *prefix, - function_entry *entry, - char *suffix) -{ - lf_printf (file, "%s(function_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(type \"%s\")", entry->type); - lf_printf (file, "\n(name \"%s\")", entry->name); - lf_printf (file, "\n(param \"%s\")", entry->param); - dump_table_entry (file, "\n(code ", entry->code, ")"); - lf_printf (file, "\n(is_internal %d)", entry->is_internal); - lf_printf (file, "\n(next 0x%lx)", (long) entry->next); - } - lf_printf (file, "%s", suffix); -} - -static void -dump_function_entries (lf *file, - char *prefix, - function_entry *entry, - char *suffix) -{ - lf_printf (file, "%s", prefix); - lf_indent (file, +1); - while (entry != NULL) - { - dump_function_entry (file, "\n(", entry, ")"); - entry = entry->next; - } - lf_indent (file, -1); - lf_printf (file, "%s", suffix); -} - -static char * -cache_entry_type_to_str (cache_entry_type type) -{ - switch (type) - { - 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) -{ - 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(name \"%s\")", entry->name); - dump_filter (file, "\n(original_fields ", entry->original_fields, ")"); - lf_printf (file, "\n(type \"%s\")", entry->type); - lf_printf (file, "\n(expression \"%s\")", entry->expression); - lf_printf (file, "\n(next 0x%lx)", (long) entry->next); - } - lf_printf (file, "%s", suffix); -} - -void -dump_cache_entries (lf *file, - char *prefix, - cache_entry *entry, - char *suffix) -{ - lf_printf (file, "%s", prefix); - lf_indent (file, +1); - while (entry != NULL) - { - dump_cache_entry (file, "\n(", entry, ")"); - entry = entry->next; - } - lf_indent (file, -1); - lf_printf (file, "%s", suffix); -} - -static void -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) - { - lf_indent (file, +1); - dump_line_ref (file, "\n(line ", entry->line, ")"); - dump_filter (file, "\n(flags ", entry->flags, ")"); - dump_table_entry (file, "\n(entry ", entry->entry, ")"); - 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", prefix); -} - -static void -dump_model_datas (lf *file, - char *prefix, - model_data *entry, - char *suffix) -{ - lf_printf (file, "%s", prefix); - lf_indent (file, +1); - while (entry != NULL) - { - dump_model_data (file, "\n(", entry, ")"); - entry = entry->next; - } - lf_indent (file, -1); - lf_printf (file, "%s", suffix); -} - -static void -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) - { - lf_indent (file, +1); - dump_line_ref (file, "\n(line ", entry->line, ")"); - dump_filter (file, "\n(flags ", entry->flags, ")"); - lf_printf (file, "\n(name \"%s\")", entry->name); - lf_printf (file, "\n(full_name \"%s\")", entry->full_name); - lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data); - lf_printf (file, "\n(next 0x%lx)", (long) entry->next); - lf_indent (file, -1); - } - lf_printf (file, "%s", prefix); -} - -static void -dump_model_entries (lf *file, - char *prefix, - model_entry *entry, - char *suffix) -{ - lf_printf (file, "%s", prefix); - lf_indent (file, +1); - while (entry != NULL) - { - dump_model_entry (file, "\n(", entry, ")"); - entry = entry->next; - } - lf_indent (file, -1); - lf_printf (file, "%s", suffix); -} - - -static void -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) - { - lf_indent (file, +1); - dump_filter (file, "\n(processors ", entry->processors, ")"); - lf_printf (file, "\n(nr_models %d)", entry->nr_models); - dump_model_entries (file, "\n(models ", entry->models, ")"); - dump_model_datas (file, "\n(macros ", entry->macros, ")"); - dump_model_datas (file, "\n(data ", entry->data, ")"); - dump_function_entries (file, "\n(statics ", entry->statics, ")"); - dump_function_entries (file, "\n(internals ", entry->functions, ")"); - dump_function_entries (file, "\n(functions ", entry->functions, ")"); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - - -static char * -insn_field_type_to_str (insn_field_type type) -{ - 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"; - } - ERROR ("bad switch"); - return 0; -} - -void -dump_insn_field (lf *file, - char *prefix, - insn_field_entry *field, - char *suffix) -{ - char *sep = " "; - lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field); - if (field != NULL) - { - lf_indent (file, +1); - 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)); - switch (field->type) - { - case insn_field_invalid: - ASSERT (0); - break; - case insn_field_int: - lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int); - break; - case insn_field_reserved: - /* nothing output */ - break; - case insn_field_wild: - /* nothing output */ - break; - case insn_field_string: - lf_printf (file, "%s(val \"%s\")", sep, field->val_string); - break; - } - lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next); - lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - -void -dump_insn_word_entry (lf *file, - char *prefix, - insn_word_entry *word, - char *suffix) -{ - lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word); - if (word != NULL) - { - int i; - insn_field_entry *field; - lf_indent (file, +1); - lf_printf (file, "\n(first 0x%lx)", (long) word->first); - lf_printf (file, "\n(last 0x%lx)", (long) word->last); - 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); - lf_printf (file, ")"); - for (field = word->first; field != NULL; field = field->next) - dump_insn_field (file, "\n(", field, ")"); - dump_filter (file, "\n(field_names ", word->field_names, ")"); - lf_printf (file, "\n(next 0x%lx)", (long) word->next); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - -static void -dump_insn_word_entries (lf *file, - char *prefix, - insn_word_entry *word, - char *suffix) -{ - lf_printf (file, "%s", prefix); - while (word != NULL) - { - dump_insn_word_entry (file, "\n(", word, ")"); - word = word->next; - } - lf_printf (file, "%s", suffix); -} - -static void -dump_insn_model_entry (lf *file, - char *prefix, - insn_model_entry *model, - char *suffix) -{ - lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model); - if (model != NULL) - { - lf_indent (file, +1); - dump_line_ref (file, "\n(line ", model->line, ")"); - 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); - lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)", - (long) model->next); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - -static void -dump_insn_model_entries (lf *file, - char *prefix, - insn_model_entry *model, - char *suffix) -{ - lf_printf (file, "%s", prefix); - while (model != NULL) - { - dump_insn_model_entry (file, "\n", model, ""); - model = model->next; - } - lf_printf (file, "%s", suffix); -} - - -static void -dump_insn_mnemonic_entry (lf *file, - char *prefix, - insn_mnemonic_entry *mnemonic, - char *suffix) -{ - lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix, (long) mnemonic); - if (mnemonic != NULL) - { - lf_indent (file, +1); - dump_line_ref (file, "\n(line ", mnemonic->line, ")"); - lf_printf (file, "\n(format \"%s\")", mnemonic->format); - lf_printf (file, "\n(condition \"%s\")", mnemonic->condition); - lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", - (long) mnemonic->insn); - lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)", - (long) mnemonic->next); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - -static void -dump_insn_mnemonic_entries (lf *file, - char *prefix, - insn_mnemonic_entry *mnemonic, - char *suffix) -{ - lf_printf (file, "%s", prefix); - while (mnemonic != NULL) - { - dump_insn_mnemonic_entry (file, "\n", mnemonic, ""); - mnemonic = mnemonic->next; - } - lf_printf (file, "%s", suffix); -} - -void -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) - { - int i; - lf_indent (file, +1); - dump_line_ref (file, "\n(line ", entry->line, ")"); - dump_filter (file, "\n(flags ", entry->flags, ")"); - lf_printf (file, "\n(nr_words %d)", entry->nr_words); - dump_insn_word_entries (file, "\n(words ", entry->words, ")"); - lf_printf (file, "\n(word"); - for (i = 0; i < entry->nr_models; i++) - lf_printf (file, " 0x%lx", (long) entry->word[i]); - lf_printf (file, ")"); - dump_filter (file, "\n(field_names ", entry->field_names, ")"); - lf_printf (file, "\n(format_name \"%s\")", entry->format_name); - dump_filter (file, "\n(options ", entry->options, ")"); - lf_printf (file, "\n(name \"%s\")", entry->name); - lf_printf (file, "\n(nr_models %d)", entry->nr_models); - dump_insn_model_entries (file, "\n(models ", entry->models, ")"); - lf_printf (file, "\n(model"); - for (i = 0; i < entry->nr_models; i++) - 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_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) -{ - lf_printf (file, "%s", prefix); - lf_indent (file, +1); - while (entry != NULL) - { - dump_insn_entry (file, "\n(", entry, ")"); - entry = entry->next; - } - lf_indent (file, -1); - lf_printf (file, "%s", suffix); -} - - - -void -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) - { - lf_indent (file, +1); - dump_cache_entries (file, "\n(caches ", isa->caches, ")"); - lf_printf (file, "\n(nr_insns %d)", isa->nr_insns); - lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words); - dump_insn_entries (file, "\n(insns ", isa->insns, ")"); - dump_function_entries (file, "\n(functions ", isa->functions, ")"); - dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")"); - dump_model_table (file, "\n(model ", isa->model, ")"); - dump_filter (file, "\n(flags ", isa->flags, ")"); - dump_filter (file, "\n(options ", isa->options, ")"); - lf_indent (file, -1); - } - lf_printf (file, "%s", suffix); -} - -#ifdef MAIN - -igen_options options; - -int -main (int argc, char **argv) -{ - insn_table *isa; - lf *l; - - INIT_OPTIONS (options); - - if (argc == 3) - filter_parse (&options.flags_filter, argv[2]); - else if (argc != 2) - error (NULL, "Usage: insn <insn-table> [ <filter-in> ]\n"); - - isa = load_insn_table (argv[1], NULL); - l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); - dump_insn_table (l, "(isa ", isa, ")\n"); - - return 0; -} - -#endif |