From ec91d9bebf406b01b09054ddad77835c5aa8d276 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 29 May 2023 01:04:56 +0300 Subject: [PATCH] ppc/svp64: allow w/dw/sw macro expansion --- gas/config/tc-ppc-svp64.c | 73 +++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index f840da7b2fc..84512ff5932 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -148,6 +148,35 @@ svp64_setup_records (void) #define SVP64_SEP '/' +static inline char * +svp64_expression (char *str, expressionS *exp) +{ + char old_sep; + char *str_tail; + char *str_head = str; + char *old_ilp = input_line_pointer; + + memset (exp, 0, sizeof *exp); + + while (! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0') + ++str; + if (*str != '\0') + *str++ = '\0'; + str_tail = str; + old_sep = *str; + *str = '\0'; + str = str_head; + input_line_pointer = str; + + expression (exp); + resolve_register (exp); + + input_line_pointer = old_ilp; + *str_tail = old_sep; + + return ((exp->X_op == O_absent) ? str_head : str_tail); +} + struct svp64_predicate_map { const char *str; unsigned int len : 3; @@ -340,41 +369,39 @@ svp64_decode_vec (char *str, struct svp64_ctx *svp64) struct svp64_width_map { const char *str; - unsigned int len; - unsigned int width; + unsigned int len : 2; + unsigned int num : 6; + unsigned int width : 8; }; -#define SVP64_WIDTH_MAP(STR, WIDTH) \ - { STR, (sizeof (STR) - 1), WIDTH } +#define SVP64_WIDTH_MAP(NUM, WIDTH) \ + { #NUM, (sizeof (#NUM) - 1), NUM, WIDTH } static char * svp64_decode_width (char *str, unsigned int *width) { size_t i; + char *origin; + expressionS exp; static const struct svp64_width_map table[] = { - SVP64_WIDTH_MAP ("8", 3), - SVP64_WIDTH_MAP ("16", 2), - SVP64_WIDTH_MAP ("32", 1), + 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) + origin = str; + str = svp64_expression (str, &exp); + if ((str != origin) && (exp.X_op == O_constant)) { - 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') + for (i = 0; i < (sizeof (table) / sizeof (table[0])); ++i) { - str -= entry->len; - continue; - } - - *width = entry->width; - - *str++ = '\0'; + const struct svp64_width_map *entry = &table[i]; - return str; + if (entry->num == exp.X_add_number) + { + *width = entry->width; + return str; + } + } } return NULL; -- 2.30.2