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

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
« no previous file with comments | « no previous file | tests/corelib/big_integer_arith_vm_test.dart » ('j') | 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) 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 1263
1272 // *ajp++ = low32(t) 1264 // *ajp++ = low32(t)
1273 // *ajp = high32(t) 1265 // *ajp = high32(t)
1274 __ movl(Address(ESI, 0), EAX); 1266 __ movl(Address(ESI, 0), EAX);
1275 __ movl(Address(ESI, kWordSize), EDX); 1267 __ movl(Address(ESI, kWordSize), EDX);
1276 1268
1277 // Restore CTX and return. 1269 // Restore CTX and return.
1278 __ Drop(3); 1270 __ Drop(3);
1279 __ popl(CTX); 1271 __ popl(CTX);
1280 __ Bind(&x_zero); 1272 __ Bind(&x_zero);
1281 // TODO(regis): Confirm that returning Object::null() is not required. 1273 // Returning Object::null() is not required, since this method is private.
1282 __ ret(); 1274 __ ret();
1283 } 1275 }
1284 1276
1285 1277
1286 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1287 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1288 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1278 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1289 // Pseudo code: 1279 // Pseudo code:
1290 // static void _estQuotientDigit(Uint32List args, Uint32List digits, int i) { 1280 // static void _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
1291 // uint32_t yt = args[_YT]; // _YT == 0. 1281 // uint32_t yt = args[_YT]; // _YT == 0.
1292 // uint32_t* dp = &digits[i >> 1]; // i is Smi. 1282 // uint32_t* dp = &digits[i >> 1]; // i is Smi.
1293 // uint32_t dh = dp[0]; // dh == digits[i >> 1]. 1283 // uint32_t dh = dp[0]; // dh == digits[i >> 1].
1294 // uint32_t qd; 1284 // uint32_t qd;
1295 // if (dh == yt) { 1285 // if (dh == yt) {
1296 // qd = DIGIT_MASK; 1286 // qd = DIGIT_MASK;
1297 // } else { 1287 // } else {
(...skipping 28 matching lines...) Expand all
1326 // EAX = dl = dp[-1] 1316 // EAX = dl = dp[-1]
1327 __ movl(EAX, Address(EBX, -kWordSize)); 1317 __ movl(EAX, Address(EBX, -kWordSize));
1328 1318
1329 // EAX = qd = dh:dl / yt = EDX:EAX / ECX 1319 // EAX = qd = dh:dl / yt = EDX:EAX / ECX
1330 __ divl(ECX); 1320 __ divl(ECX);
1331 1321
1332 __ Bind(&return_qd); 1322 __ Bind(&return_qd);
1333 // args[1] = qd 1323 // args[1] = qd
1334 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1324 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX);
1335 1325
1336 // TODO(regis): Confirm that returning Object::null() is not required. 1326 // Returning Object::null() is not required, since this method is private.
1337 __ ret(); 1327 __ ret();
1338 } 1328 }
1339 1329
1340 1330
1341 // TODO(regis): Once this intrinsic is implemented on all architectures, the
1342 // corresponding Dart method will be untested. Add a test with --no-intrinsify.
1343 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1331 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
1344 // Pseudo code: 1332 // Pseudo code:
1345 // static void _mulMod(Uint32List args, Uint32List digits, int i) { 1333 // static void _mulMod(Uint32List args, Uint32List digits, int i) {
1346 // uint32_t rho = args[_RHO]; // _RHO == 0. 1334 // uint32_t rho = args[_RHO]; // _RHO == 0.
1347 // uint32_t d = digits[i >> 1]; // i is Smi. 1335 // uint32_t d = digits[i >> 1]; // i is Smi.
1348 // uint64_t t = rho*d; 1336 // uint64_t t = rho*d;
1349 // args[_MU] = t mod DIGIT_BASE; // _MU == 1. 1337 // args[_MU] = t mod DIGIT_BASE; // _MU == 1.
1350 // } 1338 // }
1351 1339
1352 // EDI = args 1340 // EDI = args
1353 __ movl(EDI, Address(ESP, 3 * kWordSize)); // args 1341 __ movl(EDI, Address(ESP, 3 * kWordSize)); // args
1354 1342
1355 // ECX = rho = args[0] 1343 // ECX = rho = args[0]
1356 __ movl(ECX, FieldAddress(EDI, TypedData::data_offset())); 1344 __ movl(ECX, FieldAddress(EDI, TypedData::data_offset()));
1357 1345
1358 // EAX = digits[i >> 1] 1346 // EAX = digits[i >> 1]
1359 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits 1347 __ movl(EBX, Address(ESP, 2 * kWordSize)); // digits
1360 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi 1348 __ movl(EAX, Address(ESP, 1 * kWordSize)); // i is Smi
1361 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset())); 1349 __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset()));
1362 1350
1363 // EDX:EAX = t = rho*d 1351 // EDX:EAX = t = rho*d
1364 __ mull(ECX); 1352 __ mull(ECX);
1365 1353
1366 // args[1] = t mod DIGIT_BASE = low32(t) 1354 // args[1] = t mod DIGIT_BASE = low32(t)
1367 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX); 1355 __ movl(FieldAddress(EDI, TypedData::data_offset() + kWordSize), EAX);
1368 1356
1369 // TODO(regis): Confirm that returning Object::null() is not required. 1357 // Returning Object::null() is not required, since this method is private.
1370 __ ret(); 1358 __ ret();
1371 } 1359 }
1372 1360
1373 1361
1374 // Check if the last argument is a double, jump to label 'is_smi' if smi 1362 // Check if the last argument is a double, jump to label 'is_smi' if smi
1375 // (easy to convert to double), otherwise jump to label 'not_double_smi', 1363 // (easy to convert to double), otherwise jump to label 'not_double_smi',
1376 // Returns the last argument in EAX. 1364 // Returns the last argument in EAX.
1377 static void TestLastArgumentIsDouble(Assembler* assembler, 1365 static void TestLastArgumentIsDouble(Assembler* assembler,
1378 Label* is_smi, 1366 Label* is_smi,
1379 Label* not_double_smi) { 1367 Label* not_double_smi) {
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 Isolate::current_tag_offset()); 2087 Isolate::current_tag_offset());
2100 // Set return value to Isolate::current_tag_. 2088 // Set return value to Isolate::current_tag_.
2101 __ movl(EAX, current_tag_addr); 2089 __ movl(EAX, current_tag_addr);
2102 __ ret(); 2090 __ ret();
2103 } 2091 }
2104 2092
2105 #undef __ 2093 #undef __
2106 } // namespace dart 2094 } // namespace dart
2107 2095
2108 #endif // defined TARGET_ARCH_IA32 2096 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/big_integer_arith_vm_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698