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