Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 11d04ee

Browse files
committed
ARM: implement __sync_fetch_and_* operations
Since these are primarily useful for deeply embedded targets where code size is very important, they are each in a separate file making use of infrastructure in sync-ops.h. This allows a linker to include just the functions that are actually used. rdar://problem/14736665 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@202812 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5ad91b8 commit 11d04ee

24 files changed

+510
-1
lines changed

lib/builtins/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,26 @@ set(arm_SOURCES
213213
arm/switch32.S
214214
arm/switch8.S
215215
arm/switchu8.S
216+
arm/sync_fetch_and_add_4.S
217+
arm/sync_fetch_and_add_8.S
218+
arm/sync_fetch_and_and_4.S
219+
arm/sync_fetch_and_and_8.S
220+
arm/sync_fetch_and_max_4.S
221+
arm/sync_fetch_and_max_8.S
222+
arm/sync_fetch_and_min_4.S
223+
arm/sync_fetch_and_min_8.S
224+
arm/sync_fetch_and_nand_4.S
225+
arm/sync_fetch_and_nand_8.S
226+
arm/sync_fetch_and_or_4.S
227+
arm/sync_fetch_and_or_8.S
228+
arm/sync_fetch_and_sub_4.S
229+
arm/sync_fetch_and_sub_8.S
230+
arm/sync_fetch_and_umax_4.S
231+
arm/sync_fetch_and_umax_8.S
232+
arm/sync_fetch_and_umin_4.S
233+
arm/sync_fetch_and_umin_8.S
234+
arm/sync_fetch_and_xor_4.S
235+
arm/sync_fetch_and_xor_8.S
216236
arm/sync_synchronize.S
217237
arm/truncdfsf2vfp.S
218238
arm/udivmodsi4.S

lib/builtins/arm/Makefile.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
ModuleName := builtins
1111
SubDirs :=
12-
OnlyArchs := armv5 armv6 armv7 armv7k armv7m armv7em armv7s
12+
OnlyArchs := armv5 armv6 armv6m armv7 armv7k armv7m armv7em armv7s
1313

1414
AsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file)))
1515
Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))

