diff options
author | Jan Beulich <jbeulich@suse.com> | 2024-10-14 14:38:02 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2024-10-14 14:38:02 +0200 |
commit | f5bb7f33242b29481ac109ab4f672bbd749b2b2d (patch) | |
tree | e29cb941891b2470b9e9112e02c7c0f0d87deea2 | |
parent | b03815327ab1bc34b1784455ca56c2b626cf5794 (diff) | |
download | binutils-f5bb7f33242b29481ac109ab4f672bbd749b2b2d.zip binutils-f5bb7f33242b29481ac109ab4f672bbd749b2b2d.tar.gz binutils-f5bb7f33242b29481ac109ab4f672bbd749b2b2d.tar.bz2 |
x86: also template-expand trailing mnemonic part
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.
-rw-r--r-- | opcodes/i386-gen.c | 132 |
1 files changed, 72 insertions, 60 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 565aae7..2b9f4fc 100644 --- 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 *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); |