OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/base/macros.h" | 8 #include "src/base/macros.h" |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 | 154 |
155 } // namespace | 155 } // namespace |
156 | 156 |
157 //------------------------------------------------------------------- | 157 //------------------------------------------------------------------- |
158 | 158 |
159 // SIMD helper functions. | 159 // SIMD helper functions. |
160 | 160 |
161 RUNTIME_FUNCTION(Runtime_IsSimdValue) { | 161 RUNTIME_FUNCTION(Runtime_IsSimdValue) { |
162 HandleScope scope(isolate); | 162 HandleScope scope(isolate); |
163 DCHECK(args.length() == 1); | 163 DCHECK_EQ(1, args.length()); |
164 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); | 164 return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); |
165 } | 165 } |
166 | 166 |
167 | 167 |
168 //------------------------------------------------------------------- | 168 //------------------------------------------------------------------- |
169 | 169 |
170 // Utility macros. | 170 // Utility macros. |
171 | 171 |
172 // TODO(gdeepti): Fix to use ToNumber conversion once polyfill is updated. | 172 // TODO(gdeepti): Fix to use ToNumber conversion once polyfill is updated. |
173 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ | 173 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ |
(...skipping 13 matching lines...) Expand all Loading... |
187 Handle<Type> name; \ | 187 Handle<Type> name; \ |
188 if (args[index]->Is##Type()) { \ | 188 if (args[index]->Is##Type()) { \ |
189 name = args.at<Type>(index); \ | 189 name = args.at<Type>(index); \ |
190 } else { \ | 190 } else { \ |
191 THROW_NEW_ERROR_RETURN_FAILURE( \ | 191 THROW_NEW_ERROR_RETURN_FAILURE( \ |
192 isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ | 192 isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ |
193 } | 193 } |
194 | 194 |
195 #define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ | 195 #define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ |
196 static const int kLaneCount = lane_count; \ | 196 static const int kLaneCount = lane_count; \ |
197 DCHECK(args.length() == 1); \ | 197 DCHECK_EQ(1, args.length()); \ |
198 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 198 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
199 lane_type lanes[kLaneCount]; \ | 199 lane_type lanes[kLaneCount]; \ |
200 for (int i = 0; i < kLaneCount; i++) { \ | 200 for (int i = 0; i < kLaneCount; i++) { \ |
201 lanes[i] = op(a->get_lane(i)); \ | 201 lanes[i] = op(a->get_lane(i)); \ |
202 } \ | 202 } \ |
203 Handle<type> result = isolate->factory()->New##type(lanes); | 203 Handle<type> result = isolate->factory()->New##type(lanes); |
204 | 204 |
205 #define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ | 205 #define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ |
206 static const int kLaneCount = lane_count; \ | 206 static const int kLaneCount = lane_count; \ |
207 DCHECK(args.length() == 2); \ | 207 DCHECK_EQ(2, args.length()); \ |
208 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 208 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
209 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ | 209 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ |
210 lane_type lanes[kLaneCount]; \ | 210 lane_type lanes[kLaneCount]; \ |
211 for (int i = 0; i < kLaneCount; i++) { \ | 211 for (int i = 0; i < kLaneCount; i++) { \ |
212 lanes[i] = op(a->get_lane(i), b->get_lane(i)); \ | 212 lanes[i] = op(a->get_lane(i), b->get_lane(i)); \ |
213 } \ | 213 } \ |
214 Handle<type> result = isolate->factory()->New##type(lanes); | 214 Handle<type> result = isolate->factory()->New##type(lanes); |
215 | 215 |
216 #define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ | 216 #define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ |
217 static const int kLaneCount = lane_count; \ | 217 static const int kLaneCount = lane_count; \ |
218 DCHECK(args.length() == 2); \ | 218 DCHECK_EQ(2, args.length()); \ |
219 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 219 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
220 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ | 220 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ |
221 bool lanes[kLaneCount]; \ | 221 bool lanes[kLaneCount]; \ |
222 for (int i = 0; i < kLaneCount; i++) { \ | 222 for (int i = 0; i < kLaneCount; i++) { \ |
223 lanes[i] = a->get_lane(i) op b->get_lane(i); \ | 223 lanes[i] = a->get_lane(i) op b->get_lane(i); \ |
224 } \ | 224 } \ |
225 Handle<bool_type> result = isolate->factory()->New##bool_type(lanes); | 225 Handle<bool_type> result = isolate->factory()->New##bool_type(lanes); |
226 | 226 |
227 //------------------------------------------------------------------- | 227 //------------------------------------------------------------------- |
228 | 228 |
(...skipping 28 matching lines...) Expand all Loading... |
257 lane_type lanes[kLaneCount]; \ | 257 lane_type lanes[kLaneCount]; \ |
258 for (int i = 0; i < kLaneCount; i++) { \ | 258 for (int i = 0; i < kLaneCount; i++) { \ |
259 replace(lane_type, lanes[i], i) \ | 259 replace(lane_type, lanes[i], i) \ |
260 } \ | 260 } \ |
261 return *isolate->factory()->New##type(lanes); \ | 261 return *isolate->factory()->New##type(lanes); \ |
262 } | 262 } |
263 | 263 |
264 #define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 264 #define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
265 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ | 265 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ |
266 HandleScope scope(isolate); \ | 266 HandleScope scope(isolate); \ |
267 DCHECK(args.length() == 2); \ | 267 DCHECK_EQ(2, args.length()); \ |
268 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 268 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
269 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ | 269 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ |
270 return *isolate->factory()->extract(a->get_lane(lane)); \ | 270 return *isolate->factory()->extract(a->get_lane(lane)); \ |
271 } | 271 } |
272 | 272 |
273 #define SIMD_REPLACE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 273 #define SIMD_REPLACE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
274 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ | 274 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ |
275 static const int kLaneCount = lane_count; \ | 275 static const int kLaneCount = lane_count; \ |
276 HandleScope scope(isolate); \ | 276 HandleScope scope(isolate); \ |
277 DCHECK(args.length() == 3); \ | 277 DCHECK_EQ(3, args.length()); \ |
278 CONVERT_SIMD_ARG_HANDLE_THROW(type, simd, 0); \ | 278 CONVERT_SIMD_ARG_HANDLE_THROW(type, simd, 0); \ |
279 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ | 279 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ |
280 lane_type lanes[kLaneCount]; \ | 280 lane_type lanes[kLaneCount]; \ |
281 for (int i = 0; i < kLaneCount; i++) { \ | 281 for (int i = 0; i < kLaneCount; i++) { \ |
282 lanes[i] = simd->get_lane(i); \ | 282 lanes[i] = simd->get_lane(i); \ |
283 } \ | 283 } \ |
284 replace(lane_type, lanes[lane], 2); \ | 284 replace(lane_type, lanes[lane], 2); \ |
285 Handle<type> result = isolate->factory()->New##type(lanes); \ | 285 Handle<type> result = isolate->factory()->New##type(lanes); \ |
286 return *result; \ | 286 return *result; \ |
287 } | 287 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ | 415 isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ |
416 } \ | 416 } \ |
417 int32_t signed_shift = 0; \ | 417 int32_t signed_shift = 0; \ |
418 args[index]->ToInt32(&signed_shift); \ | 418 args[index]->ToInt32(&signed_shift); \ |
419 uint32_t name = bit_cast<uint32_t>(signed_shift); | 419 uint32_t name = bit_cast<uint32_t>(signed_shift); |
420 | 420 |
421 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 421 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
422 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ | 422 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ |
423 static const int kLaneCount = lane_count; \ | 423 static const int kLaneCount = lane_count; \ |
424 HandleScope scope(isolate); \ | 424 HandleScope scope(isolate); \ |
425 DCHECK(args.length() == 2); \ | 425 DCHECK_EQ(2, args.length()); \ |
426 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 426 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
427 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 427 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
428 lane_type lanes[kLaneCount] = {0}; \ | 428 lane_type lanes[kLaneCount] = {0}; \ |
429 shift &= lane_bits - 1; \ | 429 shift &= lane_bits - 1; \ |
430 for (int i = 0; i < kLaneCount; i++) { \ | 430 for (int i = 0; i < kLaneCount; i++) { \ |
431 lanes[i] = a->get_lane(i) << shift; \ | 431 lanes[i] = a->get_lane(i) << shift; \ |
432 } \ | 432 } \ |
433 Handle<type> result = isolate->factory()->New##type(lanes); \ | 433 Handle<type> result = isolate->factory()->New##type(lanes); \ |
434 return *result; \ | 434 return *result; \ |
435 } | 435 } |
436 | 436 |
437 #define SIMD_LSR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 437 #define SIMD_LSR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
438 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ | 438 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ |
439 static const int kLaneCount = lane_count; \ | 439 static const int kLaneCount = lane_count; \ |
440 HandleScope scope(isolate); \ | 440 HandleScope scope(isolate); \ |
441 DCHECK(args.length() == 2); \ | 441 DCHECK_EQ(2, args.length()); \ |
442 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 442 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
443 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 443 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
444 lane_type lanes[kLaneCount] = {0}; \ | 444 lane_type lanes[kLaneCount] = {0}; \ |
445 shift &= lane_bits - 1; \ | 445 shift &= lane_bits - 1; \ |
446 for (int i = 0; i < kLaneCount; i++) { \ | 446 for (int i = 0; i < kLaneCount; i++) { \ |
447 lanes[i] = static_cast<lane_type>(bit_cast<lane_type>(a->get_lane(i)) >> \ | 447 lanes[i] = static_cast<lane_type>(bit_cast<lane_type>(a->get_lane(i)) >> \ |
448 shift); \ | 448 shift); \ |
449 } \ | 449 } \ |
450 Handle<type> result = isolate->factory()->New##type(lanes); \ | 450 Handle<type> result = isolate->factory()->New##type(lanes); \ |
451 return *result; \ | 451 return *result; \ |
452 } | 452 } |
453 | 453 |
454 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 454 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
455 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ | 455 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ |
456 static const int kLaneCount = lane_count; \ | 456 static const int kLaneCount = lane_count; \ |
457 HandleScope scope(isolate); \ | 457 HandleScope scope(isolate); \ |
458 DCHECK(args.length() == 2); \ | 458 DCHECK_EQ(2, args.length()); \ |
459 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 459 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
460 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 460 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
461 shift &= lane_bits - 1; \ | 461 shift &= lane_bits - 1; \ |
462 lane_type lanes[kLaneCount]; \ | 462 lane_type lanes[kLaneCount]; \ |
463 for (int i = 0; i < kLaneCount; i++) { \ | 463 for (int i = 0; i < kLaneCount; i++) { \ |
464 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ | 464 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ |
465 lanes[i] = static_cast<lane_type>(shifted); \ | 465 lanes[i] = static_cast<lane_type>(shifted); \ |
466 } \ | 466 } \ |
467 Handle<type> result = isolate->factory()->New##type(lanes); \ | 467 Handle<type> result = isolate->factory()->New##type(lanes); \ |
468 return *result; \ | 468 return *result; \ |
469 } | 469 } |
470 | 470 |
471 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) | 471 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) |
472 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) | 472 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) |
473 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) | 473 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) |
474 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) | 474 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) |
475 | 475 |
476 //------------------------------------------------------------------- | 476 //------------------------------------------------------------------- |
477 | 477 |
478 // Bool-only functions. | 478 // Bool-only functions. |
479 | 479 |
480 #define SIMD_BOOL_TYPES(FUNCTION) \ | 480 #define SIMD_BOOL_TYPES(FUNCTION) \ |
481 FUNCTION(Bool32x4, 4) \ | 481 FUNCTION(Bool32x4, 4) \ |
482 FUNCTION(Bool16x8, 8) \ | 482 FUNCTION(Bool16x8, 8) \ |
483 FUNCTION(Bool8x16, 16) | 483 FUNCTION(Bool8x16, 16) |
484 | 484 |
485 #define SIMD_ANY_FUNCTION(type, lane_count) \ | 485 #define SIMD_ANY_FUNCTION(type, lane_count) \ |
486 RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ | 486 RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ |
487 HandleScope scope(isolate); \ | 487 HandleScope scope(isolate); \ |
488 DCHECK(args.length() == 1); \ | 488 DCHECK_EQ(1, args.length()); \ |
489 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 489 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
490 bool result = false; \ | 490 bool result = false; \ |
491 for (int i = 0; i < lane_count; i++) { \ | 491 for (int i = 0; i < lane_count; i++) { \ |
492 if (a->get_lane(i)) { \ | 492 if (a->get_lane(i)) { \ |
493 result = true; \ | 493 result = true; \ |
494 break; \ | 494 break; \ |
495 } \ | 495 } \ |
496 } \ | 496 } \ |
497 return isolate->heap()->ToBoolean(result); \ | 497 return isolate->heap()->ToBoolean(result); \ |
498 } | 498 } |
499 | 499 |
500 #define SIMD_ALL_FUNCTION(type, lane_count) \ | 500 #define SIMD_ALL_FUNCTION(type, lane_count) \ |
501 RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ | 501 RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ |
502 HandleScope scope(isolate); \ | 502 HandleScope scope(isolate); \ |
503 DCHECK(args.length() == 1); \ | 503 DCHECK_EQ(1, args.length()); \ |
504 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ | 504 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
505 bool result = true; \ | 505 bool result = true; \ |
506 for (int i = 0; i < lane_count; i++) { \ | 506 for (int i = 0; i < lane_count; i++) { \ |
507 if (!a->get_lane(i)) { \ | 507 if (!a->get_lane(i)) { \ |
508 result = false; \ | 508 result = false; \ |
509 break; \ | 509 break; \ |
510 } \ | 510 } \ |
511 } \ | 511 } \ |
512 return isolate->heap()->ToBoolean(result); \ | 512 return isolate->heap()->ToBoolean(result); \ |
513 } | 513 } |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 FUNCTION(Uint32x4, uint32_t, Bool32x4, 4) \ | 735 FUNCTION(Uint32x4, uint32_t, Bool32x4, 4) \ |
736 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ | 736 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ |
737 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ | 737 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ |
738 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ | 738 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ |
739 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) | 739 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) |
740 | 740 |
741 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ | 741 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ |
742 RUNTIME_FUNCTION(Runtime_##type##Select) { \ | 742 RUNTIME_FUNCTION(Runtime_##type##Select) { \ |
743 static const int kLaneCount = lane_count; \ | 743 static const int kLaneCount = lane_count; \ |
744 HandleScope scope(isolate); \ | 744 HandleScope scope(isolate); \ |
745 DCHECK(args.length() == 3); \ | 745 DCHECK_EQ(3, args.length()); \ |
746 CONVERT_SIMD_ARG_HANDLE_THROW(bool_type, mask, 0); \ | 746 CONVERT_SIMD_ARG_HANDLE_THROW(bool_type, mask, 0); \ |
747 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 1); \ | 747 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 1); \ |
748 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 2); \ | 748 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 2); \ |
749 lane_type lanes[kLaneCount]; \ | 749 lane_type lanes[kLaneCount]; \ |
750 for (int i = 0; i < kLaneCount; i++) { \ | 750 for (int i = 0; i < kLaneCount; i++) { \ |
751 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ | 751 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ |
752 } \ | 752 } \ |
753 Handle<type> result = isolate->factory()->New##type(lanes); \ | 753 Handle<type> result = isolate->factory()->New##type(lanes); \ |
754 return *result; \ | 754 return *result; \ |
755 } | 755 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 FUNCTION(Uint32x4, uint32_t, 4, Int32x4, int32_t) \ | 788 FUNCTION(Uint32x4, uint32_t, 4, Int32x4, int32_t) \ |
789 FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ | 789 FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ |
790 FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ | 790 FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ |
791 FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ | 791 FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ |
792 FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) | 792 FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) |
793 | 793 |
794 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ | 794 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ |
795 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ | 795 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ |
796 static const int kLaneCount = lane_count; \ | 796 static const int kLaneCount = lane_count; \ |
797 HandleScope scope(isolate); \ | 797 HandleScope scope(isolate); \ |
798 DCHECK(args.length() == 1); \ | 798 DCHECK_EQ(1, args.length()); \ |
799 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ | 799 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ |
800 lane_type lanes[kLaneCount]; \ | 800 lane_type lanes[kLaneCount]; \ |
801 for (int i = 0; i < kLaneCount; i++) { \ | 801 for (int i = 0; i < kLaneCount; i++) { \ |
802 from_ctype a_value = a->get_lane(i); \ | 802 from_ctype a_value = a->get_lane(i); \ |
803 if (a_value != a_value || !CanCast<lane_type>(a_value)) { \ | 803 if (a_value != a_value || !CanCast<lane_type>(a_value)) { \ |
804 THROW_NEW_ERROR_RETURN_FAILURE( \ | 804 THROW_NEW_ERROR_RETURN_FAILURE( \ |
805 isolate, NewRangeError(MessageTemplate::kInvalidSimdLaneValue)); \ | 805 isolate, NewRangeError(MessageTemplate::kInvalidSimdLaneValue)); \ |
806 } \ | 806 } \ |
807 lanes[i] = static_cast<lane_type>(a_value); \ | 807 lanes[i] = static_cast<lane_type>(a_value); \ |
808 } \ | 808 } \ |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 FUNCTION(Uint8x16, uint8_t, 16, Int32x4) \ | 853 FUNCTION(Uint8x16, uint8_t, 16, Int32x4) \ |
854 FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ | 854 FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ |
855 FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ | 855 FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ |
856 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ | 856 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ |
857 FUNCTION(Uint8x16, uint8_t, 16, Int8x16) | 857 FUNCTION(Uint8x16, uint8_t, 16, Int8x16) |
858 | 858 |
859 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ | 859 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ |
860 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ | 860 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ |
861 static const int kLaneCount = lane_count; \ | 861 static const int kLaneCount = lane_count; \ |
862 HandleScope scope(isolate); \ | 862 HandleScope scope(isolate); \ |
863 DCHECK(args.length() == 1); \ | 863 DCHECK_EQ(1, args.length()); \ |
864 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ | 864 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ |
865 lane_type lanes[kLaneCount]; \ | 865 lane_type lanes[kLaneCount]; \ |
866 a->CopyBits(lanes); \ | 866 a->CopyBits(lanes); \ |
867 Handle<type> result = isolate->factory()->New##type(lanes); \ | 867 Handle<type> result = isolate->factory()->New##type(lanes); \ |
868 return *result; \ | 868 return *result; \ |
869 } | 869 } |
870 | 870 |
871 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) | 871 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) |
872 | 872 |
873 | 873 |
(...skipping 15 matching lines...) Expand all Loading... |
889 if (number_object->Number() != length_object->Number()) { \ | 889 if (number_object->Number() != length_object->Number()) { \ |
890 THROW_NEW_ERROR_RETURN_FAILURE( \ | 890 THROW_NEW_ERROR_RETURN_FAILURE( \ |
891 isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ | 891 isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ |
892 } \ | 892 } \ |
893 int32_t name = number_object->Number(); | 893 int32_t name = number_object->Number(); |
894 | 894 |
895 // Common Load and Store Functions | 895 // Common Load and Store Functions |
896 | 896 |
897 #define SIMD_LOAD(type, lane_type, lane_count, count, result) \ | 897 #define SIMD_LOAD(type, lane_type, lane_count, count, result) \ |
898 static const int kLaneCount = lane_count; \ | 898 static const int kLaneCount = lane_count; \ |
899 DCHECK(args.length() == 2); \ | 899 DCHECK_EQ(2, args.length()); \ |
900 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ | 900 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ |
901 SIMD_COERCE_INDEX(index, 1); \ | 901 SIMD_COERCE_INDEX(index, 1); \ |
902 size_t bpe = tarray->element_size(); \ | 902 size_t bpe = tarray->element_size(); \ |
903 uint32_t bytes = count * sizeof(lane_type); \ | 903 uint32_t bytes = count * sizeof(lane_type); \ |
904 size_t byte_length = NumberToSize(tarray->byte_length()); \ | 904 size_t byte_length = NumberToSize(tarray->byte_length()); \ |
905 if (index < 0 || index * bpe + bytes > byte_length) { \ | 905 if (index < 0 || index * bpe + bytes > byte_length) { \ |
906 THROW_NEW_ERROR_RETURN_FAILURE( \ | 906 THROW_NEW_ERROR_RETURN_FAILURE( \ |
907 isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ | 907 isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ |
908 } \ | 908 } \ |
909 size_t tarray_offset = NumberToSize(tarray->byte_offset()); \ | 909 size_t tarray_offset = NumberToSize(tarray->byte_offset()); \ |
910 uint8_t* tarray_base = \ | 910 uint8_t* tarray_base = \ |
911 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ | 911 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ |
912 tarray_offset; \ | 912 tarray_offset; \ |
913 lane_type lanes[kLaneCount] = {0}; \ | 913 lane_type lanes[kLaneCount] = {0}; \ |
914 memcpy(lanes, tarray_base + index * bpe, bytes); \ | 914 memcpy(lanes, tarray_base + index * bpe, bytes); \ |
915 Handle<type> result = isolate->factory()->New##type(lanes); | 915 Handle<type> result = isolate->factory()->New##type(lanes); |
916 | 916 |
917 #define SIMD_STORE(type, lane_type, lane_count, count, a) \ | 917 #define SIMD_STORE(type, lane_type, lane_count, count, a) \ |
918 static const int kLaneCount = lane_count; \ | 918 static const int kLaneCount = lane_count; \ |
919 DCHECK(args.length() == 3); \ | 919 DCHECK_EQ(3, args.length()); \ |
920 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ | 920 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ |
921 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 2); \ | 921 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 2); \ |
922 SIMD_COERCE_INDEX(index, 1); \ | 922 SIMD_COERCE_INDEX(index, 1); \ |
923 size_t bpe = tarray->element_size(); \ | 923 size_t bpe = tarray->element_size(); \ |
924 uint32_t bytes = count * sizeof(lane_type); \ | 924 uint32_t bytes = count * sizeof(lane_type); \ |
925 size_t byte_length = NumberToSize(tarray->byte_length()); \ | 925 size_t byte_length = NumberToSize(tarray->byte_length()); \ |
926 if (index < 0 || byte_length < index * bpe + bytes) { \ | 926 if (index < 0 || byte_length < index * bpe + bytes) { \ |
927 THROW_NEW_ERROR_RETURN_FAILURE( \ | 927 THROW_NEW_ERROR_RETURN_FAILURE( \ |
928 isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ | 928 isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ |
929 } \ | 929 } \ |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 SIMD_LOADN_STOREN_TYPES(SIMD_LOAD3_FUNCTION) | 1007 SIMD_LOADN_STOREN_TYPES(SIMD_LOAD3_FUNCTION) |
1008 SIMD_NUMERIC_TYPES(SIMD_STORE_FUNCTION) | 1008 SIMD_NUMERIC_TYPES(SIMD_STORE_FUNCTION) |
1009 SIMD_LOADN_STOREN_TYPES(SIMD_STORE1_FUNCTION) | 1009 SIMD_LOADN_STOREN_TYPES(SIMD_STORE1_FUNCTION) |
1010 SIMD_LOADN_STOREN_TYPES(SIMD_STORE2_FUNCTION) | 1010 SIMD_LOADN_STOREN_TYPES(SIMD_STORE2_FUNCTION) |
1011 SIMD_LOADN_STOREN_TYPES(SIMD_STORE3_FUNCTION) | 1011 SIMD_LOADN_STOREN_TYPES(SIMD_STORE3_FUNCTION) |
1012 | 1012 |
1013 //------------------------------------------------------------------- | 1013 //------------------------------------------------------------------- |
1014 | 1014 |
1015 } // namespace internal | 1015 } // namespace internal |
1016 } // namespace v8 | 1016 } // namespace v8 |
OLD | NEW |