if (Kind != CK_Lakemont)
setFeatureEnabledImpl(Features, "x87", true);
+ // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards
+ // compatibility.
+ if (Kind >= CK_i586 || Kind == CK_Generic)
+ setFeatureEnabledImpl(Features, "cx8", true);
+
switch (Kind) {
case CK_Generic:
case CK_i386:
HasMOVBE = true;
} else if (Feature == "+sgx") {
HasSGX = true;
+ } else if (Feature == "+cx8") {
+ HasCX8 = true;
} else if (Feature == "+cx16") {
HasCX16 = true;
} else if (Feature == "+fxsr") {
break;
}
- if (CPU >= CK_i486) {
+ if (CPU >= CK_i486 || CPU == CK_Generic) {
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
}
- if (CPU >= CK_i586)
+ if (HasCX8)
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
.Case("clflushopt", HasCLFLUSHOPT)
.Case("clwb", HasCLWB)
.Case("clzero", HasCLZERO)
+ .Case("cx8", HasCX8)
.Case("cx16", HasCX16)
.Case("f16c", HasF16C)
.Case("fma", HasFMA)
bool HasMPX = false;
bool HasSHSTK = false;
bool HasSGX = false;
+ bool HasCX8 = false;
bool HasCX16 = false;
bool HasFXSR = false;
bool HasXSAVE = false;
(1 << TargetInfo::LongDouble));
// x86-32 has atomics up to 8 bytes
- // FIXME: Check that we actually have cmpxchg8b before setting
- // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ MaxAtomicPromoteWidth = 64;
+ MaxAtomicInlineWidth = 32;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return X86TargetInfo::validateOperandSize(Constraint, Size);
}
+ void setMaxAtomicWidth() override {
+ if (hasFeature("cx8"))
+ MaxAtomicInlineWidth = 64;
+ }
+
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
};
// WINDOWS: define dso_local i32 @DispatchFirst.B
// WINDOWS: ret i32 1
-// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
-// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
-// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87"
+// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+cx8,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
+// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+cx8,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
+// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+cx8,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87"
_mm_srai_pi32(a, c);
}
-// CHECK: "target-features"="+mmx,+sse,+x87"
+// CHECK: "target-features"="+cx8,+mmx,+sse,+x87"
// CHECK: qq{{.*}} #6
// CHECK: lake{{.*}} #7
// CHECK: use_before_def{{.*}} #7
-// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+x87"
-// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
-// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-aes,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
-// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
-// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
-// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes"
-// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-3dnow,-3dnowa,-mmx"
-// CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+mmx"
+// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87"
+// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
+// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-aes,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
+// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
+// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
+// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes"
+// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-3dnow,-3dnowa,-mmx"
+// CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+cx8,+mmx"
// CHECK: foo{{.*}} #0
// CHECK: bar{{.*}} #1
-// CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
+// CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
// HARD: "use-soft-float"="false"
// SOFT: "use-soft-float"="true"
-// CHECK: #1 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,-x87"
+// CHECK: #1 = {{.*}}"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,-x87"
// HARD: "use-soft-float"="false"
// SOFT: "use-soft-float"="true"
// I386:#define __i386__ 1
// I386:#define i386 1
//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN32 %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX -check-prefix I386-LINUX-ALIGN32 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN64 %s
//
// I386-LINUX-NOT:#define _LP64
// I386-LINUX:#define __BIGGEST_ALIGNMENT__ 16
// I386-LINUX:#define __FLT_MIN_EXP__ (-125)
// I386-LINUX:#define __FLT_MIN__ 1.17549435e-38F
// I386-LINUX:#define __FLT_RADIX__ 2
+// I386-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// I386-LINUX-ALIGN32:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// I386-LINUX-ALIGN64:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// I386-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// I386-LINUX:#define __INT16_C_SUFFIX__
// I386-LINUX:#define __INT16_FMTd__ "hd"
// I386-LINUX:#define __INT16_FMTi__ "hi"
// I386-LINUX:#define __i386__ 1
// I386-LINUX:#define i386 1
//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
+//
//
// I386-NETBSD-NOT:#define _LP64
// I386-NETBSD:#define __BIGGEST_ALIGNMENT__ 16
// I386-NETBSD:#define __FLT_MIN_EXP__ (-125)
// I386-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
// I386-NETBSD:#define __FLT_RADIX__ 2
+// I386-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// I386-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// I386-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// I386-NETBSD:#define __INT16_C_SUFFIX__
// I386-NETBSD:#define __INT16_FMTd__ "hd"
// I386-NETBSD:#define __INT16_FMTi__ "hi"
// X86_64-LINUX:#define __FLT_MIN_EXP__ (-125)
// X86_64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
// X86_64-LINUX:#define __FLT_RADIX__ 2
+// X86_64-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// X86_64-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// X86_64-LINUX:#define __INT16_C_SUFFIX__
// X86_64-LINUX:#define __INT16_FMTd__ "hd"
// X86_64-LINUX:#define __INT16_FMTi__ "hi"
// X86_64-NETBSD:#define __FLT_MIN_EXP__ (-125)
// X86_64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
// X86_64-NETBSD:#define __FLT_RADIX__ 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// X86_64-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// X86_64-NETBSD:#define __INT16_C_SUFFIX__
// X86_64-NETBSD:#define __INT16_FMTd__ "hd"
// X86_64-NETBSD:#define __INT16_FMTi__ "hi"
// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS64
// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
-// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | grep GCC | count 1
+// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | grep GCC | count 5
// CHECK-MS64: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS64: #define _MSC_EXTENSIONS 1
// CHECK-MS64: #define _MSC_VER 1900
// CHECK-MS64-NOT: GNU
// CHECK-MS64-NOT: GXX
// CHECK-MS64: #define __GCC_ASM_FLAG_OUTPUTS__ 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
// CHECK-MS64-NOT: GNU
// CHECK-MS64-NOT: GXX
// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS
// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
-// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | grep GCC | count 1
+// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | grep GCC | count 5
// CHECK-MS: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS: #define _MSC_EXTENSIONS 1
// CHECK-MS: #define _MSC_VER 1900
// CHECK-MS-NOT: GNU
// CHECK-MS-NOT: GXX
// CHECK-MS: #define __GCC_ASM_FLAG_OUTPUTS__ 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
// CHECK-MS-NOT: GNU
// CHECK-MS-NOT: GXX