/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_x64_MacroAssembler_x64_h
#define jit_x64_MacroAssembler_x64_h

#include "jit/shared/MacroAssembler-x86-shared.h"
#include "jit/MoveResolver.h"
#include "jit/IonFrames.h"
#include "jsnum.h"

namespace js {
namespace jit {

struct ImmShiftedTag : public ImmWord
{
    ImmShiftedTag(JSValueShiftedTag shtag)
      : ImmWord((uintptr_t)shtag)
    { }

    ImmShiftedTag(JSValueType type)
      : ImmWord(uintptr_t(JSValueShiftedTag(JSVAL_TYPE_TO_SHIFTED_TAG(type))))
    { }
};

struct ImmTag : public Imm32
{
    ImmTag(JSValueTag tag)
      : Imm32(tag)
    { }
};

class MacroAssemblerX64 : public MacroAssemblerX86Shared
{
    // Number of bytes the stack is adjusted inside a call to C. Calls to C may
    // not be nested.
    bool inCall_;
    uint32_t args_;
    uint32_t passedIntArgs_;
    uint32_t passedFloatArgs_;
    uint32_t stackForCall_;
    bool dynamicAlignment_;
    bool enoughMemory_;

    void setupABICall(uint32_t arg);

  protected:
    MoveResolver moveResolver_;

  public:
    using MacroAssemblerX86Shared::call;
    using MacroAssemblerX86Shared::Push;
    using MacroAssemblerX86Shared::callWithExitFrame;
    using MacroAssemblerX86Shared::branch32;

    enum Result {
        GENERAL,
        DOUBLE
    };

    typedef MoveResolver::MoveOperand MoveOperand;
    typedef MoveResolver::Move Move;

    MacroAssemblerX64()
      : inCall_(false),
        enoughMemory_(true)
    {
    }

    bool oom() const {
        return MacroAssemblerX86Shared::oom() || !enoughMemory_;
    }

    /////////////////////////////////////////////////////////////////
    // X64 helpers.
    /////////////////////////////////////////////////////////////////
    void call(ImmWord target) {
        mov(target, rax);
        call(rax);
    }

    // Refers to the upper 32 bits of a 64-bit Value operand.
    // On x86_64, the upper 32 bits do not necessarily only contain the type.
    Operand ToUpper32(Operand base) {
        switch (base.kind()) {
          case Operand::REG_DISP:
            return Operand(Register::FromCode(base.base()), base.disp() + 4);

          case Operand::SCALE:
            return Operand(Register::FromCode(base.base()), Register::FromCode(base.index()),
                           base.scale(), base.disp() + 4);

          default:
            JS_NOT_REACHED("unexpected operand kind");
            return base; // Silence GCC warning.
        }
    }
    static inline Operand ToUpper32(const Address &address) {
        return Operand(address.base, address.offset + 4);
    }
    static inline Operand ToUpper32(const BaseIndex &address) {
        return Operand(address.base, address.index, address.scale, address.offset + 4);
    }

    uint32_t Upper32Of(JSValueShiftedTag tag) {
        union { // Implemented in this way to appease MSVC++.
            uint64_t tag;
            struct {
                uint32_t lo32;
                uint32_t hi32;
            } s;
        } e;
        e.tag = tag;
        return e.s.hi32;
    }

    JSValueShiftedTag GetShiftedTag(JSValueType type) {
        return (JSValueShiftedTag)JSVAL_TYPE_TO_SHIFTED_TAG(type);
    }

    /////////////////////////////////////////////////////////////////
    // X86/X64-common interface.
    /////////////////////////////////////////////////////////////////
    void storeValue(ValueOperand val, Operand dest) {
        movq(val.valueReg(), dest);
    }
    void storeValue(ValueOperand val, const Address &dest) {
        storeValue(val, Operand(dest));
    }
    template <typename T>
    void storeValue(JSValueType type, Register reg, const T &dest) {
        // Value types with 32-bit payloads can be emitted as two 32-bit moves.
        if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
            movl(reg, Operand(dest));
            movl(Imm32(Upper32Of(GetShiftedTag(type))), ToUpper32(Operand(dest)));
        } else {
            boxValue(type, reg, ScratchReg);
            movq(ScratchReg, Operand(dest));
        }
    }
    template <typename T>
    void storeValue(const Value &val, const T &dest) {
        jsval_layout jv = JSVAL_TO_IMPL(val);
        movq(ImmWord(jv.asBits), ScratchReg);
        if (val.isMarkable())
            writeDataRelocation(val);
        movq(ScratchReg, Operand(dest));
    }
    void storeValue(ValueOperand val, BaseIndex dest) {
        storeValue(val, Operand(dest));
    }
    void loadValue(Operand src, ValueOperand val) {
        movq(src, val.valueReg());
    }
    void loadValue(Address src, ValueOperand val) {
        loadValue(Operand(src), val);
    }
    void loadValue(const BaseIndex &src, ValueOperand val) {
        loadValue(Operand(src), val);
    }
    void tagValue(JSValueType type, Register payload, ValueOperand dest) {
        JS_ASSERT(dest.valueReg() != ScratchReg);
        if (payload != dest.valueReg())
            movq(payload, dest.valueReg());
        mov(ImmShiftedTag(type), ScratchReg);
        orq(ScratchReg, dest.valueReg());
    }
    void pushValue(ValueOperand val) {
        push(val.valueReg());
    }
    void Push(const ValueOperand &val) {
        pushValue(val);
        framePushed_ += sizeof(Value);
    }
    void popValue(ValueOperand val) {
        pop(val.valueReg());
    }
    void pushValue(const Value &val) {
        jsval_layout jv = JSVAL_TO_IMPL(val);
        push(ImmWord(jv.asBits));
    }
    void pushValue(JSValueType type, Register reg) {
        boxValue(type, reg, ScratchReg);
        push(ScratchReg);
    }
    void pushValue(const Address &addr) {
        push(Operand(addr));
    }

