From: Dmitry Selyutin Date: Mon, 25 Jul 2022 19:21:38 +0000 (+0300) Subject: ppc/svp64: determine instruction type X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=edec9886672486ecf51db2364f146e421c9d0c54;p=binutils-gdb.git ppc/svp64: determine instruction type --- diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index f0427976c24..7b43a37c138 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -46,11 +46,19 @@ struct svp64_ctx { unsigned int rg : 1; unsigned int crm : 1; unsigned int svm : 1; + unsigned int type : 2; }; #define SVP64_RC1_ACTIVE (1U << 3U) #define SVP64_RC1_INVERT (SVP64_RC1_ACTIVE | (1U << 4U)) +enum svp64_type { + SVP64_TYPE_NONE, + SVP64_TYPE_LD, + SVP64_TYPE_ST, + SVP64_TYPE_BC, +}; + static jmp_buf svp64_exception; #define svp64_raise(...) \ @@ -565,10 +573,151 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64) return NULL; } +struct svp64_str_map { + const char *str; + size_t len; +}; +#define SVP64_STR_MAP(STR) \ + { STR, (sizeof (STR) - 1) } + +static bool +svp64_str_map_cmp(const char *str, size_t len, + const struct svp64_str_map *map, size_t cnt) +{ + size_t i; + + for (i = 0; i < cnt; ++i) { + const struct svp64_str_map *entry = &map[i]; + + if ((entry->len == len) && (memcmp(entry->str, str, len) == 0)) + return true; + } + + return false; +} +#define SVP64_STR_MAP_CMP(STR, LEN, MAP) \ + svp64_str_map_cmp(STR, LEN, MAP, (sizeof (MAP) / sizeof (*MAP))) + +static bool +svp64_is_ld(const char *str, size_t len) +{ + static const struct svp64_str_map table[] = { + /* load byte */ + SVP64_STR_MAP ("lbarx"), + SVP64_STR_MAP ("lbz"), + SVP64_STR_MAP ("lbzu"), + SVP64_STR_MAP ("lbzux"), + SVP64_STR_MAP ("lbzx"), + /* load double */ + SVP64_STR_MAP ("ld"), + SVP64_STR_MAP ("ldarx"), + SVP64_STR_MAP ("ldbrx"), + SVP64_STR_MAP ("ldu"), + SVP64_STR_MAP ("ldux"), + SVP64_STR_MAP ("ldx"), + /* FP load single */ + SVP64_STR_MAP ("lfs"), + SVP64_STR_MAP ("lfsx"), + SVP64_STR_MAP ("lfsu"), + SVP64_STR_MAP ("lfsux"), + /* FP load double */ + SVP64_STR_MAP ("lfd"), + SVP64_STR_MAP ("lfdx"), + SVP64_STR_MAP ("lfdu"), + SVP64_STR_MAP ("lfdux"), + SVP64_STR_MAP ("lfiwzx"), + SVP64_STR_MAP ("lfiwax"), + /* load half */ + SVP64_STR_MAP ("lha"), + SVP64_STR_MAP ("lharx"), + SVP64_STR_MAP ("lhau"), + SVP64_STR_MAP ("lhaux"), + SVP64_STR_MAP ("lhax"), + SVP64_STR_MAP ("lhbrx"), + SVP64_STR_MAP ("lhz"), + SVP64_STR_MAP ("lhzu"), + SVP64_STR_MAP ("lhzux"), + SVP64_STR_MAP ("lhzx"), + /* load word */ + SVP64_STR_MAP ("lwa"), + SVP64_STR_MAP ("lwarx"), + SVP64_STR_MAP ("lwaux"), + SVP64_STR_MAP ("lwax"), + SVP64_STR_MAP ("lwbrx"), + SVP64_STR_MAP ("lwz"), + SVP64_STR_MAP ("lwzcix"), + SVP64_STR_MAP ("lwzu"), + SVP64_STR_MAP ("lwzux"), + SVP64_STR_MAP ("lwzx"), + }; + + return SVP64_STR_MAP_CMP(str, len, table); +} + +static bool +svp64_is_st(const char *str, size_t len) +{ + static const struct svp64_str_map table[] = { + /* store byte */ + SVP64_STR_MAP ("stb"), + SVP64_STR_MAP ("stbcix"), + SVP64_STR_MAP ("stbcx"), + SVP64_STR_MAP ("stbu"), + SVP64_STR_MAP ("stbux"), + SVP64_STR_MAP ("stbx"), + /* store double */ + SVP64_STR_MAP ("std"), + SVP64_STR_MAP ("stdbrx"), + SVP64_STR_MAP ("stdcx"), + SVP64_STR_MAP ("stdu"), + SVP64_STR_MAP ("stdux"), + SVP64_STR_MAP ("stdx"), + /* FP store single */ + SVP64_STR_MAP ("stfs"), + SVP64_STR_MAP ("stfsx"), + SVP64_STR_MAP ("stfsu"), + SVP64_STR_MAP ("stfux"), + /* FP store double */ + SVP64_STR_MAP ("stfd"), + SVP64_STR_MAP ("stfdx"), + SVP64_STR_MAP ("stfdu"), + SVP64_STR_MAP ("stfdux"), + SVP64_STR_MAP ("stfiwx"), + /* store half */ + SVP64_STR_MAP ("sth"), + SVP64_STR_MAP ("sthbrx"), + SVP64_STR_MAP ("sthcx"), + SVP64_STR_MAP ("sthu"), + SVP64_STR_MAP ("sthux"), + SVP64_STR_MAP ("sthx"), + /* store word */ + SVP64_STR_MAP ("stw"), + SVP64_STR_MAP ("stwbrx"), + SVP64_STR_MAP ("stwcx"), + SVP64_STR_MAP ("stwu"), + SVP64_STR_MAP ("stwux"), + SVP64_STR_MAP ("stwx"), + }; + + return SVP64_STR_MAP_CMP(str, len, table); +} + +static bool +svp64_is_bc(const char *str, size_t len) +{ + static const struct svp64_str_map table[] = { + SVP64_STR_MAP ("bc"), + SVP64_STR_MAP ("bclr"), + }; + + return SVP64_STR_MAP_CMP(str, len, table); +} + static void svp64_decode (char *str, struct svp64_ctx *svp64) { char *opc; + size_t opclen; char *iter; str += (sizeof ("sv.") - 1); @@ -578,9 +727,17 @@ svp64_decode (char *str, struct svp64_ctx *svp64) opc = str; for (; ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0'; ++str) ; + opclen = (str - opc); if (*str != '\0') *str++ = '\0'; + if (svp64_is_ld (opc, opclen)) + svp64->type = SVP64_TYPE_LD; + else if (svp64_is_st (opc, opclen)) + svp64->type = SVP64_TYPE_ST; + else if (svp64_is_bc (opc, opclen)) + svp64->type = SVP64_TYPE_BC; + for (; (iter = svp64_decode_mode (str, svp64)) != NULL; str = iter) ;