PAPI 7.1.0.0
Loading...
Searching...
No Matches
mips.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2007 Thiemo Seufer <ths@networkno.de>
3 *
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
6 *
7 * Permission is hereby granted to use or copy this program
8 * for any purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is granted,
10 * provided the above notices are retained, and a notice that the code was
11 * modified is included with the above copyright notice.
12 */
13
14/*
15 * FIXME: This should probably make finer distinctions. SGI MIPS is
16 * much more strongly ordered, and in fact closer to sequentially
17 * consistent. This is really aimed at modern embedded implementations.
18 */
19
20/* Data dependence does not imply read ordering. */
21#define AO_NO_DD_ORDERING
22
23/* #include "../standard_ao_double_t.h" */
24/* TODO: Implement double-wide operations if available. */
25
26#if (AO_GNUC_PREREQ(4, 9) || AO_CLANG_PREREQ(3, 5)) \
27 && !defined(AO_DISABLE_GCC_ATOMICS)
28 /* Probably, it could be enabled even for earlier gcc/clang versions. */
29
30 /* As of clang-3.6/mips[64], __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n missing. */
31# if defined(__clang__)
32# define AO_GCC_FORCE_HAVE_CAS
33# endif
34
35# include "generic.h"
36
37#else /* AO_DISABLE_GCC_ATOMICS */
38
39# include "../test_and_set_t_is_ao_t.h"
40# include "../all_aligned_atomic_load_store.h"
41
42# if !defined(_ABI64) || _MIPS_SIM != _ABI64
43# define AO_T_IS_INT
44# if __mips_isa_rev >= 6
45 /* Encoding of ll/sc in mips rel6 differs from that of mips2/3. */
46# define AO_MIPS_SET_ISA ""
47# else
48# define AO_MIPS_SET_ISA " .set mips2\n"
49# endif
50# define AO_MIPS_LL_1(args) " ll " args "\n"
51# define AO_MIPS_SC(args) " sc " args "\n"
52# else
53# if __mips_isa_rev >= 6
54# define AO_MIPS_SET_ISA ""
55# else
56# define AO_MIPS_SET_ISA " .set mips3\n"
57# endif
58# define AO_MIPS_LL_1(args) " lld " args "\n"
59# define AO_MIPS_SC(args) " scd " args "\n"
60# endif /* _MIPS_SIM == _ABI64 */
61
62#ifdef AO_ICE9A1_LLSC_WAR
63 /* ICE9 rev A1 chip (used in very few systems) is reported to */
64 /* have a low-frequency bug that causes LL to fail. */
65 /* To workaround, just issue the second 'LL'. */
66# define AO_MIPS_LL(args) AO_MIPS_LL_1(args) AO_MIPS_LL_1(args)
67#else
68# define AO_MIPS_LL(args) AO_MIPS_LL_1(args)
69#endif
70
71AO_INLINE void
73{
74 __asm__ __volatile__(
75 " .set push\n"
77 " .set noreorder\n"
78 " .set nomacro\n"
79 " sync\n"
80 " .set pop"
81 : : : "memory");
82}
83#define AO_HAVE_nop_full
84
85#ifndef AO_PREFER_GENERALIZED
87AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
88{
89 register int result;
90 register int temp;
91
92 __asm__ __volatile__(
93 " .set push\n"
95 " .set noreorder\n"
96 " .set nomacro\n"
97 "1: "
98 AO_MIPS_LL("%0, %2")
99 " addu %1, %0, %3\n"
100 AO_MIPS_SC("%1, %2")
101 " beqz %1, 1b\n"
102 " nop\n"
103 " .set pop"
104 : "=&r" (result), "=&r" (temp), "+m" (*addr)
105 : "Ir" (incr)
106 : "memory");
107 return (AO_t)result;
108}
109#define AO_HAVE_fetch_and_add
110
113{
114 register int oldval;
115 register int temp;
116
117 __asm__ __volatile__(
118 " .set push\n"
120 " .set noreorder\n"
121 " .set nomacro\n"
122 "1: "
123 AO_MIPS_LL("%0, %2")
124 " move %1, %3\n"
125 AO_MIPS_SC("%1, %2")
126 " beqz %1, 1b\n"
127 " nop\n"
128 " .set pop"
129 : "=&r" (oldval), "=&r" (temp), "+m" (*addr)
130 : "r" (1)
131 : "memory");
132 return (AO_TS_VAL_t)oldval;
133}
134#define AO_HAVE_test_and_set
135
136 /* TODO: Implement AO_and/or/xor primitives directly. */
137#endif /* !AO_PREFER_GENERALIZED */
138
139#ifndef AO_GENERALIZE_ASM_BOOL_CAS
140 AO_INLINE int
141 AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
142 {
143 register int was_equal = 0;
144 register int temp;
145
146 __asm__ __volatile__(
147 " .set push\n"
149 " .set noreorder\n"
150 " .set nomacro\n"
151 "1: "
152 AO_MIPS_LL("%0, %1")
153 " bne %0, %4, 2f\n"
154 " move %0, %3\n"
155 AO_MIPS_SC("%0, %1")
156 " .set pop\n"
157 " beqz %0, 1b\n"
158 " li %2, 1\n"
159 "2:"
160 : "=&r" (temp), "+m" (*addr), "+r" (was_equal)
161 : "r" (new_val), "r" (old)
162 : "memory");
163 return was_equal;
164 }
165# define AO_HAVE_compare_and_swap
166#endif /* !AO_GENERALIZE_ASM_BOOL_CAS */
167
169AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
170{
171 register int fetched_val;
172 register int temp;
173
174 __asm__ __volatile__(
175 " .set push\n"
177 " .set noreorder\n"
178 " .set nomacro\n"
179 "1: "
180 AO_MIPS_LL("%0, %2")
181 " bne %0, %4, 2f\n"
182 " move %1, %3\n"
183 AO_MIPS_SC("%1, %2")
184 " beqz %1, 1b\n"
185 " nop\n"
186 " .set pop\n"
187 "2:"
188 : "=&r" (fetched_val), "=&r" (temp), "+m" (*addr)
189 : "r" (new_val), "Jr" (old)
190 : "memory");
191 return (AO_t)fetched_val;
192}
193#define AO_HAVE_fetch_compare_and_swap
194
195#endif /* AO_DISABLE_GCC_ATOMICS */
196
197/* CAS primitives with acquire, release and full semantics are */
198/* generated automatically (and AO_int_... primitives are */
199/* defined properly after the first generalization pass). */
200
201#undef AO_GCC_FORCE_HAVE_CAS
202#undef AO_MIPS_LL
203#undef AO_MIPS_LL_1
204#undef AO_MIPS_SC
205#undef AO_MIPS_SET_ISA
volatile int result
#define AO_t
Definition: atomic_ops.h:156
#define AO_INLINE
Definition: atomic_ops.h:186
#define AO_TS_t
Definition: gcc/hppa.h:39
#define AO_TS_VAL_t
Definition: gcc/hppa.h:44
#define AO_MIPS_SET_ISA
Definition: mips.h:48
AO_INLINE AO_t AO_fetch_and_add(volatile AO_t *addr, AO_t incr)
Definition: mips.h:87
AO_INLINE int AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
Definition: mips.h:141
#define AO_MIPS_SC(args)
Definition: mips.h:51
AO_INLINE AO_TS_VAL_t AO_test_and_set(volatile AO_TS_t *addr)
Definition: mips.h:112
#define AO_MIPS_LL(args)
Definition: mips.h:68
AO_INLINE AO_t AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
Definition: mips.h:169
AO_INLINE void AO_nop_full(void)
Definition: mips.h:72