Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 690 __ ret(); | 690 __ ret(); |
| 691 } | 691 } |
| 692 | 692 |
| 693 | 693 |
| 694 void Intrinsifier::Smi_bitLength(Assembler* assembler) { | 694 void Intrinsifier::Smi_bitLength(Assembler* assembler) { |
| 695 // TODO(sra): Implement as word-length - CLZ. | 695 // TODO(sra): Implement as word-length - CLZ. |
| 696 } | 696 } |
| 697 | 697 |
| 698 | 698 |
| 699 void Intrinsifier::Bigint_lsh(Assembler* assembler) { | 699 void Intrinsifier::Bigint_lsh(Assembler* assembler) { |
| 700 // TODO(regis): Implement. | 700 // static void _lsh(Uint32List x_digits, int x_used, int n, |
| 701 // Uint32List r_digits) | |
| 702 | |
| 703 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi. | |
| 704 __ ldp(R2, R3, Address(SP, 2 * kWordSize, Address::PairOffset)); | |
| 705 __ add(R2, R2, Operand(2)); // x_used > 0, Smi. R2 = x_used + 1, round up. | |
| 706 __ AsrImmediate(R2, R2, 2); // R2 = num of digit pairs to read. | |
| 707 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0. | |
| 708 __ ldp(R4, R5, Address(SP, 0 * kWordSize, Address::PairOffset)); | |
| 709 __ SmiUntag(R5); | |
| 710 // R0 = n ~/ (2*_DIGIT_BITS) | |
| 711 __ AsrImmediate(R0, R5, 6); | |
| 712 // R6 = &x_digits[0] | |
| 713 __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | |
| 714 // R7 = &x_digits[2*R2] | |
| 715 __ add(R7, R6, Operand(R2, LSL, 3)); | |
| 716 // R8 = &r_digits[2*1] | |
| 717 __ add(R8, R4, Operand(TypedData::data_offset() - kHeapObjectTag + | |
| 718 2 * Bigint::kBytesPerDigit)); | |
| 719 // R8 = &r_digits[2*(R2 + n ~/ (2*_DIGIT_BITS) + 1)] | |
| 720 __ add(R0, R0, Operand(R2)); | |
| 721 __ add(R8, R8, Operand(R0, LSL, 3)); | |
| 722 // R3 = n % (2 * _DIGIT_BITS) | |
| 723 __ AndImmediate(R3, R5, 63, kNoPP); | |
| 724 // R2 = 64 - R3 | |
| 725 __ LoadImmediate(R2, 64, kNoPP); | |
| 726 __ sub(R2, R2, Operand(R3)); | |
| 727 __ mov(R1, ZR); | |
| 728 Label loop; | |
| 729 __ Bind(&loop); | |
| 730 __ ldr(R0, Address(R7, -2 * Bigint::kBytesPerDigit, Address::PreIndex)); | |
|
Cutch
2015/05/04 17:24:45
Maybe a comment about Address::PreIndex altering R
regis
2015/05/05 07:31:34
Using pre and post indexing is very common in loop
| |
| 731 __ lsrv(R4, R0, R2); | |
| 732 __ orr(R1, R1, Operand(R4)); | |
| 733 __ str(R1, Address(R8, -2 * Bigint::kBytesPerDigit, Address::PreIndex)); | |
| 734 __ lslv(R1, R0, R3); | |
| 735 __ cmp(R7, Operand(R6)); | |
| 736 __ b(&loop, NE); | |
| 737 __ str(R1, Address(R8, -2 * Bigint::kBytesPerDigit, Address::PreIndex)); | |
| 738 // Returning Object::null() is not required, since this method is private. | |
| 739 __ ret(); | |
| 701 } | 740 } |
| 702 | 741 |
| 703 | 742 |
| 704 void Intrinsifier::Bigint_rsh(Assembler* assembler) { | 743 void Intrinsifier::Bigint_rsh(Assembler* assembler) { |
| 705 // TODO(regis): Implement. | 744 // static void _lsh(Uint32List x_digits, int x_used, int n, |
| 745 // Uint32List r_digits) | |
| 746 | |
| 747 // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi. | |
| 748 __ ldp(R2, R3, Address(SP, 2 * kWordSize, Address::PairOffset)); | |
| 749 __ add(R2, R2, Operand(2)); // x_used > 0, Smi. R2 = x_used + 1, round up. | |
| 750 __ AsrImmediate(R2, R2, 2); // R2 = num of digit pairs to read. | |
| 751 // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0. | |
| 752 __ ldp(R4, R5, Address(SP, 0 * kWordSize, Address::PairOffset)); | |
| 753 __ SmiUntag(R5); | |
| 754 // R0 = n ~/ (2*_DIGIT_BITS) | |
| 755 __ AsrImmediate(R0, R5, 6); | |
| 756 // R8 = &r_digits[0] | |
| 757 __ add(R8, R4, Operand(TypedData::data_offset() - kHeapObjectTag)); | |
| 758 // R7 = &x_digits[2*(n ~/ (2*_DIGIT_BITS))] | |
| 759 __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | |
| 760 __ add(R7, R7, Operand(R0, LSL, 3)); | |
| 761 // R6 = &r_digits[2*(R2 - n ~/ (2*_DIGIT_BITS) - 1)] | |
| 762 __ add(R0, R0, Operand(1)); | |
| 763 __ sub(R0, R2, Operand(R0)); | |
| 764 __ add(R6, R8, Operand(R0, LSL, 3)); | |
| 765 // R3 = n % (2*_DIGIT_BITS) | |
| 766 __ AndImmediate(R3, R5, 63, kNoPP); | |
| 767 // R2 = 64 - R3 | |
| 768 __ LoadImmediate(R2, 64, kNoPP); | |
| 769 __ sub(R2, R2, Operand(R3)); | |
| 770 // R1 = x_digits[n ~/ (2*_DIGIT_BITS)] >> (n % (2*_DIGIT_BITS)) | |
| 771 __ ldr(R1, Address(R7, 2 * Bigint::kBytesPerDigit, Address::PostIndex)); | |
| 772 __ lsrv(R1, R1, R3); | |
| 773 Label loop_entry; | |
| 774 __ b(&loop_entry); | |
| 775 Label loop; | |
| 776 __ Bind(&loop); | |
| 777 __ ldr(R0, Address(R7, 2 * Bigint::kBytesPerDigit, Address::PostIndex)); | |
| 778 __ lslv(R4, R0, R2); | |
| 779 __ orr(R1, R1, Operand(R4)); | |
| 780 __ str(R1, Address(R8, 2 * Bigint::kBytesPerDigit, Address::PostIndex)); | |
| 781 __ lsrv(R1, R0, R3); | |
| 782 __ Bind(&loop_entry); | |
| 783 __ cmp(R8, Operand(R6)); | |
| 784 __ b(&loop, NE); | |
| 785 __ str(R1, Address(R8, 0)); | |
| 786 // Returning Object::null() is not required, since this method is private. | |
| 787 __ ret(); | |
| 706 } | 788 } |
| 707 | 789 |
| 708 | 790 |
| 709 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { | 791 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
| 710 // static void _absAdd(Uint32List digits, int used, | 792 // static void _absAdd(Uint32List digits, int used, |
| 711 // Uint32List a_digits, int a_used, | 793 // Uint32List a_digits, int a_used, |
| 712 // Uint32List r_digits) | 794 // Uint32List r_digits) |
| 713 | 795 |
| 714 // R2 = used, R3 = digits | 796 // R2 = used, R3 = digits |
| 715 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); | 797 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2021 Isolate* isolate = Isolate::Current(); | 2103 Isolate* isolate = Isolate::Current(); |
| 2022 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); | 2104 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); |
| 2023 // Set return value to Isolate::current_tag_. | 2105 // Set return value to Isolate::current_tag_. |
| 2024 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 2106 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
| 2025 __ ret(); | 2107 __ ret(); |
| 2026 } | 2108 } |
| 2027 | 2109 |
| 2028 } // namespace dart | 2110 } // namespace dart |
| 2029 | 2111 |
| 2030 #endif // defined TARGET_ARCH_ARM64 | 2112 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |