ppc/svp64: support w/dw/sw modes
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 19 Jun 2022 08:06:19 +0000 (11:06 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Fri, 23 Sep 2022 17:11:54 +0000 (20:11 +0300)
gas/config/tc-ppc-svp64.c

index cae359f1f003083e1fe71a59595d5d499c5d7987..76189b56e2697f9c96b0ed24deaee9dc3530e187 100644 (file)
@@ -32,6 +32,14 @@ struct svp64_ctx {
   unsigned int has_smask : 1;
   unsigned int mask_m_specified : 1;
   unsigned int subvl : 2;
+  unsigned int destwid : 2;
+  unsigned int srcwid : 2;
+  unsigned int ldst_elstride : 1;
+  unsigned int sv_mode_explicit : 1;
+  unsigned int sv_mode : 2;
+  unsigned int sat : 1;
+  unsigned int src_zero : 1;
+  unsigned int dst_zero : 1;
 };
 
 static jmp_buf svp64_exception;
@@ -242,6 +250,164 @@ svp64_decode_vec (char *str, struct svp64_ctx *svp64)
   return str;
 }
 
+struct svp64_width_map {
+  const char *str;
+  unsigned int len;
+  unsigned int width;
+};
+#define SVP64_WIDTH_MAP(STR, WIDTH) \
+  { STR, (sizeof (STR) - 1), WIDTH }
+
+static char *
+svp64_decode_width (char *str, unsigned int *width)
+{
+  size_t i;
+  static const struct svp64_width_map table[] = {
+    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)
+    {
+      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')
+        {
+          str -= entry->len;
+          continue;
+        }
+
+      *width = entry->width;
+
+      *str++ = '\0';
+
+      return str;
+    }
+
+  return NULL;
+}
+
+static char *
+svp64_decode_w (char *str, struct svp64_ctx *svp64)
+{
+  char *iter;
+  unsigned int width;
+
+  str += (sizeof ("w=") - 1);
+  iter = svp64_decode_width (str, &width);
+  if (!iter)
+    svp64_raise (_("unrecognized mode: `%s'"), str);
+
+  svp64->srcwid = width;
+  svp64->destwid = width;
+
+  return iter;
+}
+
+static char *
+svp64_decode_dw (char *str, struct svp64_ctx *svp64)
+{
+  char *iter;
+  unsigned int width;
+
+  str += (sizeof ("dw=") - 1);
+  iter = svp64_decode_width (str, &width);
+  if (!iter)
+    svp64_raise (_("unrecognized mode: `%s'"), str);
+
+  svp64->destwid = width;
+
+  return iter;
+}
+
+static char *
+svp64_decode_sw (char *str, struct svp64_ctx *svp64)
+{
+  char *iter;
+  unsigned int width;
+
+  str += (sizeof ("sw=") - 1);
+  iter = svp64_decode_width (str, &width);
+  if (!iter)
+    svp64_raise (_("unrecognized mode: `%s'"), str);
+
+  svp64->srcwid = width;
+
+  return iter;
+}
+
+static char *
+svp64_decode_els (char *str, struct svp64_ctx *svp64)
+{
+  str += (sizeof ("els") - 1);
+  if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+    return NULL;
+
+  svp64->ldst_elstride = 1;
+
+  *str++ = '\0';
+
+  return str;
+}
+
+static char *
+svp64_decode_sat (char *str, struct svp64_ctx *svp64)
+{
+  unsigned char mode;
+
+  str += (sizeof ("sat") - 1);
+  if ((*str != 's') && (*str != 'u'))
+    return NULL;
+
+  mode = *str++;
+  if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+    return NULL;
+
+  if (svp64->sv_mode_explicit)
+    svp64_raise (_("SV mode conflict: `%s'"), str);
+
+  svp64->sv_mode_explicit = 1;
+  svp64->sv_mode = 2;
+  svp64->sat = (mode == 's');
+
+  *str++ = '\0';
+
+  return str;
+}
+
+static char *
+svp64_decode_sz (char *str, struct svp64_ctx *svp64)
+{
+  str += (sizeof ("sz") - 1);
+  if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+    return NULL;
+
+  svp64->src_zero = 1;
+
+  *str++ = '\0';
+
+  return str;
+}
+
+static char *
+svp64_decode_dz (char *str, struct svp64_ctx *svp64)
+{
+  str += (sizeof ("dz") - 1);
+  if ( ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+    return NULL;
+
+  svp64->dst_zero = 1;
+
+  *str++ = '\0';
+
+  return str;
+}
+
 static char *
 svp64_decode_mode (char *str, struct svp64_ctx *svp64)
 {
@@ -253,6 +419,14 @@ svp64_decode_mode (char *str, struct svp64_ctx *svp64)
     SVP64_DECODER ("vec2", svp64_decode_vec),
     SVP64_DECODER ("vec3", svp64_decode_vec),
     SVP64_DECODER ("vec4", svp64_decode_vec),
+    SVP64_DECODER ("w=" ,  svp64_decode_w),
+    SVP64_DECODER ("dw=" , svp64_decode_dw),
+    SVP64_DECODER ("sw=" , svp64_decode_sw),
+    SVP64_DECODER ("els" , svp64_decode_els),
+    SVP64_DECODER ("sats", svp64_decode_sat),
+    SVP64_DECODER ("satu", svp64_decode_sat),
+    SVP64_DECODER ("sz"  , svp64_decode_sz),
+    SVP64_DECODER ("dz"  , svp64_decode_dz),
   };
 
   for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i)