X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=sim%2Figen%2Fld-insn.c;h=f812199e749ae2504bf699f3f895a5c82973fe71;hb=e7b564aa85a5d135b65798288784ed9ae9ad9687;hp=7fc0e37f33c181b85f3fb100bc42091d4fd3c1bd;hpb=13eaae2fd07512516eec601d4a3ab78bf9af34ec;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/igen/ld-insn.c b/sim/igen/ld-insn.c index 7fc0e37f33..f812199e74 100644 --- a/sim/igen/ld-insn.c +++ b/sim/igen/ld-insn.c @@ -326,52 +326,18 @@ parse_insn_word (line_ref *line, 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 we encounter a constant conditional, encode + their bit value. */ + if (field->conditions != NULL + && field->conditions->test == insn_field_cond_eq + && field->conditions->type == insn_field_cond_value) { - 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; - } + word->bit[i]->mask = 1; + word->bit[i]->value = ((field->conditions->value + & ((insn_uint)1 << (field->last - i))) + != 0); } - if (cond->field == NULL) - error (line, "Condition field refers to non-existant field `%s'\n", - cond->string); + break; } } } @@ -433,7 +399,7 @@ parse_insn_words (insn_entry *insn, chp++; } - /* now create a quick access array of the same structure */ + /* create a quick access array (indexed by word) of the same structure */ { int i; insn_word_entry *word; @@ -443,6 +409,64 @@ parse_insn_words (insn_entry *insn, i++, word = word->next) insn->word[i] = word; } + + /* 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 */ + { + int i; + for (i = 0; i < insn->nr_words; i++) + { + insn_word_entry *word = insn->word[i]; + 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) + { + int j; + if (strcmp (cond->string, f->val_string) == 0) + error (insn->line, + "Conditional `%s' of field `%s' refers to its self\n", + cond->string, f->val_string); + for (j = 0; j <= i && cond->field == NULL; j++) + { + insn_word_entry *refered_word = insn->word[j]; + insn_field_entry *refered_field; + for (refered_field = refered_word->first; + refered_field != NULL && cond->field == NULL; + refered_field = refered_field->next) + { + if (refered_field->type == insn_field_string + && strcmp (refered_field->val_string, cond->string) == 0) + { + /* found field being refered to by conditonal */ + cond->field = refered_field; + /* check refered to and this field are + the same size */ + 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); + } + } + } + if (cond->field == NULL) + error (insn->line, + "Conditional `%s' of field `%s' not yet defined\n", + cond->string, f->val_string); + } + } + } + } + } + } typedef enum { @@ -1201,6 +1225,8 @@ load_insn_table (char *file_name, new_insn->code = record; record = table_read (file); } + else if (options.warn.unimplemented) + notify (new_insn->line, "unimplemented\n"); /* insert it */ if (!filter_is_subset (options.flags_filter, new_insn->flags)) {