xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/sync-ops.h (revision ef84fd3bd8895f4e6be1e38baf19e6dc3255bc64)
161f2f256Sjoerg /*===-- sync-ops.h - --===//
261f2f256Sjoerg  *
361f2f256Sjoerg  *                     The LLVM Compiler Infrastructure
461f2f256Sjoerg  *
561f2f256Sjoerg  * This file is dual licensed under the MIT and the University of Illinois Open
661f2f256Sjoerg  * Source Licenses. See LICENSE.TXT for details.
761f2f256Sjoerg  *
861f2f256Sjoerg  *===----------------------------------------------------------------------===//
961f2f256Sjoerg  *
1061f2f256Sjoerg  * This file implements outline macros for the __sync_fetch_and_*
1161f2f256Sjoerg  * operations. Different instantiations will generate appropriate assembly for
1261f2f256Sjoerg  * ARM and Thumb-2 versions of the functions.
1361f2f256Sjoerg  *
1461f2f256Sjoerg  *===----------------------------------------------------------------------===*/
1561f2f256Sjoerg 
1661f2f256Sjoerg #include "../assembly.h"
1761f2f256Sjoerg 
1861f2f256Sjoerg #define SYNC_OP_4(op) \
1961f2f256Sjoerg         .p2align 2 ; \
2061f2f256Sjoerg         .thumb ; \
21190e92d8Sjoerg         .syntax unified ; \
22*ef84fd3bSjoerg         DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_ ## op) \
2361f2f256Sjoerg         dmb ; \
2461f2f256Sjoerg         mov r12, r0 ; \
2561f2f256Sjoerg         LOCAL_LABEL(tryatomic_ ## op): \
2661f2f256Sjoerg         ldrex r0, [r12] ; \
2761f2f256Sjoerg         op(r2, r0, r1) ; \
2861f2f256Sjoerg         strex r3, r2, [r12] ; \
29190e92d8Sjoerg         cmp r3, #0 ; \
30190e92d8Sjoerg         bne LOCAL_LABEL(tryatomic_ ## op) ; \
3161f2f256Sjoerg         dmb ; \
3261f2f256Sjoerg         bx lr
3361f2f256Sjoerg 
3461f2f256Sjoerg #define SYNC_OP_8(op) \
3561f2f256Sjoerg         .p2align 2 ; \
3661f2f256Sjoerg         .thumb ; \
37190e92d8Sjoerg         .syntax unified ; \
38*ef84fd3bSjoerg         DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_ ## op) \
3961f2f256Sjoerg         push {r4, r5, r6, lr} ; \
4061f2f256Sjoerg         dmb ; \
4161f2f256Sjoerg         mov r12, r0 ; \
4261f2f256Sjoerg         LOCAL_LABEL(tryatomic_ ## op): \
4361f2f256Sjoerg         ldrexd r0, r1, [r12] ; \
4461f2f256Sjoerg         op(r4, r5, r0, r1, r2, r3) ; \
4561f2f256Sjoerg         strexd r6, r4, r5, [r12] ; \
46190e92d8Sjoerg         cmp r6, #0 ; \
47190e92d8Sjoerg         bne LOCAL_LABEL(tryatomic_ ## op) ; \
4861f2f256Sjoerg         dmb ; \
4961f2f256Sjoerg         pop {r4, r5, r6, pc}
5061f2f256Sjoerg 
5161f2f256Sjoerg #define MINMAX_4(rD, rN, rM, cmp_kind) \
5261f2f256Sjoerg         cmp rN, rM ; \
5361f2f256Sjoerg         mov rD, rM ; \
5461f2f256Sjoerg         it cmp_kind ; \
5561f2f256Sjoerg         mov##cmp_kind rD, rN
5661f2f256Sjoerg 
5761f2f256Sjoerg #define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind) \
5861f2f256Sjoerg         cmp rN_LO, rM_LO ; \
5961f2f256Sjoerg         sbcs rN_HI, rM_HI ; \
6061f2f256Sjoerg         mov rD_LO, rM_LO ; \
6161f2f256Sjoerg         mov rD_HI, rM_HI ; \
6261f2f256Sjoerg         itt cmp_kind ; \
6361f2f256Sjoerg         mov##cmp_kind rD_LO, rN_LO ; \
6461f2f256Sjoerg         mov##cmp_kind rD_HI, rN_HI
65