Index: runtime/vm/stub_code_mips.cc |
=================================================================== |
--- runtime/vm/stub_code_mips.cc (revision 24063) |
+++ runtime/vm/stub_code_mips.cc (working copy) |
@@ -95,11 +95,11 @@ |
// Load Context pointer from Isolate structure into A2. |
__ lw(A2, Address(CTX, Isolate::top_context_offset())); |
- // Reload NULLREG. |
- __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null())); |
+ // Load null. |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
// Reset Context pointer in Isolate structure. |
- __ sw(NULLREG, Address(CTX, Isolate::top_context_offset())); |
+ __ sw(TMP, Address(CTX, Isolate::top_context_offset())); |
// Cache Context pointer into CTX while executing Dart code. |
__ mov(CTX, A2); |
@@ -202,11 +202,11 @@ |
// Load Context pointer from Isolate structure into A2. |
__ lw(A2, Address(CTX, Isolate::top_context_offset())); |
- // Reload NULLREG. |
- __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null())); |
+ // Load null. |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
// Reset Context pointer in Isolate structure. |
- __ sw(NULLREG, Address(CTX, Isolate::top_context_offset())); |
+ __ sw(TMP, Address(CTX, Isolate::top_context_offset())); |
// Cache Context pointer into CTX while executing Dart code. |
__ mov(CTX, A2); |
@@ -228,7 +228,8 @@ |
__ addiu(SP, SP, Immediate(-2 * kWordSize)); |
__ sw(S4, Address(SP, 1 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 0 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kPatchStaticCallRuntimeEntry); |
__ TraceSimMsg("CallStaticFunctionStub return"); |
@@ -257,7 +258,8 @@ |
// Setup space on stack for return value and preserve arguments descriptor. |
__ addiu(SP, SP, Immediate(-2 * kWordSize)); |
__ sw(S4, Address(SP, 1 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 0 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kFixCallersTargetRuntimeEntry); |
// Get Code object result and restore arguments descriptor array. |
__ lw(T0, Address(SP, 0 * kWordSize)); |
@@ -279,7 +281,7 @@ |
static void PushArgumentsArray(Assembler* assembler) { |
__ TraceSimMsg("PushArgumentsArray"); |
// Allocate array to store arguments of caller. |
- __ mov(A0, NULLREG); |
+ __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null())); |
// A0: Null element type for raw Array. |
// A1: Smi-tagged argument count, may be zero. |
__ BranchLink(&StubCode::AllocateArrayLabel()); |
@@ -329,7 +331,8 @@ |
// Push TMP1 data object. |
// Push arguments descriptor array. |
__ addiu(SP, SP, Immediate(-4 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 3 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 3 * kWordSize)); |
__ sw(T1, Address(SP, 2 * kWordSize)); |
__ sw(S5, Address(SP, 1 * kWordSize)); |
__ sw(S4, Address(SP, 0 * kWordSize)); |
@@ -498,8 +501,44 @@ |
void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
- __ Unimplemented("MegamorphicMiss stub"); |
- return; |
+ __ EnterStubFrame(); |
+ |
+ // Load the receiver. |
+ __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
+ __ sll(T2, T2, 1); // T2 is a Smi. |
+ __ addu(TMP, FP, T2); |
+ __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); |
+ |
+ // Preserve IC data and arguments descriptor. |
+ __ addiu(SP, SP, Immediate(-6 * kWordSize)); |
+ __ sw(S5, Address(SP, 5 * kWordSize)); |
+ __ sw(S4, Address(SP, 4 * kWordSize)); |
+ |
+ // Push space for the return value. |
+ // Push the receiver. |
+ // Push IC data object. |
+ // Push arguments descriptor array. |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 3 * kWordSize)); |
+ __ sw(T6, Address(SP, 2 * kWordSize)); |
+ __ sw(S5, Address(SP, 1 * kWordSize)); |
+ __ sw(S4, Address(SP, 0 * kWordSize)); |
+ |
+ __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); |
+ |
+ __ lw(T0, Address(SP, 3 * kWordSize)); // Get result. |
+ __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. |
+ __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. |
+ __ addiu(SP, SP, Immediate(6 * kWordSize)); |
+ |
+ __ LeaveStubFrame(); |
+ |
+ Label nonnull; |
+ __ BranchNotEqual(T0, reinterpret_cast<int32_t>(Object::null()), &nonnull); |
+ __ Branch(&StubCode::InstanceFunctionLookupLabel()); |
+ __ Bind(&nonnull); |
+ __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
+ __ jr(T0); |
} |
@@ -604,12 +643,13 @@ |
// T3: iterator which initially points to the start of the variable |
// data area to be initialized. |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
Label loop, loop_exit; |
__ BranchUnsignedGreaterEqual(T3, T2, &loop_exit); |
__ Bind(&loop); |
__ addiu(T3, T3, Immediate(kWordSize)); |
__ bne(T3, T2, &loop); |
- __ delay_slot()->sw(NULLREG, Address(T3, -kWordSize)); |
+ __ delay_slot()->sw(T7, Address(T3, -kWordSize)); |
__ Bind(&loop_exit); |
// Done allocating and initializing the array. |
@@ -627,17 +667,17 @@ |
// Setup space on stack for return value. |
// Push array length as Smi and element type. |
__ addiu(SP, SP, Immediate(-3 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 2 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 2 * kWordSize)); |
__ sw(A1, Address(SP, 1 * kWordSize)); |
- __ sw(T3, Address(SP, 0 * kWordSize)); |
+ __ sw(A0, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kAllocateArrayRuntimeEntry); |
__ TraceSimMsg("AllocateArrayStub return"); |
// Pop arguments; result is popped in IP. |
- __ lw(TMP1, Address(SP, 2 * kWordSize)); |
+ __ lw(V0, Address(SP, 2 * kWordSize)); |
__ lw(A1, Address(SP, 1 * kWordSize)); |
- __ lw(T3, Address(SP, 0 * kWordSize)); |
+ __ lw(A0, Address(SP, 0 * kWordSize)); |
__ addiu(SP, SP, Immediate(3 * kWordSize)); |
- __ mov(V0, TMP1); |
__ LeaveStubFrameAndReturn(); |
} |
@@ -666,8 +706,10 @@ |
// Verify that T1 is a closure by checking its class. |
Label not_closure; |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ |
// See if it is not a closure, but null object. |
- __ beq(T1, NULLREG, ¬_closure); |
+ __ beq(T1, T7, ¬_closure); |
__ andi(CMPRES, T1, Immediate(kSmiTagMask)); |
__ beq(CMPRES, ZR, ¬_closure); // Not a closure, but a smi. |
@@ -678,7 +720,7 @@ |
__ lw(T0, FieldAddress(T0, Class::signature_function_offset())); |
// See if actual class is not a closure class. |
- __ beq(T0, NULLREG, ¬_closure); |
+ __ beq(T0, T7, ¬_closure); |
// T0 is just the signature function. Load the actual closure function. |
__ lw(T2, FieldAddress(T1, Closure::function_offset())); |
@@ -689,7 +731,7 @@ |
Label function_compiled; |
// Load closure function code in T0. |
__ lw(T0, FieldAddress(T2, Function::code_offset())); |
- __ bne(T0, NULLREG, &function_compiled); |
+ __ bne(T0, T7, &function_compiled); |
// Create a stub frame as we are pushing some objects on the stack before |
// calling into the runtime. |
@@ -731,9 +773,9 @@ |
__ EnterStubFrame(); |
// Setup space on stack for result from error reporting. |
- __ addiu(SP, SP, Immediate(2 * kWordSize)); |
+ __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
// Arguments descriptor and raw null. |
- __ sw(NULLREG, Address(SP, 1 * kWordSize)); |
+ __ sw(T7, Address(SP, 1 * kWordSize)); |
__ sw(S4, Address(SP, 0 * kWordSize)); |
// Load smi-tagged arguments array length, including the non-closure. |
@@ -825,9 +867,6 @@ |
// Compute address of 'arguments array' data area into A2. |
__ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); |
- // Load the null Object into NULLREG for easy comparisons. |
- __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null())); |
- |
// Set up arguments for the Dart call. |
Label push_arguments; |
Label done_push_arguments; |
@@ -960,20 +999,22 @@ |
// T2: isolate, not an object. |
__ sw(T2, FieldAddress(V0, Context::isolate_offset())); |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ |
// Initialize the context variables. |
// V0: new object. |
// T1: number of context variables. |
Label loop, loop_exit; |
__ blez(T1, &loop_exit); |
// Setup the parent field. |
- __ delay_slot()->sw(NULLREG, FieldAddress(V0, Context::parent_offset())); |
+ __ delay_slot()->sw(T7, FieldAddress(V0, Context::parent_offset())); |
__ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag); |
__ sll(T1, T1, 2); |
__ Bind(&loop); |
__ addiu(T1, T1, Immediate(-kWordSize)); |
__ addu(TMP1, T3, T1); |
__ bgtz(T1, &loop); |
- __ delay_slot()->sw(NULLREG, Address(TMP1)); |
+ __ delay_slot()->sw(T7, Address(TMP1)); |
__ Bind(&loop_exit); |
// Done allocating and initializing the context. |
@@ -988,7 +1029,8 @@ |
// Setup space on stack for return value. |
__ SmiTag(T1); |
__ addiu(SP, SP, Immediate(-2 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 1 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 1 * kWordSize)); // Store null. |
__ sw(T1, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. |
__ lw(V0, Address(SP, 1 * kWordSize)); // Get the new context. |
@@ -1172,6 +1214,8 @@ |
__ LoadImmediate(T0, tags); |
__ sw(T0, Address(T2, Instance::tags_offset())); |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ |
// Initialize the remaining words of the object. |
// T2: new object start. |
// T3: next object start. |
@@ -1183,7 +1227,7 @@ |
for (intptr_t current_offset = sizeof(RawObject); |
current_offset < instance_size; |
current_offset += kWordSize) { |
- __ sw(NULLREG, Address(T2, current_offset)); |
+ __ sw(T7, Address(T2, current_offset)); |
} |
} else { |
__ addiu(T4, T2, Immediate(sizeof(RawObject))); |
@@ -1197,7 +1241,7 @@ |
__ Bind(&loop); |
__ addiu(T4, T4, Immediate(kWordSize)); |
__ bne(T4, T3, &loop); |
- __ delay_slot()->sw(NULLREG, Address(T4, -kWordSize)); |
+ __ delay_slot()->sw(T7, Address(T4, -kWordSize)); |
__ Bind(&loop_exit); |
} |
if (is_cls_parameterized) { |
@@ -1223,7 +1267,8 @@ |
__ addiu(SP, SP, Immediate(-4 * kWordSize)); |
// Space on stack for return value. |
- __ sw(NULLREG, Address(SP, 3 * kWordSize)); |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(T7, Address(SP, 3 * kWordSize)); |
__ sw(TMP1, Address(SP, 2 * kWordSize)); // Class of object to be allocated. |
if (is_cls_parameterized) { |
@@ -1233,7 +1278,7 @@ |
} else { |
// Push null type arguments and kNoInstantiator. |
__ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator)); |
- __ sw(NULLREG, Address(SP, 1 * kWordSize)); |
+ __ sw(T7, Address(SP, 1 * kWordSize)); |
__ sw(T1, Address(SP, 0 * kWordSize)); |
} |
__ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. |
@@ -1264,8 +1309,8 @@ |
__ TraceSimMsg("AllocationStubForClosure"); |
__ EnterStubFrame(true); // Uses pool pointer to refer to function. |
- const intptr_t kTypeArgumentsFPOffset = 4 * kWordSize; |
- const intptr_t kReceiverFPOffset = 5 * kWordSize; |
+ const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize; |
+ const intptr_t kReceiverFPOffset = 4 * kWordSize; |
const intptr_t closure_size = Closure::InstanceSize(); |
const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
if (FLAG_inline_alloc && |
@@ -1337,7 +1382,8 @@ |
__ sw(T0, Address(T4, Context::isolate_offset())); |
// Set the parent to null. |
- __ sw(NULLREG, Address(T4, Context::parent_offset())); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(T4, Context::parent_offset())); |
// Initialize the context variable to the receiver. |
__ lw(T0, Address(FP, kReceiverFPOffset)); |
@@ -1370,24 +1416,24 @@ |
num_slots = is_implicit_instance_closure ? 4 : 3; |
} |
__ addiu(SP, SP, Immediate(-num_slots * kWordSize)); |
+ // Setup space on stack for return value. |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(T7, Address(SP, (num_slots - 1) * kWordSize)); |
__ LoadObject(TMP1, func); |
- // Setup space on stack for return value. |
- __ sw(NULLREG, Address(SP, (num_slots - 1) * kWordSize)); |
__ sw(TMP1, Address(SP, (num_slots - 2) * kWordSize)); |
if (is_implicit_static_closure) { |
__ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); |
__ TraceSimMsg("AllocationStubForClosure return"); |
} else { |
+ __ mov(T2, T7); |
if (is_implicit_instance_closure) { |
__ lw(T1, Address(FP, kReceiverFPOffset)); |
__ sw(T1, Address(SP, (num_slots - 3) * kWordSize)); // Receiver. |
- __ sw(NULLREG, Address(SP, (num_slots - 4) * kWordSize)); // Push null. |
} |
if (has_type_arguments) { |
- __ lw(V0, Address(FP, kTypeArgumentsFPOffset)); |
- // Push type arguments of closure. |
- __ sw(V0, Address(SP, (num_slots - 3) * kWordSize)); |
+ __ lw(T2, Address(FP, kTypeArgumentsFPOffset)); |
} |
+ __ sw(T2, Address(SP, 0 * kWordSize)); |
if (is_implicit_instance_closure) { |
__ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); |
@@ -1407,8 +1453,37 @@ |
} |
+// The target function was not found, so invoke method |
+// "dynamic noSuchMethod(Invocation invocation)". |
+// S5: inline cache data object. |
+// S4: arguments descriptor array. |
void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
- __ Unimplemented("CallNoSuchMethodFunction stub"); |
+ __ EnterStubFrame(); |
+ |
+ // Load the receiver. |
+ __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
+ __ sll(TMP, A1, 1); // A1 is a Smi. |
+ __ addu(TMP, FP, TMP); |
+ __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); |
+ |
+ // Push space for the return value. |
+ // Push the receiver. |
+ // Push IC data object. |
+ // Push arguments descriptor array. |
+ __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 3 * kWordSize)); |
+ __ sw(T6, Address(SP, 2 * kWordSize)); |
+ __ sw(S5, Address(SP, 1 * kWordSize)); |
+ __ sw(S4, Address(SP, 0 * kWordSize)); |
+ |
+ // A1: Smi-tagged arguments array length. |
+ PushArgumentsArray(assembler); |
+ |
+ __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); |
+ |
+ __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. |
+ __ LeaveStubFrameAndReturn(); |
} |
@@ -1585,7 +1660,8 @@ |
__ addiu(SP, SP, Immediate(-num_slots * kWordSize)); |
__ sw(S5, Address(SP, (num_slots - 1) * kWordSize)); |
__ sw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
- __ sw(NULLREG, Address(SP, (num_slots - 3) * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); |
// Push call arguments. |
for (intptr_t i = 0; i < num_args; i++) { |
__ lw(TMP1, Address(T1, -i * kWordSize)); |
@@ -1615,7 +1691,8 @@ |
__ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
__ LeaveStubFrame(); |
Label call_target_function; |
- __ bne(T3, NULLREG, &call_target_function); |
+ __ BranchNotEqual(T3, reinterpret_cast<int32_t>(Object::null()), |
+ &call_target_function); |
// NoSuchMethod or closure. |
// Mark IC call that it may be a closure call that does not collect |
@@ -1737,7 +1814,8 @@ |
// Preserve arguments descriptor and make room for result. |
__ addiu(SP, SP, Immediate(-2 * kWordSize)); |
__ sw(S4, Address(SP, 1 * kWordSize)); |
- __ sw(NULLREG, Address(SP, 0 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
// Pop code object result and restore arguments descriptor. |
__ lw(T0, Address(SP, 0 * kWordSize)); |
@@ -1837,14 +1915,17 @@ |
__ lw(T2, FieldAddress(A2, SubtypeTestCache::cache_offset())); |
__ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
+ __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
+ |
Label loop, found, not_found, next_iteration; |
// T0: instance class id. |
// T1: instance type arguments. |
// T2: Entry start. |
+ // T7: null. |
__ SmiTag(T0); |
__ Bind(&loop); |
__ lw(T3, Address(T2, kWordSize * SubtypeTestCache::kInstanceClassId)); |
- __ beq(T3, NULLREG, ¬_found); |
+ __ beq(T3, T7, ¬_found); |
if (n == 1) { |
__ beq(T3, T0, &found); |
@@ -1868,7 +1949,7 @@ |
// Fall through to not found. |
__ Bind(¬_found); |
__ Ret(); |
- __ delay_slot()->mov(V0, NULLREG); |
+ __ delay_slot()->mov(V0, T7); |
__ Bind(&found); |
__ Ret(); |
@@ -1947,6 +2028,7 @@ |
// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects. |
void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) { |
__ TraceSimMsg("EqualityWithNullArgStub"); |
+ __ Comment("EqualityWithNullArgStub"); |
__ EnterStubFrame(); |
static const intptr_t kNumArgsTested = 2; |
#if defined(DEBUG) |
@@ -2048,7 +2130,8 @@ |
__ addiu(SP, SP, Immediate(-3 * kWordSize)); |
__ sw(S4, Address(SP, 2 * kWordSize)); |
// Setup space on stack for return value. |
- __ sw(NULLREG, Address(SP, 1 * kWordSize)); |
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
+ __ sw(TMP, Address(SP, 1 * kWordSize)); |
__ sw(T0, Address(SP, 0 * kWordSize)); |
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
__ TraceSimMsg("OptimizeFunctionStub return"); |
@@ -2079,21 +2162,23 @@ |
// cannot contain a value that fits in Mint or Smi. |
void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
__ TraceSimMsg("IdenticalWithNumberCheckStub"); |
- const Register ret = CMPRES; |
+ __ Comment("IdenticalWithNumberCheckStub"); |
const Register temp1 = T2; |
const Register temp2 = T3; |
const Register left = T1; |
const Register right = T0; |
// Preserve left, right. |
- __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
- __ sw(T1, Address(SP, 1 * kWordSize)); |
- __ sw(T0, Address(SP, 0 * kWordSize)); |
+ __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
+ __ sw(temp1, Address(SP, 3 * kWordSize)); |
+ __ sw(temp2, Address(SP, 2 * kWordSize)); |
+ __ sw(left, Address(SP, 1 * kWordSize)); |
+ __ sw(right, Address(SP, 0 * kWordSize)); |
// TOS + 3: left argument. |
// TOS + 2: right argument. |
// TOS + 1: saved left |
// TOS + 0: saved right |
- __ lw(left, Address(SP, 3 * kWordSize)); |
- __ lw(right, Address(SP, 2 * kWordSize)); |
+ __ lw(left, Address(SP, 5 * kWordSize)); |
+ __ lw(right, Address(SP, 4 * kWordSize)); |
Label reference_compare, done, check_mint, check_bigint; |
// If any of the arguments is Smi do reference compare. |
__ andi(temp1, left, Immediate(kSmiTagMask)); |
@@ -2106,48 +2191,50 @@ |
__ LoadClassId(temp2, left); |
__ bne(temp1, temp2, &check_mint); |
__ LoadClassId(temp2, right); |
- __ subu(ret, temp1, temp2); |
- __ bne(ret, ZR, &done); |
+ __ subu(CMPRES, temp1, temp2); |
+ __ bne(CMPRES, ZR, &done); |
// Double values bitwise compare. |
__ lw(temp1, FieldAddress(left, Double::value_offset() + 0 * kWordSize)); |
- __ lw(temp1, FieldAddress(right, Double::value_offset() + 0 * kWordSize)); |
- __ subu(ret, temp1, temp2); |
- __ bne(ret, ZR, &done); |
+ __ lw(temp2, FieldAddress(right, Double::value_offset() + 0 * kWordSize)); |
+ __ subu(CMPRES, temp1, temp2); |
+ __ bne(CMPRES, ZR, &done); |
__ lw(temp1, FieldAddress(left, Double::value_offset() + 1 * kWordSize)); |
__ lw(temp2, FieldAddress(right, Double::value_offset() + 1 * kWordSize)); |
__ b(&done); |
- __ delay_slot()->subu(ret, temp1, temp2); |
+ __ delay_slot()->subu(CMPRES, temp1, temp2); |
__ Bind(&check_mint); |
__ LoadImmediate(temp1, kMintCid); |
__ LoadClassId(temp2, left); |
__ bne(temp1, temp2, &check_bigint); |
__ LoadClassId(temp2, right); |
- __ subu(ret, temp1, temp2); |
- __ bne(ret, ZR, &done); |
+ __ subu(CMPRES, temp1, temp2); |
+ __ bne(CMPRES, ZR, &done); |
__ lw(temp1, FieldAddress(left, Mint::value_offset() + 0 * kWordSize)); |
__ lw(temp2, FieldAddress(right, Mint::value_offset() + 0 * kWordSize)); |
- __ subu(ret, temp1, temp2); |
- __ bne(ret, ZR, &done); |
+ __ subu(CMPRES, temp1, temp2); |
+ __ bne(CMPRES, ZR, &done); |
__ lw(temp1, FieldAddress(left, Mint::value_offset() + 1 * kWordSize)); |
__ lw(temp2, FieldAddress(right, Mint::value_offset() + 1 * kWordSize)); |
__ b(&done); |
- __ delay_slot()->subu(ret, temp1, temp2); |
+ __ delay_slot()->subu(CMPRES, temp1, temp2); |
__ Bind(&check_bigint); |
__ LoadImmediate(temp1, kBigintCid); |
__ LoadClassId(temp2, left); |
__ bne(temp1, temp2, &reference_compare); |
__ LoadClassId(temp2, right); |
- __ subu(ret, temp1, temp2); |
- __ bne(ret, ZR, &done); |
+ __ subu(CMPRES, temp1, temp2); |
+ __ bne(CMPRES, ZR, &done); |
- __ EnterStubFrame(0); |
+ __ EnterStubFrame(); |
__ ReserveAlignedFrameSpace(2 * kWordSize); |
- __ sw(T1, Address(SP, 1 * kWordSize)); |
- __ sw(T0, Address(SP, 0 * kWordSize)); |
+ __ sw(left, Address(SP, 1 * kWordSize)); |
+ __ sw(right, Address(SP, 0 * kWordSize)); |
+ __ mov(A0, left); |
+ __ mov(A1, right); |
__ CallRuntime(kBigintCompareRuntimeEntry); |
__ TraceSimMsg("IdenticalWithNumberCheckStub return"); |
// Result in V0, 0 means equal. |
@@ -2156,14 +2243,16 @@ |
__ delay_slot()->mov(CMPRES, V0); |
__ Bind(&reference_compare); |
- __ subu(ret, left, right); |
+ __ subu(CMPRES, left, right); |
__ Bind(&done); |
// A branch or test after this comparison will check CMPRES == TMP1. |
__ mov(TMP1, ZR); |
- __ lw(T0, Address(SP, 0 * kWordSize)); |
- __ lw(T1, Address(SP, 1 * kWordSize)); |
+ __ lw(right, Address(SP, 0 * kWordSize)); |
+ __ lw(left, Address(SP, 1 * kWordSize)); |
+ __ lw(temp2, Address(SP, 2 * kWordSize)); |
+ __ lw(temp1, Address(SP, 3 * kWordSize)); |
__ Ret(); |
- __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
+ __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
} |
} // namespace dart |