[X86] Add 64 bit implement for __SSC_MARK
authorXiang1 Zhang <xiang1.zhang@intel.com>
Fri, 15 Jul 2022 03:18:33 +0000 (11:18 +0800)
committerXiang1 Zhang <xiang1.zhang@intel.com>
Tue, 19 Jul 2022 08:13:41 +0000 (16:13 +0800)
Reviewed By: craig.topper, pengfei.wang, jinsong
Differential Revision: https://reviews.llvm.org/D129826

clang/lib/Headers/x86gprintrin.h
clang/test/CodeGen/X86/x86-ssc-mark.c

index 01e741f..2c2fbb9 100644 (file)
 #include <crc32intrin.h>
 #endif
 
-#define __SSC_MARK(Tag)                                                        \
-  __asm__ __volatile__("mov {%%ebx, %%eax|eax, ebx}; "                      \
-                       "mov {%0, %%ebx|ebx, %0}; "                          \
+#if defined(__i386__)
+#define __FULLBX "ebx"
+#define __TMPGPR "eax"
+#else
+// When in 64-bit target, the 32-bit operands generate a 32-bit result,
+// zero-extended to a 64-bit result in the destination general-purpose,
+// It means "mov x %ebx" will clobber the higher 32 bits of rbx, so we
+// should preserve the 64-bit register rbx.
+#define __FULLBX "rbx"
+#define __TMPGPR "rax"
+#endif
+
+#define __MOVEGPR(__r1, __r2) "mov {%%"__r1 ", %%"__r2 "|"__r2 ", "__r1"};"
+
+#define __SAVE_GPRBX __MOVEGPR(__FULLBX, __TMPGPR)
+#define __RESTORE_GPRBX __MOVEGPR(__TMPGPR, __FULLBX)
+
+#define __SSC_MARK(__Tag)                                                      \
+  __asm__ __volatile__( __SAVE_GPRBX                                           \
+                       "mov {%0, %%ebx|ebx, %0}; "                             \
                        ".byte 0x64, 0x67, 0x90; "                              \
-                       "mov {%%eax, %%ebx|ebx, eax};" ::"i"(Tag)            \
-                       : "%eax");
+                        __RESTORE_GPRBX                                        \
+                       ::"i"(__Tag)                                            \
+                       :  __TMPGPR );
 
 #endif /* __X86GPRINTRIN_H */
index bcfee4f..0eb86c7 100644 (file)
@@ -1,20 +1,29 @@
 // REQUIRES: x86-registered-target
-// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -S -ffreestanding -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple=i386-unknown-unknown -S -ffreestanding -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i386-unknown-unknown -S -ffreestanding -o - | FileCheck %s --check-prefix=X86
+// RUN: %clang_cc1 %s -triple=x86_64-unknown-unknown -S -ffreestanding -o - | FileCheck %s --check-prefix=X64
 
 #include <immintrin.h>
 
 // The ebx may be use for base pointer, we need to restore it in time.
 void ssc_mark(void) {
-// CHECK-LABEL: ssc_mark
-// CHECK: #APP
-// CHECK: movl    %ebx, %eax
-// CHECK: movl    $0, %ebx
-// CHECK: .byte   100
-// CHECK: .byte   103
-// CHECK: .byte   144
-// CHECK: movl    %eax, %ebx
-// CHECK: #NO_APP
+// X86-LABEL: ssc_mark
+// X86: #APP
+// X86: movl    %ebx, %eax
+// X86: movl    $9, %ebx
+// X86: .byte   100
+// X86: .byte   103
+// X86: .byte   144
+// X86: movl    %eax, %ebx
+// X86: #NO_APP
 
-  __SSC_MARK(0x0);
+// X64-LABEL: ssc_mark
+// X64: #APP
+// X64: movq    %rbx, %rax
+// X64: movl    $9, %ebx
+// X64: .byte   100
+// X64: .byte   103
+// X64: .byte   144
+// X64: movq    %rax, %rbx
+// X64: #NO_APP
+  __SSC_MARK(0x9);
 }