aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-10-14 04:17:54 -0700
committerH.J. Lu <hjl.tools@gmail.com>2020-10-14 04:20:55 -0700
commit8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1 (patch)
tree6787d9d057850f28f7fd940774843b80871ab90b /gas
parent8c8bd0babc6039a4cef7d60d57b1b68e7a7f2e70 (diff)
downloadfsf-binutils-gdb-8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1.zip
fsf-binutils-gdb-8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1.tar.gz
fsf-binutils-gdb-8b65b8953af2d49ae1d2d7fcc5b49c5308febbc1.tar.bz2
x86: Remove the prefix byte from non-VEX/EVEX base_opcode
Replace the prefix byte in non-VEX/EVEX base_opcode with PREFIX_0X66, PREFIX_0XF2 or PREFIX_0XF3. gas/ * config/tc-i386.c (load_insn_p): Check opcodeprefix == 0 for base_opcode == 0xfc7. (match_template): Likewise. (process_suffix): Check opcodeprefix == PREFIX_0XF2 for CRC32. (check_byte_reg): Likewise. (output_insn): Don't add the 0xf3 prefix twice for PadLock instructions. Don't add prefix from non-VEX/EVEX base_opcode. opcodes/ * i386-gen.c (process_i386_opcode_modifier): Return 1 for non-VEX/EVEX/prefix encoding. (output_i386_opcode): Fail if non-VEX/EVEX/prefix base_opcode has a prefix byte. * i386-opc.tbl: Replace the prefix byte in non-VEX/EVEX base_opcode with PREFIX_0X66, PREFIX_0XF2 or PREFIX_0XF3. * i386-tbl.h: Regenerated.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-i386.c43
2 files changed, 29 insertions, 24 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 76b65df..ae54f17 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,13 @@
+2020-10-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (load_insn_p): Check opcodeprefix == 0 for
+ base_opcode == 0xfc7.
+ (match_template): Likewise.
+ (process_suffix): Check opcodeprefix == PREFIX_0XF2 for CRC32.
+ (check_byte_reg): Likewise.
+ (output_insn): Don't add the 0xf3 prefix twice for PadLock
+ instructions. Don't add prefix from non-VEX/EVEX base_opcode.
+
2020-10-13 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (build_vex_prefix): Replace vexopcode with
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index b1e8f7c..80b96d0 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4434,6 +4434,7 @@ load_insn_p (void)
/* cmpxchg8b, cmpxchg16b, xrstors. */
if (i.tm.base_opcode == 0xfc7
+ && i.tm.opcode_modifier.opcodeprefix == 0
&& (i.tm.extension_opcode == 1 || i.tm.extension_opcode == 3))
return 1;
@@ -4453,6 +4454,7 @@ load_insn_p (void)
/* vmptrld */
if (i.tm.base_opcode == 0xfc7
+ && i.tm.opcode_modifier.opcodeprefix == 0
&& i.tm.extension_opcode == 6)
return 1;
@@ -6313,8 +6315,9 @@ match_template (char mnem_suffix)
j = i.imm_operands + (t->operands > i.imm_operands + 1);
if (((i.suffix == QWORD_MNEM_SUFFIX
&& flag_code != CODE_64BIT
- && (t->base_opcode != 0x0fc7
- || t->extension_opcode != 1 /* cmpxchg8b */))
+ && !(t->base_opcode == 0xfc7
+ && i.tm.opcode_modifier.opcodeprefix == 0
+ && t->extension_opcode == 1) /* cmpxchg8b */)
|| (i.suffix == LONG_MNEM_SUFFIX
&& !cpu_arch_flags.bitfield.cpui386))
&& (intel_syntax
@@ -6759,6 +6762,8 @@ check_string (void)
static int
process_suffix (void)
{
+ bfd_boolean is_crc32 = FALSE;
+
/* If matched instruction specifies an explicit instruction mnemonic
suffix, use it. */
if (i.tm.opcode_modifier.size == SIZE16)
@@ -6772,6 +6777,9 @@ process_suffix (void)
&& !i.tm.opcode_modifier.addrprefixopreg)
{
unsigned int numop = i.operands;
+ /* CRC32 */
+ is_crc32 = (i.tm.base_opcode == 0xf38f0
+ && i.tm.opcode_modifier.opcodeprefix == PREFIX_0XF2);
/* movsx/movzx want only their source operand considered here, for the
ambiguity checking below. The suffix will be replaced afterwards
@@ -6781,8 +6789,7 @@ process_suffix (void)
--i.operands;
/* crc32 needs REX.W set regardless of suffix / source operand size. */
- if (i.tm.base_opcode == 0xf20f38f0
- && i.tm.operand_types[1].bitfield.qword)
+ if (is_crc32 && i.tm.operand_types[1].bitfield.qword)
i.rex |= REX_W;
/* If there's no instruction mnemonic suffix we try to invent one
@@ -6793,7 +6800,7 @@ process_suffix (void)
Destination register type is more significant than source
register type. crc32 in SSE4.2 prefers source register
type. */
- unsigned int op = i.tm.base_opcode != 0xf20f38f0 ? i.operands : 1;
+ unsigned int op = is_crc32 ? 1 : i.operands;
while (op--)
if (i.tm.operand_types[op].bitfield.instance == InstanceNone
@@ -7143,7 +7150,7 @@ process_suffix (void)
|| i.tm.operand_types[0].bitfield.instance == RegD
|| i.tm.operand_types[1].bitfield.instance == RegD
/* CRC32 */
- || i.tm.base_opcode == 0xf20f38f0))))
+ || is_crc32))))
i.tm.base_opcode |= 1;
break;
}
@@ -7257,7 +7264,9 @@ check_byte_reg (void)
continue;
/* crc32 only wants its source operand checked here. */
- if (i.tm.base_opcode == 0xf20f38f0 && op)
+ if (i.tm.base_opcode == 0xf38f0
+ && i.tm.opcode_modifier.opcodeprefix == PREFIX_0XF2
+ && op != 0)
continue;
/* Any other register is bad. */
@@ -9302,7 +9311,6 @@ output_insn (void)
char *p;
unsigned char *q;
unsigned int j;
- unsigned int prefix;
enum mf_cmp_kind mf_cmp;
if (avoid_fence
@@ -9382,28 +9390,15 @@ output_insn (void)
add_prefix (0xf2);
break;
case PREFIX_0XF3:
- add_prefix (0xf3);
+ if (!i.tm.cpu_flags.bitfield.cpupadlock
+ || (i.prefix[REP_PREFIX] != 0xf3))
+ add_prefix (0xf3);
break;
case PREFIX_NONE:
switch (i.tm.opcode_length)
{
case 3:
- if (i.tm.base_opcode & 0xff000000)
- {
- prefix = (i.tm.base_opcode >> 24) & 0xff;
- if (!i.tm.cpu_flags.bitfield.cpupadlock
- || prefix != REPE_PREFIX_OPCODE
- || (i.prefix[REP_PREFIX] != REPE_PREFIX_OPCODE))
- add_prefix (prefix);
- }
- break;
case 2:
- if ((i.tm.base_opcode & 0xff0000) != 0)
- {
- prefix = (i.tm.base_opcode >> 16) & 0xff;
- add_prefix (prefix);
- }
- break;
case 1:
break;
case 0: