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" |
11 #include "src/objects-inl.h" | 11 #include "src/objects-inl.h" |
12 | 12 |
13 // Implement Single Instruction Multiple Data (SIMD) operations as defined in | 13 // Implement Single Instruction Multiple Data (SIMD) operations as defined in |
14 // the SIMD.js draft spec: | 14 // the SIMD.js draft spec: |
15 // http://littledan.github.io/simd.html | 15 // http://littledan.github.io/simd.html |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 // Functions to convert Numbers to SIMD component types. | 22 // Functions to convert Numbers to SIMD component types. |
23 | 23 |
24 template <typename T, typename F> | |
25 static bool CanCast(F from) { | |
26 // A float can't represent 2^31 - 1 or 2^32 - 1 exactly, so promote the limits | |
27 // to double. Otherwise, the limit is truncated and numbers like 2^31 or 2^32 | |
28 // get through, causing any static_cast to be undefined. | |
29 return from >= static_cast<double>(std::numeric_limits<T>::min()) && | |
30 from <= static_cast<double>(std::numeric_limits<T>::max()); | |
31 } | |
32 | |
33 | |
34 // Explicitly specialize for conversions to float, which always succeed. | |
35 template <> | |
36 bool CanCast<float>(int32_t from) { | |
37 return true; | |
38 } | |
39 | |
40 | |
41 template <> | |
42 bool CanCast<float>(uint32_t from) { | |
43 return true; | |
44 } | |
45 | |
46 | |
47 template <typename T> | 24 template <typename T> |
48 static T ConvertNumber(double number); | 25 static T ConvertNumber(double number); |
49 | 26 |
50 | 27 |
51 template <> | 28 template <> |
52 float ConvertNumber<float>(double number) { | 29 float ConvertNumber<float>(double number) { |
53 return DoubleToFloat32(number); | 30 return DoubleToFloat32(number); |
54 } | 31 } |
55 | 32 |
56 | 33 |
57 template <> | 34 template <> |
58 int32_t ConvertNumber<int32_t>(double number) { | 35 int32_t ConvertNumber<int32_t>(double number) { |
59 return DoubleToInt32(number); | 36 return DoubleToInt32(number); |
60 } | 37 } |
61 | 38 |
62 | 39 |
63 template <> | 40 template <> |
64 uint32_t ConvertNumber<uint32_t>(double number) { | |
65 return DoubleToUint32(number); | |
66 } | |
67 | |
68 | |
69 template <> | |
70 int16_t ConvertNumber<int16_t>(double number) { | 41 int16_t ConvertNumber<int16_t>(double number) { |
71 return static_cast<int16_t>(DoubleToInt32(number)); | 42 return static_cast<int16_t>(DoubleToInt32(number)); |
72 } | 43 } |
73 | 44 |
74 | 45 |
75 template <> | 46 template <> |
76 uint16_t ConvertNumber<uint16_t>(double number) { | |
77 return static_cast<uint16_t>(DoubleToUint32(number)); | |
78 } | |
79 | |
80 | |
81 template <> | |
82 int8_t ConvertNumber<int8_t>(double number) { | 47 int8_t ConvertNumber<int8_t>(double number) { |
83 return static_cast<int8_t>(DoubleToInt32(number)); | 48 return static_cast<int8_t>(DoubleToInt32(number)); |
84 } | 49 } |
85 | 50 |
86 | 51 |
87 template <> | |
88 uint8_t ConvertNumber<uint8_t>(double number) { | |
89 return static_cast<uint8_t>(DoubleToUint32(number)); | |
90 } | |
91 | |
92 | |
93 // TODO(bbudge): Make this consistent with SIMD instruction results. | 52 // TODO(bbudge): Make this consistent with SIMD instruction results. |
94 inline float RecipApprox(float a) { return 1.0f / a; } | 53 inline float RecipApprox(float a) { return 1.0f / a; } |
95 | 54 |
96 | 55 |
97 // TODO(bbudge): Make this consistent with SIMD instruction results. | 56 // TODO(bbudge): Make this consistent with SIMD instruction results. |
98 inline float RecipSqrtApprox(float a) { return 1.0f / std::sqrt(a); } | 57 inline float RecipSqrtApprox(float a) { return 1.0f / std::sqrt(a); } |
99 | 58 |
100 | 59 |
101 // Saturating addition for int16_t and int8_t. | 60 // Saturating addition for int16_t and int8_t. |
102 template <typename T> | 61 template <typename T> |
103 inline T AddSaturate(T a, T b) { | 62 inline T AddSaturate(T a, T b) { |
104 const T max = std::numeric_limits<T>::max(); | 63 const T max = std::numeric_limits<T>::max(); |
105 const T min = std::numeric_limits<T>::min(); | 64 const T min = std::numeric_limits<T>::min(); |
106 int32_t result = a + b; | 65 int32_t result = a + b; |
107 if (result > max) return max; | 66 if (result > max) return max; |
108 if (result < min) return min; | 67 if (result < min) return min; |
109 return result; | 68 return result; |
110 } | 69 } |
111 | 70 |
112 | 71 |
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 | |
121 // Saturating subtraction for int16_t and int8_t. | 72 // Saturating subtraction for int16_t and int8_t. |
122 template <typename T> | 73 template <typename T> |
123 inline T SubSaturate(T a, T b) { | 74 inline T SubSaturate(T a, T b) { |
124 const T max = std::numeric_limits<T>::max(); | 75 const T max = std::numeric_limits<T>::max(); |
125 const T min = std::numeric_limits<T>::min(); | 76 const T min = std::numeric_limits<T>::min(); |
126 int32_t result = a - b; | 77 int32_t result = a - b; |
127 if (result > max) return max; | 78 if (result > max) return max; |
128 if (result < min) return min; | 79 if (result < min) return min; |
129 return result; | 80 return result; |
130 } | 81 } |
(...skipping 21 matching lines...) Expand all Loading... |
152 return Min(a, b); | 103 return Min(a, b); |
153 } | 104 } |
154 | 105 |
155 | 106 |
156 inline float MaxNumber(float a, float b) { | 107 inline float MaxNumber(float a, float b) { |
157 if (std::isnan(a)) return b; | 108 if (std::isnan(a)) return b; |
158 if (std::isnan(b)) return a; | 109 if (std::isnan(b)) return a; |
159 return Max(a, b); | 110 return Max(a, b); |
160 } | 111 } |
161 | 112 |
| 113 |
| 114 inline bool CanCast(int32_t a) { return true; } |
| 115 |
| 116 |
| 117 inline bool CanCast(float a) { |
| 118 return a > std::numeric_limits<int32_t>::min() && |
| 119 a < std::numeric_limits<int32_t>::max(); |
| 120 } |
| 121 |
162 } // namespace | 122 } // namespace |
163 | 123 |
164 //------------------------------------------------------------------- | 124 //------------------------------------------------------------------- |
165 | 125 |
166 // SIMD helper functions. | 126 // SIMD helper functions. |
167 | 127 |
168 RUNTIME_FUNCTION(Runtime_IsSimdValue) { | 128 RUNTIME_FUNCTION(Runtime_IsSimdValue) { |
169 HandleScope scope(isolate); | 129 HandleScope scope(isolate); |
170 DCHECK(args.length() == 1); | 130 DCHECK(args.length() == 1); |
171 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); | 131 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 233 |
274 // Common functions. | 234 // Common functions. |
275 | 235 |
276 #define GET_NUMERIC_ARG(lane_type, name, index) \ | 236 #define GET_NUMERIC_ARG(lane_type, name, index) \ |
277 CONVERT_NUMBER_ARG_HANDLE_CHECKED(a, index); \ | 237 CONVERT_NUMBER_ARG_HANDLE_CHECKED(a, index); \ |
278 name = ConvertNumber<lane_type>(a->Number()); | 238 name = ConvertNumber<lane_type>(a->Number()); |
279 | 239 |
280 #define GET_BOOLEAN_ARG(lane_type, name, index) \ | 240 #define GET_BOOLEAN_ARG(lane_type, name, index) \ |
281 name = args[index]->BooleanValue(); | 241 name = args[index]->BooleanValue(); |
282 | 242 |
283 #define SIMD_ALL_TYPES(FUNCTION) \ | 243 #define SIMD_ALL_TYPES(FUNCTION) \ |
284 FUNCTION(Float32x4, float, 4, NewNumber, GET_NUMERIC_ARG) \ | 244 FUNCTION(Float32x4, float, 4, NewNumber, GET_NUMERIC_ARG) \ |
285 FUNCTION(Int32x4, int32_t, 4, NewNumber, GET_NUMERIC_ARG) \ | 245 FUNCTION(Int32x4, int32_t, 4, NewNumber, GET_NUMERIC_ARG) \ |
286 FUNCTION(Uint32x4, uint32_t, 4, NewNumber, GET_NUMERIC_ARG) \ | 246 FUNCTION(Bool32x4, bool, 4, ToBoolean, GET_BOOLEAN_ARG) \ |
287 FUNCTION(Bool32x4, bool, 4, ToBoolean, GET_BOOLEAN_ARG) \ | 247 FUNCTION(Int16x8, int16_t, 8, NewNumber, GET_NUMERIC_ARG) \ |
288 FUNCTION(Int16x8, int16_t, 8, NewNumber, GET_NUMERIC_ARG) \ | 248 FUNCTION(Bool16x8, bool, 8, ToBoolean, GET_BOOLEAN_ARG) \ |
289 FUNCTION(Uint16x8, uint16_t, 8, NewNumber, GET_NUMERIC_ARG) \ | 249 FUNCTION(Int8x16, int8_t, 16, 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) \ | |
293 FUNCTION(Bool8x16, bool, 16, ToBoolean, GET_BOOLEAN_ARG) | 250 FUNCTION(Bool8x16, bool, 16, ToBoolean, GET_BOOLEAN_ARG) |
294 | 251 |
295 #define SIMD_CREATE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 252 #define SIMD_CREATE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
296 RUNTIME_FUNCTION(Runtime_Create##type) { \ | 253 RUNTIME_FUNCTION(Runtime_Create##type) { \ |
297 static const int kLaneCount = lane_count; \ | 254 static const int kLaneCount = lane_count; \ |
298 HandleScope scope(isolate); \ | 255 HandleScope scope(isolate); \ |
299 DCHECK(args.length() == kLaneCount); \ | 256 DCHECK(args.length() == kLaneCount); \ |
300 lane_type lanes[kLaneCount]; \ | 257 lane_type lanes[kLaneCount]; \ |
301 for (int i = 0; i < kLaneCount; i++) { \ | 258 for (int i = 0; i < kLaneCount; i++) { \ |
302 replace(lane_type, lanes[i], i) \ | 259 replace(lane_type, lanes[i], i) \ |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 | 396 |
440 //------------------------------------------------------------------- | 397 //------------------------------------------------------------------- |
441 | 398 |
442 // Int-only functions. | 399 // Int-only functions. |
443 | 400 |
444 #define SIMD_INT_TYPES(FUNCTION) \ | 401 #define SIMD_INT_TYPES(FUNCTION) \ |
445 FUNCTION(Int32x4, int32_t, 32, 4) \ | 402 FUNCTION(Int32x4, int32_t, 32, 4) \ |
446 FUNCTION(Int16x8, int16_t, 16, 8) \ | 403 FUNCTION(Int16x8, int16_t, 16, 8) \ |
447 FUNCTION(Int8x16, int8_t, 8, 16) | 404 FUNCTION(Int8x16, int8_t, 8, 16) |
448 | 405 |
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 | |
454 #define CONVERT_SHIFT_ARG_CHECKED(name, index) \ | 406 #define CONVERT_SHIFT_ARG_CHECKED(name, index) \ |
455 RUNTIME_ASSERT(args[index]->IsNumber()); \ | 407 RUNTIME_ASSERT(args[index]->IsNumber()); \ |
456 int32_t signed_shift = 0; \ | 408 int32_t signed_shift = 0; \ |
457 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ | 409 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ |
458 uint32_t name = bit_cast<uint32_t>(signed_shift); | 410 uint32_t name = bit_cast<uint32_t>(signed_shift); |
459 | 411 |
460 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 412 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
461 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ | 413 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ |
462 static const int kLaneCount = lane_count; \ | 414 static const int kLaneCount = lane_count; \ |
463 HandleScope scope(isolate); \ | 415 HandleScope scope(isolate); \ |
(...skipping 14 matching lines...) Expand all Loading... |
478 RUNTIME_FUNCTION(Runtime_##type##ShiftRightLogicalByScalar) { \ | 430 RUNTIME_FUNCTION(Runtime_##type##ShiftRightLogicalByScalar) { \ |
479 static const int kLaneCount = lane_count; \ | 431 static const int kLaneCount = lane_count; \ |
480 HandleScope scope(isolate); \ | 432 HandleScope scope(isolate); \ |
481 DCHECK(args.length() == 2); \ | 433 DCHECK(args.length() == 2); \ |
482 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 434 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
483 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 435 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
484 lane_type lanes[kLaneCount] = {0}; \ | 436 lane_type lanes[kLaneCount] = {0}; \ |
485 if (shift < lane_bits) { \ | 437 if (shift < lane_bits) { \ |
486 for (int i = 0; i < kLaneCount; i++) { \ | 438 for (int i = 0; i < kLaneCount; i++) { \ |
487 lanes[i] = static_cast<lane_type>( \ | 439 lanes[i] = static_cast<lane_type>( \ |
488 bit_cast<lane_type>(a->get_lane(i)) >> shift); \ | 440 bit_cast<u##lane_type>(a->get_lane(i)) >> shift); \ |
489 } \ | 441 } \ |
490 } \ | 442 } \ |
491 Handle<type> result = isolate->factory()->New##type(lanes); \ | 443 Handle<type> result = isolate->factory()->New##type(lanes); \ |
492 return *result; \ | 444 return *result; \ |
493 } | 445 } |
494 | 446 |
495 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 447 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
496 RUNTIME_FUNCTION(Runtime_##type##ShiftRightArithmeticByScalar) { \ | 448 RUNTIME_FUNCTION(Runtime_##type##ShiftRightArithmeticByScalar) { \ |
497 static const int kLaneCount = lane_count; \ | 449 static const int kLaneCount = lane_count; \ |
498 HandleScope scope(isolate); \ | 450 HandleScope scope(isolate); \ |
499 DCHECK(args.length() == 2); \ | 451 DCHECK(args.length() == 2); \ |
500 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 452 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ |
501 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 453 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
502 if (shift >= lane_bits) shift = lane_bits - 1; \ | 454 if (shift >= lane_bits) shift = lane_bits - 1; \ |
503 lane_type lanes[kLaneCount]; \ | 455 lane_type lanes[kLaneCount]; \ |
504 for (int i = 0; i < kLaneCount; i++) { \ | 456 for (int i = 0; i < kLaneCount; i++) { \ |
505 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ | 457 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ |
506 lanes[i] = static_cast<lane_type>(shifted); \ | 458 lanes[i] = static_cast<lane_type>(shifted); \ |
507 } \ | 459 } \ |
508 Handle<type> result = isolate->factory()->New##type(lanes); \ | 460 Handle<type> result = isolate->factory()->New##type(lanes); \ |
509 return *result; \ | 461 return *result; \ |
510 } | 462 } |
511 | 463 |
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 | |
524 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) | 464 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) |
525 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) | 465 SIMD_INT_TYPES(SIMD_LSR_FUNCTION) |
526 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) | 466 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) |
527 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) | |
528 SIMD_UINT_TYPES(SIMD_HORIZONTAL_SUM_FUNCTION) | |
529 | 467 |
530 //------------------------------------------------------------------- | 468 //------------------------------------------------------------------- |
531 | 469 |
532 // Bool-only functions. | 470 // Bool-only functions. |
533 | 471 |
534 #define SIMD_BOOL_TYPES(FUNCTION) \ | 472 #define SIMD_BOOL_TYPES(FUNCTION) \ |
535 FUNCTION(Bool32x4, 4) \ | 473 FUNCTION(Bool32x4, 4) \ |
536 FUNCTION(Bool16x8, 8) \ | 474 FUNCTION(Bool16x8, 8) \ |
537 FUNCTION(Bool8x16, 16) | 475 FUNCTION(Bool8x16, 16) |
538 | 476 |
(...skipping 29 matching lines...) Expand all Loading... |
568 | 506 |
569 SIMD_BOOL_TYPES(SIMD_ANY_FUNCTION) | 507 SIMD_BOOL_TYPES(SIMD_ANY_FUNCTION) |
570 SIMD_BOOL_TYPES(SIMD_ALL_FUNCTION) | 508 SIMD_BOOL_TYPES(SIMD_ALL_FUNCTION) |
571 | 509 |
572 //------------------------------------------------------------------- | 510 //------------------------------------------------------------------- |
573 | 511 |
574 // Small Int-only functions. | 512 // Small Int-only functions. |
575 | 513 |
576 #define SIMD_SMALL_INT_TYPES(FUNCTION) \ | 514 #define SIMD_SMALL_INT_TYPES(FUNCTION) \ |
577 FUNCTION(Int16x8, int16_t, 8) \ | 515 FUNCTION(Int16x8, int16_t, 8) \ |
578 FUNCTION(Uint16x8, uint16_t, 8) \ | 516 FUNCTION(Int8x16, int8_t, 16) |
579 FUNCTION(Int8x16, int8_t, 16) \ | |
580 FUNCTION(Uint8x16, uint8_t, 16) | |
581 | 517 |
582 #define SIMD_ADD_SATURATE_FUNCTION(type, lane_type, lane_count) \ | 518 #define SIMD_ADD_SATURATE_FUNCTION(type, lane_type, lane_count) \ |
583 RUNTIME_FUNCTION(Runtime_##type##AddSaturate) { \ | 519 RUNTIME_FUNCTION(Runtime_##type##AddSaturate) { \ |
584 HandleScope scope(isolate); \ | 520 HandleScope scope(isolate); \ |
585 SIMD_BINARY_OP(type, lane_type, lane_count, AddSaturate, result); \ | 521 SIMD_BINARY_OP(type, lane_type, lane_count, AddSaturate, result); \ |
586 return *result; \ | 522 return *result; \ |
587 } | 523 } |
588 | 524 |
589 #define BINARY_SUB(a, b) (a) - (b) | 525 #define BINARY_SUB(a, b) (a) - (b) |
590 #define SIMD_SUB_SATURATE_FUNCTION(type, lane_type, lane_count) \ | 526 #define SIMD_SUB_SATURATE_FUNCTION(type, lane_type, lane_count) \ |
591 RUNTIME_FUNCTION(Runtime_##type##SubSaturate) { \ | 527 RUNTIME_FUNCTION(Runtime_##type##SubSaturate) { \ |
592 HandleScope scope(isolate); \ | 528 HandleScope scope(isolate); \ |
593 SIMD_BINARY_OP(type, lane_type, lane_count, SubSaturate, result); \ | 529 SIMD_BINARY_OP(type, lane_type, lane_count, SubSaturate, result); \ |
594 return *result; \ | 530 return *result; \ |
595 } | 531 } |
596 | 532 |
597 SIMD_SMALL_INT_TYPES(SIMD_ADD_SATURATE_FUNCTION) | 533 SIMD_SMALL_INT_TYPES(SIMD_ADD_SATURATE_FUNCTION) |
598 SIMD_SMALL_INT_TYPES(SIMD_SUB_SATURATE_FUNCTION) | 534 SIMD_SMALL_INT_TYPES(SIMD_SUB_SATURATE_FUNCTION) |
599 | 535 |
600 //------------------------------------------------------------------- | 536 //------------------------------------------------------------------- |
601 | 537 |
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 | |
637 // Numeric functions. | 538 // Numeric functions. |
638 | 539 |
639 #define SIMD_NUMERIC_TYPES(FUNCTION) \ | 540 #define SIMD_NUMERIC_TYPES(FUNCTION) \ |
640 FUNCTION(Float32x4, float, 4) \ | 541 FUNCTION(Float32x4, float, 4) \ |
641 FUNCTION(Int32x4, int32_t, 4) \ | 542 FUNCTION(Int32x4, int32_t, 4) \ |
642 FUNCTION(Uint32x4, uint32_t, 4) \ | |
643 FUNCTION(Int16x8, int16_t, 8) \ | 543 FUNCTION(Int16x8, int16_t, 8) \ |
644 FUNCTION(Uint16x8, uint16_t, 8) \ | 544 FUNCTION(Int8x16, int8_t, 16) |
645 FUNCTION(Int8x16, int8_t, 16) \ | 545 |
646 FUNCTION(Uint8x16, uint8_t, 16) | 546 #define SIMD_NEG_FUNCTION(type, lane_type, lane_count) \ |
| 547 RUNTIME_FUNCTION(Runtime_##type##Neg) { \ |
| 548 HandleScope scope(isolate); \ |
| 549 SIMD_UNARY_OP(type, lane_type, lane_count, -, result); \ |
| 550 return *result; \ |
| 551 } |
647 | 552 |
648 #define BINARY_ADD(a, b) (a) + (b) | 553 #define BINARY_ADD(a, b) (a) + (b) |
649 #define SIMD_ADD_FUNCTION(type, lane_type, lane_count) \ | 554 #define SIMD_ADD_FUNCTION(type, lane_type, lane_count) \ |
650 RUNTIME_FUNCTION(Runtime_##type##Add) { \ | 555 RUNTIME_FUNCTION(Runtime_##type##Add) { \ |
651 HandleScope scope(isolate); \ | 556 HandleScope scope(isolate); \ |
652 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_ADD, result); \ | 557 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_ADD, result); \ |
653 return *result; \ | 558 return *result; \ |
654 } | 559 } |
655 | 560 |
656 #define BINARY_SUB(a, b) (a) - (b) | 561 #define BINARY_SUB(a, b) (a) - (b) |
(...skipping 19 matching lines...) Expand all Loading... |
676 return *result; \ | 581 return *result; \ |
677 } | 582 } |
678 | 583 |
679 #define SIMD_MAX_FUNCTION(type, lane_type, lane_count) \ | 584 #define SIMD_MAX_FUNCTION(type, lane_type, lane_count) \ |
680 RUNTIME_FUNCTION(Runtime_##type##Max) { \ | 585 RUNTIME_FUNCTION(Runtime_##type##Max) { \ |
681 HandleScope scope(isolate); \ | 586 HandleScope scope(isolate); \ |
682 SIMD_BINARY_OP(type, lane_type, lane_count, Max, result); \ | 587 SIMD_BINARY_OP(type, lane_type, lane_count, Max, result); \ |
683 return *result; \ | 588 return *result; \ |
684 } | 589 } |
685 | 590 |
| 591 SIMD_NUMERIC_TYPES(SIMD_NEG_FUNCTION) |
686 SIMD_NUMERIC_TYPES(SIMD_ADD_FUNCTION) | 592 SIMD_NUMERIC_TYPES(SIMD_ADD_FUNCTION) |
687 SIMD_NUMERIC_TYPES(SIMD_SUB_FUNCTION) | 593 SIMD_NUMERIC_TYPES(SIMD_SUB_FUNCTION) |
688 SIMD_NUMERIC_TYPES(SIMD_MUL_FUNCTION) | 594 SIMD_NUMERIC_TYPES(SIMD_MUL_FUNCTION) |
689 SIMD_NUMERIC_TYPES(SIMD_MIN_FUNCTION) | 595 SIMD_NUMERIC_TYPES(SIMD_MIN_FUNCTION) |
690 SIMD_NUMERIC_TYPES(SIMD_MAX_FUNCTION) | 596 SIMD_NUMERIC_TYPES(SIMD_MAX_FUNCTION) |
691 | 597 |
692 //------------------------------------------------------------------- | 598 //------------------------------------------------------------------- |
693 | 599 |
694 // Relational functions. | 600 // Relational functions. |
695 | 601 |
696 #define SIMD_RELATIONAL_TYPES(FUNCTION) \ | 602 #define SIMD_RELATIONAL_TYPES(FUNCTION) \ |
697 FUNCTION(Float32x4, Bool32x4, 4) \ | 603 FUNCTION(Float32x4, Bool32x4, 4) \ |
698 FUNCTION(Int32x4, Bool32x4, 4) \ | 604 FUNCTION(Int32x4, Bool32x4, 4) \ |
699 FUNCTION(Uint32x4, Bool32x4, 4) \ | |
700 FUNCTION(Int16x8, Bool16x8, 8) \ | 605 FUNCTION(Int16x8, Bool16x8, 8) \ |
701 FUNCTION(Uint16x8, Bool16x8, 8) \ | 606 FUNCTION(Int8x16, Bool8x16, 16) |
702 FUNCTION(Int8x16, Bool8x16, 16) \ | |
703 FUNCTION(Uint8x16, Bool8x16, 16) | |
704 | 607 |
705 #define SIMD_EQUALITY_TYPES(FUNCTION) \ | 608 #define SIMD_EQUALITY_TYPES(FUNCTION) \ |
706 SIMD_RELATIONAL_TYPES(FUNCTION) \ | 609 SIMD_RELATIONAL_TYPES(FUNCTION) \ |
707 FUNCTION(Bool32x4, Bool32x4, 4) \ | 610 FUNCTION(Bool32x4, Bool32x4, 4) \ |
708 FUNCTION(Bool16x8, Bool16x8, 8) \ | 611 FUNCTION(Bool16x8, Bool16x8, 8) \ |
709 FUNCTION(Bool8x16, Bool8x16, 16) | 612 FUNCTION(Bool8x16, Bool8x16, 16) |
710 | 613 |
711 #define SIMD_EQUAL_FUNCTION(type, bool_type, lane_count) \ | 614 #define SIMD_EQUAL_FUNCTION(type, bool_type, lane_count) \ |
712 RUNTIME_FUNCTION(Runtime_##type##Equal) { \ | 615 RUNTIME_FUNCTION(Runtime_##type##Equal) { \ |
713 HandleScope scope(isolate); \ | 616 HandleScope scope(isolate); \ |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 | 658 |
756 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_FUNCTION) | 659 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_FUNCTION) |
757 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_OR_EQUAL_FUNCTION) | 660 SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_OR_EQUAL_FUNCTION) |
758 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_FUNCTION) | 661 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_FUNCTION) |
759 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_OR_EQUAL_FUNCTION) | 662 SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_OR_EQUAL_FUNCTION) |
760 | 663 |
761 //------------------------------------------------------------------- | 664 //------------------------------------------------------------------- |
762 | 665 |
763 // Logical functions. | 666 // Logical functions. |
764 | 667 |
765 #define SIMD_LOGICAL_TYPES(FUNCTION) \ | 668 #define SIMD_LOGICAL_TYPES(FUNCTION) \ |
766 FUNCTION(Int32x4, int32_t, 4, _INT) \ | 669 FUNCTION(Int32x4, int32_t, 4, _INT) \ |
767 FUNCTION(Uint32x4, uint32_t, 4, _INT) \ | 670 FUNCTION(Int16x8, int16_t, 8, _INT) \ |
768 FUNCTION(Int16x8, int16_t, 8, _INT) \ | 671 FUNCTION(Int8x16, int8_t, 16, _INT) \ |
769 FUNCTION(Uint16x8, uint16_t, 8, _INT) \ | 672 FUNCTION(Bool32x4, bool, 4, _BOOL) \ |
770 FUNCTION(Int8x16, int8_t, 16, _INT) \ | 673 FUNCTION(Bool16x8, bool, 8, _BOOL) \ |
771 FUNCTION(Uint8x16, uint8_t, 16, _INT) \ | |
772 FUNCTION(Bool32x4, bool, 4, _BOOL) \ | |
773 FUNCTION(Bool16x8, bool, 8, _BOOL) \ | |
774 FUNCTION(Bool8x16, bool, 16, _BOOL) | 674 FUNCTION(Bool8x16, bool, 16, _BOOL) |
775 | 675 |
776 #define BINARY_AND_INT(a, b) (a) & (b) | 676 #define BINARY_AND_INT(a, b) (a) & (b) |
777 #define BINARY_AND_BOOL(a, b) (a) && (b) | 677 #define BINARY_AND_BOOL(a, b) (a) && (b) |
778 #define SIMD_AND_FUNCTION(type, lane_type, lane_count, op) \ | 678 #define SIMD_AND_FUNCTION(type, lane_type, lane_count, op) \ |
779 RUNTIME_FUNCTION(Runtime_##type##And) { \ | 679 RUNTIME_FUNCTION(Runtime_##type##And) { \ |
780 HandleScope scope(isolate); \ | 680 HandleScope scope(isolate); \ |
781 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_AND##op, result); \ | 681 SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_AND##op, result); \ |
782 return *result; \ | 682 return *result; \ |
783 } | 683 } |
(...skipping 27 matching lines...) Expand all Loading... |
811 | 711 |
812 SIMD_LOGICAL_TYPES(SIMD_AND_FUNCTION) | 712 SIMD_LOGICAL_TYPES(SIMD_AND_FUNCTION) |
813 SIMD_LOGICAL_TYPES(SIMD_OR_FUNCTION) | 713 SIMD_LOGICAL_TYPES(SIMD_OR_FUNCTION) |
814 SIMD_LOGICAL_TYPES(SIMD_XOR_FUNCTION) | 714 SIMD_LOGICAL_TYPES(SIMD_XOR_FUNCTION) |
815 SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) | 715 SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) |
816 | 716 |
817 //------------------------------------------------------------------- | 717 //------------------------------------------------------------------- |
818 | 718 |
819 // Select functions. | 719 // Select functions. |
820 | 720 |
821 #define SIMD_SELECT_TYPES(FUNCTION) \ | 721 #define SIMD_SELECT_TYPES(FUNCTION) \ |
822 FUNCTION(Float32x4, float, Bool32x4, 4) \ | 722 FUNCTION(Float32x4, float, Bool32x4, 4) \ |
823 FUNCTION(Int32x4, int32_t, Bool32x4, 4) \ | 723 FUNCTION(Int32x4, int32_t, Bool32x4, 4) \ |
824 FUNCTION(Uint32x4, uint32_t, Bool32x4, 4) \ | 724 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ |
825 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ | 725 FUNCTION(Int8x16, int8_t, Bool8x16, 16) |
826 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ | |
827 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ | |
828 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) | |
829 | 726 |
830 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ | 727 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ |
831 RUNTIME_FUNCTION(Runtime_##type##Select) { \ | 728 RUNTIME_FUNCTION(Runtime_##type##Select) { \ |
832 static const int kLaneCount = lane_count; \ | 729 static const int kLaneCount = lane_count; \ |
833 HandleScope scope(isolate); \ | 730 HandleScope scope(isolate); \ |
834 DCHECK(args.length() == 3); \ | 731 DCHECK(args.length() == 3); \ |
835 CONVERT_ARG_HANDLE_CHECKED(bool_type, mask, 0); \ | 732 CONVERT_ARG_HANDLE_CHECKED(bool_type, mask, 0); \ |
836 CONVERT_ARG_HANDLE_CHECKED(type, a, 1); \ | 733 CONVERT_ARG_HANDLE_CHECKED(type, a, 1); \ |
837 CONVERT_ARG_HANDLE_CHECKED(type, b, 2); \ | 734 CONVERT_ARG_HANDLE_CHECKED(type, b, 2); \ |
838 lane_type lanes[kLaneCount]; \ | 735 lane_type lanes[kLaneCount]; \ |
839 for (int i = 0; i < kLaneCount; i++) { \ | 736 for (int i = 0; i < kLaneCount; i++) { \ |
840 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ | 737 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ |
841 } \ | 738 } \ |
842 Handle<type> result = isolate->factory()->New##type(lanes); \ | 739 Handle<type> result = isolate->factory()->New##type(lanes); \ |
843 return *result; \ | 740 return *result; \ |
844 } | 741 } |
845 | 742 |
846 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) | 743 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) |
847 | 744 |
848 //------------------------------------------------------------------- | 745 //------------------------------------------------------------------- |
849 | 746 |
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 | |
869 // Casting functions. | 747 // Casting functions. |
870 | 748 |
871 #define SIMD_FROM_TYPES(FUNCTION) \ | 749 #define SIMD_FROM_TYPES(FUNCTION) \ |
872 FUNCTION(Float32x4, float, 4, Int32x4, int32_t) \ | 750 FUNCTION(Float32x4, float, 4, Int32x4, int32_t) \ |
873 FUNCTION(Float32x4, float, 4, Uint32x4, uint32_t) \ | 751 FUNCTION(Int32x4, int32_t, 4, Float32x4, float) |
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) | |
882 | 752 |
883 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ | 753 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ |
884 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ | 754 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ |
885 static const int kLaneCount = lane_count; \ | 755 static const int kLaneCount = lane_count; \ |
886 HandleScope scope(isolate); \ | 756 HandleScope scope(isolate); \ |
887 DCHECK(args.length() == 1); \ | 757 DCHECK(args.length() == 1); \ |
888 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 758 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ |
889 lane_type lanes[kLaneCount]; \ | 759 lane_type lanes[kLaneCount]; \ |
890 for (int i = 0; i < kLaneCount; i++) { \ | 760 for (int i = 0; i < kLaneCount; i++) { \ |
891 from_ctype a_value = a->get_lane(i); \ | 761 from_ctype a_value = a->get_lane(i); \ |
892 if (a_value != a_value) a_value = 0; \ | 762 RUNTIME_ASSERT(CanCast(a_value)); \ |
893 RUNTIME_ASSERT(CanCast<lane_type>(a_value)); \ | |
894 lanes[i] = static_cast<lane_type>(a_value); \ | 763 lanes[i] = static_cast<lane_type>(a_value); \ |
895 } \ | 764 } \ |
896 Handle<type> result = isolate->factory()->New##type(lanes); \ | 765 Handle<type> result = isolate->factory()->New##type(lanes); \ |
897 return *result; \ | 766 return *result; \ |
898 } | 767 } |
899 | 768 |
900 SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) | 769 SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) |
901 | 770 |
902 #define SIMD_FROM_BITS_TYPES(FUNCTION) \ | 771 #define SIMD_FROM_BITS_TYPES(FUNCTION) \ |
903 FUNCTION(Float32x4, float, 4, Int32x4) \ | 772 FUNCTION(Float32x4, float, 4, Int32x4) \ |
904 FUNCTION(Float32x4, float, 4, Uint32x4) \ | 773 FUNCTION(Float32x4, float, 4, Int16x8) \ |
905 FUNCTION(Float32x4, float, 4, Int16x8) \ | 774 FUNCTION(Float32x4, float, 4, Int8x16) \ |
906 FUNCTION(Float32x4, float, 4, Uint16x8) \ | 775 FUNCTION(Int32x4, int32_t, 4, Float32x4) \ |
907 FUNCTION(Float32x4, float, 4, Int8x16) \ | 776 FUNCTION(Int32x4, int32_t, 4, Int16x8) \ |
908 FUNCTION(Float32x4, float, 4, Uint8x16) \ | 777 FUNCTION(Int32x4, int32_t, 4, Int8x16) \ |
909 FUNCTION(Int32x4, int32_t, 4, Float32x4) \ | 778 FUNCTION(Int16x8, int16_t, 8, Float32x4) \ |
910 FUNCTION(Int32x4, int32_t, 4, Uint32x4) \ | 779 FUNCTION(Int16x8, int16_t, 8, Int32x4) \ |
911 FUNCTION(Int32x4, int32_t, 4, Int16x8) \ | 780 FUNCTION(Int16x8, int16_t, 8, Int8x16) \ |
912 FUNCTION(Int32x4, int32_t, 4, Uint16x8) \ | 781 FUNCTION(Int8x16, int8_t, 16, Float32x4) \ |
913 FUNCTION(Int32x4, int32_t, 4, Int8x16) \ | 782 FUNCTION(Int8x16, int8_t, 16, Int32x4) \ |
914 FUNCTION(Int32x4, int32_t, 4, Uint8x16) \ | 783 FUNCTION(Int8x16, int8_t, 16, Int16x8) |
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) | |
945 | 784 |
946 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ | 785 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ |
947 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ | 786 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ |
948 static const int kLaneCount = lane_count; \ | 787 static const int kLaneCount = lane_count; \ |
949 HandleScope scope(isolate); \ | 788 HandleScope scope(isolate); \ |
950 DCHECK(args.length() == 1); \ | 789 DCHECK(args.length() == 1); \ |
951 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 790 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ |
952 lane_type lanes[kLaneCount]; \ | 791 lane_type lanes[kLaneCount]; \ |
953 a->CopyBits(lanes); \ | 792 a->CopyBits(lanes); \ |
954 Handle<type> result = isolate->factory()->New##type(lanes); \ | 793 Handle<type> result = isolate->factory()->New##type(lanes); \ |
955 return *result; \ | 794 return *result; \ |
956 } | 795 } |
957 | 796 |
958 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) | 797 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) |
959 | 798 |
| 799 //------------------------------------------------------------------- |
| 800 |
| 801 // Unsigned extract functions. |
| 802 // TODO(bbudge): remove when spec changes to include unsigned int types. |
| 803 |
| 804 RUNTIME_FUNCTION(Runtime_Int16x8UnsignedExtractLane) { |
| 805 HandleScope scope(isolate); |
| 806 DCHECK(args.length() == 2); |
| 807 CONVERT_ARG_HANDLE_CHECKED(Int16x8, a, 0); |
| 808 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, 8); |
| 809 return *isolate->factory()->NewNumber(bit_cast<uint16_t>(a->get_lane(lane))); |
| 810 } |
| 811 |
| 812 |
| 813 RUNTIME_FUNCTION(Runtime_Int8x16UnsignedExtractLane) { |
| 814 HandleScope scope(isolate); |
| 815 DCHECK(args.length() == 2); |
| 816 CONVERT_ARG_HANDLE_CHECKED(Int8x16, a, 0); |
| 817 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, 16); |
| 818 return *isolate->factory()->NewNumber(bit_cast<uint8_t>(a->get_lane(lane))); |
| 819 } |
960 } // namespace internal | 820 } // namespace internal |
961 } // namespace v8 | 821 } // namespace v8 |
OLD | NEW |