| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 __ ret(); \ | 530 __ ret(); \ |
| 531 __ Bind(&fall_through); \ | 531 __ Bind(&fall_through); \ |
| 532 | 532 |
| 533 | 533 |
| 534 bool Intrinsifier::Int8Array_new(Assembler* assembler) { | 534 bool Intrinsifier::Int8Array_new(Assembler* assembler) { |
| 535 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); | 535 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); |
| 536 return false; | 536 return false; |
| 537 } | 537 } |
| 538 | 538 |
| 539 | 539 |
| 540 bool Intrinsifier::Int8Array_factory(Assembler* assembler) { |
| 541 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); |
| 542 return false; |
| 543 } |
| 544 |
| 545 |
| 540 bool Intrinsifier::Uint8Array_new(Assembler* assembler) { | 546 bool Intrinsifier::Uint8Array_new(Assembler* assembler) { |
| 541 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); | 547 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); |
| 542 return false; | 548 return false; |
| 543 } | 549 } |
| 544 | 550 |
| 545 | 551 |
| 552 bool Intrinsifier::Uint8Array_factory(Assembler* assembler) { |
| 553 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); |
| 554 return false; |
| 555 } |
| 556 |
| 557 |
| 546 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) { | 558 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) { |
| 547 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); | 559 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); |
| 548 return false; | 560 return false; |
| 549 } | 561 } |
| 550 | 562 |
| 551 | 563 |
| 564 bool Intrinsifier::Uint8ClampedArray_factory(Assembler* assembler) { |
| 565 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); |
| 566 return false; |
| 567 } |
| 568 |
| 569 |
| 552 bool Intrinsifier::Int16Array_new(Assembler* assembler) { | 570 bool Intrinsifier::Int16Array_new(Assembler* assembler) { |
| 553 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); | 571 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); |
| 554 return false; | 572 return false; |
| 555 } | 573 } |
| 556 | 574 |
| 557 | 575 |
| 576 bool Intrinsifier::Int16Array_factory(Assembler* assembler) { |
| 577 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); |
| 578 return false; |
| 579 } |
| 580 |
| 581 |
| 558 bool Intrinsifier::Uint16Array_new(Assembler* assembler) { | 582 bool Intrinsifier::Uint16Array_new(Assembler* assembler) { |
| 559 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); | 583 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); |
| 560 return false; | 584 return false; |
| 561 } | 585 } |
| 562 | 586 |
| 563 | 587 |
| 588 bool Intrinsifier::Uint16Array_factory(Assembler* assembler) { |
| 589 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); |
| 590 return false; |
| 591 } |
| 592 |
| 593 |
| 564 bool Intrinsifier::Int32Array_new(Assembler* assembler) { | 594 bool Intrinsifier::Int32Array_new(Assembler* assembler) { |
| 565 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); | 595 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); |
| 566 return false; | 596 return false; |
| 567 } | 597 } |
| 568 | 598 |
| 569 | 599 |
| 600 bool Intrinsifier::Int32Array_factory(Assembler* assembler) { |
| 601 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); |
| 602 return false; |
| 603 } |
| 604 |
| 605 |
| 570 bool Intrinsifier::Uint32Array_new(Assembler* assembler) { | 606 bool Intrinsifier::Uint32Array_new(Assembler* assembler) { |
| 571 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); | 607 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); |
| 572 return false; | 608 return false; |
| 573 } | 609 } |
| 574 | 610 |
| 575 | 611 |
| 612 bool Intrinsifier::Uint32Array_factory(Assembler* assembler) { |
| 613 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); |
| 614 return false; |
| 615 } |
| 616 |
| 617 |
| 576 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) { | 618 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) { |
| 577 Label fall_through; | 619 Label fall_through; |
| 578 TestByteArrayGetIndex(assembler, &fall_through); | 620 TestByteArrayGetIndex(assembler, &fall_through); |
| 579 // R12: index as Smi. | 621 // R12: index as Smi. |
| 580 // RAX: array. | 622 // RAX: array. |
| 581 __ movq(RAX, FieldAddress(RAX, | 623 __ movq(RAX, FieldAddress(RAX, |
| 582 R12, | 624 R12, |
| 583 TIMES_4, | 625 TIMES_4, |
| 584 Int64Array::data_offset())); | 626 Int64Array::data_offset())); |
| 585 // Copy RAX into R12. | 627 // Copy RAX into R12. |
| 586 // We destroy R12 while testing if RAX can fit inside a Smi. | 628 // We destroy R12 while testing if RAX can fit inside a Smi. |
| 587 __ movq(R12, RAX); | 629 __ movq(R12, RAX); |
| 588 // Verify that the signed value in RAX can fit inside a Smi. | 630 // Verify that the signed value in RAX can fit inside a Smi. |
| 589 __ shlq(R12, Immediate(0x1)); | 631 __ shlq(R12, Immediate(0x1)); |
| 590 // Jump to fall_through if it can not. | 632 // Jump to fall_through if it can not. |
| 591 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 633 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
| 592 __ SmiTag(RAX); | 634 __ SmiTag(RAX); |
| 593 __ ret(); | 635 __ ret(); |
| 594 __ Bind(&fall_through); | 636 __ Bind(&fall_through); |
| 595 return false; | 637 return false; |
| 596 } | 638 } |
| 597 | 639 |
| 598 | 640 |
| 599 bool Intrinsifier::Int64Array_new(Assembler* assembler) { | 641 bool Intrinsifier::Int64Array_new(Assembler* assembler) { |
| 600 TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8); | 642 TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8); |
| 601 return false; | 643 return false; |
| 602 } | 644 } |
| 603 | 645 |
| 604 | 646 |
| 647 bool Intrinsifier::Int64Array_factory(Assembler* assembler) { |
| 648 TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8); |
| 649 return false; |
| 650 } |
| 651 |
| 652 |
| 605 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) { | 653 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) { |
| 606 Label fall_through; | 654 Label fall_through; |
| 607 TestByteArrayGetIndex(assembler, &fall_through); | 655 TestByteArrayGetIndex(assembler, &fall_through); |
| 608 // R12: index as Smi. | 656 // R12: index as Smi. |
| 609 // RAX: array. | 657 // RAX: array. |
| 610 __ movq(RAX, FieldAddress(RAX, | 658 __ movq(RAX, FieldAddress(RAX, |
| 611 R12, | 659 R12, |
| 612 TIMES_4, | 660 TIMES_4, |
| 613 Uint64Array::data_offset())); | 661 Uint64Array::data_offset())); |
| 614 // Copy RAX into R12. | 662 // Copy RAX into R12. |
| 615 // We destroy R12 while testing if RAX can fit inside a Smi. | 663 // We destroy R12 while testing if RAX can fit inside a Smi. |
| 616 __ movq(R12, RAX); | 664 __ movq(R12, RAX); |
| 617 // Verify that the unsigned value in RAX can be stored in a Smi. | 665 // Verify that the unsigned value in RAX can be stored in a Smi. |
| 618 __ shrq(R12, Immediate(kSmiBits)); | 666 __ shrq(R12, Immediate(kSmiBits)); |
| 619 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Won't fit Smi. | 667 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Won't fit Smi. |
| 620 __ SmiTag(RAX); | 668 __ SmiTag(RAX); |
| 621 __ ret(); | 669 __ ret(); |
| 622 __ Bind(&fall_through); | 670 __ Bind(&fall_through); |
| 623 return false; | 671 return false; |
| 624 } | 672 } |
| 625 | 673 |
| 626 | 674 |
| 627 bool Intrinsifier::Uint64Array_new(Assembler* assembler) { | 675 bool Intrinsifier::Uint64Array_new(Assembler* assembler) { |
| 628 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); | 676 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); |
| 629 return false; | 677 return false; |
| 630 } | 678 } |
| 631 | 679 |
| 632 | 680 |
| 681 bool Intrinsifier::Uint64Array_factory(Assembler* assembler) { |
| 682 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); |
| 683 return false; |
| 684 } |
| 685 |
| 686 |
| 633 bool Intrinsifier::Float32Array_new(Assembler* assembler) { | 687 bool Intrinsifier::Float32Array_new(Assembler* assembler) { |
| 634 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); | 688 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); |
| 635 return false; | 689 return false; |
| 636 } | 690 } |
| 637 | 691 |
| 638 | 692 |
| 693 bool Intrinsifier::Float32Array_factory(Assembler* assembler) { |
| 694 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); |
| 695 return false; |
| 696 } |
| 697 |
| 698 |
| 639 bool Intrinsifier::Float64Array_new(Assembler* assembler) { | 699 bool Intrinsifier::Float64Array_new(Assembler* assembler) { |
| 640 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); | 700 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); |
| 641 return false; | 701 return false; |
| 642 } | 702 } |
| 643 | 703 |
| 644 | 704 |
| 705 bool Intrinsifier::Float64Array_factory(Assembler* assembler) { |
| 706 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); |
| 707 return false; |
| 708 } |
| 709 |
| 710 |
| 645 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 711 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 646 // Topmost argument is in RAX. | 712 // Topmost argument is in RAX. |
| 647 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 713 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 648 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | 714 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 649 __ movq(RCX, Address(RSP, + 2 * kWordSize)); | 715 __ movq(RCX, Address(RSP, + 2 * kWordSize)); |
| 650 __ orq(RCX, RAX); | 716 __ orq(RCX, RAX); |
| 651 __ testq(RCX, Immediate(kSmiTagMask)); | 717 __ testq(RCX, Immediate(kSmiTagMask)); |
| 652 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 718 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 653 } | 719 } |
| 654 | 720 |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 __ ret(); | 1529 __ ret(); |
| 1464 return true; | 1530 return true; |
| 1465 } | 1531 } |
| 1466 | 1532 |
| 1467 | 1533 |
| 1468 #undef __ | 1534 #undef __ |
| 1469 | 1535 |
| 1470 } // namespace dart | 1536 } // namespace dart |
| 1471 | 1537 |
| 1472 #endif // defined TARGET_ARCH_X64 | 1538 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |