i386: Only check suffix in instruction mnemonic
We should check suffix in instruction mnemonic when matching instruction. In Intel syntax, normally we check for memory operand size. But the same mnemonic with 2 different encodings can have the same memory operand size and i.suffix is set to LONG_DOUBLE_MNEM_SUFFIX from memory operand size in Intel syntax to distinguish them. When there is no suffix in mnemonic, we check LONG_DOUBLE_MNEM_SUFFIX in i.suffix for mnemonic suffix. gas/ PR gas/25167 * config/tc-i386.c (match_template): Don't check instruction suffix set from operand. * testsuite/gas/i386/code16.d: New file. * testsuite/gas/i386/code16.s: Likewise. * testsuite/gas/i386/i386.exp: Run code16. * testsuite/gas/i386/x86-64-branch-4.l: Updated. opcodes/ PR gas/25167 * i386-opc.tbl: Remove IgnoreSize from cmpsd and movsd. * i386-tbl.h: Regenerated.
This commit is contained in:
parent
992a70401e
commit
dc2be329b9
@ -1,3 +1,12 @@
|
||||
2019-11-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR gas/25167
|
||||
* config/tc-i386.c (match_template): Don't check instruction
|
||||
suffix set from operand.
|
||||
* testsuite/gas/i386/code16.d: New file.
|
||||
* testsuite/gas/i386/code16.s: Likewise.
|
||||
* testsuite/gas/i386/i386.exp: Run code16.
|
||||
|
||||
2019-11-08 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (optimize_encoding, build_modrm_byte,
|
||||
|
@ -5693,7 +5693,7 @@ match_template (char mnem_suffix)
|
||||
i386_operand_type overlap0, overlap1, overlap2, overlap3;
|
||||
i386_operand_type overlap4;
|
||||
unsigned int found_reverse_match;
|
||||
i386_opcode_modifier suffix_check, mnemsuf_check;
|
||||
i386_opcode_modifier suffix_check;
|
||||
i386_operand_type operand_types [MAX_OPERANDS];
|
||||
int addr_prefix_disp;
|
||||
unsigned int j;
|
||||
@ -5708,33 +5708,33 @@ match_template (char mnem_suffix)
|
||||
found_reverse_match = 0;
|
||||
addr_prefix_disp = -1;
|
||||
|
||||
/* Prepare for mnemonic suffix check. */
|
||||
memset (&suffix_check, 0, sizeof (suffix_check));
|
||||
if (intel_syntax && i.broadcast)
|
||||
/* nothing */;
|
||||
else if (i.suffix == BYTE_MNEM_SUFFIX)
|
||||
suffix_check.no_bsuf = 1;
|
||||
else if (i.suffix == WORD_MNEM_SUFFIX)
|
||||
suffix_check.no_wsuf = 1;
|
||||
else if (i.suffix == SHORT_MNEM_SUFFIX)
|
||||
suffix_check.no_ssuf = 1;
|
||||
else if (i.suffix == LONG_MNEM_SUFFIX)
|
||||
suffix_check.no_lsuf = 1;
|
||||
else if (i.suffix == QWORD_MNEM_SUFFIX)
|
||||
suffix_check.no_qsuf = 1;
|
||||
else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX)
|
||||
suffix_check.no_ldsuf = 1;
|
||||
|
||||
memset (&mnemsuf_check, 0, sizeof (mnemsuf_check));
|
||||
if (intel_syntax)
|
||||
switch (mnem_suffix)
|
||||
{
|
||||
switch (mnem_suffix)
|
||||
{
|
||||
case BYTE_MNEM_SUFFIX: mnemsuf_check.no_bsuf = 1; break;
|
||||
case WORD_MNEM_SUFFIX: mnemsuf_check.no_wsuf = 1; break;
|
||||
case SHORT_MNEM_SUFFIX: mnemsuf_check.no_ssuf = 1; break;
|
||||
case LONG_MNEM_SUFFIX: mnemsuf_check.no_lsuf = 1; break;
|
||||
case QWORD_MNEM_SUFFIX: mnemsuf_check.no_qsuf = 1; break;
|
||||
}
|
||||
case BYTE_MNEM_SUFFIX:
|
||||
suffix_check.no_bsuf = 1;
|
||||
break;
|
||||
case WORD_MNEM_SUFFIX:
|
||||
suffix_check.no_wsuf = 1;
|
||||
break;
|
||||
case SHORT_MNEM_SUFFIX:
|
||||
suffix_check.no_ssuf = 1;
|
||||
break;
|
||||
case LONG_MNEM_SUFFIX:
|
||||
suffix_check.no_lsuf = 1;
|
||||
break;
|
||||
case QWORD_MNEM_SUFFIX:
|
||||
suffix_check.no_qsuf = 1;
|
||||
break;
|
||||
default:
|
||||
/* NB: In Intel syntax, normally we can check for memory operand
|
||||
size when there is no mnemonic suffix. But jmp and call have
|
||||
2 different encodings with Dword memory operand size, one with
|
||||
No_ldSuf and the other without. i.suffix is set to
|
||||
LONG_DOUBLE_MNEM_SUFFIX to skip the one with No_ldSuf. */
|
||||
if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX)
|
||||
suffix_check.no_ldsuf = 1;
|
||||
}
|
||||
|
||||
/* Must have right number of operands. */
|
||||
@ -5768,23 +5768,14 @@ match_template (char mnem_suffix)
|
||||
|| (!intel64 && t->opcode_modifier.intel64))
|
||||
continue;
|
||||
|
||||
/* Check the suffix, except for some instructions in intel mode. */
|
||||
/* Check the suffix. */
|
||||
i.error = invalid_instruction_suffix;
|
||||
if ((!intel_syntax || !t->opcode_modifier.ignoresize)
|
||||
&& ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
|
||||
|| (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf)
|
||||
|| (t->opcode_modifier.no_lsuf && suffix_check.no_lsuf)
|
||||
|| (t->opcode_modifier.no_ssuf && suffix_check.no_ssuf)
|
||||
|| (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf)
|
||||
|| (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf)))
|
||||
continue;
|
||||
/* In Intel mode all mnemonic suffixes must be explicitly allowed. */
|
||||
if ((t->opcode_modifier.no_bsuf && mnemsuf_check.no_bsuf)
|
||||
|| (t->opcode_modifier.no_wsuf && mnemsuf_check.no_wsuf)
|
||||
|| (t->opcode_modifier.no_lsuf && mnemsuf_check.no_lsuf)
|
||||
|| (t->opcode_modifier.no_ssuf && mnemsuf_check.no_ssuf)
|
||||
|| (t->opcode_modifier.no_qsuf && mnemsuf_check.no_qsuf)
|
||||
|| (t->opcode_modifier.no_ldsuf && mnemsuf_check.no_ldsuf))
|
||||
if ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
|
||||
|| (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf)
|
||||
|| (t->opcode_modifier.no_lsuf && suffix_check.no_lsuf)
|
||||
|| (t->opcode_modifier.no_ssuf && suffix_check.no_ssuf)
|
||||
|| (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf)
|
||||
|| (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf))
|
||||
continue;
|
||||
|
||||
size_match = operand_size_match (t);
|
||||
|
15
gas/testsuite/gas/i386/code16.d
Normal file
15
gas/testsuite/gas/i386/code16.d
Normal file
@ -0,0 +1,15 @@
|
||||
#objdump: -drw -mi8086
|
||||
#name: i386 with .code16
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <.text>:
|
||||
+[a-f0-9]+: f3 66 a5 rep movsl %ds:\(%si\),%es:\(%di\)
|
||||
+[a-f0-9]+: f3 66 a7 repz cmpsl %es:\(%di\),%ds:\(%si\)
|
||||
+[a-f0-9]+: 66 f3 a5 rep movsl %ds:\(%si\),%es:\(%di\)
|
||||
+[a-f0-9]+: 66 f3 a7 repz cmpsl %es:\(%di\),%ds:\(%si\)
|
||||
+[a-f0-9]+: 66 f3 a5 rep movsl %ds:\(%si\),%es:\(%di\)
|
||||
+[a-f0-9]+: 66 f3 a7 repz cmpsl %es:\(%di\),%ds:\(%si\)
|
||||
#pass
|
9
gas/testsuite/gas/i386/code16.s
Normal file
9
gas/testsuite/gas/i386/code16.s
Normal file
@ -0,0 +1,9 @@
|
||||
.text
|
||||
.code16
|
||||
rep; movsd
|
||||
rep; cmpsd
|
||||
rep movsd %ds:(%si),%es:(%di)
|
||||
rep cmpsd %es:(%di),%ds:(%si)
|
||||
.intel_syntax noprefix
|
||||
rep movsd dword ptr es:[di], dword ptr ds:[si]
|
||||
rep cmpsd dword ptr ds:[si], dword ptr es:[di]
|
@ -132,6 +132,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
|
||||
run_dump_test "noreg32"
|
||||
run_dump_test "addr16"
|
||||
run_dump_test "addr32"
|
||||
run_dump_test "code16"
|
||||
run_list_test "oversized16" "-al"
|
||||
run_dump_test "sse4_1"
|
||||
run_dump_test "sse4_1-intel"
|
||||
|
@ -7,11 +7,11 @@
|
||||
.*:9: Error: operand type mismatch for `call'
|
||||
.*:10: Error: invalid instruction suffix for `call'
|
||||
.*:11: Error: invalid instruction suffix for `call'
|
||||
.*:12: Error: invalid instruction suffix for `call'
|
||||
.*:12: Error: operand size mismatch for `call'
|
||||
.*:13: Error: operand type mismatch for `jmp'
|
||||
.*:14: Error: invalid instruction suffix for `jmp'
|
||||
.*:15: Error: invalid instruction suffix for `jmp'
|
||||
.*:16: Error: invalid instruction suffix for `jmp'
|
||||
.*:16: Error: operand size mismatch for `jmp'
|
||||
GAS LISTING .*
|
||||
#...
|
||||
[ ]*1[ ]+\.text
|
||||
|
@ -1,3 +1,9 @@
|
||||
2019-11-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR gas/25167
|
||||
* i386-opc.tbl: Remove IgnoreSize from cmpsd and movsd.
|
||||
* i386-tbl.h: Regenerated.
|
||||
|
||||
2019-11-08 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* i386-gen.c (operand_type_init): Add Class= to
|
||||
|
@ -1405,7 +1405,7 @@ cmppd, 3, 0x66c2, None, 1, CpuAVX, Modrm|Vex|VexOpcode=0|VexVVVV=1|VexW=1|No_bSu
|
||||
cmppd, 3, 0x660fc2, None, 2, CpuSSE2, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM }
|
||||
// Intel mode string compare.
|
||||
cmpsd, 0, 0xa7, None, 1, 0, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { 0 }
|
||||
cmpsd, 2, 0xa7, None, 1, 0, Size32|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { Dword|Unspecified|BaseIndex|EsSeg, Dword|Unspecified|BaseIndex }
|
||||
cmpsd, 2, 0xa7, None, 1, 0, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { Dword|Unspecified|BaseIndex|EsSeg, Dword|Unspecified|BaseIndex }
|
||||
cmpsd, 3, 0xf2c2, None, 1, CpuAVX, Modrm|Vex=3|VexOpcode=0|VexVVVV=1|VexW=1|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|SSE2AVX, { Imm8, Qword|Unspecified|BaseIndex|RegXMM, RegXMM }
|
||||
cmpsd, 3, 0xf20fc2, None, 2, CpuSSE2, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, Qword|Unspecified|BaseIndex|RegXMM, RegXMM }
|
||||
comisd, 2, 0x662f, None, 1, CpuAVX, Modrm|Vex=3|VexOpcode=0|VexW=1|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|SSE2AVX, { Qword|Unspecified|BaseIndex|RegXMM, RegXMM }
|
||||
@ -1441,7 +1441,7 @@ movntpd, 2, 0x662b, None, 1, CpuAVX, Modrm|Vex|VexOpcode=0|VexW=1|No_bSuf|No_wSu
|
||||
movntpd, 2, 0x660f2b, None, 2, CpuSSE2, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM, Xmmword|Unspecified|BaseIndex }
|
||||
// Intel mode string move.
|
||||
movsd, 0, 0xa5, None, 1, 0, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { 0 }
|
||||
movsd, 2, 0xa5, None, 1, 0, Size32|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { Dword|Unspecified|BaseIndex, Dword|Unspecified|BaseIndex|EsSeg }
|
||||
movsd, 2, 0xa5, None, 1, 0, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, { Dword|Unspecified|BaseIndex, Dword|Unspecified|BaseIndex|EsSeg }
|
||||
movsd, 2, 0xf210, None, 1, CpuAVX, D|Modrm|Vex=3|VexOpcode=0|VexW=1|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|SSE2AVX, { Qword|Unspecified|BaseIndex, RegXMM }
|
||||
movsd, 2, 0xf210, None, 1, CpuAVX, D|Modrm|Vex=3|VexOpcode=0|VexVVVV=1|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|SSE2AVX, { RegXMM, RegXMM }
|
||||
movsd, 2, 0xf20f10, None, 2, CpuSSE2, D|Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Qword|Unspecified|BaseIndex|RegXMM, RegXMM }
|
||||
|
@ -15607,7 +15607,7 @@ const insn_template i386_optab[] =
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 1, 1, 1, 1, 1,
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1, 1,
|
||||
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0 },
|
||||
@ -16134,7 +16134,7 @@ const insn_template i386_optab[] =
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 1, 1, 1, 1, 1,
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1, 1,
|
||||
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0 },
|
||||
|
Loading…
Reference in New Issue
Block a user