GNU Linux-libre 4.14.328-gnu1
[releases.git] / arch / sparc / lib / locks.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * locks.S: SMP low-level lock primitives on Sparc.
4  *
5  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
6  * Copyright (C) 1998 Anton Blanchard (anton@progsoc.uts.edu.au)
7  * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
8  */
9
10 #include <asm/ptrace.h>
11 #include <asm/psr.h>
12 #include <asm/smp.h>
13 #include <asm/spinlock.h>
14 #include <asm/export.h>
15
16         .text
17         .align  4
18
19         /* Read/writer locks, as usual this is overly clever to make it
20          * as fast as possible.
21          */
22
23         /* caches... */
24 ___rw_read_enter_spin_on_wlock:
25         orcc    %g2, 0x0, %g0
26         be,a    ___rw_read_enter
27          ldstub [%g1 + 3], %g2
28         b       ___rw_read_enter_spin_on_wlock
29          ldub   [%g1 + 3], %g2
30 ___rw_read_try_spin_on_wlock:
31         andcc   %g2, 0xff, %g0
32         be,a    ___rw_read_try
33          ldstub [%g1 + 3], %g2
34         xnorcc  %g2, 0x0, %o0   /* if g2 is ~0, set o0 to 0 and bugger off */
35         bne,a   ___rw_read_enter_spin_on_wlock
36          ld     [%g1], %g2
37         retl
38          mov    %g4, %o7
39 ___rw_read_exit_spin_on_wlock:
40         orcc    %g2, 0x0, %g0
41         be,a    ___rw_read_exit
42          ldstub [%g1 + 3], %g2
43         b       ___rw_read_exit_spin_on_wlock
44          ldub   [%g1 + 3], %g2
45 ___rw_write_enter_spin_on_wlock:
46         orcc    %g2, 0x0, %g0
47         be,a    ___rw_write_enter
48          ldstub [%g1 + 3], %g2
49         b       ___rw_write_enter_spin_on_wlock
50          ld     [%g1], %g2
51
52         .globl  ___rw_read_enter
53 EXPORT_SYMBOL(___rw_read_enter)
54 ___rw_read_enter:
55         orcc    %g2, 0x0, %g0
56         bne,a   ___rw_read_enter_spin_on_wlock
57          ldub   [%g1 + 3], %g2
58         ld      [%g1], %g2
59         add     %g2, 1, %g2
60         st      %g2, [%g1]
61         retl
62          mov    %g4, %o7
63
64         .globl  ___rw_read_exit
65 EXPORT_SYMBOL(___rw_read_exit)
66 ___rw_read_exit:
67         orcc    %g2, 0x0, %g0
68         bne,a   ___rw_read_exit_spin_on_wlock
69          ldub   [%g1 + 3], %g2
70         ld      [%g1], %g2
71         sub     %g2, 0x1ff, %g2
72         st      %g2, [%g1]
73         retl
74          mov    %g4, %o7
75
76         .globl  ___rw_read_try
77 EXPORT_SYMBOL(___rw_read_try)
78 ___rw_read_try:
79         orcc    %g2, 0x0, %g0
80         bne     ___rw_read_try_spin_on_wlock
81          ld     [%g1], %g2
82         add     %g2, 1, %g2
83         st      %g2, [%g1]
84         set     1, %o1
85         retl
86          mov    %g4, %o7
87
88         .globl  ___rw_write_enter
89 EXPORT_SYMBOL(___rw_write_enter)
90 ___rw_write_enter:
91         orcc    %g2, 0x0, %g0
92         bne     ___rw_write_enter_spin_on_wlock
93          ld     [%g1], %g2
94         andncc  %g2, 0xff, %g0
95         bne,a   ___rw_write_enter_spin_on_wlock
96          stb    %g0, [%g1 + 3]
97         retl
98          mov    %g4, %o7