| 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 // 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 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 | 1029 |
| 1030 | 1030 |
| 1031 // TODO(regis): Once this intrinsic is implemented on all architectures, the | 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. | 1032 // corresponding Dart method will be untested. Add a test with --no-intrinsify. |
| 1033 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { | 1033 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { |
| 1034 // Pseudo code: | 1034 // Pseudo code: |
| 1035 // static void _mulAdd(Uint32List x_digits, int xi, | 1035 // static void _mulAdd(Uint32List x_digits, int xi, |
| 1036 // Uint32List m_digits, int i, | 1036 // Uint32List m_digits, int i, |
| 1037 // Uint32List a_digits, int j, int n) { | 1037 // Uint32List a_digits, int j, int n) { |
| 1038 // uint32_t x = x_digits[xi >> 1]; // xi is Smi. | 1038 // uint32_t x = x_digits[xi >> 1]; // xi is Smi. |
| 1039 // if (x == 0 || n == 0) { | 1039 // if (x == 0 || n == 0) { |
| 1040 // return; | 1040 // return; |
| 1041 // } | 1041 // } |
| 1042 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi. | 1042 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi. |
| 1043 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi. | 1043 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi. |
| 1044 // uint32_t c = 0; | 1044 // uint32_t c = 0; |
| 1045 // SmiUntag(n); | 1045 // SmiUntag(n); |
| 1046 // do { | 1046 // do { |
| 1047 // uint32_t mi = *mip++; | 1047 // uint32_t mi = *mip++; |
| 1048 // uint32_t aj = *ajp; | 1048 // uint32_t aj = *ajp; |
| 1049 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit. | 1049 // uint64_t t = x*mi + aj + c; // 32-bit * 32-bit -> 64-bit. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 // *ajp++ = low32(t); | 1171 // *ajp++ = low32(t); |
| 1172 // c = high64(t); // 33-bit. | 1172 // c = high64(t); // 33-bit. |
| 1173 // } | 1173 // } |
| 1174 // uint32_t aj = *ajp; | 1174 // uint32_t aj = *ajp; |
| 1175 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. | 1175 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. |
| 1176 // *ajp++ = low32(t); | 1176 // *ajp++ = low32(t); |
| 1177 // *ajp = high32(t); | 1177 // *ajp = high32(t); |
| 1178 // } | 1178 // } |
| 1179 | 1179 |
| 1180 // EDI = xip = &x_digits[i >> 1] | 1180 // EDI = xip = &x_digits[i >> 1] |
| 1181 __ movl(EDI, Address(ESP, 4 * kWordSize)); // m_digits | 1181 __ movl(EDI, Address(ESP, 4 * kWordSize)); // x_digits |
| 1182 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi | 1182 __ movl(EAX, Address(ESP, 3 * kWordSize)); // i is Smi |
| 1183 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); | 1183 __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset())); |
| 1184 | 1184 |
| 1185 // EBX = x = *xip++, return if x == 0 | 1185 // EBX = x = *xip++, return if x == 0 |
| 1186 Label x_zero; | 1186 Label x_zero; |
| 1187 __ movl(EBX, Address(EDI, 0)); | 1187 __ movl(EBX, Address(EDI, 0)); |
| 1188 __ cmpl(EBX, Immediate(0)); | 1188 __ cmpl(EBX, Immediate(0)); |
| 1189 __ j(EQUAL, &x_zero); | 1189 __ j(EQUAL, &x_zero); |
| 1190 __ addl(EDI, Immediate(kWordSize)); | 1190 __ addl(EDI, Immediate(kWordSize)); |
| 1191 | 1191 |
| 1192 // Preserve CTX to free ESI. | 1192 // Preserve CTX to free ESI. |
| 1193 __ pushl(CTX); | 1193 __ pushl(CTX); |
| 1194 ASSERT(CTX == ESI); | 1194 ASSERT(CTX == ESI); |
| 1195 | 1195 |
| 1196 // ESI = ajp = &a_digits[i] | 1196 // ESI = ajp = &a_digits[i] |
| 1197 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits | 1197 __ movl(ESI, Address(ESP, 3 * kWordSize)); // a_digits |
| 1198 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); | 1198 __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset())); |
| 1199 | 1199 |
| 1200 // EDX:EAX = t = x*x + *ajp | 1200 // EDX:EAX = t = x*x + *ajp |
| 1201 __ movl(EAX, EBX); | 1201 __ movl(EAX, EBX); |
| 1202 __ mull(EBX); | 1202 __ mull(EBX); |
| 1203 __ addl(EAX, Address(ESI, 0)); | 1203 __ addl(EAX, Address(ESI, 0)); |
| 1204 __ adcl(EDX, Immediate(0)); | 1204 __ adcl(EDX, Immediate(0)); |
| 1205 | 1205 |
| 1206 // *ajp++ = low32(t) | 1206 // *ajp++ = low32(t) |
| 1207 __ movl(Address(ESI, 0), EAX); | 1207 __ movl(Address(ESI, 0), EAX); |
| 1208 __ addl(ESI, Immediate(kWordSize)); | 1208 __ addl(ESI, Immediate(kWordSize)); |
| 1209 | 1209 |
| 1210 // int n = used - i - 1; // All Smi. | 1210 // int n = used - i - 1 |
| 1211 __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi | 1211 __ movl(EAX, Address(ESP, 2 * kWordSize)); // used is Smi |
| 1212 __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi | 1212 __ subl(EAX, Address(ESP, 4 * kWordSize)); // i is Smi |
| 1213 __ SmiUntag(EAX); | 1213 __ SmiUntag(EAX); |
| 1214 __ decl(EAX); | 1214 __ decl(EAX); |
| 1215 __ pushl(EAX); // Save n on stack. | 1215 __ pushl(EAX); // Save n on stack. |
| 1216 | 1216 |
| 1217 // uint64_t c = high32(t) | 1217 // uint64_t c = high32(t) |
| 1218 __ pushl(Immediate(0)); // push high32(c) == 0 | 1218 __ pushl(Immediate(0)); // push high32(c) == 0 |
| 1219 __ pushl(EDX); // push low32(c) == high32(t) | 1219 __ pushl(EDX); // push low32(c) == high32(t) |
| 1220 | 1220 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 __ movl(Address(ESI, 0), EAX); | 1256 __ movl(Address(ESI, 0), EAX); |
| 1257 __ addl(ESI, Immediate(kWordSize)); | 1257 __ addl(ESI, Immediate(kWordSize)); |
| 1258 | 1258 |
| 1259 // c = high64(t) | 1259 // c = high64(t) |
| 1260 __ movl(cl_addr, EDX); | 1260 __ movl(cl_addr, EDX); |
| 1261 __ movl(ch_addr, ECX); | 1261 __ movl(ch_addr, ECX); |
| 1262 | 1262 |
| 1263 __ jmp(&loop, Assembler::kNearJump); | 1263 __ jmp(&loop, Assembler::kNearJump); |
| 1264 | 1264 |
| 1265 __ Bind(&done); | 1265 __ Bind(&done); |
| 1266 // uint32_t aj = *ajp; | 1266 // uint64_t t = aj + c |
| 1267 __ movl(EAX, Address(ESI, 0)); | |
| 1268 | |
| 1269 // uint64_t t = aj + c; // 32-bit + 33-bit -> 34-bit. | |
| 1270 __ movl(EAX, cl_addr); // t = c | 1267 __ movl(EAX, cl_addr); // t = c |
| 1271 __ movl(EDX, ch_addr); | 1268 __ movl(EDX, ch_addr); |
| 1272 __ addl(EAX, Address(ESI, 0)); // t += aj | 1269 __ addl(EAX, Address(ESI, 0)); // t += *ajp |
| 1273 __ adcl(EDX, Immediate(0)); | 1270 __ adcl(EDX, Immediate(0)); |
| 1274 | 1271 |
| 1275 // *ajp++ = low32(t); | 1272 // *ajp++ = low32(t) |
| 1273 // *ajp = high32(t) |
| 1276 __ movl(Address(ESI, 0), EAX); | 1274 __ movl(Address(ESI, 0), EAX); |
| 1277 __ addl(ESI, Immediate(kWordSize)); | 1275 __ movl(Address(ESI, kWordSize), EDX); |
| 1278 | |
| 1279 // *ajp = high32(t); | |
| 1280 __ movl(Address(ESI, 0), EDX); | |
| 1281 | 1276 |
| 1282 // Restore CTX and return. | 1277 // Restore CTX and return. |
| 1283 __ Drop(3); | 1278 __ Drop(3); |
| 1284 __ popl(CTX); | 1279 __ popl(CTX); |
| 1285 __ Bind(&x_zero); | 1280 __ Bind(&x_zero); |
| 1286 // TODO(regis): Confirm that returning Object::null() is not required. | 1281 // TODO(regis): Confirm that returning Object::null() is not required. |
| 1287 __ ret(); | 1282 __ ret(); |
| 1288 } | 1283 } |
| 1289 | 1284 |
| 1290 | 1285 |
| (...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2104 Isolate::current_tag_offset()); | 2099 Isolate::current_tag_offset()); |
| 2105 // Set return value to Isolate::current_tag_. | 2100 // Set return value to Isolate::current_tag_. |
| 2106 __ movl(EAX, current_tag_addr); | 2101 __ movl(EAX, current_tag_addr); |
| 2107 __ ret(); | 2102 __ ret(); |
| 2108 } | 2103 } |
| 2109 | 2104 |
| 2110 #undef __ | 2105 #undef __ |
| 2111 } // namespace dart | 2106 } // namespace dart |
| 2112 | 2107 |
| 2113 #endif // defined TARGET_ARCH_IA32 | 2108 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |