[PATCH 2/2] x86: make sure all PUSH/POP honor DefaultSize

Jan Beulich jbeulich@suse.com
Mon Nov 25 07:29:00 GMT 2019


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.

gas/
2019-11-XX  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.

--- 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
--- a/gas/testsuite/gas/i386/general.l
+++ b/gas/testsuite/gas/i386/general.l
@@ -32,6 +32,10 @@
 .*:144: Warning:.*
 .*:178: Warning:.*
 .*:224: Warning:.*
+.*:233: Warning:.*
+.*:234: Warning:.*
+.*:238: Warning:.*
+.*:239: Warning:.*
    1                       	.psize 0
    2                       	.text
    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]*[ 	]+66683412 0000[ 	]+push	\$0x1234
 [ 	]*[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]*[ 	]+669C[ 	]+pushf
 [ 	]*[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]*[ 	]+669D[ 	]+popf
 [ 	]*[1-9][0-9]*[ 	]+[0-9a-f]*[ 	]+66C3[ 	]+ret
--- a/gas/testsuite/gas/i386/general.s
+++ b/gas/testsuite/gas/i386/general.s
@@ -230,9 +230,13 @@
 	push	$0
 	push	$0x1234
 	push	(%bx)
+	push	%es
+	push	%fs
 	pusha
 	pushf
 	pop	(%bx)
+	pop	%es
+	pop	%fs
 	popa
 	popf
 	ret



More information about the Binutils mailing list