/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QBuffer>
#include <QFile>

#include "qv4engine_p.h"
#include "qv4baselineassembler_p.h"
#include "qv4assemblercommon_p.h"
#include <private/qv4function_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4stackframe_p.h>

#include <wtf/Vector.h>
#include <assembler/MacroAssembler.h>
#include <assembler/MacroAssemblerCodeRef.h>
#include <assembler/LinkBuffer.h>
#include <WTFStubs.h>

#undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES

QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {

#define ASM_GENERATE_RUNTIME_CALL(function, destination) \
    pasm()->GENERATE_RUNTIME_CALL(function, destination)
#define callHelper(x) \
    PlatformAssemblerCommon::callRuntimeUnchecked(reinterpret_cast<void *>(&x), #x)

const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;

static ReturnedValue toNumberHelper(ReturnedValue v)
{
    return Encode(Value::fromReturnedValue(v).toNumber());
}

static ReturnedValue toInt32Helper(ReturnedValue v)
{
    return Encode(Value::fromReturnedValue(v).toInt32());
}

#if QT_POINTER_SIZE == 8 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
class PlatformAssembler64 : public PlatformAssemblerCommon
{
public:
    PlatformAssembler64(const Value *constantTable)
        : PlatformAssemblerCommon(constantTable)
    {}

    void callRuntime(const void *funcPtr, CallResultDestination dest)
    {
        PlatformAssemblerCommon::callRuntime(funcPtr);
        if (dest == CallResultDestination::InAccumulator)
            saveReturnValueInAccumulator();
        else if (AccumulatorRegister == ReturnValueRegister)
            loadUndefined();
    }

    void saveReturnValueInAccumulator()
    {
        move(ReturnValueRegister, AccumulatorRegister);
    }

    void loadUndefined(RegisterID dest = AccumulatorRegister)
    {
        move(TrustedImm64(0), dest);
    }

    void copyConst(int constIndex, Address dest)
    {
        //###
        if (constant(constIndex).isUndefined()) {
            loadUndefined(ScratchRegister);
        } else {
            load64(loadConstAddress(constIndex, ScratchRegister), ScratchRegister);
        }
        store64(ScratchRegister, dest);
    }

    void copyReg(Address src, Address dst)
    {
        load64(src, ScratchRegister);
        store64(ScratchRegister, dst);
    }

    void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegister)
    {
        load64(addr, dest);
    }

    void loadAccumulator(Address addr)
    {
        load64(addr, AccumulatorRegister);
    }

    void storeAccumulator(Address addr)
    {
        store64(AccumulatorRegister, addr);
    }

    void moveReg(Address sourceRegAddress, Address destRegAddress)
    {
        load64(sourceRegAddress, ScratchRegister);
        store64(ScratchRegister, destRegAddress);
    }

    void loadString(int stringId)
    {
        loadAccumulator(loadStringAddress(stringId));
    }

    void loadValue(ReturnedValue value)
    {
        move(TrustedImm64(value), AccumulatorRegister);
    }

    void storeHeapObject(RegisterID source, Address addr)
    {
        store64(source, addr);
    }

    void generateCatchTrampoline()
    {
        PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
    }

    void jumpNotUndefined(int offset)
    {
        auto jump = branch64(NotEqual, AccumulatorRegister, TrustedImm64(0));
        addJumpToOffset(jump, offset);
    }

    Jump jumpEmpty()
    {
        return branch64(Equal, AccumulatorRegister, TrustedImm64(Value::emptyValue().asReturnedValue()));
    }

    Jump jumpNotEmpty()
    {
        return branch64(NotEqual, AccumulatorRegister, TrustedImm64(Value::emptyValue().asReturnedValue()));
    }

    void toBoolean(std::function<void(RegisterID)> continuation)
    {
        urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister);
        auto needsConversion = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
        continuation(AccumulatorRegister);
        Jump done = jump();

        // slow path:
        needsConversion.link(this);
        push(AccumulatorRegister);
        move(AccumulatorRegister, registerForArg(0));
        callHelper(Value::toBooleanImpl);
        and32(TrustedImm32(1), ReturnValueRegister, ScratchRegister);
        pop(AccumulatorRegister);
        continuation(ScratchRegister);

        done.link(this);
    }

    void toNumber()
    {
        urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister);
        auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));

        move(AccumulatorRegister, registerForArg(0));
        callHelper(toNumberHelper);
        saveReturnValueInAccumulator();

        isNumber.link(this);
    }

    // this converts both the lhs and the accumulator to int32
    void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
    {
        load64(lhs, lhsTarget);
        urshift64(lhsTarget, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
        auto lhsIsInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);

        const Address accumulatorStackAddress(JSStackFrameRegister,
                                              offsetof(CallData, accumulator));
        storeAccumulator(accumulatorStackAddress);
        move(lhsTarget, registerForArg(0));
        callHelper(toInt32Helper);
        move(ReturnValueRegister, lhsTarget);
        loadAccumulator(accumulatorStackAddress);

        lhsIsInt.link(this);
        urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
        auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);

        pushAligned(lhsTarget);
        move(AccumulatorRegister, registerForArg(0));
        callHelper(toInt32Helper);
        saveReturnValueInAccumulator();
        popAligned(lhsTarget);

        isInt.link(this);
    }

    void toInt32()
    {
        urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
        auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);

        move(AccumulatorRegister, registerForArg(0));
        callHelper(toInt32Helper);
        saveReturnValueInAccumulator();

        isInt.link(this);
    }

    void regToInt32(Address srcReg, RegisterID targetReg)
    {
        load64(srcReg, targetReg);
        urshift64(targetReg, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
        auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);

        pushAligned(AccumulatorRegister);
        move(targetReg, registerForArg(0));
        callHelper(toInt32Helper);
        move(ReturnValueRegister, targetReg);
        popAligned(AccumulatorRegister);

        isInt.link(this);
    }

    void isNullOrUndefined()
    {
        move(AccumulatorRegister, ScratchRegister);
        compare64(Equal, ScratchRegister, TrustedImm32(0), AccumulatorRegister);
        Jump isUndef = branch32(NotEqual, TrustedImm32(0), AccumulatorRegister);

        // not undefined
        rshift64(TrustedImm32(32), ScratchRegister);
        compare32(Equal, ScratchRegister, TrustedImm32(int(QV4::Value::ValueTypeInternal::Null)),
                  AccumulatorRegister);

        isUndef.link(this);
    }

    Jump isIntOrBool()
    {
        urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerOrBool_Shift), ScratchRegister);
        return branch32(Equal, TrustedImm32(3), ScratchRegister);
    }

    void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
    {
        Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
        load64(lhsAddr, ScratchRegister);
        Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
        Jump equal = branch32(Equal, TrustedImm32(rhs), ScratchRegister);
        addJumpToOffset(equal, offset);
        isUndef.link(this);
    }

    void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
    {
        Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
        load64(lhsAddr, ScratchRegister);
        Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
        addJumpToOffset(isUndef, offset);
        Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
        addJumpToOffset(notEqual, offset);
    }

    void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
    {
        if (sourceReg == NoRegister)
            or64(TrustedImm64(int64_t(tag) << 32), AccumulatorRegister);
        else
            or64(TrustedImm64(int64_t(tag) << 32), sourceReg, AccumulatorRegister);
    }

    void encodeDoubleIntoAccumulator(FPRegisterID src)
    {
        moveDoubleTo64(src, AccumulatorRegister);
        move(TrustedImm64(Value::NaNEncodeMask), ScratchRegister);
        xor64(ScratchRegister, AccumulatorRegister);
    }

    void pushValueAligned(ReturnedValue v)
    {
        loadValue(v);
        pushAligned(AccumulatorRegister);
    }

    void popValueAligned()
    {
        addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
    }

    Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
    {
        urshift64(AccumulatorRegister, TrustedImm32(32), ScratchRegister);
        Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
        load64(lhsAddr, ScratchRegister);
        urshift64(ScratchRegister, TrustedImm32(32), ScratchRegister2);
        Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister2);

        // both integer
        Jump failure = fastPath();
        Jump done = jump();

        // all other cases
        if (failure.isSet())
            failure.link(this);
        accNotInt.link(this);
        lhsNotInt.link(this);

        return done;
    }

    Jump unopIntPath(std::function<Jump(void)> fastPath)
    {
        urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister);
        Jump accNotIntConvertible = branch32(NotEqual, TrustedImm32(1), ScratchRegister);

        // both integer
        Jump failure = fastPath();
        Jump done = jump();

        // all other cases
        if (failure.isSet())
            failure.link(this);
        accNotIntConvertible.link(this);

        return done;
    }

    void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
    {
        passAsArg(AccumulatorRegister, 0);
        doCall();
    }
};

