[binutils-gdb] x86/Solaris: support Sun form of CMOVcc

Jan Beulich jbeulich@sourceware.org
Fri Nov 29 08:38:08 GMT 2024


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

commit 8a07ebae720c312aef3f19abf2070fbf4ba11187
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Nov 29 09:37:13 2024 +0100

    x86/Solaris: support Sun form of CMOVcc
    
    Sun specifies an alternative form for CMOVcc [1], which for some reason
    we never cared to support, even if - as per gcc's configure checking for
    it - it may have been the only permitted form at some point.
    
    While documentation doesn't indicate FCMOVcc to have similar alternative
    forms, gcc assumes so. Hence cover FCMOVcc as well.
    
    [1] https://docs.oracle.com/cd/E37838_01/html/E61064/ennbz.html#XALRMeoizm

Diff:
---
 gas/config/tc-i386.c                       | 27 +++++++++++++++++++++++++++
 gas/testsuite/gas/i386/solaris/cmov.d      | 27 +++++++++++++++++++++++++++
 gas/testsuite/gas/i386/solaris/cmov.s      | 24 ++++++++++++++++++++++++
 gas/testsuite/gas/i386/solaris/solaris.exp |  2 ++
 4 files changed, 80 insertions(+)

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ab4e57b95e4..55fd2be8b30 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7757,6 +7757,33 @@ 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
new file mode 100644
index 00000000000..16467ad9879
--- /dev/null
+++ b/gas/testsuite/gas/i386/solaris/cmov.d
@@ -0,0 +1,27 @@
+#objdump: -dw
+#name: {,F}CMOVcc alternative forms
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <cmov>:
+[ 	]*[a-f0-9]+:	0f 47 c8             	cmova  %eax,%ecx
+[ 	]*[a-f0-9]+:	0f 47 c8             	cmova  %eax,%ecx
+[ 	]*[a-f0-9]+:	0f 47 c8             	cmova  %eax,%ecx
+[ 	]*[a-f0-9]+:	0f 47 c8             	cmova  %eax,%ecx
+[ 	]*[a-f0-9]+:	66 0f 4a c8          	cmovp  %ax,%cx
+[ 	]*[a-f0-9]+:	66 0f 4a c8          	cmovp  %ax,%cx
+[ 	]*[a-f0-9]+:	66 0f 4a c8          	cmovp  %ax,%cx
+[ 	]*[a-f0-9]+:	66 0f 4a c8          	cmovp  %ax,%cx
+[ 	]*[a-f0-9]+:	0f 4c 08             	cmovl  \(%rax\),%ecx
+[ 	]*[a-f0-9]+:	0f 4c 08             	cmovl  \(%rax\),%ecx
+[ 	]*[a-f0-9]+:	0f 4c 08             	cmovl  \(%rax\),%ecx
+[ 	]*[a-f0-9]+:	0f 4c 08             	cmovl  \(%rax\),%ecx
+[ 	]*[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]+:	48 0f 44 08          	cmove  \(%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
new file mode 100644
index 00000000000..e5026efa25c
--- /dev/null
+++ b/gas/testsuite/gas/i386/solaris/cmov.s
@@ -0,0 +1,24 @@
+	.text
+cmov:
+	cmova		%eax, %ecx
+	cmov.a		%eax, %ecx
+	cmovnbe		%eax, %ecx
+	cmov.nbe	%eax, %ecx
+
+	cmovpw		%ax, %cx
+	cmovw.p		%ax, %cx
+	cmovpew		%ax, %cx
+	cmovw.pe	%ax, %cx
+
+	cmovll		(%rax), %ecx
+	cmovl.l		(%rax), %ecx
+	cmovngel	(%rax), %ecx
+	cmovl.nge	(%rax), %ecx
+
+	cmovzq		(%rax), %rcx
+	cmovq.z		(%rax), %rcx
+	cmoveq		(%rax), %rcx
+	cmovq.e		(%rax), %rcx
+
+	fcmovu		%st(1), %st
+	fcmov.u		%st(1), %st
diff --git a/gas/testsuite/gas/i386/solaris/solaris.exp b/gas/testsuite/gas/i386/solaris/solaris.exp
index 6e4ddcafc3f..dccdbf7d5bd 100644
--- a/gas/testsuite/gas/i386/solaris/solaris.exp
+++ b/gas/testsuite/gas/i386/solaris/solaris.exp
@@ -32,6 +32,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check] &&
     set ASFLAGS "$ASFLAGS --64 --defsym x86_64=1 --strip-local-absolute"
 
     run_dump_test "reloc64"
+    run_dump_test "cmov"
+
     run_dump_test "x86-64-mpx-branch-1"
     run_dump_test "x86-64-mpx-branch-2"


More information about the Binutils-cvs mailing list