x86: also template-expand trailing mnemonic part

Message ID 61689246-5031-4ad0-ace2-8e31f244af11@suse.com
State New
Headers
Series x86: also template-expand trailing mnemonic part |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jan Beulich Oct. 8, 2024, 10:28 a.m. UTC
  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.
  

Comments

Jiang, Haochen Oct. 9, 2024, 3:14 a.m. UTC | #1
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Tuesday, October 8, 2024 6:29 PM
> 
> 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.
> 

I am not sure if the patch could solve the problem. Since the actual error is
before...

>  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
> 

... this loop, I am a little concerned about that.

I will have a try on that to see if it works.

Thx,
Haochen

>        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);
  
Jiang, Haochen Oct. 9, 2024, 3:21 a.m. UTC | #2
> From: Jiang, Haochen
> Sent: Wednesday, October 9, 2024 11:14 AM
> 
> > From: Jan Beulich <jbeulich@suse.com>
> > Sent: Tuesday, October 8, 2024 6:29 PM
> >
> > 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.
> >
> 
> I am not sure if the patch could solve the problem. Since the actual error is
> before...
> 
> >  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
> >
> 
> ... this loop, I am a little concerned about that.
> 
> I will have a try on that to see if it works.
> 

Aha it works, I forgot that the function itself is wrapped by others. Thank for
your help!

Thx,
Haochen
  

Patch

--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -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
 
       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);