~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/corelib/arch/qatomic_alpha.h

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtCore module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#ifndef QATOMIC_ALPHA_H
 
43
#define QATOMIC_ALPHA_H
 
44
 
 
45
#include <QtCore/qoldbasicatomic.h>
 
46
 
 
47
QT_BEGIN_HEADER
 
48
 
 
49
QT_BEGIN_NAMESPACE
 
50
 
 
51
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
 
52
 
 
53
inline bool QBasicAtomicInt::isReferenceCountingNative()
 
54
{ return true; }
 
55
inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
 
56
{ return false; }
 
57
 
 
58
#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
 
59
 
 
60
inline bool QBasicAtomicInt::isTestAndSetNative()
 
61
{ return true; }
 
62
inline bool QBasicAtomicInt::isTestAndSetWaitFree()
 
63
{ return false; }
 
64
 
 
65
#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
 
66
 
 
67
inline bool QBasicAtomicInt::isFetchAndStoreNative()
 
68
{ return true; }
 
69
inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
 
70
{ return false; }
 
71
 
 
72
#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
 
73
 
 
74
inline bool QBasicAtomicInt::isFetchAndAddNative()
 
75
{ return true; }
 
76
inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
 
77
{ return false; }
 
78
 
 
79
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
 
80
 
 
81
template <typename T>
 
82
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
 
83
{ return true; }
 
84
template <typename T>
 
85
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
 
86
{ return false; }
 
87
 
 
88
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
 
89
 
 
90
template <typename T>
 
91
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
 
92
{ return true; }
 
93
template <typename T>
 
94
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
 
95
{ return false; }
 
96
 
 
97
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
 
98
 
 
99
template <typename T>
 
100
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
 
101
{ return true; }
 
102
template <typename T>
 
103
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
 
104
{ return false; }
 
105
 
 
106
#if defined(Q_CC_GNU)
 
107
 
 
108
inline bool QBasicAtomicInt::ref()
 
109
{
 
110
    register int old, tmp;
 
111
    asm volatile("1:\n"
 
112
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
113
                 "addl  %0,1,%1\n" /* tmp=old+1;                              */
 
114
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
115
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
116
                 "br    3f\n"      /* goto 3;                                 */
 
117
                 "2: br 1b\n"      /* goto 1;                                 */
 
118
                 "3:\n"
 
119
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
120
                 :
 
121
                 : "memory");
 
122
    return old != -1;
 
123
}
 
124
 
 
125
inline bool QBasicAtomicInt::deref()
 
126
{
 
127
    register int old, tmp;
 
128
    asm volatile("1:\n"
 
129
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
130
                 "subl  %0,1,%1\n" /* tmp=old-1;                              */
 
131
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
132
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
133
                 "br    3f\n"      /* goto 3;                                 */
 
134
                 "2: br 1b\n"      /* goto 1;                                 */
 
135
                 "3:\n"
 
136
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
137
                 :
 
138
                 : "memory");
 
139
    return old != 1;
 
140
}
 
141
 
 
142
inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
 
143
{
 
144
    register int ret;
 
145
    asm volatile("1:\n"
 
146
                 "ldl_l %0,%1\n"   /* ret=*ptr;                               */
 
147
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
 
148
                 "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
 
149
                 "mov   %3,%0\n"   /* ret=newval;                             */
 
150
                 "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
 
151
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
152
                 "br    3f\n"      /* goto 3;                                 */
 
153
                 "2: br 1b\n"      /* goto 1;                                 */
 
154
                 "3:\n"
 
155
                 : "=&r" (ret), "+m" (_q_value)
 
156
                 : "r" (expectedValue), "r" (newValue)
 
157
                 : "memory");
 
158
    return ret != 0;
 
159
}
 
160
 
 
161
inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
 