typedef PlatformAssembler64 PlatformAssembler;
#endif

#if QT_POINTER_SIZE == 4 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
class PlatformAssembler32 : public PlatformAssemblerCommon
{
public:
    PlatformAssembler32(const Value *constantTable)
        : PlatformAssemblerCommon(constantTable)
    {}

    void callRuntime(const void *funcPtr, CallResultDestination dest)
    {
        PlatformAssemblerCommon::callRuntime(funcPtr);
        if (dest == CallResultDestination::InAccumulator)
            saveReturnValueInAccumulator();
        else if (AccumulatorRegisterValue == ReturnValueRegisterValue)
            loadUndefined();
    }

    void saveReturnValueInAccumulator()
    {
        move(ReturnValueRegisterValue, AccumulatorRegisterValue);
        move(ReturnValueRegisterTag, AccumulatorRegisterTag);
    }

    void loadUndefined()
    {
        move(TrustedImm32(0), AccumulatorRegisterValue);
        move(TrustedImm32(0), AccumulatorRegisterTag);
    }

    void copyConst(int constIndex, Address destRegAddr)
    {
        //###
        if (constant(constIndex).isUndefined()) {
            move(TrustedImm32(0), ScratchRegister);
            store32(ScratchRegister, destRegAddr);
            destRegAddr.offset += 4;
            store32(ScratchRegister, destRegAddr);
        } else {
            Address src = loadConstAddress(constIndex);
            loadDouble(src, FPScratchRegister);
            storeDouble(FPScratchRegister, destRegAddr);
        }
    }

    void copyReg(Address src, Address dest)
    {
        loadDouble(src, FPScratchRegister);
        storeDouble(FPScratchRegister, dest);
    }

