xref: /minix3/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/sync-ops.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*===-- sync-ops.h - --===//
2*0a6a1f1dSLionel Sambuc  *
3*0a6a1f1dSLionel Sambuc  *                     The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc  *
5*0a6a1f1dSLionel Sambuc  * This file is dual licensed under the MIT and the University of Illinois Open
6*0a6a1f1dSLionel Sambuc  * Source Licenses. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc  *
8*0a6a1f1dSLionel Sambuc  *===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc  *
10*0a6a1f1dSLionel Sambuc  * This file implements outline macros for the __sync_fetch_and_*
11*0a6a1f1dSLionel Sambuc  * operations. Different instantiations will generate appropriate assembly for
12*0a6a1f1dSLionel Sambuc  * ARM and Thumb-2 versions of the functions.
13*0a6a1f1dSLionel Sambuc  *
14*0a6a1f1dSLionel Sambuc  *===----------------------------------------------------------------------===*/
15*0a6a1f1dSLionel Sambuc 
16*0a6a1f1dSLionel Sambuc #include "../assembly.h"
17*0a6a1f1dSLionel Sambuc 
18*0a6a1f1dSLionel Sambuc #define SYNC_OP_4(op) \
19*0a6a1f1dSLionel Sambuc         .p2align 2 ; \
20*0a6a1f1dSLionel Sambuc         .thumb ; \
21*0a6a1f1dSLionel Sambuc         .syntax unified ; \
22*0a6a1f1dSLionel Sambuc         DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_ ## op) \
23*0a6a1f1dSLionel Sambuc         dmb ; \
24*0a6a1f1dSLionel Sambuc         mov r12, r0 ; \
25*0a6a1f1dSLionel Sambuc         LOCAL_LABEL(tryatomic_ ## op): \
26*0a6a1f1dSLionel Sambuc         ldrex r0, [r12] ; \
27*0a6a1f1dSLionel Sambuc         op(r2, r0, r1) ; \
28*0a6a1f1dSLionel Sambuc         strex r3, r2, [r12] ; \
29*0a6a1f1dSLionel Sambuc         cmp r3, #0 ; \
30*0a6a1f1dSLionel Sambuc         bne LOCAL_LABEL(tryatomic_ ## op) ; \
31*0a6a1f1dSLionel Sambuc         dmb ; \
32*0a6a1f1dSLionel Sambuc         bx lr
33*0a6a1f1dSLionel Sambuc 
34*0a6a1f1dSLionel Sambuc #define SYNC_OP_8(op) \
35*0a6a1f1dSLionel Sambuc         .p2align 2 ; \
36*0a6a1f1dSLionel Sambuc         .thumb ; \
37*0a6a1f1dSLionel Sambuc         .syntax unified ; \
38*0a6a1f1dSLionel Sambuc         DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_ ## op) \
39*0a6a1f1dSLionel Sambuc         push {r4, r5, r6, lr} ; \
40*0a6a1f1dSLionel Sambuc         dmb ; \
41*0a6a1f1dSLionel Sambuc         mov r12, r0 ; \
42*0a6a1f1dSLionel Sambuc         LOCAL_LABEL(tryatomic_ ## op): \
43*0a6a1f1dSLionel Sambuc         ldrexd r0, r1, [r12] ; \
44*0a6a1f1dSLionel Sambuc         op(r4, r5, r0, r1, r2, r3) ; \
45*0a6a1f1dSLionel Sambuc         strexd r6, r4, r5, [r12] ; \
46*0a6a1f1dSLionel Sambuc         cmp r6, #0 ; \
47*0a6a1f1dSLionel Sambuc         bne LOCAL_LABEL(tryatomic_ ## op) ; \
48*0a6a1f1dSLionel Sambuc         dmb ; \
49*0a6a1f1dSLionel Sambuc         pop {r4, r5, r6, pc}
50*0a6a1f1dSLionel Sambuc 
51*0a6a1f1dSLionel Sambuc #define MINMAX_4(rD, rN, rM, cmp_kind) \
52*0a6a1f1dSLionel Sambuc         cmp rN, rM ; \
53*0a6a1f1dSLionel Sambuc         mov rD, rM ; \
54*0a6a1f1dSLionel Sambuc         it cmp_kind ; \
55*0a6a1f1dSLionel Sambuc         mov##cmp_kind rD, rN
56*0a6a1f1dSLionel Sambuc 
57*0a6a1f1dSLionel Sambuc #define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind) \
58*0a6a1f1dSLionel Sambuc         cmp rN_LO, rM_LO ; \
59*0a6a1f1dSLionel Sambuc         sbcs rN_HI, rM_HI ; \
60*0a6a1f1dSLionel Sambuc         mov rD_LO, rM_LO ; \
61*0a6a1f1dSLionel Sambuc         mov rD_HI, rM_HI ; \
62*0a6a1f1dSLionel Sambuc         itt cmp_kind ; \
63*0a6a1f1dSLionel Sambuc         mov##cmp_kind rD_LO, rN_LO ; \
64*0a6a1f1dSLionel Sambuc         mov##cmp_kind rD_HI, rN_HI
65