x86: make sure all PUSH/POP honor DefaultSize

While segment registers are registers, their use doesn't allow sizing
of insns without suffix / explicit operand size specifier. Prevent
PUSH and POP of segment registers from entering that path, instead
allowing them to observe the stackop_size setting just like other
PUSH/POP and alike do.
This commit is contained in:
Jan Beulich
2019-12-04 10:40:40 +01:00
parent 3036c89919
commit 13e600d0f5
4 changed files with 40 additions and 8 deletions

View File

@ -1,3 +1,13 @@
2019-12-04 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (process_suffix): Arrange for insns with a
single non-GPR register operand to not have its suffix guessed
from GPR operands. Extend DefaultSize handling to cover PUSH/POP
of segment registers.
* testsuite/gas/i386/general.s: Add PUSH/POP sreg to .code16gcc
set of insns.
* testsuite/gas/i386/general.l: Adjust expectations.
2019-12-04 Jan Beulich <jbeulich@suse.com> 2019-12-04 Jan Beulich <jbeulich@suse.com>
* config/tc-i386.c (process_suffix): Exclude SYSRET alongside * config/tc-i386.c (process_suffix): Exclude SYSRET alongside

View File

@ -6207,10 +6207,11 @@ process_suffix (void)
i.suffix = LONG_MNEM_SUFFIX; i.suffix = LONG_MNEM_SUFFIX;
else if (i.tm.opcode_modifier.size == SIZE64) else if (i.tm.opcode_modifier.size == SIZE64)
i.suffix = QWORD_MNEM_SUFFIX; i.suffix = QWORD_MNEM_SUFFIX;
else if (i.reg_operands) else if (i.reg_operands
&& (i.operands > 1 || i.types[0].bitfield.class == Reg))
{ {
/* If there's no instruction mnemonic suffix we try to invent one /* If there's no instruction mnemonic suffix we try to invent one
based on register operands. */ based on GPR operands. */
if (!i.suffix) if (!i.suffix)
{ {
/* We take i.suffix from the last register operand specified, /* We take i.suffix from the last register operand specified,
@ -6315,19 +6316,24 @@ process_suffix (void)
/* exclude sysret */ /* exclude sysret */
&& i.tm.base_opcode != 0x0f07) && i.tm.base_opcode != 0x0f07)
{ {
if (stackop_size == LONG_MNEM_SUFFIX i.suffix = stackop_size;
&& i.tm.base_opcode == 0xcf) if (stackop_size == LONG_MNEM_SUFFIX)
{ {
/* stackop_size is set to LONG_MNEM_SUFFIX for the /* stackop_size is set to LONG_MNEM_SUFFIX for the
.code16gcc directive to support 16-bit mode with .code16gcc directive to support 16-bit mode with
32-bit address. For IRET without a suffix, generate 32-bit address. For IRET without a suffix, generate
16-bit IRET (opcode 0xcf) to return from an interrupt 16-bit IRET (opcode 0xcf) to return from an interrupt
handler. */ handler. */
i.suffix = WORD_MNEM_SUFFIX; if (i.tm.base_opcode == 0xcf)
as_warn (_("generating 16-bit `iret' for .code16gcc directive")); {
i.suffix = WORD_MNEM_SUFFIX;
as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
}
/* Warn about changed behavior for segment register push/pop. */
else if ((i.tm.base_opcode | 1) == 0x07)
as_warn (_("generating 32-bit `%s', unlike earlier gas versions"),
i.tm.name);
} }
else
i.suffix = stackop_size;
} }
else if (intel_syntax else if (intel_syntax
&& !i.suffix && !i.suffix

View File

@ -32,6 +32,10 @@
.*:144: Warning:.* .*:144: Warning:.*
.*:178: Warning:.* .*:178: Warning:.*
.*:224: Warning:.* .*:224: Warning:.*
.*:233: Warning:.*
.*:234: Warning:.*
.*:238: Warning:.*
.*:239: Warning:.*
1 .psize 0 1 .psize 0
2 .text 2 .text
3 #test jumps and calls 3 #test jumps and calls
@ -298,9 +302,17 @@
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+666A00[ ]+push \$0 [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+666A00[ ]+push \$0
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66683412 0000[ ]+push \$0x1234 [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66683412 0000[ ]+push \$0x1234
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66FF37[ ]+push \(%bx\) [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66FF37[ ]+push \(%bx\)
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6606[ ]+push %es
.*Warning:.*32-bit.*push.*
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+660FA0[ ]+push %fs
.*Warning:.*32-bit.*push.*
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6660[ ]+pusha [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6660[ ]+pusha
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+669C[ ]+pushf [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+669C[ ]+pushf
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+668F07[ ]+pop \(%bx\) [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+668F07[ ]+pop \(%bx\)
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6607[ ]+pop %es
.*Warning:.*32-bit.*pop.*
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+660FA1[ ]+pop %fs
.*Warning:.*32-bit.*pop.*
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6661[ ]+popa [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+6661[ ]+popa
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+669D[ ]+popf [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+669D[ ]+popf
[ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66C3[ ]+ret [ ]*[1-9][0-9]*[ ]+[0-9a-f]*[ ]+66C3[ ]+ret

View File

@ -230,9 +230,13 @@
push $0 push $0
push $0x1234 push $0x1234
push (%bx) push (%bx)
push %es
push %fs
pusha pusha
pushf pushf
pop (%bx) pop (%bx)
pop %es
pop %fs
popa popa
popf popf
ret ret