frv: fix the broken preempt
[linux-3.10.git] / arch / frv / lib / atomic64-ops.S
1 /* kernel atomic64 operations
2  *
3  * For an explanation of how atomic ops work in this arch, see:
4  *   Documentation/frv/atomic-ops.txt
5  *
6  * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
7  * Written by David Howells (dhowells@redhat.com)
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version
12  * 2 of the License, or (at your option) any later version.
13  */
14
15 #include <asm/spr-regs.h>
16
17         .text
18         .balign 4
19
20
21 ###############################################################################
22 #
23 # long long atomic64_inc_return(atomic64_t *v)
24 #
25 ###############################################################################
26         .globl          atomic64_inc_return
27         .type           atomic64_inc_return,@function
28 atomic64_inc_return:
29         or.p            gr8,gr8,gr10
30 0:
31         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
32         ckeq            icc3,cc7
33         ldd.p           @(gr10,gr0),gr8                 /* LDD.P/ORCR must be atomic */
34         orcr            cc7,cc7,cc3                     /* set CC3 to true */
35         addicc          gr9,#1,gr9,icc0
36         addxi           gr8,#0,gr8,icc0
37         cstd.p          gr8,@(gr10,gr0)         ,cc3,#1
38         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
39         beq             icc3,#0,0b
40         bralr
41
42         .size           atomic64_inc_return, .-atomic64_inc_return
43
44 ###############################################################################
45 #
46 # long long atomic64_dec_return(atomic64_t *v)
47 #
48 ###############################################################################
49         .globl          atomic64_dec_return
50         .type           atomic64_dec_return,@function
51 atomic64_dec_return:
52         or.p            gr8,gr8,gr10
53 0:
54         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
55         ckeq            icc3,cc7
56         ldd.p           @(gr10,gr0),gr8                 /* LDD.P/ORCR must be atomic */
57         orcr            cc7,cc7,cc3                     /* set CC3 to true */
58         subicc          gr9,#1,gr9,icc0
59         subxi           gr8,#0,gr8,icc0
60         cstd.p          gr8,@(gr10,gr0)         ,cc3,#1
61         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
62         beq             icc3,#0,0b
63         bralr
64
65         .size           atomic64_dec_return, .-atomic64_dec_return
66
67 ###############################################################################
68 #
69 # long long atomic64_add_return(long long i, atomic64_t *v)
70 #
71 ###############################################################################
72         .globl          atomic64_add_return
73         .type           atomic64_add_return,@function
74 atomic64_add_return:
75         or.p            gr8,gr8,gr4
76         or              gr9,gr9,gr5
77 0:
78         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
79         ckeq            icc3,cc7
80         ldd.p           @(gr10,gr0),gr8                 /* LDD.P/ORCR must be atomic */
81         orcr            cc7,cc7,cc3                     /* set CC3 to true */
82         addcc           gr9,gr5,gr9,icc0
83         addx            gr8,gr4,gr8,icc0
84         cstd.p          gr8,@(gr10,gr0)         ,cc3,#1
85         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
86         beq             icc3,#0,0b
87         bralr
88
89         .size           atomic64_add_return, .-atomic64_add_return
90
91 ###############################################################################
92 #
93 # long long atomic64_sub_return(long long i, atomic64_t *v)
94 #
95 ###############################################################################
96         .globl          atomic64_sub_return
97         .type           atomic64_sub_return,@function
98 atomic64_sub_return:
99         or.p            gr8,gr8,gr4
100         or              gr9,gr9,gr5
101 0:
102         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
103         ckeq            icc3,cc7
104         ldd.p           @(gr10,gr0),gr8                 /* LDD.P/ORCR must be atomic */
105         orcr            cc7,cc7,cc3                     /* set CC3 to true */
106         subcc           gr9,gr5,gr9,icc0
107         subx            gr8,gr4,gr8,icc0
108         cstd.p          gr8,@(gr10,gr0)         ,cc3,#1
109         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
110         beq             icc3,#0,0b
111         bralr
112
113         .size           atomic64_sub_return, .-atomic64_sub_return
114
115 ###############################################################################
116 #
117 # uint64_t __xchg_64(uint64_t i, uint64_t *v)
118 #
119 ###############################################################################
120         .globl          __xchg_64
121         .type           __xchg_64,@function
122 __xchg_64:
123         or.p            gr8,gr8,gr4
124         or              gr9,gr9,gr5
125 0:
126         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
127         ckeq            icc3,cc7
128         ldd.p           @(gr10,gr0),gr8                 /* LDD.P/ORCR must be atomic */
129         orcr            cc7,cc7,cc3                     /* set CC3 to true */
130         cstd.p          gr4,@(gr10,gr0)         ,cc3,#1
131         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
132         beq             icc3,#0,0b
133         bralr
134
135         .size           __xchg_64, .-__xchg_64
136
137 ###############################################################################
138 #
139 # uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v)
140 #
141 ###############################################################################
142         .globl          __cmpxchg_64
143         .type           __cmpxchg_64,@function
144 __cmpxchg_64:
145         or.p            gr8,gr8,gr4
146         or              gr9,gr9,gr5
147 0:
148         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
149         ckeq            icc3,cc7
150         ldd.p           @(gr12,gr0),gr8                 /* LDD.P/ORCR must be atomic */
151         orcr            cc7,cc7,cc3
152         subcc           gr8,gr4,gr0,icc0
153         subcc.p         gr9,gr5,gr0,icc1
154         bnelr           icc0,#0
155         bnelr           icc1,#0
156         cstd.p          gr10,@(gr12,gr0)        ,cc3,#1
157         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
158         beq             icc3,#0,0b
159         bralr
160
161         .size           __cmpxchg_64, .-__cmpxchg_64
162