/* The IGEN simulator generator for GDB, the GNU Debugger.
- Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright 2002-2020 Free Software Foundation, Inc.
Contributed by Andrew Cagney.
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)
/****************************************************************/
-#if 0
-typedef enum
-{
- field_is_not_constant = 0,
- field_constant_int = 1,
- field_constant_reserved = 2,
- field_constant_string = 3
-}
-constant_field_types;
-
-static constant_field_types
-insn_field_is_constant (insn_field * field, decode_table *rule)
-{
- switch (field->type)
- {
- case insn_field_int:
- /* field is an integer */
- return field_constant_int;
- case insn_field_reserved:
- /* field is `/' and treating that as a constant */
- if (rule->with_zero_reserved)
- return field_constant_reserved;
- else
- return field_is_not_constant;
- case insn_field_wild:
- return field_is_not_constant; /* never constant */
- case insn_field_string:
- /* field, though variable, is on the list of forced constants */
- if (filter_is_member (rule->constant_field_names, field->val_string))
- return field_constant_string;
- else
- return field_is_not_constant;
- }
- ERROR ("Internal error");
- return field_is_not_constant;
-}
-#endif
-
-
-/****************************************************************/
-
-
/* Is the bit, according to the decode rule, identical across all the
instructions? */
static int
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;
break;
}
-
-#if 0
- for (entry = insns; entry != NULL; entry = entry->next)
- {
- insn_word_entry *fields = entry->insn->word[rule->word_nr];
- opcode_field new_opcode;
-
- ASSERT (fields != NULL);
-
- /* find a start point for the opcode field */
- new_opcode.first = rule->first;
- while (new_opcode.first <= rule->last
- && (!string_only
- ||
- (insn_field_is_constant (fields->bit[new_opcode.first], rule)
- != field_constant_string)) && (string_only
- ||
- (insn_field_is_constant
- (fields->
- bit[new_opcode.first],
- rule) ==
- field_is_not_constant)))
- {
- int new_first = fields->bit[new_opcode.first]->last + 1;
- ASSERT (new_first > new_opcode.first);
- new_opcode.first = new_first;
- }
- ASSERT (new_opcode.first > rule->last
- || (string_only
- && insn_field_is_constant (fields->bit[new_opcode.first],
- rule) == field_constant_string)
- || (!string_only
- && insn_field_is_constant (fields->bit[new_opcode.first],
- rule)));
-
- /* find the end point for the opcode field */
- new_opcode.last = rule->last;
- while (new_opcode.last >= rule->first
- && (!string_only
- || insn_field_is_constant (fields->bit[new_opcode.last],
- rule) != field_constant_string)
- && (string_only
- || !insn_field_is_constant (fields->bit[new_opcode.last],
- rule)))
- {
- int new_last = fields->bit[new_opcode.last]->first - 1;
- ASSERT (new_last < new_opcode.last);
- new_opcode.last = new_last;
- }
- ASSERT (new_opcode.last < rule->first
- || (string_only
- && insn_field_is_constant (fields->bit[new_opcode.last],
- rule) == field_constant_string)
- || (!string_only
- && insn_field_is_constant (fields->bit[new_opcode.last],
- rule)));
-
- /* now see if our current opcode needs expanding to include the
- interesting fields within this instruction */
- if (new_opcode.first <= rule->last
- && curr_opcode.first > new_opcode.first)
- curr_opcode.first = new_opcode.first;
- if (new_opcode.last >= rule->first
- && curr_opcode.last < new_opcode.last)
- curr_opcode.last = new_opcode.last;
-
- }
-#endif
-
/* did the final opcode field end up being empty? */
if (curr_opcode.first > curr_opcode.last)
{