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