ppc/svp64: support ff/pr modes
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 28 May 2023 22:04:56 +0000 (01:04 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 14 Nov 2023 19:53:34 +0000 (22:53 +0300)
gas/config/tc-ppc-svp64.c

index ca635781861447592793ebc4ec4e8b083afcc803..0da55638c6af4141f959048e9c8966b945586cc0 100644 (file)
@@ -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)