    void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegisterValue)
    {
        load32(addr, dest);
    }

    void loadAccumulator(Address src)
    {
        load32(src, AccumulatorRegisterValue);
        src.offset += 4;
        load32(src, AccumulatorRegisterTag);
    }

    void storeAccumulator(Address addr)
    {
        store32(AccumulatorRegisterValue, addr);
        addr.offset += 4;
        store32(AccumulatorRegisterTag, addr);
    }

    void moveReg(Address sourceRegAddress, Address destRegAddress)
    {
        load32(sourceRegAddress, ScratchRegister);
        store32(ScratchRegister, destRegAddress);
        sourceRegAddress.offset += 4;
        destRegAddress.offset += 4;
        load32(sourceRegAddress, ScratchRegister);
        store32(ScratchRegister, destRegAddress);
    }

    void loadString(int stringId)
    {
        load32(loadStringAddress(stringId), AccumulatorRegisterValue);
        move(TrustedImm32(0), AccumulatorRegisterTag);
    }

    void loadValue(ReturnedValue value)
    {
        move(TrustedImm32(Value::fromReturnedValue(value).value()), AccumulatorRegisterValue);
        move(TrustedImm32(Value::fromReturnedValue(value).tag()), AccumulatorRegisterTag);
    }

    void storeHeapObject(RegisterID source, Address addr)
    {
        store32(source, addr);
        addr.offset += 4;
        store32(TrustedImm32(0), addr);
    }


    void generateCatchTrampoline()
    {
        PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
    }

    void toNumber()
    {
        urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
        auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));

        if (ArgInRegCount < 2) {
            subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); // stack alignment
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        } else {
            move(AccumulatorRegisterValue, registerForArg(0));
            move(AccumulatorRegisterTag, registerForArg(1));
        }
        callHelper(toNumberHelper);
        saveReturnValueInAccumulator();
        if (ArgInRegCount < 2)
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);

        isNumber.link(this);
    }

    // this converts both the lhs and the accumulator to int32
    void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
    {
        bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
                || AccumulatorRegisterTag == ReturnValueRegisterTag;
        lhs.offset += 4;
        load32(lhs, lhsTarget);
        lhs.offset -= 4;
        auto lhsIsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), lhsTarget);
        load32(lhs, lhsTarget);
        auto lhsIsInt = jump();

        lhsIsNotInt.link(this);

        // Save accumulator from being garbage collected, no matter if we will reuse the register.
        const Address accumulatorStackAddress(JSStackFrameRegister,
                                              offsetof(CallData, accumulator));
        storeAccumulator(accumulatorStackAddress);

        if (ArgInRegCount < 2) {
            subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            push(lhsTarget);
            load32(lhs, lhsTarget);
            push(lhsTarget);
        } else {
            move(lhsTarget, registerForArg(1));
            load32(lhs, registerForArg(0));
        }
        callHelper(toInt32Helper);
        move(ReturnValueRegisterValue, lhsTarget);
        if (ArgInRegCount < 2)
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);

        if (accumulatorNeedsSaving) // otherwise it's still the same
            loadAccumulator(accumulatorStackAddress);

        lhsIsInt.link(this);

        auto rhsIsInt = branch32(Equal, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);

        pushAligned(lhsTarget);
        if (ArgInRegCount < 2) {
            subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        } else {
            move(AccumulatorRegisterValue, registerForArg(0));
            move(AccumulatorRegisterTag, registerForArg(1));
        }
        callHelper(toInt32Helper);
        saveReturnValueInAccumulator();
        if (ArgInRegCount < 2)
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
        popAligned(lhsTarget);

        rhsIsInt.link(this);
    }

    void toInt32()
    {
        urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
        auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister);

        if (ArgInRegCount < 2) {
            subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); // align the stack on a 16-byte boundary
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        } else {
            move(AccumulatorRegisterValue, registerForArg(0));
            move(AccumulatorRegisterTag, registerForArg(1));
        }
        callHelper(toInt32Helper);
        saveReturnValueInAccumulator();
        if (ArgInRegCount < 2)
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);

        isInt.link(this);
    }

    void regToInt32(Address srcReg, RegisterID targetReg)
    {
        bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
                || AccumulatorRegisterTag == ReturnValueRegisterTag;
        if (accumulatorNeedsSaving) {
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        }
        if (ArgInRegCount < 2) {
            if (!accumulatorNeedsSaving)
                subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            srcReg.offset += 4;
            load32(srcReg, targetReg);
            push(targetReg);
            srcReg.offset -= 4;
            load32(srcReg, targetReg);
            push(targetReg);
        } else {
            if (accumulatorNeedsSaving)
                subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            load32(srcReg, registerForArg(0));
            srcReg.offset += 4;
            load32(srcReg, registerForArg(1));
        }
        callHelper(toInt32Helper);
        move(ReturnValueRegisterValue, targetReg);
        if (accumulatorNeedsSaving) {
            addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            pop(AccumulatorRegisterValue);
            pop(AccumulatorRegisterTag);
        } else if (ArgInRegCount < 2) {
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
        }
    }

    void isNullOrUndefined()
    {
        Jump notUndefOrPtr = branch32(NotEqual, TrustedImm32(0), AccumulatorRegisterTag);
        compare32(Equal, AccumulatorRegisterValue, TrustedImm32(0), AccumulatorRegisterValue);
        auto done = jump();

        // not undefined or managed
        notUndefOrPtr.link(this);
        compare32(Equal, AccumulatorRegisterTag, TrustedImm32(int(QV4::Value::ValueTypeInternal::Null)),
                  AccumulatorRegisterValue);

        done.link(this);
    }

    Jump isIntOrBool()
    {
        urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerOrBool_Shift - 32), ScratchRegister);
        return branch32(Equal, TrustedImm32(3), ScratchRegister);
    }

    void pushValue(ReturnedValue v)
    {
        push(TrustedImm32(v >> 32));
        push(TrustedImm32(v));
    }

    void jumpNotUndefined(int offset)
    {
        move(AccumulatorRegisterTag, ScratchRegister);
        or32(AccumulatorRegisterValue, ScratchRegister);
        auto jump = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
        addJumpToOffset(jump, offset);
    }

    Jump jumpEmpty()
    {
        return branch32(Equal, AccumulatorRegisterTag, TrustedImm32(Value::emptyValue().asReturnedValue() >> 32));
    }

    Jump jumpNotEmpty()
    {
        return branch32(NotEqual, AccumulatorRegisterTag, TrustedImm32(Value::emptyValue().asReturnedValue() >> 32));
    }

    void toBoolean(std::function<void(RegisterID)> continuation)
    {
        urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerConvertible_Shift - 32),
                  ScratchRegister);
        auto needsConversion = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
        continuation(AccumulatorRegisterValue);
        Jump done = jump();

        // slow path:
        needsConversion.link(this);

        bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
                || AccumulatorRegisterTag == ReturnValueRegisterTag;
        if (accumulatorNeedsSaving) {
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        }

        if (ArgInRegCount < 2) {
            if (!accumulatorNeedsSaving)
                subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        } else {
            if (accumulatorNeedsSaving)
                subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            move(AccumulatorRegisterValue, registerForArg(0));
            move(AccumulatorRegisterTag, registerForArg(1));
        }
        callHelper(Value::toBooleanImpl);
        and32(TrustedImm32(1), ReturnValueRegisterValue, ScratchRegister);
        if (accumulatorNeedsSaving) {
            addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            pop(AccumulatorRegisterValue);
            pop(AccumulatorRegisterTag);
        } else if (ArgInRegCount < 2) {
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
        }
        continuation(ScratchRegister);

        done.link(this);
    }

    void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
    {
        Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
        load32(lhsAddr, ScratchRegister);
        Jump notEqInt = branch32(NotEqual, ScratchRegister, TrustedImm32(rhs));
        Jump notEqUndefVal = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
        addJumpToOffset(notEqUndefVal, offset);
        lhsAddr.offset += 4;
        load32(lhsAddr, ScratchRegister);
        Jump notEqUndefTag = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
        addJumpToOffset(notEqUndefTag, offset);
        notEqInt.link(this);
    }

    void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
    {
        Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
        load32(lhsAddr, ScratchRegister);
        Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
        addJumpToOffset(notEqual, offset);
        Jump notUndefValue = branch32(NotEqual, TrustedImm32(0), ScratchRegister);
        lhsAddr.offset += 4;
        load32(lhsAddr, ScratchRegister);
        Jump equalUndef = branch32(Equal, TrustedImm32(0), ScratchRegister);
        addJumpToOffset(equalUndef, offset);
        notUndefValue.link(this);
    }

    void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
    {
        if (sourceReg != NoRegister)
            move(sourceReg, AccumulatorRegisterValue);
        move(TrustedImm32(int(tag)), AccumulatorRegisterTag);
    }

    void encodeDoubleIntoAccumulator(FPRegisterID src)
    {
        moveDoubleToInts(src, AccumulatorRegisterValue, AccumulatorRegisterTag);
        xor32(TrustedImm32(Value::NaNEncodeMask >> 32), AccumulatorRegisterTag);
    }

    void pushValueAligned(ReturnedValue v)
    {
        pushValue(v);
    }

    void popValueAligned()
    {
        popValue();
    }

    Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
    {
        Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
        Address lhsAddrTag = lhsAddr; lhsAddrTag.offset += Value::tagOffset();
        load32(lhsAddrTag, ScratchRegister);
        Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);

        // both integer
        Address lhsAddrValue = lhsAddr; lhsAddrValue.offset += Value::valueOffset();
        load32(lhsAddrValue, ScratchRegister);
        Jump failure = fastPath();
        Jump done = jump();

        // all other cases
        if (failure.isSet())
            failure.link(this);
        accNotInt.link(this);
        lhsNotInt.link(this);

        return done;
    }

    Jump unopIntPath(std::function<Jump(void)> fastPath)
    {
        Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);

        // both integer
        Jump failure = fastPath();
        Jump done = jump();

        // all other cases
        if (failure.isSet())
            failure.link(this);
        accNotInt.link(this);

        return done;
    }

    void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
    {
        if (ArgInRegCount < 2) {
            subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
            push(AccumulatorRegisterTag);
            push(AccumulatorRegisterValue);
        } else {
            move(AccumulatorRegisterValue, registerForArg(0));
            move(AccumulatorRegisterTag, registerForArg(1));
        }
        doCall();
        if (ArgInRegCount < 2)
            addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
    }
};

