// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"

#if defined(V8_TARGET_ARCH_X64)

#include "bootstrapper.h"
#include "code-stubs.h"
#include "regexp-macro-assembler.h"

namespace v8 {
namespace internal {

#define __ ACCESS_MASM(masm)

void ToNumberStub::Generate(MacroAssembler* masm) {
  // The ToNumber stub takes one argument in eax.
  NearLabel check_heap_number, call_builtin;
  __ SmiTest(rax);
  __ j(not_zero, &check_heap_number);
  __ Ret();

  __ bind(&check_heap_number);
  __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
                 Heap::kHeapNumberMapRootIndex);
  __ j(not_equal, &call_builtin);
  __ Ret();

  __ bind(&call_builtin);
  __ pop(rcx);  // Pop return address.
  __ push(rax);
  __ push(rcx);  // Push return address.
  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}


void FastNewClosureStub::Generate(MacroAssembler* masm) {
  // Create a new closure from the given function info in new
  // space. Set the context to the current context in rsi.
  Label gc;
  __ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);

  // Get the function info from the stack.
  __ movq(rdx, Operand(rsp, 1 * kPointerSize));

  int map_index = strict_mode_ == kStrictMode
      ? Context::STRICT_MODE_FUNCTION_MAP_INDEX
      : Context::FUNCTION_MAP_INDEX;

  // Compute the function map in the current global context and set that
  // as the map of the allocated object.
  __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
  __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
  __ movq(rcx, Operand(rcx, Context::SlotOffset(map_index)));
  __ movq(FieldOperand(rax, JSObject::kMapOffset), rcx);

  // Initialize the rest of the function. We don't have to update the
  // write barrier because the allocated object is in new space.
  __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
  __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
  __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
  __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx);
  __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), rcx);
  __ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx);
  __ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi);
  __ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx);
  __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset), rdi);

  // Initialize the code pointer in the function to be the one
  // found in the shared function info object.
  __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
  __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
  __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);


  // Return and remove the on-stack parameter.
  __ ret(1 * kPointerSize);

  // Create a new closure through the slower runtime call.
  __ bind(&gc);
  __ pop(rcx);  // Temporarily remove return address.
  __ pop(rdx);
  __ push(rsi);
  __ push(rdx);
  __ PushRoot(Heap::kFalseValueRootIndex);
  __ push(rcx);  // Restore return address.
  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
}


void FastNewContextStub::Generate(MacroAssembler* masm) {
  // Try to allocate the context in new space.
  Label gc;
  int length = slots_ + Context::MIN_CONTEXT_SLOTS;
  __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
                        rax, rbx, rcx, &gc, TAG_OBJECT);

  // Get the function from the stack.
  __ movq(rcx, Operand(rsp, 1 * kPointerSize));

  // Setup the object header.
  __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex);
  __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
  __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));

  // Setup the fixed slots.
  __ Set(rbx, 0);  // Set to NULL.
  __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
  __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
  __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
  __ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx);

  // Copy the global object from the surrounding context.
  __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
  __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);

  // Initialize the rest of the slots to undefined.
  __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
  for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
    __ movq(Operand(rax, Context::SlotOffset(i)), rbx);
  }

  // Return and remove the on-stack parameter.
  __ movq(rsi, rax);
  __ ret(1 * kPointerSize);

  // Need to collect. Call into runtime system.
  __ bind(&gc);
  __ TailCallRuntime(Runtime::kNewContext, 1, 1);
}


void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
  // Stack layout on entry:
  //
  // [rsp + kPointerSize]: constant elements.
  // [rsp + (2 * kPointerSize)]: literal index.
  // [rsp + (3 * kPointerSize)]: literals array.

  // All sizes here are multiples of kPointerSize.
  int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
  int size = JSArray::kSize + elements_size;

  // Load boilerplate object into rcx and check if we need to create a
  // boilerplate.
  Label slow_case;
  __ movq(rcx, Operand(rsp, 3 * kPointerSize));
  __ movq(rax, Operand(rsp, 2 * kPointerSize));
  SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
  __ movq(rcx,
          FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize));
  __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
  __ j(equal, &slow_case);

  if (FLAG_debug_code) {
    const char* message;
    Heap::RootListIndex expected_map_index;
    if (mode_ == CLONE_ELEMENTS) {
      message = "Expected (writable) fixed array";
      expected_map_index = Heap::kFixedArrayMapRootIndex;
    } else {
      ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
      message = "Expected copy-on-write fixed array";
      expected_map_index = Heap::kFixedCOWArrayMapRootIndex;
    }
    __ push(rcx);
    __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
    __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
                   expected_map_index);
    __ Assert(equal, message);
    __ pop(rcx);
  }

  // Allocate both the JS array and the elements array in one big
  // allocation. This avoids multiple limit checks.
  __ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT);

  // Copy the JS array part.
  for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
    if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
      __ movq(rbx, FieldOperand(rcx, i));
      __ movq(FieldOperand(rax, i), rbx);
    }
  }

  if (length_ > 0) {
    // Get hold of the elements array of the boilerplate and setup the
    // elements pointer in the resulting object.
    __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
    __ lea(rdx, Operand(rax, JSArray::kSize));
    __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);

    // Copy the elements array.
    for (int i = 0; i < elements_size; i += kPointerSize) {
      __ movq(rbx, FieldOperand(rcx, i));
      __ movq(FieldOperand(rdx, i), rbx);
    }
  }

  // Return and remove the on-stack parameters.
  __ ret(3 * kPointerSize);

  __ bind(&slow_case);
  __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1);
}


void ToBooleanStub::Generate(MacroAssembler* masm) {
  NearLabel false_result, true_result, not_string;
  __ movq(rax, Operand(rsp, 1 * kPointerSize));

  // 'null' => false.
  __ CompareRoot(rax, Heap::kNullValueRootIndex);
  __ j(equal, &false_result);

  // Get the map and type of the heap object.
  // We don't use CmpObjectType because we manipulate the type field.
  __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
  __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset));

  // Undetectable => false.
  __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
  __ and_(rbx, Immediate(1 << Map::kIsUndetectable));
  __ j(not_zero, &false_result);

  // JavaScript object => true.
  __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE));
  __ j(above_equal, &true_result);

  // String value => false iff empty.
  __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
  __ j(above_equal, &not_string);
  __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
  __ SmiTest(rdx);
  __ j(zero, &false_result);
  __ jmp(&true_result);

  __ bind(&not_string);
  __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
  __ j(not_equal, &true_result);
  // HeapNumber => false iff +0, -0, or NaN.
  // These three cases set the zero flag when compared to zero using ucomisd.
  __ xorps(xmm0, xmm0);
  __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
  __ j(zero, &false_result);
  // Fall through to |true_result|.

  // Return 1/0 for true/false in rax.
  __ bind(&true_result);
  __ Set(rax, 1);
  __ ret(1 * kPointerSize);
  __ bind(&false_result);
  __ Set(rax, 0);
  __ ret(1 * kPointerSize);
}


class FloatingPointHelper : public AllStatic {
 public:
  // Load the operands from rdx and rax into xmm0 and xmm1, as doubles.
  // If the operands are not both numbers, jump to not_numbers.
  // Leaves rdx and rax unchanged.  SmiOperands assumes both are smis.
  // NumberOperands assumes both are smis or heap numbers.
  static void LoadSSE2SmiOperands(MacroAssembler* masm);
  static void LoadSSE2NumberOperands(MacroAssembler* masm);
  static void LoadSSE2UnknownOperands(MacroAssembler* masm,
                                      Label* not_numbers);

  // Takes the operands in rdx and rax and loads them as integers in rax
  // and rcx.
  static void LoadAsIntegers(MacroAssembler* masm,
                             Label* operand_conversion_failure,
                             Register heap_number_map);
  // As above, but we know the operands to be numbers. In that case,
  // conversion can't fail.
  static void LoadNumbersAsIntegers(MacroAssembler* masm);

  // Tries to convert two values to smis losslessly.
  // This fails if either argument is not a Smi nor a HeapNumber,
  // or if it's a HeapNumber with a value that can't be converted
  // losslessly to a Smi. In that case, control transitions to the
  // on_not_smis label.
  // On success, either control goes to the on_success label (if one is
  // provided), or it falls through at the end of the code (if on_success
  // is NULL).
  // On success, both first and second holds Smi tagged values.
  // One of first or second must be non-Smi when entering.
  static void NumbersToSmis(MacroAssembler* masm,
                            Register first,
                            Register second,
                            Register scratch1,
                            Register scratch2,
                            Register scratch3,
                            Label* on_success,
                            Label* on_not_smis);
};


Handle<Code> GetTypeRecordingBinaryOpStub(int key,
    TRBinaryOpIC::TypeInfo type_info,
    TRBinaryOpIC::TypeInfo result_type_info) {
  TypeRecordingBinaryOpStub stub(key, type_info, result_type_info);
  return stub.GetCode();
}


void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
  __ pop(rcx);  // Save return address.
  __ push(rdx);
  __ push(rax);
  // Left and right arguments are now on top.
  // Push this stub's key. Although the operation and the type info are
  // encoded into the key, the encoding is opaque, so push them too.
  __ Push(Smi::FromInt(MinorKey()));
  __ Push(Smi::FromInt(op_));
  __ Push(Smi::FromInt(operands_type_));

  __ push(rcx);  // Push return address.

  // Patch the caller to an appropriate specialized stub and return the
  // operation result to the caller of the stub.
  __ TailCallExternalReference(
      ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
                        masm->isolate()),
      5,
      1);
}


void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
  switch (operands_type_) {
    case TRBinaryOpIC::UNINITIALIZED:
      GenerateTypeTransition(masm);
      break;
    case TRBinaryOpIC::SMI:
      GenerateSmiStub(masm);
      break;
    case TRBinaryOpIC::INT32:
      UNREACHABLE();
      // The int32 case is identical to the Smi case.  We avoid creating this
      // ic state on x64.
      break;
    case TRBinaryOpIC::HEAP_NUMBER:
      GenerateHeapNumberStub(masm);
      break;
    case TRBinaryOpIC::ODDBALL:
      GenerateOddballStub(masm);
      break;
    case TRBinaryOpIC::BOTH_STRING:
      GenerateBothStringStub(masm);
      break;
    case TRBinaryOpIC::STRING:
      GenerateStringStub(masm);
      break;
    case TRBinaryOpIC::GENERIC:
      GenerateGeneric(masm);
      break;
    default:
      UNREACHABLE();
  }
}


const char* TypeRecordingBinaryOpStub::GetName() {
  if (name_ != NULL) return name_;
  const int kMaxNameLength = 100;
  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
      kMaxNameLength);
  if (name_ == NULL) return "OOM";
  const char* op_name = Token::Name(op_);
  const char* overwrite_name;
  switch (mode_) {
    case NO_OVERWRITE: overwrite_name = "Alloc"; break;
    case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
    case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
    default: overwrite_name = "UnknownOverwrite"; break;
  }

  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
               "TypeRecordingBinaryOpStub_%s_%s_%s",
               op_name,
               overwrite_name,
               TRBinaryOpIC::GetName(operands_type_));
  return name_;
}


void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
    Label* slow,
    SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {

  // Arguments to TypeRecordingBinaryOpStub are in rdx and rax.
  Register left = rdx;
  Register right = rax;

  // We only generate heapnumber answers for overflowing calculations
  // for the four basic arithmetic operations and logical right shift by 0.
  bool generate_inline_heapnumber_results =
      (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) &&
      (op_ == Token::ADD || op_ == Token::SUB ||
       op_ == Token::MUL || op_ == Token::DIV || op_ == Token::SHR);

  // Smi check of both operands.  If op is BIT_OR, the check is delayed
  // until after the OR operation.
  Label not_smis;
  Label use_fp_on_smis;
  Label fail;

  if (op_ != Token::BIT_OR) {
    Comment smi_check_comment(masm, "-- Smi check arguments");
    __ JumpIfNotBothSmi(left, right, &not_smis);
  }

  Label smi_values;
  __ bind(&smi_values);
  // Perform the operation.
  Comment perform_smi(masm, "-- Perform smi operation");
  switch (op_) {
    case Token::ADD:
      ASSERT(right.is(rax));
      __ SmiAdd(right, right, left, &use_fp_on_smis);  // ADD is commutative.
      break;

    case Token::SUB:
      __ SmiSub(left, left, right, &use_fp_on_smis);
      __ movq(rax, left);
      break;

    case Token::MUL:
      ASSERT(right.is(rax));
      __ SmiMul(right, right, left, &use_fp_on_smis);  // MUL is commutative.
      break;

    case Token::DIV:
      // SmiDiv will not accept left in rdx or right in rax.
      left = rcx;
      right = rbx;
      __ movq(rbx, rax);
      __ movq(rcx, rdx);
      __ SmiDiv(rax, left, right, &use_fp_on_smis);
      break;

    case Token::MOD:
      // SmiMod will not accept left in rdx or right in rax.
      left = rcx;
      right = rbx;
      __ movq(rbx, rax);
      __ movq(rcx, rdx);
      __ SmiMod(rax, left, right, &use_fp_on_smis);
      break;

    case Token::BIT_OR: {
      ASSERT(right.is(rax));
      __ SmiOrIfSmis(right, right, left, &not_smis);  // BIT_OR is commutative.
      break;
      }
    case Token::BIT_XOR:
      ASSERT(right.is(rax));
      __ SmiXor(right, right, left);  // BIT_XOR is commutative.
      break;

    case Token::BIT_AND:
      ASSERT(right.is(rax));
      __ SmiAnd(right, right, left);  // BIT_AND is commutative.
      break;

    case Token::SHL:
      __ SmiShiftLeft(left, left, right);
      __ movq(rax, left);
      break;

    case Token::SAR:
      __ SmiShiftArithmeticRight(left, left, right);
      __ movq(rax, left);
      break;

    case Token::SHR:
      __ SmiShiftLogicalRight(left, left, right, &use_fp_on_smis);
      __ movq(rax, left);
      break;

    default:
      UNREACHABLE();
  }

  // 5. Emit return of result in rax.  Some operations have registers pushed.
  __ ret(0);

  if (use_fp_on_smis.is_linked()) {
    // 6. For some operations emit inline code to perform floating point
    //    operations on known smis (e.g., if the result of the operation
    //    overflowed the smi range).
    __ bind(&use_fp_on_smis);
    if (op_ == Token::DIV || op_ == Token::MOD) {
      // Restore left and right to rdx and rax.
      __ movq(rdx, rcx);
      __ movq(rax, rbx);
    }

    if (generate_inline_heapnumber_results) {
      __ AllocateHeapNumber(rcx, rbx, slow);
      Comment perform_float(masm, "-- Perform float operation on smis");
      if (op_ == Token::SHR) {
        __ SmiToInteger32(left, left);
        __ cvtqsi2sd(xmm0, left);
      } else {
        FloatingPointHelper::LoadSSE2SmiOperands(masm);
        switch (op_) {
        case Token::ADD: __ addsd(xmm0, xmm1); break;
        case Token::SUB: __ subsd(xmm0, xmm1); break;
        case Token::MUL: __ mulsd(xmm0, xmm1); break;
        case Token::DIV: __ divsd(xmm0, xmm1); break;
        default: UNREACHABLE();
        }
      }
      __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
      __ movq(rax, rcx);
      __ ret(0);
    } else {
      __ jmp(&fail);
    }
  }

  // 7. Non-smi operands reach the end of the code generated by
  //    GenerateSmiCode, and fall through to subsequent code,
  //    with the operands in rdx and rax.
  //    But first we check if non-smi values are HeapNumbers holding
  //    values that could be smi.
  __ bind(&not_smis);
  Comment done_comment(masm, "-- Enter non-smi code");
  FloatingPointHelper::NumbersToSmis(masm, left, right, rbx, rdi, rcx,
                                     &smi_values, &fail);
  __ jmp(&smi_values);
  __ bind(&fail);
}


void TypeRecordingBinaryOpStub::GenerateFloatingPointCode(
    MacroAssembler* masm,
    Label* allocation_failure,
    Label* non_numeric_failure) {
  switch (op_) {
    case Token::ADD:
    case Token::SUB:
    case Token::MUL:
    case Token::DIV: {
      FloatingPointHelper::LoadSSE2UnknownOperands(masm, non_numeric_failure);

      switch (op_) {
        case Token::ADD: __ addsd(xmm0, xmm1); break;
        case Token::SUB: __ subsd(xmm0, xmm1); break;
        case Token::MUL: __ mulsd(xmm0, xmm1); break;
        case Token::DIV: __ divsd(xmm0, xmm1); break;
        default: UNREACHABLE();
      }
      GenerateHeapResultAllocation(masm, allocation_failure);
      __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
      __ ret(0);
      break;
    }
    case Token::MOD: {
      // For MOD we jump to the allocation_failure label, to call runtime.
      __ jmp(allocation_failure);
      break;
    }
    case Token::BIT_OR:
    case Token::BIT_AND:
    case Token::BIT_XOR:
    case Token::SAR:
    case Token::SHL:
    case Token::SHR: {
      Label non_smi_shr_result;
      Register heap_number_map = r9;
      __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
      FloatingPointHelper::LoadAsIntegers(masm, non_numeric_failure,
                                          heap_number_map);
      switch (op_) {
        case Token::BIT_OR:  __ orl(rax, rcx); break;
        case Token::BIT_AND: __ andl(rax, rcx); break;
        case Token::BIT_XOR: __ xorl(rax, rcx); break;
        case Token::SAR: __ sarl_cl(rax); break;
        case Token::SHL: __ shll_cl(rax); break;
        case Token::SHR: {
          __ shrl_cl(rax);
          // Check if result is negative. This can only happen for a shift
          // by zero.
          __ testl(rax, rax);
          __ j(negative, &non_smi_shr_result);
          break;
        }
        default: UNREACHABLE();
      }
      STATIC_ASSERT(kSmiValueSize == 32);
      // Tag smi result and return.
      __ Integer32ToSmi(rax, rax);
      __ Ret();

      // Logical shift right can produce an unsigned int32 that is not
      // an int32, and so is not in the smi range.  Allocate a heap number
      // in that case.
      if (op_ == Token::SHR) {
        __ bind(&non_smi_shr_result);
        Label allocation_failed;
        __ movl(rbx, rax);  // rbx holds result value (uint32 value as int64).
        // Allocate heap number in new space.
        // Not using AllocateHeapNumber macro in order to reuse
        // already loaded heap_number_map.
        __ AllocateInNewSpace(HeapNumber::kSize,
                              rax,
                              rcx,
                              no_reg,
                              &allocation_failed,
                              TAG_OBJECT);
        // Set the map.
        if (FLAG_debug_code) {
          __ AbortIfNotRootValue(heap_number_map,
                                 Heap::kHeapNumberMapRootIndex,
                                 "HeapNumberMap register clobbered.");
        }
        __ movq(FieldOperand(rax, HeapObject::kMapOffset),
                heap_number_map);
        __ cvtqsi2sd(xmm0, rbx);
        __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
        __ Ret();

        __ bind(&allocation_failed);
        // We need tagged values in rdx and rax for the following code,
        // not int32 in rax and rcx.
        __ Integer32ToSmi(rax, rcx);
        __ Integer32ToSmi(rdx, rax);
        __ jmp(allocation_failure);
      }
      break;
    }
    default: UNREACHABLE(); break;
  }
  // No fall-through from this generated code.
  if (FLAG_debug_code) {
    __ Abort("Unexpected fall-through in "
             "TypeRecordingBinaryStub::GenerateFloatingPointCode.");
  }
}


void TypeRecordingBinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) {
  ASSERT(op_ == Token::ADD);
  NearLabel left_not_string, call_runtime;

  // Registers containing left and right operands respectively.
  Register left = rdx;
  Register right = rax;

  // Test if left operand is a string.
  __ JumpIfSmi(left, &left_not_string);
  __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx);
  __ j(above_equal, &left_not_string);
  StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
  GenerateRegisterArgsPush(masm);
  __ TailCallStub(&string_add_left_stub);

  // Left operand is not a string, test right.
  __ bind(&left_not_string);
  __ JumpIfSmi(right, &call_runtime);
  __ CmpObjectType(right, FIRST_NONSTRING_TYPE, rcx);
  __ j(above_equal, &call_runtime);

  StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
  GenerateRegisterArgsPush(masm);
  __ TailCallStub(&string_add_right_stub);

  // Neither argument is a string.
  __ bind(&call_runtime);
}


void TypeRecordingBinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) {
  GenerateRegisterArgsPush(masm);
  switch (op_) {
    case Token::ADD:
      __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
      break;
    case Token::SUB:
      __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
      break;
    case Token::MUL:
      __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
      break;
    case Token::DIV:
      __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
      break;
    case Token::MOD:
      __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
      break;
    case Token::BIT_OR:
      __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
      break;
    case Token::BIT_AND:
      __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
      break;
    case Token::BIT_XOR:
      __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
      break;
    case Token::SAR:
      __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
      break;
    case Token::SHL:
      __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
      break;
    case Token::SHR:
      __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
      break;
    default:
      UNREACHABLE();
  }
}


void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
  Label call_runtime;
  if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
      result_type_ == TRBinaryOpIC::SMI) {
    // Only allow smi results.
    GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS);
  } else {
    // Allow heap number result and don't make a transition if a heap number
    // cannot be allocated.
    GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
  }

  // Code falls through if the result is not returned as either a smi or heap
  // number.
  GenerateTypeTransition(masm);

  if (call_runtime.is_linked()) {
    __ bind(&call_runtime);
    GenerateCallRuntimeCode(masm);
  }
}


void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
  ASSERT(operands_type_ == TRBinaryOpIC::STRING);
  ASSERT(op_ == Token::ADD);
  GenerateStringAddCode(masm);
  // Try to add arguments as strings, otherwise, transition to the generic
  // TRBinaryOpIC type.
  GenerateTypeTransition(masm);
}


void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
  Label call_runtime;
  ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
  ASSERT(op_ == Token::ADD);
  // If both arguments are strings, call the string add stub.
  // Otherwise, do a transition.

  // Registers containing left and right operands respectively.
  Register left = rdx;
  Register right = rax;

  // Test if left operand is a string.
  __ JumpIfSmi(left, &call_runtime);
  __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx);
  __ j(above_equal, &call_runtime);

  // Test if right operand is a string.
  __ JumpIfSmi(right, &call_runtime);
  __ CmpObjectType(right, FIRST_NONSTRING_TYPE, rcx);
  __ j(above_equal, &call_runtime);

  StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
  GenerateRegisterArgsPush(masm);
  __ TailCallStub(&string_add_stub);

  __ bind(&call_runtime);
  GenerateTypeTransition(masm);
}


void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
  Label call_runtime;

  if (op_ == Token::ADD) {
    // Handle string addition here, because it is the only operation
    // that does not do a ToNumber conversion on the operands.
    GenerateStringAddCode(masm);
  }

  // Convert oddball arguments to numbers.
  NearLabel check, done;
  __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
  __ j(not_equal, &check);
  if (Token::IsBitOp(op_)) {
    __ xor_(rdx, rdx);
  } else {
    __ LoadRoot(rdx, Heap::kNanValueRootIndex);
  }
  __ jmp(&done);
  __ bind(&check);
  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
  __ j(not_equal, &done);
  if (Token::IsBitOp(op_)) {
    __ xor_(rax, rax);
  } else {
    __ LoadRoot(rax, Heap::kNanValueRootIndex);
  }
  __ bind(&done);

  GenerateHeapNumberStub(masm);
}


void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
  Label gc_required, not_number;
  GenerateFloatingPointCode(masm, &gc_required, &not_number);

  __ bind(&not_number);
  GenerateTypeTransition(masm);

  __ bind(&gc_required);
  GenerateCallRuntimeCode(masm);
}


void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
  Label call_runtime, call_string_add_or_runtime;

  GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);

  GenerateFloatingPointCode(masm, &call_runtime, &call_string_add_or_runtime);

  __ bind(&call_string_add_or_runtime);
  if (op_ == Token::ADD) {
    GenerateStringAddCode(masm);
  }

  __ bind(&call_runtime);
  GenerateCallRuntimeCode(masm);
}


void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
    MacroAssembler* masm,
    Label* alloc_failure) {
  Label skip_allocation;
  OverwriteMode mode = mode_;
  switch (mode) {
    case OVERWRITE_LEFT: {
      // If the argument in rdx is already an object, we skip the
      // allocation of a heap number.
      __ JumpIfNotSmi(rdx, &skip_allocation);
      // Allocate a heap number for the result. Keep eax and edx intact
      // for the possible runtime call.
      __ AllocateHeapNumber(rbx, rcx, alloc_failure);
      // Now rdx can be overwritten losing one of the arguments as we are
      // now done and will not need it any more.
      __ movq(rdx, rbx);
      __ bind(&skip_allocation);
      // Use object in rdx as a result holder
      __ movq(rax, rdx);
      break;
    }
    case OVERWRITE_RIGHT:
      // If the argument in rax is already an object, we skip the
      // allocation of a heap number.
      __ JumpIfNotSmi(rax, &skip_allocation);
      // Fall through!
    case NO_OVERWRITE:
      // Allocate a heap number for the result. Keep rax and rdx intact
      // for the possible runtime call.
      __ AllocateHeapNumber(rbx, rcx, alloc_failure);
      // Now rax can be overwritten losing one of the arguments as we are
      // now done and will not need it any more.
      __ movq(rax, rbx);
      __ bind(&skip_allocation);
      break;
    default: UNREACHABLE();
  }
}


void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
  __ pop(rcx);
  __ push(rdx);
  __ push(rax);
  __ push(rcx);
}


void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
  // TAGGED case:
  //   Input:
  //     rsp[8]: argument (should be number).
  //     rsp[0]: return address.
  //   Output:
  //     rax: tagged double result.
  // UNTAGGED case:
  //   Input::
  //     rsp[0]: return address.
  //     xmm1: untagged double input argument
  //   Output:
  //     xmm1: untagged double result.

  Label runtime_call;
  Label runtime_call_clear_stack;
  Label skip_cache;
  const bool tagged = (argument_type_ == TAGGED);
  if (tagged) {
    NearLabel input_not_smi;
    NearLabel loaded;
    // Test that rax is a number.
    __ movq(rax, Operand(rsp, kPointerSize));
    __ JumpIfNotSmi(rax, &input_not_smi);
    // Input is a smi. Untag and load it onto the FPU stack.
    // Then load the bits of the double into rbx.
    __ SmiToInteger32(rax, rax);
    __ subq(rsp, Immediate(kDoubleSize));
    __ cvtlsi2sd(xmm1, rax);
    __ movsd(Operand(rsp, 0), xmm1);
    __ movq(rbx, xmm1);
    __ movq(rdx, xmm1);
    __ fld_d(Operand(rsp, 0));
    __ addq(rsp, Immediate(kDoubleSize));
    __ jmp(&loaded);

    __ bind(&input_not_smi);
    // Check if input is a HeapNumber.
    __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
    __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
    __ j(not_equal, &runtime_call);
    // Input is a HeapNumber. Push it on the FPU stack and load its
    // bits into rbx.
    __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
    __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
    __ movq(rdx, rbx);

    __ bind(&loaded);
  } else {  // UNTAGGED.
    __ movq(rbx, xmm1);
    __ movq(rdx, xmm1);
  }

  // ST[0] == double value, if TAGGED.
  // rbx = bits of double value.
  // rdx = also bits of double value.
  // Compute hash (h is 32 bits, bits are 64 and the shifts are arithmetic):
  //   h = h0 = bits ^ (bits >> 32);
  //   h ^= h >> 16;
  //   h ^= h >> 8;
  //   h = h & (cacheSize - 1);
  // or h = (h0 ^ (h0 >> 8) ^ (h0 >> 16) ^ (h0 >> 24)) & (cacheSize - 1)
  __ sar(rdx, Immediate(32));
  __ xorl(rdx, rbx);
  __ movl(rcx, rdx);
  __ movl(rax, rdx);
  __ movl(rdi, rdx);
  __ sarl(rdx, Immediate(8));
  __ sarl(rcx, Immediate(16));
  __ sarl(rax, Immediate(24));
  __ xorl(rcx, rdx);
  __ xorl(rax, rdi);
  __ xorl(rcx, rax);
  ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
  __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));

  // ST[0] == double value.
  // rbx = bits of double value.
  // rcx = TranscendentalCache::hash(double value).
  ExternalReference cache_array =
      ExternalReference::transcendental_cache_array_address(masm->isolate());
  __ movq(rax, cache_array);
  int cache_array_index =
      type_ * sizeof(Isolate::Current()->transcendental_cache()->caches_[0]);
  __ movq(rax, Operand(rax, cache_array_index));
  // rax points to the cache for the type type_.
  // If NULL, the cache hasn't been initialized yet, so go through runtime.
  __ testq(rax, rax);
  __ j(zero, &runtime_call_clear_stack);  // Only clears stack if TAGGED.
#ifdef DEBUG
  // Check that the layout of cache elements match expectations.
  {  // NOLINT - doesn't like a single brace on a line.
    TranscendentalCache::SubCache::Element test_elem[2];
    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
    char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
    char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
    // Two uint_32's and a pointer per element.
    CHECK_EQ(16, static_cast<int>(elem2_start - elem_start));
    CHECK_EQ(0, static_cast<int>(elem_in0 - elem_start));
    CHECK_EQ(kIntSize, static_cast<int>(elem_in1 - elem_start));
    CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start));
  }
#endif
  // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16].
  __ addl(rcx, rcx);
  __ lea(rcx, Operand(rax, rcx, times_8, 0));
  // Check if cache matches: Double value is stored in uint32_t[2] array.
  NearLabel cache_miss;
  __ cmpq(rbx, Operand(rcx, 0));
  __ j(not_equal, &cache_miss);
  // Cache hit!
  __ movq(rax, Operand(rcx, 2 * kIntSize));
  if (tagged) {
    __ fstp(0);  // Clear FPU stack.
    __ ret(kPointerSize);
  } else {  // UNTAGGED.
    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
    __ Ret();
  }

  __ bind(&cache_miss);
  // Update cache with new value.
  if (tagged) {
  __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack);
  } else {  // UNTAGGED.
    __ AllocateHeapNumber(rax, rdi, &skip_cache);
    __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1);
    __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
  }
  GenerateOperation(masm);
  __ movq(Operand(rcx, 0), rbx);
  __ movq(Operand(rcx, 2 * kIntSize), rax);
  __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
  if (tagged) {
    __ ret(kPointerSize);
  } else {  // UNTAGGED.
    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
    __ Ret();

    // Skip cache and return answer directly, only in untagged case.
    __ bind(&skip_cache);
    __ subq(rsp, Immediate(kDoubleSize));
    __ movsd(Operand(rsp, 0), xmm1);
    __ fld_d(Operand(rsp, 0));
    GenerateOperation(masm);
    __ fstp_d(Operand(rsp, 0));
    __ movsd(xmm1, Operand(rsp, 0));
    __ addq(rsp, Immediate(kDoubleSize));
    // We return the value in xmm1 without adding it to the cache, but
    // we cause a scavenging GC so that future allocations will succeed.
    __ EnterInternalFrame();
    // Allocate an unused object bigger than a HeapNumber.
    __ Push(Smi::FromInt(2 * kDoubleSize));
    __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
    __ LeaveInternalFrame();
    __ Ret();
  }

  // Call runtime, doing whatever allocation and cleanup is necessary.
  if (tagged) {
    __ bind(&runtime_call_clear_stack);
    __ fstp(0);
    __ bind(&runtime_call);
    __ TailCallExternalReference(
        ExternalReference(RuntimeFunction(), masm->isolate()), 1, 1);
  } else {  // UNTAGGED.
    __ bind(&runtime_call_clear_stack);
    __ bind(&runtime_call);
    __ AllocateHeapNumber(rax, rdi, &skip_cache);
    __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1);
    __ EnterInternalFrame();
    __ push(rax);
    __ CallRuntime(RuntimeFunction(), 1);
    __ LeaveInternalFrame();
    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
    __ Ret();
  }
}


Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
  switch (type_) {
    // Add more cases when necessary.
    case TranscendentalCache::SIN: return Runtime::kMath_sin;
    case TranscendentalCache::COS: return Runtime::kMath_cos;
    case TranscendentalCache::LOG: return Runtime::kMath_log;
    default:
      UNIMPLEMENTED();
      return Runtime::kAbort;
  }
}


void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
  // Registers:
  // rax: Newly allocated HeapNumber, which must be preserved.
  // rbx: Bits of input double. Must be preserved.
  // rcx: Pointer to cache entry. Must be preserved.
  // st(0): Input double
  Label done;
  if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
    // Both fsin and fcos require arguments in the range +/-2^63 and
    // return NaN for infinities and NaN. They can share all code except
    // the actual fsin/fcos operation.
    Label in_range;
    // If argument is outside the range -2^63..2^63, fsin/cos doesn't
    // work. We must reduce it to the appropriate range.
    __ movq(rdi, rbx);
    // Move exponent and sign bits to low bits.
    __ shr(rdi, Immediate(HeapNumber::kMantissaBits));
    // Remove sign bit.
    __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1));
    int supported_exponent_limit = (63 + HeapNumber::kExponentBias);
    __ cmpl(rdi, Immediate(supported_exponent_limit));
    __ j(below, &in_range);
    // Check for infinity and NaN. Both return NaN for sin.
    __ cmpl(rdi, Immediate(0x7ff));
    NearLabel non_nan_result;
    __ j(not_equal, &non_nan_result);
    // Input is +/-Infinity or NaN. Result is NaN.
    __ fstp(0);
    __ LoadRoot(kScratchRegister, Heap::kNanValueRootIndex);
    __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset));
    __ jmp(&done);

    __ bind(&non_nan_result);

    // Use fpmod to restrict argument to the range +/-2*PI.
    __ movq(rdi, rax);  // Save rax before using fnstsw_ax.
    __ fldpi();
    __ fadd(0);
    __ fld(1);
    // FPU Stack: input, 2*pi, input.
    {
      Label no_exceptions;
      __ fwait();
      __ fnstsw_ax();
      // Clear if Illegal Operand or Zero Division exceptions are set.
      __ testl(rax, Immediate(5));  // #IO and #ZD flags of FPU status word.
      __ j(zero, &no_exceptions);
      __ fnclex();
      __ bind(&no_exceptions);
    }

    // Compute st(0) % st(1)
    {
      NearLabel partial_remainder_loop;
      __ bind(&partial_remainder_loop);
      __ fprem1();
      __ fwait();
      __ fnstsw_ax();
      __ testl(rax, Immediate(0x400));  // Check C2 bit of FPU status word.
      // If C2 is set, computation only has partial result. Loop to
      // continue computation.
      __ j(not_zero, &partial_remainder_loop);
  }
    // FPU Stack: input, 2*pi, input % 2*pi
    __ fstp(2);
    // FPU Stack: input % 2*pi, 2*pi,
    __ fstp(0);
    // FPU Stack: input % 2*pi
    __ movq(rax, rdi);  // Restore rax, pointer to the new HeapNumber.
    __ bind(&in_range);
    switch (type_) {
      case TranscendentalCache::SIN:
        __ fsin();
        break;
      case TranscendentalCache::COS:
        __ fcos();
        break;
      default:
        UNREACHABLE();
    }
    __ bind(&done);
  } else {
    ASSERT(type_ == TranscendentalCache::LOG);
    __ fldln2();
    __ fxch();
    __ fyl2x();
  }
}


