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