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

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

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

Powered by Google App Engine
This is Rietveld 408576698