Upgrade libm to 0.2.8

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/libm
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: Ic6b0c796cd48d10e02e5908a7dfef6b41ccc5fb4
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 9ccba83..ebcfd1a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "4c8a973741c014b11ce7f1477693a3e5d4ef9609"
+    "sha1": "721a5edc1be6b0412e4b1704590aed76f9a55899"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..ec6e107
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,21 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+[*.md]
+# double whitespace at end of line
+# denotes a line break in Markdown
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_size = 2
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index decd71f..0000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: CI
-on: [push, pull_request]
-
-jobs:
-  docker:
-    name: Docker
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        target:
-        - aarch64-unknown-linux-gnu
-        - arm-unknown-linux-gnueabi
-        - arm-unknown-linux-gnueabihf
-        - armv7-unknown-linux-gnueabihf
-        # - i686-unknown-linux-gnu
-        - mips-unknown-linux-gnu
-        - mips64-unknown-linux-gnuabi64
-        - mips64el-unknown-linux-gnuabi64
-        - powerpc-unknown-linux-gnu
-        - powerpc64-unknown-linux-gnu
-        - powerpc64le-unknown-linux-gnu
-        - x86_64-unknown-linux-gnu
-    steps:
-    - uses: actions/checkout@master
-    - name: Install Rust
-      run: rustup update nightly && rustup default nightly
-    - run: rustup target add ${{ matrix.target }}
-    - run: rustup target add x86_64-unknown-linux-musl
-    - run: cargo generate-lockfile
-    - run: ./ci/run-docker.sh ${{ matrix.target }}
-
-  rustfmt:
-    name: Rustfmt
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@master
-    - name: Install Rust
-      run: rustup update stable && rustup default stable && rustup component add rustfmt
-    - run: cargo fmt -- --check
-
-  wasm:
-    name: WebAssembly
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@master
-    - name: Install Rust
-      run: rustup update nightly && rustup default nightly
-    - run: rustup target add wasm32-unknown-unknown
-    - run: cargo build --target wasm32-unknown-unknown
-
-  cb:
-    name: "The compiler-builtins crate works"
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@master
-    - name: Install Rust
-      run: rustup update nightly && rustup default nightly
-    - run: cargo build -p cb
-
-  benchmarks:
-    name: Benchmarks
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@master
-    - name: Install Rust
-      run: rustup update nightly && rustup default nightly
-    - run: cargo bench --all
diff --git a/Android.bp b/Android.bp
index b34acc5..3de525b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@
     host_supported: true,
     crate_name: "libm",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.6",
+    cargo_pkg_version: "0.2.8",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: ["default"],
@@ -61,7 +61,7 @@
     host_supported: true,
     crate_name: "libm",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.6",
+    cargo_pkg_version: "0.2.8",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
diff --git a/Cargo.toml b/Cargo.toml
index 5752ce6..dcb94d5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,8 +12,12 @@
 [package]
 edition = "2018"
 name = "libm"
-version = "0.2.6"
+version = "0.2.8"
 authors = ["Jorge Aparicio <jorge@japaric.io>"]
+exclude = [
+    "/ci/",
+    "/.github/workflows/",
+]
 description = "libm in pure Rust"
 documentation = "https://docs.rs/libm"
 readme = "README.md"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index f942fde..d33ca61 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -8,8 +8,9 @@
 name = "libm"
 readme = "README.md"
 repository = "https://github.com/rust-lang/libm"
-version = "0.2.6"
+version = "0.2.8"
 edition = "2018"
+exclude = ["/ci/", "/.github/workflows/"]
 
 [features]
 default = []
diff --git a/METADATA b/METADATA
index 5735ca3..5235bbd 100644
--- a/METADATA
+++ b/METADATA
@@ -1,23 +1,20 @@
 # This project was upgraded with external_updater.
-# Usage: tools/external_updater/updater.sh update rust/crates/libm
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# Usage: tools/external_updater/updater.sh update external/rust/crates/libm
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "libm"
 description: "libm in pure Rust"
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://crates.io/crates/libm"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://static.crates.io/crates/libm/libm-0.2.6.crate"
-  }
-  version: "0.2.6"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 12
-    day: 12
+    year: 2024
+    month: 2
+    day: 2
+  }
+  homepage: "https://crates.io/crates/libm"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/libm/libm-0.2.8.crate"
+    version: "0.2.8"
   }
 }
diff --git a/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 9e2559f..0000000
--- a/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
-    qemu-user-static
-ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
-    CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64-static \
-    QEMU_LD_PREFIX=/usr/aarch64-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/arm-unknown-linux-gnueabi/Dockerfile b/ci/docker/arm-unknown-linux-gnueabi/Dockerfile
deleted file mode 100644
index afab874..0000000
--- a/ci/docker/arm-unknown-linux-gnueabi/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-arm-linux-gnueabi libc6-dev-armel-cross qemu-user-static
-ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER=arm-linux-gnueabi-gcc \
-    CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_RUNNER=qemu-arm-static \
-    QEMU_LD_PREFIX=/usr/arm-linux-gnueabi \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile
deleted file mode 100644
index 3ed3602..0000000
--- a/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static
-ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
-    CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm-static \
-    QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile
deleted file mode 100644
index 6617af1..0000000
--- a/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static
-ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
-    CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm-static \
-    QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/i686-unknown-linux-gnu/Dockerfile b/ci/docker/i686-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 5783e28..0000000
--- a/ci/docker/i686-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc-multilib libc6-dev ca-certificates
diff --git a/ci/docker/mips-unknown-linux-gnu/Dockerfile b/ci/docker/mips-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index f47e8f5..0000000
--- a/ci/docker/mips-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-mips-linux-gnu libc6-dev-mips-cross \
-    binfmt-support qemu-user-static qemu-system-mips
-
-ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \
-    CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER=qemu-mips-static \
-    QEMU_LD_PREFIX=/usr/mips-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
deleted file mode 100644
index 8fa77c7..0000000
--- a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    ca-certificates \
-    gcc \
-    gcc-mips64-linux-gnuabi64 \
-    libc6-dev \
-    libc6-dev-mips64-cross \
-    qemu-user-static \
-    qemu-system-mips
-ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \
-    CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64-static \
-    CC_mips64_unknown_linux_gnuabi64=mips64-linux-gnuabi64-gcc \
-    QEMU_LD_PREFIX=/usr/mips64-linux-gnuabi64 \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
deleted file mode 100644
index c6611d9..0000000
--- a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    ca-certificates \
-    gcc \
-    gcc-mips64el-linux-gnuabi64 \
-    libc6-dev \
-    libc6-dev-mips64el-cross \
-    qemu-user-static
-ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER=mips64el-linux-gnuabi64-gcc \
-    CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64el-static \
-    CC_mips64el_unknown_linux_gnuabi64=mips64el-linux-gnuabi64-gcc \
-    QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/mipsel-unknown-linux-gnu/Dockerfile b/ci/docker/mipsel-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 0bc6956..0000000
--- a/ci/docker/mipsel-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-mipsel-linux-gnu libc6-dev-mipsel-cross \
-    binfmt-support qemu-user-static
-
-ENV CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_LINKER=mipsel-linux-gnu-gcc \
-    CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_RUNNER=qemu-mipsel-static \
-    QEMU_LD_PREFIX=/usr/mipsel-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/powerpc-unknown-linux-gnu/Dockerfile b/ci/docker/powerpc-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 2d39fef..0000000
--- a/ci/docker/powerpc-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev qemu-user-static ca-certificates \
-    gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \
-    qemu-system-ppc
-
-ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER=powerpc-linux-gnu-gcc \
-    CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc-static \
-    QEMU_LD_PREFIX=/usr/powerpc-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile b/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 653cd35..0000000
--- a/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates \
-    gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \
-    binfmt-support qemu-user-static qemu-system-ppc
-
-ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER=powerpc64-linux-gnu-gcc \
-    CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64-static \
-    CC_powerpc64_unknown_linux_gnu=powerpc64-linux-gnu-gcc \
-    QEMU_LD_PREFIX=/usr/powerpc64-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile b/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 63ea9af..0000000
--- a/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev qemu-user-static ca-certificates \
-    gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross \
-    qemu-system-ppc
-
-ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER=powerpc64le-linux-gnu-gcc \
-    CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \
-    QEMU_CPU=POWER8 \
-    QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \
-    RUST_TEST_THREADS=1
diff --git a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
deleted file mode 100644
index 98000f4..0000000
--- a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM ubuntu:18.04
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    gcc libc6-dev ca-certificates
diff --git a/ci/run-docker.sh b/ci/run-docker.sh
deleted file mode 100755
index c7ad60f..0000000
--- a/ci/run-docker.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-# Small script to run tests for a target (or all targets) inside all the
-# respective docker images.
-
-set -ex
-
-run() {
-    local target=$1
-
-    echo $target
-
-    # This directory needs to exist before calling docker, otherwise docker will create it but it
-    # will be owned by root
-    mkdir -p target
-
-    docker build -t $target ci/docker/$target
-    docker run \
-           --rm \
-           --user $(id -u):$(id -g) \
-           -e CARGO_HOME=/cargo \
-           -e CARGO_TARGET_DIR=/target \
-           -v "${HOME}/.cargo":/cargo \
-           -v `pwd`/target:/target \
-           -v `pwd`:/checkout:ro \
-           -v `rustc --print sysroot`:/rust:ro \
-           --init \
-           -w /checkout \
-           $target \
-           sh -c "HOME=/tmp PATH=\$PATH:/rust/bin exec ci/run.sh $target"
-}
-
-if [ -z "$1" ]; then
-  for d in `ls ci/docker/`; do
-    run $d
-  done
-else
-  run $1
-fi
diff --git a/ci/run.sh b/ci/run.sh
deleted file mode 100755
index d0cd42a..0000000
--- a/ci/run.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env sh
-
-set -ex
-TARGET=$1
-
-CMD="cargo test --all --target $TARGET"
-
-# Needed for no-panic to correct detect a lack of panics
-export RUSTFLAGS="$RUSTFLAGS -Ccodegen-units=1"
-
-# stable by default
-$CMD
-$CMD --release
-
-# unstable with a feature
-$CMD --features 'unstable'
-$CMD --release --features 'unstable'
-
-# also run the reference tests
-$CMD --features 'unstable musl-reference-tests'
-$CMD --release --features 'unstable musl-reference-tests'
diff --git a/src/lib.rs b/src/lib.rs
index 29742b4..4a17d3a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,11 +12,13 @@
 #![allow(clippy::eq_op)]
 #![allow(clippy::assign_op_pattern)]
 
