@@ -39,24 +39,57 @@ macro_rules! cfg_if {
3939 ( @__identity $( $tokens: tt) * ) => { $( $tokens) * } ;
4040}
4141
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.
4445///
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.
4749///
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.
5058macro_rules! select_implementation {
5159 (
5260 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, ) ?
5367 // Configuration meta for when to call intrinsics and let LLVM figure it out
5468 $( use_intrinsic: $use_intrinsic: meta, ) ?
5569 args: $( $arg: ident) ,+ ,
5670 ) => {
5771 // FIXME: these use paths that are a pretty fragile (`super`). We should figure out
5872 // something better w.r.t. how this is vendored into compiler-builtins.
5973
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+
6093 // Never use intrinsics if we are forcing soft floats, and only enable with the
6194 // `unstable-intrinsics` feature.
6295 #[ cfg( intrinsics_enabled) ]
0 commit comments