aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2025-01-22 09:51:23 +0100
committerJan Beulich <jbeulich@suse.com>2025-01-22 09:55:34 +0100
commit4aa7c2f11182ba7f9102e3d6205992f23cf64233 (patch)
treeb14c61bdc8f9d874dcbd235b624b119dd71d2df4
parent9fa991b6a4229090f44c228f7dc61746cc758197 (diff)
downloadgdb-4aa7c2f11182ba7f9102e3d6205992f23cf64233.zip
gdb-4aa7c2f11182ba7f9102e3d6205992f23cf64233.tar.gz
gdb-4aa7c2f11182ba7f9102e3d6205992f23cf64233.tar.bz2
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.
-rw-r--r--gas/config/tc-i386.c53
-rw-r--r--gas/testsuite/gas/i386/solaris/cmov.d4
-rw-r--r--gas/testsuite/gas/i386/solaris/cmov.s5
3 files changed, 35 insertions, 27 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 8498b13..e598834 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 16467ad..a4f2e44 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 e5026ef..93173b9 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