From 158900a5d6a810f0f9675b77a4a27c473b161a29 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 29 May 2023 01:04:57 +0300 Subject: [PATCH] ppc/svp64: disassemble SVP64 operands --- opcodes/ppc-dis.c | 130 +++++++++++++++++++++++----------------- opcodes/ppc-svp64-dis.c | 78 ++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 54 deletions(-) diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index a19b2a84061..adfd19d44ee 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -989,6 +989,7 @@ print_insn_powerpc_opcode (struct disassemble_info *info, d34 = 0; for (opindex = opcode->operands; *opindex != 0; opindex++) { + bool vector; int64_t value; operand = powerpc_operands + *opindex; @@ -1006,7 +1007,13 @@ print_insn_powerpc_opcode (struct disassemble_info *info, continue; } + vector = false; value = operand_value_powerpc (operand, insn, dialect); + if (svp64) + { + value = svp64_operand_value (svp64, + value, *opindex, operand->flags, &vector); + } if (op_separator == need_comma) (*info->fprintf_styled_func) (info->stream, dis_style_text, ","); @@ -1016,65 +1023,80 @@ print_insn_powerpc_opcode (struct disassemble_info *info, (*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; + /* 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, + "%sr%" PRId64, + (vector ? "*" : ""), value); + else if ((operand->flags & PPC_OPERAND_FPR) != 0) + (*info->fprintf_styled_func) (info->stream, dis_style_register, + "%sf%" PRId64, + (vector ? "*" : ""), 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, - "+"); + if (svp64) + { + (*info->fprintf_styled_func) (info->stream, + dis_style_register, + "%scr%d", + (vector ? "*" : ""), + cr); + (*info->fprintf_styled_func) (info->stream, dis_style_text, + "."); + } + else + { + (*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, diff --git a/opcodes/ppc-svp64-dis.c b/opcodes/ppc-svp64-dis.c index 2ffecff825a..9e6f96b8fa8 100644 --- a/opcodes/ppc-svp64-dis.c +++ b/opcodes/ppc-svp64-dis.c @@ -119,3 +119,81 @@ svp64_lookup (uint64_t insn, ppc_cpu_t dialect, return opcode; } + +static int64_t +svp64_operand_value_common (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, bool *vector, + int vector_shift, int scalar_shift, int spec_shift) +{ + uint64_t spec; + const struct svp64_extra_desc *desc; + + desc = svp64_extra_desc (svp64->desc, opindex); + spec = (*desc->get) (&svp64->insn); + + if (spec == 0) + return value; + + *vector = (((spec >> 2) & 1) != 0); + if (svp64->desc->etype == SVP64_ETYPE_EXTRA2) + spec <<= 1; + + spec = (spec & 0x3); + + if (*vector) + value = ((value << vector_shift) | (spec << spec_shift)); + else + value = ((spec << scalar_shift) | value); + + return value; +} + +static int64_t +svp64_operand_value_gpr (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, bool *vector) +{ + return svp64_operand_value_common (svp64, value, opindex, vector, 2, 5, 0); +} + +static int64_t +svp64_operand_value_fpr (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, bool *vector) +{ + return svp64_operand_value_common (svp64, value, opindex, vector, 2, 5, 0); +} + +static int64_t +svp64_operand_value_cr_reg (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, bool *vector) +{ + return svp64_operand_value_common (svp64, value, opindex, vector, 4, 3, 2); +} + +static int64_t +svp64_operand_value_cr_bit (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, bool *vector) +{ + uint64_t bits = (value & 0x3); + + value >>= 2; + value = svp64_operand_value_common (svp64, value, opindex, vector, 4, 3, 2); + value = ((value << 2) | bits); + + return value; +} + +static int64_t +svp64_operand_value (const struct svp64_ctx *svp64, + int64_t value, ppc_opindex_t opindex, uint64_t flags, bool *vector) +{ + if (flags & (PPC_OPERAND_GPR | PPC_OPERAND_GPR_0)) + return svp64_operand_value_gpr (svp64, value, opindex, vector); + else if (flags & PPC_OPERAND_FPR) + return svp64_operand_value_fpr (svp64, value, opindex, vector); + else if (flags & PPC_OPERAND_CR_REG) + return svp64_operand_value_cr_reg (svp64, value, opindex, vector); + else if (flags & PPC_OPERAND_CR_BIT) + return svp64_operand_value_cr_bit (svp64, value, opindex, vector); + else + return value; +} -- 2.30.2