Skip to content

Commit 436a24a

Browse files
committed
Implement many more float intrinsics
1 parent bdf23c0 commit 436a24a

File tree

2 files changed

+72
-67
lines changed

2 files changed

+72
-67
lines changed

example/std_example.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn main() {
3030
println!("{}", 2.3f32.ceil());
3131
println!("{}", 2.3f32.min(1.0));
3232
println!("{}", 2.3f32.max(1.0));
33+
println!("{}", 2.3f32.powi(2));
3334

3435
assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
3536
assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);

src/intrinsics.rs

+71-67
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,35 @@ macro_rules! intrinsic_match {
5959
};
6060
}
6161

62+
macro_rules! call_intrinsic_match {
63+
($fx:expr, $intrinsic:expr, $substs:expr, $ret:expr, $destination:expr, $args:expr, $(
64+
$name:ident($($arg:ident),*) -> $ty:ident => $func:ident,
65+
)*) => {
66+
match $intrinsic {
67+
$(
68+
stringify!($name) => {
69+
assert!($substs.is_noop());
70+
if let [$($arg),*] = *$args {
71+
let res = $fx.easy_call(stringify!($func), &[$($arg),*], $fx.tcx.types.$ty);
72+
$ret.write_cvalue($fx, res);
73+
74+
if let Some((_, dest)) = $destination {
75+
let ret_ebb = $fx.get_ebb(dest);
76+
$fx.bcx.ins().jump(ret_ebb, &[]);
77+
return;
78+
} else {
79+
unreachable!();
80+
}
81+
} else {
82+
bug!("wrong number of args for intrinsic {:?}", $intrinsic);
83+
}
84+
}
85+
)*
86+
_ => {}
87+
}
88+
}
89+
}
90+
6291
macro_rules! atomic_binop_return_old {
6392
($fx:expr, $op:ident<$T:ident>($ptr:ident, $src:ident) -> $ret:ident) => {
6493
let clif_ty = $fx.clif_type($T).unwrap();
@@ -117,6 +146,48 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
117146
let u64_layout = fx.layout_of(fx.tcx.types.u64);
118147
let usize_layout = fx.layout_of(fx.tcx.types.usize);
119148

149+
call_intrinsic_match! {
150+
fx, intrinsic, substs, ret, destination, args,
151+
expf32(flt) -> f32 => expf,
152+
expf64(flt) -> f64 => exp,
153+
exp2f32(flt) -> f32 => exp2f,
154+
exp2f64(flt) -> f64 => exp2,
155+
sqrtf32(flt) -> f32 => sqrtf,
156+
sqrtf64(flt) -> f64 => sqrt,
157+
powif32(a, x) -> f32 => __powisf2, // compiler-builtins
158+
powif64(a, x) -> f64 => __powidf2, // compiler-builtins
159+
logf32(flt) -> f32 => logf,
160+
logf64(flt) -> f64 => log,
161+
fabsf32(flt) -> f32 => fabsf,
162+
fabsf64(flt) -> f64 => fabs,
163+
fmaf32(x, y, z) -> f32 => fmaf,
164+
fmaf64(x, y, z) -> f64 => fma,
165+
166+
// rounding variants
167+
floorf32(flt) -> f32 => floorf,
168+
floorf64(flt) -> f64 => floor,
169+
ceilf32(flt) -> f32 => ceilf,
170+
ceilf64(flt) -> f64 => ceil,
171+
truncf32(flt) -> f32 => truncf,
172+
truncf64(flt) -> f64 => trunc,
173+
roundf32(flt) -> f32 => roundf,
174+
roundf64(flt) -> f64 => round,
175+
176+
// trigonometry
177+
sinf32(flt) -> f32 => sinf,
178+
sinf64(flt) -> f64 => sin,
179+
cosf32(flt) -> f32 => cosf,
180+
cosf64(flt) -> f64 => cos,
181+
tanf32(flt) -> f32 => tanf,
182+
tanf64(flt) -> f64 => tan,
183+
184+
// minmax
185+
minnumf32(a, b) -> f32 => fminf,
186+
minnumf64(a, b) -> f64 => fmin,
187+
maxnumf32(a, b) -> f32 => fmaxf,
188+
maxnumf64(a, b) -> f64 => fmax,
189+
}
190+
120191
intrinsic_match! {
121192
fx, intrinsic, substs, args,
122193

@@ -604,73 +675,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
604675
_ if intrinsic.starts_with("atomic_umin"), <T> (v ptr, v src) {
605676
atomic_minmax!(fx, IntCC::UnsignedLessThan, <T> (ptr, src) -> ret);
606677
};
607-
608-
expf32, (c flt) {
609-
let res = fx.easy_call("expf", &[flt], fx.tcx.types.f32);
610-
ret.write_cvalue(fx, res);
611-
};
612-
expf64, (c flt) {
613-
let res = fx.easy_call("exp", &[flt], fx.tcx.types.f64);
614-
ret.write_cvalue(fx, res);
615-
};
616-
exp2f32, (c flt) {
617-
let res = fx.easy_call("exp2f", &[flt], fx.tcx.types.f32);
618-
ret.write_cvalue(fx, res);
619-
};
620-
exp2f64, (c flt) {
621-
let res = fx.easy_call("exp2", &[flt], fx.tcx.types.f64);
622-
ret.write_cvalue(fx, res);
623-
};
624-
fabsf32, (c flt) {
625-
let res = fx.easy_call("fabsf", &[flt], fx.tcx.types.f32);
626-
ret.write_cvalue(fx, res);
627-
};
628-
fabsf64, (c flt) {
629-
let res = fx.easy_call("fabs", &[flt], fx.tcx.types.f64);
630-
ret.write_cvalue(fx, res);
631-
};
632-
sqrtf32, (c flt) {
633-
let res = fx.easy_call("sqrtf", &[flt], fx.tcx.types.f32);
634-
ret.write_cvalue(fx, res);
635-
};
636-
sqrtf64, (c flt) {
637-
let res = fx.easy_call("sqrt", &[flt], fx.tcx.types.f64);
638-
ret.write_cvalue(fx, res);
639-
};
640-
floorf32, (c flt) {
641-
let res = fx.easy_call("floorf", &[flt], fx.tcx.types.f32);
642-
ret.write_cvalue(fx, res);
643-
};
644-
floorf64, (c flt) {
645-
let res = fx.easy_call("floor", &[flt], fx.tcx.types.f64);
646-
ret.write_cvalue(fx, res);
647-
};
648-
ceilf32, (c flt) {
649-
let res = fx.easy_call("ceilf", &[flt], fx.tcx.types.f32);
650-
ret.write_cvalue(fx, res);
651-
};
652-
ceilf64, (c flt) {
653-
let res = fx.easy_call("ceil", &[flt], fx.tcx.types.f64);
654-
ret.write_cvalue(fx, res);
655-
};
656-
657-
minnumf32, (c a, c b) {
658-
let res = fx.easy_call("fminf", &[a, b], fx.tcx.types.f32);
659-
ret.write_cvalue(fx, res);
660-
};
661-
minnumf64, (c a, c b) {
662-
let res = fx.easy_call("fmin", &[a, b], fx.tcx.types.f64);
663-
ret.write_cvalue(fx, res);
664-
};
665-
maxnumf32, (c a, c b) {
666-
let res = fx.easy_call("fmaxf", &[a, b], fx.tcx.types.f32);
667-
ret.write_cvalue(fx, res);
668-
};
669-
maxnumf64, (c a, c b) {
670-
let res = fx.easy_call("fmax", &[a, b], fx.tcx.types.f64);
671-
ret.write_cvalue(fx, res);
672-
};
673-
674678
}
675679

676680
if let Some((_, dest)) = destination {

0 commit comments

Comments
 (0)