| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 } | 899 } |
| 900 | 900 |
| 901 | 901 |
| 902 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { | 902 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { |
| 903 // static void _absAdd(Uint32List digits, int used, | 903 // static void _absAdd(Uint32List digits, int used, |
| 904 // Uint32List a_digits, int a_used, | 904 // Uint32List a_digits, int a_used, |
| 905 // Uint32List r_digits) | 905 // Uint32List r_digits) |
| 906 | 906 |
| 907 // R2 = used, R3 = digits | 907 // R2 = used, R3 = digits |
| 908 __ ldrd(R2, Address(SP, 3 * kWordSize)); | 908 __ ldrd(R2, Address(SP, 3 * kWordSize)); |
| 909 // R3 = &digits[0] |
| 909 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | 910 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 910 | 911 |
| 911 // R4 = a_used, R5 = a_digits | 912 // R4 = a_used, R5 = a_digits |
| 912 __ ldrd(R4, Address(SP, 1 * kWordSize)); | 913 __ ldrd(R4, Address(SP, 1 * kWordSize)); |
| 914 // R5 = &a_digits[0] |
| 913 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); | 915 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 914 | 916 |
| 915 // R6 = r_digits | 917 // R6 = r_digits |
| 916 __ ldr(R6, Address(SP, 0 * kWordSize)); | 918 __ ldr(R6, Address(SP, 0 * kWordSize)); |
| 919 // R6 = &r_digits[0] |
| 917 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); | 920 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 918 | 921 |
| 919 // R7 = &digits[a_used >> 1], a_used is Smi. | 922 // R7 = &digits[a_used >> 1], a_used is Smi. |
| 920 __ add(R7, R3, Operand(R4, LSL, 1)); | 923 __ add(R7, R3, Operand(R4, LSL, 1)); |
| 921 | 924 |
| 922 // R8 = &digits[used >> 1], used is Smi. | 925 // R8 = &digits[used >> 1], used is Smi. |
| 923 __ add(R8, R3, Operand(R2, LSL, 1)); | 926 __ add(R8, R3, Operand(R2, LSL, 1)); |
| 924 | 927 |
| 925 __ adds(R0, R0, Operand(0)); // carry flag = 0 | 928 __ adds(R0, R0, Operand(0)); // carry flag = 0 |
| 926 Label add_loop; | 929 Label add_loop; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 956 } | 959 } |
| 957 | 960 |
| 958 | 961 |
| 959 void Intrinsifier::Bigint_absSub(Assembler* assembler) { | 962 void Intrinsifier::Bigint_absSub(Assembler* assembler) { |
| 960 // static void _absSub(Uint32List digits, int used, | 963 // static void _absSub(Uint32List digits, int used, |
| 961 // Uint32List a_digits, int a_used, | 964 // Uint32List a_digits, int a_used, |
| 962 // Uint32List r_digits) | 965 // Uint32List r_digits) |
| 963 | 966 |
| 964 // R2 = used, R3 = digits | 967 // R2 = used, R3 = digits |
| 965 __ ldrd(R2, Address(SP, 3 * kWordSize)); | 968 __ ldrd(R2, Address(SP, 3 * kWordSize)); |
| 969 // R3 = &digits[0] |
| 966 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); | 970 __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 967 | 971 |
| 968 // R4 = a_used, R5 = a_digits | 972 // R4 = a_used, R5 = a_digits |
| 969 __ ldrd(R4, Address(SP, 1 * kWordSize)); | 973 __ ldrd(R4, Address(SP, 1 * kWordSize)); |
| 974 // R5 = &a_digits[0] |
| 970 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); | 975 __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 971 | 976 |
| 972 // R6 = r_digits | 977 // R6 = r_digits |
| 973 __ ldr(R6, Address(SP, 0 * kWordSize)); | 978 __ ldr(R6, Address(SP, 0 * kWordSize)); |
| 979 // R6 = &r_digits[0] |
| 974 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); | 980 __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag)); |
| 975 | 981 |
| 976 // R7 = &digits[a_used >> 1], a_used is Smi. | 982 // R7 = &digits[a_used >> 1], a_used is Smi. |
| 977 __ add(R7, R3, Operand(R4, LSL, 1)); | 983 __ add(R7, R3, Operand(R4, LSL, 1)); |
| 978 | 984 |
| 979 // R8 = &digits[used >> 1], used is Smi. | 985 // R8 = &digits[used >> 1], used is Smi. |
| 980 __ add(R8, R3, Operand(R2, LSL, 1)); | 986 __ add(R8, R3, Operand(R2, LSL, 1)); |
| 981 | 987 |
| 982 __ subs(R0, R0, Operand(0)); // carry flag = 1 | 988 __ subs(R0, R0, Operand(0)); // carry flag = 1 |
| 983 Label sub_loop; | 989 Label sub_loop; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 // c: R7:R6 | 1192 // c: R7:R6 |
| 1187 // t: R2:R1:R0 (not live at loop entry) | 1193 // t: R2:R1:R0 (not live at loop entry) |
| 1188 // n: R8 | 1194 // n: R8 |
| 1189 | 1195 |
| 1190 // uint32_t xi = *xip++ | 1196 // uint32_t xi = *xip++ |
| 1191 __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex)); | 1197 __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex)); |
| 1192 | 1198 |
| 1193 // uint32_t aj = *ajp | 1199 // uint32_t aj = *ajp |
| 1194 __ ldr(R1, Address(R5, 0)); | 1200 __ ldr(R1, Address(R5, 0)); |
| 1195 | 1201 |
| 1196 // uint96_t t = R2:R1:R0 = 2*x*xi + aj + c | 1202 // uint96_t t = R7:R6:R0 = 2*x*xi + aj + c |
| 1197 __ mov(R0, Operand(0)); | 1203 __ mov(R0, Operand(0)); |
| 1198 __ umaal(R0, R1, R2, R3); // R1:R0 = R3*R2 + R1 + R0 = x*xi + aj + 0. | 1204 __ umaal(R0, R1, R2, R3); // R1:R0 = R3*R2 + R1 + R0 = x*xi + aj + 0. |
| 1199 __ umlal(R6, R7, R2, R3); // R7:R6 += R3*R2; c += x*xi. | 1205 __ umlal(R6, R7, R2, R3); // R7:R6 += R3*R2; c += x*xi. |
| 1200 __ adds(R0, R0, Operand(R6)); | 1206 __ adds(R0, R0, Operand(R6)); |
| 1201 __ adcs(R6, R1, Operand(R7)); | 1207 __ adcs(R6, R1, Operand(R7)); |
| 1202 __ mov(R7, Operand(0)); | 1208 __ mov(R7, Operand(0)); |
| 1203 __ adc(R7, R7, Operand(0)); // R7:R6:R0 = R1:R0 + R7:R6 = 2*x*xi + aj + c. | 1209 __ adc(R7, R7, Operand(0)); // R7:R6:R0 = R1:R0 + R7:R6 = 2*x*xi + aj + c. |
| 1204 | 1210 |
| 1205 // *ajp++ = low32(t) = R0 | 1211 // *ajp++ = low32(t) = R0 |
| 1206 __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex)); | 1212 __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1221 // *(ajp + 1) = high32(t) = R7 | 1227 // *(ajp + 1) = high32(t) = R7 |
| 1222 __ strd(R6, Address(R5, 0)); | 1228 __ strd(R6, Address(R5, 0)); |
| 1223 | 1229 |
| 1224 __ Bind(&x_zero); | 1230 __ Bind(&x_zero); |
| 1225 // Returning Object::null() is not required, since this method is private. | 1231 // Returning Object::null() is not required, since this method is private. |
| 1226 __ Ret(); | 1232 __ Ret(); |
| 1227 } | 1233 } |
| 1228 | 1234 |
| 1229 | 1235 |
| 1230 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { | 1236 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { |
| 1231 // TODO(regis): Implement. | 1237 // No unsigned 64-bit / 32-bit divide instruction. |
| 1232 } | 1238 } |
| 1233 | 1239 |
| 1234 | 1240 |
| 1235 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { | 1241 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { |
| 1236 if (TargetCPUFeatures::arm_version() != ARMv7) { | 1242 if (TargetCPUFeatures::arm_version() != ARMv7) { |
| 1237 return; | 1243 return; |
| 1238 } | 1244 } |
| 1239 // Pseudo code: | 1245 // Pseudo code: |
| 1240 // static void _mulMod(Uint32List args, Uint32List digits, int i) { | 1246 // static void _mulMod(Uint32List args, Uint32List digits, int i) { |
| 1241 // uint32_t rho = args[_RHO]; // _RHO == 0. | 1247 // uint32_t rho = args[_RHO]; // _RHO == 0. |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 Isolate* isolate = Isolate::Current(); | 2010 Isolate* isolate = Isolate::Current(); |
| 2005 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); | 2011 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); |
| 2006 // Set return value to Isolate::current_tag_. | 2012 // Set return value to Isolate::current_tag_. |
| 2007 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 2013 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
| 2008 __ Ret(); | 2014 __ Ret(); |
| 2009 } | 2015 } |
| 2010 | 2016 |
| 2011 } // namespace dart | 2017 } // namespace dart |
| 2012 | 2018 |
| 2013 #endif // defined TARGET_ARCH_ARM | 2019 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |