| 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 |