| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/base/macros.h" | 8 #include "src/base/macros.h" |
| 9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 from <= static_cast<double>(std::numeric_limits<T>::max()); | 30 from <= static_cast<double>(std::numeric_limits<T>::max()); |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 // Explicitly specialize for conversions to float, which always succeed. | 34 // Explicitly specialize for conversions to float, which always succeed. |
| 35 template <> | 35 template <> |
| 36 bool CanCast<float>(int32_t from) { | 36 bool CanCast<float>(int32_t from) { |
| 37 return true; | 37 return true; |
| 38 } | 38 } |
| 39 | 39 |
| 40 } // namespace | 40 |
| 41 template <> |
| 42 bool CanCast<float>(uint32_t from) { |
| 43 return true; |
| 44 } |
| 45 |
| 41 | 46 |
| 42 template <typename T> | 47 template <typename T> |
| 43 static T ConvertNumber(double number); | 48 static T ConvertNumber(double number); |
| 44 | 49 |
| 45 | 50 |
| 46 template <> | 51 template <> |
| 47 float ConvertNumber<float>(double number) { | 52 float ConvertNumber<float>(double number) { |
| 48 return DoubleToFloat32(number); | 53 return DoubleToFloat32(number); |
| 49 } | 54 } |
| 50 | 55 |
| 51 | 56 |
| 52 template <> | 57 template <> |
| 53 int32_t ConvertNumber<int32_t>(double number) { | 58 int32_t ConvertNumber<int32_t>(double number) { |
| 54 return DoubleToInt32(number); | 59 return DoubleToInt32(number); |
| 55 } | 60 } |
| 56 | 61 |
| 57 | 62 |
| 58 template <> | 63 template <> |
| 64 uint32_t ConvertNumber<uint32_t>(double number) { |
| 65 return DoubleToUint32(number); |
| 66 } |
| 67 |
| 68 |
| 69 template <> |
| 59 int16_t ConvertNumber<int16_t>(double number) { | 70 int16_t ConvertNumber<int16_t>(double number) { |
| 60 return static_cast<int16_t>(DoubleToInt32(number)); | 71 return static_cast<int16_t>(DoubleToInt32(number)); |
| 61 } | 72 } |
| 62 | 73 |
| 63 | 74 |
| 64 template <> | 75 template <> |
| 76 uint16_t ConvertNumber<uint16_t>(double number) { |
| 77 return static_cast<uint16_t>(DoubleToUint32(number)); |
| 78 } |
| 79 |
| 80 |
| 81 template <> |
| 65 int8_t ConvertNumber<int8_t>(double number) { | 82 int8_t ConvertNumber<int8_t>(double number) { |
| 66 return static_cast<int8_t>(DoubleToInt32(number)); | 83 return static_cast<int8_t>(DoubleToInt32(number)); |
| 67 } | 84 } |
| 68 | 85 |
| 69 | 86 |
| 87 template <> |
| 88 uint8_t ConvertNumber<uint8_t>(double number) { |
| 89 return static_cast<uint8_t>(DoubleToUint32(number)); |
| 90 } |
| 91 |
| 92 |
| 70 // TODO(bbudge): Make this consistent with SIMD instruction results. | 93 // TODO(bbudge): Make this consistent with SIMD instruction results. |
| 71 inline float RecipApprox(float a) { return 1.0f / a; } | 94 inline float RecipApprox(float a) { return 1.0f / a; } |
| 72 | 95 |
| 73 | 96 |
| 74 // TODO(bbudge): Make this consistent with SIMD instruction results. | 97 // TODO(bbudge): Make this consistent with SIMD instruction results. |
| 75 inline float RecipSqrtApprox(float a) { return 1.0f / std::sqrt(a); } | 98 inline float RecipSqrtApprox(float a) { return 1.0f / std::sqrt(a); } |
| 76 | 99 |
| 77 | 100 |
| 78 // Saturating addition for int16_t and int8_t. | 101 // Saturating addition for int16_t and int8_t. |
| 79 template <typename T> | 102 template <typename T> |
| 80 inline T AddSaturate(T a, T b) { | 103 inline T AddSaturate(T a, T b) { |
| 81 const T max = std::numeric_limits<T>::max(); | 104 const T max = std::numeric_limits<T>::max(); |
| 82 const T min = std::numeric_limits<T>::min(); | 105 const T min = std::numeric_limits<T>::min(); |
| 83 int32_t result = a + b; | 106 int32_t result = a + b; |
| 84 if (result > max) return max; | 107 if (result > max) return max; |
| 85 if (result < min) return min; | 108 if (result < min) return min; |
| 86 return result; | 109 return result; |
| 87 } | 110 } |
| 88 | 111 |
| 89 | 112 |
| 113 // Widening absolute difference for uint16_t and uint8_t. |
| 114 template <typename T> |
| 115 inline uint32_t AbsoluteDifference(T a, T b) { |
| 116 uint32_t result = std::abs(a - b); |
| 117 return result; |
| 118 } |
| 119 |
| 120 |
| 90 // Saturating subtraction for int16_t and int8_t. | 121 // Saturating subtraction for int16_t and int8_t. |
| 91 template <typename T> | 122 template <typename T> |
| 92 inline T SubSaturate(T a, T b) { | 123 inline T SubSaturate(T a, T b) { |
| 93 const T max = std::numeric_limits<T>::max(); | 124 const T max = std::numeric_limits<T>::max(); |
| 94 const T min = std::numeric_limits<T>::min(); | 125 const T min = std::numeric_limits<T>::min(); |
| 95 int32_t result = a - b; | 126 int32_t result = a - b; |
| 96 if (result > max) return max; | 127 if (result > max) return max; |
| 97 if (result < min) return min; | 128 if (result < min) return min; |
| 98 return result; | 129 return result; |
| 99 } | 130 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 121 return Min(a, b); | 152 return Min(a, b); |
| 122 } | 153 } |
| 123 | 154 |
| 124 | 155 |
| 125 inline float MaxNumber(float a, float b) { | 156 inline float MaxNumber(float a, float b) { |
| 126 if (std::isnan(a)) return b; | 157 if (std::isnan(a)) return b; |
| 127 if (std::isnan(b)) return a; | 158 if (std::isnan(b)) return a; |
| 128 return Max(a, b); | 159 return Max(a, b); |
| 129 } | 160 } |
| 130 | 161 |
| 162 } // namespace |
| 131 | 163 |
| 132 //------------------------------------------------------------------- | 164 //------------------------------------------------------------------- |
| 133 | 165 |
| 134 // SIMD helper functions. | 166 // SIMD helper functions. |
| 135 | 167 |
| 136 RUNTIME_FUNCTION(Runtime_IsSimdValue) { | 168 RUNTIME_FUNCTION(Runtime_IsSimdValue) { |
| 137 HandleScope scope(isolate); | 169 HandleScope scope(isolate); |
| 138 DCHECK(args.length() == 1); | 170 DCHECK(args.length() == 1); |
| 139 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); | 171 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); |
| 140 } | 172 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 273 |
| 242 // Common functions. | 274 // Common functions. |
| 243 | 275 |
| 244 #define GET_NUMERIC_ARG(lane_type, name, index) \ | 276 #define GET_NUMERIC_ARG(lane_type, name, index) \ |
| 245 CONVERT_NUMBER_ARG_HANDLE_CHECKED(a, index); \ | 277 CONVERT_NUMBER_ARG_HANDLE_CHECKED(a, index); \ |
| 246 name = ConvertNumber<lane_type>(a->Number()); | 278 name = ConvertNumber<lane_type>(a->Number()); |
| 247 | 279 |
| 248 #define GET_BOOLEAN_ARG(lane_type, name, index) \ | 280 #define GET_BOOLEAN_ARG(lane_type, name, index) \ |
| 249 name = args[index]->BooleanValue(); | 281 name = args[index]->BooleanValue(); |
| 250 | 282 |
| 251 #define SIMD_ALL_TYPES(FUNCTION) \ | 283 #define SIMD_ALL_TYPES(FUNCTION) \ |
| 252 FUNCTION(Float32x4, float, 4, NewNumber, GET_NUMERIC_ARG) \ | 284 FUNCTION(Float32x4, float, 4, NewNumber, GET_NUMERIC_ARG) \ |
| 253 FUNCTION(Int32x4, int32_t, 4, NewNumber, GET_NUMERIC_ARG) \ | 285 FUNCTION(Int32x4, int32_t, 4, NewNumber, GET_NUMERIC_ARG) \ |
| 254 FUNCTION(Bool32x4, bool, 4, ToBoolean, GET_BOOLEAN_ARG) \ | 286 FUNCTION(Uint32x4, uint32_t, 4, NewNumber, GET_NUMERIC_ARG) \ |
| 255 FUNCTION(Int16x8, int16_t, 8, NewNumber, GET_NUMERIC_ARG) \ | 287 FUNCTION(Bool32x4, bool, 4, ToBoolean, GET_BOOLEAN_ARG) \ |
| 256 FUNCTION(Bool16x8, bool, 8, ToBoolean, GET_BOOLEAN_ARG) \ | 288 FUNCTION(Int16x8, int16_t, 8, NewNumber, GET_NUMERIC_ARG) \ |
| 257 FUNCTION(Int8x16, int8_t, 16, NewNumber, GET_NUMERIC_ARG) \ | 289 FUNCTION(Uint16x8, uint16_t, 8, NewNumber, GET_NUMERIC_ARG) \ |
| 290 FUNCTION(Bool16x8, bool, 8, ToBoolean, GET_BOOLEAN_ARG) \ |
| 291 FUNCTION(Int8x16, int8_t, 16, NewNumber, GET_NUMERIC_ARG) \ |
| 292 FUNCTION(Uint8x16, uint8_t, 16, NewNumber, GET_NUMERIC_ARG) \ |
| 258 FUNCTION(Bool8x16, bool, 16, ToBoolean, GET_BOOLEAN_ARG) | 293 FUNCTION(Bool8x16, bool, 16, ToBoolean, GET_BOOLEAN_ARG) |
| 259 | 294 |
| 260 #define SIMD_CREATE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 295 #define SIMD_CREATE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
| 261 RUNTIME_FUNCTION(Runtime_Create##type) { \ | 296 RUNTIME_FUNCTION(Runtime_Create##type) { \ |
| 262 static const int kLaneCount = lane_count; \ | 297 static const int kLaneCount = lane_count; \ |
| 263 HandleScope scope(isolate); \ | 298 HandleScope scope(isolate); \ |
| 264 DCHECK(args.length() == kLaneCount); \ | 299 DCHECK(args.length() == kLaneCount); \ |
| 265 lane_type lanes[kLaneCount]; \ | 300 lane_type lanes[kLaneCount]; \ |
| 266 for (int i = 0; i < kLaneCount; i++) { \ | 301 for (int i = 0; i < kLaneCount; i++) { \ |
| 267 replace(lane_type, lanes[i], i) \ | 302 replace(lane_type, lanes[i], i) \ |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 439 |
| 405 //------------------------------------------------------------------- | 440 //------------------------------------------------------------------- |
| 406 | 441 |
| 407 // Int-only functions. | 442 // Int-only functions. |
| 408 | 443 |
| 409 #define SIMD_INT_TYPES(FUNCTION) \ | 444 #define SIMD_INT_TYPES(FUNCTION) \ |
| 410 FUNCTION(Int32x4, int32_t, 32, 4) \ | 445 FUNCTION(Int32x4, int32_t, 32, 4) \ |
| 411 FUNCTION(Int16x8, int16_t, 16, 8) \ | 446 FUNCTION(Int16x8, int16_t, 16, 8) \ |
| 412 FUNCTION(Int8x16, int8_t, 8, 16) | 447 FUNCTION(Int8x16, int8_t, 8, 16) |
| 413 | 448 |
| 449 #define SIMD_UINT_TYPES(FUNCTION) \ |
| 450 FUNCTION(Uint32x4, uint32_t, 32, 4) \ |
| 451 FUNCTION(Uint16x8, uint16_t, 16, 8) \ |
| 452 FUNCTION(Uint8x16, uint8_t, 8, 16) |
| 453 |
| 414 #define CONVERT_SHIFT_ARG_CHECKED(name, index) \ | 454 #define CONVERT_SHIFT_ARG_CHECKED(name, index) \ |
| 415 RUNTIME_ASSERT(args[index]->IsNumber()); \ | 455 RUNTIME_ASSERT(args[index]->IsNumber()); \ |
| 416 int32_t signed_shift = 0; \ | 456 int32_t signed_shift = 0; \ |
| 417 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ | 457 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ |
| 418 uint32_t name = bit_cast<uint32_t>(signed_shift); | 458 uint32_t name = bit_cast<uint32_t>(signed_shift); |
| 419 | 459 |
| 420 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 460 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
| 421 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ | 461 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ |
| 422 static const int kLaneCount = lane_count; \ | 462 static const int kLaneCount = lane_count; \ |
| 423 HandleScope scope(isolate); \ | 463 HandleScope scope(isolate); \ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 438 RUNTIME_FUNCTION(Runtime_##type##ShiftRightLogicalByScalar) { \ | 478 RUNTIME_FUNCTION(Runtime_##type##ShiftRightLogicalByScalar) { \ |
| 439 static const int kLaneCount = lane_count; \ | 479 static const int kLaneCount = lane_count; \ |
| 440 HandleScope scope(isolate); \ | 480 HandleScope scope(isolate); \ |
| 441 DCHECK(args.length() == 2); \ | 481 DCHECK(args.length() == 2); \ |
| 442 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 482 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
| 443 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 483 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
| 444 lane_type lanes[kLaneCount] = {0}; \ | 484 lane_type lanes[kLaneCount] = {0}; \ |
| 445 if (shift < lane_bits) { \ | 485 if (shift < lane_bits) { \ |
| 446 for (int i = 0; i < kLaneCount; i++) { \ | 486 for (int i = 0; i < kLaneCount; i++) { \ |
| 447 lanes[i] = static_cast<lane_type>( \ | 487 lanes[i] = static_cast<lane_type>( \ |
| 448 bit_cast<u##lane_type>(a->get_lane(i)) >> shift); \ | 488 bit_cast<lane_type>(a->get_lane(i)) >> shift); \ |
| 449 } \ | 489 } \ |
| 450 } \ | 490 } \ |
| 451 Handle<type> result = isolate->factory()->New##type(lanes); \ | 491 Handle<type> result = isolate->factory()->New##type(lanes); \ |
| 452 return *result; \ | 492 return *result; \ |
| 453 } | 493 } |
| 454 | 494 |
| 455 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 495 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
| 456 RUNTIME_FUNCTION(Runtime_##type##ShiftRightArithmeticByScalar) { \ | 496 RUNTIME_FUNCTION(Runtime_##type##ShiftRightArithmeticByScalar) { \ |
| 457 static const int kLaneCount = lane_count; \ | 497 static const int kLaneCount = lane_count; \ |
| 458 HandleScope scope(isolate); \ | 498 HandleScope scope(isolate); \ |
| 459 DCHECK(args.length() == 2); \ | 499 DCHECK(args.length() == 2); \ |
| 460 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 500 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
| 461 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 501 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
| 462 if (shift >= lane_bits) shift = lane_bits - 1; \ | 502 if (shift >= lane_bits) shift = lane_bits - 1; \ |
| 463 lane_type lanes[kLaneCount]; \ | 503 lane_type lanes[kLaneCount]; \ |
| 464 for (int i = 0; i < kLaneCount; i++) { \ | 504 for (int i = 0; i < kLaneCount; i++) { \ |
| 465 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ | 505 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ |
| 466 lanes[i] = static_cast<lane_type>(shifted); \ | 506 lanes[i] = static_cast<lane_type>(shifted); \ |
| 467 } \ | 507 } \ |
| 468 Handle<type> result = isolate->factory()->New##type(lanes); \ | 508 Handle<type> result = isolate->factory()->New##type(lanes); \ |
| 469 return *result; \ | 509 return *result; \ |
| 470 } | 510 } |
| 471 | 511 |
| 512 #define SIMD_HORIZONTAL_SUM_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
| 513 RUNTIME_FUNCTION(Runtime_##type##HorizontalSum) { \ |
| 514 HandleScope scope(isolate); \ |
| 515 DCHECK(args.length() == 1); \ |
| 516 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
| 517 double sum = 0; \ |
| 518 for (int i = 0; i < lane_count; i++) { \ |
| 519 sum += a->get_lane(i); \ |
| 520 } \ |
| 521 return *isolate->factory()->NewNumber(sum); \ |
| 522 } |
| 523 |
| 472 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) | 524 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) |
| 473 SIMD_INT_TYPES(SIMD_LSR_FUNCTION) | 525 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) |
| 474 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) | 526 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) |
| 527 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) |
| 528 SIMD_UINT_TYPES(SIMD_HORIZONTAL_SUM_FUNCTION) |
| 475 | 529 |
| 476 //------------------------------------------------------------------- | 530 //------------------------------------------------------------------- |
| 477 | 531 |
| 478 // Bool-only functions. | 532 // Bool-only functions. |
| 479 | 533 |
| 480 #define SIMD_BOOL_TYPES(FUNCTION) \ | 534 #define SIMD_BOOL_TYPES(FUNCTION) \ |
| 481 FUNCTION(Bool32x4, 4) \ | 535 FUNCTION(Bool32x4, 4) \ |
| 482 FUNCTION(Bool16x8, 8) \ | 536 FUNCTION(Bool16x8, 8) \ |
| 483 FUNCTION(Bool8x16, 16) | 537 FUNCTION(Bool8x16, 16) |
| 484 | 538 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 514 | 568 |
| 515 SIMD_BOOL_TYPES(SIMD_ANY_FUNCTION) | 569 SIMD_BOOL_TYPES(SIMD_ANY_FUNCTION) |
| 516 SIMD_BOOL_TYPES(SIMD_ALL_FUNCTION) | 570 SIMD_BOOL_TYPES(SIMD_ALL_FUNCTION) |
| 517 | 571 |
| 518 //------------------------------------------------------------------- | 572 //------------------------------------------------------------------- |
| 519 | 573 |
| 520 // Small Int-only functions. | 574 // Small Int-only functions. |
| 521 | 575 |
| 522 #define SIMD_SMALL_INT_TYPES(FUNCTION) \ | 576 #define SIMD_SMALL_INT_TYPES(FUNCTION) \ |
| 523 FUNCTION(Int16x8, int16_t, 8) \ | 577 FUNCTION(Int16x8, int16_t, 8) \ |
| 524 FUNCTION(Int8x16, int8_t, 16) | 578 FUNCTION(Uint16x8, uint16_t, 8) \ |
| 579 FUNCTION(Int8x16, int8_t, 16) \ |
| 580 FUNCTION(Uint8x16, uint8_t, 16) |
| 525 | 581 |
| 526 #define SIMD_ADD_SATURATE_FUNCTION(type, lane_type, lane_count) \ | 582 #define SIMD_ADD_SATURATE_FUNCTION(type, lane_type, lane_count) \ |
| 527 RUNTIME_FUNCTION(Runtime_##type##AddSaturate) { \ | 583 RUNTIME_FUNCTION(Runtime_##type##AddSaturate) { \ |
| 528 HandleScope scope(isolate); \ | 584 HandleScope scope(isolate); \ |
| 529 SIMD_BINARY_OP(type, lane_type, lane_count, AddSaturate, result); \ | 585 SIMD_BINARY_OP(type, lane_type, lane_count, AddSaturate, result); \ |
| 530 return *result; \ | 586 return *result; \ |
| 531 } | 587 } |
| 532 | 588 |
| 533 #define BINARY_SUB(a, b) (a) - (b) | 589 #define BINARY_SUB(a, b) (a) - (b) |
| 534 #define SIMD_SUB_SATURATE_FUNCTION(type, lane_type, lane_count) \ | 590 #define SIMD_SUB_SATURATE_FUNCTION(type, lane_type, lane_count) \ |
| 535 RUNTIME_FUNCTION(Runtime_##type##SubSaturate) { \ | 591 RUNTIME_FUNCTION(Runtime_##type##SubSaturate) { \ |
| 536 HandleScope scope(isolate); \ | 592 HandleScope scope(isolate); \ |
| 537 SIMD_BINARY_OP(type, lane_type, lane_count, SubSaturate, result); \ | 593 SIMD_BINARY_OP(type, lane_type, lane_count, SubSaturate, result); \ |
| 538 return *result; \ | 594 return *result; \ |
| 539 } | 595 } |
| 540 | 596 |
| 541 SIMD_SMALL_INT_TYPES(SIMD_ADD_SATURATE_FUNCTION) | 597 SIMD_SMALL_INT_TYPES(SIMD_ADD_SATURATE_FUNCTION) |
| 542 SIMD_SMALL_INT_TYPES(SIMD_SUB_SATURATE_FUNCTION) | 598 SIMD_SMALL_INT_TYPES(SIMD_SUB_SATURATE_FUNCTION) |
| 543 | 599 |
| 544 //------------------------------------------------------------------- | 600 //------------------------------------------------------------------- |
| 545 | 601 |
| 602 // Small Unsigned int-only functions. |
| 603 |
| 604 #define SIMD_SMALL_UINT_TYPES(FUNCTION) \ |
| 605 FUNCTION(Uint16x8, uint16_t, 8, Uint32x4, uint32_t) \ |
| 606 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8, uint16_t) |
| 607 |
| 608 #define SIMD_ABS_DIFF_FUNCTION(type, lane_type, lane_count, wide_type, \ |
| 609 wide_ctype) \ |
| 610 RUNTIME_FUNCTION(Runtime_##type##AbsoluteDifference) { \ |
| 611 HandleScope scope(isolate); \ |
| 612 SIMD_BINARY_OP(type, lane_type, lane_count, AbsoluteDifference, result); \ |
| 613 return *result; \ |
| 614 } |
| 615 |
| 616 #define SIMD_WIDE_ABS_DIFF_FUNCTION(type, lane_type, lane_count, wide_type, \ |
| 617 wide_ctype) \ |
| 618 RUNTIME_FUNCTION(Runtime_##type##WidenedAbsoluteDifference) { \ |
| 619 HandleScope scope(isolate); \ |
| 620 static const int kLaneCount = lane_count / 2; \ |
| 621 DCHECK(args.length() == 2); \ |
| 622 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
| 623 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ |
| 624 wide_ctype lanes[kLaneCount]; \ |
| 625 for (int i = 0; i < kLaneCount; i++) { \ |
| 626 lanes[i] = AbsoluteDifference(a->get_lane(i), b->get_lane(i)); \ |
| 627 } \ |
| 628 Handle<wide_type> result = isolate->factory()->New##wide_type(lanes); \ |
| 629 return *result; \ |
| 630 } |
| 631 |
| 632 SIMD_SMALL_UINT_TYPES(SIMD_ABS_DIFF_FUNCTION) |
| 633 SIMD_SMALL_UINT_TYPES(SIMD_WIDE_ABS_DIFF_FUNCTION) |
| 634 |
| 635 //------------------------------------------------------------------- |
| 636 |
| 546 // Numeric functions. | 637 // Numeric functions. |
| 547 | 638 |
| 548 #define SIMD_NUMERIC_TYPES(FUNCTION) \ | 639 #define SIMD_NUMERIC_TYPES(FUNCTION) \ |
| 549 FUNCTION(Float32x4, float, 4) \ | 640 FUNCTION(Float32x4, float, 4) \ |
| 550 FUNCTION(Int32x4, int32_t, 4) \ | 641 FUNCTION(Int32x4, int32_t, 4) \ |
| 642 FUNCTION(Uint32x4, uint32_t, 4) \ |
| 551 FUNCTION(Int16x8, int16_t, 8) \ | 643 FUNCTION(Int16x8, int16_t, 8) \ |
| 552 FUNCTION(Int8x16, int8_t, 16) | 644 FUNCTION(Uint16x8, uint16_t, 8) \ |
| 553 | 645 FUNCTION(Int8x16, int8_t, 16) \ |
| 554 #define SIMD_NEG_FUNCTION(type, lane_type, lane_count) \ | 646 FUNCTION(Uint8x16, uint8_t, 16) |
| 555 RUNTIME_FUNCTION(Runtime_##type##Neg) { \ | |
| 556 HandleScope scope(isolate); \ | |
| 557 SIMD_UNARY_OP(type, lane_type, lane_count, -, result); \ | |
| 558 return *result; \ | |
| 559 } | |
| 560 | 647 |
| 561 #define BINARY_ADD(a, b) (a) + (b) | 648 #define BINARY_ADD(a, b) (a) + (b) |
| 562 #define SIMD_ADD_FUNCTION(type, lane_type, lane_count) \ | 649 #define SIMD_ADD_FUNCTION(type, lane_type, lane_count) \ |
| 563 RUNTIME_FUNCTION(Runtime_##type##Add) { \ | 650 RUNTIME_FUNCTION(Runtime_##type##Add) { \ |
| 564 HandleScope scope(isolate); \ | 651 HandleScope scope(isolate); \ |
| 565 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_ADD, result); \ | 652 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_ADD, result); \ |
| 566 return *result; \ | 653 return *result; \ |
| 567 } | 654 } |
| 568 | 655 |
| 569 #define BINARY_SUB(a, b) (a) - (b) | 656 #define BINARY_SUB(a, b) (a) - (b) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 589 return *result; \ | 676 return *result; \ |
| 590 } | 677 } |
| 591 | 678 |
| 592 #define SIMD_MAX_FUNCTION(type, lane_type, lane_count) \ | 679 #define SIMD_MAX_FUNCTION(type, lane_type, lane_count) \ |
| 593 RUNTIME_FUNCTION(Runtime_##type##Max) { \ | 680 RUNTIME_FUNCTION(Runtime_##type##Max) { \ |
| 594 HandleScope scope(isolate); \ | 681 HandleScope scope(isolate); \ |
| 595 SIMD_BINARY_OP(type, lane_type, lane_count, Max, result); \ | 682 SIMD_BINARY_OP(type, lane_type, lane_count, Max, result); \ |
| 596 return *result; \ | 683 return *result; \ |
| 597 } | 684 } |
| 598 | 685 |
| 599 SIMD_NUMERIC_TYPES(SIMD_NEG_FUNCTION) | |
| 600 SIMD_NUMERIC_TYPES(SIMD_ADD_FUNCTION) | 686 SIMD_NUMERIC_TYPES(SIMD_ADD_FUNCTION) |
| 601 SIMD_NUMERIC_TYPES(SIMD_SUB_FUNCTION) | 687 SIMD_NUMERIC_TYPES(SIMD_SUB_FUNCTION) |
| 602 SIMD_NUMERIC_TYPES(SIMD_MUL_FUNCTION) | 688 SIMD_NUMERIC_TYPES(SIMD_MUL_FUNCTION) |
| 603 SIMD_NUMERIC_TYPES(SIMD_MIN_FUNCTION) | 689 SIMD_NUMERIC_TYPES(SIMD_MIN_FUNCTION) |
| 604 SIMD_NUMERIC_TYPES(SIMD_MAX_FUNCTION) | 690 SIMD_NUMERIC_TYPES(SIMD_MAX_FUNCTION) |
| 605 | 691 |
| 606 //------------------------------------------------------------------- | 692 //------------------------------------------------------------------- |
| 607 | 693 |
| 608 // Relational functions. | 694 // Relational functions. |
| 609 | 695 |
| 610 #define SIMD_RELATIONAL_TYPES(FUNCTION) \ | 696 #define SIMD_RELATIONAL_TYPES(FUNCTION) \ |
| 611 FUNCTION(Float32x4, Bool32x4, 4) \ | 697 FUNCTION(Float32x4, Bool32x4, 4) \ |
| 612 FUNCTION(Int32x4, Bool32x4, 4) \ | 698 FUNCTION(Int32x4, Bool32x4, 4) \ |
| 699 FUNCTION(Uint32x4, Bool32x4, 4) \ |
| 613 FUNCTION(Int16x8, Bool16x8, 8) \ | 700 FUNCTION(Int16x8, Bool16x8, 8) \ |
| 614 FUNCTION(Int8x16, Bool8x16, 16) | 701 FUNCTION(Uint16x8, Bool16x8, 8) \ |
| 702 FUNCTION(Int8x16, Bool8x16, 16) \ |
| 703 FUNCTION(Uint8x16, Bool8x16, 16) |
| 615 | 704 |
| 616 #define SIMD_EQUALITY_TYPES(FUNCTION) \ | 705 #define SIMD_EQUALITY_TYPES(FUNCTION) \ |
| 617 SIMD_RELATIONAL_TYPES(FUNCTION) \ | 706 SIMD_RELATIONAL_TYPES(FUNCTION) \ |
| 618 FUNCTION(Bool32x4, Bool32x4, 4) \ | 707 FUNCTION(Bool32x4, Bool32x4, 4) \ |
| 619 FUNCTION(Bool16x8, Bool16x8, 8) \ | 708 FUNCTION(Bool16x8, Bool16x8, 8) \ |
| 620 FUNCTION(Bool8x16, Bool8x16, 16) | 709 FUNCTION(Bool8x16, Bool8x16, 16) |
| 621 | 710 |
| 622 #define SIMD_EQUAL_FUNCTION(type, bool_type, lane_count) \ | 711 #define SIMD_EQUAL_FUNCTION(type, bool_type, lane_count) \ |
| 623 RUNTIME_FUNCTION(Runtime_##type##Equal) { \ | 712 RUNTIME_FUNCTION(Runtime_##type##Equal) { \ |
| 624 HandleScope scope(isolate); \ | 713 HandleScope scope(isolate); \ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 | 755 |
| 667 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_FUNCTION) | 756 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_FUNCTION) |
| 668 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_OR_EQUAL_FUNCTION) | 757 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_OR_EQUAL_FUNCTION) |
| 669 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_FUNCTION) | 758 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_FUNCTION) |
| 670 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_OR_EQUAL_FUNCTION) | 759 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_OR_EQUAL_FUNCTION) |
| 671 | 760 |
| 672 //------------------------------------------------------------------- | 761 //------------------------------------------------------------------- |
| 673 | 762 |
| 674 // Logical functions. | 763 // Logical functions. |
| 675 | 764 |
| 676 #define SIMD_LOGICAL_TYPES(FUNCTION) \ | 765 #define SIMD_LOGICAL_TYPES(FUNCTION) \ |
| 677 FUNCTION(Int32x4, int32_t, 4, _INT) \ | 766 FUNCTION(Int32x4, int32_t, 4, _INT) \ |
| 678 FUNCTION(Int16x8, int16_t, 8, _INT) \ | 767 FUNCTION(Uint32x4, uint32_t, 4, _INT) \ |
| 679 FUNCTION(Int8x16, int8_t, 16, _INT) \ | 768 FUNCTION(Int16x8, int16_t, 8, _INT) \ |
| 680 FUNCTION(Bool32x4, bool, 4, _BOOL) \ | 769 FUNCTION(Uint16x8, uint16_t, 8, _INT) \ |
| 681 FUNCTION(Bool16x8, bool, 8, _BOOL) \ | 770 FUNCTION(Int8x16, int8_t, 16, _INT) \ |
| 771 FUNCTION(Uint8x16, uint8_t, 16, _INT) \ |
| 772 FUNCTION(Bool32x4, bool, 4, _BOOL) \ |
| 773 FUNCTION(Bool16x8, bool, 8, _BOOL) \ |
| 682 FUNCTION(Bool8x16, bool, 16, _BOOL) | 774 FUNCTION(Bool8x16, bool, 16, _BOOL) |
| 683 | 775 |
| 684 #define BINARY_AND_INT(a, b) (a) & (b) | 776 #define BINARY_AND_INT(a, b) (a) & (b) |
| 685 #define BINARY_AND_BOOL(a, b) (a) && (b) | 777 #define BINARY_AND_BOOL(a, b) (a) && (b) |
| 686 #define SIMD_AND_FUNCTION(type, lane_type, lane_count, op) \ | 778 #define SIMD_AND_FUNCTION(type, lane_type, lane_count, op) \ |
| 687 RUNTIME_FUNCTION(Runtime_##type##And) { \ | 779 RUNTIME_FUNCTION(Runtime_##type##And) { \ |
| 688 HandleScope scope(isolate); \ | 780 HandleScope scope(isolate); \ |
| 689 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_AND##op, result); \ | 781 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_AND##op, result); \ |
| 690 return *result; \ | 782 return *result; \ |
| 691 } | 783 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 719 | 811 |
| 720 SIMD_LOGICAL_TYPES(SIMD_AND_FUNCTION) | 812 SIMD_LOGICAL_TYPES(SIMD_AND_FUNCTION) |
| 721 SIMD_LOGICAL_TYPES(SIMD_OR_FUNCTION) | 813 SIMD_LOGICAL_TYPES(SIMD_OR_FUNCTION) |
| 722 SIMD_LOGICAL_TYPES(SIMD_XOR_FUNCTION) | 814 SIMD_LOGICAL_TYPES(SIMD_XOR_FUNCTION) |
| 723 SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) | 815 SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) |
| 724 | 816 |
| 725 //------------------------------------------------------------------- | 817 //------------------------------------------------------------------- |
| 726 | 818 |
| 727 // Select functions. | 819 // Select functions. |
| 728 | 820 |
| 729 #define SIMD_SELECT_TYPES(FUNCTION) \ | 821 #define SIMD_SELECT_TYPES(FUNCTION) \ |
| 730 FUNCTION(Float32x4, float, Bool32x4, 4) \ | 822 FUNCTION(Float32x4, float, Bool32x4, 4) \ |
| 731 FUNCTION(Int32x4, int32_t, Bool32x4, 4) \ | 823 FUNCTION(Int32x4, int32_t, Bool32x4, 4) \ |
| 732 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ | 824 FUNCTION(Uint32x4, uint32_t, Bool32x4, 4) \ |
| 733 FUNCTION(Int8x16, int8_t, Bool8x16, 16) | 825 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ |
| 826 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ |
| 827 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ |
| 828 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) |
| 734 | 829 |
| 735 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ | 830 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ |
| 736 RUNTIME_FUNCTION(Runtime_##type##Select) { \ | 831 RUNTIME_FUNCTION(Runtime_##type##Select) { \ |
| 737 static const int kLaneCount = lane_count; \ | 832 static const int kLaneCount = lane_count; \ |
| 738 HandleScope scope(isolate); \ | 833 HandleScope scope(isolate); \ |
| 739 DCHECK(args.length() == 3); \ | 834 DCHECK(args.length() == 3); \ |
| 740 CONVERT_ARG_HANDLE_CHECKED(bool_type, mask, 0); \ | 835 CONVERT_ARG_HANDLE_CHECKED(bool_type, mask, 0); \ |
| 741 CONVERT_ARG_HANDLE_CHECKED(type, a, 1); \ | 836 CONVERT_ARG_HANDLE_CHECKED(type, a, 1); \ |
| 742 CONVERT_ARG_HANDLE_CHECKED(type, b, 2); \ | 837 CONVERT_ARG_HANDLE_CHECKED(type, b, 2); \ |
| 743 lane_type lanes[kLaneCount]; \ | 838 lane_type lanes[kLaneCount]; \ |
| 744 for (int i = 0; i < kLaneCount; i++) { \ | 839 for (int i = 0; i < kLaneCount; i++) { \ |
| 745 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ | 840 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ |
| 746 } \ | 841 } \ |
| 747 Handle<type> result = isolate->factory()->New##type(lanes); \ | 842 Handle<type> result = isolate->factory()->New##type(lanes); \ |
| 748 return *result; \ | 843 return *result; \ |
| 749 } | 844 } |
| 750 | 845 |
| 751 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) | 846 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) |
| 752 | 847 |
| 753 //------------------------------------------------------------------- | 848 //------------------------------------------------------------------- |
| 754 | 849 |
| 850 // Signed / unsigned functions. |
| 851 |
| 852 #define SIMD_SIGNED_TYPES(FUNCTION) \ |
| 853 FUNCTION(Float32x4, float, 4) \ |
| 854 FUNCTION(Int32x4, int32_t, 4) \ |
| 855 FUNCTION(Int16x8, int16_t, 8) \ |
| 856 FUNCTION(Int8x16, int8_t, 16) |
| 857 |
| 858 #define SIMD_NEG_FUNCTION(type, lane_type, lane_count) \ |
| 859 RUNTIME_FUNCTION(Runtime_##type##Neg) { \ |
| 860 HandleScope scope(isolate); \ |
| 861 SIMD_UNARY_OP(type, lane_type, lane_count, -, result); \ |
| 862 return *result; \ |
| 863 } |
| 864 |
| 865 SIMD_SIGNED_TYPES(SIMD_NEG_FUNCTION) |
| 866 |
| 867 //------------------------------------------------------------------- |
| 868 |
| 755 // Casting functions. | 869 // Casting functions. |
| 756 | 870 |
| 757 #define SIMD_FROM_TYPES(FUNCTION) \ | 871 #define SIMD_FROM_TYPES(FUNCTION) \ |
| 758 FUNCTION(Float32x4, float, 4, Int32x4, int32_t) \ | 872 FUNCTION(Float32x4, float, 4, Int32x4, int32_t) \ |
| 759 FUNCTION(Int32x4, int32_t, 4, Float32x4, float) | 873 FUNCTION(Float32x4, float, 4, Uint32x4, uint32_t) \ |
| 874 FUNCTION(Int32x4, int32_t, 4, Float32x4, float) \ |
| 875 FUNCTION(Int32x4, int32_t, 4, Uint32x4, uint32_t) \ |
| 876 FUNCTION(Uint32x4, uint32_t, 4, Float32x4, float) \ |
| 877 FUNCTION(Uint32x4, uint32_t, 4, Int32x4, int32_t) \ |
| 878 FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ |
| 879 FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ |
| 880 FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ |
| 881 FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) |
| 760 | 882 |
| 761 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ | 883 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ |
| 762 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ | 884 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ |
| 763 static const int kLaneCount = lane_count; \ | 885 static const int kLaneCount = lane_count; \ |
| 764 HandleScope scope(isolate); \ | 886 HandleScope scope(isolate); \ |
| 765 DCHECK(args.length() == 1); \ | 887 DCHECK(args.length() == 1); \ |
| 766 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 888 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ |
| 767 lane_type lanes[kLaneCount]; \ | 889 lane_type lanes[kLaneCount]; \ |
| 768 for (int i = 0; i < kLaneCount; i++) { \ | 890 for (int i = 0; i < kLaneCount; i++) { \ |
| 769 from_ctype a_value = a->get_lane(i); \ | 891 from_ctype a_value = a->get_lane(i); \ |
| 892 if (a_value != a_value) a_value = 0; \ |
| 770 RUNTIME_ASSERT(CanCast<lane_type>(a_value)); \ | 893 RUNTIME_ASSERT(CanCast<lane_type>(a_value)); \ |
| 771 lanes[i] = static_cast<lane_type>(a_value); \ | 894 lanes[i] = static_cast<lane_type>(a_value); \ |
| 772 } \ | 895 } \ |
| 773 Handle<type> result = isolate->factory()->New##type(lanes); \ | 896 Handle<type> result = isolate->factory()->New##type(lanes); \ |
| 774 return *result; \ | 897 return *result; \ |
| 775 } | 898 } |
| 776 | 899 |
| 777 SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) | 900 SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) |
| 778 | 901 |
| 779 #define SIMD_FROM_BITS_TYPES(FUNCTION) \ | 902 #define SIMD_FROM_BITS_TYPES(FUNCTION) \ |
| 780 FUNCTION(Float32x4, float, 4, Int32x4) \ | 903 FUNCTION(Float32x4, float, 4, Int32x4) \ |
| 781 FUNCTION(Float32x4, float, 4, Int16x8) \ | 904 FUNCTION(Float32x4, float, 4, Uint32x4) \ |
| 782 FUNCTION(Float32x4, float, 4, Int8x16) \ | 905 FUNCTION(Float32x4, float, 4, Int16x8) \ |
| 783 FUNCTION(Int32x4, int32_t, 4, Float32x4) \ | 906 FUNCTION(Float32x4, float, 4, Uint16x8) \ |
| 784 FUNCTION(Int32x4, int32_t, 4, Int16x8) \ | 907 FUNCTION(Float32x4, float, 4, Int8x16) \ |
| 785 FUNCTION(Int32x4, int32_t, 4, Int8x16) \ | 908 FUNCTION(Float32x4, float, 4, Uint8x16) \ |
| 786 FUNCTION(Int16x8, int16_t, 8, Float32x4) \ | 909 FUNCTION(Int32x4, int32_t, 4, Float32x4) \ |
| 787 FUNCTION(Int16x8, int16_t, 8, Int32x4) \ | 910 FUNCTION(Int32x4, int32_t, 4, Uint32x4) \ |
| 788 FUNCTION(Int16x8, int16_t, 8, Int8x16) \ | 911 FUNCTION(Int32x4, int32_t, 4, Int16x8) \ |
| 789 FUNCTION(Int8x16, int8_t, 16, Float32x4) \ | 912 FUNCTION(Int32x4, int32_t, 4, Uint16x8) \ |
| 790 FUNCTION(Int8x16, int8_t, 16, Int32x4) \ | 913 FUNCTION(Int32x4, int32_t, 4, Int8x16) \ |
| 791 FUNCTION(Int8x16, int8_t, 16, Int16x8) | 914 FUNCTION(Int32x4, int32_t, 4, Uint8x16) \ |
| 915 FUNCTION(Uint32x4, uint32_t, 4, Float32x4) \ |
| 916 FUNCTION(Uint32x4, uint32_t, 4, Int32x4) \ |
| 917 FUNCTION(Uint32x4, uint32_t, 4, Int16x8) \ |
| 918 FUNCTION(Uint32x4, uint32_t, 4, Uint16x8) \ |
| 919 FUNCTION(Uint32x4, uint32_t, 4, Int8x16) \ |
| 920 FUNCTION(Uint32x4, uint32_t, 4, Uint8x16) \ |
| 921 FUNCTION(Int16x8, int16_t, 8, Float32x4) \ |
| 922 FUNCTION(Int16x8, int16_t, 8, Int32x4) \ |
| 923 FUNCTION(Int16x8, int16_t, 8, Uint32x4) \ |
| 924 FUNCTION(Int16x8, int16_t, 8, Uint16x8) \ |
| 925 FUNCTION(Int16x8, int16_t, 8, Int8x16) \ |
| 926 FUNCTION(Int16x8, int16_t, 8, Uint8x16) \ |
| 927 FUNCTION(Uint16x8, uint16_t, 8, Float32x4) \ |
| 928 FUNCTION(Uint16x8, uint16_t, 8, Int32x4) \ |
| 929 FUNCTION(Uint16x8, uint16_t, 8, Uint32x4) \ |
| 930 FUNCTION(Uint16x8, uint16_t, 8, Int16x8) \ |
| 931 FUNCTION(Uint16x8, uint16_t, 8, Int8x16) \ |
| 932 FUNCTION(Uint16x8, uint16_t, 8, Uint8x16) \ |
| 933 FUNCTION(Int8x16, int8_t, 16, Float32x4) \ |
| 934 FUNCTION(Int8x16, int8_t, 16, Int32x4) \ |
| 935 FUNCTION(Int8x16, int8_t, 16, Uint32x4) \ |
| 936 FUNCTION(Int8x16, int8_t, 16, Int16x8) \ |
| 937 FUNCTION(Int8x16, int8_t, 16, Uint16x8) \ |
| 938 FUNCTION(Int8x16, int8_t, 16, Uint8x16) \ |
| 939 FUNCTION(Uint8x16, uint8_t, 16, Float32x4) \ |
| 940 FUNCTION(Uint8x16, uint8_t, 16, Int32x4) \ |
| 941 FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ |
| 942 FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ |
| 943 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ |
| 944 FUNCTION(Uint8x16, uint8_t, 16, Int8x16) |
| 792 | 945 |
| 793 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ | 946 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ |
| 794 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ | 947 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ |
| 795 static const int kLaneCount = lane_count; \ | 948 static const int kLaneCount = lane_count; \ |
| 796 HandleScope scope(isolate); \ | 949 HandleScope scope(isolate); \ |
| 797 DCHECK(args.length() == 1); \ | 950 DCHECK(args.length() == 1); \ |
| 798 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 951 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ |
| 799 lane_type lanes[kLaneCount]; \ | 952 lane_type lanes[kLaneCount]; \ |
| 800 a->CopyBits(lanes); \ | 953 a->CopyBits(lanes); \ |
| 801 Handle<type> result = isolate->factory()->New##type(lanes); \ | 954 Handle<type> result = isolate->factory()->New##type(lanes); \ |
| 802 return *result; \ | 955 return *result; \ |
| 803 } | 956 } |
| 804 | 957 |
| 805 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) | 958 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) |
| 806 | 959 |
| 807 //------------------------------------------------------------------- | |
| 808 | |
| 809 // Unsigned extract functions. | |
| 810 // TODO(bbudge): remove when spec changes to include unsigned int types. | |
| 811 | |
| 812 RUNTIME_FUNCTION(Runtime_Int16x8UnsignedExtractLane) { | |
| 813 HandleScope scope(isolate); | |
| 814 DCHECK(args.length() == 2); | |
| 815 CONVERT_ARG_HANDLE_CHECKED(Int16x8, a, 0); | |
| 816 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, 8); | |
| 817 return *isolate->factory()->NewNumber(bit_cast<uint16_t>(a->get_lane(lane))); | |
| 818 } | |
| 819 | |
| 820 | |
| 821 RUNTIME_FUNCTION(Runtime_Int8x16UnsignedExtractLane) { | |
| 822 HandleScope scope(isolate); | |
| 823 DCHECK(args.length() == 2); | |
| 824 CONVERT_ARG_HANDLE_CHECKED(Int8x16, a, 0); | |
| 825 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, 16); | |
| 826 return *isolate->factory()->NewNumber(bit_cast<uint8_t>(a->get_lane(lane))); | |
| 827 } | |
| 828 } // namespace internal | 960 } // namespace internal |
| 829 } // namespace v8 | 961 } // namespace v8 |
| OLD | NEW |