@@ -39,24 +39,57 @@ macro_rules! cfg_if {
39
39
( @__identity $( $tokens: tt) * ) => { $( $tokens) * } ;
40
40
}
41
41
42
- /// Choose between using an intrinsic (if available) and the function body. Returns directly if
43
- /// the intrinsic is used, otherwise the rest of the function body is used.
42
+ /// Choose among using an intrinsic, an arch-specific implementation, and the function body.
43
+ /// Returns directly if the intrinsic or arch is used, otherwise continue with the rest of the
44
+ /// function.
44
45
///
45
- /// Use this if the intrinsic is likely to be more performant on the platform(s) specified
46
- /// in `intrinsic_available`.
46
+ /// Specify a `use_intrinsic` meta field if the intrinsic is (1) available on the platforms (i.e.
47
+ /// LLVM lowers it without libcalls that may recurse), (2) it is likely to be more performant.
48
+ /// Intrinsics require wrappers in the `math::arch::intrinsics` module.
47
49
///
48
- /// The `cfg` used here is controlled by `build.rs` so the passed meta does not need to account
49
- /// for e.g. the `unstable-intrinsics` or `force-soft-float` features.
50
+ /// Specify a `use_arch` meta field if an architecture-specific implementation is provided.
51
+ /// These live in the `math::arch::some_target_arch` module.
52
+ ///
53
+ /// Specify a `use_arch_required` meta field if something architecture-specific must be used
54
+ /// regardless of feature configuration (`force-soft-floats`).
55
+ ///
56
+ /// The passed meta options do not need to account for relevant Cargo features
57
+ /// (`unstable-intrinsics`, `arch`, `force-soft-floats`), this macro handles that part.
50
58
macro_rules! select_implementation {
51
59
(
52
60
name: $fname: ident,
61
+ // Configuration meta for when to use arch-specific implementation that requires hard
62
+ // float ops
63
+ $( use_arch: $use_arch: meta, ) ?
64
+ // Configuration meta for when to use the arch module regardless of whether softfloats
65
+ // have been requested.
66
+ $( use_arch_required: $use_arch_required: meta, ) ?
53
67
// Configuration meta for when to call intrinsics and let LLVM figure it out
54
68
$( use_intrinsic: $use_intrinsic: meta, ) ?
55
69
args: $( $arg: ident) ,+ ,
56
70
) => {
57
71
// FIXME: these use paths that are a pretty fragile (`super`). We should figure out
58
72
// something better w.r.t. how this is vendored into compiler-builtins.
59
73
74
+ // However, we do need a few things from `arch` that are used even with soft floats.
75
+ //
76
+ select_implementation! {
77
+ @cfg $( $use_arch_required) ?;
78
+ if true {
79
+ return super :: arch:: $fname( $( $arg) ,+ ) ;
80
+ }
81
+ }
82
+
83
+ // By default, never use arch-specific implementations if we have force-soft-floats
84
+ #[ cfg( arch_enabled) ]
85
+ select_implementation! {
86
+ @cfg $( $use_arch) ?;
87
+ // Wrap in `if true` to avoid unused warnings
88
+ if true {
89
+ return super :: arch:: $fname( $( $arg) ,+ ) ;
90
+ }
91
+ }
92
+
60
93
// Never use intrinsics if we are forcing soft floats, and only enable with the
61
94
// `unstable-intrinsics` feature.
62
95
#[ cfg( intrinsics_enabled) ]
0 commit comments