Index: clang/lib/Headers/x86gprintrin.h =================================================================== --- clang/lib/Headers/x86gprintrin.h +++ clang/lib/Headers/x86gprintrin.h @@ -25,11 +25,29 @@ #include #endif +#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__("mov {%%ebx, %%eax|eax, ebx}; " \ - "mov {%0, %%ebx|ebx, %0}; " \ + __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: clang/test/CodeGen/X86/x86-ssc-mark.c =================================================================== --- clang/test/CodeGen/X86/x86-ssc-mark.c +++ clang/test/CodeGen/X86/x86-ssc-mark.c @@ -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 // 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); }