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

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

Issue 620943002: Add a bigint test with --no_intrinsify. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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
OLDNEW
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 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 905
906 void Intrinsifier::Bigint_setDigits(Assembler* assembler) { 906 void Intrinsifier::Bigint_setDigits(Assembler* assembler) {
907 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 907 __ movl(EAX, Address(ESP, + 1 * kWordSize));
908 __ movl(ECX, Address(ESP, + 2 * kWordSize)); 908 __ movl(ECX, Address(ESP, + 2 * kWordSize));
909 __ StoreIntoObject(ECX, 909 __ StoreIntoObject(ECX,
910 FieldAddress(ECX, Bigint::digits_offset()), EAX, false); 910 FieldAddress(ECX, Bigint::digits_offset()), EAX, false);
911 __ ret(); 911 __ ret();
912 } 912 }
913 913
914 914
915 // TODO(regis): Once this intrinsic is implemented on all architectures, the
916 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
917 void Intrinsifier::Bigint_absAdd(Assembler* assembler) { 915 void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
918 // static void _absAdd(Uint32List digits, int used, 916 // static void _absAdd(Uint32List digits, int used,
919 // Uint32List a_digits, int a_used, 917 // Uint32List a_digits, int a_used,
920 // Uint32List r_digits) 918 // Uint32List r_digits)
921 919
922 // Preserve CTX to free ESI. 920 // Preserve CTX to free ESI.
923 __ pushl(CTX); 921 __ pushl(CTX);
924 ASSERT(CTX == ESI); 922 ASSERT(CTX == ESI);
925 923
926 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits 924 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 __ decl(ECX); // Does not affect CF. 958 __ decl(ECX); // Does not affect CF.
961 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); 959 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
962 960
963 __ Bind(&last_carry); 961 __ Bind(&last_carry);
964 __ movl(EAX, Immediate(0)); 962 __ movl(EAX, Immediate(0));
965 __ adcl(EAX, Immediate(0)); 963 __ adcl(EAX, Immediate(0));
966 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 964 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
967 965
968 // Restore CTX and return. 966 // Restore CTX and return.
969 __ popl(CTX); 967 __ popl(CTX);
970 // TODO(regis): Confirm that returning Object::null() is not required. 968 // Returning Object::null() is not required, since this method is private.
971 __ ret(); 969 __ ret();
972 } 970 }
973 971
974 972
975 // TODO(regis): Once this intrinsic is implemented on all architectures, the
976 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
977 void Intrinsifier::Bigint_absSub(Assembler* assembler) { 973 void Intrinsifier::Bigint_absSub(Assembler* assembler) {
978 // static void _absSub(Uint32List digits, int used, 974 // static void _absSub(Uint32List digits, int used,
979 // Uint32List a_digits, int a_used, 975 // Uint32List a_digits, int a_used,
980 // Uint32List r_digits) 976 // Uint32List r_digits)
981 977
982 // Preserve CTX to free ESI. 978 // Preserve CTX to free ESI.
983 __ pushl(CTX); 979 __ pushl(CTX);
984 ASSERT(CTX == ESI); 980 ASSERT(CTX == ESI);
985 981
986 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits 982 __ movl(EDI, Address(ESP, 6 * kWordSize)); // digits
(...skipping 29 matching lines...) Expand all
1016 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset())); 1012 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
1017 __ sbbl(EAX, Immediate(0)); 1013 __ sbbl(EAX, Immediate(0));
1018 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX); 1014 __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
1019 __ incl(EDX); // Does not affect CF. 1015 __ incl(EDX); // Does not affect CF.
1020 __ decl(ECX); // Does not affect CF. 1016 __ decl(ECX); // Does not affect CF.
1021 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump); 1017 __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
1022 1018
1023 __ Bind(&done); 1019 __ Bind(&done);
1024 // Restore CTX and return. 1020 // Restore CTX and return.
1025 __ popl(CTX); 1021 __ popl(CTX);
1026 // TODO(regis): Confirm that returning Object::null() is not required. 1022 // Returning Object::null() is not required, since this method is private.
1027 __ ret(); 1023 __ ret();
1028 } 1024 }
1029 1025
1030 1026
1031 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1032 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1033 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { 1027 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
1034 // Pseudo code: 1028 // Pseudo code:
1035 // static void _mulAdd(Uint32List x_digits, int xi, 1029 // static void _mulAdd(Uint32List x_digits, int xi,
1036 // Uint32List m_digits, int i, 1030 // Uint32List m_digits, int i,
1037 // Uint32List a_digits, int j, int n) { 1031 // Uint32List a_digits, int j, int n) {
1038 // uint32_t x = x_digits[xi >> 1]; // xi is Smi. 1032 // uint32_t x = x_digits[xi >> 1]; // xi is Smi.
1039 // if (x == 0 || n == 0) { 1033 // if (x == 0 || n == 0) {
1040 // return; 1034 // return;
1041 // } 1035 // }
1042 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi. 1036 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 __ addl(ESI, Immediate(kWordSize)); 1131 __ addl(ESI, Immediate(kWordSize));
1138 __ incl(Address(ESI, 0)); // c == 0 or 1 1132 __ incl(Address(ESI, 0)); // c == 0 or 1
1139 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump); 1133 __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
1140 1134
1141 __ Bind(&done); 1135 __ Bind(&done);
1142 __ Drop(1); // n 1136 __ Drop(1); // n
1143 // Restore CTX and return. 1137 // Restore CTX and return.
1144 __ popl(CTX); 1138 __ popl(CTX);
1145 1139
1146 __ Bind(&no_op); 1140 __ Bind(&no_op);
1147 // TODO(regis): Confirm that returning Object::null() is not required. 1141 // Returning Object::null() is not required, since this method is private.
1148 __ ret(); 1142 __ ret();
1149 } 1143 }
1150 1144
1151 1145
1152 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1153 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1154 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { 1146 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
1155 // Pseudo code: 1147 // Pseudo code:
1156 // static void _sqrAdd(Uint32List x_digits, int i, 1148 // static void _sqrAdd(Uint32List x_digits, int i,
1157 // Uint32List a_digits, int used) { 1149 // Uint32List a_digits, int used) {
1158 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi. 1150 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi.
1159 // uint32_t x = *xip++; 1151 // uint32_t x = *xip++;
1160 // if (x == 0) return; 1152 // if (x == 0) return;
1161 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi. 1153 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi.
1162 // uint32_t aj = *ajp; 1154 // uint32_t aj = *ajp;
1163 // uint64_t t = x*x + aj; 1155 // uint64_t t = x*x + aj;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 __ movl(Address(ESI, 0), EAX); 1268 __ movl(Address(ESI, 0), EAX);
1277 __ addl(ESI, Immediate(kWordSize)); 1269 __ addl(ESI, Immediate(kWordSize));
1278 1270
1279 // *ajp = high32(t); 1271 // *ajp = high32(t);
1280 __ movl(Address(ESI, 0), EDX); 1272 __ movl(Address(ESI, 0), EDX);
1281 1273
1282 // Restore CTX and return. 1274 // Restore CTX and return.
1283 __ Drop(3); 1275 __ Drop(3);
1284 __ popl(CTX); 1276 __ popl(CTX);
1285 __ Bind(&x_zero); 1277 __ Bind(&x_zero);
1286 // TODO(regis): Confirm that returning Object::null() is not required. 1278 // Returning Object::null() is not required, since this method is private.
1287 __ ret(); 1279 __ ret();
1288 } 1280 }
1289 1281
1290 1282
1291 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1292 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1293 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1283 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1294 // Pseudo code: 1284 // Pseudo code:
1295 // static void _estQuotientDigit(Uint32List args, Uint32List digits, int i) { 1285 // static void _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
1296 // uint32_t yt = args[_YT]; // _YT == 0. 1286 // uint32_t yt = args[_YT]; // _YT == 0.
1297 // uint32_t* dp = &digits[i >> 1]; // i is Smi. 1287 // uint32_t* dp = &digits[i >> 1]; // i is Smi.
1298 // uint32_t dh = dp[0]; // dh == digits[i >> 1]. 1288 // uint32_t dh = dp[0]; // dh == digits[i >> 1].
1299 // uint32_t qd; 1289 // uint32_t qd;
1300 // if (dh == yt) { 1290 // if (dh == yt) {
1301 // qd = DIGIT_MASK; 1291 // qd = DIGIT_MASK;
1302 // } else { 1292 // } else {
(...skipping 28 matching lines...) Expand all
1331 // EAX = dl = dp[-1] 1321 // EAX = dl = dp[-1]
1332 __ movl(EAX, Address(EBX, -kWordSize)); 1322 __ movl(EAX, Address(EBX, -kWordSize));
1333 1323
1334 // EAX = qd = dh:dl / yt = EDX:EAX / ECX 1324 // EAX = qd = dh:dl / yt = EDX:EAX / ECX
1335 __ divl(ECX); 1325 __ divl(ECX);
1336 1326
1337 __ Bind(&return_qd); 1327 __ Bind(&return_qd);
1338 // args[1] = qd 1328 // args[1] = qd
1339 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1329 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX);
1340 1330
1341 // TODO(regis): Confirm that returning Object::null() is not required. 1331 // Returning Object::null() is not required, since this method is private.
1342 __ ret(); 1332 __ ret();
1343 } 1333 }
1344 1334
1345 1335
1346 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1347 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1348 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1336 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
1349 // Pseudo code: 1337 // Pseudo code:
1350 // static void _mulMod(Uint32List args, Uint32List digits, int i) { 1338 // static void _mulMod(Uint32List args, Uint32List digits, int i) {
1351 // uint32_t rho = args[_RHO]; // _RHO == 0. 1339 // uint32_t rho = args[_RHO]; // _RHO == 0.
1352 // uint32_t d = digits[i >> 1]; // i is Smi. 1340 // uint32_t d = digits[i >> 1]; // i is Smi.
1353 // uint64_t t = rho*d; 1341 // uint64_t t = rho*d;
1354 // args[_MU] = t mod DIGIT_BASE; // _MU == 1. 1342 // args[_MU] = t mod DIGIT_BASE; // _MU == 1.
1355 // } 1343 // }
1356 1344
1357 // EDI = args 1345 // EDI = args
1358 __ movl(EDI, Address(ESP, 3 * kWordSize)); // args 1346 __ movl(EDI, Address(ESP, 3 * kWordSize)); // args
1359 1347
1360 // ECX = rho = args[0] 1348 // ECX = rho = args[0]
1361 __ movl(ECX, FieldAddress(EDI, TypedData::data_offset())); 1349 __ movl(ECX, FieldAddress(EDI, TypedData::data_offset()));
1362 1350
1363 // EAX = digits[i >> 1] 1351 // EAX = digits[i >> 1]
1364 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits 1352 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits
1365 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi 1353 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi
1366 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset())); 1354 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset()));
1367 1355
1368 // EDX:EAX = t = rho*d 1356 // EDX:EAX = t = rho*d
1369 __ mull(ECX); 1357 __ mull(ECX);
1370 1358
1371 // args[1] = t mod DIGIT_BASE = low32(t) 1359 // args[1] = t mod DIGIT_BASE = low32(t)
1372 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1360 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX);
1373 1361
1374 // TODO(regis): Confirm that returning Object::null() is not required. 1362 // Returning Object::null() is not required, since this method is private.
1375 __ ret(); 1363 __ ret();
1376 } 1364 }
1377 1365
1378 1366
1379 // Check if the last argument is a double, jump to label 'is_smi' if smi 1367 // Check if the last argument is a double, jump to label 'is_smi' if smi
1380 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1368 // (easy to convert to double), otherwise jump to label 'not_double_smi',
1381 // Returns the last argument in EAX. 1369 // Returns the last argument in EAX.
1382 static void TestLastArgumentIsDouble(Assembler* assembler, 1370 static void TestLastArgumentIsDouble(Assembler* assembler,
1383 Label* is_smi, 1371 Label* is_smi,
1384 Label* not_double_smi) { 1372 Label* not_double_smi) {
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 Isolate::current_tag_offset()); 2092 Isolate::current_tag_offset());
2105 // Set return value to Isolate::current_tag_. 2093 // Set return value to Isolate::current_tag_.
2106 __ movl(EAX, current_tag_addr); 2094 __ movl(EAX, current_tag_addr);
2107 __ ret(); 2095 __ ret();
2108 } 2096 }
2109 2097
2110 #undef __ 2098 #undef __
2111 } // namespace dart 2099 } // namespace dart
2112 2100
2113 #endif // defined TARGET_ARCH_IA32 2101 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/big_integer_arith_vm_test.dart » ('j') | tests/corelib/corelib.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698