aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/igen/ChangeLog11
-rw-r--r--sim/igen/gen-icache.c2
-rw-r--r--sim/igen/gen-idecode.c8
-rw-r--r--sim/igen/gen.c16
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;