summaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2022-08-16 09:14:39 +0200
committerJan Beulich <jbeulich@suse.com>2022-08-16 09:14:39 +0200
commite07ae9a3efee6a4978703f6a4a15c0870faff55d (patch)
tree3ba93f36a35f111d3517d397199585b59422b5ef /opcodes/i386-gen.c
parentb9df5afb694a95b55c352e817ad664600a894f2e (diff)
downloadbinutils-gdb-e07ae9a3efee6a4978703f6a4a15c0870faff55d.tar.gz
x86: template-ize certain vector conversion insns
Many of the vector conversion insns come with X/Y/Z suffixed forms, for disambiguation purposes in AT&T syntax. All of these gorups follow certain patterns. Introduce "xy" and "xyz" templates to reduce redundancy. To facilitate using a uniform name for both AVX and AVX512, further introduce a means to purge a previously defined template: A standalone <name> will be recognized to have this effect. Note that in the course of the conversion VFPCLASSPH is properly split to separate AT&T and Intel syntax forms, matching VFPCLASSP{S,D} and yielding the intended "ambiguous operand size" diagnostic in Intel mode.
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 181ea53b7ab..92ee3592929 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -822,13 +822,13 @@ struct template_param {
};
struct template {
- const struct template *next;
+ struct template *next;
const char *name;
const struct template_instance *instances;
const struct template_param *params;
};
-static const struct template *templates;
+static struct template *templates;
static int
compare (const void *x, const void *y)
@@ -1509,18 +1509,40 @@ static void
parse_template (char *buf, int lineno)
{
char sep, *end, *name;
- struct template *tmpl = xmalloc (sizeof (*tmpl));
+ struct template *tmpl;
struct template_instance *last_inst = NULL;
buf = remove_leading_whitespaces (buf + 1);
end = strchr (buf, ':');
if (end == NULL)
- fail ("%s: %d: missing ':'\n", filename, lineno);
+ {
+ struct template *prev = NULL;
+
+ end = strchr (buf, '>');
+ if (end == NULL)
+ fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
+ if (*remove_leading_whitespaces (end + 1))
+ fail ("%s: %d: malformed template purge\n", filename, lineno);
+ *end = '\0';
+ remove_trailing_whitespaces (buf);
+ /* Don't bother freeing the various structures. */
+ for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
+ if (!strcmp (buf, tmpl->name))
+ break;
+ if (tmpl == NULL)
+ fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
+ if (prev)
+ prev->next = tmpl->next;
+ else
+ templates = tmpl->next;
+ return;
+ }
*end++ = '\0';
remove_trailing_whitespaces (buf);
if (*buf == '\0')
fail ("%s: %d: missing template identifier\n", filename, lineno);
+ tmpl = xmalloc (sizeof (*tmpl));
tmpl->name = xstrdup (buf);
tmpl->params = NULL;