summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Khasanov <rob.khasanov@gmail.com>2014-09-19 10:29:22 +0000
committerRobert Khasanov <rob.khasanov@gmail.com>2014-09-19 10:29:22 +0000
commit7c96e0197cc969ca963814fdf76be2b6e8744e8b (patch)
treef29c3043a9cec5cfb06fa1436820aef3f6a43782
parente78020210a782def1570f7e2adef94b2b647cc0d (diff)
[x86] Add _addcarry_u{32|64} and _subborrow_u{32|64}.
They are added to adxintrin.h but outside __ADX__ block. These intrinics generates adc and sbb correspondingly that were available before ADX git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218118 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/BuiltinsX86.def4
-rw-r--r--lib/Headers/adxintrin.h34
-rw-r--r--test/CodeGen/adc-builtins.c31
3 files changed, 69 insertions, 0 deletions
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 0cced4cfbd..a571fca96f 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -628,6 +628,10 @@ BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "")
// ADX
BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "")
BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "")
+BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "")
+BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "")
+BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "")
+BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "")
// RDSEED
BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "")
diff --git a/lib/Headers/adxintrin.h b/lib/Headers/adxintrin.h
index 650279e8f7..4065c24a96 100644
--- a/lib/Headers/adxintrin.h
+++ b/lib/Headers/adxintrin.h
@@ -28,6 +28,7 @@
#ifndef __ADXINTRIN_H
#define __ADXINTRIN_H
+/* Intrinsics that are available only if __ADX__ defined */
#ifdef __ADX__
static __inline unsigned char __attribute__((__always_inline__, __nodebug__))
_addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
@@ -46,4 +47,37 @@ _addcarryx_u64(unsigned char __cf, unsigned long __x, unsigned long __y,
#endif
#endif
+/* Intrinsics that are also available if __ADX__ undefined */
+static __inline unsigned char __attribute__((__always_inline__, __nodebug__))
+_addcarry_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
+ unsigned int *__p)
+{
+ return __builtin_ia32_addcarry_u32(__cf, __x, __y, __p);
+}
+
+#ifdef __x86_64__
+static __inline unsigned char __attribute__((__always_inline__, __nodebug__))
+_addcarry_u64(unsigned char __cf, unsigned long __x, unsigned long __y,
+ unsigned long long *__p)
+{
+ return __builtin_ia32_addcarry_u64(__cf, __x, __y, __p);
+}
+#endif
+
+static __inline unsigned char __attribute__((__always_inline__, __nodebug__))
+_subborrow_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
+ unsigned int *__p)
+{
+ return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p);
+}
+
+#ifdef __x86_64__
+static __inline unsigned char __attribute__((__always_inline__, __nodebug__))
+_subborrow_u64(unsigned char __cf, unsigned long __x, unsigned long __y,
+ unsigned long long *__p)
+{
+ return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p);
+}
+#endif
+
#endif /* __ADXINTRIN_H */
diff --git a/test/CodeGen/adc-builtins.c b/test/CodeGen/adc-builtins.c
new file mode 100644
index 0000000000..1ee0a69c26
--- /dev/null
+++ b/test/CodeGen/adc-builtins.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ffreestanding -emit-llvm -o - %s | FileCheck %s
+
+#include <x86intrin.h>
+
+unsigned char test_addcarry_u32(unsigned char __cf, unsigned int __x,
+ unsigned int __y, unsigned int *__p) {
+// CHECK-LABEL: test_addcarry_u32
+// CHECK: call i8 @llvm.x86.addcarry.u32
+ return _addcarry_u32(__cf, __x, __y, __p);
+}
+
+unsigned char test_addcarry_u64(unsigned char __cf, unsigned long __x,
+ unsigned long __y, unsigned long long *__p) {
+// CHECK-LABEL: test_addcarry_u64
+// CHECK: call i8 @llvm.x86.addcarry.u64
+ return _addcarry_u64(__cf, __x, __y, __p);
+}
+
+unsigned char test_subborrow_u32(unsigned char __cf, unsigned int __x,
+ unsigned int __y, unsigned int *__p) {
+// CHECK-LABEL: test_subborrow_u32
+// CHECK: call i8 @llvm.x86.subborrow.u32
+ return _subborrow_u32(__cf, __x, __y, __p);
+}
+
+unsigned char test_subborrow_u64(unsigned char __cf, unsigned long __x,
+ unsigned long __y, unsigned long long *__p) {
+// CHECK-LABEL: test_subborrow_u64
+// CHECK: call i8 @llvm.x86.subborrow.u64
+ return _subborrow_u64(__cf, __x, __y, __p);
+}