@@ -16,6 +16,22 @@ impl<'c> Translation<'c> {
16
16
let memorder = & self . ast_context [ expr] ;
17
17
let i = match memorder. kind {
18
18
CExprKind :: Literal ( _, CLiteral :: Integer ( i, _) ) => Some ( i) ,
19
+ CExprKind :: DeclRef ( _, decl_id, LRValue :: RValue ) => {
20
+ let decl = self
21
+ . ast_context
22
+ . get_decl ( & decl_id)
23
+ . unwrap ( ) ;
24
+ match decl. kind {
25
+ CDeclKind :: EnumConstant { name : _, value : v} => match v {
26
+ ConstIntExpr :: I ( i) => {
27
+ assert ! ( 0 <= i) ;
28
+ Some ( i as u64 )
29
+ } ,
30
+ ConstIntExpr :: U ( u) => Some ( u) ,
31
+ }
32
+ _ => unimplemented ! ( )
33
+ }
34
+ } ,
19
35
_ => None ,
20
36
} ?;
21
37
use Ordering :: * ;
@@ -76,7 +92,8 @@ impl<'c> Translation<'c> {
76
92
}
77
93
78
94
match name {
79
- "__atomic_load" | "__atomic_load_n" => ptr. and_then ( |ptr| {
95
+ "__atomic_load" | "__atomic_load_n" | "__c11_atomic_load"
96
+ => ptr. and_then ( |ptr| {
80
97
let intrinsic_name = format ! ( "atomic_load_{}" , order_name( static_order( order) ) ) ;
81
98
82
99
self . use_feature ( "core_intrinsics" ) ;
@@ -105,7 +122,9 @@ impl<'c> Translation<'c> {
105
122
}
106
123
} ) ,
107
124
108
- "__atomic_store" | "__atomic_store_n" => {
125
+ "__atomic_store"
126
+ | "__atomic_store_n"
127
+ | "__c11_atomic_store" => {
109
128
let val = val1. expect ( "__atomic_store must have a val argument" ) ;
110
129
ptr. and_then ( |ptr| {
111
130
val. and_then ( |val| {
@@ -131,7 +150,28 @@ impl<'c> Translation<'c> {
131
150
} )
132
151
}
133
152
134
- "__atomic_exchange" | "__atomic_exchange_n" => {
153
+ // NOTE: there is no corresponding __atomic_init builtin in clang
154
+ "__c11_atomic_init" => {
155
+ let val = val1. expect (
156
+ & format ! ( "__atomic_init must have a val argument" ) ) ;
157
+ ptr. and_then ( |ptr| {
158
+ val. and_then ( |val| {
159
+ let assignment = mk ( ) . assign_expr (
160
+ mk ( ) . unary_expr ( UnOp :: Deref ( Default :: default ( ) ) , ptr) ,
161
+ val,
162
+ ) ;
163
+ self . convert_side_effects_expr (
164
+ ctx,
165
+ WithStmts :: new_val ( assignment) ,
166
+ "Builtin is not supposed to be used" ,
167
+ )
168
+ } )
169
+ } )
170
+ } ,
171
+
172
+ "__atomic_exchange"
173
+ | "__atomic_exchange_n"
174
+ | "__c11_atomic_exchange" => {
135
175
let val = val1. expect ( "__atomic_store must have a val argument" ) ;
136
176
ptr. and_then ( |ptr| {
137
177
val. and_then ( |val| {
@@ -176,10 +216,19 @@ impl<'c> Translation<'c> {
176
216
} )
177
217
}
178
218
179
- "__atomic_compare_exchange" | "__atomic_compare_exchange_n" => {
219
+ "__atomic_compare_exchange"
220
+ | "__atomic_compare_exchange_n"
221
+ | "__c11_atomic_compare_exchange_strong" => {
180
222
let expected =
181
223
val1. expect ( "__atomic_compare_exchange must have a expected argument" ) ;
182
224
let desired = val2. expect ( "__atomic_compare_exchange must have a desired argument" ) ;
225
+ // Some C11 atomic operations encode the weak property in the name
226
+ let weak = match ( name, weak) {
227
+ ( "__c11_atomic_compare_exchange_strong" , None ) => Some ( false ) ,
228
+ ( "__c11_atomic_compare_exchange_weak" , None ) => Some ( true ) ,
229
+ _ => weak
230
+ } ;
231
+
183
232
ptr. and_then ( |ptr| {
184
233
expected. and_then ( |expected| {
185
234
desired. and_then ( |desired| {
@@ -258,7 +307,13 @@ impl<'c> Translation<'c> {
258
307
| "__atomic_fetch_and"
259
308
| "__atomic_fetch_xor"
260
309
| "__atomic_fetch_or"
261
- | "__atomic_fetch_nand" => {
310
+ | "__atomic_fetch_nand"
311
+ | "__c11_atomic_fetch_add"
312
+ | "__c11_atomic_fetch_sub"
313
+ | "__c11_atomic_fetch_and"
314
+ | "__c11_atomic_fetch_xor"
315
+ | "__c11_atomic_fetch_or"
316
+ | "__c11_atomic_fetch_nand" => {
262
317
let intrinsic_name = if name. contains ( "_add" ) {
263
318
"atomic_xadd"
264
319
} else if name. contains ( "_sub" ) {
@@ -285,7 +340,7 @@ impl<'c> Translation<'c> {
285
340
} )
286
341
}
287
342
288
- _ => unimplemented ! ( "atomic not implemented" ) ,
343
+ _ => unimplemented ! ( "atomic not implemented: {}" , name ) ,
289
344
}
290
345
}
291
346
0 commit comments