162
{
 
163
    register int ret;
 
164
    asm volatile("1:\n"
 
165
                 "ldl_l %0,%1\n"   /* ret=*ptr;                               */
 
166
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
 
167
                 "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
 
168
                 "mov   %3,%0\n"   /* ret=newval;                             */
 
169
                 "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
 
170
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
171
                 "br    3f\n"      /* goto 3;                                 */
 
172
                 "2: br 1b\n"      /* goto 1;                                 */
 
173
                 "3:\n"
 
174
                 "mb\n"
 
175
                 : "=&r" (ret), "+m" (_q_value)
 
176
                 : "r" (expectedValue), "r" (newValue)
 
177
                 : "memory");
 
178
    return ret != 0;
 
179
}
 
180
 
 
181
inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
 
182
{
 
183
    register int ret;
 
184
    asm volatile("mb\n"
 
185
                 "1:\n"
 
186
                 "ldl_l %0,%1\n"   /* ret=*ptr;                               */
 
187
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
 
188
                 "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
 
189
                 "mov   %3,%0\n"   /* ret=newval;                             */
 
190
                 "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
 
191
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
192
                 "br    3f\n"      /* goto 3;                                 */
 
193
                 "2: br 1b\n"      /* goto 1;                                 */
 
194
                 "3:\n"
 
195
                 : "=&r" (ret), "+m" (_q_value)
 
196
                 : "r" (expectedValue), "r" (newValue)
 
197
                 : "memory");
 
198
    return ret != 0;
 
199
}
 
200
 
 
201
inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
 
202
{
 
203
    register int old, tmp;
 
204
    asm volatile("1:\n"
 
205
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
206
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
207
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
208
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
209
                 "br    3f\n"      /* goto 3;                                 */
 
210
                 "2: br 1b\n"      /* goto 1;                                 */
 
211
                 "3:\n"
 
212
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
213
                 : "r" (newValue)
 
214
                 : "memory");
 
215
    return old;
 
216
}
 
217
 
 
218
inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
 
219
{
 
220
    register int old, tmp;
 
221
    asm volatile("1:\n"
 
222
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
223
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
224
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
225
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
226
                 "br    3f\n"      /* goto 3;                                 */
 
227
                 "2: br 1b\n"      /* goto 1;                                 */
 
228
                 "3:\n"
 
229
                 "mb\n"
 
230
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
231
                 : "r" (newValue)
 
232
                 : "memory");
 
233
    return old;
 
234
}
 
235
 
 
236
inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
 
237
{
 
238
    register int old, tmp;
 
239
    asm volatile("mb\n"
 
240
                 "1:\n"
 
241
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
242
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
243
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
244
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
245
                 "br    3f\n"      /* goto 3;                                 */
 
246
                 "2: br 1b\n"      /* goto 1;                                 */
 
247
                 "3:\n"
 
248
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
249
                 : "r" (newValue)
 
250
                 : "memory");
 
251
    return old;
 
252
}
 
253
 
 
254
inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
 
255
{
 
256
    register int old, tmp;
 
257
    asm volatile("1:\n"
 
258
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
259
                 "addl  %0,%3,%1\n"/* tmp=old+value;                          */
 
260
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
261
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
262
                 "br    3f\n"      /* goto 3;                                 */
 
263
                 "2: br 1b\n"      /* goto 1;                                 */
 
264
                 "3:\n"
 
265
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
266
                 : "r" (valueToAdd)
 
267
                 : "memory");
 
268
    return old;
 
269
}
 
270
 
 
271
inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
 
272
{
 
273
    register int old, tmp;
 
274
    asm volatile("1:\n"
 
275
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
276
                 "addl  %0,%3,%1\n"/* tmp=old+value;                          */
 
277
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
278
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
279
                 "br    3f\n"      /* goto 3;                                 */
 
280
                 "2: br 1b\n"      /* goto 1;                                 */
 
281
                 "3:\n"
 
282
                 "mb\n"
 
283
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
284
                 : "r" (valueToAdd)
 
285
                 : "memory");
 
286
    return old;
 
287
}
 
