ppc/svp64: support ff/pr modes
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 19 Jun 2022 11:33:15 +0000 (14:33 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Fri, 23 Sep 2022 17:11:54 +0000 (20:11 +0300)
gas/config/tc-ppc-svp64.c

index 76189b56e2697f9c96b0ed24deaee9dc3530e187..ee5acd4eb4fc36c3c53c9efc899d7a37e6f28070 100644 (file)
@@ -40,8 +40,13 @@ struct svp64_ctx {
   unsigned int sat : 1;
   unsigned int src_zero : 1;
   unsigned int dst_zero : 1;
+  unsigned int ff : 3 + 2; /* 3-bit plus RC1 */
+  unsigned int pr : 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(...)                \
@@ -83,7 +88,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 }
@@ -114,6 +119,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)
@@ -159,7 +167,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);
@@ -183,7 +191,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);
@@ -205,7 +213,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);
@@ -408,6 +416,50 @@ svp64_decode_dz (char *str, struct svp64_ctx *svp64)
   return str;
 }
 
+static char *
+svp64_decode_ff (char *str, struct svp64_ctx *svp64)
+{
+  char *iter;
+  bool cr;
+  unsigned int mask;
+
+  str += (sizeof ("ff=") - 1);
+  if (svp64->sv_mode_explicit)
+    svp64_raise (_("SV mode conflict: `%s'"), str);
+
+  iter = svp64_decode_predicate (str, &cr, &mask);
+  if (!iter || !(cr || ((mask & SVP64_RC1_ACTIVE) != 0)))
+    svp64_raise (_("unrecognized mode: `%s'"), str);
+
+  svp64->sv_mode_explicit = 1;
+  svp64->sv_mode = 0x1;
+  svp64->ff = mask;
+
+  return iter;
+}
+
+static char *
+svp64_decode_pr (char *str, struct svp64_ctx *svp64)
+{
+  char *iter;
+  bool cr;
+  unsigned int mask;
+
+  str += (sizeof ("pr=") - 1);
+  if (svp64->sv_mode_explicit)
+    svp64_raise (_("SV mode conflict: `%s'"), str);
+
+  iter = svp64_decode_predicate (str, &cr, &mask);
+  if (!iter || !(cr || ((mask & SVP64_RC1_ACTIVE) != 0)))
+    svp64_raise (_("unrecognized mode: `%s'"), str);
+
+  svp64->sv_mode_explicit = 1;
+  svp64->sv_mode = 0x3;
+  svp64->pr = mask;
+
+  return iter;
+}
+
 static char *
 svp64_decode_mode (char *str, struct svp64_ctx *svp64)
 {
@@ -427,6 +479,8 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64)
     SVP64_DECODER ("satu", svp64_decode_sat),
     SVP64_DECODER ("sz"  , svp64_decode_sz),
     SVP64_DECODER ("dz"  , svp64_decode_dz),
+    SVP64_DECODER ("ff=" , svp64_decode_ff),
+    SVP64_DECODER ("pr=" , svp64_decode_pr),
   };
 
   for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i)