From: Dmitry Selyutin Date: Sun, 28 May 2023 22:04:56 +0000 (+0300) Subject: ppc/svp64: support ff/pr modes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10f3c534ccdabf59e8eeafdb278730e4f7c3b873;p=binutils-gdb.git ppc/svp64: support ff/pr modes --- diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index ca635781861..0da55638c6a 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -43,8 +43,12 @@ struct svp64_ctx { unsigned int sat : 1; unsigned int dz : 1; unsigned int sz : 1; + unsigned int ff : 3 + 2; /* 3-bit plus RC1 */ }; +#define SVP64_RC1_ACTIVE (1U << 3U) +#define SVP64_RC1_INVERT (SVP64_RC1_ACTIVE | (1U << 4U)) + static jmp_buf svp64_exception; #define svp64_raise(...) \ @@ -86,7 +90,7 @@ struct svp64_predicate_map { const char *str; unsigned int len : 3; unsigned int cr : 1; - unsigned int mask : 3; + unsigned int mask : 3 + 2; /* 3-bit plus RC1 */ }; #define SVP64_PREDICATE_MAP(STR, MODE, MASK) \ { STR, (sizeof (STR) - 1), MODE, MASK } @@ -117,6 +121,9 @@ svp64_decode_predicate (char *str, bool *cr, unsigned int *mask) SVP64_PREDICATE_MAP ("un" , 1, 6), /* same value as so */ SVP64_PREDICATE_MAP ("ns" , 1, 7), SVP64_PREDICATE_MAP ("nu" , 1, 7), /* same value as ns */ + /* RC1 */ + SVP64_PREDICATE_MAP ("RC1" , 0, SVP64_RC1_ACTIVE), + SVP64_PREDICATE_MAP ("~RC1" , 0, SVP64_RC1_INVERT), }; for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i) @@ -144,6 +151,22 @@ svp64_decode_predicate (char *str, bool *cr, unsigned int *mask) return NULL; } +static char * +svp64_decode_predicate_bo (char *str, unsigned int *mask) +{ + bool cr; + char *iter; + + iter = svp64_decode_predicate (str, &cr, mask); + if (!iter || !(cr || ((*mask & SVP64_RC1_ACTIVE) != 0))) + return NULL; + + *mask = ((((*mask >> 0) & 0x1) << 2) | + (((*mask >> 1) & 0x3) << 0)); + + return iter; +} + struct svp64_decoder { char *(*call)(char *str, struct svp64_ctx *svp64); const char *str; @@ -162,7 +185,7 @@ svp64_decode_m (char *str, struct svp64_ctx *svp64) str += (sizeof ("m=") - 1); iter = svp64_decode_predicate (str, &cr, &pmask); - if (!iter) + if (!iter || ((pmask & SVP64_RC1_ACTIVE) != 0)) svp64_raise (_("unrecognized mode: `%s'"), str); pmmode = (cr ? 1 : 0); @@ -186,7 +209,7 @@ svp64_decode_dm (char *str, struct svp64_ctx *svp64) str += (sizeof ("dm=") - 1); iter = svp64_decode_predicate (str, &cr, &pmask); - if (!iter) + if (!iter || ((pmask & SVP64_RC1_ACTIVE) != 0)) svp64_raise (_("unrecognized mode: `%s'"), str); pmmode = (cr ? 1 : 0); @@ -208,7 +231,7 @@ svp64_decode_sm (char *str, struct svp64_ctx *svp64) str += (sizeof ("sm=") - 1); iter = svp64_decode_predicate (str, &cr, &smask); - if (!iter) + if (!iter || ((smask & SVP64_RC1_ACTIVE) != 0)) svp64_raise (_("unrecognized mode: `%s'"), str); smmode = (cr ? 1 : 0); @@ -445,6 +468,27 @@ svp64_decode_sz (char *str, struct svp64_ctx *svp64) return str; } +static char * +svp64_decode_ff (char *str, struct svp64_ctx *svp64) +{ + char *iter; + unsigned int mask; + + str += (sizeof ("ff=") - 1); + if (svp64->sv_mode_explicit) + svp64_raise (_("SV mode conflict: `%s'"), str); + + iter = svp64_decode_predicate_bo (str, &mask); + if (!iter) + svp64_raise (_("unrecognized mode: `%s'"), str); + + svp64->sv_mode_explicit = 1; + svp64->sv_mode = 0x1; + svp64->ff = mask; + + return iter; +} + static char * svp64_decode_mode (char *str, struct svp64_ctx *svp64) { @@ -466,6 +510,7 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64) SVP64_DECODER ("zz" , svp64_decode_zz), SVP64_DECODER ("dz" , svp64_decode_dz), SVP64_DECODER ("sz" , svp64_decode_sz), + SVP64_DECODER ("ff=" , svp64_decode_ff), }; for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i)