about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2019-07-27 16:51:48 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2019-07-27 16:52:00 +0200
commit436a24a85dd235743852359b990c66761ff3a4b1 (patch)
tree83c93c13f828f0bb93b0ec2c6ca3b0e9329fbc21
parentbdf23c02018ec87f30a24dd98c8ad4a8bfbf15dd (diff)
downloadrust-436a24a85dd235743852359b990c66761ff3a4b1.tar.gz
rust-436a24a85dd235743852359b990c66761ff3a4b1.zip
Implement many more float intrinsics
-rw-r--r--example/std_example.rs1
-rw-r--r--src/intrinsics.rs138
2 files changed, 72 insertions, 67 deletions
diff --git a/example/std_example.rs b/example/std_example.rs
index a09e050ce3b..2a9df999559 100644
--- a/example/std_example.rs
+++ b/example/std_example.rs
@@ -30,6 +30,7 @@ fn main() {
     println!("{}", 2.3f32.ceil());
     println!("{}", 2.3f32.min(1.0));
     println!("{}", 2.3f32.max(1.0));
+    println!("{}", 2.3f32.powi(2));
 
     assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
     assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);
diff --git a/src/intrinsics.rs b/src/intrinsics.rs
index ee00924ad82..1f86b096e63 100644
--- a/src/intrinsics.rs
+++ b/src/intrinsics.rs
@@ -59,6 +59,35 @@ macro_rules! intrinsic_match {
     };
 }
 
+macro_rules! call_intrinsic_match {
+    ($fx:expr, $intrinsic:expr, $substs:expr, $ret:expr, $destination:expr, $args:expr, $(
+        $name:ident($($arg:ident),*) -> $ty:ident => $func:ident,
+    )*) => {
+        match $intrinsic {
+            $(
+                stringify!($name) => {
+                    assert!($substs.is_noop());
+                    if let [$($arg),*] = *$args {
+                        let res = $fx.easy_call(stringify!($func), &[$($arg),*], $fx.tcx.types.$ty);
+                        $ret.write_cvalue($fx, res);
+
+                        if let Some((_, dest)) = $destination {
+                            let ret_ebb = $fx.get_ebb(dest);
+                            $fx.bcx.ins().jump(ret_ebb, &[]);
+                            return;
+                        } else {
+                            unreachable!();
+                        }
+                    } else {
+                        bug!("wrong number of args for intrinsic {:?}", $intrinsic);
+                    }
+                }
+            )*
+            _ => {}
+        }
+    }
+}
+
 macro_rules! atomic_binop_return_old {
     ($fx:expr, $op:ident<$T:ident>($ptr:ident, $src:ident) -> $ret:ident) => {
         let clif_ty = $fx.clif_type($T).unwrap();
@@ -117,6 +146,48 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
     let u64_layout = fx.layout_of(fx.tcx.types.u64);
     let usize_layout = fx.layout_of(fx.tcx.types.usize);
 
+    call_intrinsic_match! {
+        fx, intrinsic, substs, ret, destination, args,
+        expf32(flt) -> f32 => expf,
+        expf64(flt) -> f64 => exp,
+        exp2f32(flt) -> f32 => exp2f,
+        exp2f64(flt) -> f64 => exp2,
+        sqrtf32(flt) -> f32 => sqrtf,
+        sqrtf64(flt) -> f64 => sqrt,
+        powif32(a, x) -> f32 => __powisf2, // compiler-builtins
+        powif64(a, x) -> f64 => __powidf2, // compiler-builtins
+        logf32(flt) -> f32 => logf,
+        logf64(flt) -> f64 => log,
+        fabsf32(flt) -> f32 => fabsf,
+        fabsf64(flt) -> f64 => fabs,
+        fmaf32(x, y, z) -> f32 => fmaf,
+        fmaf64(x, y, z) -> f64 => fma,
+
+        // rounding variants
+        floorf32(flt) -> f32 => floorf,
+        floorf64(flt) -> f64 => floor,
+        ceilf32(flt) -> f32 => ceilf,
+        ceilf64(flt) -> f64 => ceil,
+        truncf32(flt) -> f32 => truncf,
+        truncf64(flt) -> f64 => trunc,
+        roundf32(flt) -> f32 => roundf,
+        roundf64(flt) -> f64 => round,
+
+        // trigonometry
+        sinf32(flt) -> f32 => sinf,
+        sinf64(flt) -> f64 => sin,
+        cosf32(flt) -> f32 => cosf,
+        cosf64(flt) -> f64 => cos,
+        tanf32(flt) -> f32 => tanf,
+        tanf64(flt) -> f64 => tan,
+
+        // minmax
+        minnumf32(a, b) -> f32 => fminf,
+        minnumf64(a, b) -> f64 => fmin,
+        maxnumf32(a, b) -> f32 => fmaxf,
+        maxnumf64(a, b) -> f64 => fmax,
+    }
+
     intrinsic_match! {
         fx, intrinsic, substs, args,
 
@@ -604,73 +675,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
         _ if intrinsic.starts_with("atomic_umin"), <T> (v ptr, v src) {
             atomic_minmax!(fx, IntCC::UnsignedLessThan, <T> (ptr, src) -> ret);
         };
-
-        expf32, (c flt) {
-            let res = fx.easy_call("expf", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        expf64, (c flt) {
-            let res = fx.easy_call("exp", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        exp2f32, (c flt) {
-            let res = fx.easy_call("exp2f", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        exp2f64, (c flt) {
-            let res = fx.easy_call("exp2", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        fabsf32, (c flt) {
-            let res = fx.easy_call("fabsf", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        fabsf64, (c flt) {
-            let res = fx.easy_call("fabs", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        sqrtf32, (c flt) {
-            let res = fx.easy_call("sqrtf", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        sqrtf64, (c flt) {
-            let res = fx.easy_call("sqrt", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        floorf32, (c flt) {
-            let res = fx.easy_call("floorf", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        floorf64, (c flt) {
-            let res = fx.easy_call("floor", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        ceilf32, (c flt) {
-            let res = fx.easy_call("ceilf", &[flt], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        ceilf64, (c flt) {
-            let res = fx.easy_call("ceil", &[flt], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-
-        minnumf32, (c a, c b) {
-            let res = fx.easy_call("fminf", &[a, b], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        minnumf64, (c a, c b) {
-            let res = fx.easy_call("fmin", &[a, b], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-        maxnumf32, (c a, c b) {
-            let res = fx.easy_call("fmaxf", &[a, b], fx.tcx.types.f32);
-            ret.write_cvalue(fx, res);
-        };
-        maxnumf64, (c a, c b) {
-            let res = fx.easy_call("fmax", &[a, b], fx.tcx.types.f64);
-            ret.write_cvalue(fx, res);
-        };
-
     }
 
     if let Some((_, dest)) = destination {