Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Unified Diff: runtime/vm/stub_code_mips.cc

Issue 14733002: On MIPS, uses more branch delay slots. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/vm/stub_code_arm.cc ('K') | « runtime/vm/stub_code_arm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/stub_code_mips.cc
===================================================================
--- runtime/vm/stub_code_mips.cc (revision 22187)
+++ runtime/vm/stub_code_mips.cc (working copy)
@@ -81,10 +81,11 @@
__ addiu(A2, A2, Immediate(kWordSize)); // Set argv in NativeArguments.
ASSERT(retval_offset == 3 * kWordSize);
- __ addiu(A3, A2, Immediate(kWordSize)); // Retval is next to 1st argument.
// Call runtime or redirection via simulator.
__ jalr(S5);
+ // Retval is next to 1st argument.
+ __ delay_slot()->addiu(A3, A2, Immediate(kWordSize));
__ TraceSimMsg("CallToRuntimeStub return");
// Reset exit frame information in Isolate structure.
@@ -175,10 +176,9 @@
__ sw(A1, Address(SP, 1 * kWordSize));
__ sw(A0, Address(SP, 0 * kWordSize));
- __ mov(A0, SP); // Pass the pointer to the NativeArguments.
-
// Call native function or redirection via simulator.
__ jalr(T5);
+ __ delay_slot()->mov(A0, SP); // Pass the pointer to the NativeArguments.
__ TraceSimMsg("CallNativeCFunctionStub return");
// Reset exit frame information in Isolate structure.
@@ -228,6 +228,7 @@
__ lw(T0, FieldAddress(T0, Code::instructions_offset()));
__ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
__ jr(T0);
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -250,10 +251,12 @@
__ addiu(SP, SP, Immediate(2 * kWordSize));
// Remove the stub frame.
__ LeaveStubFrame();
+
// Jump to the dart function.
__ lw(T0, FieldAddress(T0, Code::instructions_offset()));
__ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag);
__ jr(T0);
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -274,19 +277,21 @@
__ sll(T1, A1, 1);
__ addu(T1, FP, T1);
__ AddImmediate(T1, (kLastParamSlotIndex - 1) * kWordSize);
- __ AddImmediate(T2, V0, Array::data_offset() - kHeapObjectTag);
// T1: address of first argument on stack.
// T2: address of first argument in array.
- Label loop, loop_condition;
- __ b(&loop_condition);
+
+ Label loop, loop_exit;
+ __ blez(A1, &loop_exit);
+ __ delay_slot()->addiu(T2, V0,
+ Immediate(Array::data_offset() - kHeapObjectTag));
__ Bind(&loop);
__ lw(TMP, Address(T1));
- __ sw(TMP, Address(T2));
- __ AddImmediate(T1, -kWordSize);
- __ AddImmediate(T2, kWordSize);
- __ Bind(&loop_condition);
- __ AddImmediate(A1, -Smi::RawValue(1)); // A1 is Smi.
- __ BranchSignedGreaterEqual(A1, ZR, &loop);
+ __ addiu(A1, A1, Immediate(-Smi::RawValue(1)));
+ __ addiu(T1, T1, Immediate(-kWordSize));
+ __ addiu(T2, T2, Immediate(kWordSize));
+ __ bgez(A1, &loop);
+ __ delay_slot()->sw(TMP, Address(T2, -kWordSize));
+ __ Bind(&loop_exit);
}
@@ -338,6 +343,7 @@
__ addiu(SP, SP, Immediate(5 * kWordSize)); // Get result into V0.
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -454,6 +460,7 @@
}
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -570,17 +577,21 @@
// T2: new object end address.
// A1: Array length as Smi.
__ AddImmediate(T3, V0, Array::data_offset() - kHeapObjectTag);
- // R1: iterator which initially points to the start of the variable
+ // T3: iterator which initially points to the start of the variable
// data area to be initialized.
- __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
- Label loop, test;
- __ b(&test);
+
+ Label loop, loop_exit;
+ intptr_t null = reinterpret_cast<intptr_t>(Object::null());
+ uint16_t null_lo = Utils::Low16Bits(null);
+ uint16_t null_hi = Utils::High16Bits(null);
+ __ lui(TMP1, Immediate(null_hi));
+ __ BranchUnsignedGreaterEqual(T3, T2, &loop_exit);
+ __ delay_slot()->ori(TMP1, TMP1, Immediate(null_lo));
__ Bind(&loop);
- // TODO(cshapiro): StoreIntoObjectNoBarrier
- __ sw(TMP1, Address(T3, 0));
- __ AddImmediate(T3, kWordSize);
- __ Bind(&test);
+ __ addiu(T3, T3, Immediate(kWordSize));
__ bne(T3, T2, &loop);
+ __ delay_slot()->sw(TMP1, Address(T3, -kWordSize));
+ __ Bind(&loop_exit);
// Done allocating and initializing the array.
// V0: new object.
@@ -611,6 +622,7 @@
__ mov(V0, TMP1);
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -682,6 +694,7 @@
// Remove the stub frame as we are about to jump to the closure function.
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
__ Bind(&function_compiled);
// T0: Code.
@@ -727,6 +740,7 @@
// Remove the stub frame as we are about to return.
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -795,12 +809,13 @@
// Compute address of 'arguments array' data area into A2.
__ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle));
- __ AddImmediate(A2, Array::data_offset() - kHeapObjectTag);
// Set up arguments for the Dart call.
Label push_arguments;
Label done_push_arguments;
__ beq(T1, ZR, &done_push_arguments); // check if there are arguments.
+ __ delay_slot()->addiu(A2, A2,
+ Immediate(Array::data_offset() - kHeapObjectTag));
__ mov(A1, ZR);
__ Bind(&push_arguments);
__ lw(A3, Address(A2));
@@ -845,6 +860,7 @@
// Restore the frame pointer and return.
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
}
@@ -927,26 +943,24 @@
// T2: isolate, not an object.
__ sw(T2, FieldAddress(V0, Context::isolate_offset()));
- // Setup the parent field.
- // V0: new object.
- // T1: number of context variables.
__ LoadImmediate(T2, reinterpret_cast<intptr_t>(Object::null()));
- __ sw(T2, FieldAddress(V0, Context::parent_offset()));
// Initialize the context variables.
// V0: new object.
// T1: number of context variables.
// T2: raw null.
- Label loop, loop_test;
+ Label loop, loop_exit;
+ __ blez(T1, &loop_exit);
+ // Setup the parent field.
+ __ delay_slot()->sw(T2, FieldAddress(V0, Context::parent_offset()));
__ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag);
- __ b(&loop_test);
- __ delay_slot()->sll(T1, T1, 2);
+ __ sll(T1, T1, 2);
__ Bind(&loop);
+ __ addiu(T1, T1, Immediate(-kWordSize));
__ addu(TMP1, T3, T1);
- __ sw(T2, Address(TMP1));
- __ Bind(&loop_test);
- __ addiu(T1, T1, Immediate(-kWordSize));
- __ bne(T1, ZR, &loop); // Loop if R1 not zero.
+ __ bgtz(T1, &loop);
+ __ delay_slot()->sw(T2, Address(TMP1));
+ __ Bind(&loop_exit);
// Done allocating and initializing the context.
// V0: new object.
@@ -970,6 +984,7 @@
// V0: new object
// Restore the frame pointer.
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
regis 2013/05/01 01:21:46 Why didn't you use the delay slot here?
zra 2013/05/01 16:53:17 Missed it. Thanks!
__ Ret();
}
@@ -1152,14 +1167,13 @@
// T3: next object start.
// T4: next word to be initialized.
// T1: new object type arguments (if is_cls_parameterized).
- Label init_loop;
- Label done;
- __ Bind(&init_loop);
- __ BranchUnsignedGreaterEqual(T4, T3, &done); // Done if T4 >= T3.
- __ sw(T0, Address(T4));
- __ AddImmediate(T4, kWordSize);
- __ b(&init_loop);
- __ Bind(&done);
+ Label loop, loop_exit;
+ __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit);
+ __ Bind(&loop);
+ __ addiu(T4, T4, Immediate(kWordSize));
+ __ bne(T4, T3, &loop);
+ __ delay_slot()->sw(T0, Address(T4, -kWordSize));
+ __ Bind(&loop_exit);
}
if (is_cls_parameterized) {
// R1: new object type arguments.
@@ -1206,6 +1220,7 @@
// Restore the frame pointer.
__ LeaveStubFrame(true);
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore(true);
}
@@ -1322,6 +1337,7 @@
__ addiu(V0, T2, Immediate(kHeapObjectTag));
__ LeaveStubFrame(true);
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore(true);
__ Bind(&slow_case);
}
@@ -1369,6 +1385,7 @@
// Restore the frame pointer.
__ LeaveStubFrame(true);
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore(true);
}
@@ -1398,6 +1415,7 @@
__ lw(T0, Address(SP, 4 * kWordSize));
__ addiu(SP, SP, Immediate(5 * kWordSize)); // Discard argument;
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
}
__ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
Label is_hot;
@@ -1583,6 +1601,7 @@
Label call_target_function;
__ BranchNotEqual(T3, reinterpret_cast<intptr_t>(Object::null()),
&call_target_function);
+ __ delay_slot()->LeaveStubFrameSPRestore();
// NoSuchMethod or closure.
// Mark IC call that it may be a closure call that does not collect
// type feedback.
@@ -1611,6 +1630,8 @@
__ lw(T3, FieldAddress(T3, Code::instructions_offset()));
__ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
__ jr(T3);
+ __ delay_slot()->addiu(T3, T3,
+ Immediate(Instructions::HeaderSize() - kHeapObjectTag));
// Instance in T3, return its class-id in T3 as Smi.
__ Bind(&get_class_id_as_smi);
@@ -1618,13 +1639,13 @@
// Test if Smi -> load Smi class for comparison.
__ andi(TMP1, T3, Immediate(kSmiTagMask));
__ bne(TMP1, ZR, &not_smi);
- __ LoadImmediate(T3, Smi::RawValue(kSmiCid));
__ jr(RA);
+ __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
__ Bind(&not_smi);
__ LoadClassId(T3, T3);
- __ SmiTag(T3);
__ jr(RA);
+ __ delay_slot()->SmiTag(T3);
}
@@ -1706,6 +1727,7 @@
__ lw(S4, Address(SP, 1 * kWordSize));
__ addiu(SP, SP, Immediate(2 * kWordSize));
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
// Now call the static function. The breakpoint handler function
// ensures that the call target is compiled.
@@ -1725,6 +1747,7 @@
__ CallRuntime(kBreakpointReturnHandlerRuntimeEntry);
__ Pop(V0);
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
// Instead of returning to the patched Dart function, emulate the
// smashed return code pattern and return to the function's caller.
@@ -1748,6 +1771,7 @@
__ lw(S5, Address(SP, 1 * kWordSize));
__ addiu(SP, SP, Immediate(2 * kWordSize));
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
// Find out which dispatch stub to call.
__ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset()));
@@ -1825,12 +1849,17 @@
}
}
__ Bind(&next_iteration);
- __ AddImmediate(T2, kWordSize * SubtypeTestCache::kTestEntryLength);
__ b(&loop);
+ __ delay_slot()->addiu(T2, T2,
+ Immediate(kWordSize * SubtypeTestCache::kTestEntryLength));
// Fall through to not found.
__ Bind(&not_found);
- __ LoadImmediate(V0, reinterpret_cast<intptr_t>(Object::null()));
+ intptr_t null = reinterpret_cast<intptr_t>(Object::null());
+ uint16_t null_lo = Utils::Low16Bits(null);
+ uint16_t null_hi = Utils::High16Bits(null);
+ __ lui(V0, Immediate(null_hi));
__ Ret();
+ __ delay_slot()->ori(V0, V0, Immediate(null_lo));
__ Bind(&found);
__ Ret();
@@ -1893,8 +1922,8 @@
__ mov(V0, A3); // Exception object.
__ lw(V1, Address(SP, 0)); // StackTrace object.
__ mov(FP, A2); // Frame_pointer.
- __ mov(SP, A1); // Stack pointer.
__ jr(A0); // Jump to the exception handler code.
+ __ delay_slot()->mov(SP, A1); // Stack pointer.
}
@@ -1939,8 +1968,14 @@
__ beq(T2, T3, &found); // Class id match?
__ Bind(&no_match);
// Next check group.
- __ AddImmediate(T6, kWordSize * ICData::TestEntryLengthFor(kNumArgsTested));
- __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop); // Done?
+ intptr_t entry_bytes = kWordSize * ICData::TestEntryLengthFor(kNumArgsTested);
+ if (Utils::IsInt(kImmBits, entry_bytes)) {
+ __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop); // Done?
+ __ delay_slot()->addiu(T6, T6, Immediate(entry_bytes));
+ } else {
+ __ AddImmediate(T6, entry_bytes);
+ __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop); // Done?
+ }
Label update_ic_data;
__ b(&update_ic_data);
@@ -1965,6 +2000,7 @@
__ movn(V0, TMP2, CMPRES);
__ LeaveStubFrame();
__ Ret();
+ __ delay_slot()->LeaveStubFrameSPRestore();
__ Bind(&get_class_id_as_smi);
// Test if Smi -> load Smi class for comparison.
@@ -2016,6 +2052,7 @@
__ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
__ LeaveStubFrame();
__ jr(T0);
+ __ delay_slot()->LeaveStubFrameSPRestore();
__ break_(0);
}
@@ -2109,6 +2146,7 @@
__ TraceSimMsg("IdenticalWithNumberCheckStub return");
// Result in V0, 0 means equal.
__ LeaveStubFrame();
+ __ LeaveStubFrameSPRestore();
__ b(&done);
__ delay_slot()->mov(CMPRES, V0);
« runtime/vm/stub_code_arm.cc ('K') | « runtime/vm/stub_code_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698