aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-07-22 12:00:39 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-07-22 12:00:39 -0700
commitc7213af9b3e47d3341f95fe24549681029a53853 (patch)
tree19c67f5fe49cc8756f6e81d57cc1faf4246561fd
parent17cbafdbbef78d7e05ade53d4cc867fa8ac2f432 (diff)
downloadbinutils-c7213af9b3e47d3341f95fe24549681029a53853.zip
binutils-c7213af9b3e47d3341f95fe24549681029a53853.tar.gz
binutils-c7213af9b3e47d3341f95fe24549681029a53853.tar.bz2
x86: Determine vector length from the last vector operand
Determine VEX/EVEXE vector length from the last multi-length vector operand. * config/tc-i386.c (build_vex_prefix): Determine vector length from the last multi-length vector operand. (build_evex_prefix): Likewise.
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-i386.c35
2 files changed, 31 insertions, 10 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3253a9f..5df35569 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (build_vex_prefix): Determine vector
+ length from the last multi-length vector operand.
+ (build_evex_prefix): Likewise.
+
2018-07-20 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (match_simd_size): Break long line.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index c4ccffc..575b017 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -3363,10 +3363,12 @@ build_vex_prefix (const insn_template *t)
vector_length = 1;
else
{
- unsigned int op;
+ int op;
+ /* Determine vector length from the last multi-length vector
+ operand. */
vector_length = 0;
- for (op = 0; op < t->operands; ++op)
+ for (op = t->operands - 1; op >= 0; op--)
if (t->operand_types[op].bitfield.xmmword
&& t->operand_types[op].bitfield.ymmword
&& i.types[op].bitfield.ymmword)
@@ -3611,20 +3613,31 @@ build_evex_prefix (void)
if (!i.tm.opcode_modifier.evex
|| i.tm.opcode_modifier.evex == EVEXDYN)
{
- unsigned int op;
+ int op;
+ /* Determine vector length from the last multi-length vector
+ operand. */
vec_length = 0;
- for (op = 0; op < i.tm.operands; ++op)
+ for (op = i.operands - 1; op >= 0; op--)
if (i.tm.operand_types[op].bitfield.xmmword
+ i.tm.operand_types[op].bitfield.ymmword
+ i.tm.operand_types[op].bitfield.zmmword > 1)
{
if (i.types[op].bitfield.zmmword)
- i.tm.opcode_modifier.evex = EVEX512;
+ {
+ i.tm.opcode_modifier.evex = EVEX512;
+ break;
+ }
else if (i.types[op].bitfield.ymmword)
- i.tm.opcode_modifier.evex = EVEX256;
+ {
+ i.tm.opcode_modifier.evex = EVEX256;
+ break;
+ }
else if (i.types[op].bitfield.xmmword)
- i.tm.opcode_modifier.evex = EVEX128;
+ {
+ i.tm.opcode_modifier.evex = EVEX128;
+ break;
+ }
else if (i.broadcast && (int) op == i.broadcast->operand)
{
switch ((i.tm.operand_types[op].bitfield.dword ? 4 : 8)
@@ -3640,12 +3653,14 @@ build_evex_prefix (void)
i.tm.opcode_modifier.evex = EVEX128;
break;
default:
- continue;
+ abort ();
}
+ break;
}
- continue;
- break;
}
+
+ if (op < 0)
+ abort ();
}
switch (i.tm.opcode_modifier.evex)