1 // pathfinder/simd/src/extras.rs
2 //
3 // Copyright © 2019 The Pathfinder Project Developers.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 use crate::default::{F32x2, F32x4, I32x2, I32x4};
12 use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
13 
14 // Two 32-bit floats
15 
16 impl F32x2 {
17     // Constructors
18 
19     #[inline]
from_slice(slice: &[f32]) -> F32x220     pub fn from_slice(slice: &[f32]) -> F32x2 {
21         F32x2::new(slice[0], slice[1])
22     }
23 
24     // Accessors
25 
26     #[inline]
x(self) -> f3227     pub fn x(self) -> f32 {
28         self[0]
29     }
30 
31     #[inline]
y(self) -> f3232     pub fn y(self) -> f32 {
33         self[1]
34     }
35 
36     // Mutators
37 
38     #[inline]
set_x(&mut self, x: f32)39     pub fn set_x(&mut self, x: f32) {
40         self[0] = x
41     }
42 
43     #[inline]
set_y(&mut self, y: f32)44     pub fn set_y(&mut self, y: f32) {
45         self[1] = y
46     }
47 
48     // Comparisons
49 
50     #[inline]
approx_eq(self, other: F32x2, epsilon: f32) -> bool51     pub fn approx_eq(self, other: F32x2, epsilon: f32) -> bool {
52         (self - other).abs().packed_gt(F32x2::splat(epsilon)).all_false()
53     }
54 }
55 
56 impl AddAssign for F32x2 {
57     #[inline]
add_assign(&mut self, other: F32x2)58     fn add_assign(&mut self, other: F32x2) {
59         *self = *self + other
60     }
61 }
62 
63 impl SubAssign for F32x2 {
64     #[inline]
sub_assign(&mut self, other: F32x2)65     fn sub_assign(&mut self, other: F32x2) {
66         *self = *self - other
67     }
68 }
69 
70 impl MulAssign for F32x2 {
71     #[inline]
mul_assign(&mut self, other: F32x2)72     fn mul_assign(&mut self, other: F32x2) {
73         *self = *self * other
74     }
75 }
76 
77 impl Neg for F32x2 {
78     type Output = F32x2;
79     #[inline]
neg(self) -> F32x280     fn neg(self) -> F32x2 {
81         F32x2::default() - self
82     }
83 }
84 
85 // Four 32-bit floats
86 
87 impl F32x4 {
88     // Constructors
89 
90     #[inline]
from_slice(slice: &[f32]) -> F32x491     pub fn from_slice(slice: &[f32]) -> F32x4 {
92         F32x4::new(slice[0], slice[1], slice[2], slice[3])
93     }
94 
95     // Accessors
96 
97     #[inline]
x(self) -> f3298     pub fn x(self) -> f32 {
99         self[0]
100     }
101 
102     #[inline]
y(self) -> f32103     pub fn y(self) -> f32 {
104         self[1]
105     }
106 
107     #[inline]
z(self) -> f32108     pub fn z(self) -> f32 {
109         self[2]
110     }
111 
112     #[inline]
w(self) -> f32113     pub fn w(self) -> f32 {
114         self[3]
115     }
116 
117     // Mutators
118 
119     #[inline]
set_x(&mut self, x: f32)120     pub fn set_x(&mut self, x: f32) {
121         self[0] = x
122     }
123 
124     #[inline]
set_y(&mut self, y: f32)125     pub fn set_y(&mut self, y: f32) {
126         self[1] = y
127     }
128 
129     #[inline]
set_z(&mut self, z: f32)130     pub fn set_z(&mut self, z: f32) {
131         self[2] = z
132     }
133 
134     #[inline]
set_w(&mut self, w: f32)135     pub fn set_w(&mut self, w: f32) {
136         self[3] = w
137     }
138 
139     // Comparisons
140 
141     #[inline]
approx_eq(self, other: F32x4, epsilon: f32) -> bool142     pub fn approx_eq(self, other: F32x4, epsilon: f32) -> bool {
143         (self - other).abs().packed_gt(F32x4::splat(epsilon)).all_false()
144     }
145 }
146 
147 impl AddAssign for F32x4 {
148     #[inline]
add_assign(&mut self, other: F32x4)149     fn add_assign(&mut self, other: F32x4) {
150         *self = *self + other
151     }
152 }
153 
154 impl SubAssign for F32x4 {
155     #[inline]
sub_assign(&mut self, other: F32x4)156     fn sub_assign(&mut self, other: F32x4) {
157         *self = *self - other
158     }
159 }
160 
161 impl MulAssign for F32x4 {
162     #[inline]
mul_assign(&mut self, other: F32x4)163     fn mul_assign(&mut self, other: F32x4) {
164         *self = *self * other
165     }
166 }
167 
168 impl Neg for F32x4 {
169     type Output = F32x4;
170     #[inline]
neg(self) -> F32x4171     fn neg(self) -> F32x4 {
172         F32x4::default() - self
173     }
174 }
175 
176 // Two 32-bit integers
177 
178 impl AddAssign for I32x2 {
179     #[inline]
add_assign(&mut self, other: I32x2)180     fn add_assign(&mut self, other: I32x2) {
181         *self = *self + other
182     }
183 }
184 
185 impl SubAssign for I32x2 {
186     #[inline]
sub_assign(&mut self, other: I32x2)187     fn sub_assign(&mut self, other: I32x2) {
188         *self = *self - other
189     }
190 }
191 
192 impl MulAssign for I32x2 {
193     #[inline]
mul_assign(&mut self, other: I32x2)194     fn mul_assign(&mut self, other: I32x2) {
195         *self = *self * other
196     }
197 }
198 
199 impl Neg for I32x2 {
200     type Output = I32x2;
201     #[inline]
neg(self) -> I32x2202     fn neg(self) -> I32x2 {
203         I32x2::default() - self
204     }
205 }
206 
207 // Four 32-bit integers
208 
209 impl I32x4 {
210     // Accessors
211 
212     #[inline]
x(self) -> i32213     pub fn x(self) -> i32 {
214         self[0]
215     }
216 
217     #[inline]
y(self) -> i32218     pub fn y(self) -> i32 {
219         self[1]
220     }
221 
222     #[inline]
z(self) -> i32223     pub fn z(self) -> i32 {
224         self[2]
225     }
226 
227     #[inline]
w(self) -> i32228     pub fn w(self) -> i32 {
229         self[3]
230     }
231 }
232 
233 impl AddAssign for I32x4 {
234     #[inline]
add_assign(&mut self, other: I32x4)235     fn add_assign(&mut self, other: I32x4) {
236         *self = *self + other
237     }
238 }
239 
240 impl SubAssign for I32x4 {
241     #[inline]
sub_assign(&mut self, other: I32x4)242     fn sub_assign(&mut self, other: I32x4) {
243         *self = *self - other
244     }
245 }
246 
247 impl MulAssign for I32x4 {
248     #[inline]
mul_assign(&mut self, other: I32x4)249     fn mul_assign(&mut self, other: I32x4) {
250         *self = *self * other
251     }
252 }
253 
254 impl Neg for I32x4 {
255     type Output = I32x4;
256     #[inline]
neg(self) -> I32x4257     fn neg(self) -> I32x4 {
258         I32x4::default() - self
259     }
260 }
261