]>
Commit | Line | Data |
---|---|---|
b7449926 | 1 | // run-pass |
94b46f34 XL |
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" { | |
19 | fn simd_fsqrt<T>(x: T) -> T; | |
20 | fn simd_fabs<T>(x: T) -> T; | |
21 | fn simd_fsin<T>(x: T) -> T; | |
22 | fn simd_fcos<T>(x: T) -> T; | |
94b46f34 XL |
23 | fn simd_fexp<T>(x: T) -> T; |
24 | fn simd_fexp2<T>(x: T) -> T; | |
94b46f34 XL |
25 | fn simd_fma<T>(x: T, y: T, z: T) -> T; |
26 | fn simd_flog<T>(x: T) -> T; | |
27 | fn simd_flog10<T>(x: T) -> T; | |
28 | fn simd_flog2<T>(x: T) -> T; | |
29 | fn simd_fpow<T>(x: T, y: T) -> T; | |
30 | fn simd_fpowi<T>(x: T, y: i32) -> T; | |
cdc7bbd5 XL |
31 | |
32 | // rounding functions | |
33 | fn simd_ceil<T>(x: T) -> T; | |
34 | fn simd_floor<T>(x: T) -> T; | |
35 | fn simd_round<T>(x: T) -> T; | |
36 | fn simd_trunc<T>(x: T) -> T; | |
94b46f34 XL |
37 | } |
38 | ||
8faf50e0 XL |
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 | ||
94b46f34 XL |
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); | |
8faf50e0 | 66 | assert_approx_eq!(x, r); |
94b46f34 XL |
67 | |
68 | let r = simd_fcos(z); | |
8faf50e0 | 69 | assert_approx_eq!(x, r); |
94b46f34 | 70 | |
94b46f34 | 71 | let r = simd_fexp(z); |
8faf50e0 | 72 | assert_approx_eq!(x, r); |
94b46f34 XL |
73 | |
74 | let r = simd_fexp2(z); | |
8faf50e0 | 75 | assert_approx_eq!(x, r); |
94b46f34 | 76 | |
94b46f34 | 77 | let r = simd_fma(x, h, h); |
8faf50e0 | 78 | assert_approx_eq!(x, r); |
94b46f34 XL |
79 | |
80 | let r = simd_fsqrt(x); | |
8faf50e0 | 81 | assert_approx_eq!(x, r); |
94b46f34 XL |
82 | |
83 | let r = simd_flog(x); | |
8faf50e0 | 84 | assert_approx_eq!(z, r); |
94b46f34 XL |
85 | |
86 | let r = simd_flog2(x); | |
8faf50e0 | 87 | assert_approx_eq!(z, r); |
94b46f34 XL |
88 | |
89 | let r = simd_flog10(x); | |
8faf50e0 | 90 | assert_approx_eq!(z, r); |
94b46f34 XL |
91 | |
92 | let r = simd_fpow(h, x); | |
8faf50e0 | 93 | assert_approx_eq!(h, r); |
94b46f34 XL |
94 | |
95 | let r = simd_fpowi(h, 1); | |
8faf50e0 | 96 | assert_approx_eq!(h, r); |
94b46f34 XL |
97 | |
98 | let r = simd_fsin(z); | |
8faf50e0 | 99 | assert_approx_eq!(z, r); |
cdc7bbd5 XL |
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); | |
94b46f34 XL |
113 | } |
114 | } |