// Get the integer part of a heap number.
// Overwrites the contents of rdi, rbx and rcx. Result cannot be rdi or rbx.
void IntegerConvert(MacroAssembler* masm,
                    Register result,
                    Register source) {
  // Result may be rcx. If result and source are the same register, source will
  // be overwritten.
  ASSERT(!result.is(rdi) && !result.is(rbx));
  // TODO(lrn): When type info reaches here, if value is a 32-bit integer, use
  // cvttsd2si (32-bit version) directly.
  Register double_exponent = rbx;
  Register double_value = rdi;
  NearLabel done, exponent_63_plus;
  // Get double and extract exponent.
  __ movq(double_value, FieldOperand(source, HeapNumber::kValueOffset));
  // Clear result preemptively, in case we need to return zero.
  __ xorl(result, result);
  __ movq(xmm0, double_value);  // Save copy in xmm0 in case we need it there.
  // Double to remove sign bit, shift exponent down to least significant bits.
  // and subtract bias to get the unshifted, unbiased exponent.
  __ lea(double_exponent, Operand(double_value, double_value, times_1, 0));
  __ shr(double_exponent, Immediate(64 - HeapNumber::kExponentBits));
  __ subl(double_exponent, Immediate(HeapNumber::kExponentBias));
  // Check whether the exponent is too big for a 63 bit unsigned integer.
  __ cmpl(double_exponent, Immediate(63));
  __ j(above_equal, &exponent_63_plus);
  // Handle exponent range 0..62.
  __ cvttsd2siq(result, xmm0);
  __ jmp(&done);

  __ bind(&exponent_63_plus);
  // Exponent negative or 63+.
  __ cmpl(double_exponent, Immediate(83));
  // If exponent negative or above 83, number contains no significant bits in
  // the range 0..2^31, so result is zero, and rcx already holds zero.
  __ j(above, &done);

  // Exponent in rage 63..83.
  // Mantissa * 2^exponent contains bits in the range 2^0..2^31, namely
  // the least significant exponent-52 bits.

  // Negate low bits of mantissa if value is negative.
  __ addq(double_value, double_value);  // Move sign bit to carry.
  __ sbbl(result, result);  // And convert carry to -1 in result register.
  // if scratch2 is negative, do (scratch2-1)^-1, otherwise (scratch2-0)^0.
  __ addl(double_value, result);
  // Do xor in opposite directions depending on where we want the result
  // (depending on whether result is rcx or not).

  if (result.is(rcx)) {
    __ xorl(double_value, result);
    // Left shift mantissa by (exponent - mantissabits - 1) to save the
    // bits that have positional values below 2^32 (the extra -1 comes from the
    // doubling done above to move the sign bit into the carry flag).
    __ leal(rcx, Operand(double_exponent, -HeapNumber::kMantissaBits - 1));
    __ shll_cl(double_value);
    __ movl(result, double_value);
  } else {
    // As the then-branch, but move double-value to result before shifting.
    __ xorl(result, double_value);
    __ leal(rcx, Operand(double_exponent, -HeapNumber::kMantissaBits - 1));
    __ shll_cl(result);
  }

  __ bind(&done);
}


// Input: rdx, rax are the left and right objects of a bit op.
// Output: rax, rcx are left and right integers for a bit op.
void FloatingPointHelper::LoadNumbersAsIntegers(MacroAssembler* masm) {
  // Check float operands.
  Label done;
  Label rax_is_smi;
  Label rax_is_object;
  Label rdx_is_object;

  __ JumpIfNotSmi(rdx, &rdx_is_object);
  __ SmiToInteger32(rdx, rdx);
  __ JumpIfSmi(rax, &rax_is_smi);

  __ bind(&rax_is_object);
  IntegerConvert(masm, rcx, rax);  // Uses rdi, rcx and rbx.
  __ jmp(&done);

  __ bind(&rdx_is_object);
  IntegerConvert(masm, rdx, rdx);  // Uses rdi, rcx and rbx.
  __ JumpIfNotSmi(rax, &rax_is_object);
  __ bind(&rax_is_smi);
  __ SmiToInteger32(rcx, rax);

  __ bind(&done);
  __ movl(rax, rdx);
}


// Input: rdx, rax are the left and right objects of a bit op.
// Output: rax, rcx are left and right integers for a bit op.
// Jump to conversion_failure: rdx and rax are unchanged.
void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
                                         Label* conversion_failure,
                                         Register heap_number_map) {
  // Check float operands.
  Label arg1_is_object, check_undefined_arg1;
  Label arg2_is_object, check_undefined_arg2;
  Label load_arg2, done;

  __ JumpIfNotSmi(rdx, &arg1_is_object);
  __ SmiToInteger32(r8, rdx);
  __ jmp(&load_arg2);

  // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
  __ bind(&check_undefined_arg1);
  __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
  __ j(not_equal, conversion_failure);
  __ Set(r8, 0);
  __ jmp(&load_arg2);

  __ bind(&arg1_is_object);
  __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map);
  __ j(not_equal, &check_undefined_arg1);
  // Get the untagged integer version of the rdx heap number in rcx.
  IntegerConvert(masm, r8, rdx);

  // Here r8 has the untagged integer, rax has a Smi or a heap number.
  __ bind(&load_arg2);
  // Test if arg2 is a Smi.
  __ JumpIfNotSmi(rax, &arg2_is_object);
  __ SmiToInteger32(rcx, rax);
  __ jmp(&done);

  // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
  __ bind(&check_undefined_arg2);
  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
  __ j(not_equal, conversion_failure);
  __ Set(rcx, 0);
  __ jmp(&done);

  __ bind(&arg2_is_object);
  __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map);
  __ j(not_equal, &check_undefined_arg2);
  // Get the untagged integer version of the rax heap number in rcx.
  IntegerConvert(masm, rcx, rax);
  __ bind(&done);
  __ movl(rax, r8);
}


void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
  __ SmiToInteger32(kScratchRegister, rdx);
  __ cvtlsi2sd(xmm0, kScratchRegister);
  __ SmiToInteger32(kScratchRegister, rax);
  __ cvtlsi2sd(xmm1, kScratchRegister);
}


void FloatingPointHelper::LoadSSE2NumberOperands(MacroAssembler* masm) {
  Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, done;
  // Load operand in rdx into xmm0.
  __ JumpIfSmi(rdx, &load_smi_rdx);
  __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
  // Load operand in rax into xmm1.
  __ JumpIfSmi(rax, &load_smi_rax);
  __ bind(&load_nonsmi_rax);
  __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
  __ jmp(&done);

  __ bind(&load_smi_rdx);
  __ SmiToInteger32(kScratchRegister, rdx);
  __ cvtlsi2sd(xmm0, kScratchRegister);
  __ JumpIfNotSmi(rax, &load_nonsmi_rax);

  __ bind(&load_smi_rax);
  __ SmiToInteger32(kScratchRegister, rax);
  __ cvtlsi2sd(xmm1, kScratchRegister);

  __ bind(&done);
}


void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
                                                  Label* not_numbers) {
  Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done;
  // Load operand in rdx into xmm0, or branch to not_numbers.
  __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex);
  __ JumpIfSmi(rdx, &load_smi_rdx);
  __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), rcx);
  __ j(not_equal, not_numbers);  // Argument in rdx is not a number.
  __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
  // Load operand in rax into xmm1, or branch to not_numbers.
  __ JumpIfSmi(rax, &load_smi_rax);

  __ bind(&load_nonsmi_rax);
  __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), rcx);
  __ j(not_equal, not_numbers);
  __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
  __ jmp(&done);

  __ bind(&load_smi_rdx);
  __ SmiToInteger32(kScratchRegister, rdx);
  __ cvtlsi2sd(xmm0, kScratchRegister);
  __ JumpIfNotSmi(rax, &load_nonsmi_rax);

  __ bind(&load_smi_rax);
  __ SmiToInteger32(kScratchRegister, rax);
  __ cvtlsi2sd(xmm1, kScratchRegister);
  __ bind(&done);
}


void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
                                        Register first,
                                        Register second,
                                        Register scratch1,
                                        Register scratch2,
                                        Register scratch3,
                                        Label* on_success,
                                        Label* on_not_smis)   {
  Register heap_number_map = scratch3;
  Register smi_result = scratch1;
  Label done;

  __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);

  NearLabel first_smi, check_second;
  __ JumpIfSmi(first, &first_smi);
  __ cmpq(FieldOperand(first, HeapObject::kMapOffset), heap_number_map);
  __ j(not_equal, on_not_smis);
  // Convert HeapNumber to smi if possible.
  __ movsd(xmm0, FieldOperand(first, HeapNumber::kValueOffset));
  __ movq(scratch2, xmm0);
  __ cvttsd2siq(smi_result, xmm0);
  // Check if conversion was successful by converting back and
  // comparing to the original double's bits.
  __ cvtlsi2sd(xmm1, smi_result);
  __ movq(kScratchRegister, xmm1);
  __ cmpq(scratch2, kScratchRegister);
  __ j(not_equal, on_not_smis);
  __ Integer32ToSmi(first, smi_result);

  __ bind(&check_second);
  __ JumpIfSmi(second, (on_success != NULL) ? on_success : &done);
  __ bind(&first_smi);
  if (FLAG_debug_code) {
    // Second should be non-smi if we get here.
    __ AbortIfSmi(second);
  }
  __ cmpq(FieldOperand(second, HeapObject::kMapOffset), heap_number_map);
  __ j(not_equal, on_not_smis);
  // Convert second to smi, if possible.
  __ movsd(xmm0, FieldOperand(second, HeapNumber::kValueOffset));
  __ movq(scratch2, xmm0);
  __ cvttsd2siq(smi_result, xmm0);
  __ cvtlsi2sd(xmm1, smi_result);
  __ movq(kScratchRegister, xmm1);
  __ cmpq(scratch2, kScratchRegister);
  __ j(not_equal, on_not_smis);
  __ Integer32ToSmi(second, smi_result);
  if (on_success != NULL) {
    __ jmp(on_success);
  } else {
    __ bind(&done);
  }
}


void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
  Label slow, done;

  if (op_ == Token::SUB) {
    if (include_smi_code_) {
      // Check whether the value is a smi.
      Label try_float;
      __ JumpIfNotSmi(rax, &try_float);
      if (negative_zero_ == kIgnoreNegativeZero) {
        __ SmiCompare(rax, Smi::FromInt(0));
        __ j(equal, &done);
      }
      __ SmiNeg(rax, rax, &done);
      __ jmp(&slow);  // zero, if not handled above, and Smi::kMinValue.

      // Try floating point case.
      __ bind(&try_float);
    } else if (FLAG_debug_code) {
      __ AbortIfSmi(rax);
    }

    __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
                   Heap::kHeapNumberMapRootIndex);
    __ j(not_equal, &slow);
    // Operand is a float, negate its value by flipping sign bit.
    __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
    __ Set(kScratchRegister, 0x01);
    __ shl(kScratchRegister, Immediate(63));
    __ xor_(rdx, kScratchRegister);  // Flip sign.
    // rdx is value to store.
    if (overwrite_ == UNARY_OVERWRITE) {
      __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
    } else {
      __ AllocateHeapNumber(rcx, rbx, &slow);
      // rcx: allocated 'empty' number
      __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
      __ movq(rax, rcx);
    }
  } else if (op_ == Token::BIT_NOT) {
    if (include_smi_code_) {
      Label try_float;
      __ JumpIfNotSmi(rax, &try_float);
      __ SmiNot(rax, rax);
      __ jmp(&done);
      // Try floating point case.
      __ bind(&try_float);
    } else if (FLAG_debug_code) {
      __ AbortIfSmi(rax);
    }

    // Check if the operand is a heap number.
    __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
                   Heap::kHeapNumberMapRootIndex);
    __ j(not_equal, &slow);

    // Convert the heap number in rax to an untagged integer in rcx.
    IntegerConvert(masm, rax, rax);

    // Do the bitwise operation and smi tag the result.
    __ notl(rax);
    __ Integer32ToSmi(rax, rax);
  }

  // Return from the stub.
  __ bind(&done);
  __ StubReturn(1);

  // Handle the slow case by jumping to the JavaScript builtin.
  __ bind(&slow);
  __ pop(rcx);  // pop return address
  __ push(rax);
  __ push(rcx);  // push return address
  switch (op_) {
    case Token::SUB:
      __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
      break;
    case Token::BIT_NOT:
      __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
      break;
    default:
      UNREACHABLE();
  }
}


void MathPowStub::Generate(MacroAssembler* masm) {
  // Registers are used as follows:
  // rdx = base
  // rax = exponent
  // rcx = temporary, result

  Label allocate_return, call_runtime;

  // Load input parameters.
  __ movq(rdx, Operand(rsp, 2 * kPointerSize));
  __ movq(rax, Operand(rsp, 1 * kPointerSize));

  // Save 1 in xmm3 - we need this several times later on.
  __ Set(rcx, 1);
  __ cvtlsi2sd(xmm3, rcx);

  Label exponent_nonsmi;
  Label base_nonsmi;
  // If the exponent is a heap number go to that specific case.
  __ JumpIfNotSmi(rax, &exponent_nonsmi);
  __ JumpIfNotSmi(rdx, &base_nonsmi);

  // Optimized version when both exponent and base are smis.
  Label powi;
  __ SmiToInteger32(rdx, rdx);
  __ cvtlsi2sd(xmm0, rdx);
  __ jmp(&powi);
  // Exponent is a smi and base is a heapnumber.
  __ bind(&base_nonsmi);
  __ CompareRoot(FieldOperand(rdx, HeapObject::kMapOffset),
                 Heap::kHeapNumberMapRootIndex);
  __ j(not_equal, &call_runtime);

  __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));

  // Optimized version of pow if exponent is a smi.
  // xmm0 contains the base.
  __ bind(&powi);
  __ SmiToInteger32(rax, rax);

  // Save exponent in base as we need to check if exponent is negative later.
  // We know that base and exponent are in different registers.
  __ movq(rdx, rax);

  // Get absolute value of exponent.
  NearLabel no_neg;
  __ cmpl(rax, Immediate(0));
  __ j(greater_equal, &no_neg);
  __ negl(rax);
  __ bind(&no_neg);

  // Load xmm1 with 1.
  __ movaps(xmm1, xmm3);
  NearLabel while_true;
  NearLabel no_multiply;

  __ bind(&while_true);
  __ shrl(rax, Immediate(1));
  __ j(not_carry, &no_multiply);
  __ mulsd(xmm1, xmm0);
  __ bind(&no_multiply);
  __ mulsd(xmm0, xmm0);
  __ j(not_zero, &while_true);

  // Base has the original value of the exponent - if the exponent  is
  // negative return 1/result.
  __ testl(rdx, rdx);
  __ j(positive, &allocate_return);
  // Special case if xmm1 has reached infinity.
  __ divsd(xmm3, xmm1);
  __ movaps(xmm1, xmm3);
  __ xorps(xmm0, xmm0);
  __ ucomisd(xmm0, xmm1);
  __ j(equal, &call_runtime);

  __ jmp(&allocate_return);

  // Exponent (or both) is a heapnumber - no matter what we should now work
  // on doubles.
  __ bind(&exponent_nonsmi);
  __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
                 Heap::kHeapNumberMapRootIndex);
  __ j(not_equal, &call_runtime);
  __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
  // Test if exponent is nan.
  __ ucomisd(xmm1, xmm1);
  __ j(parity_even, &call_runtime);

  NearLabel base_not_smi;
  NearLabel handle_special_cases;
  __ JumpIfNotSmi(rdx, &base_not_smi);
  __ SmiToInteger32(rdx, rdx);
  __ cvtlsi2sd(xmm0, rdx);
  __ jmp(&handle_special_cases);

  __ bind(&base_not_smi);
  __ CompareRoot(FieldOperand(rdx, HeapObject::kMapOffset),
                 Heap::kHeapNumberMapRootIndex);
  __ j(not_equal, &call_runtime);
  __ movl(rcx, FieldOperand(rdx, HeapNumber::kExponentOffset));
  __ andl(rcx, Immediate(HeapNumber::kExponentMask));
  __ cmpl(rcx, Immediate(HeapNumber::kExponentMask));
  // base is NaN or +/-Infinity
  __ j(greater_equal, &call_runtime);
  __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));

  // base is in xmm0 and exponent is in xmm1.
  __ bind(&handle_special_cases);
  NearLabel not_minus_half;
  // Test for -0.5.
  // Load xmm2 with -0.5.
  __ movq(rcx, V8_UINT64_C(0xBFE0000000000000), RelocInfo::NONE);
  __ movq(xmm2, rcx);
  // xmm2 now has -0.5.
  __ ucomisd(xmm2, xmm1);
  __ j(not_equal, &not_minus_half);

  // Calculates reciprocal of square root.
  // sqrtsd returns -0 when input is -0.  ECMA spec requires +0.
  __ xorps(xmm1, xmm1);
  __ addsd(xmm1, xmm0);
  __ sqrtsd(xmm1, xmm1);
  __ divsd(xmm3, xmm1);
  __ movaps(xmm1, xmm3);
  __ jmp(&allocate_return);

  // Test for 0.5.
  __ bind(&not_minus_half);
  // Load xmm2 with 0.5.
  // Since xmm3 is 1 and xmm2 is -0.5 this is simply xmm2 + xmm3.
  __ addsd(xmm2, xmm3);
  // xmm2 now has 0.5.
  __ ucomisd(xmm2, xmm1);
  __ j(not_equal, &call_runtime);
  // Calculates square root.
  // sqrtsd returns -0 when input is -0.  ECMA spec requires +0.
  __ xorps(xmm1, xmm1);
  __ addsd(xmm1, xmm0);  // Convert -0 to 0.
  __ sqrtsd(xmm1, xmm1);

  __ bind(&allocate_return);
  __ AllocateHeapNumber(rcx, rax, &call_runtime);
  __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm1);
  __ movq(rax, rcx);
  __ ret(2 * kPointerSize);

  __ bind(&call_runtime);
  __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
}


void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
  // The key is in rdx and the parameter count is in rax.

  // The displacement is used for skipping the frame pointer on the
  // stack. It is the offset of the last parameter (if any) relative
  // to the frame pointer.
  static const int kDisplacement = 1 * kPointerSize;

  // Check that the key is a smi.
  Label slow;
  __ JumpIfNotSmi(rdx, &slow);

  // Check if the calling frame is an arguments adaptor frame.  We look at the
  // context offset, and if the frame is not a regular one, then we find a
  // Smi instead of the context.  We can't use SmiCompare here, because that
  // only works for comparing two smis.
  Label adaptor;
  __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
  __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
         Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
  __ j(equal, &adaptor);

  // Check index against formal parameters count limit passed in
  // through register rax. Use unsigned comparison to get negative
  // check for free.
  __ cmpq(rdx, rax);
  __ j(above_equal, &slow);

  // Read the argument from the stack and return it.
  SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
  __ lea(rbx, Operand(rbp, index.reg, index.scale, 0));
  index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2);
  __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement));
  __ Ret();

  // Arguments adaptor case: Check index against actual arguments
  // limit found in the arguments adaptor frame. Use unsigned
  // comparison to get negative check for free.
  __ bind(&adaptor);
  __ movq(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
  __ cmpq(rdx, rcx);
  __ j(above_equal, &slow);

  // Read the argument from the stack and return it.
  index = masm->SmiToIndex(rax, rcx, kPointerSizeLog2);
  __ lea(rbx, Operand(rbx, index.reg, index.scale, 0));
  index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2);
  __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement));
  __ Ret();

  // Slow-case: Handle non-smi or out-of-bounds access to arguments
  // by calling the runtime system.
  __ bind(&slow);
  __ pop(rbx);  // Return address.
  __ push(rdx);
  __ push(rbx);
  __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
}


void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
  // rsp[0] : return address
  // rsp[8] : number of parameters
  // rsp[16] : receiver displacement
  // rsp[24] : function

  // The displacement is used for skipping the return address and the
  // frame pointer on the stack. It is the offset of the last
  // parameter (if any) relative to the frame pointer.
  static const int kDisplacement = 2 * kPointerSize;

  // Check if the calling frame is an arguments adaptor frame.
  Label adaptor_frame, try_allocate, runtime;
  __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
  __ Cmp(Operand(rdx, StandardFrameConstants::kContextOffset),
         Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
  __ j(equal, &adaptor_frame);

  // Get the length from the frame.
  __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
  __ jmp(&try_allocate);

  // Patch the arguments.length and the parameters pointer.
  __ bind(&adaptor_frame);
  __ SmiToInteger32(rcx,
                    Operand(rdx,
                            ArgumentsAdaptorFrameConstants::kLengthOffset));
  // Space on stack must already hold a smi.
  __ Integer32ToSmiField(Operand(rsp, 1 * kPointerSize), rcx);
  // Do not clobber the length index for the indexing operation since
  // it is used compute the size for allocation later.
  __ lea(rdx, Operand(rdx, rcx, times_pointer_size, kDisplacement));
  __ movq(Operand(rsp, 2 * kPointerSize), rdx);

  // Try the new space allocation. Start out with computing the size of
  // the arguments object and the elements array.
  Label add_arguments_object;
  __ bind(&try_allocate);
  __ testl(rcx, rcx);
  __ j(zero, &add_arguments_object);
  __ leal(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
  __ bind(&add_arguments_object);
  __ addl(rcx, Immediate(GetArgumentsObjectSize()));

  // Do the allocation of both objects in one go.
  __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);

  // Get the arguments boilerplate from the current (global) context.
  __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
  __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
  __ movq(rdi, Operand(rdi,
                       Context::SlotOffset(GetArgumentsBoilerplateIndex())));

  // Copy the JS object part.
  STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize);
  __ movq(kScratchRegister, FieldOperand(rdi, 0 * kPointerSize));
  __ movq(rdx, FieldOperand(rdi, 1 * kPointerSize));
  __ movq(rbx, FieldOperand(rdi, 2 * kPointerSize));
  __ movq(FieldOperand(rax, 0 * kPointerSize), kScratchRegister);
  __ movq(FieldOperand(rax, 1 * kPointerSize), rdx);
  __ movq(FieldOperand(rax, 2 * kPointerSize), rbx);

  if (type_ == NEW_NON_STRICT) {
    // Setup the callee in-object property.
    ASSERT(Heap::kArgumentsCalleeIndex == 1);
    __ movq(kScratchRegister, Operand(rsp, 3 * kPointerSize));
    __ movq(FieldOperand(rax, JSObject::kHeaderSize +
                              Heap::kArgumentsCalleeIndex * kPointerSize),
            kScratchRegister);
  }

  // Get the length (smi tagged) and set that as an in-object property too.
  ASSERT(Heap::kArgumentsLengthIndex == 0);
  __ movq(rcx, Operand(rsp, 1 * kPointerSize));
  __ movq(FieldOperand(rax, JSObject::kHeaderSize +
                            Heap::kArgumentsLengthIndex * kPointerSize),
          rcx);

  // If there are no actual arguments, we're done.
  Label done;
  __ SmiTest(rcx);
  __ j(zero, &done);

  // Get the parameters pointer from the stack and untag the length.
  __ movq(rdx, Operand(rsp, 2 * kPointerSize));

  // Setup the elements pointer in the allocated arguments object and
  // initialize the header in the elements fixed array.
  __ lea(rdi, Operand(rax, GetArgumentsObjectSize()));
  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
  __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
  __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
  __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
  __ SmiToInteger32(rcx, rcx);  // Untag length for the loop below.

  // Copy the fixed array slots.
  Label loop;
  __ bind(&loop);
  __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize));  // Skip receiver.
  __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
  __ addq(rdi, Immediate(kPointerSize));
  __ subq(rdx, Immediate(kPointerSize));
  __ decl(rcx);
  __ j(not_zero, &loop);

  // Return and remove the on-stack parameters.
  __ bind(&done);
  __ ret(3 * kPointerSize);

  // Do the runtime call to allocate the arguments object.
  __ bind(&runtime);
  __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
}


void RegExpExecStub::Generate(MacroAssembler* masm) {
  // Just jump directly to runtime if native RegExp is not selected at compile
  // time or if regexp entry in generated code is turned off runtime switch or
  // at compilation.
#ifdef V8_INTERPRETED_REGEXP
  __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
#else  // V8_INTERPRETED_REGEXP
  if (!FLAG_regexp_entry_native) {
    __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
    return;
  }

  // Stack frame on entry.
  //  rsp[0]: return address
  //  rsp[8]: last_match_info (expected JSArray)
  //  rsp[16]: previous index
  //  rsp[24]: subject string
  //  rsp[32]: JSRegExp object

  static const int kLastMatchInfoOffset = 1 * kPointerSize;
  static const int kPreviousIndexOffset = 2 * kPointerSize;
  static const int kSubjectOffset = 3 * kPointerSize;
  static const int kJSRegExpOffset = 4 * kPointerSize;

  Label runtime;
  // Ensure that a RegExp stack is allocated.
  Isolate* isolate = masm->isolate();
  ExternalReference address_of_regexp_stack_memory_address =
      ExternalReference::address_of_regexp_stack_memory_address(isolate);
  ExternalReference address_of_regexp_stack_memory_size =
      ExternalReference::address_of_regexp_stack_memory_size(isolate);
  __ Load(kScratchRegister, address_of_regexp_stack_memory_size);
  __ testq(kScratchRegister, kScratchRegister);
  __ j(zero, &runtime);


  // Check that the first argument is a JSRegExp object.
  __ movq(rax, Operand(rsp, kJSRegExpOffset));
  __ JumpIfSmi(rax, &runtime);
  __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
  __ j(not_equal, &runtime);
  // Check that the RegExp has been compiled (data contains a fixed array).
  __ movq(rax, FieldOperand(rax, JSRegExp::kDataOffset));
  if (FLAG_debug_code) {
    Condition is_smi = masm->CheckSmi(rax);
    __ Check(NegateCondition(is_smi),
        "Unexpected type for RegExp data, FixedArray expected");
    __ CmpObjectType(rax, FIXED_ARRAY_TYPE, kScratchRegister);
    __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
  }

  // rax: RegExp data (FixedArray)
  // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
  __ SmiToInteger32(rbx, FieldOperand(rax, JSRegExp::kDataTagOffset));
  __ cmpl(rbx, Immediate(JSRegExp::IRREGEXP));
  __ j(not_equal, &runtime);

  // rax: RegExp data (FixedArray)
  // Check that the number of captures fit in the static offsets vector buffer.
  __ SmiToInteger32(rdx,
                    FieldOperand(rax, JSRegExp::kIrregexpCaptureCountOffset));
  // Calculate number of capture registers (number_of_captures + 1) * 2.
  __ leal(rdx, Operand(rdx, rdx, times_1, 2));
  // Check that the static offsets vector buffer is large enough.
  __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
  __ j(above, &runtime);

  // rax: RegExp data (FixedArray)
  // rdx: Number of capture registers
  // Check that the second argument is a string.
  __ movq(rdi, Operand(rsp, kSubjectOffset));
  __ JumpIfSmi(rdi, &runtime);
  Condition is_string = masm->IsObjectStringType(rdi, rbx, rbx);
  __ j(NegateCondition(is_string), &runtime);

  // rdi: Subject string.
  // rax: RegExp data (FixedArray).
  // rdx: Number of capture registers.
  // Check that the third argument is a positive smi less than the string
  // length. A negative value will be greater (unsigned comparison).
  __ movq(rbx, Operand(rsp, kPreviousIndexOffset));
  __ JumpIfNotSmi(rbx, &runtime);
  __ SmiCompare(rbx, FieldOperand(rdi, String::kLengthOffset));
  __ j(above_equal, &runtime);

  // rax: RegExp data (FixedArray)
  // rdx: Number of capture registers
  // Check that the fourth object is a JSArray object.
  __ movq(rdi, Operand(rsp, kLastMatchInfoOffset));
  __ JumpIfSmi(rdi, &runtime);
  __ CmpObjectType(rdi, JS_ARRAY_TYPE, kScratchRegister);
  __ j(not_equal, &runtime);
  // Check that the JSArray is in fast case.
  __ movq(rbx, FieldOperand(rdi, JSArray::kElementsOffset));
  __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
  __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
                 Heap::kFixedArrayMapRootIndex);
  __ j(not_equal, &runtime);
  // Check that the last match info has space for the capture registers and the
  // additional information. Ensure no overflow in add.
  STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
  __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
  __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
  __ cmpl(rdx, rdi);
  __ j(greater, &runtime);

  // rax: RegExp data (FixedArray)
  // Check the representation and encoding of the subject string.
  NearLabel seq_ascii_string, seq_two_byte_string, check_code;
  __ movq(rdi, Operand(rsp, kSubjectOffset));
  __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
  __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
  // First check for flat two byte string.
  __ andb(rbx, Immediate(
      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
  STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
  __ j(zero, &seq_two_byte_string);
  // Any other flat string must be a flat ascii string.
  __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
  __ j(zero, &seq_ascii_string);

  // Check for flat cons string.
  // A flat cons string is a cons string where the second part is the empty
  // string. In that case the subject string is just the first part of the cons
  // string. Also in this case the first part of the cons string is known to be
  // a sequential string or an external string.
  STATIC_ASSERT(kExternalStringTag !=0);
  STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0);
  __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag));
  __ j(not_zero, &runtime);
  // String is a cons string.
  __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
                 Heap::kEmptyStringRootIndex);
  __ j(not_equal, &runtime);
  __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
  __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
  // String is a cons string with empty second part.
  // rdi: first part of cons string.
  // rbx: map of first part of cons string.
  // Is first part a flat two byte string?
  __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
           Immediate(kStringRepresentationMask | kStringEncodingMask));
  STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
  __ j(zero, &seq_two_byte_string);
  // Any other flat string must be ascii.
  __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
           Immediate(kStringRepresentationMask));
  __ j(not_zero, &runtime);

  __ bind(&seq_ascii_string);
  // rdi: subject string (sequential ascii)
  // rax: RegExp data (FixedArray)
  __ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset));
  __ Set(rcx, 1);  // Type is ascii.
  __ jmp(&check_code);

  __ bind(&seq_two_byte_string);
  // rdi: subject string (flat two-byte)
  // rax: RegExp data (FixedArray)
  __ movq(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset));
  __ Set(rcx, 0);  // Type is two byte.

  __ bind(&check_code);
  // Check that the irregexp code has been generated for the actual string
  // encoding. If it has, the field contains a code object otherwise it contains
  // the hole.
  __ CmpObjectType(r11, CODE_TYPE, kScratchRegister);
  __ j(not_equal, &runtime);

  // rdi: subject string
  // rcx: encoding of subject string (1 if ascii, 0 if two_byte);
  // r11: code
  // Load used arguments before starting to push arguments for call to native
  // RegExp code to avoid handling changing stack height.
  __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset));

  // rdi: subject string
  // rbx: previous index
  // rcx: encoding of subject string (1 if ascii 0 if two_byte);
  // r11: code
  // All checks done. Now push arguments for native regexp code.
  Counters* counters = masm->isolate()->counters();
  __ IncrementCounter(counters->regexp_entry_native(), 1);

  // Isolates: note we add an additional parameter here (isolate pointer).
  static const int kRegExpExecuteArguments = 8;
  int argument_slots_on_stack =
      masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
  __ EnterApiExitFrame(argument_slots_on_stack);

  // Argument 8: Pass current isolate address.
  // __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
  //     Immediate(ExternalReference::isolate_address()));
  __ LoadAddress(kScratchRegister, ExternalReference::isolate_address());
  __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
          kScratchRegister);

  // Argument 7: Indicate that this is a direct call from JavaScript.
  __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
          Immediate(1));

  // Argument 6: Start (high end) of backtracking stack memory area.
  __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
  __ movq(r9, Operand(kScratchRegister, 0));
  __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
  __ addq(r9, Operand(kScratchRegister, 0));
  // Argument 6 passed in r9 on Linux and on the stack on Windows.
#ifdef _WIN64
  __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
#endif

  // Argument 5: static offsets vector buffer.
  __ LoadAddress(r8,
                 ExternalReference::address_of_static_offsets_vector(isolate));
  // Argument 5 passed in r8 on Linux and on the stack on Windows.
#ifdef _WIN64
  __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), r8);
#endif

  // First four arguments are passed in registers on both Linux and Windows.
#ifdef _WIN64
  Register arg4 = r9;
  Register arg3 = r8;
  Register arg2 = rdx;
  Register arg1 = rcx;
#else
  Register arg4 = rcx;
  Register arg3 = rdx;
  Register arg2 = rsi;
  Register arg1 = rdi;
#endif

  // Keep track on aliasing between argX defined above and the registers used.
  // rdi: subject string
  // rbx: previous index
  // rcx: encoding of subject string (1 if ascii 0 if two_byte);
  // r11: code

  // Argument 4: End of string data
  // Argument 3: Start of string data
  NearLabel setup_two_byte, setup_rest;
  __ testb(rcx, rcx);  // Last use of rcx as encoding of subject string.
  __ j(zero, &setup_two_byte);
  __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
  __ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
  __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
  __ jmp(&setup_rest);
  __ bind(&setup_two_byte);
  __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
  __ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
  __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));

  __ bind(&setup_rest);
  // Argument 2: Previous index.
  __ movq(arg2, rbx);

  // Argument 1: Subject string.
#ifdef _WIN64
  __ movq(arg1, rdi);
#else
  // Already there in AMD64 calling convention.
  ASSERT(arg1.is(rdi));
#endif

  // Locate the code entry and call it.
  __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
  __ call(r11);

  __ LeaveApiExitFrame();

  // Check the result.
  NearLabel success;
  Label exception;
  __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
  __ j(equal, &success);
  __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
  __ j(equal, &exception);
  __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
  // If none of the above, it can only be retry.
  // Handle that in the runtime system.
  __ j(not_equal, &runtime);

  // For failure return null.
  __ LoadRoot(rax, Heap::kNullValueRootIndex);
  __ ret(4 * kPointerSize);

  // Load RegExp data.
  __ bind(&success);
  __ movq(rax, Operand(rsp, kJSRegExpOffset));
  __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
  __ SmiToInteger32(rax,
                    FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
  // Calculate number of capture registers (number_of_captures + 1) * 2.
  __ leal(rdx, Operand(rax, rax, times_1, 2));

  // rdx: Number of capture registers
  // Load last_match_info which is still known to be a fast case JSArray.
  __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
  __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));

  // rbx: last_match_info backing store (FixedArray)
  // rdx: number of capture registers
  // Store the capture count.
  __ Integer32ToSmi(kScratchRegister, rdx);
  __ movq(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset),
          kScratchRegister);
  // Store last subject and last input.
  __ movq(rax, Operand(rsp, kSubjectOffset));
  __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
  __ movq(rcx, rbx);
  __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi);
  __ movq(rax, Operand(rsp, kSubjectOffset));
  __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
  __ movq(rcx, rbx);
  __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi);

  // Get the static offsets vector filled by the native regexp code.
  __ LoadAddress(rcx,
                 ExternalReference::address_of_static_offsets_vector(isolate));

  // rbx: last_match_info backing store (FixedArray)
  // rcx: offsets vector
  // rdx: number of capture registers
  NearLabel next_capture, done;
  // Capture register counter starts from number of capture registers and
  // counts down until wraping after zero.
  __ bind(&next_capture);
  __ subq(rdx, Immediate(1));
  __ j(negative, &done);
  // Read the value from the static offsets vector buffer and make it a smi.
  __ movl(rdi, Operand(rcx, rdx, times_int_size, 0));
  __ Integer32ToSmi(rdi, rdi);
  // Store the smi value in the last match info.
  __ movq(FieldOperand(rbx,
                       rdx,
                       times_pointer_size,
                       RegExpImpl::kFirstCaptureOffset),
          rdi);
  __ jmp(&next_capture);
  __ bind(&done);

  // Return last match info.
  __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
  __ ret(4 * kPointerSize);

  __ bind(&exception);
  // Result must now be exception. If there is no pending exception already a
  // stack overflow (on the backtrack stack) was detected in RegExp code but
  // haven't created the exception yet. Handle that in the runtime system.
  // TODO(592): Rerunning the RegExp to get the stack overflow exception.
  ExternalReference pending_exception_address(
      Isolate::k_pending_exception_address, isolate);
  Operand pending_exception_operand =
      masm->ExternalOperand(pending_exception_address, rbx);
  __ movq(rax, pending_exception_operand);
  __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
  __ cmpq(rax, rdx);
  __ j(equal, &runtime);
  __ movq(pending_exception_operand, rdx);

  __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
  NearLabel termination_exception;
  __ j(equal, &termination_exception);
  __ Throw(rax);

  __ bind(&termination_exception);
  __ ThrowUncatchable(TERMINATION, rax);

  // Do the runtime call to execute the regexp.
  __ bind(&runtime);
  __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
