]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: also template-expand trailing mnemonic part
authorJan Beulich <jbeulich@suse.com>
Mon, 14 Oct 2024 12:38:02 +0000 (14:38 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 14 Oct 2024 12:38:02 +0000 (14:38 +0200)
So far template expansion was limited to fields other than the insn
mnemonic. In order to be able to use <fop> also for AVX10.2 we want the
trailing mnemonic part to also be expanded. Split out the respective
piece of code into a helper function, which is then invoked twice.

opcodes/i386-gen.c

index 565aae722f828fe93b429804babd0c7b0394f611..2b9f4fceadd8ae934da599f770904ee12b85e89c 100644 (file)
@@ -1672,6 +1672,69 @@ parse_template (char *buf, int lineno)
   return true;
 }
 
+static void
+expand_template (const struct template *tmpl,
+                const struct template_instance *inst,
+                char *dst, const char *src, int lineno)
+{
+  while (*src)
+    {
+      const char *ident = tmpl->name, *end;
+      const struct template_param *param;
+      const struct template_arg *arg;
+
+      if ((*dst = *src++) != '<')
+       {
+         ++dst;
+         continue;
+       }
+      while (ISSPACE(*src))
+       ++src;
+      while (*ident && *src == *ident)
+       ++src, ++ident;
+      while (ISSPACE(*src))
+       ++src;
+      if (*src != ':' || *ident != '\0')
+       {
+         memcpy (++dst, tmpl->name, ident - tmpl->name);
+         dst += ident - tmpl->name;
+         continue;
+       }
+      while (ISSPACE(*++src))
+       ;
+
+      end = src;
+      while (*end != '\0' && !ISSPACE(*end) && *end != '>')
+       ++end;
+
+      for (param = tmpl->params, arg = inst->args; param;
+          param = param->next, arg = arg->next)
+       {
+         if (end - src == strlen (param->name)
+             && !memcmp (src, param->name, end - src))
+           {
+             src = end;
+             break;
+           }
+       }
+
+      if (param == NULL)
+       fail ("template '%s' has no parameter '%.*s'\n",
+             tmpl->name, (int)(end - src), src);
+
+      while (ISSPACE(*src))
+       ++src;
+      if (*src != '>')
+       fail ("%s: %d: missing '>'\n", filename, lineno);
+
+      memcpy(dst, arg->val, strlen(arg->val));
+      dst += strlen(arg->val);
+      ++src;
+    }
+
+  *dst = '\0';
+}
+
 static unsigned int
 expand_templates (char *name, const char *str, htab_t opcode_hash_table,
                  struct opcode_hash_entry ***opcode_array_p, int lineno)
@@ -1746,71 +1809,20 @@ expand_templates (char *name, const char *str, htab_t opcode_hash_table,
 
       for (inst = tmpl->instances; inst; inst = inst->next)
        {
-         char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
+         char *name2 = xmalloc(strlen(name) + strlen(inst->name)
+                       + 2 * strlen(ptr2) + 1);
          char *str2 = xmalloc(2 * strlen(str));
-         const char *src;
 
-         strcpy (name2, name);
-         strcat (name2, inst->name);
-         strcat (name2, ptr2);
+         ptr1 = stpcpy (name2, name);
+         ptr1 = stpcpy (ptr1, inst->name);
 
-         for (ptr1 = str2, src = str; *src; )
-           {
-             const char *ident = tmpl->name, *end;
-             const struct template_param *param;
-             const struct template_arg *arg;
-
-             if ((*ptr1 = *src++) != '<')
-               {
-                 ++ptr1;
-                 continue;
-               }
-             while (ISSPACE(*src))
-               ++src;
-             while (*ident && *src == *ident)
-               ++src, ++ident;
-             while (ISSPACE(*src))
-               ++src;
-             if (*src != ':' || *ident != '\0')
-               {
-                 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
-                 ptr1 += ident - tmpl->name;
-                 continue;
-               }
-             while (ISSPACE(*++src))
-               ;
-
-             end = src;
-             while (*end != '\0' && !ISSPACE(*end) && *end != '>')
-               ++end;
-
-             for (param = tmpl->params, arg = inst->args; param;
-                  param = param->next, arg = arg->next)
-               {
-                 if (end - src == strlen (param->name)
-                     && !memcmp (src, param->name, end - src))
-                   {
-                     src = end;
-                     break;
-                   }
-               }
-
-             if (param == NULL)
-               fail ("template '%s' has no parameter '%.*s'\n",
-                     tmpl->name, (int)(end - src), src);
-
-             while (ISSPACE(*src))
-               ++src;
-             if (*src != '>')
-               fail ("%s: %d: missing '>'\n", filename, lineno);
-
-             memcpy(ptr1, arg->val, strlen(arg->val));
-             ptr1 += strlen(arg->val);
-             ++src;
-           }
+         /* Expand this template in trailing portion of mnemonic.  */
+         expand_template (tmpl, inst, ptr1, ptr2, lineno);
 
-         *ptr1 = '\0';
+         /* Expand this template in attributes and operands.  */
+         expand_template (tmpl, inst, str2, str, lineno);
 
+         /* Expand further templates, if any. */
          expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
                            lineno);