From: Dmitry Selyutin Date: Tue, 11 Apr 2023 18:27:26 +0000 (+0300) Subject: ppc/svp64: disassemble ld/st imm mode X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a7d552643aa5e1374e6e28cec3b5f882f1b4c65b;p=binutils-gdb.git ppc/svp64: disassemble ld/st imm mode --- diff --git a/opcodes/ppc-svp64-dis.c b/opcodes/ppc-svp64-dis.c index d3c5b843408..137bdda4cdd 100644 --- a/opcodes/ppc-svp64-dis.c +++ b/opcodes/ppc-svp64-dis.c @@ -376,6 +376,14 @@ svp64_spec_width (const struct svp64_ctx *svp64, return len; } +static size_t +svp64_spec_els (struct disassemble_info *info, bool els) +{ + if (els) + return svp64_spec_printf (info, "els"); + return 0; +} + static size_t svp64_spec_normal (const struct svp64_ctx *svp64, struct disassemble_info *info) @@ -462,6 +470,91 @@ svp64_spec_normal_sat (const struct svp64_ctx *svp64, return len; } +static size_t +svp64_spec_ldst_imm (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + + len += svp64_spec_width (svp64, info); + len += svp64_spec_mask (svp64, info); + len += svp64_spec_vec (svp64, info); + + return len; +} + +static size_t +svp64_spec_ldst_imm_simple (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t zz = svp64_insn_get_prefix_rm_ldst_imm_simple_zz (&svp64->insn); + uint64_t els = svp64_insn_get_prefix_rm_ldst_imm_simple_els (&svp64->insn); + + len += svp64_spec_dz_sz_zz (info, zz, zz); + len += svp64_spec_els (info, els); + len += svp64_spec_ldst_imm (svp64, info); + + return len; +} + +static size_t +svp64_spec_ldst_imm_rsvd (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + (void)svp64; + (void)info; + + return 0; +} + +static size_t +svp64_spec_ldst_imm_ffrc1 (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t inv = svp64_insn_get_prefix_rm_ldst_imm_ffrc1_inv (&svp64->insn); + uint64_t CR = svp64_insn_get_prefix_rm_ldst_imm_ffrc1_CR (&svp64->insn); + + len += svp64_spec_ffrc1 (info, inv, CR); + len += svp64_spec_ldst_imm (svp64, info); + + return len; +} + +static size_t +svp64_spec_ldst_imm_ffrc0 (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t inv = svp64_insn_get_prefix_rm_ldst_imm_ffrc0_inv (&svp64->insn); + uint64_t els = svp64_insn_get_prefix_rm_ldst_imm_ffrc0_els (&svp64->insn); + uint64_t RC1 = svp64_insn_get_prefix_rm_ldst_imm_ffrc0_RC1 (&svp64->insn); + + len += svp64_spec_ffrc0 (info, inv, RC1); + len += svp64_spec_els (info, els); + len += svp64_spec_ldst_imm (svp64, info); + + return len; +} + +static size_t +svp64_spec_ldst_imm_sat (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t N = svp64_insn_get_prefix_rm_ldst_imm_sat_N (&svp64->insn); + uint64_t zz = svp64_insn_get_prefix_rm_ldst_imm_sat_zz (&svp64->insn); + uint64_t els = svp64_insn_get_prefix_rm_ldst_imm_sat_els (&svp64->insn); + + len += svp64_spec_sat (info, N); + len += svp64_spec_dz_sz_zz (info, zz, zz); + len += svp64_spec_els (info, els); + len += svp64_spec_normal (svp64, info); + + return len; +} + static size_t svp64_print_spec (const struct svp64_ctx *svp64, struct disassemble_info *info) @@ -475,8 +568,16 @@ svp64_print_spec (const struct svp64_ctx *svp64, {0x10, 0x31, svp64_spec_normal_ffrc0}, /* ffirst, Rc=0 */ {0x20, 0x30, svp64_spec_normal_sat}, /* saturation (no Rc) */ }; + static const struct svp64_spec_subtable ldst_imm[] = { + {0x00, 0x38, svp64_spec_ldst_imm_simple}, /* simple (no Rc) */ + {0x08, 0x38, svp64_spec_ldst_imm_rsvd}, /* rsvd (no Rc) */ + {0x11, 0x31, svp64_spec_ldst_imm_ffrc1}, /* ffirst, Rc=1 */ + {0x10, 0x31, svp64_spec_ldst_imm_ffrc0}, /* ffirst, Rc=0 */ + {0x20, 0x30, svp64_spec_ldst_imm_sat}, /* saturation (no Rc) */ + }; static const struct svp64_spec_table tables[] = { [SVP64_MODE_NORMAL] = {normal, ARRAY_SIZE (normal)}, + [SVP64_MODE_LDST_IMM] = {ldst_imm, ARRAY_SIZE (ldst_imm)}, }; const struct svp64_spec_table *table = &tables[svp64->desc->mode]; uint64_t mode = svp64_insn_get_prefix_rm_mode (&svp64->insn);