+/* Find a match for INSN in the PREFIX opcode table. */
+
+static const struct powerpc_opcode *
+lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
+{
+ const struct powerpc_opcode *opcode, *opcode_end, *last;
+ unsigned long seg;
+
+ /* Get the opcode segment of the instruction. */
+ seg = PPC_PREFIX_SEG (insn);
+
+ /* Find the first match in the opcode table for this major opcode. */
+ opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
+ last = NULL;
+ for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
+ opcode < opcode_end;
+ ++opcode)
+ {
+ const unsigned char *opindex;
+ const struct powerpc_operand *operand;
+ int invalid;
+
+ if ((insn & opcode->mask) != opcode->opcode
+ || ((dialect & PPC_OPCODE_ANY) == 0
+ && ((opcode->flags & dialect) == 0
+ || (opcode->deprecated & dialect) != 0)))
+ continue;
+
+ /* Check validity of operands. */
+ invalid = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ operand = powerpc_operands + *opindex;
+ if (operand->extract)
+ (*operand->extract) (insn, dialect, &invalid);
+ }
+ if (invalid)
+ continue;
+
+ if ((dialect & PPC_OPCODE_RAW) == 0)
+ return opcode;
+
+ /* The raw machine insn is one that is not a specialization. */
+ if (last == NULL
+ || (last->mask & ~opcode->mask) != 0)
+ last = opcode;
+ }
+
+ return last;
+}
+