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 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 const Register temp2 = T3; | 2204 const Register temp2 = T3; |
2205 const Register left = T1; | 2205 const Register left = T1; |
2206 const Register right = T0; | 2206 const Register right = T0; |
2207 __ lw(left, Address(SP, 1 * kWordSize)); | 2207 __ lw(left, Address(SP, 1 * kWordSize)); |
2208 __ lw(right, Address(SP, 0 * kWordSize)); | 2208 __ lw(right, Address(SP, 0 * kWordSize)); |
2209 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2209 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2210 __ Ret(); | 2210 __ Ret(); |
2211 } | 2211 } |
2212 | 2212 |
2213 | 2213 |
| 2214 // Called from megamorphic calls. |
| 2215 // T0: receiver |
| 2216 // S5: MegamorphicCache (preserved) |
| 2217 // Result: |
| 2218 // T1: target entry point |
| 2219 // CODE_REG: target Code |
| 2220 // S4: arguments descriptor |
2214 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { | 2221 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { |
2215 __ LoadTaggedClassIdMayBeSmi(T0, T0); | 2222 __ LoadTaggedClassIdMayBeSmi(T0, T0); |
2216 // T0: class ID of the receiver (smi). | 2223 // T0: class ID of the receiver (smi). |
2217 __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset())); | 2224 __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset())); |
2218 __ lw(T2, FieldAddress(S5, MegamorphicCache::buckets_offset())); | 2225 __ lw(T2, FieldAddress(S5, MegamorphicCache::buckets_offset())); |
2219 __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset())); | 2226 __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset())); |
2220 // T2: cache buckets array. | 2227 // T2: cache buckets array. |
2221 // T1: mask. | 2228 // T1: mask. |
2222 __ mov(T3, T0); | 2229 __ mov(T3, T0); |
2223 // T3: probe. | 2230 // T3: probe. |
(...skipping 22 matching lines...) Expand all Loading... |
2246 // be invoked as a normal Dart function. | 2253 // be invoked as a normal Dart function. |
2247 __ sll(T1, T3, 2); | 2254 __ sll(T1, T3, 2); |
2248 __ addu(T1, T2, T1); | 2255 __ addu(T1, T2, T1); |
2249 __ lw(T0, FieldAddress(T1, base + kWordSize)); | 2256 __ lw(T0, FieldAddress(T1, base + kWordSize)); |
2250 | 2257 |
2251 __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); | 2258 __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); |
2252 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); | 2259 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); |
2253 } | 2260 } |
2254 | 2261 |
2255 | 2262 |
2256 // Called from megamorphic calls. | |
2257 // T0: receiver | |
2258 // S5: MegamorphicCache (preserved) | |
2259 // Result: | |
2260 // T1: target entry point | |
2261 // CODE_REG: target Code | |
2262 // S4: arguments descriptor | |
2263 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2263 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2264 EmitMegamorphicLookup(assembler); | 2264 EmitMegamorphicLookup(assembler); |
2265 __ Ret(); | 2265 __ Ret(); |
2266 } | 2266 } |
2267 | 2267 |
2268 | 2268 |
2269 // Called from switchable IC calls. | 2269 // Called from switchable IC calls. |
2270 // T0: receiver | 2270 // T0: receiver |
2271 // S5: ICData (preserved) | 2271 // S5: ICData (preserved) |
2272 // Result: | 2272 // Result: |
2273 // T1: target entry point | 2273 // T1: target entry point |
2274 // CODE_REG: target Code object | 2274 // CODE_REG: target Code object |
2275 // S4: arguments descriptor | 2275 // S4: arguments descriptor |
2276 void StubCode::GenerateICLookupStub(Assembler* assembler) { | 2276 static void EmitICLookup(Assembler* assembler, |
| 2277 intptr_t args_checked, |
| 2278 Token::Kind kind) { |
| 2279 if (kind != Token::kILLEGAL) { |
| 2280 __ Comment("Fast Smi op"); |
| 2281 Label not_smi_or_overflow; |
| 2282 |
| 2283 // T0: Receiver. |
| 2284 __ lw(T1, Address(SP, 0 * kWordSize)); |
| 2285 // T1: Argument. |
| 2286 __ or_(CMPRES1, T0, T1); |
| 2287 __ andi(CMPRES1, CMPRES1, Immediate(kSmiTagMask)); |
| 2288 __ bne(CMPRES1, ZR, ¬_smi_or_overflow); |
| 2289 |
| 2290 switch (kind) { |
| 2291 case Token::kADD: { |
| 2292 __ AdduDetectOverflow(V0, T1, T0, CMPRES1); // Add. |
| 2293 __ bltz(CMPRES1, ¬_smi_or_overflow); // Fall through on overflow. |
| 2294 break; |
| 2295 } |
| 2296 case Token::kSUB: { |
| 2297 __ SubuDetectOverflow(V0, T1, T0, CMPRES1); // Subtract. |
| 2298 __ bltz(CMPRES1, ¬_smi_or_overflow); // Fall through on overflow. |
| 2299 break; |
| 2300 } |
| 2301 case Token::kEQ: { |
| 2302 Label true_label, done; |
| 2303 __ beq(T1, T0, &true_label); |
| 2304 __ LoadObject(V0, Bool::False()); |
| 2305 __ b(&done); |
| 2306 __ Bind(&true_label); |
| 2307 __ LoadObject(V0, Bool::True()); |
| 2308 __ Bind(&done); |
| 2309 break; |
| 2310 } |
| 2311 default: UNIMPLEMENTED(); |
| 2312 } |
| 2313 // Return past the call to lookup result and delay slot. |
| 2314 __ addiu(RA, RA, Immediate(2 * Instr::kInstrSize)); |
| 2315 __ Ret(); |
| 2316 |
| 2317 __ Bind(¬_smi_or_overflow); |
| 2318 } |
| 2319 |
2277 Label loop, found, miss; | 2320 Label loop, found, miss; |
2278 __ lw(T6, FieldAddress(S5, ICData::ic_data_offset())); | 2321 __ lw(T6, FieldAddress(S5, ICData::ic_data_offset())); |
2279 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); | 2322 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
2280 __ AddImmediate(T6, T6, Array::data_offset() - kHeapObjectTag); | 2323 __ AddImmediate(T6, T6, Array::data_offset() - kHeapObjectTag); |
2281 // T6: first IC entry. | 2324 // T6: first IC entry. |
2282 __ LoadTaggedClassIdMayBeSmi(T1, T0); | 2325 __ LoadTaggedClassIdMayBeSmi(T1, T0); |
2283 // T1: receiver cid as Smi | 2326 // T1: receiver cid as Smi |
2284 | 2327 |
2285 __ Bind(&loop); | 2328 __ Bind(&loop); |
2286 __ lw(T2, Address(T6, 0)); | 2329 __ lw(T2, Address(T6, 0)); |
2287 __ beq(T1, T2, &found); | 2330 __ beq(T1, T2, &found); |
2288 ASSERT(Smi::RawValue(kIllegalCid) == 0); | 2331 ASSERT(Smi::RawValue(kIllegalCid) == 0); |
2289 __ beq(T2, ZR, &miss); | 2332 __ beq(T2, ZR, &miss); |
2290 | 2333 |
2291 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; | 2334 const intptr_t entry_length = |
| 2335 ICData::TestEntryLengthFor(args_checked) * kWordSize; |
2292 __ AddImmediate(T6, entry_length); // Next entry. | 2336 __ AddImmediate(T6, entry_length); // Next entry. |
2293 __ b(&loop); | 2337 __ b(&loop); |
2294 | 2338 |
2295 __ Bind(&found); | 2339 __ Bind(&found); |
2296 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; | 2340 const intptr_t target_offset = |
| 2341 ICData::TargetIndexFor(args_checked) * kWordSize; |
2297 __ lw(T0, Address(T6, target_offset)); | 2342 __ lw(T0, Address(T6, target_offset)); |
2298 __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); | 2343 __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); |
2299 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); | 2344 __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); |
2300 __ Ret(); | 2345 __ Ret(); |
2301 | 2346 |
2302 __ Bind(&miss); | 2347 __ Bind(&miss); |
2303 __ LoadIsolate(T2); | 2348 __ LoadIsolate(T2); |
2304 __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset())); | 2349 __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset())); |
2305 __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2350 __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset())); |
2306 __ Ret(); | 2351 __ Ret(); |
2307 } | 2352 } |
2308 | 2353 |
| 2354 |
| 2355 void StubCode::GenerateICLookupStub(Assembler* assembler) { |
| 2356 EmitICLookup(assembler, 1, Token::kILLEGAL); |
| 2357 } |
| 2358 |
| 2359 |
| 2360 void StubCode::GenerateICSmiAddLookupStub(Assembler* assembler) { |
| 2361 EmitICLookup(assembler, 2, Token::kADD); |
| 2362 } |
| 2363 |
| 2364 |
| 2365 void StubCode::GenerateICSmiSubLookupStub(Assembler* assembler) { |
| 2366 EmitICLookup(assembler, 2, Token::kSUB); |
| 2367 } |
| 2368 |
| 2369 |
| 2370 void StubCode::GenerateICSmiEqualLookupStub(Assembler* assembler) { |
| 2371 EmitICLookup(assembler, 2, Token::kEQ); |
| 2372 } |
| 2373 |
2309 } // namespace dart | 2374 } // namespace dart |
2310 | 2375 |
2311 #endif // defined TARGET_ARCH_MIPS | 2376 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |