Home | History | Annotate | Download | only in arm
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "bootstrapper.h"
     31 #include "codegen-inl.h"
     32 #include "compiler.h"
     33 #include "debug.h"
     34 #include "parser.h"
     35 #include "register-allocator-inl.h"
     36 #include "runtime.h"
     37 #include "scopes.h"
     38 
     39 
     40 namespace v8 {
     41 namespace internal {
     42 
     43 #define __ ACCESS_MASM(masm_)
     44 
     45 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
     46                                           Label* slow,
     47                                           Condition cc,
     48                                           bool never_nan_nan);
     49 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
     50                                     Label* lhs_not_nan,
     51                                     Label* slow,
     52                                     bool strict);
     53 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc);
     54 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm);
     55 static void MultiplyByKnownInt(MacroAssembler* masm,
     56                                Register source,
     57                                Register destination,
     58                                int known_int);
     59 static bool IsEasyToMultiplyBy(int x);
     60 
     61 
     62 
     63 // -------------------------------------------------------------------------
     64 // Platform-specific DeferredCode functions.
     65 
     66 void DeferredCode::SaveRegisters() {
     67   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
     68     int action = registers_[i];
     69     if (action == kPush) {
     70       __ push(RegisterAllocator::ToRegister(i));
     71     } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
     72       __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
     73     }
     74   }
     75 }
     76 
     77 
     78 void DeferredCode::RestoreRegisters() {
     79   // Restore registers in reverse order due to the stack.
     80   for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
     81     int action = registers_[i];
     82     if (action == kPush) {
     83       __ pop(RegisterAllocator::ToRegister(i));
     84     } else if (action != kIgnore) {
     85       action &= ~kSyncedFlag;
     86       __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
     87     }
     88   }
     89 }
     90 
     91 
     92 // -------------------------------------------------------------------------
     93 // CodeGenState implementation.
     94 
     95 CodeGenState::CodeGenState(CodeGenerator* owner)
     96     : owner_(owner),
     97       true_target_(NULL),
     98       false_target_(NULL),
     99       previous_(NULL) {
    100   owner_->set_state(this);
    101 }
    102 
    103 
    104 CodeGenState::CodeGenState(CodeGenerator* owner,
    105                            JumpTarget* true_target,
    106                            JumpTarget* false_target)
    107     : owner_(owner),
    108       true_target_(true_target),
    109       false_target_(false_target),
    110       previous_(owner->state()) {
    111   owner_->set_state(this);
    112 }
    113 
    114 
    115 CodeGenState::~CodeGenState() {
    116   ASSERT(owner_->state() == this);
    117   owner_->set_state(previous_);
    118 }
    119 
    120 
    121 // -------------------------------------------------------------------------
    122 // CodeGenerator implementation
    123 
    124 CodeGenerator::CodeGenerator(MacroAssembler* masm)
    125     : deferred_(8),
    126       masm_(masm),
    127       info_(NULL),
    128       frame_(NULL),
    129       allocator_(NULL),
    130       cc_reg_(al),
    131       state_(NULL),
    132       function_return_is_shadowed_(false) {
    133 }
    134 
    135 
    136 Scope* CodeGenerator::scope() { return info_->function()->scope(); }
    137 
    138 
    139 // Calling conventions:
    140 // fp: caller's frame pointer
    141 // sp: stack pointer
    142 // r1: called JS function
    143 // cp: callee's context
    144 
    145 void CodeGenerator::Generate(CompilationInfo* info) {
    146   // Record the position for debugging purposes.
    147   CodeForFunctionPosition(info->function());
    148 
    149   // Initialize state.
    150   info_ = info;
    151   ASSERT(allocator_ == NULL);
    152   RegisterAllocator register_allocator(this);
    153   allocator_ = &register_allocator;
    154   ASSERT(frame_ == NULL);
    155   frame_ = new VirtualFrame();
    156   cc_reg_ = al;
    157   {
    158     CodeGenState state(this);
    159 
    160     // Entry:
    161     // Stack: receiver, arguments
    162     // lr: return address
    163     // fp: caller's frame pointer
    164     // sp: stack pointer
    165     // r1: called JS function
    166     // cp: callee's context
    167     allocator_->Initialize();
    168 
    169 #ifdef DEBUG
    170     if (strlen(FLAG_stop_at) > 0 &&
    171         info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
    172       frame_->SpillAll();
    173       __ stop("stop-at");
    174     }
    175 #endif
    176 
    177     if (info->mode() == CompilationInfo::PRIMARY) {
    178       frame_->Enter();
    179       // tos: code slot
    180 
    181       // Allocate space for locals and initialize them.  This also checks
    182       // for stack overflow.
    183       frame_->AllocateStackSlots();
    184 
    185       VirtualFrame::SpilledScope spilled_scope;
    186       int heap_slots = scope()->num_heap_slots();
    187       if (heap_slots > 0) {
    188         // Allocate local context.
    189         // Get outer context and create a new context based on it.
    190         __ ldr(r0, frame_->Function());
    191         frame_->EmitPush(r0);
    192         if (heap_slots <= FastNewContextStub::kMaximumSlots) {
    193           FastNewContextStub stub(heap_slots);
    194           frame_->CallStub(&stub, 1);
    195         } else {
    196           frame_->CallRuntime(Runtime::kNewContext, 1);
    197         }
    198 
    199 #ifdef DEBUG
    200         JumpTarget verified_true;
    201         __ cmp(r0, Operand(cp));
    202         verified_true.Branch(eq);
    203         __ stop("NewContext: r0 is expected to be the same as cp");
    204         verified_true.Bind();
    205 #endif
    206         // Update context local.
    207         __ str(cp, frame_->Context());
    208       }
    209 
    210       // TODO(1241774): Improve this code:
    211       // 1) only needed if we have a context
    212       // 2) no need to recompute context ptr every single time
    213       // 3) don't copy parameter operand code from SlotOperand!
    214       {
    215         Comment cmnt2(masm_, "[ copy context parameters into .context");
    216         // Note that iteration order is relevant here! If we have the same
    217         // parameter twice (e.g., function (x, y, x)), and that parameter
    218         // needs to be copied into the context, it must be the last argument
    219         // passed to the parameter that needs to be copied. This is a rare
    220         // case so we don't check for it, instead we rely on the copying
    221         // order: such a parameter is copied repeatedly into the same
    222         // context location and thus the last value is what is seen inside
    223         // the function.
    224         for (int i = 0; i < scope()->num_parameters(); i++) {
    225           Variable* par = scope()->parameter(i);
    226           Slot* slot = par->slot();
    227           if (slot != NULL && slot->type() == Slot::CONTEXT) {
    228             ASSERT(!scope()->is_global_scope());  // No params in global scope.
    229             __ ldr(r1, frame_->ParameterAt(i));
    230             // Loads r2 with context; used below in RecordWrite.
    231             __ str(r1, SlotOperand(slot, r2));
    232             // Load the offset into r3.
    233             int slot_offset =
    234                 FixedArray::kHeaderSize + slot->index() * kPointerSize;
    235             __ mov(r3, Operand(slot_offset));
    236             __ RecordWrite(r2, r3, r1);
    237           }
    238         }
    239       }
    240 
    241       // Store the arguments object.  This must happen after context
    242       // initialization because the arguments object may be stored in the
    243       // context.
    244       if (scope()->arguments() != NULL) {
    245         Comment cmnt(masm_, "[ allocate arguments object");
    246         ASSERT(scope()->arguments_shadow() != NULL);
    247         Variable* arguments = scope()->arguments()->var();
    248         Variable* shadow = scope()->arguments_shadow()->var();
    249         ASSERT(arguments != NULL && arguments->slot() != NULL);
    250         ASSERT(shadow != NULL && shadow->slot() != NULL);
    251         ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
    252         __ ldr(r2, frame_->Function());
    253         // The receiver is below the arguments, the return address, and the
    254         // frame pointer on the stack.
    255         const int kReceiverDisplacement = 2 + scope()->num_parameters();
    256         __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
    257         __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
    258         frame_->Adjust(3);
    259         __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
    260         frame_->CallStub(&stub, 3);
    261         frame_->EmitPush(r0);
    262         StoreToSlot(arguments->slot(), NOT_CONST_INIT);
    263         StoreToSlot(shadow->slot(), NOT_CONST_INIT);
    264         frame_->Drop();  // Value is no longer needed.
    265       }
    266 
    267       // Initialize ThisFunction reference if present.
    268       if (scope()->is_function_scope() && scope()->function() != NULL) {
    269         __ mov(ip, Operand(Factory::the_hole_value()));
    270         frame_->EmitPush(ip);
    271         StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
    272       }
    273     } else {
    274       // When used as the secondary compiler for splitting, r1, cp,
    275       // fp, and lr have been pushed on the stack.  Adjust the virtual
    276       // frame to match this state.
    277       frame_->Adjust(4);
    278       allocator_->Unuse(r1);
    279       allocator_->Unuse(lr);
    280 
    281       // Bind all the bailout labels to the beginning of the function.
    282       List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
    283       for (int i = 0; i < bailouts->length(); i++) {
    284         __ bind(bailouts->at(i)->label());
    285       }
    286     }
    287 
    288     // Initialize the function return target after the locals are set
    289     // up, because it needs the expected frame height from the frame.
    290     function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
    291     function_return_is_shadowed_ = false;
    292 
    293     // Generate code to 'execute' declarations and initialize functions
    294     // (source elements). In case of an illegal redeclaration we need to
    295     // handle that instead of processing the declarations.
    296     if (scope()->HasIllegalRedeclaration()) {
    297       Comment cmnt(masm_, "[ illegal redeclarations");
    298       scope()->VisitIllegalRedeclaration(this);
    299     } else {
    300       Comment cmnt(masm_, "[ declarations");
    301       ProcessDeclarations(scope()->declarations());
    302       // Bail out if a stack-overflow exception occurred when processing
    303       // declarations.
    304       if (HasStackOverflow()) return;
    305     }
    306 
    307     if (FLAG_trace) {
    308       frame_->CallRuntime(Runtime::kTraceEnter, 0);
    309       // Ignore the return value.
    310     }
    311 
    312     // Compile the body of the function in a vanilla state. Don't
    313     // bother compiling all the code if the scope has an illegal
    314     // redeclaration.
    315     if (!scope()->HasIllegalRedeclaration()) {
    316       Comment cmnt(masm_, "[ function body");
    317 #ifdef DEBUG
    318       bool is_builtin = Bootstrapper::IsActive();
    319       bool should_trace =
    320           is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
    321       if (should_trace) {
    322         frame_->CallRuntime(Runtime::kDebugTrace, 0);
    323         // Ignore the return value.
    324       }
    325 #endif
    326       VisitStatementsAndSpill(info->function()->body());
    327     }
    328   }
    329 
    330   // Generate the return sequence if necessary.
    331   if (has_valid_frame() || function_return_.is_linked()) {
    332     if (!function_return_.is_linked()) {
    333       CodeForReturnPosition(info->function());
    334     }
    335     // exit
    336     // r0: result
    337     // sp: stack pointer
    338     // fp: frame pointer
    339     // cp: callee's context
    340     __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
    341 
    342     function_return_.Bind();
    343     if (FLAG_trace) {
    344       // Push the return value on the stack as the parameter.
    345       // Runtime::TraceExit returns the parameter as it is.
    346       frame_->EmitPush(r0);
    347       frame_->CallRuntime(Runtime::kTraceExit, 1);
    348     }
    349 
    350     // Add a label for checking the size of the code used for returning.
    351     Label check_exit_codesize;
    352     masm_->bind(&check_exit_codesize);
    353 
    354     // Calculate the exact length of the return sequence and make sure that
    355     // the constant pool is not emitted inside of the return sequence.
    356     int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
    357     int return_sequence_length = Assembler::kJSReturnSequenceLength;
    358     if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) {
    359       // Additional mov instruction generated.
    360       return_sequence_length++;
    361     }
    362     masm_->BlockConstPoolFor(return_sequence_length);
    363 
    364     // Tear down the frame which will restore the caller's frame pointer and
    365     // the link register.
    366     frame_->Exit();
    367 
    368     // Here we use masm_-> instead of the __ macro to avoid the code coverage
    369     // tool from instrumenting as we rely on the code size here.
    370     masm_->add(sp, sp, Operand(sp_delta));
    371     masm_->Jump(lr);
    372 
    373     // Check that the size of the code used for returning matches what is
    374     // expected by the debugger. The add instruction above is an addressing
    375     // mode 1 instruction where there are restrictions on which immediate values
    376     // can be encoded in the instruction and which immediate values requires
    377     // use of an additional instruction for moving the immediate to a temporary
    378     // register.
    379     ASSERT_EQ(return_sequence_length,
    380               masm_->InstructionsGeneratedSince(&check_exit_codesize));
    381   }
    382 
    383   // Code generation state must be reset.
    384   ASSERT(!has_cc());
    385   ASSERT(state_ == NULL);
    386   ASSERT(!function_return_is_shadowed_);
    387   function_return_.Unuse();
    388   DeleteFrame();
    389 
    390   // Process any deferred code using the register allocator.
    391   if (!HasStackOverflow()) {
    392     ProcessDeferred();
    393   }
    394 
    395   allocator_ = NULL;
    396 }
    397 
    398 
    399 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
    400   // Currently, this assertion will fail if we try to assign to
    401   // a constant variable that is constant because it is read-only
    402   // (such as the variable referring to a named function expression).
    403   // We need to implement assignments to read-only variables.
    404   // Ideally, we should do this during AST generation (by converting
    405   // such assignments into expression statements); however, in general
    406   // we may not be able to make the decision until past AST generation,
    407   // that is when the entire program is known.
    408   ASSERT(slot != NULL);
    409   int index = slot->index();
    410   switch (slot->type()) {
    411     case Slot::PARAMETER:
    412       return frame_->ParameterAt(index);
    413 
    414     case Slot::LOCAL:
    415       return frame_->LocalAt(index);
    416 
    417     case Slot::CONTEXT: {
    418       // Follow the context chain if necessary.
    419       ASSERT(!tmp.is(cp));  // do not overwrite context register
    420       Register context = cp;
    421       int chain_length = scope()->ContextChainLength(slot->var()->scope());
    422       for (int i = 0; i < chain_length; i++) {
    423         // Load the closure.
    424         // (All contexts, even 'with' contexts, have a closure,
    425         // and it is the same for all contexts inside a function.
    426         // There is no need to go to the function context first.)
    427         __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
    428         // Load the function context (which is the incoming, outer context).
    429         __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
    430         context = tmp;
    431       }
    432       // We may have a 'with' context now. Get the function context.
    433       // (In fact this mov may never be the needed, since the scope analysis
    434       // may not permit a direct context access in this case and thus we are
    435       // always at a function context. However it is safe to dereference be-
    436       // cause the function context of a function context is itself. Before
    437       // deleting this mov we should try to create a counter-example first,
    438       // though...)
    439       __ ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
    440       return ContextOperand(tmp, index);
    441     }
    442 
    443     default:
    444       UNREACHABLE();
    445       return MemOperand(r0, 0);
    446   }
    447 }
    448 
    449 
    450 MemOperand CodeGenerator::ContextSlotOperandCheckExtensions(
    451     Slot* slot,
    452     Register tmp,
    453     Register tmp2,
    454     JumpTarget* slow) {
    455   ASSERT(slot->type() == Slot::CONTEXT);
    456   Register context = cp;
    457 
    458   for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) {
    459     if (s->num_heap_slots() > 0) {
    460       if (s->calls_eval()) {
    461         // Check that extension is NULL.
    462         __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX));
    463         __ tst(tmp2, tmp2);
    464         slow->Branch(ne);
    465       }
    466       __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
    467       __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
    468       context = tmp;
    469     }
    470   }
    471   // Check that last extension is NULL.
    472   __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX));
    473   __ tst(tmp2, tmp2);
    474   slow->Branch(ne);
    475   __ ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
    476   return ContextOperand(tmp, slot->index());
    477 }
    478 
    479 
    480 // Loads a value on TOS. If it is a boolean value, the result may have been
    481 // (partially) translated into branches, or it may have set the condition
    482 // code register. If force_cc is set, the value is forced to set the
    483 // condition code register and no value is pushed. If the condition code
    484 // register was set, has_cc() is true and cc_reg_ contains the condition to
    485 // test for 'true'.
    486 void CodeGenerator::LoadCondition(Expression* x,
    487                                   JumpTarget* true_target,
    488                                   JumpTarget* false_target,
    489                                   bool force_cc) {
    490   ASSERT(!has_cc());
    491   int original_height = frame_->height();
    492 
    493   { CodeGenState new_state(this, true_target, false_target);
    494     Visit(x);
    495 
    496     // If we hit a stack overflow, we may not have actually visited
    497     // the expression.  In that case, we ensure that we have a
    498     // valid-looking frame state because we will continue to generate
    499     // code as we unwind the C++ stack.
    500     //
    501     // It's possible to have both a stack overflow and a valid frame
    502     // state (eg, a subexpression overflowed, visiting it returned
    503     // with a dummied frame state, and visiting this expression
    504     // returned with a normal-looking state).
    505     if (HasStackOverflow() &&
    506         has_valid_frame() &&
    507         !has_cc() &&
    508         frame_->height() == original_height) {
    509       true_target->Jump();
    510     }
    511   }
    512   if (force_cc && frame_ != NULL && !has_cc()) {
    513     // Convert the TOS value to a boolean in the condition code register.
    514     ToBoolean(true_target, false_target);
    515   }
    516   ASSERT(!force_cc || !has_valid_frame() || has_cc());
    517   ASSERT(!has_valid_frame() ||
    518          (has_cc() && frame_->height() == original_height) ||
    519          (!has_cc() && frame_->height() == original_height + 1));
    520 }
    521 
    522 
    523 void CodeGenerator::Load(Expression* expr) {
    524 #ifdef DEBUG
    525   int original_height = frame_->height();
    526 #endif
    527   JumpTarget true_target;
    528   JumpTarget false_target;
    529   LoadCondition(expr, &true_target, &false_target, false);
    530 
    531   if (has_cc()) {
    532     // Convert cc_reg_ into a boolean value.
    533     JumpTarget loaded;
    534     JumpTarget materialize_true;
    535     materialize_true.Branch(cc_reg_);
    536     __ LoadRoot(r0, Heap::kFalseValueRootIndex);
    537     frame_->EmitPush(r0);
    538     loaded.Jump();
    539     materialize_true.Bind();
    540     __ LoadRoot(r0, Heap::kTrueValueRootIndex);
    541     frame_->EmitPush(r0);
    542     loaded.Bind();
    543     cc_reg_ = al;
    544   }
    545 
    546   if (true_target.is_linked() || false_target.is_linked()) {
    547     // We have at least one condition value that has been "translated"
    548     // into a branch, thus it needs to be loaded explicitly.
    549     JumpTarget loaded;
    550     if (frame_ != NULL) {
    551       loaded.Jump();  // Don't lose the current TOS.
    552     }
    553     bool both = true_target.is_linked() && false_target.is_linked();
    554     // Load "true" if necessary.
    555     if (true_target.is_linked()) {
    556       true_target.Bind();
    557       __ LoadRoot(r0, Heap::kTrueValueRootIndex);
    558       frame_->EmitPush(r0);
    559     }
    560     // If both "true" and "false" need to be loaded jump across the code for
    561     // "false".
    562     if (both) {
    563       loaded.Jump();
    564     }
    565     // Load "false" if necessary.
    566     if (false_target.is_linked()) {
    567       false_target.Bind();
    568       __ LoadRoot(r0, Heap::kFalseValueRootIndex);
    569       frame_->EmitPush(r0);
    570     }
    571     // A value is loaded on all paths reaching this point.
    572     loaded.Bind();
    573   }
    574   ASSERT(has_valid_frame());
    575   ASSERT(!has_cc());
    576   ASSERT(frame_->height() == original_height + 1);
    577 }
    578 
    579 
    580 void CodeGenerator::LoadGlobal() {
    581   VirtualFrame::SpilledScope spilled_scope;
    582   __ ldr(r0, GlobalObject());
    583   frame_->EmitPush(r0);
    584 }
    585 
    586 
    587 void CodeGenerator::LoadGlobalReceiver(Register scratch) {
    588   VirtualFrame::SpilledScope spilled_scope;
    589   __ ldr(scratch, ContextOperand(cp, Context::GLOBAL_INDEX));
    590   __ ldr(scratch,
    591          FieldMemOperand(scratch, GlobalObject::kGlobalReceiverOffset));
    592   frame_->EmitPush(scratch);
    593 }
    594 
    595 
    596 void CodeGenerator::LoadTypeofExpression(Expression* expr) {
    597   // Special handling of identifiers as subexpressions of typeof.
    598   VirtualFrame::SpilledScope spilled_scope;
    599   Variable* variable = expr->AsVariableProxy()->AsVariable();
    600   if (variable != NULL && !variable->is_this() && variable->is_global()) {
    601     // For a global variable we build the property reference
    602     // <global>.<variable> and perform a (regular non-contextual) property
    603     // load to make sure we do not get reference errors.
    604     Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
    605     Literal key(variable->name());
    606     Property property(&global, &key, RelocInfo::kNoPosition);
    607     Reference ref(this, &property);
    608     ref.GetValueAndSpill();
    609   } else if (variable != NULL && variable->slot() != NULL) {
    610     // For a variable that rewrites to a slot, we signal it is the immediate
    611     // subexpression of a typeof.
    612     LoadFromSlot(variable->slot(), INSIDE_TYPEOF);
    613     frame_->SpillAll();
    614   } else {
    615     // Anything else can be handled normally.
    616     LoadAndSpill(expr);
    617   }
    618 }
    619 
    620 
    621 Reference::Reference(CodeGenerator* cgen,
    622                      Expression* expression,
    623                      bool persist_after_get)
    624     : cgen_(cgen),
    625       expression_(expression),
    626       type_(ILLEGAL),
    627       persist_after_get_(persist_after_get) {
    628   cgen->LoadReference(this);
    629 }
    630 
    631 
    632 Reference::~Reference() {
    633   ASSERT(is_unloaded() || is_illegal());
    634 }
    635 
    636 
    637 void CodeGenerator::LoadReference(Reference* ref) {
    638   VirtualFrame::SpilledScope spilled_scope;
    639   Comment cmnt(masm_, "[ LoadReference");
    640   Expression* e = ref->expression();
    641   Property* property = e->AsProperty();
    642   Variable* var = e->AsVariableProxy()->AsVariable();
    643 
    644   if (property != NULL) {
    645     // The expression is either a property or a variable proxy that rewrites
    646     // to a property.
    647     LoadAndSpill(property->obj());
    648     if (property->key()->IsPropertyName()) {
    649       ref->set_type(Reference::NAMED);
    650     } else {
    651       LoadAndSpill(property->key());
    652       ref->set_type(Reference::KEYED);
    653     }
    654   } else if (var != NULL) {
    655     // The expression is a variable proxy that does not rewrite to a
    656     // property.  Global variables are treated as named property references.
    657     if (var->is_global()) {
    658       LoadGlobal();
    659       ref->set_type(Reference::NAMED);
    660     } else {
    661       ASSERT(var->slot() != NULL);
    662       ref->set_type(Reference::SLOT);
    663     }
    664   } else {
    665     // Anything else is a runtime error.
    666     LoadAndSpill(e);
    667     frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
    668   }
    669 }
    670 
    671 
    672 void CodeGenerator::UnloadReference(Reference* ref) {
    673   VirtualFrame::SpilledScope spilled_scope;
    674   // Pop a reference from the stack while preserving TOS.
    675   Comment cmnt(masm_, "[ UnloadReference");
    676   int size = ref->size();
    677   if (size > 0) {
    678     frame_->EmitPop(r0);
    679     frame_->Drop(size);
    680     frame_->EmitPush(r0);
    681   }
    682   ref->set_unloaded();
    683 }
    684 
    685 
    686 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given
    687 // register to a boolean in the condition code register. The code
    688 // may jump to 'false_target' in case the register converts to 'false'.
    689 void CodeGenerator::ToBoolean(JumpTarget* true_target,
    690                               JumpTarget* false_target) {
    691   VirtualFrame::SpilledScope spilled_scope;
    692   // Note: The generated code snippet does not change stack variables.
    693   //       Only the condition code should be set.
    694   frame_->EmitPop(r0);
    695 
    696   // Fast case checks
    697 
    698   // Check if the value is 'false'.
    699   __ LoadRoot(ip, Heap::kFalseValueRootIndex);
    700   __ cmp(r0, ip);
    701   false_target->Branch(eq);
    702 
    703   // Check if the value is 'true'.
    704   __ LoadRoot(ip, Heap::kTrueValueRootIndex);
    705   __ cmp(r0, ip);
    706   true_target->Branch(eq);
    707 
    708   // Check if the value is 'undefined'.
    709   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
    710   __ cmp(r0, ip);
    711   false_target->Branch(eq);
    712 
    713   // Check if the value is a smi.
    714   __ cmp(r0, Operand(Smi::FromInt(0)));
    715   false_target->Branch(eq);
    716   __ tst(r0, Operand(kSmiTagMask));
    717   true_target->Branch(eq);
    718 
    719   // Slow case: call the runtime.
    720   frame_->EmitPush(r0);
    721   frame_->CallRuntime(Runtime::kToBool, 1);
    722   // Convert the result (r0) to a condition code.
    723   __ LoadRoot(ip, Heap::kFalseValueRootIndex);
    724   __ cmp(r0, ip);
    725 
    726   cc_reg_ = ne;
    727 }
    728 
    729 
    730 void CodeGenerator::GenericBinaryOperation(Token::Value op,
    731                                            OverwriteMode overwrite_mode,
    732                                            int constant_rhs) {
    733   VirtualFrame::SpilledScope spilled_scope;
    734   // sp[0] : y
    735   // sp[1] : x
    736   // result : r0
    737 
    738   // Stub is entered with a call: 'return address' is in lr.
    739   switch (op) {
    740     case Token::ADD:  // fall through.
    741     case Token::SUB:  // fall through.
    742     case Token::MUL:
    743     case Token::DIV:
    744     case Token::MOD:
    745     case Token::BIT_OR:
    746     case Token::BIT_AND:
    747     case Token::BIT_XOR:
    748     case Token::SHL:
    749     case Token::SHR:
    750     case Token::SAR: {
    751       frame_->EmitPop(r0);  // r0 : y
    752       frame_->EmitPop(r1);  // r1 : x
    753       GenericBinaryOpStub stub(op, overwrite_mode, constant_rhs);
    754       frame_->CallStub(&stub, 0);
    755       break;
    756     }
    757 
    758     case Token::COMMA:
    759       frame_->EmitPop(r0);
    760       // simply discard left value
    761       frame_->Drop();
    762       break;
    763 
    764     default:
    765       // Other cases should have been handled before this point.
    766       UNREACHABLE();
    767       break;
    768   }
    769 }
    770 
    771 
    772 class DeferredInlineSmiOperation: public DeferredCode {
    773  public:
    774   DeferredInlineSmiOperation(Token::Value op,
    775                              int value,
    776                              bool reversed,
    777                              OverwriteMode overwrite_mode)
    778       : op_(op),
    779         value_(value),
    780         reversed_(reversed),
    781         overwrite_mode_(overwrite_mode) {
    782     set_comment("[ DeferredInlinedSmiOperation");
    783   }
    784 
    785   virtual void Generate();
    786 
    787  private:
    788   Token::Value op_;
    789   int value_;
    790   bool reversed_;
    791   OverwriteMode overwrite_mode_;
    792 };
    793 
    794 
    795 void DeferredInlineSmiOperation::Generate() {
    796   switch (op_) {
    797     case Token::ADD: {
    798       // Revert optimistic add.
    799       if (reversed_) {
    800         __ sub(r0, r0, Operand(Smi::FromInt(value_)));
    801         __ mov(r1, Operand(Smi::FromInt(value_)));
    802       } else {
    803         __ sub(r1, r0, Operand(Smi::FromInt(value_)));
    804         __ mov(r0, Operand(Smi::FromInt(value_)));
    805       }
    806       break;
    807     }
    808 
    809     case Token::SUB: {
    810       // Revert optimistic sub.
    811       if (reversed_) {
    812         __ rsb(r0, r0, Operand(Smi::FromInt(value_)));
    813         __ mov(r1, Operand(Smi::FromInt(value_)));
    814       } else {
    815         __ add(r1, r0, Operand(Smi::FromInt(value_)));
    816         __ mov(r0, Operand(Smi::FromInt(value_)));
    817       }
    818       break;
    819     }
    820 
    821     // For these operations there is no optimistic operation that needs to be
    822     // reverted.
    823     case Token::MUL:
    824     case Token::MOD:
    825     case Token::BIT_OR:
    826     case Token::BIT_XOR:
    827     case Token::BIT_AND: {
    828       if (reversed_) {
    829         __ mov(r1, Operand(Smi::FromInt(value_)));
    830       } else {
    831         __ mov(r1, Operand(r0));
    832         __ mov(r0, Operand(Smi::FromInt(value_)));
    833       }
    834       break;
    835     }
    836 
    837     case Token::SHL:
    838     case Token::SHR:
    839     case Token::SAR: {
    840       if (!reversed_) {
    841         __ mov(r1, Operand(r0));
    842         __ mov(r0, Operand(Smi::FromInt(value_)));
    843       } else {
    844         UNREACHABLE();  // Should have been handled in SmiOperation.
    845       }
    846       break;
    847     }
    848 
    849     default:
    850       // Other cases should have been handled before this point.
    851       UNREACHABLE();
    852       break;
    853   }
    854 
    855   GenericBinaryOpStub stub(op_, overwrite_mode_, value_);
    856   __ CallStub(&stub);
    857 }
    858 
    859 
    860 static bool PopCountLessThanEqual2(unsigned int x) {
    861   x &= x - 1;
    862   return (x & (x - 1)) == 0;
    863 }
    864 
    865 
    866 // Returns the index of the lowest bit set.
    867 static int BitPosition(unsigned x) {
    868   int bit_posn = 0;
    869   while ((x & 0xf) == 0) {
    870     bit_posn += 4;
    871     x >>= 4;
    872   }
    873   while ((x & 1) == 0) {
    874     bit_posn++;
    875     x >>= 1;
    876   }
    877   return bit_posn;
    878 }
    879 
    880 
    881 void CodeGenerator::SmiOperation(Token::Value op,
    882                                  Handle<Object> value,
    883                                  bool reversed,
    884                                  OverwriteMode mode) {
    885   VirtualFrame::SpilledScope spilled_scope;
    886   // NOTE: This is an attempt to inline (a bit) more of the code for
    887   // some possible smi operations (like + and -) when (at least) one
    888   // of the operands is a literal smi. With this optimization, the
    889   // performance of the system is increased by ~15%, and the generated
    890   // code size is increased by ~1% (measured on a combination of
    891   // different benchmarks).
    892 
    893   // sp[0] : operand
    894 
    895   int int_value = Smi::cast(*value)->value();
    896 
    897   JumpTarget exit;
    898   frame_->EmitPop(r0);
    899 
    900   bool something_to_inline = true;
    901   switch (op) {
    902     case Token::ADD: {
    903       DeferredCode* deferred =
    904           new DeferredInlineSmiOperation(op, int_value, reversed, mode);
    905 
    906       __ add(r0, r0, Operand(value), SetCC);
    907       deferred->Branch(vs);
    908       __ tst(r0, Operand(kSmiTagMask));
    909       deferred->Branch(ne);
    910       deferred->BindExit();
    911       break;
    912     }
    913 
    914     case Token::SUB: {
    915       DeferredCode* deferred =
    916           new DeferredInlineSmiOperation(op, int_value, reversed, mode);
    917 
    918       if (reversed) {
    919         __ rsb(r0, r0, Operand(value), SetCC);
    920       } else {
    921         __ sub(r0, r0, Operand(value), SetCC);
    922       }
    923       deferred->Branch(vs);
    924       __ tst(r0, Operand(kSmiTagMask));
    925       deferred->Branch(ne);
    926       deferred->BindExit();
    927       break;
    928     }
    929 
    930 
    931     case Token::BIT_OR:
    932     case Token::BIT_XOR:
    933     case Token::BIT_AND: {
    934       DeferredCode* deferred =
    935         new DeferredInlineSmiOperation(op, int_value, reversed, mode);
    936       __ tst(r0, Operand(kSmiTagMask));
    937       deferred->Branch(ne);
    938       switch (op) {
    939         case Token::BIT_OR:  __ orr(r0, r0, Operand(value)); break;
    940         case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
    941         case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break;
    942         default: UNREACHABLE();
    943       }
    944       deferred->BindExit();
    945       break;
    946     }
    947 
    948     case Token::SHL:
    949     case Token::SHR:
    950     case Token::SAR: {
    951       if (reversed) {
    952         something_to_inline = false;
    953         break;
    954       }
    955       int shift_value = int_value & 0x1f;  // least significant 5 bits
    956       DeferredCode* deferred =
    957         new DeferredInlineSmiOperation(op, shift_value, false, mode);
    958       __ tst(r0, Operand(kSmiTagMask));
    959       deferred->Branch(ne);
    960       __ mov(r2, Operand(r0, ASR, kSmiTagSize));  // remove tags
    961       switch (op) {
    962         case Token::SHL: {
    963           if (shift_value != 0) {
    964             __ mov(r2, Operand(r2, LSL, shift_value));
    965           }
    966           // check that the *unsigned* result fits in a smi
    967           __ add(r3, r2, Operand(0x40000000), SetCC);
    968           deferred->Branch(mi);
    969           break;
    970         }
    971         case Token::SHR: {
    972           // LSR by immediate 0 means shifting 32 bits.
    973           if (shift_value != 0) {
    974             __ mov(r2, Operand(r2, LSR, shift_value));
    975           }
    976           // check that the *unsigned* result fits in a smi
    977           // neither of the two high-order bits can be set:
    978           // - 0x80000000: high bit would be lost when smi tagging
    979           // - 0x40000000: this number would convert to negative when
    980           // smi tagging these two cases can only happen with shifts
    981           // by 0 or 1 when handed a valid smi
    982           __ and_(r3, r2, Operand(0xc0000000), SetCC);
    983           deferred->Branch(ne);
    984           break;
    985         }
    986         case Token::SAR: {
    987           if (shift_value != 0) {
    988             // ASR by immediate 0 means shifting 32 bits.
    989             __ mov(r2, Operand(r2, ASR, shift_value));
    990           }
    991           break;
    992         }
    993         default: UNREACHABLE();
    994       }
    995       __ mov(r0, Operand(r2, LSL, kSmiTagSize));
    996       deferred->BindExit();
    997       break;
    998     }
    999 
   1000     case Token::MOD: {
   1001       if (reversed || int_value < 2 || !IsPowerOf2(int_value)) {
   1002         something_to_inline = false;
   1003         break;
   1004       }
   1005       DeferredCode* deferred =
   1006         new DeferredInlineSmiOperation(op, int_value, reversed, mode);
   1007       unsigned mask = (0x80000000u | kSmiTagMask);
   1008       __ tst(r0, Operand(mask));
   1009       deferred->Branch(ne);  // Go to deferred code on non-Smis and negative.
   1010       mask = (int_value << kSmiTagSize) - 1;
   1011       __ and_(r0, r0, Operand(mask));
   1012       deferred->BindExit();
   1013       break;
   1014     }
   1015 
   1016     case Token::MUL: {
   1017       if (!IsEasyToMultiplyBy(int_value)) {
   1018         something_to_inline = false;
   1019         break;
   1020       }
   1021       DeferredCode* deferred =
   1022         new DeferredInlineSmiOperation(op, int_value, reversed, mode);
   1023       unsigned max_smi_that_wont_overflow = Smi::kMaxValue / int_value;
   1024       max_smi_that_wont_overflow <<= kSmiTagSize;
   1025       unsigned mask = 0x80000000u;
   1026       while ((mask & max_smi_that_wont_overflow) == 0) {
   1027         mask |= mask >> 1;
   1028       }
   1029       mask |= kSmiTagMask;
   1030       // This does a single mask that checks for a too high value in a
   1031       // conservative way and for a non-Smi.  It also filters out negative
   1032       // numbers, unfortunately, but since this code is inline we prefer
   1033       // brevity to comprehensiveness.
   1034       __ tst(r0, Operand(mask));
   1035       deferred->Branch(ne);
   1036       MultiplyByKnownInt(masm_, r0, r0, int_value);
   1037       deferred->BindExit();
   1038       break;
   1039     }
   1040 
   1041     default:
   1042       something_to_inline = false;
   1043       break;
   1044   }
   1045 
   1046   if (!something_to_inline) {
   1047     if (!reversed) {
   1048       frame_->EmitPush(r0);
   1049       __ mov(r0, Operand(value));
   1050       frame_->EmitPush(r0);
   1051       GenericBinaryOperation(op, mode, int_value);
   1052     } else {
   1053       __ mov(ip, Operand(value));
   1054       frame_->EmitPush(ip);
   1055       frame_->EmitPush(r0);
   1056       GenericBinaryOperation(op, mode, kUnknownIntValue);
   1057     }
   1058   }
   1059 
   1060   exit.Bind();
   1061 }
   1062 
   1063 
   1064 void CodeGenerator::Comparison(Condition cc,
   1065                                Expression* left,
   1066                                Expression* right,
   1067                                bool strict) {
   1068   if (left != NULL) LoadAndSpill(left);
   1069   if (right != NULL) LoadAndSpill(right);
   1070 
   1071   VirtualFrame::SpilledScope spilled_scope;
   1072   // sp[0] : y
   1073   // sp[1] : x
   1074   // result : cc register
   1075 
   1076   // Strict only makes sense for equality comparisons.
   1077   ASSERT(!strict || cc == eq);
   1078 
   1079   JumpTarget exit;
   1080   JumpTarget smi;
   1081   // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
   1082   if (cc == gt || cc == le) {
   1083     cc = ReverseCondition(cc);
   1084     frame_->EmitPop(r1);
   1085     frame_->EmitPop(r0);
   1086   } else {
   1087     frame_->EmitPop(r0);
   1088     frame_->EmitPop(r1);
   1089   }
   1090   __ orr(r2, r0, Operand(r1));
   1091   __ tst(r2, Operand(kSmiTagMask));
   1092   smi.Branch(eq);
   1093 
   1094   // Perform non-smi comparison by stub.
   1095   // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0.
   1096   // We call with 0 args because there are 0 on the stack.
   1097   CompareStub stub(cc, strict);
   1098   frame_->CallStub(&stub, 0);
   1099   __ cmp(r0, Operand(0));
   1100   exit.Jump();
   1101 
   1102   // Do smi comparisons by pointer comparison.
   1103   smi.Bind();
   1104   __ cmp(r1, Operand(r0));
   1105 
   1106   exit.Bind();
   1107   cc_reg_ = cc;
   1108 }
   1109 
   1110 
   1111 // Call the function on the stack with the given arguments.
   1112 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
   1113                                       CallFunctionFlags flags,
   1114                                       int position) {
   1115   VirtualFrame::SpilledScope spilled_scope;
   1116   // Push the arguments ("left-to-right") on the stack.
   1117   int arg_count = args->length();
   1118   for (int i = 0; i < arg_count; i++) {
   1119     LoadAndSpill(args->at(i));
   1120   }
   1121 
   1122   // Record the position for debugging purposes.
   1123   CodeForSourcePosition(position);
   1124 
   1125   // Use the shared code stub to call the function.
   1126   InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   1127   CallFunctionStub call_function(arg_count, in_loop, flags);
   1128   frame_->CallStub(&call_function, arg_count + 1);
   1129 
   1130   // Restore context and pop function from the stack.
   1131   __ ldr(cp, frame_->Context());
   1132   frame_->Drop();  // discard the TOS
   1133 }
   1134 
   1135 
   1136 void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
   1137   VirtualFrame::SpilledScope spilled_scope;
   1138   ASSERT(has_cc());
   1139   Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_);
   1140   target->Branch(cc);
   1141   cc_reg_ = al;
   1142 }
   1143 
   1144 
   1145 void CodeGenerator::CheckStack() {
   1146   VirtualFrame::SpilledScope spilled_scope;
   1147   Comment cmnt(masm_, "[ check stack");
   1148   __ LoadRoot(ip, Heap::kStackLimitRootIndex);
   1149   // Put the lr setup instruction in the delay slot.  kInstrSize is added to
   1150   // the implicit 8 byte offset that always applies to operations with pc and
   1151   // gives a return address 12 bytes down.
   1152   masm_->add(lr, pc, Operand(Assembler::kInstrSize));
   1153   masm_->cmp(sp, Operand(ip));
   1154   StackCheckStub stub;
   1155   // Call the stub if lower.
   1156   masm_->mov(pc,
   1157              Operand(reinterpret_cast<intptr_t>(stub.GetCode().location()),
   1158                      RelocInfo::CODE_TARGET),
   1159              LeaveCC,
   1160              lo);
   1161 }
   1162 
   1163 
   1164 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
   1165 #ifdef DEBUG
   1166   int original_height = frame_->height();
   1167 #endif
   1168   VirtualFrame::SpilledScope spilled_scope;
   1169   for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
   1170     VisitAndSpill(statements->at(i));
   1171   }
   1172   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1173 }
   1174 
   1175 
   1176 void CodeGenerator::VisitBlock(Block* node) {
   1177 #ifdef DEBUG
   1178   int original_height = frame_->height();
   1179 #endif
   1180   VirtualFrame::SpilledScope spilled_scope;
   1181   Comment cmnt(masm_, "[ Block");
   1182   CodeForStatementPosition(node);
   1183   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1184   VisitStatementsAndSpill(node->statements());
   1185   if (node->break_target()->is_linked()) {
   1186     node->break_target()->Bind();
   1187   }
   1188   node->break_target()->Unuse();
   1189   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1190 }
   1191 
   1192 
   1193 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   1194   VirtualFrame::SpilledScope spilled_scope;
   1195   frame_->EmitPush(cp);
   1196   __ mov(r0, Operand(pairs));
   1197   frame_->EmitPush(r0);
   1198   __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
   1199   frame_->EmitPush(r0);
   1200   frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
   1201   // The result is discarded.
   1202 }
   1203 
   1204 
   1205 void CodeGenerator::VisitDeclaration(Declaration* node) {
   1206 #ifdef DEBUG
   1207   int original_height = frame_->height();
   1208 #endif
   1209   VirtualFrame::SpilledScope spilled_scope;
   1210   Comment cmnt(masm_, "[ Declaration");
   1211   Variable* var = node->proxy()->var();
   1212   ASSERT(var != NULL);  // must have been resolved
   1213   Slot* slot = var->slot();
   1214 
   1215   // If it was not possible to allocate the variable at compile time,
   1216   // we need to "declare" it at runtime to make sure it actually
   1217   // exists in the local context.
   1218   if (slot != NULL && slot->type() == Slot::LOOKUP) {
   1219     // Variables with a "LOOKUP" slot were introduced as non-locals
   1220     // during variable resolution and must have mode DYNAMIC.
   1221     ASSERT(var->is_dynamic());
   1222     // For now, just do a runtime call.
   1223     frame_->EmitPush(cp);
   1224     __ mov(r0, Operand(var->name()));
   1225     frame_->EmitPush(r0);
   1226     // Declaration nodes are always declared in only two modes.
   1227     ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
   1228     PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
   1229     __ mov(r0, Operand(Smi::FromInt(attr)));
   1230     frame_->EmitPush(r0);
   1231     // Push initial value, if any.
   1232     // Note: For variables we must not push an initial value (such as
   1233     // 'undefined') because we may have a (legal) redeclaration and we
   1234     // must not destroy the current value.
   1235     if (node->mode() == Variable::CONST) {
   1236       __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
   1237       frame_->EmitPush(r0);
   1238     } else if (node->fun() != NULL) {
   1239       LoadAndSpill(node->fun());
   1240     } else {
   1241       __ mov(r0, Operand(0));  // no initial value!
   1242       frame_->EmitPush(r0);
   1243     }
   1244     frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
   1245     // Ignore the return value (declarations are statements).
   1246     ASSERT(frame_->height() == original_height);
   1247     return;
   1248   }
   1249 
   1250   ASSERT(!var->is_global());
   1251 
   1252   // If we have a function or a constant, we need to initialize the variable.
   1253   Expression* val = NULL;
   1254   if (node->mode() == Variable::CONST) {
   1255     val = new Literal(Factory::the_hole_value());
   1256   } else {
   1257     val = node->fun();  // NULL if we don't have a function
   1258   }
   1259 
   1260   if (val != NULL) {
   1261     {
   1262       // Set initial value.
   1263       Reference target(this, node->proxy());
   1264       LoadAndSpill(val);
   1265       target.SetValue(NOT_CONST_INIT);
   1266     }
   1267     // Get rid of the assigned value (declarations are statements).
   1268     frame_->Drop();
   1269   }
   1270   ASSERT(frame_->height() == original_height);
   1271 }
   1272 
   1273 
   1274 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
   1275 #ifdef DEBUG
   1276   int original_height = frame_->height();
   1277 #endif
   1278   VirtualFrame::SpilledScope spilled_scope;
   1279   Comment cmnt(masm_, "[ ExpressionStatement");
   1280   CodeForStatementPosition(node);
   1281   Expression* expression = node->expression();
   1282   expression->MarkAsStatement();
   1283   LoadAndSpill(expression);
   1284   frame_->Drop();
   1285   ASSERT(frame_->height() == original_height);
   1286 }
   1287 
   1288 
   1289 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
   1290 #ifdef DEBUG
   1291   int original_height = frame_->height();
   1292 #endif
   1293   VirtualFrame::SpilledScope spilled_scope;
   1294   Comment cmnt(masm_, "// EmptyStatement");
   1295   CodeForStatementPosition(node);
   1296   // nothing to do
   1297   ASSERT(frame_->height() == original_height);
   1298 }
   1299 
   1300 
   1301 void CodeGenerator::VisitIfStatement(IfStatement* node) {
   1302 #ifdef DEBUG
   1303   int original_height = frame_->height();
   1304 #endif
   1305   VirtualFrame::SpilledScope spilled_scope;
   1306   Comment cmnt(masm_, "[ IfStatement");
   1307   // Generate different code depending on which parts of the if statement
   1308   // are present or not.
   1309   bool has_then_stm = node->HasThenStatement();
   1310   bool has_else_stm = node->HasElseStatement();
   1311 
   1312   CodeForStatementPosition(node);
   1313 
   1314   JumpTarget exit;
   1315   if (has_then_stm && has_else_stm) {
   1316     Comment cmnt(masm_, "[ IfThenElse");
   1317     JumpTarget then;
   1318     JumpTarget else_;
   1319     // if (cond)
   1320     LoadConditionAndSpill(node->condition(), &then, &else_, true);
   1321     if (frame_ != NULL) {
   1322       Branch(false, &else_);
   1323     }
   1324     // then
   1325     if (frame_ != NULL || then.is_linked()) {
   1326       then.Bind();
   1327       VisitAndSpill(node->then_statement());
   1328     }
   1329     if (frame_ != NULL) {
   1330       exit.Jump();
   1331     }
   1332     // else
   1333     if (else_.is_linked()) {
   1334       else_.Bind();
   1335       VisitAndSpill(node->else_statement());
   1336     }
   1337 
   1338   } else if (has_then_stm) {
   1339     Comment cmnt(masm_, "[ IfThen");
   1340     ASSERT(!has_else_stm);
   1341     JumpTarget then;
   1342     // if (cond)
   1343     LoadConditionAndSpill(node->condition(), &then, &exit, true);
   1344     if (frame_ != NULL) {
   1345       Branch(false, &exit);
   1346     }
   1347     // then
   1348     if (frame_ != NULL || then.is_linked()) {
   1349       then.Bind();
   1350       VisitAndSpill(node->then_statement());
   1351     }
   1352 
   1353   } else if (has_else_stm) {
   1354     Comment cmnt(masm_, "[ IfElse");
   1355     ASSERT(!has_then_stm);
   1356     JumpTarget else_;
   1357     // if (!cond)
   1358     LoadConditionAndSpill(node->condition(), &exit, &else_, true);
   1359     if (frame_ != NULL) {
   1360       Branch(true, &exit);
   1361     }
   1362     // else
   1363     if (frame_ != NULL || else_.is_linked()) {
   1364       else_.Bind();
   1365       VisitAndSpill(node->else_statement());
   1366     }
   1367 
   1368   } else {
   1369     Comment cmnt(masm_, "[ If");
   1370     ASSERT(!has_then_stm && !has_else_stm);
   1371     // if (cond)
   1372     LoadConditionAndSpill(node->condition(), &exit, &exit, false);
   1373     if (frame_ != NULL) {
   1374       if (has_cc()) {
   1375         cc_reg_ = al;
   1376       } else {
   1377         frame_->Drop();
   1378       }
   1379     }
   1380   }
   1381 
   1382   // end
   1383   if (exit.is_linked()) {
   1384     exit.Bind();
   1385   }
   1386   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1387 }
   1388 
   1389 
   1390 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
   1391   VirtualFrame::SpilledScope spilled_scope;
   1392   Comment cmnt(masm_, "[ ContinueStatement");
   1393   CodeForStatementPosition(node);
   1394   node->target()->continue_target()->Jump();
   1395 }
   1396 
   1397 
   1398 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
   1399   VirtualFrame::SpilledScope spilled_scope;
   1400   Comment cmnt(masm_, "[ BreakStatement");
   1401   CodeForStatementPosition(node);
   1402   node->target()->break_target()->Jump();
   1403 }
   1404 
   1405 
   1406 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
   1407   VirtualFrame::SpilledScope spilled_scope;
   1408   Comment cmnt(masm_, "[ ReturnStatement");
   1409 
   1410   CodeForStatementPosition(node);
   1411   LoadAndSpill(node->expression());
   1412   if (function_return_is_shadowed_) {
   1413     frame_->EmitPop(r0);
   1414     function_return_.Jump();
   1415   } else {
   1416     // Pop the result from the frame and prepare the frame for
   1417     // returning thus making it easier to merge.
   1418     frame_->EmitPop(r0);
   1419     frame_->PrepareForReturn();
   1420 
   1421     function_return_.Jump();
   1422   }
   1423 }
   1424 
   1425 
   1426 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
   1427 #ifdef DEBUG
   1428   int original_height = frame_->height();
   1429 #endif
   1430   VirtualFrame::SpilledScope spilled_scope;
   1431   Comment cmnt(masm_, "[ WithEnterStatement");
   1432   CodeForStatementPosition(node);
   1433   LoadAndSpill(node->expression());
   1434   if (node->is_catch_block()) {
   1435     frame_->CallRuntime(Runtime::kPushCatchContext, 1);
   1436   } else {
   1437     frame_->CallRuntime(Runtime::kPushContext, 1);
   1438   }
   1439 #ifdef DEBUG
   1440   JumpTarget verified_true;
   1441   __ cmp(r0, Operand(cp));
   1442   verified_true.Branch(eq);
   1443   __ stop("PushContext: r0 is expected to be the same as cp");
   1444   verified_true.Bind();
   1445 #endif
   1446   // Update context local.
   1447   __ str(cp, frame_->Context());
   1448   ASSERT(frame_->height() == original_height);
   1449 }
   1450 
   1451 
   1452 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
   1453 #ifdef DEBUG
   1454   int original_height = frame_->height();
   1455 #endif
   1456   VirtualFrame::SpilledScope spilled_scope;
   1457   Comment cmnt(masm_, "[ WithExitStatement");
   1458   CodeForStatementPosition(node);
   1459   // Pop context.
   1460   __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
   1461   // Update context local.
   1462   __ str(cp, frame_->Context());
   1463   ASSERT(frame_->height() == original_height);
   1464 }
   1465 
   1466 
   1467 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
   1468 #ifdef DEBUG
   1469   int original_height = frame_->height();
   1470 #endif
   1471   VirtualFrame::SpilledScope spilled_scope;
   1472   Comment cmnt(masm_, "[ SwitchStatement");
   1473   CodeForStatementPosition(node);
   1474   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1475 
   1476   LoadAndSpill(node->tag());
   1477 
   1478   JumpTarget next_test;
   1479   JumpTarget fall_through;
   1480   JumpTarget default_entry;
   1481   JumpTarget default_exit(JumpTarget::BIDIRECTIONAL);
   1482   ZoneList<CaseClause*>* cases = node->cases();
   1483   int length = cases->length();
   1484   CaseClause* default_clause = NULL;
   1485 
   1486   for (int i = 0; i < length; i++) {
   1487     CaseClause* clause = cases->at(i);
   1488     if (clause->is_default()) {
   1489       // Remember the default clause and compile it at the end.
   1490       default_clause = clause;
   1491       continue;
   1492     }
   1493 
   1494     Comment cmnt(masm_, "[ Case clause");
   1495     // Compile the test.
   1496     next_test.Bind();
   1497     next_test.Unuse();
   1498     // Duplicate TOS.
   1499     __ ldr(r0, frame_->Top());
   1500     frame_->EmitPush(r0);
   1501     Comparison(eq, NULL, clause->label(), true);
   1502     Branch(false, &next_test);
   1503 
   1504     // Before entering the body from the test, remove the switch value from
   1505     // the stack.
   1506     frame_->Drop();
   1507 
   1508     // Label the body so that fall through is enabled.
   1509     if (i > 0 && cases->at(i - 1)->is_default()) {
   1510       default_exit.Bind();
   1511     } else {
   1512       fall_through.Bind();
   1513       fall_through.Unuse();
   1514     }
   1515     VisitStatementsAndSpill(clause->statements());
   1516 
   1517     // If control flow can fall through from the body, jump to the next body
   1518     // or the end of the statement.
   1519     if (frame_ != NULL) {
   1520       if (i < length - 1 && cases->at(i + 1)->is_default()) {
   1521         default_entry.Jump();
   1522       } else {
   1523         fall_through.Jump();
   1524       }
   1525     }
   1526   }
   1527 
   1528   // The final "test" removes the switch value.
   1529   next_test.Bind();
   1530   frame_->Drop();
   1531 
   1532   // If there is a default clause, compile it.
   1533   if (default_clause != NULL) {
   1534     Comment cmnt(masm_, "[ Default clause");
   1535     default_entry.Bind();
   1536     VisitStatementsAndSpill(default_clause->statements());
   1537     // If control flow can fall out of the default and there is a case after
   1538     // it, jup to that case's body.
   1539     if (frame_ != NULL && default_exit.is_bound()) {
   1540       default_exit.Jump();
   1541     }
   1542   }
   1543 
   1544   if (fall_through.is_linked()) {
   1545     fall_through.Bind();
   1546   }
   1547 
   1548   if (node->break_target()->is_linked()) {
   1549     node->break_target()->Bind();
   1550   }
   1551   node->break_target()->Unuse();
   1552   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1553 }
   1554 
   1555 
   1556 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
   1557 #ifdef DEBUG
   1558   int original_height = frame_->height();
   1559 #endif
   1560   VirtualFrame::SpilledScope spilled_scope;
   1561   Comment cmnt(masm_, "[ DoWhileStatement");
   1562   CodeForStatementPosition(node);
   1563   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1564   JumpTarget body(JumpTarget::BIDIRECTIONAL);
   1565 
   1566   // Label the top of the loop for the backward CFG edge.  If the test
   1567   // is always true we can use the continue target, and if the test is
   1568   // always false there is no need.
   1569   ConditionAnalysis info = AnalyzeCondition(node->cond());
   1570   switch (info) {
   1571     case ALWAYS_TRUE:
   1572       node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   1573       node->continue_target()->Bind();
   1574       break;
   1575     case ALWAYS_FALSE:
   1576       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1577       break;
   1578     case DONT_KNOW:
   1579       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1580       body.Bind();
   1581       break;
   1582   }
   1583 
   1584   CheckStack();  // TODO(1222600): ignore if body contains calls.
   1585   VisitAndSpill(node->body());
   1586 
   1587   // Compile the test.
   1588   switch (info) {
   1589     case ALWAYS_TRUE:
   1590       // If control can fall off the end of the body, jump back to the
   1591       // top.
   1592       if (has_valid_frame()) {
   1593         node->continue_target()->Jump();
   1594       }
   1595       break;
   1596     case ALWAYS_FALSE:
   1597       // If we have a continue in the body, we only have to bind its
   1598       // jump target.
   1599       if (node->continue_target()->is_linked()) {
   1600         node->continue_target()->Bind();
   1601       }
   1602       break;
   1603     case DONT_KNOW:
   1604       // We have to compile the test expression if it can be reached by
   1605       // control flow falling out of the body or via continue.
   1606       if (node->continue_target()->is_linked()) {
   1607         node->continue_target()->Bind();
   1608       }
   1609       if (has_valid_frame()) {
   1610         Comment cmnt(masm_, "[ DoWhileCondition");
   1611         CodeForDoWhileConditionPosition(node);
   1612         LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
   1613         if (has_valid_frame()) {
   1614           // A invalid frame here indicates that control did not
   1615           // fall out of the test expression.
   1616           Branch(true, &body);
   1617         }
   1618       }
   1619       break;
   1620   }
   1621 
   1622   if (node->break_target()->is_linked()) {
   1623     node->break_target()->Bind();
   1624   }
   1625   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1626 }
   1627 
   1628 
   1629 void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
   1630 #ifdef DEBUG
   1631   int original_height = frame_->height();
   1632 #endif
   1633   VirtualFrame::SpilledScope spilled_scope;
   1634   Comment cmnt(masm_, "[ WhileStatement");
   1635   CodeForStatementPosition(node);
   1636 
   1637   // If the test is never true and has no side effects there is no need
   1638   // to compile the test or body.
   1639   ConditionAnalysis info = AnalyzeCondition(node->cond());
   1640   if (info == ALWAYS_FALSE) return;
   1641 
   1642   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1643 
   1644   // Label the top of the loop with the continue target for the backward
   1645   // CFG edge.
   1646   node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   1647   node->continue_target()->Bind();
   1648 
   1649   if (info == DONT_KNOW) {
   1650     JumpTarget body;
   1651     LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
   1652     if (has_valid_frame()) {
   1653       // A NULL frame indicates that control did not fall out of the
   1654       // test expression.
   1655       Branch(false, node->break_target());
   1656     }
   1657     if (has_valid_frame() || body.is_linked()) {
   1658       body.Bind();
   1659     }
   1660   }
   1661 
   1662   if (has_valid_frame()) {
   1663     CheckStack();  // TODO(1222600): ignore if body contains calls.
   1664     VisitAndSpill(node->body());
   1665 
   1666     // If control flow can fall out of the body, jump back to the top.
   1667     if (has_valid_frame()) {
   1668       node->continue_target()->Jump();
   1669     }
   1670   }
   1671   if (node->break_target()->is_linked()) {
   1672     node->break_target()->Bind();
   1673   }
   1674   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1675 }
   1676 
   1677 
   1678 void CodeGenerator::VisitForStatement(ForStatement* node) {
   1679 #ifdef DEBUG
   1680   int original_height = frame_->height();
   1681 #endif
   1682   VirtualFrame::SpilledScope spilled_scope;
   1683   Comment cmnt(masm_, "[ ForStatement");
   1684   CodeForStatementPosition(node);
   1685   if (node->init() != NULL) {
   1686     VisitAndSpill(node->init());
   1687   }
   1688 
   1689   // If the test is never true there is no need to compile the test or
   1690   // body.
   1691   ConditionAnalysis info = AnalyzeCondition(node->cond());
   1692   if (info == ALWAYS_FALSE) return;
   1693 
   1694   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1695 
   1696   // If there is no update statement, label the top of the loop with the
   1697   // continue target, otherwise with the loop target.
   1698   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
   1699   if (node->next() == NULL) {
   1700     node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   1701     node->continue_target()->Bind();
   1702   } else {
   1703     node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1704     loop.Bind();
   1705   }
   1706 
   1707   // If the test is always true, there is no need to compile it.
   1708   if (info == DONT_KNOW) {
   1709     JumpTarget body;
   1710     LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
   1711     if (has_valid_frame()) {
   1712       Branch(false, node->break_target());
   1713     }
   1714     if (has_valid_frame() || body.is_linked()) {
   1715       body.Bind();
   1716     }
   1717   }
   1718 
   1719   if (has_valid_frame()) {
   1720     CheckStack();  // TODO(1222600): ignore if body contains calls.
   1721     VisitAndSpill(node->body());
   1722 
   1723     if (node->next() == NULL) {
   1724       // If there is no update statement and control flow can fall out
   1725       // of the loop, jump directly to the continue label.
   1726       if (has_valid_frame()) {
   1727         node->continue_target()->Jump();
   1728       }
   1729     } else {
   1730       // If there is an update statement and control flow can reach it
   1731       // via falling out of the body of the loop or continuing, we
   1732       // compile the update statement.
   1733       if (node->continue_target()->is_linked()) {
   1734         node->continue_target()->Bind();
   1735       }
   1736       if (has_valid_frame()) {
   1737         // Record source position of the statement as this code which is
   1738         // after the code for the body actually belongs to the loop
   1739         // statement and not the body.
   1740         CodeForStatementPosition(node);
   1741         VisitAndSpill(node->next());
   1742         loop.Jump();
   1743       }
   1744     }
   1745   }
   1746   if (node->break_target()->is_linked()) {
   1747     node->break_target()->Bind();
   1748   }
   1749   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   1750 }
   1751 
   1752 
   1753 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
   1754 #ifdef DEBUG
   1755   int original_height = frame_->height();
   1756 #endif
   1757   VirtualFrame::SpilledScope spilled_scope;
   1758   Comment cmnt(masm_, "[ ForInStatement");
   1759   CodeForStatementPosition(node);
   1760 
   1761   JumpTarget primitive;
   1762   JumpTarget jsobject;
   1763   JumpTarget fixed_array;
   1764   JumpTarget entry(JumpTarget::BIDIRECTIONAL);
   1765   JumpTarget end_del_check;
   1766   JumpTarget exit;
   1767 
   1768   // Get the object to enumerate over (converted to JSObject).
   1769   LoadAndSpill(node->enumerable());
   1770 
   1771   // Both SpiderMonkey and kjs ignore null and undefined in contrast
   1772   // to the specification.  12.6.4 mandates a call to ToObject.
   1773   frame_->EmitPop(r0);
   1774   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   1775   __ cmp(r0, ip);
   1776   exit.Branch(eq);
   1777   __ LoadRoot(ip, Heap::kNullValueRootIndex);
   1778   __ cmp(r0, ip);
   1779   exit.Branch(eq);
   1780 
   1781   // Stack layout in body:
   1782   // [iteration counter (Smi)]
   1783   // [length of array]
   1784   // [FixedArray]
   1785   // [Map or 0]
   1786   // [Object]
   1787 
   1788   // Check if enumerable is already a JSObject
   1789   __ tst(r0, Operand(kSmiTagMask));
   1790   primitive.Branch(eq);
   1791   __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
   1792   jsobject.Branch(hs);
   1793 
   1794   primitive.Bind();
   1795   frame_->EmitPush(r0);
   1796   frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, 1);
   1797 
   1798   jsobject.Bind();
   1799   // Get the set of properties (as a FixedArray or Map).
   1800   // r0: value to be iterated over
   1801   frame_->EmitPush(r0);  // Push the object being iterated over.
   1802 
   1803   // Check cache validity in generated code. This is a fast case for
   1804   // the JSObject::IsSimpleEnum cache validity checks. If we cannot
   1805   // guarantee cache validity, call the runtime system to check cache
   1806   // validity or get the property names in a fixed array.
   1807   JumpTarget call_runtime;
   1808   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
   1809   JumpTarget check_prototype;
   1810   JumpTarget use_cache;
   1811   __ mov(r1, Operand(r0));
   1812   loop.Bind();
   1813   // Check that there are no elements.
   1814   __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
   1815   __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex);
   1816   __ cmp(r2, r4);
   1817   call_runtime.Branch(ne);
   1818   // Check that instance descriptors are not empty so that we can
   1819   // check for an enum cache.  Leave the map in r3 for the subsequent
   1820   // prototype load.
   1821   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
   1822   __ ldr(r2, FieldMemOperand(r3, Map::kInstanceDescriptorsOffset));
   1823   __ LoadRoot(ip, Heap::kEmptyDescriptorArrayRootIndex);
   1824   __ cmp(r2, ip);
   1825   call_runtime.Branch(eq);
   1826   // Check that there in an enum cache in the non-empty instance
   1827   // descriptors.  This is the case if the next enumeration index
   1828   // field does not contain a smi.
   1829   __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumerationIndexOffset));
   1830   __ tst(r2, Operand(kSmiTagMask));
   1831   call_runtime.Branch(eq);
   1832   // For all objects but the receiver, check that the cache is empty.
   1833   // r4: empty fixed array root.
   1834   __ cmp(r1, r0);
   1835   check_prototype.Branch(eq);
   1836   __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheBridgeCacheOffset));
   1837   __ cmp(r2, r4);
   1838   call_runtime.Branch(ne);
   1839   check_prototype.Bind();
   1840   // Load the prototype from the map and loop if non-null.
   1841   __ ldr(r1, FieldMemOperand(r3, Map::kPrototypeOffset));
   1842   __ LoadRoot(ip, Heap::kNullValueRootIndex);
   1843   __ cmp(r1, ip);
   1844   loop.Branch(ne);
   1845   // The enum cache is valid.  Load the map of the object being
   1846   // iterated over and use the cache for the iteration.
   1847   __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
   1848   use_cache.Jump();
   1849 
   1850   call_runtime.Bind();
   1851   // Call the runtime to get the property names for the object.
   1852   frame_->EmitPush(r0);  // push the object (slot 4) for the runtime call
   1853   frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1);
   1854 
   1855   // If we got a map from the runtime call, we can do a fast
   1856   // modification check. Otherwise, we got a fixed array, and we have
   1857   // to do a slow check.
   1858   // r0: map or fixed array (result from call to
   1859   // Runtime::kGetPropertyNamesFast)
   1860   __ mov(r2, Operand(r0));
   1861   __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
   1862   __ LoadRoot(ip, Heap::kMetaMapRootIndex);
   1863   __ cmp(r1, ip);
   1864   fixed_array.Branch(ne);
   1865 
   1866   use_cache.Bind();
   1867   // Get enum cache
   1868   // r0: map (either the result from a call to
   1869   // Runtime::kGetPropertyNamesFast or has been fetched directly from
   1870   // the object)
   1871   __ mov(r1, Operand(r0));
   1872   __ ldr(r1, FieldMemOperand(r1, Map::kInstanceDescriptorsOffset));
   1873   __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset));
   1874   __ ldr(r2,
   1875          FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
   1876 
   1877   frame_->EmitPush(r0);  // map
   1878   frame_->EmitPush(r2);  // enum cache bridge cache
   1879   __ ldr(r0, FieldMemOperand(r2, FixedArray::kLengthOffset));
   1880   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   1881   frame_->EmitPush(r0);
   1882   __ mov(r0, Operand(Smi::FromInt(0)));
   1883   frame_->EmitPush(r0);
   1884   entry.Jump();
   1885 
   1886   fixed_array.Bind();
   1887   __ mov(r1, Operand(Smi::FromInt(0)));
   1888   frame_->EmitPush(r1);  // insert 0 in place of Map
   1889   frame_->EmitPush(r0);
   1890 
   1891   // Push the length of the array and the initial index onto the stack.
   1892   __ ldr(r0, FieldMemOperand(r0, FixedArray::kLengthOffset));
   1893   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   1894   frame_->EmitPush(r0);
   1895   __ mov(r0, Operand(Smi::FromInt(0)));  // init index
   1896   frame_->EmitPush(r0);
   1897 
   1898   // Condition.
   1899   entry.Bind();
   1900   // sp[0] : index
   1901   // sp[1] : array/enum cache length
   1902   // sp[2] : array or enum cache
   1903   // sp[3] : 0 or map
   1904   // sp[4] : enumerable
   1905   // Grab the current frame's height for the break and continue
   1906   // targets only after all the state is pushed on the frame.
   1907   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1908   node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   1909 
   1910   __ ldr(r0, frame_->ElementAt(0));  // load the current count
   1911   __ ldr(r1, frame_->ElementAt(1));  // load the length
   1912   __ cmp(r0, Operand(r1));  // compare to the array length
   1913   node->break_target()->Branch(hs);
   1914 
   1915   __ ldr(r0, frame_->ElementAt(0));
   1916 
   1917   // Get the i'th entry of the array.
   1918   __ ldr(r2, frame_->ElementAt(2));
   1919   __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   1920   __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
   1921 
   1922   // Get Map or 0.
   1923   __ ldr(r2, frame_->ElementAt(3));
   1924   // Check if this (still) matches the map of the enumerable.
   1925   // If not, we have to filter the key.
   1926   __ ldr(r1, frame_->ElementAt(4));
   1927   __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
   1928   __ cmp(r1, Operand(r2));
   1929   end_del_check.Branch(eq);
   1930 
   1931   // Convert the entry to a string (or null if it isn't a property anymore).
   1932   __ ldr(r0, frame_->ElementAt(4));  // push enumerable
   1933   frame_->EmitPush(r0);
   1934   frame_->EmitPush(r3);  // push entry
   1935   frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, 2);
   1936   __ mov(r3, Operand(r0));
   1937 
   1938   // If the property has been removed while iterating, we just skip it.
   1939   __ LoadRoot(ip, Heap::kNullValueRootIndex);
   1940   __ cmp(r3, ip);
   1941   node->continue_target()->Branch(eq);
   1942 
   1943   end_del_check.Bind();
   1944   // Store the entry in the 'each' expression and take another spin in the
   1945   // loop.  r3: i'th entry of the enum cache (or string there of)
   1946   frame_->EmitPush(r3);  // push entry
   1947   { Reference each(this, node->each());
   1948     if (!each.is_illegal()) {
   1949       if (each.size() > 0) {
   1950         __ ldr(r0, frame_->ElementAt(each.size()));
   1951         frame_->EmitPush(r0);
   1952         each.SetValue(NOT_CONST_INIT);
   1953         frame_->Drop(2);
   1954       } else {
   1955         // If the reference was to a slot we rely on the convenient property
   1956         // that it doesn't matter whether a value (eg, r3 pushed above) is
   1957         // right on top of or right underneath a zero-sized reference.
   1958         each.SetValue(NOT_CONST_INIT);
   1959         frame_->Drop();
   1960       }
   1961     }
   1962   }
   1963   // Body.
   1964   CheckStack();  // TODO(1222600): ignore if body contains calls.
   1965   VisitAndSpill(node->body());
   1966 
   1967   // Next.  Reestablish a spilled frame in case we are coming here via
   1968   // a continue in the body.
   1969   node->continue_target()->Bind();
   1970   frame_->SpillAll();
   1971   frame_->EmitPop(r0);
   1972   __ add(r0, r0, Operand(Smi::FromInt(1)));
   1973   frame_->EmitPush(r0);
   1974   entry.Jump();
   1975 
   1976   // Cleanup.  No need to spill because VirtualFrame::Drop is safe for
   1977   // any frame.
   1978   node->break_target()->Bind();
   1979   frame_->Drop(5);
   1980 
   1981   // Exit.
   1982   exit.Bind();
   1983   node->continue_target()->Unuse();
   1984   node->break_target()->Unuse();
   1985   ASSERT(frame_->height() == original_height);
   1986 }
   1987 
   1988 
   1989 void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
   1990 #ifdef DEBUG
   1991   int original_height = frame_->height();
   1992 #endif
   1993   VirtualFrame::SpilledScope spilled_scope;
   1994   Comment cmnt(masm_, "[ TryCatchStatement");
   1995   CodeForStatementPosition(node);
   1996 
   1997   JumpTarget try_block;
   1998   JumpTarget exit;
   1999 
   2000   try_block.Call();
   2001   // --- Catch block ---
   2002   frame_->EmitPush(r0);
   2003 
   2004   // Store the caught exception in the catch variable.
   2005   Variable* catch_var = node->catch_var()->var();
   2006   ASSERT(catch_var != NULL && catch_var->slot() != NULL);
   2007   StoreToSlot(catch_var->slot(), NOT_CONST_INIT);
   2008 
   2009   // Remove the exception from the stack.
   2010   frame_->Drop();
   2011 
   2012   VisitStatementsAndSpill(node->catch_block()->statements());
   2013   if (frame_ != NULL) {
   2014     exit.Jump();
   2015   }
   2016 
   2017 
   2018   // --- Try block ---
   2019   try_block.Bind();
   2020 
   2021   frame_->PushTryHandler(TRY_CATCH_HANDLER);
   2022   int handler_height = frame_->height();
   2023 
   2024   // Shadow the labels for all escapes from the try block, including
   2025   // returns. During shadowing, the original label is hidden as the
   2026   // LabelShadow and operations on the original actually affect the
   2027   // shadowing label.
   2028   //
   2029   // We should probably try to unify the escaping labels and the return
   2030   // label.
   2031   int nof_escapes = node->escaping_targets()->length();
   2032   List<ShadowTarget*> shadows(1 + nof_escapes);
   2033 
   2034   // Add the shadow target for the function return.
   2035   static const int kReturnShadowIndex = 0;
   2036   shadows.Add(new ShadowTarget(&function_return_));
   2037   bool function_return_was_shadowed = function_return_is_shadowed_;
   2038   function_return_is_shadowed_ = true;
   2039   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
   2040 
   2041   // Add the remaining shadow targets.
   2042   for (int i = 0; i < nof_escapes; i++) {
   2043     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
   2044   }
   2045 
   2046   // Generate code for the statements in the try block.
   2047   VisitStatementsAndSpill(node->try_block()->statements());
   2048 
   2049   // Stop the introduced shadowing and count the number of required unlinks.
   2050   // After shadowing stops, the original labels are unshadowed and the
   2051   // LabelShadows represent the formerly shadowing labels.
   2052   bool has_unlinks = false;
   2053   for (int i = 0; i < shadows.length(); i++) {
   2054     shadows[i]->StopShadowing();
   2055     has_unlinks = has_unlinks || shadows[i]->is_linked();
   2056   }
   2057   function_return_is_shadowed_ = function_return_was_shadowed;
   2058 
   2059   // Get an external reference to the handler address.
   2060   ExternalReference handler_address(Top::k_handler_address);
   2061 
   2062   // If we can fall off the end of the try block, unlink from try chain.
   2063   if (has_valid_frame()) {
   2064     // The next handler address is on top of the frame.  Unlink from
   2065     // the handler list and drop the rest of this handler from the
   2066     // frame.
   2067     ASSERT(StackHandlerConstants::kNextOffset == 0);
   2068     frame_->EmitPop(r1);
   2069     __ mov(r3, Operand(handler_address));
   2070     __ str(r1, MemOperand(r3));
   2071     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   2072     if (has_unlinks) {
   2073       exit.Jump();
   2074     }
   2075   }
   2076 
   2077   // Generate unlink code for the (formerly) shadowing labels that have been
   2078   // jumped to.  Deallocate each shadow target.
   2079   for (int i = 0; i < shadows.length(); i++) {
   2080     if (shadows[i]->is_linked()) {
   2081       // Unlink from try chain;
   2082       shadows[i]->Bind();
   2083       // Because we can be jumping here (to spilled code) from unspilled
   2084       // code, we need to reestablish a spilled frame at this block.
   2085       frame_->SpillAll();
   2086 
   2087       // Reload sp from the top handler, because some statements that we
   2088       // break from (eg, for...in) may have left stuff on the stack.
   2089       __ mov(r3, Operand(handler_address));
   2090       __ ldr(sp, MemOperand(r3));
   2091       frame_->Forget(frame_->height() - handler_height);
   2092 
   2093       ASSERT(StackHandlerConstants::kNextOffset == 0);
   2094       frame_->EmitPop(r1);
   2095       __ str(r1, MemOperand(r3));
   2096       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   2097 
   2098       if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
   2099         frame_->PrepareForReturn();
   2100       }
   2101       shadows[i]->other_target()->Jump();
   2102     }
   2103   }
   2104 
   2105   exit.Bind();
   2106   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   2107 }
   2108 
   2109 
   2110 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
   2111 #ifdef DEBUG
   2112   int original_height = frame_->height();
   2113 #endif
   2114   VirtualFrame::SpilledScope spilled_scope;
   2115   Comment cmnt(masm_, "[ TryFinallyStatement");
   2116   CodeForStatementPosition(node);
   2117 
   2118   // State: Used to keep track of reason for entering the finally
   2119   // block. Should probably be extended to hold information for
   2120   // break/continue from within the try block.
   2121   enum { FALLING, THROWING, JUMPING };
   2122 
   2123   JumpTarget try_block;
   2124   JumpTarget finally_block;
   2125 
   2126   try_block.Call();
   2127 
   2128   frame_->EmitPush(r0);  // save exception object on the stack
   2129   // In case of thrown exceptions, this is where we continue.
   2130   __ mov(r2, Operand(Smi::FromInt(THROWING)));
   2131   finally_block.Jump();
   2132 
   2133   // --- Try block ---
   2134   try_block.Bind();
   2135 
   2136   frame_->PushTryHandler(TRY_FINALLY_HANDLER);
   2137   int handler_height = frame_->height();
   2138 
   2139   // Shadow the labels for all escapes from the try block, including
   2140   // returns.  Shadowing hides the original label as the LabelShadow and
   2141   // operations on the original actually affect the shadowing label.
   2142   //
   2143   // We should probably try to unify the escaping labels and the return
   2144   // label.
   2145   int nof_escapes = node->escaping_targets()->length();
   2146   List<ShadowTarget*> shadows(1 + nof_escapes);
   2147 
   2148   // Add the shadow target for the function return.
   2149   static const int kReturnShadowIndex = 0;
   2150   shadows.Add(new ShadowTarget(&function_return_));
   2151   bool function_return_was_shadowed = function_return_is_shadowed_;
   2152   function_return_is_shadowed_ = true;
   2153   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
   2154 
   2155   // Add the remaining shadow targets.
   2156   for (int i = 0; i < nof_escapes; i++) {
   2157     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
   2158   }
   2159 
   2160   // Generate code for the statements in the try block.
   2161   VisitStatementsAndSpill(node->try_block()->statements());
   2162 
   2163   // Stop the introduced shadowing and count the number of required unlinks.
   2164   // After shadowing stops, the original labels are unshadowed and the
   2165   // LabelShadows represent the formerly shadowing labels.
   2166   int nof_unlinks = 0;
   2167   for (int i = 0; i < shadows.length(); i++) {
   2168     shadows[i]->StopShadowing();
   2169     if (shadows[i]->is_linked()) nof_unlinks++;
   2170   }
   2171   function_return_is_shadowed_ = function_return_was_shadowed;
   2172 
   2173   // Get an external reference to the handler address.
   2174   ExternalReference handler_address(Top::k_handler_address);
   2175 
   2176   // If we can fall off the end of the try block, unlink from the try
   2177   // chain and set the state on the frame to FALLING.
   2178   if (has_valid_frame()) {
   2179     // The next handler address is on top of the frame.
   2180     ASSERT(StackHandlerConstants::kNextOffset == 0);
   2181     frame_->EmitPop(r1);
   2182     __ mov(r3, Operand(handler_address));
   2183     __ str(r1, MemOperand(r3));
   2184     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   2185 
   2186     // Fake a top of stack value (unneeded when FALLING) and set the
   2187     // state in r2, then jump around the unlink blocks if any.
   2188     __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   2189     frame_->EmitPush(r0);
   2190     __ mov(r2, Operand(Smi::FromInt(FALLING)));
   2191     if (nof_unlinks > 0) {
   2192       finally_block.Jump();
   2193     }
   2194   }
   2195 
   2196   // Generate code to unlink and set the state for the (formerly)
   2197   // shadowing targets that have been jumped to.
   2198   for (int i = 0; i < shadows.length(); i++) {
   2199     if (shadows[i]->is_linked()) {
   2200       // If we have come from the shadowed return, the return value is
   2201       // in (a non-refcounted reference to) r0.  We must preserve it
   2202       // until it is pushed.
   2203       //
   2204       // Because we can be jumping here (to spilled code) from
   2205       // unspilled code, we need to reestablish a spilled frame at
   2206       // this block.
   2207       shadows[i]->Bind();
   2208       frame_->SpillAll();
   2209 
   2210       // Reload sp from the top handler, because some statements that
   2211       // we break from (eg, for...in) may have left stuff on the
   2212       // stack.
   2213       __ mov(r3, Operand(handler_address));
   2214       __ ldr(sp, MemOperand(r3));
   2215       frame_->Forget(frame_->height() - handler_height);
   2216 
   2217       // Unlink this handler and drop it from the frame.  The next
   2218       // handler address is currently on top of the frame.
   2219       ASSERT(StackHandlerConstants::kNextOffset == 0);
   2220       frame_->EmitPop(r1);
   2221       __ str(r1, MemOperand(r3));
   2222       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   2223 
   2224       if (i == kReturnShadowIndex) {
   2225         // If this label shadowed the function return, materialize the
   2226         // return value on the stack.
   2227         frame_->EmitPush(r0);
   2228       } else {
   2229         // Fake TOS for targets that shadowed breaks and continues.
   2230         __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   2231         frame_->EmitPush(r0);
   2232       }
   2233       __ mov(r2, Operand(Smi::FromInt(JUMPING + i)));
   2234       if (--nof_unlinks > 0) {
   2235         // If this is not the last unlink block, jump around the next.
   2236         finally_block.Jump();
   2237       }
   2238     }
   2239   }
   2240 
   2241   // --- Finally block ---
   2242   finally_block.Bind();
   2243 
   2244   // Push the state on the stack.
   2245   frame_->EmitPush(r2);
   2246 
   2247   // We keep two elements on the stack - the (possibly faked) result
   2248   // and the state - while evaluating the finally block.
   2249   //
   2250   // Generate code for the statements in the finally block.
   2251   VisitStatementsAndSpill(node->finally_block()->statements());
   2252 
   2253   if (has_valid_frame()) {
   2254     // Restore state and return value or faked TOS.
   2255     frame_->EmitPop(r2);
   2256     frame_->EmitPop(r0);
   2257   }
   2258 
   2259   // Generate code to jump to the right destination for all used
   2260   // formerly shadowing targets.  Deallocate each shadow target.
   2261   for (int i = 0; i < shadows.length(); i++) {
   2262     if (has_valid_frame() && shadows[i]->is_bound()) {
   2263       JumpTarget* original = shadows[i]->other_target();
   2264       __ cmp(r2, Operand(Smi::FromInt(JUMPING + i)));
   2265       if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
   2266         JumpTarget skip;
   2267         skip.Branch(ne);
   2268         frame_->PrepareForReturn();
   2269         original->Jump();
   2270         skip.Bind();
   2271       } else {
   2272         original->Branch(eq);
   2273       }
   2274     }
   2275   }
   2276 
   2277   if (has_valid_frame()) {
   2278     // Check if we need to rethrow the exception.
   2279     JumpTarget exit;
   2280     __ cmp(r2, Operand(Smi::FromInt(THROWING)));
   2281     exit.Branch(ne);
   2282 
   2283     // Rethrow exception.
   2284     frame_->EmitPush(r0);
   2285     frame_->CallRuntime(Runtime::kReThrow, 1);
   2286 
   2287     // Done.
   2288     exit.Bind();
   2289   }
   2290   ASSERT(!has_valid_frame() || frame_->height() == original_height);
   2291 }
   2292 
   2293 
   2294 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
   2295 #ifdef DEBUG
   2296   int original_height = frame_->height();
   2297 #endif
   2298   VirtualFrame::SpilledScope spilled_scope;
   2299   Comment cmnt(masm_, "[ DebuggerStatament");
   2300   CodeForStatementPosition(node);
   2301 #ifdef ENABLE_DEBUGGER_SUPPORT
   2302   frame_->DebugBreak();
   2303 #endif
   2304   // Ignore the return value.
   2305   ASSERT(frame_->height() == original_height);
   2306 }
   2307 
   2308 
   2309 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
   2310   VirtualFrame::SpilledScope spilled_scope;
   2311   ASSERT(boilerplate->IsBoilerplate());
   2312 
   2313   __ mov(r0, Operand(boilerplate));
   2314   // Use the fast case closure allocation code that allocates in new
   2315   // space for nested functions that don't need literals cloning.
   2316   if (scope()->is_function_scope() && boilerplate->NumberOfLiterals() == 0) {
   2317     FastNewClosureStub stub;
   2318     frame_->EmitPush(r0);
   2319     frame_->CallStub(&stub, 1);
   2320     frame_->EmitPush(r0);
   2321   } else {
   2322     // Create a new closure.
   2323     frame_->EmitPush(cp);
   2324     frame_->EmitPush(r0);
   2325     frame_->CallRuntime(Runtime::kNewClosure, 2);
   2326     frame_->EmitPush(r0);
   2327   }
   2328 }
   2329 
   2330 
   2331 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
   2332 #ifdef DEBUG
   2333   int original_height = frame_->height();
   2334 #endif
   2335   VirtualFrame::SpilledScope spilled_scope;
   2336   Comment cmnt(masm_, "[ FunctionLiteral");
   2337 
   2338   // Build the function boilerplate and instantiate it.
   2339   Handle<JSFunction> boilerplate =
   2340       Compiler::BuildBoilerplate(node, script(), this);
   2341   // Check for stack-overflow exception.
   2342   if (HasStackOverflow()) {
   2343     ASSERT(frame_->height() == original_height);
   2344     return;
   2345   }
   2346   InstantiateBoilerplate(boilerplate);
   2347   ASSERT(frame_->height() == original_height + 1);
   2348 }
   2349 
   2350 
   2351 void CodeGenerator::VisitFunctionBoilerplateLiteral(
   2352     FunctionBoilerplateLiteral* node) {
   2353 #ifdef DEBUG
   2354   int original_height = frame_->height();
   2355 #endif
   2356   VirtualFrame::SpilledScope spilled_scope;
   2357   Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
   2358   InstantiateBoilerplate(node->boilerplate());
   2359   ASSERT(frame_->height() == original_height + 1);
   2360 }
   2361 
   2362 
   2363 void CodeGenerator::VisitConditional(Conditional* node) {
   2364 #ifdef DEBUG
   2365   int original_height = frame_->height();
   2366 #endif
   2367   VirtualFrame::SpilledScope spilled_scope;
   2368   Comment cmnt(masm_, "[ Conditional");
   2369   JumpTarget then;
   2370   JumpTarget else_;
   2371   LoadConditionAndSpill(node->condition(), &then, &else_, true);
   2372   if (has_valid_frame()) {
   2373     Branch(false, &else_);
   2374   }
   2375   if (has_valid_frame() || then.is_linked()) {
   2376     then.Bind();
   2377     LoadAndSpill(node->then_expression());
   2378   }
   2379   if (else_.is_linked()) {
   2380     JumpTarget exit;
   2381     if (has_valid_frame()) exit.Jump();
   2382     else_.Bind();
   2383     LoadAndSpill(node->else_expression());
   2384     if (exit.is_linked()) exit.Bind();
   2385   }
   2386   ASSERT(frame_->height() == original_height + 1);
   2387 }
   2388 
   2389 
   2390 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
   2391   VirtualFrame::SpilledScope spilled_scope;
   2392   if (slot->type() == Slot::LOOKUP) {
   2393     ASSERT(slot->var()->is_dynamic());
   2394 
   2395     JumpTarget slow;
   2396     JumpTarget done;
   2397 
   2398     // Generate fast-case code for variables that might be shadowed by
   2399     // eval-introduced variables.  Eval is used a lot without
   2400     // introducing variables.  In those cases, we do not want to
   2401     // perform a runtime call for all variables in the scope
   2402     // containing the eval.
   2403     if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
   2404       LoadFromGlobalSlotCheckExtensions(slot, typeof_state, r1, r2, &slow);
   2405       // If there was no control flow to slow, we can exit early.
   2406       if (!slow.is_linked()) {
   2407         frame_->EmitPush(r0);
   2408         return;
   2409       }
   2410 
   2411       done.Jump();
   2412 
   2413     } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
   2414       Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
   2415       // Only generate the fast case for locals that rewrite to slots.
   2416       // This rules out argument loads.
   2417       if (potential_slot != NULL) {
   2418         __ ldr(r0,
   2419                ContextSlotOperandCheckExtensions(potential_slot,
   2420                                                  r1,
   2421                                                  r2,
   2422                                                  &slow));
   2423         if (potential_slot->var()->mode() == Variable::CONST) {
   2424           __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
   2425           __ cmp(r0, ip);
   2426           __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
   2427         }
   2428         // There is always control flow to slow from
   2429         // ContextSlotOperandCheckExtensions so we have to jump around
   2430         // it.
   2431         done.Jump();
   2432       }
   2433     }
   2434 
   2435     slow.Bind();
   2436     frame_->EmitPush(cp);
   2437     __ mov(r0, Operand(slot->var()->name()));
   2438     frame_->EmitPush(r0);
   2439 
   2440     if (typeof_state == INSIDE_TYPEOF) {
   2441       frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
   2442     } else {
   2443       frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
   2444     }
   2445 
   2446     done.Bind();
   2447     frame_->EmitPush(r0);
   2448 
   2449   } else {
   2450     // Special handling for locals allocated in registers.
   2451     __ ldr(r0, SlotOperand(slot, r2));
   2452     frame_->EmitPush(r0);
   2453     if (slot->var()->mode() == Variable::CONST) {
   2454       // Const slots may contain 'the hole' value (the constant hasn't been
   2455       // initialized yet) which needs to be converted into the 'undefined'
   2456       // value.
   2457       Comment cmnt(masm_, "[ Unhole const");
   2458       frame_->EmitPop(r0);
   2459       __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
   2460       __ cmp(r0, ip);
   2461       __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
   2462       frame_->EmitPush(r0);
   2463     }
   2464   }
   2465 }
   2466 
   2467 
   2468 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
   2469   ASSERT(slot != NULL);
   2470   if (slot->type() == Slot::LOOKUP) {
   2471     ASSERT(slot->var()->is_dynamic());
   2472 
   2473     // For now, just do a runtime call.
   2474     frame_->EmitPush(cp);
   2475     __ mov(r0, Operand(slot->var()->name()));
   2476     frame_->EmitPush(r0);
   2477 
   2478     if (init_state == CONST_INIT) {
   2479       // Same as the case for a normal store, but ignores attribute
   2480       // (e.g. READ_ONLY) of context slot so that we can initialize
   2481       // const properties (introduced via eval("const foo = (some
   2482       // expr);")). Also, uses the current function context instead of
   2483       // the top context.
   2484       //
   2485       // Note that we must declare the foo upon entry of eval(), via a
   2486       // context slot declaration, but we cannot initialize it at the
   2487       // same time, because the const declaration may be at the end of
   2488       // the eval code (sigh...) and the const variable may have been
   2489       // used before (where its value is 'undefined'). Thus, we can only
   2490       // do the initialization when we actually encounter the expression
   2491       // and when the expression operands are defined and valid, and
   2492       // thus we need the split into 2 operations: declaration of the
   2493       // context slot followed by initialization.
   2494       frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
   2495     } else {
   2496       frame_->CallRuntime(Runtime::kStoreContextSlot, 3);
   2497     }
   2498     // Storing a variable must keep the (new) value on the expression
   2499     // stack. This is necessary for compiling assignment expressions.
   2500     frame_->EmitPush(r0);
   2501 
   2502   } else {
   2503     ASSERT(!slot->var()->is_dynamic());
   2504 
   2505     JumpTarget exit;
   2506     if (init_state == CONST_INIT) {
   2507       ASSERT(slot->var()->mode() == Variable::CONST);
   2508       // Only the first const initialization must be executed (the slot
   2509       // still contains 'the hole' value). When the assignment is
   2510       // executed, the code is identical to a normal store (see below).
   2511       Comment cmnt(masm_, "[ Init const");
   2512       __ ldr(r2, SlotOperand(slot, r2));
   2513       __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
   2514       __ cmp(r2, ip);
   2515       exit.Branch(ne);
   2516     }
   2517 
   2518     // We must execute the store.  Storing a variable must keep the
   2519     // (new) value on the stack. This is necessary for compiling
   2520     // assignment expressions.
   2521     //
   2522     // Note: We will reach here even with slot->var()->mode() ==
   2523     // Variable::CONST because of const declarations which will
   2524     // initialize consts to 'the hole' value and by doing so, end up
   2525     // calling this code.  r2 may be loaded with context; used below in
   2526     // RecordWrite.
   2527     frame_->EmitPop(r0);
   2528     __ str(r0, SlotOperand(slot, r2));
   2529     frame_->EmitPush(r0);
   2530     if (slot->type() == Slot::CONTEXT) {
   2531       // Skip write barrier if the written value is a smi.
   2532       __ tst(r0, Operand(kSmiTagMask));
   2533       exit.Branch(eq);
   2534       // r2 is loaded with context when calling SlotOperand above.
   2535       int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
   2536       __ mov(r3, Operand(offset));
   2537       __ RecordWrite(r2, r3, r1);
   2538     }
   2539     // If we definitely did not jump over the assignment, we do not need
   2540     // to bind the exit label.  Doing so can defeat peephole
   2541     // optimization.
   2542     if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) {
   2543       exit.Bind();
   2544     }
   2545   }
   2546 }
   2547 
   2548 
   2549 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot,
   2550                                                       TypeofState typeof_state,
   2551                                                       Register tmp,
   2552                                                       Register tmp2,
   2553                                                       JumpTarget* slow) {
   2554   // Check that no extension objects have been created by calls to
   2555   // eval from the current scope to the global scope.
   2556   Register context = cp;
   2557   Scope* s = scope();
   2558   while (s != NULL) {
   2559     if (s->num_heap_slots() > 0) {
   2560       if (s->calls_eval()) {
   2561         // Check that extension is NULL.
   2562         __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX));
   2563         __ tst(tmp2, tmp2);
   2564         slow->Branch(ne);
   2565       }
   2566       // Load next context in chain.
   2567       __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
   2568       __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
   2569       context = tmp;
   2570     }
   2571     // If no outer scope calls eval, we do not need to check more
   2572     // context extensions.
   2573     if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
   2574     s = s->outer_scope();
   2575   }
   2576 
   2577   if (s->is_eval_scope()) {
   2578     Label next, fast;
   2579     if (!context.is(tmp)) {
   2580       __ mov(tmp, Operand(context));
   2581     }
   2582     __ bind(&next);
   2583     // Terminate at global context.
   2584     __ ldr(tmp2, FieldMemOperand(tmp, HeapObject::kMapOffset));
   2585     __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
   2586     __ cmp(tmp2, ip);
   2587     __ b(eq, &fast);
   2588     // Check that extension is NULL.
   2589     __ ldr(tmp2, ContextOperand(tmp, Context::EXTENSION_INDEX));
   2590     __ tst(tmp2, tmp2);
   2591     slow->Branch(ne);
   2592     // Load next context in chain.
   2593     __ ldr(tmp, ContextOperand(tmp, Context::CLOSURE_INDEX));
   2594     __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
   2595     __ b(&next);
   2596     __ bind(&fast);
   2597   }
   2598 
   2599   // All extension objects were empty and it is safe to use a global
   2600   // load IC call.
   2601   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
   2602   // Load the global object.
   2603   LoadGlobal();
   2604   // Setup the name register.
   2605   __ mov(r2, Operand(slot->var()->name()));
   2606   // Call IC stub.
   2607   if (typeof_state == INSIDE_TYPEOF) {
   2608     frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
   2609   } else {
   2610     frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0);
   2611   }
   2612 
   2613   // Drop the global object. The result is in r0.
   2614   frame_->Drop();
   2615 }
   2616 
   2617 
   2618 void CodeGenerator::VisitSlot(Slot* node) {
   2619 #ifdef DEBUG
   2620   int original_height = frame_->height();
   2621 #endif
   2622   VirtualFrame::SpilledScope spilled_scope;
   2623   Comment cmnt(masm_, "[ Slot");
   2624   LoadFromSlot(node, NOT_INSIDE_TYPEOF);
   2625   ASSERT(frame_->height() == original_height + 1);
   2626 }
   2627 
   2628 
   2629 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
   2630 #ifdef DEBUG
   2631   int original_height = frame_->height();
   2632 #endif
   2633   VirtualFrame::SpilledScope spilled_scope;
   2634   Comment cmnt(masm_, "[ VariableProxy");
   2635 
   2636   Variable* var = node->var();
   2637   Expression* expr = var->rewrite();
   2638   if (expr != NULL) {
   2639     Visit(expr);
   2640   } else {
   2641     ASSERT(var->is_global());
   2642     Reference ref(this, node);
   2643     ref.GetValueAndSpill();
   2644   }
   2645   ASSERT(frame_->height() == original_height + 1);
   2646 }
   2647 
   2648 
   2649 void CodeGenerator::VisitLiteral(Literal* node) {
   2650 #ifdef DEBUG
   2651   int original_height = frame_->height();
   2652 #endif
   2653   VirtualFrame::SpilledScope spilled_scope;
   2654   Comment cmnt(masm_, "[ Literal");
   2655   __ mov(r0, Operand(node->handle()));
   2656   frame_->EmitPush(r0);
   2657   ASSERT(frame_->height() == original_height + 1);
   2658 }
   2659 
   2660 
   2661 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
   2662 #ifdef DEBUG
   2663   int original_height = frame_->height();
   2664 #endif
   2665   VirtualFrame::SpilledScope spilled_scope;
   2666   Comment cmnt(masm_, "[ RexExp Literal");
   2667 
   2668   // Retrieve the literal array and check the allocated entry.
   2669 
   2670   // Load the function of this activation.
   2671   __ ldr(r1, frame_->Function());
   2672 
   2673   // Load the literals array of the function.
   2674   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
   2675 
   2676   // Load the literal at the ast saved index.
   2677   int literal_offset =
   2678       FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
   2679   __ ldr(r2, FieldMemOperand(r1, literal_offset));
   2680 
   2681   JumpTarget done;
   2682   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   2683   __ cmp(r2, ip);
   2684   done.Branch(ne);
   2685 
   2686   // If the entry is undefined we call the runtime system to computed
   2687   // the literal.
   2688   frame_->EmitPush(r1);  // literal array  (0)
   2689   __ mov(r0, Operand(Smi::FromInt(node->literal_index())));
   2690   frame_->EmitPush(r0);  // literal index  (1)
   2691   __ mov(r0, Operand(node->pattern()));  // RegExp pattern (2)
   2692   frame_->EmitPush(r0);
   2693   __ mov(r0, Operand(node->flags()));  // RegExp flags   (3)
   2694   frame_->EmitPush(r0);
   2695   frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
   2696   __ mov(r2, Operand(r0));
   2697 
   2698   done.Bind();
   2699   // Push the literal.
   2700   frame_->EmitPush(r2);
   2701   ASSERT(frame_->height() == original_height + 1);
   2702 }
   2703 
   2704 
   2705 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
   2706 #ifdef DEBUG
   2707   int original_height = frame_->height();
   2708 #endif
   2709   VirtualFrame::SpilledScope spilled_scope;
   2710   Comment cmnt(masm_, "[ ObjectLiteral");
   2711 
   2712   // Load the function of this activation.
   2713   __ ldr(r2, frame_->Function());
   2714   // Literal array.
   2715   __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
   2716   // Literal index.
   2717   __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
   2718   // Constant properties.
   2719   __ mov(r0, Operand(node->constant_properties()));
   2720   frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
   2721   if (node->depth() > 1) {
   2722     frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
   2723   } else {
   2724     frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
   2725   }
   2726   frame_->EmitPush(r0);  // save the result
   2727   for (int i = 0; i < node->properties()->length(); i++) {
   2728     // At the start of each iteration, the top of stack contains
   2729     // the newly created object literal.
   2730     ObjectLiteral::Property* property = node->properties()->at(i);
   2731     Literal* key = property->key();
   2732     Expression* value = property->value();
   2733     switch (property->kind()) {
   2734       case ObjectLiteral::Property::CONSTANT:
   2735         break;
   2736       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   2737         if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
   2738         // else fall through
   2739       case ObjectLiteral::Property::COMPUTED:
   2740         if (key->handle()->IsSymbol()) {
   2741           Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   2742           LoadAndSpill(value);
   2743           frame_->EmitPop(r0);
   2744           __ mov(r2, Operand(key->handle()));
   2745           __ ldr(r1, frame_->Top());  // Load the receiver.
   2746           frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
   2747           break;
   2748         }
   2749         // else fall through
   2750       case ObjectLiteral::Property::PROTOTYPE: {
   2751         __ ldr(r0, frame_->Top());
   2752         frame_->EmitPush(r0);  // dup the result
   2753         LoadAndSpill(key);
   2754         LoadAndSpill(value);
   2755         frame_->CallRuntime(Runtime::kSetProperty, 3);
   2756         break;
   2757       }
   2758       case ObjectLiteral::Property::SETTER: {
   2759         __ ldr(r0, frame_->Top());
   2760         frame_->EmitPush(r0);
   2761         LoadAndSpill(key);
   2762         __ mov(r0, Operand(Smi::FromInt(1)));
   2763         frame_->EmitPush(r0);
   2764         LoadAndSpill(value);
   2765         frame_->CallRuntime(Runtime::kDefineAccessor, 4);
   2766         break;
   2767       }
   2768       case ObjectLiteral::Property::GETTER: {
   2769         __ ldr(r0, frame_->Top());
   2770         frame_->EmitPush(r0);
   2771         LoadAndSpill(key);
   2772         __ mov(r0, Operand(Smi::FromInt(0)));
   2773         frame_->EmitPush(r0);
   2774         LoadAndSpill(value);
   2775         frame_->CallRuntime(Runtime::kDefineAccessor, 4);
   2776         break;
   2777       }
   2778     }
   2779   }
   2780   ASSERT(frame_->height() == original_height + 1);
   2781 }
   2782 
   2783 
   2784 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
   2785 #ifdef DEBUG
   2786   int original_height = frame_->height();
   2787 #endif
   2788   VirtualFrame::SpilledScope spilled_scope;
   2789   Comment cmnt(masm_, "[ ArrayLiteral");
   2790 
   2791   // Load the function of this activation.
   2792   __ ldr(r2, frame_->Function());
   2793   // Load the literals array of the function.
   2794   __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
   2795   __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
   2796   __ mov(r0, Operand(node->constant_elements()));
   2797   frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
   2798   int length = node->values()->length();
   2799   if (node->depth() > 1) {
   2800     frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
   2801   } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
   2802     frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
   2803   } else {
   2804     FastCloneShallowArrayStub stub(length);
   2805     frame_->CallStub(&stub, 3);
   2806   }
   2807   frame_->EmitPush(r0);  // save the result
   2808   // r0: created object literal
   2809 
   2810   // Generate code to set the elements in the array that are not
   2811   // literals.
   2812   for (int i = 0; i < node->values()->length(); i++) {
   2813     Expression* value = node->values()->at(i);
   2814 
   2815     // If value is a literal the property value is already set in the
   2816     // boilerplate object.
   2817     if (value->AsLiteral() != NULL) continue;
   2818     // If value is a materialized literal the property value is already set
   2819     // in the boilerplate object if it is simple.
   2820     if (CompileTimeValue::IsCompileTimeValue(value)) continue;
   2821 
   2822     // The property must be set by generated code.
   2823     LoadAndSpill(value);
   2824     frame_->EmitPop(r0);
   2825 
   2826     // Fetch the object literal.
   2827     __ ldr(r1, frame_->Top());
   2828     // Get the elements array.
   2829     __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
   2830 
   2831     // Write to the indexed properties array.
   2832     int offset = i * kPointerSize + FixedArray::kHeaderSize;
   2833     __ str(r0, FieldMemOperand(r1, offset));
   2834 
   2835     // Update the write barrier for the array address.
   2836     __ mov(r3, Operand(offset));
   2837     __ RecordWrite(r1, r3, r2);
   2838   }
   2839   ASSERT(frame_->height() == original_height + 1);
   2840 }
   2841 
   2842 
   2843 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
   2844 #ifdef DEBUG
   2845   int original_height = frame_->height();
   2846 #endif
   2847   VirtualFrame::SpilledScope spilled_scope;
   2848   // Call runtime routine to allocate the catch extension object and
   2849   // assign the exception value to the catch variable.
   2850   Comment cmnt(masm_, "[ CatchExtensionObject");
   2851   LoadAndSpill(node->key());
   2852   LoadAndSpill(node->value());
   2853   frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
   2854   frame_->EmitPush(r0);
   2855   ASSERT(frame_->height() == original_height + 1);
   2856 }
   2857 
   2858 
   2859 void CodeGenerator::VisitAssignment(Assignment* node) {
   2860 #ifdef DEBUG
   2861   int original_height = frame_->height();
   2862 #endif
   2863   VirtualFrame::SpilledScope spilled_scope;
   2864   Comment cmnt(masm_, "[ Assignment");
   2865 
   2866   { Reference target(this, node->target(), node->is_compound());
   2867     if (target.is_illegal()) {
   2868       // Fool the virtual frame into thinking that we left the assignment's
   2869       // value on the frame.
   2870       __ mov(r0, Operand(Smi::FromInt(0)));
   2871       frame_->EmitPush(r0);
   2872       ASSERT(frame_->height() == original_height + 1);
   2873       return;
   2874     }
   2875 
   2876     if (node->op() == Token::ASSIGN ||
   2877         node->op() == Token::INIT_VAR ||
   2878         node->op() == Token::INIT_CONST) {
   2879       LoadAndSpill(node->value());
   2880 
   2881     } else {  // Assignment is a compound assignment.
   2882       // Get the old value of the lhs.
   2883       target.GetValueAndSpill();
   2884       Literal* literal = node->value()->AsLiteral();
   2885       bool overwrite =
   2886           (node->value()->AsBinaryOperation() != NULL &&
   2887            node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
   2888       if (literal != NULL && literal->handle()->IsSmi()) {
   2889         SmiOperation(node->binary_op(),
   2890                      literal->handle(),
   2891                      false,
   2892                      overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
   2893         frame_->EmitPush(r0);
   2894 
   2895       } else {
   2896         LoadAndSpill(node->value());
   2897         GenericBinaryOperation(node->binary_op(),
   2898                                overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
   2899         frame_->EmitPush(r0);
   2900       }
   2901     }
   2902     Variable* var = node->target()->AsVariableProxy()->AsVariable();
   2903     if (var != NULL &&
   2904         (var->mode() == Variable::CONST) &&
   2905         node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
   2906       // Assignment ignored - leave the value on the stack.
   2907       UnloadReference(&target);
   2908     } else {
   2909       CodeForSourcePosition(node->position());
   2910       if (node->op() == Token::INIT_CONST) {
   2911         // Dynamic constant initializations must use the function context
   2912         // and initialize the actual constant declared. Dynamic variable
   2913         // initializations are simply assignments and use SetValue.
   2914         target.SetValue(CONST_INIT);
   2915       } else {
   2916         target.SetValue(NOT_CONST_INIT);
   2917       }
   2918     }
   2919   }
   2920   ASSERT(frame_->height() == original_height + 1);
   2921 }
   2922 
   2923 
   2924 void CodeGenerator::VisitThrow(Throw* node) {
   2925 #ifdef DEBUG
   2926   int original_height = frame_->height();
   2927 #endif
   2928   VirtualFrame::SpilledScope spilled_scope;
   2929   Comment cmnt(masm_, "[ Throw");
   2930 
   2931   LoadAndSpill(node->exception());
   2932   CodeForSourcePosition(node->position());
   2933   frame_->CallRuntime(Runtime::kThrow, 1);
   2934   frame_->EmitPush(r0);
   2935   ASSERT(frame_->height() == original_height + 1);
   2936 }
   2937 
   2938 
   2939 void CodeGenerator::VisitProperty(Property* node) {
   2940 #ifdef DEBUG
   2941   int original_height = frame_->height();
   2942 #endif
   2943   VirtualFrame::SpilledScope spilled_scope;
   2944   Comment cmnt(masm_, "[ Property");
   2945 
   2946   { Reference property(this, node);
   2947     property.GetValueAndSpill();
   2948   }
   2949   ASSERT(frame_->height() == original_height + 1);
   2950 }
   2951 
   2952 
   2953 void CodeGenerator::VisitCall(Call* node) {
   2954 #ifdef DEBUG
   2955   int original_height = frame_->height();
   2956 #endif
   2957   VirtualFrame::SpilledScope spilled_scope;
   2958   Comment cmnt(masm_, "[ Call");
   2959 
   2960   Expression* function = node->expression();
   2961   ZoneList<Expression*>* args = node->arguments();
   2962 
   2963   // Standard function call.
   2964   // Check if the function is a variable or a property.
   2965   Variable* var = function->AsVariableProxy()->AsVariable();
   2966   Property* property = function->AsProperty();
   2967 
   2968   // ------------------------------------------------------------------------
   2969   // Fast-case: Use inline caching.
   2970   // ---
   2971   // According to ECMA-262, section 11.2.3, page 44, the function to call
   2972   // must be resolved after the arguments have been evaluated. The IC code
   2973   // automatically handles this by loading the arguments before the function
   2974   // is resolved in cache misses (this also holds for megamorphic calls).
   2975   // ------------------------------------------------------------------------
   2976 
   2977   if (var != NULL && var->is_possibly_eval()) {
   2978     // ----------------------------------
   2979     // JavaScript example: 'eval(arg)'  // eval is not known to be shadowed
   2980     // ----------------------------------
   2981 
   2982     // In a call to eval, we first call %ResolvePossiblyDirectEval to
   2983     // resolve the function we need to call and the receiver of the
   2984     // call.  Then we call the resolved function using the given
   2985     // arguments.
   2986     // Prepare stack for call to resolved function.
   2987     LoadAndSpill(function);
   2988     __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
   2989     frame_->EmitPush(r2);  // Slot for receiver
   2990     int arg_count = args->length();
   2991     for (int i = 0; i < arg_count; i++) {
   2992       LoadAndSpill(args->at(i));
   2993     }
   2994 
   2995     // Prepare stack for call to ResolvePossiblyDirectEval.
   2996     __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize));
   2997     frame_->EmitPush(r1);
   2998     if (arg_count > 0) {
   2999       __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
   3000       frame_->EmitPush(r1);
   3001     } else {
   3002       frame_->EmitPush(r2);
   3003     }
   3004 
   3005     // Push the receiver.
   3006     __ ldr(r1, frame_->Receiver());
   3007     frame_->EmitPush(r1);
   3008 
   3009     // Resolve the call.
   3010     frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
   3011 
   3012     // Touch up stack with the right values for the function and the receiver.
   3013     __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
   3014     __ str(r1, MemOperand(sp, arg_count * kPointerSize));
   3015 
   3016     // Call the function.
   3017     CodeForSourcePosition(node->position());
   3018 
   3019     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   3020     CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
   3021     frame_->CallStub(&call_function, arg_count + 1);
   3022 
   3023     __ ldr(cp, frame_->Context());
   3024     // Remove the function from the stack.
   3025     frame_->Drop();
   3026     frame_->EmitPush(r0);
   3027 
   3028   } else if (var != NULL && !var->is_this() && var->is_global()) {
   3029     // ----------------------------------
   3030     // JavaScript example: 'foo(1, 2, 3)'  // foo is global
   3031     // ----------------------------------
   3032     // Pass the global object as the receiver and let the IC stub
   3033     // patch the stack to use the global proxy as 'this' in the
   3034     // invoked function.
   3035     LoadGlobal();
   3036 
   3037     // Load the arguments.
   3038     int arg_count = args->length();
   3039     for (int i = 0; i < arg_count; i++) {
   3040       LoadAndSpill(args->at(i));
   3041     }
   3042 
   3043     // Setup the name register and call the IC initialization code.
   3044     __ mov(r2, Operand(var->name()));
   3045     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   3046     Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
   3047     CodeForSourcePosition(node->position());
   3048     frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
   3049                            arg_count + 1);
   3050     __ ldr(cp, frame_->Context());
   3051     frame_->EmitPush(r0);
   3052 
   3053   } else if (var != NULL && var->slot() != NULL &&
   3054              var->slot()->type() == Slot::LOOKUP) {
   3055     // ----------------------------------
   3056     // JavaScript example: 'with (obj) foo(1, 2, 3)'  // foo is in obj
   3057     // ----------------------------------
   3058 
   3059     // Load the function
   3060     frame_->EmitPush(cp);
   3061     __ mov(r0, Operand(var->name()));
   3062     frame_->EmitPush(r0);
   3063     frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
   3064     // r0: slot value; r1: receiver
   3065 
   3066     // Load the receiver.
   3067     frame_->EmitPush(r0);  // function
   3068     frame_->EmitPush(r1);  // receiver
   3069 
   3070     // Call the function.
   3071     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
   3072     frame_->EmitPush(r0);
   3073 
   3074   } else if (property != NULL) {
   3075     // Check if the key is a literal string.
   3076     Literal* literal = property->key()->AsLiteral();
   3077 
   3078     if (literal != NULL && literal->handle()->IsSymbol()) {
   3079       // ------------------------------------------------------------------
   3080       // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
   3081       // ------------------------------------------------------------------
   3082 
   3083       LoadAndSpill(property->obj());  // Receiver.
   3084       // Load the arguments.
   3085       int arg_count = args->length();
   3086       for (int i = 0; i < arg_count; i++) {
   3087         LoadAndSpill(args->at(i));
   3088       }
   3089 
   3090       // Set the name register and call the IC initialization code.
   3091       __ mov(r2, Operand(literal->handle()));
   3092       InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   3093       Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
   3094       CodeForSourcePosition(node->position());
   3095       frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
   3096       __ ldr(cp, frame_->Context());
   3097       frame_->EmitPush(r0);
   3098 
   3099     } else {
   3100       // -------------------------------------------
   3101       // JavaScript example: 'array[index](1, 2, 3)'
   3102       // -------------------------------------------
   3103 
   3104       LoadAndSpill(property->obj());
   3105       LoadAndSpill(property->key());
   3106       EmitKeyedLoad(false);
   3107       frame_->Drop();  // key
   3108       // Put the function below the receiver.
   3109       if (property->is_synthetic()) {
   3110         // Use the global receiver.
   3111         frame_->Drop();
   3112         frame_->EmitPush(r0);
   3113         LoadGlobalReceiver(r0);
   3114       } else {
   3115         frame_->EmitPop(r1);  // receiver
   3116         frame_->EmitPush(r0);  // function
   3117         frame_->EmitPush(r1);  // receiver
   3118       }
   3119 
   3120       // Call the function.
   3121       CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
   3122       frame_->EmitPush(r0);
   3123     }
   3124 
   3125   } else {
   3126     // ----------------------------------
   3127     // JavaScript example: 'foo(1, 2, 3)'  // foo is not global
   3128     // ----------------------------------
   3129 
   3130     // Load the function.
   3131     LoadAndSpill(function);
   3132 
   3133     // Pass the global proxy as the receiver.
   3134     LoadGlobalReceiver(r0);
   3135 
   3136     // Call the function.
   3137     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
   3138     frame_->EmitPush(r0);
   3139   }
   3140   ASSERT(frame_->height() == original_height + 1);
   3141 }
   3142 
   3143 
   3144 void CodeGenerator::VisitCallNew(CallNew* node) {
   3145 #ifdef DEBUG
   3146   int original_height = frame_->height();
   3147 #endif
   3148   VirtualFrame::SpilledScope spilled_scope;
   3149   Comment cmnt(masm_, "[ CallNew");
   3150 
   3151   // According to ECMA-262, section 11.2.2, page 44, the function
   3152   // expression in new calls must be evaluated before the
   3153   // arguments. This is different from ordinary calls, where the
   3154   // actual function to call is resolved after the arguments have been
   3155   // evaluated.
   3156 
   3157   // Compute function to call and use the global object as the
   3158   // receiver. There is no need to use the global proxy here because
   3159   // it will always be replaced with a newly allocated object.
   3160   LoadAndSpill(node->expression());
   3161   LoadGlobal();
   3162 
   3163   // Push the arguments ("left-to-right") on the stack.
   3164   ZoneList<Expression*>* args = node->arguments();
   3165   int arg_count = args->length();
   3166   for (int i = 0; i < arg_count; i++) {
   3167     LoadAndSpill(args->at(i));
   3168   }
   3169 
   3170   // r0: the number of arguments.
   3171   __ mov(r0, Operand(arg_count));
   3172   // Load the function into r1 as per calling convention.
   3173   __ ldr(r1, frame_->ElementAt(arg_count + 1));
   3174 
   3175   // Call the construct call builtin that handles allocation and
   3176   // constructor invocation.
   3177   CodeForSourcePosition(node->position());
   3178   Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
   3179   frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1);
   3180 
   3181   // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
   3182   __ str(r0, frame_->Top());
   3183   ASSERT(frame_->height() == original_height + 1);
   3184 }
   3185 
   3186 
   3187 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
   3188   VirtualFrame::SpilledScope spilled_scope;
   3189   ASSERT(args->length() == 1);
   3190   JumpTarget leave, null, function, non_function_constructor;
   3191 
   3192   // Load the object into r0.
   3193   LoadAndSpill(args->at(0));
   3194   frame_->EmitPop(r0);
   3195 
   3196   // If the object is a smi, we return null.
   3197   __ tst(r0, Operand(kSmiTagMask));
   3198   null.Branch(eq);
   3199 
   3200   // Check that the object is a JS object but take special care of JS
   3201   // functions to make sure they have 'Function' as their class.
   3202   __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE);
   3203   null.Branch(lt);
   3204 
   3205   // As long as JS_FUNCTION_TYPE is the last instance type and it is
   3206   // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
   3207   // LAST_JS_OBJECT_TYPE.
   3208   ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
   3209   ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
   3210   __ cmp(r1, Operand(JS_FUNCTION_TYPE));
   3211   function.Branch(eq);
   3212 
   3213   // Check if the constructor in the map is a function.
   3214   __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
   3215   __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
   3216   non_function_constructor.Branch(ne);
   3217 
   3218   // The r0 register now contains the constructor function. Grab the
   3219   // instance class name from there.
   3220   __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
   3221   __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset));
   3222   frame_->EmitPush(r0);
   3223   leave.Jump();
   3224 
   3225   // Functions have class 'Function'.
   3226   function.Bind();
   3227   __ mov(r0, Operand(Factory::function_class_symbol()));
   3228   frame_->EmitPush(r0);
   3229   leave.Jump();
   3230 
   3231   // Objects with a non-function constructor have class 'Object'.
   3232   non_function_constructor.Bind();
   3233   __ mov(r0, Operand(Factory::Object_symbol()));
   3234   frame_->EmitPush(r0);
   3235   leave.Jump();
   3236 
   3237   // Non-JS objects have class null.
   3238   null.Bind();
   3239   __ LoadRoot(r0, Heap::kNullValueRootIndex);
   3240   frame_->EmitPush(r0);
   3241 
   3242   // All done.
   3243   leave.Bind();
   3244 }
   3245 
   3246 
   3247 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
   3248   VirtualFrame::SpilledScope spilled_scope;
   3249   ASSERT(args->length() == 1);
   3250   JumpTarget leave;
   3251   LoadAndSpill(args->at(0));
   3252   frame_->EmitPop(r0);  // r0 contains object.
   3253   // if (object->IsSmi()) return the object.
   3254   __ tst(r0, Operand(kSmiTagMask));
   3255   leave.Branch(eq);
   3256   // It is a heap object - get map. If (!object->IsJSValue()) return the object.
   3257   __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE);
   3258   leave.Branch(ne);
   3259   // Load the value.
   3260   __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
   3261   leave.Bind();
   3262   frame_->EmitPush(r0);
   3263 }
   3264 
   3265 
   3266 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
   3267   VirtualFrame::SpilledScope spilled_scope;
   3268   ASSERT(args->length() == 2);
   3269   JumpTarget leave;
   3270   LoadAndSpill(args->at(0));  // Load the object.
   3271   LoadAndSpill(args->at(1));  // Load the value.
   3272   frame_->EmitPop(r0);  // r0 contains value
   3273   frame_->EmitPop(r1);  // r1 contains object
   3274   // if (object->IsSmi()) return object.
   3275   __ tst(r1, Operand(kSmiTagMask));
   3276   leave.Branch(eq);
   3277   // It is a heap object - get map. If (!object->IsJSValue()) return the object.
   3278   __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE);
   3279   leave.Branch(ne);
   3280   // Store the value.
   3281   __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset));
   3282   // Update the write barrier.
   3283   __ mov(r2, Operand(JSValue::kValueOffset - kHeapObjectTag));
   3284   __ RecordWrite(r1, r2, r3);
   3285   // Leave.
   3286   leave.Bind();
   3287   frame_->EmitPush(r0);
   3288 }
   3289 
   3290 
   3291 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
   3292   VirtualFrame::SpilledScope spilled_scope;
   3293   ASSERT(args->length() == 1);
   3294   LoadAndSpill(args->at(0));
   3295   frame_->EmitPop(r0);
   3296   __ tst(r0, Operand(kSmiTagMask));
   3297   cc_reg_ = eq;
   3298 }
   3299 
   3300 
   3301 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
   3302   VirtualFrame::SpilledScope spilled_scope;
   3303   // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc.
   3304   ASSERT_EQ(args->length(), 3);
   3305 #ifdef ENABLE_LOGGING_AND_PROFILING
   3306   if (ShouldGenerateLog(args->at(0))) {
   3307     LoadAndSpill(args->at(1));
   3308     LoadAndSpill(args->at(2));
   3309     __ CallRuntime(Runtime::kLog, 2);
   3310   }
   3311 #endif
   3312   __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   3313   frame_->EmitPush(r0);
   3314 }
   3315 
   3316 
   3317 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
   3318   VirtualFrame::SpilledScope spilled_scope;
   3319   ASSERT(args->length() == 1);
   3320   LoadAndSpill(args->at(0));
   3321   frame_->EmitPop(r0);
   3322   __ tst(r0, Operand(kSmiTagMask | 0x80000000u));
   3323   cc_reg_ = eq;
   3324 }
   3325 
   3326 
   3327 // This should generate code that performs a charCodeAt() call or returns
   3328 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
   3329 // It is not yet implemented on ARM, so it always goes to the slow case.
   3330 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   3331   VirtualFrame::SpilledScope spilled_scope;
   3332   ASSERT(args->length() == 2);
   3333   Comment(masm_, "[ GenerateFastCharCodeAt");
   3334 
   3335   LoadAndSpill(args->at(0));
   3336   LoadAndSpill(args->at(1));
   3337   frame_->EmitPop(r0);  // Index.
   3338   frame_->EmitPop(r1);  // String.
   3339 
   3340   Label slow, end, not_a_flat_string, ascii_string, try_again_with_new_string;
   3341 
   3342   __ tst(r1, Operand(kSmiTagMask));
   3343   __ b(eq, &slow);  // The 'string' was a Smi.
   3344 
   3345   ASSERT(kSmiTag == 0);
   3346   __ tst(r0, Operand(kSmiTagMask | 0x80000000u));
   3347   __ b(ne, &slow);  // The index was negative or not a Smi.
   3348 
   3349   __ bind(&try_again_with_new_string);
   3350   __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE);
   3351   __ b(ge, &slow);
   3352 
   3353   // Now r2 has the string type.
   3354   __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
   3355   // Now r3 has the length of the string.  Compare with the index.
   3356   __ cmp(r3, Operand(r0, LSR, kSmiTagSize));
   3357   __ b(le, &slow);
   3358 
   3359   // Here we know the index is in range.  Check that string is sequential.
   3360   ASSERT_EQ(0, kSeqStringTag);
   3361   __ tst(r2, Operand(kStringRepresentationMask));
   3362   __ b(ne, &not_a_flat_string);
   3363 
   3364   // Check whether it is an ASCII string.
   3365   ASSERT_EQ(0, kTwoByteStringTag);
   3366   __ tst(r2, Operand(kStringEncodingMask));
   3367   __ b(ne, &ascii_string);
   3368 
   3369   // 2-byte string.  We can add without shifting since the Smi tag size is the
   3370   // log2 of the number of bytes in a two-byte character.
   3371   ASSERT_EQ(1, kSmiTagSize);
   3372   ASSERT_EQ(0, kSmiShiftSize);
   3373   __ add(r1, r1, Operand(r0));
   3374   __ ldrh(r0, FieldMemOperand(r1, SeqTwoByteString::kHeaderSize));
   3375   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   3376   __ jmp(&end);
   3377 
   3378   __ bind(&ascii_string);
   3379   __ add(r1, r1, Operand(r0, LSR, kSmiTagSize));
   3380   __ ldrb(r0, FieldMemOperand(r1, SeqAsciiString::kHeaderSize));
   3381   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
   3382   __ jmp(&end);
   3383 
   3384   __ bind(&not_a_flat_string);
   3385   __ and_(r2, r2, Operand(kStringRepresentationMask));
   3386   __ cmp(r2, Operand(kConsStringTag));
   3387   __ b(ne, &slow);
   3388 
   3389   // ConsString.
   3390   // Check that the right hand side is the empty string (ie if this is really a
   3391   // flat string in a cons string).  If that is not the case we would rather go
   3392   // to the runtime system now, to flatten the string.
   3393   __ ldr(r2, FieldMemOperand(r1, ConsString::kSecondOffset));
   3394   __ LoadRoot(r3, Heap::kEmptyStringRootIndex);
   3395   __ cmp(r2, Operand(r3));
   3396   __ b(ne, &slow);
   3397 
   3398   // Get the first of the two strings.
   3399   __ ldr(r1, FieldMemOperand(r1, ConsString::kFirstOffset));
   3400   __ jmp(&try_again_with_new_string);
   3401 
   3402   __ bind(&slow);
   3403   __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   3404 
   3405   __ bind(&end);
   3406   frame_->EmitPush(r0);
   3407 }
   3408 
   3409 
   3410 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
   3411   VirtualFrame::SpilledScope spilled_scope;
   3412   ASSERT(args->length() == 1);
   3413   LoadAndSpill(args->at(0));
   3414   JumpTarget answer;
   3415   // We need the CC bits to come out as not_equal in the case where the
   3416   // object is a smi.  This can't be done with the usual test opcode so
   3417   // we use XOR to get the right CC bits.
   3418   frame_->EmitPop(r0);
   3419   __ and_(r1, r0, Operand(kSmiTagMask));
   3420   __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
   3421   answer.Branch(ne);
   3422   // It is a heap object - get the map. Check if the object is a JS array.
   3423   __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
   3424   answer.Bind();
   3425   cc_reg_ = eq;
   3426 }
   3427 
   3428 
   3429 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
   3430   VirtualFrame::SpilledScope spilled_scope;
   3431   ASSERT(args->length() == 1);
   3432   LoadAndSpill(args->at(0));
   3433   JumpTarget answer;
   3434   // We need the CC bits to come out as not_equal in the case where the
   3435   // object is a smi.  This can't be done with the usual test opcode so
   3436   // we use XOR to get the right CC bits.
   3437   frame_->EmitPop(r0);
   3438   __ and_(r1, r0, Operand(kSmiTagMask));
   3439   __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
   3440   answer.Branch(ne);
   3441   // It is a heap object - get the map. Check if the object is a regexp.
   3442   __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
   3443   answer.Bind();
   3444   cc_reg_ = eq;
   3445 }
   3446 
   3447 
   3448 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
   3449   // This generates a fast version of:
   3450   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
   3451   VirtualFrame::SpilledScope spilled_scope;
   3452   ASSERT(args->length() == 1);
   3453   LoadAndSpill(args->at(0));
   3454   frame_->EmitPop(r1);
   3455   __ tst(r1, Operand(kSmiTagMask));
   3456   false_target()->Branch(eq);
   3457 
   3458   __ LoadRoot(ip, Heap::kNullValueRootIndex);
   3459   __ cmp(r1, ip);
   3460   true_target()->Branch(eq);
   3461 
   3462   Register map_reg = r2;
   3463   __ ldr(map_reg, FieldMemOperand(r1, HeapObject::kMapOffset));
   3464   // Undetectable objects behave like undefined when tested with typeof.
   3465   __ ldrb(r1, FieldMemOperand(map_reg, Map::kBitFieldOffset));
   3466   __ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
   3467   __ cmp(r1, Operand(1 << Map::kIsUndetectable));
   3468   false_target()->Branch(eq);
   3469 
   3470   __ ldrb(r1, FieldMemOperand(map_reg, Map::kInstanceTypeOffset));
   3471   __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
   3472   false_target()->Branch(lt);
   3473   __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
   3474   cc_reg_ = le;
   3475 }
   3476 
   3477 
   3478 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
   3479   // This generates a fast version of:
   3480   // (%_ClassOf(arg) === 'Function')
   3481   VirtualFrame::SpilledScope spilled_scope;
   3482   ASSERT(args->length() == 1);
   3483   LoadAndSpill(args->at(0));
   3484   frame_->EmitPop(r0);
   3485   __ tst(r0, Operand(kSmiTagMask));
   3486   false_target()->Branch(eq);
   3487   Register map_reg = r2;
   3488   __ CompareObjectType(r0, map_reg, r1, JS_FUNCTION_TYPE);
   3489   cc_reg_ = eq;
   3490 }
   3491 
   3492 
   3493 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
   3494   VirtualFrame::SpilledScope spilled_scope;
   3495   ASSERT(args->length() == 1);
   3496   LoadAndSpill(args->at(0));
   3497   frame_->EmitPop(r0);
   3498   __ tst(r0, Operand(kSmiTagMask));
   3499   false_target()->Branch(eq);
   3500   __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
   3501   __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
   3502   __ tst(r1, Operand(1 << Map::kIsUndetectable));
   3503   cc_reg_ = ne;
   3504 }
   3505 
   3506 
   3507 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
   3508   VirtualFrame::SpilledScope spilled_scope;
   3509   ASSERT(args->length() == 0);
   3510 
   3511   // Get the frame pointer for the calling frame.
   3512   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   3513 
   3514   // Skip the arguments adaptor frame if it exists.
   3515   Label check_frame_marker;
   3516   __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
   3517   __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   3518   __ b(ne, &check_frame_marker);
   3519   __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset));
   3520 
   3521   // Check the marker in the calling frame.
   3522   __ bind(&check_frame_marker);
   3523   __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
   3524   __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
   3525   cc_reg_ = eq;
   3526 }
   3527 
   3528 
   3529 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   3530   VirtualFrame::SpilledScope spilled_scope;
   3531   ASSERT(args->length() == 0);
   3532 
   3533   // Seed the result with the formal parameters count, which will be used
   3534   // in case no arguments adaptor frame is found below the current frame.
   3535   __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
   3536 
   3537   // Call the shared stub to get to the arguments.length.
   3538   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
   3539   frame_->CallStub(&stub, 0);
   3540   frame_->EmitPush(r0);
   3541 }
   3542 
   3543 
   3544 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
   3545   VirtualFrame::SpilledScope spilled_scope;
   3546   ASSERT(args->length() == 1);
   3547 
   3548   // Satisfy contract with ArgumentsAccessStub:
   3549   // Load the key into r1 and the formal parameters count into r0.
   3550   LoadAndSpill(args->at(0));
   3551   frame_->EmitPop(r1);
   3552   __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
   3553 
   3554   // Call the shared stub to get to arguments[key].
   3555   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   3556   frame_->CallStub(&stub, 0);
   3557   frame_->EmitPush(r0);
   3558 }
   3559 
   3560 
   3561 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
   3562   VirtualFrame::SpilledScope spilled_scope;
   3563   ASSERT(args->length() == 0);
   3564   __ Call(ExternalReference::random_positive_smi_function().address(),
   3565           RelocInfo::RUNTIME_ENTRY);
   3566   frame_->EmitPush(r0);
   3567 }
   3568 
   3569 
   3570 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
   3571   ASSERT_EQ(2, args->length());
   3572 
   3573   Load(args->at(0));
   3574   Load(args->at(1));
   3575 
   3576   StringAddStub stub(NO_STRING_ADD_FLAGS);
   3577   frame_->CallStub(&stub, 2);
   3578   frame_->EmitPush(r0);
   3579 }
   3580 
   3581 
   3582 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
   3583   ASSERT_EQ(3, args->length());
   3584 
   3585   Load(args->at(0));
   3586   Load(args->at(1));
   3587   Load(args->at(2));
   3588 
   3589   SubStringStub stub;
   3590   frame_->CallStub(&stub, 3);
   3591   frame_->EmitPush(r0);
   3592 }
   3593 
   3594 
   3595 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
   3596   ASSERT_EQ(2, args->length());
   3597 
   3598   Load(args->at(0));
   3599   Load(args->at(1));
   3600 
   3601   StringCompareStub stub;
   3602   frame_->CallStub(&stub, 2);
   3603   frame_->EmitPush(r0);
   3604 }
   3605 
   3606 
   3607 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
   3608   ASSERT_EQ(4, args->length());
   3609 
   3610   Load(args->at(0));
   3611   Load(args->at(1));
   3612   Load(args->at(2));
   3613   Load(args->at(3));
   3614 
   3615   frame_->CallRuntime(Runtime::kRegExpExec, 4);
   3616   frame_->EmitPush(r0);
   3617 }
   3618 
   3619 
   3620 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
   3621   ASSERT_EQ(args->length(), 1);
   3622 
   3623   // Load the argument on the stack and jump to the runtime.
   3624   Load(args->at(0));
   3625 
   3626   frame_->CallRuntime(Runtime::kNumberToString, 1);
   3627   frame_->EmitPush(r0);
   3628 }
   3629 
   3630 
   3631 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
   3632   ASSERT_EQ(args->length(), 1);
   3633   // Load the argument on the stack and jump to the runtime.
   3634   Load(args->at(0));
   3635   frame_->CallRuntime(Runtime::kMath_sin, 1);
   3636   frame_->EmitPush(r0);
   3637 }
   3638 
   3639 
   3640 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
   3641   ASSERT_EQ(args->length(), 1);
   3642   // Load the argument on the stack and jump to the runtime.
   3643   Load(args->at(0));
   3644   frame_->CallRuntime(Runtime::kMath_cos, 1);
   3645   frame_->EmitPush(r0);
   3646 }
   3647 
   3648 
   3649 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
   3650   VirtualFrame::SpilledScope spilled_scope;
   3651   ASSERT(args->length() == 2);
   3652 
   3653   // Load the two objects into registers and perform the comparison.
   3654   LoadAndSpill(args->at(0));
   3655   LoadAndSpill(args->at(1));
   3656   frame_->EmitPop(r0);
   3657   frame_->EmitPop(r1);
   3658   __ cmp(r0, Operand(r1));
   3659   cc_reg_ = eq;
   3660 }
   3661 
   3662 
   3663 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
   3664 #ifdef DEBUG
   3665   int original_height = frame_->height();
   3666 #endif
   3667   VirtualFrame::SpilledScope spilled_scope;
   3668   if (CheckForInlineRuntimeCall(node)) {
   3669     ASSERT((has_cc() && frame_->height() == original_height) ||
   3670            (!has_cc() && frame_->height() == original_height + 1));
   3671     return;
   3672   }
   3673 
   3674   ZoneList<Expression*>* args = node->arguments();
   3675   Comment cmnt(masm_, "[ CallRuntime");
   3676   Runtime::Function* function = node->function();
   3677 
   3678   if (function == NULL) {
   3679     // Prepare stack for calling JS runtime function.
   3680     // Push the builtins object found in the current global object.
   3681     __ ldr(r1, GlobalObject());
   3682     __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
   3683     frame_->EmitPush(r0);
   3684   }
   3685 
   3686   // Push the arguments ("left-to-right").
   3687   int arg_count = args->length();
   3688   for (int i = 0; i < arg_count; i++) {
   3689     LoadAndSpill(args->at(i));
   3690   }
   3691 
   3692   if (function == NULL) {
   3693     // Call the JS runtime function.
   3694     __ mov(r2, Operand(node->name()));
   3695     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   3696     Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
   3697     frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
   3698     __ ldr(cp, frame_->Context());
   3699     frame_->EmitPush(r0);
   3700   } else {
   3701     // Call the C runtime function.
   3702     frame_->CallRuntime(function, arg_count);
   3703     frame_->EmitPush(r0);
   3704   }
   3705   ASSERT(frame_->height() == original_height + 1);
   3706 }
   3707 
   3708 
   3709 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
   3710 #ifdef DEBUG
   3711   int original_height = frame_->height();
   3712 #endif
   3713   VirtualFrame::SpilledScope spilled_scope;
   3714   Comment cmnt(masm_, "[ UnaryOperation");
   3715 
   3716   Token::Value op = node->op();
   3717 
   3718   if (op == Token::NOT) {
   3719     LoadConditionAndSpill(node->expression(),
   3720                           false_target(),
   3721                           true_target(),
   3722                           true);
   3723     // LoadCondition may (and usually does) leave a test and branch to
   3724     // be emitted by the caller.  In that case, negate the condition.
   3725     if (has_cc()) cc_reg_ = NegateCondition(cc_reg_);
   3726 
   3727   } else if (op == Token::DELETE) {
   3728     Property* property = node->expression()->AsProperty();
   3729     Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
   3730     if (property != NULL) {
   3731       LoadAndSpill(property->obj());
   3732       LoadAndSpill(property->key());
   3733       frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
   3734 
   3735     } else if (variable != NULL) {
   3736       Slot* slot = variable->slot();
   3737       if (variable->is_global()) {
   3738         LoadGlobal();
   3739         __ mov(r0, Operand(variable->name()));
   3740         frame_->EmitPush(r0);
   3741         frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
   3742 
   3743       } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
   3744         // lookup the context holding the named variable
   3745         frame_->EmitPush(cp);
   3746         __ mov(r0, Operand(variable->name()));
   3747         frame_->EmitPush(r0);
   3748         frame_->CallRuntime(Runtime::kLookupContext, 2);
   3749         // r0: context
   3750         frame_->EmitPush(r0);
   3751         __ mov(r0, Operand(variable->name()));
   3752         frame_->EmitPush(r0);
   3753         frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
   3754 
   3755       } else {
   3756         // Default: Result of deleting non-global, not dynamically
   3757         // introduced variables is false.
   3758         __ LoadRoot(r0, Heap::kFalseValueRootIndex);
   3759       }
   3760 
   3761     } else {
   3762       // Default: Result of deleting expressions is true.
   3763       LoadAndSpill(node->expression());  // may have side-effects
   3764       frame_->Drop();
   3765       __ LoadRoot(r0, Heap::kTrueValueRootIndex);
   3766     }
   3767     frame_->EmitPush(r0);
   3768 
   3769   } else if (op == Token::TYPEOF) {
   3770     // Special case for loading the typeof expression; see comment on
   3771     // LoadTypeofExpression().
   3772     LoadTypeofExpression(node->expression());
   3773     frame_->CallRuntime(Runtime::kTypeof, 1);
   3774     frame_->EmitPush(r0);  // r0 has result
   3775 
   3776   } else {
   3777     bool overwrite =
   3778         (node->expression()->AsBinaryOperation() != NULL &&
   3779          node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
   3780     LoadAndSpill(node->expression());
   3781     frame_->EmitPop(r0);
   3782     switch (op) {
   3783       case Token::NOT:
   3784       case Token::DELETE:
   3785       case Token::TYPEOF:
   3786         UNREACHABLE();  // handled above
   3787         break;
   3788 
   3789       case Token::SUB: {
   3790         GenericUnaryOpStub stub(Token::SUB, overwrite);
   3791         frame_->CallStub(&stub, 0);
   3792         break;
   3793       }
   3794 
   3795       case Token::BIT_NOT: {
   3796         // smi check
   3797         JumpTarget smi_label;
   3798         JumpTarget continue_label;
   3799         __ tst(r0, Operand(kSmiTagMask));
   3800         smi_label.Branch(eq);
   3801 
   3802         GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
   3803         frame_->CallStub(&stub, 0);
   3804         continue_label.Jump();
   3805 
   3806         smi_label.Bind();
   3807         __ mvn(r0, Operand(r0));
   3808         __ bic(r0, r0, Operand(kSmiTagMask));  // bit-clear inverted smi-tag
   3809         continue_label.Bind();
   3810         break;
   3811       }
   3812 
   3813       case Token::VOID:
   3814         // since the stack top is cached in r0, popping and then
   3815         // pushing a value can be done by just writing to r0.
   3816         __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   3817         break;
   3818 
   3819       case Token::ADD: {
   3820         // Smi check.
   3821         JumpTarget continue_label;
   3822         __ tst(r0, Operand(kSmiTagMask));
   3823         continue_label.Branch(eq);
   3824         frame_->EmitPush(r0);
   3825         frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
   3826         continue_label.Bind();
   3827         break;
   3828       }
   3829       default:
   3830         UNREACHABLE();
   3831     }
   3832     frame_->EmitPush(r0);  // r0 has result
   3833   }
   3834   ASSERT(!has_valid_frame() ||
   3835          (has_cc() && frame_->height() == original_height) ||
   3836          (!has_cc() && frame_->height() == original_height + 1));
   3837 }
   3838 
   3839 
   3840 void CodeGenerator::VisitCountOperation(CountOperation* node) {
   3841 #ifdef DEBUG
   3842   int original_height = frame_->height();
   3843 #endif
   3844   VirtualFrame::SpilledScope spilled_scope;
   3845   Comment cmnt(masm_, "[ CountOperation");
   3846 
   3847   bool is_postfix = node->is_postfix();
   3848   bool is_increment = node->op() == Token::INC;
   3849 
   3850   Variable* var = node->expression()->AsVariableProxy()->AsVariable();
   3851   bool is_const = (var != NULL && var->mode() == Variable::CONST);
   3852 
   3853   // Postfix: Make room for the result.
   3854   if (is_postfix) {
   3855      __ mov(r0, Operand(0));
   3856      frame_->EmitPush(r0);
   3857   }
   3858 
   3859   // A constant reference is not saved to, so a constant reference is not a
   3860   // compound assignment reference.
   3861   { Reference target(this, node->expression(), !is_const);
   3862     if (target.is_illegal()) {
   3863       // Spoof the virtual frame to have the expected height (one higher
   3864       // than on entry).
   3865       if (!is_postfix) {
   3866         __ mov(r0, Operand(Smi::FromInt(0)));
   3867         frame_->EmitPush(r0);
   3868       }
   3869       ASSERT(frame_->height() == original_height + 1);
   3870       return;
   3871     }
   3872     target.GetValueAndSpill();
   3873     frame_->EmitPop(r0);
   3874 
   3875     JumpTarget slow;
   3876     JumpTarget exit;
   3877 
   3878     // Load the value (1) into register r1.
   3879     __ mov(r1, Operand(Smi::FromInt(1)));
   3880 
   3881     // Check for smi operand.
   3882     __ tst(r0, Operand(kSmiTagMask));
   3883     slow.Branch(ne);
   3884 
   3885     // Postfix: Store the old value as the result.
   3886     if (is_postfix) {
   3887       __ str(r0, frame_->ElementAt(target.size()));
   3888     }
   3889 
   3890     // Perform optimistic increment/decrement.
   3891     if (is_increment) {
   3892       __ add(r0, r0, Operand(r1), SetCC);
   3893     } else {
   3894       __ sub(r0, r0, Operand(r1), SetCC);
   3895     }
   3896 
   3897     // If the increment/decrement didn't overflow, we're done.
   3898     exit.Branch(vc);
   3899 
   3900     // Revert optimistic increment/decrement.
   3901     if (is_increment) {
   3902       __ sub(r0, r0, Operand(r1));
   3903     } else {
   3904       __ add(r0, r0, Operand(r1));
   3905     }
   3906 
   3907     // Slow case: Convert to number.
   3908     slow.Bind();
   3909     {
   3910       // Convert the operand to a number.
   3911       frame_->EmitPush(r0);
   3912       frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
   3913     }
   3914     if (is_postfix) {
   3915       // Postfix: store to result (on the stack).
   3916       __ str(r0, frame_->ElementAt(target.size()));
   3917     }
   3918 
   3919     // Compute the new value.
   3920     __ mov(r1, Operand(Smi::FromInt(1)));
   3921     frame_->EmitPush(r0);
   3922     frame_->EmitPush(r1);
   3923     if (is_increment) {
   3924       frame_->CallRuntime(Runtime::kNumberAdd, 2);
   3925     } else {
   3926       frame_->CallRuntime(Runtime::kNumberSub, 2);
   3927     }
   3928 
   3929     // Store the new value in the target if not const.
   3930     exit.Bind();
   3931     frame_->EmitPush(r0);
   3932     if (!is_const) target.SetValue(NOT_CONST_INIT);
   3933   }
   3934 
   3935   // Postfix: Discard the new value and use the old.
   3936   if (is_postfix) frame_->EmitPop(r0);
   3937   ASSERT(frame_->height() == original_height + 1);
   3938 }
   3939 
   3940 
   3941 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
   3942 #ifdef DEBUG
   3943   int original_height = frame_->height();
   3944 #endif
   3945   VirtualFrame::SpilledScope spilled_scope;
   3946   Comment cmnt(masm_, "[ BinaryOperation");
   3947   Token::Value op = node->op();
   3948 
   3949   // According to ECMA-262 section 11.11, page 58, the binary logical
   3950   // operators must yield the result of one of the two expressions
   3951   // before any ToBoolean() conversions. This means that the value
   3952   // produced by a && or || operator is not necessarily a boolean.
   3953 
   3954   // NOTE: If the left hand side produces a materialized value (not in
   3955   // the CC register), we force the right hand side to do the
   3956   // same. This is necessary because we may have to branch to the exit
   3957   // after evaluating the left hand side (due to the shortcut
   3958   // semantics), but the compiler must (statically) know if the result
   3959   // of compiling the binary operation is materialized or not.
   3960 
   3961   if (op == Token::AND) {
   3962     JumpTarget is_true;
   3963     LoadConditionAndSpill(node->left(),
   3964                           &is_true,
   3965                           false_target(),
   3966                           false);
   3967     if (has_valid_frame() && !has_cc()) {
   3968       // The left-hand side result is on top of the virtual frame.
   3969       JumpTarget pop_and_continue;
   3970       JumpTarget exit;
   3971 
   3972       __ ldr(r0, frame_->Top());  // Duplicate the stack top.
   3973       frame_->EmitPush(r0);
   3974       // Avoid popping the result if it converts to 'false' using the
   3975       // standard ToBoolean() conversion as described in ECMA-262,
   3976       // section 9.2, page 30.
   3977       ToBoolean(&pop_and_continue, &exit);
   3978       Branch(false, &exit);
   3979 
   3980       // Pop the result of evaluating the first part.
   3981       pop_and_continue.Bind();
   3982       frame_->EmitPop(r0);
   3983 
   3984       // Evaluate right side expression.
   3985       is_true.Bind();
   3986       LoadAndSpill(node->right());
   3987 
   3988       // Exit (always with a materialized value).
   3989       exit.Bind();
   3990     } else if (has_cc() || is_true.is_linked()) {
   3991       // The left-hand side is either (a) partially compiled to
   3992       // control flow with a final branch left to emit or (b) fully
   3993       // compiled to control flow and possibly true.
   3994       if (has_cc()) {
   3995         Branch(false, false_target());
   3996       }
   3997       is_true.Bind();
   3998       LoadConditionAndSpill(node->right(),
   3999                             true_target(),
   4000                             false_target(),
   4001                             false);
   4002     } else {
   4003       // Nothing to do.
   4004       ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked());
   4005     }
   4006 
   4007   } else if (op == Token::OR) {
   4008     JumpTarget is_false;
   4009     LoadConditionAndSpill(node->left(),
   4010                           true_target(),
   4011                           &is_false,
   4012                           false);
   4013     if (has_valid_frame() && !has_cc()) {
   4014       // The left-hand side result is on top of the virtual frame.
   4015       JumpTarget pop_and_continue;
   4016       JumpTarget exit;
   4017 
   4018       __ ldr(r0, frame_->Top());
   4019       frame_->EmitPush(r0);
   4020       // Avoid popping the result if it converts to 'true' using the
   4021       // standard ToBoolean() conversion as described in ECMA-262,
   4022       // section 9.2, page 30.
   4023       ToBoolean(&exit, &pop_and_continue);
   4024       Branch(true, &exit);
   4025 
   4026       // Pop the result of evaluating the first part.
   4027       pop_and_continue.Bind();
   4028       frame_->EmitPop(r0);
   4029 
   4030       // Evaluate right side expression.
   4031       is_false.Bind();
   4032       LoadAndSpill(node->right());
   4033 
   4034       // Exit (always with a materialized value).
   4035       exit.Bind();
   4036     } else if (has_cc() || is_false.is_linked()) {
   4037       // The left-hand side is either (a) partially compiled to
   4038       // control flow with a final branch left to emit or (b) fully
   4039       // compiled to control flow and possibly false.
   4040       if (has_cc()) {
   4041         Branch(true, true_target());
   4042       }
   4043       is_false.Bind();
   4044       LoadConditionAndSpill(node->right(),
   4045                             true_target(),
   4046                             false_target(),
   4047                             false);
   4048     } else {
   4049       // Nothing to do.
   4050       ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked());
   4051     }
   4052 
   4053   } else {
   4054     // Optimize for the case where (at least) one of the expressions
   4055     // is a literal small integer.
   4056     Literal* lliteral = node->left()->AsLiteral();
   4057     Literal* rliteral = node->right()->AsLiteral();
   4058     // NOTE: The code below assumes that the slow cases (calls to runtime)
   4059     // never return a constant/immutable object.
   4060     bool overwrite_left =
   4061         (node->left()->AsBinaryOperation() != NULL &&
   4062          node->left()->AsBinaryOperation()->ResultOverwriteAllowed());
   4063     bool overwrite_right =
   4064         (node->right()->AsBinaryOperation() != NULL &&
   4065          node->right()->AsBinaryOperation()->ResultOverwriteAllowed());
   4066 
   4067     if (rliteral != NULL && rliteral->handle()->IsSmi()) {
   4068       LoadAndSpill(node->left());
   4069       SmiOperation(node->op(),
   4070                    rliteral->handle(),
   4071                    false,
   4072                    overwrite_right ? OVERWRITE_RIGHT : NO_OVERWRITE);
   4073 
   4074     } else if (lliteral != NULL && lliteral->handle()->IsSmi()) {
   4075       LoadAndSpill(node->right());
   4076       SmiOperation(node->op(),
   4077                    lliteral->handle(),
   4078                    true,
   4079                    overwrite_left ? OVERWRITE_LEFT : NO_OVERWRITE);
   4080 
   4081     } else {
   4082       OverwriteMode overwrite_mode = NO_OVERWRITE;
   4083       if (overwrite_left) {
   4084         overwrite_mode = OVERWRITE_LEFT;
   4085       } else if (overwrite_right) {
   4086         overwrite_mode = OVERWRITE_RIGHT;
   4087       }
   4088       LoadAndSpill(node->left());
   4089       LoadAndSpill(node->right());
   4090       GenericBinaryOperation(node->op(), overwrite_mode);
   4091     }
   4092     frame_->EmitPush(r0);
   4093   }
   4094   ASSERT(!has_valid_frame() ||
   4095          (has_cc() && frame_->height() == original_height) ||
   4096          (!has_cc() && frame_->height() == original_height + 1));
   4097 }
   4098 
   4099 
   4100 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
   4101 #ifdef DEBUG
   4102   int original_height = frame_->height();
   4103 #endif
   4104   VirtualFrame::SpilledScope spilled_scope;
   4105   __ ldr(r0, frame_->Function());
   4106   frame_->EmitPush(r0);
   4107   ASSERT(frame_->height() == original_height + 1);
   4108 }
   4109 
   4110 
   4111 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
   4112 #ifdef DEBUG
   4113   int original_height = frame_->height();
   4114 #endif
   4115   VirtualFrame::SpilledScope spilled_scope;
   4116   Comment cmnt(masm_, "[ CompareOperation");
   4117 
   4118   // Get the expressions from the node.
   4119   Expression* left = node->left();
   4120   Expression* right = node->right();
   4121   Token::Value op = node->op();
   4122 
   4123   // To make null checks efficient, we check if either left or right is the
   4124   // literal 'null'. If so, we optimize the code by inlining a null check
   4125   // instead of calling the (very) general runtime routine for checking
   4126   // equality.
   4127   if (op == Token::EQ || op == Token::EQ_STRICT) {
   4128     bool left_is_null =
   4129         left->AsLiteral() != NULL && left->AsLiteral()->IsNull();
   4130     bool right_is_null =
   4131         right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
   4132     // The 'null' value can only be equal to 'null' or 'undefined'.
   4133     if (left_is_null || right_is_null) {
   4134       LoadAndSpill(left_is_null ? right : left);
   4135       frame_->EmitPop(r0);
   4136       __ LoadRoot(ip, Heap::kNullValueRootIndex);
   4137       __ cmp(r0, ip);
   4138 
   4139       // The 'null' value is only equal to 'undefined' if using non-strict
   4140       // comparisons.
   4141       if (op != Token::EQ_STRICT) {
   4142         true_target()->Branch(eq);
   4143 
   4144         __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   4145         __ cmp(r0, Operand(ip));
   4146         true_target()->Branch(eq);
   4147 
   4148         __ tst(r0, Operand(kSmiTagMask));
   4149         false_target()->Branch(eq);
   4150 
   4151         // It can be an undetectable object.
   4152         __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
   4153         __ ldrb(r0, FieldMemOperand(r0, Map::kBitFieldOffset));
   4154         __ and_(r0, r0, Operand(1 << Map::kIsUndetectable));
   4155         __ cmp(r0, Operand(1 << Map::kIsUndetectable));
   4156       }
   4157 
   4158       cc_reg_ = eq;
   4159       ASSERT(has_cc() && frame_->height() == original_height);
   4160       return;
   4161     }
   4162   }
   4163 
   4164   // To make typeof testing for natives implemented in JavaScript really
   4165   // efficient, we generate special code for expressions of the form:
   4166   // 'typeof <expression> == <string>'.
   4167   UnaryOperation* operation = left->AsUnaryOperation();
   4168   if ((op == Token::EQ || op == Token::EQ_STRICT) &&
   4169       (operation != NULL && operation->op() == Token::TYPEOF) &&
   4170       (right->AsLiteral() != NULL &&
   4171        right->AsLiteral()->handle()->IsString())) {
   4172     Handle<String> check(String::cast(*right->AsLiteral()->handle()));
   4173 
   4174     // Load the operand, move it to register r1.
   4175     LoadTypeofExpression(operation->expression());
   4176     frame_->EmitPop(r1);
   4177 
   4178     if (check->Equals(Heap::number_symbol())) {
   4179       __ tst(r1, Operand(kSmiTagMask));
   4180       true_target()->Branch(eq);
   4181       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
   4182       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
   4183       __ cmp(r1, ip);
   4184       cc_reg_ = eq;
   4185 
   4186     } else if (check->Equals(Heap::string_symbol())) {
   4187       __ tst(r1, Operand(kSmiTagMask));
   4188       false_target()->Branch(eq);
   4189 
   4190       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
   4191 
   4192       // It can be an undetectable string object.
   4193       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset));
   4194       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable));
   4195       __ cmp(r2, Operand(1 << Map::kIsUndetectable));
   4196       false_target()->Branch(eq);
   4197 
   4198       __ ldrb(r2, FieldMemOperand(r1, Map::kInstanceTypeOffset));
   4199       __ cmp(r2, Operand(FIRST_NONSTRING_TYPE));
   4200       cc_reg_ = lt;
   4201 
   4202     } else if (check->Equals(Heap::boolean_symbol())) {
   4203       __ LoadRoot(ip, Heap::kTrueValueRootIndex);
   4204       __ cmp(r1, ip);
   4205       true_target()->Branch(eq);
   4206       __ LoadRoot(ip, Heap::kFalseValueRootIndex);
   4207       __ cmp(r1, ip);
   4208       cc_reg_ = eq;
   4209 
   4210     } else if (check->Equals(Heap::undefined_symbol())) {
   4211       __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   4212       __ cmp(r1, ip);
   4213       true_target()->Branch(eq);
   4214 
   4215       __ tst(r1, Operand(kSmiTagMask));
   4216       false_target()->Branch(eq);
   4217 
   4218       // It can be an undetectable object.
   4219       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
   4220       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset));
   4221       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable));
   4222       __ cmp(r2, Operand(1 << Map::kIsUndetectable));
   4223 
   4224       cc_reg_ = eq;
   4225 
   4226     } else if (check->Equals(Heap::function_symbol())) {
   4227       __ tst(r1, Operand(kSmiTagMask));
   4228       false_target()->Branch(eq);
   4229       Register map_reg = r2;
   4230       __ CompareObjectType(r1, map_reg, r1, JS_FUNCTION_TYPE);
   4231       true_target()->Branch(eq);
   4232       // Regular expressions are callable so typeof == 'function'.
   4233       __ CompareInstanceType(map_reg, r1, JS_REGEXP_TYPE);
   4234       cc_reg_ = eq;
   4235 
   4236     } else if (check->Equals(Heap::object_symbol())) {
   4237       __ tst(r1, Operand(kSmiTagMask));
   4238       false_target()->Branch(eq);
   4239 
   4240       __ LoadRoot(ip, Heap::kNullValueRootIndex);
   4241       __ cmp(r1, ip);
   4242       true_target()->Branch(eq);
   4243 
   4244       Register map_reg = r2;
   4245       __ CompareObjectType(r1, map_reg, r1, JS_REGEXP_TYPE);
   4246       false_target()->Branch(eq);
   4247 
   4248       // It can be an undetectable object.
   4249       __ ldrb(r1, FieldMemOperand(map_reg, Map::kBitFieldOffset));
   4250       __ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
   4251       __ cmp(r1, Operand(1 << Map::kIsUndetectable));
   4252       false_target()->Branch(eq);
   4253 
   4254       __ ldrb(r1, FieldMemOperand(map_reg, Map::kInstanceTypeOffset));
   4255       __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
   4256       false_target()->Branch(lt);
   4257       __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
   4258       cc_reg_ = le;
   4259 
   4260     } else {
   4261       // Uncommon case: typeof testing against a string literal that is
   4262       // never returned from the typeof operator.
   4263       false_target()->Jump();
   4264     }
   4265     ASSERT(!has_valid_frame() ||
   4266            (has_cc() && frame_->height() == original_height));
   4267     return;
   4268   }
   4269 
   4270   switch (op) {
   4271     case Token::EQ:
   4272       Comparison(eq, left, right, false);
   4273       break;
   4274 
   4275     case Token::LT:
   4276       Comparison(lt, left, right);
   4277       break;
   4278 
   4279     case Token::GT:
   4280       Comparison(gt, left, right);
   4281       break;
   4282 
   4283     case Token::LTE:
   4284       Comparison(le, left, right);
   4285       break;
   4286 
   4287     case Token::GTE:
   4288       Comparison(ge, left, right);
   4289       break;
   4290 
   4291     case Token::EQ_STRICT:
   4292       Comparison(eq, left, right, true);
   4293       break;
   4294 
   4295     case Token::IN: {
   4296       LoadAndSpill(left);
   4297       LoadAndSpill(right);
   4298       frame_->InvokeBuiltin(Builtins::IN, CALL_JS, 2);
   4299       frame_->EmitPush(r0);
   4300       break;
   4301     }
   4302 
   4303     case Token::INSTANCEOF: {
   4304       LoadAndSpill(left);
   4305       LoadAndSpill(right);
   4306       InstanceofStub stub;
   4307       frame_->CallStub(&stub, 2);
   4308       // At this point if instanceof succeeded then r0 == 0.
   4309       __ tst(r0, Operand(r0));
   4310       cc_reg_ = eq;
   4311       break;
   4312     }
   4313 
   4314     default:
   4315       UNREACHABLE();
   4316   }
   4317   ASSERT((has_cc() && frame_->height() == original_height) ||
   4318          (!has_cc() && frame_->height() == original_height + 1));
   4319 }
   4320 
   4321 
   4322 void CodeGenerator::EmitKeyedLoad(bool is_global) {
   4323   Comment cmnt(masm_, "[ Load from keyed Property");
   4324   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
   4325   RelocInfo::Mode rmode = is_global
   4326                           ? RelocInfo::CODE_TARGET_CONTEXT
   4327                           : RelocInfo::CODE_TARGET;
   4328   frame_->CallCodeObject(ic, rmode, 0);
   4329 }
   4330 
   4331 
   4332 #ifdef DEBUG
   4333 bool CodeGenerator::HasValidEntryRegisters() { return true; }
   4334 #endif
   4335 
   4336 
   4337 #undef __
   4338 #define __ ACCESS_MASM(masm)
   4339 
   4340 
   4341 Handle<String> Reference::GetName() {
   4342   ASSERT(type_ == NAMED);
   4343   Property* property = expression_->AsProperty();
   4344   if (property == NULL) {
   4345     // Global variable reference treated as a named property reference.
   4346     VariableProxy* proxy = expression_->AsVariableProxy();
   4347     ASSERT(proxy->AsVariable() != NULL);
   4348     ASSERT(proxy->AsVariable()->is_global());
   4349     return proxy->name();
   4350   } else {
   4351     Literal* raw_name = property->key()->AsLiteral();
   4352     ASSERT(raw_name != NULL);
   4353     return Handle<String>(String::cast(*raw_name->handle()));
   4354   }
   4355 }
   4356 
   4357 
   4358 void Reference::GetValue() {
   4359   ASSERT(cgen_->HasValidEntryRegisters());
   4360   ASSERT(!is_illegal());
   4361   ASSERT(!cgen_->has_cc());
   4362   MacroAssembler* masm = cgen_->masm();
   4363   Property* property = expression_->AsProperty();
   4364   if (property != NULL) {
   4365     cgen_->CodeForSourcePosition(property->position());
   4366   }
   4367 
   4368   switch (type_) {
   4369     case SLOT: {
   4370       Comment cmnt(masm, "[ Load from Slot");
   4371       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
   4372       ASSERT(slot != NULL);
   4373       cgen_->LoadFromSlot(slot, NOT_INSIDE_TYPEOF);
   4374       break;
   4375     }
   4376 
   4377     case NAMED: {
   4378       VirtualFrame* frame = cgen_->frame();
   4379       Comment cmnt(masm, "[ Load from named Property");
   4380       Handle<String> name(GetName());
   4381       Variable* var = expression_->AsVariableProxy()->AsVariable();
   4382       Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
   4383       // Setup the name register.
   4384       __ mov(r2, Operand(name));
   4385       ASSERT(var == NULL || var->is_global());
   4386       RelocInfo::Mode rmode = (var == NULL)
   4387                             ? RelocInfo::CODE_TARGET
   4388                             : RelocInfo::CODE_TARGET_CONTEXT;
   4389       frame->CallCodeObject(ic, rmode, 0);
   4390       frame->EmitPush(r0);
   4391       break;
   4392     }
   4393 
   4394     case KEYED: {
   4395       // TODO(181): Implement inlined version of array indexing once
   4396       // loop nesting is properly tracked on ARM.
   4397       ASSERT(property != NULL);
   4398       Variable* var = expression_->AsVariableProxy()->AsVariable();
   4399       ASSERT(var == NULL || var->is_global());
   4400       cgen_->EmitKeyedLoad(var != NULL);
   4401       cgen_->frame()->EmitPush(r0);
   4402       break;
   4403     }
   4404 
   4405     default:
   4406       UNREACHABLE();
   4407   }
   4408 
   4409   if (!persist_after_get_) {
   4410     cgen_->UnloadReference(this);
   4411   }
   4412 }
   4413 
   4414 
   4415 void Reference::SetValue(InitState init_state) {
   4416   ASSERT(!is_illegal());
   4417   ASSERT(!cgen_->has_cc());
   4418   MacroAssembler* masm = cgen_->masm();
   4419   VirtualFrame* frame = cgen_->frame();
   4420   Property* property = expression_->AsProperty();
   4421   if (property != NULL) {
   4422     cgen_->CodeForSourcePosition(property->position());
   4423   }
   4424 
   4425   switch (type_) {
   4426     case SLOT: {
   4427       Comment cmnt(masm, "[ Store to Slot");
   4428       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
   4429       cgen_->StoreToSlot(slot, init_state);
   4430       cgen_->UnloadReference(this);
   4431       break;
   4432     }
   4433 
   4434     case NAMED: {
   4435       Comment cmnt(masm, "[ Store to named Property");
   4436       // Call the appropriate IC code.
   4437       Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   4438       Handle<String> name(GetName());
   4439 
   4440       frame->EmitPop(r0);
   4441       frame->EmitPop(r1);
   4442       __ mov(r2, Operand(name));
   4443       frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
   4444       frame->EmitPush(r0);
   4445       set_unloaded();
   4446       break;
   4447     }
   4448 
   4449     case KEYED: {
   4450       Comment cmnt(masm, "[ Store to keyed Property");
   4451       Property* property = expression_->AsProperty();
   4452       ASSERT(property != NULL);
   4453       cgen_->CodeForSourcePosition(property->position());
   4454 
   4455       // Call IC code.
   4456       Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
   4457       frame->EmitPop(r0);  // value
   4458       frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
   4459       frame->EmitPush(r0);
   4460       cgen_->UnloadReference(this);
   4461       break;
   4462     }
   4463 
   4464     default:
   4465       UNREACHABLE();
   4466   }
   4467 }
   4468 
   4469 
   4470 void FastNewClosureStub::Generate(MacroAssembler* masm) {
   4471   // Clone the boilerplate in new space. Set the context to the
   4472   // current context in cp.
   4473   Label gc;
   4474 
   4475   // Pop the boilerplate function from the stack.
   4476   __ pop(r3);
   4477 
   4478   // Attempt to allocate new JSFunction in new space.
   4479   __ AllocateInNewSpace(JSFunction::kSize / kPointerSize,
   4480                         r0,
   4481                         r1,
   4482                         r2,
   4483                         &gc,
   4484                         TAG_OBJECT);
   4485 
   4486   // Compute the function map in the current global context and set that
   4487   // as the map of the allocated object.
   4488   __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   4489   __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
   4490   __ ldr(r2, MemOperand(r2, Context::SlotOffset(Context::FUNCTION_MAP_INDEX)));
   4491   __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
   4492 
   4493   // Clone the rest of the boilerplate fields. We don't have to update
   4494   // the write barrier because the allocated object is in new space.
   4495   for (int offset = kPointerSize;
   4496        offset < JSFunction::kSize;
   4497        offset += kPointerSize) {
   4498     if (offset == JSFunction::kContextOffset) {
   4499       __ str(cp, FieldMemOperand(r0, offset));
   4500     } else {
   4501       __ ldr(r1, FieldMemOperand(r3, offset));
   4502       __ str(r1, FieldMemOperand(r0, offset));
   4503     }
   4504   }
   4505 
   4506   // Return result. The argument boilerplate has been popped already.
   4507   __ Ret();
   4508 
   4509   // Create a new closure through the slower runtime call.
   4510   __ bind(&gc);
   4511   __ push(cp);
   4512   __ push(r3);
   4513   __ TailCallRuntime(ExternalReference(Runtime::kNewClosure), 2, 1);
   4514 }
   4515 
   4516 
   4517 void FastNewContextStub::Generate(MacroAssembler* masm) {
   4518   // Try to allocate the context in new space.
   4519   Label gc;
   4520   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
   4521 
   4522   // Attempt to allocate the context in new space.
   4523   __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize),
   4524                         r0,
   4525                         r1,
   4526                         r2,
   4527                         &gc,
   4528                         TAG_OBJECT);
   4529 
   4530   // Load the function from the stack.
   4531   __ ldr(r3, MemOperand(sp, 0));
   4532 
   4533   // Setup the object header.
   4534   __ LoadRoot(r2, Heap::kContextMapRootIndex);
   4535   __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
   4536   __ mov(r2, Operand(length));
   4537   __ str(r2, FieldMemOperand(r0, Array::kLengthOffset));
   4538 
   4539   // Setup the fixed slots.
   4540   __ mov(r1, Operand(Smi::FromInt(0)));
   4541   __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
   4542   __ str(r0, MemOperand(r0, Context::SlotOffset(Context::FCONTEXT_INDEX)));
   4543   __ str(r1, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
   4544   __ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX)));
   4545 
   4546   // Copy the global object from the surrounding context.
   4547   __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   4548   __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
   4549 
   4550   // Initialize the rest of the slots to undefined.
   4551   __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
   4552   for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
   4553     __ str(r1, MemOperand(r0, Context::SlotOffset(i)));
   4554   }
   4555 
   4556   // Remove the on-stack argument and return.
   4557   __ mov(cp, r0);
   4558   __ pop();
   4559   __ Ret();
   4560 
   4561   // Need to collect. Call into runtime system.
   4562   __ bind(&gc);
   4563   __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1);
   4564 }
   4565 
   4566 
   4567 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
   4568   // Stack layout on entry:
   4569   //
   4570   // [sp]: constant elements.
   4571   // [sp + kPointerSize]: literal index.
   4572   // [sp + (2 * kPointerSize)]: literals array.
   4573 
   4574   // All sizes here are multiples of kPointerSize.
   4575   int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
   4576   int size = JSArray::kSize + elements_size;
   4577 
   4578   // Load boilerplate object into r3 and check if we need to create a
   4579   // boilerplate.
   4580   Label slow_case;
   4581   __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
   4582   __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
   4583   __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   4584   __ ldr(r3, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
   4585   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   4586   __ cmp(r3, ip);
   4587   __ b(eq, &slow_case);
   4588 
   4589   // Allocate both the JS array and the elements array in one big
   4590   // allocation. This avoids multiple limit checks.
   4591   __ AllocateInNewSpace(size / kPointerSize,
   4592                         r0,
   4593                         r1,
   4594                         r2,
   4595                         &slow_case,
   4596                         TAG_OBJECT);
   4597 
   4598   // Copy the JS array part.
   4599   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
   4600     if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
   4601       __ ldr(r1, FieldMemOperand(r3, i));
   4602       __ str(r1, FieldMemOperand(r0, i));
   4603     }
   4604   }
   4605 
   4606   if (length_ > 0) {
   4607     // Get hold of the elements array of the boilerplate and setup the
   4608     // elements pointer in the resulting object.
   4609     __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
   4610     __ add(r2, r0, Operand(JSArray::kSize));
   4611     __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset));
   4612 
   4613     // Copy the elements array.
   4614     for (int i = 0; i < elements_size; i += kPointerSize) {
   4615       __ ldr(r1, FieldMemOperand(r3, i));
   4616       __ str(r1, FieldMemOperand(r2, i));
   4617     }
   4618   }
   4619 
   4620   // Return and remove the on-stack parameters.
   4621   __ add(sp, sp, Operand(3 * kPointerSize));
   4622   __ Ret();
   4623 
   4624   __ bind(&slow_case);
   4625   ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
   4626   __ TailCallRuntime(runtime, 3, 1);
   4627 }
   4628 
   4629 
   4630 // Count leading zeros in a 32 bit word.  On ARM5 and later it uses the clz
   4631 // instruction.  On pre-ARM5 hardware this routine gives the wrong answer for 0
   4632 // (31 instead of 32).
   4633 static void CountLeadingZeros(
   4634     MacroAssembler* masm,
   4635     Register source,
   4636     Register scratch,
   4637     Register zeros) {
   4638 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
   4639   __ clz(zeros, source);  // This instruction is only supported after ARM5.
   4640 #else
   4641   __ mov(zeros, Operand(0));
   4642   __ mov(scratch, source);
   4643   // Top 16.
   4644   __ tst(scratch, Operand(0xffff0000));
   4645   __ add(zeros, zeros, Operand(16), LeaveCC, eq);
   4646   __ mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq);
   4647   // Top 8.
   4648   __ tst(scratch, Operand(0xff000000));
   4649   __ add(zeros, zeros, Operand(8), LeaveCC, eq);
   4650   __ mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq);
   4651   // Top 4.
   4652   __ tst(scratch, Operand(0xf0000000));
   4653   __ add(zeros, zeros, Operand(4), LeaveCC, eq);
   4654   __ mov(scratch, Operand(scratch, LSL, 4), LeaveCC, eq);
   4655   // Top 2.
   4656   __ tst(scratch, Operand(0xc0000000));
   4657   __ add(zeros, zeros, Operand(2), LeaveCC, eq);
   4658   __ mov(scratch, Operand(scratch, LSL, 2), LeaveCC, eq);
   4659   // Top bit.
   4660   __ tst(scratch, Operand(0x80000000u));
   4661   __ add(zeros, zeros, Operand(1), LeaveCC, eq);
   4662 #endif
   4663 }
   4664 
   4665 
   4666 // Takes a Smi and converts to an IEEE 64 bit floating point value in two
   4667 // registers.  The format is 1 sign bit, 11 exponent bits (biased 1023) and
   4668 // 52 fraction bits (20 in the first word, 32 in the second).  Zeros is a
   4669 // scratch register.  Destroys the source register.  No GC occurs during this
   4670 // stub so you don't have to set up the frame.
   4671 class ConvertToDoubleStub : public CodeStub {
   4672  public:
   4673   ConvertToDoubleStub(Register result_reg_1,
   4674                       Register result_reg_2,
   4675                       Register source_reg,
   4676                       Register scratch_reg)
   4677       : result1_(result_reg_1),
   4678         result2_(result_reg_2),
   4679         source_(source_reg),
   4680         zeros_(scratch_reg) { }
   4681 
   4682  private:
   4683   Register result1_;
   4684   Register result2_;
   4685   Register source_;
   4686   Register zeros_;
   4687 
   4688   // Minor key encoding in 16 bits.
   4689   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
   4690   class OpBits: public BitField<Token::Value, 2, 14> {};
   4691 
   4692   Major MajorKey() { return ConvertToDouble; }
   4693   int MinorKey() {
   4694     // Encode the parameters in a unique 16 bit value.
   4695     return  result1_.code() +
   4696            (result2_.code() << 4) +
   4697            (source_.code() << 8) +
   4698            (zeros_.code() << 12);
   4699   }
   4700 
   4701   void Generate(MacroAssembler* masm);
   4702 
   4703   const char* GetName() { return "ConvertToDoubleStub"; }
   4704 
   4705 #ifdef DEBUG
   4706   void Print() { PrintF("ConvertToDoubleStub\n"); }
   4707 #endif
   4708 };
   4709 
   4710 
   4711 void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
   4712 #ifndef BIG_ENDIAN_FLOATING_POINT
   4713   Register exponent = result1_;
   4714   Register mantissa = result2_;
   4715 #else
   4716   Register exponent = result2_;
   4717   Register mantissa = result1_;
   4718 #endif
   4719   Label not_special;
   4720   // Convert from Smi to integer.
   4721   __ mov(source_, Operand(source_, ASR, kSmiTagSize));
   4722   // Move sign bit from source to destination.  This works because the sign bit
   4723   // in the exponent word of the double has the same position and polarity as
   4724   // the 2's complement sign bit in a Smi.
   4725   ASSERT(HeapNumber::kSignMask == 0x80000000u);
   4726   __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC);
   4727   // Subtract from 0 if source was negative.
   4728   __ rsb(source_, source_, Operand(0), LeaveCC, ne);
   4729   __ cmp(source_, Operand(1));
   4730   __ b(gt, &not_special);
   4731 
   4732   // We have -1, 0 or 1, which we treat specially.
   4733   __ cmp(source_, Operand(0));
   4734   // For 1 or -1 we need to or in the 0 exponent (biased to 1023).
   4735   static const uint32_t exponent_word_for_1 =
   4736       HeapNumber::kExponentBias << HeapNumber::kExponentShift;
   4737   __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, ne);
   4738   // 1, 0 and -1 all have 0 for the second word.
   4739   __ mov(mantissa, Operand(0));
   4740   __ Ret();
   4741 
   4742   __ bind(&not_special);
   4743   // Count leading zeros.  Uses result2 for a scratch register on pre-ARM5.
   4744   // Gets the wrong answer for 0, but we already checked for that case above.
   4745   CountLeadingZeros(masm, source_, mantissa, zeros_);
   4746   // Compute exponent and or it into the exponent register.
   4747   // We use result2 as a scratch register here.
   4748   __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias));
   4749   __ orr(exponent,
   4750          exponent,
   4751          Operand(mantissa, LSL, HeapNumber::kExponentShift));
   4752   // Shift up the source chopping the top bit off.
   4753   __ add(zeros_, zeros_, Operand(1));
   4754   // This wouldn't work for 1.0 or -1.0 as the shift would be 32 which means 0.
   4755   __ mov(source_, Operand(source_, LSL, zeros_));
   4756   // Compute lower part of fraction (last 12 bits).
   4757   __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord));
   4758   // And the top (top 20 bits).
   4759   __ orr(exponent,
   4760          exponent,
   4761          Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord));
   4762   __ Ret();
   4763 }
   4764 
   4765 
   4766 // This stub can convert a signed int32 to a heap number (double).  It does
   4767 // not work for int32s that are in Smi range!  No GC occurs during this stub
   4768 // so you don't have to set up the frame.
   4769 class WriteInt32ToHeapNumberStub : public CodeStub {
   4770  public:
   4771   WriteInt32ToHeapNumberStub(Register the_int,
   4772                              Register the_heap_number,
   4773                              Register scratch)
   4774       : the_int_(the_int),
   4775         the_heap_number_(the_heap_number),
   4776         scratch_(scratch) { }
   4777 
   4778  private:
   4779   Register the_int_;
   4780   Register the_heap_number_;
   4781   Register scratch_;
   4782 
   4783   // Minor key encoding in 16 bits.
   4784   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
   4785   class OpBits: public BitField<Token::Value, 2, 14> {};
   4786 
   4787   Major MajorKey() { return WriteInt32ToHeapNumber; }
   4788   int MinorKey() {
   4789     // Encode the parameters in a unique 16 bit value.
   4790     return  the_int_.code() +
   4791            (the_heap_number_.code() << 4) +
   4792            (scratch_.code() << 8);
   4793   }
   4794 
   4795   void Generate(MacroAssembler* masm);
   4796 
   4797   const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
   4798 
   4799 #ifdef DEBUG
   4800   void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
   4801 #endif
   4802 };
   4803 
   4804 
   4805 // See comment for class.
   4806 void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
   4807   Label max_negative_int;
   4808   // the_int_ has the answer which is a signed int32 but not a Smi.
   4809   // We test for the special value that has a different exponent.  This test
   4810   // has the neat side effect of setting the flags according to the sign.
   4811   ASSERT(HeapNumber::kSignMask == 0x80000000u);
   4812   __ cmp(the_int_, Operand(0x80000000u));
   4813   __ b(eq, &max_negative_int);
   4814   // Set up the correct exponent in scratch_.  All non-Smi int32s have the same.
   4815   // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).
   4816   uint32_t non_smi_exponent =
   4817       (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
   4818   __ mov(scratch_, Operand(non_smi_exponent));
   4819   // Set the sign bit in scratch_ if the value was negative.
   4820   __ orr(scratch_, scratch_, Operand(HeapNumber::kSignMask), LeaveCC, cs);
   4821   // Subtract from 0 if the value was negative.
   4822   __ rsb(the_int_, the_int_, Operand(0), LeaveCC, cs);
   4823   // We should be masking the implict first digit of the mantissa away here,
   4824   // but it just ends up combining harmlessly with the last digit of the
   4825   // exponent that happens to be 1.  The sign bit is 0 so we shift 10 to get
   4826   // the most significant 1 to hit the last bit of the 12 bit sign and exponent.
   4827   ASSERT(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0);
   4828   const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
   4829   __ orr(scratch_, scratch_, Operand(the_int_, LSR, shift_distance));
   4830   __ str(scratch_, FieldMemOperand(the_heap_number_,
   4831                                    HeapNumber::kExponentOffset));
   4832   __ mov(scratch_, Operand(the_int_, LSL, 32 - shift_distance));
   4833   __ str(scratch_, FieldMemOperand(the_heap_number_,
   4834                                    HeapNumber::kMantissaOffset));
   4835   __ Ret();
   4836 
   4837   __ bind(&max_negative_int);
   4838   // The max negative int32 is stored as a positive number in the mantissa of
   4839   // a double because it uses a sign bit instead of using two's complement.
   4840   // The actual mantissa bits stored are all 0 because the implicit most
   4841   // significant 1 bit is not stored.
   4842   non_smi_exponent += 1 << HeapNumber::kExponentShift;
   4843   __ mov(ip, Operand(HeapNumber::kSignMask | non_smi_exponent));
   4844   __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kExponentOffset));
   4845   __ mov(ip, Operand(0));
   4846   __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset));
   4847   __ Ret();
   4848 }
   4849 
   4850 
   4851 // Handle the case where the lhs and rhs are the same object.
   4852 // Equality is almost reflexive (everything but NaN), so this is a test
   4853 // for "identity and not NaN".
   4854 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
   4855                                           Label* slow,
   4856                                           Condition cc,
   4857                                           bool never_nan_nan) {
   4858   Label not_identical;
   4859   Label heap_number, return_equal;
   4860   Register exp_mask_reg = r5;
   4861   __ cmp(r0, Operand(r1));
   4862   __ b(ne, &not_identical);
   4863 
   4864   // The two objects are identical.  If we know that one of them isn't NaN then
   4865   // we now know they test equal.
   4866   if (cc != eq || !never_nan_nan) {
   4867     __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask));
   4868 
   4869     // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
   4870     // so we do the second best thing - test it ourselves.
   4871     // They are both equal and they are not both Smis so both of them are not
   4872     // Smis.  If it's not a heap number, then return equal.
   4873     if (cc == lt || cc == gt) {
   4874       __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
   4875       __ b(ge, slow);
   4876     } else {
   4877       __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
   4878       __ b(eq, &heap_number);
   4879       // Comparing JS objects with <=, >= is complicated.
   4880       if (cc != eq) {
   4881         __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
   4882         __ b(ge, slow);
   4883         // Normally here we fall through to return_equal, but undefined is
   4884         // special: (undefined == undefined) == true, but
   4885         // (undefined <= undefined) == false!  See ECMAScript 11.8.5.
   4886         if (cc == le || cc == ge) {
   4887           __ cmp(r4, Operand(ODDBALL_TYPE));
   4888           __ b(ne, &return_equal);
   4889           __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
   4890           __ cmp(r0, Operand(r2));
   4891           __ b(ne, &return_equal);
   4892           if (cc == le) {
   4893             // undefined <= undefined should fail.
   4894             __ mov(r0, Operand(GREATER));
   4895           } else  {
   4896             // undefined >= undefined should fail.
   4897             __ mov(r0, Operand(LESS));
   4898           }
   4899           __ mov(pc, Operand(lr));       // Return.
   4900         }
   4901       }
   4902     }
   4903   }
   4904 
   4905   __ bind(&return_equal);
   4906   if (cc == lt) {
   4907     __ mov(r0, Operand(GREATER));  // Things aren't less than themselves.
   4908   } else if (cc == gt) {
   4909     __ mov(r0, Operand(LESS));     // Things aren't greater than themselves.
   4910   } else {
   4911     __ mov(r0, Operand(EQUAL));    // Things are <=, >=, ==, === themselves.
   4912   }
   4913   __ mov(pc, Operand(lr));  // Return.
   4914 
   4915   if (cc != eq || !never_nan_nan) {
   4916     // For less and greater we don't have to check for NaN since the result of
   4917     // x < x is false regardless.  For the others here is some code to check
   4918     // for NaN.
   4919     if (cc != lt && cc != gt) {
   4920       __ bind(&heap_number);
   4921       // It is a heap number, so return non-equal if it's NaN and equal if it's
   4922       // not NaN.
   4923 
   4924       // The representation of NaN values has all exponent bits (52..62) set,
   4925       // and not all mantissa bits (0..51) clear.
   4926       // Read top bits of double representation (second word of value).
   4927       __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
   4928       // Test that exponent bits are all set.
   4929       __ and_(r3, r2, Operand(exp_mask_reg));
   4930       __ cmp(r3, Operand(exp_mask_reg));
   4931       __ b(ne, &return_equal);
   4932 
   4933       // Shift out flag and all exponent bits, retaining only mantissa.
   4934       __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord));
   4935       // Or with all low-bits of mantissa.
   4936       __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
   4937       __ orr(r0, r3, Operand(r2), SetCC);
   4938       // For equal we already have the right value in r0:  Return zero (equal)
   4939       // if all bits in mantissa are zero (it's an Infinity) and non-zero if
   4940       // not (it's a NaN).  For <= and >= we need to load r0 with the failing
   4941       // value if it's a NaN.
   4942       if (cc != eq) {
   4943         // All-zero means Infinity means equal.
   4944         __ mov(pc, Operand(lr), LeaveCC, eq);  // Return equal
   4945         if (cc == le) {
   4946           __ mov(r0, Operand(GREATER));  // NaN <= NaN should fail.
   4947         } else {
   4948           __ mov(r0, Operand(LESS));     // NaN >= NaN should fail.
   4949         }
   4950       }
   4951       __ mov(pc, Operand(lr));  // Return.
   4952     }
   4953     // No fall through here.
   4954   }
   4955 
   4956   __ bind(&not_identical);
   4957 }
   4958 
   4959 
   4960 // See comment at call site.
   4961 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
   4962                                     Label* lhs_not_nan,
   4963                                     Label* slow,
   4964                                     bool strict) {
   4965   Label rhs_is_smi;
   4966   __ tst(r0, Operand(kSmiTagMask));
   4967   __ b(eq, &rhs_is_smi);
   4968 
   4969   // Lhs is a Smi.  Check whether the rhs is a heap number.
   4970   __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
   4971   if (strict) {
   4972     // If rhs is not a number and lhs is a Smi then strict equality cannot
   4973     // succeed.  Return non-equal (r0 is already not zero)
   4974     __ mov(pc, Operand(lr), LeaveCC, ne);  // Return.
   4975   } else {
   4976     // Smi compared non-strictly with a non-Smi non-heap-number.  Call
   4977     // the runtime.
   4978     __ b(ne, slow);
   4979   }
   4980 
   4981   // Lhs (r1) is a smi, rhs (r0) is a number.
   4982   if (CpuFeatures::IsSupported(VFP3)) {
   4983     // Convert lhs to a double in d7              .
   4984     CpuFeatures::Scope scope(VFP3);
   4985     __ mov(r7, Operand(r1, ASR, kSmiTagSize));
   4986     __ vmov(s15, r7);
   4987     __ vcvt(d7, s15);
   4988     // Load the double from rhs, tagged HeapNumber r0, to d6.
   4989     __ sub(r7, r0, Operand(kHeapObjectTag));
   4990     __ vldr(d6, r7, HeapNumber::kValueOffset);
   4991   } else {
   4992     __ push(lr);
   4993     // Convert lhs to a double in r2, r3.
   4994     __ mov(r7, Operand(r1));
   4995     ConvertToDoubleStub stub1(r3, r2, r7, r6);
   4996     __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
   4997     // Load rhs to a double in r0, r1.
   4998     __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
   4999     __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
   5000     __ pop(lr);
   5001   }
   5002 
   5003   // We now have both loaded as doubles but we can skip the lhs nan check
   5004   // since it's a smi.
   5005   __ jmp(lhs_not_nan);
   5006 
   5007   __ bind(&rhs_is_smi);
   5008   // Rhs is a smi.  Check whether the non-smi lhs is a heap number.
   5009   __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
   5010   if (strict) {
   5011     // If lhs is not a number and rhs is a smi then strict equality cannot
   5012     // succeed.  Return non-equal.
   5013     __ mov(r0, Operand(1), LeaveCC, ne);  // Non-zero indicates not equal.
   5014     __ mov(pc, Operand(lr), LeaveCC, ne);  // Return.
   5015   } else {
   5016     // Smi compared non-strictly with a non-smi non-heap-number.  Call
   5017     // the runtime.
   5018     __ b(ne, slow);
   5019   }
   5020 
   5021   // Rhs (r0) is a smi, lhs (r1) is a heap number.
   5022   if (CpuFeatures::IsSupported(VFP3)) {
   5023     // Convert rhs to a double in d6              .
   5024     CpuFeatures::Scope scope(VFP3);
   5025     // Load the double from lhs, tagged HeapNumber r1, to d7.
   5026     __ sub(r7, r1, Operand(kHeapObjectTag));
   5027     __ vldr(d7, r7, HeapNumber::kValueOffset);
   5028     __ mov(r7, Operand(r0, ASR, kSmiTagSize));
   5029     __ vmov(s13, r7);
   5030     __ vcvt(d6, s13);
   5031   } else {
   5032     __ push(lr);
   5033     // Load lhs to a double in r2, r3.
   5034     __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
   5035     __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
   5036     // Convert rhs to a double in r0, r1.
   5037     __ mov(r7, Operand(r0));
   5038     ConvertToDoubleStub stub2(r1, r0, r7, r6);
   5039     __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
   5040     __ pop(lr);
   5041   }
   5042   // Fall through to both_loaded_as_doubles.
   5043 }
   5044 
   5045 
   5046 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) {
   5047   bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
   5048   Register rhs_exponent = exp_first ? r0 : r1;
   5049   Register lhs_exponent = exp_first ? r2 : r3;
   5050   Register rhs_mantissa = exp_first ? r1 : r0;
   5051   Register lhs_mantissa = exp_first ? r3 : r2;
   5052   Label one_is_nan, neither_is_nan;
   5053   Label lhs_not_nan_exp_mask_is_loaded;
   5054 
   5055   Register exp_mask_reg = r5;
   5056 
   5057   __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask));
   5058   __ and_(r4, lhs_exponent, Operand(exp_mask_reg));
   5059   __ cmp(r4, Operand(exp_mask_reg));
   5060   __ b(ne, &lhs_not_nan_exp_mask_is_loaded);
   5061   __ mov(r4,
   5062          Operand(lhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
   5063          SetCC);
   5064   __ b(ne, &one_is_nan);
   5065   __ cmp(lhs_mantissa, Operand(0));
   5066   __ b(ne, &one_is_nan);
   5067 
   5068   __ bind(lhs_not_nan);
   5069   __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask));
   5070   __ bind(&lhs_not_nan_exp_mask_is_loaded);
   5071   __ and_(r4, rhs_exponent, Operand(exp_mask_reg));
   5072   __ cmp(r4, Operand(exp_mask_reg));
   5073   __ b(ne, &neither_is_nan);
   5074   __ mov(r4,
   5075          Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
   5076          SetCC);
   5077   __ b(ne, &one_is_nan);
   5078   __ cmp(rhs_mantissa, Operand(0));
   5079   __ b(eq, &neither_is_nan);
   5080 
   5081   __ bind(&one_is_nan);
   5082   // NaN comparisons always fail.
   5083   // Load whatever we need in r0 to make the comparison fail.
   5084   if (cc == lt || cc == le) {
   5085     __ mov(r0, Operand(GREATER));
   5086   } else {
   5087     __ mov(r0, Operand(LESS));
   5088   }
   5089   __ mov(pc, Operand(lr));  // Return.
   5090 
   5091   __ bind(&neither_is_nan);
   5092 }
   5093 
   5094 
   5095 // See comment at call site.
   5096 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) {
   5097   bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
   5098   Register rhs_exponent = exp_first ? r0 : r1;
   5099   Register lhs_exponent = exp_first ? r2 : r3;
   5100   Register rhs_mantissa = exp_first ? r1 : r0;
   5101   Register lhs_mantissa = exp_first ? r3 : r2;
   5102 
   5103   // r0, r1, r2, r3 have the two doubles.  Neither is a NaN.
   5104   if (cc == eq) {
   5105     // Doubles are not equal unless they have the same bit pattern.
   5106     // Exception: 0 and -0.
   5107     __ cmp(rhs_mantissa, Operand(lhs_mantissa));
   5108     __ orr(r0, rhs_mantissa, Operand(lhs_mantissa), LeaveCC, ne);
   5109     // Return non-zero if the numbers are unequal.
   5110     __ mov(pc, Operand(lr), LeaveCC, ne);
   5111 
   5112     __ sub(r0, rhs_exponent, Operand(lhs_exponent), SetCC);
   5113     // If exponents are equal then return 0.
   5114     __ mov(pc, Operand(lr), LeaveCC, eq);
   5115 
   5116     // Exponents are unequal.  The only way we can return that the numbers
   5117     // are equal is if one is -0 and the other is 0.  We already dealt
   5118     // with the case where both are -0 or both are 0.
   5119     // We start by seeing if the mantissas (that are equal) or the bottom
   5120     // 31 bits of the rhs exponent are non-zero.  If so we return not
   5121     // equal.
   5122     __ orr(r4, lhs_mantissa, Operand(lhs_exponent, LSL, kSmiTagSize), SetCC);
   5123     __ mov(r0, Operand(r4), LeaveCC, ne);
   5124     __ mov(pc, Operand(lr), LeaveCC, ne);  // Return conditionally.
   5125     // Now they are equal if and only if the lhs exponent is zero in its
   5126     // low 31 bits.
   5127     __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize));
   5128     __ mov(pc, Operand(lr));
   5129   } else {
   5130     // Call a native function to do a comparison between two non-NaNs.
   5131     // Call C routine that may not cause GC or other trouble.
   5132     __ mov(r5, Operand(ExternalReference::compare_doubles()));
   5133     __ Jump(r5);  // Tail call.
   5134   }
   5135 }
   5136 
   5137 
   5138 // See comment at call site.
   5139 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm) {
   5140     // If either operand is a JSObject or an oddball value, then they are
   5141     // not equal since their pointers are different.
   5142     // There is no test for undetectability in strict equality.
   5143     ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
   5144     Label first_non_object;
   5145     // Get the type of the first operand into r2 and compare it with
   5146     // FIRST_JS_OBJECT_TYPE.
   5147     __ CompareObjectType(r0, r2, r2, FIRST_JS_OBJECT_TYPE);
   5148     __ b(lt, &first_non_object);
   5149 
   5150     // Return non-zero (r0 is not zero)
   5151     Label return_not_equal;
   5152     __ bind(&return_not_equal);
   5153     __ mov(pc, Operand(lr));  // Return.
   5154 
   5155     __ bind(&first_non_object);
   5156     // Check for oddballs: true, false, null, undefined.
   5157     __ cmp(r2, Operand(ODDBALL_TYPE));
   5158     __ b(eq, &return_not_equal);
   5159 
   5160     __ CompareObjectType(r1, r3, r3, FIRST_JS_OBJECT_TYPE);
   5161     __ b(ge, &return_not_equal);
   5162 
   5163     // Check for oddballs: true, false, null, undefined.
   5164     __ cmp(r3, Operand(ODDBALL_TYPE));
   5165     __ b(eq, &return_not_equal);
   5166 
   5167     // Now that we have the types we might as well check for symbol-symbol.
   5168     // Ensure that no non-strings have the symbol bit set.
   5169     ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
   5170     ASSERT(kSymbolTag != 0);
   5171     __ and_(r2, r2, Operand(r3));
   5172     __ tst(r2, Operand(kIsSymbolMask));
   5173     __ b(ne, &return_not_equal);
   5174 }
   5175 
   5176 
   5177 // See comment at call site.
   5178 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
   5179                                        Label* both_loaded_as_doubles,
   5180                                        Label* not_heap_numbers,
   5181                                        Label* slow) {
   5182   __ CompareObjectType(r0, r3, r2, HEAP_NUMBER_TYPE);
   5183   __ b(ne, not_heap_numbers);
   5184   __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
   5185   __ cmp(r2, r3);
   5186   __ b(ne, slow);  // First was a heap number, second wasn't.  Go slow case.
   5187 
   5188   // Both are heap numbers.  Load them up then jump to the code we have
   5189   // for that.
   5190   if (CpuFeatures::IsSupported(VFP3)) {
   5191     CpuFeatures::Scope scope(VFP3);
   5192     __ sub(r7, r0, Operand(kHeapObjectTag));
   5193     __ vldr(d6, r7, HeapNumber::kValueOffset);
   5194     __ sub(r7, r1, Operand(kHeapObjectTag));
   5195     __ vldr(d7, r7, HeapNumber::kValueOffset);
   5196   } else {
   5197     __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
   5198     __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
   5199     __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
   5200     __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
   5201   }
   5202   __ jmp(both_loaded_as_doubles);
   5203 }
   5204 
   5205 
   5206 // Fast negative check for symbol-to-symbol equality.
   5207 static void EmitCheckForSymbols(MacroAssembler* masm, Label* slow) {
   5208   // r2 is object type of r0.
   5209   // Ensure that no non-strings have the symbol bit set.
   5210   ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
   5211   ASSERT(kSymbolTag != 0);
   5212   __ tst(r2, Operand(kIsSymbolMask));
   5213   __ b(eq, slow);
   5214   __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
   5215   __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
   5216   __ tst(r3, Operand(kIsSymbolMask));
   5217   __ b(eq, slow);
   5218 
   5219   // Both are symbols.  We already checked they weren't the same pointer
   5220   // so they are not equal.
   5221   __ mov(r0, Operand(1));   // Non-zero indicates not equal.
   5222   __ mov(pc, Operand(lr));  // Return.
   5223 }
   5224 
   5225 
   5226 // On entry r0 (rhs) and r1 (lhs) are the values to be compared.
   5227 // On exit r0 is 0, positive or negative to indicate the result of
   5228 // the comparison.
   5229 void CompareStub::Generate(MacroAssembler* masm) {
   5230   Label slow;  // Call builtin.
   5231   Label not_smis, both_loaded_as_doubles, lhs_not_nan;
   5232 
   5233   // NOTICE! This code is only reached after a smi-fast-case check, so
   5234   // it is certain that at least one operand isn't a smi.
   5235 
   5236   // Handle the case where the objects are identical.  Either returns the answer
   5237   // or goes to slow.  Only falls through if the objects were not identical.
   5238   EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_);
   5239 
   5240   // If either is a Smi (we know that not both are), then they can only
   5241   // be strictly equal if the other is a HeapNumber.
   5242   ASSERT_EQ(0, kSmiTag);
   5243   ASSERT_EQ(0, Smi::FromInt(0));
   5244   __ and_(r2, r0, Operand(r1));
   5245   __ tst(r2, Operand(kSmiTagMask));
   5246   __ b(ne, &not_smis);
   5247   // One operand is a smi.  EmitSmiNonsmiComparison generates code that can:
   5248   // 1) Return the answer.
   5249   // 2) Go to slow.
   5250   // 3) Fall through to both_loaded_as_doubles.
   5251   // 4) Jump to lhs_not_nan.
   5252   // In cases 3 and 4 we have found out we were dealing with a number-number
   5253   // comparison.  If VFP3 is supported the double values of the numbers have
   5254   // been loaded into d7 and d6.  Otherwise, the double values have been loaded
   5255   // into r0, r1, r2, and r3.
   5256   EmitSmiNonsmiComparison(masm, &lhs_not_nan, &slow, strict_);
   5257 
   5258   __ bind(&both_loaded_as_doubles);
   5259   // The arguments have been converted to doubles and stored in d6 and d7, if
   5260   // VFP3 is supported, or in r0, r1, r2, and r3.
   5261   if (CpuFeatures::IsSupported(VFP3)) {
   5262     __ bind(&lhs_not_nan);
   5263     CpuFeatures::Scope scope(VFP3);
   5264     Label no_nan;
   5265     // ARMv7 VFP3 instructions to implement double precision comparison.
   5266     __ vcmp(d7, d6);
   5267     __ vmrs(pc);  // Move vector status bits to normal status bits.
   5268     Label nan;
   5269     __ b(vs, &nan);
   5270     __ mov(r0, Operand(EQUAL), LeaveCC, eq);
   5271     __ mov(r0, Operand(LESS), LeaveCC, lt);
   5272     __ mov(r0, Operand(GREATER), LeaveCC, gt);
   5273     __ mov(pc, Operand(lr));
   5274 
   5275     __ bind(&nan);
   5276     // If one of the sides was a NaN then the v flag is set.  Load r0 with
   5277     // whatever it takes to make the comparison fail, since comparisons with NaN
   5278     // always fail.
   5279     if (cc_ == lt || cc_ == le) {
   5280       __ mov(r0, Operand(GREATER));
   5281     } else {
   5282       __ mov(r0, Operand(LESS));
   5283     }
   5284     __ mov(pc, Operand(lr));
   5285   } else {
   5286     // Checks for NaN in the doubles we have loaded.  Can return the answer or
   5287     // fall through if neither is a NaN.  Also binds lhs_not_nan.
   5288     EmitNanCheck(masm, &lhs_not_nan, cc_);
   5289     // Compares two doubles in r0, r1, r2, r3 that are not NaNs.  Returns the
   5290     // answer.  Never falls through.
   5291     EmitTwoNonNanDoubleComparison(masm, cc_);
   5292   }
   5293 
   5294   __ bind(&not_smis);
   5295   // At this point we know we are dealing with two different objects,
   5296   // and neither of them is a Smi.  The objects are in r0 and r1.
   5297   if (strict_) {
   5298     // This returns non-equal for some object types, or falls through if it
   5299     // was not lucky.
   5300     EmitStrictTwoHeapObjectCompare(masm);
   5301   }
   5302 
   5303   Label check_for_symbols;
   5304   Label flat_string_check;
   5305   // Check for heap-number-heap-number comparison.  Can jump to slow case,
   5306   // or load both doubles into r0, r1, r2, r3 and jump to the code that handles
   5307   // that case.  If the inputs are not doubles then jumps to check_for_symbols.
   5308   // In this case r2 will contain the type of r0.  Never falls through.
   5309   EmitCheckForTwoHeapNumbers(masm,
   5310                              &both_loaded_as_doubles,
   5311                              &check_for_symbols,
   5312                              &flat_string_check);
   5313 
   5314   __ bind(&check_for_symbols);
   5315   // In the strict case the EmitStrictTwoHeapObjectCompare already took care of
   5316   // symbols.
   5317   if (cc_ == eq && !strict_) {
   5318     // Either jumps to slow or returns the answer.  Assumes that r2 is the type
   5319     // of r0 on entry.
   5320     EmitCheckForSymbols(masm, &flat_string_check);
   5321   }
   5322 
   5323   // Check for both being sequential ASCII strings, and inline if that is the
   5324   // case.
   5325   __ bind(&flat_string_check);
   5326 
   5327   __ JumpIfNonSmisNotBothSequentialAsciiStrings(r0, r1, r2, r3, &slow);
   5328 
   5329   __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3);
   5330   StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
   5331                                                      r1,
   5332                                                      r0,
   5333                                                      r2,
   5334                                                      r3,
   5335                                                      r4,
   5336                                                      r5);
   5337   // Never falls through to here.
   5338 
   5339   __ bind(&slow);
   5340 
   5341   __ push(r1);
   5342   __ push(r0);
   5343   // Figure out which native to call and setup the arguments.
   5344   Builtins::JavaScript native;
   5345   if (cc_ == eq) {
   5346     native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
   5347   } else {
   5348     native = Builtins::COMPARE;
   5349     int ncr;  // NaN compare result
   5350     if (cc_ == lt || cc_ == le) {
   5351       ncr = GREATER;
   5352     } else {
   5353       ASSERT(cc_ == gt || cc_ == ge);  // remaining cases
   5354       ncr = LESS;
   5355     }
   5356     __ mov(r0, Operand(Smi::FromInt(ncr)));
   5357     __ push(r0);
   5358   }
   5359 
   5360   // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
   5361   // tagged as a small integer.
   5362   __ InvokeBuiltin(native, JUMP_JS);
   5363 }
   5364 
   5365 
   5366 // Allocates a heap number or jumps to the label if the young space is full and
   5367 // a scavenge is needed.
   5368 static void AllocateHeapNumber(
   5369     MacroAssembler* masm,
   5370     Label* need_gc,       // Jump here if young space is full.
   5371     Register result,  // The tagged address of the new heap number.
   5372     Register scratch1,  // A scratch register.
   5373     Register scratch2) {  // Another scratch register.
   5374   // Allocate an object in the heap for the heap number and tag it as a heap
   5375   // object.
   5376   __ AllocateInNewSpace(HeapNumber::kSize / kPointerSize,
   5377                         result,
   5378                         scratch1,
   5379                         scratch2,
   5380                         need_gc,
   5381                         TAG_OBJECT);
   5382 
   5383   // Get heap number map and store it in the allocated object.
   5384   __ LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex);
   5385   __ str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
   5386 }
   5387 
   5388 
   5389 // We fall into this code if the operands were Smis, but the result was
   5390 // not (eg. overflow).  We branch into this code (to the not_smi label) if
   5391 // the operands were not both Smi.  The operands are in r0 and r1.  In order
   5392 // to call the C-implemented binary fp operation routines we need to end up
   5393 // with the double precision floating point operands in r0 and r1 (for the
   5394 // value in r1) and r2 and r3 (for the value in r0).
   5395 static void HandleBinaryOpSlowCases(MacroAssembler* masm,
   5396                                     Label* not_smi,
   5397                                     const Builtins::JavaScript& builtin,
   5398                                     Token::Value operation,
   5399                                     OverwriteMode mode) {
   5400   Label slow, slow_pop_2_first, do_the_call;
   5401   Label r0_is_smi, r1_is_smi, finished_loading_r0, finished_loading_r1;
   5402   // Smi-smi case (overflow).
   5403   // Since both are Smis there is no heap number to overwrite, so allocate.
   5404   // The new heap number is in r5.  r6 and r7 are scratch.
   5405   AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5406 
   5407   // If we have floating point hardware, inline ADD, SUB, MUL, and DIV,
   5408   // using registers d7 and d6 for the double values.
   5409   bool use_fp_registers = CpuFeatures::IsSupported(VFP3) &&
   5410       Token::MOD != operation;
   5411   if (use_fp_registers) {
   5412     CpuFeatures::Scope scope(VFP3);
   5413     __ mov(r7, Operand(r0, ASR, kSmiTagSize));
   5414     __ vmov(s15, r7);
   5415     __ vcvt(d7, s15);
   5416     __ mov(r7, Operand(r1, ASR, kSmiTagSize));
   5417     __ vmov(s13, r7);
   5418     __ vcvt(d6, s13);
   5419   } else {
   5420     // Write Smi from r0 to r3 and r2 in double format.  r6 is scratch.
   5421     __ mov(r7, Operand(r0));
   5422     ConvertToDoubleStub stub1(r3, r2, r7, r6);
   5423     __ push(lr);
   5424     __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
   5425     // Write Smi from r1 to r1 and r0 in double format.  r6 is scratch.
   5426     __ mov(r7, Operand(r1));
   5427     ConvertToDoubleStub stub2(r1, r0, r7, r6);
   5428     __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
   5429     __ pop(lr);
   5430   }
   5431 
   5432   __ jmp(&do_the_call);  // Tail call.  No return.
   5433 
   5434   // We jump to here if something goes wrong (one param is not a number of any
   5435   // sort or new-space allocation fails).
   5436   __ bind(&slow);
   5437 
   5438   // Push arguments to the stack
   5439   __ push(r1);
   5440   __ push(r0);
   5441 
   5442   if (Token::ADD == operation) {
   5443     // Test for string arguments before calling runtime.
   5444     // r1 : first argument
   5445     // r0 : second argument
   5446     // sp[0] : second argument
   5447     // sp[4] : first argument
   5448 
   5449     Label not_strings, not_string1, string1;
   5450     __ tst(r1, Operand(kSmiTagMask));
   5451     __ b(eq, &not_string1);
   5452     __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE);
   5453     __ b(ge, &not_string1);
   5454 
   5455     // First argument is a a string, test second.
   5456     __ tst(r0, Operand(kSmiTagMask));
   5457     __ b(eq, &string1);
   5458     __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE);
   5459     __ b(ge, &string1);
   5460 
   5461     // First and second argument are strings.
   5462     StringAddStub stub(NO_STRING_CHECK_IN_STUB);
   5463     __ TailCallStub(&stub);
   5464 
   5465     // Only first argument is a string.
   5466     __ bind(&string1);
   5467     __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_JS);
   5468 
   5469     // First argument was not a string, test second.
   5470     __ bind(&not_string1);
   5471     __ tst(r0, Operand(kSmiTagMask));
   5472     __ b(eq, &not_strings);
   5473     __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE);
   5474     __ b(ge, &not_strings);
   5475 
   5476     // Only second argument is a string.
   5477     __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_JS);
   5478 
   5479     __ bind(&not_strings);
   5480   }
   5481 
   5482   __ InvokeBuiltin(builtin, JUMP_JS);  // Tail call.  No return.
   5483 
   5484   // We branch here if at least one of r0 and r1 is not a Smi.
   5485   __ bind(not_smi);
   5486   if (mode == NO_OVERWRITE) {
   5487     // In the case where there is no chance of an overwritable float we may as
   5488     // well do the allocation immediately while r0 and r1 are untouched.
   5489     AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5490   }
   5491 
   5492   // Move r0 to a double in r2-r3.
   5493   __ tst(r0, Operand(kSmiTagMask));
   5494   __ b(eq, &r0_is_smi);  // It's a Smi so don't check it's a heap number.
   5495   __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
   5496   __ b(ne, &slow);
   5497   if (mode == OVERWRITE_RIGHT) {
   5498     __ mov(r5, Operand(r0));  // Overwrite this heap number.
   5499   }
   5500   if (use_fp_registers) {
   5501     CpuFeatures::Scope scope(VFP3);
   5502     // Load the double from tagged HeapNumber r0 to d7.
   5503     __ sub(r7, r0, Operand(kHeapObjectTag));
   5504     __ vldr(d7, r7, HeapNumber::kValueOffset);
   5505   } else {
   5506     // Calling convention says that second double is in r2 and r3.
   5507     __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
   5508     __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4));
   5509   }
   5510   __ jmp(&finished_loading_r0);
   5511   __ bind(&r0_is_smi);
   5512   if (mode == OVERWRITE_RIGHT) {
   5513     // We can't overwrite a Smi so get address of new heap number into r5.
   5514     AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5515   }
   5516 
   5517   if (use_fp_registers) {
   5518     CpuFeatures::Scope scope(VFP3);
   5519     // Convert smi in r0 to double in d7.
   5520     __ mov(r7, Operand(r0, ASR, kSmiTagSize));
   5521     __ vmov(s15, r7);
   5522     __ vcvt(d7, s15);
   5523   } else {
   5524     // Write Smi from r0 to r3 and r2 in double format.
   5525     __ mov(r7, Operand(r0));
   5526     ConvertToDoubleStub stub3(r3, r2, r7, r6);
   5527     __ push(lr);
   5528     __ Call(stub3.GetCode(), RelocInfo::CODE_TARGET);
   5529     __ pop(lr);
   5530   }
   5531 
   5532   __ bind(&finished_loading_r0);
   5533 
   5534   // Move r1 to a double in r0-r1.
   5535   __ tst(r1, Operand(kSmiTagMask));
   5536   __ b(eq, &r1_is_smi);  // It's a Smi so don't check it's a heap number.
   5537   __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
   5538   __ b(ne, &slow);
   5539   if (mode == OVERWRITE_LEFT) {
   5540     __ mov(r5, Operand(r1));  // Overwrite this heap number.
   5541   }
   5542   if (use_fp_registers) {
   5543     CpuFeatures::Scope scope(VFP3);
   5544     // Load the double from tagged HeapNumber r1 to d6.
   5545     __ sub(r7, r1, Operand(kHeapObjectTag));
   5546     __ vldr(d6, r7, HeapNumber::kValueOffset);
   5547   } else {
   5548     // Calling convention says that first double is in r0 and r1.
   5549     __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
   5550     __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4));
   5551   }
   5552   __ jmp(&finished_loading_r1);
   5553   __ bind(&r1_is_smi);
   5554   if (mode == OVERWRITE_LEFT) {
   5555     // We can't overwrite a Smi so get address of new heap number into r5.
   5556     AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5557   }
   5558 
   5559   if (use_fp_registers) {
   5560     CpuFeatures::Scope scope(VFP3);
   5561     // Convert smi in r1 to double in d6.
   5562     __ mov(r7, Operand(r1, ASR, kSmiTagSize));
   5563     __ vmov(s13, r7);
   5564     __ vcvt(d6, s13);
   5565   } else {
   5566     // Write Smi from r1 to r1 and r0 in double format.
   5567     __ mov(r7, Operand(r1));
   5568     ConvertToDoubleStub stub4(r1, r0, r7, r6);
   5569     __ push(lr);
   5570     __ Call(stub4.GetCode(), RelocInfo::CODE_TARGET);
   5571     __ pop(lr);
   5572   }
   5573 
   5574   __ bind(&finished_loading_r1);
   5575 
   5576   __ bind(&do_the_call);
   5577   // If we are inlining the operation using VFP3 instructions for
   5578   // add, subtract, multiply, or divide, the arguments are in d6 and d7.
   5579   if (use_fp_registers) {
   5580     CpuFeatures::Scope scope(VFP3);
   5581     // ARMv7 VFP3 instructions to implement
   5582     // double precision, add, subtract, multiply, divide.
   5583 
   5584     if (Token::MUL == operation) {
   5585       __ vmul(d5, d6, d7);
   5586     } else if (Token::DIV == operation) {
   5587       __ vdiv(d5, d6, d7);
   5588     } else if (Token::ADD == operation) {
   5589       __ vadd(d5, d6, d7);
   5590     } else if (Token::SUB == operation) {
   5591       __ vsub(d5, d6, d7);
   5592     } else {
   5593       UNREACHABLE();
   5594     }
   5595     __ sub(r0, r5, Operand(kHeapObjectTag));
   5596     __ vstr(d5, r0, HeapNumber::kValueOffset);
   5597     __ add(r0, r0, Operand(kHeapObjectTag));
   5598     __ mov(pc, lr);
   5599     return;
   5600   }
   5601 
   5602   // If we did not inline the operation, then the arguments are in:
   5603   // r0: Left value (least significant part of mantissa).
   5604   // r1: Left value (sign, exponent, top of mantissa).
   5605   // r2: Right value (least significant part of mantissa).
   5606   // r3: Right value (sign, exponent, top of mantissa).
   5607   // r5: Address of heap number for result.
   5608 
   5609   __ push(lr);   // For later.
   5610   __ push(r5);   // Address of heap number that is answer.
   5611   __ AlignStack(0);
   5612   // Call C routine that may not cause GC or other trouble.
   5613   __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
   5614   __ Call(r5);
   5615   __ pop(r4);  // Address of heap number.
   5616   __ cmp(r4, Operand(Smi::FromInt(0)));
   5617   __ pop(r4, eq);  // Conditional pop instruction to get rid of alignment push.
   5618   // Store answer in the overwritable heap number.
   5619 #if !defined(USE_ARM_EABI)
   5620   // Double returned in fp coprocessor register 0 and 1, encoded as register
   5621   // cr8.  Offsets must be divisible by 4 for coprocessor so we need to
   5622   // substract the tag from r4.
   5623   __ sub(r5, r4, Operand(kHeapObjectTag));
   5624   __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
   5625 #else
   5626   // Double returned in registers 0 and 1.
   5627   __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
   5628   __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + 4));
   5629 #endif
   5630   __ mov(r0, Operand(r4));
   5631   // And we are done.
   5632   __ pop(pc);
   5633 }
   5634 
   5635 
   5636 // Tries to get a signed int32 out of a double precision floating point heap
   5637 // number.  Rounds towards 0.  Fastest for doubles that are in the ranges
   5638 // -0x7fffffff to -0x40000000 or 0x40000000 to 0x7fffffff.  This corresponds
   5639 // almost to the range of signed int32 values that are not Smis.  Jumps to the
   5640 // label 'slow' if the double isn't in the range -0x80000000.0 to 0x80000000.0
   5641 // (excluding the endpoints).
   5642 static void GetInt32(MacroAssembler* masm,
   5643                      Register source,
   5644                      Register dest,
   5645                      Register scratch,
   5646                      Register scratch2,
   5647                      Label* slow) {
   5648   Label right_exponent, done;
   5649   // Get exponent word.
   5650   __ ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset));
   5651   // Get exponent alone in scratch2.
   5652   __ and_(scratch2, scratch, Operand(HeapNumber::kExponentMask));
   5653   // Load dest with zero.  We use this either for the final shift or
   5654   // for the answer.
   5655   __ mov(dest, Operand(0));
   5656   // Check whether the exponent matches a 32 bit signed int that is not a Smi.
   5657   // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).  This is
   5658   // the exponent that we are fastest at and also the highest exponent we can
   5659   // handle here.
   5660   const uint32_t non_smi_exponent =
   5661       (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
   5662   __ cmp(scratch2, Operand(non_smi_exponent));
   5663   // If we have a match of the int32-but-not-Smi exponent then skip some logic.
   5664   __ b(eq, &right_exponent);
   5665   // If the exponent is higher than that then go to slow case.  This catches
   5666   // numbers that don't fit in a signed int32, infinities and NaNs.
   5667   __ b(gt, slow);
   5668 
   5669   // We know the exponent is smaller than 30 (biased).  If it is less than
   5670   // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie
   5671   // it rounds to zero.
   5672   const uint32_t zero_exponent =
   5673       (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift;
   5674   __ sub(scratch2, scratch2, Operand(zero_exponent), SetCC);
   5675   // Dest already has a Smi zero.
   5676   __ b(lt, &done);
   5677   if (!CpuFeatures::IsSupported(VFP3)) {
   5678     // We have a shifted exponent between 0 and 30 in scratch2.
   5679     __ mov(dest, Operand(scratch2, LSR, HeapNumber::kExponentShift));
   5680     // We now have the exponent in dest.  Subtract from 30 to get
   5681     // how much to shift down.
   5682     __ rsb(dest, dest, Operand(30));
   5683   }
   5684   __ bind(&right_exponent);
   5685   if (CpuFeatures::IsSupported(VFP3)) {
   5686     CpuFeatures::Scope scope(VFP3);
   5687     // ARMv7 VFP3 instructions implementing double precision to integer
   5688     // conversion using round to zero.
   5689     __ ldr(scratch2, FieldMemOperand(source, HeapNumber::kMantissaOffset));
   5690     __ vmov(d7, scratch2, scratch);
   5691     __ vcvt(s15, d7);
   5692     __ vmov(dest, s15);
   5693   } else {
   5694     // Get the top bits of the mantissa.
   5695     __ and_(scratch2, scratch, Operand(HeapNumber::kMantissaMask));
   5696     // Put back the implicit 1.
   5697     __ orr(scratch2, scratch2, Operand(1 << HeapNumber::kExponentShift));
   5698     // Shift up the mantissa bits to take up the space the exponent used to
   5699     // take. We just orred in the implicit bit so that took care of one and
   5700     // we want to leave the sign bit 0 so we subtract 2 bits from the shift
   5701     // distance.
   5702     const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
   5703     __ mov(scratch2, Operand(scratch2, LSL, shift_distance));
   5704     // Put sign in zero flag.
   5705     __ tst(scratch, Operand(HeapNumber::kSignMask));
   5706     // Get the second half of the double. For some exponents we don't
   5707     // actually need this because the bits get shifted out again, but
   5708     // it's probably slower to test than just to do it.
   5709     __ ldr(scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset));
   5710     // Shift down 22 bits to get the last 10 bits.
   5711     __ orr(scratch, scratch2, Operand(scratch, LSR, 32 - shift_distance));
   5712     // Move down according to the exponent.
   5713     __ mov(dest, Operand(scratch, LSR, dest));
   5714     // Fix sign if sign bit was set.
   5715     __ rsb(dest, dest, Operand(0), LeaveCC, ne);
   5716   }
   5717   __ bind(&done);
   5718 }
   5719 
   5720 // For bitwise ops where the inputs are not both Smis we here try to determine
   5721 // whether both inputs are either Smis or at least heap numbers that can be
   5722 // represented by a 32 bit signed value.  We truncate towards zero as required
   5723 // by the ES spec.  If this is the case we do the bitwise op and see if the
   5724 // result is a Smi.  If so, great, otherwise we try to find a heap number to
   5725 // write the answer into (either by allocating or by overwriting).
   5726 // On entry the operands are in r0 and r1.  On exit the answer is in r0.
   5727 void GenericBinaryOpStub::HandleNonSmiBitwiseOp(MacroAssembler* masm) {
   5728   Label slow, result_not_a_smi;
   5729   Label r0_is_smi, r1_is_smi;
   5730   Label done_checking_r0, done_checking_r1;
   5731 
   5732   __ tst(r1, Operand(kSmiTagMask));
   5733   __ b(eq, &r1_is_smi);  // It's a Smi so don't check it's a heap number.
   5734   __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
   5735   __ b(ne, &slow);
   5736   GetInt32(masm, r1, r3, r5, r4, &slow);
   5737   __ jmp(&done_checking_r1);
   5738   __ bind(&r1_is_smi);
   5739   __ mov(r3, Operand(r1, ASR, 1));
   5740   __ bind(&done_checking_r1);
   5741 
   5742   __ tst(r0, Operand(kSmiTagMask));
   5743   __ b(eq, &r0_is_smi);  // It's a Smi so don't check it's a heap number.
   5744   __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
   5745   __ b(ne, &slow);
   5746   GetInt32(masm, r0, r2, r5, r4, &slow);
   5747   __ jmp(&done_checking_r0);
   5748   __ bind(&r0_is_smi);
   5749   __ mov(r2, Operand(r0, ASR, 1));
   5750   __ bind(&done_checking_r0);
   5751 
   5752   // r0 and r1: Original operands (Smi or heap numbers).
   5753   // r2 and r3: Signed int32 operands.
   5754   switch (op_) {
   5755     case Token::BIT_OR:  __ orr(r2, r2, Operand(r3)); break;
   5756     case Token::BIT_XOR: __ eor(r2, r2, Operand(r3)); break;
   5757     case Token::BIT_AND: __ and_(r2, r2, Operand(r3)); break;
   5758     case Token::SAR:
   5759       // Use only the 5 least significant bits of the shift count.
   5760       __ and_(r2, r2, Operand(0x1f));
   5761       __ mov(r2, Operand(r3, ASR, r2));
   5762       break;
   5763     case Token::SHR:
   5764       // Use only the 5 least significant bits of the shift count.
   5765       __ and_(r2, r2, Operand(0x1f));
   5766       __ mov(r2, Operand(r3, LSR, r2), SetCC);
   5767       // SHR is special because it is required to produce a positive answer.
   5768       // The code below for writing into heap numbers isn't capable of writing
   5769       // the register as an unsigned int so we go to slow case if we hit this
   5770       // case.
   5771       __ b(mi, &slow);
   5772       break;
   5773     case Token::SHL:
   5774       // Use only the 5 least significant bits of the shift count.
   5775       __ and_(r2, r2, Operand(0x1f));
   5776       __ mov(r2, Operand(r3, LSL, r2));
   5777       break;
   5778     default: UNREACHABLE();
   5779   }
   5780   // check that the *signed* result fits in a smi
   5781   __ add(r3, r2, Operand(0x40000000), SetCC);
   5782   __ b(mi, &result_not_a_smi);
   5783   __ mov(r0, Operand(r2, LSL, kSmiTagSize));
   5784   __ Ret();
   5785 
   5786   Label have_to_allocate, got_a_heap_number;
   5787   __ bind(&result_not_a_smi);
   5788   switch (mode_) {
   5789     case OVERWRITE_RIGHT: {
   5790       __ tst(r0, Operand(kSmiTagMask));
   5791       __ b(eq, &have_to_allocate);
   5792       __ mov(r5, Operand(r0));
   5793       break;
   5794     }
   5795     case OVERWRITE_LEFT: {
   5796       __ tst(r1, Operand(kSmiTagMask));
   5797       __ b(eq, &have_to_allocate);
   5798       __ mov(r5, Operand(r1));
   5799       break;
   5800     }
   5801     case NO_OVERWRITE: {
   5802       // Get a new heap number in r5.  r6 and r7 are scratch.
   5803       AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5804     }
   5805     default: break;
   5806   }
   5807   __ bind(&got_a_heap_number);
   5808   // r2: Answer as signed int32.
   5809   // r5: Heap number to write answer into.
   5810 
   5811   // Nothing can go wrong now, so move the heap number to r0, which is the
   5812   // result.
   5813   __ mov(r0, Operand(r5));
   5814 
   5815   // Tail call that writes the int32 in r2 to the heap number in r0, using
   5816   // r3 as scratch.  r0 is preserved and returned.
   5817   WriteInt32ToHeapNumberStub stub(r2, r0, r3);
   5818   __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
   5819 
   5820   if (mode_ != NO_OVERWRITE) {
   5821     __ bind(&have_to_allocate);
   5822     // Get a new heap number in r5.  r6 and r7 are scratch.
   5823     AllocateHeapNumber(masm, &slow, r5, r6, r7);
   5824     __ jmp(&got_a_heap_number);
   5825   }
   5826 
   5827   // If all else failed then we go to the runtime system.
   5828   __ bind(&slow);
   5829   __ push(r1);  // restore stack
   5830   __ push(r0);
   5831   switch (op_) {
   5832     case Token::BIT_OR:
   5833       __ InvokeBuiltin(Builtins::BIT_OR, JUMP_JS);
   5834       break;
   5835     case Token::BIT_AND:
   5836       __ InvokeBuiltin(Builtins::BIT_AND, JUMP_JS);
   5837       break;
   5838     case Token::BIT_XOR:
   5839       __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_JS);
   5840       break;
   5841     case Token::SAR:
   5842       __ InvokeBuiltin(Builtins::SAR, JUMP_JS);
   5843       break;
   5844     case Token::SHR:
   5845       __ InvokeBuiltin(Builtins::SHR, JUMP_JS);
   5846       break;
   5847     case Token::SHL:
   5848       __ InvokeBuiltin(Builtins::SHL, JUMP_JS);
   5849       break;
   5850     default:
   5851       UNREACHABLE();
   5852   }
   5853 }
   5854 
   5855 
   5856 // Can we multiply by x with max two shifts and an add.
   5857 // This answers yes to all integers from 2 to 10.
   5858 static bool IsEasyToMultiplyBy(int x) {
   5859   if (x < 2) return false;                          // Avoid special cases.
   5860   if (x > (Smi::kMaxValue + 1) >> 2) return false;  // Almost always overflows.
   5861   if (IsPowerOf2(x)) return true;                   // Simple shift.
   5862   if (PopCountLessThanEqual2(x)) return true;       // Shift and add and shift.
   5863   if (IsPowerOf2(x + 1)) return true;               // Patterns like 11111.
   5864   return false;
   5865 }
   5866 
   5867 
   5868 // Can multiply by anything that IsEasyToMultiplyBy returns true for.
   5869 // Source and destination may be the same register.  This routine does
   5870 // not set carry and overflow the way a mul instruction would.
   5871 static void MultiplyByKnownInt(MacroAssembler* masm,
   5872                                Register source,
   5873                                Register destination,
   5874                                int known_int) {
   5875   if (IsPowerOf2(known_int)) {
   5876     __ mov(destination, Operand(source, LSL, BitPosition(known_int)));
   5877   } else if (PopCountLessThanEqual2(known_int)) {
   5878     int first_bit = BitPosition(known_int);
   5879     int second_bit = BitPosition(known_int ^ (1 << first_bit));
   5880     __ add(destination, source, Operand(source, LSL, second_bit - first_bit));
   5881     if (first_bit != 0) {
   5882       __ mov(destination, Operand(destination, LSL, first_bit));
   5883     }
   5884   } else {
   5885     ASSERT(IsPowerOf2(known_int + 1));  // Patterns like 1111.
   5886     int the_bit = BitPosition(known_int + 1);
   5887     __ rsb(destination, source, Operand(source, LSL, the_bit));
   5888   }
   5889 }
   5890 
   5891 
   5892 // This function (as opposed to MultiplyByKnownInt) takes the known int in a
   5893 // a register for the cases where it doesn't know a good trick, and may deliver
   5894 // a result that needs shifting.
   5895 static void MultiplyByKnownInt2(
   5896     MacroAssembler* masm,
   5897     Register result,
   5898     Register source,
   5899     Register known_int_register,   // Smi tagged.
   5900     int known_int,
   5901     int* required_shift) {  // Including Smi tag shift
   5902   switch (known_int) {
   5903     case 3:
   5904       __ add(result, source, Operand(source, LSL, 1));
   5905       *required_shift = 1;
   5906       break;
   5907     case 5:
   5908       __ add(result, source, Operand(source, LSL, 2));
   5909       *required_shift = 1;
   5910       break;
   5911     case 6:
   5912       __ add(result, source, Operand(source, LSL, 1));
   5913       *required_shift = 2;
   5914       break;
   5915     case 7:
   5916       __ rsb(result, source, Operand(source, LSL, 3));
   5917       *required_shift = 1;
   5918       break;
   5919     case 9:
   5920       __ add(result, source, Operand(source, LSL, 3));
   5921       *required_shift = 1;
   5922       break;
   5923     case 10:
   5924       __ add(result, source, Operand(source, LSL, 2));
   5925       *required_shift = 2;
   5926       break;
   5927     default:
   5928       ASSERT(!IsPowerOf2(known_int));  // That would be very inefficient.
   5929       __ mul(result, source, known_int_register);
   5930       *required_shift = 0;
   5931   }
   5932 }
   5933 
   5934 
   5935 const char* GenericBinaryOpStub::GetName() {
   5936   if (name_ != NULL) return name_;
   5937   const int len = 100;
   5938   name_ = Bootstrapper::AllocateAutoDeletedArray(len);
   5939   if (name_ == NULL) return "OOM";
   5940   const char* op_name = Token::Name(op_);
   5941   const char* overwrite_name;
   5942   switch (mode_) {
   5943     case NO_OVERWRITE: overwrite_name = "Alloc"; break;
   5944     case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
   5945     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
   5946     default: overwrite_name = "UnknownOverwrite"; break;
   5947   }
   5948 
   5949   OS::SNPrintF(Vector<char>(name_, len),
   5950                "GenericBinaryOpStub_%s_%s%s",
   5951                op_name,
   5952                overwrite_name,
   5953                specialized_on_rhs_ ? "_ConstantRhs" : 0);
   5954   return name_;
   5955 }
   5956 
   5957 
   5958 
   5959 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
   5960   // r1 : x
   5961   // r0 : y
   5962   // result : r0
   5963 
   5964   // All ops need to know whether we are dealing with two Smis.  Set up r2 to
   5965   // tell us that.
   5966   __ orr(r2, r1, Operand(r0));  // r2 = x | y;
   5967 
   5968   switch (op_) {
   5969     case Token::ADD: {
   5970       Label not_smi;
   5971       // Fast path.
   5972       ASSERT(kSmiTag == 0);  // Adjust code below.
   5973       __ tst(r2, Operand(kSmiTagMask));
   5974       __ b(ne, &not_smi);
   5975       __ add(r0, r1, Operand(r0), SetCC);  // Add y optimistically.
   5976       // Return if no overflow.
   5977       __ Ret(vc);
   5978       __ sub(r0, r0, Operand(r1));  // Revert optimistic add.
   5979 
   5980       HandleBinaryOpSlowCases(masm,
   5981                               &not_smi,
   5982                               Builtins::ADD,
   5983                               Token::ADD,
   5984                               mode_);
   5985       break;
   5986     }
   5987 
   5988     case Token::SUB: {
   5989       Label not_smi;
   5990       // Fast path.
   5991       ASSERT(kSmiTag == 0);  // Adjust code below.
   5992       __ tst(r2, Operand(kSmiTagMask));
   5993       __ b(ne, &not_smi);
   5994       __ sub(r0, r1, Operand(r0), SetCC);  // Subtract y optimistically.
   5995       // Return if no overflow.
   5996       __ Ret(vc);
   5997       __ sub(r0, r1, Operand(r0));  // Revert optimistic subtract.
   5998 
   5999       HandleBinaryOpSlowCases(masm,
   6000                               &not_smi,
   6001                               Builtins::SUB,
   6002                               Token::SUB,
   6003                               mode_);
   6004       break;
   6005     }
   6006 
   6007     case Token::MUL: {
   6008       Label not_smi, slow;
   6009       ASSERT(kSmiTag == 0);  // adjust code below
   6010       __ tst(r2, Operand(kSmiTagMask));
   6011       __ b(ne, &not_smi);
   6012       // Remove tag from one operand (but keep sign), so that result is Smi.
   6013       __ mov(ip, Operand(r0, ASR, kSmiTagSize));
   6014       // Do multiplication
   6015       __ smull(r3, r2, r1, ip);  // r3 = lower 32 bits of ip*r1.
   6016       // Go slow on overflows (overflow bit is not set).
   6017       __ mov(ip, Operand(r3, ASR, 31));
   6018       __ cmp(ip, Operand(r2));  // no overflow if higher 33 bits are identical
   6019       __ b(ne, &slow);
   6020       // Go slow on zero result to handle -0.
   6021       __ tst(r3, Operand(r3));
   6022       __ mov(r0, Operand(r3), LeaveCC, ne);
   6023       __ Ret(ne);
   6024       // We need -0 if we were multiplying a negative number with 0 to get 0.
   6025       // We know one of them was zero.
   6026       __ add(r2, r0, Operand(r1), SetCC);
   6027       __ mov(r0, Operand(Smi::FromInt(0)), LeaveCC, pl);
   6028       __ Ret(pl);  // Return Smi 0 if the non-zero one was positive.
   6029       // Slow case.  We fall through here if we multiplied a negative number
   6030       // with 0, because that would mean we should produce -0.
   6031       __ bind(&slow);
   6032 
   6033       HandleBinaryOpSlowCases(masm,
   6034                               &not_smi,
   6035                               Builtins::MUL,
   6036                               Token::MUL,
   6037                               mode_);
   6038       break;
   6039     }
   6040 
   6041     case Token::DIV:
   6042     case Token::MOD: {
   6043       Label not_smi;
   6044       if (specialized_on_rhs_) {
   6045         Label smi_is_unsuitable;
   6046         __ BranchOnNotSmi(r1, &not_smi);
   6047         if (IsPowerOf2(constant_rhs_)) {
   6048           if (op_ == Token::MOD) {
   6049             __ and_(r0,
   6050                     r1,
   6051                     Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1)),
   6052                     SetCC);
   6053             // We now have the answer, but if the input was negative we also
   6054             // have the sign bit.  Our work is done if the result is
   6055             // positive or zero:
   6056             __ Ret(pl);
   6057             // A mod of a negative left hand side must return a negative number.
   6058             // Unfortunately if the answer is 0 then we must return -0.  And we
   6059             // already optimistically trashed r0 so we may need to restore it.
   6060             __ eor(r0, r0, Operand(0x80000000u), SetCC);
   6061             // Next two instructions are conditional on the answer being -0.
   6062             __ mov(r0, Operand(Smi::FromInt(constant_rhs_)), LeaveCC, eq);
   6063             __ b(eq, &smi_is_unsuitable);
   6064             // We need to subtract the dividend.  Eg. -3 % 4 == -3.
   6065             __ sub(r0, r0, Operand(Smi::FromInt(constant_rhs_)));
   6066           } else {
   6067             ASSERT(op_ == Token::DIV);
   6068             __ tst(r1,
   6069                    Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1)));
   6070             __ b(ne, &smi_is_unsuitable);  // Go slow on negative or remainder.
   6071             int shift = 0;
   6072             int d = constant_rhs_;
   6073             while ((d & 1) == 0) {
   6074               d >>= 1;
   6075               shift++;
   6076             }
   6077             __ mov(r0, Operand(r1, LSR, shift));
   6078             __ bic(r0, r0, Operand(kSmiTagMask));
   6079           }
   6080         } else {
   6081           // Not a power of 2.
   6082           __ tst(r1, Operand(0x80000000u));
   6083           __ b(ne, &smi_is_unsuitable);
   6084           // Find a fixed point reciprocal of the divisor so we can divide by
   6085           // multiplying.
   6086           double divisor = 1.0 / constant_rhs_;
   6087           int shift = 32;
   6088           double scale = 4294967296.0;  // 1 << 32.
   6089           uint32_t mul;
   6090           // Maximise the precision of the fixed point reciprocal.
   6091           while (true) {
   6092             mul = static_cast<uint32_t>(scale * divisor);
   6093             if (mul >= 0x7fffffff) break;
   6094             scale *= 2.0;
   6095             shift++;
   6096           }
   6097           mul++;
   6098           __ mov(r2, Operand(mul));
   6099           __ umull(r3, r2, r2, r1);
   6100           __ mov(r2, Operand(r2, LSR, shift - 31));
   6101           // r2 is r1 / rhs.  r2 is not Smi tagged.
   6102           // r0 is still the known rhs.  r0 is Smi tagged.
   6103           // r1 is still the unkown lhs.  r1 is Smi tagged.
   6104           int required_r4_shift = 0;  // Including the Smi tag shift of 1.
   6105           // r4 = r2 * r0.
   6106           MultiplyByKnownInt2(masm,
   6107                               r4,
   6108                               r2,
   6109                               r0,
   6110                               constant_rhs_,
   6111                               &required_r4_shift);
   6112           // r4 << required_r4_shift is now the Smi tagged rhs * (r1 / rhs).
   6113           if (op_ == Token::DIV) {
   6114             __ sub(r3, r1, Operand(r4, LSL, required_r4_shift), SetCC);
   6115             __ b(ne, &smi_is_unsuitable);  // There was a remainder.
   6116             __ mov(r0, Operand(r2, LSL, kSmiTagSize));
   6117           } else {
   6118             ASSERT(op_ == Token::MOD);
   6119             __ sub(r0, r1, Operand(r4, LSL, required_r4_shift));
   6120           }
   6121         }
   6122         __ Ret();
   6123         __ bind(&smi_is_unsuitable);
   6124       } else {
   6125         __ jmp(&not_smi);
   6126       }
   6127       HandleBinaryOpSlowCases(masm,
   6128                               &not_smi,
   6129                               op_ == Token::MOD ? Builtins::MOD : Builtins::DIV,
   6130                               op_,
   6131                               mode_);
   6132       break;
   6133     }
   6134 
   6135     case Token::BIT_OR:
   6136     case Token::BIT_AND:
   6137     case Token::BIT_XOR:
   6138     case Token::SAR:
   6139     case Token::SHR:
   6140     case Token::SHL: {
   6141       Label slow;
   6142       ASSERT(kSmiTag == 0);  // adjust code below
   6143       __ tst(r2, Operand(kSmiTagMask));
   6144       __ b(ne, &slow);
   6145       switch (op_) {
   6146         case Token::BIT_OR:  __ orr(r0, r0, Operand(r1)); break;
   6147         case Token::BIT_AND: __ and_(r0, r0, Operand(r1)); break;
   6148         case Token::BIT_XOR: __ eor(r0, r0, Operand(r1)); break;
   6149         case Token::SAR:
   6150           // Remove tags from right operand.
   6151           __ GetLeastBitsFromSmi(r2, r0, 5);
   6152           __ mov(r0, Operand(r1, ASR, r2));
   6153           // Smi tag result.
   6154           __ bic(r0, r0, Operand(kSmiTagMask));
   6155           break;
   6156         case Token::SHR:
   6157           // Remove tags from operands.  We can't do this on a 31 bit number
   6158           // because then the 0s get shifted into bit 30 instead of bit 31.
   6159           __ mov(r3, Operand(r1, ASR, kSmiTagSize));  // x
   6160           __ GetLeastBitsFromSmi(r2, r0, 5);
   6161           __ mov(r3, Operand(r3, LSR, r2));
   6162           // Unsigned shift is not allowed to produce a negative number, so
   6163           // check the sign bit and the sign bit after Smi tagging.
   6164           __ tst(r3, Operand(0xc0000000));
   6165           __ b(ne, &slow);
   6166           // Smi tag result.
   6167           __ mov(r0, Operand(r3, LSL, kSmiTagSize));
   6168           break;
   6169         case Token::SHL:
   6170           // Remove tags from operands.
   6171           __ mov(r3, Operand(r1, ASR, kSmiTagSize));  // x
   6172           __ GetLeastBitsFromSmi(r2, r0, 5);
   6173           __ mov(r3, Operand(r3, LSL, r2));
   6174           // Check that the signed result fits in a Smi.
   6175           __ add(r2, r3, Operand(0x40000000), SetCC);
   6176           __ b(mi, &slow);
   6177           __ mov(r0, Operand(r3, LSL, kSmiTagSize));
   6178           break;
   6179         default: UNREACHABLE();
   6180       }
   6181       __ Ret();
   6182       __ bind(&slow);
   6183       HandleNonSmiBitwiseOp(masm);
   6184       break;
   6185     }
   6186 
   6187     default: UNREACHABLE();
   6188   }
   6189   // This code should be unreachable.
   6190   __ stop("Unreachable");
   6191 }
   6192 
   6193 
   6194 void StackCheckStub::Generate(MacroAssembler* masm) {
   6195   // Do tail-call to runtime routine.  Runtime routines expect at least one
   6196   // argument, so give it a Smi.
   6197   __ mov(r0, Operand(Smi::FromInt(0)));
   6198   __ push(r0);
   6199   __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
   6200 
   6201   __ StubReturn(1);
   6202 }
   6203 
   6204 
   6205 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
   6206   Label slow, done;
   6207 
   6208   if (op_ == Token::SUB) {
   6209     // Check whether the value is a smi.
   6210     Label try_float;
   6211     __ tst(r0, Operand(kSmiTagMask));
   6212     __ b(ne, &try_float);
   6213 
   6214     // Go slow case if the value of the expression is zero
   6215     // to make sure that we switch between 0 and -0.
   6216     __ cmp(r0, Operand(0));
   6217     __ b(eq, &slow);
   6218 
   6219     // The value of the expression is a smi that is not zero.  Try
   6220     // optimistic subtraction '0 - value'.
   6221     __ rsb(r1, r0, Operand(0), SetCC);
   6222     __ b(vs, &slow);
   6223 
   6224     __ mov(r0, Operand(r1));  // Set r0 to result.
   6225     __ b(&done);
   6226 
   6227     __ bind(&try_float);
   6228     __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE);
   6229     __ b(ne, &slow);
   6230     // r0 is a heap number.  Get a new heap number in r1.
   6231     if (overwrite_) {
   6232       __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
   6233       __ eor(r2, r2, Operand(HeapNumber::kSignMask));  // Flip sign.
   6234       __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
   6235     } else {
   6236       AllocateHeapNumber(masm, &slow, r1, r2, r3);
   6237       __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
   6238       __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
   6239       __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset));
   6240       __ eor(r2, r2, Operand(HeapNumber::kSignMask));  // Flip sign.
   6241       __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset));
   6242       __ mov(r0, Operand(r1));
   6243     }
   6244   } else if (op_ == Token::BIT_NOT) {
   6245     // Check if the operand is a heap number.
   6246     __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE);
   6247     __ b(ne, &slow);
   6248 
   6249     // Convert the heap number is r0 to an untagged integer in r1.
   6250     GetInt32(masm, r0, r1, r2, r3, &slow);
   6251 
   6252     // Do the bitwise operation (move negated) and check if the result
   6253     // fits in a smi.
   6254     Label try_float;
   6255     __ mvn(r1, Operand(r1));
   6256     __ add(r2, r1, Operand(0x40000000), SetCC);
   6257     __ b(mi, &try_float);
   6258     __ mov(r0, Operand(r1, LSL, kSmiTagSize));
   6259     __ b(&done);
   6260 
   6261     __ bind(&try_float);
   6262     if (!overwrite_) {
   6263       // Allocate a fresh heap number, but don't overwrite r0 until
   6264       // we're sure we can do it without going through the slow case
   6265       // that needs the value in r0.
   6266       AllocateHeapNumber(masm, &slow, r2, r3, r4);
   6267       __ mov(r0, Operand(r2));
   6268     }
   6269 
   6270     // WriteInt32ToHeapNumberStub does not trigger GC, so we do not
   6271     // have to set up a frame.
   6272     WriteInt32ToHeapNumberStub stub(r1, r0, r2);
   6273     __ push(lr);
   6274     __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
   6275     __ pop(lr);
   6276   } else {
   6277     UNIMPLEMENTED();
   6278   }
   6279 
   6280   __ bind(&done);
   6281   __ StubReturn(1);
   6282 
   6283   // Handle the slow case by jumping to the JavaScript builtin.
   6284   __ bind(&slow);
   6285   __ push(r0);
   6286   switch (op_) {
   6287     case Token::SUB:
   6288       __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS);
   6289       break;
   6290     case Token::BIT_NOT:
   6291       __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_JS);
   6292       break;
   6293     default:
   6294       UNREACHABLE();
   6295   }
   6296 }
   6297 
   6298 
   6299 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   6300   // r0 holds the exception.
   6301 
   6302   // Adjust this code if not the case.
   6303   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
   6304 
   6305   // Drop the sp to the top of the handler.
   6306   __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
   6307   __ ldr(sp, MemOperand(r3));
   6308 
   6309   // Restore the next handler and frame pointer, discard handler state.
   6310   ASSERT(StackHandlerConstants::kNextOffset == 0);
   6311   __ pop(r2);
   6312   __ str(r2, MemOperand(r3));
   6313   ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
   6314   __ ldm(ia_w, sp, r3.bit() | fp.bit());  // r3: discarded state.
   6315 
   6316   // Before returning we restore the context from the frame pointer if
   6317   // not NULL.  The frame pointer is NULL in the exception handler of a
   6318   // JS entry frame.
   6319   __ cmp(fp, Operand(0));
   6320   // Set cp to NULL if fp is NULL.
   6321   __ mov(cp, Operand(0), LeaveCC, eq);
   6322   // Restore cp otherwise.
   6323   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
   6324 #ifdef DEBUG
   6325   if (FLAG_debug_code) {
   6326     __ mov(lr, Operand(pc));
   6327   }
   6328 #endif
   6329   ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
   6330   __ pop(pc);
   6331 }
   6332 
   6333 
   6334 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
   6335                                           UncatchableExceptionType type) {
   6336   // Adjust this code if not the case.
   6337   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
   6338 
   6339   // Drop sp to the top stack handler.
   6340   __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
   6341   __ ldr(sp, MemOperand(r3));
   6342 
   6343   // Unwind the handlers until the ENTRY handler is found.
   6344   Label loop, done;
   6345   __ bind(&loop);
   6346   // Load the type of the current stack handler.
   6347   const int kStateOffset = StackHandlerConstants::kStateOffset;
   6348   __ ldr(r2, MemOperand(sp, kStateOffset));
   6349   __ cmp(r2, Operand(StackHandler::ENTRY));
   6350   __ b(eq, &done);
   6351   // Fetch the next handler in the list.
   6352   const int kNextOffset = StackHandlerConstants::kNextOffset;
   6353   __ ldr(sp, MemOperand(sp, kNextOffset));
   6354   __ jmp(&loop);
   6355   __ bind(&done);
   6356 
   6357   // Set the top handler address to next handler past the current ENTRY handler.
   6358   ASSERT(StackHandlerConstants::kNextOffset == 0);
   6359   __ pop(r2);
   6360   __ str(r2, MemOperand(r3));
   6361 
   6362   if (type == OUT_OF_MEMORY) {
   6363     // Set external caught exception to false.
   6364     ExternalReference external_caught(Top::k_external_caught_exception_address);
   6365     __ mov(r0, Operand(false));
   6366     __ mov(r2, Operand(external_caught));
   6367     __ str(r0, MemOperand(r2));
   6368 
   6369     // Set pending exception and r0 to out of memory exception.
   6370     Failure* out_of_memory = Failure::OutOfMemoryException();
   6371     __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
   6372     __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
   6373     __ str(r0, MemOperand(r2));
   6374   }
   6375 
   6376   // Stack layout at this point. See also StackHandlerConstants.
   6377   // sp ->   state (ENTRY)
   6378   //         fp
   6379   //         lr
   6380 
   6381   // Discard handler state (r2 is not used) and restore frame pointer.
   6382   ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
   6383   __ ldm(ia_w, sp, r2.bit() | fp.bit());  // r2: discarded state.
   6384   // Before returning we restore the context from the frame pointer if
   6385   // not NULL.  The frame pointer is NULL in the exception handler of a
   6386   // JS entry frame.
   6387   __ cmp(fp, Operand(0));
   6388   // Set cp to NULL if fp is NULL.
   6389   __ mov(cp, Operand(0), LeaveCC, eq);
   6390   // Restore cp otherwise.
   6391   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
   6392 #ifdef DEBUG
   6393   if (FLAG_debug_code) {
   6394     __ mov(lr, Operand(pc));
   6395   }
   6396 #endif
   6397   ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
   6398   __ pop(pc);
   6399 }
   6400 
   6401 
   6402 void CEntryStub::GenerateCore(MacroAssembler* masm,
   6403                               Label* throw_normal_exception,
   6404                               Label* throw_termination_exception,
   6405                               Label* throw_out_of_memory_exception,
   6406                               bool do_gc,
   6407                               bool always_allocate) {
   6408   // r0: result parameter for PerformGC, if any
   6409   // r4: number of arguments including receiver  (C callee-saved)
   6410   // r5: pointer to builtin function  (C callee-saved)
   6411   // r6: pointer to the first argument (C callee-saved)
   6412 
   6413   if (do_gc) {
   6414     // Passing r0.
   6415     ExternalReference gc_reference = ExternalReference::perform_gc_function();
   6416     __ Call(gc_reference.address(), RelocInfo::RUNTIME_ENTRY);
   6417   }
   6418 
   6419   ExternalReference scope_depth =
   6420       ExternalReference::heap_always_allocate_scope_depth();
   6421   if (always_allocate) {
   6422     __ mov(r0, Operand(scope_depth));
   6423     __ ldr(r1, MemOperand(r0));
   6424     __ add(r1, r1, Operand(1));
   6425     __ str(r1, MemOperand(r0));
   6426   }
   6427 
   6428   // Call C built-in.
   6429   // r0 = argc, r1 = argv
   6430   __ mov(r0, Operand(r4));
   6431   __ mov(r1, Operand(r6));
   6432 
   6433   // TODO(1242173): To let the GC traverse the return address of the exit
   6434   // frames, we need to know where the return address is. Right now,
   6435   // we push it on the stack to be able to find it again, but we never
   6436   // restore from it in case of changes, which makes it impossible to
   6437   // support moving the C entry code stub. This should be fixed, but currently
   6438   // this is OK because the CEntryStub gets generated so early in the V8 boot
   6439   // sequence that it is not moving ever.
   6440   masm->add(lr, pc, Operand(4));  // compute return address: (pc + 8) + 4
   6441   masm->push(lr);
   6442   masm->Jump(r5);
   6443 
   6444   if (always_allocate) {
   6445     // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1
   6446     // though (contain the result).
   6447     __ mov(r2, Operand(scope_depth));
   6448     __ ldr(r3, MemOperand(r2));
   6449     __ sub(r3, r3, Operand(1));
   6450     __ str(r3, MemOperand(r2));
   6451   }
   6452 
   6453   // check for failure result
   6454   Label failure_returned;
   6455   ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
   6456   // Lower 2 bits of r2 are 0 iff r0 has failure tag.
   6457   __ add(r2, r0, Operand(1));
   6458   __ tst(r2, Operand(kFailureTagMask));
   6459   __ b(eq, &failure_returned);
   6460 
   6461   // Exit C frame and return.
   6462   // r0:r1: result
   6463   // sp: stack pointer
   6464   // fp: frame pointer
   6465   __ LeaveExitFrame(mode_);
   6466 
   6467   // check if we should retry or throw exception
   6468   Label retry;
   6469   __ bind(&failure_returned);
   6470   ASSERT(Failure::RETRY_AFTER_GC == 0);
   6471   __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
   6472   __ b(eq, &retry);
   6473 
   6474   // Special handling of out of memory exceptions.
   6475   Failure* out_of_memory = Failure::OutOfMemoryException();
   6476   __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
   6477   __ b(eq, throw_out_of_memory_exception);
   6478 
   6479   // Retrieve the pending exception and clear the variable.
   6480   __ mov(ip, Operand(ExternalReference::the_hole_value_location()));
   6481   __ ldr(r3, MemOperand(ip));
   6482   __ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
   6483   __ ldr(r0, MemOperand(ip));
   6484   __ str(r3, MemOperand(ip));
   6485 
   6486   // Special handling of termination exceptions which are uncatchable
   6487   // by javascript code.
   6488   __ cmp(r0, Operand(Factory::termination_exception()));
   6489   __ b(eq, throw_termination_exception);
   6490 
   6491   // Handle normal exception.
   6492   __ jmp(throw_normal_exception);
   6493 
   6494   __ bind(&retry);  // pass last failure (r0) as parameter (r0) when retrying
   6495 }
   6496 
   6497 
   6498 void CEntryStub::Generate(MacroAssembler* masm) {
   6499   // Called from JavaScript; parameters are on stack as if calling JS function
   6500   // r0: number of arguments including receiver
   6501   // r1: pointer to builtin function
   6502   // fp: frame pointer  (restored after C call)
   6503   // sp: stack pointer  (restored as callee's sp after C call)
   6504   // cp: current context  (C callee-saved)
   6505 
   6506   // Result returned in r0 or r0+r1 by default.
   6507 
   6508   // NOTE: Invocations of builtins may return failure objects
   6509   // instead of a proper result. The builtin entry handles
   6510   // this by performing a garbage collection and retrying the
   6511   // builtin once.
   6512 
   6513   // Enter the exit frame that transitions from JavaScript to C++.
   6514   __ EnterExitFrame(mode_);
   6515 
   6516   // r4: number of arguments (C callee-saved)
   6517   // r5: pointer to builtin function (C callee-saved)
   6518   // r6: pointer to first argument (C callee-saved)
   6519 
   6520   Label throw_normal_exception;
   6521   Label throw_termination_exception;
   6522   Label throw_out_of_memory_exception;
   6523 
   6524   // Call into the runtime system.
   6525   GenerateCore(masm,
   6526                &throw_normal_exception,
   6527                &throw_termination_exception,
   6528                &throw_out_of_memory_exception,
   6529                false,
   6530                false);
   6531 
   6532   // Do space-specific GC and retry runtime call.
   6533   GenerateCore(masm,
   6534                &throw_normal_exception,
   6535                &throw_termination_exception,
   6536                &throw_out_of_memory_exception,
   6537                true,
   6538                false);
   6539 
   6540   // Do full GC and retry runtime call one final time.
   6541   Failure* failure = Failure::InternalError();
   6542   __ mov(r0, Operand(reinterpret_cast<int32_t>(failure)));
   6543   GenerateCore(masm,
   6544                &throw_normal_exception,
   6545                &throw_termination_exception,
   6546                &throw_out_of_memory_exception,
   6547                true,
   6548                true);
   6549 
   6550   __ bind(&throw_out_of_memory_exception);
   6551   GenerateThrowUncatchable(masm, OUT_OF_MEMORY);
   6552 
   6553   __ bind(&throw_termination_exception);
   6554   GenerateThrowUncatchable(masm, TERMINATION);
   6555 
   6556   __ bind(&throw_normal_exception);
   6557   GenerateThrowTOS(masm);
   6558 }
   6559 
   6560 
   6561 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   6562   // r0: code entry
   6563   // r1: function
   6564   // r2: receiver
   6565   // r3: argc
   6566   // [sp+0]: argv
   6567 
   6568   Label invoke, exit;
   6569 
   6570   // Called from C, so do not pop argc and args on exit (preserve sp)
   6571   // No need to save register-passed args
   6572   // Save callee-saved registers (incl. cp and fp), sp, and lr
   6573   __ stm(db_w, sp, kCalleeSaved | lr.bit());
   6574 
   6575   // Get address of argv, see stm above.
   6576   // r0: code entry
   6577   // r1: function
   6578   // r2: receiver
   6579   // r3: argc
   6580   __ ldr(r4, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize));  // argv
   6581 
   6582   // Push a frame with special values setup to mark it as an entry frame.
   6583   // r0: code entry
   6584   // r1: function
   6585   // r2: receiver
   6586   // r3: argc
   6587   // r4: argv
   6588   __ mov(r8, Operand(-1));  // Push a bad frame pointer to fail if it is used.
   6589   int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
   6590   __ mov(r7, Operand(Smi::FromInt(marker)));
   6591   __ mov(r6, Operand(Smi::FromInt(marker)));
   6592   __ mov(r5, Operand(ExternalReference(Top::k_c_entry_fp_address)));
   6593   __ ldr(r5, MemOperand(r5));
   6594   __ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | r8.bit());
   6595 
   6596   // Setup frame pointer for the frame to be pushed.
   6597   __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
   6598 
   6599   // Call a faked try-block that does the invoke.
   6600   __ bl(&invoke);
   6601 
   6602   // Caught exception: Store result (exception) in the pending
   6603   // exception field in the JSEnv and return a failure sentinel.
   6604   // Coming in here the fp will be invalid because the PushTryHandler below
   6605   // sets it to 0 to signal the existence of the JSEntry frame.
   6606   __ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
   6607   __ str(r0, MemOperand(ip));
   6608   __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception())));
   6609   __ b(&exit);
   6610 
   6611   // Invoke: Link this frame into the handler chain.
   6612   __ bind(&invoke);
   6613   // Must preserve r0-r4, r5-r7 are available.
   6614   __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
   6615   // If an exception not caught by another handler occurs, this handler
   6616   // returns control to the code after the bl(&invoke) above, which
   6617   // restores all kCalleeSaved registers (including cp and fp) to their
   6618   // saved values before returning a failure to C.
   6619 
   6620   // Clear any pending exceptions.
   6621   __ mov(ip, Operand(ExternalReference::the_hole_value_location()));
   6622   __ ldr(r5, MemOperand(ip));
   6623   __ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
   6624   __ str(r5, MemOperand(ip));
   6625 
   6626   // Invoke the function by calling through JS entry trampoline builtin.
   6627   // Notice that we cannot store a reference to the trampoline code directly in
   6628   // this stub, because runtime stubs are not traversed when doing GC.
   6629 
   6630   // Expected registers by Builtins::JSEntryTrampoline
   6631   // r0: code entry
   6632   // r1: function
   6633   // r2: receiver
   6634   // r3: argc
   6635   // r4: argv
   6636   if (is_construct) {
   6637     ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
   6638     __ mov(ip, Operand(construct_entry));
   6639   } else {
   6640     ExternalReference entry(Builtins::JSEntryTrampoline);
   6641     __ mov(ip, Operand(entry));
   6642   }
   6643   __ ldr(ip, MemOperand(ip));  // deref address
   6644 
   6645   // Branch and link to JSEntryTrampoline.  We don't use the double underscore
   6646   // macro for the add instruction because we don't want the coverage tool
   6647   // inserting instructions here after we read the pc.
   6648   __ mov(lr, Operand(pc));
   6649   masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
   6650 
   6651   // Unlink this frame from the handler chain. When reading the
   6652   // address of the next handler, there is no need to use the address
   6653   // displacement since the current stack pointer (sp) points directly
   6654   // to the stack handler.
   6655   __ ldr(r3, MemOperand(sp, StackHandlerConstants::kNextOffset));
   6656   __ mov(ip, Operand(ExternalReference(Top::k_handler_address)));
   6657   __ str(r3, MemOperand(ip));
   6658   // No need to restore registers
   6659   __ add(sp, sp, Operand(StackHandlerConstants::kSize));
   6660 
   6661 
   6662   __ bind(&exit);  // r0 holds result
   6663   // Restore the top frame descriptors from the stack.
   6664   __ pop(r3);
   6665   __ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
   6666   __ str(r3, MemOperand(ip));
   6667 
   6668   // Reset the stack to the callee saved registers.
   6669   __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
   6670 
   6671   // Restore callee-saved registers and return.
   6672 #ifdef DEBUG
   6673   if (FLAG_debug_code) {
   6674     __ mov(lr, Operand(pc));
   6675   }
   6676 #endif
   6677   __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
   6678 }
   6679 
   6680 
   6681 // This stub performs an instanceof, calling the builtin function if
   6682 // necessary.  Uses r1 for the object, r0 for the function that it may
   6683 // be an instance of (these are fetched from the stack).
   6684 void InstanceofStub::Generate(MacroAssembler* masm) {
   6685   // Get the object - slow case for smis (we may need to throw an exception
   6686   // depending on the rhs).
   6687   Label slow, loop, is_instance, is_not_instance;
   6688   __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
   6689   __ BranchOnSmi(r0, &slow);
   6690 
   6691   // Check that the left hand is a JS object and put map in r3.
   6692   __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE);
   6693   __ b(lt, &slow);
   6694   __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE));
   6695   __ b(gt, &slow);
   6696 
   6697   // Get the prototype of the function (r4 is result, r2 is scratch).
   6698   __ ldr(r1, MemOperand(sp, 0));
   6699   __ TryGetFunctionPrototype(r1, r4, r2, &slow);
   6700 
   6701   // Check that the function prototype is a JS object.
   6702   __ BranchOnSmi(r4, &slow);
   6703   __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE);
   6704   __ b(lt, &slow);
   6705   __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE));
   6706   __ b(gt, &slow);
   6707 
   6708   // Register mapping: r3 is object map and r4 is function prototype.
   6709   // Get prototype of object into r2.
   6710   __ ldr(r2, FieldMemOperand(r3, Map::kPrototypeOffset));
   6711 
   6712   // Loop through the prototype chain looking for the function prototype.
   6713   __ bind(&loop);
   6714   __ cmp(r2, Operand(r4));
   6715   __ b(eq, &is_instance);
   6716   __ LoadRoot(ip, Heap::kNullValueRootIndex);
   6717   __ cmp(r2, ip);
   6718   __ b(eq, &is_not_instance);
   6719   __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
   6720   __ ldr(r2, FieldMemOperand(r2, Map::kPrototypeOffset));
   6721   __ jmp(&loop);
   6722 
   6723   __ bind(&is_instance);
   6724   __ mov(r0, Operand(Smi::FromInt(0)));
   6725   __ pop();
   6726   __ pop();
   6727   __ mov(pc, Operand(lr));  // Return.
   6728 
   6729   __ bind(&is_not_instance);
   6730   __ mov(r0, Operand(Smi::FromInt(1)));
   6731   __ pop();
   6732   __ pop();
   6733   __ mov(pc, Operand(lr));  // Return.
   6734 
   6735   // Slow-case.  Tail call builtin.
   6736   __ bind(&slow);
   6737   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_JS);
   6738 }
   6739 
   6740 
   6741 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
   6742   // Check if the calling frame is an arguments adaptor frame.
   6743   Label adaptor;
   6744   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   6745   __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
   6746   __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   6747   __ b(eq, &adaptor);
   6748 
   6749   // Nothing to do: The formal number of parameters has already been
   6750   // passed in register r0 by calling function. Just return it.
   6751   __ Jump(lr);
   6752 
   6753   // Arguments adaptor case: Read the arguments length from the
   6754   // adaptor frame and return it.
   6755   __ bind(&adaptor);
   6756   __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
   6757   __ Jump(lr);
   6758 }
   6759 
   6760 
   6761 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   6762   // The displacement is the offset of the last parameter (if any)
   6763   // relative to the frame pointer.
   6764   static const int kDisplacement =
   6765       StandardFrameConstants::kCallerSPOffset - kPointerSize;
   6766 
   6767   // Check that the key is a smi.
   6768   Label slow;
   6769   __ BranchOnNotSmi(r1, &slow);
   6770 
   6771   // Check if the calling frame is an arguments adaptor frame.
   6772   Label adaptor;
   6773   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   6774   __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
   6775   __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   6776   __ b(eq, &adaptor);
   6777 
   6778   // Check index against formal parameters count limit passed in
   6779   // through register r0. Use unsigned comparison to get negative
   6780   // check for free.
   6781   __ cmp(r1, r0);
   6782   __ b(cs, &slow);
   6783 
   6784   // Read the argument from the stack and return it.
   6785   __ sub(r3, r0, r1);
   6786   __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
   6787   __ ldr(r0, MemOperand(r3, kDisplacement));
   6788   __ Jump(lr);
   6789 
   6790   // Arguments adaptor case: Check index against actual arguments
   6791   // limit found in the arguments adaptor frame. Use unsigned
   6792   // comparison to get negative check for free.
   6793   __ bind(&adaptor);
   6794   __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
   6795   __ cmp(r1, r0);
   6796   __ b(cs, &slow);
   6797 
   6798   // Read the argument from the adaptor frame and return it.
   6799   __ sub(r3, r0, r1);
   6800   __ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
   6801   __ ldr(r0, MemOperand(r3, kDisplacement));
   6802   __ Jump(lr);
   6803 
   6804   // Slow-case: Handle non-smi or out-of-bounds access to arguments
   6805   // by calling the runtime system.
   6806   __ bind(&slow);
   6807   __ push(r1);
   6808   __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
   6809 }
   6810 
   6811 
   6812 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
   6813   // sp[0] : number of parameters
   6814   // sp[4] : receiver displacement
   6815   // sp[8] : function
   6816 
   6817   // Check if the calling frame is an arguments adaptor frame.
   6818   Label adaptor_frame, try_allocate, runtime;
   6819   __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
   6820   __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
   6821   __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   6822   __ b(eq, &adaptor_frame);
   6823 
   6824   // Get the length from the frame.
   6825   __ ldr(r1, MemOperand(sp, 0));
   6826   __ b(&try_allocate);
   6827 
   6828   // Patch the arguments.length and the parameters pointer.
   6829   __ bind(&adaptor_frame);
   6830   __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
   6831   __ str(r1, MemOperand(sp, 0));
   6832   __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
   6833   __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
   6834   __ str(r3, MemOperand(sp, 1 * kPointerSize));
   6835 
   6836   // Try the new space allocation. Start out with computing the size
   6837   // of the arguments object and the elements array (in words, not
   6838   // bytes because AllocateInNewSpace expects words).
   6839   Label add_arguments_object;
   6840   __ bind(&try_allocate);
   6841   __ cmp(r1, Operand(0));
   6842   __ b(eq, &add_arguments_object);
   6843   __ mov(r1, Operand(r1, LSR, kSmiTagSize));
   6844   __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
   6845   __ bind(&add_arguments_object);
   6846   __ add(r1, r1, Operand(Heap::kArgumentsObjectSize / kPointerSize));
   6847 
   6848   // Do the allocation of both objects in one go.
   6849   __ AllocateInNewSpace(r1, r0, r2, r3, &runtime, TAG_OBJECT);
   6850 
   6851   // Get the arguments boilerplate from the current (global) context.
   6852   int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
   6853   __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
   6854   __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
   6855   __ ldr(r4, MemOperand(r4, offset));
   6856 
   6857   // Copy the JS object part.
   6858   for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
   6859     __ ldr(r3, FieldMemOperand(r4, i));
   6860     __ str(r3, FieldMemOperand(r0, i));
   6861   }
   6862 
   6863   // Setup the callee in-object property.
   6864   ASSERT(Heap::arguments_callee_index == 0);
   6865   __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
   6866   __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize));
   6867 
   6868   // Get the length (smi tagged) and set that as an in-object property too.
   6869   ASSERT(Heap::arguments_length_index == 1);
   6870   __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
   6871   __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize));
   6872 
   6873   // If there are no actual arguments, we're done.
   6874   Label done;
   6875   __ cmp(r1, Operand(0));
   6876   __ b(eq, &done);
   6877 
   6878   // Get the parameters pointer from the stack and untag the length.
   6879   __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
   6880   __ mov(r1, Operand(r1, LSR, kSmiTagSize));
   6881 
   6882   // Setup the elements pointer in the allocated arguments object and
   6883   // initialize the header in the elements fixed array.
   6884   __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
   6885   __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
   6886   __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
   6887   __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
   6888   __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
   6889 
   6890   // Copy the fixed array slots.
   6891   Label loop;
   6892   // Setup r4 to point to the first array slot.
   6893   __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   6894   __ bind(&loop);
   6895   // Pre-decrement r2 with kPointerSize on each iteration.
   6896   // Pre-decrement in order to skip receiver.
   6897   __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
   6898   // Post-increment r4 with kPointerSize on each iteration.
   6899   __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
   6900   __ sub(r1, r1, Operand(1));
   6901   __ cmp(r1, Operand(0));
   6902   __ b(ne, &loop);
   6903 
   6904   // Return and remove the on-stack parameters.
   6905   __ bind(&done);
   6906   __ add(sp, sp, Operand(3 * kPointerSize));
   6907   __ Ret();
   6908 
   6909   // Do the runtime call to allocate the arguments object.
   6910   __ bind(&runtime);
   6911   __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
   6912 }
   6913 
   6914 
   6915 void CallFunctionStub::Generate(MacroAssembler* masm) {
   6916   Label slow;
   6917 
   6918   // If the receiver might be a value (string, number or boolean) check for this
   6919   // and box it if it is.
   6920   if (ReceiverMightBeValue()) {
   6921     // Get the receiver from the stack.
   6922     // function, receiver [, arguments]
   6923     Label receiver_is_value, receiver_is_js_object;
   6924     __ ldr(r1, MemOperand(sp, argc_ * kPointerSize));
   6925 
   6926     // Check if receiver is a smi (which is a number value).
   6927     __ BranchOnSmi(r1, &receiver_is_value);
   6928 
   6929     // Check if the receiver is a valid JS object.
   6930     __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE);
   6931     __ b(ge, &receiver_is_js_object);
   6932 
   6933     // Call the runtime to box the value.
   6934     __ bind(&receiver_is_value);
   6935     __ EnterInternalFrame();
   6936     __ push(r1);
   6937     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
   6938     __ LeaveInternalFrame();
   6939     __ str(r0, MemOperand(sp, argc_ * kPointerSize));
   6940 
   6941     __ bind(&receiver_is_js_object);
   6942   }
   6943 
   6944   // Get the function to call from the stack.
   6945   // function, receiver [, arguments]
   6946   __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize));
   6947 
   6948   // Check that the function is really a JavaScript function.
   6949   // r1: pushed function (to be verified)
   6950   __ BranchOnSmi(r1, &slow);
   6951   // Get the map of the function object.
   6952   __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
   6953   __ b(ne, &slow);
   6954 
   6955   // Fast-case: Invoke the function now.
   6956   // r1: pushed function
   6957   ParameterCount actual(argc_);
   6958   __ InvokeFunction(r1, actual, JUMP_FUNCTION);
   6959 
   6960   // Slow-case: Non-function called.
   6961   __ bind(&slow);
   6962   // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
   6963   // of the original receiver from the call site).
   6964   __ str(r1, MemOperand(sp, argc_ * kPointerSize));
   6965   __ mov(r0, Operand(argc_));  // Setup the number of arguments.
   6966   __ mov(r2, Operand(0));
   6967   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
   6968   __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
   6969           RelocInfo::CODE_TARGET);
   6970 }
   6971 
   6972 
   6973 const char* CompareStub::GetName() {
   6974   switch (cc_) {
   6975     case lt: return "CompareStub_LT";
   6976     case gt: return "CompareStub_GT";
   6977     case le: return "CompareStub_LE";
   6978     case ge: return "CompareStub_GE";
   6979     case ne: {
   6980       if (strict_) {
   6981         if (never_nan_nan_) {
   6982           return "CompareStub_NE_STRICT_NO_NAN";
   6983         } else {
   6984           return "CompareStub_NE_STRICT";
   6985         }
   6986       } else {
   6987         if (never_nan_nan_) {
   6988           return "CompareStub_NE_NO_NAN";
   6989         } else {
   6990           return "CompareStub_NE";
   6991         }
   6992       }
   6993     }
   6994     case eq: {
   6995       if (strict_) {
   6996         if (never_nan_nan_) {
   6997           return "CompareStub_EQ_STRICT_NO_NAN";
   6998         } else {
   6999           return "CompareStub_EQ_STRICT";
   7000         }
   7001       } else {
   7002         if (never_nan_nan_) {
   7003           return "CompareStub_EQ_NO_NAN";
   7004         } else {
   7005           return "CompareStub_EQ";
   7006         }
   7007       }
   7008     }
   7009     default: return "CompareStub";
   7010   }
   7011 }
   7012 
   7013 
   7014 int CompareStub::MinorKey() {
   7015   // Encode the three parameters in a unique 16 bit value.
   7016   ASSERT((static_cast<unsigned>(cc_) >> 26) < (1 << 16));
   7017   int nnn_value = (never_nan_nan_ ? 2 : 0);
   7018   if (cc_ != eq) nnn_value = 0;  // Avoid duplicate stubs.
   7019   return (static_cast<unsigned>(cc_) >> 26) | nnn_value | (strict_ ? 1 : 0);
   7020 }
   7021 
   7022 
   7023 void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
   7024                                             Register dest,
   7025                                             Register src,
   7026                                             Register count,
   7027                                             Register scratch,
   7028                                             bool ascii) {
   7029   Label loop;
   7030   Label done;
   7031   // This loop just copies one character at a time, as it is only used for very
   7032   // short strings.
   7033   if (!ascii) {
   7034     __ add(count, count, Operand(count), SetCC);
   7035   } else {
   7036     __ cmp(count, Operand(0));
   7037   }
   7038   __ b(eq, &done);
   7039 
   7040   __ bind(&loop);
   7041   __ ldrb(scratch, MemOperand(src, 1, PostIndex));
   7042   // Perform sub between load and dependent store to get the load time to
   7043   // complete.
   7044   __ sub(count, count, Operand(1), SetCC);
   7045   __ strb(scratch, MemOperand(dest, 1, PostIndex));
   7046   // last iteration.
   7047   __ b(gt, &loop);
   7048 
   7049   __ bind(&done);
   7050 }
   7051 
   7052 
   7053 enum CopyCharactersFlags {
   7054   COPY_ASCII = 1,
   7055   DEST_ALWAYS_ALIGNED = 2
   7056 };
   7057 
   7058 
   7059 void StringStubBase::GenerateCopyCharactersLong(MacroAssembler* masm,
   7060                                                 Register dest,
   7061                                                 Register src,
   7062                                                 Register count,
   7063                                                 Register scratch1,
   7064                                                 Register scratch2,
   7065                                                 Register scratch3,
   7066                                                 Register scratch4,
   7067                                                 Register scratch5,
   7068                                                 int flags) {
   7069   bool ascii = (flags & COPY_ASCII) != 0;
   7070   bool dest_always_aligned = (flags & DEST_ALWAYS_ALIGNED) != 0;
   7071 
   7072   if (dest_always_aligned && FLAG_debug_code) {
   7073     // Check that destination is actually word aligned if the flag says
   7074     // that it is.
   7075     __ tst(dest, Operand(kPointerAlignmentMask));
   7076     __ Check(eq, "Destination of copy not aligned.");
   7077   }
   7078 
   7079   const int kReadAlignment = 4;
   7080   const int kReadAlignmentMask = kReadAlignment - 1;
   7081   // Ensure that reading an entire aligned word containing the last character
   7082   // of a string will not read outside the allocated area (because we pad up
   7083   // to kObjectAlignment).
   7084   ASSERT(kObjectAlignment >= kReadAlignment);
   7085   // Assumes word reads and writes are little endian.
   7086   // Nothing to do for zero characters.
   7087   Label done;
   7088   if (!ascii) {
   7089     __ add(count, count, Operand(count), SetCC);
   7090   } else {
   7091     __ cmp(count, Operand(0));
   7092   }
   7093   __ b(eq, &done);
   7094 
   7095   // Assume that you cannot read (or write) unaligned.
   7096   Label byte_loop;
   7097   // Must copy at least eight bytes, otherwise just do it one byte at a time.
   7098   __ cmp(count, Operand(8));
   7099   __ add(count, dest, Operand(count));
   7100   Register limit = count;  // Read until src equals this.
   7101   __ b(lt, &byte_loop);
   7102 
   7103   if (!dest_always_aligned) {
   7104     // Align dest by byte copying. Copies between zero and three bytes.
   7105     __ and_(scratch4, dest, Operand(kReadAlignmentMask), SetCC);
   7106     Label dest_aligned;
   7107     __ b(eq, &dest_aligned);
   7108     __ cmp(scratch4, Operand(2));
   7109     __ ldrb(scratch1, MemOperand(src, 1, PostIndex));
   7110     __ ldrb(scratch2, MemOperand(src, 1, PostIndex), le);
   7111     __ ldrb(scratch3, MemOperand(src, 1, PostIndex), lt);
   7112     __ strb(scratch1, MemOperand(dest, 1, PostIndex));
   7113     __ strb(scratch2, MemOperand(dest, 1, PostIndex), le);
   7114     __ strb(scratch3, MemOperand(dest, 1, PostIndex), lt);
   7115     __ bind(&dest_aligned);
   7116   }
   7117 
   7118   Label simple_loop;
   7119 
   7120   __ sub(scratch4, dest, Operand(src));
   7121   __ and_(scratch4, scratch4, Operand(0x03), SetCC);
   7122   __ b(eq, &simple_loop);
   7123   // Shift register is number of bits in a source word that
   7124   // must be combined with bits in the next source word in order
   7125   // to create a destination word.
   7126 
   7127   // Complex loop for src/dst that are not aligned the same way.
   7128   {
   7129     Label loop;
   7130     __ mov(scratch4, Operand(scratch4, LSL, 3));
   7131     Register left_shift = scratch4;
   7132     __ and_(src, src, Operand(~3));  // Round down to load previous word.
   7133     __ ldr(scratch1, MemOperand(src, 4, PostIndex));
   7134     // Store the "shift" most significant bits of scratch in the least
   7135     // signficant bits (i.e., shift down by (32-shift)).
   7136     __ rsb(scratch2, left_shift, Operand(32));
   7137     Register right_shift = scratch2;
   7138     __ mov(scratch1, Operand(scratch1, LSR, right_shift));
   7139 
   7140     __ bind(&loop);
   7141     __ ldr(scratch3, MemOperand(src, 4, PostIndex));
   7142     __ sub(scratch5, limit, Operand(dest));
   7143     __ orr(scratch1, scratch1, Operand(scratch3, LSL, left_shift));
   7144     __ str(scratch1, MemOperand(dest, 4, PostIndex));
   7145     __ mov(scratch1, Operand(scratch3, LSR, right_shift));
   7146     // Loop if four or more bytes left to copy.
   7147     // Compare to eight, because we did the subtract before increasing dst.
   7148     __ sub(scratch5, scratch5, Operand(8), SetCC);
   7149     __ b(ge, &loop);
   7150   }
   7151   // There is now between zero and three bytes left to copy (negative that
   7152   // number is in scratch5), and between one and three bytes already read into
   7153   // scratch1 (eight times that number in scratch4). We may have read past
   7154   // the end of the string, but because objects are aligned, we have not read
   7155   // past the end of the object.
   7156   // Find the minimum of remaining characters to move and preloaded characters
   7157   // and write those as bytes.
   7158   __ add(scratch5, scratch5, Operand(4), SetCC);
   7159   __ b(eq, &done);
   7160   __ cmp(scratch4, Operand(scratch5, LSL, 3), ne);
   7161   // Move minimum of bytes read and bytes left to copy to scratch4.
   7162   __ mov(scratch5, Operand(scratch4, LSR, 3), LeaveCC, lt);
   7163   // Between one and three (value in scratch5) characters already read into
   7164   // scratch ready to write.
   7165   __ cmp(scratch5, Operand(2));
   7166   __ strb(scratch1, MemOperand(dest, 1, PostIndex));
   7167   __ mov(scratch1, Operand(scratch1, LSR, 8), LeaveCC, ge);
   7168   __ strb(scratch1, MemOperand(dest, 1, PostIndex), ge);
   7169   __ mov(scratch1, Operand(scratch1, LSR, 8), LeaveCC, gt);
   7170   __ strb(scratch1, MemOperand(dest, 1, PostIndex), gt);
   7171   // Copy any remaining bytes.
   7172   __ b(&byte_loop);
   7173 
   7174   // Simple loop.
   7175   // Copy words from src to dst, until less than four bytes left.
   7176   // Both src and dest are word aligned.
   7177   __ bind(&simple_loop);
   7178   {
   7179     Label loop;
   7180     __ bind(&loop);
   7181     __ ldr(scratch1, MemOperand(src, 4, PostIndex));
   7182     __ sub(scratch3, limit, Operand(dest));
   7183     __ str(scratch1, MemOperand(dest, 4, PostIndex));
   7184     // Compare to 8, not 4, because we do the substraction before increasing
   7185     // dest.
   7186     __ cmp(scratch3, Operand(8));
   7187     __ b(ge, &loop);
   7188   }
   7189 
   7190   // Copy bytes from src to dst until dst hits limit.
   7191   __ bind(&byte_loop);
   7192   __ cmp(dest, Operand(limit));
   7193   __ ldrb(scratch1, MemOperand(src, 1, PostIndex), lt);
   7194   __ b(ge, &done);
   7195   __ strb(scratch1, MemOperand(dest, 1, PostIndex));
   7196   __ b(&byte_loop);
   7197 
   7198   __ bind(&done);
   7199 }
   7200 
   7201 
   7202 void SubStringStub::Generate(MacroAssembler* masm) {
   7203   Label runtime;
   7204 
   7205   // Stack frame on entry.
   7206   //  lr: return address
   7207   //  sp[0]: to
   7208   //  sp[4]: from
   7209   //  sp[8]: string
   7210 
   7211   // This stub is called from the native-call %_SubString(...), so
   7212   // nothing can be assumed about the arguments. It is tested that:
   7213   //  "string" is a sequential string,
   7214   //  both "from" and "to" are smis, and
   7215   //  0 <= from <= to <= string.length.
   7216   // If any of these assumptions fail, we call the runtime system.
   7217 
   7218   static const int kToOffset = 0 * kPointerSize;
   7219   static const int kFromOffset = 1 * kPointerSize;
   7220   static const int kStringOffset = 2 * kPointerSize;
   7221 
   7222 
   7223   // Check bounds and smi-ness.
   7224   __ ldr(r7, MemOperand(sp, kToOffset));
   7225   __ ldr(r6, MemOperand(sp, kFromOffset));
   7226   ASSERT_EQ(0, kSmiTag);
   7227   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
   7228   // I.e., arithmetic shift right by one un-smi-tags.
   7229   __ mov(r2, Operand(r7, ASR, 1), SetCC);
   7230   __ mov(r3, Operand(r6, ASR, 1), SetCC, cc);
   7231   // If either r2 or r6 had the smi tag bit set, then carry is set now.
   7232   __ b(cs, &runtime);  // Either "from" or "to" is not a smi.
   7233   __ b(mi, &runtime);  // From is negative.
   7234 
   7235   __ sub(r2, r2, Operand(r3), SetCC);
   7236   __ b(mi, &runtime);  // Fail if from > to.
   7237   // Handle sub-strings of length 2 and less in the runtime system.
   7238   __ cmp(r2, Operand(2));
   7239   __ b(le, &runtime);
   7240 
   7241   // r2: length
   7242   // r6: from (smi)
   7243   // r7: to (smi)
   7244 
   7245   // Make sure first argument is a sequential (or flat) string.
   7246   __ ldr(r5, MemOperand(sp, kStringOffset));
   7247   ASSERT_EQ(0, kSmiTag);
   7248   __ tst(r5, Operand(kSmiTagMask));
   7249   __ b(eq, &runtime);
   7250   Condition is_string = masm->IsObjectStringType(r5, r1);
   7251   __ b(NegateCondition(is_string), &runtime);
   7252 
   7253   // r1: instance type
   7254   // r2: length
   7255   // r5: string
   7256   // r6: from (smi)
   7257   // r7: to (smi)
   7258   Label seq_string;
   7259   __ and_(r4, r1, Operand(kStringRepresentationMask));
   7260   ASSERT(kSeqStringTag < kConsStringTag);
   7261   ASSERT(kExternalStringTag > kConsStringTag);
   7262   __ cmp(r4, Operand(kConsStringTag));
   7263   __ b(gt, &runtime);  // External strings go to runtime.
   7264   __ b(lt, &seq_string);  // Sequential strings are handled directly.
   7265 
   7266   // Cons string. Try to recurse (once) on the first substring.
   7267   // (This adds a little more generality than necessary to handle flattened
   7268   // cons strings, but not much).
   7269   __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset));
   7270   __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
   7271   __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   7272   __ tst(r1, Operand(kStringRepresentationMask));
   7273   ASSERT_EQ(0, kSeqStringTag);
   7274   __ b(ne, &runtime);  // Cons and External strings go to runtime.
   7275 
   7276   // Definitly a sequential string.
   7277   __ bind(&seq_string);
   7278 
   7279   // r1: instance type.
   7280   // r2: length
   7281   // r5: string
   7282   // r6: from (smi)
   7283   // r7: to (smi)
   7284   __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
   7285   __ cmp(r4, Operand(r7, ASR, 1));
   7286   __ b(lt, &runtime);  // Fail if to > length.
   7287 
   7288   // r1: instance type.
   7289   // r2: result string length.
   7290   // r5: string.
   7291   // r6: from offset (smi)
   7292   // Check for flat ascii string.
   7293   Label non_ascii_flat;
   7294   __ tst(r1, Operand(kStringEncodingMask));
   7295   ASSERT_EQ(0, kTwoByteStringTag);
   7296   __ b(eq, &non_ascii_flat);
   7297 
   7298   // Allocate the result.
   7299   __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime);
   7300 
   7301   // r0: result string.
   7302   // r2: result string length.
   7303   // r5: string.
   7304   // r6: from offset (smi)
   7305   // Locate first character of result.
   7306   __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7307   // Locate 'from' character of string.
   7308   __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7309   __ add(r5, r5, Operand(r6, ASR, 1));
   7310 
   7311   // r0: result string.
   7312   // r1: first character of result string.
   7313   // r2: result string length.
   7314   // r5: first character of sub string to copy.
   7315   ASSERT_EQ(0, SeqAsciiString::kHeaderSize & kObjectAlignmentMask);
   7316   GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
   7317                              COPY_ASCII | DEST_ALWAYS_ALIGNED);
   7318   __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
   7319   __ add(sp, sp, Operand(3 * kPointerSize));
   7320   __ Ret();
   7321 
   7322   __ bind(&non_ascii_flat);
   7323   // r2: result string length.
   7324   // r5: string.
   7325   // r6: from offset (smi)
   7326   // Check for flat two byte string.
   7327 
   7328   // Allocate the result.
   7329   __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime);
   7330 
   7331   // r0: result string.
   7332   // r2: result string length.
   7333   // r5: string.
   7334   // Locate first character of result.
   7335   __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   7336   // Locate 'from' character of string.
   7337     __ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   7338   // As "from" is a smi it is 2 times the value which matches the size of a two
   7339   // byte character.
   7340   __ add(r5, r5, Operand(r6));
   7341 
   7342   // r0: result string.
   7343   // r1: first character of result.
   7344   // r2: result length.
   7345   // r5: first character of string to copy.
   7346   ASSERT_EQ(0, SeqTwoByteString::kHeaderSize & kObjectAlignmentMask);
   7347   GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
   7348                              DEST_ALWAYS_ALIGNED);
   7349   __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
   7350   __ add(sp, sp, Operand(3 * kPointerSize));
   7351   __ Ret();
   7352 
   7353   // Just jump to runtime to create the sub string.
   7354   __ bind(&runtime);
   7355   __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1);
   7356 }
   7357 
   7358 
   7359 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
   7360                                                         Register left,
   7361                                                         Register right,
   7362                                                         Register scratch1,
   7363                                                         Register scratch2,
   7364                                                         Register scratch3,
   7365                                                         Register scratch4) {
   7366   Label compare_lengths;
   7367   // Find minimum length and length difference.
   7368   __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
   7369   __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
   7370   __ sub(scratch3, scratch1, Operand(scratch2), SetCC);
   7371   Register length_delta = scratch3;
   7372   __ mov(scratch1, scratch2, LeaveCC, gt);
   7373   Register min_length = scratch1;
   7374   __ tst(min_length, Operand(min_length));
   7375   __ b(eq, &compare_lengths);
   7376 
   7377   // Setup registers so that we only need to increment one register
   7378   // in the loop.
   7379   __ add(scratch2, min_length,
   7380          Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7381   __ add(left, left, Operand(scratch2));
   7382   __ add(right, right, Operand(scratch2));
   7383   // Registers left and right points to the min_length character of strings.
   7384   __ rsb(min_length, min_length, Operand(-1));
   7385   Register index = min_length;
   7386   // Index starts at -min_length.
   7387 
   7388   {
   7389     // Compare loop.
   7390     Label loop;
   7391     __ bind(&loop);
   7392     // Compare characters.
   7393     __ add(index, index, Operand(1), SetCC);
   7394     __ ldrb(scratch2, MemOperand(left, index), ne);
   7395     __ ldrb(scratch4, MemOperand(right, index), ne);
   7396     // Skip to compare lengths with eq condition true.
   7397     __ b(eq, &compare_lengths);
   7398     __ cmp(scratch2, scratch4);
   7399     __ b(eq, &loop);
   7400     // Fallthrough with eq condition false.
   7401   }
   7402   // Compare lengths -  strings up to min-length are equal.
   7403   __ bind(&compare_lengths);
   7404   ASSERT(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
   7405   // Use zero length_delta as result.
   7406   __ mov(r0, Operand(length_delta), SetCC, eq);
   7407   // Fall through to here if characters compare not-equal.
   7408   __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt);
   7409   __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt);
   7410   __ Ret();
   7411 }
   7412 
   7413 
   7414 void StringCompareStub::Generate(MacroAssembler* masm) {
   7415   Label runtime;
   7416 
   7417   // Stack frame on entry.
   7418   //  sp[0]: right string
   7419   //  sp[4]: left string
   7420   __ ldr(r0, MemOperand(sp, 1 * kPointerSize));  // left
   7421   __ ldr(r1, MemOperand(sp, 0 * kPointerSize));  // right
   7422 
   7423   Label not_same;
   7424   __ cmp(r0, r1);
   7425   __ b(ne, &not_same);
   7426   ASSERT_EQ(0, EQUAL);
   7427   ASSERT_EQ(0, kSmiTag);
   7428   __ mov(r0, Operand(Smi::FromInt(EQUAL)));
   7429   __ IncrementCounter(&Counters::string_compare_native, 1, r1, r2);
   7430   __ add(sp, sp, Operand(2 * kPointerSize));
   7431   __ Ret();
   7432 
   7433   __ bind(&not_same);
   7434 
   7435   // Check that both objects are sequential ascii strings.
   7436   __ JumpIfNotBothSequentialAsciiStrings(r0, r1, r2, r3, &runtime);
   7437 
   7438   // Compare flat ascii strings natively. Remove arguments from stack first.
   7439   __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3);
   7440   __ add(sp, sp, Operand(2 * kPointerSize));
   7441   GenerateCompareFlatAsciiStrings(masm, r0, r1, r2, r3, r4, r5);
   7442 
   7443   // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
   7444   // tagged as a small integer.
   7445   __ bind(&runtime);
   7446   __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
   7447 }
   7448 
   7449 
   7450 void StringAddStub::Generate(MacroAssembler* masm) {
   7451   Label string_add_runtime;
   7452   // Stack on entry:
   7453   // sp[0]: second argument.
   7454   // sp[4]: first argument.
   7455 
   7456   // Load the two arguments.
   7457   __ ldr(r0, MemOperand(sp, 1 * kPointerSize));  // First argument.
   7458   __ ldr(r1, MemOperand(sp, 0 * kPointerSize));  // Second argument.
   7459 
   7460   // Make sure that both arguments are strings if not known in advance.
   7461   if (string_check_) {
   7462     ASSERT_EQ(0, kSmiTag);
   7463     __ JumpIfEitherSmi(r0, r1, &string_add_runtime);
   7464     // Load instance types.
   7465     __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
   7466     __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
   7467     __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   7468     __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
   7469     ASSERT_EQ(0, kStringTag);
   7470     // If either is not a string, go to runtime.
   7471     __ tst(r4, Operand(kIsNotStringMask));
   7472     __ tst(r5, Operand(kIsNotStringMask), eq);
   7473     __ b(ne, &string_add_runtime);
   7474   }
   7475 
   7476   // Both arguments are strings.
   7477   // r0: first string
   7478   // r1: second string
   7479   // r4: first string instance type (if string_check_)
   7480   // r5: second string instance type (if string_check_)
   7481   {
   7482     Label strings_not_empty;
   7483     // Check if either of the strings are empty. In that case return the other.
   7484     __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset));
   7485     __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
   7486     __ cmp(r2, Operand(0));  // Test if first string is empty.
   7487     __ mov(r0, Operand(r1), LeaveCC, eq);  // If first is empty, return second.
   7488     __ cmp(r3, Operand(0), ne);  // Else test if second string is empty.
   7489     __ b(ne, &strings_not_empty);  // If either string was empty, return r0.
   7490 
   7491     __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
   7492     __ add(sp, sp, Operand(2 * kPointerSize));
   7493     __ Ret();
   7494 
   7495     __ bind(&strings_not_empty);
   7496   }
   7497 
   7498   // Both strings are non-empty.
   7499   // r0: first string
   7500   // r1: second string
   7501   // r2: length of first string
   7502   // r3: length of second string
   7503   // r4: first string instance type (if string_check_)
   7504   // r5: second string instance type (if string_check_)
   7505   // Look at the length of the result of adding the two strings.
   7506   Label string_add_flat_result;
   7507   // Adding two lengths can't overflow.
   7508   ASSERT(String::kMaxLength * 2 > String::kMaxLength);
   7509   __ add(r6, r2, Operand(r3));
   7510   // Use the runtime system when adding two one character strings, as it
   7511   // contains optimizations for this specific case using the symbol table.
   7512   __ cmp(r6, Operand(2));
   7513   __ b(eq, &string_add_runtime);
   7514   // Check if resulting string will be flat.
   7515   __ cmp(r6, Operand(String::kMinNonFlatLength));
   7516   __ b(lt, &string_add_flat_result);
   7517   // Handle exceptionally long strings in the runtime system.
   7518   ASSERT((String::kMaxLength & 0x80000000) == 0);
   7519   ASSERT(IsPowerOf2(String::kMaxLength + 1));
   7520   // kMaxLength + 1 is representable as shifted literal, kMaxLength is not.
   7521   __ cmp(r6, Operand(String::kMaxLength + 1));
   7522   __ b(hs, &string_add_runtime);
   7523 
   7524   // If result is not supposed to be flat, allocate a cons string object.
   7525   // If both strings are ascii the result is an ascii cons string.
   7526   if (!string_check_) {
   7527     __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
   7528     __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
   7529     __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   7530     __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
   7531   }
   7532   Label non_ascii, allocated;
   7533   ASSERT_EQ(0, kTwoByteStringTag);
   7534   __ tst(r4, Operand(kStringEncodingMask));
   7535   __ tst(r5, Operand(kStringEncodingMask), ne);
   7536   __ b(eq, &non_ascii);
   7537 
   7538   // Allocate an ASCII cons string.
   7539   __ AllocateAsciiConsString(r7, r6, r4, r5, &string_add_runtime);
   7540   __ bind(&allocated);
   7541   // Fill the fields of the cons string.
   7542   __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
   7543   __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
   7544   __ mov(r0, Operand(r7));
   7545   __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
   7546   __ add(sp, sp, Operand(2 * kPointerSize));
   7547   __ Ret();
   7548 
   7549   __ bind(&non_ascii);
   7550   // Allocate a two byte cons string.
   7551   __ AllocateTwoByteConsString(r7, r6, r4, r5, &string_add_runtime);
   7552   __ jmp(&allocated);
   7553 
   7554   // Handle creating a flat result. First check that both strings are
   7555   // sequential and that they have the same encoding.
   7556   // r0: first string
   7557   // r1: second string
   7558   // r2: length of first string
   7559   // r3: length of second string
   7560   // r4: first string instance type (if string_check_)
   7561   // r5: second string instance type (if string_check_)
   7562   // r6: sum of lengths.
   7563   __ bind(&string_add_flat_result);
   7564   if (!string_check_) {
   7565     __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
   7566     __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
   7567     __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   7568     __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
   7569   }
   7570   // Check that both strings are sequential.
   7571   ASSERT_EQ(0, kSeqStringTag);
   7572   __ tst(r4, Operand(kStringRepresentationMask));
   7573   __ tst(r5, Operand(kStringRepresentationMask), eq);
   7574   __ b(ne, &string_add_runtime);
   7575   // Now check if both strings have the same encoding (ASCII/Two-byte).
   7576   // r0: first string.
   7577   // r1: second string.
   7578   // r2: length of first string.
   7579   // r3: length of second string.
   7580   // r6: sum of lengths..
   7581   Label non_ascii_string_add_flat_result;
   7582   ASSERT(IsPowerOf2(kStringEncodingMask));  // Just one bit to test.
   7583   __ eor(r7, r4, Operand(r5));
   7584   __ tst(r7, Operand(kStringEncodingMask));
   7585   __ b(ne, &string_add_runtime);
   7586   // And see if it's ASCII or two-byte.
   7587   __ tst(r4, Operand(kStringEncodingMask));
   7588   __ b(eq, &non_ascii_string_add_flat_result);
   7589 
   7590   // Both strings are sequential ASCII strings. We also know that they are
   7591   // short (since the sum of the lengths is less than kMinNonFlatLength).
   7592   __ AllocateAsciiString(r7, r6, r4, r5, r9, &string_add_runtime);
   7593   // Locate first character of result.
   7594   __ add(r6, r7, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7595   // Locate first character of first argument.
   7596   __ add(r0, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7597   // r0: first character of first string.
   7598   // r1: second string.
   7599   // r2: length of first string.
   7600   // r3: length of second string.
   7601   // r6: first character of result.
   7602   // r7: result string.
   7603   GenerateCopyCharacters(masm, r6, r0, r2, r4, true);
   7604 
   7605   // Load second argument and locate first character.
   7606   __ add(r1, r1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   7607   // r1: first character of second string.
   7608   // r3: length of second string.
   7609   // r6: next character of result.
   7610   // r7: result string.
   7611   GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
   7612   __ mov(r0, Operand(r7));
   7613   __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
   7614   __ add(sp, sp, Operand(2 * kPointerSize));
   7615   __ Ret();
   7616 
   7617   __ bind(&non_ascii_string_add_flat_result);
   7618   // Both strings are sequential two byte strings.
   7619   // r0: first string.
   7620   // r1: second string.
   7621   // r2: length of first string.
   7622   // r3: length of second string.
   7623   // r6: sum of length of strings.
   7624   __ AllocateTwoByteString(r7, r6, r4, r5, r9, &string_add_runtime);
   7625   // r0: first string.
   7626   // r1: second string.
   7627   // r2: length of first string.
   7628   // r3: length of second string.
   7629   // r7: result string.
   7630 
   7631   // Locate first character of result.
   7632   __ add(r6, r7, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   7633   // Locate first character of first argument.
   7634   __ add(r0, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   7635 
   7636   // r0: first character of first string.
   7637   // r1: second string.
   7638   // r2: length of first string.
   7639   // r3: length of second string.
   7640   // r6: first character of result.
   7641   // r7: result string.
   7642   GenerateCopyCharacters(masm, r6, r0, r2, r4, false);
   7643 
   7644   // Locate first character of second argument.
   7645   __ add(r1, r1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   7646 
   7647   // r1: first character of second string.
   7648   // r3: length of second string.
   7649   // r6: next character of result (after copy of first string).
   7650   // r7: result string.
   7651   GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
   7652 
   7653   __ mov(r0, Operand(r7));
   7654   __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
   7655   __ add(sp, sp, Operand(2 * kPointerSize));
   7656   __ Ret();
   7657 
   7658   // Just jump to runtime to add the two strings.
   7659   __ bind(&string_add_runtime);
   7660   __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
   7661 }
   7662 
   7663 
   7664 #undef __
   7665 
   7666 } }  // namespace v8::internal
   7667