    void moveValue(const Value &val, const Register &dest) {
        jsval_layout jv = JSVAL_TO_IMPL(val);
        movq(ImmWord(jv.asPtr), dest);
        writeDataRelocation(val);
    }
    void moveValue(const Value &src, const ValueOperand &dest) {
        moveValue(src, dest.valueReg());
    }
    void moveValue(const ValueOperand &src, const ValueOperand &dest) {
        if (src.valueReg() != dest.valueReg())
            movq(src.valueReg(), dest.valueReg());
    }
    void boxValue(JSValueType type, Register src, Register dest) {
        JS_ASSERT(src != dest);

        JSValueShiftedTag tag = (JSValueShiftedTag)JSVAL_TYPE_TO_SHIFTED_TAG(type);
#ifdef DEBUG
        if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
            Label upper32BitsZeroed;
            movePtr(ImmWord(UINT32_MAX), dest);
            branchPtr(Assembler::BelowOrEqual, src, dest, &upper32BitsZeroed);
            breakpoint();
            bind(&upper32BitsZeroed);
        }
#endif
        mov(ImmShiftedTag(tag), dest);
        orq(src, dest);
    }

    Condition testUndefined(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_UNDEFINED));
        return cond;
    }
    Condition testInt32(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_INT32));
        return cond;
    }
    Condition testBoolean(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_BOOLEAN));
        return cond;
    }
    Condition testNull(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_NULL));
        return cond;
    }
    Condition testString(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_STRING));
        return cond;
    }
    Condition testObject(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_OBJECT));
        return cond;
    }
    Condition testDouble(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, Imm32(JSVAL_TAG_MAX_DOUBLE));
        return cond == Equal ? BelowOrEqual : Above;
    }
    Condition testNumber(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, Imm32(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET));
        return cond == Equal ? BelowOrEqual : Above;
    }
    Condition testGCThing(Condition cond, Register tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, Imm32(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
        return cond == Equal ? AboveOrEqual : Below;
    }

    Condition testMagic(Condition cond, const Register &tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_TAG_MAGIC));
        return cond;
    }
    Condition testError(Condition cond, const Register &tag) {
        return testMagic(cond, tag);
    }
    Condition testPrimitive(Condition cond, const Register &tag) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(tag, ImmTag(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET));
        return cond == Equal ? Below : AboveOrEqual;
    }

    Condition testUndefined(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testUndefined(cond, ScratchReg);
    }
    Condition testInt32(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testInt32(cond, ScratchReg);
    }
    Condition testBoolean(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testBoolean(cond, ScratchReg);
    }
    Condition testDouble(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testDouble(cond, ScratchReg);
    }
    Condition testNumber(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testNumber(cond, ScratchReg);
    }
    Condition testNull(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testNull(cond, ScratchReg);
    }
    Condition testString(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testString(cond, ScratchReg);
    }
    Condition testObject(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testObject(cond, ScratchReg);
    }
    Condition testGCThing(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testGCThing(cond, ScratchReg);
    }
    Condition testGCThing(Condition cond, const Address &src) {
        splitTag(src, ScratchReg);
        return testGCThing(cond, ScratchReg);
    }
    Condition testMagic(Condition cond, const Address &src) {
        splitTag(src, ScratchReg);
        return testMagic(cond, ScratchReg);
    }
    Condition testPrimitive(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testPrimitive(cond, ScratchReg);
    }


    Condition testUndefined(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testUndefined(cond, ScratchReg);
    }
    Condition testNull(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testNull(cond, ScratchReg);
    }
    Condition testBoolean(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testBoolean(cond, ScratchReg);
    }
    Condition testString(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testString(cond, ScratchReg);
    }
    Condition testInt32(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testInt32(cond, ScratchReg);
    }
    Condition testObject(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testObject(cond, ScratchReg);
    }
    Condition testDouble(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testDouble(cond, ScratchReg);
    }
    Condition testMagic(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testMagic(cond, ScratchReg);
    }
    Condition testGCThing(Condition cond, const BaseIndex &src) {
        splitTag(src, ScratchReg);
        return testGCThing(cond, ScratchReg);
    }

    Condition isMagic(Condition cond, const ValueOperand &src, JSWhyMagic why) {
        uint64_t magic = MagicValue(why).asRawBits();
        cmpPtr(src.valueReg(), ImmWord(magic));
        return cond;
    }

    void cmpPtr(const Register &lhs, const ImmWord rhs) {
        JS_ASSERT(lhs != ScratchReg);
        mov(rhs, ScratchReg);
        cmpq(lhs, ScratchReg);
    }
    void cmpPtr(const Register &lhs, const ImmGCPtr rhs) {
        JS_ASSERT(lhs != ScratchReg);
        movq(rhs, ScratchReg);
        cmpq(lhs, ScratchReg);
    }
    void cmpPtr(const Operand &lhs, const ImmGCPtr rhs) {
        movq(rhs, ScratchReg);
        cmpq(lhs, ScratchReg);
    }
    void cmpPtr(const Operand &lhs, const ImmWord rhs) {
        if ((intptr_t)rhs.value <= INT32_MAX && (intptr_t)rhs.value >= INT32_MIN) {
            cmpq(lhs, Imm32((int32_t)rhs.value));
        } else {
            mov(rhs, ScratchReg);
            cmpq(lhs, ScratchReg);
        }
    }
    void cmpPtr(const Address &lhs, const ImmGCPtr rhs) {
        cmpPtr(Operand(lhs), rhs);
    }
    void cmpPtr(const Address &lhs, const ImmWord rhs) {
        cmpPtr(Operand(lhs), rhs);
    }
    void cmpPtr(const Operand &lhs, const Register &rhs) {
        cmpq(lhs, rhs);
    }
    void cmpPtr(const Operand &lhs, const Imm32 rhs) {
        cmpq(lhs, rhs);
    }
    void cmpPtr(const Address &lhs, const Register &rhs) {
        cmpPtr(Operand(lhs), rhs);
    }
    void cmpPtr(const Register &lhs, const Register &rhs) {
        return cmpq(lhs, rhs);
    }
    void testPtr(const Register &lhs, const Register &rhs) {
        testq(lhs, rhs);
    }

    Condition testNegativeZero(const FloatRegister &reg, const Register &scratch);

    /////////////////////////////////////////////////////////////////
    // Common interface.
    /////////////////////////////////////////////////////////////////
    void reserveStack(uint32_t amount) {
        if (amount)
            subq(Imm32(amount), StackPointer);
        framePushed_ += amount;
    }
    void freeStack(uint32_t amount) {
        JS_ASSERT(amount <= framePushed_);
        if (amount)
            addq(Imm32(amount), StackPointer);
        framePushed_ -= amount;
    }
    void freeStack(Register amount) {
        addq(amount, StackPointer);
    }

    void addPtr(const Register &src, const Register &dest) {
        addq(src, dest);
    }
    void addPtr(Imm32 imm, const Register &dest) {
        addq(imm, dest);
    }
    void addPtr(Imm32 imm, const Address &dest) {
        addq(imm, Operand(dest));
    }
    void addPtr(ImmWord imm, const Register &dest) {
        JS_ASSERT(dest != ScratchReg);
        if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) {
            addq(Imm32((int32_t)imm.value), dest);
        } else {
            mov(imm, ScratchReg);
            addq(ScratchReg, dest);
        }
    }
    void addPtr(const Address &src, const Register &dest) {
        addq(Operand(src), dest);
    }
    void subPtr(Imm32 imm, const Register &dest) {
        subq(imm, dest);
    }
    void subPtr(const Register &src, const Register &dest) {
        subq(src, dest);
    }
    void subPtr(const Address &addr, const Register &dest) {
        subq(Operand(addr), dest);
    }

    void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) {
        mov(ImmWord(lhs.addr), ScratchReg);
        branch32(cond, Address(ScratchReg, 0), rhs, label);
    }
    void branch32(Condition cond, const AbsoluteAddress &lhs, Register rhs, Label *label) {
        mov(ImmWord(lhs.addr), ScratchReg);
        branch32(cond, Address(ScratchReg, 0), rhs, label);
    }

    // Specialization for AbsoluteAddress.
    void branchPtr(Condition cond, const AbsoluteAddress &addr, const Register &ptr, Label *label) {
        JS_ASSERT(ptr != ScratchReg);
        mov(ImmWord(addr.addr), ScratchReg);
        branchPtr(cond, Operand(ScratchReg, 0x0), ptr, label);
    }

    template <typename T>
    void branchPrivatePtr(Condition cond, T lhs, ImmWord ptr, Label *label) {
        branchPtr(cond, lhs, ImmWord(ptr.value >> 1), label);
    }

    void branchPrivatePtr(Condition cond, Address lhs, Register ptr, Label *label) {
        if (ptr != ScratchReg)
            movePtr(ptr, ScratchReg);
        rshiftPtr(Imm32(1), ScratchReg);
        branchPtr(cond, lhs, ScratchReg, label);
    }

    template <typename T, typename S>
    void branchPtr(Condition cond, T lhs, S ptr, Label *label) {
        cmpPtr(Operand(lhs), ptr);
        j(cond, label);
    }

    CodeOffsetJump jumpWithPatch(RepatchLabel *label) {
        JmpSrc src = jmpSrc(label);
        return CodeOffsetJump(size(), addPatchableJump(src, Relocation::HARDCODED));
    }
    template <typename S, typename T>
    CodeOffsetJump branchPtrWithPatch(Condition cond, S lhs, T ptr, RepatchLabel *label) {
        cmpPtr(lhs, ptr);
        JmpSrc src = jSrc(cond, label);
        return CodeOffsetJump(size(), addPatchableJump(src, Relocation::HARDCODED));
    }
    void branchPtr(Condition cond, Register lhs, Register rhs, Label *label) {
        cmpPtr(lhs, rhs);
        j(cond, label);
    }
    void branchTestPtr(Condition cond, Register lhs, Register rhs, Label *label) {
        testq(lhs, rhs);
        j(cond, label);
    }
    void branchTestPtr(Condition cond, Register lhs, Imm32 imm, Label *label) {
        testq(lhs, imm);
        j(cond, label);
    }
    void branchTestPtr(Condition cond, const Address &lhs, Imm32 imm, Label *label) {
        testq(Operand(lhs), imm);
        j(cond, label);
    }
    void decBranchPtr(Condition cond, const Register &lhs, Imm32 imm, Label *label) {
        subPtr(imm, lhs);
        j(cond, label);
    }

    void movePtr(const Register &src, const Register &dest) {
        movq(src, dest);
    }
    void movePtr(const Register &src, const Operand &dest) {
        movq(src, dest);
    }
    void movePtr(ImmWord imm, Register dest) {
        mov(imm, dest);
    }
    void movePtr(ImmGCPtr imm, Register dest) {
        movq(imm, dest);
    }
    void loadPtr(const AbsoluteAddress &address, Register dest) {
        mov(ImmWord(address.addr), ScratchReg);
        movq(Operand(ScratchReg, 0x0), dest);
    }
    void loadPtr(const Address &address, Register dest) {
        movq(Operand(address), dest);
    }
    void loadPtr(const Operand &src, Register dest) {
        movq(src, dest);
    }
    void loadPtr(const BaseIndex &src, Register dest) {
        movq(Operand(src), dest);
    }
    void loadPrivate(const Address &src, Register dest) {
        loadPtr(src, dest);
        shlq(Imm32(1), dest);
    }
    void storePtr(ImmWord imm, const Address &address) {
        if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) {
            mov(Imm32((int32_t)imm.value), Operand(address));
        } else {
            mov(imm, ScratchReg);
            movq(ScratchReg, Operand(address));
        }
    }
    void storePtr(ImmGCPtr imm, const Address &address) {
        movq(imm, ScratchReg);
        movq(ScratchReg, Operand(address));
    }
    void storePtr(Register src, const Address &address) {
        movq(src, Operand(address));
    }
    void storePtr(Register src, const Operand &dest) {
        movq(src, dest);
    }
    void storePtr(const Register &src, const AbsoluteAddress &address) {
        mov(ImmWord(address.addr), ScratchReg);
        movq(src, Operand(ScratchReg, 0x0));
    }
    void rshiftPtr(Imm32 imm, Register dest) {
        shrq(imm, dest);
    }
    void lshiftPtr(Imm32 imm, Register dest) {
        shlq(imm, dest);
    }
    void xorPtr(Imm32 imm, Register dest) {
        xorq(imm, dest);
    }
    void xorPtr(Register src, Register dest) {
        xorq(src, dest);
    }
    void orPtr(Imm32 imm, Register dest) {
        orq(imm, dest);
    }
    void orPtr(Register src, Register dest) {
        orq(src, dest);
    }
    void andPtr(Imm32 imm, Register dest) {
        andq(imm, dest);
    }
    void andPtr(Register src, Register dest) {
        andq(src, dest);
    }

    void splitTag(Register src, Register dest) {
        if (src != dest)
            movq(src, dest);
        shrq(Imm32(JSVAL_TAG_SHIFT), dest);
    }
    void splitTag(const ValueOperand &operand, const Register &dest) {
        splitTag(operand.valueReg(), dest);
    }
    void splitTag(const Operand &operand, const Register &dest) {
        movq(operand, dest);
        shrq(Imm32(JSVAL_TAG_SHIFT), dest);
    }
    void splitTag(const Address &operand, const Register &dest) {
        splitTag(Operand(operand), dest);
    }
    void splitTag(const BaseIndex &operand, const Register &dest) {
        splitTag(Operand(operand), dest);
    }

    // Extracts the tag of a value and places it in ScratchReg.
    Register splitTagForTest(const ValueOperand &value) {
        splitTag(value, ScratchReg);
        return ScratchReg;
    }
    void cmpTag(const ValueOperand &operand, ImmTag tag) {
        Register reg = splitTagForTest(operand);
        cmpl(reg, tag);
    }

    void branchTestUndefined(Condition cond, Register tag, Label *label) {
        cond = testUndefined(cond, tag);
        j(cond, label);
    }
    void branchTestInt32(Condition cond, Register tag, Label *label) {
        cond = testInt32(cond, tag);
        j(cond, label);
    }
    void branchTestDouble(Condition cond, Register tag, Label *label) {
        cond = testDouble(cond, tag);
        j(cond, label);
    }
    void branchTestBoolean(Condition cond, Register tag, Label *label) {
        cond = testBoolean(cond, tag);
        j(cond, label);
    }
    void branchTestNull(Condition cond, Register tag, Label *label) {
        cond = testNull(cond, tag);
        j(cond, label);
    }
    void branchTestString(Condition cond, Register tag, Label *label) {
        cond = testString(cond, tag);
        j(cond, label);
    }
    void branchTestObject(Condition cond, Register tag, Label *label) {
        cond = testObject(cond, tag);
        j(cond, label);
    }
    void branchTestNumber(Condition cond, Register tag, Label *label) {
        cond = testNumber(cond, tag);
        j(cond, label);
    }

    // x64 can test for certain types directly from memory when the payload
    // of the type is limited to 32 bits. This avoids loading into a register,
    // accesses half as much memory, and removes a right-shift.
    void branchTestUndefined(Condition cond, const Operand &operand, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(ToUpper32(operand), Imm32(Upper32Of(GetShiftedTag(JSVAL_TYPE_UNDEFINED))));
        j(cond, label);
    }
    void branchTestInt32(Condition cond, const Operand &operand, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(ToUpper32(operand), Imm32(Upper32Of(GetShiftedTag(JSVAL_TYPE_INT32))));
        j(cond, label);
    }
    void branchTestInt32(Condition cond, const Address &address, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        branchTestInt32(cond, Operand(address), label);
    }
    void branchTestDouble(Condition cond, const Operand &operand, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        splitTag(operand, ScratchReg);
        branchTestDouble(cond, ScratchReg, label);
    }
    void branchTestDouble(Condition cond, const Address &address, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        branchTestDouble(cond, Operand(address), label);
    }
    void branchTestBoolean(Condition cond, const Operand &operand, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(ToUpper32(operand), Imm32(Upper32Of(GetShiftedTag(JSVAL_TYPE_BOOLEAN))));
        j(cond, label);
    }
    void branchTestNull(Condition cond, const Operand &operand, Label *label) {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        cmpl(ToUpper32(operand), Imm32(Upper32Of(GetShiftedTag(JSVAL_TYPE_NULL))));
        j(cond, label);
    }

    // Perform a type-test on a full Value loaded into a register.
    // Clobbers the ScratchReg.
    void branchTestUndefined(Condition cond, const ValueOperand &src, Label *label) {
        cond = testUndefined(cond, src);
        j(cond, label);
    }
    void branchTestInt32(Condition cond, const ValueOperand &src, Label *label) {
        splitTag(src, ScratchReg);
        branchTestInt32(cond, ScratchReg, label);
    }
    void branchTestBoolean(Condition cond, const ValueOperand &src, Label *label) {
        splitTag(src, ScratchReg);
        branchTestBoolean(cond, ScratchReg, label);
    }
    void branchTestDouble(Condition cond, const ValueOperand &src, Label *label) {
        cond = testDouble(cond, src);
        j(cond, label);
    }
    void branchTestNull(Condition cond, const ValueOperand &src, Label *label) {
        cond = testNull(cond, src);
        j(cond, label);
    }
    void branchTestString(Condition cond, const ValueOperand &src, Label *label) {
        cond = testString(cond, src);
        j(cond, label);
    }
    void branchTestObject(Condition cond, const ValueOperand &src, Label *label) {
        cond = testObject(cond, src);
        j(cond, label);
    }
    void branchTestNumber(Condition cond, const ValueOperand &src, Label *label) {
        cond = testNumber(cond, src);
        j(cond, label);
    }
    template <typename T>
    void branchTestGCThing(Condition cond, const T &src, Label *label) {
        cond = testGCThing(cond, src);
        j(cond, label);
    }
    template <typename T>
    void branchTestPrimitive(Condition cond, const T &t, Label *label) {
        cond = testPrimitive(cond, t);
        j(cond, label);
    }
    template <typename T>
    void branchTestMagic(Condition cond, const T &t, Label *label) {
        cond = testMagic(cond, t);
        j(cond, label);
    }
    void branchTestMagicValue(Condition cond, const ValueOperand &val, JSWhyMagic why,
                              Label *label)
    {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        // Test for magic
        Label notmagic;
        Condition testCond = testMagic(cond, val);
        j(InvertCondition(testCond), &notmagic);
        // Test magic value
        unboxMagic(val, ScratchReg);
        branch32(cond, ScratchReg, Imm32(static_cast<int32_t>(why)), label);
        bind(&notmagic);
    }
    Condition testMagic(Condition cond, const ValueOperand &src) {
        splitTag(src, ScratchReg);
        return testMagic(cond, ScratchReg);
    }
    Condition testError(Condition cond, const ValueOperand &src) {
        return testMagic(cond, src);
    }
    void branchTestValue(Condition cond, const ValueOperand &value, const Value &v, Label *label) {
        JS_ASSERT(value.valueReg() != ScratchReg);
        moveValue(v, ScratchReg);
        cmpq(value.valueReg(), ScratchReg);
        j(cond, label);
    }
    void branchTestValue(Condition cond, const Address &valaddr, const ValueOperand &value,
                         Label *label)
    {
        JS_ASSERT(cond == Equal || cond == NotEqual);
        branchPtr(cond, valaddr, value.valueReg(), label);
    }

    void boxDouble(const FloatRegister &src, const ValueOperand &dest) {
        movqsd(src, dest.valueReg());
    }
    void boxNonDouble(JSValueType type, const Register &src, const ValueOperand &dest) {
        JS_ASSERT(src != dest.valueReg());
        boxValue(type, src, dest.valueReg());
    }

    // Note that the |dest| register here may be ScratchReg, so we shouldn't
    // use it.
    void unboxInt32(const ValueOperand &src, const Register &dest) {
        movl(src.valueReg(), dest);
    }
    void unboxInt32(const Operand &src, const Register &dest) {
        movl(src, dest);
    }
    void unboxInt32(const Address &src, const Register &dest) {
        unboxInt32(Operand(src), dest);
    }
    void unboxDouble(const Address &src, const FloatRegister &dest) {
        movsd(Operand(src), dest);
    }

    void unboxArgObjMagic(const ValueOperand &src, const Register &dest) {
        unboxArgObjMagic(Operand(src.valueReg()), dest);
    }
    void unboxArgObjMagic(const Operand &src, const Register &dest) {
        xorq(dest, dest);
    }
    void unboxArgObjMagic(const Address &src, const Register &dest) {
        unboxArgObjMagic(Operand(src), dest);
    }

    void unboxBoolean(const ValueOperand &src, const Register &dest) {
        movl(src.valueReg(), dest);
    }
    void unboxBoolean(const Operand &src, const Register &dest) {
        movl(src, dest);
    }
    void unboxBoolean(const Address &src, const Register &dest) {
        unboxBoolean(Operand(src), dest);
    }

    void unboxMagic(const ValueOperand &src, const Register &dest) {
        movl(src.valueReg(), dest);
    }

    void unboxDouble(const ValueOperand &src, const FloatRegister &dest) {
        movqsd(src.valueReg(), dest);
    }
    void unboxPrivate(const ValueOperand &src, const Register dest) {
        movq(src.valueReg(), dest);
        shlq(Imm32(1), dest);
    }

    void notBoolean(const ValueOperand &val) {
        xorq(Imm32(1), val.valueReg());
    }

    // Unbox any non-double value into dest. Prefer unboxInt32 or unboxBoolean
    // instead if the source type is known.
    void unboxNonDouble(const ValueOperand &src, const Register &dest) {
        if (src.valueReg() == dest) {
            movq(ImmWord(JSVAL_PAYLOAD_MASK), ScratchReg);
            andq(ScratchReg, dest);
        } else {
            movq(ImmWord(JSVAL_PAYLOAD_MASK), dest);
            andq(src.valueReg(), dest);
        }
    }
    void unboxNonDouble(const Operand &src, const Register &dest) {
        // Explicitly permits |dest| to be used in |src|.
        JS_ASSERT(dest != ScratchReg);
        movq(ImmWord(JSVAL_PAYLOAD_MASK), ScratchReg);
        movq(src, dest);
        andq(ScratchReg, dest);
    }

    void unboxString(const ValueOperand &src, const Register &dest) { unboxNonDouble(src, dest); }
    void unboxString(const Operand &src, const Register &dest) { unboxNonDouble(src, dest); }

    void unboxObject(const ValueOperand &src, const Register &dest) { unboxNonDouble(src, dest); }
    void unboxObject(const Operand &src, const Register &dest) { unboxNonDouble(src, dest); }

    // Extended unboxing API. If the payload is already in a register, returns
    // that register. Otherwise, provides a move to the given scratch register,
    // and returns that.
    Register extractObject(const Address &address, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        loadPtr(address, ScratchReg);
        unboxObject(ValueOperand(ScratchReg), scratch);
        return scratch;
    }
    Register extractObject(const ValueOperand &value, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        unboxObject(value, scratch);
        return scratch;
    }
    Register extractInt32(const ValueOperand &value, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        unboxInt32(value, scratch);
        return scratch;
    }
    Register extractBoolean(const ValueOperand &value, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        unboxBoolean(value, scratch);
        return scratch;
    }
    Register extractTag(const Address &address, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        loadPtr(address, scratch);
        splitTag(scratch, scratch);
        return scratch;
    }
    Register extractTag(const ValueOperand &value, Register scratch) {
        JS_ASSERT(scratch != ScratchReg);
        splitTag(value, scratch);
        return scratch;
    }

    void unboxValue(const ValueOperand &src, AnyRegister dest) {
        if (dest.isFloat()) {
            Label notInt32, end;
            branchTestInt32(Assembler::NotEqual, src, &notInt32);
            cvtsi2sd(src.valueReg(), dest.fpu());
            jump(&end);
            bind(&notInt32);
            unboxDouble(src, dest.fpu());
            bind(&end);
        } else {
            unboxNonDouble(src, dest.gpr());
        }
    }

    // These two functions use the low 32-bits of the full value register.
    void boolValueToDouble(const ValueOperand &operand, const FloatRegister &dest) {
        cvtsi2sd(operand.valueReg(), dest);
    }
    void int32ValueToDouble(const ValueOperand &operand, const FloatRegister &dest) {
        cvtsi2sd(operand.valueReg(), dest);
    }

    void loadConstantDouble(double d, const FloatRegister &dest) {
        union DoublePun {
            uint64_t u;
            double d;
        } pun;
        pun.d = d;
        if (!maybeInlineDouble(pun.u, dest)) {
            mov(ImmWord(pun.u), ScratchReg);
            movqsd(ScratchReg, dest);
        }
    }
    void loadStaticDouble(const double *dp, const FloatRegister &dest) {
        loadConstantDouble(*dp, dest);
    }

    void branchTruncateDouble(const FloatRegister &src, const Register &dest, Label *fail) {
        const uint64_t IndefiniteIntegerValue = 0x8000000000000000;
        JS_ASSERT(dest != ScratchReg);
        cvttsd2sq(src, dest);
        movq(ImmWord(IndefiniteIntegerValue), ScratchReg);
        cmpq(dest, ScratchReg);
        j(Assembler::Equal, fail);
        movl(dest, dest); // Zero upper 32-bits.
    }

    Condition testInt32Truthy(bool truthy, const ValueOperand &operand) {
        testl(operand.valueReg(), operand.valueReg());
        return truthy ? NonZero : Zero;
    }
    void branchTestBooleanTruthy(bool truthy, const ValueOperand &operand, Label *label) {
        testl(operand.valueReg(), operand.valueReg());
        j(truthy ? NonZero : Zero, label);
    }
    // This returns the tag in ScratchReg.
    Condition testStringTruthy(bool truthy, const ValueOperand &value) {
        unboxString(value, ScratchReg);

        Operand lengthAndFlags(ScratchReg, JSString::offsetOfLengthAndFlags());
        movq(lengthAndFlags, ScratchReg);
        shrq(Imm32(JSString::LENGTH_SHIFT), ScratchReg);
        testq(ScratchReg, ScratchReg);
        return truthy ? Assembler::NonZero : Assembler::Zero;
    }


    void loadInt32OrDouble(const Operand &operand, const FloatRegister &dest) {
        Label notInt32, end;
        branchTestInt32(Assembler::NotEqual, operand, &notInt32);
        cvtsi2sd(operand, dest);
        jump(&end);
        bind(&notInt32);
        movsd(operand, dest);
        bind(&end);
    }

    template <typename T>
    void loadUnboxedValue(const T &src, MIRType type, AnyRegister dest) {
        if (dest.isFloat())
            loadInt32OrDouble(Operand(src), dest.fpu());
        else if (type == MIRType_Int32 || type == MIRType_Boolean)
            movl(Operand(src), dest.gpr());
        else
            unboxNonDouble(Operand(src), dest.gpr());
    }

    void loadInstructionPointerAfterCall(const Register &dest) {
        movq(Operand(StackPointer, 0x0), dest);
    }

    void convertUInt32ToDouble(const Register &src, const FloatRegister &dest) {
        cvtsq2sd(src, dest);
    }

    void inc64(AbsoluteAddress dest) {
        mov(ImmWord(dest.addr), ScratchReg);
        addPtr(Imm32(1), Address(ScratchReg, 0));
    }

    // If source is a double, load it into dest. If source is int32,
    // convert it to double. Else, branch to failure.
    void ensureDouble(const ValueOperand &source, FloatRegister dest, Label *failure) {
        Label isDouble, done;
        Register tag = splitTagForTest(source);
        branchTestDouble(Assembler::Equal, tag, &isDouble);
        branchTestInt32(Assembler::NotEqual, tag, failure);

        unboxInt32(source, ScratchReg);
        convertInt32ToDouble(ScratchReg, dest);
        jump(&done);

        bind(&isDouble);
        unboxDouble(source, dest);

        bind(&done);
    }

    // Setup a call to C/C++ code, given the number of general arguments it
    // takes. Note that this only supports cdecl.
    //
    // In order for alignment to work correctly, the MacroAssembler must have a
    // consistent view of the stack displacement. It is okay to call "push"
    // manually, however, if the stack alignment were to change, the macro
    // assembler should be notified before starting a call.
    void setupAlignedABICall(uint32_t args);

    // Sets up an ABI call for when the alignment is not known. This may need a
    // scratch register.
    void setupUnalignedABICall(uint32_t args, const Register &scratch);

    // Arguments must be assigned to a C/C++ call in order. They are moved
    // in parallel immediately before performing the call. This process may
    // temporarily use more stack, in which case esp-relative addresses will be
    // automatically adjusted. It is extremely important that esp-relative
    // addresses are computed *after* setupABICall(). Furthermore, no
    // operations should be emitted while setting arguments.
    void passABIArg(const MoveOperand &from);
    void passABIArg(const Register &reg);
    void passABIArg(const FloatRegister &reg);

  private:
    void callWithABIPre(uint32_t *stackAdjust);
    void callWithABIPost(uint32_t stackAdjust, Result result);

  public:
    // Emits a call to a C/C++ function, resolving all argument moves.
    void callWithABI(void *fun, Result result = GENERAL);
    void callWithABI(Address fun, Result result = GENERAL);

    void handleFailureWithHandler(void *handler);

    void makeFrameDescriptor(Register frameSizeReg, FrameType type) {
        shlq(Imm32(FRAMESIZE_SHIFT), frameSizeReg);
        orq(Imm32(type), frameSizeReg);
    }

    // Save an exit frame (which must be aligned to the stack pointer) to
    // ThreadData::ionTop of the main thread.
    void linkExitFrame() {
        mov(ImmWord(GetIonContext()->runtime), ScratchReg);
        mov(StackPointer, Operand(ScratchReg, offsetof(JSRuntime, mainThread.ionTop)));
    }

    void callWithExitFrame(IonCode *target, Register dynStack) {
        addPtr(Imm32(framePushed()), dynStack);
        makeFrameDescriptor(dynStack, IonFrame_OptimizedJS);
        Push(dynStack);
        call(target);
    }

    // Save an exit frame to the thread data of the current thread, given a
    // register that holds a PerThreadData *.
    void linkParallelExitFrame(const Register &pt) {
        mov(StackPointer, Operand(pt, offsetof(PerThreadData, ionTop)));
    }

    void enterOsr(Register calleeToken, Register code) {
        push(Imm32(0)); // num actual args.
        push(calleeToken);
        push(Imm32(MakeFrameDescriptor(0, IonFrame_Osr)));
        call(code);
        addq(Imm32(sizeof(uintptr_t) * 2), rsp);
    }

    // See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
    void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, unsigned codeBytes,
                                unsigned globalDataOffset)
    {
        uint8_t *nextInsn = code + offset;
        JS_ASSERT(nextInsn <= code + codeBytes);
        uint8_t *target = code + codeBytes + globalDataOffset;
        ((int32_t *)nextInsn)[-1] = target - nextInsn;
    }
    void memIntToValue(Address Source, Address Dest) {
        load32(Source, ScratchReg);
        storeValue(JSVAL_TYPE_INT32, ScratchReg, Dest);
    }

};

typedef MacroAssemblerX64 MacroAssemblerSpecific;

} // namespace jit
} // namespace js

#endif /* jit_x64_MacroAssembler_x64_h */
