1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Runtime.CompilerServices; 6 7 namespace System.Numerics 8 { 9 /// <summary> 10 /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another. 11 /// </summary> 12 public static partial class Vector 13 { 14 // JIT is not looking at the Vector class methods 15 // all methods here should be inlined and they must be implemented in terms of Vector<T> intrinsics 16 #region Select Methods 17 /// <summary> 18 /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. 19 /// </summary> 20 /// <param name="condition">The integral mask vector used to drive selection.</param> 21 /// <param name="left">The first source vector.</param> 22 /// <param name="right">The second source vector.</param> 23 /// <returns>The new vector with elements selected based on the mask.</returns> 24 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] ConditionalSelect(Vector<int> condition, Vector<Single> left, Vector<Single> right)25 public static Vector<Single> ConditionalSelect(Vector<int> condition, Vector<Single> left, Vector<Single> right) 26 { 27 return (Vector<Single>)Vector<Single>.ConditionalSelect((Vector<Single>)condition, left, right); 28 } 29 30 /// <summary> 31 /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. 32 /// </summary> 33 /// <param name="condition">The integral mask vector used to drive selection.</param> 34 /// <param name="left">The first source vector.</param> 35 /// <param name="right">The second source vector.</param> 36 /// <returns>The new vector with elements selected based on the mask.</returns> 37 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] ConditionalSelect(Vector<long> condition, Vector<double> left, Vector<double> right)38 public static Vector<double> ConditionalSelect(Vector<long> condition, Vector<double> left, Vector<double> right) 39 { 40 return (Vector<double>)Vector<double>.ConditionalSelect((Vector<double>)condition, left, right); 41 } 42 43 /// <summary> 44 /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. 45 /// </summary> 46 /// <param name="condition">The mask vector used to drive selection.</param> 47 /// <param name="left">The first source vector.</param> 48 /// <param name="right">The second source vector.</param> 49 /// <returns>The new vector with elements selected based on the mask.</returns> 50 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 51 public static Vector<T> ConditionalSelect<T>(Vector<T> condition, Vector<T> left, Vector<T> right) where T : struct 52 { 53 return Vector<T>.ConditionalSelect(condition, left, right); 54 } 55 #endregion Select Methods 56 57 #region Comparison methods 58 #region Equals methods 59 /// <summary> 60 /// Returns a new vector whose elements signal whether the elements in left and right were equal. 61 /// </summary> 62 /// <param name="left">The first vector to compare.</param> 63 /// <param name="right">The second vector to compare.</param> 64 /// <returns>The resultant vector.</returns> 65 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 66 public static Vector<T> Equals<T>(Vector<T> left, Vector<T> right) where T : struct 67 { 68 return Vector<T>.Equals(left, right); 69 } 70 71 /// <summary> 72 /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. 73 /// </summary> 74 /// <param name="left">The first vector to compare.</param> 75 /// <param name="right">The second vector to compare.</param> 76 /// <returns>The resultant vector.</returns> 77 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] Equals(Vector<Single> left, Vector<Single> right)78 public static Vector<int> Equals(Vector<Single> left, Vector<Single> right) 79 { 80 return (Vector<int>)Vector<Single>.Equals(left, right); 81 } 82 83 /// <summary> 84 /// Returns a new vector whose elements signal whether the elements in left and right were equal. 85 /// </summary> 86 /// <param name="left">The first vector to compare.</param> 87 /// <param name="right">The second vector to compare.</param> 88 /// <returns>The resultant vector.</returns> 89 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] Equals(Vector<int> left, Vector<int> right)90 public static Vector<int> Equals(Vector<int> left, Vector<int> right) 91 { 92 return Vector<int>.Equals(left, right); 93 } 94 95 /// <summary> 96 /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. 97 /// </summary> 98 /// <param name="left">The first vector to compare.</param> 99 /// <param name="right">The second vector to compare.</param> 100 /// <returns>The resultant vector.</returns> 101 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] Equals(Vector<double> left, Vector<double> right)102 public static Vector<long> Equals(Vector<double> left, Vector<double> right) 103 { 104 return (Vector<long>)Vector<double>.Equals(left, right); 105 } 106 107 /// <summary> 108 /// Returns a new vector whose elements signal whether the elements in left and right were equal. 109 /// </summary> 110 /// <param name="left">The first vector to compare.</param> 111 /// <param name="right">The second vector to compare.</param> 112 /// <returns>The resultant vector.</returns> 113 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] Equals(Vector<long> left, Vector<long> right)114 public static Vector<long> Equals(Vector<long> left, Vector<long> right) 115 { 116 return Vector<long>.Equals(left, right); 117 } 118 119 /// <summary> 120 /// Returns a boolean indicating whether each pair of elements in the given vectors are equal. 121 /// </summary> 122 /// <param name="left">The first vector to compare.</param> 123 /// <param name="right">The first vector to compare.</param> 124 /// <returns>True if all elements are equal; False otherwise.</returns> 125 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 126 public static bool EqualsAll<T>(Vector<T> left, Vector<T> right) where T : struct 127 { 128 return left == right; 129 } 130 131 /// <summary> 132 /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal. 133 /// </summary> 134 /// <param name="left">The first vector to compare.</param> 135 /// <param name="right">The second vector to compare.</param> 136 /// <returns>True if any element pairs are equal; False if no element pairs are equal.</returns> 137 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 138 public static bool EqualsAny<T>(Vector<T> left, Vector<T> right) where T : struct 139 { 140 return !Vector<T>.Equals(left, right).Equals(Vector<T>.Zero); 141 } 142 #endregion Equals methods 143 144 #region Lessthan Methods 145 /// <summary> 146 /// Returns a new vector whose elements signal whether the elements in left were less than their 147 /// corresponding elements in right. 148 /// </summary> 149 /// <param name="left">The first vector to compare.</param> 150 /// <param name="right">The second vector to compare.</param> 151 /// <returns>The resultant vector.</returns> 152 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 153 public static Vector<T> LessThan<T>(Vector<T> left, Vector<T> right) where T : struct 154 { 155 return Vector<T>.LessThan(left, right); 156 } 157 158 /// <summary> 159 /// Returns an integral vector whose elements signal whether the elements in left were less than their 160 /// corresponding elements in right. 161 /// </summary> 162 /// <param name="left">The first vector to compare.</param> 163 /// <param name="right">The second vector to compare.</param> 164 /// <returns>The resultant integral vector.</returns> 165 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThan(Vector<Single> left, Vector<Single> right)166 public static Vector<int> LessThan(Vector<Single> left, Vector<Single> right) 167 { 168 return (Vector<int>)Vector<Single>.LessThan(left, right); 169 } 170 171 /// <summary> 172 /// Returns a new vector whose elements signal whether the elements in left were less than their 173 /// corresponding elements in right. 174 /// </summary> 175 /// <param name="left">The first vector to compare.</param> 176 /// <param name="right">The second vector to compare.</param> 177 /// <returns>The resultant vector.</returns> 178 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThan(Vector<int> left, Vector<int> right)179 public static Vector<int> LessThan(Vector<int> left, Vector<int> right) 180 { 181 return Vector<int>.LessThan(left, right); 182 } 183 184 /// <summary> 185 /// Returns an integral vector whose elements signal whether the elements in left were less than their 186 /// corresponding elements in right. 187 /// </summary> 188 /// <param name="left">The first vector to compare.</param> 189 /// <param name="right">The second vector to compare.</param> 190 /// <returns>The resultant integral vector.</returns> 191 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThan(Vector<double> left, Vector<double> right)192 public static Vector<long> LessThan(Vector<double> left, Vector<double> right) 193 { 194 return (Vector<long>)Vector<double>.LessThan(left, right); 195 } 196 197 /// <summary> 198 /// Returns a new vector whose elements signal whether the elements in left were less than their 199 /// corresponding elements in right. 200 /// </summary> 201 /// <param name="left">The first vector to compare.</param> 202 /// <param name="right">The second vector to compare.</param> 203 /// <returns>The resultant vector.</returns> 204 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThan(Vector<long> left, Vector<long> right)205 public static Vector<long> LessThan(Vector<long> left, Vector<long> right) 206 { 207 return Vector<long>.LessThan(left, right); 208 } 209 210 /// <summary> 211 /// Returns a boolean indicating whether all of the elements in left are less than their corresponding elements in right. 212 /// </summary> 213 /// <param name="left">The first vector to compare.</param> 214 /// <param name="right">The second vector to compare.</param> 215 /// <returns>True if all elements in left are less than their corresponding elements in right; False otherwise.</returns> 216 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 217 public static bool LessThanAll<T>(Vector<T> left, Vector<T> right) where T : struct 218 { 219 Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right); 220 return cond.Equals(Vector<int>.AllOnes); 221 } 222 223 /// <summary> 224 /// Returns a boolean indicating whether any element in left is less than its corresponding element in right. 225 /// </summary> 226 /// <param name="left">The first vector to compare.</param> 227 /// <param name="right">The second vector to compare.</param> 228 /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns> 229 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 230 public static bool LessThanAny<T>(Vector<T> left, Vector<T> right) where T : struct 231 { 232 Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right); 233 return !cond.Equals(Vector<int>.Zero); 234 } 235 #endregion LessthanMethods 236 237 #region Lessthanorequal methods 238 /// <summary> 239 /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their 240 /// corresponding elements in right. 241 /// </summary> 242 /// <param name="left">The first vector to compare.</param> 243 /// <param name="right">The second vector to compare.</param> 244 /// <returns>The resultant vector.</returns> 245 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 246 public static Vector<T> LessThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct 247 { 248 return Vector<T>.LessThanOrEqual(left, right); 249 } 250 251 /// <summary> 252 /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their 253 /// corresponding elements in right. 254 /// </summary> 255 /// <param name="left">The first vector to compare.</param> 256 /// <param name="right">The second vector to compare.</param> 257 /// <returns>The resultant integral vector.</returns> 258 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThanOrEqual(Vector<Single> left, Vector<Single> right)259 public static Vector<int> LessThanOrEqual(Vector<Single> left, Vector<Single> right) 260 { 261 return (Vector<int>)Vector<Single>.LessThanOrEqual(left, right); 262 } 263 264 /// <summary> 265 /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their 266 /// corresponding elements in right. 267 /// </summary> 268 /// <param name="left">The first vector to compare.</param> 269 /// <param name="right">The second vector to compare.</param> 270 /// <returns>The resultant vector.</returns> 271 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThanOrEqual(Vector<int> left, Vector<int> right)272 public static Vector<int> LessThanOrEqual(Vector<int> left, Vector<int> right) 273 { 274 return Vector<int>.LessThanOrEqual(left, right); 275 } 276 277 /// <summary> 278 /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their 279 /// corresponding elements in right. 280 /// </summary> 281 /// <param name="left">The first vector to compare.</param> 282 /// <param name="right">The second vector to compare.</param> 283 /// <returns>The resultant vector.</returns> 284 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThanOrEqual(Vector<long> left, Vector<long> right)285 public static Vector<long> LessThanOrEqual(Vector<long> left, Vector<long> right) 286 { 287 return Vector<long>.LessThanOrEqual(left, right); 288 } 289 290 /// <summary> 291 /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their 292 /// corresponding elements in right. 293 /// </summary> 294 /// <param name="left">The first vector to compare.</param> 295 /// <param name="right">The second vector to compare.</param> 296 /// <returns>The resultant integral vector.</returns> 297 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] LessThanOrEqual(Vector<double> left, Vector<double> right)298 public static Vector<long> LessThanOrEqual(Vector<double> left, Vector<double> right) 299 { 300 return (Vector<long>)Vector<double>.LessThanOrEqual(left, right); 301 } 302 303 /// <summary> 304 /// Returns a boolean indicating whether all elements in left are less than or equal to their corresponding elements in right. 305 /// </summary> 306 /// <param name="left">The first vector to compare.</param> 307 /// <param name="right">The second vector to compare.</param> 308 /// <returns>True if all elements in left are less than or equal to their corresponding elements in right; False otherwise.</returns> 309 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 310 public static bool LessThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct 311 { 312 Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right); 313 return cond.Equals(Vector<int>.AllOnes); 314 } 315 316 /// <summary> 317 /// Returns a boolean indicating whether any element in left is less than or equal to its corresponding element in right. 318 /// </summary> 319 /// <param name="left">The first vector to compare.</param> 320 /// <param name="right">The second vector to compare.</param> 321 /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns> 322 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 323 public static bool LessThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct 324 { 325 Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right); 326 return !cond.Equals(Vector<int>.Zero); 327 } 328 #endregion Lessthanorequal methods 329 330 #region Greaterthan methods 331 /// <summary> 332 /// Returns a new vector whose elements signal whether the elements in left were greater than their 333 /// corresponding elements in right. 334 /// </summary> 335 /// <param name="left">The first vector to compare.</param> 336 /// <param name="right">The second vector to compare.</param> 337 /// <returns>The resultant vector.</returns> 338 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 339 public static Vector<T> GreaterThan<T>(Vector<T> left, Vector<T> right) where T : struct 340 { 341 return Vector<T>.GreaterThan(left, right); 342 } 343 344 /// <summary> 345 /// Returns an integral vector whose elements signal whether the elements in left were greater than their 346 /// corresponding elements in right. 347 /// </summary> 348 /// <param name="left">The first vector to compare.</param> 349 /// <param name="right">The second vector to compare.</param> 350 /// <returns>The resultant integral vector.</returns> 351 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThan(Vector<Single> left, Vector<Single> right)352 public static Vector<int> GreaterThan(Vector<Single> left, Vector<Single> right) 353 { 354 return (Vector<int>)Vector<Single>.GreaterThan(left, right); 355 } 356 357 /// <summary> 358 /// Returns a new vector whose elements signal whether the elements in left were greater than their 359 /// corresponding elements in right. 360 /// </summary> 361 /// <param name="left">The first vector to compare.</param> 362 /// <param name="right">The second vector to compare.</param> 363 /// <returns>The resultant vector.</returns> 364 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThan(Vector<int> left, Vector<int> right)365 public static Vector<int> GreaterThan(Vector<int> left, Vector<int> right) 366 { 367 return Vector<int>.GreaterThan(left, right); 368 } 369 370 /// <summary> 371 /// Returns an integral vector whose elements signal whether the elements in left were greater than their 372 /// corresponding elements in right. 373 /// </summary> 374 /// <param name="left">The first vector to compare.</param> 375 /// <param name="right">The second vector to compare.</param> 376 /// <returns>The resultant integral vector.</returns> 377 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThan(Vector<double> left, Vector<double> right)378 public static Vector<long> GreaterThan(Vector<double> left, Vector<double> right) 379 { 380 return (Vector<long>)Vector<double>.GreaterThan(left, right); 381 } 382 383 /// <summary> 384 /// Returns a new vector whose elements signal whether the elements in left were greater than their 385 /// corresponding elements in right. 386 /// </summary> 387 /// <param name="left">The first vector to compare.</param> 388 /// <param name="right">The second vector to compare.</param> 389 /// <returns>The resultant vector.</returns> 390 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThan(Vector<long> left, Vector<long> right)391 public static Vector<long> GreaterThan(Vector<long> left, Vector<long> right) 392 { 393 return Vector<long>.GreaterThan(left, right); 394 } 395 396 /// <summary> 397 /// Returns a boolean indicating whether all elements in left are greater than the corresponding elements in right. 398 /// elements in right. 399 /// </summary> 400 /// <param name="left">The first vector to compare.</param> 401 /// <param name="right">The second vector to compare.</param> 402 /// <returns>True if all elements in left are greater than their corresponding elements in right; False otherwise.</returns> 403 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 404 public static bool GreaterThanAll<T>(Vector<T> left, Vector<T> right) where T : struct 405 { 406 Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right); 407 return cond.Equals(Vector<int>.AllOnes); 408 } 409 410 /// <summary> 411 /// Returns a boolean indicating whether any element in left is greater than its corresponding element in right. 412 /// </summary> 413 /// <param name="left">The first vector to compare.</param> 414 /// <param name="right">The second vector to compare.</param> 415 /// <returns>True if any elements in left are greater than their corresponding elements in right; False otherwise.</returns> 416 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 417 public static bool GreaterThanAny<T>(Vector<T> left, Vector<T> right) where T : struct 418 { 419 Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right); 420 return !cond.Equals(Vector<int>.Zero); 421 } 422 #endregion Greaterthan methods 423 424 #region Greaterthanorequal methods 425 /// <summary> 426 /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their 427 /// corresponding elements in right. 428 /// </summary> 429 /// <param name="left">The first vector to compare.</param> 430 /// <param name="right">The second vector to compare.</param> 431 /// <returns>The resultant vector.</returns> 432 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 433 public static Vector<T> GreaterThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct 434 { 435 return Vector<T>.GreaterThanOrEqual(left, right); 436 } 437 438 /// <summary> 439 /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to their 440 /// corresponding elements in right. 441 /// </summary> 442 /// <param name="left">The first vector to compare.</param> 443 /// <param name="right">The second vector to compare.</param> 444 /// <returns>The resultant integral vector.</returns> 445 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThanOrEqual(Vector<Single> left, Vector<Single> right)446 public static Vector<int> GreaterThanOrEqual(Vector<Single> left, Vector<Single> right) 447 { 448 return (Vector<int>)Vector<Single>.GreaterThanOrEqual(left, right); 449 } 450 451 /// <summary> 452 /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their 453 /// corresponding elements in right. 454 /// </summary> 455 /// <param name="left">The first vector to compare.</param> 456 /// <param name="right">The second vector to compare.</param> 457 /// <returns>The resultant vector.</returns> 458 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThanOrEqual(Vector<int> left, Vector<int> right)459 public static Vector<int> GreaterThanOrEqual(Vector<int> left, Vector<int> right) 460 { 461 return Vector<int>.GreaterThanOrEqual(left, right); 462 } 463 464 /// <summary> 465 /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their 466 /// corresponding elements in right. 467 /// </summary> 468 /// <param name="left">The first vector to compare.</param> 469 /// <param name="right">The second vector to compare.</param> 470 /// <returns>The resultant vector.</returns> 471 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThanOrEqual(Vector<long> left, Vector<long> right)472 public static Vector<long> GreaterThanOrEqual(Vector<long> left, Vector<long> right) 473 { 474 return Vector<long>.GreaterThanOrEqual(left, right); 475 } 476 477 /// <summary> 478 /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to 479 /// their corresponding elements in right. 480 /// </summary> 481 /// <param name="left">The first vector to compare.</param> 482 /// <param name="right">The second vector to compare.</param> 483 /// <returns>The resultant integral vector.</returns> 484 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] GreaterThanOrEqual(Vector<double> left, Vector<double> right)485 public static Vector<long> GreaterThanOrEqual(Vector<double> left, Vector<double> right) 486 { 487 return (Vector<long>)Vector<double>.GreaterThanOrEqual(left, right); 488 } 489 490 /// <summary> 491 /// Returns a boolean indicating whether all of the elements in left are greater than or equal to 492 /// their corresponding elements in right. 493 /// </summary> 494 /// <param name="left">The first vector to compare.</param> 495 /// <param name="right">The second vector to compare.</param> 496 /// <returns>True if all elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns> 497 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 498 public static bool GreaterThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct 499 { 500 Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right); 501 return cond.Equals(Vector<int>.AllOnes); 502 } 503 504 /// <summary> 505 /// Returns a boolean indicating whether any element in left is greater than or equal to its corresponding element in right. 506 /// </summary> 507 /// <param name="left">The first vector to compare.</param> 508 /// <param name="right">The second vector to compare.</param> 509 /// <returns>True if any elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns> 510 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 511 public static bool GreaterThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct 512 { 513 Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right); 514 return !cond.Equals(Vector<int>.Zero); 515 } 516 #endregion Greaterthanorequal methods 517 #endregion Comparison methods 518 519 #region Vector Math Methods 520 // Every operation must either be a JIT intrinsic or implemented over a JIT intrinsic 521 // as a thin wrapper 522 // Operations implemented over a JIT intrinsic should be inlined 523 // Methods that do not have a <T> type parameter are recognized as intrinsics 524 /// <summary> 525 /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support. 526 /// </summary> 527 [JitIntrinsic] 528 public static bool IsHardwareAccelerated 529 { 530 get 531 { 532 return false; 533 } 534 } 535 536 // Vector<T> 537 // Basic Math 538 // All Math operations for Vector<T> are aggressively inlined here 539 540 /// <summary> 541 /// Returns a new vector whose elements are the absolute values of the given vector's elements. 542 /// </summary> 543 /// <param name="value">The source vector.</param> 544 /// <returns>The absolute value vector.</returns> 545 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 546 public static Vector<T> Abs<T>(Vector<T> value) where T : struct 547 { 548 return Vector<T>.Abs(value); 549 } 550 551 /// <summary> 552 /// Returns a new vector whose elements are the minimum of each pair of elements in the two given vectors. 553 /// </summary> 554 /// <param name="left">The first source vector.</param> 555 /// <param name="right">The second source vector.</param> 556 /// <returns>The minimum vector.</returns> 557 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 558 public static Vector<T> Min<T>(Vector<T> left, Vector<T> right) where T : struct 559 { 560 return Vector<T>.Min(left, right); 561 } 562 563 /// <summary> 564 /// Returns a new vector whose elements are the maximum of each pair of elements in the two given vectors. 565 /// </summary> 566 /// <param name="left">The first source vector.</param> 567 /// <param name="right">The second source vector.</param> 568 /// <returns>The maximum vector.</returns> 569 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 570 public static Vector<T> Max<T>(Vector<T> left, Vector<T> right) where T : struct 571 { 572 return Vector<T>.Max(left, right); 573 } 574 575 // Specialized vector operations 576 577 /// <summary> 578 /// Returns the dot product of two vectors. 579 /// </summary> 580 /// <param name="left">The first source vector.</param> 581 /// <param name="right">The second source vector.</param> 582 /// <returns>The dot product.</returns> 583 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 584 public static T Dot<T>(Vector<T> left, Vector<T> right) where T : struct 585 { 586 return Vector<T>.DotProduct(left, right); 587 } 588 589 /// <summary> 590 /// Returns a new vector whose elements are the square roots of the given vector's elements. 591 /// </summary> 592 /// <param name="value">The source vector.</param> 593 /// <returns>The square root vector.</returns> 594 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 595 public static Vector<T> SquareRoot<T>(Vector<T> value) where T : struct 596 { 597 return Vector<T>.SquareRoot(value); 598 } 599 #endregion Vector Math Methods 600 601 #region Named Arithmetic Operators 602 /// <summary> 603 /// Creates a new vector whose values are the sum of each pair of elements from the two given vectors. 604 /// </summary> 605 /// <param name="left">The first source vector.</param> 606 /// <param name="right">The second source vector.</param> 607 /// <returns>The summed vector.</returns> 608 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 609 public static Vector<T> Add<T>(Vector<T> left, Vector<T> right) where T : struct 610 { 611 return left + right; 612 } 613 614 /// <summary> 615 /// Creates a new vector whose values are the difference between each pairs of elements in the given vectors. 616 /// </summary> 617 /// <param name="left">The first source vector.</param> 618 /// <param name="right">The second source vector.</param> 619 /// <returns>The difference vector.</returns> 620 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 621 public static Vector<T> Subtract<T>(Vector<T> left, Vector<T> right) where T : struct 622 { 623 return left - right; 624 } 625 626 /// <summary> 627 /// Creates a new vector whose values are the product of each pair of elements from the two given vectors. 628 /// </summary> 629 /// <param name="left">The first source vector.</param> 630 /// <param name="right">The second source vector.</param> 631 /// <returns>The summed vector.</returns> 632 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 633 public static Vector<T> Multiply<T>(Vector<T> left, Vector<T> right) where T : struct 634 { 635 return left * right; 636 } 637 638 /// <summary> 639 /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. 640 /// </summary> 641 /// <param name="left">The source vector.</param> 642 /// <param name="right">The scalar factor.</param> 643 /// <returns>The scaled vector.</returns> 644 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 645 public static Vector<T> Multiply<T>(Vector<T> left, T right) where T : struct 646 { 647 return left * right; 648 } 649 650 /// <summary> 651 /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. 652 /// </summary> 653 /// <param name="left">The scalar factor.</param> 654 /// <param name="right">The source vector.</param> 655 /// <returns>The scaled vector.</returns> 656 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 657 public static Vector<T> Multiply<T>(T left, Vector<T> right) where T : struct 658 { 659 return left * right; 660 } 661 662 /// <summary> 663 /// Returns a new vector whose values are the result of dividing the first vector's elements 664 /// by the corresponding elements in the second vector. 665 /// </summary> 666 /// <param name="left">The first source vector.</param> 667 /// <param name="right">The second source vector.</param> 668 /// <returns>The divided vector.</returns> 669 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 670 public static Vector<T> Divide<T>(Vector<T> left, Vector<T> right) where T : struct 671 { 672 return left / right; 673 } 674 675 /// <summary> 676 /// Returns a new vector whose elements are the given vector's elements negated. 677 /// </summary> 678 /// <param name="value">The source vector.</param> 679 /// <returns>The negated vector.</returns> 680 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 681 public static Vector<T> Negate<T>(Vector<T> value) where T : struct 682 { 683 return -value; 684 } 685 #endregion Named Arithmetic Operators 686 687 #region Named Bitwise Operators 688 /// <summary> 689 /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors. 690 /// </summary> 691 /// <param name="left">The first source vector.</param> 692 /// <param name="right">The second source vector.</param> 693 /// <returns>The resultant vector.</returns> 694 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 695 public static Vector<T> BitwiseAnd<T>(Vector<T> left, Vector<T> right) where T : struct 696 { 697 return left & right; 698 } 699 700 /// <summary> 701 /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors. 702 /// </summary> 703 /// <param name="left">The first source vector.</param> 704 /// <param name="right">The second source vector.</param> 705 /// <returns>The resultant vector.</returns> 706 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 707 public static Vector<T> BitwiseOr<T>(Vector<T> left, Vector<T> right) where T : struct 708 { 709 return left | right; 710 } 711 712 /// <summary> 713 /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements. 714 /// </summary> 715 /// <param name="value">The source vector.</param> 716 /// <returns>The one's complement vector.</returns> 717 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 718 public static Vector<T> OnesComplement<T>(Vector<T> value) where T : struct 719 { 720 return ~value; 721 } 722 723 /// <summary> 724 /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors. 725 /// </summary> 726 /// <param name="left">The first source vector.</param> 727 /// <param name="right">The second source vector.</param> 728 /// <returns>The resultant vector.</returns> 729 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 730 public static Vector<T> Xor<T>(Vector<T> left, Vector<T> right) where T : struct 731 { 732 return left ^ right; 733 } 734 735 /// <summary> 736 /// Returns a new vector by performing a bitwise-and-not operation on each of the elements in the given vectors. 737 /// </summary> 738 /// <param name="left">The first source vector.</param> 739 /// <param name="right">The second source vector.</param> 740 /// <returns>The resultant vector.</returns> 741 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 742 public static Vector<T> AndNot<T>(Vector<T> left, Vector<T> right) where T : struct 743 { 744 return left & ~right; 745 } 746 #endregion Named Bitwise Operators 747 748 #region Conversion Methods 749 /// <summary> 750 /// Reinterprets the bits of the given vector into those of a vector of unsigned bytes. 751 /// </summary> 752 /// <param name="value">The source vector</param> 753 /// <returns>The reinterpreted vector.</returns> 754 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 755 public static Vector<Byte> AsVectorByte<T>(Vector<T> value) where T : struct 756 { 757 return (Vector<Byte>)value; 758 } 759 760 /// <summary> 761 /// Reinterprets the bits of the given vector into those of a vector of signed bytes. 762 /// </summary> 763 /// <param name="value">The source vector</param> 764 /// <returns>The reinterpreted vector.</returns> 765 [CLSCompliant(false)] 766 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 767 public static Vector<SByte> AsVectorSByte<T>(Vector<T> value) where T : struct 768 { 769 return (Vector<SByte>)value; 770 } 771 772 /// <summary> 773 /// Reinterprets the bits of the given vector into those of a vector of 16-bit integers. 774 /// </summary> 775 /// <param name="value">The source vector</param> 776 /// <returns>The reinterpreted vector.</returns> 777 [CLSCompliant(false)] 778 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 779 public static Vector<UInt16> AsVectorUInt16<T>(Vector<T> value) where T : struct 780 { 781 return (Vector<UInt16>)value; 782 } 783 784 /// <summary> 785 /// Reinterprets the bits of the given vector into those of a vector of signed 16-bit integers. 786 /// </summary> 787 /// <param name="value">The source vector</param> 788 /// <returns>The reinterpreted vector.</returns> 789 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 790 public static Vector<Int16> AsVectorInt16<T>(Vector<T> value) where T : struct 791 { 792 return (Vector<Int16>)value; 793 } 794 795 /// <summary> 796 /// Reinterprets the bits of the given vector into those of a vector of unsigned 32-bit integers. 797 /// </summary> 798 /// <param name="value">The source vector</param> 799 /// <returns>The reinterpreted vector.</returns> 800 [CLSCompliant(false)] 801 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 802 public static Vector<UInt32> AsVectorUInt32<T>(Vector<T> value) where T : struct 803 { 804 return (Vector<UInt32>)value; 805 } 806 807 /// <summary> 808 /// Reinterprets the bits of the given vector into those of a vector of signed 32-bit integers. 809 /// </summary> 810 /// <param name="value">The source vector</param> 811 /// <returns>The reinterpreted vector.</returns> 812 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 813 public static Vector<Int32> AsVectorInt32<T>(Vector<T> value) where T : struct 814 { 815 return (Vector<Int32>)value; 816 } 817 818 /// <summary> 819 /// Reinterprets the bits of the given vector into those of a vector of unsigned 64-bit integers. 820 /// </summary> 821 /// <param name="value">The source vector</param> 822 /// <returns>The reinterpreted vector.</returns> 823 [CLSCompliant(false)] 824 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 825 public static Vector<UInt64> AsVectorUInt64<T>(Vector<T> value) where T : struct 826 { 827 return (Vector<UInt64>)value; 828 } 829 830 831 /// <summary> 832 /// Reinterprets the bits of the given vector into those of a vector of signed 64-bit integers. 833 /// </summary> 834 /// <param name="value">The source vector</param> 835 /// <returns>The reinterpreted vector.</returns> 836 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 837 public static Vector<Int64> AsVectorInt64<T>(Vector<T> value) where T : struct 838 { 839 return (Vector<Int64>)value; 840 } 841 842 /// <summary> 843 /// Reinterprets the bits of the given vector into those of a vector of 32-bit floating point numbers. 844 /// </summary> 845 /// <param name="value">The source vector</param> 846 /// <returns>The reinterpreted vector.</returns> 847 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 848 public static Vector<Single> AsVectorSingle<T>(Vector<T> value) where T : struct 849 { 850 return (Vector<Single>)value; 851 } 852 853 /// <summary> 854 /// Reinterprets the bits of the given vector into those of a vector of 64-bit floating point numbers. 855 /// </summary> 856 /// <param name="value">The source vector</param> 857 /// <returns>The reinterpreted vector.</returns> 858 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] 859 public static Vector<Double> AsVectorDouble<T>(Vector<T> value) where T : struct 860 { 861 return (Vector<Double>)value; 862 } 863 #endregion Conversion Methods 864 } 865 } 866