From 4bb19de4b6cbe56636a1e7cd9c53aae3dcf4d4b0 Mon Sep 17 00:00:00 2001 From: Xiang1 Zhang Date: Fri, 15 Jul 2022 11:18:33 +0800 Subject: [PATCH] [X86] Add 64 bit implement for __SSC_MARK Reviewed By: craig.topper, pengfei.wang, jinsong Differential Revision: https://reviews.llvm.org/D129826 --- clang/lib/Headers/x86gprintrin.h | 28 +++++++++++++++++++++++----- clang/test/CodeGen/X86/x86-ssc-mark.c | 33 +++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/clang/lib/Headers/x86gprintrin.h b/clang/lib/Headers/x86gprintrin.h index 01e741f..2c2fbb9 100644 --- a/clang/lib/Headers/x86gprintrin.h +++ b/clang/lib/Headers/x86gprintrin.h @@ -25,11 +25,29 @@ #include #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 */ diff --git a/clang/test/CodeGen/X86/x86-ssc-mark.c b/clang/test/CodeGen/X86/x86-ssc-mark.c index bcfee4f..0eb86c7 100644 --- a/clang/test/CodeGen/X86/x86-ssc-mark.c +++ b/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); } -- 2.7.4