// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_X64_MACRO_ASSEMBLER_X64_H_
#define V8_X64_MACRO_ASSEMBLER_X64_H_

#include "src/assembler.h"
#include "src/bailout-reason.h"
#include "src/frames.h"
#include "src/globals.h"

namespace v8 {
namespace internal {

// Default scratch register used by MacroAssembler (and other code that needs
// a spare register). The register isn't callee save, and not used by the
// function calling convention.
const Register kScratchRegister = { 10 };      // r10.
const Register kSmiConstantRegister = { 12 };  // r12 (callee save).
const Register kRootRegister = { 13 };         // r13 (callee save).
// Value of smi in kSmiConstantRegister.
const int kSmiConstantRegisterValue = 1;
// Actual value of root register is offset from the root array's start
// to take advantage of negitive 8-bit displacement values.
const int kRootRegisterBias = 128;

// Convenience for platform-independent signatures.
typedef Operand MemOperand;

enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
enum PointersToHereCheck {
  kPointersToHereMaybeInteresting,
  kPointersToHereAreAlwaysInteresting
};

enum SmiOperationConstraint {
  PRESERVE_SOURCE_REGISTER,
  BAILOUT_ON_NO_OVERFLOW,
  BAILOUT_ON_OVERFLOW,
  NUMBER_OF_CONSTRAINTS
};

STATIC_ASSERT(NUMBER_OF_CONSTRAINTS <= 8);

class SmiOperationExecutionMode : public EnumSet<SmiOperationConstraint, byte> {
 public:
  SmiOperationExecutionMode() : EnumSet<SmiOperationConstraint, byte>(0) { }
  explicit SmiOperationExecutionMode(byte bits)
      : EnumSet<SmiOperationConstraint, byte>(bits) { }
};

#ifdef DEBUG
bool AreAliased(Register reg1,
                Register reg2,
                Register reg3 = no_reg,
                Register reg4 = no_reg,
                Register reg5 = no_reg,
                Register reg6 = no_reg,
                Register reg7 = no_reg,
                Register reg8 = no_reg);
#endif

// Forward declaration.
class JumpTarget;

struct SmiIndex {
  SmiIndex(Register index_register, ScaleFactor scale)
      : reg(index_register),
        scale(scale) {}
  Register reg;
  ScaleFactor scale;
};


// MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler {
 public:
  // The isolate parameter can be NULL if the macro assembler should
  // not use isolate-dependent functionality. In this case, it's the
  // responsibility of the caller to never invoke such function on the
  // macro assembler.
  MacroAssembler(Isolate* isolate, void* buffer, int size);

  // Prevent the use of the RootArray during the lifetime of this
  // scope object.
  class NoRootArrayScope BASE_EMBEDDED {
   public:
    explicit NoRootArrayScope(MacroAssembler* assembler)
        : variable_(&assembler->root_array_available_),
          old_value_(assembler->root_array_available_) {
      assembler->root_array_available_ = false;
    }
    ~NoRootArrayScope() {
      *variable_ = old_value_;
    }
   private:
    bool* variable_;
    bool old_value_;
  };

  // Operand pointing to an external reference.
  // May emit code to set up the scratch register. The operand is
  // only guaranteed to be correct as long as the scratch register
  // isn't changed.
  // If the operand is used more than once, use a scratch register
  // that is guaranteed not to be clobbered.
  Operand ExternalOperand(ExternalReference reference,
                          Register scratch = kScratchRegister);
  // Loads and stores the value of an external reference.
  // Special case code for load and store to take advantage of
  // load_rax/store_rax if possible/necessary.
  // For other operations, just use:
  //   Operand operand = ExternalOperand(extref);
  //   operation(operand, ..);
  void Load(Register destination, ExternalReference source);
  void Store(ExternalReference destination, Register source);
  // Loads the address of the external reference into the destination
  // register.
  void LoadAddress(Register destination, ExternalReference source);
  // Returns the size of the code generated by LoadAddress.
  // Used by CallSize(ExternalReference) to find the size of a call.
  int LoadAddressSize(ExternalReference source);
  // Pushes the address of the external reference onto the stack.
  void PushAddress(ExternalReference source);

  // Operations on roots in the root-array.
  void LoadRoot(Register destination, Heap::RootListIndex index);
  void StoreRoot(Register source, Heap::RootListIndex index);
  // Load a root value where the index (or part of it) is variable.
  // The variable_offset register is added to the fixed_offset value
  // to get the index into the root-array.
  void LoadRootIndexed(Register destination,
                       Register variable_offset,
                       int fixed_offset);
  void CompareRoot(Register with, Heap::RootListIndex index);
  void CompareRoot(const Operand& with, Heap::RootListIndex index);
  void PushRoot(Heap::RootListIndex index);

  // These functions do not arrange the registers in any particular order so
  // they are not useful for calls that can cause a GC.  The caller can
  // exclude up to 3 registers that do not need to be saved and restored.
  void PushCallerSaved(SaveFPRegsMode fp_mode,
                       Register exclusion1 = no_reg,
                       Register exclusion2 = no_reg,
                       Register exclusion3 = no_reg);
  void PopCallerSaved(SaveFPRegsMode fp_mode,
                      Register exclusion1 = no_reg,
                      Register exclusion2 = no_reg,
                      Register exclusion3 = no_reg);

// ---------------------------------------------------------------------------
// GC Support


  enum RememberedSetFinalAction {
    kReturnAtEnd,
    kFallThroughAtEnd
  };

  // Record in the remembered set the fact that we have a pointer to new space
  // at the address pointed to by the addr register.  Only works if addr is not
  // in new space.
  void RememberedSetHelper(Register object,  // Used for debug code.
                           Register addr,
                           Register scratch,
                           SaveFPRegsMode save_fp,
                           RememberedSetFinalAction and_then);

  void CheckPageFlag(Register object,
                     Register scratch,
                     int mask,
                     Condition cc,
                     Label* condition_met,
                     Label::Distance condition_met_distance = Label::kFar);

  // Check if object is in new space.  Jumps if the object is not in new space.
  // The register scratch can be object itself, but scratch will be clobbered.
  void JumpIfNotInNewSpace(Register object,
                           Register scratch,
                           Label* branch,
                           Label::Distance distance = Label::kFar) {
    InNewSpace(object, scratch, not_equal, branch, distance);
  }

  // Check if object is in new space.  Jumps if the object is in new space.
  // The register scratch can be object itself, but it will be clobbered.
  void JumpIfInNewSpace(Register object,
                        Register scratch,
                        Label* branch,
                        Label::Distance distance = Label::kFar) {
    InNewSpace(object, scratch, equal, branch, distance);
  }

  // Check if an object has the black incremental marking color.  Also uses rcx!
  void JumpIfBlack(Register object,
                   Register scratch0,
                   Register scratch1,
                   Label* on_black,
                   Label::Distance on_black_distance = Label::kFar);

  // Detects conservatively whether an object is data-only, i.e. it does need to
  // be scanned by the garbage collector.
  void JumpIfDataObject(Register value,
                        Register scratch,
                        Label* not_data_object,
                        Label::Distance not_data_object_distance);

