From: Dmitry Selyutin Date: Sun, 28 May 2023 22:04:57 +0000 (+0300) Subject: ppc/svp64: disassemble branch mode X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7fb9b6b71a00795b8adbe591b5575a93f962843d;p=binutils-gdb.git ppc/svp64: disassemble branch mode --- diff --git a/opcodes/ppc-svp64-dis.c b/opcodes/ppc-svp64-dis.c index d34748bcf5d..05a22f2fdf7 100644 --- a/opcodes/ppc-svp64-dis.c +++ b/opcodes/ppc-svp64-dis.c @@ -708,6 +708,104 @@ svp64_spec_crop_ff5 (const struct svp64_ctx *svp64, return len; } +static size_t +svp64_spec_branch (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t ALL = svp64_insn_get_prefix_rm_branch_ALL (&svp64->insn); + uint64_t SNZ = svp64_insn_get_prefix_rm_branch_SNZ (&svp64->insn); + uint64_t SL = svp64_insn_get_prefix_rm_branch_SL (&svp64->insn); + uint64_t SLu = svp64_insn_get_prefix_rm_branch_SLu (&svp64->insn); + uint64_t LRu = svp64_insn_get_prefix_rm_branch_LRu (&svp64->insn); + uint64_t sz = svp64_insn_get_prefix_rm_branch_sz (&svp64->insn); + uint64_t CR = svp64_insn_get_prefix_rm_mmode (&svp64->insn); + uint64_t m = svp64_insn_get_prefix_rm_mask (&svp64->insn); + + if (ALL) + len += svp64_spec_printf (info, "all"); + + len += svp64_spec_dz_sz_zz_SNZ (info, false, sz, SNZ); + + if (SL) + len += svp64_spec_printf (info, "sl"); + if (SLu) + len += svp64_spec_printf (info, "slu"); + if (LRu) + len += svp64_spec_printf (info, "lru"); + + if (m) + len += svp64_spec_printf (info, "m=%s", svp64_predicate (CR, m)); + + len += svp64_spec_vec (svp64, info); + + return len; +} + +static size_t +svp64_spec_branch_VSb_VLi (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + uint64_t VSb = svp64_insn_get_prefix_rm_branch_vls_VSb (&svp64->insn); + uint64_t VLi = svp64_insn_get_prefix_rm_branch_vls_VLi (&svp64->insn); + static const char *const table[] = {"vs", "vsi", "vsb", "vsbi"}; + + return svp64_spec_printf (info, table[((VSb << 1) | (VLi << 0))]); +} + +static size_t +svp64_spec_branch_CTi (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + uint64_t CTi = svp64_insn_get_prefix_rm_branch_ctr_CTi (&svp64->insn); + + return svp64_spec_printf (info, (CTi ? "cti" : "ctr")); +} + +static size_t +svp64_spec_branch_simple (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + return svp64_spec_branch (svp64, info); +} + +static size_t +svp64_spec_branch_vls (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + + len += svp64_spec_branch_VSb_VLi (svp64, info); + len += svp64_spec_branch (svp64, info); + + return len; +} + +static size_t +svp64_spec_branch_ctr (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + + len += svp64_spec_branch_CTi (svp64, info); + len += svp64_spec_branch (svp64, info); + + return len; +} + +static size_t +svp64_spec_branch_ctrvls (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + + len += svp64_spec_branch_VSb_VLi (svp64, info); + len += svp64_spec_branch_CTi (svp64, info); + len += svp64_spec_branch (svp64, info); + + return len; +} + static size_t svp64_print_spec (const struct svp64_ctx *svp64, struct disassemble_info *info) @@ -738,11 +836,18 @@ svp64_print_spec (const struct svp64_ctx *svp64, {0x21, 0x21, svp64_spec_crop_ff3}, /* failfirst, 3-bit CR */ {0x20, 0x20, svp64_spec_crop_ff5}, /* failfirst, 5-bit CR */ }; + static const struct svp64_spec_subtable branch[] = { + {0x00, 0x03, svp64_spec_branch_simple}, /* simple */ + {0x01, 0x03, svp64_spec_branch_vls}, /* VLset */ + {0x02, 0x03, svp64_spec_branch_ctr}, /* CTR mode */ + {0x03, 0x03, svp64_spec_branch_ctrvls}, /* CTR+VLset mode */ + }; static const struct svp64_spec_table tables[] = { [SVP64_MODE_NORMAL] = {normal, ARRAY_SIZE (normal)}, [SVP64_MODE_LDST_IMM] = {ldst_imm, ARRAY_SIZE (ldst_imm)}, [SVP64_MODE_LDST_IDX] = {ldst_idx, ARRAY_SIZE (ldst_idx)}, [SVP64_MODE_CROP] = {crop, ARRAY_SIZE (crop)}, + [SVP64_MODE_BRANCH] = {branch, ARRAY_SIZE (branch)}, }; const struct svp64_spec_table *table = &tables[svp64->desc->mode]; uint64_t mode = svp64_insn_get_prefix_rm_mode (&svp64->insn);