From 534d22e2871740579c0cf89ec476f6b3a09d7e26 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 30 Sep 2016 17:30:05 -0500 Subject: [PATCH 1/6] panic! -> abort closes #79 --- src/int/udiv.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 3de18b4..8a9da9f 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -1,4 +1,4 @@ -use core::mem; +use core::{intrinsics, mem}; use int::{Int, LargeInt}; /// Returns `n / d` @@ -7,7 +7,11 @@ use int::{Int, LargeInt}; pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 { // Special cases if d == 0 { - panic!("Division by zero"); + // NOTE This should be unreachable in safe Rust because the program will panic before + // this intrinsic is called + unsafe { + intrinsics::abort() + } } if n == 0 { @@ -129,7 +133,11 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { // K X // --- // 0 0 - panic!("Division by zero"); + // NOTE This should be unreachable in safe Rust because the program will panic before + // this intrinsic is called + unsafe { + intrinsics::abort() + } } if n.low() == 0 { From a2ffc799d065155de70cf08ee45c6a3333b365e8 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 30 Sep 2016 23:10:30 -0500 Subject: [PATCH 2/6] check that we don't have any call to panic in our implementations --- Cargo.toml | 3 ++ ci/run.sh | 10 ++++ src/bin/intrinsics.rs | 106 ++++++++++++++++++++++++------------------ 3 files changed, 75 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c198d9f..b3a5cf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,6 @@ c = [] weak = ["rlibc/weak"] [workspace] + +[profile.release] +lto = true diff --git a/ci/run.sh b/ci/run.sh index 7dc9be1..6a0906b 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -28,6 +28,16 @@ case $1 in ;; esac +# Verify that there are no undefined symbols to `panic` within our implementations +case $1 in + thumb*) + xargo build --features c --target $1 --bin intrinsics --release + ;; + *) + cargo build --features c --target $1 --bin intrinsics --release + ;; +esac + # Look out for duplicated symbols when we include the compiler-rt (C) implementation PREFIX=$(echo $1 | sed -e 's/unknown-//')- case $1 in diff --git a/src/bin/intrinsics.rs b/src/bin/intrinsics.rs index 5e23485..591765a 100644 --- a/src/bin/intrinsics.rs +++ b/src/bin/intrinsics.rs @@ -302,52 +302,70 @@ mod intrinsics { #[cfg(feature = "c")] fn run() { + use core::ptr; use intrinsics::*; - aeabi_d2f(2.); - aeabi_d2i(2.); - aeabi_d2l(2.); - aeabi_d2uiz(2.); - aeabi_d2ulz(2.); - aeabi_dadd(2., 3.); - aeabi_dcmpeq(2., 3.); - aeabi_dcmpgt(2., 3.); - aeabi_dcmplt(2., 3.); - aeabi_ddiv(2., 3.); - aeabi_dmul(2., 3.); - aeabi_dsub(2., 3.); - aeabi_f2d(2.); - aeabi_f2iz(2.); - aeabi_f2lz(2.); - aeabi_f2uiz(2.); - aeabi_f2ulz(2.); - aeabi_fadd(2., 3.); - aeabi_fcmpeq(2., 3.); - aeabi_fcmpgt(2., 3.); - aeabi_fcmplt(2., 3.); - aeabi_fdiv(2., 3.); - aeabi_fmul(2., 3.); - aeabi_fsub(2., 3.); - aeabi_i2d(2); - aeabi_i2f(2); - aeabi_idiv(2, 3); - aeabi_idivmod(2, 3); - aeabi_l2d(2); - aeabi_l2f(2); - aeabi_ldivmod(2, 3); - aeabi_lmul(2, 3); - aeabi_ui2d(2); - aeabi_ui2f(2); - aeabi_uidiv(2, 3); - aeabi_uidivmod(2, 3); - aeabi_ul2d(2); - aeabi_ul2f(2); - aeabi_uldivmod(2, 3); - moddi3(2, 3); - mulodi4(2, 3); - powidf2(2., 3); - powisf2(2., 3); - umoddi3(2, 3); + // We use volatile load/stores to prevent LLVM from optimizing away the intrinsics during LTO + macro_rules! arg { + () => { + unsafe { + ptr::read_volatile(0x0 as *const _) + } + } + } + + macro_rules! ret { + ($e:expr) => { + unsafe { + ptr::write_volatile(0x0 as *mut _, $e) + } + } + } + + ret!(aeabi_d2f(arg!())); + ret!(aeabi_d2i(arg!())); + ret!(aeabi_d2l(arg!())); + ret!(aeabi_d2uiz(arg!())); + ret!(aeabi_d2ulz(arg!())); + ret!(aeabi_dadd(arg!(), arg!())); + ret!(aeabi_dcmpeq(arg!(), arg!())); + ret!(aeabi_dcmpgt(arg!(), arg!())); + ret!(aeabi_dcmplt(arg!(), arg!())); + ret!(aeabi_ddiv(arg!(), arg!())); + ret!(aeabi_dmul(arg!(), arg!())); + ret!(aeabi_dsub(arg!(), arg!())); + ret!(aeabi_f2d(arg!())); + ret!(aeabi_f2iz(arg!())); + ret!(aeabi_f2lz(arg!())); + ret!(aeabi_f2uiz(arg!())); + ret!(aeabi_f2ulz(arg!())); + ret!(aeabi_fadd(arg!(), arg!())); + ret!(aeabi_fcmpeq(arg!(), arg!())); + ret!(aeabi_fcmpgt(arg!(), arg!())); + ret!(aeabi_fcmplt(arg!(), arg!())); + ret!(aeabi_fdiv(arg!(), arg!())); + ret!(aeabi_fmul(arg!(), arg!())); + ret!(aeabi_fsub(arg!(), arg!())); + ret!(aeabi_i2d(arg!())); + ret!(aeabi_i2f(arg!())); + ret!(aeabi_idiv(arg!(), arg!())); + ret!(aeabi_idivmod(arg!(), arg!())); + ret!(aeabi_l2d(arg!())); + ret!(aeabi_l2f(arg!())); + ret!(aeabi_ldivmod(arg!(), arg!())); + ret!(aeabi_lmul(arg!(), arg!())); + ret!(aeabi_ui2d(arg!())); + ret!(aeabi_ui2f(arg!())); + ret!(aeabi_uidiv(arg!(), arg!())); + ret!(aeabi_uidivmod(arg!(), arg!())); + ret!(aeabi_ul2d(arg!())); + ret!(aeabi_ul2f(arg!())); + ret!(aeabi_uldivmod(arg!(), arg!())); + ret!(moddi3(arg!(), arg!())); + ret!(mulodi4(arg!(), arg!())); + ret!(powidf2(arg!(), arg!())); + ret!(powisf2(arg!(), arg!())); + ret!(umoddi3(arg!(), arg!())); } #[cfg(all(feature = "c", not(thumb)))] From a21fb956f99232da08c16ef643bcb10175289667 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 5 Oct 2016 20:45:40 -0500 Subject: [PATCH 3/6] insert more `abort()` calls where division by zero may occur --- src/int/sdiv.rs | 14 ++++++++++++++ src/int/udiv.rs | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 37f5dd7..d60dda9 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -1,3 +1,5 @@ +use core::intrinsics; + use int::Int; macro_rules! div { @@ -10,6 +12,12 @@ macro_rules! div { let a = (a ^ s_a) - s_a; let b = (b ^ s_b) - s_b; let s = s_a ^ s_b; + + if b == 0 { + unsafe { + intrinsics::abort() + } + } let r = (a as $uty) / (b as $uty); (r as $ty ^ s) - s } @@ -25,6 +33,12 @@ macro_rules! mod_ { let b = (b ^ s) - s; let s = a >> (<$ty>::bits() - 1); let a = (a ^ s) - s; + + if b == 0 { + unsafe { + intrinsics::abort() + } + } let r = (a as $uty) % (b as $uty); (r as $ty ^ s) - s } diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 8a9da9f..bb1546c 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -109,6 +109,14 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { // 0 X // --- // 0 X + // NOTE This should be unreachable in safe Rust because the program will panic before + // this intrinsic is called + if d.low() == 0 { + unsafe { + intrinsics::abort() + } + } + if let Some(rem) = rem { *rem = u64::from(n.low() % d.low()); } From fd69beba295595e1ba5f70a893835ba4d187d716 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 7 Oct 2016 10:17:44 -0500 Subject: [PATCH 4/6] get profile.dev (-debug-assertions) + LTO working --- Cargo.toml | 6 ++--- ci/run.sh | 6 +++-- src/float/pow.rs | 5 ++-- src/int/sdiv.rs | 14 ++--------- src/int/udiv.rs | 15 ++++-------- src/lib.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b3a5cf4..eefb0b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ compiler-rt = { path = "compiler-rt" } c = [] weak = ["rlibc/weak"] -[workspace] +[profile.dev] +debug-assertions = false -[profile.release] -lto = true +[workspace] diff --git a/ci/run.sh b/ci/run.sh index 6a0906b..df27e35 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -31,10 +31,12 @@ esac # Verify that there are no undefined symbols to `panic` within our implementations case $1 in thumb*) - xargo build --features c --target $1 --bin intrinsics --release + xargo rustc --features c --target $1 --bin intrinsics -- -C lto + xargo rustc --features c --target $1 --bin intrinsics --release -- -C lto ;; *) - cargo build --features c --target $1 --bin intrinsics --release + cargo rustc --features c --target $1 --bin intrinsics -- -C lto + cargo rustc --features c --target $1 --bin intrinsics --release -- -C lto ;; esac diff --git a/src/float/pow.rs b/src/float/pow.rs index 14b3b9a..c02c76f 100644 --- a/src/float/pow.rs +++ b/src/float/pow.rs @@ -1,6 +1,7 @@ +use core::intrinsics; macro_rules! pow { - ($intrinsic:ident: $fty:ty, $ity:ty) => { + ($intrinsic:ident: $fty:ty, $ity:ident) => { /// Returns `a` raised to the power `b` #[cfg_attr(not(test), no_mangle)] pub extern "C" fn $intrinsic(a: $fty, b: $ity) -> $fty { @@ -11,7 +12,7 @@ macro_rules! pow { if (b & 1) != 0 { r *= a; } - b /= 2; + b = sdiv!($ity, b, 2); if b == 0 { break; } diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index d60dda9..6f96b80 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -13,12 +13,7 @@ macro_rules! div { let b = (b ^ s_b) - s_b; let s = s_a ^ s_b; - if b == 0 { - unsafe { - intrinsics::abort() - } - } - let r = (a as $uty) / (b as $uty); + let r = udiv!((a as $uty), (b as $uty)); (r as $ty ^ s) - s } } @@ -34,12 +29,7 @@ macro_rules! mod_ { let s = a >> (<$ty>::bits() - 1); let a = (a ^ s) - s; - if b == 0 { - unsafe { - intrinsics::abort() - } - } - let r = (a as $uty) % (b as $uty); + let r = urem!((a as $uty), (b as $uty)); (r as $ty ^ s) - s } } diff --git a/src/int/udiv.rs b/src/int/udiv.rs index bb1546c..999dcec 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -109,18 +109,11 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { // 0 X // --- // 0 X - // NOTE This should be unreachable in safe Rust because the program will panic before - // this intrinsic is called - if d.low() == 0 { - unsafe { - intrinsics::abort() - } - } if let Some(rem) = rem { - *rem = u64::from(n.low() % d.low()); + *rem = u64::from(urem!(n.low(), d.low())); } - return u64::from(n.low() / d.low()); + return u64::from(udiv!(n.low(), d.low())); } else { // 0 X // --- @@ -153,9 +146,9 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { // --- // K 0 if let Some(rem) = rem { - *rem = u64::from_parts(0, n.high() % d.high()); + *rem = u64::from_parts(0, urem!(n.high(), d.high())); } - return u64::from(n.high() / d.high()); + return u64::from(udiv!(n.high(), d.high())); } // K K diff --git a/src/lib.rs b/src/lib.rs index acc56c9..351be02 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,66 @@ // NOTE cfg(all(feature = "c", ..)) indicate that compiler-rt provides an arch optimized // implementation of that intrinsic and we'll prefer to use that +macro_rules! udiv { + ($a:expr, $b:expr) => { + unsafe { + let a = $a; + let b = $b; + + if b == 0 { + intrinsics::abort() + } else { + intrinsics::unchecked_div(a, b) + } + } + } +} + +macro_rules! sdiv { + ($sty:ident, $a:expr, $b:expr) => { + unsafe { + let a = $a; + let b = $b; + + if b == 0 || (b == -1 && a == $sty::min_value()) { + intrinsics::abort() + } else { + intrinsics::unchecked_div(a, b) + } + } + } +} + +macro_rules! urem { + ($a:expr, $b:expr) => { + unsafe { + let a = $a; + let b = $b; + + if b == 0 { + intrinsics::abort() + } else { + intrinsics::unchecked_rem(a, b) + } + } + } +} + +macro_rules! srem { + ($sty:ty, $a:expr, $b:expr) => { + unsafe { + let a = $a; + let b = $b; + + if b == 0 || (b == -1 && a == $sty::min_value()) { + intrinsics::abort() + } else { + intrinsics::unchecked_rem(a, b) + } + } + } +} + #[cfg(test)] #[macro_use] extern crate quickcheck; From c82403551d7093d1c50dc0167025741621038014 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 7 Oct 2016 17:48:37 -0500 Subject: [PATCH 5/6] fix unsafe warnings --- Cargo.toml | 3 --- ci/run.sh | 5 +++-- src/bin/intrinsics.rs | 4 +--- src/float/mod.rs | 1 + src/float/pow.rs | 2 -- src/int/sdiv.rs | 6 ++---- src/lib.rs | 17 +++++++++-------- 7 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eefb0b2..c198d9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,4 @@ compiler-rt = { path = "compiler-rt" } c = [] weak = ["rlibc/weak"] -[profile.dev] -debug-assertions = false - [workspace] diff --git a/ci/run.sh b/ci/run.sh index df27e35..0ac9d68 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -29,13 +29,14 @@ case $1 in esac # Verify that there are no undefined symbols to `panic` within our implementations +# TODO(#79) fix the undefined references problem for debug-assertions+lto case $1 in thumb*) - xargo rustc --features c --target $1 --bin intrinsics -- -C lto + RUSTFLAGS="-C debug-assertions=no" xargo rustc --features c --target $1 --bin intrinsics -- -C lto xargo rustc --features c --target $1 --bin intrinsics --release -- -C lto ;; *) - cargo rustc --features c --target $1 --bin intrinsics -- -C lto + RUSTFLAGS="-C debug-assertions=no" cargo rustc --features c --target $1 --bin intrinsics -- -C lto cargo rustc --features c --target $1 --bin intrinsics --release -- -C lto ;; esac diff --git a/src/bin/intrinsics.rs b/src/bin/intrinsics.rs index 591765a..ca01a9d 100644 --- a/src/bin/intrinsics.rs +++ b/src/bin/intrinsics.rs @@ -308,9 +308,7 @@ fn run() { // We use volatile load/stores to prevent LLVM from optimizing away the intrinsics during LTO macro_rules! arg { () => { - unsafe { - ptr::read_volatile(0x0 as *const _) - } + ptr::read_volatile(0x0 as *const _) } } diff --git a/src/float/mod.rs b/src/float/mod.rs index 8bd574d..7dc084d 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -1,4 +1,5 @@ use core::mem; +#[cfg(test)] use core::fmt; pub mod add; diff --git a/src/float/pow.rs b/src/float/pow.rs index c02c76f..838805f 100644 --- a/src/float/pow.rs +++ b/src/float/pow.rs @@ -1,5 +1,3 @@ -use core::intrinsics; - macro_rules! pow { ($intrinsic:ident: $fty:ty, $ity:ident) => { /// Returns `a` raised to the power `b` diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 6f96b80..a1d119f 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -1,5 +1,3 @@ -use core::intrinsics; - use int::Int; macro_rules! div { @@ -13,7 +11,7 @@ macro_rules! div { let b = (b ^ s_b) - s_b; let s = s_a ^ s_b; - let r = udiv!((a as $uty), (b as $uty)); + let r = udiv!(a as $uty, b as $uty); (r as $ty ^ s) - s } } @@ -29,7 +27,7 @@ macro_rules! mod_ { let s = a >> (<$ty>::bits() - 1); let a = (a ^ s) - s; - let r = urem!((a as $uty), (b as $uty)); + let r = urem!(a as $uty, b as $uty); (r as $ty ^ s) - s } } diff --git a/src/lib.rs b/src/lib.rs index 351be02..f5a12af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ // NOTE cfg(all(feature = "c", ..)) indicate that compiler-rt provides an arch optimized // implementation of that intrinsic and we'll prefer to use that +// TODO(rust-lang/rust#37029) use e.g. checked_div(_).unwrap_or_else(|| abort()) macro_rules! udiv { ($a:expr, $b:expr) => { unsafe { @@ -20,9 +21,9 @@ macro_rules! udiv { let b = $b; if b == 0 { - intrinsics::abort() + ::core::intrinsics::abort() } else { - intrinsics::unchecked_div(a, b) + ::core::intrinsics::unchecked_div(a, b) } } } @@ -35,9 +36,9 @@ macro_rules! sdiv { let b = $b; if b == 0 || (b == -1 && a == $sty::min_value()) { - intrinsics::abort() + ::core::intrinsics::abort() } else { - intrinsics::unchecked_div(a, b) + ::core::intrinsics::unchecked_div(a, b) } } } @@ -50,9 +51,9 @@ macro_rules! urem { let b = $b; if b == 0 { - intrinsics::abort() + ::core::intrinsics::abort() } else { - intrinsics::unchecked_rem(a, b) + ::core::intrinsics::unchecked_rem(a, b) } } } @@ -65,9 +66,9 @@ macro_rules! srem { let b = $b; if b == 0 || (b == -1 && a == $sty::min_value()) { - intrinsics::abort() + ::core::intrinsics::abort() } else { - intrinsics::unchecked_rem(a, b) + ::core::intrinsics::unchecked_rem(a, b) } } } From 96ddd4ed8d3e8ab0dcf050641171789b7eb41f0f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 7 Oct 2016 18:26:21 -0500 Subject: [PATCH 6/6] use test::black_box instead of ptr::*_volatile both prevent LLVM from optimizing away the intrinsics but the former doesn't produce an `intrinsics` binary that segfaults --- ci/run.sh | 2 +- src/bin/intrinsics.rs | 109 +++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/ci/run.sh b/ci/run.sh index 0ac9d68..3846049 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -32,7 +32,7 @@ esac # TODO(#79) fix the undefined references problem for debug-assertions+lto case $1 in thumb*) - RUSTFLAGS="-C debug-assertions=no" xargo rustc --features c --target $1 --bin intrinsics -- -C lto + RUSTFLAGS="-C debug-assertions=no -C link-arg=-nostartfiles" xargo rustc --features c --target $1 --bin intrinsics -- -C lto xargo rustc --features c --target $1 --bin intrinsics --release -- -C lto ;; *) diff --git a/src/bin/intrinsics.rs b/src/bin/intrinsics.rs index ca01a9d..e11e415 100644 --- a/src/bin/intrinsics.rs +++ b/src/bin/intrinsics.rs @@ -4,13 +4,14 @@ // to link due to the missing intrinsic (symbol). #![allow(unused_features)] +#![cfg_attr(thumb, no_main)] #![deny(dead_code)] +#![feature(asm)] #![feature(core_float)] #![feature(lang_items)] #![feature(libc)] #![feature(start)] #![no_std] -#![cfg_attr(thumb, no_main)] #[cfg(not(thumb))] extern crate libc; @@ -302,68 +303,58 @@ mod intrinsics { #[cfg(feature = "c")] fn run() { - use core::ptr; use intrinsics::*; - // We use volatile load/stores to prevent LLVM from optimizing away the intrinsics during LTO - macro_rules! arg { - () => { - ptr::read_volatile(0x0 as *const _) - } + // A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO + fn bb(dummy: T) -> T { + unsafe { asm!("" : : "r"(&dummy)) } + dummy } - macro_rules! ret { - ($e:expr) => { - unsafe { - ptr::write_volatile(0x0 as *mut _, $e) - } - } - } - - ret!(aeabi_d2f(arg!())); - ret!(aeabi_d2i(arg!())); - ret!(aeabi_d2l(arg!())); - ret!(aeabi_d2uiz(arg!())); - ret!(aeabi_d2ulz(arg!())); - ret!(aeabi_dadd(arg!(), arg!())); - ret!(aeabi_dcmpeq(arg!(), arg!())); - ret!(aeabi_dcmpgt(arg!(), arg!())); - ret!(aeabi_dcmplt(arg!(), arg!())); - ret!(aeabi_ddiv(arg!(), arg!())); - ret!(aeabi_dmul(arg!(), arg!())); - ret!(aeabi_dsub(arg!(), arg!())); - ret!(aeabi_f2d(arg!())); - ret!(aeabi_f2iz(arg!())); - ret!(aeabi_f2lz(arg!())); - ret!(aeabi_f2uiz(arg!())); - ret!(aeabi_f2ulz(arg!())); - ret!(aeabi_fadd(arg!(), arg!())); - ret!(aeabi_fcmpeq(arg!(), arg!())); - ret!(aeabi_fcmpgt(arg!(), arg!())); - ret!(aeabi_fcmplt(arg!(), arg!())); - ret!(aeabi_fdiv(arg!(), arg!())); - ret!(aeabi_fmul(arg!(), arg!())); - ret!(aeabi_fsub(arg!(), arg!())); - ret!(aeabi_i2d(arg!())); - ret!(aeabi_i2f(arg!())); - ret!(aeabi_idiv(arg!(), arg!())); - ret!(aeabi_idivmod(arg!(), arg!())); - ret!(aeabi_l2d(arg!())); - ret!(aeabi_l2f(arg!())); - ret!(aeabi_ldivmod(arg!(), arg!())); - ret!(aeabi_lmul(arg!(), arg!())); - ret!(aeabi_ui2d(arg!())); - ret!(aeabi_ui2f(arg!())); - ret!(aeabi_uidiv(arg!(), arg!())); - ret!(aeabi_uidivmod(arg!(), arg!())); - ret!(aeabi_ul2d(arg!())); - ret!(aeabi_ul2f(arg!())); - ret!(aeabi_uldivmod(arg!(), arg!())); - ret!(moddi3(arg!(), arg!())); - ret!(mulodi4(arg!(), arg!())); - ret!(powidf2(arg!(), arg!())); - ret!(powisf2(arg!(), arg!())); - ret!(umoddi3(arg!(), arg!())); + bb(aeabi_d2f(bb(2.))); + bb(aeabi_d2i(bb(2.))); + bb(aeabi_d2l(bb(2.))); + bb(aeabi_d2uiz(bb(2.))); + bb(aeabi_d2ulz(bb(2.))); + bb(aeabi_dadd(bb(2.), bb(3.))); + bb(aeabi_dcmpeq(bb(2.), bb(3.))); + bb(aeabi_dcmpgt(bb(2.), bb(3.))); + bb(aeabi_dcmplt(bb(2.), bb(3.))); + bb(aeabi_ddiv(bb(2.), bb(3.))); + bb(aeabi_dmul(bb(2.), bb(3.))); + bb(aeabi_dsub(bb(2.), bb(3.))); + bb(aeabi_f2d(bb(2.))); + bb(aeabi_f2iz(bb(2.))); + bb(aeabi_f2lz(bb(2.))); + bb(aeabi_f2uiz(bb(2.))); + bb(aeabi_f2ulz(bb(2.))); + bb(aeabi_fadd(bb(2.), bb(3.))); + bb(aeabi_fcmpeq(bb(2.), bb(3.))); + bb(aeabi_fcmpgt(bb(2.), bb(3.))); + bb(aeabi_fcmplt(bb(2.), bb(3.))); + bb(aeabi_fdiv(bb(2.), bb(3.))); + bb(aeabi_fmul(bb(2.), bb(3.))); + bb(aeabi_fsub(bb(2.), bb(3.))); + bb(aeabi_i2d(bb(2))); + bb(aeabi_i2f(bb(2))); + bb(aeabi_idiv(bb(2), bb(3))); + bb(aeabi_idivmod(bb(2), bb(3))); + bb(aeabi_l2d(bb(2))); + bb(aeabi_l2f(bb(2))); + bb(aeabi_ldivmod(bb(2), bb(3))); + bb(aeabi_lmul(bb(2), bb(3))); + bb(aeabi_ui2d(bb(2))); + bb(aeabi_ui2f(bb(2))); + bb(aeabi_uidiv(bb(2), bb(3))); + bb(aeabi_uidivmod(bb(2), bb(3))); + bb(aeabi_ul2d(bb(2))); + bb(aeabi_ul2f(bb(2))); + bb(aeabi_uldivmod(bb(2), bb(3))); + bb(moddi3(bb(2), bb(3))); + bb(mulodi4(bb(2), bb(3))); + bb(powidf2(bb(2.), bb(3))); + bb(powisf2(bb(2.), bb(3))); + bb(umoddi3(bb(2), bb(3))); } #[cfg(all(feature = "c", not(thumb)))]