From ae401c85d2e76237a2cefafb1fb9c6035e5d50b7 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Tue, 26 Aug 2014 09:50:54 +0000 Subject: [PATCH] arm_acle: Implement swap intrinsic 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 | 8 ++++++++ test/CodeGen/arm_acle.c | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/Headers/arm_acle.h b/lib/Headers/arm_acle.h index 110884b3b8..cc7171b6ae 100644 --- a/lib/Headers/arm_acle.h +++ b/lib/Headers/arm_acle.h @@ -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) diff --git a/test/CodeGen/arm_acle.c b/test/CodeGen/arm_acle.c index 8a23df836e..01f8de649d 100644 --- a/test/CodeGen/arm_acle.c +++ b/test/CodeGen/arm_acle.c @@ -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 -- 2.50.1