| 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 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 } | 803 } |
| 804 | 804 |
| 805 | 805 |
| 806 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { | 806 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
| 807 // static void _absAdd(Uint32List digits, int used, | 807 // static void _absAdd(Uint32List digits, int used, |
| 808 // Uint32List a_digits, int a_used, | 808 // Uint32List a_digits, int a_used, |
| 809 // Uint32List r_digits) | 809 // Uint32List r_digits) |
| 810 | 810 |
| 811 // R2 = used, R3 = digits | 811 // R2 = used, R3 = digits |
| 812 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); | 812 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); |
| 813 __ add(R2, R2, Operand(2)); // used > 0, Smi. R2 = used + 1, round up. |
| 814 __ add(R2, ZR, Operand(R2, ASR, 2)); // R2 = num of digit pairs to process. |
| 813 // R3 = &digits[0] | 815 // R3 = &digits[0] |
| 814 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | 816 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 815 | 817 |
| 816 // R4 = a_used, R5 = a_digits | 818 // R4 = a_used, R5 = a_digits |
| 817 __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset)); | 819 __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset)); |
| 820 __ add(R4, R4, Operand(2)); // a_used > 0, Smi. R4 = a_used + 1, round up. |
| 821 __ add(R4, ZR, Operand(R4, ASR, 2)); // R4 = num of digit pairs to process. |
| 818 // R5 = &a_digits[0] | 822 // R5 = &a_digits[0] |
| 819 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); | 823 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 820 | 824 |
| 821 // R6 = r_digits | 825 // R6 = r_digits |
| 822 __ ldr(R6, Address(SP, 0 * kWordSize)); | 826 __ ldr(R6, Address(SP, 0 * kWordSize)); |
| 823 // R6 = &r_digits[0] | 827 // R6 = &r_digits[0] |
| 824 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); | 828 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 825 | 829 |
| 826 // R7 = &digits[a_used >> 1], a_used is Smi. | 830 // R7 = &digits[a_used rounded up to even number]. |
| 827 __ add(R7, R3, Operand(R4, LSL, 1)); | 831 __ add(R7, R3, Operand(R4, LSL, 3)); |
| 828 | 832 |
| 829 // R8 = &digits[used >> 1], used is Smi. | 833 // R8 = &digits[a_used rounded up to even number]. |
| 830 __ add(R8, R3, Operand(R2, LSL, 1)); | 834 __ add(R8, R3, Operand(R2, LSL, 3)); |
| 831 | 835 |
| 832 __ adds(R0, R0, Operand(0)); // carry flag = 0 | 836 __ adds(R0, R0, Operand(0)); // carry flag = 0 |
| 833 Label add_loop; | 837 Label add_loop; |
| 834 __ Bind(&add_loop); | 838 __ Bind(&add_loop); |
| 835 // Loop a_used times, a_used > 0. | 839 // Loop (a_used+1)/2 times, a_used > 0. |
| 836 __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex), | 840 __ ldr(R0, Address(R3, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 837 kUnsignedWord); | 841 __ ldr(R1, Address(R5, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 838 __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex), | 842 __ adcs(R0, R0, R1); |
| 839 kUnsignedWord); | |
| 840 __ adcsw(R0, R0, R1); | |
| 841 __ sub(R9, R3, Operand(R7)); // Does not affect carry flag. | 843 __ sub(R9, R3, Operand(R7)); // Does not affect carry flag. |
| 842 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex), | 844 __ str(R0, Address(R6, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 843 kUnsignedWord); | |
| 844 __ cbnz(&add_loop, R9); // Does not affect carry flag. | 845 __ cbnz(&add_loop, R9); // Does not affect carry flag. |
| 845 | 846 |
| 846 Label last_carry; | 847 Label last_carry; |
| 847 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. | 848 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. |
| 848 __ cbz(&last_carry, R9); // If used - a_used == 0. | 849 __ cbz(&last_carry, R9); // If used - a_used == 0. |
| 849 | 850 |
| 850 Label carry_loop; | 851 Label carry_loop; |
| 851 __ Bind(&carry_loop); | 852 __ Bind(&carry_loop); |
| 852 // Loop used - a_used times, used - a_used > 0. | 853 // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0. |
| 853 __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex), | 854 __ ldr(R0, Address(R3, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 854 kUnsignedWord); | 855 __ adcs(R0, R0, ZR); |
| 855 __ adcsw(R0, R0, ZR); | |
| 856 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. | 856 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. |
| 857 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex), | 857 __ str(R0, Address(R6, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 858 kUnsignedWord); | |
| 859 __ cbnz(&carry_loop, R9); | 858 __ cbnz(&carry_loop, R9); |
| 860 | 859 |
| 861 __ Bind(&last_carry); | 860 __ Bind(&last_carry); |
| 862 __ adc(R0, ZR, ZR); | 861 __ adc(R0, ZR, ZR); |
| 863 __ str(R0, Address(R6, 0), kUnsignedWord); | 862 __ str(R0, Address(R6, 0)); |
| 864 | 863 |
| 865 // Returning Object::null() is not required, since this method is private. | 864 // Returning Object::null() is not required, since this method is private. |
| 866 __ ret(); | 865 __ ret(); |
| 867 } | 866 } |
| 868 | 867 |
| 869 | 868 |
| 870 void Intrinsifier::Bigint_absSub(Assembler* assembler) { | 869 void Intrinsifier::Bigint_absSub(Assembler* assembler) { |
| 871 // static void _absSub(Uint32List digits, int used, | 870 // static void _absSub(Uint32List digits, int used, |
| 872 // Uint32List a_digits, int a_used, | 871 // Uint32List a_digits, int a_used, |
| 873 // Uint32List r_digits) | 872 // Uint32List r_digits) |
| 874 | 873 |
| 875 // R2 = used, R3 = digits | 874 // R2 = used, R3 = digits |
| 876 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); | 875 __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset)); |
| 876 __ add(R2, R2, Operand(2)); // used > 0, Smi. R2 = used + 1, round up. |
| 877 __ add(R2, ZR, Operand(R2, ASR, 2)); // R2 = num of digit pairs to process. |
| 877 // R3 = &digits[0] | 878 // R3 = &digits[0] |
| 878 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | 879 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 879 | 880 |
| 880 // R4 = a_used, R5 = a_digits | 881 // R4 = a_used, R5 = a_digits |
| 881 __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset)); | 882 __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset)); |
| 883 __ add(R4, R4, Operand(2)); // a_used > 0, Smi. R4 = a_used + 1, round up. |
| 884 __ add(R4, ZR, Operand(R4, ASR, 2)); // R4 = num of digit pairs to process. |
| 882 // R5 = &a_digits[0] | 885 // R5 = &a_digits[0] |
| 883 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); | 886 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 884 | 887 |
| 885 // R6 = r_digits | 888 // R6 = r_digits |
| 886 __ ldr(R6, Address(SP, 0 * kWordSize)); | 889 __ ldr(R6, Address(SP, 0 * kWordSize)); |
| 887 // R6 = &r_digits[0] | 890 // R6 = &r_digits[0] |
| 888 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); | 891 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 889 | 892 |
| 890 // R7 = &digits[a_used >> 1], a_used is Smi. | 893 // R7 = &digits[a_used rounded up to even number]. |
| 891 __ add(R7, R3, Operand(R4, LSL, 1)); | 894 __ add(R7, R3, Operand(R4, LSL, 3)); |
| 892 | 895 |
| 893 // R8 = &digits[used >> 1], used is Smi. | 896 // R8 = &digits[a_used rounded up to even number]. |
| 894 __ add(R8, R3, Operand(R2, LSL, 1)); | 897 __ add(R8, R3, Operand(R2, LSL, 3)); |
| 895 | 898 |
| 896 __ subs(R0, R0, Operand(0)); // carry flag = 1 | 899 __ subs(R0, R0, Operand(0)); // carry flag = 1 |
| 897 Label sub_loop; | 900 Label sub_loop; |
| 898 __ Bind(&sub_loop); | 901 __ Bind(&sub_loop); |
| 899 // Loop a_used times, a_used > 0. | 902 // Loop (a_used+1)/2 times, a_used > 0. |
| 900 __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex), | 903 __ ldr(R0, Address(R3, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 901 kUnsignedWord); | 904 __ ldr(R1, Address(R5, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 902 __ ldr(R1, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex), | 905 __ sbcs(R0, R0, R1); |
| 903 kUnsignedWord); | |
| 904 __ sbcsw(R0, R0, R1); | |
| 905 __ sub(R9, R3, Operand(R7)); // Does not affect carry flag. | 906 __ sub(R9, R3, Operand(R7)); // Does not affect carry flag. |
| 906 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex), | 907 __ str(R0, Address(R6, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 907 kUnsignedWord); | |
| 908 __ cbnz(&sub_loop, R9); // Does not affect carry flag. | 908 __ cbnz(&sub_loop, R9); // Does not affect carry flag. |
| 909 | 909 |
| 910 Label done; | 910 Label done; |
| 911 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. | 911 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. |
| 912 __ cbz(&done, R9); // If used - a_used == 0. | 912 __ cbz(&done, R9); // If used - a_used == 0. |
| 913 | 913 |
| 914 Label carry_loop; | 914 Label carry_loop; |
| 915 __ Bind(&carry_loop); | 915 __ Bind(&carry_loop); |
| 916 // Loop used - a_used times, used - a_used > 0. | 916 // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0. |
| 917 __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex), | 917 __ ldr(R0, Address(R3, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 918 kUnsignedWord); | 918 __ sbcs(R0, R0, ZR); |
| 919 __ sbcsw(R0, R0, ZR); | |
| 920 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. | 919 __ sub(R9, R3, Operand(R8)); // Does not affect carry flag. |
| 921 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex), | 920 __ str(R0, Address(R6, 2*Bigint::kBytesPerDigit, Address::PostIndex)); |
| 922 kUnsignedWord); | |
| 923 __ cbnz(&carry_loop, R9); | 921 __ cbnz(&carry_loop, R9); |
| 924 | 922 |
| 925 __ Bind(&done); | 923 __ Bind(&done); |
| 926 // Returning Object::null() is not required, since this method is private. | 924 // Returning Object::null() is not required, since this method is private. |
| 927 __ ret(); | 925 __ ret(); |
| 928 } | 926 } |
| 929 | 927 |
| 930 | 928 |
| 931 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { | 929 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { |
| 932 // Pseudo code: | 930 // Pseudo code: |
| (...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2005 Isolate* isolate = Isolate::Current(); | 2003 Isolate* isolate = Isolate::Current(); |
| 2006 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); | 2004 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); |
| 2007 // Set return value to Isolate::current_tag_. | 2005 // Set return value to Isolate::current_tag_. |
| 2008 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 2006 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
| 2009 __ ret(); | 2007 __ ret(); |
| 2010 } | 2008 } |
| 2011 | 2009 |
| 2012 } // namespace dart | 2010 } // namespace dart |
| 2013 | 2011 |
| 2014 #endif // defined TARGET_ARCH_ARM64 | 2012 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |