return false;
}
+static void
+print_insn_powerpc_opcode (struct disassemble_info *info,
+ bfd_vma memaddr, uint64_t insn, ppc_cpu_t dialect,
+ const struct powerpc_opcode *opcode)
+{
+ const ppc_opindex_t *opindex;
+ const struct powerpc_operand *operand;
+ enum {
+ need_comma = 0,
+ need_1space = 1,
+ need_2spaces = 2,
+ need_3spaces = 3,
+ need_4spaces = 4,
+ need_5spaces = 5,
+ need_6spaces = 6,
+ need_7spaces = 7,
+ need_paren
+ } op_separator;
+ bool skip_optional;
+ bool is_pcrel;
+ uint64_t d34;
+ int blanks;
+
+ (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
+ "%s", opcode->name);
+ /* gdb fprintf_styled_func doesn't return count printed. */
+ blanks = 8 - strlen (opcode->name);
+ if (blanks <= 0)
+ blanks = 1;
+
+ /* Now extract and print the operands. */
+ op_separator = blanks;
+ skip_optional = false;
+ is_pcrel = false;
+ d34 = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ int64_t value;
+
+ operand = powerpc_operands + *opindex;
+
+ /* If all of the optional operands past this one have their
+ default value, then don't print any of them. Except in
+ raw mode, print them all. */
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && (dialect & PPC_OPCODE_RAW) == 0)
+ {
+ if (!skip_optional)
+ skip_optional = skip_optional_operands (opindex, insn,
+ dialect, &is_pcrel);
+ if (skip_optional)
+ continue;
+ }
+
+ value = operand_value_powerpc (operand, insn, dialect);
+
+ if (op_separator == need_comma)
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
+ else if (op_separator == need_paren)
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
+ else
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
+ op_separator, " ");
+
+ /* Print the operand as directed by the flags. */
+ if ((operand->flags & PPC_OPERAND_GPR) != 0
+ || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "r%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_FPR) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "f%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_VR) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "v%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_VSR) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "vs%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_DMR) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "dm%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_ACC) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "a%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+ (*info->print_address_func) (memaddr + value, info);
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+ (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+ else if ((operand->flags & PPC_OPERAND_FSL) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "fsl%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_FCR) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "fcr%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_UDI) != 0)
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
+ && (operand->flags & PPC_OPERAND_CR_BIT) == 0
+ && (((dialect & PPC_OPCODE_PPC) != 0)
+ || ((dialect & PPC_OPCODE_VLE) != 0)))
+ (*info->fprintf_styled_func) (info->stream, dis_style_register,
+ "cr%" PRId64, value);
+ else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
+ && (operand->flags & PPC_OPERAND_CR_REG) == 0
+ && (((dialect & PPC_OPCODE_PPC) != 0)
+ || ((dialect & PPC_OPCODE_VLE) != 0)))
+ {
+ static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+ int cr;
+ int cc;
+
+ cr = value >> 2;
+ cc = value & 3;
+ if (cr != 0)
+ {
+ (*info->fprintf_styled_func) (info->stream, dis_style_text,
+ "4*");
+ (*info->fprintf_styled_func) (info->stream,
+ dis_style_register,
+ "cr%d", cr);
+ (*info->fprintf_styled_func) (info->stream, dis_style_text,
+ "+");
+ }
+
+ (*info->fprintf_styled_func) (info->stream,
+ dis_style_sub_mnemonic,
+ "%s", cbnames[cc]);
+ }
+ else
+ {
+ /* An immediate, but what style? */
+ enum disassembler_style style;
+
+ if ((operand->flags & PPC_OPERAND_PARENS) != 0)
+ style = dis_style_address_offset;
+ else
+ style = dis_style_immediate;
+
+ (*info->fprintf_styled_func) (info->stream, style,
+ "%" PRId64, value);
+ }
+
+ if (operand->shift == 52)
+ is_pcrel = value != 0;
+ else if (operand->bitm == UINT64_C (0x3ffffffff))
+ d34 = value;
+
+ if (op_separator == need_paren)
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
+
+ op_separator = need_comma;
+ if ((operand->flags & PPC_OPERAND_PARENS) != 0)
+ op_separator = need_paren;
+ }
+
+ if (is_pcrel)
+ {
+ d34 += memaddr;
+ (*info->fprintf_styled_func) (info->stream,
+ dis_style_comment_start,
+ "\t# %" PRIx64, d34);
+ asymbol *sym = (*info->symbol_at_address_func) (d34, info);
+ if (sym)
+ (*info->fprintf_styled_func) (info->stream, dis_style_text,
+ " <%s>", bfd_asymbol_name (sym));
+
+ if (info->private_data != NULL
+ && info->section != NULL
+ && info->section->owner != NULL
+ && (bfd_get_file_flags (info->section->owner)
+ & (EXEC_P | DYNAMIC)) != 0
+ && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
+ == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
+ {
+ for (int i = 0; i < 2; i++)
+ if (print_got_plt (private_data (info)->special + i, d34, info))
+ break;
+ }
+ }
+}
+
/* Print a PowerPC or POWER instruction. */
static int
opcode = lookup_lsp (insn, dialect);
}
- if (opcode != NULL)
+ if (opcode == NULL)
{
- const ppc_opindex_t *opindex;
- const struct powerpc_operand *operand;
- enum {
- need_comma = 0,
- need_1space = 1,
- need_2spaces = 2,
- need_3spaces = 3,
- need_4spaces = 4,
- need_5spaces = 5,
- need_6spaces = 6,
- need_7spaces = 7,
- need_paren
- } op_separator;
- bool skip_optional;
- bool is_pcrel;
- uint64_t d34;
- int blanks;
-
- (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
- "%s", opcode->name);
- /* gdb fprintf_styled_func doesn't return count printed. */
- blanks = 8 - strlen (opcode->name);
- if (blanks <= 0)
- blanks = 1;
-
- /* Now extract and print the operands. */
- op_separator = blanks;
- skip_optional = false;
- is_pcrel = false;
- d34 = 0;
- for (opindex = opcode->operands; *opindex != 0; opindex++)
- {
- int64_t value;
-
- operand = powerpc_operands + *opindex;
-
- /* If all of the optional operands past this one have their
- default value, then don't print any of them. Except in
- raw mode, print them all. */
- if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
- && (dialect & PPC_OPCODE_RAW) == 0)
- {
- if (!skip_optional)
- skip_optional = skip_optional_operands (opindex, insn,
- dialect, &is_pcrel);
- if (skip_optional)
- continue;
- }
-
- value = operand_value_powerpc (operand, insn, dialect);
-
- if (op_separator == need_comma)
- (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
- else if (op_separator == need_paren)
- (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
- else
- (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
- op_separator, " ");
-
- /* Print the operand as directed by the flags. */
- if ((operand->flags & PPC_OPERAND_GPR) != 0
- || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "r%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_FPR) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "f%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_VR) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "v%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_VSR) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "vs%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_DMR) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "dm%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_ACC) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "a%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
- (*info->print_address_func) (memaddr + value, info);
- else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
- (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
- else if ((operand->flags & PPC_OPERAND_FSL) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "fsl%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_FCR) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "fcr%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_UDI) != 0)
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
- && (operand->flags & PPC_OPERAND_CR_BIT) == 0
- && (((dialect & PPC_OPCODE_PPC) != 0)
- || ((dialect & PPC_OPCODE_VLE) != 0)))
- (*info->fprintf_styled_func) (info->stream, dis_style_register,
- "cr%" PRId64, value);
- else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
- && (operand->flags & PPC_OPERAND_CR_REG) == 0
- && (((dialect & PPC_OPCODE_PPC) != 0)
- || ((dialect & PPC_OPCODE_VLE) != 0)))
- {
- static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
- int cr;
- int cc;
-
- cr = value >> 2;
- cc = value & 3;
- if (cr != 0)
- {
- (*info->fprintf_styled_func) (info->stream, dis_style_text,
- "4*");
- (*info->fprintf_styled_func) (info->stream,
- dis_style_register,
- "cr%d", cr);
- (*info->fprintf_styled_func) (info->stream, dis_style_text,
- "+");
- }
-
- (*info->fprintf_styled_func) (info->stream,
- dis_style_sub_mnemonic,
- "%s", cbnames[cc]);
- }
- else
- {
- /* An immediate, but what style? */
- enum disassembler_style style;
-
- if ((operand->flags & PPC_OPERAND_PARENS) != 0)
- style = dis_style_address_offset;
- else
- style = dis_style_immediate;
-
- (*info->fprintf_styled_func) (info->stream, style,
- "%" PRId64, value);
- }
-
- if (operand->shift == 52)
- is_pcrel = value != 0;
- else if (operand->bitm == UINT64_C (0x3ffffffff))
- d34 = value;
-
- if (op_separator == need_paren)
- (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
-
- op_separator = need_comma;
- if ((operand->flags & PPC_OPERAND_PARENS) != 0)
- op_separator = need_paren;
- }
-
- if (is_pcrel)
+ if (insn_length == 4)
+ (*info->fprintf_styled_func) (info->stream,
+ dis_style_assembler_directive, ".long");
+ else
{
- d34 += memaddr;
(*info->fprintf_styled_func) (info->stream,
- dis_style_comment_start,
- "\t# %" PRIx64, d34);
- asymbol *sym = (*info->symbol_at_address_func) (d34, info);
- if (sym)
- (*info->fprintf_styled_func) (info->stream, dis_style_text,
- " <%s>", bfd_asymbol_name (sym));
-
- if (info->private_data != NULL
- && info->section != NULL
- && info->section->owner != NULL
- && (bfd_get_file_flags (info->section->owner)
- & (EXEC_P | DYNAMIC)) != 0
- && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
- == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
- {
- for (int i = 0; i < 2; i++)
- if (print_got_plt (private_data (info)->special + i, d34, info))
- break;
- }
+ dis_style_assembler_directive, ".word");
+ insn >>= 16;
}
-
- /* We have found and printed an instruction. */
- return insn_length;
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
+ (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
+ (unsigned int) insn);
}
-
- /* We could not find a match. */
- if (insn_length == 4)
- (*info->fprintf_styled_func) (info->stream,
- dis_style_assembler_directive, ".long");
else
- {
- (*info->fprintf_styled_func) (info->stream,
- dis_style_assembler_directive, ".word");
- insn >>= 16;
- }
- (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
- (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
- (unsigned int) insn);
-
+ print_insn_powerpc_opcode (info, memaddr, insn, dialect, opcode);
return insn_length;
}