typedef PlatformAssembler32 PlatformAssembler;
#endif

#define pasm() reinterpret_cast<PlatformAssembler *>(this->d)

typedef PlatformAssembler::TrustedImmPtr TrustedImmPtr;
typedef PlatformAssembler::TrustedImm32 TrustedImm32;
typedef PlatformAssembler::TrustedImm64 TrustedImm64;
typedef PlatformAssembler::Address Address;
typedef PlatformAssembler::RegisterID RegisterID;
typedef PlatformAssembler::FPRegisterID FPRegisterID;

static Address regAddr(int reg)
{
    return Address(PlatformAssembler::JSStackFrameRegister, reg * int(sizeof(QV4::Value)));
}

BaselineAssembler::BaselineAssembler(const Value *constantTable)
    : d(new PlatformAssembler(constantTable))
{
}

BaselineAssembler::~BaselineAssembler()
{
    delete pasm();
}

void BaselineAssembler::generatePrologue()
{
    pasm()->generateFunctionEntry();
}

void BaselineAssembler::generateEpilogue()
{
    pasm()->generateCatchTrampoline();
}

void BaselineAssembler::link(Function *function)
{
    pasm()->link(function, "BaselineJIT");
}

void BaselineAssembler::addLabel(int offset)
{
    pasm()->addLabelForOffset(offset);
}

