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

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

Issue 638983002: Implement bigint mulAdd and sqrAdd intrinsics on ARM. (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 | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/simulator_arm.cc » ('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 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/simulator_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698