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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 205 |
206 | 206 |
207 //------------------------------------------------------------------- | 207 //------------------------------------------------------------------- |
208 | 208 |
209 // Utility macros. | 209 // Utility macros. |
210 | 210 |
211 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ | 211 #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ |
212 CONVERT_INT32_ARG_CHECKED(name, index); \ | 212 CONVERT_INT32_ARG_CHECKED(name, index); \ |
213 RUNTIME_ASSERT(name >= 0 && name < lanes); | 213 RUNTIME_ASSERT(name >= 0 && name < lanes); |
214 | 214 |
| 215 #define CONVERT_SIMD_ARG_HANDLE_THROW(Type, name, index) \ |
| 216 Handle<Type> name; \ |
| 217 if (args[index]->Is##Type()) { \ |
| 218 name = args.at<Type>(index); \ |
| 219 } else { \ |
| 220 THROW_NEW_ERROR_RETURN_FAILURE( \ |
| 221 isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ |
| 222 } |
| 223 |
215 #define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ | 224 #define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ |
216 static const int kLaneCount = lane_count; \ | 225 static const int kLaneCount = lane_count; \ |
217 DCHECK(args.length() == 1); \ | 226 DCHECK(args.length() == 1); \ |
218 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 227 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
219 lane_type lanes[kLaneCount]; \ | 228 lane_type lanes[kLaneCount]; \ |
220 for (int i = 0; i < kLaneCount; i++) { \ | 229 for (int i = 0; i < kLaneCount; i++) { \ |
221 lanes[i] = op(a->get_lane(i)); \ | 230 lanes[i] = op(a->get_lane(i)); \ |
222 } \ | 231 } \ |
223 Handle<type> result = isolate->factory()->New##type(lanes); | 232 Handle<type> result = isolate->factory()->New##type(lanes); |
224 | 233 |
225 #define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ | 234 #define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ |
226 static const int kLaneCount = lane_count; \ | 235 static const int kLaneCount = lane_count; \ |
227 DCHECK(args.length() == 2); \ | 236 DCHECK(args.length() == 2); \ |
228 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 237 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
229 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | 238 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ |
230 lane_type lanes[kLaneCount]; \ | 239 lane_type lanes[kLaneCount]; \ |
231 for (int i = 0; i < kLaneCount; i++) { \ | 240 for (int i = 0; i < kLaneCount; i++) { \ |
232 lanes[i] = op(a->get_lane(i), b->get_lane(i)); \ | 241 lanes[i] = op(a->get_lane(i), b->get_lane(i)); \ |
233 } \ | 242 } \ |
234 Handle<type> result = isolate->factory()->New##type(lanes); | 243 Handle<type> result = isolate->factory()->New##type(lanes); |
235 | 244 |
236 #define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ | 245 #define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ |
237 static const int kLaneCount = lane_count; \ | 246 static const int kLaneCount = lane_count; \ |
238 DCHECK(args.length() == 2); \ | 247 DCHECK(args.length() == 2); \ |
239 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 248 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
240 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | 249 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ |
241 bool lanes[kLaneCount]; \ | 250 bool lanes[kLaneCount]; \ |
242 for (int i = 0; i < kLaneCount; i++) { \ | 251 for (int i = 0; i < kLaneCount; i++) { \ |
243 lanes[i] = a->get_lane(i) op b->get_lane(i); \ | 252 lanes[i] = a->get_lane(i) op b->get_lane(i); \ |
244 } \ | 253 } \ |
245 Handle<bool_type> result = isolate->factory()->New##bool_type(lanes); | 254 Handle<bool_type> result = isolate->factory()->New##bool_type(lanes); |
246 | 255 |
247 //------------------------------------------------------------------- | 256 //------------------------------------------------------------------- |
248 | 257 |
249 // Common functions. | 258 // Common functions. |
250 | 259 |
(...skipping 25 matching lines...) Expand all Loading... |
276 for (int i = 0; i < kLaneCount; i++) { \ | 285 for (int i = 0; i < kLaneCount; i++) { \ |
277 replace(lane_type, lanes[i], i) \ | 286 replace(lane_type, lanes[i], i) \ |
278 } \ | 287 } \ |
279 return *isolate->factory()->New##type(lanes); \ | 288 return *isolate->factory()->New##type(lanes); \ |
280 } | 289 } |
281 | 290 |
282 #define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 291 #define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
283 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ | 292 RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ |
284 HandleScope scope(isolate); \ | 293 HandleScope scope(isolate); \ |
285 DCHECK(args.length() == 2); \ | 294 DCHECK(args.length() == 2); \ |
286 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 295 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
287 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ | 296 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ |
288 return *isolate->factory()->extract(a->get_lane(lane)); \ | 297 return *isolate->factory()->extract(a->get_lane(lane)); \ |
289 } | 298 } |
290 | 299 |
291 #define SIMD_REPLACE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 300 #define SIMD_REPLACE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
292 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ | 301 RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ |
293 static const int kLaneCount = lane_count; \ | 302 static const int kLaneCount = lane_count; \ |
294 HandleScope scope(isolate); \ | 303 HandleScope scope(isolate); \ |
295 DCHECK(args.length() == 3); \ | 304 DCHECK(args.length() == 3); \ |
296 CONVERT_ARG_HANDLE_CHECKED(type, simd, 0); \ | 305 CONVERT_SIMD_ARG_HANDLE_THROW(type, simd, 0); \ |
297 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ | 306 CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ |
298 lane_type lanes[kLaneCount]; \ | 307 lane_type lanes[kLaneCount]; \ |
299 for (int i = 0; i < kLaneCount; i++) { \ | 308 for (int i = 0; i < kLaneCount; i++) { \ |
300 lanes[i] = simd->get_lane(i); \ | 309 lanes[i] = simd->get_lane(i); \ |
301 } \ | 310 } \ |
302 replace(lane_type, lanes[lane], 2); \ | 311 replace(lane_type, lanes[lane], 2); \ |
303 Handle<type> result = isolate->factory()->New##type(lanes); \ | 312 Handle<type> result = isolate->factory()->New##type(lanes); \ |
304 return *result; \ | 313 return *result; \ |
305 } | 314 } |
306 | 315 |
307 #define SIMD_CHECK_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 316 #define SIMD_CHECK_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
308 RUNTIME_FUNCTION(Runtime_##type##Check) { \ | 317 RUNTIME_FUNCTION(Runtime_##type##Check) { \ |
309 HandleScope scope(isolate); \ | 318 HandleScope scope(isolate); \ |
310 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 319 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
311 return *a; \ | 320 return *a; \ |
312 } | 321 } |
313 | 322 |
314 #define SIMD_SWIZZLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 323 #define SIMD_SWIZZLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
315 RUNTIME_FUNCTION(Runtime_##type##Swizzle) { \ | 324 RUNTIME_FUNCTION(Runtime_##type##Swizzle) { \ |
316 static const int kLaneCount = lane_count; \ | 325 static const int kLaneCount = lane_count; \ |
317 HandleScope scope(isolate); \ | 326 HandleScope scope(isolate); \ |
318 DCHECK(args.length() == 1 + kLaneCount); \ | 327 DCHECK(args.length() == 1 + kLaneCount); \ |
319 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 328 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
320 lane_type lanes[kLaneCount]; \ | 329 lane_type lanes[kLaneCount]; \ |
321 for (int i = 0; i < kLaneCount; i++) { \ | 330 for (int i = 0; i < kLaneCount; i++) { \ |
322 CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 1, kLaneCount); \ | 331 CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 1, kLaneCount); \ |
323 lanes[i] = a->get_lane(index); \ | 332 lanes[i] = a->get_lane(index); \ |
324 } \ | 333 } \ |
325 Handle<type> result = isolate->factory()->New##type(lanes); \ | 334 Handle<type> result = isolate->factory()->New##type(lanes); \ |
326 return *result; \ | 335 return *result; \ |
327 } | 336 } |
328 | 337 |
329 #define SIMD_SHUFFLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ | 338 #define SIMD_SHUFFLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ |
330 RUNTIME_FUNCTION(Runtime_##type##Shuffle) { \ | 339 RUNTIME_FUNCTION(Runtime_##type##Shuffle) { \ |
331 static const int kLaneCount = lane_count; \ | 340 static const int kLaneCount = lane_count; \ |
332 HandleScope scope(isolate); \ | 341 HandleScope scope(isolate); \ |
333 DCHECK(args.length() == 2 + kLaneCount); \ | 342 DCHECK(args.length() == 2 + kLaneCount); \ |
334 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 343 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
335 CONVERT_ARG_HANDLE_CHECKED(type, b, 1); \ | 344 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ |
336 lane_type lanes[kLaneCount]; \ | 345 lane_type lanes[kLaneCount]; \ |
337 for (int i = 0; i < kLaneCount; i++) { \ | 346 for (int i = 0; i < kLaneCount; i++) { \ |
338 CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 2, kLaneCount * 2); \ | 347 CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 2, kLaneCount * 2); \ |
339 lanes[i] = index < kLaneCount ? a->get_lane(index) \ | 348 lanes[i] = index < kLaneCount ? a->get_lane(index) \ |
340 : b->get_lane(index - kLaneCount); \ | 349 : b->get_lane(index - kLaneCount); \ |
341 } \ | 350 } \ |
342 Handle<type> result = isolate->factory()->New##type(lanes); \ | 351 Handle<type> result = isolate->factory()->New##type(lanes); \ |
343 return *result; \ | 352 return *result; \ |
344 } | 353 } |
345 | 354 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 RUNTIME_ASSERT(args[index]->IsNumber()); \ | 439 RUNTIME_ASSERT(args[index]->IsNumber()); \ |
431 int32_t signed_shift = 0; \ | 440 int32_t signed_shift = 0; \ |
432 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ | 441 RUNTIME_ASSERT(args[index]->ToInt32(&signed_shift)); \ |
433 uint32_t name = bit_cast<uint32_t>(signed_shift); | 442 uint32_t name = bit_cast<uint32_t>(signed_shift); |
434 | 443 |
435 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 444 #define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
436 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ | 445 RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ |
437 static const int kLaneCount = lane_count; \ | 446 static const int kLaneCount = lane_count; \ |
438 HandleScope scope(isolate); \ | 447 HandleScope scope(isolate); \ |
439 DCHECK(args.length() == 2); \ | 448 DCHECK(args.length() == 2); \ |
440 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 449 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
441 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 450 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
442 lane_type lanes[kLaneCount] = {0}; \ | 451 lane_type lanes[kLaneCount] = {0}; \ |
443 if (shift < lane_bits) { \ | 452 if (shift < lane_bits) { \ |
444 for (int i = 0; i < kLaneCount; i++) { \ | 453 for (int i = 0; i < kLaneCount; i++) { \ |
445 lanes[i] = a->get_lane(i) << shift; \ | 454 lanes[i] = a->get_lane(i) << shift; \ |
446 } \ | 455 } \ |
447 } \ | 456 } \ |
448 Handle<type> result = isolate->factory()->New##type(lanes); \ | 457 Handle<type> result = isolate->factory()->New##type(lanes); \ |
449 return *result; \ | 458 return *result; \ |
450 } | 459 } |
451 | 460 |
452 #define SIMD_LSR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 461 #define SIMD_LSR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
453 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ | 462 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ |
454 static const int kLaneCount = lane_count; \ | 463 static const int kLaneCount = lane_count; \ |
455 HandleScope scope(isolate); \ | 464 HandleScope scope(isolate); \ |
456 DCHECK(args.length() == 2); \ | 465 DCHECK(args.length() == 2); \ |
457 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 466 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
458 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 467 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
459 lane_type lanes[kLaneCount] = {0}; \ | 468 lane_type lanes[kLaneCount] = {0}; \ |
460 if (shift < lane_bits) { \ | 469 if (shift < lane_bits) { \ |
461 for (int i = 0; i < kLaneCount; i++) { \ | 470 for (int i = 0; i < kLaneCount; i++) { \ |
462 lanes[i] = static_cast<lane_type>( \ | 471 lanes[i] = static_cast<lane_type>( \ |
463 bit_cast<lane_type>(a->get_lane(i)) >> shift); \ | 472 bit_cast<lane_type>(a->get_lane(i)) >> shift); \ |
464 } \ | 473 } \ |
465 } \ | 474 } \ |
466 Handle<type> result = isolate->factory()->New##type(lanes); \ | 475 Handle<type> result = isolate->factory()->New##type(lanes); \ |
467 return *result; \ | 476 return *result; \ |
468 } | 477 } |
469 | 478 |
470 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ | 479 #define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ |
471 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ | 480 RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ |
472 static const int kLaneCount = lane_count; \ | 481 static const int kLaneCount = lane_count; \ |
473 HandleScope scope(isolate); \ | 482 HandleScope scope(isolate); \ |
474 DCHECK(args.length() == 2); \ | 483 DCHECK(args.length() == 2); \ |
475 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 484 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
476 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ | 485 CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ |
477 if (shift >= lane_bits) shift = lane_bits - 1; \ | 486 if (shift >= lane_bits) shift = lane_bits - 1; \ |
478 lane_type lanes[kLaneCount]; \ | 487 lane_type lanes[kLaneCount]; \ |
479 for (int i = 0; i < kLaneCount; i++) { \ | 488 for (int i = 0; i < kLaneCount; i++) { \ |
480 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ | 489 int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ |
481 lanes[i] = static_cast<lane_type>(shifted); \ | 490 lanes[i] = static_cast<lane_type>(shifted); \ |
482 } \ | 491 } \ |
483 Handle<type> result = isolate->factory()->New##type(lanes); \ | 492 Handle<type> result = isolate->factory()->New##type(lanes); \ |
484 return *result; \ | 493 return *result; \ |
485 } | 494 } |
486 | 495 |
487 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) | 496 SIMD_INT_TYPES(SIMD_LSL_FUNCTION) |
488 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) | 497 SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) |
489 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) | 498 SIMD_INT_TYPES(SIMD_ASR_FUNCTION) |
490 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) | 499 SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) |
491 | 500 |
492 //------------------------------------------------------------------- | 501 //------------------------------------------------------------------- |
493 | 502 |
494 // Bool-only functions. | 503 // Bool-only functions. |
495 | 504 |
496 #define SIMD_BOOL_TYPES(FUNCTION) \ | 505 #define SIMD_BOOL_TYPES(FUNCTION) \ |
497 FUNCTION(Bool32x4, 4) \ | 506 FUNCTION(Bool32x4, 4) \ |
498 FUNCTION(Bool16x8, 8) \ | 507 FUNCTION(Bool16x8, 8) \ |
499 FUNCTION(Bool8x16, 16) | 508 FUNCTION(Bool8x16, 16) |
500 | 509 |
501 #define SIMD_ANY_FUNCTION(type, lane_count) \ | 510 #define SIMD_ANY_FUNCTION(type, lane_count) \ |
502 RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ | 511 RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ |
503 HandleScope scope(isolate); \ | 512 HandleScope scope(isolate); \ |
504 DCHECK(args.length() == 1); \ | 513 DCHECK(args.length() == 1); \ |
505 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 514 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
506 bool result = false; \ | 515 bool result = false; \ |
507 for (int i = 0; i < lane_count; i++) { \ | 516 for (int i = 0; i < lane_count; i++) { \ |
508 if (a->get_lane(i)) { \ | 517 if (a->get_lane(i)) { \ |
509 result = true; \ | 518 result = true; \ |
510 break; \ | 519 break; \ |
511 } \ | 520 } \ |
512 } \ | 521 } \ |
513 return isolate->heap()->ToBoolean(result); \ | 522 return isolate->heap()->ToBoolean(result); \ |
514 } | 523 } |
515 | 524 |
516 #define SIMD_ALL_FUNCTION(type, lane_count) \ | 525 #define SIMD_ALL_FUNCTION(type, lane_count) \ |
517 RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ | 526 RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ |
518 HandleScope scope(isolate); \ | 527 HandleScope scope(isolate); \ |
519 DCHECK(args.length() == 1); \ | 528 DCHECK(args.length() == 1); \ |
520 CONVERT_ARG_HANDLE_CHECKED(type, a, 0); \ | 529 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ |
521 bool result = true; \ | 530 bool result = true; \ |
522 for (int i = 0; i < lane_count; i++) { \ | 531 for (int i = 0; i < lane_count; i++) { \ |
523 if (!a->get_lane(i)) { \ | 532 if (!a->get_lane(i)) { \ |
524 result = false; \ | 533 result = false; \ |
525 break; \ | 534 break; \ |
526 } \ | 535 } \ |
527 } \ | 536 } \ |
528 return isolate->heap()->ToBoolean(result); \ | 537 return isolate->heap()->ToBoolean(result); \ |
529 } | 538 } |
530 | 539 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ | 761 FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ |
753 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ | 762 FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ |
754 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ | 763 FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ |
755 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) | 764 FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) |
756 | 765 |
757 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ | 766 #define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ |
758 RUNTIME_FUNCTION(Runtime_##type##Select) { \ | 767 RUNTIME_FUNCTION(Runtime_##type##Select) { \ |
759 static const int kLaneCount = lane_count; \ | 768 static const int kLaneCount = lane_count; \ |
760 HandleScope scope(isolate); \ | 769 HandleScope scope(isolate); \ |
761 DCHECK(args.length() == 3); \ | 770 DCHECK(args.length() == 3); \ |
762 CONVERT_ARG_HANDLE_CHECKED(bool_type, mask, 0); \ | 771 CONVERT_SIMD_ARG_HANDLE_THROW(bool_type, mask, 0); \ |
763 CONVERT_ARG_HANDLE_CHECKED(type, a, 1); \ | 772 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 1); \ |
764 CONVERT_ARG_HANDLE_CHECKED(type, b, 2); \ | 773 CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 2); \ |
765 lane_type lanes[kLaneCount]; \ | 774 lane_type lanes[kLaneCount]; \ |
766 for (int i = 0; i < kLaneCount; i++) { \ | 775 for (int i = 0; i < kLaneCount; i++) { \ |
767 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ | 776 lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ |
768 } \ | 777 } \ |
769 Handle<type> result = isolate->factory()->New##type(lanes); \ | 778 Handle<type> result = isolate->factory()->New##type(lanes); \ |
770 return *result; \ | 779 return *result; \ |
771 } | 780 } |
772 | 781 |
773 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) | 782 SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) |
774 | 783 |
(...skipping 30 matching lines...) Expand all Loading... |
805 FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ | 814 FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ |
806 FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ | 815 FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ |
807 FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ | 816 FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ |
808 FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) | 817 FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) |
809 | 818 |
810 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ | 819 #define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ |
811 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ | 820 RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ |
812 static const int kLaneCount = lane_count; \ | 821 static const int kLaneCount = lane_count; \ |
813 HandleScope scope(isolate); \ | 822 HandleScope scope(isolate); \ |
814 DCHECK(args.length() == 1); \ | 823 DCHECK(args.length() == 1); \ |
815 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 824 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ |
816 lane_type lanes[kLaneCount]; \ | 825 lane_type lanes[kLaneCount]; \ |
817 for (int i = 0; i < kLaneCount; i++) { \ | 826 for (int i = 0; i < kLaneCount; i++) { \ |
818 from_ctype a_value = a->get_lane(i); \ | 827 from_ctype a_value = a->get_lane(i); \ |
819 if (a_value != a_value) a_value = 0; \ | 828 if (a_value != a_value) a_value = 0; \ |
820 RUNTIME_ASSERT(CanCast<lane_type>(a_value)); \ | 829 RUNTIME_ASSERT(CanCast<lane_type>(a_value)); \ |
821 lanes[i] = static_cast<lane_type>(a_value); \ | 830 lanes[i] = static_cast<lane_type>(a_value); \ |
822 } \ | 831 } \ |
823 Handle<type> result = isolate->factory()->New##type(lanes); \ | 832 Handle<type> result = isolate->factory()->New##type(lanes); \ |
824 return *result; \ | 833 return *result; \ |
825 } | 834 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ | 877 FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ |
869 FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ | 878 FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ |
870 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ | 879 FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ |
871 FUNCTION(Uint8x16, uint8_t, 16, Int8x16) | 880 FUNCTION(Uint8x16, uint8_t, 16, Int8x16) |
872 | 881 |
873 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ | 882 #define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ |
874 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ | 883 RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ |
875 static const int kLaneCount = lane_count; \ | 884 static const int kLaneCount = lane_count; \ |
876 HandleScope scope(isolate); \ | 885 HandleScope scope(isolate); \ |
877 DCHECK(args.length() == 1); \ | 886 DCHECK(args.length() == 1); \ |
878 CONVERT_ARG_HANDLE_CHECKED(from_type, a, 0); \ | 887 CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ |
879 lane_type lanes[kLaneCount]; \ | 888 lane_type lanes[kLaneCount]; \ |
880 a->CopyBits(lanes); \ | 889 a->CopyBits(lanes); \ |
881 Handle<type> result = isolate->factory()->New##type(lanes); \ | 890 Handle<type> result = isolate->factory()->New##type(lanes); \ |
882 return *result; \ | 891 return *result; \ |
883 } | 892 } |
884 | 893 |
885 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) | 894 SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) |
886 | 895 |
887 | 896 |
888 //------------------------------------------------------------------- | 897 //------------------------------------------------------------------- |
889 | 898 |
890 // Load and Store functions. | 899 // Load and Store functions. |
891 | 900 |
892 #define SIMD_LOADN_STOREN_TYPES(FUNCTION) \ | 901 #define SIMD_LOADN_STOREN_TYPES(FUNCTION) \ |
893 FUNCTION(Float32x4, float, 4) \ | 902 FUNCTION(Float32x4, float, 4) \ |
894 FUNCTION(Int32x4, int32_t, 4) \ | 903 FUNCTION(Int32x4, int32_t, 4) \ |
895 FUNCTION(Uint32x4, uint32_t, 4) | 904 FUNCTION(Uint32x4, uint32_t, 4) |
896 | 905 |
897 | 906 |
898 // Common Load and Store Functions | 907 // Common Load and Store Functions |
899 | 908 |
900 #define SIMD_LOAD(type, lane_type, lane_count, count, result) \ | 909 #define SIMD_LOAD(type, lane_type, lane_count, count, result) \ |
901 static const int kLaneCount = lane_count; \ | 910 static const int kLaneCount = lane_count; \ |
902 DCHECK(args.length() == 2); \ | 911 DCHECK(args.length() == 2); \ |
903 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, tarray, 0); \ | 912 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ |
904 CONVERT_INT32_ARG_CHECKED(index, 1) \ | 913 CONVERT_INT32_ARG_CHECKED(index, 1) \ |
905 size_t bpe = tarray->element_size(); \ | 914 size_t bpe = tarray->element_size(); \ |
906 uint32_t bytes = count * sizeof(lane_type); \ | 915 uint32_t bytes = count * sizeof(lane_type); \ |
907 size_t byte_length = NumberToSize(isolate, tarray->byte_length()); \ | 916 size_t byte_length = NumberToSize(isolate, tarray->byte_length()); \ |
908 RUNTIME_ASSERT(index >= 0 && index * bpe + bytes <= byte_length); \ | 917 RUNTIME_ASSERT(index >= 0 && index * bpe + bytes <= byte_length); \ |
909 size_t tarray_offset = NumberToSize(isolate, tarray->byte_offset()); \ | 918 size_t tarray_offset = NumberToSize(isolate, tarray->byte_offset()); \ |
910 uint8_t* tarray_base = \ | 919 uint8_t* tarray_base = \ |
911 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ | 920 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ |
912 tarray_offset; \ | 921 tarray_offset; \ |
913 lane_type lanes[kLaneCount] = {0}; \ | 922 lane_type lanes[kLaneCount] = {0}; \ |
914 memcpy(lanes, tarray_base + index * bpe, bytes); \ | 923 memcpy(lanes, tarray_base + index * bpe, bytes); \ |
915 Handle<type> result = isolate->factory()->New##type(lanes); | 924 Handle<type> result = isolate->factory()->New##type(lanes); |
916 | 925 |
917 | 926 |
918 #define SIMD_STORE(type, lane_type, lane_count, count, a) \ | 927 #define SIMD_STORE(type, lane_type, lane_count, count, a) \ |
919 static const int kLaneCount = lane_count; \ | 928 static const int kLaneCount = lane_count; \ |
920 DCHECK(args.length() == 3); \ | 929 DCHECK(args.length() == 3); \ |
921 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, tarray, 0); \ | 930 CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ |
| 931 CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 2); \ |
922 CONVERT_INT32_ARG_CHECKED(index, 1) \ | 932 CONVERT_INT32_ARG_CHECKED(index, 1) \ |
923 CONVERT_ARG_HANDLE_CHECKED(type, a, 2); \ | |
924 size_t bpe = tarray->element_size(); \ | 933 size_t bpe = tarray->element_size(); \ |
925 uint32_t bytes = count * sizeof(lane_type); \ | 934 uint32_t bytes = count * sizeof(lane_type); \ |
926 size_t byte_length = NumberToSize(isolate, tarray->byte_length()); \ | 935 size_t byte_length = NumberToSize(isolate, tarray->byte_length()); \ |
927 RUNTIME_ASSERT(index >= 0 && index * bpe + bytes <= byte_length); \ | 936 RUNTIME_ASSERT(index >= 0 && index * bpe + bytes <= byte_length); \ |
928 size_t tarray_offset = NumberToSize(isolate, tarray->byte_offset()); \ | 937 size_t tarray_offset = NumberToSize(isolate, tarray->byte_offset()); \ |
929 uint8_t* tarray_base = \ | 938 uint8_t* tarray_base = \ |
930 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ | 939 static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ |
931 tarray_offset; \ | 940 tarray_offset; \ |
932 lane_type lanes[kLaneCount]; \ | 941 lane_type lanes[kLaneCount]; \ |
933 for (int i = 0; i < kLaneCount; i++) { \ | 942 for (int i = 0; i < kLaneCount; i++) { \ |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 SIMD_LOADN_STOREN_TYPES(SIMD_LOAD3_FUNCTION) | 1015 SIMD_LOADN_STOREN_TYPES(SIMD_LOAD3_FUNCTION) |
1007 SIMD_NUMERIC_TYPES(SIMD_STORE_FUNCTION) | 1016 SIMD_NUMERIC_TYPES(SIMD_STORE_FUNCTION) |
1008 SIMD_LOADN_STOREN_TYPES(SIMD_STORE1_FUNCTION) | 1017 SIMD_LOADN_STOREN_TYPES(SIMD_STORE1_FUNCTION) |
1009 SIMD_LOADN_STOREN_TYPES(SIMD_STORE2_FUNCTION) | 1018 SIMD_LOADN_STOREN_TYPES(SIMD_STORE2_FUNCTION) |
1010 SIMD_LOADN_STOREN_TYPES(SIMD_STORE3_FUNCTION) | 1019 SIMD_LOADN_STOREN_TYPES(SIMD_STORE3_FUNCTION) |
1011 | 1020 |
1012 //------------------------------------------------------------------- | 1021 //------------------------------------------------------------------- |
1013 | 1022 |
1014 } // namespace internal | 1023 } // namespace internal |
1015 } // namespace v8 | 1024 } // namespace v8 |
OLD | NEW |