[binutils-gdb/binutils-2_44-branch] x86/Solaris: correct support for Sun form of CMOV<size>.S

Jan Beulich jbeulich@sourceware.org
Wed Jan 22 08:56:33 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4aa7c2f11182ba7f9102e3d6205992f23cf64233

commit 4aa7c2f11182ba7f9102e3d6205992f23cf64233
Author: Jan Beulich <jbeulich@suse.com>
Date:   Wed Jan 22 09:51:23 2025 +0100

    x86/Solaris: correct support for Sun form of CMOV<size>.S
    
    PR gas/32579
    
    The deprecated .s (swapped operand encoding) functionality got in the
    way of properly recognizing this specific form. Move the Solaris-
    specific code ahead of that.

Diff:
---
 gas/config/tc-i386.c                  | 53 +++++++++++++++++------------------
 gas/testsuite/gas/i386/solaris/cmov.d |  4 +++
 gas/testsuite/gas/i386/solaris/cmov.s |  5 ++++
 3 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 8498b13e2df..e5988347e0a 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7751,6 +7751,32 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
 
   if (!current_templates.start)
     {
+#ifdef TE_SOLARIS
+      /* Sun specifies an alternative form for CMOVcc: Size suffix (if any)
+	 first, then a dot, then the condition code mnemonic.  */
+      if ((mnemonic + 4 == dot_p && !memcmp (mnemonic, "cmov", 4))
+	  /* While doc doesn't say so, gcc assumes it: Same for FCMOVcc,
+	     except that there's no size suffix to care about.  */
+	  || (mnemonic + 5 == dot_p && !memcmp (mnemonic, "fcmov", 5)))
+	{
+	  /* Simply strip the dot.  */
+	  memmove (dot_p, dot_p + 1, mnem_p - dot_p);
+	  dot_p = mnem_p - 1;
+	}
+      else if (!intel_syntax
+	       && mnemonic + 5 == dot_p
+	       && !memcmp (mnemonic, "cmov", 4)
+	       && strchr ("lqw", TOLOWER (dot_p[-1])))
+	{
+	  /* Strip the dot, while moving the suffix.  */
+	  char suffix = dot_p[-1];
+
+	  memmove (dot_p - 1, dot_p + 1, mnem_p - dot_p);
+	  mnem_p[-2] = suffix;
+	  dot_p = mnem_p - 1;
+	}
+      else
+#endif
       /* Deprecated functionality (new code should use pseudo-prefixes instead):
 	 Check if we should swap operand or force 32bit displacement in
 	 encoding.  */
@@ -7781,33 +7807,6 @@ parse_insn (const char *line, char *mnemonic, enum parse_mode mode)
 	  else if (pp.disp_encoding != disp_encoding_32bit)
 	    as_warn (_("ignoring `.d32' suffix due to earlier `{disp<N>}'"));
 	}
-#ifdef TE_SOLARIS
-      /* Sun specifies an alternative form for CMOVcc: Size suffix (if any)
-	 first, then a dot, then the condition code mnemonic.  */
-      else if ((mnemonic + 4 == dot_p
-		&& !memcmp (mnemonic, "cmov", 4))
-	       /* While doc doesn't say so, gcc assumes it: Same for FCMOVcc,
-		  except that there's no size suffix to care about.  */
-	       || (mnemonic + 5 == dot_p
-		   && !memcmp (mnemonic, "fcmov", 5)))
-	{
-	  /* Simply strip the dot.  */
-	  memmove (dot_p, dot_p + 1, mnem_p - dot_p);
-	  dot_p = mnem_p - 1;
-	}
-      else if (!intel_syntax
-	       && mnemonic + 5 == dot_p
-	       && !memcmp (mnemonic, "cmov", 4)
-	       && strchr ("lqw", TOLOWER (dot_p[-1])))
-	{
-	  /* Strip the dot, while moving the suffix.  */
-	  char suffix = dot_p[-1];
-
-	  memmove (dot_p - 1, dot_p + 1, mnem_p - dot_p);
-	  mnem_p[-2] = suffix;
-	  dot_p = mnem_p - 1;
-	}
-#endif
       else
 	goto check_suffix;
       mnem_p = dot_p;
diff --git a/gas/testsuite/gas/i386/solaris/cmov.d b/gas/testsuite/gas/i386/solaris/cmov.d
index 16467ad9879..a4f2e443e1f 100644
--- a/gas/testsuite/gas/i386/solaris/cmov.d
+++ b/gas/testsuite/gas/i386/solaris/cmov.d
@@ -22,6 +22,10 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	48 0f 44 08          	cmove  \(%rax\),%rcx
 [ 	]*[a-f0-9]+:	48 0f 44 08          	cmove  \(%rax\),%rcx
 [ 	]*[a-f0-9]+:	48 0f 44 08          	cmove  \(%rax\),%rcx
+[ 	]*[a-f0-9]+:	0f 48 c8             	cmovs  %eax,%ecx
+[ 	]*[a-f0-9]+:	66 0f 48 c8          	cmovs  %ax,%cx
+[ 	]*[a-f0-9]+:	0f 48 c8             	cmovs  %eax,%ecx
+[ 	]*[a-f0-9]+:	48 0f 48 c8          	cmovs  %rax,%rcx
 [ 	]*[a-f0-9]+:	da d9                	fcmovu %st\(1\),%st
 [ 	]*[a-f0-9]+:	da d9                	fcmovu %st\(1\),%st
 #pass
diff --git a/gas/testsuite/gas/i386/solaris/cmov.s b/gas/testsuite/gas/i386/solaris/cmov.s
index e5026efa25c..93173b962c4 100644
--- a/gas/testsuite/gas/i386/solaris/cmov.s
+++ b/gas/testsuite/gas/i386/solaris/cmov.s
@@ -20,5 +20,10 @@ cmov:
 	cmoveq		(%rax), %rcx
 	cmovq.e		(%rax), %rcx
 
+	cmov.s		%eax, %ecx
+	cmovw.s		%ax, %cx
+	cmovl.s		%eax, %ecx
+	cmovq.s		%rax, %rcx
+
 	fcmovu		%st(1), %st
 	fcmov.u		%st(1), %st


More information about the Binutils-cvs mailing list