From 088852fce21e2f54336ccc89b386fa9c7f63b2e3 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 29 May 2023 01:04:57 +0300 Subject: [PATCH] svp64: sync specifiers --- gas/config/tc-ppc-svp64.c | 225 ++++++++++++++++++++++++++++++++++++- include/opcode/ppc-svp64.h | 19 ++-- opcodes/ppc-svp64-dis.c | 71 ++++++++---- 3 files changed, 278 insertions(+), 37 deletions(-) diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index e91da81dba9..20b2bc1cafe 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -740,6 +740,211 @@ svp64_decode_crm (char *str, struct svp64_ctx *svp64) return str; } +static char * +svp64_decode_all (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("all") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_ALL (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_snz (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("snz") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_SNZ (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_sl (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("sl") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_SL (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_slu (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("slu") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_SLu (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_lru (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("lru") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_LRu (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_vs (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("vs") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_vls_VSb (&svp64->insn, 0); + svp64_insn_set_prefix_rm_branch_vls_VLi (&svp64->insn, 0); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_vsi (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("vsi") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_vls_VSb (&svp64->insn, 0); + svp64_insn_set_prefix_rm_branch_vls_VLi (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_vsb (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("vsb") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_vls_VSb (&svp64->insn, 1); + svp64_insn_set_prefix_rm_branch_vls_VLi (&svp64->insn, 0); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_vsbi (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("vsbi") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_vls_VSb (&svp64->insn, 1); + svp64_insn_set_prefix_rm_branch_vls_VLi (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_vli (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("vli") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_vls_VLi (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_ctr (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("ctr") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_ctr_CTR (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_cti (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("cti") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_branch_ctr_CTR (&svp64->insn, 1); + svp64_insn_set_prefix_rm_branch_ctr_CTi (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_pi (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("pi") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_ldst_imm_post_mode (&svp64->insn, 0x4); + svp64_insn_set_prefix_rm_ldst_imm_post_pi (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_lf (char *str, struct svp64_ctx *svp64) +{ + uint64_t mode = svp64_insn_get_prefix_rm_ldst_imm_post_mode (&svp64->insn); + + str += (sizeof ("lf") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64_insn_set_prefix_rm_ldst_imm_post_mode (&svp64->insn, (mode | 0x4)); + svp64_insn_set_prefix_rm_ldst_imm_post_lf (&svp64->insn, 1); + + *str++ = '\0'; + + return str; +} + static char * svp64_decode_mode (char *str, struct svp64_ctx *svp64) { @@ -765,6 +970,20 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64) SVP64_DECODER ("mrr" , svp64_decode_mrr), SVP64_DECODER ("mr" , svp64_decode_mr), SVP64_DECODER ("crm" , svp64_decode_crm), + SVP64_DECODER ("all" , svp64_decode_all), + SVP64_DECODER ("snz" , svp64_decode_snz), + SVP64_DECODER ("sl" , svp64_decode_sl), + SVP64_DECODER ("slu" , svp64_decode_slu), + SVP64_DECODER ("lru" , svp64_decode_lru), + SVP64_DECODER ("vs" , svp64_decode_vs), + SVP64_DECODER ("vsi" , svp64_decode_vsi), + SVP64_DECODER ("vsb" , svp64_decode_vsb), + SVP64_DECODER ("vsbi", svp64_decode_vsbi), + SVP64_DECODER ("vli" , svp64_decode_vli), + SVP64_DECODER ("ctr" , svp64_decode_ctr), + SVP64_DECODER ("cti" , svp64_decode_cti), + SVP64_DECODER ("pi" , svp64_decode_pi), + SVP64_DECODER ("lf" , svp64_decode_lf), }; for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i) @@ -827,11 +1046,7 @@ svp64_validate_and_fix_mode_bc (struct svp64_ctx *svp64) * Create mode and (overridden) src/dst widths. * TODO: sanity-check BC modes. */ - svp64->sv_mode = ((svp64->bc_svstep << SVP64_MODE_MOD2_MSB) | - (svp64->bc_vlset << SVP64_MODE_MOD2_LSB) | - (svp64->bc_snz << SVP64_MODE_BC_SNZ)); - svp64->srcwid = ((svp64->bc_vsb << 1) | svp64->bc_lru); - svp64->destwid = ((svp64->bc_lru << 1) | svp64->bc_all); + (void)svp64; } static void diff --git a/include/opcode/ppc-svp64.h b/include/opcode/ppc-svp64.h index e90d38bfbf6..de39810eefd 100644 --- a/include/opcode/ppc-svp64.h +++ b/include/opcode/ppc-svp64.h @@ -64,14 +64,17 @@ struct svp64_ctx { unsigned int mr : 1; unsigned int RG : 1; unsigned int crm : 1; - unsigned int bc_all : 1; - unsigned int bc_lru : 1; - unsigned int bc_brc : 1; - unsigned int bc_svstep : 1; - unsigned int bc_vsb : 1; - unsigned int bc_vlset : 1; - unsigned int bc_vli : 1; - unsigned int bc_snz : 1; + + unsigned int all : 1; + unsigned int snz : 1; + unsigned int sl : 1; + unsigned int slu : 1; + unsigned int lru : 1; + unsigned int vls : 1; + unsigned int vsb : 1; + unsigned int vli : 1; + unsigned int ctr : 1; + unsigned int cti : 1; }; #define SVP64_RC1_ACTIVE (1U << 3U) diff --git a/opcodes/ppc-svp64-dis.c b/opcodes/ppc-svp64-dis.c index 05a22f2fdf7..05e666f7551 100644 --- a/opcodes/ppc-svp64-dis.c +++ b/opcodes/ppc-svp64-dis.c @@ -527,11 +527,17 @@ svp64_spec_ldst_imm_simple (const struct svp64_ctx *svp64, } static size_t -svp64_spec_ldst_imm_rsvd (const struct svp64_ctx *svp64, +svp64_spec_ldst_imm_post (const struct svp64_ctx *svp64, struct disassemble_info *info) { - (void)svp64; - (void)info; + size_t len = 0; + uint64_t pi = svp64_insn_get_prefix_rm_ldst_imm_post_pi (&svp64->insn); + uint64_t lf = svp64_insn_get_prefix_rm_ldst_imm_post_lf (&svp64->insn); + + if (pi) + len += svp64_spec_printf (info, "pi"); + if (lf) + len += svp64_spec_printf (info, "lf"); return 0; } @@ -613,7 +619,23 @@ svp64_spec_ldst_idx_simple (const struct svp64_ctx *svp64, } static size_t -svp64_spec_ldst_idx_sat (const struct svp64_ctx *svp64, +svp64_spec_ldst_idx_ffrc1 (const struct svp64_ctx *svp64, + struct disassemble_info *info) +{ + size_t len = 0; + uint64_t N = svp64_insn_get_prefix_rm_ldst_idx_sat_N (&svp64->insn); + uint64_t dz = svp64_insn_get_prefix_rm_ldst_idx_sat_dz (&svp64->insn); + uint64_t sz = svp64_insn_get_prefix_rm_ldst_idx_sat_sz (&svp64->insn); + + len += svp64_spec_sat (info, N); + len += svp64_spec_dz_sz_zz (info, dz, sz); + len += svp64_spec_ldst_idx (svp64, info); + + return len; +} + +static size_t +svp64_spec_ldst_idx_ffrc0 (const struct svp64_ctx *svp64, struct disassemble_info *info) { size_t len = 0; @@ -813,34 +835,35 @@ svp64_print_spec (const struct svp64_ctx *svp64, size_t idx; uint64_t match; static const struct svp64_spec_subtable normal[] = { - {0x00, 0x38, svp64_spec_normal_simple}, /* simple (no Rc) */ - {0x08, 0x38, svp64_spec_normal_mr}, /* mapreduce (no Rc) */ - {0x11, 0x31, svp64_spec_normal_ffrc1}, /* ffirst, Rc=1 */ - {0x10, 0x31, svp64_spec_normal_ffrc0}, /* ffirst, Rc=0 */ - {0x20, 0x30, svp64_spec_normal_sat}, /* saturation (no Rc) */ + {0x00, 0x38, svp64_spec_normal_simple}, /* simple (no Rc) */ + {0x08, 0x38, svp64_spec_normal_mr}, /* mapreduce (no Rc) */ + {0x11, 0x31, svp64_spec_normal_ffrc1}, /* ffirst, Rc=1 */ + {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) */ + {0x00, 0x38, svp64_spec_ldst_imm_simple}, /* simple (no Rc) */ + {0x08, 0x38, svp64_spec_ldst_imm_post}, /* post (no Rc) */ + {0x11, 0x11, svp64_spec_ldst_imm_ffrc1}, /* ffirst, Rc=1 */ + {0x10, 0x11, svp64_spec_ldst_imm_ffrc0}, /* ffirst, Rc=0 */ + {0x20, 0x30, svp64_spec_ldst_imm_sat}, /* saturation (no Rc) */ }; static const struct svp64_spec_subtable ldst_idx[] = { - {0x00, 0x30, svp64_spec_ldst_idx_simple}, /* simple (no Rc) */ - {0x20, 0x30, svp64_spec_ldst_idx_sat}, /* saturation (no Rc) */ + {0x00, 0x10, svp64_spec_ldst_idx_simple}, /* simple (no Rc) */ + {0x11, 0x11, svp64_spec_ldst_idx_ffrc1}, /* ffirst, Rc=1 */ + {0x10, 0x11, svp64_spec_ldst_idx_ffrc0}, /* ffirst, Rc=0 */ }; static const struct svp64_spec_subtable crop[] = { - {0x00, 0x38, svp64_spec_crop_simple}, /* simple */ - {0x08, 0x38, svp64_spec_crop_mr}, /* mapreduce */ - {0x21, 0x21, svp64_spec_crop_ff3}, /* failfirst, 3-bit CR */ - {0x20, 0x20, svp64_spec_crop_ff5}, /* failfirst, 5-bit CR */ + {0x00, 0x38, svp64_spec_crop_simple}, /* simple */ + {0x08, 0x38, svp64_spec_crop_mr}, /* mapreduce */ + {0x21, 0x21, svp64_spec_crop_ff3}, /* ffirst, 3-bit CR */ + {0x20, 0x20, svp64_spec_crop_ff5}, /* ffirst, 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 */ + {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)}, -- 2.30.2