void BaselineAssembler::loadConst(int constIndex)
{
    //###
    if (pasm()->constant(constIndex).isUndefined()) {
        pasm()->loadUndefined();
    } else {
        pasm()->loadAccumulator(pasm()->loadConstAddress(constIndex));
    }
}

void BaselineAssembler::copyConst(int constIndex, int destReg)
{
    pasm()->copyConst(constIndex, regAddr(destReg));
}

void BaselineAssembler::loadReg(int reg)
{
    pasm()->loadAccumulator(regAddr(reg));
}

void JIT::BaselineAssembler::moveReg(int sourceReg, int destReg)
{
    pasm()->moveReg(regAddr(sourceReg), regAddr(destReg));
}

void BaselineAssembler::storeReg(int reg)
{
    pasm()->storeAccumulator(regAddr(reg));
}

void BaselineAssembler::loadLocal(int index, int level)
{
    Heap::CallContext ctx;
    Q_UNUSED(ctx)
    pasm()->loadPointerFromValue(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
    while (level) {
        pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
        --level;
    }
    pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
}

void BaselineAssembler::storeLocal(int index, int level)
{
    Heap::CallContext ctx;
    Q_UNUSED(ctx)
    pasm()->loadPtr(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
    while (level) {
        pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
        --level;
    }
    pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
}

void BaselineAssembler::loadString(int stringId)
{
    pasm()->loadString(stringId);
}

void BaselineAssembler::loadValue(ReturnedValue value)
{
    pasm()->loadValue(value);
}

void BaselineAssembler::storeHeapObject(int reg)
{
    pasm()->storeHeapObject(PlatformAssembler::ReturnValueRegisterValue, regAddr(reg));
}

void BaselineAssembler::loadImport(int index)
{
    Address addr = pasm()->loadCompilationUnitPtr(PlatformAssembler::ScratchRegister);
    addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, imports);
    pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister);
    addr.offset = index * int(sizeof(QV4::Value*));
    pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister);
    pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister));
}

void BaselineAssembler::toNumber()
{
    pasm()->toNumber();
}

void BaselineAssembler::uminus()
{
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(1);
    pasm()->passAccumulatorAsArg(0);
    ASM_GENERATE_RUNTIME_CALL(UMinus, CallResultDestination::InAccumulator);
    checkException();
}

void BaselineAssembler::ucompl()
{
    pasm()->toInt32();
    pasm()->xor32(TrustedImm32(-1), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

static ReturnedValue incHelper(const Value v)
{
    double d;
    if (Q_LIKELY(v.isDouble()))
        d =  v.doubleValue();
    else
        d = v.toNumberImpl();
    return Encode(d + 1.);
}

void BaselineAssembler::inc()
{
    auto done = pasm()->unopIntPath([this](){
        auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
                                              PlatformAssembler::AccumulatorRegisterValue,
                                              TrustedImm32(1),
                                              PlatformAssembler::ScratchRegister);
        pasm()->setAccumulatorTag(IntegerTag, PlatformAssembler::ScratchRegister);
        return overflowed;
    });

    // slow path:
    pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
        pasm()->callHelper(incHelper);
        pasm()->saveReturnValueInAccumulator();
    });
    checkException();

    // done.
    done.link(pasm());
}

static ReturnedValue decHelper(const Value v)
{
    double d;
    if (Q_LIKELY(v.isDouble()))
        d =  v.doubleValue();
    else
        d = v.toNumberImpl();
    return Encode(d - 1.);
}

void BaselineAssembler::dec()
{
    auto done = pasm()->unopIntPath([this](){
        auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
                                              PlatformAssembler::AccumulatorRegisterValue,
                                              TrustedImm32(1),
                                              PlatformAssembler::ScratchRegister);
        pasm()->setAccumulatorTag(IntegerTag, PlatformAssembler::ScratchRegister);
        return overflowed;
    });

    // slow path:
    pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
        pasm()->callHelper(decHelper);
        pasm()->saveReturnValueInAccumulator();
    });
    checkException();

    // done.
    done.link(pasm());
}

void BaselineAssembler::unot()
{
    pasm()->toBoolean([this](PlatformAssembler::RegisterID resultReg){
        pasm()->compare32(PlatformAssembler::Equal, resultReg,
                          TrustedImm32(0), PlatformAssembler::AccumulatorRegisterValue);
        pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
    });
}

void BaselineAssembler::add(int lhs)
{
    auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
        auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
                                              PlatformAssembler::AccumulatorRegisterValue,
                                              PlatformAssembler::ScratchRegister);
        pasm()->setAccumulatorTag(IntegerTag,
                                  PlatformAssembler::ScratchRegister);
        return overflowed;
    });

    // slow path:
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(3);
    pasm()->passAccumulatorAsArg(2);
    pasm()->passJSSlotAsArg(lhs, 1);
    pasm()->passEngineAsArg(0);
    ASM_GENERATE_RUNTIME_CALL(Add, CallResultDestination::InAccumulator);
    checkException();

    // done.
    done.link(pasm());
}

void BaselineAssembler::bitAnd(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->and32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::bitOr(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->or32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::bitXor(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->xor32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::ushr(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->urshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
    pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
                                         PlatformAssembler::AccumulatorRegisterValue,
                                         TrustedImm32(0));
    pasm()->setAccumulatorTag(IntegerTag);
    auto done = pasm()->jump();

    doubleEncode.link(pasm());
    pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
                                  PlatformAssembler::FPScratchRegister,
                                  PlatformAssembler::ScratchRegister);
    pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
    done.link(pasm());
}

void BaselineAssembler::shr(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->rshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
    pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::shl(int lhs)
{
    PlatformAssembler::Address lhsAddr = regAddr(lhs);
    pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
    pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->lshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
    pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::bitAndConst(int rhs)
{
    pasm()->toInt32();
    pasm()->and32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::bitOrConst(int rhs)
{
    pasm()->toInt32();
    pasm()->or32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::bitXorConst(int rhs)
{
    pasm()->toInt32();
    pasm()->xor32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::ushrConst(int rhs)
{
    rhs &= 0x1f;
    pasm()->toInt32();
    if (rhs) {
        // a non zero shift will always give a number encodable as an int
        pasm()->urshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
        pasm()->setAccumulatorTag(IntegerTag);
    } else {
        // shift with 0 can lead to a negative result
        auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
                                             PlatformAssembler::AccumulatorRegisterValue,
                                             TrustedImm32(0));
        pasm()->setAccumulatorTag(IntegerTag);
        auto done = pasm()->jump();

        doubleEncode.link(pasm());
        pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
                                      PlatformAssembler::FPScratchRegister,
                                      PlatformAssembler::ScratchRegister);
        pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
        done.link(pasm());
    }
}

void BaselineAssembler::shrConst(int rhs)
{
    rhs &= 0x1f;
    pasm()->toInt32();
    if (rhs)
        pasm()->rshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::shlConst(int rhs)
{
    rhs &= 0x1f;
    pasm()->toInt32();
    if (rhs)
        pasm()->lshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(IntegerTag);
}

void BaselineAssembler::mul(int lhs)
{
    auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
        auto overflowed = pasm()->branchMul32(PlatformAssembler::Overflow,
                                              PlatformAssembler::AccumulatorRegisterValue,
                                              PlatformAssembler::ScratchRegister);
        pasm()->setAccumulatorTag(IntegerTag,
                                  PlatformAssembler::ScratchRegister);
        return overflowed;
    });

    // slow path:
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(2);
    pasm()->passAccumulatorAsArg(1);
    pasm()->passJSSlotAsArg(lhs, 0);
    ASM_GENERATE_RUNTIME_CALL(Mul, CallResultDestination::InAccumulator);
    checkException();

    // done.
    done.link(pasm());
}

void BaselineAssembler::div(int lhs)
{
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(2);
    pasm()->passAccumulatorAsArg(1);
    pasm()->passJSSlotAsArg(lhs, 0);
    ASM_GENERATE_RUNTIME_CALL(Div, CallResultDestination::InAccumulator);
    checkException();
}

void BaselineAssembler::mod(int lhs)
{
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(2);
    pasm()->passAccumulatorAsArg(1);
    pasm()->passJSSlotAsArg(lhs, 0);
    ASM_GENERATE_RUNTIME_CALL(Mod, CallResultDestination::InAccumulator);
    checkException();
}

void BaselineAssembler::sub(int lhs)
{
    auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
        auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
                                              PlatformAssembler::AccumulatorRegisterValue,
                                              PlatformAssembler::ScratchRegister);
        pasm()->setAccumulatorTag(IntegerTag,
                                  PlatformAssembler::ScratchRegister);
        return overflowed;
    });

    // slow path:
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(2);
    pasm()->passAccumulatorAsArg(1);
    pasm()->passJSSlotAsArg(lhs, 0);
    ASM_GENERATE_RUNTIME_CALL(Sub, CallResultDestination::InAccumulator);
    checkException();

    // done.
    done.link(pasm());
}

void BaselineAssembler::cmpeqNull()
{
    pasm()->isNullOrUndefined();
    pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}

void BaselineAssembler::cmpneNull()
{
    pasm()->isNullOrUndefined();
    pasm()->xor32(TrustedImm32(1), PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}

void BaselineAssembler::cmpeqInt(int lhs)
{
    auto isIntOrBool = pasm()->isIntOrBool();
    saveAccumulatorInFrame();
    pasm()->pushValueAligned(Encode(lhs));
    if (PlatformAssembler::ArgInRegCount < 2)
        pasm()->push(PlatformAssembler::StackPointerRegister);
    else
        pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
    pasm()->pushAccumulatorAsArg(0);
    pasm()->callRuntimeUnchecked((void*)Runtime::Equal::call);
    pasm()->saveReturnValueInAccumulator();
    if (PlatformAssembler::ArgInRegCount < 2)
        pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
    pasm()->popValueAligned();
    auto done = pasm()->jump();
    isIntOrBool.link(pasm());
    pasm()->compare32(PlatformAssembler::Equal, PlatformAssembler::AccumulatorRegisterValue,
                      TrustedImm32(lhs),
                      PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
    done.link(pasm());
}

void BaselineAssembler::cmpneInt(int lhs)
{
    auto isIntOrBool = pasm()->isIntOrBool();
    saveAccumulatorInFrame();
    pasm()->pushValueAligned(Encode(lhs));
    if (PlatformAssembler::ArgInRegCount < 2)
        pasm()->push(PlatformAssembler::StackPointerRegister);
    else
        pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
    pasm()->pushAccumulatorAsArg(0);
    pasm()->callRuntimeUnchecked((void*)Runtime::NotEqual::call);
    pasm()->saveReturnValueInAccumulator();
    if (PlatformAssembler::ArgInRegCount < 2)
        pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
    pasm()->popValueAligned();
    auto done = pasm()->jump();
    isIntOrBool.link(pasm());
    pasm()->compare32(PlatformAssembler::NotEqual, PlatformAssembler::AccumulatorRegisterValue,
                      TrustedImm32(lhs),
                      PlatformAssembler::AccumulatorRegisterValue);
    pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
    done.link(pasm());
}

void BaselineAssembler::cmp(int cond, CmpFunc function, int lhs)
{
    auto c = static_cast<PlatformAssembler::RelationalCondition>(cond);
    auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){
        pasm()->compare32(c, PlatformAssembler::ScratchRegister,
                          PlatformAssembler::AccumulatorRegisterValue,
                          PlatformAssembler::AccumulatorRegisterValue);
        return PlatformAssembler::Jump();
    });

    // slow path:
    saveAccumulatorInFrame();
    pasm()->prepareCallWithArgCount(2);
    pasm()->passAccumulatorAsArg(1);
    pasm()->passJSSlotAsArg(lhs, 0);

    callRuntime(reinterpret_cast<void*>(function), CallResultDestination::InAccumulator);
    checkException();

    // done.
    done.link(pasm());
    pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
}

