From a837882cd40cf63ff28547ba0e71bf396459b974 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Sun, 19 Jun 2022 11:06:19 +0300 Subject: [PATCH] ppc/svp64: support w/dw/sw modes --- gas/config/tc-ppc-svp64.c | 174 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index cae359f1f00..76189b56e26 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -32,6 +32,14 @@ struct svp64_ctx { unsigned int has_smask : 1; unsigned int mask_m_specified : 1; unsigned int subvl : 2; + unsigned int destwid : 2; + unsigned int srcwid : 2; + unsigned int ldst_elstride : 1; + unsigned int sv_mode_explicit : 1; + unsigned int sv_mode : 2; + unsigned int sat : 1; + unsigned int src_zero : 1; + unsigned int dst_zero : 1; }; static jmp_buf svp64_exception; @@ -242,6 +250,164 @@ svp64_decode_vec (char *str, struct svp64_ctx *svp64) return str; } +struct svp64_width_map { + const char *str; + unsigned int len; + unsigned int width; +}; +#define SVP64_WIDTH_MAP(STR, WIDTH) \ + { STR, (sizeof (STR) - 1), WIDTH } + +static char * +svp64_decode_width (char *str, unsigned int *width) +{ + size_t i; + static const struct svp64_width_map table[] = { + SVP64_WIDTH_MAP ("8", 3), + SVP64_WIDTH_MAP ("16", 2), + SVP64_WIDTH_MAP ("32", 1), + }; + + for (i = 0; i < (sizeof (table) / sizeof (table[0])); ++i) + { + const struct svp64_width_map *entry = &table[i]; + + if (strncmp (str, entry->str, entry->len) != 0) + continue; + + str += entry->len; + if (! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + { + str -= entry->len; + continue; + } + + *width = entry->width; + + *str++ = '\0'; + + return str; + } + + return NULL; +} + +static char * +svp64_decode_w (char *str, struct svp64_ctx *svp64) +{ + char *iter; + unsigned int width; + + str += (sizeof ("w=") - 1); + iter = svp64_decode_width (str, &width); + if (!iter) + svp64_raise (_("unrecognized mode: `%s'"), str); + + svp64->srcwid = width; + svp64->destwid = width; + + return iter; +} + +static char * +svp64_decode_dw (char *str, struct svp64_ctx *svp64) +{ + char *iter; + unsigned int width; + + str += (sizeof ("dw=") - 1); + iter = svp64_decode_width (str, &width); + if (!iter) + svp64_raise (_("unrecognized mode: `%s'"), str); + + svp64->destwid = width; + + return iter; +} + +static char * +svp64_decode_sw (char *str, struct svp64_ctx *svp64) +{ + char *iter; + unsigned int width; + + str += (sizeof ("sw=") - 1); + iter = svp64_decode_width (str, &width); + if (!iter) + svp64_raise (_("unrecognized mode: `%s'"), str); + + svp64->srcwid = width; + + return iter; +} + +static char * +svp64_decode_els (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("els") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64->ldst_elstride = 1; + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_sat (char *str, struct svp64_ctx *svp64) +{ + unsigned char mode; + + str += (sizeof ("sat") - 1); + if ((*str != 's') && (*str != 'u')) + return NULL; + + mode = *str++; + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + if (svp64->sv_mode_explicit) + svp64_raise (_("SV mode conflict: `%s'"), str); + + svp64->sv_mode_explicit = 1; + svp64->sv_mode = 2; + svp64->sat = (mode == 's'); + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_sz (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("sz") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64->src_zero = 1; + + *str++ = '\0'; + + return str; +} + +static char * +svp64_decode_dz (char *str, struct svp64_ctx *svp64) +{ + str += (sizeof ("dz") - 1); + if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + return NULL; + + svp64->dst_zero = 1; + + *str++ = '\0'; + + return str; +} + static char * svp64_decode_mode (char *str, struct svp64_ctx *svp64) { @@ -253,6 +419,14 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64) SVP64_DECODER ("vec2", svp64_decode_vec), SVP64_DECODER ("vec3", svp64_decode_vec), SVP64_DECODER ("vec4", svp64_decode_vec), + SVP64_DECODER ("w=" , svp64_decode_w), + SVP64_DECODER ("dw=" , svp64_decode_dw), + SVP64_DECODER ("sw=" , svp64_decode_sw), + SVP64_DECODER ("els" , svp64_decode_els), + SVP64_DECODER ("sats", svp64_decode_sat), + SVP64_DECODER ("satu", svp64_decode_sat), + SVP64_DECODER ("sz" , svp64_decode_sz), + SVP64_DECODER ("dz" , svp64_decode_dz), }; for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i) -- 2.30.2