1353358Sdim//===-- sync-ops.h - --===//
2353358Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353358Sdim//
7353358Sdim//===----------------------------------------------------------------------===//
8353358Sdim//
9353358Sdim// This file implements outline macros for the __sync_fetch_and_*
10353358Sdim// operations. Different instantiations will generate appropriate assembly for
11353358Sdim// ARM and Thumb-2 versions of the functions.
12353358Sdim//
13353358Sdim//===----------------------------------------------------------------------===//
14276789Sdim
15276789Sdim#include "../assembly.h"
16276789Sdim
17353358Sdim#define SYNC_OP_4(op)                                                          \
18353358Sdim  .p2align 2;                                                                  \
19353358Sdim  .thumb;                                                                      \
20353358Sdim  .syntax unified;                                                             \
21353358Sdim  DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_##op)                      \
22353358Sdim  dmb;                                                                         \
23353358Sdim  mov r12, r0;                                                                 \
24353358Sdim  LOCAL_LABEL(tryatomic_##op) : ldrex r0, [r12];                               \
25353358Sdim  op(r2, r0, r1);                                                              \
26353358Sdim  strex r3, r2, [r12];                                                         \
27353358Sdim  cmp r3, #0;                                                                  \
28353358Sdim  bne LOCAL_LABEL(tryatomic_##op);                                             \
29353358Sdim  dmb;                                                                         \
30353358Sdim  bx lr
31276789Sdim
32353358Sdim#define SYNC_OP_8(op)                                                          \
33353358Sdim  .p2align 2;                                                                  \
34353358Sdim  .thumb;                                                                      \
35353358Sdim  .syntax unified;                                                             \
36353358Sdim  DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_##op)                      \
37353358Sdim  push {r4, r5, r6, lr};                                                       \
38353358Sdim  dmb;                                                                         \
39353358Sdim  mov r12, r0;                                                                 \
40353358Sdim  LOCAL_LABEL(tryatomic_##op) : ldrexd r0, r1, [r12];                          \
41353358Sdim  op(r4, r5, r0, r1, r2, r3);                                                  \
42353358Sdim  strexd r6, r4, r5, [r12];                                                    \
43353358Sdim  cmp r6, #0;                                                                  \
44353358Sdim  bne LOCAL_LABEL(tryatomic_##op);                                             \
45353358Sdim  dmb;                                                                         \
46353358Sdim  pop { r4, r5, r6, pc }
47276789Sdim
48353358Sdim#define MINMAX_4(rD, rN, rM, cmp_kind)                                         \
49353358Sdim  cmp rN, rM;                                                                  \
50353358Sdim  mov rD, rM;                                                                  \
51353358Sdim  it cmp_kind;                                                                 \
52353358Sdim  mov##cmp_kind rD, rN
53276789Sdim
54353358Sdim#define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind)           \
55353358Sdim  cmp rN_LO, rM_LO;                                                            \
56353358Sdim  sbcs rN_HI, rM_HI;                                                           \
57353358Sdim  mov rD_LO, rM_LO;                                                            \
58353358Sdim  mov rD_HI, rM_HI;                                                            \
59353358Sdim  itt cmp_kind;                                                                \
60353358Sdim  mov##cmp_kind rD_LO, rN_LO;                                                  \
61353358Sdim  mov##cmp_kind rD_HI, rN_HI
62