@@ -25,6 +25,12 @@ macro_rules! public_test_dep {
25
25
/// platforms need and elsewhere in this library it just looks like normal Rust
26
26
/// code.
27
27
///
28
+ /// When the weak-intrinsics feature is enabled, all intrinsics functions are
29
+ /// marked with #[linkage = "weak"] so that they can be replaced by another
30
+ /// implementation at link time. This is particularly useful for mixed Rust/C++
31
+ /// binaries that want to use the C++ intrinsics, otherwise linking against the
32
+ /// Rust stdlib will replace those from the compiler-rt library.
33
+ ///
28
34
/// This macro is structured to be invoked with a bunch of functions that looks
29
35
/// like:
30
36
///
@@ -46,6 +52,10 @@ macro_rules! public_test_dep {
46
52
///
47
53
/// A quick overview of attributes supported right now are:
48
54
///
55
+ /// * `weak` - indicates that the function should always be given weak linkage.
56
+ /// This attribute must come before other attributes, as the other attributes
57
+ /// will generate the final output function and need to have `weak` modify
58
+ /// them.
49
59
/// * `maybe_use_optimized_c_shim` - indicates that the Rust implementation is
50
60
/// ignored if an optimized C version was compiled.
51
61
/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and
@@ -57,7 +67,6 @@ macro_rules! public_test_dep {
57
67
/// it's a normal ABI elsewhere for returning a 128 bit integer.
58
68
/// * `arm_aeabi_alias` - handles the "aliasing" of various intrinsics on ARM
59
69
/// their otherwise typical names to other prefixed ones.
60
- ///
61
70
macro_rules! intrinsics {
62
71
( ) => ( ) ;
63
72
@@ -89,6 +98,95 @@ macro_rules! intrinsics {
89
98
90
99
intrinsics!( $( $rest) * ) ;
91
100
) ;
101
+ // Same as above but for unsafe.
102
+ (
103
+ #[ cfg_attr( $e: meta, $( $attr: tt) * ) ]
104
+ $( #[ $( $attrs: tt) * ] ) *
105
+ pub unsafe extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
106
+ $( $body: tt) *
107
+ }
108
+ $( $rest: tt) *
109
+ ) => (
110
+ #[ cfg( $e) ]
111
+ intrinsics! {
112
+ #[ $( $attr) * ]
113
+ $( #[ $( $attrs) * ] ) *
114
+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
115
+ $( $body) *
116
+ }
117
+ }
118
+
119
+ #[ cfg( not( $e) ) ]
120
+ intrinsics! {
121
+ $( #[ $( $attrs) * ] ) *
122
+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
123
+ $( $body) *
124
+ }
125
+ }
126
+
127
+ intrinsics!( $( $rest) * ) ;
128
+ ) ;
129
+
130
+ // Explicit weak linkage gets dropped when weak-intrinsics is on since it
131
+ // will be added unconditionally to all intrinsics and would conflict
132
+ // otherwise.
133
+ (
134
+ #[ weak]
135
+ $( #[ $( $attr: tt) * ] ) *
136
+ pub extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
137
+ $( $body: tt) *
138
+ }
139
+
140
+ $( $rest: tt) *
141
+ ) => (
142
+ #[ cfg( feature = "weak-intrinsics" ) ]
143
+ intrinsics! {
144
+ $( #[ $( $attr) * ] ) *
145
+ pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
146
+ $( $body) *
147
+ }
148
+ }
149
+
150
+ #[ cfg( not( feature = "weak-intrinsics" ) ) ]
151
+ intrinsics! {
152
+ $( #[ $( $attr) * ] ) *
153
+ #[ linkage = "weak" ]
154
+ pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
155
+ $( $body) *
156
+ }
157
+ }
158
+
159
+ intrinsics!( $( $rest) * ) ;
160
+ ) ;
161
+ // Same as above but for unsafe.
162
+ (
163
+ #[ weak]
164
+ $( #[ $( $attr: tt) * ] ) *
165
+ pub unsafe extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
166
+ $( $body: tt) *
167
+ }
168
+
169
+ $( $rest: tt) *
170
+ ) => (
171
+ #[ cfg( feature = "weak-intrinsics" ) ]
172
+ intrinsics! {
173
+ $( #[ $( $attr) * ] ) *
174
+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
175
+ $( $body) *
176
+ }
177
+ }
178
+
179
+ #[ cfg( not( feature = "weak-intrinsics" ) ) ]
180
+ intrinsics! {
181
+ $( #[ $( $attr) * ] ) *
182
+ #[ linkage = "weak" ]
183
+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
184
+ $( $body) *
185
+ }
186
+ }
187
+
188
+ intrinsics!( $( $rest) * ) ;
189
+ ) ;
92
190
93
191
// Right now there's a bunch of architecture-optimized intrinsics in the
94
192
// stock compiler-rt implementation. Not all of these have been ported over
@@ -112,6 +210,7 @@ macro_rules! intrinsics {
112
210
$( $rest: tt) *
113
211
) => (
114
212
#[ cfg( $name = "optimized-c" ) ]
213
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
115
214
pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
116
215
extern $abi {
117
216
fn $name( $( $argname: $ty) ,* ) $( -> $ret) ?;
@@ -211,13 +310,15 @@ macro_rules! intrinsics {
211
310
) => (
212
311
#[ cfg( all( any( windows, target_os = "uefi" ) , target_arch = "x86_64" ) ) ]
213
312
$( #[ $( $attr) * ] ) *
313
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
214
314
pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
215
315
$( $body) *
216
316
}
217
317
218
318
#[ cfg( all( any( windows, target_os = "uefi" ) , target_arch = "x86_64" ) ) ]
219
319
pub mod $name {
220
320
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
321
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
221
322
pub extern $abi fn $name( $( $argname: $ty) ,* )
222
323
-> :: macros:: win64_128bit_abi_hack:: U64x2
223
324
{
@@ -258,6 +359,7 @@ macro_rules! intrinsics {
258
359
#[ cfg( target_arch = "arm" ) ]
259
360
pub mod $name {
260
361
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
362
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
261
363
pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
262
364
super :: $name( $( $argname) ,* )
263
365
}
@@ -266,7 +368,7 @@ macro_rules! intrinsics {
266
368
#[ cfg( target_arch = "arm" ) ]
267
369
pub mod $alias {
268
370
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
269
- #[ cfg_attr( all( not( windows) , not( target_vendor="apple" ) ) , linkage = "weak" ) ]
371
+ #[ cfg_attr( any ( all( not( windows) , not( target_vendor="apple" ) , feature = "weak-intrinsics ") ) , linkage = "weak" ) ]
270
372
pub extern "aapcs" fn $alias( $( $argname: $ty) ,* ) $( -> $ret) ? {
271
373
super :: $name( $( $argname) ,* )
272
374
}
@@ -302,6 +404,7 @@ macro_rules! intrinsics {
302
404
pub mod $name {
303
405
$( #[ $( $attr) * ] ) *
304
406
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
407
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
305
408
pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
306
409
super :: $name( $( $argname) ,* )
307
410
}
@@ -325,6 +428,7 @@ macro_rules! intrinsics {
325
428
#[ naked]
326
429
$( #[ $( $attr) * ] ) *
327
430
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
431
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
328
432
pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
329
433
$( $body) *
330
434
}
@@ -391,6 +495,7 @@ macro_rules! intrinsics {
391
495
pub mod $name {
392
496
$( #[ $( $attr) * ] ) *
393
497
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
498
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
394
499
pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
395
500
super :: $name( $( $argname) ,* )
396
501
}
@@ -416,6 +521,7 @@ macro_rules! intrinsics {
416
521
pub mod $name {
417
522
$( #[ $( $attr) * ] ) *
418
523
#[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
524
+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
419
525
pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
420
526
super :: $name( $( $argname) ,* )
421
527
}
0 commit comments