288
 
 
289
inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
 
290
{
 
291
    register int old, tmp;
 
292
    asm volatile("mb\n"
 
293
                 "1:\n"
 
294
                 "ldl_l %0,%2\n"   /* old=*ptr;                               */
 
295
                 "addl  %0,%3,%1\n"/* tmp=old+value;                          */
 
296
                 "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
297
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
298
                 "br    3f\n"      /* goto 3;                                 */
 
299
                 "2: br 1b\n"      /* goto 1;                                 */
 
300
                 "3:\n"
 
301
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
302
                 : "r" (valueToAdd)
 
303
                 : "memory");
 
304
    return old;
 
305
}
 
306
 
 
307
template <typename T>
 
308
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
 
309
{
 
310
    register void *ret;
 
311
    asm volatile("1:\n"
 
312
                 "ldq_l %0,%1\n"   /* ret=*ptr;                               */
 
313
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
 
314
                 "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
 
315
                 "mov   %3,%0\n"   /* tmp=newval;                             */
 
316
                 "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
317
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
318
                 "br    3f\n"      /* goto 3;                                 */
 
319
                 "2: br 1b\n"      /* goto 1;                                 */
 
320
                 "3:\n"
 
321
                 : "=&r" (ret), "+m" (_q_value)
 
322
                 : "r" (expectedValue), "r" (newValue)
 
323
                 : "memory");
 
324
    return ret != 0;
 
325
}
 
326
 
 
327
template <typename T>
 
328
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
 
329
{
 
330
    register void *ret;
 
331
    asm volatile("1:\n"
 
332
                 "ldq_l %0,%1\n"   /* ret=*ptr;                               */
 
333
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
 
334
                 "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
 
335
                 "mov   %3,%0\n"   /* tmp=newval;                             */
 
336
                 "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
337
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
338
                 "br    3f\n"      /* goto 3;                                 */
 
339
                 "2: br 1b\n"      /* goto 1;                                 */
 
340
                 "3:\n"
 
341
                 "mb\n"
 
342
                 : "=&r" (ret), "+m" (_q_value)
 
343
                 : "r" (expectedValue), "r" (newValue)
 
344
                 : "memory");
 
345
    return ret != 0;
 
346
}
 
347
 
 
348
template <typename T>
 
349
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
 
350
{
 
351
    register void *ret;
 
352
    asm volatile("mb\n"
 
353
                 "1:\n"
 
354
                 "ldq_l %0,%1\n"   /* ret=*ptr;                               */
 
355
                 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
 
356
                 "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
 
357
                 "mov   %3,%0\n"   /* tmp=newval;                             */
 
358
                 "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
359
                 "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
 
360
                 "br    3f\n"      /* goto 3;                                 */
 
361
                 "2: br 1b\n"      /* goto 1;                                 */
 
362
                 "3:\n"
 
363
                 : "=&r" (ret), "+m" (_q_value)
 
364
                 : "r" (expectedValue), "r" (newValue)
 
365
                 : "memory");
 
366
    return ret != 0;
 
367
}
 
368
 
 
369
template <typename T>
 
370
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
 
371
{
 
372
    register T *old, *tmp;
 
373
    asm volatile("1:\n"
 
374
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
375
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
376
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
377
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
378
                 "br    3f\n"      /* goto 3;                                 */
 
379
                 "2: br 1b\n"      /* goto 1;                                 */
 
380
                 "3:\n"
 
381
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
382
                 : "r" (newValue)
 
383
                 : "memory");
 
384
    return old;
 
385
}
 
386
 
 
387
template <typename T>
 
388
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
 
389
{
 
390
    register T *old, *tmp;
 
391
    asm volatile("1:\n"
 
392
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
393
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
394
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
395
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
396
                 "br    3f\n"      /* goto 3;                                 */
 
397
                 "2: br 1b\n"      /* goto 1;                                 */
 
398
                 "3:\n"
 
399
                 "mb\n"
 
400
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
401
                 : "r" (newValue)
 
402
                 : "memory");
 
403
    return old;
 
404
}
 
