Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: runtime/vm/intrinsifier_arm64.cc

Issue 1124713003: Implement bigint shift intrinsics on arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698