+ if (ENABLE_CHECKING)
+ {
+ const unsigned char *o;
+ unsigned long omask = op->mask;
+
+ if (op != powerpc_opcodes)
+ {
+ /* The major opcodes had better be sorted. Code in the
+ disassembler assumes the insns are sorted according to
+ major opcode. */
+ if (PPC_OP (op[0].opcode) < PPC_OP (op[-1].opcode))
+ {
+ as_bad (_("major opcode is not sorted for %s"),
+ op->name);
+ bad_insn = TRUE;
+ }
+
+ /* Warn if the table isn't more strictly ordered.
+ Unfortunately it doesn't seem possible to order the
+ table on much more than the major opcode, which makes
+ it difficult to implement a binary search in the
+ disassembler. The problem is that we have multiple
+ ways to disassemble instructions, and we usually want
+ to choose a more specific form (with more bits set in
+ the opcode) than a more general form. eg. all of the
+ following are equivalent:
+ bne label # opcode = 0x40820000, mask = 0xff830003
+ bf 2,label # opcode = 0x40800000, mask = 0xff800003
+ bc 4,2,label # opcode = 0x40000000, mask = 0xfc000003
+
+ There are also cases where the table needs to be out
+ of order to disassemble the correct instruction for
+ processor variants. eg. "lhae" booke64 insn must be
+ found before "ld" ppc64 insn. */
+ else if (0)
+ {
+ unsigned long t1 = op[0].opcode;
+ unsigned long t2 = op[-1].opcode;
+
+ if (((t1 ^ t2) & 0xfc0007ff) == 0
+ && (t1 & 0xfc0006df) == 0x7c000286)
+ {
+ /* spr field is split. */
+ t1 = ((t1 & ~0x1ff800)
+ | ((t1 & 0xf800) << 5) | ((t1 & 0x1f0000) >> 5));
+ t2 = ((t2 & ~0x1ff800)
+ | ((t2 & 0xf800) << 5) | ((t2 & 0x1f0000) >> 5));
+ }
+ if (t1 < t2)
+ as_warn (_("%s (%08lx %08lx) after %s (%08lx %08lx)"),
+ op[0].name, op[0].opcode, op[0].mask,
+ op[-1].name, op[-1].opcode, op[-1].mask);
+ }
+ }
+
+ /* The mask had better not trim off opcode bits. */
+ if ((op->opcode & omask) != op->opcode)
+ {
+ as_bad (_("mask trims opcode bits for %s"),
+ op->name);
+ bad_insn = TRUE;
+ }
+
+ /* The operands must not overlap the opcode or each other. */
+ for (o = op->operands; *o; ++o)
+ if (*o >= num_powerpc_operands)
+ {
+ as_bad (_("operand index error for %s"),
+ op->name);
+ bad_insn = TRUE;
+ }
+ else
+ {
+ const struct powerpc_operand *operand = &powerpc_operands[*o];
+ if (operand->shift >= 0)
+ {
+ unsigned long mask = operand->bitm << operand->shift;
+ if (omask & mask)
+ {
+ as_bad (_("operand %d overlap in %s"),
+ (int) (o - op->operands), op->name);
+ bad_insn = TRUE;
+ }
+ omask |= mask;
+ }
+ }
+ }