void BaselineAssembler::cmpeq(int lhs)
{
    cmp(PlatformAssembler::Equal, &Runtime::CompareEqual::call, lhs);
}

void BaselineAssembler::cmpne(int lhs)
{
    cmp(PlatformAssembler::NotEqual, &Runtime::CompareNotEqual::call, lhs);
}

void BaselineAssembler::cmpgt(int lhs)
{
    cmp(PlatformAssembler::GreaterThan, &Runtime::CompareGreaterThan::call, lhs);
}

void BaselineAssembler::cmpge(int lhs)
{
    cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::CompareGreaterEqual::call, lhs);
}

void BaselineAssembler::cmplt(int lhs)
{
    cmp(PlatformAssembler::LessThan, &Runtime::CompareLessThan::call, lhs);
}

void BaselineAssembler::cmple(int lhs)
{
    cmp(PlatformAssembler::LessThanOrEqual, &Runtime::CompareLessEqual::call, lhs);
}

void BaselineAssembler::cmpStrictEqual(int lhs)
{
    cmp(PlatformAssembler::Equal, &Runtime::CompareStrictEqual::call, lhs);
}

void BaselineAssembler::cmpStrictNotEqual(int lhs)
{
    cmp(PlatformAssembler::NotEqual, &Runtime::CompareStrictNotEqual::call, lhs);
}

int BaselineAssembler::jump(int offset)
{
    pasm()->addJumpToOffset(pasm()->jump(), offset);
    return offset;
}

int BaselineAssembler::jumpTrue(int offset)
{
    pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
        auto jump = pasm()->branch32(PlatformAssembler::NotEqual, TrustedImm32(0), resultReg);
        pasm()->addJumpToOffset(jump, offset);
    });
    return offset;
}

int BaselineAssembler::jumpFalse(int offset)
{
    pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
        auto jump = pasm()->branch32(PlatformAssembler::Equal, TrustedImm32(0), resultReg);
        pasm()->addJumpToOffset(jump, offset);
    });
    return offset;
}

int BaselineAssembler::jumpNoException(int offset)
{
    auto jump = pasm()->branch32(
        PlatformAssembler::Equal,
        PlatformAssembler::Address(PlatformAssembler::EngineRegister,
                                   offsetof(EngineBase, hasException)),
        TrustedImm32(0));
    pasm()->addJumpToOffset(jump, offset);
    return offset;
}

int BaselineAssembler::jumpNotUndefined(int offset)
{
    pasm()->jumpNotUndefined(offset);
    return offset;
}

void BaselineAssembler::prepareCallWithArgCount(int argc)
{
    pasm()->prepareCallWithArgCount(argc);
}

void BaselineAssembler::storeInstructionPointer(int instructionOffset)
{
    pasm()->storeInstructionPointer(instructionOffset);
}

void BaselineAssembler::passAccumulatorAsArg(int arg)
{
    pasm()->passAccumulatorAsArg(arg);
}

void BaselineAssembler::passFunctionAsArg(int arg)
{
    pasm()->passFunctionAsArg(arg);
}

void BaselineAssembler::passEngineAsArg(int arg)
{
    pasm()->passEngineAsArg(arg);
}

void BaselineAssembler::passJSSlotAsArg(int reg, int arg)
{
    pasm()->passJSSlotAsArg(reg, arg);
}

void BaselineAssembler::passCppFrameAsArg(int arg)
{
    pasm()->passCppFrameAsArg(arg);
}

void BaselineAssembler::passInt32AsArg(int value, int arg)
{
    pasm()->passInt32AsArg(value, arg);
}

void BaselineAssembler::passPointerAsArg(void *ptr, int arg)
{
    pasm()->passPointerAsArg(ptr, arg);
}

void BaselineAssembler::callRuntime(const void *funcPtr, CallResultDestination dest)
{
    pasm()->callRuntime(funcPtr, dest);
}

void BaselineAssembler::saveAccumulatorInFrame()
{
    pasm()->storeAccumulator(PlatformAssembler::Address(PlatformAssembler::JSStackFrameRegister,
                                                        offsetof(CallData, accumulator)));
}

void BaselineAssembler::loadAccumulatorFromFrame()
{
    pasm()->loadAccumulator(PlatformAssembler::Address(PlatformAssembler::JSStackFrameRegister,
                                                       offsetof(CallData, accumulator)));
}

