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

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

Issue 1268783003: Simplify constant pool usage in x64 code generator (by removing extra argument (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Make PP implicit in LoadPoolPointer Created 5 years, 4 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
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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 // This snippet of inlined code uses the following registers: 65 // This snippet of inlined code uses the following registers:
66 // RAX, RCX, R13 66 // RAX, RCX, R13
67 // and the newly allocated object is returned in RAX. 67 // and the newly allocated object is returned in RAX.
68 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 68 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
69 const intptr_t kArrayOffset = 1 * kWordSize; 69 const intptr_t kArrayOffset = 1 * kWordSize;
70 Label fall_through; 70 Label fall_through;
71 71
72 // Try allocating in new space. 72 // Try allocating in new space.
73 const Class& cls = Class::Handle( 73 const Class& cls = Class::Handle(
74 Isolate::Current()->object_store()->growable_object_array_class()); 74 Isolate::Current()->object_store()->growable_object_array_class());
75 __ TryAllocate(cls, &fall_through, Assembler::kFarJump, RAX, kNoRegister); 75 __ TryAllocate(cls, &fall_through, Assembler::kFarJump, RAX);
76 76
77 // Store backing array object in growable array object. 77 // Store backing array object in growable array object.
78 __ movq(RCX, Address(RSP, kArrayOffset)); // data argument. 78 __ movq(RCX, Address(RSP, kArrayOffset)); // data argument.
79 // RAX is new, no barrier needed. 79 // RAX is new, no barrier needed.
80 __ InitializeFieldNoBarrier( 80 __ InitializeFieldNoBarrier(
81 RAX, 81 RAX,
82 FieldAddress(RAX, GrowableObjectArray::data_offset()), 82 FieldAddress(RAX, GrowableObjectArray::data_offset()),
83 RCX); 83 RCX);
84 84
85 // RAX: new growable array object start as a tagged pointer. 85 // RAX: new growable array object start as a tagged pointer.
(...skipping 28 matching lines...) Expand all
114 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); 114 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset()));
115 __ j(EQUAL, &fall_through); // Must grow data. 115 __ j(EQUAL, &fall_through); // Must grow data.
116 // len = len + 1; 116 // len = len + 1;
117 __ IncrementSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()), 117 __ IncrementSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()),
118 1); 118 1);
119 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value 119 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value
120 ASSERT(kSmiTagShift == 1); 120 ASSERT(kSmiTagShift == 1);
121 __ StoreIntoObject(RDX, 121 __ StoreIntoObject(RDX,
122 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), 122 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()),
123 RAX); 123 RAX);
124 __ LoadObject(RAX, Object::null_object(), PP); 124 __ LoadObject(RAX, Object::null_object());
125 __ ret(); 125 __ ret();
126 __ Bind(&fall_through); 126 __ Bind(&fall_through);
127 } 127 }
128 128
129 129
130 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \ 130 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \
131 Label fall_through; \ 131 Label fall_through; \
132 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ 132 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \
133 __ MaybeTraceAllocation(cid, &fall_through, false); \ 133 __ MaybeTraceAllocation(cid, &fall_through, false); \
134 __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \ 134 __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 __ Bind(&fall_through); 576 __ Bind(&fall_through);
577 } 577 }
578 578
579 579
580 static void CompareIntegers(Assembler* assembler, Condition true_condition) { 580 static void CompareIntegers(Assembler* assembler, Condition true_condition) {
581 Label fall_through, true_label; 581 Label fall_through, true_label;
582 TestBothArgumentsSmis(assembler, &fall_through); 582 TestBothArgumentsSmis(assembler, &fall_through);
583 // RAX contains the right argument. 583 // RAX contains the right argument.
584 __ cmpq(Address(RSP, + 2 * kWordSize), RAX); 584 __ cmpq(Address(RSP, + 2 * kWordSize), RAX);
585 __ j(true_condition, &true_label, Assembler::kNearJump); 585 __ j(true_condition, &true_label, Assembler::kNearJump);
586 __ LoadObject(RAX, Bool::False(), PP); 586 __ LoadObject(RAX, Bool::False());
587 __ ret(); 587 __ ret();
588 __ Bind(&true_label); 588 __ Bind(&true_label);
589 __ LoadObject(RAX, Bool::True(), PP); 589 __ LoadObject(RAX, Bool::True());
590 __ ret(); 590 __ ret();
591 __ Bind(&fall_through); 591 __ Bind(&fall_through);
592 } 592 }
593 593
594 594
595 void Intrinsifier::Integer_lessThan(Assembler* assembler) { 595 void Intrinsifier::Integer_lessThan(Assembler* assembler) {
596 CompareIntegers(assembler, LESS); 596 CompareIntegers(assembler, LESS);
597 } 597 }
598 598
599 599
(...skipping 26 matching lines...) Expand all
626 626
627 // For integer receiver '===' check first. 627 // For integer receiver '===' check first.
628 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); 628 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
629 __ movq(RCX, Address(RSP, + kReceiverOffset * kWordSize)); 629 __ movq(RCX, Address(RSP, + kReceiverOffset * kWordSize));
630 __ cmpq(RAX, RCX); 630 __ cmpq(RAX, RCX);
631 __ j(EQUAL, &true_label, Assembler::kNearJump); 631 __ j(EQUAL, &true_label, Assembler::kNearJump);
632 __ orq(RAX, RCX); 632 __ orq(RAX, RCX);
633 __ testq(RAX, Immediate(kSmiTagMask)); 633 __ testq(RAX, Immediate(kSmiTagMask));
634 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); 634 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
635 // Both arguments are smi, '===' is good enough. 635 // Both arguments are smi, '===' is good enough.
636 __ LoadObject(RAX, Bool::False(), PP); 636 __ LoadObject(RAX, Bool::False());
637 __ ret(); 637 __ ret();
638 __ Bind(&true_label); 638 __ Bind(&true_label);
639 __ LoadObject(RAX, Bool::True(), PP); 639 __ LoadObject(RAX, Bool::True());
640 __ ret(); 640 __ ret();
641 641
642 // At least one of the arguments was not Smi. 642 // At least one of the arguments was not Smi.
643 Label receiver_not_smi; 643 Label receiver_not_smi;
644 __ Bind(&check_for_mint); 644 __ Bind(&check_for_mint);
645 __ movq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); 645 __ movq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
646 __ testq(RAX, Immediate(kSmiTagMask)); 646 __ testq(RAX, Immediate(kSmiTagMask));
647 __ j(NOT_ZERO, &receiver_not_smi); 647 __ j(NOT_ZERO, &receiver_not_smi);
648 648
649 // Left (receiver) is Smi, return false if right is not Double. 649 // Left (receiver) is Smi, return false if right is not Double.
650 // Note that an instance of Mint or Bigint never contains a value that can be 650 // Note that an instance of Mint or Bigint never contains a value that can be
651 // represented by Smi. 651 // represented by Smi.
652 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); 652 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
653 __ CompareClassId(RAX, kDoubleCid); 653 __ CompareClassId(RAX, kDoubleCid);
654 __ j(EQUAL, &fall_through); 654 __ j(EQUAL, &fall_through);
655 __ LoadObject(RAX, Bool::False(), PP); 655 __ LoadObject(RAX, Bool::False());
656 __ ret(); 656 __ ret();
657 657
658 __ Bind(&receiver_not_smi); 658 __ Bind(&receiver_not_smi);
659 // RAX:: receiver. 659 // RAX:: receiver.
660 __ CompareClassId(RAX, kMintCid); 660 __ CompareClassId(RAX, kMintCid);
661 __ j(NOT_EQUAL, &fall_through); 661 __ j(NOT_EQUAL, &fall_through);
662 // Receiver is Mint, return false if right is Smi. 662 // Receiver is Mint, return false if right is Smi.
663 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); 663 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
664 __ testq(RAX, Immediate(kSmiTagMask)); 664 __ testq(RAX, Immediate(kSmiTagMask));
665 __ j(NOT_ZERO, &fall_through); 665 __ j(NOT_ZERO, &fall_through);
666 // Smi == Mint -> false. 666 // Smi == Mint -> false.
667 __ LoadObject(RAX, Bool::False(), PP); 667 __ LoadObject(RAX, Bool::False());
668 __ ret(); 668 __ ret();
669 // TODO(srdjan): Implement Mint == Mint comparison. 669 // TODO(srdjan): Implement Mint == Mint comparison.
670 670
671 __ Bind(&fall_through); 671 __ Bind(&fall_through);
672 } 672 }
673 673
674 674
675 void Intrinsifier::Integer_equal(Assembler* assembler) { 675 void Intrinsifier::Integer_equal(Assembler* assembler) {
676 Integer_equalToInteger(assembler); 676 Integer_equalToInteger(assembler);
677 } 677 }
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 // Both arguments are double, right operand is in RAX. 1255 // Both arguments are double, right operand is in RAX.
1256 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); 1256 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
1257 __ Bind(&double_op); 1257 __ Bind(&double_op);
1258 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument. 1258 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument.
1259 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1259 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1260 __ comisd(XMM0, XMM1); 1260 __ comisd(XMM0, XMM1);
1261 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; 1261 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
1262 __ j(true_condition, &is_true, Assembler::kNearJump); 1262 __ j(true_condition, &is_true, Assembler::kNearJump);
1263 // Fall through false. 1263 // Fall through false.
1264 __ Bind(&is_false); 1264 __ Bind(&is_false);
1265 __ LoadObject(RAX, Bool::False(), PP); 1265 __ LoadObject(RAX, Bool::False());
1266 __ ret(); 1266 __ ret();
1267 __ Bind(&is_true); 1267 __ Bind(&is_true);
1268 __ LoadObject(RAX, Bool::True(), PP); 1268 __ LoadObject(RAX, Bool::True());
1269 __ ret(); 1269 __ ret();
1270 __ Bind(&is_smi); 1270 __ Bind(&is_smi);
1271 __ SmiUntag(RAX); 1271 __ SmiUntag(RAX);
1272 __ cvtsi2sdq(XMM1, RAX); 1272 __ cvtsi2sdq(XMM1, RAX);
1273 __ jmp(&double_op); 1273 __ jmp(&double_op);
1274 __ Bind(&fall_through); 1274 __ Bind(&fall_through);
1275 } 1275 }
1276 1276
1277 1277
1278 void Intrinsifier::Double_greaterThan(Assembler* assembler) { 1278 void Intrinsifier::Double_greaterThan(Assembler* assembler) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 case Token::kSUB: __ subsd(XMM0, XMM1); break; 1314 case Token::kSUB: __ subsd(XMM0, XMM1); break;
1315 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 1315 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
1316 case Token::kDIV: __ divsd(XMM0, XMM1); break; 1316 case Token::kDIV: __ divsd(XMM0, XMM1); break;
1317 default: UNREACHABLE(); 1317 default: UNREACHABLE();
1318 } 1318 }
1319 const Class& double_class = Class::Handle( 1319 const Class& double_class = Class::Handle(
1320 Isolate::Current()->object_store()->double_class()); 1320 Isolate::Current()->object_store()->double_class());
1321 __ TryAllocate(double_class, 1321 __ TryAllocate(double_class,
1322 &fall_through, 1322 &fall_through,
1323 Assembler::kFarJump, 1323 Assembler::kFarJump,
1324 RAX, // Result register. 1324 RAX); // Result register.
1325 kNoRegister); // Pool pointer might not be loaded.
1326 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 1325 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
1327 __ ret(); 1326 __ ret();
1328 __ Bind(&fall_through); 1327 __ Bind(&fall_through);
1329 } 1328 }
1330 1329
1331 1330
1332 void Intrinsifier::Double_add(Assembler* assembler) { 1331 void Intrinsifier::Double_add(Assembler* assembler) {
1333 DoubleArithmeticOperations(assembler, Token::kADD); 1332 DoubleArithmeticOperations(assembler, Token::kADD);
1334 } 1333 }
1335 1334
(...skipping 23 matching lines...) Expand all
1359 __ SmiUntag(RAX); 1358 __ SmiUntag(RAX);
1360 __ cvtsi2sdq(XMM1, RAX); 1359 __ cvtsi2sdq(XMM1, RAX);
1361 __ movq(RAX, Address(RSP, + 2 * kWordSize)); 1360 __ movq(RAX, Address(RSP, + 2 * kWordSize));
1362 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1361 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1363 __ mulsd(XMM0, XMM1); 1362 __ mulsd(XMM0, XMM1);
1364 const Class& double_class = Class::Handle( 1363 const Class& double_class = Class::Handle(
1365 Isolate::Current()->object_store()->double_class()); 1364 Isolate::Current()->object_store()->double_class());
1366 __ TryAllocate(double_class, 1365 __ TryAllocate(double_class,
1367 &fall_through, 1366 &fall_through,
1368 Assembler::kFarJump, 1367 Assembler::kFarJump,
1369 RAX, // Result register. 1368 RAX); // Result register.
1370 kNoRegister); // Pool pointer might not be loaded.
1371 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 1369 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
1372 __ ret(); 1370 __ ret();
1373 __ Bind(&fall_through); 1371 __ Bind(&fall_through);
1374 } 1372 }
1375 1373
1376 1374
1377 // Left is double right is integer (Bigint, Mint or Smi) 1375 // Left is double right is integer (Bigint, Mint or Smi)
1378 void Intrinsifier::DoubleFromInteger(Assembler* assembler) { 1376 void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
1379 Label fall_through; 1377 Label fall_through;
1380 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1378 __ movq(RAX, Address(RSP, +1 * kWordSize));
1381 __ testq(RAX, Immediate(kSmiTagMask)); 1379 __ testq(RAX, Immediate(kSmiTagMask));
1382 __ j(NOT_ZERO, &fall_through); 1380 __ j(NOT_ZERO, &fall_through);
1383 // Is Smi. 1381 // Is Smi.
1384 __ SmiUntag(RAX); 1382 __ SmiUntag(RAX);
1385 __ cvtsi2sdq(XMM0, RAX); 1383 __ cvtsi2sdq(XMM0, RAX);
1386 const Class& double_class = Class::Handle( 1384 const Class& double_class = Class::Handle(
1387 Isolate::Current()->object_store()->double_class()); 1385 Isolate::Current()->object_store()->double_class());
1388 __ TryAllocate(double_class, 1386 __ TryAllocate(double_class,
1389 &fall_through, 1387 &fall_through,
1390 Assembler::kFarJump, 1388 Assembler::kFarJump,
1391 RAX, // Result register. 1389 RAX); // Result register.
1392 kNoRegister); // Pool pointer might not be loaded.
1393 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 1390 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
1394 __ ret(); 1391 __ ret();
1395 __ Bind(&fall_through); 1392 __ Bind(&fall_through);
1396 } 1393 }
1397 1394
1398 1395
1399 void Intrinsifier::Double_getIsNaN(Assembler* assembler) { 1396 void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
1400 Label is_true; 1397 Label is_true;
1401 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1398 __ movq(RAX, Address(RSP, +1 * kWordSize));
1402 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1399 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1403 __ comisd(XMM0, XMM0); 1400 __ comisd(XMM0, XMM0);
1404 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true; 1401 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true;
1405 __ LoadObject(RAX, Bool::False(), PP); 1402 __ LoadObject(RAX, Bool::False());
1406 __ ret(); 1403 __ ret();
1407 __ Bind(&is_true); 1404 __ Bind(&is_true);
1408 __ LoadObject(RAX, Bool::True(), PP); 1405 __ LoadObject(RAX, Bool::True());
1409 __ ret(); 1406 __ ret();
1410 } 1407 }
1411 1408
1412 1409
1413 void Intrinsifier::Double_getIsNegative(Assembler* assembler) { 1410 void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
1414 Label is_false, is_true, is_zero; 1411 Label is_false, is_true, is_zero;
1415 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1412 __ movq(RAX, Address(RSP, +1 * kWordSize));
1416 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1413 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1417 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1. 1414 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1.
1418 __ comisd(XMM0, XMM1); 1415 __ comisd(XMM0, XMM1);
1419 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false. 1416 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false.
1420 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero. 1417 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero.
1421 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false. 1418 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false.
1422 __ Bind(&is_true); 1419 __ Bind(&is_true);
1423 __ LoadObject(RAX, Bool::True(), PP); 1420 __ LoadObject(RAX, Bool::True());
1424 __ ret(); 1421 __ ret();
1425 __ Bind(&is_false); 1422 __ Bind(&is_false);
1426 __ LoadObject(RAX, Bool::False(), PP); 1423 __ LoadObject(RAX, Bool::False());
1427 __ ret(); 1424 __ ret();
1428 __ Bind(&is_zero); 1425 __ Bind(&is_zero);
1429 // Check for negative zero (get the sign bit). 1426 // Check for negative zero (get the sign bit).
1430 __ movmskpd(RAX, XMM0); 1427 __ movmskpd(RAX, XMM0);
1431 __ testq(RAX, Immediate(1)); 1428 __ testq(RAX, Immediate(1));
1432 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); 1429 __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
1433 __ jmp(&is_false, Assembler::kNearJump); 1430 __ jmp(&is_false, Assembler::kNearJump);
1434 } 1431 }
1435 1432
1436 1433
(...skipping 18 matching lines...) Expand all
1455 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1452 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1456 // Argument is double and is in RAX. 1453 // Argument is double and is in RAX.
1457 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); 1454 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
1458 __ Bind(&double_op); 1455 __ Bind(&double_op);
1459 __ sqrtsd(XMM0, XMM1); 1456 __ sqrtsd(XMM0, XMM1);
1460 const Class& double_class = Class::Handle( 1457 const Class& double_class = Class::Handle(
1461 Isolate::Current()->object_store()->double_class()); 1458 Isolate::Current()->object_store()->double_class());
1462 __ TryAllocate(double_class, 1459 __ TryAllocate(double_class,
1463 &fall_through, 1460 &fall_through,
1464 Assembler::kFarJump, 1461 Assembler::kFarJump,
1465 RAX, // Result register. 1462 RAX); // Result register.
1466 kNoRegister); // Pool pointer might not be loaded.
1467 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 1463 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
1468 __ ret(); 1464 __ ret();
1469 __ Bind(&is_smi); 1465 __ Bind(&is_smi);
1470 __ SmiUntag(RAX); 1466 __ SmiUntag(RAX);
1471 __ cvtsi2sdq(XMM1, RAX); 1467 __ cvtsi2sdq(XMM1, RAX);
1472 __ jmp(&double_op); 1468 __ jmp(&double_op);
1473 __ Bind(&fall_through); 1469 __ Bind(&fall_through);
1474 } 1470 }
1475 1471
1476 1472
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 1508
1513 // Identity comparison. 1509 // Identity comparison.
1514 void Intrinsifier::ObjectEquals(Assembler* assembler) { 1510 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1515 Label is_true; 1511 Label is_true;
1516 const intptr_t kReceiverOffset = 2; 1512 const intptr_t kReceiverOffset = 2;
1517 const intptr_t kArgumentOffset = 1; 1513 const intptr_t kArgumentOffset = 1;
1518 1514
1519 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); 1515 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
1520 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); 1516 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
1521 __ j(EQUAL, &is_true, Assembler::kNearJump); 1517 __ j(EQUAL, &is_true, Assembler::kNearJump);
1522 __ LoadObject(RAX, Bool::False(), PP); 1518 __ LoadObject(RAX, Bool::False());
1523 __ ret(); 1519 __ ret();
1524 __ Bind(&is_true); 1520 __ Bind(&is_true);
1525 __ LoadObject(RAX, Bool::True(), PP); 1521 __ LoadObject(RAX, Bool::True());
1526 __ ret(); 1522 __ ret();
1527 } 1523 }
1528 1524
1529 1525
1530 // Return type quickly for simple types (not parameterized and not signature). 1526 // Return type quickly for simple types (not parameterized and not signature).
1531 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) { 1527 void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
1532 Label fall_through; 1528 Label fall_through;
1533 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1529 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1534 __ LoadClassIdMayBeSmi(RCX, RAX); 1530 __ LoadClassIdMayBeSmi(RCX, RAX);
1535 1531
1536 // RCX: untagged cid of instance (RAX). 1532 // RCX: untagged cid of instance (RAX).
1537 __ LoadClassById(RDI, RCX, PP); 1533 __ LoadClassById(RDI, RCX);
1538 // RDI: class of instance (RAX). 1534 // RDI: class of instance (RAX).
1539 __ movq(RCX, FieldAddress(RDI, Class::signature_function_offset())); 1535 __ movq(RCX, FieldAddress(RDI, Class::signature_function_offset()));
1540 __ CompareObject(RCX, Object::null_object(), PP); 1536 __ CompareObject(RCX, Object::null_object());
1541 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1537 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1542 1538
1543 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset())); 1539 __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
1544 __ cmpq(RCX, Immediate(0)); 1540 __ cmpq(RCX, Immediate(0));
1545 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1541 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1546 __ movq(RAX, FieldAddress(RDI, Class::canonical_types_offset())); 1542 __ movq(RAX, FieldAddress(RDI, Class::canonical_types_offset()));
1547 __ CompareObject(RAX, Object::null_object(), PP); 1543 __ CompareObject(RAX, Object::null_object());
1548 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set. 1544 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Not yet set.
1549 __ ret(); 1545 __ ret();
1550 1546
1551 __ Bind(&fall_through); 1547 __ Bind(&fall_through);
1552 } 1548 }
1553 1549
1554 1550
1555 void Intrinsifier::String_getHashCode(Assembler* assembler) { 1551 void Intrinsifier::String_getHashCode(Assembler* assembler) {
1556 Label fall_through; 1552 Label fall_through;
1557 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1553 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1601 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1606 __ CompareClassId(RAX, kOneByteStringCid); 1602 __ CompareClassId(RAX, kOneByteStringCid);
1607 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump); 1603 __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
1608 __ SmiUntag(RCX); 1604 __ SmiUntag(RCX);
1609 __ movzxb(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); 1605 __ movzxb(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
1610 __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols)); 1606 __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
1611 __ j(GREATER_EQUAL, &fall_through); 1607 __ j(GREATER_EQUAL, &fall_through);
1612 const ExternalLabel symbols_label( 1608 const ExternalLabel symbols_label(
1613 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 1609 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1614 __ pushq(PP); 1610 __ pushq(PP);
1615 __ LoadPoolPointer(PP); 1611 __ LoadPoolPointer();
1616 assembler->set_constant_pool_allowed(true); 1612 assembler->set_constant_pool_allowed(true);
1617 __ LoadExternalLabel(RAX, &symbols_label, kNotPatchable, PP); 1613 __ LoadExternalLabel(RAX, &symbols_label, kNotPatchable);
1618 assembler->set_constant_pool_allowed(false); 1614 assembler->set_constant_pool_allowed(false);
1619 __ popq(PP); 1615 __ popq(PP);
1620 __ movq(RAX, Address(RAX, 1616 __ movq(RAX, Address(RAX,
1621 RCX, 1617 RCX,
1622 TIMES_8, 1618 TIMES_8,
1623 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 1619 Symbols::kNullCharCodeSymbolOffset * kWordSize));
1624 __ ret(); 1620 __ ret();
1625 1621
1626 __ Bind(&try_two_byte_string); 1622 __ Bind(&try_two_byte_string);
1627 __ CompareClassId(RAX, kTwoByteStringCid); 1623 __ CompareClassId(RAX, kTwoByteStringCid);
1628 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 1624 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
1629 ASSERT(kSmiTagShift == 1); 1625 ASSERT(kSmiTagShift == 1);
1630 __ movzxw(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); 1626 __ movzxw(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
1631 __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols)); 1627 __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
1632 __ j(GREATER_EQUAL, &fall_through); 1628 __ j(GREATER_EQUAL, &fall_through);
1633 __ pushq(PP); 1629 __ pushq(PP);
1634 __ LoadPoolPointer(PP); 1630 __ LoadPoolPointer();
1635 assembler->set_constant_pool_allowed(true); 1631 assembler->set_constant_pool_allowed(true);
1636 __ LoadExternalLabel(RAX, &symbols_label, kNotPatchable, PP); 1632 __ LoadExternalLabel(RAX, &symbols_label, kNotPatchable);
1637 assembler->set_constant_pool_allowed(false); 1633 assembler->set_constant_pool_allowed(false);
1638 __ popq(PP); 1634 __ popq(PP);
1639 __ movq(RAX, Address(RAX, 1635 __ movq(RAX, Address(RAX,
1640 RCX, 1636 RCX,
1641 TIMES_8, 1637 TIMES_8,
1642 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 1638 Symbols::kNullCharCodeSymbolOffset * kWordSize));
1643 __ ret(); 1639 __ ret();
1644 1640
1645 __ Bind(&fall_through); 1641 __ Bind(&fall_through);
1646 } 1642 }
1647 1643
1648 1644
1649 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) { 1645 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
1650 Label is_true; 1646 Label is_true;
1651 // Get length. 1647 // Get length.
1652 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1648 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1653 __ movq(RAX, FieldAddress(RAX, String::length_offset())); 1649 __ movq(RAX, FieldAddress(RAX, String::length_offset()));
1654 __ cmpq(RAX, Immediate(Smi::RawValue(0))); 1650 __ cmpq(RAX, Immediate(Smi::RawValue(0)));
1655 __ j(EQUAL, &is_true, Assembler::kNearJump); 1651 __ j(EQUAL, &is_true, Assembler::kNearJump);
1656 __ LoadObject(RAX, Bool::False(), PP); 1652 __ LoadObject(RAX, Bool::False());
1657 __ ret(); 1653 __ ret();
1658 __ Bind(&is_true); 1654 __ Bind(&is_true);
1659 __ LoadObject(RAX, Bool::True(), PP); 1655 __ LoadObject(RAX, Bool::True());
1660 __ ret(); 1656 __ ret();
1661 } 1657 }
1662 1658
1663 1659
1664 void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) { 1660 void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
1665 Label compute_hash; 1661 Label compute_hash;
1666 __ movq(RBX, Address(RSP, + 1 * kWordSize)); // OneByteString object. 1662 __ movq(RBX, Address(RSP, + 1 * kWordSize)); // OneByteString object.
1667 __ movq(RAX, FieldAddress(RBX, String::hash_offset())); 1663 __ movq(RAX, FieldAddress(RBX, String::hash_offset()));
1668 __ cmpq(RAX, Immediate(0)); 1664 __ cmpq(RAX, Immediate(0));
1669 __ j(EQUAL, &compute_hash, Assembler::kNearJump); 1665 __ j(EQUAL, &compute_hash, Assembler::kNearJump);
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 __ movzxw(RDX, 1917 __ movzxw(RDX,
1922 FieldAddress(RCX, RDI, TIMES_2, TwoByteString::data_offset())); 1918 FieldAddress(RCX, RDI, TIMES_2, TwoByteString::data_offset()));
1923 } else { 1919 } else {
1924 UNIMPLEMENTED(); 1920 UNIMPLEMENTED();
1925 } 1921 }
1926 __ cmpq(RBX, RDX); 1922 __ cmpq(RBX, RDX);
1927 __ j(NOT_EQUAL, &is_false, Assembler::kNearJump); 1923 __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
1928 __ jmp(&loop, Assembler::kNearJump); 1924 __ jmp(&loop, Assembler::kNearJump);
1929 1925
1930 __ Bind(&is_true); 1926 __ Bind(&is_true);
1931 __ LoadObject(RAX, Bool::True(), PP); 1927 __ LoadObject(RAX, Bool::True());
1932 __ ret(); 1928 __ ret();
1933 1929
1934 __ Bind(&is_false); 1930 __ Bind(&is_false);
1935 __ LoadObject(RAX, Bool::False(), PP); 1931 __ LoadObject(RAX, Bool::False());
1936 __ ret(); 1932 __ ret();
1937 1933
1938 __ Bind(&fall_through); 1934 __ Bind(&fall_through);
1939 } 1935 }
1940 1936
1941 1937
1942 void Intrinsifier::OneByteString_equality(Assembler* assembler) { 1938 void Intrinsifier::OneByteString_equality(Assembler* assembler) {
1943 StringEquality(assembler, kOneByteStringCid); 1939 StringEquality(assembler, kOneByteStringCid);
1944 } 1940 }
1945 1941
(...skipping 13 matching lines...) Expand all
1959 // Incoming registers: 1955 // Incoming registers:
1960 // RAX: Function. (Will be loaded with the specialized matcher function.) 1956 // RAX: Function. (Will be loaded with the specialized matcher function.)
1961 // RCX: Unknown. (Must be GC safe on tail call.) 1957 // RCX: Unknown. (Must be GC safe on tail call.)
1962 // R10: Arguments descriptor. (Will be preserved.) 1958 // R10: Arguments descriptor. (Will be preserved.)
1963 1959
1964 // Load the specialized function pointer into RAX. Leverage the fact the 1960 // Load the specialized function pointer into RAX. Leverage the fact the
1965 // string CIDs as well as stored function pointers are in sequence. 1961 // string CIDs as well as stored function pointers are in sequence.
1966 __ movq(RBX, Address(RSP, kRegExpParamOffset)); 1962 __ movq(RBX, Address(RSP, kRegExpParamOffset));
1967 __ movq(RDI, Address(RSP, kStringParamOffset)); 1963 __ movq(RDI, Address(RSP, kStringParamOffset));
1968 __ LoadClassId(RDI, RDI); 1964 __ LoadClassId(RDI, RDI);
1969 __ SubImmediate(RDI, Immediate(kOneByteStringCid), PP); 1965 __ SubImmediate(RDI, Immediate(kOneByteStringCid));
1970 __ movq(RAX, FieldAddress(RBX, RDI, TIMES_8, 1966 __ movq(RAX, FieldAddress(RBX, RDI, TIMES_8,
1971 JSRegExp::function_offset(kOneByteStringCid))); 1967 JSRegExp::function_offset(kOneByteStringCid)));
1972 1968
1973 // Registers are now set up for the lazy compile stub. It expects the function 1969 // Registers are now set up for the lazy compile stub. It expects the function
1974 // in RAX, the argument descriptor in R10, and IC-Data in RCX. 1970 // in RAX, the argument descriptor in R10, and IC-Data in RCX.
1975 static const intptr_t arg_count = RegExpMacroAssembler::kParamCount; 1971 static const intptr_t arg_count = RegExpMacroAssembler::kParamCount;
1976 __ LoadObject(R10, 1972 __ LoadObject(R10,
1977 Array::ZoneHandle(ArgumentsDescriptor::New(arg_count)), PP); 1973 Array::ZoneHandle(ArgumentsDescriptor::New(arg_count)));
1978 __ xorq(RCX, RCX); 1974 __ xorq(RCX, RCX);
1979 1975
1980 // Tail-call the function. 1976 // Tail-call the function.
1981 __ movq(RDI, FieldAddress(RAX, Function::instructions_offset())); 1977 __ movq(RDI, FieldAddress(RAX, Function::instructions_offset()));
1982 __ addq(RDI, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1978 __ addq(RDI, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1983 __ jmp(RDI); 1979 __ jmp(RDI);
1984 } 1980 }
1985 1981
1986 1982
1987 // On stack: user tag (+1), return-address (+0). 1983 // On stack: user tag (+1), return-address (+0).
(...skipping 25 matching lines...) Expand all
2013 __ LoadIsolate(RAX); 2009 __ LoadIsolate(RAX);
2014 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); 2010 __ movq(RAX, Address(RAX, Isolate::current_tag_offset()));
2015 __ ret(); 2011 __ ret();
2016 } 2012 }
2017 2013
2018 #undef __ 2014 #undef __
2019 2015
2020 } // namespace dart 2016 } // namespace dart
2021 2017
2022 #endif // defined TARGET_ARCH_X64 2018 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698