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 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 __ xorq(RAX, RCX); | 718 __ xorq(RAX, RCX); |
719 // BSR does not write the destination register if source is zero. Put a 1 in | 719 // BSR does not write the destination register if source is zero. Put a 1 in |
720 // the Smi tag bit to ensure BSR writes to destination register. | 720 // the Smi tag bit to ensure BSR writes to destination register. |
721 __ orq(RAX, Immediate(kSmiTagMask)); | 721 __ orq(RAX, Immediate(kSmiTagMask)); |
722 __ bsrq(RAX, RAX); | 722 __ bsrq(RAX, RAX); |
723 __ SmiTag(RAX); | 723 __ SmiTag(RAX); |
724 __ ret(); | 724 __ ret(); |
725 } | 725 } |
726 | 726 |
727 | 727 |
| 728 void Intrinsifier::Bigint_lsh(Assembler* assembler) { |
| 729 // static void _lsh(Uint32List x_digits, int x_used, int n, |
| 730 // Uint32List r_digits) |
| 731 |
| 732 __ movq(RDI, Address(RSP, 4 * kWordSize)); // x_digits |
| 733 __ movq(R8, Address(RSP, 3 * kWordSize)); // x_used is Smi |
| 734 __ subq(R8, Immediate(2)); // x_used > 0, Smi. R8 = x_used - 1, round up. |
| 735 __ sarq(R8, Immediate(2)); // R8 + 1 = number of digit pairs to read. |
| 736 __ movq(RCX, Address(RSP, 2 * kWordSize)); // n is Smi |
| 737 __ SmiUntag(RCX); |
| 738 __ movq(RBX, Address(RSP, 1 * kWordSize)); // r_digits |
| 739 __ movq(RSI, RCX); |
| 740 __ sarq(RSI, Immediate(6)); // RSI = n ~/ (2*_DIGIT_BITS). |
| 741 __ leaq(RBX, FieldAddress(RBX, RSI, TIMES_8, TypedData::data_offset())); |
| 742 __ xorq(RAX, RAX); // RAX = 0. |
| 743 __ movq(RDX, FieldAddress(RDI, R8, TIMES_8, TypedData::data_offset())); |
| 744 __ shldq(RAX, RDX, RCX); |
| 745 __ movq(Address(RBX, R8, TIMES_8, 2 * Bigint::kBytesPerDigit), RAX); |
| 746 Label last; |
| 747 __ cmpq(R8, Immediate(0)); |
| 748 __ j(EQUAL, &last, Assembler::kNearJump); |
| 749 Label loop; |
| 750 __ Bind(&loop); |
| 751 __ movq(RAX, RDX); |
| 752 __ movq(RDX, |
| 753 FieldAddress(RDI, R8, TIMES_8, |
| 754 TypedData::data_offset() - 2 * Bigint::kBytesPerDigit)); |
| 755 __ shldq(RAX, RDX, RCX); |
| 756 __ movq(Address(RBX, R8, TIMES_8, 0), RAX); |
| 757 __ decq(R8); |
| 758 __ j(NOT_ZERO, &loop, Assembler::kNearJump); |
| 759 __ Bind(&last); |
| 760 __ xorq(RAX, RAX); // RAX = 0. |
| 761 __ shldq(RDX, RAX, RCX); |
| 762 __ movq(Address(RBX, 0), RDX); |
| 763 // Returning Object::null() is not required, since this method is private. |
| 764 __ ret(); |
| 765 } |
| 766 |
| 767 |
| 768 void Intrinsifier::Bigint_rsh(Assembler* assembler) { |
| 769 // static void _rsh(Uint32List x_digits, int x_used, int n, |
| 770 // Uint32List r_digits) |
| 771 |
| 772 __ movq(RDI, Address(RSP, 4 * kWordSize)); // x_digits |
| 773 __ movq(R8, Address(RSP, 3 * kWordSize)); // x_used is Smi |
| 774 __ subq(R8, Immediate(2)); // x_used > 0, Smi. R8 = x_used - 1, round up. |
| 775 __ sarq(R8, Immediate(2)); |
| 776 __ movq(RCX, Address(RSP, 2 * kWordSize)); // n is Smi |
| 777 __ SmiUntag(RCX); |
| 778 __ movq(RBX, Address(RSP, 1 * kWordSize)); // r_digits |
| 779 __ movq(RSI, RCX); |
| 780 __ sarq(RSI, Immediate(6)); // RSI = n ~/ (2*_DIGIT_BITS). |
| 781 __ leaq(RDI, FieldAddress(RDI, RSI, TIMES_8, TypedData::data_offset())); |
| 782 __ movq(RDX, Address(RDI, 0)); |
| 783 __ subq(R8, RSI); // R8 + 1 = number of digit pairs to read. |
| 784 Label last; |
| 785 __ cmpq(R8, Immediate(0)); |
| 786 __ j(EQUAL, &last, Assembler::kNearJump); |
| 787 __ xorq(R9, R9); // R9 = 0. |
| 788 Label loop; |
| 789 __ Bind(&loop); |
| 790 __ movq(RAX, RDX); |
| 791 __ movq(RDX, Address(RDI, R9, TIMES_8, 2 * Bigint::kBytesPerDigit)); |
| 792 __ shrdq(RAX, RDX, RCX); |
| 793 __ movq(FieldAddress(RBX, R9, TIMES_8, TypedData::data_offset()), RAX); |
| 794 __ incq(R9); |
| 795 __ cmpq(R9, R8); |
| 796 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 797 __ Bind(&last); |
| 798 __ xorq(RAX, RAX); // RAX = 0. |
| 799 __ shrdq(RDX, RAX, RCX); |
| 800 __ movq(FieldAddress(RBX, R8, TIMES_8, TypedData::data_offset()), RDX); |
| 801 // Returning Object::null() is not required, since this method is private. |
| 802 __ ret(); |
| 803 } |
| 804 |
| 805 |
728 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { | 806 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
729 // static void _absAdd(Uint32List digits, int used, | 807 // static void _absAdd(Uint32List digits, int used, |
730 // Uint32List a_digits, int a_used, | 808 // Uint32List a_digits, int a_used, |
731 // Uint32List r_digits) | 809 // Uint32List r_digits) |
732 | 810 |
733 __ movq(RDI, Address(RSP, 5 * kWordSize)); // digits | 811 __ movq(RDI, Address(RSP, 5 * kWordSize)); // digits |
734 __ movq(R8, Address(RSP, 4 * kWordSize)); // used is Smi | 812 __ movq(R8, Address(RSP, 4 * kWordSize)); // used is Smi |
735 __ addq(R8, Immediate(2)); // used > 0, Smi. R8 = used + 1, round up. | 813 __ addq(R8, Immediate(2)); // used > 0, Smi. R8 = used + 1, round up. |
736 __ sarq(R8, Immediate(2)); // R8 = number of digit pairs to process. | 814 __ sarq(R8, Immediate(2)); // R8 = number of digit pairs to process. |
737 __ movq(RSI, Address(RSP, 3 * kWordSize)); // a_digits | 815 __ movq(RSI, Address(RSP, 3 * kWordSize)); // a_digits |
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 // Set return value to Isolate::current_tag_. | 1991 // Set return value to Isolate::current_tag_. |
1914 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); | 1992 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); |
1915 __ ret(); | 1993 __ ret(); |
1916 } | 1994 } |
1917 | 1995 |
1918 #undef __ | 1996 #undef __ |
1919 | 1997 |
1920 } // namespace dart | 1998 } // namespace dart |
1921 | 1999 |
1922 #endif // defined TARGET_ARCH_X64 | 2000 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |