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

Unified Diff: src/mips/codegen-mips.cc

Issue 1320006: Updates and fixes for MIPS support. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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
Index: src/mips/codegen-mips.cc
===================================================================
--- src/mips/codegen-mips.cc (revision 4259)
+++ src/mips/codegen-mips.cc (working copy)
@@ -92,7 +92,7 @@
// -----------------------------------------------------------------------------
-// CodeGenerator implementation
+// CodeGenerator implementation.
CodeGenerator::CodeGenerator(MacroAssembler* masm)
: deferred_(8),
@@ -150,6 +150,7 @@
VirtualFrame::SpilledScope spilled_scope;
if (scope()->num_heap_slots() > 0) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
{
@@ -173,6 +174,7 @@
// context.
if (scope()->arguments() != NULL) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// Generate code to 'execute' declarations and initialize functions
@@ -191,6 +193,7 @@
if (FLAG_trace) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// Compile the body of the function in a vanilla state. Don't
@@ -204,6 +207,7 @@
is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
if (should_trace) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
#endif
VisitStatementsAndSpill(info->function()->body());
@@ -225,28 +229,18 @@
function_return_.Bind();
if (FLAG_trace) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
- // Add a label for checking the size of the code used for returning.
- Label check_exit_codesize;
- masm_->bind(&check_exit_codesize);
+ // We don't check for the return code size. It may differ if the number of
+ // arguments is too big.
+ __ mov(sp, fp);
+ __ lw(fp, MemOperand(sp, 0));
+ __ lw(ra, MemOperand(sp, 4));
+ __ addiu(sp, sp, 8);
- masm_->mov(sp, fp);
- masm_->lw(fp, MemOperand(sp, 0));
- masm_->lw(ra, MemOperand(sp, 4));
- masm_->addiu(sp, sp, 8);
-
- // Here we use masm_-> instead of the __ macro to avoid the code coverage
- // tool from instrumenting as we rely on the code size here.
- // TODO(MIPS): Should we be able to use more than 0x1ffe parameters?
- masm_->addiu(sp, sp, (scope()->num_parameters() + 1) * kPointerSize);
- masm_->Jump(ra);
- // The Jump automatically generates a nop in the branch delay slot.
-
- // Check that the size of the code used for returning matches what is
- // expected by the debugger.
- ASSERT_EQ(kJSReturnSequenceLength,
- masm_->InstructionsGeneratedSince(&check_exit_codesize));
+ __ Addu(sp, sp, Operand((scope()->num_parameters() + 1) * kPointerSize));
+ __ Ret();
}
// Code generation state must be reset.
@@ -276,7 +270,7 @@
UNIMPLEMENTED_MIPS();
} else if (var != NULL) {
// The expression is a variable proxy that does not rewrite to a
- // property. Global variables are treated as named property references.
+ // property. Global variables are treated as named property references.
if (var->is_global()) {
LoadGlobal();
ref->set_type(Reference::NAMED);
@@ -286,6 +280,7 @@
}
} else {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
}
@@ -317,9 +312,7 @@
int index = slot->index();
switch (slot->type()) {
case Slot::PARAMETER:
- UNIMPLEMENTED_MIPS();
- return MemOperand(no_reg, 0);
-
+ return frame_->ParameterAt(index);
case Slot::LOCAL:
return frame_->LocalAt(index);
@@ -388,10 +381,12 @@
if (has_cc()) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
if (true_target.is_linked() || false_target.is_linked()) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
ASSERT(has_valid_frame());
ASSERT(!has_cc());
@@ -410,11 +405,13 @@
VirtualFrame::SpilledScope spilled_scope;
if (slot->type() == Slot::LOOKUP) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
} else {
- __ lw(a0, SlotOperand(slot, a2));
- frame_->EmitPush(a0);
+ __ lw(v0, SlotOperand(slot, a2));
+ frame_->EmitPush(v0);
if (slot->var()->mode() == Variable::CONST) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
}
}
@@ -424,12 +421,14 @@
ASSERT(slot != NULL);
if (slot->type() == Slot::LOOKUP) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
} else {
ASSERT(!slot->var()->is_dynamic());
JumpTarget exit;
if (init_state == CONST_INIT) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// We must execute the store. Storing a variable must keep the
@@ -446,6 +445,7 @@
frame_->EmitPush(a0);
if (slot->type() == Slot::CONTEXT) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// If we definitely did not jump over the assignment, we do not need
// to bind the exit label. Doing so can defeat peephole
@@ -466,7 +466,19 @@
void CodeGenerator::VisitBlock(Block* node) {
- UNIMPLEMENTED_MIPS();
+#ifdef DEBUG
+ int original_height = frame_->height();
+#endif
+ VirtualFrame::SpilledScope spilled_scope;
+ Comment cmnt(masm_, "[ Block");
+ CodeForStatementPosition(node);
+ node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
+ VisitStatementsAndSpill(node->statements());
+ if (node->break_target()->is_linked()) {
+ node->break_target()->Bind();
+ }
+ node->break_target()->Unuse();
+ ASSERT(!has_valid_frame() || frame_->height() == original_height);
}
@@ -483,7 +495,48 @@
void CodeGenerator::VisitDeclaration(Declaration* node) {
- UNIMPLEMENTED_MIPS();
+#ifdef DEBUG
+ int original_height = frame_->height();
+#endif
+ VirtualFrame::SpilledScope spilled_scope;
+ Comment cmnt(masm_, "[ Declaration");
+ Variable* var = node->proxy()->var();
+ ASSERT(var != NULL); // Must have been resolved.
+ Slot* slot = var->slot();
+
+ // If it was not possible to allocate the variable at compile time,
+ // we need to "declare" it at runtime to make sure it actually
+ // exists in the local context.
+ if (slot != NULL && slot->type() == Slot::LOOKUP) {
+ UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
+ return;
+ }
+
+ ASSERT(!var->is_global());
+
+ // If we have a function or a constant, we need to initialize the variable.
+ Expression* val = NULL;
+ if (node->mode() == Variable::CONST) {
+ UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
+ } else {
+ val = node->fun(); // NULL if we don't have a function.
+ }
+
+ if (val != NULL) {
+ {
+ // Set initial value.
+ Reference target(this, node->proxy());
+ LoadAndSpill(val);
+ target.SetValue(NOT_CONST_INIT);
+ // The reference is removed from the stack (preserving TOS) when
+ // it goes out of scope.
+ }
+ // Get rid of the assigned value (declarations are statements).
+ frame_->Drop();
+ }
+ ASSERT(frame_->height() == original_height);
}
@@ -504,21 +557,25 @@
void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitIfStatement(IfStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
@@ -544,67 +601,80 @@
void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitForStatement(ForStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitForInStatement(ForInStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitSharedFunctionInfoLiteral(
SharedFunctionInfoLiteral* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitConditional(Conditional* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
@@ -653,21 +723,25 @@
void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
@@ -678,7 +752,7 @@
VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ Assignment");
- { Reference target(this, node->target());
+ { Reference target(this, node->target(), node->is_compound());
if (target.is_illegal()) {
// Fool the virtual frame into thinking that we left the assignment's
// value on the frame.
@@ -693,6 +767,7 @@
LoadAndSpill(node->value());
} else {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
Variable* var = node->target()->AsVariableProxy()->AsVariable();
@@ -718,11 +793,13 @@
void CodeGenerator::VisitThrow(Throw* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitProperty(Property* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
@@ -752,22 +829,19 @@
if (var != NULL && var->is_possibly_eval()) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
} else if (var != NULL && !var->is_this() && var->is_global()) {
- // ----------------------------------
- // JavaScript example: 'foo(1, 2, 3)' // foo is global
- // ----------------------------------
+ // -----------------------------------------------------
+ // JavaScript example: 'foo(1, 2, 3)' // foo is global.
+ // -----------------------------------------------------
- int arg_count = args->length();
-
- // We need sp to be 8 bytes aligned when calling the stub.
- __ SetupAlignedCall(t0, arg_count);
-
// Pass the global object as the receiver and let the IC stub
// patch the stack to use the global proxy as 'this' in the
// invoked function.
LoadGlobal();
// Load the arguments.
+ int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
LoadAndSpill(args->at(i));
}
@@ -779,7 +853,6 @@
CodeForSourcePosition(node->position());
frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
arg_count + 1);
- __ ReturnFromAlignedCall();
__ lw(cp, frame_->Context());
// Remove the function from the stack.
frame_->EmitPush(v0);
@@ -789,8 +862,10 @@
UNIMPLEMENTED_MIPS();
} else if (property != NULL) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
} else {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
ASSERT(frame_->height() == original_height + 1);
@@ -799,174 +874,204 @@
void CodeGenerator::VisitCallNew(CallNew* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
-// This should generate code that performs a charCodeAt() call or returns
-// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
-// It is not yet implemented on ARM, so it always goes to the slow case.
void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitCountOperation(CountOperation* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
-
void CodeGenerator::VisitThisFunction(ThisFunction* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
@@ -979,7 +1084,7 @@
#define __ ACCESS_MASM(masm)
// -----------------------------------------------------------------------------
-// Reference support
+// Reference support.
Reference::Reference(CodeGenerator* cgen,
Expression* expression,
@@ -1079,11 +1184,9 @@
}
-// On entry a0 and a1 are the things to be compared. On exit v0 is 0,
-// positive or negative to indicate the result of the comparison.
void CompareStub::Generate(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x765);
+ __ break_(__LINE__);
}
@@ -1095,20 +1198,57 @@
void StackCheckStub::Generate(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x790);
+ __ break_(__LINE__);
}
-void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
+void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x808);
+ __ break_(__LINE__);
}
+void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
+ // v0 holds the exception.
+
+ // Adjust this code if not the case.
+ ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
+
+ // Drop the sp to the top of the handler.
+ __ li(a3, Operand(ExternalReference(Top::k_handler_address)));
+ __ lw(sp, MemOperand(a3));
+
+ // Restore the next handler and frame pointer, discard handler state.
+ ASSERT(StackHandlerConstants::kNextOffset == 0);
+ __ Pop(a2);
+ __ sw(a2, MemOperand(a3));
+ ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
+ __ MultiPop(a3.bit() | fp.bit());
+
+ // Before returning we restore the context from the frame pointer if
+ // not NULL. The frame pointer is NULL in the exception handler of a
+ // JS entry frame.
+ // Set cp to NULL if fp is NULL.
+ Label done;
+ __ Branch(false, &done, eq, fp, Operand(zero_reg));
+ __ mov(cp, zero_reg); // Use the branch delay slot.
+ __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ __ bind(&done);
+
+#ifdef DEBUG
+ // TODO(MIPS): Implement debug code.
+#endif
+
+ ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
+ __ Pop(t9);
+ __ Jump(t9);
+}
+
+
void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
UncatchableExceptionType type) {
UNIMPLEMENTED_MIPS();
- __ break_(0x815);
+ __ break_(__LINE__);
}
void CEntryStub::GenerateCore(MacroAssembler* masm,
@@ -1117,18 +1257,21 @@
Label* throw_out_of_memory_exception,
bool do_gc,
bool always_allocate) {
+ // v0: result parameter for PerformGC, if any
// s0: number of arguments including receiver (C callee-saved)
// s1: pointer to the first argument (C callee-saved)
// s2: pointer to builtin function (C callee-saved)
if (do_gc) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
ExternalReference scope_depth =
ExternalReference::heap_always_allocate_scope_depth();
if (always_allocate) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// Call C built-in.
@@ -1136,10 +1279,15 @@
__ mov(a0, s0);
__ mov(a1, s1);
- __ CallBuiltin(s2);
+ // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
+ // also need the argument slots.
+ __ jalr(s2);
+ __ addiu(sp, sp, -StandardFrameConstants::kCArgsSlotsSize);
Søren Thygesen Gjesse 2010/05/25 09:00:56 Please add a comment on the usage of the branch de
+ __ addiu(sp, sp, StandardFrameConstants::kCArgsSlotsSize);
if (always_allocate) {
UNIMPLEMENTED_MIPS();
+ __ break_(__LINE__);
}
// Check for failure result.
@@ -1147,7 +1295,7 @@
ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
__ addiu(a2, v0, 1);
__ andi(t0, a2, kFailureTagMask);
- __ Branch(eq, &failure_returned, t0, Operand(zero_reg));
+ __ Branch(&failure_returned, eq, t0, Operand(zero_reg));
// Exit C frame and return.
// v0:v1: result
@@ -1160,11 +1308,11 @@
__ bind(&failure_returned);
ASSERT(Failure::RETRY_AFTER_GC == 0);
__ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize);
- __ Branch(eq, &retry, t0, Operand(zero_reg));
+ __ Branch(&retry, eq, t0, Operand(zero_reg));
// Special handling of out of memory exceptions.
Failure* out_of_memory = Failure::OutOfMemoryException();
- __ Branch(eq, throw_out_of_memory_exception,
+ __ Branch(throw_out_of_memory_exception, eq,
v0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
// Retrieve the pending exception and clear the variable.
@@ -1177,14 +1325,14 @@
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ Branch(eq, throw_termination_exception,
+ __ Branch(throw_termination_exception, eq,
v0, Operand(Factory::termination_exception()));
// Handle normal exception.
- __ b(throw_normal_exception);
- __ nop(); // Branch delay slot nop.
+ __ jmp(throw_normal_exception);
- __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying
+ __ bind(&retry);
+ // Last failure (v0) will be moved to (a0) for parameter when retrying.
}
void CEntryStub::Generate(MacroAssembler* masm) {
@@ -1263,6 +1411,10 @@
// Save callee saved registers on the stack.
__ MultiPush((kCalleeSaved | ra.bit()) & ~sp.bit());
+ // Load argv in s0 register.
+ __ lw(s0, MemOperand(sp, kNumCalleeSaved * kPointerSize +
+ StandardFrameConstants::kCArgsSlotsSize));
+
// We build an EntryFrame.
__ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used.
int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
@@ -1275,10 +1427,6 @@
// Setup frame pointer for the frame to be pushed.
__ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
- // Load argv in s0 register.
- __ lw(s0, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize +
- StandardFrameConstants::kCArgsSlotsSize));
-
// Registers:
// a0: entry_address
// a1: function
@@ -1350,7 +1498,7 @@
ExternalReference entry(Builtins::JSEntryTrampoline);
__ LoadExternalReference(t0, entry);
}
- __ lw(t9, MemOperand(t0)); // deref address
+ __ lw(t9, MemOperand(t0)); // Deref address.
// Call JSEntryTrampoline.
__ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
@@ -1367,7 +1515,7 @@
// This restores sp to its position before PushTryHandler.
__ addiu(sp, sp, StackHandlerConstants::kSize);
- __ bind(&exit); // v0 holds result
+ __ bind(&exit); // v0 holds result.
// Restore the top frame descriptors from the stack.
__ Pop(t1);
__ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address));
@@ -1394,25 +1542,25 @@
void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x851);
+ __ break_(__LINE__);
}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x857);
+ __ break_(__LINE__);
}
void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
UNIMPLEMENTED_MIPS();
- __ break_(0x863);
+ __ break_(__LINE__);
}
const char* CompareStub::GetName() {
UNIMPLEMENTED_MIPS();
- return NULL; // UNIMPLEMENTED RETURN
+ return NULL; // UNIMPLEMENTED RETURN.
}

Powered by Google App Engine
This is Rietveld 408576698