+/* Return TRUE when two classes are not opcode conflicting. */
+
+static bfd_boolean
+is_compatible_p (insn_class_t classA,
+ insn_subclass_t sclassA,
+ insn_class_t classB,
+ insn_subclass_t sclassB)
+{
+ if (classA == DSP && sclassB == DPX)
+ return FALSE;
+ if (sclassA == DPX && classB == DSP)
+ return FALSE;
+ return TRUE;
+}
+
+/* Add a new element to the decode list. */
+
+static void
+add_to_decodelist (insn_class_t insn_class,
+ insn_subclass_t subclass)
+{
+ linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
+
+ t->insn_class = insn_class;
+ t->subclass = subclass;
+ t->nxt = decodelist;
+ decodelist = t;
+}
+
+/* Return TRUE if we need to skip the opcode from being
+ disassembled. */
+
+static bfd_boolean
+skip_this_opcode (const struct arc_opcode * opcode,
+ struct disassemble_info * info)
+{
+ linkclass t = decodelist;
+ bfd_boolean addme = TRUE;
+
+ /* Check opcode for major 0x06, return if it is not in. */
+ if (OPCODE (opcode->opcode) != 0x06)
+ return FALSE;
+
+ while (t != NULL
+ && is_compatible_p (t->insn_class, t->subclass,
+ opcode->insn_class, opcode->subclass))
+ {
+ if ((t->insn_class == opcode->insn_class)
+ && (t->subclass == opcode->subclass))
+ addme = FALSE;
+ t = t->nxt;
+ }
+
+ /* If we found an incompatibility then we must skip. */
+ if (t != NULL)
+ return TRUE;
+
+ /* Even if we do not precisely know the if the right mnemonics
+ is correctly displayed, keep the disassmbled code class
+ consistent. */
+ if (addme)
+ {
+ switch (opcode->insn_class)
+ {
+ case DSP:
+ case FLOAT:
+ /* Add to the conflict list only the classes which
+ counts. */
+ add_to_decodelist (opcode->insn_class, opcode->subclass);
+ /* Warn if we have to decode an opcode and no preferred
+ classes have been chosen. */
+ info->fprintf_func (info->stream, _("\n\
+Warning: disassembly may be wrong due to guessed opcode class choice.\n\
+ Use -M<class[,class]> to select the correct opcode class(es).\n\t\t\t\t"));
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}
+