1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtCore module of the Qt Toolkit.
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.
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.
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.
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.
40
****************************************************************************/
42
#ifndef QATOMIC_ALPHA_H
43
#define QATOMIC_ALPHA_H
45
#include <QtCore/qoldbasicatomic.h>
51
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
53
inline bool QBasicAtomicInt::isReferenceCountingNative()
55
inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
58
#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
60
inline bool QBasicAtomicInt::isTestAndSetNative()
62
inline bool QBasicAtomicInt::isTestAndSetWaitFree()
65
#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
67
inline bool QBasicAtomicInt::isFetchAndStoreNative()
69
inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
72
#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
74
inline bool QBasicAtomicInt::isFetchAndAddNative()
76
inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
79
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
82
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
85
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
88
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
91
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
94
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
97
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
100
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
102
template <typename T>
103
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
106
#if defined(Q_CC_GNU)
108
inline bool QBasicAtomicInt::ref()
110
register int old, tmp;
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; */
119
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
125
inline bool QBasicAtomicInt::deref()
127
register int old, tmp;
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; */
136
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
142
inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
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; */
155
: "=&r" (ret), "+m" (_q_value)
156
: "r" (expectedValue), "r" (newValue)
161
inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
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; */
175
: "=&r" (ret), "+m" (_q_value)
176
: "r" (expectedValue), "r" (newValue)
181
inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
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; */
195
: "=&r" (ret), "+m" (_q_value)
196
: "r" (expectedValue), "r" (newValue)
201
inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
203
register int old, tmp;
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; */
212
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
218
inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
220
register int old, tmp;
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; */
230
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
236
inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
238
register int old, tmp;
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; */
248
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
254
inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
256
register int old, tmp;
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; */
265
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
271
inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
273
register int old, tmp;
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; */
283
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
289
inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
291
register int old, tmp;
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; */
301
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
307
template <typename T>
308
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
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; */
321
: "=&r" (ret), "+m" (_q_value)
322
: "r" (expectedValue), "r" (newValue)
327
template <typename T>
328
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
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; */
342
: "=&r" (ret), "+m" (_q_value)
343
: "r" (expectedValue), "r" (newValue)
348
template <typename T>
349
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
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; */
363
: "=&r" (ret), "+m" (_q_value)
364
: "r" (expectedValue), "r" (newValue)
369
template <typename T>
370
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
372
register T *old, *tmp;
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; */
381
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
387
template <typename T>
388
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
390
register T *old, *tmp;
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; */
400
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
406
template <typename T>
407
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
409
register T *old, *tmp;
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; */
419
: "=&r" (old), "=&r" (tmp), "+m" (_q_value)
425
template <typename T>
426
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
428
register T *old, *tmp;
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; */
437
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
440
return reinterpret_cast<T *>(old);
443
template <typename T>
444
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
446
register T *old, *tmp;
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; */
456
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
459
return reinterpret_cast<T *>(old);
462
template <typename T>
463
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
465
register T *old, *tmp;
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; */
475
: "=&r" (old), "=&r" (tmp), "+m"(_q_value)
478
return reinterpret_cast<T *>(old);
482
# error "This compiler for Alpha is not supported"
485
inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
487
return testAndSetAcquire(expectedValue, newValue);
490
inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
492
return fetchAndStoreAcquire(newValue);
495
inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
497
return fetchAndAddAcquire(valueToAdd);
500
template <typename T>
501
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
503
return testAndSetAcquire(expectedValue, newValue);
506
template <typename T>
507
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
509
return fetchAndStoreAcquire(newValue);
512
template <typename T>
513
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
515
return fetchAndAddAcquire(valueToAdd);
522
#endif // QATOMIC_ALPHA_H