OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [sync.c] - Blame information for rev 775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* Out-of-line libgcc versions of __sync_* builtins.  */
2
/* Copyright (C) 2008, 2009, 2011  Free Software Foundation, Inc.
3
 
4
This file is part of GCC.
5
 
6
GCC is free software; you can redistribute it and/or modify it under
7
the terms of the GNU General Public License as published by the Free
8
Software Foundation; either version 3, or (at your option) any later
9
version.
10
 
11
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
for more details.
15
 
16
Under Section 7 of GPL version 3, you are granted additional
17
permissions described in the GCC Runtime Library Exception, version
18
3.1, as published by the Free Software Foundation.
19
 
20
You should have received a copy of the GNU General Public License and
21
a copy of the GCC Runtime Library Exception along with this program;
22
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
<http://www.gnu.org/licenses/>.  */
24
 
25
/* This file is used by targets whose makefiles define SYNC
26
   to "yes".  It is compiled with SYNC_CFLAGS and provides
27
   out-of-line versions of all relevant __sync_* primitives.
28
 
29
   These routines are intended for targets like MIPS that have two
30
   ISA encodings (the "normal" ISA and the MIPS16 ISA).  The normal
31
   ISA provides full synchronization capabilities but the MIPS16 ISA
32
   has no encoding for them.  MIPS16 code must therefore call external
33
   non-MIPS16 implementations of the __sync_* routines.
34
 
35
   The file is compiled once for each routine.  The following __foo
36
   routines are selected by defining a macro called L<foo>:
37
 
38
       __sync_synchronize
39
 
40
   The following __foo_N routines are selected by defining FN=foo
41
   and SIZE=N:
42
 
43
       __sync_fetch_and_add_N
44
       __sync_fetch_and_sub_N
45
       __sync_fetch_and_or_N
46
       __sync_fetch_and_and_N
47
       __sync_fetch_and_xor_N
48
       __sync_fetch_and_nand_N
49
       __sync_add_and_fetch_N
50
       __sync_sub_and_fetch_N
51
       __sync_or_and_fetch_N
52
       __sync_and_and_fetch_N
53
       __sync_xor_and_fetch_N
54
       __sync_nand_and_fetch_N
55
       __sync_bool_compare_and_swap_N
56
       __sync_val_compare_and_swap_N
57
       __sync_lock_test_and_set_N
58
 
59
   SIZE can be 1, 2, 4, 8 or 16.  __foo_N is omitted if the target does
60
   not provide __sync_compare_and_swap_N.
61
 
62
   Note that __sync_lock_release does not fall back on external
63
   __sync_lock_release_N functions.  The default implementation
64
   of __sync_lock_release is a call to __sync_synchronize followed
65
   by a store of zero, so we don't need separate library functions
66
   for it.  */
67
 
68
#if defined FN
69
 
70
/* Define macros for each __sync_* function type.  Each macro defines a
71
   local function called <NAME>_<UNITS> that acts like __<NAME>_<UNITS>.
72
   TYPE is a type that has UNITS bytes.  */
73
 
74
#define DEFINE_V_PV(NAME, UNITS, TYPE)                                  \
75
  static TYPE                                                           \
76
  NAME##_##UNITS (TYPE *ptr, TYPE value)                                \
77
  {                                                                     \
78
    return __##NAME (ptr, value);                                       \
79
  }
80
 
81
#define DEFINE_V_PVV(NAME, UNITS, TYPE)                         \
82
  static TYPE                                                           \
83
  NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2)                  \
84
  {                                                                     \
85
    return __##NAME (ptr, value1, value2);                              \
86
  }
87
 
88
#define DEFINE_BOOL_PVV(NAME, UNITS, TYPE)                              \
89
  static _Bool                                                          \
90
  NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2)                  \
91
  {                                                                     \
92
    return __##NAME (ptr, value1, value2);                              \
93
  }
94
 
95
/* Map function names to the appropriate DEFINE_* macro.  */
96
 
97
#define local_sync_fetch_and_add DEFINE_V_PV
98
#define local_sync_fetch_and_sub DEFINE_V_PV
99
#define local_sync_fetch_and_or DEFINE_V_PV
100
#define local_sync_fetch_and_and DEFINE_V_PV
101
#define local_sync_fetch_and_xor DEFINE_V_PV
102
#define local_sync_fetch_and_nand DEFINE_V_PV
103
 
104
#define local_sync_add_and_fetch DEFINE_V_PV
105
#define local_sync_sub_and_fetch DEFINE_V_PV
106
#define local_sync_or_and_fetch DEFINE_V_PV
107
#define local_sync_and_and_fetch DEFINE_V_PV
108
#define local_sync_xor_and_fetch DEFINE_V_PV
109
#define local_sync_nand_and_fetch DEFINE_V_PV
110
 
111
#define local_sync_bool_compare_and_swap DEFINE_BOOL_PVV
112
#define local_sync_val_compare_and_swap DEFINE_V_PVV
113
 
114
#define local_sync_lock_test_and_set DEFINE_V_PV
115
 
116
/* Define the function __<NAME>_<UNITS>, given that TYPE is a type with
117
   UNITS bytes.  */
118
#define DEFINE1(NAME, UNITS, TYPE) \
119
  static int unused[sizeof (TYPE) == UNITS ? 1 : -1]    \
120
    __attribute__((unused));                            \
121
  local_##NAME (NAME, UNITS, TYPE);                     \
122
  typeof (NAME##_##UNITS) __##NAME##_##UNITS            \
123
    __attribute__((alias (#NAME "_" #UNITS)));
124
 
125
/* As above, but performing macro expansion on the arguments.  */
126
#define DEFINE(NAME, UNITS, TYPE) DEFINE1 (NAME, UNITS, TYPE)
127
 
128
/* Find an appropriate type TYPE for SIZE and invoke DEFINE (FN, SIZE, TYPE).
129
 
130
   The types chosen here may be incorrect for some targets.
131
   For example, targets with 16-byte atomicity support might not
132
   support OImode.  We would need some kind of target-specific
133
   override if that becomes a problem.  */
134
 
135
#if SIZE == 1 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
136
 
137
typedef unsigned int UQItype __attribute__((mode (QI)));
138
DEFINE (FN, 1, UQItype)
139
 
140
#elif SIZE == 2 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
141
 
142
typedef unsigned int UHItype __attribute__((mode (HI)));
143
DEFINE (FN, 2, UHItype)
144
 
145
#elif SIZE == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
146
 
147
typedef unsigned int USItype __attribute__((mode (SI)));
148
DEFINE (FN, 4, USItype)
149
 
150
#elif SIZE == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
151
 
152
typedef unsigned int UDItype __attribute__((mode (DI)));
153
DEFINE (FN, 8, UDItype)
154
 
155
#elif SIZE == 16 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
156
 
157
typedef unsigned int UOItype __attribute__((mode (OI)));
158
DEFINE (FN, 8, UOItype)
159
 
160
#endif
161
 
162
#elif __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 \
163
      || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 \
164
      || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 \
165
      || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 \
166
      || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
167
 
168
#if defined Lsync_synchronize
169
 
170
static void
171
sync_synchronize (void)
172
{
173
  __sync_synchronize ();
174
}
175
typeof (sync_synchronize) __sync_synchronize \
176
  __attribute__((alias ("sync_synchronize")));
177
 
178
#endif
179
 
180
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.