aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2022-08-16 09:11:59 +0200
committerJan Beulich <jbeulich@suse.com>2022-08-16 09:11:59 +0200
commit73d214b268a95d06a0eff0f2347049820d1ae320 (patch)
treebe94a9d12fe55f6fbf92373b58a5cc24fcfdadcc /opcodes/i386-gen.c
parent33b6a20af3854e1aa144fbfca6ff98fccd0ef86d (diff)
downloadgdb-73d214b268a95d06a0eff0f2347049820d1ae320.zip
gdb-73d214b268a95d06a0eff0f2347049820d1ae320.tar.gz
gdb-73d214b268a95d06a0eff0f2347049820d1ae320.tar.bz2
x86: template-ize packed/scalar vector floating point insns
The vast majority of vector FP insns comes in single/double pairs. Many pairs follow certain encoding patterns. Introduce an "sd" template to reduce redundancy. Similarly, to further cover similarities between AVX512F and AVX512-FP16, introduce an "sdh" template. For element-size Disp8 shift generalize i386-gen's broadcast size determination, allowing Disp8MemShift to be specified without an operand in the affected templated templates. While doing the adjustment also eliminate an unhelpful (lost information) diagnostic combined with a use after free in what is now get_element_size(). Note that in the course of the conversion - the AVX512F form of VMOVUPD has a stray (leftover) Load attribute dropped, - VMOVSH has a benign IgnoreSize added (the attribute is still strictly necessary for VMOVSD, and necessary for VMOVSS as long as we permit strange combinations like "-march=i286+avx"), - VFPCLASSPH is properly split to separate AT&T and Intel syntax forms, matching VFPCLASSP{S,D}.
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index eaeb207..181ea53 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -1111,18 +1111,21 @@ output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
fprintf (table, "%d },\n", modifier[i].value);
}
+/* Returns LOG2 of element size. */
static int
-adjust_broadcast_modifier (char **opnd)
+get_element_size (char **opnd, int lineno)
{
char *str, *next, *last, *op;
- int bcst_type = INT_MAX;
+ const char *full = opnd[0];
+ int elem_size = INT_MAX;
- /* Skip the immediate operand. */
- op = opnd[0];
- if (strcasecmp(op, "Imm8") == 0)
- op = opnd[1];
+ /* Find the memory operand. */
+ while (full != NULL && strstr(full, "BaseIndex") == NULL)
+ full = *++opnd;
+ if (full == NULL)
+ fail (_("%s: %d: no memory operand\n"), filename, lineno);
- op = xstrdup (op);
+ op = xstrdup (full);
last = op + strlen (op);
for (next = op; next && next < last; )
{
@@ -1131,34 +1134,34 @@ adjust_broadcast_modifier (char **opnd)
{
if (strcasecmp(str, "Byte") == 0)
{
- /* The smalest broadcast type, no need to check
+ /* The smallest element size, no need to check
further. */
- bcst_type = BYTE_BROADCAST;
+ elem_size = 0;
break;
}
else if (strcasecmp(str, "Word") == 0)
{
- if (bcst_type > WORD_BROADCAST)
- bcst_type = WORD_BROADCAST;
+ if (elem_size > 1)
+ elem_size = 1;
}
else if (strcasecmp(str, "Dword") == 0)
{
- if (bcst_type > DWORD_BROADCAST)
- bcst_type = DWORD_BROADCAST;
+ if (elem_size > 2)
+ elem_size = 2;
}
else if (strcasecmp(str, "Qword") == 0)
{
- if (bcst_type > QWORD_BROADCAST)
- bcst_type = QWORD_BROADCAST;
+ if (elem_size > 3)
+ elem_size = 3;
}
}
}
free (op);
- if (bcst_type == INT_MAX)
- fail (_("unknown broadcast operand: %s\n"), op);
+ if (elem_size == INT_MAX)
+ fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
- return bcst_type;
+ return elem_size;
}
static void
@@ -1185,7 +1188,9 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
{
int val = 1;
if (strcasecmp(str, "Broadcast") == 0)
- val = adjust_broadcast_modifier (opnd);
+ val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
+ else if (strcasecmp(str, "Disp8MemShift") == 0)
+ val = get_element_size (opnd, lineno);
set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
lineno);