aboutsummaryrefslogtreecommitdiff
path: root/sim/igen
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>1998-04-14 00:00:15 +0000
committerAndrew Cagney <cagney@redhat.com>1998-04-14 00:00:15 +0000
commit346a3d6c11e5dd2ef80d345f2ee8f231e1080efc (patch)
tree89d8c62b0fab7088b54f6be69ff2dafc2e82707d /sim/igen
parent27aa0c7e559ff1426b1679b644441649d72a19c7 (diff)
downloadgdb-346a3d6c11e5dd2ef80d345f2ee8f231e1080efc.zip
gdb-346a3d6c11e5dd2ef80d345f2ee8f231e1080efc.tar.gz
gdb-346a3d6c11e5dd2ef80d345f2ee8f231e1080efc.tar.bz2
Add support for instruction word conditionals of the form `XXX!YYY'
and XXX=YYY'. See mn10300 for examples.
Diffstat (limited to 'sim/igen')
-rw-r--r--sim/igen/ChangeLog38
-rw-r--r--sim/igen/gen.c241
-rw-r--r--sim/igen/igen.c29
-rw-r--r--sim/igen/igen.h2
-rw-r--r--sim/igen/ld-insn.c197
5 files changed, 428 insertions, 79 deletions
diff --git a/sim/igen/ChangeLog b/sim/igen/ChangeLog
index c62353b..537c786 100644
--- a/sim/igen/ChangeLog
+++ b/sim/igen/ChangeLog
@@ -1,3 +1,41 @@
+Tue Apr 14 08:44:53 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * igen.h (struct igen_trace_options): Add members insn_expansion
+ and insn_insertion.
+
+ * igen.c (main): Add options -Gtrace-insn-expansion,
+ -Gtrace-insn-insertion and -Gtrace-all.
+
+ * gen.c (gen_entry_expand_insns): Trace each instruction as it is
+ selected for expansion.
+ (gen_entry_expand_opcode): Trace each expanded instruction as it
+ is inserted into the table.
+
+Mon Apr 13 19:21:47 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ld-insn.c (parse_insn_word): Parse conditional operators.
+ (parse_insn_word): Verify field conditionals.
+
+ * ld-insn.h: Extend syntax to allow macros and field equality.
+ (struct insn_field_cond): Rename insn_field_exclusion, add type.
+
+ * gen.c (gen_entry_expand_opcode): Check type of conditional.
+ (insns_bit_useless): Ditto.
+
+ * ld-insn.c (parse_macro_record): New function.
+
+Mon Apr 13 22:37:47 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ld-insn.h (enum insn_field_type): Add insn_field_invalid.
+
+ * ld-insn.c (parse_insn_word): Check instruction field type
+ correctly initialized.
+ (print_insn_words): Ditto.
+ (insn_field_type_to_str): Ditto.
+ (dump_insn_field): Ditto.
+
+ * gen.c (insns_bit_useless): Ditto.
+
Fri Apr 3 18:08:16 1998 Andrew Cagney <cagney@b1.cygnus.com>
* gen.h, igen.c (print_include_inline, print_includes,
diff --git a/sim/igen/gen.c b/sim/igen/gen.c
index 927f165..f630b9f 100644
--- a/sim/igen/gen.c
+++ b/sim/igen/gen.c
@@ -73,8 +73,8 @@ print_gen_entry_path (line_ref *line,
{
if (table->parent == NULL)
{
- if (table->top->processor != NULL)
- print (line, "%s", table->top->processor);
+ if (table->top->model != NULL)
+ print (line, "%s", table->top->model->name);
else
print (line, "");
}
@@ -282,9 +282,9 @@ insn_list_insert (insn_list **cur_insn_ptr,
/* two instructions with the same constant field
values across all words and bits */
warning (insn->line,
- "Location of second (duplicated?) instruction");
+ "Two instructions with identical constant fields\n");
error ((*cur_insn_ptr)->insn->line,
- "Two instructions with identical constant fields\n");
+ "Location of second (duplicated?) instruction\n");
case merge_duplicate_insns:
/* Add the opcode path to the instructions list */
if (opcodes != NULL)
@@ -382,19 +382,19 @@ gen_entry_traverse_tree (lf *file,
static gen_list *
make_table (insn_table *isa,
decode_table *rules,
- char *processor)
+ model_entry *model)
{
insn_entry *insn;
gen_list *entry = ZALLOC (gen_list);
entry->table = ZALLOC (gen_entry);
entry->table->top = entry;
- entry->processor = processor;
+ entry->model = model;
entry->isa = isa;
for (insn = isa->insns; insn != NULL; insn = insn->next)
{
- if (processor == NULL
+ if (model == NULL
|| insn->processors == NULL
- || filter_is_member (insn->processors, processor))
+ || filter_is_member (insn->processors, model->name))
{
insn_list_insert (&entry->table->insns,
&entry->table->nr_insns,
@@ -420,18 +420,21 @@ make_gen_tables (insn_table *isa,
if (options.gen.multi_sim)
{
gen_list **last = &gen->tables;
- char *processor;
+ model_entry *model;
filter *processors;
if (options.model_filter != NULL)
processors = options.model_filter;
else
processors = isa->model->processors;
- for (processor = filter_next (processors, "");
- processor != NULL;
- processor = filter_next (processors, processor))
+ for (model = isa->model->models;
+ model != NULL;
+ model = model->next)
{
- *last = make_table (isa, rules, processor);
- last = &(*last)->next;
+ if (filter_is_member (processors, model->name))
+ {
+ *last = make_table (isa, rules, model);
+ last = &(*last)->next;
+ }
}
}
else
@@ -495,12 +498,18 @@ insns_bit_useless (insn_list *insns,
insn_list *entry;
int value = -1;
int is_useless = 1; /* cleared if something actually found */
+
+ /* check the instructions for some constant value in at least one of
+ the bit fields */
for (entry = insns; entry != NULL; entry = entry->next)
{
insn_word_entry *word = entry->insn->word[rule->word_nr];
insn_bit_entry *bit = word->bit[bit_nr];
switch (bit->field->type)
{
+ case insn_field_invalid:
+ ASSERT (0);
+ break;
case insn_field_wild:
case insn_field_reserved:
/* neither useless or useful - ignore */
@@ -514,7 +523,9 @@ insns_bit_useless (insn_list *insns,
case decode_find_constants:
case decode_find_mixed:
/* an integer is useful if its value isn't the same
- between all instructions? */
+ between all instructions. The first time through the
+ value is saved, the second time through (if the
+ values differ) it is marked as useful. */
if (value < 0)
value = bit->value;
else if (value != bit->value)
@@ -531,9 +542,9 @@ insns_bit_useless (insn_list *insns,
break;
case decode_find_constants:
case decode_find_mixed:
- /* a string field forced to constant */
if (filter_is_member (rule->constant_field_names,
bit->field->val_string))
+ /* a string field forced to constant? */
is_useless = 0;
else if (rule->search == decode_find_constants)
/* the string field isn't constant */
@@ -542,6 +553,77 @@ insns_bit_useless (insn_list *insns,
}
}
}
+
+ /* Given only one constant value has been found, check through all
+ the instructions to see if at least one conditional makes it
+ usefull */
+ if (value >= 0 && is_useless)
+ {
+ for (entry = insns; entry != NULL; entry = entry->next)
+ {
+ insn_word_entry *word = entry->insn->word[rule->word_nr];
+ insn_bit_entry *bit = word->bit[bit_nr];
+ switch (bit->field->type)
+ {
+ case insn_field_invalid:
+ ASSERT (0);
+ break;
+ case insn_field_wild:
+ case insn_field_reserved:
+ case insn_field_int:
+ /* already processed */
+ break;
+ case insn_field_string:
+ switch (rule->search)
+ {
+ case decode_find_strings:
+ case decode_find_constants:
+ /* already processed */
+ break;
+ case decode_find_mixed:
+ /* string field with conditions. If this condition
+ eliminates the value then the compare is useful */
+ if (bit->field->conditions != NULL)
+ {
+ insn_field_cond *condition;
+ int shift = bit->field->last - bit_nr;
+ for (condition = bit->field->conditions;
+ condition != NULL;
+ condition = condition->next)
+ {
+ printf ("useless %s%s\n",
+ (condition->type == insn_field_cond_eq ? "=" : "!"),
+ condition->string);
+ switch (condition->type)
+ {
+ case insn_field_cond_value:
+ switch (condition->test)
+ {
+ case insn_field_cond_ne:
+ if (((condition->value >> shift) & 1) == value)
+ /* conditional field excludes the
+ current value */
+ is_useless = 0;
+ break;
+ case insn_field_cond_eq:
+ if (((condition->value >> shift) & 1) != value)
+ /* conditional field requires the
+ current value */
+ is_useless = 0;
+ break;
+ }
+ break;
+ case insn_field_cond_field:
+ /* are these handled separatly? */
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
return is_useless;
}
@@ -753,6 +835,15 @@ gen_entry_expand_opcode (gen_entry *table,
{
/* Only include the hardwired bit information with an entry IF
that entry (and hence its functions) are being duplicated. */
+ if (options.trace.insn_expansion)
+ {
+ print_gen_entry_path (table->opcode_rule->line, table, notify);
+ notify (NULL, ": insert %d - %s.%s%s\n",
+ opcode_nr,
+ instruction->format_name,
+ instruction->name,
+ (table->opcode_rule->with_duplicates ? " (duplicated)" : ""));
+ }
if (table->opcode_rule->with_duplicates)
{
gen_entry_insert_insn (table, instruction,
@@ -762,6 +853,10 @@ gen_entry_expand_opcode (gen_entry *table,
}
else
{
+ if (options.trace.insn_insertion)
+ {
+
+ }
gen_entry_insert_insn (table, instruction,
table->opcode->word_nr,
table->nr_prefetched_words,
@@ -773,9 +868,11 @@ gen_entry_expand_opcode (gen_entry *table,
insn_word_entry *word = instruction->word[table->opcode->word_nr];
insn_field_entry *field = word->bit[bit_nr]->field;
int last_pos = ((field->last < table->opcode->last)
- ? field->last : table->opcode->last);
+ ? field->last
+ : table->opcode->last);
int first_pos = ((field->first > table->opcode->first)
- ? field->first : table->opcode->first);
+ ? field->first
+ : table->opcode->first);
int width = last_pos - first_pos + 1;
switch (field->type)
{
@@ -800,21 +897,77 @@ gen_entry_expand_opcode (gen_entry *table,
{
int val;
int last_val = (table->opcode->is_boolean
- ? 2 : (1 << width));
+ ? 2
+ : (1 << width));
for (val = 0; val < last_val; val++)
{
- /* check to see if the value has been limited */
- insn_field_exclusion *exclusion;
- for (exclusion = field->exclusions;
- exclusion != NULL;
- exclusion = exclusion->next)
+ /* check to see if the value has been precluded
+ (by a conditional) in some way */
+ int is_precluded;
+ insn_field_cond *condition;
+ for (condition = field->conditions, is_precluded = 0;
+ condition != NULL && !is_precluded;
+ condition = condition->next)
{
- int value = sub_val (exclusion->value, field,
- first_pos, last_pos);
- if (value == val)
- break;
+ switch (condition->type)
+ {
+ case insn_field_cond_value:
+ {
+ int value = sub_val (condition->value, field,
+ first_pos, last_pos);
+ switch (condition->test)
+ {
+ case insn_field_cond_ne:
+ if (value == val)
+ is_precluded = 1;
+ break;
+ case insn_field_cond_eq:
+ if (value != val)
+ is_precluded = 1;
+ break;
+ }
+ break;
+ }
+ case insn_field_cond_field:
+ {
+ int value;
+ /* Find a value for the conditional by
+ looking back through the previously
+ defined bits for the specified
+ conditonal field */
+ opcode_bits *bit = bits;
+ for (bit = bits;
+ bit != NULL;
+ bit = bit->next)
+ {
+ if (bit->field == condition->field
+ && (bit->last - bit->first + 1 == condition->field->width))
+ /* the bit field fully specified
+ the conditional field's value */
+ break;
+ }
+ if (bit == NULL)
+ error (instruction->line,
+ "Conditional `%s' of field `%s' isn't expanded",
+ condition->string, field->val_string);
+ value = sub_val (bit->value, field,
+ first_pos, last_pos);
+ switch (condition->test)
+ {
+ case insn_field_cond_ne:
+ if (value == val)
+ is_precluded = 1;
+ break;
+ case insn_field_cond_eq:
+ if (value != val)
+ is_precluded = 1;
+ break;
+ }
+ break;
+ }
+ }
}
- if (exclusion == NULL)
+ if (!is_precluded)
{
/* Only add additional hardwired bit
information if the entry is not going to
@@ -985,10 +1138,10 @@ gen_entry_expand_insns (gen_entry *table)
opcode_rule = opcode_rule->next)
{
char *discard_reason;
- if (table->top->processor != NULL
+ if (table->top->model != NULL
&& opcode_rule->model_names != NULL
&& !filter_is_member (opcode_rule->model_names,
- table->top->processor))
+ table->top->model->name))
{
/* the rule isn't applicable to this processor */
discard_reason = "wrong model";
@@ -1075,15 +1228,7 @@ gen_entry_expand_insns (gen_entry *table)
table->opcode->parent = table->parent->opcode;
}
- /* expand the raw instructions according to the opcode */
- {
- insn_list *entry;
- for (entry = table->insns; entry != NULL; entry = entry->next)
- {
- gen_entry_insert_expanding (table, entry->insn);
- }
- }
-
+ /* report the rule being used to expand the instructions */
if (options.trace.rule_selection)
{
print_gen_entry_path (table->opcode_rule->line, table, notify);
@@ -1098,6 +1243,22 @@ gen_entry_expand_insns (gen_entry *table)
table->nr_entries);
}
+ /* expand the raw instructions according to the opcode */
+ {
+ insn_list *entry;
+ for (entry = table->insns; entry != NULL; entry = entry->next)
+ {
+ if (options.trace.insn_expansion)
+ {
+ print_gen_entry_path (table->opcode_rule->line, table, notify);
+ notify (NULL, ": expand - %s.%s\n",
+ entry->insn->format_name,
+ entry->insn->name);
+ }
+ gen_entry_insert_expanding (table, entry->insn);
+ }
+ }
+
/* dump the results */
if (options.trace.entries)
{
diff --git a/sim/igen/igen.c b/sim/igen/igen.c
index fd9b20d..4a95f2f 100644
--- a/sim/igen/igen.c
+++ b/sim/igen/igen.c
@@ -1101,14 +1101,17 @@ main (int argc,
printf ("\t trace-entries - report entries after a rules application\n");
printf ("\t trace-rule-rejection - report each rule as rejected\n");
printf ("\t trace-rule-selection - report each rule as selected\n");
+ printf ("\t trace-insn-insertion - report each instruction as it is inserted into a decode table\n");
+ printf ("\t trace-rule-expansion - report each instruction as it is expanded (before insertion into a decode table)\n");
+ printf ("\t trace-all - enable all trace options\n");
printf ("\n");
- printf ("\t field-widths - instruction formats specify widths (depreciated)\n");
- printf ("\t By default, an instruction format specifies bit\n");
- printf ("\t positions\n");
- printf ("\t This option can now be set directly in the\n");
- printf ("\t instruction table\n");
- printf ("\t jumps - use jumps instead of function calls\n");
- printf ("\t omit-line-numbers - do not include line number information in the output\n");
+ printf ("\t field-widths - instruction formats specify widths (depreciated)\n");
+ printf ("\t By default, an instruction format specifies bit\n");
+ printf ("\t positions\n");
+ printf ("\t This option can now be set directly in the\n");
+ printf ("\t instruction table\n");
+ printf ("\t jumps - use jumps instead of function calls\n");
+ printf ("\t omit-line-numbers - do not include line number information in the output\n");
printf ("\n");
printf ("Input options:\n");
printf ("\n");
@@ -1426,6 +1429,10 @@ main (int argc,
{
options.gen.nia = nia_is_void;
}
+ else if (strcmp (argp, "trace-all") == 0)
+ {
+ memset (&options.trace, enable_p, sizeof (options.trace));
+ }
else if (strcmp (argp, "trace-combine") == 0)
{
options.trace.combine = enable_p;
@@ -1442,6 +1449,14 @@ main (int argc,
{
options.trace.rule_selection = enable_p;
}
+ else if (strcmp (argp, "trace-insn-insertion") == 0)
+ {
+ options.trace.insn_insertion = enable_p;
+ }
+ else if (strcmp (argp, "trace-insn-expansion") == 0)
+ {
+ options.trace.insn_expansion = enable_p;
+ }
else if (strcmp (argp, "jumps") == 0)
{
options.gen.code = generate_jumps;
diff --git a/sim/igen/igen.h b/sim/igen/igen.h
index 7aa70ef..6977e06 100644
--- a/sim/igen/igen.h
+++ b/sim/igen/igen.h
@@ -86,6 +86,8 @@ typedef struct _igen_trace_options igen_trace_options;
struct _igen_trace_options {
int rule_selection;
int rule_rejection;
+ int insn_insertion;
+ int insn_expansion;
int entries;
int combine;
};
diff --git a/sim/igen/ld-insn.c b/sim/igen/ld-insn.c
index ca57306..2fc6cf3 100644
--- a/sim/igen/ld-insn.c
+++ b/sim/igen/ld-insn.c
@@ -118,36 +118,69 @@ parse_insn_word (line_ref *line,
if (strlen_val == 0)
error (line, "Empty value field\n");
- /* break out any conditional fields - { "!" <value> } */
- while (*chp == '!')
+ /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
+ while (*chp == '!' || *chp == '=')
{
char *start;
+ char *end;
int len;
- insn_field_exclusion *new_exclusion = ZALLOC (insn_field_exclusion);
- insn_field_exclusion **last;
+ insn_field_cond *new_cond = ZALLOC (insn_field_cond);
+ insn_field_cond **last;
- /* what type of conditional field */
+ /* 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);
- /* the value */
start = chp;
- chp = skip_digits (chp);
- len = chp - start;
+ chp = skip_to_separator (chp, "+,:");
+ end = back_spaces (start, chp);
+ len = end - start;
if (len == 0)
error (line, "Missing or invalid conditional value\n");
- /* fill in the entry */
- new_exclusion->string = NZALLOC (char, len + 1);
- strncpy (new_exclusion->string, start, len);
- new_exclusion->value = a2i (new_exclusion->string);
+ 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 */
- last = &new_field->exclusions;
+ last = &new_field->conditions;
while (*last != NULL)
last = &(*last)->next;
- *last = new_exclusion;
- chp = skip_spaces (chp);
+ *last = new_cond;
}
- /* NOW verify that the field ws finished */
+ /* NOW verify that the field was finished */
if (*chp == ',')
{
chp = skip_spaces (chp + 1);
@@ -156,7 +189,7 @@ parse_insn_word (line_ref *line,
}
else if (*chp != '\0')
{
- error (line, "Missing field separator");
+ error (line, "Missing field separator\n");
}
/* copy the value */
@@ -203,8 +236,8 @@ parse_insn_word (line_ref *line,
filter_parse (&word->field_names, new_field->val_string);
}
if (new_field->type != insn_field_string
- && new_field->exclusions != NULL)
- error (line, "Exclusions only apply to name fields\n");
+ && 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);
@@ -281,6 +314,9 @@ parse_insn_word (line_ref *line,
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
@@ -295,6 +331,51 @@ parse_insn_word (line_ref *line,
}
}
+ /* 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;
}
@@ -635,7 +716,8 @@ parse_function_record (table *file,
table_entry *record,
function_entry **list,
function_entry **list_entry,
- int is_internal)
+ int is_internal,
+ model_table *model)
{
function_entry *new_function;
new_function = ZALLOC (function_entry);
@@ -669,8 +751,12 @@ parse_function_record (table *file,
while (record != NULL
&& record_prefix_is (record, '*', nr_function_model_fields))
{
- filter_parse (&new_function->models,
- 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))
+ {
+ error (record->line, "machine model `%s' undefined\n", model_name);
+ }
record = table_read (file);
}
/* parse the function body */
@@ -683,12 +769,15 @@ parse_function_record (table *file,
if (!filter_is_subset (options.flags_filter, new_function->flags))
{
if (options.warn.discard)
- notify (new_function->line, "Discarding function entry - filter flags\n");
+ notify (new_function->line, "Discarding function %s - filter flags\n",
+ new_function->name);
}
- else if (!filter_is_subset (options.model_filter, new_function->models))
+ 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 entry - filter models\n");
+ notify (new_function->line, "Discarding function %s - filter models\n",
+ new_function->name);
}
else
{
@@ -803,6 +892,34 @@ parse_insn_mnemonic_record (table *file,
}
+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)
@@ -842,7 +959,8 @@ load_insn_table (char *file_name,
record = parse_function_record (file, record,
&isa->functions,
&function,
- 0/*is-internal*/);
+ 0/*is-internal*/,
+ model);
/* convert a string function record into an internal function */
if (function != NULL)
{
@@ -863,7 +981,8 @@ load_insn_table (char *file_name,
record = parse_function_record (file, record,
&isa->functions,
NULL,
- 0/*is-internal*/);
+ 0/*is-internal*/,
+ model);
break;
}
@@ -874,7 +993,8 @@ load_insn_table (char *file_name,
record = parse_function_record (file, record,
&isa->functions,
&function,
- 1/*is-internal*/);
+ 1/*is-internal*/,
+ model);
/* check what was inserted to see if a pseudo-instruction
entry also needs to be created */
if (function != NULL)
@@ -1015,21 +1135,24 @@ load_insn_table (char *file_name,
record = parse_function_record (file, record,
&model->statics,
NULL,
- 0/*is internal*/);
+ 0/*is internal*/,
+ model);
break;
case model_internal_record:
record = parse_function_record (file, record,
&model->internals,
NULL,
- 1/*is internal*/);
+ 1/*is internal*/,
+ model);
break;
case model_function_record:
record = parse_function_record (file, record,
&model->functions,
NULL,
- 0/*is internal*/);
+ 0/*is internal*/,
+ model);
break;
case insn_record: /* instruction records */
@@ -1118,8 +1241,11 @@ load_insn_table (char *file_name,
break;
}
- case unknown_record:
case define_record:
+ record = parse_macro_record (file, record);
+ break;
+
+ case unknown_record:
case code_record:
error (record->line, "Unknown or unexpected entry\n");
@@ -1148,6 +1274,9 @@ print_insn_words (lf *file,
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;
@@ -1397,6 +1526,7 @@ 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";
@@ -1423,6 +1553,9 @@ dump_insn_field (lf *file,
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;