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" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 | 402 |
403 default: | 403 default: |
404 UNREACHABLE(); | 404 UNREACHABLE(); |
405 } | 405 } |
406 } | 406 } |
407 } | 407 } |
408 | 408 |
409 | 409 |
410 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, | 410 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, |
411 bool opt) const { | 411 bool opt) const { |
412 const intptr_t kNumInputs = 2; | 412 const intptr_t kNumInputs = 3; |
413 const intptr_t kNumTemps = 0; | 413 const intptr_t kNumTemps = 0; |
414 LocationSummary* summary = new (zone) | 414 LocationSummary* summary = new (zone) |
415 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 415 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
416 summary->set_in(0, Location::RegisterLocation(A0)); // Value. | 416 summary->set_in(0, Location::RegisterLocation(A0)); // Value. |
417 summary->set_in(1, Location::RegisterLocation(A1)); // Type arguments. | 417 summary->set_in(1, Location::RegisterLocation(A1)); // Instant. type args. |
| 418 summary->set_in(2, Location::RegisterLocation(A2)); // Function type args. |
418 summary->set_out(0, Location::RegisterLocation(A0)); | 419 summary->set_out(0, Location::RegisterLocation(A0)); |
419 return summary; | 420 return summary; |
420 } | 421 } |
421 | 422 |
422 | 423 |
423 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, | 424 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, |
424 bool opt) const { | 425 bool opt) const { |
425 const intptr_t kNumInputs = 1; | 426 const intptr_t kNumInputs = 1; |
426 const intptr_t kNumTemps = 0; | 427 const intptr_t kNumTemps = 0; |
427 LocationSummary* locs = new (zone) | 428 LocationSummary* locs = new (zone) |
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 value, CanValueBeSmi()); | 2229 value, CanValueBeSmi()); |
2229 } else { | 2230 } else { |
2230 __ StoreIntoObjectNoBarrier( | 2231 __ StoreIntoObjectNoBarrier( |
2231 temp, FieldAddress(temp, Field::static_value_offset()), value); | 2232 temp, FieldAddress(temp, Field::static_value_offset()), value); |
2232 } | 2233 } |
2233 } | 2234 } |
2234 | 2235 |
2235 | 2236 |
2236 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, | 2237 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, |
2237 bool opt) const { | 2238 bool opt) const { |
2238 const intptr_t kNumInputs = 2; | 2239 const intptr_t kNumInputs = 3; |
2239 const intptr_t kNumTemps = 0; | 2240 const intptr_t kNumTemps = 0; |
2240 LocationSummary* summary = new (zone) | 2241 LocationSummary* summary = new (zone) |
2241 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2242 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2242 summary->set_in(0, Location::RegisterLocation(A0)); | 2243 summary->set_in(0, Location::RegisterLocation(A0)); // Instance. |
2243 summary->set_in(1, Location::RegisterLocation(A1)); | 2244 summary->set_in(1, Location::RegisterLocation(A1)); // Instant. type args. |
| 2245 summary->set_in(2, Location::RegisterLocation(A2)); // Function type args. |
2244 summary->set_out(0, Location::RegisterLocation(V0)); | 2246 summary->set_out(0, Location::RegisterLocation(V0)); |
2245 return summary; | 2247 return summary; |
2246 } | 2248 } |
2247 | 2249 |
2248 | 2250 |
2249 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2251 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2250 ASSERT(locs()->in(0).reg() == A0); // Value. | 2252 ASSERT(locs()->in(0).reg() == A0); // Value. |
2251 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments. | 2253 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments. |
| 2254 ASSERT(locs()->in(2).reg() == A2); // Function type arguments. |
2252 | 2255 |
2253 __ Comment("InstanceOfInstr"); | 2256 __ Comment("InstanceOfInstr"); |
2254 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); | 2257 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); |
2255 ASSERT(locs()->out(0).reg() == V0); | 2258 ASSERT(locs()->out(0).reg() == V0); |
2256 } | 2259 } |
2257 | 2260 |
2258 | 2261 |
2259 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, | 2262 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, |
2260 bool opt) const { | 2263 bool opt) const { |
2261 const intptr_t kNumInputs = 2; | 2264 const intptr_t kNumInputs = 2; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2448 | 2451 |
2449 __ Bind(&load_pointer); | 2452 __ Bind(&load_pointer); |
2450 } | 2453 } |
2451 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); | 2454 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); |
2452 __ Bind(&done); | 2455 __ Bind(&done); |
2453 } | 2456 } |
2454 | 2457 |
2455 | 2458 |
2456 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, | 2459 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, |
2457 bool opt) const { | 2460 bool opt) const { |
2458 const intptr_t kNumInputs = 1; | 2461 const intptr_t kNumInputs = 2; |
2459 const intptr_t kNumTemps = 0; | 2462 const intptr_t kNumTemps = 0; |
2460 LocationSummary* locs = new (zone) | 2463 LocationSummary* locs = new (zone) |
2461 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2464 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2462 locs->set_in(0, Location::RegisterLocation(T0)); | 2465 locs->set_in(0, Location::RegisterLocation(T0)); // Instant. type args. |
| 2466 locs->set_in(1, Location::RegisterLocation(T1)); // Function type args. |
2463 locs->set_out(0, Location::RegisterLocation(T0)); | 2467 locs->set_out(0, Location::RegisterLocation(T0)); |
2464 return locs; | 2468 return locs; |
2465 } | 2469 } |
2466 | 2470 |
2467 | 2471 |
2468 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2472 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2469 __ Comment("InstantiateTypeInstr"); | 2473 __ Comment("InstantiateTypeInstr"); |
2470 Register instantiator_reg = locs()->in(0).reg(); | 2474 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2475 Register function_type_args_reg = locs()->in(1).reg(); |
2471 Register result_reg = locs()->out(0).reg(); | 2476 Register result_reg = locs()->out(0).reg(); |
2472 | 2477 |
2473 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2478 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2479 // 'function_type_args_reg' is a TypeArguments object (or null). |
2474 // A runtime call to instantiate the type is required. | 2480 // A runtime call to instantiate the type is required. |
2475 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2481 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
2476 __ LoadObject(TMP, Object::null_object()); | 2482 __ LoadObject(TMP, Object::null_object()); |
2477 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. | 2483 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result. |
2478 __ LoadObject(TMP, type()); | 2484 __ LoadObject(TMP, type()); |
2479 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2485 __ sw(TMP, Address(SP, 2 * kWordSize)); |
2480 // Push instantiator type arguments. | 2486 __ sw(instantiator_type_args_reg, Address(SP, 1 * kWordSize)); |
2481 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); | 2487 __ sw(function_type_args_reg, Address(SP, 0 * kWordSize)); |
2482 | 2488 |
2483 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2489 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2484 kInstantiateTypeRuntimeEntry, 2, locs()); | 2490 kInstantiateTypeRuntimeEntry, 3, locs()); |
2485 // Pop instantiated type. | 2491 // Pop instantiated type. |
2486 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2492 __ lw(result_reg, Address(SP, 3 * kWordSize)); |
| 2493 |
2487 // Drop instantiator and uninstantiated type. | 2494 // Drop instantiator and uninstantiated type. |
2488 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2495 __ addiu(SP, SP, Immediate(4 * kWordSize)); |
2489 ASSERT(instantiator_reg == result_reg); | |
2490 } | 2496 } |
2491 | 2497 |
2492 | 2498 |
2493 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2499 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
2494 Zone* zone, | 2500 Zone* zone, |
2495 bool opt) const { | 2501 bool opt) const { |
2496 const intptr_t kNumInputs = 1; | 2502 const intptr_t kNumInputs = 2; |
2497 const intptr_t kNumTemps = 0; | 2503 const intptr_t kNumTemps = 0; |
2498 LocationSummary* locs = new (zone) | 2504 LocationSummary* locs = new (zone) |
2499 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2505 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2500 locs->set_in(0, Location::RegisterLocation(T0)); | 2506 locs->set_in(0, Location::RegisterLocation(T0)); // Instant. type args. |
| 2507 locs->set_in(1, Location::RegisterLocation(T1)); // Function type args. |
2501 locs->set_out(0, Location::RegisterLocation(T0)); | 2508 locs->set_out(0, Location::RegisterLocation(T0)); |
2502 return locs; | 2509 return locs; |
2503 } | 2510 } |
2504 | 2511 |
2505 | 2512 |
2506 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2513 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
2507 FlowGraphCompiler* compiler) { | 2514 FlowGraphCompiler* compiler) { |
2508 __ Comment("InstantiateTypeArgumentsInstr"); | 2515 __ Comment("InstantiateTypeArgumentsInstr"); |
2509 Register instantiator_reg = locs()->in(0).reg(); | 2516 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2517 Register function_type_args_reg = locs()->in(1).reg(); |
2510 Register result_reg = locs()->out(0).reg(); | 2518 Register result_reg = locs()->out(0).reg(); |
2511 ASSERT(instantiator_reg == T0); | 2519 ASSERT(instantiator_type_args_reg == T0); |
2512 ASSERT(instantiator_reg == result_reg); | 2520 ASSERT(instantiator_type_args_reg == result_reg); |
2513 | 2521 |
2514 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2522 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2523 // 'function_type_args_reg' is a TypeArguments object (or null). |
2515 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2524 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
2516 !type_arguments().CanShareInstantiatorTypeArguments( | 2525 !type_arguments().CanShareInstantiatorTypeArguments( |
2517 instantiator_class())); | 2526 instantiator_class())); |
2518 // If the instantiator is null and if the type argument vector | 2527 // If both the instantiator and function type arguments are null and if the |
2519 // instantiated from null becomes a vector of dynamic, then use null as | 2528 // type argument vector instantiated from null becomes a vector of dynamic, |
2520 // the type arguments. | 2529 // then use null as the type arguments. |
2521 Label type_arguments_instantiated; | 2530 Label type_arguments_instantiated; |
2522 const intptr_t len = type_arguments().Length(); | 2531 const intptr_t len = type_arguments().Length(); |
2523 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2532 if (type_arguments().IsRawInstantiatedRaw(len)) { |
2524 __ BranchEqual(instantiator_reg, Object::null_object(), | 2533 Label non_null_type_args; |
| 2534 __ BranchNotEqual(instantiator_type_args_reg, Object::null_object(), |
| 2535 &non_null_type_args); |
| 2536 __ BranchEqual(function_type_args_reg, Object::null_object(), |
2525 &type_arguments_instantiated); | 2537 &type_arguments_instantiated); |
| 2538 __ Bind(&non_null_type_args); |
2526 } | 2539 } |
2527 | 2540 |
| 2541 // Lookup cache before calling runtime. |
| 2542 // TODO(regis): Consider moving this into a shared stub to reduce |
| 2543 // generated code size. |
2528 __ LoadObject(T2, type_arguments()); | 2544 __ LoadObject(T2, type_arguments()); |
2529 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); | 2545 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); |
2530 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 2546 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
2531 // The instantiations cache is initialized with Object::zero_array() and is | 2547 // The instantiations cache is initialized with Object::zero_array() and is |
2532 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2548 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
2533 Label loop, found, slow_case; | 2549 Label loop, next, found, slow_case; |
2534 __ Bind(&loop); | 2550 __ Bind(&loop); |
2535 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. | 2551 __ lw(T3, Address(T2, 0 * kWordSize)); // Cached instantiator type args. |
2536 __ beq(T1, T0, &found); | 2552 __ bne(T3, T0, &next); |
2537 __ BranchNotEqual(T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), | 2553 __ lw(T4, Address(T2, 1 * kWordSize)); // Cached function type args. |
| 2554 __ beq(T4, T1, &found); |
| 2555 __ Bind(&next); |
| 2556 __ BranchNotEqual(T3, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), |
2538 &loop); | 2557 &loop); |
2539 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); | 2558 __ delay_slot()->addiu( |
| 2559 T2, T2, Immediate(StubCode::kInstantiationSizeInWords * kWordSize)); |
2540 __ b(&slow_case); | 2560 __ b(&slow_case); |
2541 __ Bind(&found); | 2561 __ Bind(&found); |
2542 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. | 2562 __ lw(T0, Address(T2, 2 * kWordSize)); // Cached instantiated args. |
2543 __ b(&type_arguments_instantiated); | 2563 __ b(&type_arguments_instantiated); |
2544 | 2564 |
2545 __ Bind(&slow_case); | 2565 __ Bind(&slow_case); |
2546 // Instantiate non-null type arguments. | 2566 // Instantiate non-null type arguments. |
2547 // A runtime call to instantiate the type arguments is required. | 2567 // A runtime call to instantiate the type arguments is required. |
2548 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2568 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
2549 __ LoadObject(TMP, Object::null_object()); | 2569 __ LoadObject(TMP, Object::null_object()); |
2550 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. | 2570 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result. |
2551 __ LoadObject(TMP, type_arguments()); | 2571 __ LoadObject(TMP, type_arguments()); |
2552 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2572 __ sw(TMP, Address(SP, 2 * kWordSize)); |
2553 // Push instantiator type arguments. | 2573 __ sw(instantiator_type_args_reg, Address(SP, 1 * kWordSize)); |
2554 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); | 2574 __ sw(function_type_args_reg, Address(SP, 0 * kWordSize)); |
2555 | 2575 |
2556 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2576 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2557 kInstantiateTypeArgumentsRuntimeEntry, 2, | 2577 kInstantiateTypeArgumentsRuntimeEntry, 3, |
2558 locs()); | 2578 locs()); |
2559 // Pop instantiated type arguments. | 2579 // Pop instantiated type arguments. |
2560 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2580 __ lw(result_reg, Address(SP, 3 * kWordSize)); |
2561 // Drop instantiator and uninstantiated type arguments. | 2581 // Drop 2 type argument vectors and uninstantiated type arguments. |
2562 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2582 __ addiu(SP, SP, Immediate(4 * kWordSize)); |
2563 __ Bind(&type_arguments_instantiated); | 2583 __ Bind(&type_arguments_instantiated); |
2564 } | 2584 } |
2565 | 2585 |
2566 | 2586 |
2567 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( | 2587 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( |
2568 Zone* zone, | 2588 Zone* zone, |
2569 bool opt) const { | 2589 bool opt) const { |
2570 ASSERT(opt); | 2590 ASSERT(opt); |
2571 const intptr_t kNumInputs = 0; | 2591 const intptr_t kNumInputs = 0; |
2572 const intptr_t kNumTemps = 3; | 2592 const intptr_t kNumTemps = 3; |
(...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6080 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 6100 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
6081 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6101 kGrowRegExpStackRuntimeEntry, 1, locs()); |
6082 __ lw(result, Address(SP, 1 * kWordSize)); | 6102 __ lw(result, Address(SP, 1 * kWordSize)); |
6083 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 6103 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
6084 } | 6104 } |
6085 | 6105 |
6086 | 6106 |
6087 } // namespace dart | 6107 } // namespace dart |
6088 | 6108 |
6089 #endif // defined TARGET_ARCH_MIPS | 6109 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |