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

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

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed Slava's feedback Created 6 years, 3 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_arm64.cc ('k') | runtime/vm/intrinsifier_mips.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 11 matching lines...) Expand all
22 #include "vm/symbols.h" 22 #include "vm/symbols.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DECLARE_FLAG(bool, enable_type_checks); 26 DECLARE_FLAG(bool, enable_type_checks);
27 27
28 28
29 #define __ assembler-> 29 #define __ assembler->
30 30
31 31
32 void Intrinsifier::ObjectArrayLength(Assembler* assembler) { 32 intptr_t Intrinsifier::ParameterSlotFromSp() { return 0; }
33 __ movl(EAX, Address(ESP, + 1 * kWordSize));
34 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
35 __ ret();
36 }
37
38
39 void Intrinsifier::ImmutableArrayLength(Assembler* assembler) {
40 ObjectArrayLength(assembler);
41 }
42
43
44 void Intrinsifier::ObjectArrayGetIndexed(Assembler* assembler) {
45 Label fall_through;
46 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
47 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
48 __ testl(EBX, Immediate(kSmiTagMask));
49 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
50 // Range check.
51 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
52 // Runtime throws exception.
53 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
54 // Note that EBX is Smi, i.e, times 2.
55 ASSERT(kSmiTagShift == 1);
56 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
57 __ ret();
58 __ Bind(&fall_through);
59 }
60
61
62 void Intrinsifier::ImmutableArrayGetIndexed(Assembler* assembler) {
63 ObjectArrayGetIndexed(assembler);
64 }
65 33
66 34
67 static intptr_t ComputeObjectArrayTypeArgumentsOffset() { 35 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
68 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 36 const Library& core_lib = Library::Handle(Library::CoreLibrary());
69 const Class& cls = Class::Handle( 37 const Class& cls = Class::Handle(
70 core_lib.LookupClassAllowPrivate(Symbols::_List())); 38 core_lib.LookupClassAllowPrivate(Symbols::_List()));
71 ASSERT(!cls.IsNull()); 39 ASSERT(!cls.IsNull());
72 ASSERT(cls.NumTypeArguments() == 1); 40 ASSERT(cls.NumTypeArguments() == 1);
73 const intptr_t field_offset = cls.type_arguments_field_offset(); 41 const intptr_t field_offset = cls.type_arguments_field_offset();
74 ASSERT(field_offset != Class::kNoTypeArguments); 42 ASSERT(field_offset != Class::kNoTypeArguments);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 134
167 // Set the length field in the growable array object to 0. 135 // Set the length field in the growable array object to 0.
168 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), 136 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
169 Immediate(0)); 137 Immediate(0));
170 __ ret(); // returns the newly allocated object in EAX. 138 __ ret(); // returns the newly allocated object in EAX.
171 139
172 __ Bind(&fall_through); 140 __ Bind(&fall_through);
173 } 141 }
174 142
175 143
176 // Get length of growable object array.
177 // On stack: growable array (+1), return-address (+0).
178 void Intrinsifier::GrowableArrayLength(Assembler* assembler) {
179 __ movl(EAX, Address(ESP, + 1 * kWordSize));
180 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
181 __ ret();
182 }
183
184
185 // Get capacity of growable object array.
186 // On stack: growable array (+1), return-address (+0).
187 void Intrinsifier::GrowableArrayCapacity(Assembler* assembler) {
188 __ movl(EAX, Address(ESP, + 1 * kWordSize));
189 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
190 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
191 __ ret();
192 }
193
194
195 // Access growable object array at specified index. 144 // Access growable object array at specified index.
196 // On stack: growable array (+2), index (+1), return-address (+0). 145 // On stack: growable array (+2), index (+1), return-address (+0).
197 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { 146 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) {
198 Label fall_through; 147 Label fall_through;
199 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 148 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
200 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray. 149 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray.
201 __ testl(EBX, Immediate(kSmiTagMask)); 150 __ testl(EBX, Immediate(kSmiTagMask));
202 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 151 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
203 // Range check using _length field. 152 // Range check using _length field.
204 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); 153 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ 347 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \
399 __ movl(Address(EDI, 0), ECX); \ 348 __ movl(Address(EDI, 0), ECX); \
400 __ addl(EDI, Immediate(kWordSize)); \ 349 __ addl(EDI, Immediate(kWordSize)); \
401 __ jmp(&init_loop, Assembler::kNearJump); \ 350 __ jmp(&init_loop, Assembler::kNearJump); \
402 __ Bind(&done); \ 351 __ Bind(&done); \
403 \ 352 \
404 __ ret(); \ 353 __ ret(); \
405 __ Bind(&fall_through); \ 354 __ Bind(&fall_through); \
406 355
407 356
408
409 // Gets the length of a TypedData.
410 void Intrinsifier::TypedDataLength(Assembler* assembler) {
411 __ movl(EAX, Address(ESP, + 1 * kWordSize));
412 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset()));
413 __ ret();
414 }
415
416
417 void Intrinsifier::Uint8ArrayGetIndexed(Assembler* assembler) {
418 Label fall_through;
419 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
420 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
421 __ testl(EBX, Immediate(kSmiTagMask));
422 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
423 // Range check.
424 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
425 // Runtime throws exception.
426 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
427
428 __ SmiUntag(EBX);
429 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, TypedData::data_offset()));
430 __ SmiTag(EAX);
431 __ ret();
432 __ Bind(&fall_through);
433 }
434
435
436 void Intrinsifier::ExternalUint8ArrayGetIndexed(Assembler* assembler) {
437 Label fall_through;
438 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
439 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
440 __ testl(EBX, Immediate(kSmiTagMask));
441 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
442 // Range check.
443 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
444 // Runtime throws exception.
445 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
446
447 __ movl(EAX, FieldAddress(EAX, ExternalTypedData::data_offset()));
448 __ SmiUntag(EBX);
449 __ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0));
450 __ SmiTag(EAX);
451 __ ret();
452 __ Bind(&fall_through);
453 }
454
455
456 void Intrinsifier::Float64ArrayGetIndexed(Assembler* assembler) {
457 Label fall_through;
458 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
459 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
460 __ testl(EBX, Immediate(kSmiTagMask));
461 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
462 // Range check.
463 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
464 // Runtime throws exception.
465 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
466
467 Address element_address =
468 Assembler::ElementAddressForRegIndex(false, // Not external
469 kTypedDataFloat64ArrayCid, // Cid.
470 8, // Index scale.
471 EAX, // Array.
472 EBX); // Index.
473
474 __ movsd(XMM0, element_address);
475
476 const Class& double_class = Class::Handle(
477 Isolate::Current()->object_store()->double_class());
478 __ TryAllocate(double_class,
479 &fall_through,
480 Assembler::kNearJump,
481 EAX, // Result register.
482 EBX);
483 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
484 __ ret();
485 __ Bind(&fall_through);
486 }
487
488
489 void Intrinsifier::Float64ArraySetIndexed(Assembler* assembler) {
490 Label fall_through;
491 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
492 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array.
493 __ testl(EBX, Immediate(kSmiTagMask));
494 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
495 // Range check.
496 __ cmpl(EBX, FieldAddress(EAX, TypedData::length_offset()));
497 // Runtime throws exception.
498 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
499
500 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value.
501 __ testl(ECX, Immediate(kSmiTagMask));
502 __ j(ZERO, &fall_through, Assembler::kNearJump); // Value is Smi.
503 __ LoadClassId(EDI, ECX);
504
505 __ cmpl(EDI, Immediate(kDoubleCid));
506 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); // Not a Double.
507
508 __ movsd(XMM0, FieldAddress(ECX, Double::value_offset()));
509
510 Address element_address =
511 Assembler::ElementAddressForRegIndex(false, // Not external
512 kTypedDataFloat64ArrayCid, // Cid.
513 8, // Index scale.
514 EAX, // Array.
515 EBX); // Index.
516
517 __ movsd(element_address, XMM0);
518 __ ret();
519 __ Bind(&fall_through);
520 }
521
522
523 static ScaleFactor GetScaleFactor(intptr_t size) { 357 static ScaleFactor GetScaleFactor(intptr_t size) {
524 switch (size) { 358 switch (size) {
525 case 1: return TIMES_1; 359 case 1: return TIMES_1;
526 case 2: return TIMES_2; 360 case 2: return TIMES_2;
527 case 4: return TIMES_4; 361 case 4: return TIMES_4;
528 case 8: return TIMES_8; 362 case 8: return TIMES_8;
529 case 16: return TIMES_16; 363 case 16: return TIMES_16;
530 } 364 }
531 UNREACHABLE(); 365 UNREACHABLE();
532 return static_cast<ScaleFactor>(0); 366 return static_cast<ScaleFactor>(0);
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1194 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1361 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); 1195 __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
1362 __ cmpl(EAX, Immediate(0)); 1196 __ cmpl(EAX, Immediate(0));
1363 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1197 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1364 __ ret(); 1198 __ ret();
1365 __ Bind(&fall_through); 1199 __ Bind(&fall_through);
1366 // Hash not yet computed. 1200 // Hash not yet computed.
1367 } 1201 }
1368 1202
1369 1203
1370 void Intrinsifier::StringBaseLength(Assembler* assembler) {
1371 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1372 __ movl(EAX, FieldAddress(EAX, String::length_offset()));
1373 __ ret();
1374 }
1375
1376
1377 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) { 1204 void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
1378 Label fall_through, try_two_byte_string; 1205 Label fall_through, try_two_byte_string;
1379 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 1206 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
1380 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String. 1207 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String.
1381 __ testl(EBX, Immediate(kSmiTagMask)); 1208 __ testl(EBX, Immediate(kSmiTagMask));
1382 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 1209 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
1383 // Range check. 1210 // Range check.
1384 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); 1211 __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
1385 // Runtime throws exception. 1212 // Runtime throws exception.
1386 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1213 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 Isolate::current_tag_offset()); 1617 Isolate::current_tag_offset());
1791 // Set return value to Isolate::current_tag_. 1618 // Set return value to Isolate::current_tag_.
1792 __ movl(EAX, current_tag_addr); 1619 __ movl(EAX, current_tag_addr);
1793 __ ret(); 1620 __ ret();
1794 } 1621 }
1795 1622
1796 #undef __ 1623 #undef __
1797 } // namespace dart 1624 } // namespace dart
1798 1625
1799 #endif // defined TARGET_ARCH_IA32 1626 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698