diff options
-rw-r--r-- | sim/igen/ChangeLog | 11 | ||||
-rw-r--r-- | sim/igen/gen-icache.c | 2 | ||||
-rw-r--r-- | sim/igen/gen-idecode.c | 8 | ||||
-rw-r--r-- | sim/igen/gen.c | 16 |
4 files changed, 35 insertions, 2 deletions
diff --git a/sim/igen/ChangeLog b/sim/igen/ChangeLog index 576962e..7b14eee 100644 --- a/sim/igen/ChangeLog +++ b/sim/igen/ChangeLog @@ -1,5 +1,16 @@ 2011-07-08 Hans-Peter Nilsson <hp@axis.com> + Correct handling of constant fields. + * gen.c (insn_field_cmp): Tweak comment about neither field + being an insn_field_string with a cond_eq-to-value condition. + (insns_bit_useless) <case insn_field_string, case + decode_find_mixed>: Handle cond_eq-to-value fields as + insn_field_int. + * gen-idecode.c (print_idecode_validate): Handle + insn_field_string cond-equal-to-value fields as insn_field_int. + * gen-icache.c (print_icache_body): Add comment why constant + string fields are handled. + Remove all #if 0'd code. * filter.c: Remove #if 0'd function it_is. (main): Remove #if 0'd code. diff --git a/sim/igen/gen-icache.c b/sim/igen/gen-icache.c index b6fc43c..783765b 100644 --- a/sim/igen/gen-icache.c +++ b/sim/igen/gen-icache.c @@ -424,6 +424,8 @@ print_icache_body (lf *file, cur_field->first < options.insn_bit_size; cur_field = cur_field->next) { + /* Always expand named fields (even if constant), so + references are valid. */ if (cur_field->type == insn_field_string) { cache_entry *cache_rule; diff --git a/sim/igen/gen-idecode.c b/sim/igen/gen-idecode.c index cb5ae54..b24a2eb 100644 --- a/sim/igen/gen-idecode.c +++ b/sim/igen/gen-idecode.c @@ -750,7 +750,13 @@ print_idecode_validate (lf *file, /* Only need to validate constant (and reserved) bits. Skip any others */ if (field->type != insn_field_int - && field->type != insn_field_reserved) + && field->type != insn_field_reserved + /* Consider a named field equal to a value to be just as + constant as an integer field. */ + && (field->type != insn_field_string + || field->conditions == NULL + || field->conditions->test != insn_field_cond_eq + || field->conditions->type != insn_field_cond_value)) continue; /* Look through the list of opcode paths that lead to this diff --git a/sim/igen/gen.c b/sim/igen/gen.c index 5c1b4be..9b76711 100644 --- a/sim/igen/gen.c +++ b/sim/igen/gen.c @@ -151,7 +151,9 @@ insn_field_cmp (insn_word_entry *l, insn_word_entry *r) return -1; /* The case of both fields having constant values should have already have been handled because such fields are converted - into normal constant fields. */ + into normal constant fields, but we must not make this + an assert, as we wouldn't gracefully handle an (invalid) + duplicate insn description. */ continue; } if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) @@ -611,6 +613,18 @@ insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr) bit->field->val_string)) /* a string field forced to constant? */ is_useless = 0; + else if (bit->field->conditions != NULL + && bit->field->conditions->test == insn_field_cond_eq + && bit->field->conditions->type == insn_field_cond_value) + { + int shift = bit->field->last - bit_nr; + int bitvalue = (bit->field->conditions->value >> shift) & 1; + + if (value < 0) + value = bitvalue; + else if (value != bitvalue) + is_useless = 0; + } else if (rule->search == decode_find_constants) /* the string field isn't constant */ return 1; |