static ReturnedValue TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing(CppStackFrame *frame, ExecutionEngine *engine)
{
    return Runtime::TailCall::call(frame, engine);
}

void BaselineAssembler::jsTailCall(int func, int thisObject, int argc, int argv)
{
    Address tos = pasm()->jsAlloca(4);

    int32_t argcOffset = tos.offset + int32_t(sizeof(Value)) * Runtime::StackOffsets::tailCall_argc;
    int32_t argvOffset = tos.offset + int32_t(sizeof(Value)) * Runtime::StackOffsets::tailCall_argv;
    int32_t thisOffset = tos.offset + int32_t(sizeof(Value)) * Runtime::StackOffsets::tailCall_thisObject;
    int32_t funcOffset = tos.offset + int32_t(sizeof(Value)) * Runtime::StackOffsets::tailCall_function;

    pasm()->storeInt32AsValue(argc,      Address(tos.base, argcOffset));
    pasm()->storeInt32AsValue(argv,      Address(tos.base, argvOffset));
    pasm()->moveReg(regAddr(thisObject), Address(tos.base, thisOffset));
    pasm()->moveReg(regAddr(func),       Address(tos.base, funcOffset));
    pasm()->tailCallRuntime(
            reinterpret_cast<void *>(TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing),
            "TheJitIs__Tail_Calling__ToTheRuntimeSoTheJitFrameIsMissing");
}

void BaselineAssembler::checkException()
{
    pasm()->checkException();
}

void BaselineAssembler::gotoCatchException()
{
    pasm()->addCatchyJump(pasm()->jump());
}

void BaselineAssembler::getException()
{
    Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);

    Address hasExceptionAddr(PlatformAssembler::EngineRegister,
                             offsetof(EngineBase, hasException));
    PlatformAssembler::Jump nope = pasm()->branch8(PlatformAssembler::Equal,
                                                  hasExceptionAddr,
                                                  TrustedImm32(0));
    pasm()->loadPtr(Address(PlatformAssembler::EngineRegister,
                            offsetof(EngineBase, exceptionValue)),
                    PlatformAssembler::ScratchRegister);
    pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister));
    pasm()->store8(TrustedImm32(0), hasExceptionAddr);
    auto done = pasm()->jump();
    nope.link(pasm());
    pasm()->loadValue(Value::emptyValue().asReturnedValue());

    done.link(pasm());
}

void BaselineAssembler::setException()
{
    auto noException = pasm()->jumpEmpty();
    Address addr(PlatformAssembler::EngineRegister, offsetof(EngineBase, exceptionValue));
    pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister);
    pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister));
    addr.offset = offsetof(EngineBase, hasException);
    Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
    pasm()->store8(TrustedImm32(1), addr);
    noException.link(pasm());
}

int BaselineAssembler::setUnwindHandler(int offset)
{
    auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
    pasm()->addEHTarget(l, offset);
    return offset;
}


void BaselineAssembler::clearUnwindHandler()
{
    pasm()->storePtr(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
}

void JIT::BaselineAssembler::unwindDispatch()
{
    checkException();
    pasm()->load32(Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)), PlatformAssembler::ScratchRegister);
    auto noUnwind = pasm()->branch32(PlatformAssembler::Equal, PlatformAssembler::ScratchRegister, TrustedImm32(0));
    pasm()->sub32(TrustedImm32(1), PlatformAssembler::ScratchRegister);
    pasm()->store32(PlatformAssembler::ScratchRegister, Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)));
    auto jump = pasm()->branch32(PlatformAssembler::Equal, PlatformAssembler::ScratchRegister, TrustedImm32(0));
    gotoCatchException();
    jump.link(pasm());

    pasm()->loadPtr(Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLabel)), PlatformAssembler::ScratchRegister);
    pasm()->jump(PlatformAssembler::ScratchRegister);

    noUnwind.link(pasm());
}

int JIT::BaselineAssembler::unwindToLabel(int level, int offset)
{
    auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLabel)));
    pasm()->addEHTarget(l, offset);
    pasm()->store32(TrustedImm32(level), Address(PlatformAssembler::CppStackFrameRegister, offsetof(CppStackFrame, unwindLevel)));
    gotoCatchException();
    return offset;
}

void BaselineAssembler::pushCatchContext(int index, int name)
{
    pasm()->prepareCallWithArgCount(3);
    pasm()->passInt32AsArg(name, 2);
    pasm()->passInt32AsArg(index, 1);
    pasm()->passEngineAsArg(0);
    ASM_GENERATE_RUNTIME_CALL(PushCatchContext, CallResultDestination::Ignore);
}

void BaselineAssembler::popContext()
{
    Heap::CallContext ctx;
    Q_UNUSED(ctx)
    pasm()->loadPointerFromValue(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
    pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
    pasm()->storeHeapObject(PlatformAssembler::ScratchRegister, regAddr(CallData::Context));
}

void BaselineAssembler::deadTemporalZoneCheck(int offsetForSavedIP, int variableName)
{
    auto valueIsAliveJump = pasm()->jumpNotEmpty();
    storeInstructionPointer(offsetForSavedIP);
    prepareCallWithArgCount(2);
    passInt32AsArg(variableName, 1);
    passEngineAsArg(0);
    ASM_GENERATE_RUNTIME_CALL(ThrowReferenceError, CallResultDestination::Ignore);
    gotoCatchException();
    valueIsAliveJump.link(pasm());
}

void BaselineAssembler::ret()
{
    pasm()->generateFunctionExit();
}

} // JIT namespace
} // QV4 namepsace

QT_END_NAMESPACE