#endif  // V8_INTERPRETED_REGEXP
}


void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
  const int kMaxInlineLength = 100;
  Label slowcase;
  Label done;
  __ movq(r8, Operand(rsp, kPointerSize * 3));
  __ JumpIfNotSmi(r8, &slowcase);
  __ SmiToInteger32(rbx, r8);
  __ cmpl(rbx, Immediate(kMaxInlineLength));
  __ j(above, &slowcase);
  // Smi-tagging is equivalent to multiplying by 2.
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);
  // Allocate RegExpResult followed by FixedArray with size in rbx.
  // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
  // Elements:  [Map][Length][..elements..]
  __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
                        times_pointer_size,
                        rbx,  // In: Number of elements.
                        rax,  // Out: Start of allocation (tagged).
                        rcx,  // Out: End of allocation.
                        rdx,  // Scratch register
                        &slowcase,
                        TAG_OBJECT);
  // rax: Start of allocated area, object-tagged.
  // rbx: Number of array elements as int32.
  // r8: Number of array elements as smi.

  // Set JSArray map to global.regexp_result_map().
  __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
  __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
  __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
  __ movq(FieldOperand(rax, HeapObject::kMapOffset), rdx);

  // Set empty properties FixedArray.
  __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
  __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);

  // Set elements to point to FixedArray allocated right after the JSArray.
  __ lea(rcx, Operand(rax, JSRegExpResult::kSize));
  __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);

  // Set input, index and length fields from arguments.
  __ movq(r8, Operand(rsp, kPointerSize * 1));
  __ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8);
  __ movq(r8, Operand(rsp, kPointerSize * 2));
  __ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8);
  __ movq(r8, Operand(rsp, kPointerSize * 3));
  __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);

  // Fill out the elements FixedArray.
  // rax: JSArray.
  // rcx: FixedArray.
  // rbx: Number of elements in array as int32.

  // Set map.
  __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
  __ movq(FieldOperand(rcx, HeapObject::kMapOffset), kScratchRegister);
  // Set length.
  __ Integer32ToSmi(rdx, rbx);
  __ movq(FieldOperand(rcx, FixedArray::kLengthOffset), rdx);
  // Fill contents of fixed-array with the-hole.
  __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
  __ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize));
  // Fill fixed array elements with hole.
  // rax: JSArray.
  // rbx: Number of elements in array that remains to be filled, as int32.
  // rcx: Start of elements in FixedArray.
  // rdx: the hole.
  Label loop;
  __ testl(rbx, rbx);
  __ bind(&loop);
  __ j(less_equal, &done);  // Jump if rcx is negative or zero.
  __ subl(rbx, Immediate(1));
  __ movq(Operand(rcx, rbx, times_pointer_size, 0), rdx);
  __ jmp(&loop);

  __ bind(&done);
  __ ret(3 * kPointerSize);

  __ bind(&slowcase);
  __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1);
}


void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
                                                         Register object,
                                                         Register result,
                                                         Register scratch1,
                                                         Register scratch2,
                                                         bool object_is_smi,
                                                         Label* not_found) {
  // Use of registers. Register result is used as a temporary.
  Register number_string_cache = result;
  Register mask = scratch1;
  Register scratch = scratch2;

  // Load the number string cache.
  __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);

  // Make the hash mask from the length of the number string cache. It
  // contains two elements (number and string) for each cache entry.
  __ SmiToInteger32(
      mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
  __ shrl(mask, Immediate(1));
  __ subq(mask, Immediate(1));  // Make mask.

  // Calculate the entry in the number string cache. The hash value in the
  // number string cache for smis is just the smi value, and the hash for
  // doubles is the xor of the upper and lower words. See
  // Heap::GetNumberStringCache.
  Label is_smi;
  Label load_result_from_cache;
  Factory* factory = masm->isolate()->factory();
  if (!object_is_smi) {
    __ JumpIfSmi(object, &is_smi);
    __ CheckMap(object, factory->heap_number_map(), not_found, true);

    STATIC_ASSERT(8 == kDoubleSize);
    __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
    __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset));
    GenerateConvertHashCodeToIndex(masm, scratch, mask);

    Register index = scratch;
    Register probe = mask;
    __ movq(probe,
            FieldOperand(number_string_cache,
                         index,
                         times_1,
                         FixedArray::kHeaderSize));
    __ JumpIfSmi(probe, not_found);
    __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
    __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
    __ ucomisd(xmm0, xmm1);
    __ j(parity_even, not_found);  // Bail out if NaN is involved.
    __ j(not_equal, not_found);  // The cache did not contain this value.
    __ jmp(&load_result_from_cache);
  }

  __ bind(&is_smi);
  __ SmiToInteger32(scratch, object);
  GenerateConvertHashCodeToIndex(masm, scratch, mask);

  Register index = scratch;
  // Check if the entry is the smi we are looking for.
  __ cmpq(object,
          FieldOperand(number_string_cache,
                       index,
                       times_1,
                       FixedArray::kHeaderSize));
  __ j(not_equal, not_found);

  // Get the result from the cache.
  __ bind(&load_result_from_cache);
  __ movq(result,
          FieldOperand(number_string_cache,
                       index,
                       times_1,
                       FixedArray::kHeaderSize + kPointerSize));
  Counters* counters = masm->isolate()->counters();
  __ IncrementCounter(counters->number_to_string_native(), 1);
}


void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm,
                                                        Register hash,
                                                        Register mask) {
  __ and_(hash, mask);
  // Each entry in string cache consists of two pointer sized fields,
  // but times_twice_pointer_size (multiplication by 16) scale factor
  // is not supported by addrmode on x64 platform.
  // So we have to premultiply entry index before lookup.
  __ shl(hash, Immediate(kPointerSizeLog2 + 1));
}


void NumberToStringStub::Generate(MacroAssembler* masm) {
  Label runtime;

  __ movq(rbx, Operand(rsp, kPointerSize));

  // Generate code to lookup number in the number string cache.
  GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
  __ ret(1 * kPointerSize);

  __ bind(&runtime);
  // Handle number to string in the runtime system if not found in the cache.
  __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
}


static int NegativeComparisonResult(Condition cc) {
  ASSERT(cc != equal);
  ASSERT((cc == less) || (cc == less_equal)
      || (cc == greater) || (cc == greater_equal));
  return (cc == greater || cc == greater_equal) ? LESS : GREATER;
}


void CompareStub::Generate(MacroAssembler* masm) {
  ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));

  Label check_unequal_objects, done;
  Factory* factory = masm->isolate()->factory();

  // Compare two smis if required.
  if (include_smi_compare_) {
    Label non_smi, smi_done;
    __ JumpIfNotBothSmi(rax, rdx, &non_smi);
    __ subq(rdx, rax);
    __ j(no_overflow, &smi_done);
    __ not_(rdx);  // Correct sign in case of overflow. rdx cannot be 0 here.
    __ bind(&smi_done);
    __ movq(rax, rdx);
    __ ret(0);
    __ bind(&non_smi);
  } else if (FLAG_debug_code) {
    Label ok;
    __ JumpIfNotSmi(rdx, &ok);
    __ JumpIfNotSmi(rax, &ok);
    __ Abort("CompareStub: smi operands");
    __ bind(&ok);
  }

  // The compare stub returns a positive, negative, or zero 64-bit integer
  // value in rax, corresponding to result of comparing the two inputs.
  // NOTICE! This code is only reached after a smi-fast-case check, so
  // it is certain that at least one operand isn't a smi.

  // Two identical objects are equal unless they are both NaN or undefined.
  {
    NearLabel not_identical;
    __ cmpq(rax, rdx);
    __ j(not_equal, &not_identical);

    if (cc_ != equal) {
      // Check for undefined.  undefined OP undefined is false even though
      // undefined == undefined.
      NearLabel check_for_nan;
      __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
      __ j(not_equal, &check_for_nan);
      __ Set(rax, NegativeComparisonResult(cc_));
      __ ret(0);
      __ bind(&check_for_nan);
    }

    // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(),
    // so we do the second best thing - test it ourselves.
    // Note: if cc_ != equal, never_nan_nan_ is not used.
    // We cannot set rax to EQUAL until just before return because
    // rax must be unchanged on jump to not_identical.
    if (never_nan_nan_ && (cc_ == equal)) {
      __ Set(rax, EQUAL);
      __ ret(0);
    } else {
      NearLabel heap_number;
      // If it's not a heap number, then return equal for (in)equality operator.
      __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
             factory->heap_number_map());
      __ j(equal, &heap_number);
      if (cc_ != equal) {
        // Call runtime on identical JSObjects.  Otherwise return equal.
        __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
        __ j(above_equal, &not_identical);
      }
      __ Set(rax, EQUAL);
      __ ret(0);

      __ bind(&heap_number);
      // It is a heap number, so return  equal if it's not NaN.
      // For NaN, return 1 for every condition except greater and
      // greater-equal.  Return -1 for them, so the comparison yields
      // false for all conditions except not-equal.
      __ Set(rax, EQUAL);
      __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
      __ ucomisd(xmm0, xmm0);
      __ setcc(parity_even, rax);
      // rax is 0 for equal non-NaN heapnumbers, 1 for NaNs.
      if (cc_ == greater_equal || cc_ == greater) {
        __ neg(rax);
      }
      __ ret(0);
    }

    __ bind(&not_identical);
  }

  if (cc_ == equal) {  // Both strict and non-strict.
    Label slow;  // Fallthrough label.

    // If we're doing a strict equality comparison, we don't have to do
    // type conversion, so we generate code to do fast comparison for objects
    // and oddballs. Non-smi numbers and strings still go through the usual
    // slow-case code.
    if (strict_) {
      // If either is a Smi (we know that not both are), then they can only
      // be equal if the other is a HeapNumber. If so, use the slow case.
      {
        Label not_smis;
        __ SelectNonSmi(rbx, rax, rdx, &not_smis);

        // Check if the non-smi operand is a heap number.
        __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
               factory->heap_number_map());
        // If heap number, handle it in the slow case.
        __ j(equal, &slow);
        // Return non-equal.  ebx (the lower half of rbx) is not zero.
        __ movq(rax, rbx);
        __ ret(0);

        __ bind(&not_smis);
      }

      // If either operand is a JSObject or an oddball value, then they are not
      // equal since their pointers are different
      // There is no test for undetectability in strict equality.

      // If the first object is a JS object, we have done pointer comparison.
      STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
      NearLabel first_non_object;
      __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
      __ j(below, &first_non_object);
      // Return non-zero (eax (not rax) is not zero)
      Label return_not_equal;
      STATIC_ASSERT(kHeapObjectTag != 0);
      __ bind(&return_not_equal);
      __ ret(0);

      __ bind(&first_non_object);
      // Check for oddballs: true, false, null, undefined.
      __ CmpInstanceType(rcx, ODDBALL_TYPE);
      __ j(equal, &return_not_equal);

      __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
      __ j(above_equal, &return_not_equal);

      // Check for oddballs: true, false, null, undefined.
      __ CmpInstanceType(rcx, ODDBALL_TYPE);
      __ j(equal, &return_not_equal);

      // Fall through to the general case.
    }
    __ bind(&slow);
  }

  // Generate the number comparison code.
  if (include_number_compare_) {
    Label non_number_comparison;
    NearLabel unordered;
    FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison);
    __ xorl(rax, rax);
    __ xorl(rcx, rcx);
    __ ucomisd(xmm0, xmm1);

    // Don't base result on EFLAGS when a NaN is involved.
    __ j(parity_even, &unordered);
    // Return a result of -1, 0, or 1, based on EFLAGS.
    __ setcc(above, rax);
    __ setcc(below, rcx);
    __ subq(rax, rcx);
    __ ret(0);

    // If one of the numbers was NaN, then the result is always false.
    // The cc is never not-equal.
    __ bind(&unordered);
    ASSERT(cc_ != not_equal);
    if (cc_ == less || cc_ == less_equal) {
      __ Set(rax, 1);
    } else {
      __ Set(rax, -1);
    }
    __ ret(0);

    // The number comparison code did not provide a valid result.
    __ bind(&non_number_comparison);
  }

  // Fast negative check for symbol-to-symbol equality.
  Label check_for_strings;
  if (cc_ == equal) {
    BranchIfNonSymbol(masm, &check_for_strings, rax, kScratchRegister);
    BranchIfNonSymbol(masm, &check_for_strings, rdx, kScratchRegister);

    // We've already checked for object identity, so if both operands
    // are symbols they aren't equal. Register eax (not rax) already holds a
    // non-zero value, which indicates not equal, so just return.
    __ ret(0);
  }

  __ bind(&check_for_strings);

  __ JumpIfNotBothSequentialAsciiStrings(
      rdx, rax, rcx, rbx, &check_unequal_objects);

  // Inline comparison of ascii strings.
  StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
                                                     rdx,
                                                     rax,
                                                     rcx,
                                                     rbx,
                                                     rdi,
                                                     r8);

#ifdef DEBUG
  __ Abort("Unexpected fall-through from string comparison");
#endif

  __ bind(&check_unequal_objects);
  if (cc_ == equal && !strict_) {
    // Not strict equality.  Objects are unequal if
    // they are both JSObjects and not undetectable,
    // and their pointers are different.
    NearLabel not_both_objects, return_unequal;
    // At most one is a smi, so we can test for smi by adding the two.
    // A smi plus a heap object has the low bit set, a heap object plus
    // a heap object has the low bit clear.
    STATIC_ASSERT(kSmiTag == 0);
    STATIC_ASSERT(kSmiTagMask == 1);
    __ lea(rcx, Operand(rax, rdx, times_1, 0));
    __ testb(rcx, Immediate(kSmiTagMask));
    __ j(not_zero, &not_both_objects);
    __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
    __ j(below, &not_both_objects);
    __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
    __ j(below, &not_both_objects);
    __ testb(FieldOperand(rbx, Map::kBitFieldOffset),
             Immediate(1 << Map::kIsUndetectable));
    __ j(zero, &return_unequal);
    __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
             Immediate(1 << Map::kIsUndetectable));
    __ j(zero, &return_unequal);
    // The objects are both undetectable, so they both compare as the value
    // undefined, and are equal.
    __ Set(rax, EQUAL);
    __ bind(&return_unequal);
    // Return non-equal by returning the non-zero object pointer in rax,
    // or return equal if we fell through to here.
    __ ret(0);
    __ bind(&not_both_objects);
  }

  // Push arguments below the return address to prepare jump to builtin.
  __ pop(rcx);
  __ push(rdx);
  __ push(rax);

  // Figure out which native to call and setup the arguments.
  Builtins::JavaScript builtin;
  if (cc_ == equal) {
    builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
  } else {
    builtin = Builtins::COMPARE;
    __ Push(Smi::FromInt(NegativeComparisonResult(cc_)));
  }

  // Restore return address on the stack.
  __ push(rcx);

  // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
  // tagged as a small integer.
  __ InvokeBuiltin(builtin, JUMP_FUNCTION);
}


void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
                                    Label* label,
                                    Register object,
                                    Register scratch) {
  __ JumpIfSmi(object, label);
  __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset));
  __ movzxbq(scratch,
             FieldOperand(scratch, Map::kInstanceTypeOffset));
  // Ensure that no non-strings have the symbol bit set.
  STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask);
  STATIC_ASSERT(kSymbolTag != 0);
  __ testb(scratch, Immediate(kIsSymbolMask));
  __ j(zero, label);
}


void StackCheckStub::Generate(MacroAssembler* masm) {
  __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
}


void CallFunctionStub::Generate(MacroAssembler* masm) {
  Label slow;

  // If the receiver might be a value (string, number or boolean) check for this
  // and box it if it is.
  if (ReceiverMightBeValue()) {
    // Get the receiver from the stack.
    // +1 ~ return address
    Label receiver_is_value, receiver_is_js_object;
    __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));

    // Check if receiver is a smi (which is a number value).
    __ JumpIfSmi(rax, &receiver_is_value);

    // Check if the receiver is a valid JS object.
    __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdi);
    __ j(above_equal, &receiver_is_js_object);

    // Call the runtime to box the value.
    __ bind(&receiver_is_value);
    __ EnterInternalFrame();
    __ push(rax);
    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
    __ LeaveInternalFrame();
    __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax);

    __ bind(&receiver_is_js_object);
  }

  // Get the function to call from the stack.
  // +2 ~ receiver, return address
  __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize));

  // Check that the function really is a JavaScript function.
  __ JumpIfSmi(rdi, &slow);
  // Goto slow case if we do not have a function.
  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
  __ j(not_equal, &slow);

  // Fast-case: Just invoke the function.
  ParameterCount actual(argc_);
  __ InvokeFunction(rdi, actual, JUMP_FUNCTION);

  // Slow-case: Non-function called.
  __ bind(&slow);
  // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
  // of the original receiver from the call site).
  __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
  __ Set(rax, argc_);
  __ Set(rbx, 0);
  __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
  Handle<Code> adaptor =
      Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline();
  __ Jump(adaptor, RelocInfo::CODE_TARGET);
}


bool CEntryStub::NeedsImmovableCode() {
  return false;
}


void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
  // Throw exception in eax.
  __ Throw(rax);
}


