| 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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 __ sw(TMP, Address(SP, 0 * kWordSize)); | 320 __ sw(TMP, Address(SP, 0 * kWordSize)); |
| 321 | 321 |
| 322 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 322 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 323 __ Comment("CallStaticFunctionStub return"); | 323 __ Comment("CallStaticFunctionStub return"); |
| 324 | 324 |
| 325 // Get Code object result and restore arguments descriptor array. | 325 // Get Code object result and restore arguments descriptor array. |
| 326 __ lw(T0, Address(SP, 0 * kWordSize)); | 326 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 327 __ lw(S4, Address(SP, 1 * kWordSize)); | 327 __ lw(S4, Address(SP, 1 * kWordSize)); |
| 328 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 328 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 329 | 329 |
| 330 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 330 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
| 331 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 332 | 331 |
| 333 // Remove the stub frame as we are about to jump to the dart function. | 332 // Remove the stub frame as we are about to jump to the dart function. |
| 334 __ LeaveStubFrameAndReturn(T0); | 333 __ LeaveStubFrameAndReturn(T0); |
| 335 } | 334 } |
| 336 | 335 |
| 337 | 336 |
| 338 // Called from a static call only when an invalid code has been entered | 337 // Called from a static call only when an invalid code has been entered |
| 339 // (invalid because its function was optimized or deoptimized). | 338 // (invalid because its function was optimized or deoptimized). |
| 340 // S4: arguments descriptor array. | 339 // S4: arguments descriptor array. |
| 341 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 340 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 342 // Create a stub frame as we are pushing some objects on the stack before | 341 // Create a stub frame as we are pushing some objects on the stack before |
| 343 // calling into the runtime. | 342 // calling into the runtime. |
| 344 __ Comment("FixCallersTarget"); | 343 __ Comment("FixCallersTarget"); |
| 345 __ EnterStubFrame(); | 344 __ EnterStubFrame(); |
| 346 // Setup space on stack for return value and preserve arguments descriptor. | 345 // Setup space on stack for return value and preserve arguments descriptor. |
| 347 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 346 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 348 __ sw(S4, Address(SP, 1 * kWordSize)); | 347 __ sw(S4, Address(SP, 1 * kWordSize)); |
| 349 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 348 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 350 __ sw(TMP, Address(SP, 0 * kWordSize)); | 349 __ sw(TMP, Address(SP, 0 * kWordSize)); |
| 351 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 350 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 352 // Get Code object result and restore arguments descriptor array. | 351 // Get Code object result and restore arguments descriptor array. |
| 353 __ lw(T0, Address(SP, 0 * kWordSize)); | 352 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 354 __ lw(S4, Address(SP, 1 * kWordSize)); | 353 __ lw(S4, Address(SP, 1 * kWordSize)); |
| 355 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 354 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 356 | 355 |
| 357 // Jump to the dart function. | 356 // Jump to the dart function. |
| 358 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 357 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
| 359 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 360 | 358 |
| 361 // Remove the stub frame. | 359 // Remove the stub frame. |
| 362 __ LeaveStubFrameAndReturn(T0); | 360 __ LeaveStubFrameAndReturn(T0); |
| 363 } | 361 } |
| 364 | 362 |
| 365 | 363 |
| 366 // Called from object allocate instruction when the allocation stub has been | 364 // Called from object allocate instruction when the allocation stub has been |
| 367 // disabled. | 365 // disabled. |
| 368 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 366 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
| 369 __ Comment("FixAllocationStubTarget"); | 367 __ Comment("FixAllocationStubTarget"); |
| 370 __ EnterStubFrame(); | 368 __ EnterStubFrame(); |
| 371 // Setup space on stack for return value. | 369 // Setup space on stack for return value. |
| 372 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 370 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
| 373 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 371 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 374 __ sw(TMP, Address(SP, 0 * kWordSize)); | 372 __ sw(TMP, Address(SP, 0 * kWordSize)); |
| 375 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 373 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 376 // Get Code object result. | 374 // Get Code object result. |
| 377 __ lw(T0, Address(SP, 0 * kWordSize)); | 375 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 378 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 376 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
| 379 | 377 |
| 380 // Jump to the dart function. | 378 // Jump to the dart function. |
| 381 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 379 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
| 382 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 383 | 380 |
| 384 // Remove the stub frame. | 381 // Remove the stub frame. |
| 385 __ LeaveStubFrameAndReturn(T0); | 382 __ LeaveStubFrameAndReturn(T0); |
| 386 } | 383 } |
| 387 | 384 |
| 388 | 385 |
| 389 // Input parameters: | 386 // Input parameters: |
| 390 // A1: Smi-tagged argument count, may be zero. | 387 // A1: Smi-tagged argument count, may be zero. |
| 391 // FP[kParamEndSlotFromFp + 1]: Last argument. | 388 // FP[kParamEndSlotFromFp + 1]: Last argument. |
| 392 static void PushArgumentsArray(Assembler* assembler) { | 389 static void PushArgumentsArray(Assembler* assembler) { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 626 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
| 630 | 627 |
| 631 __ LeaveStubFrame(); | 628 __ LeaveStubFrame(); |
| 632 | 629 |
| 633 if (!FLAG_lazy_dispatchers) { | 630 if (!FLAG_lazy_dispatchers) { |
| 634 Label call_target_function; | 631 Label call_target_function; |
| 635 GenerateDispatcherCode(assembler, &call_target_function); | 632 GenerateDispatcherCode(assembler, &call_target_function); |
| 636 __ Bind(&call_target_function); | 633 __ Bind(&call_target_function); |
| 637 } | 634 } |
| 638 | 635 |
| 639 __ lw(T2, FieldAddress(T0, Function::instructions_offset())); | 636 __ lw(T2, FieldAddress(T0, Function::entry_point_offset())); |
| 640 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 641 __ jr(T2); | 637 __ jr(T2); |
| 642 } | 638 } |
| 643 | 639 |
| 644 | 640 |
| 645 // Called for inline allocation of arrays. | 641 // Called for inline allocation of arrays. |
| 646 // Input parameters: | 642 // Input parameters: |
| 647 // RA: return address. | 643 // RA: return address. |
| 648 // A1: Array length as Smi (must be preserved). | 644 // A1: Array length as Smi (must be preserved). |
| 649 // A0: array element type (either NULL or an instantiated type). | 645 // A0: array element type (either NULL or an instantiated type). |
| 650 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. | 646 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); | 1593 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); |
| 1598 __ movz(T4, T7, CMPRES1); | 1594 __ movz(T4, T7, CMPRES1); |
| 1599 __ sw(T4, Address(T0, count_offset)); | 1595 __ sw(T4, Address(T0, count_offset)); |
| 1600 } | 1596 } |
| 1601 | 1597 |
| 1602 __ Comment("Call target"); | 1598 __ Comment("Call target"); |
| 1603 __ Bind(&call_target_function); | 1599 __ Bind(&call_target_function); |
| 1604 // T0 <- T3: Target function. | 1600 // T0 <- T3: Target function. |
| 1605 __ mov(T0, T3); | 1601 __ mov(T0, T3); |
| 1606 Label is_compiled; | 1602 Label is_compiled; |
| 1607 __ lw(T4, FieldAddress(T0, Function::instructions_offset())); | 1603 __ lw(T4, FieldAddress(T0, Function::entry_point_offset())); |
| 1608 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1609 if (range_collection_mode == kCollectRanges) { | 1604 if (range_collection_mode == kCollectRanges) { |
| 1610 const intptr_t frame_size = num_args + 2; | 1605 const intptr_t frame_size = num_args + 2; |
| 1611 __ lw(T3, Address(SP, 0 * kWordSize)); | 1606 __ lw(T3, Address(SP, 0 * kWordSize)); |
| 1612 if (num_args == 2) { | 1607 if (num_args == 2) { |
| 1613 __ lw(T1, Address(SP, 1 * kWordSize)); | 1608 __ lw(T1, Address(SP, 1 * kWordSize)); |
| 1614 } | 1609 } |
| 1615 __ EnterStubFrame(); | 1610 __ EnterStubFrame(); |
| 1616 __ addiu(SP, SP, Immediate(- frame_size * kWordSize)); | 1611 __ addiu(SP, SP, Immediate(- frame_size * kWordSize)); |
| 1617 __ sw(RA, Address(SP, (frame_size - 1) * kWordSize)); // Return address. | 1612 __ sw(RA, Address(SP, (frame_size - 1) * kWordSize)); // Return address. |
| 1618 __ sw(S5, Address(SP, (frame_size - 2) * kWordSize)); // Preserve IC data. | 1613 __ sw(S5, Address(SP, (frame_size - 2) * kWordSize)); // Preserve IC data. |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); | 1777 __ LoadImmediate(T4, Smi::RawValue(Smi::kMaxValue)); |
| 1783 __ movz(T4, T7, CMPRES1); | 1778 __ movz(T4, T7, CMPRES1); |
| 1784 __ sw(T4, Address(T0, count_offset)); | 1779 __ sw(T4, Address(T0, count_offset)); |
| 1785 } | 1780 } |
| 1786 | 1781 |
| 1787 // Load arguments descriptor into S4. | 1782 // Load arguments descriptor into S4. |
| 1788 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | 1783 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
| 1789 | 1784 |
| 1790 // Get function and call it, if possible. | 1785 // Get function and call it, if possible. |
| 1791 __ lw(T0, Address(T0, target_offset)); | 1786 __ lw(T0, Address(T0, target_offset)); |
| 1792 __ lw(T4, FieldAddress(T0, Function::instructions_offset())); | 1787 __ lw(T4, FieldAddress(T0, Function::entry_point_offset())); |
| 1793 | |
| 1794 // T4: target instructions. | |
| 1795 __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1796 __ jr(T4); | 1788 __ jr(T4); |
| 1797 | 1789 |
| 1798 // Call single step callback in debugger. | 1790 // Call single step callback in debugger. |
| 1799 if (FLAG_support_debugger) { | 1791 if (FLAG_support_debugger) { |
| 1800 __ Bind(&stepping); | 1792 __ Bind(&stepping); |
| 1801 __ EnterStubFrame(); | 1793 __ EnterStubFrame(); |
| 1802 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1794 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1803 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. | 1795 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. |
| 1804 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 1796 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
| 1805 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1797 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object. | 1830 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data object. |
| 1839 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array. | 1831 __ sw(S4, Address(SP, 1 * kWordSize)); // Preserve args descriptor array. |
| 1840 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function. | 1832 __ sw(T0, Address(SP, 0 * kWordSize)); // Pass function. |
| 1841 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1833 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1842 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function. | 1834 __ lw(T0, Address(SP, 0 * kWordSize)); // Restore function. |
| 1843 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array. | 1835 __ lw(S4, Address(SP, 1 * kWordSize)); // Restore args descriptor array. |
| 1844 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array. | 1836 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data array. |
| 1845 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 1837 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1846 __ LeaveStubFrame(); | 1838 __ LeaveStubFrame(); |
| 1847 | 1839 |
| 1848 __ lw(T2, FieldAddress(T0, Function::instructions_offset())); | 1840 __ lw(T2, FieldAddress(T0, Function::entry_point_offset())); |
| 1849 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag); | |
| 1850 __ jr(T2); | 1841 __ jr(T2); |
| 1851 } | 1842 } |
| 1852 | 1843 |
| 1853 | 1844 |
| 1854 // S5: Contains an ICData. | 1845 // S5: Contains an ICData. |
| 1855 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1846 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
| 1856 __ Comment("ICCallBreakpoint stub"); | 1847 __ Comment("ICCallBreakpoint stub"); |
| 1857 __ EnterStubFrame(); | 1848 __ EnterStubFrame(); |
| 1858 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1849 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1859 __ sw(S5, Address(SP, 1 * kWordSize)); | 1850 __ sw(S5, Address(SP, 1 * kWordSize)); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2069 // Setup space on stack for return value. | 2060 // Setup space on stack for return value. |
| 2070 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 2061 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 2071 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2062 __ sw(TMP, Address(SP, 1 * kWordSize)); |
| 2072 __ sw(T0, Address(SP, 0 * kWordSize)); | 2063 __ sw(T0, Address(SP, 0 * kWordSize)); |
| 2073 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 2064 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 2074 __ Comment("OptimizeFunctionStub return"); | 2065 __ Comment("OptimizeFunctionStub return"); |
| 2075 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object | 2066 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object |
| 2076 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. | 2067 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. |
| 2077 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. | 2068 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. |
| 2078 | 2069 |
| 2079 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 2070 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
| 2080 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 2081 __ LeaveStubFrameAndReturn(T0); | 2071 __ LeaveStubFrameAndReturn(T0); |
| 2082 __ break_(0); | 2072 __ break_(0); |
| 2083 } | 2073 } |
| 2084 | 2074 |
| 2085 | 2075 |
| 2086 // Does identical check (object references are equal or not equal) with special | 2076 // Does identical check (object references are equal or not equal) with special |
| 2087 // checks for boxed numbers. | 2077 // checks for boxed numbers. |
| 2088 // Returns: CMPRES1 is zero if equal, non-zero otherwise. | 2078 // Returns: CMPRES1 is zero if equal, non-zero otherwise. |
| 2089 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint | 2079 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint |
| 2090 // cannot contain a value that fits in Mint or Smi. | 2080 // cannot contain a value that fits in Mint or Smi. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 | 2241 |
| 2252 __ Bind(&call_target_function); | 2242 __ Bind(&call_target_function); |
| 2253 // Call the target found in the cache. For a class id match, this is a | 2243 // Call the target found in the cache. For a class id match, this is a |
| 2254 // proper target for the given name and arguments descriptor. If the | 2244 // proper target for the given name and arguments descriptor. If the |
| 2255 // illegal class id was found, the target is a cache miss handler that can | 2245 // illegal class id was found, the target is a cache miss handler that can |
| 2256 // be invoked as a normal Dart function. | 2246 // be invoked as a normal Dart function. |
| 2257 __ sll(T1, T3, 2); | 2247 __ sll(T1, T3, 2); |
| 2258 __ addu(T1, T2, T1); | 2248 __ addu(T1, T2, T1); |
| 2259 __ lw(T0, FieldAddress(T1, base + kWordSize)); | 2249 __ lw(T0, FieldAddress(T1, base + kWordSize)); |
| 2260 | 2250 |
| 2261 __ lw(target, FieldAddress(T0, Function::instructions_offset())); | 2251 __ lw(target, FieldAddress(T0, Function::entry_point_offset())); |
| 2262 // TODO(srdjan): Evaluate performance impact of moving the instruction below | |
| 2263 // to the call site, instead of having it here. | |
| 2264 __ AddImmediate(target, Instructions::HeaderSize() - kHeapObjectTag); | |
| 2265 } | 2252 } |
| 2266 | 2253 |
| 2267 | 2254 |
| 2268 // Called from megamorphic calls. | 2255 // Called from megamorphic calls. |
| 2269 // T0: receiver. | 2256 // T0: receiver. |
| 2270 // T1: lookup cache. | 2257 // T1: lookup cache. |
| 2271 // Result: | 2258 // Result: |
| 2272 // T1: entry point. | 2259 // T1: entry point. |
| 2273 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2260 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2274 EmitMegamorphicLookup(assembler, T0, T1, T1); | 2261 EmitMegamorphicLookup(assembler, T0, T1, T1); |
| 2275 __ Ret(); | 2262 __ Ret(); |
| 2276 } | 2263 } |
| 2277 | 2264 |
| 2278 } // namespace dart | 2265 } // namespace dart |
| 2279 | 2266 |
| 2280 #endif // defined TARGET_ARCH_MIPS | 2267 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |