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 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 } | 1690 } |
1691 #endif // DEBUG | 1691 #endif // DEBUG |
1692 | 1692 |
1693 | 1693 |
1694 // Check single stepping. | 1694 // Check single stepping. |
1695 Label not_stepping; | 1695 Label not_stepping; |
1696 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1696 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
1697 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1697 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
1698 __ BranchEqual(T0, 0, ¬_stepping); | 1698 __ BranchEqual(T0, 0, ¬_stepping); |
1699 // Call single step callback in debugger. | 1699 // Call single step callback in debugger. |
| 1700 __ EnterStubFrame(); |
1700 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1701 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1701 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. | 1702 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. |
1702 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 1703 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
1703 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1704 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1704 __ lw(RA, Address(SP, 0 * kWordSize)); | 1705 __ lw(RA, Address(SP, 0 * kWordSize)); |
1705 __ lw(S5, Address(SP, 1 * kWordSize)); | 1706 __ lw(S5, Address(SP, 1 * kWordSize)); |
1706 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1707 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1708 __ LeaveStubFrame(); |
1707 __ Bind(¬_stepping); | 1709 __ Bind(¬_stepping); |
1708 | 1710 |
1709 // Load argument descriptor into S4. | 1711 // Load argument descriptor into S4. |
1710 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | 1712 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
1711 // Preserve return address, since RA is needed for subroutine call. | 1713 // Preserve return address, since RA is needed for subroutine call. |
1712 __ mov(T2, RA); | 1714 __ mov(T2, RA); |
1713 // Loop that checks if there is an IC data match. | 1715 // Loop that checks if there is an IC data match. |
1714 Label loop, update, test, found, get_class_id_as_smi; | 1716 Label loop, update, test, found, get_class_id_as_smi; |
1715 // S5: IC data object (preserved). | 1717 // S5: IC data object (preserved). |
1716 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); | 1718 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 __ Bind(&ok); | 1964 __ Bind(&ok); |
1963 } | 1965 } |
1964 #endif // DEBUG | 1966 #endif // DEBUG |
1965 | 1967 |
1966 // Check single stepping. | 1968 // Check single stepping. |
1967 Label not_stepping; | 1969 Label not_stepping; |
1968 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1970 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
1969 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1971 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
1970 __ BranchEqual(T0, 0, ¬_stepping); | 1972 __ BranchEqual(T0, 0, ¬_stepping); |
1971 // Call single step callback in debugger. | 1973 // Call single step callback in debugger. |
| 1974 __ EnterStubFrame(); |
1972 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1975 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1973 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. | 1976 __ sw(S5, Address(SP, 1 * kWordSize)); // Preserve IC data. |
1974 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 1977 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
1975 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1978 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1976 __ lw(RA, Address(SP, 0 * kWordSize)); | 1979 __ lw(RA, Address(SP, 0 * kWordSize)); |
1977 __ lw(S5, Address(SP, 1 * kWordSize)); | 1980 __ lw(S5, Address(SP, 1 * kWordSize)); |
1978 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1981 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1982 __ LeaveStubFrame(); |
1979 __ Bind(¬_stepping); | 1983 __ Bind(¬_stepping); |
1980 | 1984 |
1981 | 1985 |
1982 // S5: IC data object (preserved). | 1986 // S5: IC data object (preserved). |
1983 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); | 1987 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); |
1984 // T0: ic_data_array with entries: target functions and count. | 1988 // T0: ic_data_array with entries: target functions and count. |
1985 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); | 1989 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); |
1986 // T0: points directly to the first ic data array element. | 1990 // T0: points directly to the first ic data array element. |
1987 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1991 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
1988 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; | 1992 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2071 __ lw(S5, Address(SP, 2 * kWordSize)); | 2075 __ lw(S5, Address(SP, 2 * kWordSize)); |
2072 __ lw(S4, Address(SP, 1 * kWordSize)); | 2076 __ lw(S4, Address(SP, 1 * kWordSize)); |
2073 __ lw(T0, Address(SP, 0 * kWordSize)); | 2077 __ lw(T0, Address(SP, 0 * kWordSize)); |
2074 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2078 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
2075 __ LeaveStubFrame(); | 2079 __ LeaveStubFrame(); |
2076 __ jr(T0); | 2080 __ jr(T0); |
2077 } | 2081 } |
2078 | 2082 |
2079 | 2083 |
2080 // RA: return address (Dart code). | 2084 // RA: return address (Dart code). |
2081 // S5: IC data (unoptimized static call). | |
2082 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | |
2083 __ TraceSimMsg("BreakpointStaticStub"); | |
2084 // Create a stub frame as we are pushing some objects on the stack before | |
2085 // calling into the runtime. | |
2086 __ EnterStubFrame(); | |
2087 // Preserve arguments descriptor and make room for result. | |
2088 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
2089 __ sw(S5, Address(SP, 1 * kWordSize)); | |
2090 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
2091 __ sw(TMP, Address(SP, 0 * kWordSize)); | |
2092 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); | |
2093 // Pop code object result and restore arguments descriptor. | |
2094 __ lw(T0, Address(SP, 0 * kWordSize)); | |
2095 __ lw(S5, Address(SP, 1 * kWordSize)); | |
2096 __ addiu(SP, SP, Immediate(2 * kWordSize)); | |
2097 __ LeaveStubFrame(); | |
2098 | |
2099 // Now call the static function. The breakpoint handler function | |
2100 // ensures that the call target is compiled. | |
2101 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | |
2102 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | |
2103 // Load arguments descriptor into S4. | |
2104 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | |
2105 __ jr(T0); | |
2106 } | |
2107 | |
2108 | |
2109 // RA: return address (Dart code). | |
2110 // S5: Inline cache data array. | 2085 // S5: Inline cache data array. |
2111 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 2086 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
2112 // Create a stub frame as we are pushing some objects on the stack before | 2087 // Create a stub frame as we are pushing some objects on the stack before |
2113 // calling into the runtime. | 2088 // calling into the runtime. |
2114 __ TraceSimMsg("BreakpointDynamicStub"); | 2089 __ TraceSimMsg("BreakpointDynamicStub"); |
2115 __ EnterStubFrame(); | 2090 __ EnterStubFrame(); |
2116 __ Push(S5); | 2091 __ Push(S5); |
2117 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); | 2092 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
2118 __ Pop(S5); | 2093 __ Pop(S5); |
2119 __ LeaveStubFrame(); | 2094 __ LeaveStubFrame(); |
(...skipping 19 matching lines...) Expand all Loading... |
2139 | 2114 |
2140 // Called only from unoptimized code. All relevant registers have been saved. | 2115 // Called only from unoptimized code. All relevant registers have been saved. |
2141 // RA: return address. | 2116 // RA: return address. |
2142 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { | 2117 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { |
2143 // Check single stepping. | 2118 // Check single stepping. |
2144 Label not_stepping; | 2119 Label not_stepping; |
2145 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 2120 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
2146 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 2121 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
2147 __ BranchEqual(T0, 0, ¬_stepping); | 2122 __ BranchEqual(T0, 0, ¬_stepping); |
2148 // Call single step callback in debugger. | 2123 // Call single step callback in debugger. |
| 2124 __ EnterStubFrame(); |
2149 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 2125 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
2150 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 2126 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 2127 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
2152 __ lw(RA, Address(SP, 0 * kWordSize)); | 2128 __ lw(RA, Address(SP, 0 * kWordSize)); |
2153 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 2129 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
| 2130 __ LeaveStubFrame(); |
2154 __ Bind(¬_stepping); | 2131 __ Bind(¬_stepping); |
2155 __ Ret(); | 2132 __ Ret(); |
2156 } | 2133 } |
2157 | 2134 |
2158 | 2135 |
2159 // Used to check class and type arguments. Arguments passed in registers: | 2136 // Used to check class and type arguments. Arguments passed in registers: |
2160 // RA: return address. | 2137 // RA: return address. |
2161 // A0: instance (must be preserved). | 2138 // A0: instance (must be preserved). |
2162 // A1: instantiator type arguments or NULL. | 2139 // A1: instantiator type arguments or NULL. |
2163 // A2: cache array. | 2140 // A2: cache array. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2412 // SP + 0: right operand. | 2389 // SP + 0: right operand. |
2413 // Returns: CMPRES1 is zero if equal, non-zero otherwise. | 2390 // Returns: CMPRES1 is zero if equal, non-zero otherwise. |
2414 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2391 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
2415 Assembler* assembler) { | 2392 Assembler* assembler) { |
2416 // Check single stepping. | 2393 // Check single stepping. |
2417 Label not_stepping; | 2394 Label not_stepping; |
2418 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 2395 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
2419 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 2396 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
2420 __ BranchEqual(T0, 0, ¬_stepping); | 2397 __ BranchEqual(T0, 0, ¬_stepping); |
2421 // Call single step callback in debugger. | 2398 // Call single step callback in debugger. |
| 2399 __ EnterStubFrame(); |
2422 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 2400 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
2423 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. | 2401 __ sw(RA, Address(SP, 0 * kWordSize)); // Return address. |
2424 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 2402 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
2425 __ lw(RA, Address(SP, 0 * kWordSize)); | 2403 __ lw(RA, Address(SP, 0 * kWordSize)); |
2426 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 2404 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
| 2405 __ LeaveStubFrame(); |
2427 __ Bind(¬_stepping); | 2406 __ Bind(¬_stepping); |
2428 | 2407 |
2429 const Register temp1 = T2; | 2408 const Register temp1 = T2; |
2430 const Register temp2 = T3; | 2409 const Register temp2 = T3; |
2431 const Register left = T1; | 2410 const Register left = T1; |
2432 const Register right = T0; | 2411 const Register right = T0; |
2433 __ lw(left, Address(SP, 1 * kWordSize)); | 2412 __ lw(left, Address(SP, 1 * kWordSize)); |
2434 __ lw(right, Address(SP, 0 * kWordSize)); | 2413 __ lw(right, Address(SP, 0 * kWordSize)); |
2435 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2414 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2436 __ Ret(); | 2415 __ Ret(); |
(...skipping 12 matching lines...) Expand all Loading... |
2449 const Register right = T0; | 2428 const Register right = T0; |
2450 __ lw(left, Address(SP, 1 * kWordSize)); | 2429 __ lw(left, Address(SP, 1 * kWordSize)); |
2451 __ lw(right, Address(SP, 0 * kWordSize)); | 2430 __ lw(right, Address(SP, 0 * kWordSize)); |
2452 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2431 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2453 __ Ret(); | 2432 __ Ret(); |
2454 } | 2433 } |
2455 | 2434 |
2456 } // namespace dart | 2435 } // namespace dart |
2457 | 2436 |
2458 #endif // defined TARGET_ARCH_MIPS | 2437 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |