diff options
Diffstat (limited to 'clang/lib/Headers/x86gprintrin.h')
-rw-r--r-- | clang/lib/Headers/x86gprintrin.h | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/clang/lib/Headers/x86gprintrin.h b/clang/lib/Headers/x86gprintrin.h index 01e741f1eb61..2c2fbb97c9ac 100644 --- a/clang/lib/Headers/x86gprintrin.h +++ b/clang/lib/Headers/x86gprintrin.h @@ -25,11 +25,29 @@ #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 */ |