arm64: bitops: patch in lse instructions when supported by the CPU
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / lib / bitops.S
1 /*
2  * Based on arch/arm/lib/bitops.h
3  *
4  * Copyright (C) 2013 ARM Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/linkage.h>
20 #include <asm/assembler.h>
21 #include <asm/lse.h>
22
23 /*
24  * x0: bits 5:0  bit offset
25  *     bits 31:6 word offset
26  * x1: address
27  */
28         .macro  bitop, name, llsc, lse
29 ENTRY(  \name   )
30         and     w3, w0, #63             // Get bit offset
31         eor     w0, w0, w3              // Clear low bits
32         mov     x2, #1
33         add     x1, x1, x0, lsr #3      // Get word offset
34         lsl     x3, x2, x3              // Create mask
35
36 alt_lse "1:     ldxr    x2, [x1]",              "\lse   x3, [x1]"
37 alt_lse "       \llsc   x2, x2, x3",            "nop"
38 alt_lse "       stxr    w0, x2, [x1]",          "nop"
39 alt_lse "       cbnz    w0, 1b",                "nop"
40
41         ret
42 ENDPROC(\name   )
43         .endm
44
45         .macro  testop, name, llsc, lse
46 ENTRY(  \name   )
47         and     w3, w0, #63             // Get bit offset
48         eor     w0, w0, w3              // Clear low bits
49         mov     x2, #1
50         add     x1, x1, x0, lsr #3      // Get word offset
51         lsl     x4, x2, x3              // Create mask
52
53 alt_lse "1:     ldxr    x2, [x1]",              "\lse   x4, x2, [x1]"
54         lsr     x0, x2, x3
55 alt_lse "       \llsc   x2, x2, x4",            "nop"
56 alt_lse "       stlxr   w5, x2, [x1]",          "nop"
57 alt_lse "       cbnz    w5, 1b",                "nop"
58 alt_lse "       dmb     ish",                   "nop"
59
60         and     x0, x0, #1
61         ret
62 ENDPROC(\name   )
63         .endm
64
65 /*
66  * Atomic bit operations.
67  */
68         bitop   change_bit, eor, steor
69         bitop   clear_bit, bic, stclr
70         bitop   set_bit, orr, stset
71
72         testop  test_and_change_bit, eor, ldeoral
73         testop  test_and_clear_bit, bic, ldclral
74         testop  test_and_set_bit, orr, ldsetal