  // Checks the color of an object.  If the object is already grey or black
  // then we just fall through, since it is already live.  If it is white and
  // we can determine that it doesn't need to be scanned, then we just mark it
  // black and fall through.  For the rest we jump to the label so the
  // incremental marker can fix its assumptions.
  void EnsureNotWhite(Register object,
                      Register scratch1,
                      Register scratch2,
                      Label* object_is_white_and_not_data,
                      Label::Distance distance);

  // Notify the garbage collector that we wrote a pointer into an object.
  // |object| is the object being stored into, |value| is the object being
  // stored.  value and scratch registers are clobbered by the operation.
  // The offset is the offset from the start of the object, not the offset from
  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
  void RecordWriteField(
      Register object,
      int offset,
      Register value,
      Register scratch,
      SaveFPRegsMode save_fp,
      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
      SmiCheck smi_check = INLINE_SMI_CHECK,
      PointersToHereCheck pointers_to_here_check_for_value =
          kPointersToHereMaybeInteresting);

  // As above, but the offset has the tag presubtracted.  For use with
  // Operand(reg, off).
  void RecordWriteContextSlot(
      Register context,
      int offset,
      Register value,
      Register scratch,
      SaveFPRegsMode save_fp,
      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
      SmiCheck smi_check = INLINE_SMI_CHECK,
      PointersToHereCheck pointers_to_here_check_for_value =
          kPointersToHereMaybeInteresting) {
    RecordWriteField(context,
                     offset + kHeapObjectTag,
                     value,
                     scratch,
                     save_fp,
                     remembered_set_action,
                     smi_check,
                     pointers_to_here_check_for_value);
  }

  // Notify the garbage collector that we wrote a pointer into a fixed array.
  // |array| is the array being stored into, |value| is the
  // object being stored.  |index| is the array index represented as a non-smi.
  // All registers are clobbered by the operation RecordWriteArray
  // filters out smis so it does not update the write barrier if the
  // value is a smi.
  void RecordWriteArray(
      Register array,
      Register value,
      Register index,
      SaveFPRegsMode save_fp,
      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
      SmiCheck smi_check = INLINE_SMI_CHECK,
      PointersToHereCheck pointers_to_here_check_for_value =
          kPointersToHereMaybeInteresting);

  void RecordWriteForMap(
      Register object,
      Register map,
      Register dst,
      SaveFPRegsMode save_fp);

  // For page containing |object| mark region covering |address|
  // dirty. |object| is the object being stored into, |value| is the
  // object being stored. The address and value registers are clobbered by the
  // operation.  RecordWrite filters out smis so it does not update
  // the write barrier if the value is a smi.
  void RecordWrite(
      Register object,
      Register address,
      Register value,
      SaveFPRegsMode save_fp,
      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
      SmiCheck smi_check = INLINE_SMI_CHECK,
      PointersToHereCheck pointers_to_here_check_for_value =
          kPointersToHereMaybeInteresting);

  // ---------------------------------------------------------------------------
  // Debugger Support

  void DebugBreak();

  // Generates function and stub prologue code.
  void StubPrologue();
  void Prologue(bool code_pre_aging);

  // Enter specific kind of exit frame; either in normal or
  // debug mode. Expects the number of arguments in register rax and
  // sets up the number of arguments in register rdi and the pointer
  // to the first argument in register rsi.
  //
  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
  // accessible via StackSpaceOperand.
  void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false);

  // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize
  // memory (not GCed) on the stack accessible via StackSpaceOperand.
  void EnterApiExitFrame(int arg_stack_space);

  // Leave the current exit frame. Expects/provides the return value in
  // register rax:rdx (untouched) and the pointer to the first
  // argument in register rsi.
  void LeaveExitFrame(bool save_doubles = false);

  // Leave the current exit frame. Expects/provides the return value in
  // register rax (untouched).
  void LeaveApiExitFrame(bool restore_context);