+mod libm_helper;
 mod math;
 
 use core::{f32, f64};
 
 pub use self::math::*;
+pub use libm_helper::*;
 
 /// Approximate equality with 1 ULP of tolerance
 #[doc(hidden)]
diff --git a/src/libm_helper.rs b/src/libm_helper.rs
new file mode 100644
index 0000000..52d0c4c
--- /dev/null
+++ b/src/libm_helper.rs
@@ -0,0 +1,171 @@
+use core::marker::PhantomData;
+
+use crate::*;
+
+/// Generic helper for libm functions, abstracting over f32 and f64. <br/>
+/// # Type Parameter:
+/// - `T`: Either `f32` or `f64`
+///
+/// # Examples
+/// ```rust
+/// use libm::{self, Libm};
+///
+/// const PI_F32: f32 = 3.1415927410e+00;
+/// const PI_F64: f64 = 3.1415926535897931160e+00;
+///
+/// assert!(Libm::<f32>::cos(0.0f32) == libm::cosf(0.0));
+/// assert!(Libm::<f32>::sin(PI_F32) == libm::sinf(PI_F32));
+///
+/// assert!(Libm::<f64>::cos(0.0f64) == libm::cos(0.0));
+/// assert!(Libm::<f64>::sin(PI_F64) == libm::sin(PI_F64));
+/// ```
+pub struct Libm<T>(PhantomData<T>);
+
+macro_rules! libm_helper {
+    ($t:ident, funcs: $funcs:tt) => {
+        impl Libm<$t> {
+            #![allow(unused_parens)]
+
+            libm_helper! { $funcs }
+        }
+    };
+
+    ({$($func:tt);*}) => {
+        $(
+            libm_helper! { $func }
+        )*
+    };
+
+    ((fn $func:ident($($arg:ident: $arg_typ:ty),*) -> ($($ret_typ:ty),*); => $libm_fn:ident)) => {
+        #[inline(always)]
+        pub fn $func($($arg: $arg_typ),*) -> ($($ret_typ),*) {
+            $libm_fn($($arg),*)
+        }
+    };
+}
+
+libm_helper! {
+    f32,
+    funcs: {
+        (fn acos(x: f32) -> (f32);                  => acosf);
+        (fn acosh(x: f32) -> (f32);                 => acoshf);
+        (fn asin(x: f32) -> (f32);                  => asinf);
+        (fn asinh(x: f32) -> (f32);                 => asinhf);
+        (fn atan(x: f32) -> (f32);                  => atanf);
+        (fn atan2(y: f32, x: f32) -> (f32);         => atan2f);
+        (fn atanh(x: f32) -> (f32);                 => atanhf);
+        (fn cbrt(x: f32) -> (f32);                  => cbrtf);
+        (fn ceil(x: f32) -> (f32);                  => ceilf);
+        (fn copysign(x: f32, y: f32) -> (f32);      => copysignf);
+        (fn cos(x: f32) -> (f32);                   => cosf);
+        (fn cosh(x: f32) -> (f32);                  => coshf);
+        (fn erf(x: f32) -> (f32);                   => erff);
+        (fn erfc(x: f32) -> (f32);                  => erfcf);
+        (fn exp(x: f32) -> (f32);                   => expf);
+        (fn exp2(x: f32) -> (f32);                  => exp2f);
+        (fn exp10(x: f32) -> (f32);                 => exp10f);
+        (fn expm1(x: f32) -> (f32);                 => expm1f);
+        (fn fabs(x: f32) -> (f32);                  => fabsf);
+        (fn fdim(x: f32, y: f32) -> (f32);          => fdimf);
+        (fn floor(x: f32) -> (f32);                 => floorf);
+        (fn fma(x: f32, y: f32, z: f32) -> (f32);   => fmaf);
+        (fn fmax(x: f32, y: f32) -> (f32);          => fmaxf);
+        (fn fmin(x: f32, y: f32) -> (f32);          => fminf);
+        (fn fmod(x: f32, y: f32) -> (f32);          => fmodf);
+        (fn frexp(x: f32) -> (f32, i32);            => frexpf);
+        (fn hypot(x: f32, y: f32) -> (f32);         => hypotf);
+        (fn ilogb(x: f32) -> (i32);                 => ilogbf);
+        (fn j0(x: f32) -> (f32);                    => j0f);
+        (fn j1(x: f32) -> (f32);                    => j1f);
+        (fn jn(n: i32, x: f32) -> (f32);            => jnf);
+        (fn ldexp(x: f32, n: i32) -> (f32);         => ldexpf);
+        (fn lgamma_r(x: f32) -> (f32, i32);         => lgammaf_r);
+        (fn lgamma(x: f32) -> (f32);                => lgammaf);
+        (fn log(x: f32) -> (f32);                   => logf);
+        (fn log1p(x: f32) -> (f32);                 => log1pf);
+        (fn log2(x: f32) -> (f32);                  => log2f);
+        (fn log10(x: f32) -> (f32);                 => log10f);
+        (fn modf(x: f32) -> (f32, f32);             => modff);
+        (fn nextafter(x: f32, y: f32) -> (f32);     => nextafterf);
+        (fn pow(x: f32, y: f32) -> (f32);           => powf);
+        (fn remainder(x: f32, y: f32) -> (f32);     => remainderf);
+        (fn remquo(x: f32, y: f32) -> (f32, i32);   => remquof);
+        (fn rint(x: f32) -> (f32);                  => rintf);
+        (fn round(x: f32) -> (f32);                 => roundf);
+        (fn scalbn(x: f32, n: i32) -> (f32);        => scalbnf);
+        (fn sin(x: f32) -> (f32);                   => sinf);
+        (fn sincos(x: f32) -> (f32, f32);           => sincosf);
+        (fn sinh(x: f32) -> (f32);                  => sinhf);
+        (fn sqrt(x: f32) -> (f32);                  => sqrtf);
+        (fn tan(x: f32) -> (f32);                   => tanf);
+        (fn tanh(x: f32) -> (f32);                  => tanhf);
+        (fn tgamma(x: f32) -> (f32);                => tgammaf);
+        (fn trunc(x: f32) -> (f32);                 => truncf);
+        (fn y0(x: f32) -> (f32);                    => y0f);
+        (fn y1(x: f32) -> (f32);                    => y1f);
+        (fn yn(n: i32, x: f32) -> (f32);            => ynf)
+    }
+}
+
+libm_helper! {
+    f64,
+    funcs: {
+        (fn acos(x: f64) -> (f64);                  => acos);
+        (fn acosh(x: f64) -> (f64);                 => acosh);
+        (fn asin(x: f64) -> (f64);                  => asin);
+        (fn asinh(x: f64) -> (f64);                 => asinh);
+        (fn atan(x: f64) -> (f64);                  => atan);
+        (fn atan2(y: f64, x: f64) -> (f64);         => atan2);
+        (fn atanh(x: f64) -> (f64);                 => atanh);
+        (fn cbrt(x: f64) -> (f64);                  => cbrt);
+        (fn ceil(x: f64) -> (f64);                  => ceil);
+        (fn copysign(x: f64, y: f64) -> (f64);      => copysign);
+        (fn cos(x: f64) -> (f64);                   => cos);
+        (fn cosh(x: f64) -> (f64);                  => cosh);
+        (fn erf(x: f64) -> (f64);                   => erf);
+        (fn erfc(x: f64) -> (f64);                  => erfc);
+        (fn exp(x: f64) -> (f64);                   => exp);
+        (fn exp2(x: f64) -> (f64);                  => exp2);
+        (fn exp10(x: f64) -> (f64);                 => exp10);
+        (fn expm1(x: f64) -> (f64);                 => expm1);
+        (fn fabs(x: f64) -> (f64);                  => fabs);
+        (fn fdim(x: f64, y: f64) -> (f64);          => fdim);
+        (fn floor(x: f64) -> (f64);                 => floor);
+        (fn fma(x: f64, y: f64, z: f64) -> (f64);   => fma);
+        (fn fmax(x: f64, y: f64) -> (f64);          => fmax);
+        (fn fmin(x: f64, y: f64) -> (f64);          => fmin);
+        (fn fmod(x: f64, y: f64) -> (f64);          => fmod);
+        (fn frexp(x: f64) -> (f64, i32);            => frexp);
+        (fn hypot(x: f64, y: f64) -> (f64);         => hypot);
+        (fn ilogb(x: f64) -> (i32);                 => ilogb);
+        (fn j0(x: f64) -> (f64);                    => j0);
+        (fn j1(x: f64) -> (f64);                    => j1);
+        (fn jn(n: i32, x: f64) -> (f64);            => jn);
+        (fn ldexp(x: f64, n: i32) -> (f64);         => ldexp);
+        (fn lgamma_r(x: f64) -> (f64, i32);         => lgamma_r);
+        (fn lgamma(x: f64) -> (f64);                => lgamma);
+        (fn log(x: f64) -> (f64);                   => log);
+        (fn log1p(x: f64) -> (f64);                 => log1p);
+        (fn log2(x: f64) -> (f64);                  => log2);
+        (fn log10(x: f64) -> (f64);                 => log10);
+        (fn modf(x: f64) -> (f64, f64);             => modf);
+        (fn nextafter(x: f64, y: f64) -> (f64);     => nextafter);
+        (fn pow(x: f64, y: f64) -> (f64);           => pow);
+        (fn remainder(x: f64, y: f64) -> (f64);     => remainder);
+        (fn remquo(x: f64, y: f64) -> (f64, i32);   => remquo);
+        (fn rint(x: f64) -> (f64);                  => rint);
+        (fn round(x: f64) -> (f64);                 => round);
+        (fn scalbn(x: f64, n: i32) -> (f64);        => scalbn);
+        (fn sin(x: f64) -> (f64);                   => sin);
+        (fn sincos(x: f64) -> (f64, f64);           => sincos);
+        (fn sinh(x: f64) -> (f64);                  => sinh);
+        (fn sqrt(x: f64) -> (f64);                  => sqrt);
+        (fn tan(x: f64) -> (f64);                   => tan);
+        (fn tanh(x: f64) -> (f64);                  => tanh);
+        (fn tgamma(x: f64) -> (f64);                => tgamma);
+        (fn trunc(x: f64) -> (f64);                 => trunc);
+        (fn y0(x: f64) -> (f64);                    => y0);
+        (fn y1(x: f64) -> (f64);                    => y1);
+        (fn yn(n: i32, x: f64) -> (f64);            => yn)
+    }
+}
diff --git a/src/math/erf.rs b/src/math/erf.rs
index 5e21ba5..55569af 100644
--- a/src/math/erf.rs
+++ b/src/math/erf.rs
@@ -263,7 +263,7 @@
     }
 }
 
