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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 85 }
86 86
87 87
88 CodeGenState::~CodeGenState() { 88 CodeGenState::~CodeGenState() {
89 ASSERT(owner_->state() == this); 89 ASSERT(owner_->state() == this);
90 owner_->set_state(previous_); 90 owner_->set_state(previous_);
91 } 91 }
92 92
93 93
94 // ----------------------------------------------------------------------------- 94 // -----------------------------------------------------------------------------
95 // CodeGenerator implementation 95 // CodeGenerator implementation.
96 96
97 CodeGenerator::CodeGenerator(MacroAssembler* masm) 97 CodeGenerator::CodeGenerator(MacroAssembler* masm)
98 : deferred_(8), 98 : deferred_(8),
99 masm_(masm), 99 masm_(masm),
100 frame_(NULL), 100 frame_(NULL),
101 allocator_(NULL), 101 allocator_(NULL),
102 cc_reg_(cc_always), 102 cc_reg_(cc_always),
103 state_(NULL), 103 state_(NULL),
104 function_return_is_shadowed_(false) { 104 function_return_is_shadowed_(false) {
105 } 105 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // Allocate space for locals and initialize them. 143 // Allocate space for locals and initialize them.
144 frame_->AllocateStackSlots(); 144 frame_->AllocateStackSlots();
145 145
146 // Initialize the function return target. 146 // Initialize the function return target.
147 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 147 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
148 function_return_is_shadowed_ = false; 148 function_return_is_shadowed_ = false;
149 149
150 VirtualFrame::SpilledScope spilled_scope; 150 VirtualFrame::SpilledScope spilled_scope;
151 if (scope()->num_heap_slots() > 0) { 151 if (scope()->num_heap_slots() > 0) {
152 UNIMPLEMENTED_MIPS(); 152 UNIMPLEMENTED_MIPS();
153 __ break_(__LINE__);
153 } 154 }
154 155
155 { 156 {
156 Comment cmnt2(masm_, "[ copy context parameters into .context"); 157 Comment cmnt2(masm_, "[ copy context parameters into .context");
157 158
158 // Note that iteration order is relevant here! If we have the same 159 // Note that iteration order is relevant here! If we have the same
159 // parameter twice (e.g., function (x, y, x)), and that parameter 160 // parameter twice (e.g., function (x, y, x)), and that parameter
160 // needs to be copied into the context, it must be the last argument 161 // needs to be copied into the context, it must be the last argument
161 // passed to the parameter that needs to be copied. This is a rare 162 // passed to the parameter that needs to be copied. This is a rare
162 // case so we don't check for it, instead we rely on the copying 163 // case so we don't check for it, instead we rely on the copying
163 // order: such a parameter is copied repeatedly into the same 164 // order: such a parameter is copied repeatedly into the same
164 // context location and thus the last value is what is seen inside 165 // context location and thus the last value is what is seen inside
165 // the function. 166 // the function.
166 for (int i = 0; i < scope()->num_parameters(); i++) { 167 for (int i = 0; i < scope()->num_parameters(); i++) {
167 UNIMPLEMENTED_MIPS(); 168 UNIMPLEMENTED_MIPS();
168 } 169 }
169 } 170 }
170 171
171 // Store the arguments object. This must happen after context 172 // Store the arguments object. This must happen after context
172 // initialization because the arguments object may be stored in the 173 // initialization because the arguments object may be stored in the
173 // context. 174 // context.
174 if (scope()->arguments() != NULL) { 175 if (scope()->arguments() != NULL) {
175 UNIMPLEMENTED_MIPS(); 176 UNIMPLEMENTED_MIPS();
177 __ break_(__LINE__);
176 } 178 }
177 179
178 // Generate code to 'execute' declarations and initialize functions 180 // Generate code to 'execute' declarations and initialize functions
179 // (source elements). In case of an illegal redeclaration we need to 181 // (source elements). In case of an illegal redeclaration we need to
180 // handle that instead of processing the declarations. 182 // handle that instead of processing the declarations.
181 if (scope()->HasIllegalRedeclaration()) { 183 if (scope()->HasIllegalRedeclaration()) {
182 Comment cmnt(masm_, "[ illegal redeclarations"); 184 Comment cmnt(masm_, "[ illegal redeclarations");
183 scope()->VisitIllegalRedeclaration(this); 185 scope()->VisitIllegalRedeclaration(this);
184 } else { 186 } else {
185 Comment cmnt(masm_, "[ declarations"); 187 Comment cmnt(masm_, "[ declarations");
186 ProcessDeclarations(scope()->declarations()); 188 ProcessDeclarations(scope()->declarations());
187 // Bail out if a stack-overflow exception occurred when processing 189 // Bail out if a stack-overflow exception occurred when processing
188 // declarations. 190 // declarations.
189 if (HasStackOverflow()) return; 191 if (HasStackOverflow()) return;
190 } 192 }
191 193
192 if (FLAG_trace) { 194 if (FLAG_trace) {
193 UNIMPLEMENTED_MIPS(); 195 UNIMPLEMENTED_MIPS();
196 __ break_(__LINE__);
194 } 197 }
195 198
196 // Compile the body of the function in a vanilla state. Don't 199 // Compile the body of the function in a vanilla state. Don't
197 // bother compiling all the code if the scope has an illegal 200 // bother compiling all the code if the scope has an illegal
198 // redeclaration. 201 // redeclaration.
199 if (!scope()->HasIllegalRedeclaration()) { 202 if (!scope()->HasIllegalRedeclaration()) {
200 Comment cmnt(masm_, "[ function body"); 203 Comment cmnt(masm_, "[ function body");
201 #ifdef DEBUG 204 #ifdef DEBUG
202 bool is_builtin = Bootstrapper::IsActive(); 205 bool is_builtin = Bootstrapper::IsActive();
203 bool should_trace = 206 bool should_trace =
204 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls; 207 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
205 if (should_trace) { 208 if (should_trace) {
206 UNIMPLEMENTED_MIPS(); 209 UNIMPLEMENTED_MIPS();
210 __ break_(__LINE__);
207 } 211 }
208 #endif 212 #endif
209 VisitStatementsAndSpill(info->function()->body()); 213 VisitStatementsAndSpill(info->function()->body());
210 } 214 }
211 } 215 }
212 216
213 if (has_valid_frame() || function_return_.is_linked()) { 217 if (has_valid_frame() || function_return_.is_linked()) {
214 if (!function_return_.is_linked()) { 218 if (!function_return_.is_linked()) {
215 CodeForReturnPosition(info->function()); 219 CodeForReturnPosition(info->function());
216 } 220 }
217 // Registers: 221 // Registers:
218 // v0: result 222 // v0: result
219 // sp: stack pointer 223 // sp: stack pointer
220 // fp: frame pointer 224 // fp: frame pointer
221 // cp: callee's context 225 // cp: callee's context
222 226
223 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 227 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
224 228
225 function_return_.Bind(); 229 function_return_.Bind();
226 if (FLAG_trace) { 230 if (FLAG_trace) {
227 UNIMPLEMENTED_MIPS(); 231 UNIMPLEMENTED_MIPS();
232 __ break_(__LINE__);
228 } 233 }
229 234
230 // Add a label for checking the size of the code used for returning. 235 // We don't check for the return code size. It may differ if the number of
231 Label check_exit_codesize; 236 // arguments is too big.
232 masm_->bind(&check_exit_codesize); 237 __ mov(sp, fp);
238 __ lw(fp, MemOperand(sp, 0));
239 __ lw(ra, MemOperand(sp, 4));
240 __ addiu(sp, sp, 8);
233 241
234 masm_->mov(sp, fp); 242 __ Addu(sp, sp, Operand((scope()->num_parameters() + 1) * kPointerSize));
235 masm_->lw(fp, MemOperand(sp, 0)); 243 __ Ret();
236 masm_->lw(ra, MemOperand(sp, 4));
237 masm_->addiu(sp, sp, 8);
238
239 // Here we use masm_-> instead of the __ macro to avoid the code coverage
240 // tool from instrumenting as we rely on the code size here.
241 // TODO(MIPS): Should we be able to use more than 0x1ffe parameters?
242 masm_->addiu(sp, sp, (scope()->num_parameters() + 1) * kPointerSize);
243 masm_->Jump(ra);
244 // The Jump automatically generates a nop in the branch delay slot.
245
246 // Check that the size of the code used for returning matches what is
247 // expected by the debugger.
248 ASSERT_EQ(kJSReturnSequenceLength,
249 masm_->InstructionsGeneratedSince(&check_exit_codesize));
250 } 244 }
251 245
252 // Code generation state must be reset. 246 // Code generation state must be reset.
253 ASSERT(!has_cc()); 247 ASSERT(!has_cc());
254 ASSERT(state_ == NULL); 248 ASSERT(state_ == NULL);
255 ASSERT(!function_return_is_shadowed_); 249 ASSERT(!function_return_is_shadowed_);
256 function_return_.Unuse(); 250 function_return_.Unuse();
257 DeleteFrame(); 251 DeleteFrame();
258 252
259 // Process any deferred code using the register allocator. 253 // Process any deferred code using the register allocator.
260 if (!HasStackOverflow()) { 254 if (!HasStackOverflow()) {
261 ProcessDeferred(); 255 ProcessDeferred();
262 } 256 }
263 257
264 allocator_ = NULL; 258 allocator_ = NULL;
265 } 259 }
266 260
267 261
268 void CodeGenerator::LoadReference(Reference* ref) { 262 void CodeGenerator::LoadReference(Reference* ref) {
269 VirtualFrame::SpilledScope spilled_scope; 263 VirtualFrame::SpilledScope spilled_scope;
270 Comment cmnt(masm_, "[ LoadReference"); 264 Comment cmnt(masm_, "[ LoadReference");
271 Expression* e = ref->expression(); 265 Expression* e = ref->expression();
272 Property* property = e->AsProperty(); 266 Property* property = e->AsProperty();
273 Variable* var = e->AsVariableProxy()->AsVariable(); 267 Variable* var = e->AsVariableProxy()->AsVariable();
274 268
275 if (property != NULL) { 269 if (property != NULL) {
276 UNIMPLEMENTED_MIPS(); 270 UNIMPLEMENTED_MIPS();
277 } else if (var != NULL) { 271 } else if (var != NULL) {
278 // The expression is a variable proxy that does not rewrite to a 272 // The expression is a variable proxy that does not rewrite to a
279 // property. Global variables are treated as named property references. 273 // property. Global variables are treated as named property references.
280 if (var->is_global()) { 274 if (var->is_global()) {
281 LoadGlobal(); 275 LoadGlobal();
282 ref->set_type(Reference::NAMED); 276 ref->set_type(Reference::NAMED);
283 } else { 277 } else {
284 ASSERT(var->slot() != NULL); 278 ASSERT(var->slot() != NULL);
285 ref->set_type(Reference::SLOT); 279 ref->set_type(Reference::SLOT);
286 } 280 }
287 } else { 281 } else {
288 UNIMPLEMENTED_MIPS(); 282 UNIMPLEMENTED_MIPS();
283 __ break_(__LINE__);
289 } 284 }
290 } 285 }
291 286
292 287
293 void CodeGenerator::UnloadReference(Reference* ref) { 288 void CodeGenerator::UnloadReference(Reference* ref) {
294 VirtualFrame::SpilledScope spilled_scope; 289 VirtualFrame::SpilledScope spilled_scope;
295 // Pop a reference from the stack while preserving TOS. 290 // Pop a reference from the stack while preserving TOS.
296 Comment cmnt(masm_, "[ UnloadReference"); 291 Comment cmnt(masm_, "[ UnloadReference");
297 int size = ref->size(); 292 int size = ref->size();
298 if (size > 0) { 293 if (size > 0) {
(...skipping 11 matching lines...) Expand all
310 // (such as the variable referring to a named function expression). 305 // (such as the variable referring to a named function expression).
311 // We need to implement assignments to read-only variables. 306 // We need to implement assignments to read-only variables.
312 // Ideally, we should do this during AST generation (by converting 307 // Ideally, we should do this during AST generation (by converting
313 // such assignments into expression statements); however, in general 308 // such assignments into expression statements); however, in general
314 // we may not be able to make the decision until past AST generation, 309 // we may not be able to make the decision until past AST generation,
315 // that is when the entire program is known. 310 // that is when the entire program is known.
316 ASSERT(slot != NULL); 311 ASSERT(slot != NULL);
317 int index = slot->index(); 312 int index = slot->index();
318 switch (slot->type()) { 313 switch (slot->type()) {
319 case Slot::PARAMETER: 314 case Slot::PARAMETER:
320 UNIMPLEMENTED_MIPS(); 315 return frame_->ParameterAt(index);
321 return MemOperand(no_reg, 0);
322
323 case Slot::LOCAL: 316 case Slot::LOCAL:
324 return frame_->LocalAt(index); 317 return frame_->LocalAt(index);
325 318
326 case Slot::CONTEXT: { 319 case Slot::CONTEXT: {
327 UNIMPLEMENTED_MIPS(); 320 UNIMPLEMENTED_MIPS();
328 return MemOperand(no_reg, 0); 321 return MemOperand(no_reg, 0);
329 } 322 }
330 323
331 default: 324 default:
332 UNREACHABLE(); 325 UNREACHABLE();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 void CodeGenerator::Load(Expression* x) { 374 void CodeGenerator::Load(Expression* x) {
382 #ifdef DEBUG 375 #ifdef DEBUG
383 int original_height = frame_->height(); 376 int original_height = frame_->height();
384 #endif 377 #endif
385 JumpTarget true_target; 378 JumpTarget true_target;
386 JumpTarget false_target; 379 JumpTarget false_target;
387 LoadCondition(x, &true_target, &false_target, false); 380 LoadCondition(x, &true_target, &false_target, false);
388 381
389 if (has_cc()) { 382 if (has_cc()) {
390 UNIMPLEMENTED_MIPS(); 383 UNIMPLEMENTED_MIPS();
384 __ break_(__LINE__);
391 } 385 }
392 386
393 if (true_target.is_linked() || false_target.is_linked()) { 387 if (true_target.is_linked() || false_target.is_linked()) {
394 UNIMPLEMENTED_MIPS(); 388 UNIMPLEMENTED_MIPS();
389 __ break_(__LINE__);
395 } 390 }
396 ASSERT(has_valid_frame()); 391 ASSERT(has_valid_frame());
397 ASSERT(!has_cc()); 392 ASSERT(!has_cc());
398 ASSERT(frame_->height() == original_height + 1); 393 ASSERT(frame_->height() == original_height + 1);
399 } 394 }
400 395
401 396
402 void CodeGenerator::LoadGlobal() { 397 void CodeGenerator::LoadGlobal() {
403 VirtualFrame::SpilledScope spilled_scope; 398 VirtualFrame::SpilledScope spilled_scope;
404 __ lw(a0, GlobalObject()); 399 __ lw(a0, GlobalObject());
405 frame_->EmitPush(a0); 400 frame_->EmitPush(a0);
406 } 401 }
407 402
408 403
409 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { 404 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
410 VirtualFrame::SpilledScope spilled_scope; 405 VirtualFrame::SpilledScope spilled_scope;
411 if (slot->type() == Slot::LOOKUP) { 406 if (slot->type() == Slot::LOOKUP) {
412 UNIMPLEMENTED_MIPS(); 407 UNIMPLEMENTED_MIPS();
408 __ break_(__LINE__);
413 } else { 409 } else {
414 __ lw(a0, SlotOperand(slot, a2)); 410 __ lw(v0, SlotOperand(slot, a2));
415 frame_->EmitPush(a0); 411 frame_->EmitPush(v0);
416 if (slot->var()->mode() == Variable::CONST) { 412 if (slot->var()->mode() == Variable::CONST) {
417 UNIMPLEMENTED_MIPS(); 413 UNIMPLEMENTED_MIPS();
414 __ break_(__LINE__);
418 } 415 }
419 } 416 }
420 } 417 }
421 418
422 419
423 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { 420 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
424 ASSERT(slot != NULL); 421 ASSERT(slot != NULL);
425 if (slot->type() == Slot::LOOKUP) { 422 if (slot->type() == Slot::LOOKUP) {
426 UNIMPLEMENTED_MIPS(); 423 UNIMPLEMENTED_MIPS();
424 __ break_(__LINE__);
427 } else { 425 } else {
428 ASSERT(!slot->var()->is_dynamic()); 426 ASSERT(!slot->var()->is_dynamic());
429 427
430 JumpTarget exit; 428 JumpTarget exit;
431 if (init_state == CONST_INIT) { 429 if (init_state == CONST_INIT) {
432 UNIMPLEMENTED_MIPS(); 430 UNIMPLEMENTED_MIPS();
431 __ break_(__LINE__);
433 } 432 }
434 433
435 // We must execute the store. Storing a variable must keep the 434 // We must execute the store. Storing a variable must keep the
436 // (new) value on the stack. This is necessary for compiling 435 // (new) value on the stack. This is necessary for compiling
437 // assignment expressions. 436 // assignment expressions.
438 // 437 //
439 // Note: We will reach here even with slot->var()->mode() == 438 // Note: We will reach here even with slot->var()->mode() ==
440 // Variable::CONST because of const declarations which will 439 // Variable::CONST because of const declarations which will
441 // initialize consts to 'the hole' value and by doing so, end up 440 // initialize consts to 'the hole' value and by doing so, end up
442 // calling this code. a2 may be loaded with context; used below in 441 // calling this code. a2 may be loaded with context; used below in
443 // RecordWrite. 442 // RecordWrite.
444 frame_->EmitPop(a0); 443 frame_->EmitPop(a0);
445 __ sw(a0, SlotOperand(slot, a2)); 444 __ sw(a0, SlotOperand(slot, a2));
446 frame_->EmitPush(a0); 445 frame_->EmitPush(a0);
447 if (slot->type() == Slot::CONTEXT) { 446 if (slot->type() == Slot::CONTEXT) {
448 UNIMPLEMENTED_MIPS(); 447 UNIMPLEMENTED_MIPS();
448 __ break_(__LINE__);
449 } 449 }
450 // If we definitely did not jump over the assignment, we do not need 450 // If we definitely did not jump over the assignment, we do not need
451 // to bind the exit label. Doing so can defeat peephole 451 // to bind the exit label. Doing so can defeat peephole
452 // optimization. 452 // optimization.
453 if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) { 453 if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) {
454 exit.Bind(); 454 exit.Bind();
455 } 455 }
456 } 456 }
457 } 457 }
458 458
459 459
460 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 460 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
461 VirtualFrame::SpilledScope spilled_scope; 461 VirtualFrame::SpilledScope spilled_scope;
462 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 462 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
463 VisitAndSpill(statements->at(i)); 463 VisitAndSpill(statements->at(i));
464 } 464 }
465 } 465 }
466 466
467 467
468 void CodeGenerator::VisitBlock(Block* node) { 468 void CodeGenerator::VisitBlock(Block* node) {
469 UNIMPLEMENTED_MIPS(); 469 #ifdef DEBUG
470 int original_height = frame_->height();
471 #endif
472 VirtualFrame::SpilledScope spilled_scope;
473 Comment cmnt(masm_, "[ Block");
474 CodeForStatementPosition(node);
475 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
476 VisitStatementsAndSpill(node->statements());
477 if (node->break_target()->is_linked()) {
478 node->break_target()->Bind();
479 }
480 node->break_target()->Unuse();
481 ASSERT(!has_valid_frame() || frame_->height() == original_height);
470 } 482 }
471 483
472 484
473 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 485 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
474 VirtualFrame::SpilledScope spilled_scope; 486 VirtualFrame::SpilledScope spilled_scope;
475 frame_->EmitPush(cp); 487 frame_->EmitPush(cp);
476 __ li(t0, Operand(pairs)); 488 __ li(t0, Operand(pairs));
477 frame_->EmitPush(t0); 489 frame_->EmitPush(t0);
478 __ li(t0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); 490 __ li(t0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
479 frame_->EmitPush(t0); 491 frame_->EmitPush(t0);
480 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 492 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
481 // The result is discarded. 493 // The result is discarded.
482 } 494 }
483 495
484 496
485 void CodeGenerator::VisitDeclaration(Declaration* node) { 497 void CodeGenerator::VisitDeclaration(Declaration* node) {
486 UNIMPLEMENTED_MIPS(); 498 #ifdef DEBUG
499 int original_height = frame_->height();
500 #endif
501 VirtualFrame::SpilledScope spilled_scope;
502 Comment cmnt(masm_, "[ Declaration");
503 Variable* var = node->proxy()->var();
504 ASSERT(var != NULL); // Must have been resolved.
505 Slot* slot = var->slot();
506
507 // If it was not possible to allocate the variable at compile time,
508 // we need to "declare" it at runtime to make sure it actually
509 // exists in the local context.
510 if (slot != NULL && slot->type() == Slot::LOOKUP) {
511 UNIMPLEMENTED_MIPS();
512 __ break_(__LINE__);
513 return;
514 }
515
516 ASSERT(!var->is_global());
517
518 // If we have a function or a constant, we need to initialize the variable.
519 Expression* val = NULL;
520 if (node->mode() == Variable::CONST) {
521 UNIMPLEMENTED_MIPS();
522 __ break_(__LINE__);
523 } else {
524 val = node->fun(); // NULL if we don't have a function.
525 }
526
527 if (val != NULL) {
528 {
529 // Set initial value.
530 Reference target(this, node->proxy());
531 LoadAndSpill(val);
532 target.SetValue(NOT_CONST_INIT);
533 // The reference is removed from the stack (preserving TOS) when
534 // it goes out of scope.
535 }
536 // Get rid of the assigned value (declarations are statements).
537 frame_->Drop();
538 }
539 ASSERT(frame_->height() == original_height);
487 } 540 }
488 541
489 542
490 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 543 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
491 #ifdef DEBUG 544 #ifdef DEBUG
492 int original_height = frame_->height(); 545 int original_height = frame_->height();
493 #endif 546 #endif
494 VirtualFrame::SpilledScope spilled_scope; 547 VirtualFrame::SpilledScope spilled_scope;
495 Comment cmnt(masm_, "[ ExpressionStatement"); 548 Comment cmnt(masm_, "[ ExpressionStatement");
496 CodeForStatementPosition(node); 549 CodeForStatementPosition(node);
497 Expression* expression = node->expression(); 550 Expression* expression = node->expression();
498 expression->MarkAsStatement(); 551 expression->MarkAsStatement();
499 LoadAndSpill(expression); 552 LoadAndSpill(expression);
500 frame_->Drop(); 553 frame_->Drop();
501 ASSERT(frame_->height() == original_height); 554 ASSERT(frame_->height() == original_height);
502 } 555 }
503 556
504 557
505 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 558 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
506 UNIMPLEMENTED_MIPS(); 559 UNIMPLEMENTED_MIPS();
560 __ break_(__LINE__);
507 } 561 }
508 562
509 563
510 void CodeGenerator::VisitIfStatement(IfStatement* node) { 564 void CodeGenerator::VisitIfStatement(IfStatement* node) {
511 UNIMPLEMENTED_MIPS(); 565 UNIMPLEMENTED_MIPS();
566 __ break_(__LINE__);
512 } 567 }
513 568
514 569
515 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 570 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
516 UNIMPLEMENTED_MIPS(); 571 UNIMPLEMENTED_MIPS();
572 __ break_(__LINE__);
517 } 573 }
518 574
519 575
520 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 576 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
521 UNIMPLEMENTED_MIPS(); 577 UNIMPLEMENTED_MIPS();
578 __ break_(__LINE__);
522 } 579 }
523 580
524 581
525 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 582 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
526 VirtualFrame::SpilledScope spilled_scope; 583 VirtualFrame::SpilledScope spilled_scope;
527 Comment cmnt(masm_, "[ ReturnStatement"); 584 Comment cmnt(masm_, "[ ReturnStatement");
528 585
529 CodeForStatementPosition(node); 586 CodeForStatementPosition(node);
530 LoadAndSpill(node->expression()); 587 LoadAndSpill(node->expression());
531 if (function_return_is_shadowed_) { 588 if (function_return_is_shadowed_) {
532 frame_->EmitPop(v0); 589 frame_->EmitPop(v0);
533 function_return_.Jump(); 590 function_return_.Jump();
534 } else { 591 } else {
535 // Pop the result from the frame and prepare the frame for 592 // Pop the result from the frame and prepare the frame for
536 // returning thus making it easier to merge. 593 // returning thus making it easier to merge.
537 frame_->EmitPop(v0); 594 frame_->EmitPop(v0);
538 frame_->PrepareForReturn(); 595 frame_->PrepareForReturn();
539 596
540 function_return_.Jump(); 597 function_return_.Jump();
541 } 598 }
542 } 599 }
543 600
544 601
545 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 602 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
546 UNIMPLEMENTED_MIPS(); 603 UNIMPLEMENTED_MIPS();
604 __ break_(__LINE__);
547 } 605 }
548 606
549 607
550 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 608 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
551 UNIMPLEMENTED_MIPS(); 609 UNIMPLEMENTED_MIPS();
610 __ break_(__LINE__);
552 } 611 }
553 612
554 613
555 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 614 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
556 UNIMPLEMENTED_MIPS(); 615 UNIMPLEMENTED_MIPS();
616 __ break_(__LINE__);
557 } 617 }
558 618
559 619
560 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { 620 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
561 UNIMPLEMENTED_MIPS(); 621 UNIMPLEMENTED_MIPS();
622 __ break_(__LINE__);
562 } 623 }
563 624
564 625
565 void CodeGenerator::VisitWhileStatement(WhileStatement* node) { 626 void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
566 UNIMPLEMENTED_MIPS(); 627 UNIMPLEMENTED_MIPS();
628 __ break_(__LINE__);
567 } 629 }
568 630
569 631
570 void CodeGenerator::VisitForStatement(ForStatement* node) { 632 void CodeGenerator::VisitForStatement(ForStatement* node) {
571 UNIMPLEMENTED_MIPS(); 633 UNIMPLEMENTED_MIPS();
634 __ break_(__LINE__);
572 } 635 }
573 636
574 637
575 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 638 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
576 UNIMPLEMENTED_MIPS(); 639 UNIMPLEMENTED_MIPS();
640 __ break_(__LINE__);
577 } 641 }
578 642
579 643
580 void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) { 644 void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
581 UNIMPLEMENTED_MIPS(); 645 UNIMPLEMENTED_MIPS();
646 __ break_(__LINE__);
582 } 647 }
583 648
584 649
585 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) { 650 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
586 UNIMPLEMENTED_MIPS(); 651 UNIMPLEMENTED_MIPS();
652 __ break_(__LINE__);
587 } 653 }
588 654
589 655
590 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 656 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
591 UNIMPLEMENTED_MIPS(); 657 UNIMPLEMENTED_MIPS();
658 __ break_(__LINE__);
592 } 659 }
593 660
594 661
595 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 662 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
596 UNIMPLEMENTED_MIPS(); 663 UNIMPLEMENTED_MIPS();
664 __ break_(__LINE__);
597 } 665 }
598 666
599 667
600 void CodeGenerator::VisitSharedFunctionInfoLiteral( 668 void CodeGenerator::VisitSharedFunctionInfoLiteral(
601 SharedFunctionInfoLiteral* node) { 669 SharedFunctionInfoLiteral* node) {
602 UNIMPLEMENTED_MIPS(); 670 UNIMPLEMENTED_MIPS();
671 __ break_(__LINE__);
603 } 672 }
604 673
605 674
606 void CodeGenerator::VisitConditional(Conditional* node) { 675 void CodeGenerator::VisitConditional(Conditional* node) {
607 UNIMPLEMENTED_MIPS(); 676 UNIMPLEMENTED_MIPS();
677 __ break_(__LINE__);
608 } 678 }
609 679
610 680
611 void CodeGenerator::VisitSlot(Slot* node) { 681 void CodeGenerator::VisitSlot(Slot* node) {
612 #ifdef DEBUG 682 #ifdef DEBUG
613 int original_height = frame_->height(); 683 int original_height = frame_->height();
614 #endif 684 #endif
615 VirtualFrame::SpilledScope spilled_scope; 685 VirtualFrame::SpilledScope spilled_scope;
616 Comment cmnt(masm_, "[ Slot"); 686 Comment cmnt(masm_, "[ Slot");
617 LoadFromSlot(node, typeof_state()); 687 LoadFromSlot(node, typeof_state());
(...skipping 28 matching lines...) Expand all
646 VirtualFrame::SpilledScope spilled_scope; 716 VirtualFrame::SpilledScope spilled_scope;
647 Comment cmnt(masm_, "[ Literal"); 717 Comment cmnt(masm_, "[ Literal");
648 __ li(t0, Operand(node->handle())); 718 __ li(t0, Operand(node->handle()));
649 frame_->EmitPush(t0); 719 frame_->EmitPush(t0);
650 ASSERT(frame_->height() == original_height + 1); 720 ASSERT(frame_->height() == original_height + 1);
651 } 721 }
652 722
653 723
654 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 724 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
655 UNIMPLEMENTED_MIPS(); 725 UNIMPLEMENTED_MIPS();
726 __ break_(__LINE__);
656 } 727 }
657 728
658 729
659 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 730 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
660 UNIMPLEMENTED_MIPS(); 731 UNIMPLEMENTED_MIPS();
732 __ break_(__LINE__);
661 } 733 }
662 734
663 735
664 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 736 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
665 UNIMPLEMENTED_MIPS(); 737 UNIMPLEMENTED_MIPS();
738 __ break_(__LINE__);
666 } 739 }
667 740
668 741
669 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 742 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
670 UNIMPLEMENTED_MIPS(); 743 UNIMPLEMENTED_MIPS();
744 __ break_(__LINE__);
671 } 745 }
672 746
673 747
674 void CodeGenerator::VisitAssignment(Assignment* node) { 748 void CodeGenerator::VisitAssignment(Assignment* node) {
675 #ifdef DEBUG 749 #ifdef DEBUG
676 int original_height = frame_->height(); 750 int original_height = frame_->height();
677 #endif 751 #endif
678 VirtualFrame::SpilledScope spilled_scope; 752 VirtualFrame::SpilledScope spilled_scope;
679 Comment cmnt(masm_, "[ Assignment"); 753 Comment cmnt(masm_, "[ Assignment");
680 754
681 { Reference target(this, node->target()); 755 { Reference target(this, node->target(), node->is_compound());
682 if (target.is_illegal()) { 756 if (target.is_illegal()) {
683 // Fool the virtual frame into thinking that we left the assignment's 757 // Fool the virtual frame into thinking that we left the assignment's
684 // value on the frame. 758 // value on the frame.
685 frame_->EmitPush(zero_reg); 759 frame_->EmitPush(zero_reg);
686 ASSERT(frame_->height() == original_height + 1); 760 ASSERT(frame_->height() == original_height + 1);
687 return; 761 return;
688 } 762 }
689 763
690 if (node->op() == Token::ASSIGN || 764 if (node->op() == Token::ASSIGN ||
691 node->op() == Token::INIT_VAR || 765 node->op() == Token::INIT_VAR ||
692 node->op() == Token::INIT_CONST) { 766 node->op() == Token::INIT_CONST) {
693 LoadAndSpill(node->value()); 767 LoadAndSpill(node->value());
694 } else { 768 } else {
695 UNIMPLEMENTED_MIPS(); 769 UNIMPLEMENTED_MIPS();
770 __ break_(__LINE__);
696 } 771 }
697 772
698 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 773 Variable* var = node->target()->AsVariableProxy()->AsVariable();
699 if (var != NULL && 774 if (var != NULL &&
700 (var->mode() == Variable::CONST) && 775 (var->mode() == Variable::CONST) &&
701 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 776 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
702 // Assignment ignored - leave the value on the stack. 777 // Assignment ignored - leave the value on the stack.
703 } else { 778 } else {
704 CodeForSourcePosition(node->position()); 779 CodeForSourcePosition(node->position());
705 if (node->op() == Token::INIT_CONST) { 780 if (node->op() == Token::INIT_CONST) {
706 // Dynamic constant initializations must use the function context 781 // Dynamic constant initializations must use the function context
707 // and initialize the actual constant declared. Dynamic variable 782 // and initialize the actual constant declared. Dynamic variable
708 // initializations are simply assignments and use SetValue. 783 // initializations are simply assignments and use SetValue.
709 target.SetValue(CONST_INIT); 784 target.SetValue(CONST_INIT);
710 } else { 785 } else {
711 target.SetValue(NOT_CONST_INIT); 786 target.SetValue(NOT_CONST_INIT);
712 } 787 }
713 } 788 }
714 } 789 }
715 ASSERT(frame_->height() == original_height + 1); 790 ASSERT(frame_->height() == original_height + 1);
716 } 791 }
717 792
718 793
719 void CodeGenerator::VisitThrow(Throw* node) { 794 void CodeGenerator::VisitThrow(Throw* node) {
720 UNIMPLEMENTED_MIPS(); 795 UNIMPLEMENTED_MIPS();
796 __ break_(__LINE__);
721 } 797 }
722 798
723 799
724 void CodeGenerator::VisitProperty(Property* node) { 800 void CodeGenerator::VisitProperty(Property* node) {
725 UNIMPLEMENTED_MIPS(); 801 UNIMPLEMENTED_MIPS();
802 __ break_(__LINE__);
726 } 803 }
727 804
728 805
729 void CodeGenerator::VisitCall(Call* node) { 806 void CodeGenerator::VisitCall(Call* node) {
730 #ifdef DEBUG 807 #ifdef DEBUG
731 int original_height = frame_->height(); 808 int original_height = frame_->height();
732 #endif 809 #endif
733 VirtualFrame::SpilledScope spilled_scope; 810 VirtualFrame::SpilledScope spilled_scope;
734 Comment cmnt(masm_, "[ Call"); 811 Comment cmnt(masm_, "[ Call");
735 812
736 Expression* function = node->expression(); 813 Expression* function = node->expression();
737 ZoneList<Expression*>* args = node->arguments(); 814 ZoneList<Expression*>* args = node->arguments();
738 815
739 // Standard function call. 816 // Standard function call.
740 // Check if the function is a variable or a property. 817 // Check if the function is a variable or a property.
741 Variable* var = function->AsVariableProxy()->AsVariable(); 818 Variable* var = function->AsVariableProxy()->AsVariable();
742 Property* property = function->AsProperty(); 819 Property* property = function->AsProperty();
743 820
744 // ------------------------------------------------------------------------ 821 // ------------------------------------------------------------------------
745 // Fast-case: Use inline caching. 822 // Fast-case: Use inline caching.
746 // --- 823 // ---
747 // According to ECMA-262, section 11.2.3, page 44, the function to call 824 // According to ECMA-262, section 11.2.3, page 44, the function to call
748 // must be resolved after the arguments have been evaluated. The IC code 825 // must be resolved after the arguments have been evaluated. The IC code
749 // automatically handles this by loading the arguments before the function 826 // automatically handles this by loading the arguments before the function
750 // is resolved in cache misses (this also holds for megamorphic calls). 827 // is resolved in cache misses (this also holds for megamorphic calls).
751 // ------------------------------------------------------------------------ 828 // ------------------------------------------------------------------------
752 829
753 if (var != NULL && var->is_possibly_eval()) { 830 if (var != NULL && var->is_possibly_eval()) {
754 UNIMPLEMENTED_MIPS(); 831 UNIMPLEMENTED_MIPS();
832 __ break_(__LINE__);
755 } else if (var != NULL && !var->is_this() && var->is_global()) { 833 } else if (var != NULL && !var->is_this() && var->is_global()) {
756 // ---------------------------------- 834 // -----------------------------------------------------
757 // JavaScript example: 'foo(1, 2, 3)' // foo is global 835 // JavaScript example: 'foo(1, 2, 3)' // foo is global.
758 // ---------------------------------- 836 // -----------------------------------------------------
759
760 int arg_count = args->length();
761
762 // We need sp to be 8 bytes aligned when calling the stub.
763 __ SetupAlignedCall(t0, arg_count);
764 837
765 // Pass the global object as the receiver and let the IC stub 838 // Pass the global object as the receiver and let the IC stub
766 // patch the stack to use the global proxy as 'this' in the 839 // patch the stack to use the global proxy as 'this' in the
767 // invoked function. 840 // invoked function.
768 LoadGlobal(); 841 LoadGlobal();
769 842
770 // Load the arguments. 843 // Load the arguments.
844 int arg_count = args->length();
771 for (int i = 0; i < arg_count; i++) { 845 for (int i = 0; i < arg_count; i++) {
772 LoadAndSpill(args->at(i)); 846 LoadAndSpill(args->at(i));
773 } 847 }
774 848
775 // Setup the receiver register and call the IC initialization code. 849 // Setup the receiver register and call the IC initialization code.
776 __ li(a2, Operand(var->name())); 850 __ li(a2, Operand(var->name()));
777 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 851 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
778 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 852 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
779 CodeForSourcePosition(node->position()); 853 CodeForSourcePosition(node->position());
780 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 854 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
781 arg_count + 1); 855 arg_count + 1);
782 __ ReturnFromAlignedCall();
783 __ lw(cp, frame_->Context()); 856 __ lw(cp, frame_->Context());
784 // Remove the function from the stack. 857 // Remove the function from the stack.
785 frame_->EmitPush(v0); 858 frame_->EmitPush(v0);
786 859
787 } else if (var != NULL && var->slot() != NULL && 860 } else if (var != NULL && var->slot() != NULL &&
788 var->slot()->type() == Slot::LOOKUP) { 861 var->slot()->type() == Slot::LOOKUP) {
789 UNIMPLEMENTED_MIPS(); 862 UNIMPLEMENTED_MIPS();
790 } else if (property != NULL) { 863 } else if (property != NULL) {
791 UNIMPLEMENTED_MIPS(); 864 UNIMPLEMENTED_MIPS();
865 __ break_(__LINE__);
792 } else { 866 } else {
793 UNIMPLEMENTED_MIPS(); 867 UNIMPLEMENTED_MIPS();
868 __ break_(__LINE__);
794 } 869 }
795 870
796 ASSERT(frame_->height() == original_height + 1); 871 ASSERT(frame_->height() == original_height + 1);
797 } 872 }
798 873
799 874
800 void CodeGenerator::VisitCallNew(CallNew* node) { 875 void CodeGenerator::VisitCallNew(CallNew* node) {
801 UNIMPLEMENTED_MIPS(); 876 UNIMPLEMENTED_MIPS();
877 __ break_(__LINE__);
802 } 878 }
803 879
804 880
805 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 881 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
806 UNIMPLEMENTED_MIPS(); 882 UNIMPLEMENTED_MIPS();
883 __ break_(__LINE__);
807 } 884 }
808 885
809 886
810 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { 887 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
811 UNIMPLEMENTED_MIPS(); 888 UNIMPLEMENTED_MIPS();
889 __ break_(__LINE__);
812 } 890 }
813 891
814 892
815 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { 893 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
816 UNIMPLEMENTED_MIPS(); 894 UNIMPLEMENTED_MIPS();
895 __ break_(__LINE__);
817 } 896 }
818 897
819 898
820 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { 899 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
821 UNIMPLEMENTED_MIPS(); 900 UNIMPLEMENTED_MIPS();
901 __ break_(__LINE__);
822 } 902 }
823 903
824 904
825 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { 905 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
826 UNIMPLEMENTED_MIPS(); 906 UNIMPLEMENTED_MIPS();
907 __ break_(__LINE__);
827 } 908 }
828 909
829 910
830 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 911 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
831 UNIMPLEMENTED_MIPS(); 912 UNIMPLEMENTED_MIPS();
913 __ break_(__LINE__);
832 } 914 }
833 915
834 916
835 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { 917 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
836 UNIMPLEMENTED_MIPS(); 918 UNIMPLEMENTED_MIPS();
919 __ break_(__LINE__);
837 } 920 }
838 921
839 922
840 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { 923 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
841 UNIMPLEMENTED_MIPS(); 924 UNIMPLEMENTED_MIPS();
925 __ break_(__LINE__);
842 } 926 }
843 927
844 928
845 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { 929 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
846 UNIMPLEMENTED_MIPS(); 930 UNIMPLEMENTED_MIPS();
931 __ break_(__LINE__);
847 } 932 }
848 933
849 934
850 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { 935 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
851 UNIMPLEMENTED_MIPS(); 936 UNIMPLEMENTED_MIPS();
852 } 937 __ break_(__LINE__);
853 938 }
854 939
855 // This should generate code that performs a charCodeAt() call or returns 940
856 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
857 // It is not yet implemented on ARM, so it always goes to the slow case.
858 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 941 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
859 UNIMPLEMENTED_MIPS(); 942 UNIMPLEMENTED_MIPS();
943 __ break_(__LINE__);
860 } 944 }
861 945
862 946
863 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) { 947 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
864 UNIMPLEMENTED_MIPS(); 948 UNIMPLEMENTED_MIPS();
949 __ break_(__LINE__);
865 } 950 }
866 951
867 952
868 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { 953 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
869 UNIMPLEMENTED_MIPS(); 954 UNIMPLEMENTED_MIPS();
955 __ break_(__LINE__);
870 } 956 }
871 957
872 958
873 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) { 959 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
874 UNIMPLEMENTED_MIPS(); 960 UNIMPLEMENTED_MIPS();
961 __ break_(__LINE__);
875 } 962 }
876 963
877 964
878 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) { 965 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
879 UNIMPLEMENTED_MIPS(); 966 UNIMPLEMENTED_MIPS();
967 __ break_(__LINE__);
880 } 968 }
881 969
882 970
883 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 971 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
884 UNIMPLEMENTED_MIPS(); 972 UNIMPLEMENTED_MIPS();
973 __ break_(__LINE__);
885 } 974 }
886 975
887 976
888 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { 977 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
889 UNIMPLEMENTED_MIPS(); 978 UNIMPLEMENTED_MIPS();
979 __ break_(__LINE__);
890 } 980 }
891 981
892 982
893 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) { 983 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
894 UNIMPLEMENTED_MIPS(); 984 UNIMPLEMENTED_MIPS();
985 __ break_(__LINE__);
895 } 986 }
896 987
897 988
898 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 989 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
899 UNIMPLEMENTED_MIPS(); 990 UNIMPLEMENTED_MIPS();
991 __ break_(__LINE__);
900 } 992 }
901 993
902 994
903 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) { 995 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
904 UNIMPLEMENTED_MIPS(); 996 UNIMPLEMENTED_MIPS();
997 __ break_(__LINE__);
905 } 998 }
906 999
907 1000
908 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) { 1001 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
909 UNIMPLEMENTED_MIPS(); 1002 UNIMPLEMENTED_MIPS();
1003 __ break_(__LINE__);
910 } 1004 }
911 1005
912 1006
913 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) { 1007 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
914 UNIMPLEMENTED_MIPS(); 1008 UNIMPLEMENTED_MIPS();
1009 __ break_(__LINE__);
915 } 1010 }
916 1011
917 1012
918 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) { 1013 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
919 UNIMPLEMENTED_MIPS(); 1014 UNIMPLEMENTED_MIPS();
1015 __ break_(__LINE__);
920 } 1016 }
921 1017
922 1018
923 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) { 1019 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
924 UNIMPLEMENTED_MIPS(); 1020 UNIMPLEMENTED_MIPS();
1021 __ break_(__LINE__);
925 } 1022 }
926 1023
927 1024
928 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) { 1025 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
929 UNIMPLEMENTED_MIPS(); 1026 UNIMPLEMENTED_MIPS();
1027 __ break_(__LINE__);
930 } 1028 }
931 1029
932 1030
933 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { 1031 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
934 UNIMPLEMENTED_MIPS(); 1032 UNIMPLEMENTED_MIPS();
1033 __ break_(__LINE__);
935 } 1034 }
936 1035
937 1036
938 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { 1037 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
939 UNIMPLEMENTED_MIPS(); 1038 UNIMPLEMENTED_MIPS();
1039 __ break_(__LINE__);
940 } 1040 }
941 1041
942 1042
943 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 1043 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
944 UNIMPLEMENTED_MIPS(); 1044 UNIMPLEMENTED_MIPS();
1045 __ break_(__LINE__);
945 } 1046 }
946 1047
947 1048
948 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { 1049 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
949 UNIMPLEMENTED_MIPS(); 1050 UNIMPLEMENTED_MIPS();
1051 __ break_(__LINE__);
950 } 1052 }
951 1053
952 1054
953 void CodeGenerator::VisitCountOperation(CountOperation* node) { 1055 void CodeGenerator::VisitCountOperation(CountOperation* node) {
954 UNIMPLEMENTED_MIPS(); 1056 UNIMPLEMENTED_MIPS();
1057 __ break_(__LINE__);
955 } 1058 }
956 1059
957 1060
958 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 1061 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
959 UNIMPLEMENTED_MIPS(); 1062 UNIMPLEMENTED_MIPS();
960 } 1063 __ break_(__LINE__);
961 1064 }
962 1065
963 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 1066 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
964 UNIMPLEMENTED_MIPS(); 1067 UNIMPLEMENTED_MIPS();
1068 __ break_(__LINE__);
965 } 1069 }
966 1070
967 1071
968 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 1072 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
969 UNIMPLEMENTED_MIPS(); 1073 UNIMPLEMENTED_MIPS();
970 } 1074 __ break_(__LINE__);
971 1075 }
972 1076
1077
973 #ifdef DEBUG 1078 #ifdef DEBUG
974 bool CodeGenerator::HasValidEntryRegisters() { return true; } 1079 bool CodeGenerator::HasValidEntryRegisters() { return true; }
975 #endif 1080 #endif
976 1081
977 1082
978 #undef __ 1083 #undef __
979 #define __ ACCESS_MASM(masm) 1084 #define __ ACCESS_MASM(masm)
980 1085
981 // ----------------------------------------------------------------------------- 1086 // -----------------------------------------------------------------------------
982 // Reference support 1087 // Reference support.
983 1088
984 Reference::Reference(CodeGenerator* cgen, 1089 Reference::Reference(CodeGenerator* cgen,
985 Expression* expression, 1090 Expression* expression,
986 bool persist_after_get) 1091 bool persist_after_get)
987 : cgen_(cgen), 1092 : cgen_(cgen),
988 expression_(expression), 1093 expression_(expression),
989 type_(ILLEGAL), 1094 type_(ILLEGAL),
990 persist_after_get_(persist_after_get) { 1095 persist_after_get_(persist_after_get) {
991 cgen->LoadReference(this); 1096 cgen->LoadReference(this);
992 } 1097 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 UNIMPLEMENTED_MIPS(); 1177 UNIMPLEMENTED_MIPS();
1073 break; 1178 break;
1074 } 1179 }
1075 1180
1076 default: 1181 default:
1077 UNREACHABLE(); 1182 UNREACHABLE();
1078 } 1183 }
1079 } 1184 }
1080 1185
1081 1186
1082 // On entry a0 and a1 are the things to be compared. On exit v0 is 0,
1083 // positive or negative to indicate the result of the comparison.
1084 void CompareStub::Generate(MacroAssembler* masm) { 1187 void CompareStub::Generate(MacroAssembler* masm) {
1085 UNIMPLEMENTED_MIPS(); 1188 UNIMPLEMENTED_MIPS();
1086 __ break_(0x765); 1189 __ break_(__LINE__);
1087 } 1190 }
1088 1191
1089 1192
1090 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { 1193 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
1091 UNIMPLEMENTED_MIPS(); 1194 UNIMPLEMENTED_MIPS();
1092 return Handle<Code>::null(); 1195 return Handle<Code>::null();
1093 } 1196 }
1094 1197
1095 1198
1096 void StackCheckStub::Generate(MacroAssembler* masm) { 1199 void StackCheckStub::Generate(MacroAssembler* masm) {
1097 UNIMPLEMENTED_MIPS(); 1200 UNIMPLEMENTED_MIPS();
1098 __ break_(0x790); 1201 __ break_(__LINE__);
1202 }
1203
1204
1205 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
1206 UNIMPLEMENTED_MIPS();
1207 __ break_(__LINE__);
1099 } 1208 }
1100 1209
1101 1210
1102 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 1211 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
1103 UNIMPLEMENTED_MIPS(); 1212 // v0 holds the exception.
1104 __ break_(0x808); 1213
1214 // Adjust this code if not the case.
1215 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
1216
1217 // Drop the sp to the top of the handler.
1218 __ li(a3, Operand(ExternalReference(Top::k_handler_address)));
1219 __ lw(sp, MemOperand(a3));
1220
1221 // Restore the next handler and frame pointer, discard handler state.
1222 ASSERT(StackHandlerConstants::kNextOffset == 0);
1223 __ Pop(a2);
1224 __ sw(a2, MemOperand(a3));
1225 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
1226 __ MultiPop(a3.bit() | fp.bit());
1227
1228 // Before returning we restore the context from the frame pointer if
1229 // not NULL. The frame pointer is NULL in the exception handler of a
1230 // JS entry frame.
1231 // Set cp to NULL if fp is NULL.
1232 Label done;
1233 __ Branch(false, &done, eq, fp, Operand(zero_reg));
1234 __ mov(cp, zero_reg); // Use the branch delay slot.
1235 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1236 __ bind(&done);
1237
1238 #ifdef DEBUG
1239 // TODO(MIPS): Implement debug code.
1240 #endif
1241
1242 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
1243 __ Pop(t9);
1244 __ Jump(t9);
1105 } 1245 }
1106 1246
1107 1247
1108 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, 1248 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
1109 UncatchableExceptionType type) { 1249 UncatchableExceptionType type) {
1110 UNIMPLEMENTED_MIPS(); 1250 UNIMPLEMENTED_MIPS();
1111 __ break_(0x815); 1251 __ break_(__LINE__);
1112 } 1252 }
1113 1253
1114 void CEntryStub::GenerateCore(MacroAssembler* masm, 1254 void CEntryStub::GenerateCore(MacroAssembler* masm,
1115 Label* throw_normal_exception, 1255 Label* throw_normal_exception,
1116 Label* throw_termination_exception, 1256 Label* throw_termination_exception,
1117 Label* throw_out_of_memory_exception, 1257 Label* throw_out_of_memory_exception,
1118 bool do_gc, 1258 bool do_gc,
1119 bool always_allocate) { 1259 bool always_allocate) {
1260 // v0: result parameter for PerformGC, if any
1120 // s0: number of arguments including receiver (C callee-saved) 1261 // s0: number of arguments including receiver (C callee-saved)
1121 // s1: pointer to the first argument (C callee-saved) 1262 // s1: pointer to the first argument (C callee-saved)
1122 // s2: pointer to builtin function (C callee-saved) 1263 // s2: pointer to builtin function (C callee-saved)
1123 1264
1124 if (do_gc) { 1265 if (do_gc) {
1125 UNIMPLEMENTED_MIPS(); 1266 UNIMPLEMENTED_MIPS();
1267 __ break_(__LINE__);
1126 } 1268 }
1127 1269
1128 ExternalReference scope_depth = 1270 ExternalReference scope_depth =
1129 ExternalReference::heap_always_allocate_scope_depth(); 1271 ExternalReference::heap_always_allocate_scope_depth();
1130 if (always_allocate) { 1272 if (always_allocate) {
1131 UNIMPLEMENTED_MIPS(); 1273 UNIMPLEMENTED_MIPS();
1274 __ break_(__LINE__);
1132 } 1275 }
1133 1276
1134 // Call C built-in. 1277 // Call C built-in.
1135 // a0 = argc, a1 = argv 1278 // a0 = argc, a1 = argv
1136 __ mov(a0, s0); 1279 __ mov(a0, s0);
1137 __ mov(a1, s1); 1280 __ mov(a1, s1);
1138 1281
1139 __ CallBuiltin(s2); 1282 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
1283 // also need the argument slots.
1284 __ jalr(s2);
1285 __ 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
1286 __ addiu(sp, sp, StandardFrameConstants::kCArgsSlotsSize);
1140 1287
1141 if (always_allocate) { 1288 if (always_allocate) {
1142 UNIMPLEMENTED_MIPS(); 1289 UNIMPLEMENTED_MIPS();
1290 __ break_(__LINE__);
1143 } 1291 }
1144 1292
1145 // Check for failure result. 1293 // Check for failure result.
1146 Label failure_returned; 1294 Label failure_returned;
1147 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 1295 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
1148 __ addiu(a2, v0, 1); 1296 __ addiu(a2, v0, 1);
1149 __ andi(t0, a2, kFailureTagMask); 1297 __ andi(t0, a2, kFailureTagMask);
1150 __ Branch(eq, &failure_returned, t0, Operand(zero_reg)); 1298 __ Branch(&failure_returned, eq, t0, Operand(zero_reg));
1151 1299
1152 // Exit C frame and return. 1300 // Exit C frame and return.
1153 // v0:v1: result 1301 // v0:v1: result
1154 // sp: stack pointer 1302 // sp: stack pointer
1155 // fp: frame pointer 1303 // fp: frame pointer
1156 __ LeaveExitFrame(mode_); 1304 __ LeaveExitFrame(mode_);
1157 1305
1158 // Check if we should retry or throw exception. 1306 // Check if we should retry or throw exception.
1159 Label retry; 1307 Label retry;
1160 __ bind(&failure_returned); 1308 __ bind(&failure_returned);
1161 ASSERT(Failure::RETRY_AFTER_GC == 0); 1309 ASSERT(Failure::RETRY_AFTER_GC == 0);
1162 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize); 1310 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize);
1163 __ Branch(eq, &retry, t0, Operand(zero_reg)); 1311 __ Branch(&retry, eq, t0, Operand(zero_reg));
1164 1312
1165 // Special handling of out of memory exceptions. 1313 // Special handling of out of memory exceptions.
1166 Failure* out_of_memory = Failure::OutOfMemoryException(); 1314 Failure* out_of_memory = Failure::OutOfMemoryException();
1167 __ Branch(eq, throw_out_of_memory_exception, 1315 __ Branch(throw_out_of_memory_exception, eq,
1168 v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); 1316 v0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
1169 1317
1170 // Retrieve the pending exception and clear the variable. 1318 // Retrieve the pending exception and clear the variable.
1171 __ LoadExternalReference(t0, ExternalReference::the_hole_value_location()); 1319 __ LoadExternalReference(t0, ExternalReference::the_hole_value_location());
1172 __ lw(a3, MemOperand(t0)); 1320 __ lw(a3, MemOperand(t0));
1173 __ LoadExternalReference(t0, 1321 __ LoadExternalReference(t0,
1174 ExternalReference(Top::k_pending_exception_address)); 1322 ExternalReference(Top::k_pending_exception_address));
1175 __ lw(v0, MemOperand(t0)); 1323 __ lw(v0, MemOperand(t0));
1176 __ sw(a3, MemOperand(t0)); 1324 __ sw(a3, MemOperand(t0));
1177 1325
1178 // Special handling of termination exceptions which are uncatchable 1326 // Special handling of termination exceptions which are uncatchable
1179 // by javascript code. 1327 // by javascript code.
1180 __ Branch(eq, throw_termination_exception, 1328 __ Branch(throw_termination_exception, eq,
1181 v0, Operand(Factory::termination_exception())); 1329 v0, Operand(Factory::termination_exception()));
1182 1330
1183 // Handle normal exception. 1331 // Handle normal exception.
1184 __ b(throw_normal_exception); 1332 __ jmp(throw_normal_exception);
1185 __ nop(); // Branch delay slot nop.
1186 1333
1187 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying 1334 __ bind(&retry);
1335 // Last failure (v0) will be moved to (a0) for parameter when retrying.
1188 } 1336 }
1189 1337
1190 void CEntryStub::Generate(MacroAssembler* masm) { 1338 void CEntryStub::Generate(MacroAssembler* masm) {
1191 // Called from JavaScript; parameters are on stack as if calling JS function 1339 // Called from JavaScript; parameters are on stack as if calling JS function
1192 // a0: number of arguments including receiver 1340 // a0: number of arguments including receiver
1193 // a1: pointer to builtin function 1341 // a1: pointer to builtin function
1194 // fp: frame pointer (restored after C call) 1342 // fp: frame pointer (restored after C call)
1195 // sp: stack pointer (restored as callee's sp after C call) 1343 // sp: stack pointer (restored as callee's sp after C call)
1196 // cp: current context (C callee-saved) 1344 // cp: current context (C callee-saved)
1197 1345
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 // a2: reveiver 1404 // a2: reveiver
1257 // a3: argc 1405 // a3: argc
1258 // 1406 //
1259 // Stack: 1407 // Stack:
1260 // 4 args slots 1408 // 4 args slots
1261 // args 1409 // args
1262 1410
1263 // Save callee saved registers on the stack. 1411 // Save callee saved registers on the stack.
1264 __ MultiPush((kCalleeSaved | ra.bit()) & ~sp.bit()); 1412 __ MultiPush((kCalleeSaved | ra.bit()) & ~sp.bit());
1265 1413
1414 // Load argv in s0 register.
1415 __ lw(s0, MemOperand(sp, kNumCalleeSaved * kPointerSize +
1416 StandardFrameConstants::kCArgsSlotsSize));
1417
1266 // We build an EntryFrame. 1418 // We build an EntryFrame.
1267 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. 1419 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used.
1268 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 1420 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
1269 __ li(t2, Operand(Smi::FromInt(marker))); 1421 __ li(t2, Operand(Smi::FromInt(marker)));
1270 __ li(t1, Operand(Smi::FromInt(marker))); 1422 __ li(t1, Operand(Smi::FromInt(marker)));
1271 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address)); 1423 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address));
1272 __ lw(t0, MemOperand(t0)); 1424 __ lw(t0, MemOperand(t0));
1273 __ MultiPush(t0.bit() | t1.bit() | t2.bit() | t3.bit()); 1425 __ MultiPush(t0.bit() | t1.bit() | t2.bit() | t3.bit());
1274 1426
1275 // Setup frame pointer for the frame to be pushed. 1427 // Setup frame pointer for the frame to be pushed.
1276 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset); 1428 __ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
1277 1429
1278 // Load argv in s0 register.
1279 __ lw(s0, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize +
1280 StandardFrameConstants::kCArgsSlotsSize));
1281
1282 // Registers: 1430 // Registers:
1283 // a0: entry_address 1431 // a0: entry_address
1284 // a1: function 1432 // a1: function
1285 // a2: reveiver_pointer 1433 // a2: reveiver_pointer
1286 // a3: argc 1434 // a3: argc
1287 // s0: argv 1435 // s0: argv
1288 // 1436 //
1289 // Stack: 1437 // Stack:
1290 // caller fp | 1438 // caller fp |
1291 // function slot | entry frame 1439 // function slot | entry frame
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 // 4 args slots 1491 // 4 args slots
1344 // args 1492 // args
1345 1493
1346 if (is_construct) { 1494 if (is_construct) {
1347 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline); 1495 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
1348 __ LoadExternalReference(t0, construct_entry); 1496 __ LoadExternalReference(t0, construct_entry);
1349 } else { 1497 } else {
1350 ExternalReference entry(Builtins::JSEntryTrampoline); 1498 ExternalReference entry(Builtins::JSEntryTrampoline);
1351 __ LoadExternalReference(t0, entry); 1499 __ LoadExternalReference(t0, entry);
1352 } 1500 }
1353 __ lw(t9, MemOperand(t0)); // deref address 1501 __ lw(t9, MemOperand(t0)); // Deref address.
1354 1502
1355 // Call JSEntryTrampoline. 1503 // Call JSEntryTrampoline.
1356 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag); 1504 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
1357 __ CallBuiltin(t9); 1505 __ CallBuiltin(t9);
1358 1506
1359 // Unlink this frame from the handler chain. When reading the 1507 // Unlink this frame from the handler chain. When reading the
1360 // address of the next handler, there is no need to use the address 1508 // address of the next handler, there is no need to use the address
1361 // displacement since the current stack pointer (sp) points directly 1509 // displacement since the current stack pointer (sp) points directly
1362 // to the stack handler. 1510 // to the stack handler.
1363 __ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset)); 1511 __ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
1364 __ LoadExternalReference(t0, ExternalReference(Top::k_handler_address)); 1512 __ LoadExternalReference(t0, ExternalReference(Top::k_handler_address));
1365 __ sw(t1, MemOperand(t0)); 1513 __ sw(t1, MemOperand(t0));
1366 1514
1367 // This restores sp to its position before PushTryHandler. 1515 // This restores sp to its position before PushTryHandler.
1368 __ addiu(sp, sp, StackHandlerConstants::kSize); 1516 __ addiu(sp, sp, StackHandlerConstants::kSize);
1369 1517
1370 __ bind(&exit); // v0 holds result 1518 __ bind(&exit); // v0 holds result.
1371 // Restore the top frame descriptors from the stack. 1519 // Restore the top frame descriptors from the stack.
1372 __ Pop(t1); 1520 __ Pop(t1);
1373 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address)); 1521 __ LoadExternalReference(t0, ExternalReference(Top::k_c_entry_fp_address));
1374 __ sw(t1, MemOperand(t0)); 1522 __ sw(t1, MemOperand(t0));
1375 1523
1376 // Reset the stack to the callee saved registers. 1524 // Reset the stack to the callee saved registers.
1377 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset); 1525 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset);
1378 1526
1379 // Restore callee saved registers from the stack. 1527 // Restore callee saved registers from the stack.
1380 __ MultiPop((kCalleeSaved | ra.bit()) & ~sp.bit()); 1528 __ MultiPop((kCalleeSaved | ra.bit()) & ~sp.bit());
1381 // Return. 1529 // Return.
1382 __ Jump(ra); 1530 __ Jump(ra);
1383 } 1531 }
1384 1532
1385 1533
1386 // This stub performs an instanceof, calling the builtin function if 1534 // This stub performs an instanceof, calling the builtin function if
1387 // necessary. Uses a1 for the object, a0 for the function that it may 1535 // necessary. Uses a1 for the object, a0 for the function that it may
1388 // be an instance of (these are fetched from the stack). 1536 // be an instance of (these are fetched from the stack).
1389 void InstanceofStub::Generate(MacroAssembler* masm) { 1537 void InstanceofStub::Generate(MacroAssembler* masm) {
1390 UNIMPLEMENTED_MIPS(); 1538 UNIMPLEMENTED_MIPS();
1391 __ break_(0x845); 1539 __ break_(0x845);
1392 } 1540 }
1393 1541
1394 1542
1395 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { 1543 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
1396 UNIMPLEMENTED_MIPS(); 1544 UNIMPLEMENTED_MIPS();
1397 __ break_(0x851); 1545 __ break_(__LINE__);
1398 } 1546 }
1399 1547
1400 1548
1401 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 1549 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
1402 UNIMPLEMENTED_MIPS(); 1550 UNIMPLEMENTED_MIPS();
1403 __ break_(0x857); 1551 __ break_(__LINE__);
1404 } 1552 }
1405 1553
1406 1554
1407 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { 1555 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
1408 UNIMPLEMENTED_MIPS(); 1556 UNIMPLEMENTED_MIPS();
1409 __ break_(0x863); 1557 __ break_(__LINE__);
1410 } 1558 }
1411 1559
1412 1560
1413 const char* CompareStub::GetName() { 1561 const char* CompareStub::GetName() {
1414 UNIMPLEMENTED_MIPS(); 1562 UNIMPLEMENTED_MIPS();
1415 return NULL; // UNIMPLEMENTED RETURN 1563 return NULL; // UNIMPLEMENTED RETURN.
1416 } 1564 }
1417 1565
1418 1566
1419 int CompareStub::MinorKey() { 1567 int CompareStub::MinorKey() {
1420 // Encode the two parameters in a unique 16 bit value. 1568 // Encode the two parameters in a unique 16 bit value.
1421 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); 1569 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15));
1422 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); 1570 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0);
1423 } 1571 }
1424 1572
1425 1573
1426 #undef __ 1574 #undef __
1427 1575
1428 } } // namespace v8::internal 1576 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698