1 // Vector4ui.cs
2 //
3 // Author:
4 //   Rodrigo Kumpera (rkumpera@novell.com)
5 //
6 // (C) 2008 Novell, Inc. (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27 using System;
28 using System.Runtime.InteropServices;
29 
30 namespace Mono.Simd
31 {
32 	public static class ArrayExtensions
33 	{
34 		[Acceleration (AccelMode.SSE1)]
35 		[CLSCompliant(false)]
GetVector(this double[] array, int offset)36 		public static Vector2d GetVector (this double[] array, int offset)
37 		{
38 			return new Vector2d (array [offset], array [offset + 1]);
39 		}
40 
41 		[Acceleration (AccelMode.SSE1)]
42 		[CLSCompliant(false)]
GetVector(this long[] array, int offset)43 		public static Vector2l GetVector (this long[] array, int offset)
44 		{
45 			return new Vector2l (array [offset], array [offset + 1]);
46 		}
47 
48 		[Acceleration (AccelMode.SSE1)]
49 		[CLSCompliant(false)]
GetVector(this ulong[] array, int offset)50 		public static Vector2ul GetVector (this ulong[] array, int offset)
51 		{
52 			return new Vector2ul (array [offset], array [offset + 1]);
53 		}
54 
55 		[Acceleration (AccelMode.SSE1)]
56 		[CLSCompliant(false)]
GetVector(this float[] array, int offset)57 		public static Vector4f GetVector (this float[] array, int offset)
58 		{
59 			return new Vector4f (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
60 		}
61 
62 		[Acceleration (AccelMode.SSE1)]
63 		[CLSCompliant(false)]
GetVector(this int[] array, int offset)64 		public static Vector4i GetVector (this int[] array, int offset)
65 		{
66 			return new Vector4i (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
67 		}
68 
69 		[Acceleration (AccelMode.SSE1)]
70 		[CLSCompliant(false)]
GetVector(this uint[] array, int offset)71 		public static Vector4ui GetVector (this uint[] array, int offset)
72 		{
73 			return new Vector4ui (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
74 		}
75 
76 		[Acceleration (AccelMode.SSE1)]
77 		[CLSCompliant(false)]
GetVector(this short[] array, int offset)78 		public static Vector8s GetVector (this short[] array, int offset)
79 		{
80 			if (offset < 0 || offset > array.Length - 8)
81 				throw new IndexOutOfRangeException ();
82 			unsafe {
83 				fixed (void *ptr = &array[offset]) {
84 					return *(Vector8s*)ptr;
85 				}
86 			}
87 		}
88 
89 		[Acceleration (AccelMode.SSE1)]
90 		[CLSCompliant(false)]
GetVector(this ushort[] array, int offset)91 		public static Vector8us GetVector (this ushort[] array, int offset)
92 		{
93 			if (offset < 0 || offset > array.Length - 8)
94 				throw new IndexOutOfRangeException ();
95 			unsafe {
96 				fixed (void *ptr = &array[offset]) {
97 					return *(Vector8us*)ptr;
98 				}
99 			}
100 		}
101 
102 		[Acceleration (AccelMode.SSE1)]
103 		[CLSCompliant(false)]
GetVector(this sbyte[] array, int offset)104 		public static Vector16sb GetVector (this sbyte[] array, int offset)
105 		{
106 			if (offset < 0 || offset > array.Length - 16)
107 				throw new IndexOutOfRangeException ();
108 			unsafe {
109 				fixed (void *ptr = &array[offset]) {
110 					return *(Vector16sb*)ptr;
111 				}
112 			}
113 		}
114 
115 		[Acceleration (AccelMode.SSE1)]
116 		[CLSCompliant(false)]
GetVector(this byte[] array, int offset)117 		public static Vector16b GetVector (this byte[] array, int offset)
118 		{
119 			if (offset < 0 || offset > array.Length - 16)
120 				throw new IndexOutOfRangeException ();
121 			unsafe {
122 				fixed (void *ptr = &array[offset]) {
123 					return *(Vector16b*)ptr;
124 				}
125 			}
126 		}
127 
128 		[Acceleration (AccelMode.SSE1)]
129 		[CLSCompliant(false)]
SetVector(this double[] array, Vector2d val, int offset)130 		public static void SetVector (this double[] array, Vector2d val, int offset)
131 		{
132 			array [offset + 0] = val.X;
133 			array [offset + 1] = val.Y;
134 		}
135 
136 		[Acceleration (AccelMode.SSE1)]
137 		[CLSCompliant(false)]
SetVector(this long[] array, Vector2l val, int offset)138 		public static void SetVector (this long[] array, Vector2l val, int offset)
139 		{
140 			array [offset + 0] = val.X;
141 			array [offset + 1] = val.Y;
142 		}
143 
144 		[Acceleration (AccelMode.SSE1)]
145 		[CLSCompliant(false)]
SetVector(this ulong[] array, Vector2ul val, int offset)146 		public static void SetVector (this ulong[] array, Vector2ul val, int offset)
147 		{
148 			array [offset + 0] = val.X;
149 			array [offset + 1] = val.Y;
150 		}
151 
152 		[Acceleration (AccelMode.SSE1)]
153 		[CLSCompliant(false)]
SetVector(this float[] array, Vector4f val, int offset)154 		public static void SetVector (this float[] array, Vector4f val, int offset)
155 		{
156 			array [offset + 0] = val.X;
157 			array [offset + 1] = val.Y;
158 			array [offset + 2] = val.Z;
159 			array [offset + 3] = val.W;
160 		}
161 
162 		[Acceleration (AccelMode.SSE1)]
163 		[CLSCompliant(false)]
SetVector(this int[] array, Vector4i val, int offset)164 		public static void SetVector (this int[] array, Vector4i val, int offset)
165 		{
166 			array [offset + 0] = val.X;
167 			array [offset + 1] = val.Y;
168 			array [offset + 2] = val.Z;
169 			array [offset + 3] = val.W;
170 		}
171 
172 		[Acceleration (AccelMode.SSE1)]
173 		[CLSCompliant(false)]
SetVector(this uint[] array, Vector4ui val, int offset)174 		public static void SetVector (this uint[] array, Vector4ui val, int offset)
175 		{
176 			array [offset + 0] = val.X;
177 			array [offset + 1] = val.Y;
178 			array [offset + 2] = val.Z;
179 			array [offset + 3] = val.W;
180 		}
181 
182 		[Acceleration (AccelMode.SSE1)]
183 		[CLSCompliant(false)]
SetVector(this short[] array, Vector8s val, int offset)184 		public static void SetVector (this short[] array, Vector8s val, int offset)
185 		{
186 			array [offset + 0] = val.V0;
187 			array [offset + 1] = val.V1;
188 			array [offset + 2] = val.V2;
189 			array [offset + 3] = val.V3;
190 			array [offset + 4] = val.V4;
191 			array [offset + 5] = val.V5;
192 			array [offset + 6] = val.V6;
193 			array [offset + 7] = val.V7;
194 		}
195 
196 		[Acceleration (AccelMode.SSE1)]
197 		[CLSCompliant(false)]
SetVector(this ushort[] array, Vector8us val, int offset)198 		public static void SetVector (this ushort[] array, Vector8us val, int offset)
199 		{
200 			array [offset + 0] = val.V0;
201 			array [offset + 1] = val.V1;
202 			array [offset + 2] = val.V2;
203 			array [offset + 3] = val.V3;
204 			array [offset + 4] = val.V4;
205 			array [offset + 5] = val.V5;
206 			array [offset + 6] = val.V6;
207 			array [offset + 7] = val.V7;
208 		}
209 
210 		[Acceleration (AccelMode.SSE1)]
211 		[CLSCompliant(false)]
SetVector(this sbyte[] array, Vector16sb val, int offset)212 		public static void SetVector (this sbyte[] array, Vector16sb val, int offset)
213 		{
214 			for (int i = 0; i < 16; ++i)
215 				array [offset + i] = val [i];
216 		}
217 
218 		[Acceleration (AccelMode.SSE1)]
219 		[CLSCompliant(false)]
SetVector(this byte[] array, Vector16b val, int offset)220 		public static void SetVector (this byte[] array, Vector16b val, int offset)
221 		{
222 			for (int i = 0; i < 16; ++i)
223 				array [offset + i] = val [i];
224 		}
225 
226 
227 		[Acceleration (AccelMode.SSE1)]
228 		[CLSCompliant(false)]
GetVectorAligned(this double[] array, int offset)229 		public static Vector2d GetVectorAligned (this double[] array, int offset)
230 		{
231 			return new Vector2d (array [offset], array [offset + 1]);
232 		}
233 
234 		[Acceleration (AccelMode.SSE1)]
235 		[CLSCompliant(false)]
GetVectorAligned(this long[] array, int offset)236 		public static Vector2l GetVectorAligned (this long[] array, int offset)
237 		{
238 			return new Vector2l (array [offset], array [offset + 1]);
239 		}
240 
241 		[Acceleration (AccelMode.SSE1)]
242 		[CLSCompliant(false)]
GetVectorAligned(this ulong[] array, int offset)243 		public static Vector2ul GetVectorAligned (this ulong[] array, int offset)
244 		{
245 			return new Vector2ul (array [offset], array [offset + 1]);
246 		}
247 
248 		[Acceleration (AccelMode.SSE1)]
249 		[CLSCompliant(false)]
GetVectorAligned(this float[] array, int offset)250 		public static Vector4f GetVectorAligned (this float[] array, int offset)
251 		{
252 			return new Vector4f (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
253 		}
254 
255 		[Acceleration (AccelMode.SSE1)]
256 		[CLSCompliant(false)]
GetVectorAligned(this int[] array, int offset)257 		public static Vector4i GetVectorAligned (this int[] array, int offset)
258 		{
259 			return new Vector4i (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
260 		}
261 
262 		[Acceleration (AccelMode.SSE1)]
263 		[CLSCompliant(false)]
GetVectorAligned(this uint[] array, int offset)264 		public static Vector4ui GetVectorAligned (this uint[] array, int offset)
265 		{
266 			return new Vector4ui (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
267 		}
268 
269 		[Acceleration (AccelMode.SSE1)]
270 		[CLSCompliant(false)]
GetVectorAligned(this short[] array, int offset)271 		public static Vector8s GetVectorAligned (this short[] array, int offset)
272 		{
273 			if (offset < 0 || offset > array.Length - 8)
274 				throw new IndexOutOfRangeException ();
275 			unsafe {
276 				fixed (void *ptr = &array[offset]) {
277 					return *(Vector8s*)ptr;
278 				}
279 			}
280 		}
281 
282 		[Acceleration (AccelMode.SSE1)]
283 		[CLSCompliant(false)]
GetVectorAligned(this ushort[] array, int offset)284 		public static Vector8us GetVectorAligned (this ushort[] array, int offset)
285 		{
286 			if (offset < 0 || offset > array.Length - 8)
287 				throw new IndexOutOfRangeException ();
288 			unsafe {
289 				fixed (void *ptr = &array[offset]) {
290 					return *(Vector8us*)ptr;
291 				}
292 			}
293 		}
294 
295 		[Acceleration (AccelMode.SSE1)]
296 		[CLSCompliant(false)]
GetVectorAligned(this sbyte[] array, int offset)297 		public static Vector16sb GetVectorAligned (this sbyte[] array, int offset)
298 		{
299 			if (offset < 0 || offset > array.Length - 16)
300 				throw new IndexOutOfRangeException ();
301 			unsafe {
302 				fixed (void *ptr = &array[offset]) {
303 					return *(Vector16sb*)ptr;
304 				}
305 			}
306 		}
307 
308 		[Acceleration (AccelMode.SSE1)]
309 		[CLSCompliant(false)]
GetVectorAligned(this byte[] array, int offset)310 		public static Vector16b GetVectorAligned (this byte[] array, int offset)
311 		{
312 			if (offset < 0 || offset > array.Length - 16)
313 				throw new IndexOutOfRangeException ();
314 			unsafe {
315 				fixed (void *ptr = &array[offset]) {
316 					return *(Vector16b*)ptr;
317 				}
318 			}
319 		}
320 
321 		[Acceleration (AccelMode.SSE1)]
322 		[CLSCompliant(false)]
SetVectorAligned(this double[] array, Vector2d val, int offset)323 		public static void SetVectorAligned (this double[] array, Vector2d val, int offset)
324 		{
325 			array [offset + 0] = val.X;
326 			array [offset + 1] = val.Y;
327 		}
328 
329 		[Acceleration (AccelMode.SSE1)]
330 		[CLSCompliant(false)]
SetVectorAligned(this long[] array, Vector2l val, int offset)331 		public static void SetVectorAligned (this long[] array, Vector2l val, int offset)
332 		{
333 			array [offset + 0] = val.X;
334 			array [offset + 1] = val.Y;
335 		}
336 
337 		[Acceleration (AccelMode.SSE1)]
338 		[CLSCompliant(false)]
SetVectorAligned(this ulong[] array, Vector2ul val, int offset)339 		public static void SetVectorAligned (this ulong[] array, Vector2ul val, int offset)
340 		{
341 			array [offset + 0] = val.X;
342 			array [offset + 1] = val.Y;
343 		}
344 
345 		[Acceleration (AccelMode.SSE1)]
346 		[CLSCompliant(false)]
SetVectorAligned(this float[] array, Vector4f val, int offset)347 		public static void SetVectorAligned (this float[] array, Vector4f val, int offset)
348 		{
349 			array [offset + 0] = val.X;
350 			array [offset + 1] = val.Y;
351 			array [offset + 2] = val.Z;
352 			array [offset + 3] = val.W;
353 		}
354 
355 		[Acceleration (AccelMode.SSE1)]
356 		[CLSCompliant(false)]
SetVectorAligned(this int[] array, Vector4i val, int offset)357 		public static void SetVectorAligned (this int[] array, Vector4i val, int offset)
358 		{
359 			array [offset + 0] = val.X;
360 			array [offset + 1] = val.Y;
361 			array [offset + 2] = val.Z;
362 			array [offset + 3] = val.W;
363 		}
364 
365 		[Acceleration (AccelMode.SSE1)]
366 		[CLSCompliant(false)]
SetVectorAligned(this uint[] array, Vector4ui val, int offset)367 		public static void SetVectorAligned (this uint[] array, Vector4ui val, int offset)
368 		{
369 			array [offset + 0] = val.X;
370 			array [offset + 1] = val.Y;
371 			array [offset + 2] = val.Z;
372 			array [offset + 3] = val.W;
373 		}
374 
375 		[Acceleration (AccelMode.SSE1)]
376 		[CLSCompliant(false)]
SetVectorAligned(this short[] array, Vector8s val, int offset)377 		public static void SetVectorAligned (this short[] array, Vector8s val, int offset)
378 		{
379 			array [offset + 0] = val.V0;
380 			array [offset + 1] = val.V1;
381 			array [offset + 2] = val.V2;
382 			array [offset + 3] = val.V3;
383 			array [offset + 4] = val.V4;
384 			array [offset + 5] = val.V5;
385 			array [offset + 6] = val.V6;
386 			array [offset + 7] = val.V7;
387 		}
388 
389 		[Acceleration (AccelMode.SSE1)]
390 		[CLSCompliant(false)]
SetVectorAligned(this ushort[] array, Vector8us val, int offset)391 		public static void SetVectorAligned (this ushort[] array, Vector8us val, int offset)
392 		{
393 			array [offset + 0] = val.V0;
394 			array [offset + 1] = val.V1;
395 			array [offset + 2] = val.V2;
396 			array [offset + 3] = val.V3;
397 			array [offset + 4] = val.V4;
398 			array [offset + 5] = val.V5;
399 			array [offset + 6] = val.V6;
400 			array [offset + 7] = val.V7;
401 		}
402 
403 		[Acceleration (AccelMode.SSE1)]
404 		[CLSCompliant(false)]
SetVectorAligned(this sbyte[] array, Vector16sb val, int offset)405 		public static void SetVectorAligned (this sbyte[] array, Vector16sb val, int offset)
406 		{
407 			for (int i = 0; i < 16; ++i)
408 				array [offset + i] = val [i];
409 		}
410 
411 		[Acceleration (AccelMode.SSE1)]
412 		[CLSCompliant(false)]
SetVectorAligned(this byte[] array, Vector16b val, int offset)413 		public static void SetVectorAligned (this byte[] array, Vector16b val, int offset)
414 		{
415 			for (int i = 0; i < 16; ++i)
416 				array [offset + i] = val [i];
417 		}
418 
419 		public static bool IsAligned<T> (this T[] vect, int index) where T : struct
420 		{
421 			int size = Marshal.SizeOf (typeof (T));
422 			return size * index % 16 == 0;
423 		}
424 	}
425 }
426