aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2024-11-29 09:37:13 +0100
committerJan Beulich <jbeulich@suse.com>2024-11-29 09:37:13 +0100
commit8a07ebae720c312aef3f19abf2070fbf4ba11187 (patch)
tree12401a84eec5ab543abe069559438ff622399e12 /gas
parent37fb148efeb246e93b0705e662df47118b04ba66 (diff)
downloadgdb-8a07ebae720c312aef3f19abf2070fbf4ba11187.zip
gdb-8a07ebae720c312aef3f19abf2070fbf4ba11187.tar.gz
gdb-8a07ebae720c312aef3f19abf2070fbf4ba11187.tar.bz2
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
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-i386.c27
-rw-r--r--gas/testsuite/gas/i386/solaris/cmov.d27
-rw-r--r--gas/testsuite/gas/i386/solaris/cmov.s24
-rw-r--r--gas/testsuite/gas/i386/solaris/solaris.exp2
4 files changed, 80 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ab4e57b..55fd2be 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 0000000..16467ad
--- /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 0000000..e5026ef
--- /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 6e4ddca..dccdbf7 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"