ppc/svp64: allow w/dw/sw macro expansion
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 28 May 2023 22:04:56 +0000 (01:04 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 15 Aug 2023 19:22:00 +0000 (22:22 +0300)
gas/config/tc-ppc-svp64.c

index f840da7b2fc51a40ebb75d3e650d715444df63c7..84512ff59325d7cae58d11c0003de843cbbd06a1 100644 (file)
@@ -148,6 +148,35 @@ svp64_setup_records (void)
 
 #define SVP64_SEP '/'
 
+static inline char *
+svp64_expression (char *str, expressionS *exp)
+{
+  char old_sep;
+  char *str_tail;
+  char *str_head = str;
+  char *old_ilp = input_line_pointer;
+
+  memset (exp, 0, sizeof *exp);
+
+  while (! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+    ++str;
+  if (*str != '\0')
+    *str++ = '\0';
+  str_tail = str;
+  old_sep = *str;
+  *str = '\0';
+  str = str_head;
+  input_line_pointer = str;
+
+  expression (exp);
+  resolve_register (exp);
+
+  input_line_pointer = old_ilp;
+  *str_tail = old_sep;
+
+  return ((exp->X_op == O_absent) ? str_head : str_tail);
+}
+
 struct svp64_predicate_map {
   const char *str;
   unsigned int len : 3;
@@ -340,41 +369,39 @@ svp64_decode_vec (char *str, struct svp64_ctx *svp64)
 
 struct svp64_width_map {
   const char *str;
-  unsigned int len;
-  unsigned int width;
+  unsigned int len : 2;
+  unsigned int num : 6;
+  unsigned int width : 8;
 };
-#define SVP64_WIDTH_MAP(STR, WIDTH) \
-  { STR, (sizeof (STR) - 1), WIDTH }
+#define SVP64_WIDTH_MAP(NUM, WIDTH) \
+  { #NUM, (sizeof (#NUM) - 1), NUM, WIDTH }
 
 static char *
 svp64_decode_width (char *str, unsigned int *width)
 {
   size_t i;
+  char *origin;
+  expressionS exp;
   static const struct svp64_width_map table[] = {
-    SVP64_WIDTH_MAP ("8", 3),
-    SVP64_WIDTH_MAP ("16", 2),
-    SVP64_WIDTH_MAP ("32", 1),
+    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)
+  origin = str;
+  str = svp64_expression (str, &exp);
+  if ((str != origin) && (exp.X_op == O_constant))
     {
-      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')
+      for (i = 0; i < (sizeof (table) / sizeof (table[0])); ++i)
         {
-          str -= entry->len;
-          continue;
-        }
-
-      *width = entry->width;
-
-      *str++ = '\0';
+          const struct svp64_width_map *entry = &table[i];
 
-      return str;
+          if (entry->num == exp.X_add_number)
+            {
+              *width = entry->width;
+              return str;
+            }
+        }
     }
 
   return NULL;