Преглед на файлове

Shore up docs in the macros module

Alex Crichton преди 7 години
родител
ревизия
eabb6fab4a
променени са 1 файла, в които са добавени 77 реда и са изтрити 12 реда
  1. 77 12
      src/macros.rs

+ 77 - 12
src/macros.rs

@@ -1,10 +1,63 @@
+//! Macros shared throughout the compiler-builtins implementation
+
+/// The "main macro" used for defining intrinsics.
+///
+/// The compiler-builtins library is super platform-specific with tons of crazy
+/// little tweaks for various platforms. As a result it *could* involve a lot fo
+/// #[cfg] and macro soup, but the intention is that this macro alleviates a lof
+/// of that complexity. Ideally this macro has all the weird ABI things
+/// platforms need and elsewhere in this library it just looks like normal Rust
+/// code.
+///
+/// This macro is structured to be invoked with a bunch of functions that looks
+/// like:
+///
+///     intrinsics! {
+///         pub extern "C" fn foo(a: i32) -> u32 {
+///             // ...
+///         }
+///
+///         #[nonstandard_attribute]
+///         pub extern "C" fn bar(a: i32) -> u32 {
+///             // ...
+///         }
+///     }
+///
+/// Each function is defined in a manner that looks like a normal Rust function.
+/// The macro then accepts a few nonstandard attributes that can decorate
+/// various functions. Each of the attributes is documented below with what it
+/// can do, and each of them slightly tweaks how further expansion happens.
+///
+/// A quick overview of attributes supported right now are:
+///
+/// * `use_c_shim_if` - takes a #[cfg] directive and falls back to the
+///   C-compiled version if `feature = "c"` is specified.
+/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and
+///   the specified ABI everywhere else.
+/// * `unadjusted_on_win64` - like `aapcs_on_arm` this switches to the
+///   `"unadjusted"` abi on Win64 and the specified abi elsewhere.
+/// * `win64_128bit_abi_hack` - this attribute is used for 128-bit integer
+///   intrinsics where the ABI is slightly tweaked on Windows platforms, but
+///   it's a normal ABI elsewhere for returning a 128 bit integer.
+/// * `arm_aeabi_alias` - handles the "aliasing" of various intrinsics on ARM
+///   their otherwise typical names to other prefixed ones.
+///
 macro_rules! intrinsics {
     () => ();
 
-    // Anything which has a `not(feature = "c")` we'll generate a shim function
-    // which calls out to the C function if the `c` feature is enabled.
-    // Otherwise if the `c` feature isn't enabled then we'll just have a normal
-    // intrinsic.
+    // Right now there's a bunch of architecture-optimized intrinsics in the
+    // stock compiler-rt implementation. Not all of these have been ported over
+    // to Rust yet so when the `c` feature of this crate is enabled we fall back
+    // to the architecture-specific versions which should be more optimized. The
+    // purpose of this macro is to easily allow specifying this.
+    //
+    // The argument to `use_c_shim_if` is a `#[cfg]` directive which, when true,
+    // will cause this crate's exported version of `$name` to just redirect to
+    // the C implementation. No symbol named `$name` will be in the object file
+    // for this crate itself.
+    //
+    // When the `#[cfg]` directive is false, or when the `c` feature is
+    // disabled, the provided implementation is used instead.
     (
         #[use_c_shim_if($($cfg_clause:tt)*)]
         $(#[$($attr:tt)*])*
@@ -97,8 +150,13 @@ macro_rules! intrinsics {
         intrinsics!($($rest)*);
     );
 
-    // Another attribute we recognize is an "abi hack" for win64 to get the 128
-    // bit calling convention correct.
+    // Some intrinsics on win64 which return a 128-bit integer have an.. unusual
+    // calling convention. That's managed here with this "abi hack" which alters
+    // the generated symbol's ABI.
+    //
+    // This will still define a function in this crate with the given name and
+    // signature, but the actual symbol for the intrinsic may have a slightly
+    // different ABI on win64.
     (
         #[win64_128bit_abi_hack]
         $(#[$($attr:tt)*])*
@@ -119,10 +177,10 @@ macro_rules! intrinsics {
 
             intrinsics! {
                 pub extern $abi fn $name( $($argname: $ty),* )
-                    -> ::macros::win64_abi_hack::U64x2
+                    -> ::macros::win64_128bit_abi_hack::U64x2
                 {
                     let e: $ret = super::$name($($argname),*);
-                    ::macros::win64_abi_hack::U64x2::from(e)
+                    ::macros::win64_128bit_abi_hack::U64x2::from(e)
                 }
             }
         }
@@ -140,7 +198,8 @@ macro_rules! intrinsics {
 
     // A bunch of intrinsics on ARM are aliased in the standard compiler-rt
     // build under `__aeabi_*` aliases, and LLVM will call these instead of the
-    // original function. Handle that here
+    // original function. The aliasing here is used to generate these symbols in
+    // the object file.
     (
         #[arm_aeabi_alias = $alias:ident]
         $(#[$($attr:tt)*])*
@@ -151,7 +210,6 @@ macro_rules! intrinsics {
         $($rest:tt)*
     ) => (
         #[cfg(target_arch = "arm")]
-        $(#[$($attr)*])*
         pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
             $($body)*
         }
@@ -180,6 +238,12 @@ macro_rules! intrinsics {
         intrinsics!($($rest)*);
     );
 
+    // This is the final catch-all rule. At this point we just generate an
+    // intrinsic with a conditional `#[no_mangle]` directive to avoid
+    // interfereing with duplicate symbols and whatnot.
+    //
+    // After the intrinsic is defined we just continue with the rest of the
+    // input we were given.
     (
         $(#[$($attr:tt)*])*
         pub extern $abi:tt fn $name:ident( $($argname:ident:  $ty:ty),* ) -> $ret:ty {
@@ -198,9 +262,10 @@ macro_rules! intrinsics {
     );
 }
 
-// Hack for LLVM expectations for ABI on windows
+// Hack for LLVM expectations for ABI on windows. This is used by the
+// `#[win64_128bit_abi_hack]` attribute recognized above
 #[cfg(all(windows, target_pointer_width="64"))]
-pub mod win64_abi_hack {
+pub mod win64_128bit_abi_hack {
     #[repr(simd)]
     pub struct U64x2(u64, u64);