/*
 * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
 * Copyright (C) 2009 University of Szeged
 * All rights reserved.
 * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY MIPS TECHNOLOGIES, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#if ENABLE(ASSEMBLER) && CPU(MIPS)

#include "AssemblerBuffer.h"
#include "JITCompilationEffort.h"
#include "MIPSRegisters.h"
#include <limits.h>
#include <wtf/Assertions.h>
#include <wtf/SegmentedVector.h>

namespace JSC {

typedef uint32_t MIPSWord;

namespace RegisterNames {
typedef enum : int8_t {
#define REGISTER_ID(id, name, r, cs) id,
    FOR_EACH_GP_REGISTER(REGISTER_ID)
#undef REGISTER_ID
#define REGISTER_ALIAS(id, alias) id = alias,
    FOR_EACH_REGISTER_ALIAS(REGISTER_ALIAS)
#undef REGISTER_ALIAS
    InvalidGPRReg = -1,
} RegisterID;

typedef enum : int8_t {
#define REGISTER_ID(id, name, idx) id = idx,
    FOR_EACH_SP_REGISTER(REGISTER_ID)
#undef REGISTER_ID
} SPRegisterID;

typedef enum : int8_t {
#define REGISTER_ID(id, name, r, cs) id,
    FOR_EACH_FP_REGISTER(REGISTER_ID)
#undef REGISTER_ID
    InvalidFPRReg = -1,
} FPRegisterID;

} // namespace MIPSRegisters

class MIPSAssembler {
public:
    typedef MIPSRegisters::RegisterID RegisterID;
    typedef MIPSRegisters::SPRegisterID SPRegisterID;
    typedef MIPSRegisters::FPRegisterID FPRegisterID;
    typedef SegmentedVector<AssemblerLabel, 64> Jumps;

    static constexpr RegisterID firstRegister() { return MIPSRegisters::r0; }
    static constexpr RegisterID lastRegister() { return MIPSRegisters::r31; }
    static constexpr unsigned numberOfRegisters() { return lastRegister() - firstRegister() + 1; }

    static constexpr SPRegisterID firstSPRegister() { return MIPSRegisters::fir; }
    static constexpr SPRegisterID lastSPRegister() { return MIPSRegisters::pc; }
    static constexpr unsigned numberOfSPRegisters() { return lastSPRegister() - firstSPRegister() + 1; }

    static constexpr FPRegisterID firstFPRegister() { return MIPSRegisters::f0; }
    static constexpr FPRegisterID lastFPRegister() { return MIPSRegisters::f31; }
    static constexpr unsigned numberOfFPRegisters() { return lastFPRegister() - firstFPRegister() + 1; }
    
    static const char* gprName(RegisterID id)
    {
        ASSERT(id >= firstRegister() && id <= lastRegister());
        static const char* const nameForRegister[numberOfRegisters()] = {
#define REGISTER_NAME(id, name, r, c) name,
        FOR_EACH_GP_REGISTER(REGISTER_NAME)
#undef REGISTER_NAME
        };
        return nameForRegister[id];
    }

    static const char* sprName(SPRegisterID id)
    {
        ASSERT(id >= firstSPRegister() && id <= lastSPRegister());
        static const char* const nameForRegister[numberOfSPRegisters()] = {
#define REGISTER_NAME(id, name, idx) name,
        FOR_EACH_SP_REGISTER(REGISTER_NAME)
#undef REGISTER_NAME
        };
        return nameForRegister[id];
    }

    static const char* fprName(FPRegisterID id)
    {
        ASSERT(id >= firstFPRegister() && id <= lastFPRegister());
        static const char* const nameForRegister[numberOfFPRegisters()] = {
#define REGISTER_NAME(id, name, r, cs) name,
        FOR_EACH_FP_REGISTER(REGISTER_NAME)
#undef REGISTER_NAME
        };
        return nameForRegister[id];
    }

    MIPSAssembler()
        : m_indexOfLastWatchpoint(INT_MIN)
        , m_indexOfTailOfLastWatchpoint(INT_MIN)
    {
    }

    AssemblerBuffer& buffer() { return m_buffer; }

    // MIPS instruction opcode field position
    enum {
        OP_SH_RD = 11,
        OP_SH_RT = 16,
        OP_SH_RS = 21,
        OP_SH_SHAMT = 6,
        OP_SH_CODE = 16,
        OP_SH_FD = 6,
        OP_SH_FS = 11,
        OP_SH_FT = 16,
        OP_SH_MSB = 11,
        OP_SH_LSB = 6
    };

    // FCSR Bits
    enum {
        FP_CAUSE_INVALID_OPERATION = 1 << 16
    };

    void emitInst(MIPSWord op)
    {
        void* oldBase = m_buffer.data();

        m_buffer.putInt(op);

        void* newBase = m_buffer.data();
        if (oldBase != newBase)
            relocateJumps(oldBase, newBase);
    }

    void nop()
    {
        emitInst(0x00000000);
    }
    
    using CopyFunction = void*(&)(void*, const void*, size_t);

    template <CopyFunction copy>
    static void fillNops(void* base, size_t size)
    {
        UNUSED_PARAM(copy);
        RELEASE_ASSERT(!(size % sizeof(int32_t)));

        int32_t* ptr = static_cast<int32_t*>(base);
        const size_t num32s = size / sizeof(int32_t);
        const int32_t insn = 0x00000000;
        for (size_t i = 0; i < num32s; i++)
            *ptr++ = insn;
    }
    
    void sync()
    {
        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=169984
        // We might get a performance improvements by using SYNC_MB in some or
        // all cases.
        emitInst(0x0000000f);
    }

    /* Need to insert one load data delay nop for mips1.  */
    void loadDelayNop()
    {
#if WTF_MIPS_ISA(1)
        nop();
#endif
    }

    /* Need to insert one coprocessor access delay nop for mips1.  */
    void copDelayNop()
    {
#if WTF_MIPS_ISA(1)
        nop();
#endif
    }

    void move(RegisterID rd, RegisterID rs)
    {
        /* addu */
        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS));
    }

    /* Set an immediate value to a register.  This may generate 1 or 2
       instructions.  */
    void li(RegisterID dest, int imm)
    {
        if (imm >= -32768 && imm <= 32767)
            addiu(dest, MIPSRegisters::zero, imm);
        else if (imm >= 0 && imm < 65536)
            ori(dest, MIPSRegisters::zero, imm);
        else {
            lui(dest, imm >> 16);
            if (imm & 0xffff)
                ori(dest, dest, imm);
        }
    }

    void ext(RegisterID rt, RegisterID rs, int pos, int size)
    {
        int msb = size - 1;
        emitInst(0x7c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (pos << OP_SH_LSB) | (msb << OP_SH_MSB));
    }

    void mfhc1(RegisterID rt, FPRegisterID fs)
    {
        emitInst(0x4460000 | (rt << OP_SH_RT) | (fs << OP_SH_FS));
    }

    void lui(RegisterID rt, int imm)
    {
        emitInst(0x3c000000 | (rt << OP_SH_RT) | (imm & 0xffff));
    }

    void clz(RegisterID rd, RegisterID rs)
    {
        emitInst(0x70000020 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rd << OP_SH_RT));
    }

    void addiu(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x24000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void addu(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void subu(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000023 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void mult(RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000018 | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void div(RegisterID rs, RegisterID rt)
    {
        emitInst(0x0000001a | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void mfhi(RegisterID rd)
    {
        emitInst(0x00000010 | (rd << OP_SH_RD));
    }

    void mflo(RegisterID rd)
    {
        emitInst(0x00000012 | (rd << OP_SH_RD));
    }

    void mul(RegisterID rd, RegisterID rs, RegisterID rt)
    {
#if WTF_MIPS_ISA_AT_LEAST(32) 
        emitInst(0x70000002 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
#else
        mult(rs, rt);
        mflo(rd);
#endif
    }

    void andInsn(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000024 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void andi(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x30000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void nor(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000027 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void orInsn(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000025 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void ori(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x34000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void xorInsn(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x00000026 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void xori(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x38000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void slt(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x0000002a | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void sltu(RegisterID rd, RegisterID rs, RegisterID rt)
    {
        emitInst(0x0000002b | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT));
    }

    void slti(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x28000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void sltiu(RegisterID rt, RegisterID rs, int imm)
    {
        emitInst(0x2c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void sll(RegisterID rd, RegisterID rt, int shamt)
    {
        emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT));
    }

    void sllv(RegisterID rd, RegisterID rt, RegisterID rs)
    {
        emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS));
    }

    void sra(RegisterID rd, RegisterID rt, int shamt)
    {
        emitInst(0x00000003 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT));
    }

    void srav(RegisterID rd, RegisterID rt, RegisterID rs)
    {
        emitInst(0x00000007 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS));
    }

    void srl(RegisterID rd, RegisterID rt, int shamt)
    {
        emitInst(0x00000002 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT));
    }

    void srlv(RegisterID rd, RegisterID rt, RegisterID rs)
    {
        emitInst(0x00000006 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS));
    }

    void lb(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x80000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lbu(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x90000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lw(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x8c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lwl(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x88000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lwr(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x98000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lh(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x84000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void lhu(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0x94000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
        loadDelayNop();
    }

    void sb(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0xa0000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void sh(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0xa4000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void sw(RegisterID rt, RegisterID rs, int offset)
    {
        emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void jr(RegisterID rs)
    {
        emitInst(0x00000008 | (rs << OP_SH_RS));
    }

    void jalr(RegisterID rs)
    {
        emitInst(0x0000f809 | (rs << OP_SH_RS));
    }

    void jal()
    {
        emitInst(0x0c000000);
    }

    void bkpt()
    {
        int value = 512; /* BRK_BUG */
        emitInst(0x0000000d | ((value & 0x3ff) << OP_SH_CODE));
    }

    static bool isBkpt(void* address)
    {
        int value = 512; /* BRK_BUG */
        MIPSWord expected = (0x0000000d | ((value & 0x3ff) << OP_SH_CODE));
        MIPSWord candidateInstruction = *reinterpret_cast<MIPSWord*>(address);
        return candidateInstruction == expected;
    }

    void bgez(RegisterID rs, int imm)
    {
        emitInst(0x04010000 | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void bltz(RegisterID rs, int imm)
    {
        emitInst(0x04000000 | (rs << OP_SH_RS) | (imm & 0xffff));
    }

    void beq(RegisterID rs, RegisterID rt, int imm)
    {
        emitInst(0x10000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
    }

    void bne(RegisterID rs, RegisterID rt, int imm)
    {
        emitInst(0x14000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
    }

    void bc1t()
    {
        emitInst(0x45010000);
    }

    void bc1f()
    {
        emitInst(0x45000000);
    }

    void appendJump()
    {
        m_jumps.append(m_buffer.label());
    }

    void addd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200000 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT));
    }

    void subd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200001 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT));
    }

    void muld(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200002 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT));
    }

    void divd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200003 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT));
    }

    void lwc1(FPRegisterID ft, RegisterID rs, int offset)
    {
        emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff));
        copDelayNop();
    }

    void ldc1(FPRegisterID ft, RegisterID rs, int offset)
    {
        emitInst(0xd4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void swc1(FPRegisterID ft, RegisterID rs, int offset)
    {
        emitInst(0xe4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void sdc1(FPRegisterID ft, RegisterID rs, int offset)
    {
        emitInst(0xf4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff));
    }

    void mtc1(RegisterID rt, FPRegisterID fs)
    {
        emitInst(0x44800000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
        copDelayNop();
    }

    void mthc1(RegisterID rt, FPRegisterID fs)
    {
        emitInst(0x44e00000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
        copDelayNop();
    }

    void mfc1(RegisterID rt, FPRegisterID fs)
    {
        emitInst(0x44000000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
        copDelayNop();
    }

    void sqrtd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200004 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void absd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200005 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void movd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200006 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void negd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200007 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void truncwd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x4620000d | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void cvtdw(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void cvtds(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46000021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void cvtwd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200024 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void cvtsd(FPRegisterID fd, FPRegisterID fs)
    {
        emitInst(0x46200020 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
    }

    void ceqd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cngtd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x4620003f | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cnged(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x4620003d | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cltd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x4620003c | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cled(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x4620003e | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cueqd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200033 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void coled(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200036 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void coltd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200034 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void culed(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200037 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cultd(FPRegisterID fs, FPRegisterID ft)
    {
        emitInst(0x46200035 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
        copDelayNop();
    }

    void cfc1(RegisterID rt, SPRegisterID fs)
    {
        emitInst(0x44400000 | (rt << OP_SH_RT) | (fs << OP_SH_FS));
        copDelayNop();
    }

    // General helpers

    AssemblerLabel labelIgnoringWatchpoints()
    {
        return m_buffer.label();
    }

    AssemblerLabel labelForWatchpoint()
    {
        AssemblerLabel result = m_buffer.label();
        if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
            result = label();
        m_indexOfLastWatchpoint = result.m_offset;
        m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
        return result;
    }

    AssemblerLabel label()
    {
        AssemblerLabel result = m_buffer.label();
        while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
            nop();
            result = m_buffer.label();
        }
        return result;
    }

    AssemblerLabel align(int alignment)
    {
        while (!m_buffer.isAligned(alignment))
            bkpt();

        return label();
    }

    static void* getRelocatedAddress(void* code, AssemblerLabel label)
    {
        return reinterpret_cast<void*>(reinterpret_cast<char*>(code) + label.m_offset);
    }

    static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
    {
        return b.m_offset - a.m_offset;
    }

    // Assembler admin methods:

    size_t codeSize() const
    {
        return m_buffer.codeSize();
    }

    unsigned debugOffset() { return m_buffer.debugOffset(); }

    // Assembly helpers for moving data between fp and registers.
    void vmov(RegisterID rd1, RegisterID rd2, FPRegisterID rn)
    {
#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
        mfc1(rd1, rn);
        mfhc1(rd2, rn);
#else
        mfc1(rd1, rn);
        mfc1(rd2, FPRegisterID(rn + 1));
#endif
    }

    void vmov(FPRegisterID rd, RegisterID rn1, RegisterID rn2)
    {
#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
        mtc1(rn1, rd);
        mthc1(rn2, rd);
#else
        mtc1(rn1, rd);
        mtc1(rn2, FPRegisterID(rd + 1));
#endif
    }

    static unsigned getCallReturnOffset(AssemblerLabel call)
    {
        // The return address is after a call and a delay slot instruction
        return call.m_offset;
    }

    // Linking & patching:
    //
    // 'link' and 'patch' methods are for use on unprotected code - such as the code
    // within the AssemblerBuffer, and code being patched by the patch buffer. Once
    // code has been finalized it is (platform support permitting) within a non-
    // writable region of memory; to modify the code in an execute-only execuable
    // pool the 'repatch' and 'relink' methods should be used.

    static size_t linkDirectJump(void* code, void* to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code));
        size_t ops = 0;
        int32_t slotAddr = reinterpret_cast<int>(insn) + 4;
        int32_t toAddr = reinterpret_cast<int>(to);

        if ((slotAddr & 0xf0000000) != (toAddr & 0xf0000000)) {
            // lui
            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((toAddr >> 16) & 0xffff);
            ++insn;
            // ori
            *insn = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (toAddr & 0xffff);
            ++insn;
            // jr
            *insn = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
            ++insn;
            ops = 4 * sizeof(MIPSWord);
        } else {
            // j
            *insn = 0x08000000 | ((toAddr & 0x0fffffff) >> 2);
            ++insn;
            ops = 2 * sizeof(MIPSWord);
        }
        // nop
        *insn = 0x00000000;
        return ops;
    }

    void linkJump(AssemblerLabel from, AssemblerLabel to)
    {
        ASSERT(to.isSet());
        ASSERT(from.isSet());
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + from.m_offset);
        MIPSWord* toPos = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + to.m_offset);

        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
        insn = insn - 6;
        linkWithOffset(insn, toPos);
    }

    static void linkJump(void* code, AssemblerLabel from, void* to)
    {
        ASSERT(from.isSet());
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);

        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
        insn = insn - 6;
        linkWithOffset(insn, to);
    }

    static void linkCall(void* code, AssemblerLabel from, void* to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
        linkCallInternal(insn, to);
    }

    static void linkPointer(void* code, AssemblerLabel from, void* to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
        insn++;
        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
        *insn = (*insn & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
    }

    static void relinkJump(void* from, void* to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);

        ASSERT(!(*(insn - 1)) && !(*(insn - 5)));
        insn = insn - 6;
        int flushSize = linkWithOffset(insn, to);

        cacheFlush(insn, flushSize);
    }

    static void relinkJumpToNop(void* from)
    {
        relinkJump(from, from);
    }

    static void relinkCall(void* from, void* to)
    {
        void* start;
        int size = linkCallInternal(from, to);
        if (size == sizeof(MIPSWord))
            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 2 * sizeof(MIPSWord));
        else
            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 4 * sizeof(MIPSWord));

        cacheFlush(start, size);
    }

    static void repatchInt32(void* from, int32_t to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        *insn = (*insn & 0xffff0000) | ((to >> 16) & 0xffff);
        insn++;
        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
        *insn = (*insn & 0xffff0000) | (to & 0xffff);
        cacheFlush(from, 2 * sizeof(MIPSWord));
    }

    static int32_t readInt32(void* from)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        int32_t result = (*insn & 0x0000ffff) << 16;
        insn++;
        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
        result |= *insn & 0x0000ffff;
        return result;
    }
    
    static void repatchCompact(void* where, int32_t value)
    {
        repatchInt32(where, value);
    }

    static void repatchPointer(void* from, void* to)
    {
        repatchInt32(from, reinterpret_cast<int32_t>(to));
    }

    static void* readPointer(void* from)
    {
        return reinterpret_cast<void*>(readInt32(from));
    }

    static void* readCallTarget(void* from)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
        insn -= 4;
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        int32_t result = (*insn & 0x0000ffff) << 16;
        insn++;
        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
        result |= *insn & 0x0000ffff;
        return reinterpret_cast<void*>(result);
    }

    static void cacheFlush(void* code, size_t size)
    {
        intptr_t end = reinterpret_cast<intptr_t>(code) + size;
        __builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(end));
    }

    static ptrdiff_t maxJumpReplacementSize()
    {
        return sizeof(MIPSWord) * 4;
    }

    static constexpr ptrdiff_t patchableJumpSize()
    {
        return sizeof(MIPSWord) * 8;
    }

    static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
    {
        MIPSWord* insn = static_cast<MIPSWord*>(instructionStart);
        size_t codeSize = 2 * sizeof(MIPSWord);

        // lui
        *insn = 0x3c000000 | (rt << OP_SH_RT) | ((imm >> 16) & 0xffff);
        ++insn;
        // ori
        *insn = 0x34000000 | (rt << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff);
        ++insn;
        // if jr $t9
        if (*insn == 0x03200008) {
            *insn = 0x00000000;
            codeSize += sizeof(MIPSWord);
        }
        cacheFlush(instructionStart, codeSize);
    }

    static void replaceWithJump(void* instructionStart, void* to)
    {
        ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 3));
        ASSERT(!(bitwise_cast<uintptr_t>(to) & 3));
        size_t ops = linkDirectJump(instructionStart, to);
        cacheFlush(instructionStart, ops);
    }

    static void replaceWithLoad(void* instructionStart)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(instructionStart);
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        insn++;
        ASSERT((*insn & 0xfc0007ff) == 0x00000021); // addu
        insn++;
        *insn = 0x8c000000 | ((*insn) & 0x3ffffff); // lw
        cacheFlush(insn, 4);
    }

    static void replaceWithAddressComputation(void* instructionStart)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(instructionStart);
        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        insn++;
        ASSERT((*insn & 0xfc0007ff) == 0x00000021); // addu
        insn++;
        *insn = 0x24000000 | ((*insn) & 0x3ffffff); // addiu
        cacheFlush(insn, 4);
    }

    /* Update each jump in the buffer of newBase.  */
    void relocateJumps(void* oldBase, void* newBase)
    {
        // Check each jump
        for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
            int pos = iter->m_offset;
            MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(newBase) + pos);
            insn = insn + 2;
            // Need to make sure we have 5 valid instructions after pos
            if ((unsigned)pos >= m_buffer.codeSize() - 5 * sizeof(MIPSWord))
                continue;

            if ((*insn & 0xfc000000) == 0x08000000) { // j
                int offset = *insn & 0x03ffffff;
                int oldInsnAddress = (int)insn - (int)newBase + (int)oldBase;
                int topFourBits = (oldInsnAddress + 4) >> 28;
                int oldTargetAddress = (topFourBits << 28) | (offset << 2);
                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
                int newInsnAddress = (int)insn;
                if (((newInsnAddress + 4) >> 28) == (newTargetAddress >> 28))
                    *insn = 0x08000000 | ((newTargetAddress >> 2) & 0x3ffffff);
                else {
                    /* lui */
                    *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
                    /* ori */
                    *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
                    /* jr */
                    *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
                }
            } else if ((*insn & 0xffe00000) == 0x3c000000) { // lui
                int high = (*insn & 0xffff) << 16;
                int low = *(insn + 1) & 0xffff;
                int oldTargetAddress = high | low;
                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
                /* lui */
                *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
                /* ori */
                *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
            }
        }
    }

private:
    static int linkWithOffset(MIPSWord* insn, void* to)
    {
        ASSERT((*insn & 0xfc000000) == 0x10000000 // beq
            || (*insn & 0xfc000000) == 0x14000000 // bne
            || (*insn & 0xffff0000) == 0x45010000 // bc1t
            || (*insn & 0xffff0000) == 0x45000000); // bc1f
        intptr_t diff = (reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(insn) - 4) >> 2;

        if (diff < -32768 || diff > 32767 || *(insn + 2) != 0x10000003) {
            /*
                Convert the sequence:
                  beq $2, $3, target
                  nop
                  b 1f
                  nop
                  nop
                  nop
                1:

                to the new sequence if possible:
                  bne $2, $3, 1f
                  nop
                  j    target
                  nop
                  nop
                  nop
                1:

                OR to the new sequence:
                  bne $2, $3, 1f
                  nop
                  lui $25, target >> 16
                  ori $25, $25, target & 0xffff
                  jr $25
                  nop
                1:

                Note: beq/bne/bc1t/bc1f are converted to bne/beq/bc1f/bc1t.
            */

            if (*(insn + 2) == 0x10000003) {
                if ((*insn & 0xfc000000) == 0x10000000) // beq
                    *insn = (*insn & 0x03ff0000) | 0x14000005; // bne
                else if ((*insn & 0xfc000000) == 0x14000000) // bne
                    *insn = (*insn & 0x03ff0000) | 0x10000005; // beq
                else if ((*insn & 0xffff0000) == 0x45010000) // bc1t
                    *insn = 0x45000005; // bc1f
                else if ((*insn & 0xffff0000) == 0x45000000) // bc1f
                    *insn = 0x45010005; // bc1t
                else
                    ASSERT(0);
            }

            insn = insn + 2;
            if ((reinterpret_cast<intptr_t>(insn) + 4) >> 28
                == reinterpret_cast<intptr_t>(to) >> 28) {
                *insn = 0x08000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
                *(insn + 1) = 0;
                return 4 * sizeof(MIPSWord);
            }

            intptr_t newTargetAddress = reinterpret_cast<intptr_t>(to);
            /* lui */
            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
            /* ori */
            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
            /* jr */
            *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
            return 5 * sizeof(MIPSWord);
        }

        *insn = (*insn & 0xffff0000) | (diff & 0xffff);
        return sizeof(MIPSWord);
    }

    static int linkCallInternal(void* from, void* to)
    {
        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
        insn = insn - 4;

        if ((*(insn + 2) & 0xfc000000) == 0x0c000000) { // jal
            if ((reinterpret_cast<intptr_t>(from) - 4) >> 28
                == reinterpret_cast<intptr_t>(to) >> 28) {
                *(insn + 2) = 0x0c000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
                return sizeof(MIPSWord);
            }

            /* lui $25, (to >> 16) & 0xffff */
            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
            /* ori $25, $25, to & 0xffff */
            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (reinterpret_cast<intptr_t>(to) & 0xffff);
            /* jalr $25 */
            *(insn + 2) = 0x0000f809 | (MIPSRegisters::t9 << OP_SH_RS);
            return 3 * sizeof(MIPSWord);
        }

        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
        ASSERT((*(insn + 1) & 0xfc000000) == 0x34000000); // ori

        /* lui */
        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
        /* ori */
        *(insn + 1) = (*(insn + 1) & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
        return 2 * sizeof(MIPSWord);
    }

    AssemblerBuffer m_buffer;
    Jumps m_jumps;
    int m_indexOfLastWatchpoint;
    int m_indexOfTailOfLastWatchpoint;
};

} // namespace JSC

#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