void CEntryStub::GenerateCore(MacroAssembler* masm,
                              Label* throw_normal_exception,
                              Label* throw_termination_exception,
                              Label* throw_out_of_memory_exception,
                              bool do_gc,
                              bool always_allocate_scope) {
  // rax: result parameter for PerformGC, if any.
  // rbx: pointer to C function  (C callee-saved).
  // rbp: frame pointer  (restored after C call).
  // rsp: stack pointer  (restored after C call).
  // r14: number of arguments including receiver (C callee-saved).
  // r15: pointer to the first argument (C callee-saved).
  //      This pointer is reused in LeaveExitFrame(), so it is stored in a
  //      callee-saved register.

  // Simple results returned in rax (both AMD64 and Win64 calling conventions).
  // Complex results must be written to address passed as first argument.
  // AMD64 calling convention: a struct of two pointers in rax+rdx

  // Check stack alignment.
  if (FLAG_debug_code) {
    __ CheckStackAlignment();
  }

  if (do_gc) {
    // Pass failure code returned from last attempt as first argument to
    // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
    // stack is known to be aligned. This function takes one argument which is
    // passed in register.
#ifdef _WIN64
    __ movq(rcx, rax);
#else  // _WIN64
    __ movq(rdi, rax);
#endif
    __ movq(kScratchRegister,
            FUNCTION_ADDR(Runtime::PerformGC),
            RelocInfo::RUNTIME_ENTRY);
    __ call(kScratchRegister);
  }

  ExternalReference scope_depth =
      ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
  if (always_allocate_scope) {
    Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
    __ incl(scope_depth_operand);
  }

  // Call C function.
#ifdef _WIN64
  // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9
  // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
  __ movq(StackSpaceOperand(0), r14);  // argc.
  __ movq(StackSpaceOperand(1), r15);  // argv.
  if (result_size_ < 2) {
    // Pass a pointer to the Arguments object as the first argument.
    // Return result in single register (rax).
    __ lea(rcx, StackSpaceOperand(0));
    __ LoadAddress(rdx, ExternalReference::isolate_address());
  } else {
    ASSERT_EQ(2, result_size_);
    // Pass a pointer to the result location as the first argument.
    __ lea(rcx, StackSpaceOperand(2));
    // Pass a pointer to the Arguments object as the second argument.
    __ lea(rdx, StackSpaceOperand(0));
    __ LoadAddress(r8, ExternalReference::isolate_address());
  }

#else  // _WIN64
  // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
  __ movq(rdi, r14);  // argc.
  __ movq(rsi, r15);  // argv.
  __ movq(rdx, ExternalReference::isolate_address());
#endif
  __ call(rbx);
  // Result is in rax - do not destroy this register!

  if (always_allocate_scope) {
    Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
    __ decl(scope_depth_operand);
  }

  // Check for failure result.
  Label failure_returned;
  STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
#ifdef _WIN64
  // If return value is on the stack, pop it to registers.
  if (result_size_ > 1) {
    ASSERT_EQ(2, result_size_);
    // Read result values stored on stack. Result is stored
    // above the four argument mirror slots and the two
    // Arguments object slots.
    __ movq(rax, Operand(rsp, 6 * kPointerSize));
    __ movq(rdx, Operand(rsp, 7 * kPointerSize));
  }
#endif
  __ lea(rcx, Operand(rax, 1));
  // Lower 2 bits of rcx are 0 iff rax has failure tag.
  __ testl(rcx, Immediate(kFailureTagMask));
  __ j(zero, &failure_returned);

  // Exit the JavaScript to C++ exit frame.
  __ LeaveExitFrame(save_doubles_);
  __ ret(0);

  // Handling of failure.
  __ bind(&failure_returned);

  NearLabel retry;
  // If the returned exception is RETRY_AFTER_GC continue at retry label
  STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
  __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
  __ j(zero, &retry);

  // Special handling of out of memory exceptions.
  __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
  __ cmpq(rax, kScratchRegister);
  __ j(equal, throw_out_of_memory_exception);

  // Retrieve the pending exception and clear the variable.
  ExternalReference pending_exception_address(
      Isolate::k_pending_exception_address, masm->isolate());
  Operand pending_exception_operand =
      masm->ExternalOperand(pending_exception_address);
  __ movq(rax, pending_exception_operand);
  __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
  __ movq(pending_exception_operand, rdx);

  // Special handling of termination exceptions which are uncatchable
  // by javascript code.
  __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
  __ j(equal, throw_termination_exception);

  // Handle normal exception.
  __ jmp(throw_normal_exception);

  // Retry.
  __ bind(&retry);
}


void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
                                          UncatchableExceptionType type) {
  __ ThrowUncatchable(type, rax);
}


void CEntryStub::Generate(MacroAssembler* masm) {
  // rax: number of arguments including receiver
  // rbx: pointer to C function  (C callee-saved)
  // rbp: frame pointer of calling JS frame (restored after C call)
  // rsp: stack pointer  (restored after C call)
  // rsi: current context (restored)

  // NOTE: Invocations of builtins may return failure objects
  // instead of a proper result. The builtin entry handles
  // this by performing a garbage collection and retrying the
  // builtin once.

  // Enter the exit frame that transitions from JavaScript to C++.
#ifdef _WIN64
  int arg_stack_space = (result_size_ < 2 ? 2 : 4);
#else
  int arg_stack_space = 0;
#endif
  __ EnterExitFrame(arg_stack_space, save_doubles_);

  // rax: Holds the context at this point, but should not be used.
  //      On entry to code generated by GenerateCore, it must hold
  //      a failure result if the collect_garbage argument to GenerateCore
  //      is true.  This failure result can be the result of code
  //      generated by a previous call to GenerateCore.  The value
  //      of rax is then passed to Runtime::PerformGC.
  // rbx: pointer to builtin function  (C callee-saved).
  // rbp: frame pointer of exit frame  (restored after C call).
  // rsp: stack pointer (restored after C call).
  // r14: number of arguments including receiver (C callee-saved).
  // r15: argv pointer (C callee-saved).

  Label throw_normal_exception;
  Label throw_termination_exception;
  Label throw_out_of_memory_exception;

  // Call into the runtime system.
  GenerateCore(masm,
               &throw_normal_exception,
               &throw_termination_exception,
               &throw_out_of_memory_exception,
               false,
               false);

  // Do space-specific GC and retry runtime call.
  GenerateCore(masm,
               &throw_normal_exception,
               &throw_termination_exception,
               &throw_out_of_memory_exception,
               true,
               false);

  // Do full GC and retry runtime call one final time.
  Failure* failure = Failure::InternalError();
  __ movq(rax, failure, RelocInfo::NONE);
  GenerateCore(masm,
               &throw_normal_exception,
               &throw_termination_exception,
               &throw_out_of_memory_exception,
               true,
               true);

  __ bind(&throw_out_of_memory_exception);
  GenerateThrowUncatchable(masm, OUT_OF_MEMORY);

  __ bind(&throw_termination_exception);
  GenerateThrowUncatchable(masm, TERMINATION);

  __ bind(&throw_normal_exception);
  GenerateThrowTOS(masm);
}


void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
  Label invoke, exit;
#ifdef ENABLE_LOGGING_AND_PROFILING
  Label not_outermost_js, not_outermost_js_2;
#endif
  {  // NOLINT. Scope block confuses linter.
    MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
    // Setup frame.
    __ push(rbp);
    __ movq(rbp, rsp);

    // Push the stack frame type marker twice.
    int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
    // Scratch register is neither callee-save, nor an argument register on any
    // platform. It's free to use at this point.
    // Cannot use smi-register for loading yet.
    __ movq(kScratchRegister,
            reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
            RelocInfo::NONE);
    __ push(kScratchRegister);  // context slot
    __ push(kScratchRegister);  // function slot
    // Save callee-saved registers (X64/Win64 calling conventions).
    __ push(r12);
    __ push(r13);
    __ push(r14);
    __ push(r15);
#ifdef _WIN64
    __ push(rdi);  // Only callee save in Win64 ABI, argument in AMD64 ABI.
    __ push(rsi);  // Only callee save in Win64 ABI, argument in AMD64 ABI.
#endif
    __ push(rbx);
    // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are
    // callee save as well.

    // Set up the roots and smi constant registers.
    // Needs to be done before any further smi loads.
    __ InitializeSmiConstantRegister();
    __ InitializeRootRegister();
  }

  Isolate* isolate = masm->isolate();

  // Save copies of the top frame descriptor on the stack.
  ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, isolate);
  {
    Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
    __ push(c_entry_fp_operand);
  }

#ifdef ENABLE_LOGGING_AND_PROFILING
  // If this is the outermost JS call, set js_entry_sp value.
  ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
  __ Load(rax, js_entry_sp);
  __ testq(rax, rax);
  __ j(not_zero, &not_outermost_js);
  __ movq(rax, rbp);
  __ Store(js_entry_sp, rax);
  __ bind(&not_outermost_js);
#endif

  // Call a faked try-block that does the invoke.
  __ call(&invoke);

  // Caught exception: Store result (exception) in the pending
  // exception field in the JSEnv and return a failure sentinel.
  ExternalReference pending_exception(Isolate::k_pending_exception_address,
                                      isolate);
  __ Store(pending_exception, rax);
  __ movq(rax, Failure::Exception(), RelocInfo::NONE);
  __ jmp(&exit);

  // Invoke: Link this frame into the handler chain.
  __ bind(&invoke);
  __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);

  // Clear any pending exceptions.
  __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
  __ Store(pending_exception, rax);

  // Fake a receiver (NULL).
  __ push(Immediate(0));  // receiver

  // Invoke the function by calling through JS entry trampoline
  // builtin and pop the faked function when we return. We load the address
  // from an external reference instead of inlining the call target address
  // directly in the code, because the builtin stubs may not have been
  // generated yet at the time this code is generated.
  if (is_construct) {
    ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
                                      isolate);
    __ Load(rax, construct_entry);
  } else {
    ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
    __ Load(rax, entry);
  }
  __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
  __ call(kScratchRegister);

  // Unlink this frame from the handler chain.
  Operand handler_operand =
      masm->ExternalOperand(ExternalReference(Isolate::k_handler_address,
                                              isolate));
  __ pop(handler_operand);
  // Pop next_sp.
  __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));

#ifdef ENABLE_LOGGING_AND_PROFILING
  // If current RBP value is the same as js_entry_sp value, it means that
  // the current function is the outermost.
  __ movq(kScratchRegister, js_entry_sp);
  __ cmpq(rbp, Operand(kScratchRegister, 0));
  __ j(not_equal, &not_outermost_js_2);
  __ movq(Operand(kScratchRegister, 0), Immediate(0));
  __ bind(&not_outermost_js_2);
#endif

  // Restore the top frame descriptor from the stack.
  __ bind(&exit);
  {
    Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
    __ pop(c_entry_fp_operand);
  }

  // Restore callee-saved registers (X64 conventions).
  __ pop(rbx);
#ifdef _WIN64
  // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI.
  __ pop(rsi);
  __ pop(rdi);
#endif
  __ pop(r15);
  __ pop(r14);
  __ pop(r13);
  __ pop(r12);
  __ addq(rsp, Immediate(2 * kPointerSize));  // remove markers

  // Restore frame pointer and return.
  __ pop(rbp);
  __ ret(0);
}


void InstanceofStub::Generate(MacroAssembler* masm) {
  // Implements "value instanceof function" operator.
  // Expected input state with no inline cache:
  //   rsp[0] : return address
  //   rsp[1] : function pointer
  //   rsp[2] : value
  // Expected input state with an inline one-element cache:
  //   rsp[0] : return address
  //   rsp[1] : offset from return address to location of inline cache
  //   rsp[2] : function pointer
  //   rsp[3] : value
  // Returns a bitwise zero to indicate that the value
  // is and instance of the function and anything else to
  // indicate that the value is not an instance.

  static const int kOffsetToMapCheckValue = 2;
  static const int kOffsetToResultValue = 18;
  // The last 4 bytes of the instruction sequence
  //   movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
  //   Move(kScratchRegister, FACTORY->the_hole_value())
  // in front of the hole value address.
  static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78;
  // The last 4 bytes of the instruction sequence
  //   __ j(not_equal, &cache_miss);
  //   __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
  // before the offset of the hole value in the root array.
  static const unsigned int kWordBeforeResultValue = 0x458B4909;
  // Only the inline check flag is supported on X64.
  ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
  int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0;

  // Get the object - go slow case if it's a smi.
  Label slow;

  __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
  __ JumpIfSmi(rax, &slow);

  // Check that the left hand is a JS object. Leave its map in rax.
  __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
  __ j(below, &slow);
  __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE);
  __ j(above, &slow);

  // Get the prototype of the function.
  __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
  // rdx is function, rax is map.

  // If there is a call site cache don't look in the global cache, but do the
  // real lookup and update the call site cache.
  if (!HasCallSiteInlineCheck()) {
    // Look up the function and the map in the instanceof cache.
    NearLabel miss;
    __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
    __ j(not_equal, &miss);
    __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex);
    __ j(not_equal, &miss);
    __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
    __ ret(2 * kPointerSize);
    __ bind(&miss);
  }

  __ TryGetFunctionPrototype(rdx, rbx, &slow);

  // Check that the function prototype is a JS object.
  __ JumpIfSmi(rbx, &slow);
  __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister);
  __ j(below, &slow);
  __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
  __ j(above, &slow);

  // Register mapping:
  //   rax is object map.
  //   rdx is function.
  //   rbx is function prototype.
  if (!HasCallSiteInlineCheck()) {
    __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
    __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
  } else {
    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
    __ movq(Operand(kScratchRegister, kOffsetToMapCheckValue), rax);
    if (FLAG_debug_code) {
      __ movl(rdi, Immediate(kWordBeforeMapCheckValue));
      __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
      __ Assert(equal, "InstanceofStub unexpected call site cache (check).");
    }
  }

  __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset));

  // Loop through the prototype chain looking for the function prototype.
  NearLabel loop, is_instance, is_not_instance;
  __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex);
  __ bind(&loop);
  __ cmpq(rcx, rbx);
  __ j(equal, &is_instance);
  __ cmpq(rcx, kScratchRegister);
  // The code at is_not_instance assumes that kScratchRegister contains a
  // non-zero GCable value (the null object in this case).
  __ j(equal, &is_not_instance);
  __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
  __ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
  __ jmp(&loop);

  __ bind(&is_instance);
  if (!HasCallSiteInlineCheck()) {
    __ xorl(rax, rax);
    // Store bitwise zero in the cache.  This is a Smi in GC terms.
    STATIC_ASSERT(kSmiTag == 0);
    __ StoreRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
  } else {
    // Store offset of true in the root array at the inline check site.
    ASSERT((Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias
        == 0xB0 - 0x100);
    __ movl(rax, Immediate(0xB0));  // TrueValue is at -10 * kPointerSize.
    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
    __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
    if (FLAG_debug_code) {
      __ movl(rax, Immediate(kWordBeforeResultValue));
      __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
      __ Assert(equal, "InstanceofStub unexpected call site cache (mov).");
    }
    __ Set(rax, 0);
  }
  __ ret(2 * kPointerSize + extra_stack_space);

  __ bind(&is_not_instance);
  if (!HasCallSiteInlineCheck()) {
    // We have to store a non-zero value in the cache.
    __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex);
  } else {
    // Store offset of false in the root array at the inline check site.
    ASSERT((Heap::kFalseValueRootIndex << kPointerSizeLog2) - kRootRegisterBias
        == 0xB8 - 0x100);
    __ movl(rax, Immediate(0xB8));  // FalseValue is at -9 * kPointerSize.
    __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
    __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
    __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
    if (FLAG_debug_code) {
      __ movl(rax, Immediate(kWordBeforeResultValue));
      __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
      __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
    }
  }
  __ ret(2 * kPointerSize + extra_stack_space);

  // Slow-case: Go through the JavaScript implementation.
  __ bind(&slow);
  if (HasCallSiteInlineCheck()) {
    // Remove extra value from the stack.
    __ pop(rcx);
    __ pop(rax);
    __ push(rcx);
  }
  __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
}


// Passing arguments in registers is not supported.
Register InstanceofStub::left() { return no_reg; }


Register InstanceofStub::right() { return no_reg; }


int CompareStub::MinorKey() {
  // Encode the three parameters in a unique 16 bit value. To avoid duplicate
  // stubs the never NaN NaN condition is only taken into account if the
  // condition is equals.
  ASSERT(static_cast<unsigned>(cc_) < (1 << 12));
  ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
  return ConditionField::encode(static_cast<unsigned>(cc_))
         | RegisterField::encode(false)    // lhs_ and rhs_ are not used
         | StrictField::encode(strict_)
         | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false)
         | IncludeNumberCompareField::encode(include_number_compare_)
         | IncludeSmiCompareField::encode(include_smi_compare_);
}


// Unfortunately you have to run without snapshots to see most of these
// names in the profile since most compare stubs end up in the snapshot.
const char* CompareStub::GetName() {
  ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));

  if (name_ != NULL) return name_;
  const int kMaxNameLength = 100;
  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
      kMaxNameLength);
  if (name_ == NULL) return "OOM";

  const char* cc_name;
  switch (cc_) {
    case less: cc_name = "LT"; break;
    case greater: cc_name = "GT"; break;
    case less_equal: cc_name = "LE"; break;
    case greater_equal: cc_name = "GE"; break;
    case equal: cc_name = "EQ"; break;
    case not_equal: cc_name = "NE"; break;
    default: cc_name = "UnknownCondition"; break;
  }

  const char* strict_name = "";
  if (strict_ && (cc_ == equal || cc_ == not_equal)) {
    strict_name = "_STRICT";
  }

  const char* never_nan_nan_name = "";
  if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
    never_nan_nan_name = "_NO_NAN";
  }

  const char* include_number_compare_name = "";
  if (!include_number_compare_) {
    include_number_compare_name = "_NO_NUMBER";
  }

  const char* include_smi_compare_name = "";
  if (!include_smi_compare_) {
    include_smi_compare_name = "_NO_SMI";
  }

  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
               "CompareStub_%s%s%s%s",
               cc_name,
               strict_name,
               never_nan_nan_name,
               include_number_compare_name,
               include_smi_compare_name);
  return name_;
}


// -------------------------------------------------------------------------
// StringCharCodeAtGenerator

void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
  Label flat_string;
  Label ascii_string;
  Label got_char_code;

  // If the receiver is a smi trigger the non-string case.
  __ JumpIfSmi(object_, receiver_not_string_);

  // Fetch the instance type of the receiver into result register.
  __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
  __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
  // If the receiver is not a string trigger the non-string case.
  __ testb(result_, Immediate(kIsNotStringMask));
  __ j(not_zero, receiver_not_string_);

  // If the index is non-smi trigger the non-smi case.
  __ JumpIfNotSmi(index_, &index_not_smi_);

  // Put smi-tagged index into scratch register.
  __ movq(scratch_, index_);
  __ bind(&got_smi_index_);

  // Check for index out of range.
  __ SmiCompare(scratch_, FieldOperand(object_, String::kLengthOffset));
  __ j(above_equal, index_out_of_range_);

  // We need special handling for non-flat strings.
  STATIC_ASSERT(kSeqStringTag == 0);
  __ testb(result_, Immediate(kStringRepresentationMask));
  __ j(zero, &flat_string);

  // Handle non-flat strings.
  __ testb(result_, Immediate(kIsConsStringMask));
  __ j(zero, &call_runtime_);

  // ConsString.
  // Check whether the right hand side is the empty string (i.e. if
  // this is really a flat string in a cons string). If that is not
  // the case we would rather go to the runtime system now to flatten
  // the string.
  __ CompareRoot(FieldOperand(object_, ConsString::kSecondOffset),
                 Heap::kEmptyStringRootIndex);
  __ j(not_equal, &call_runtime_);
  // Get the first of the two strings and load its instance type.
  __ movq(object_, FieldOperand(object_, ConsString::kFirstOffset));
  __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
  __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
  // If the first cons component is also non-flat, then go to runtime.
  STATIC_ASSERT(kSeqStringTag == 0);
  __ testb(result_, Immediate(kStringRepresentationMask));
  __ j(not_zero, &call_runtime_);

  // Check for 1-byte or 2-byte string.
  __ bind(&flat_string);
  STATIC_ASSERT(kAsciiStringTag != 0);
  __ testb(result_, Immediate(kStringEncodingMask));
  __ j(not_zero, &ascii_string);

  // 2-byte string.
  // Load the 2-byte character code into the result register.
  __ SmiToInteger32(scratch_, scratch_);
  __ movzxwl(result_, FieldOperand(object_,
                                   scratch_, times_2,
                                   SeqTwoByteString::kHeaderSize));
  __ jmp(&got_char_code);

  // ASCII string.
  // Load the byte into the result register.
  __ bind(&ascii_string);
  __ SmiToInteger32(scratch_, scratch_);
  __ movzxbl(result_, FieldOperand(object_,
                                   scratch_, times_1,
                                   SeqAsciiString::kHeaderSize));
  __ bind(&got_char_code);
  __ Integer32ToSmi(result_, result_);
  __ bind(&exit_);
}


void StringCharCodeAtGenerator::GenerateSlow(
    MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
  __ Abort("Unexpected fallthrough to CharCodeAt slow case");

  Factory* factory = masm->isolate()->factory();
  // Index is not a smi.
  __ bind(&index_not_smi_);
  // If index is a heap number, try converting it to an integer.
  __ CheckMap(index_, factory->heap_number_map(), index_not_number_, true);
  call_helper.BeforeCall(masm);
  __ push(object_);
  __ push(index_);
  __ push(index_);  // Consumed by runtime conversion function.
  if (index_flags_ == STRING_INDEX_IS_NUMBER) {
    __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
  } else {
    ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
    // NumberToSmi discards numbers that are not exact integers.
    __ CallRuntime(Runtime::kNumberToSmi, 1);
  }
  if (!scratch_.is(rax)) {
    // Save the conversion result before the pop instructions below
    // have a chance to overwrite it.
    __ movq(scratch_, rax);
  }
  __ pop(index_);
  __ pop(object_);
  // Reload the instance type.
  __ movq(result_, FieldOperand(object_, HeapObject::kMapOffset));
  __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
  call_helper.AfterCall(masm);
  // If index is still not a smi, it must be out of range.
  __ JumpIfNotSmi(scratch_, index_out_of_range_);
  // Otherwise, return to the fast path.
  __ jmp(&got_smi_index_);

  // Call runtime. We get here when the receiver is a string and the
  // index is a number, but the code of getting the actual character
  // is too complex (e.g., when the string needs to be flattened).
  __ bind(&call_runtime_);
  call_helper.BeforeCall(masm);
  __ push(object_);
  __ push(index_);
  __ CallRuntime(Runtime::kStringCharCodeAt, 2);
  if (!result_.is(rax)) {
    __ movq(result_, rax);
  }
  call_helper.AfterCall(masm);
  __ jmp(&exit_);

  __ Abort("Unexpected fallthrough from CharCodeAt slow case");
}


// -------------------------------------------------------------------------
// StringCharFromCodeGenerator

void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
  // Fast case of Heap::LookupSingleCharacterStringFromCode.
  __ JumpIfNotSmi(code_, &slow_case_);
  __ SmiCompare(code_, Smi::FromInt(String::kMaxAsciiCharCode));
  __ j(above, &slow_case_);

  __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
  SmiIndex index = masm->SmiToIndex(kScratchRegister, code_, kPointerSizeLog2);
  __ movq(result_, FieldOperand(result_, index.reg, index.scale,
                                FixedArray::kHeaderSize));
  __ CompareRoot(result_, Heap::kUndefinedValueRootIndex);
  __ j(equal, &slow_case_);
  __ bind(&exit_);
}


void StringCharFromCodeGenerator::GenerateSlow(
    MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
  __ Abort("Unexpected fallthrough to CharFromCode slow case");

  __ bind(&slow_case_);
  call_helper.BeforeCall(masm);
  __ push(code_);
  __ CallRuntime(Runtime::kCharFromCode, 1);
  if (!result_.is(rax)) {
    __ movq(result_, rax);
  }
  call_helper.AfterCall(masm);
  __ jmp(&exit_);

  __ Abort("Unexpected fallthrough from CharFromCode slow case");
}


// -------------------------------------------------------------------------
// StringCharAtGenerator

void StringCharAtGenerator::GenerateFast(MacroAssembler* masm) {
  char_code_at_generator_.GenerateFast(masm);
  char_from_code_generator_.GenerateFast(masm);
}


void StringCharAtGenerator::GenerateSlow(
    MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
  char_code_at_generator_.GenerateSlow(masm, call_helper);
  char_from_code_generator_.GenerateSlow(masm, call_helper);
}


void StringAddStub::Generate(MacroAssembler* masm) {
  Label string_add_runtime, call_builtin;
  Builtins::JavaScript builtin_id = Builtins::ADD;

  // Load the two arguments.
  __ movq(rax, Operand(rsp, 2 * kPointerSize));  // First argument (left).
  __ movq(rdx, Operand(rsp, 1 * kPointerSize));  // Second argument (right).

  // Make sure that both arguments are strings if not known in advance.
  if (flags_ == NO_STRING_ADD_FLAGS) {
    Condition is_smi;
    is_smi = masm->CheckSmi(rax);
    __ j(is_smi, &string_add_runtime);
    __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8);
    __ j(above_equal, &string_add_runtime);

    // First argument is a a string, test second.
    is_smi = masm->CheckSmi(rdx);
    __ j(is_smi, &string_add_runtime);
    __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, r9);
    __ j(above_equal, &string_add_runtime);
  } else {
    // Here at least one of the arguments is definitely a string.
    // We convert the one that is not known to be a string.
    if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
      ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
      GenerateConvertArgument(masm, 2 * kPointerSize, rax, rbx, rcx, rdi,
                              &call_builtin);
      builtin_id = Builtins::STRING_ADD_RIGHT;
    } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
      ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
      GenerateConvertArgument(masm, 1 * kPointerSize, rdx, rbx, rcx, rdi,
                              &call_builtin);
      builtin_id = Builtins::STRING_ADD_LEFT;
    }
  }

  // Both arguments are strings.
  // rax: first string
  // rdx: second string
  // Check if either of the strings are empty. In that case return the other.
  NearLabel second_not_zero_length, both_not_zero_length;
  __ movq(rcx, FieldOperand(rdx, String::kLengthOffset));
  __ SmiTest(rcx);
  __ j(not_zero, &second_not_zero_length);
  // Second string is empty, result is first string which is already in rax.
  Counters* counters = masm->isolate()->counters();
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);
  __ bind(&second_not_zero_length);
  __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
  __ SmiTest(rbx);
  __ j(not_zero, &both_not_zero_length);
  // First string is empty, result is second string which is in rdx.
  __ movq(rax, rdx);
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);

  // Both strings are non-empty.
  // rax: first string
  // rbx: length of first string
  // rcx: length of second string
  // rdx: second string
  // r8: map of first string (if flags_ == NO_STRING_ADD_FLAGS)
  // r9: map of second string (if flags_ == NO_STRING_ADD_FLAGS)
  Label string_add_flat_result, longer_than_two;
  __ bind(&both_not_zero_length);

  // If arguments where known to be strings, maps are not loaded to r8 and r9
  // by the code above.
  if (flags_ != NO_STRING_ADD_FLAGS) {
    __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset));
    __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
  }
  // Get the instance types of the two strings as they will be needed soon.
  __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
  __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));

  // Look at the length of the result of adding the two strings.
  STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
  __ SmiAdd(rbx, rbx, rcx);
  // Use the symbol table when adding two one character strings, as it
  // helps later optimizations to return a symbol here.
  __ SmiCompare(rbx, Smi::FromInt(2));
  __ j(not_equal, &longer_than_two);

  // Check that both strings are non-external ascii strings.
  __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
                                                  &string_add_runtime);

  // Get the two characters forming the sub string.
  __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize));
  __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize));

  // Try to lookup two character string in symbol table. If it is not found
  // just allocate a new one.
  Label make_two_character_string, make_flat_ascii_string;
  StringHelper::GenerateTwoCharacterSymbolTableProbe(
      masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);

  __ bind(&make_two_character_string);
  __ Set(rbx, 2);
  __ jmp(&make_flat_ascii_string);

  __ bind(&longer_than_two);
  // Check if resulting string will be flat.
  __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength));
  __ j(below, &string_add_flat_result);
  // Handle exceptionally long strings in the runtime system.
  STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
  __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength));
  __ j(above, &string_add_runtime);

  // If result is not supposed to be flat, allocate a cons string object. If
  // both strings are ascii the result is an ascii cons string.
  // rax: first string
  // rbx: length of resulting flat string
  // rdx: second string
  // r8: instance type of first string
  // r9: instance type of second string
  Label non_ascii, allocated, ascii_data;
  __ movl(rcx, r8);
  __ and_(rcx, r9);
  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
  __ testl(rcx, Immediate(kAsciiStringTag));
  __ j(zero, &non_ascii);
  __ bind(&ascii_data);
  // Allocate an acsii cons string.
  __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime);
  __ bind(&allocated);
  // Fill the fields of the cons string.
  __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
  __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset),
          Immediate(String::kEmptyHashField));
  __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
  __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
  __ movq(rax, rcx);
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);
  __ bind(&non_ascii);
  // At least one of the strings is two-byte. Check whether it happens
  // to contain only ascii characters.
  // rcx: first instance type AND second instance type.
  // r8: first instance type.
  // r9: second instance type.
  __ testb(rcx, Immediate(kAsciiDataHintMask));
  __ j(not_zero, &ascii_data);
  __ xor_(r8, r9);
  STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0);
  __ andb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag));
  __ cmpb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag));
  __ j(equal, &ascii_data);
  // Allocate a two byte cons string.
  __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime);
  __ jmp(&allocated);

  // Handle creating a flat result. First check that both strings are not
  // external strings.
  // rax: first string
  // rbx: length of resulting flat string as smi
  // rdx: second string
  // r8: instance type of first string
  // r9: instance type of first string
  __ bind(&string_add_flat_result);
  __ SmiToInteger32(rbx, rbx);
  __ movl(rcx, r8);
  __ and_(rcx, Immediate(kStringRepresentationMask));
  __ cmpl(rcx, Immediate(kExternalStringTag));
  __ j(equal, &string_add_runtime);
  __ movl(rcx, r9);
  __ and_(rcx, Immediate(kStringRepresentationMask));
  __ cmpl(rcx, Immediate(kExternalStringTag));
  __ j(equal, &string_add_runtime);
  // Now check if both strings are ascii strings.
  // rax: first string
  // rbx: length of resulting flat string
  // rdx: second string
  // r8: instance type of first string
  // r9: instance type of second string
  Label non_ascii_string_add_flat_result;
  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
  __ testl(r8, Immediate(kAsciiStringTag));
  __ j(zero, &non_ascii_string_add_flat_result);
  __ testl(r9, Immediate(kAsciiStringTag));
  __ j(zero, &string_add_runtime);

  __ bind(&make_flat_ascii_string);
  // Both strings are ascii strings. As they are short they are both flat.
  __ AllocateAsciiString(rcx, rbx, rdi, r14, r11, &string_add_runtime);
  // rcx: result string
  __ movq(rbx, rcx);
  // Locate first character of result.
  __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
  // Locate first character of first argument
  __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset));
  __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
  // rax: first char of first argument
  // rbx: result string
  // rcx: first character of result
  // rdx: second string
  // rdi: length of first argument
  StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, true);
  // Locate first character of second argument.
  __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset));
  __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
  // rbx: result string
  // rcx: next character of result
  // rdx: first char of second argument
  // rdi: length of second argument
  StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, true);
  __ movq(rax, rbx);
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);

  // Handle creating a flat two byte result.
  // rax: first string - known to be two byte
  // rbx: length of resulting flat string
  // rdx: second string
  // r8: instance type of first string
  // r9: instance type of first string
  __ bind(&non_ascii_string_add_flat_result);
  __ and_(r9, Immediate(kAsciiStringTag));
  __ j(not_zero, &string_add_runtime);
  // Both strings are two byte strings. As they are short they are both
  // flat.
  __ AllocateTwoByteString(rcx, rbx, rdi, r14, r11, &string_add_runtime);
  // rcx: result string
  __ movq(rbx, rcx);
  // Locate first character of result.
  __ addq(rcx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
  // Locate first character of first argument.
  __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset));
  __ addq(rax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
  // rax: first char of first argument
  // rbx: result string
  // rcx: first character of result
  // rdx: second argument
  // rdi: length of first argument
  StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, false);
  // Locate first character of second argument.
  __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset));
  __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
  // rbx: result string
  // rcx: next character of result
  // rdx: first char of second argument
  // rdi: length of second argument
  StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, false);
  __ movq(rax, rbx);
  __ IncrementCounter(counters->string_add_native(), 1);
  __ ret(2 * kPointerSize);

  // Just jump to runtime to add the two strings.
  __ bind(&string_add_runtime);
  __ TailCallRuntime(Runtime::kStringAdd, 2, 1);

  if (call_builtin.is_linked()) {
    __ bind(&call_builtin);
    __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
  }
}


void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
                                            int stack_offset,
                                            Register arg,
                                            Register scratch1,
                                            Register scratch2,
                                            Register scratch3,
                                            Label* slow) {
  // First check if the argument is already a string.
  Label not_string, done;
  __ JumpIfSmi(arg, &not_string);
  __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
  __ j(below, &done);

  // Check the number to string cache.
  Label not_cached;
  __ bind(&not_string);
  // Puts the cached result into scratch1.
  NumberToStringStub::GenerateLookupNumberStringCache(masm,
                                                      arg,
                                                      scratch1,
                                                      scratch2,
                                                      scratch3,
                                                      false,
                                                      &not_cached);
  __ movq(arg, scratch1);
  __ movq(Operand(rsp, stack_offset), arg);
  __ jmp(&done);

  // Check if the argument is a safe string wrapper.
  __ bind(&not_cached);
  __ JumpIfSmi(arg, slow);
  __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1);  // map -> scratch1.
  __ j(not_equal, slow);
  __ testb(FieldOperand(scratch1, Map::kBitField2Offset),
           Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
  __ j(zero, slow);
  __ movq(arg, FieldOperand(arg, JSValue::kValueOffset));
  __ movq(Operand(rsp, stack_offset), arg);

  __ bind(&done);
}


void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
                                          Register dest,
                                          Register src,
                                          Register count,
                                          bool ascii) {
  Label loop;
  __ bind(&loop);
  // This loop just copies one character at a time, as it is only used for very
  // short strings.
  if (ascii) {
    __ movb(kScratchRegister, Operand(src, 0));
    __ movb(Operand(dest, 0), kScratchRegister);
    __ incq(src);
    __ incq(dest);
  } else {
    __ movzxwl(kScratchRegister, Operand(src, 0));
    __ movw(Operand(dest, 0), kScratchRegister);
    __ addq(src, Immediate(2));
    __ addq(dest, Immediate(2));
  }
  __ decl(count);
  __ j(not_zero, &loop);
}


void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
                                             Register dest,
                                             Register src,
                                             Register count,
                                             bool ascii) {
  // Copy characters using rep movs of doublewords. Align destination on 4 byte
  // boundary before starting rep movs. Copy remaining characters after running
  // rep movs.
  // Count is positive int32, dest and src are character pointers.
  ASSERT(dest.is(rdi));  // rep movs destination
  ASSERT(src.is(rsi));  // rep movs source
  ASSERT(count.is(rcx));  // rep movs count

  // Nothing to do for zero characters.
  NearLabel done;
  __ testl(count, count);
  __ j(zero, &done);

  // Make count the number of bytes to copy.
  if (!ascii) {
    STATIC_ASSERT(2 == sizeof(uc16));
    __ addl(count, count);
  }

  // Don't enter the rep movs if there are less than 4 bytes to copy.
  NearLabel last_bytes;
  __ testl(count, Immediate(~7));
  __ j(zero, &last_bytes);

  // Copy from edi to esi using rep movs instruction.
  __ movl(kScratchRegister, count);
  __ shr(count, Immediate(3));  // Number of doublewords to copy.
  __ repmovsq();

  // Find number of bytes left.
  __ movl(count, kScratchRegister);
  __ and_(count, Immediate(7));

  // Check if there are more bytes to copy.
  __ bind(&last_bytes);
  __ testl(count, count);
  __ j(zero, &done);

  // Copy remaining characters.
  Label loop;
  __ bind(&loop);
  __ movb(kScratchRegister, Operand(src, 0));
  __ movb(Operand(dest, 0), kScratchRegister);
  __ incq(src);
  __ incq(dest);
  __ decl(count);
  __ j(not_zero, &loop);

  __ bind(&done);
}

void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
                                                        Register c1,
                                                        Register c2,
                                                        Register scratch1,
                                                        Register scratch2,
                                                        Register scratch3,
                                                        Register scratch4,
                                                        Label* not_found) {
  // Register scratch3 is the general scratch register in this function.
  Register scratch = scratch3;

  // Make sure that both characters are not digits as such strings has a
  // different hash algorithm. Don't try to look for these in the symbol table.
  NearLabel not_array_index;
  __ leal(scratch, Operand(c1, -'0'));
  __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
  __ j(above, &not_array_index);
  __ leal(scratch, Operand(c2, -'0'));
  __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
  __ j(below_equal, not_found);

  __ bind(&not_array_index);
  // Calculate the two character string hash.
  Register hash = scratch1;
  GenerateHashInit(masm, hash, c1, scratch);
  GenerateHashAddCharacter(masm, hash, c2, scratch);
  GenerateHashGetHash(masm, hash, scratch);

  // Collect the two characters in a register.
  Register chars = c1;
  __ shl(c2, Immediate(kBitsPerByte));
  __ orl(chars, c2);

  // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
  // hash:  hash of two character string.

  // Load the symbol table.
  Register symbol_table = c2;
  __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex);

  // Calculate capacity mask from the symbol table capacity.
  Register mask = scratch2;
  __ SmiToInteger32(mask,
                    FieldOperand(symbol_table, SymbolTable::kCapacityOffset));
  __ decl(mask);

  Register map = scratch4;

  // Registers
  // chars:        two character string, char 1 in byte 0 and char 2 in byte 1.
  // hash:         hash of two character string (32-bit int)
  // symbol_table: symbol table
  // mask:         capacity mask (32-bit int)
  // map:          -
  // scratch:      -

  // Perform a number of probes in the symbol table.
  static const int kProbes = 4;
  Label found_in_symbol_table;
  Label next_probe[kProbes];
  for (int i = 0; i < kProbes; i++) {
    // Calculate entry in symbol table.
    __ movl(scratch, hash);
    if (i > 0) {
      __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i)));
    }
    __ andl(scratch, mask);

    // Load the entry from the symbol table.
    Register candidate = scratch;  // Scratch register contains candidate.
    STATIC_ASSERT(SymbolTable::kEntrySize == 1);
    __ movq(candidate,
            FieldOperand(symbol_table,
                         scratch,
                         times_pointer_size,
                         SymbolTable::kElementsStartOffset));

    // If entry is undefined no string with this hash can be found.
    NearLabel is_string;
    __ CmpObjectType(candidate, ODDBALL_TYPE, map);
    __ j(not_equal, &is_string);

    __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
    __ j(equal, not_found);
    // Must be null (deleted entry).
    __ jmp(&next_probe[i]);

    __ bind(&is_string);

    // If length is not 2 the string is not a candidate.
    __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
                  Smi::FromInt(2));
    __ j(not_equal, &next_probe[i]);

    // We use kScratchRegister as a temporary register in assumption that
    // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
    Register temp = kScratchRegister;

    // Check that the candidate is a non-external ascii string.
    __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
    __ JumpIfInstanceTypeIsNotSequentialAscii(
        temp, temp, &next_probe[i]);

    // Check if the two characters match.
    __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
    __ andl(temp, Immediate(0x0000ffff));
    __ cmpl(chars, temp);
    __ j(equal, &found_in_symbol_table);
    __ bind(&next_probe[i]);
  }

  // No matching 2 character string found by probing.
  __ jmp(not_found);

  // Scratch register contains result when we fall through to here.
  Register result = scratch;
  __ bind(&found_in_symbol_table);
  if (!result.is(rax)) {
    __ movq(rax, result);
  }
}


void StringHelper::GenerateHashInit(MacroAssembler* masm,
                                    Register hash,
                                    Register character,
                                    Register scratch) {
  // hash = character + (character << 10);
  __ movl(hash, character);
  __ shll(hash, Immediate(10));
  __ addl(hash, character);
  // hash ^= hash >> 6;
  __ movl(scratch, hash);
  __ sarl(scratch, Immediate(6));
  __ xorl(hash, scratch);
}


void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
                                            Register hash,
                                            Register character,
                                            Register scratch) {
  // hash += character;
  __ addl(hash, character);
  // hash += hash << 10;
  __ movl(scratch, hash);
  __ shll(scratch, Immediate(10));
  __ addl(hash, scratch);
  // hash ^= hash >> 6;
  __ movl(scratch, hash);
  __ sarl(scratch, Immediate(6));
  __ xorl(hash, scratch);
}


void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
                                       Register hash,
                                       Register scratch) {
  // hash += hash << 3;
  __ leal(hash, Operand(hash, hash, times_8, 0));
  // hash ^= hash >> 11;
  __ movl(scratch, hash);
  __ sarl(scratch, Immediate(11));
  __ xorl(hash, scratch);
  // hash += hash << 15;
  __ movl(scratch, hash);
  __ shll(scratch, Immediate(15));
  __ addl(hash, scratch);

  // if (hash == 0) hash = 27;
  Label hash_not_zero;
  __ j(not_zero, &hash_not_zero);
  __ Set(hash, 27);
  __ bind(&hash_not_zero);
}

void SubStringStub::Generate(MacroAssembler* masm) {
  Label runtime;

  // Stack frame on entry.
  //  rsp[0]: return address
  //  rsp[8]: to
  //  rsp[16]: from
  //  rsp[24]: string

  const int kToOffset = 1 * kPointerSize;
  const int kFromOffset = kToOffset + kPointerSize;
  const int kStringOffset = kFromOffset + kPointerSize;
  const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;

  // Make sure first argument is a string.
  __ movq(rax, Operand(rsp, kStringOffset));
  STATIC_ASSERT(kSmiTag == 0);
  __ testl(rax, Immediate(kSmiTagMask));
  __ j(zero, &runtime);
  Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
  __ j(NegateCondition(is_string), &runtime);

  // rax: string
  // rbx: instance type
  // Calculate length of sub string using the smi values.
  Label result_longer_than_two;
  __ movq(rcx, Operand(rsp, kToOffset));
  __ movq(rdx, Operand(rsp, kFromOffset));
  __ JumpUnlessBothNonNegativeSmi(rcx, rdx, &runtime);

  __ SmiSub(rcx, rcx, rdx);  // Overflow doesn't happen.
  __ cmpq(FieldOperand(rax, String::kLengthOffset), rcx);
  Label return_rax;
  __ j(equal, &return_rax);
  // Special handling of sub-strings of length 1 and 2. One character strings
  // are handled in the runtime system (looked up in the single character
  // cache). Two character strings are looked for in the symbol cache.
  __ SmiToInteger32(rcx, rcx);
  __ cmpl(rcx, Immediate(2));
  __ j(greater, &result_longer_than_two);
  __ j(less, &runtime);

  // Sub string of length 2 requested.
  // rax: string
  // rbx: instance type
  // rcx: sub string length (value is 2)
  // rdx: from index (smi)
  __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &runtime);

  // Get the two characters forming the sub string.
  __ SmiToInteger32(rdx, rdx);  // From index is no longer smi.
  __ movzxbq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize));
  __ movzxbq(rcx,
             FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize + 1));

  // Try to lookup two character string in symbol table.
  Label make_two_character_string;
  StringHelper::GenerateTwoCharacterSymbolTableProbe(
      masm, rbx, rcx, rax, rdx, rdi, r14, &make_two_character_string);
  __ ret(3 * kPointerSize);

  __ bind(&make_two_character_string);
  // Setup registers for allocating the two character string.
  __ movq(rax, Operand(rsp, kStringOffset));
  __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
  __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
  __ Set(rcx, 2);

  __ bind(&result_longer_than_two);

  // rax: string
  // rbx: instance type
  // rcx: result string length
  // Check for flat ascii string
  Label non_ascii_flat;
  __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &non_ascii_flat);

  // Allocate the result.
  __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime);

  // rax: result string
  // rcx: result string length
  __ movq(rdx, rsi);  // esi used by following code.
  // Locate first character of result.
  __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize));
  // Load string argument and locate character of sub string start.
  __ movq(rsi, Operand(rsp, kStringOffset));
  __ movq(rbx, Operand(rsp, kFromOffset));
  {
    SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_1);
    __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
                        SeqAsciiString::kHeaderSize - kHeapObjectTag));
  }

  // rax: result string
  // rcx: result length
  // rdx: original value of rsi
  // rdi: first character of result
  // rsi: character of sub string start
  StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
  __ movq(rsi, rdx);  // Restore rsi.
  Counters* counters = masm->isolate()->counters();
  __ IncrementCounter(counters->sub_string_native(), 1);
  __ ret(kArgumentsSize);

  __ bind(&non_ascii_flat);
  // rax: string
  // rbx: instance type & kStringRepresentationMask | kStringEncodingMask
  // rcx: result string length
  // Check for sequential two byte string
  __ cmpb(rbx, Immediate(kSeqStringTag | kTwoByteStringTag));
  __ j(not_equal, &runtime);

  // Allocate the result.
  __ AllocateTwoByteString(rax, rcx, rbx, rdx, rdi, &runtime);

  // rax: result string
  // rcx: result string length
  __ movq(rdx, rsi);  // esi used by following code.
  // Locate first character of result.
  __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
  // Load string argument and locate character of sub string start.
  __ movq(rsi, Operand(rsp, kStringOffset));
  __ movq(rbx, Operand(rsp, kFromOffset));
  {
    SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_2);
    __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
                        SeqAsciiString::kHeaderSize - kHeapObjectTag));
  }

  // rax: result string
  // rcx: result length
  // rdx: original value of rsi
  // rdi: first character of result
  // rsi: character of sub string start
  StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
  __ movq(rsi, rdx);  // Restore esi.

  __ bind(&return_rax);
  __ IncrementCounter(counters->sub_string_native(), 1);
  __ ret(kArgumentsSize);

  // Just jump to runtime to create the sub string.
  __ bind(&runtime);
  __ TailCallRuntime(Runtime::kSubString, 3, 1);
}


void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
                                                        Register left,
                                                        Register right,
                                                        Register scratch1,
                                                        Register scratch2,
                                                        Register scratch3,
                                                        Register scratch4) {
  // Ensure that you can always subtract a string length from a non-negative
  // number (e.g. another length).
  STATIC_ASSERT(String::kMaxLength < 0x7fffffff);

  // Find minimum length and length difference.
  __ movq(scratch1, FieldOperand(left, String::kLengthOffset));
  __ movq(scratch4, scratch1);
  __ SmiSub(scratch4,
            scratch4,
            FieldOperand(right, String::kLengthOffset));
  // Register scratch4 now holds left.length - right.length.
  const Register length_difference = scratch4;
  NearLabel left_shorter;
  __ j(less, &left_shorter);
  // The right string isn't longer that the left one.
  // Get the right string's length by subtracting the (non-negative) difference
  // from the left string's length.
  __ SmiSub(scratch1, scratch1, length_difference);
  __ bind(&left_shorter);
  // Register scratch1 now holds Min(left.length, right.length).
  const Register min_length = scratch1;

  NearLabel compare_lengths;
  // If min-length is zero, go directly to comparing lengths.
  __ SmiTest(min_length);
  __ j(zero, &compare_lengths);

  __ SmiToInteger32(min_length, min_length);

  // Registers scratch2 and scratch3 are free.
  NearLabel result_not_equal;
  Label loop;
  {
    // Check characters 0 .. min_length - 1 in a loop.
    // Use scratch3 as loop index, min_length as limit and scratch2
    // for computation.
    const Register index = scratch3;
    __ Set(index, 0);  // Index into strings.
    __ bind(&loop);
    // Compare characters.
    // TODO(lrn): Could we load more than one character at a time?
    __ movb(scratch2, FieldOperand(left,
                                   index,
                                   times_1,
                                   SeqAsciiString::kHeaderSize));
    // Increment index and use -1 modifier on next load to give
    // the previous load extra time to complete.
    __ addl(index, Immediate(1));
    __ cmpb(scratch2, FieldOperand(right,
                                   index,
                                   times_1,
                                   SeqAsciiString::kHeaderSize - 1));
    __ j(not_equal, &result_not_equal);
    __ cmpl(index, min_length);
    __ j(not_equal, &loop);
  }
  // Completed loop without finding different characters.
  // Compare lengths (precomputed).
  __ bind(&compare_lengths);
  __ SmiTest(length_difference);
  __ j(not_zero, &result_not_equal);

  // Result is EQUAL.
  __ Move(rax, Smi::FromInt(EQUAL));
  __ ret(0);

  NearLabel result_greater;
  __ bind(&result_not_equal);
  // Unequal comparison of left to right, either character or length.
  __ j(greater, &result_greater);

  // Result is LESS.
  __ Move(rax, Smi::FromInt(LESS));
  __ ret(0);

  // Result is GREATER.
  __ bind(&result_greater);
  __ Move(rax, Smi::FromInt(GREATER));
  __ ret(0);
}


void StringCompareStub::Generate(MacroAssembler* masm) {
  Label runtime;

  // Stack frame on entry.
  //  rsp[0]: return address
  //  rsp[8]: right string
  //  rsp[16]: left string

  __ movq(rdx, Operand(rsp, 2 * kPointerSize));  // left
  __ movq(rax, Operand(rsp, 1 * kPointerSize));  // right

  // Check for identity.
  NearLabel not_same;
  __ cmpq(rdx, rax);
  __ j(not_equal, &not_same);
  __ Move(rax, Smi::FromInt(EQUAL));
  Counters* counters = masm->isolate()->counters();
  __ IncrementCounter(counters->string_compare_native(), 1);
  __ ret(2 * kPointerSize);

  __ bind(&not_same);

  // Check that both are sequential ASCII strings.
  __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime);

  // Inline comparison of ascii strings.
  __ IncrementCounter(counters->string_compare_native(), 1);
  // Drop arguments from the stack
  __ pop(rcx);
  __ addq(rsp, Immediate(2 * kPointerSize));
  __ push(rcx);
  GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8);

  // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
  // tagged as a small integer.
  __ bind(&runtime);
  __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
}


void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
  ASSERT(state_ == CompareIC::SMIS);
  NearLabel miss;
  __ JumpIfNotBothSmi(rdx, rax, &miss);

  if (GetCondition() == equal) {
    // For equality we do not care about the sign of the result.
    __ subq(rax, rdx);
  } else {
    NearLabel done;
    __ subq(rdx, rax);
    __ j(no_overflow, &done);
    // Correct sign of result in case of overflow.
    __ SmiNot(rdx, rdx);
    __ bind(&done);
    __ movq(rax, rdx);
  }
  __ ret(0);

  __ bind(&miss);
  GenerateMiss(masm);
}


void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
  ASSERT(state_ == CompareIC::HEAP_NUMBERS);

  NearLabel generic_stub;
  NearLabel unordered;
  NearLabel miss;
  Condition either_smi = masm->CheckEitherSmi(rax, rdx);
  __ j(either_smi, &generic_stub);

  __ CmpObjectType(rax, HEAP_NUMBER_TYPE, rcx);
  __ j(not_equal, &miss);
  __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
  __ j(not_equal, &miss);

  // Load left and right operand
  __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
  __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));

  // Compare operands
  __ ucomisd(xmm0, xmm1);

  // Don't base result on EFLAGS when a NaN is involved.
  __ j(parity_even, &unordered);

  // Return a result of -1, 0, or 1, based on EFLAGS.
  // Performing mov, because xor would destroy the flag register.
  __ movl(rax, Immediate(0));
  __ movl(rcx, Immediate(0));
  __ setcc(above, rax);  // Add one to zero if carry clear and not equal.
  __ sbbq(rax, rcx);  // Subtract one if below (aka. carry set).
  __ ret(0);

  __ bind(&unordered);

  CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS);
  __ bind(&generic_stub);
  __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);

  __ bind(&miss);
  GenerateMiss(masm);
}


void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
  ASSERT(state_ == CompareIC::OBJECTS);
  NearLabel miss;
  Condition either_smi = masm->CheckEitherSmi(rdx, rax);
  __ j(either_smi, &miss);

  __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx);
  __ j(not_equal, &miss, not_taken);
  __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
  __ j(not_equal, &miss, not_taken);

  ASSERT(GetCondition() == equal);
  __ subq(rax, rdx);
  __ ret(0);

  __ bind(&miss);
  GenerateMiss(masm);
}


void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
  // Save the registers.
  __ pop(rcx);
  __ push(rdx);
  __ push(rax);
  __ push(rcx);

  // Call the runtime system in a fresh internal frame.
  ExternalReference miss =
      ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
  __ EnterInternalFrame();
  __ push(rdx);
  __ push(rax);
  __ Push(Smi::FromInt(op_));
  __ CallExternalReference(miss, 3);
  __ LeaveInternalFrame();

  // Compute the entry point of the rewritten stub.
  __ lea(rdi, FieldOperand(rax, Code::kHeaderSize));

  // Restore registers.
  __ pop(rcx);
  __ pop(rax);
  __ pop(rdx);
  __ push(rcx);

  // Do a tail call to the rewritten stub.
  __ jmp(rdi);
}


#undef __

} }  // namespace v8::internal

#endif  // V8_TARGET_ARCH_X64
