compiler-builtins

repository·main·Indexed 19 days ago

https://github.com/rust-lang/compiler-builtins

Core implementations for compiler-builtins and libm, providing essential symbols for the Rust compiler and mathematical functions for the Rust core library. compiler-builtins provides external symbols for basic operations lacking direct hardware support, while libm provides Rust implementations of the C math library.

Tokens
8.2K
Snippets
36
Records
46
Agent score
67%

What's inside compiler-builtins

  1. Overview of compiler-builtins

    main

    The compiler-builtins crate provides external symbols that the Rust compiler expects to be available during the build process. These symbols are typically software routines for basic operations that lack direct hardware support. The crate is largely a port of LLVM's compiler-rt and is distributed as part of the Rust sysroot.

    Because it is part of the sysroot, you do not need to add compiler-builtins as an explicit dependency in your Cargo.toml file.

  2. Overview of compiler-builtins and libm

    main

    This repository provides two primary crates used in the Rust ecosystem:

    • compiler-builtins: Provides symbols that the Rust compiler expects to be available at link time.
    • libm: A Rust implementation of C math libraries, which is used to provide mathematical implementations within core.

    For specific details on each crate, refer to their respective documentation: compiler-builtins/README.md and libm/README.md.

  3. Use `libm` for float math functions

    main

    The libm crate provides Rust implementations of the C math library. It serves as a fallback for Rust's float math functions in core when the core_float_math feature is used.

    If your environment already provides the necessary float math functions via core, you do not need to add libm as a dependency. However, if you require more extensive math functionality than what is available in core, you can use libm directly in your project.

    [dependencies]
    libm = "0.2.11"
  4. Use libm as a pure Rust math library

    main

    The libm crate provides a pure Rust implementation of the standard math library (libm), designed for #![no_std] environments. It is useful for platforms that lack a math library or require a consistent implementation across different targets. The crate exports all mathematical functions from its internal math module and helper functions from libm_helper.

    use libm::{sin, cos, sqrt, /* other math functions */};
  5. The Float trait for floating-point operations

    main

    The Float trait defines a common interface for floating-point types (like f32, f64, and optionally f16, f128) used within libm. It provides access to mathematical constants, bit-level manipulation, and properties like NaN or infinity status.

    Key capabilities include:

    • Bit Manipulation: Convert to/from integer representations using to_bits() and from_bits().
    • Constants: Access standard values like ZERO, ONE, INFINITY, NAN, PI, and EPSILON.
    • Properties: Check for is_nan(), is_qnan(), is_snan(), is_infinite(), and is_sign_negative().
    • Structure: Access bitwidth (BITS), significand bits (SIG_BITS), and exponent bits (EXP_BITS).
    use libm::Float;
    
    fn process_float<F: Float>(val: F) {
        if val.is_nan() {
            println!("Value is NaN");
        } else if val.is_infinite() {
            println!("Value is infinite");
        }
        let bits = val.to_bits();
        println!("Bits: {:x}", bits);
    }
  6. Identify the scope of an operation using OpScope

    main

    The OpScope enum is used to categorize where a function is defined and its visibility. This is used by test crates to determine which modules to inspect for specific APIs.

    Available scopes:

    • LibmPublic: Part of the libm public API.
    • LibmPrivate: Functions internal to libm (e.g., rem_pio2).
    • BuiltinsPublic: Functions that are part of the public API for compiler-builtins.
    pub enum OpScope {
        LibmPublic,
        LibmPrivate,
        BuiltinsPublic,
    }
  7. Licensing for compiler-builtins and libm

    main

    The licensing for the crates in this repository is as follows:

    • libm: MIT License.
    • compiler-builtins: MIT License and the Apache License, Version 2.0 with the LLVM exception.

    Note that all original contributions must be licensed under all of: the MIT license, the Apache-2.0 license, and the Apache-2.0 license with the LLVM exception.

  8. fmaximum_num functions for IEEE 754 maximumNumber

    main

    The fmaximum_num family of functions returns the greater of two arguments. If either argument is NaN, the result is NaN. This behavior coincides with the IEEE 754-2019 maximumNumber standard. Note that the result orders -0.0 < 0.0.

    Available types (subject to feature flags):

    • f16 via fmaximum_numf16 (requires f16_enabled)
    • f32 via fmaximum_numf
    • f64 via fmaximum_num
    • f128 via fmaximum_numf128 (requires f128_enabled)
    // Example usage for f64
    let result = fmaximum_num(1.0, 2.0); // returns 2.0
    let nan_result = fmaximum_num(1.0, f64::NAN); // returns NaN
    let zero_result = fmaximum_num(0.0, -0.0); // returns 0.0
  9. Enable LSE atomics on AArch64

    main

    AArch64 targets support two atomic implementations: the older, slower Load-Locked/Store-Conditional (LL/SC) and the newer, faster Large System Extensions (LSE). To use the faster LSE instructions, you must call __rust_enable_lse() to signal that the host CPU supports them. This allows the 'outlined atomics' runtime to dispatch between the two implementations at runtime.

    // Call this to enable LSE support for outlined atomic operations
    unsafe {
        __rust_enable_lse();
    }
  10. fminimum_num functions for IEEE 754 minimumNumber

    main

    The fminimum_num family of functions returns the lesser of two arguments. If either argument is NaN, the result is NaN. This behavior coincides with the IEEE 754-2019 minimumNumber standard. Note that the result orders -0.0 < 0.0.

    Available types (subject to feature flags):

    • f16 via fminimum_numf16 (requires f16_enabled)
    • f32 via fminimum_numf
    • f64 via fminimum_num
    • f128 via fminimum_numf128 (requires f128_enabled)
    // Example usage for f32
    let result = fminimum_numf(1.0, 2.0); // returns 1.0
    let nan_result = fminimum_numf(1.0, f32::NAN); // returns NaN
    let zero_result = fminimum_numf(0.0, -0.0); // returns -0.0