Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/runtime/runtime-simd.cc

Issue 1309513005: Revert of [simd.js] Update to spec version 0.8.2. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/runtime/runtime.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698