]> granicus.if.org Git - clang/commitdiff
arm_acle: Implement swap intrinsic
authorYi Kong <Yi.Kong@arm.com>
Tue, 26 Aug 2014 09:50:54 +0000 (09:50 +0000)
committerYi Kong <Yi.Kong@arm.com>
Tue, 26 Aug 2014 09:50:54 +0000 (09:50 +0000)
Insert the LDREX/STREX instruction sequence specified in ARM ACLE 2.0,
as SWP instruction is deprecated since ARMv6.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216446 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/arm_acle.h
test/CodeGen/arm_acle.c

index 110884b3b872f4fa9b0a160c2b2107525e411d1d..cc7171b6aeb5162171a480dc7312ffd36e2930b6 100644 (file)
@@ -66,6 +66,14 @@ static __inline__ void __attribute__((always_inline, nodebug)) __yield(void) {
 }
 #endif
 
+/* 8.5 Swap */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __swp(uint32_t x, volatile uint32_t *p) {
+  uint32_t v;
+  do v = __builtin_arm_ldrex(p); while (__builtin_arm_strex(x, p));
+  return v;
+}
+
 /* 8.6 Memory prefetch intrinsics */
 /* 8.6.1 Data prefetch */
 #define __pld(addr) __pldx(0, 0, 0, addr)
index 8a23df836e4eb249850a22ff2750079ff249c7cd..01f8de649dd9b669e943daf5ade6ed0f80fbc397 100644 (file)
@@ -62,6 +62,16 @@ void test_sevl(void) {
   __sevl();
 }
 
+/* 8.5 Swap */
+// ARM-LABEL: test_swp
+// AArch32: call i32 @llvm.arm.ldrex
+// AArch32: call i32 @llvm.arm.strex
+// AArch64: call i64 @llvm.aarch64.ldxr
+// AArch64: call i32 @llvm.aarch64.stxr
+uint32_t test_swp(uint32_t x, volatile void *p) {
+  __swp(x, p);
+}
+
 /* 8.6 Memory prefetch intrinsics */
 /* 8.6.1 Data prefetch */
 // ARM-LABEL: test_pld