1 // run-pass
2 // ignore-emscripten
3 // ignore-android
4
5 // FIXME: this test fails on arm-android because the NDK version 14 is too old.
6 // It needs at least version 18. We disable it on all android build bots because
7 // there is no way in compile-test to disable it for an (arch,os) pair.
8
9 // Test that the simd floating-point math intrinsics produce correct results.
10
11 #![feature(repr_simd, platform_intrinsics)]
12 #![allow(non_camel_case_types)]
13
14 #[repr(simd)]
15 #[derive(Copy, Clone, PartialEq, Debug)]
16 struct f32x4(pub f32, pub f32, pub f32, pub f32);
17
18 extern "platform-intrinsic" {
simd_fsqrt<T>(x: T) -> T19 fn simd_fsqrt<T>(x: T) -> T;
simd_fabs<T>(x: T) -> T20 fn simd_fabs<T>(x: T) -> T;
simd_fsin<T>(x: T) -> T21 fn simd_fsin<T>(x: T) -> T;
simd_fcos<T>(x: T) -> T22 fn simd_fcos<T>(x: T) -> T;
simd_fexp<T>(x: T) -> T23 fn simd_fexp<T>(x: T) -> T;
simd_fexp2<T>(x: T) -> T24 fn simd_fexp2<T>(x: T) -> T;
simd_fma<T>(x: T, y: T, z: T) -> T25 fn simd_fma<T>(x: T, y: T, z: T) -> T;
simd_flog<T>(x: T) -> T26 fn simd_flog<T>(x: T) -> T;
simd_flog10<T>(x: T) -> T27 fn simd_flog10<T>(x: T) -> T;
simd_flog2<T>(x: T) -> T28 fn simd_flog2<T>(x: T) -> T;
simd_fpow<T>(x: T, y: T) -> T29 fn simd_fpow<T>(x: T, y: T) -> T;
simd_fpowi<T>(x: T, y: i32) -> T30 fn simd_fpowi<T>(x: T, y: i32) -> T;
31
32 // rounding functions
simd_ceil<T>(x: T) -> T33 fn simd_ceil<T>(x: T) -> T;
simd_floor<T>(x: T) -> T34 fn simd_floor<T>(x: T) -> T;
simd_round<T>(x: T) -> T35 fn simd_round<T>(x: T) -> T;
simd_trunc<T>(x: T) -> T36 fn simd_trunc<T>(x: T) -> T;
37 }
38
39 macro_rules! assert_approx_eq_f32 {
40 ($a:expr, $b:expr) => ({
41 let (a, b) = (&$a, &$b);
42 assert!((*a - *b).abs() < 1.0e-6,
43 "{} is not approximately equal to {}", *a, *b);
44 })
45 }
46 macro_rules! assert_approx_eq {
47 ($a:expr, $b:expr) => ({
48 let a = $a;
49 let b = $b;
50 assert_approx_eq_f32!(a.0, b.0);
51 assert_approx_eq_f32!(a.1, b.1);
52 assert_approx_eq_f32!(a.2, b.2);
53 assert_approx_eq_f32!(a.3, b.3);
54 })
55 }
56
main()57 fn main() {
58 let x = f32x4(1.0, 1.0, 1.0, 1.0);
59 let y = f32x4(-1.0, -1.0, -1.0, -1.0);
60 let z = f32x4(0.0, 0.0, 0.0, 0.0);
61
62 let h = f32x4(0.5, 0.5, 0.5, 0.5);
63
64 unsafe {
65 let r = simd_fabs(y);
66 assert_approx_eq!(x, r);
67
68 let r = simd_fcos(z);
69 assert_approx_eq!(x, r);
70
71 let r = simd_fexp(z);
72 assert_approx_eq!(x, r);
73
74 let r = simd_fexp2(z);
75 assert_approx_eq!(x, r);
76
77 let r = simd_fma(x, h, h);
78 assert_approx_eq!(x, r);
79
80 let r = simd_fsqrt(x);
81 assert_approx_eq!(x, r);
82
83 let r = simd_flog(x);
84 assert_approx_eq!(z, r);
85
86 let r = simd_flog2(x);
87 assert_approx_eq!(z, r);
88
89 let r = simd_flog10(x);
90 assert_approx_eq!(z, r);
91
92 let r = simd_fpow(h, x);
93 assert_approx_eq!(h, r);
94
95 let r = simd_fpowi(h, 1);
96 assert_approx_eq!(h, r);
97
98 let r = simd_fsin(z);
99 assert_approx_eq!(z, r);
100
101 // rounding functions
102 let r = simd_floor(h);
103 assert_eq!(z, r);
104
105 let r = simd_ceil(h);
106 assert_eq!(x, r);
107
108 let r = simd_round(h);
109 assert_eq!(x, r);
110
111 let r = simd_trunc(h);
112 assert_eq!(z, r);
113 }
114 }
115