  // Push and pop the registers that can hold pointers.
  void PushSafepointRegisters() { Pushad(); }
  void PopSafepointRegisters() { Popad(); }
  // Store the value in register src in the safepoint register stack
  // slot for register dst.
  void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm);
  void StoreToSafepointRegisterSlot(Register dst, Register src);
  void LoadFromSafepointRegisterSlot(Register dst, Register src);

  void InitializeRootRegister() {
    ExternalReference roots_array_start =
        ExternalReference::roots_array_start(isolate());
    Move(kRootRegister, roots_array_start);
    addp(kRootRegister, Immediate(kRootRegisterBias));
  }

  // ---------------------------------------------------------------------------
  // JavaScript invokes

  // Invoke the JavaScript function code by either calling or jumping.
  void InvokeCode(Register code,
                  const ParameterCount& expected,
                  const ParameterCount& actual,
                  InvokeFlag flag,
                  const CallWrapper& call_wrapper);

  // Invoke the JavaScript function in the given register. Changes the
  // current context to the context in the function before invoking.
  void InvokeFunction(Register function,
                      const ParameterCount& actual,
                      InvokeFlag flag,
                      const CallWrapper& call_wrapper);

  void InvokeFunction(Register function,
                      const ParameterCount& expected,
                      const ParameterCount& actual,
                      InvokeFlag flag,
                      const CallWrapper& call_wrapper);

  void InvokeFunction(Handle<JSFunction> function,
                      const ParameterCount& expected,
                      const ParameterCount& actual,
                      InvokeFlag flag,
                      const CallWrapper& call_wrapper);

  // Invoke specified builtin JavaScript function. Adds an entry to
  // the unresolved list if the name does not resolve.
  void InvokeBuiltin(Builtins::JavaScript id,
                     InvokeFlag flag,
                     const CallWrapper& call_wrapper = NullCallWrapper());

  // Store the function for the given builtin in the target register.
  void GetBuiltinFunction(Register target, Builtins::JavaScript id);

  // Store the code object for the given builtin in the target register.
  void GetBuiltinEntry(Register target, Builtins::JavaScript id);


  // ---------------------------------------------------------------------------
  // Smi tagging, untagging and operations on tagged smis.

  // Support for constant splitting.
  bool IsUnsafeInt(const int32_t x);
  void SafeMove(Register dst, Smi* src);
  void SafePush(Smi* src);

  void InitializeSmiConstantRegister() {
    Move(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue),
         Assembler::RelocInfoNone());
  }

  // Conversions between tagged smi values and non-tagged integer values.

  // Tag an integer value. The result must be known to be a valid smi value.
  // Only uses the low 32 bits of the src register. Sets the N and Z flags
  // based on the value of the resulting smi.
  void Integer32ToSmi(Register dst, Register src);

  // Stores an integer32 value into a memory field that already holds a smi.
  void Integer32ToSmiField(const Operand& dst, Register src);

  // Adds constant to src and tags the result as a smi.
  // Result must be a valid smi.
  void Integer64PlusConstantToSmi(Register dst, Register src, int constant);

  // Convert smi to 32-bit integer. I.e., not sign extended into
  // high 32 bits of destination.
  void SmiToInteger32(Register dst, Register src);
  void SmiToInteger32(Register dst, const Operand& src);

  // Convert smi to 64-bit integer (sign extended if necessary).
  void SmiToInteger64(Register dst, Register src);
  void SmiToInteger64(Register dst, const Operand& src);

  // Multiply a positive smi's integer value by a power of two.
  // Provides result as 64-bit integer value.
  void PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
                                             Register src,
                                             int power);

  // Divide a positive smi's integer value by a power of two.
  // Provides result as 32-bit integer value.
  void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
                                           Register src,
                                           int power);

  // Perform the logical or of two smi values and return a smi value.
  // If either argument is not a smi, jump to on_not_smis and retain
  // the original values of source registers. The destination register
  // may be changed if it's not one of the source registers.
  void SmiOrIfSmis(Register dst,
                   Register src1,
                   Register src2,
                   Label* on_not_smis,
                   Label::Distance near_jump = Label::kFar);


  // Simple comparison of smis.  Both sides must be known smis to use these,
  // otherwise use Cmp.
  void SmiCompare(Register smi1, Register smi2);
  void SmiCompare(Register dst, Smi* src);
  void SmiCompare(Register dst, const Operand& src);
  void SmiCompare(const Operand& dst, Register src);
  void SmiCompare(const Operand& dst, Smi* src);
  // Compare the int32 in src register to the value of the smi stored at dst.
  void SmiCompareInteger32(const Operand& dst, Register src);
  // Sets sign and zero flags depending on value of smi in register.
  void SmiTest(Register src);

  // Functions performing a check on a known or potential smi. Returns
  // a condition that is satisfied if the check is successful.

  // Is the value a tagged smi.
  Condition CheckSmi(Register src);
  Condition CheckSmi(const Operand& src);

  // Is the value a non-negative tagged smi.
  Condition CheckNonNegativeSmi(Register src);

  // Are both values tagged smis.
  Condition CheckBothSmi(Register first, Register second);

  // Are both values non-negative tagged smis.
  Condition CheckBothNonNegativeSmi(Register first, Register second);

  // Are either value a tagged smi.
  Condition CheckEitherSmi(Register first,
                           Register second,
                           Register scratch = kScratchRegister);

  // Is the value the minimum smi value (since we are using
  // two's complement numbers, negating the value is known to yield
  // a non-smi value).
  Condition CheckIsMinSmi(Register src);

  // Checks whether an 32-bit integer value is a valid for conversion
  // to a smi.
  Condition CheckInteger32ValidSmiValue(Register src);

  // Checks whether an 32-bit unsigned integer value is a valid for
  // conversion to a smi.
  Condition CheckUInteger32ValidSmiValue(Register src);

  // Check whether src is a Smi, and set dst to zero if it is a smi,
  // and to one if it isn't.
  void CheckSmiToIndicator(Register dst, Register src);
  void CheckSmiToIndicator(Register dst, const Operand& src);

  // Test-and-jump functions. Typically combines a check function
  // above with a conditional jump.

  // Jump if the value can be represented by a smi.
  void JumpIfValidSmiValue(Register src, Label* on_valid,
                           Label::Distance near_jump = Label::kFar);

  // Jump if the value cannot be represented by a smi.
  void JumpIfNotValidSmiValue(Register src, Label* on_invalid,
                              Label::Distance near_jump = Label::kFar);

  // Jump if the unsigned integer value can be represented by a smi.
  void JumpIfUIntValidSmiValue(Register src, Label* on_valid,
                               Label::Distance near_jump = Label::kFar);

  // Jump if the unsigned integer value cannot be represented by a smi.
  void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid,
                                  Label::Distance near_jump = Label::kFar);

  // Jump to label if the value is a tagged smi.
  void JumpIfSmi(Register src,
                 Label* on_smi,
                 Label::Distance near_jump = Label::kFar);

  // Jump to label if the value is not a tagged smi.
  void JumpIfNotSmi(Register src,
                    Label* on_not_smi,
                    Label::Distance near_jump = Label::kFar);

  // Jump to label if the value is not a non-negative tagged smi.
  void JumpUnlessNonNegativeSmi(Register src,
                                Label* on_not_smi,
                                Label::Distance near_jump = Label::kFar);

  // Jump to label if the value, which must be a tagged smi, has value equal
  // to the constant.
  void JumpIfSmiEqualsConstant(Register src,
                               Smi* constant,
                               Label* on_equals,
                               Label::Distance near_jump = Label::kFar);

  // Jump if either or both register are not smi values.
  void JumpIfNotBothSmi(Register src1,
                        Register src2,
                        Label* on_not_both_smi,
                        Label::Distance near_jump = Label::kFar);

  // Jump if either or both register are not non-negative smi values.
  void JumpUnlessBothNonNegativeSmi(Register src1, Register src2,
                                    Label* on_not_both_smi,
                                    Label::Distance near_jump = Label::kFar);

  // Operations on tagged smi values.

  // Smis represent a subset of integers. The subset is always equivalent to
  // a two's complement interpretation of a fixed number of bits.

  // Add an integer constant to a tagged smi, giving a tagged smi as result.
  // No overflow testing on the result is done.
  void SmiAddConstant(Register dst, Register src, Smi* constant);

  // Add an integer constant to a tagged smi, giving a tagged smi as result.
  // No overflow testing on the result is done.
  void SmiAddConstant(const Operand& dst, Smi* constant);

  // Add an integer constant to a tagged smi, giving a tagged smi as result,
  // or jumping to a label if the result cannot be represented by a smi.
  void SmiAddConstant(Register dst,
                      Register src,
                      Smi* constant,
                      SmiOperationExecutionMode mode,
                      Label* bailout_label,
                      Label::Distance near_jump = Label::kFar);

  // Subtract an integer constant from a tagged smi, giving a tagged smi as
  // result. No testing on the result is done. Sets the N and Z flags
  // based on the value of the resulting integer.
  void SmiSubConstant(Register dst, Register src, Smi* constant);

  // Subtract an integer constant from a tagged smi, giving a tagged smi as
  // result, or jumping to a label if the result cannot be represented by a smi.
  void SmiSubConstant(Register dst,
                      Register src,
                      Smi* constant,
                      SmiOperationExecutionMode mode,
                      Label* bailout_label,
                      Label::Distance near_jump = Label::kFar);

  // Negating a smi can give a negative zero or too large positive value.
  // NOTICE: This operation jumps on success, not failure!
  void SmiNeg(Register dst,
              Register src,
              Label* on_smi_result,
              Label::Distance near_jump = Label::kFar);

  // Adds smi values and return the result as a smi.
  // If dst is src1, then src1 will be destroyed if the operation is
  // successful, otherwise kept intact.
  void SmiAdd(Register dst,
              Register src1,
              Register src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);
  void SmiAdd(Register dst,
              Register src1,
              const Operand& src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);

  void SmiAdd(Register dst,
              Register src1,
              Register src2);

  // Subtracts smi values and return the result as a smi.
  // If dst is src1, then src1 will be destroyed if the operation is
  // successful, otherwise kept intact.
  void SmiSub(Register dst,
              Register src1,
              Register src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);
  void SmiSub(Register dst,
              Register src1,
              const Operand& src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);

  void SmiSub(Register dst,
              Register src1,
              Register src2);

  void SmiSub(Register dst,
              Register src1,
              const Operand& src2);

  // Multiplies smi values and return the result as a smi,
  // if possible.
  // If dst is src1, then src1 will be destroyed, even if
  // the operation is unsuccessful.
  void SmiMul(Register dst,
              Register src1,
              Register src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);

  // Divides one smi by another and returns the quotient.
  // Clobbers rax and rdx registers.
  void SmiDiv(Register dst,
              Register src1,
              Register src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);

  // Divides one smi by another and returns the remainder.
  // Clobbers rax and rdx registers.
  void SmiMod(Register dst,
              Register src1,
              Register src2,
              Label* on_not_smi_result,
              Label::Distance near_jump = Label::kFar);

  // Bitwise operations.
  void SmiNot(Register dst, Register src);
  void SmiAnd(Register dst, Register src1, Register src2);
  void SmiOr(Register dst, Register src1, Register src2);
  void SmiXor(Register dst, Register src1, Register src2);
  void SmiAndConstant(Register dst, Register src1, Smi* constant);
  void SmiOrConstant(Register dst, Register src1, Smi* constant);
  void SmiXorConstant(Register dst, Register src1, Smi* constant);

  void SmiShiftLeftConstant(Register dst,
                            Register src,
                            int shift_value,
                            Label* on_not_smi_result = NULL,
                            Label::Distance near_jump = Label::kFar);
  void SmiShiftLogicalRightConstant(Register dst,
                                    Register src,
                                    int shift_value,
                                    Label* on_not_smi_result,
                                    Label::Distance near_jump = Label::kFar);
  void SmiShiftArithmeticRightConstant(Register dst,
                                       Register src,
                                       int shift_value);

  // Shifts a smi value to the left, and returns the result if that is a smi.
  // Uses and clobbers rcx, so dst may not be rcx.
  void SmiShiftLeft(Register dst,
                    Register src1,
                    Register src2,
                    Label* on_not_smi_result = NULL,
                    Label::Distance near_jump = Label::kFar);
  // Shifts a smi value to the right, shifting in zero bits at the top, and
  // returns the unsigned intepretation of the result if that is a smi.
  // Uses and clobbers rcx, so dst may not be rcx.
  void SmiShiftLogicalRight(Register dst,
                            Register src1,
                            Register src2,
                            Label* on_not_smi_result,
                            Label::Distance near_jump = Label::kFar);
  // Shifts a smi value to the right, sign extending the top, and
  // returns the signed intepretation of the result. That will always
  // be a valid smi value, since it's numerically smaller than the
  // original.
  // Uses and clobbers rcx, so dst may not be rcx.
  void SmiShiftArithmeticRight(Register dst,
                               Register src1,
                               Register src2);

  // Specialized operations

  // Select the non-smi register of two registers where exactly one is a
  // smi. If neither are smis, jump to the failure label.
  void SelectNonSmi(Register dst,
                    Register src1,
                    Register src2,
                    Label* on_not_smis,
                    Label::Distance near_jump = Label::kFar);

  // Converts, if necessary, a smi to a combination of number and
  // multiplier to be used as a scaled index.
  // The src register contains a *positive* smi value. The shift is the
  // power of two to multiply the index value by (e.g.
  // to index by smi-value * kPointerSize, pass the smi and kPointerSizeLog2).
  // The returned index register may be either src or dst, depending
  // on what is most efficient. If src and dst are different registers,
  // src is always unchanged.
  SmiIndex SmiToIndex(Register dst, Register src, int shift);

  // Converts a positive smi to a negative index.
  SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);

  // Add the value of a smi in memory to an int32 register.
  // Sets flags as a normal add.
  void AddSmiField(Register dst, const Operand& src);

  // Basic Smi operations.
  void Move(Register dst, Smi* source) {
    LoadSmiConstant(dst, source);
  }

  void Move(const Operand& dst, Smi* source) {
    Register constant = GetSmiConstant(source);
    movp(dst, constant);
  }

  void Push(Smi* smi);

  // Save away a raw integer with pointer size on the stack as two integers
  // masquerading as smis so that the garbage collector skips visiting them.
  void PushRegisterAsTwoSmis(Register src, Register scratch = kScratchRegister);
  // Reconstruct a raw integer with pointer size from two integers masquerading
  // as smis on the top of stack.
  void PopRegisterAsTwoSmis(Register dst, Register scratch = kScratchRegister);

  void Test(const Operand& dst, Smi* source);


  // ---------------------------------------------------------------------------
  // String macros.

  // Generate code to do a lookup in the number string cache. If the number in
  // the register object is found in the cache the generated code falls through
  // with the result in the result register. The object and the result register
  // can be the same. If the number is not found in the cache the code jumps to
  // the label not_found with only the content of register object unchanged.
  void LookupNumberStringCache(Register object,
                               Register result,
                               Register scratch1,
                               Register scratch2,
                               Label* not_found);

  // If object is a string, its map is loaded into object_map.
  void JumpIfNotString(Register object,
                       Register object_map,
                       Label* not_string,
                       Label::Distance near_jump = Label::kFar);


  void JumpIfNotBothSequentialOneByteStrings(
      Register first_object, Register second_object, Register scratch1,
      Register scratch2, Label* on_not_both_flat_one_byte,
      Label::Distance near_jump = Label::kFar);

  // Check whether the instance type represents a flat one-byte string. Jump
  // to the label if not. If the instance type can be scratched specify same
  // register for both instance type and scratch.
  void JumpIfInstanceTypeIsNotSequentialOneByte(
      Register instance_type, Register scratch,
      Label* on_not_flat_one_byte_string,
      Label::Distance near_jump = Label::kFar);

  void JumpIfBothInstanceTypesAreNotSequentialOneByte(
      Register first_object_instance_type, Register second_object_instance_type,
      Register scratch1, Register scratch2, Label* on_fail,
      Label::Distance near_jump = Label::kFar);

  void EmitSeqStringSetCharCheck(Register string,
                                 Register index,
                                 Register value,
                                 uint32_t encoding_mask);

  // Checks if the given register or operand is a unique name
  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name,
                                       Label::Distance distance = Label::kFar);
  void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name,
                                       Label::Distance distance = Label::kFar);

  // ---------------------------------------------------------------------------
  // Macro instructions.

  // Load/store with specific representation.
  void Load(Register dst, const Operand& src, Representation r);
  void Store(const Operand& dst, Register src, Representation r);

  // Load a register with a long value as efficiently as possible.
  void Set(Register dst, int64_t x);
  void Set(const Operand& dst, intptr_t x);

  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
  // hinders register renaming and makes dependence chains longer. So we use
  // xorps to clear the dst register before cvtsi2sd to solve this issue.
  void Cvtlsi2sd(XMMRegister dst, Register src);
  void Cvtlsi2sd(XMMRegister dst, const Operand& src);

  // Move if the registers are not identical.
  void Move(Register target, Register source);

  // TestBit and Load SharedFunctionInfo special field.
  void TestBitSharedFunctionInfoSpecialField(Register base,
                                             int offset,
                                             int bit_index);
  void LoadSharedFunctionInfoSpecialField(Register dst,
                                          Register base,
                                          int offset);

  // Handle support
  void Move(Register dst, Handle<Object> source);
  void Move(const Operand& dst, Handle<Object> source);
  void Cmp(Register dst, Handle<Object> source);
  void Cmp(const Operand& dst, Handle<Object> source);
  void Cmp(Register dst, Smi* src);
  void Cmp(const Operand& dst, Smi* src);
  void Push(Handle<Object> source);

  // Load a heap object and handle the case of new-space objects by
  // indirecting via a global cell.
  void MoveHeapObject(Register result, Handle<Object> object);

  // Load a global cell into a register.
  void LoadGlobalCell(Register dst, Handle<Cell> cell);

  // Compare the given value and the value of weak cell.
  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);

  // Load the value of the weak cell in the value register. Branch to the given
  // miss label if the weak cell was cleared.
  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);

  // Emit code to discard a non-negative number of pointer-sized elements
  // from the stack, clobbering only the rsp register.
  void Drop(int stack_elements);
  // Emit code to discard a positive number of pointer-sized elements
  // from the stack under the return address which remains on the top,
  // clobbering the rsp register.
  void DropUnderReturnAddress(int stack_elements,
                              Register scratch = kScratchRegister);

  void Call(Label* target) { call(target); }
  void Push(Register src);
  void Push(const Operand& src);
  void PushQuad(const Operand& src);
  void Push(Immediate value);
  void PushImm32(int32_t imm32);
  void Pop(Register dst);
  void Pop(const Operand& dst);
  void PopQuad(const Operand& dst);
  void PushReturnAddressFrom(Register src) { pushq(src); }
  void PopReturnAddressTo(Register dst) { popq(dst); }
  void Move(Register dst, ExternalReference ext) {
    movp(dst, reinterpret_cast<void*>(ext.address()),
         RelocInfo::EXTERNAL_REFERENCE);
  }

  // Loads a pointer into a register with a relocation mode.
  void Move(Register dst, void* ptr, RelocInfo::Mode rmode) {
    // This method must not be used with heap object references. The stored
    // address is not GC safe. Use the handle version instead.
    DCHECK(rmode > RelocInfo::LAST_GCED_ENUM);
    movp(dst, ptr, rmode);
  }

  void Move(Register dst, Handle<Object> value, RelocInfo::Mode rmode) {
    AllowDeferredHandleDereference using_raw_address;
    DCHECK(!RelocInfo::IsNone(rmode));
    DCHECK(value->IsHeapObject());
    DCHECK(!isolate()->heap()->InNewSpace(*value));
    movp(dst, reinterpret_cast<void*>(value.location()), rmode);
  }

  void Move(XMMRegister dst, uint32_t src);
  void Move(XMMRegister dst, uint64_t src);

  // Control Flow
  void Jump(Address destination, RelocInfo::Mode rmode);
  void Jump(ExternalReference ext);
  void Jump(const Operand& op);
  void Jump(Handle<Code> code_object, RelocInfo::Mode rmode);

  void Call(Address destination, RelocInfo::Mode rmode);
  void Call(ExternalReference ext);
  void Call(const Operand& op);
  void Call(Handle<Code> code_object,
            RelocInfo::Mode rmode,
            TypeFeedbackId ast_id = TypeFeedbackId::None());

  // The size of the code generated for different call instructions.
  int CallSize(Address destination) {
    return kCallSequenceLength;
  }
  int CallSize(ExternalReference ext);
  int CallSize(Handle<Code> code_object) {
    // Code calls use 32-bit relative addressing.
    return kShortCallInstructionLength;
  }
  int CallSize(Register target) {
    // Opcode: REX_opt FF /2 m64
    return (target.high_bit() != 0) ? 3 : 2;
  }
  int CallSize(const Operand& target) {
    // Opcode: REX_opt FF /2 m64
    return (target.requires_rex() ? 2 : 1) + target.operand_size();
  }

  // Emit call to the code we are currently generating.
  void CallSelf() {
    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
    Call(self, RelocInfo::CODE_TARGET);
  }

  // Non-x64 instructions.
  // Push/pop all general purpose registers.
  // Does not push rsp/rbp nor any of the assembler's special purpose registers
  // (kScratchRegister, kSmiConstantRegister, kRootRegister).
  void Pushad();
  void Popad();
  // Sets the stack as after performing Popad, without actually loading the
  // registers.
  void Dropad();

  // Compare object type for heap object.
  // Always use unsigned comparisons: above and below, not less and greater.
  // Incoming register is heap_object and outgoing register is map.
  // They may be the same register, and may be kScratchRegister.
  void CmpObjectType(Register heap_object, InstanceType type, Register map);

  // Compare instance type for map.
  // Always use unsigned comparisons: above and below, not less and greater.
  void CmpInstanceType(Register map, InstanceType type);

  // Check if a map for a JSObject indicates that the object has fast elements.
  // Jump to the specified label if it does not.
  void CheckFastElements(Register map,
                         Label* fail,
                         Label::Distance distance = Label::kFar);

  // Check if a map for a JSObject indicates that the object can have both smi
  // and HeapObject elements.  Jump to the specified label if it does not.
  void CheckFastObjectElements(Register map,
                               Label* fail,
                               Label::Distance distance = Label::kFar);

  // Check if a map for a JSObject indicates that the object has fast smi only
  // elements.  Jump to the specified label if it does not.
  void CheckFastSmiElements(Register map,
                            Label* fail,
                            Label::Distance distance = Label::kFar);

  // Check to see if maybe_number can be stored as a double in
  // FastDoubleElements. If it can, store it at the index specified by index in
  // the FastDoubleElements array elements, otherwise jump to fail.  Note that
  // index must not be smi-tagged.
  void StoreNumberToDoubleElements(Register maybe_number,
                                   Register elements,
                                   Register index,
                                   XMMRegister xmm_scratch,
                                   Label* fail,
                                   int elements_offset = 0);

  // Compare an object's map with the specified map.
  void CompareMap(Register obj, Handle<Map> map);

  // Check if the map of an object is equal to a specified map and branch to
  // label if not. Skip the smi check if not required (object is known to be a
  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
  // against maps that are ElementsKind transition maps of the specified map.
  void CheckMap(Register obj,
                Handle<Map> map,
                Label* fail,
                SmiCheckType smi_check_type);

  // Check if the map of an object is equal to a specified weak map and branch
  // to a specified target if equal. Skip the smi check if not required
  // (object is known to be a heap object)
  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
                       Handle<WeakCell> cell, Handle<Code> success,
                       SmiCheckType smi_check_type);

  // Check if the object in register heap_object is a string. Afterwards the
  // register map contains the object map and the register instance_type
  // contains the instance_type. The registers map and instance_type can be the
  // same in which case it contains the instance type afterwards. Either of the
  // registers map and instance_type can be the same as heap_object.
  Condition IsObjectStringType(Register heap_object,
                               Register map,
                               Register instance_type);

  // Check if the object in register heap_object is a name. Afterwards the
  // register map contains the object map and the register instance_type
  // contains the instance_type. The registers map and instance_type can be the
  // same in which case it contains the instance type afterwards. Either of the
  // registers map and instance_type can be the same as heap_object.
  Condition IsObjectNameType(Register heap_object,
                             Register map,
                             Register instance_type);

  // FCmp compares and pops the two values on top of the FPU stack.
  // The flag results are similar to integer cmp, but requires unsigned
  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
  void FCmp();

  void ClampUint8(Register reg);

  void ClampDoubleToUint8(XMMRegister input_reg,
                          XMMRegister temp_xmm_reg,
                          Register result_reg);

  void SlowTruncateToI(Register result_reg, Register input_reg,
      int offset = HeapNumber::kValueOffset - kHeapObjectTag);

  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);

  void DoubleToI(Register result_reg, XMMRegister input_reg,
                 XMMRegister scratch, MinusZeroMode minus_zero_mode,
                 Label* lost_precision, Label* is_nan, Label* minus_zero,
                 Label::Distance dst = Label::kFar);

  void LoadUint32(XMMRegister dst, Register src);

  void LoadInstanceDescriptors(Register map, Register descriptors);
  void EnumLength(Register dst, Register map);
  void NumberOfOwnDescriptors(Register dst, Register map);

  template<typename Field>
  void DecodeField(Register reg) {
    static const int shift = Field::kShift;
    static const int mask = Field::kMask >> Field::kShift;
    if (shift != 0) {
      shrp(reg, Immediate(shift));
    }
    andp(reg, Immediate(mask));
  }

  template<typename Field>
  void DecodeFieldToSmi(Register reg) {
    if (SmiValuesAre32Bits()) {
      andp(reg, Immediate(Field::kMask));
      shlp(reg, Immediate(kSmiShift - Field::kShift));
    } else {
      static const int shift = Field::kShift;
      static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
      DCHECK(SmiValuesAre31Bits());
      DCHECK(kSmiShift == kSmiTagSize);
      DCHECK((mask & 0x80000000u) == 0);
      if (shift < kSmiShift) {
        shlp(reg, Immediate(kSmiShift - shift));
      } else if (shift > kSmiShift) {
        sarp(reg, Immediate(shift - kSmiShift));
      }
      andp(reg, Immediate(mask));
    }
  }

  // Abort execution if argument is not a number, enabled via --debug-code.
  void AssertNumber(Register object);

  // Abort execution if argument is a smi, enabled via --debug-code.
  void AssertNotSmi(Register object);

  // Abort execution if argument is not a smi, enabled via --debug-code.
  void AssertSmi(Register object);
  void AssertSmi(const Operand& object);

  // Abort execution if a 64 bit register containing a 32 bit payload does not
  // have zeros in the top 32 bits, enabled via --debug-code.
  void AssertZeroExtended(Register reg);

  // Abort execution if argument is not a string, enabled via --debug-code.
  void AssertString(Register object);

  // Abort execution if argument is not a name, enabled via --debug-code.
  void AssertName(Register object);

  // Abort execution if argument is not undefined or an AllocationSite, enabled
  // via --debug-code.
  void AssertUndefinedOrAllocationSite(Register object);

  // Abort execution if argument is not the root value with the given index,
  // enabled via --debug-code.
  void AssertRootValue(Register src,
                       Heap::RootListIndex root_value_index,
                       BailoutReason reason);

  // ---------------------------------------------------------------------------
  // Exception handling

  // Push a new try handler and link it into try handler chain.
  void PushTryHandler(StackHandler::Kind kind, int handler_index);

  // Unlink the stack handler on top of the stack from the try handler chain.
  void PopTryHandler();

  // Activate the top handler in the try hander chain and pass the
  // thrown value.
  void Throw(Register value);

  // Propagate an uncatchable exception out of the current JS stack.
  void ThrowUncatchable(Register value);

  // ---------------------------------------------------------------------------
  // Inline caching support

  // Generate code for checking access rights - used for security checks
  // on access to global objects across environments. The holder register
  // is left untouched, but the scratch register and kScratchRegister,
  // which must be different, are clobbered.
  void CheckAccessGlobalProxy(Register holder_reg,
                              Register scratch,
                              Label* miss);

  void GetNumberHash(Register r0, Register scratch);

  void LoadFromNumberDictionary(Label* miss,
                                Register elements,
                                Register key,
                                Register r0,
                                Register r1,
                                Register r2,
                                Register result);


  // ---------------------------------------------------------------------------
  // Allocation support

  // Allocate an object in new space or old pointer space. If the given space
  // is exhausted control continues at the gc_required label. The allocated
  // object is returned in result and end of the new object is returned in
  // result_end. The register scratch can be passed as no_reg in which case
  // an additional object reference will be added to the reloc info. The
  // returned pointers in result and result_end have not yet been tagged as
  // heap objects. If result_contains_top_on_entry is true the content of
  // result is known to be the allocation top on entry (could be result_end
  // from a previous call). If result_contains_top_on_entry is true scratch
  // should be no_reg as it is never used.
  void Allocate(int object_size,
                Register result,
                Register result_end,
                Register scratch,
                Label* gc_required,
                AllocationFlags flags);

  void Allocate(int header_size,
                ScaleFactor element_size,
                Register element_count,
                Register result,
                Register result_end,
                Register scratch,
                Label* gc_required,
                AllocationFlags flags);

  void Allocate(Register object_size,
                Register result,
                Register result_end,
                Register scratch,
                Label* gc_required,
                AllocationFlags flags);

  // Undo allocation in new space. The object passed and objects allocated after
  // it will no longer be allocated. Make sure that no pointers are left to the
  // object(s) no longer allocated as they would be invalid when allocation is
  // un-done.
  void UndoAllocationInNewSpace(Register object);

  // Allocate a heap number in new space with undefined value. Returns
  // tagged pointer in result register, or jumps to gc_required if new
  // space is full.
  void AllocateHeapNumber(Register result,
                          Register scratch,
                          Label* gc_required,
                          MutableMode mode = IMMUTABLE);

  // Allocate a sequential string. All the header fields of the string object
  // are initialized.
  void AllocateTwoByteString(Register result,
                             Register length,
                             Register scratch1,
                             Register scratch2,
                             Register scratch3,
                             Label* gc_required);
  void AllocateOneByteString(Register result, Register length,
                             Register scratch1, Register scratch2,
                             Register scratch3, Label* gc_required);

  // Allocate a raw cons string object. Only the map field of the result is
  // initialized.
  void AllocateTwoByteConsString(Register result,
                          Register scratch1,
                          Register scratch2,
                          Label* gc_required);
  void AllocateOneByteConsString(Register result, Register scratch1,
                                 Register scratch2, Label* gc_required);

  // Allocate a raw sliced string object. Only the map field of the result is
  // initialized.
  void AllocateTwoByteSlicedString(Register result,
                            Register scratch1,
                            Register scratch2,
                            Label* gc_required);
  void AllocateOneByteSlicedString(Register result, Register scratch1,
                                   Register scratch2, Label* gc_required);

  // ---------------------------------------------------------------------------
  // Support functions.

  // Check if result is zero and op is negative.
  void NegativeZeroTest(Register result, Register op, Label* then_label);

  // Check if result is zero and op is negative in code using jump targets.
  void NegativeZeroTest(CodeGenerator* cgen,
                        Register result,
                        Register op,
                        JumpTarget* then_target);

  // Check if result is zero and any of op1 and op2 are negative.
  // Register scratch is destroyed, and it must be different from op2.
  void NegativeZeroTest(Register result, Register op1, Register op2,
                        Register scratch, Label* then_label);

  // Try to get function prototype of a function and puts the value in
  // the result register. Checks that the function really is a
  // function and jumps to the miss label if the fast checks fail. The
  // function register will be untouched; the other register may be
  // clobbered.
  void TryGetFunctionPrototype(Register function,
                               Register result,
                               Label* miss,
                               bool miss_on_bound_function = false);

  // Picks out an array index from the hash field.
  // Register use:
  //   hash - holds the index's hash. Clobbered.
  //   index - holds the overwritten index on exit.
  void IndexFromHash(Register hash, Register index);

  // Find the function context up the context chain.
  void LoadContext(Register dst, int context_chain_length);

  // Conditionally load the cached Array transitioned map of type
  // transitioned_kind from the native context if the map in register
  // map_in_out is the cached Array map in the native context of
  // expected_kind.
  void LoadTransitionedArrayMapConditional(
      ElementsKind expected_kind,
      ElementsKind transitioned_kind,
      Register map_in_out,
      Register scratch,
      Label* no_map_match);

  // Load the global function with the given index.
  void LoadGlobalFunction(int index, Register function);

  // Load the initial map from the global function. The registers
  // function and map can be the same.
  void LoadGlobalFunctionInitialMap(Register function, Register map);

  // ---------------------------------------------------------------------------
  // Runtime calls

  // Call a code stub.
  void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());

  // Tail call a code stub (jump).
  void TailCallStub(CodeStub* stub);

  // Return from a code stub after popping its arguments.
  void StubReturn(int argc);

  // Call a runtime routine.
  void CallRuntime(const Runtime::Function* f,
                   int num_arguments,
                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);

  // Call a runtime function and save the value of XMM registers.
  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
    const Runtime::Function* function = Runtime::FunctionForId(id);
    CallRuntime(function, function->nargs, kSaveFPRegs);
  }

  // Convenience function: Same as above, but takes the fid instead.
  void CallRuntime(Runtime::FunctionId id,
                   int num_arguments,
                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
  }

  // Convenience function: call an external reference.
  void CallExternalReference(const ExternalReference& ext,
                             int num_arguments);

  // Tail call of a runtime routine (jump).
  // Like JumpToExternalReference, but also takes care of passing the number
  // of parameters.
  void TailCallExternalReference(const ExternalReference& ext,
                                 int num_arguments,
                                 int result_size);

  // Convenience function: tail call a runtime routine (jump).
  void TailCallRuntime(Runtime::FunctionId fid,
                       int num_arguments,
                       int result_size);

  // Jump to a runtime routine.
  void JumpToExternalReference(const ExternalReference& ext, int result_size);

  // Prepares stack to put arguments (aligns and so on).  WIN64 calling
  // convention requires to put the pointer to the return value slot into
  // rcx (rcx must be preserverd until CallApiFunctionAndReturn).  Saves
  // context (rsi).  Clobbers rax.  Allocates arg_stack_space * kPointerSize
  // inside the exit frame (not GCed) accessible via StackSpaceOperand.
  void PrepareCallApiFunction(int arg_stack_space);

  // Calls an API function.  Allocates HandleScope, extracts returned value
  // from handle and propagates exceptions.  Clobbers r14, r15, rbx and
  // caller-save registers.  Restores context.  On return removes
  // stack_space * kPointerSize (GCed).
  void CallApiFunctionAndReturn(Register function_address,
                                ExternalReference thunk_ref,
                                Register thunk_last_arg,
                                int stack_space,
                                Operand return_value_operand,
                                Operand* context_restore_operand);

  // Before calling a C-function from generated code, align arguments on stack.
  // After aligning the frame, arguments must be stored in rsp[0], rsp[8],
  // etc., not pushed. The argument count assumes all arguments are word sized.
  // The number of slots reserved for arguments depends on platform. On Windows
  // stack slots are reserved for the arguments passed in registers. On other
  // platforms stack slots are only reserved for the arguments actually passed
  // on the stack.
  void PrepareCallCFunction(int num_arguments);

  // Calls a C function and cleans up the space for arguments allocated
  // by PrepareCallCFunction. The called function is not allowed to trigger a
  // garbage collection, since that might move the code and invalidate the
  // return address (unless this is somehow accounted for by the called
  // function).
  void CallCFunction(ExternalReference function, int num_arguments);
  void CallCFunction(Register function, int num_arguments);

  // Calculate the number of stack slots to reserve for arguments when calling a
  // C function.
  int ArgumentStackSlotsForCFunctionCall(int num_arguments);

  // ---------------------------------------------------------------------------
  // Utilities

  void Ret();

  // Return and drop arguments from stack, where the number of arguments
  // may be bigger than 2^16 - 1.  Requires a scratch register.
  void Ret(int bytes_dropped, Register scratch);

  Handle<Object> CodeObject() {
    DCHECK(!code_object_.is_null());
    return code_object_;
  }

  // Copy length bytes from source to destination.
  // Uses scratch register internally (if you have a low-eight register
  // free, do use it, otherwise kScratchRegister will be used).
  // The min_length is a minimum limit on the value that length will have.
  // The algorithm has some special cases that might be omitted if the string
  // is known to always be long.
  void CopyBytes(Register destination,
                 Register source,
                 Register length,
                 int min_length = 0,
                 Register scratch = kScratchRegister);

  // Initialize fields with filler values.  Fields starting at |start_offset|
  // not including end_offset are overwritten with the value in |filler|.  At
  // the end the loop, |start_offset| takes the value of |end_offset|.
  void InitializeFieldsWithFiller(Register start_offset,
                                  Register end_offset,
                                  Register filler);


  // Emit code for a truncating division by a constant. The dividend register is
  // unchanged, the result is in rdx, and rax gets clobbered.
  void TruncatingDiv(Register dividend, int32_t divisor);

  // ---------------------------------------------------------------------------
  // StatsCounter support

  void SetCounter(StatsCounter* counter, int value);
  void IncrementCounter(StatsCounter* counter, int value);
  void DecrementCounter(StatsCounter* counter, int value);


  // ---------------------------------------------------------------------------
  // Debugging

  // Calls Abort(msg) if the condition cc is not satisfied.
  // Use --debug_code to enable.
  void Assert(Condition cc, BailoutReason reason);

  void AssertFastElements(Register elements);

  // Like Assert(), but always enabled.
  void Check(Condition cc, BailoutReason reason);

  // Print a message to stdout and abort execution.
  void Abort(BailoutReason msg);

  // Check that the stack is aligned.
  void CheckStackAlignment();

  // Verify restrictions about code generated in stubs.
  void set_generating_stub(bool value) { generating_stub_ = value; }
  bool generating_stub() { return generating_stub_; }
  void set_has_frame(bool value) { has_frame_ = value; }
  bool has_frame() { return has_frame_; }
  inline bool AllowThisStubCall(CodeStub* stub);

  static int SafepointRegisterStackIndex(Register reg) {
    return SafepointRegisterStackIndex(reg.code());
  }

  // Activation support.
  void EnterFrame(StackFrame::Type type);
  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
  void LeaveFrame(StackFrame::Type type);

  // Expects object in rax and returns map with validated enum cache
  // in rax.  Assumes that any other register can be used as a scratch.
  void CheckEnumCache(Register null_value,
                      Label* call_runtime);

  // AllocationMemento support. Arrays may have an associated
  // AllocationMemento object that can be checked for in order to pretransition
  // to another type.
  // On entry, receiver_reg should point to the array object.
  // scratch_reg gets clobbered.
  // If allocation info is present, condition flags are set to equal.
  void TestJSArrayForAllocationMemento(Register receiver_reg,
                                       Register scratch_reg,
                                       Label* no_memento_found);

  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
                                         Register scratch_reg,
                                         Label* memento_found) {
    Label no_memento_found;
    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
                                    &no_memento_found);
    j(equal, memento_found);
    bind(&no_memento_found);
  }

  // Jumps to found label if a prototype map has dictionary elements.
  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
                                        Register scratch1, Label* found);

 private:
  // Order general registers are pushed by Pushad.
  // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
  static const int kSafepointPushRegisterIndices[Register::kNumRegisters];
  static const int kNumSafepointSavedRegisters = 11;
  static const int kSmiShift = kSmiTagSize + kSmiShiftSize;

  bool generating_stub_;
  bool has_frame_;
  bool root_array_available_;

  // Returns a register holding the smi value. The register MUST NOT be
  // modified. It may be the "smi 1 constant" register.
  Register GetSmiConstant(Smi* value);

  int64_t RootRegisterDelta(ExternalReference other);

  // Moves the smi value to the destination register.
  void LoadSmiConstant(Register dst, Smi* value);

  // This handle will be patched with the code object on installation.
  Handle<Object> code_object_;

  // Helper functions for generating invokes.
  void InvokePrologue(const ParameterCount& expected,
                      const ParameterCount& actual,
                      Handle<Code> code_constant,
                      Register code_register,
                      Label* done,
                      bool* definitely_mismatches,
                      InvokeFlag flag,
                      Label::Distance near_jump = Label::kFar,
                      const CallWrapper& call_wrapper = NullCallWrapper());

  void EnterExitFramePrologue(bool save_rax);

  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
  // accessible via StackSpaceOperand.
  void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);

  void LeaveExitFrameEpilogue(bool restore_context);

  // Allocation support helpers.
  // Loads the top of new-space into the result register.
  // Otherwise the address of the new-space top is loaded into scratch (if
  // scratch is valid), and the new-space top is loaded into result.
  void LoadAllocationTopHelper(Register result,
                               Register scratch,
                               AllocationFlags flags);

  void MakeSureDoubleAlignedHelper(Register result,
                                   Register scratch,
                                   Label* gc_required,
                                   AllocationFlags flags);

  // Update allocation top with value in result_end register.
  // If scratch is valid, it contains the address of the allocation top.
  void UpdateAllocationTopHelper(Register result_end,
                                 Register scratch,
                                 AllocationFlags flags);

  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
  void InNewSpace(Register object,
                  Register scratch,
                  Condition cc,
                  Label* branch,
                  Label::Distance distance = Label::kFar);

  // Helper for finding the mark bits for an address.  Afterwards, the
  // bitmap register points at the word with the mark bits and the mask
  // the position of the first bit.  Uses rcx as scratch and leaves addr_reg
  // unchanged.
  inline void GetMarkBits(Register addr_reg,
                          Register bitmap_reg,
                          Register mask_reg);

  // Helper for throwing exceptions.  Compute a handler address and jump to
  // it.  See the implementation for register usage.
  void JumpToHandlerEntry();

  // Compute memory operands for safepoint stack slots.
  Operand SafepointRegisterSlot(Register reg);
  static int SafepointRegisterStackIndex(int reg_code) {
    return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
  }

  // Needs access to SafepointRegisterStackIndex for compiled frame
  // traversal.
  friend class StandardFrame;
};


