aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2019-11-08 09:31:06 -0800
committerH.J. Lu <hjl.tools@gmail.com>2019-11-08 09:31:17 -0800
commitdc2be329b9508395b7270b7c3bebc19a6f1e2e07 (patch)
tree04840e8c94ba97be2d64220119e2a70cb77f9c39 /gas
parent992a70401ec229425ee75b2ad9b731f30d2de391 (diff)
downloadfsf-binutils-gdb-dc2be329b9508395b7270b7c3bebc19a6f1e2e07.zip
fsf-binutils-gdb-dc2be329b9508395b7270b7c3bebc19a6f1e2e07.tar.gz
fsf-binutils-gdb-dc2be329b9508395b7270b7c3bebc19a6f1e2e07.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-i386.c75
-rw-r--r--gas/testsuite/gas/i386/code16.d15
-rw-r--r--gas/testsuite/gas/i386/code16.s9
-rw-r--r--gas/testsuite/gas/i386/i386.exp1
-rw-r--r--gas/testsuite/gas/i386/x86-64-branch-4.l4
6 files changed, 69 insertions, 44 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 75e056c..29cf763 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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,
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ba6b82a..abbb93a 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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);
diff --git a/gas/testsuite/gas/i386/code16.d b/gas/testsuite/gas/i386/code16.d
new file mode 100644
index 0000000..b860448
--- /dev/null
+++ b/gas/testsuite/gas/i386/code16.d
@@ -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
diff --git a/gas/testsuite/gas/i386/code16.s b/gas/testsuite/gas/i386/code16.s
new file mode 100644
index 0000000..d18fa51
--- /dev/null
+++ b/gas/testsuite/gas/i386/code16.s
@@ -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]
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index ff2d235..4e7f8b9 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -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"
diff --git a/gas/testsuite/gas/i386/x86-64-branch-4.l b/gas/testsuite/gas/i386/x86-64-branch-4.l
index db55394..8f681f8 100644
--- a/gas/testsuite/gas/i386/x86-64-branch-4.l
+++ b/gas/testsuite/gas/i386/x86-64-branch-4.l
@@ -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