lib/builtins/arm/sync-ops.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*===-- sync-ops.h - --===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* FIXME: description
11+
* This file implements the __udivsi3 (32-bit unsigned integer divide)
12+
* function for the ARM architecture. A naive digit-by-digit computation is
13+
* employed for simplicity.
14+
*
15+
*===----------------------------------------------------------------------===*/
16+
17+
#include "../assembly.h"
18+
19+
#define SYNC_OP_4(op) \
20+
.align 2 ; \
21+
.thumb ; \
22+
DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_ ## op) \
23+
dmb ; \
24+
mov r12, r0 ; \
25+
LOCAL_LABEL(tryatomic_ ## op): \
26+
ldrex r0, [r12] ; \
27+
op(r2, r0, r1) ; \
28+
strex r3, r2, [r12] ; \
29+
cbnz r3, LOCAL_LABEL(tryatomic_ ## op) ; \
30+
dmb ; \
31+
bx lr
32+
33+
#define SYNC_OP_8(op) \
34+
.align 2 ; \
35+
.thumb ; \
36+
DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_ ## op) \
37+
push {r4, r5, r6, lr} ; \
38+
dmb ; \
39+
mov r12, r0 ; \
40+
LOCAL_LABEL(tryatomic_ ## op): \
41+
ldrexd r0, r1, [r12] ; \
42+
op(r4, r5, r0, r1, r2, r3) ; \
43+
strexd r6, r4, r5, [r12] ; \
44+
cbnz r6, LOCAL_LABEL(tryatomic_ ## op) ; \
45+
dmb ; \
46+
pop {r4, r5, r6, pc}
47+
48+
#define MINMAX_4(rD, rN, rM, cmp_kind) \
49+
cmp rN, rM ; \
50+
mov rD, rM ; \
51+
it cmp_kind ; \
52+
mov##cmp_kind rD, rN
53+
54+
#define MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, cmp_kind) \
55+
cmp rN_LO, rM_LO ; \
56+
sbcs rN_HI, rM_HI ; \
57+
mov rD_LO, rM_LO ; \
58+
mov rD_HI, rM_HI ; \
59+
itt cmp_kind ; \
60+
mov##cmp_kind rD_LO, rN_LO ; \
61+
mov##cmp_kind rD_HI, rN_HI
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*===-- sync_fetch_and_add_4.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_add_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
/* "adds" is 2 bytes shorter than "add". */
18+
#define add_4(rD, rN, rM) add rD, rN, rM
19+
20+
SYNC_OP_4(add_4)
21+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*===-- sync_fetch_and_add_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_add_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define add_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \
18+
adds rD_LO, rN_LO, rM_LO ; \
19+
adc rD_HI, rN_HI, rM_HI
20+
21+
SYNC_OP_8(add_8)
22+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*===-- sync_fetch_and_and_4.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_and_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define and_4(rD, rN, rM) and rD, rN, rM
18+
19+
SYNC_OP_4(and_4)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*===-- sync_fetch_and_and_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_and_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define and_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \
18+
and rD_LO, rN_LO, rM_LO ; \
19+
and rD_HI, rN_HI, rM_HI
20+
21+
SYNC_OP_8(and_8)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*===-- sync_fetch_and_max_4.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_max_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define max_4(rD, rN, rM) MINMAX_4(rD, rN, rM, gt)
18+
19+
SYNC_OP_4(max_4)
20+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*===-- sync_fetch_and_max_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_max_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define max_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, gt)
18+
19+
SYNC_OP_8(max_8)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*===-- sync_fetch_and_min_4.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_min_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define min_4(rD, rN, rM) MINMAX_4(rD, rN, rM, lt)
18+
19+
SYNC_OP_4(min_4)
20+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*===-- sync_fetch_and_min_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_min_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define min_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) MINMAX_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI, lt)
18+
19+
SYNC_OP_8(min_8)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*===-- sync_fetch_and_nand_4.S - -----------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_nand_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define nand_4(rD, rN, rM) bic rD, rN, rM
18+
19+
SYNC_OP_4(nand_4)
20+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*===-- sync_fetch_and_nand_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_nand_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define nand_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \
18+
bic rD_LO, rN_LO, rM_LO ; \
19+
bic rD_HI, rN_HI, rM_HI
20+
21+
SYNC_OP_8(nand_8)
22+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*===-- sync_fetch_and_or_4.S - -------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_or_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define or_4(rD, rN, rM) orr rD, rN, rM
18+
19+
SYNC_OP_4(or_4)
20+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*===-- sync_fetch_and_or_8.S - -------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_or_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define or_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \
18+
orr rD_LO, rN_LO, rM_LO ; \
19+
orr rD_HI, rN_HI, rM_HI
20+
21+
SYNC_OP_8(or_8)
22+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*===-- sync_fetch_and_sub_4.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_sub_4 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
/* "subs" is 2 bytes shorter than "sub". */
18+
#define sub_4(rD, rN, rM) sub rD, rN, rM
19+
20+
SYNC_OP_4(sub_4)
21+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*===-- sync_fetch_and_sub_8.S - ------------------------------------------===//
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
*===----------------------------------------------------------------------===//
9+
*
10+
* This file implements the __sync_fetch_and_sub_8 function for the ARM
11+
* architecture.
12+
*
13+
*===----------------------------------------------------------------------===*/
14+
15+
#include "sync-ops.h"
16+
17+
#define sub_8(rD_LO, rD_HI, rN_LO, rN_HI, rM_LO, rM_HI) \
18+
subs rD_LO, rN_LO, rM_LO ; \
19+
sbc rD_HI, rN_HI, rM_HI
20+
21+
SYNC_OP_8(sub_8)
22+

0 commit comments

Comments
 (0)