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

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

Issue 2874763003: Add AddImmediate(reg, int) to ARM64 assembler (Closed)
Patch Set: Fix bug Created 3 years, 7 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
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | no next file » | 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 80
81 // There are no runtime calls to closures, so we do not need to set the tag 81 // There are no runtime calls to closures, so we do not need to set the tag
82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. 82 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
83 ASSERT(argc_tag_offset == 1 * kWordSize); 83 ASSERT(argc_tag_offset == 1 * kWordSize);
84 __ mov(R1, R4); // Set argc in NativeArguments. 84 __ mov(R1, R4); // Set argc in NativeArguments.
85 85
86 ASSERT(argv_offset == 2 * kWordSize); 86 ASSERT(argv_offset == 2 * kWordSize);
87 __ add(R2, ZR, Operand(R4, LSL, 3)); 87 __ add(R2, ZR, Operand(R4, LSL, 3));
88 __ add(R2, FP, Operand(R2)); // Compute argv. 88 __ add(R2, FP, Operand(R2)); // Compute argv.
89 // Set argv in NativeArguments. 89 // Set argv in NativeArguments.
90 __ AddImmediate(R2, R2, kParamEndSlotFromFp * kWordSize); 90 __ AddImmediate(R2, kParamEndSlotFromFp * kWordSize);
91 91
92 ASSERT(retval_offset == 3 * kWordSize); 92 ASSERT(retval_offset == 3 * kWordSize);
93 __ AddImmediate(R3, R2, kWordSize); 93 __ AddImmediate(R3, R2, kWordSize);
94 94
95 __ StoreToOffset(R0, SP, thread_offset); 95 __ StoreToOffset(R0, SP, thread_offset);
96 __ StoreToOffset(R1, SP, argc_tag_offset); 96 __ StoreToOffset(R1, SP, argc_tag_offset);
97 __ StoreToOffset(R2, SP, argv_offset); 97 __ StoreToOffset(R2, SP, argv_offset);
98 __ StoreToOffset(R3, SP, retval_offset); 98 __ StoreToOffset(R3, SP, retval_offset);
99 __ mov(R0, SP); // Pass the pointer to the NativeArguments. 99 __ mov(R0, SP); // Pass the pointer to the NativeArguments.
100 100
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 static void PushArgumentsArray(Assembler* assembler) { 410 static void PushArgumentsArray(Assembler* assembler) {
411 // Allocate array to store arguments of caller. 411 // Allocate array to store arguments of caller.
412 __ LoadObject(R1, Object::null_object()); 412 __ LoadObject(R1, Object::null_object());
413 // R1: null element type for raw Array. 413 // R1: null element type for raw Array.
414 // R2: smi-tagged argument count, may be zero. 414 // R2: smi-tagged argument count, may be zero.
415 __ BranchLink(*StubCode::AllocateArray_entry()); 415 __ BranchLink(*StubCode::AllocateArray_entry());
416 // R0: newly allocated array. 416 // R0: newly allocated array.
417 // R2: smi-tagged argument count, may be zero (was preserved by the stub). 417 // R2: smi-tagged argument count, may be zero (was preserved by the stub).
418 __ Push(R0); // Array is in R0 and on top of stack. 418 __ Push(R0); // Array is in R0 and on top of stack.
419 __ add(R1, FP, Operand(R2, LSL, 2)); 419 __ add(R1, FP, Operand(R2, LSL, 2));
420 __ AddImmediate(R1, R1, kParamEndSlotFromFp * kWordSize); 420 __ AddImmediate(R1, kParamEndSlotFromFp * kWordSize);
421 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag); 421 __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag);
422 // R1: address of first argument on stack. 422 // R1: address of first argument on stack.
423 // R3: address of first argument in array. 423 // R3: address of first argument in array.
424 424
425 Label loop, loop_exit; 425 Label loop, loop_exit;
426 __ CompareRegisters(R2, ZR); 426 __ CompareRegisters(R2, ZR);
427 __ b(&loop_exit, LE); 427 __ b(&loop_exit, LE);
428 __ Bind(&loop); 428 __ Bind(&loop);
429 __ ldr(R7, Address(R1)); 429 __ ldr(R7, Address(R1));
430 __ AddImmediate(R1, R1, -kWordSize); 430 __ AddImmediate(R1, -kWordSize);
431 __ AddImmediate(R3, R3, kWordSize); 431 __ AddImmediate(R3, kWordSize);
432 __ AddImmediateSetFlags(R2, R2, -Smi::RawValue(1)); 432 __ AddImmediateSetFlags(R2, R2, -Smi::RawValue(1));
433 __ str(R7, Address(R3, -kWordSize)); 433 __ str(R7, Address(R3, -kWordSize));
434 __ b(&loop, GE); 434 __ b(&loop, GE);
435 __ Bind(&loop_exit); 435 __ Bind(&loop_exit);
436 } 436 }
437 437
438 438
439 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. 439 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
440 // This stub translates optimized frame into unoptimized frame. The optimized 440 // This stub translates optimized frame into unoptimized frame. The optimized
441 // frame can contain values in registers and on stack, the unoptimized 441 // frame can contain values in registers and on stack, the unoptimized
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag); 790 __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag);
791 // R1: iterator which initially points to the start of the variable 791 // R1: iterator which initially points to the start of the variable
792 // data area to be initialized. 792 // data area to be initialized.
793 __ LoadObject(TMP, Object::null_object()); 793 __ LoadObject(TMP, Object::null_object());
794 Label loop, done; 794 Label loop, done;
795 __ Bind(&loop); 795 __ Bind(&loop);
796 // TODO(cshapiro): StoreIntoObjectNoBarrier 796 // TODO(cshapiro): StoreIntoObjectNoBarrier
797 __ CompareRegisters(R1, R7); 797 __ CompareRegisters(R1, R7);
798 __ b(&done, CS); 798 __ b(&done, CS);
799 __ str(TMP, Address(R1)); // Store if unsigned lower. 799 __ str(TMP, Address(R1)); // Store if unsigned lower.
800 __ AddImmediate(R1, R1, kWordSize); 800 __ AddImmediate(R1, kWordSize);
801 __ b(&loop); // Loop until R1 == R7. 801 __ b(&loop); // Loop until R1 == R7.
802 __ Bind(&done); 802 __ Bind(&done);
803 803
804 // Done allocating and initializing the array. 804 // Done allocating and initializing the array.
805 // R0: new object. 805 // R0: new object.
806 // R2: array length as Smi (preserved for the caller.) 806 // R2: array length as Smi (preserved for the caller.)
807 __ ret(); 807 __ ret();
808 808
809 // Unable to allocate the array using the fast inline code, just call 809 // Unable to allocate the array using the fast inline code, just call
810 // into the runtime. 810 // into the runtime.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 887
888 // Load arguments descriptor array into R4, which is passed to Dart code. 888 // Load arguments descriptor array into R4, which is passed to Dart code.
889 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle); 889 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle);
890 890
891 // Load number of arguments into S5. 891 // Load number of arguments into S5.
892 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset()); 892 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset());
893 __ SmiUntag(R5); 893 __ SmiUntag(R5);
894 894
895 // Compute address of 'arguments array' data area into R2. 895 // Compute address of 'arguments array' data area into R2.
896 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle); 896 __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle);
897 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); 897 __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag);
898 898
899 // Set up arguments for the Dart call. 899 // Set up arguments for the Dart call.
900 Label push_arguments; 900 Label push_arguments;
901 Label done_push_arguments; 901 Label done_push_arguments;
902 __ cmp(R5, Operand(0)); 902 __ cmp(R5, Operand(0));
903 __ b(&done_push_arguments, EQ); // check if there are arguments. 903 __ b(&done_push_arguments, EQ); // check if there are arguments.
904 __ LoadImmediate(R1, 0); 904 __ LoadImmediate(R1, 0);
905 __ Bind(&push_arguments); 905 __ Bind(&push_arguments);
906 __ ldr(R3, Address(R2)); 906 __ ldr(R3, Address(R2));
907 __ Push(R3); 907 __ Push(R3);
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 // R2: new object. 1215 // R2: new object.
1216 // R3: next object start. 1216 // R3: next object start.
1217 // R4: next word to be initialized. 1217 // R4: next word to be initialized.
1218 // R1: new object type arguments (if is_cls_parameterized). 1218 // R1: new object type arguments (if is_cls_parameterized).
1219 Label init_loop; 1219 Label init_loop;
1220 Label done; 1220 Label done;
1221 __ Bind(&init_loop); 1221 __ Bind(&init_loop);
1222 __ CompareRegisters(R4, R3); 1222 __ CompareRegisters(R4, R3);
1223 __ b(&done, CS); 1223 __ b(&done, CS);
1224 __ str(R0, Address(R4)); 1224 __ str(R0, Address(R4));
1225 __ AddImmediate(R4, R4, kWordSize); 1225 __ AddImmediate(R4, kWordSize);
1226 __ b(&init_loop); 1226 __ b(&init_loop);
1227 __ Bind(&done); 1227 __ Bind(&done);
1228 } 1228 }
1229 if (is_cls_parameterized) { 1229 if (is_cls_parameterized) {
1230 // R1: new object type arguments. 1230 // R1: new object type arguments.
1231 // Set the type arguments in the new object. 1231 // Set the type arguments in the new object.
1232 __ StoreToOffset(R1, R2, cls.type_arguments_field_offset()); 1232 __ StoreToOffset(R1, R2, cls.type_arguments_field_offset());
1233 } 1233 }
1234 // Done allocating and initializing the instance. 1234 // Done allocating and initializing the instance.
1235 // R2: new object still missing its heap tag. 1235 // R2: new object still missing its heap tag.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1324 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1325 Register temp_reg) { 1325 Register temp_reg) {
1326 if (FLAG_optimization_counter_threshold >= 0) { 1326 if (FLAG_optimization_counter_threshold >= 0) {
1327 Register ic_reg = R5; 1327 Register ic_reg = R5;
1328 Register func_reg = temp_reg; 1328 Register func_reg = temp_reg;
1329 ASSERT(temp_reg == R6); 1329 ASSERT(temp_reg == R6);
1330 __ Comment("Increment function counter"); 1330 __ Comment("Increment function counter");
1331 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset()); 1331 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset());
1332 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(), 1332 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(),
1333 kWord); 1333 kWord);
1334 __ AddImmediate(R7, R7, 1); 1334 __ AddImmediate(R7, 1);
1335 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(), 1335 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(),
1336 kWord); 1336 kWord);
1337 } 1337 }
1338 } 1338 }
1339 1339
1340 1340
1341 // Note: R5 must be preserved. 1341 // Note: R5 must be preserved.
1342 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1342 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1343 // must have been primed with a Smi/Smi check that will be used for counting 1343 // must have been primed with a Smi/Smi check that will be used for counting
1344 // the invocations. 1344 // the invocations.
(...skipping 25 matching lines...) Expand all
1370 __ csel(R0, R1, R0, NE); 1370 __ csel(R0, R1, R0, NE);
1371 break; 1371 break;
1372 } 1372 }
1373 default: 1373 default:
1374 UNIMPLEMENTED(); 1374 UNIMPLEMENTED();
1375 } 1375 }
1376 1376
1377 // R5: IC data object (preserved). 1377 // R5: IC data object (preserved).
1378 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); 1378 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
1379 // R6: ic_data_array with check entries: classes and target functions. 1379 // R6: ic_data_array with check entries: classes and target functions.
1380 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1380 __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
1381 // R6: points directly to the first ic data array element. 1381 // R6: points directly to the first ic data array element.
1382 #if defined(DEBUG) 1382 #if defined(DEBUG)
1383 // Check that first entry is for Smi/Smi. 1383 // Check that first entry is for Smi/Smi.
1384 Label error, ok; 1384 Label error, ok;
1385 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid)); 1385 const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid));
1386 __ ldr(R1, Address(R6, 0)); 1386 __ ldr(R1, Address(R6, 0));
1387 __ CompareImmediate(R1, imm_smi_cid); 1387 __ CompareImmediate(R1, imm_smi_cid);
1388 __ b(&error, NE); 1388 __ b(&error, NE);
1389 __ ldr(R1, Address(R6, kWordSize)); 1389 __ ldr(R1, Address(R6, kWordSize));
1390 __ CompareImmediate(R1, imm_smi_cid); 1390 __ CompareImmediate(R1, imm_smi_cid);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 __ Bind(&not_smi_or_overflow); 1455 __ Bind(&not_smi_or_overflow);
1456 1456
1457 __ Comment("Extract ICData initial values and receiver cid"); 1457 __ Comment("Extract ICData initial values and receiver cid");
1458 // Load arguments descriptor into R4. 1458 // Load arguments descriptor into R4.
1459 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); 1459 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset());
1460 // Loop that checks if there is an IC data match. 1460 // Loop that checks if there is an IC data match.
1461 Label loop, found, miss; 1461 Label loop, found, miss;
1462 // R5: IC data object (preserved). 1462 // R5: IC data object (preserved).
1463 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); 1463 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
1464 // R6: ic_data_array with check entries: classes and target functions. 1464 // R6: ic_data_array with check entries: classes and target functions.
1465 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1465 __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
1466 // R6: points directly to the first ic data array element. 1466 // R6: points directly to the first ic data array element.
1467 1467
1468 // Get the receiver's class ID (first read number of arguments from 1468 // Get the receiver's class ID (first read number of arguments from
1469 // arguments descriptor array and then access the receiver from the stack). 1469 // arguments descriptor array and then access the receiver from the stack).
1470 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset()); 1470 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset());
1471 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode. 1471 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode.
1472 __ sub(R7, R7, Operand(1)); 1472 __ sub(R7, R7, Operand(1));
1473 1473
1474 // R0 <- [SP + (R7 << 3)] 1474 // R0 <- [SP + (R7 << 3)]
1475 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled)); 1475 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled));
(...skipping 20 matching lines...) Expand all
1496 __ b(&update, NE); // Continue. 1496 __ b(&update, NE); // Continue.
1497 __ LoadFromOffset(R2, R6, kWordSize); 1497 __ LoadFromOffset(R2, R6, kWordSize);
1498 __ CompareRegisters(R1, R2); // Class id match? 1498 __ CompareRegisters(R1, R2); // Class id match?
1499 } 1499 }
1500 __ b(&found, EQ); // Break. 1500 __ b(&found, EQ); // Break.
1501 1501
1502 __ Bind(&update); 1502 __ Bind(&update);
1503 1503
1504 const intptr_t entry_size = 1504 const intptr_t entry_size =
1505 ICData::TestEntryLengthFor(num_args) * kWordSize; 1505 ICData::TestEntryLengthFor(num_args) * kWordSize;
1506 __ AddImmediate(R6, R6, entry_size); // Next entry. 1506 __ AddImmediate(R6, entry_size); // Next entry.
1507 1507
1508 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); // Done? 1508 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); // Done?
1509 if (unroll == 0) { 1509 if (unroll == 0) {
1510 __ b(&loop, NE); 1510 __ b(&loop, NE);
1511 } else { 1511 } else {
1512 __ b(&miss, EQ); 1512 __ b(&miss, EQ);
1513 } 1513 }
1514 } 1514 }
1515 1515
1516 __ Bind(&miss); 1516 __ Bind(&miss);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 __ LoadIsolate(R6); 1675 __ LoadIsolate(R6);
1676 __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte); 1676 __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte);
1677 __ CompareImmediate(R6, 0); 1677 __ CompareImmediate(R6, 0);
1678 __ b(&stepping, NE); 1678 __ b(&stepping, NE);
1679 __ Bind(&done_stepping); 1679 __ Bind(&done_stepping);
1680 } 1680 }
1681 1681
1682 // R5: IC data object (preserved). 1682 // R5: IC data object (preserved).
1683 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset()); 1683 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
1684 // R6: ic_data_array with entries: target functions and count. 1684 // R6: ic_data_array with entries: target functions and count.
1685 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1685 __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
1686 // R6: points directly to the first ic data array element. 1686 // R6: points directly to the first ic data array element.
1687 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1687 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1688 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1688 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1689 1689
1690 if (FLAG_optimization_counter_threshold >= 0) { 1690 if (FLAG_optimization_counter_threshold >= 0) {
1691 // Increment count for this call, ignore overflow. 1691 // Increment count for this call, ignore overflow.
1692 __ LoadFromOffset(R1, R6, count_offset); 1692 __ LoadFromOffset(R1, R6, count_offset);
1693 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1693 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1694 __ StoreToOffset(R1, R6, count_offset); 1694 __ StoreToOffset(R1, R6, count_offset);
1695 } 1695 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 __ Bind(&has_no_type_arguments); 1819 __ Bind(&has_no_type_arguments);
1820 } 1820 }
1821 __ LoadClassId(R6, R0); 1821 __ LoadClassId(R6, R0);
1822 // R0: instance. 1822 // R0: instance.
1823 // R1: instantiator type arguments (only if n == 4, can be raw_null). 1823 // R1: instantiator type arguments (only if n == 4, can be raw_null).
1824 // R2: function type arguments (only if n == 4, can be raw_null). 1824 // R2: function type arguments (only if n == 4, can be raw_null).
1825 // R3: SubtypeTestCache. 1825 // R3: SubtypeTestCache.
1826 // R6: instance class id. 1826 // R6: instance class id.
1827 // R4: instance type arguments (null if none), used only if n > 1. 1827 // R4: instance type arguments (null if none), used only if n > 1.
1828 __ LoadFieldFromOffset(R3, R3, SubtypeTestCache::cache_offset()); 1828 __ LoadFieldFromOffset(R3, R3, SubtypeTestCache::cache_offset());
1829 __ AddImmediate(R3, R3, Array::data_offset() - kHeapObjectTag); 1829 __ AddImmediate(R3, Array::data_offset() - kHeapObjectTag);
1830 1830
1831 Label loop, found, not_found, next_iteration; 1831 Label loop, found, not_found, next_iteration;
1832 // R3: entry start. 1832 // R3: entry start.
1833 // R6: instance class id. 1833 // R6: instance class id.
1834 // R4: instance type arguments (still null if closure). 1834 // R4: instance type arguments (still null if closure).
1835 __ SmiTag(R6); 1835 __ SmiTag(R6);
1836 __ CompareImmediate(R6, Smi::RawValue(kClosureCid)); 1836 __ CompareImmediate(R6, Smi::RawValue(kClosureCid));
1837 __ b(&loop, NE); 1837 __ b(&loop, NE);
1838 __ LoadFieldFromOffset(R4, R0, Closure::function_type_arguments_offset()); 1838 __ LoadFieldFromOffset(R4, R0, Closure::function_type_arguments_offset());
1839 __ CompareObject(R4, Object::null_object()); 1839 __ CompareObject(R4, Object::null_object());
(...skipping 22 matching lines...) Expand all
1862 R5, R3, kWordSize * SubtypeTestCache::kInstantiatorTypeArguments); 1862 R5, R3, kWordSize * SubtypeTestCache::kInstantiatorTypeArguments);
1863 __ CompareRegisters(R5, R1); 1863 __ CompareRegisters(R5, R1);
1864 __ b(&next_iteration, NE); 1864 __ b(&next_iteration, NE);
1865 __ LoadFromOffset(R5, R3, 1865 __ LoadFromOffset(R5, R3,
1866 kWordSize * SubtypeTestCache::kFunctionTypeArguments); 1866 kWordSize * SubtypeTestCache::kFunctionTypeArguments);
1867 __ CompareRegisters(R5, R2); 1867 __ CompareRegisters(R5, R2);
1868 __ b(&found, EQ); 1868 __ b(&found, EQ);
1869 } 1869 }
1870 } 1870 }
1871 __ Bind(&next_iteration); 1871 __ Bind(&next_iteration);
1872 __ AddImmediate(R3, R3, kWordSize * SubtypeTestCache::kTestEntryLength); 1872 __ AddImmediate(R3, kWordSize * SubtypeTestCache::kTestEntryLength);
1873 __ b(&loop); 1873 __ b(&loop);
1874 // Fall through to not found. 1874 // Fall through to not found.
1875 __ Bind(&not_found); 1875 __ Bind(&not_found);
1876 __ LoadObject(R1, Object::null_object()); 1876 __ LoadObject(R1, Object::null_object());
1877 __ ret(); 1877 __ ret();
1878 1878
1879 __ Bind(&found); 1879 __ Bind(&found);
1880 __ LoadFromOffset(R1, R3, kWordSize * SubtypeTestCache::kTestResult); 1880 __ LoadFromOffset(R1, R3, kWordSize * SubtypeTestCache::kTestResult);
1881 __ ret(); 1881 __ ret();
1882 } 1882 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2177 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2178 __ br(R1); 2178 __ br(R1);
2179 2179
2180 // Probe failed, check if it is a miss. 2180 // Probe failed, check if it is a miss.
2181 __ Bind(&probe_failed); 2181 __ Bind(&probe_failed);
2182 ASSERT(kIllegalCid == 0); 2182 ASSERT(kIllegalCid == 0);
2183 __ tst(R6, Operand(R6)); 2183 __ tst(R6, Operand(R6));
2184 __ b(&load_target, EQ); // branch if miss. 2184 __ b(&load_target, EQ); // branch if miss.
2185 2185
2186 // Try next extry in the table. 2186 // Try next extry in the table.
2187 __ AddImmediate(R3, R3, Smi::RawValue(1)); 2187 __ AddImmediate(R3, Smi::RawValue(1));
2188 __ b(&loop); 2188 __ b(&loop);
2189 2189
2190 // Load cid for the Smi case. 2190 // Load cid for the Smi case.
2191 __ Bind(&smi_case); 2191 __ Bind(&smi_case);
2192 __ LoadImmediate(R0, kSmiCid); 2192 __ LoadImmediate(R0, kSmiCid);
2193 __ b(&cid_loaded); 2193 __ b(&cid_loaded);
2194 } 2194 }
2195 2195
2196 2196
2197 // Called from switchable IC calls. 2197 // Called from switchable IC calls.
2198 // R0: receiver 2198 // R0: receiver
2199 // R5: ICData (preserved) 2199 // R5: ICData (preserved)
2200 // Passed to target: 2200 // Passed to target:
2201 // CODE_REG: target Code object 2201 // CODE_REG: target Code object
2202 // R4: arguments descriptor 2202 // R4: arguments descriptor
2203 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) { 2203 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) {
2204 Label loop, found, miss; 2204 Label loop, found, miss;
2205 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2205 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2206 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2206 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2207 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2207 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
2208 // R8: first IC entry 2208 // R8: first IC entry
2209 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2209 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2210 // R1: receiver cid as Smi 2210 // R1: receiver cid as Smi
2211 2211
2212 __ Bind(&loop); 2212 __ Bind(&loop);
2213 __ ldr(R2, Address(R8, 0)); 2213 __ ldr(R2, Address(R8, 0));
2214 __ cmp(R1, Operand(R2)); 2214 __ cmp(R1, Operand(R2));
2215 __ b(&found, EQ); 2215 __ b(&found, EQ);
2216 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2216 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2217 __ b(&miss, EQ); 2217 __ b(&miss, EQ);
2218 2218
2219 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2219 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2220 __ AddImmediate(R8, R8, entry_length); // Next entry. 2220 __ AddImmediate(R8, entry_length); // Next entry.
2221 __ b(&loop); 2221 __ b(&loop);
2222 2222
2223 __ Bind(&found); 2223 __ Bind(&found);
2224 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; 2224 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
2225 __ ldr(R0, Address(R8, target_offset)); 2225 __ ldr(R0, Address(R8, target_offset));
2226 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); 2226 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
2227 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2227 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2228 __ br(R1); 2228 __ br(R1);
2229 2229
2230 __ Bind(&miss); 2230 __ Bind(&miss);
2231 __ LoadIsolate(R2); 2231 __ LoadIsolate(R2);
2232 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); 2232 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
2233 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); 2233 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
2234 __ br(R1); 2234 __ br(R1);
2235 } 2235 }
2236 2236
2237 2237
2238 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) { 2238 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
2239 Label loop, found, miss; 2239 Label loop, found, miss;
2240 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2240 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2241 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2241 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2242 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2242 __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
2243 // R8: first IC entry 2243 // R8: first IC entry
2244 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2244 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2245 // R1: receiver cid as Smi 2245 // R1: receiver cid as Smi
2246 2246
2247 __ Bind(&loop); 2247 __ Bind(&loop);
2248 __ ldr(R2, Address(R8, 0)); 2248 __ ldr(R2, Address(R8, 0));
2249 __ cmp(R1, Operand(R2)); 2249 __ cmp(R1, Operand(R2));
2250 __ b(&found, EQ); 2250 __ b(&found, EQ);
2251 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2251 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2252 __ b(&miss, EQ); 2252 __ b(&miss, EQ);
2253 2253
2254 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2254 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2255 __ AddImmediate(R8, R8, entry_length); // Next entry. 2255 __ AddImmediate(R8, entry_length); // Next entry.
2256 __ b(&loop); 2256 __ b(&loop);
2257 2257
2258 __ Bind(&found); 2258 __ Bind(&found);
2259 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; 2259 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
2260 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; 2260 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
2261 __ ldr(R1, Address(R8, entry_offset)); 2261 __ ldr(R1, Address(R8, entry_offset));
2262 __ ldr(CODE_REG, Address(R8, code_offset)); 2262 __ ldr(CODE_REG, Address(R8, code_offset));
2263 __ br(R1); 2263 __ br(R1);
2264 2264
2265 __ Bind(&miss); 2265 __ Bind(&miss);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 } 2361 }
2362 2362
2363 2363
2364 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { 2364 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
2365 __ brk(0); 2365 __ brk(0);
2366 } 2366 }
2367 2367
2368 } // namespace dart 2368 } // namespace dart
2369 2369
2370 #endif // defined TARGET_ARCH_ARM64 2370 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698