-/// Error function (f64)
+/// Complementary error function (f64)
 ///
 /// Calculates the complementary probability.
 /// Is `1 - erf(x)`. Is computed directly, so that you can use it to avoid
diff --git a/src/math/erff.rs b/src/math/erff.rs
index f74d4b6..7b25474 100644
--- a/src/math/erff.rs
+++ b/src/math/erff.rs
@@ -174,7 +174,7 @@
     }
 }
 
-/// Error function (f32)
+/// Complementary error function (f32)
 ///
 /// Calculates the complementary probability.
 /// Is `1 - erf(x)`. Is computed directly, so that you can use it to avoid
diff --git a/src/math/fma.rs b/src/math/fma.rs
index f9a86dc..940ee2d 100644
--- a/src/math/fma.rs
+++ b/src/math/fma.rs
@@ -29,21 +29,10 @@
     Num { m: ix, e, sign }
 }
 
+#[inline]
 fn mul(x: u64, y: u64) -> (u64, u64) {
-    let t1: u64;
-    let t2: u64;
-    let t3: u64;
-    let xlo: u64 = x as u32 as u64;
-    let xhi: u64 = x >> 32;
-    let ylo: u64 = y as u32 as u64;
-    let yhi: u64 = y >> 32;
-
-    t1 = xlo * ylo;
-    t2 = xlo * yhi + xhi * ylo;
-    t3 = xhi * yhi;
-    let lo = t1.wrapping_add(t2 << 32);
-    let hi = t3 + (t2 >> 32) + (t1 > lo) as u64;
-    (hi, lo)
+    let t = (x as u128).wrapping_mul(y as u128);
+    ((t >> 64) as u64, t as u64)
 }
 
 /// Floating multiply add (f64)