// The code patcher is used to patch (typically) small parts of code e.g. for
// debugging and other types of instrumentation. When using the code patcher
// the exact number of bytes specified must be emitted. Is not legal to emit
// relocation information. If any of these constraints are violated it causes
// an assertion.
class CodePatcher {
 public:
  CodePatcher(byte* address, int size);
  virtual ~CodePatcher();

  // Macro assembler to emit code.
  MacroAssembler* masm() { return &masm_; }

 private:
  byte* address_;  // The address of the code being patched.
  int size_;  // Number of bytes of the expected patch size.
  MacroAssembler masm_;  // Macro assembler used to generate the code.
};


// -----------------------------------------------------------------------------
// Static helper functions.

// Generate an Operand for loading a field from an object.
inline Operand FieldOperand(Register object, int offset) {
  return Operand(object, offset - kHeapObjectTag);
}


// Generate an Operand for loading an indexed field from an object.
inline Operand FieldOperand(Register object,
                            Register index,
                            ScaleFactor scale,
                            int offset) {
  return Operand(object, index, scale, offset - kHeapObjectTag);
}


inline Operand ContextOperand(Register context, int index) {
  return Operand(context, Context::SlotOffset(index));
}


inline Operand GlobalObjectOperand() {
  return ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX);
}


// Provides access to exit frame stack space (not GCed).
inline Operand StackSpaceOperand(int index) {
#ifdef _WIN64
  const int kShaddowSpace = 4;
  return Operand(rsp, (index + kShaddowSpace) * kPointerSize);
#else
  return Operand(rsp, index * kPointerSize);
#endif
}


inline Operand StackOperandForReturnAddress(int32_t disp) {
  return Operand(rsp, disp);
}


#ifdef GENERATED_CODE_COVERAGE
extern void LogGeneratedCodeCoverage(const char* file_line);
#define CODE_COVERAGE_STRINGIFY(x) #x
#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
#define ACCESS_MASM(masm) {                                                  \
    Address x64_coverage_function = FUNCTION_ADDR(LogGeneratedCodeCoverage); \
    masm->pushfq();                                                          \
    masm->Pushad();                                                          \
    masm->Push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));            \
    masm->Call(x64_coverage_function, RelocInfo::EXTERNAL_REFERENCE);        \
    masm->Pop(rax);                                                          \
    masm->Popad();                                                           \
    masm->popfq();                                                           \
  }                                                                          \
  masm->
#else
#define ACCESS_MASM(masm) masm->
#endif

} }  // namespace v8::internal

#endif  // V8_X64_MACRO_ASSEMBLER_X64_H_