405
 
 
406
template <typename T>
 
407
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
 
408
{
 
409
    register T *old, *tmp;
 
410
    asm volatile("mb\n"
 
411
                 "1:\n"
 
412
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
413
                 "mov   %3,%1\n"   /* tmp=newval;                             */
 
414
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
415
                 "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
 
416
                 "br    3f\n"      /* goto 3;                                 */
 
417
                 "2: br 1b\n"      /* goto 1;                                 */
 
418
                 "3:\n"
 
419
                 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
 
420
                 : "r" (newValue)
 
421
                 : "memory");
 
422
    return old;
 
423
}
 
424
 
 
425
template <typename T>
 
426
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
 
427
{
 
428
    register T *old, *tmp;
 
429
    asm volatile("1:\n"
 
430
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
431
                 "addq  %0,%3,%1\n"/* tmp=old+value;                          */
 
432
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
433
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
434
                 "br    3f\n"      /* goto 3;                                 */
 
435
                 "2: br 1b\n"      /* goto 1;                                 */
 
436
                 "3:\n"
 
437
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
438
                 : "r" (valueToAdd)
 
439
                 : "memory");
 
440
    return reinterpret_cast<T *>(old);
 
441
}
 
442
 
 
443
template <typename T>
 
444
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
 
445
{
 
446
    register T *old, *tmp;
 
447
    asm volatile("1:\n"
 
448
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
449
                 "addq  %0,%3,%1\n"/* tmp=old+value;                          */
 
450
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
451
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
452
                 "br    3f\n"      /* goto 3;                                 */
 
453
                 "2: br 1b\n"      /* goto 1;                                 */
 
454
                 "3:\n"
 
455
                 "mb\n"
 
456
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
457
                 : "r" (valueToAdd)
 
458
                 : "memory");
 
459
    return reinterpret_cast<T *>(old);
 
460
}
 
461
 
 
462
template <typename T>
 
463
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
 
464
{
 
465
    register T *old, *tmp;
 
466
    asm volatile("mb\n"
 
467
                 "1:\n"
 
468
                 "ldq_l %0,%2\n"   /* old=*ptr;                               */
 
469
                 "addq  %0,%3,%1\n"/* tmp=old+value;                          */
 
470
                 "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
 
471
                 "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
 
472
                 "br    3f\n"      /* goto 3;                                 */
 
473
                 "2: br 1b\n"      /* goto 1;                                 */
 
474
                 "3:\n"
 
475
                 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
 
476
                 : "r" (valueToAdd)
 
477
                 : "memory");
 
478
    return reinterpret_cast<T *>(old);
 
479
}
 
480
 
 
481
#else
 
482
# error "This compiler for Alpha is not supported"
 
483
#endif // Q_CC_GNU
 
484
 
 
485
inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
 
486
{
 
487
    return testAndSetAcquire(expectedValue, newValue);
 
488
}
 
489
 
 
490
inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
 
491
{
 
492
    return fetchAndStoreAcquire(newValue);
 
493
}
 
494
 
 
495
inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
 
496
{
 
497
    return fetchAndAddAcquire(valueToAdd);
 
498
}
 
499
 
 
500
template <typename T>
 
501
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
 
502
{
 
503
    return testAndSetAcquire(expectedValue, newValue);
 
504
}
 
505
 
 
506
template <typename T>
 
507
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
 
508
{
 
509
    return fetchAndStoreAcquire(newValue);
 
510
}
 
511
 
 
512
template <typename T>
 
513
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
 
514
{
 
515
    return fetchAndAddAcquire(valueToAdd);
 
516
}
 
517
 
 
518
QT_END_NAMESPACE
 
519
 
 
520
QT_END_HEADER
 
521
 
 
522
#endif // QATOMIC_ALPHA_H