diff --git a/src/math/pow.rs b/src/math/pow.rs
index 6a19ae6..3020b1a 100644
--- a/src/math/pow.rs
+++ b/src/math/pow.rs
@@ -608,7 +608,7 @@
 
         // Factoring -1 out:
         // (negative anything ^ integer should be (-1 ^ integer) * (positive anything ^ integer))
-        (&[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS])
+        &[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS]
             .iter()
             .for_each(|int_set| {
                 int_set.iter().for_each(|int| {
@@ -620,7 +620,7 @@
 
         // Negative base (imaginary results):
         // (-anything except 0 and Infinity ^ non-integer should be NAN)
-        (&NEG[1..(NEG.len() - 1)]).iter().for_each(|set| {
+        &NEG[1..(NEG.len() - 1)].iter().for_each(|set| {
             set.iter().for_each(|val| {
                 test_sets(&ALL[3..7], &|v: f64| pow(*val, v), &|_| NAN);
             })
diff --git a/src/math/rint.rs b/src/math/rint.rs
index 0c6025c..8edbe34 100644
--- a/src/math/rint.rs
+++ b/src/math/rint.rs
@@ -8,9 +8,19 @@
         x
     } else {
         let ans = if is_positive {
-            x + one_over_e - one_over_e
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let x = force_eval!(x);
+            let xplusoneovere = x + one_over_e;
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let xplusoneovere = force_eval!(xplusoneovere);
+            xplusoneovere - one_over_e
         } else {
-            x - one_over_e + one_over_e
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let x = force_eval!(x);
+            let xminusoneovere = x - one_over_e;
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let xminusoneovere = force_eval!(xminusoneovere);
+            xminusoneovere + one_over_e
         };
 
         if ans == 0.0 {
diff --git a/src/math/rintf.rs b/src/math/rintf.rs
index d427793..7a7da61 100644
--- a/src/math/rintf.rs
+++ b/src/math/rintf.rs
@@ -8,9 +8,19 @@
         x
     } else {
         let ans = if is_positive {
-            x + one_over_e - one_over_e
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let x = force_eval!(x);
+            let xplusoneovere = x + one_over_e;
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let xplusoneovere = force_eval!(xplusoneovere);
+            xplusoneovere - one_over_e
         } else {
-            x - one_over_e + one_over_e
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let x = force_eval!(x);
+            let xminusoneovere = x - one_over_e;
+            #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+            let xminusoneovere = force_eval!(xminusoneovere);
+            xminusoneovere + one_over_e
         };
 
         if ans == 0.0 {
diff --git a/src/math/sqrt.rs b/src/math/sqrt.rs
index f06b209..3733ba0 100644
--- a/src/math/sqrt.rs
+++ b/src/math/sqrt.rs
@@ -261,4 +261,20 @@
             assert_eq!(sqrt(f), f);
         }
     }
+
+    #[test]
+    fn conformance_tests() {
+        let values = [3.14159265359, 10000.0, f64::from_bits(0x0000000f), INFINITY];
+        let results = [
+            4610661241675116657u64,
+            4636737291354636288u64,
+            2197470602079456986u64,
+            9218868437227405312u64,
+        ];
+
+        for i in 0..values.len() {
+            let bits = f64::to_bits(sqrt(values[i]));
+            assert_eq!(results[i], bits);
+        }
+    }
 }
diff --git a/src/math/sqrtf.rs b/src/math/sqrtf.rs
index 00b20e5..8ec72fb 100644
--- a/src/math/sqrtf.rs
+++ b/src/math/sqrtf.rs
@@ -151,4 +151,20 @@
             assert_eq!(sqrtf(f), f);
         }
     }
+
+    #[test]
+    fn conformance_tests() {
+        let values = [
+            3.14159265359f32,
+            10000.0f32,
+            f32::from_bits(0x0000000f),
+            INFINITY,
+        ];
+        let results = [1071833029u32, 1120403456u32, 456082799u32, 2139095040u32];
+
+        for i in 0..values.len() {
+            let bits = f32::to_bits(sqrtf(values[i]));
+            assert_eq!(results[i], bits);
+        }
+    }
 }