| 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 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 // Remove arguments. | 583 // Remove arguments. |
| 584 __ Drop(3); | 584 __ Drop(3); |
| 585 __ Pop(R0); // Get result into R0 (target function). | 585 __ Pop(R0); // Get result into R0 (target function). |
| 586 | 586 |
| 587 // Restore IC data and arguments descriptor. | 587 // Restore IC data and arguments descriptor. |
| 588 __ PopList((1 << R4) | (1 << R5)); | 588 __ PopList((1 << R4) | (1 << R5)); |
| 589 | 589 |
| 590 __ LeaveStubFrame(); | 590 __ LeaveStubFrame(); |
| 591 | 591 |
| 592 // Tail-call to target function. | 592 // Tail-call to target function. |
| 593 __ ldr(R2, FieldAddress(R0, Function::code_offset())); | 593 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); |
| 594 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); | |
| 595 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); | 594 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); |
| 596 __ bx(R2); | 595 __ bx(R2); |
| 597 } | 596 } |
| 598 | 597 |
| 599 | 598 |
| 600 // Called for inline allocation of arrays. | 599 // Called for inline allocation of arrays. |
| 601 // Input parameters: | 600 // Input parameters: |
| 602 // LR: return address. | 601 // LR: return address. |
| 603 // R1: array element type (either NULL or an instantiated type). | 602 // R1: array element type (either NULL or an instantiated type). |
| 604 // R2: array length as Smi (must be preserved). | 603 // R2: array length as Smi (must be preserved). |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 __ LoadFromOffset(kWord, R0, R6, target_offset); | 1375 __ LoadFromOffset(kWord, R0, R6, target_offset); |
| 1377 __ LoadFromOffset(kWord, R1, R6, count_offset); | 1376 __ LoadFromOffset(kWord, R1, R6, count_offset); |
| 1378 __ adds(R1, R1, Operand(Smi::RawValue(1))); | 1377 __ adds(R1, R1, Operand(Smi::RawValue(1))); |
| 1379 __ StoreToOffset(kWord, R1, R6, count_offset); | 1378 __ StoreToOffset(kWord, R1, R6, count_offset); |
| 1380 __ b(&call_target_function, VC); // No overflow. | 1379 __ b(&call_target_function, VC); // No overflow. |
| 1381 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); | 1380 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); |
| 1382 __ StoreToOffset(kWord, R1, R6, count_offset); | 1381 __ StoreToOffset(kWord, R1, R6, count_offset); |
| 1383 | 1382 |
| 1384 __ Bind(&call_target_function); | 1383 __ Bind(&call_target_function); |
| 1385 // R0: target function. | 1384 // R0: target function. |
| 1386 __ ldr(R2, FieldAddress(R0, Function::code_offset())); | 1385 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); |
| 1387 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); | |
| 1388 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); | 1386 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); |
| 1389 __ bx(R2); | 1387 __ bx(R2); |
| 1390 | 1388 |
| 1391 // Instance in R0, return its class-id in R0 as Smi. | 1389 // Instance in R0, return its class-id in R0 as Smi. |
| 1392 __ Bind(&get_class_id_as_smi); | 1390 __ Bind(&get_class_id_as_smi); |
| 1393 | 1391 |
| 1394 // Test if Smi -> load Smi class for comparison. | 1392 // Test if Smi -> load Smi class for comparison. |
| 1395 __ tst(R0, Operand(kSmiTagMask)); | 1393 __ tst(R0, Operand(kSmiTagMask)); |
| 1396 __ mov(R0, Operand(Smi::RawValue(kSmiCid)), EQ); | 1394 __ mov(R0, Operand(Smi::RawValue(kSmiCid)), EQ); |
| 1397 __ bx(LR, EQ); | 1395 __ bx(LR, EQ); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 __ b(&increment_done, VC); // No overflow. | 1510 __ b(&increment_done, VC); // No overflow. |
| 1513 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); | 1511 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue)); |
| 1514 __ StoreToOffset(kWord, R1, R6, count_offset); | 1512 __ StoreToOffset(kWord, R1, R6, count_offset); |
| 1515 __ Bind(&increment_done); | 1513 __ Bind(&increment_done); |
| 1516 | 1514 |
| 1517 // Load arguments descriptor into R4. | 1515 // Load arguments descriptor into R4. |
| 1518 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1516 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
| 1519 | 1517 |
| 1520 // Get function and call it, if possible. | 1518 // Get function and call it, if possible. |
| 1521 __ LoadFromOffset(kWord, R0, R6, target_offset); | 1519 __ LoadFromOffset(kWord, R0, R6, target_offset); |
| 1522 __ ldr(R2, FieldAddress(R0, Function::code_offset())); | 1520 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); |
| 1523 | 1521 |
| 1524 // R0: function. | 1522 // R0: function. |
| 1525 // R2: target code. | 1523 // R2: target instructions. |
| 1526 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); | |
| 1527 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); | 1524 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); |
| 1528 __ bx(R2); | 1525 __ bx(R2); |
| 1529 } | 1526 } |
| 1530 | 1527 |
| 1531 | 1528 |
| 1532 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1529 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1533 GenerateUsageCounterIncrement(assembler, R6); | 1530 GenerateUsageCounterIncrement(assembler, R6); |
| 1534 GenerateNArgsCheckInlineCacheStub( | 1531 GenerateNArgsCheckInlineCacheStub( |
| 1535 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); | 1532 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); |
| 1536 } | 1533 } |
| 1537 | 1534 |
| 1538 | 1535 |
| 1539 // Stub for compiling a function and jumping to the compiled code. | 1536 // Stub for compiling a function and jumping to the compiled code. |
| 1540 // R5: IC-Data (for methods). | 1537 // R5: IC-Data (for methods). |
| 1541 // R4: Arguments descriptor. | 1538 // R4: Arguments descriptor. |
| 1542 // R0: Function. | 1539 // R0: Function. |
| 1543 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { | 1540 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1544 // Preserve arg desc. and IC data object. | 1541 // Preserve arg desc. and IC data object. |
| 1545 __ EnterStubFrame(); | 1542 __ EnterStubFrame(); |
| 1546 __ PushList((1 << R4) | (1 << R5)); | 1543 __ PushList((1 << R4) | (1 << R5)); |
| 1547 __ Push(R0); // Pass function. | 1544 __ Push(R0); // Pass function. |
| 1548 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1545 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1549 __ Pop(R0); // Restore argument. | 1546 __ Pop(R0); // Restore argument. |
| 1550 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data. | 1547 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data. |
| 1551 __ LeaveStubFrame(); | 1548 __ LeaveStubFrame(); |
| 1552 | 1549 |
| 1553 __ ldr(R2, FieldAddress(R0, Function::code_offset())); | 1550 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); |
| 1554 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); | |
| 1555 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); | 1551 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); |
| 1556 __ bx(R2); | 1552 __ bx(R2); |
| 1557 } | 1553 } |
| 1558 | 1554 |
| 1559 | 1555 |
| 1560 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1556 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1561 __ EnterStubFrame(); | 1557 __ EnterStubFrame(); |
| 1562 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1558 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 1563 // Preserve arguments descriptor and make room for result. | 1559 // Preserve arguments descriptor and make room for result. |
| 1564 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); | 1560 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1858 const Register right = R0; | 1854 const Register right = R0; |
| 1859 __ ldr(left, Address(SP, 1 * kWordSize)); | 1855 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 1860 __ ldr(right, Address(SP, 0 * kWordSize)); | 1856 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 1861 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1857 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1862 __ Ret(); | 1858 __ Ret(); |
| 1863 } | 1859 } |
| 1864 | 1860 |
| 1865 } // namespace dart | 1861 } // namespace dart |
| 1866 | 1862 |
| 1867 #endif // defined TARGET_ARCH_ARM | 1863 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |