diff options
author | Jan Beulich <jbeulich@suse.com> | 2019-12-04 10:40:40 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2019-12-04 10:40:40 +0100 |
commit | 13e600d0f5601e354f1f3ed896db35845a682fee (patch) | |
tree | 0a66e700226c227eecf509ca406a3586b02a9e35 /gas/config | |
parent | 3036c8991964674ca2407c543645d841ad431267 (diff) | |
download | binutils-gdb-13e600d0f5601e354f1f3ed896db35845a682fee.tar.gz |
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.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-i386.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 64312d27ab0..b8babed68ba 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6207,10 +6207,11 @@ process_suffix (void) i.suffix = LONG_MNEM_SUFFIX; else if (i.tm.opcode_modifier.size == SIZE64) 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 - based on register operands. */ + based on GPR operands. */ if (!i.suffix) { /* We take i.suffix from the last register operand specified, @@ -6315,19 +6316,24 @@ process_suffix (void) /* exclude sysret */ && i.tm.base_opcode != 0x0f07) { - if (stackop_size == LONG_MNEM_SUFFIX - && i.tm.base_opcode == 0xcf) + i.suffix = stackop_size; + if (stackop_size == LONG_MNEM_SUFFIX) { /* stackop_size is set to LONG_MNEM_SUFFIX for the .code16gcc directive to support 16-bit mode with 32-bit address. For IRET without a suffix, generate 16-bit IRET (opcode 0xcf) to return from an interrupt handler. */ - i.suffix = WORD_MNEM_SUFFIX; - as_warn (_("generating 16-bit `iret' for .code16gcc directive")); + if (i.tm.base_opcode == 0xcf) + { + 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 && !i.suffix |