diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 75 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/code16.d | 15 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/code16.s | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/i386.exp | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-branch-4.l | 4 |
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 |