/* -*- 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/. */

#include "jit/mips/Assembler-mips.h"

#include "mozilla/DebugOnly.h"
#include "mozilla/MathAlgorithms.h"

#include "jscompartment.h"
#include "jsutil.h"

#include "assembler/jit/ExecutableAllocator.h"
#include "gc/Marking.h"
#include "jit/JitCompartment.h"

using mozilla::DebugOnly;

using namespace js;
using namespace js::jit;

ABIArgGenerator::ABIArgGenerator()
  : usedArgSlots_(0),
    firstArgFloat(false),
    current_()
{}

ABIArg
ABIArgGenerator::next(MIRType type)
{
    MOZ_ASSUME_UNREACHABLE("NYI");
    return ABIArg();
}
const Register ABIArgGenerator::NonArgReturnVolatileReg0 = t0;
const Register ABIArgGenerator::NonArgReturnVolatileReg1 = t1;

// Encode a standard register when it is being used as rd, the rs, and
// an extra register(rt). These should never be called with an InvalidReg.
uint32_t
js::jit::RS(Register r)
{
    JS_ASSERT((r.code() & ~RegMask) == 0);
    return r.code() << RSShift;
}

uint32_t
js::jit::RT(Register r)
{
    JS_ASSERT((r.code() & ~RegMask) == 0);
    return r.code() << RTShift;
}

uint32_t
js::jit::RT(FloatRegister r)
{
    JS_ASSERT(r.code() < FloatRegisters::Total);
    return r.code() << RTShift;
}

uint32_t
js::jit::RD(Register r)
{
    JS_ASSERT((r.code() & ~RegMask) == 0);
    return r.code() << RDShift;
}

uint32_t
js::jit::RD(FloatRegister r)
{
    JS_ASSERT(r.code() < FloatRegisters::Total);
    return r.code() << RDShift;
}

uint32_t
js::jit::SA(uint32_t value)
{
    JS_ASSERT(value < 32);
    return value << SAShift;
}

uint32_t
js::jit::SA(FloatRegister r)
{
    JS_ASSERT(r.code() < FloatRegisters::Total);
    return r.code() << SAShift;
}

Register
js::jit::toRS(Instruction &i)
{
    return Register::FromCode((i.encode() & RSMask ) >> RSShift);
}

Register
js::jit::toRT(Instruction &i)
{
    return Register::FromCode((i.encode() & RTMask ) >> RTShift);
}

Register
js::jit::toRD(Instruction &i)
{
    return Register::FromCode((i.encode() & RDMask ) >> RDShift);
}

Register
js::jit::toR(Instruction &i)
{
    return Register::FromCode(i.encode() & RegMask);
}

void
InstImm::extractImm16(BOffImm16 *dest)
{
    *dest = BOffImm16(*this);
}

// Used to patch jumps created by MacroAssemblerMIPSCompat::jumpWithPatch.
void
jit::PatchJump(CodeLocationJump &jump_, CodeLocationLabel label)
{
    Instruction *inst1 = (Instruction *)jump_.raw();
    Instruction *inst2 = inst1->next();

    Assembler::updateLuiOriValue(inst1, inst2, (uint32_t)label.raw());

    AutoFlushICache::flush(uintptr_t(inst1), 8);
}

void
Assembler::finish()
{
    JS_ASSERT(!isFinished);
    isFinished = true;
}

void
Assembler::executableCopy(uint8_t *buffer)
{
    JS_ASSERT(isFinished);
    m_buffer.executableCopy(buffer);

    // Patch all long jumps during code copy.
    for (size_t i = 0; i < longJumps_.length(); i++) {
        Instruction *inst1 = (Instruction *) ((uint32_t)buffer + longJumps_[i]);

        uint32_t value = extractLuiOriValue(inst1, inst1->next());
        updateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value);
    }

    AutoFlushICache::setRange(uintptr_t(buffer), m_buffer.size());
}

uint32_t
Assembler::actualOffset(uint32_t off_) const
{
    return off_;
}

uint32_t
Assembler::actualIndex(uint32_t idx_) const
{
    return idx_;
}

uint8_t *
Assembler::PatchableJumpAddress(JitCode *code, uint32_t pe_)
{
    return code->raw() + pe_;
}

class RelocationIterator
{
    CompactBufferReader reader_;
    // offset in bytes
    uint32_t offset_;

  public:
    RelocationIterator(CompactBufferReader &reader)
      : reader_(reader)
    { }

    bool read() {
        if (!reader_.more())
            return false;
        offset_ = reader_.readUnsigned();
        return true;
    }

    uint32_t offset() const {
        return offset_;
    }
};

uintptr_t
Assembler::getPointer(uint8_t *instPtr)
{
    Instruction *inst = (Instruction*)instPtr;
    return Assembler::extractLuiOriValue(inst, inst->next());
}

static JitCode *
CodeFromJump(Instruction *jump)
{
    uint8_t *target = (uint8_t *)Assembler::extractLuiOriValue(jump, jump->next());
    return JitCode::FromExecutable(target);
}

void
Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader)
{
    RelocationIterator iter(reader);
    while (iter.read()) {
        JitCode *child = CodeFromJump((Instruction *)(code->raw() + iter.offset()));
        MarkJitCodeUnbarriered(trc, &child, "rel32");
    }
}

static void
TraceDataRelocations(JSTracer *trc, uint8_t *buffer, CompactBufferReader &reader)
{
    while (reader.more()) {
        size_t offset = reader.readUnsigned();
        Instruction *inst = (Instruction*)(buffer + offset);
        void *ptr = (void *)Assembler::extractLuiOriValue(inst, inst->next());

        // No barrier needed since these are constants.
        gc::MarkGCThingUnbarriered(trc, reinterpret_cast<void **>(&ptr), "ion-masm-ptr");
    }
}

static void
TraceDataRelocations(JSTracer *trc, MIPSBuffer *buffer, CompactBufferReader &reader)
{
    while (reader.more()) {
        BufferOffset bo (reader.readUnsigned());
        MIPSBuffer::AssemblerBufferInstIterator iter(bo, buffer);

        void *ptr = (void *)Assembler::extractLuiOriValue(iter.cur(), iter.next());

        // No barrier needed since these are constants.
        gc::MarkGCThingUnbarriered(trc, reinterpret_cast<void **>(&ptr), "ion-masm-ptr");
    }
}

void
Assembler::TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader)
{
    ::TraceDataRelocations(trc, code->raw(), reader);
}

void
Assembler::copyJumpRelocationTable(uint8_t *dest)
{
    if (jumpRelocations_.length())
        memcpy(dest, jumpRelocations_.buffer(), jumpRelocations_.length());
}

void
Assembler::copyDataRelocationTable(uint8_t *dest)
{
    if (dataRelocations_.length())
        memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
}

void
Assembler::copyPreBarrierTable(uint8_t *dest)
{
    if (preBarriers_.length())
        memcpy(dest, preBarriers_.buffer(), preBarriers_.length());
}

void
Assembler::trace(JSTracer *trc)
{
    for (size_t i = 0; i < jumps_.length(); i++) {
        RelativePatch &rp = jumps_[i];
        if (rp.kind == Relocation::JITCODE) {
            JitCode *code = JitCode::FromExecutable((uint8_t *)rp.target);
            MarkJitCodeUnbarriered(trc, &code, "masmrel32");
            JS_ASSERT(code == JitCode::FromExecutable((uint8_t *)rp.target));
        }
    }
    if (dataRelocations_.length()) {
        CompactBufferReader reader(dataRelocations_);
        ::TraceDataRelocations(trc, &m_buffer, reader);
    }
}

void
Assembler::processCodeLabels(uint8_t *rawCode)
{
    for (size_t i = 0; i < codeLabels_.length(); i++) {
        CodeLabel label = codeLabels_[i];
        Bind(rawCode, label.dest(), rawCode + actualOffset(label.src()->offset()));
    }
}

void
Assembler::Bind(uint8_t *rawCode, AbsoluteLabel *label, const void *address)
{
    if (label->used()) {
        int32_t src = label->offset();
        do {
            Instruction *inst = (Instruction *) (rawCode + src);
            uint32_t next = Assembler::extractLuiOriValue(inst, inst->next());
            Assembler::updateLuiOriValue(inst, inst->next(), (uint32_t)address);
            src = next;
        } while (src != AbsoluteLabel::INVALID_OFFSET);
    }
    label->bind();
}

Assembler::Condition
Assembler::InvertCondition(Condition cond)
{
    switch (cond) {
      case Equal:
        return NotEqual;
      case NotEqual:
        return Equal;
      case Zero:
        return NonZero;
      case NonZero:
        return Zero;
      case LessThan:
        return GreaterThanOrEqual;
      case LessThanOrEqual:
        return GreaterThan;
      case GreaterThan:
        return LessThanOrEqual;
      case GreaterThanOrEqual:
        return LessThan;
      case Above:
        return BelowOrEqual;
      case AboveOrEqual:
        return Below;
      case Below:
        return AboveOrEqual;
      case BelowOrEqual:
        return Above;
      case Signed:
        return NotSigned;
      case NotSigned:
        return Signed;
      default:
        MOZ_ASSUME_UNREACHABLE("unexpected condition");
        return Equal;
    }
}

Assembler::DoubleCondition
Assembler::InvertCondition(DoubleCondition cond)
{
    switch (cond) {
      case DoubleOrdered:
        return DoubleUnordered;
      case DoubleEqual:
        return DoubleNotEqualOrUnordered;
      case DoubleNotEqual:
        return DoubleEqualOrUnordered;
      case DoubleGreaterThan:
        return DoubleLessThanOrEqualOrUnordered;
      case DoubleGreaterThanOrEqual:
        return DoubleLessThanOrUnordered;
      case DoubleLessThan:
        return DoubleGreaterThanOrEqualOrUnordered;
      case DoubleLessThanOrEqual:
        return DoubleGreaterThanOrUnordered;
      case DoubleUnordered:
        return DoubleOrdered;
      case DoubleEqualOrUnordered:
        return DoubleNotEqual;
      case DoubleNotEqualOrUnordered:
        return DoubleEqual;
      case DoubleGreaterThanOrUnordered:
        return DoubleLessThanOrEqual;
      case DoubleGreaterThanOrEqualOrUnordered:
        return DoubleLessThan;
      case DoubleLessThanOrUnordered:
        return DoubleGreaterThanOrEqual;
      case DoubleLessThanOrEqualOrUnordered:
        return DoubleGreaterThan;
      default:
        MOZ_ASSUME_UNREACHABLE("unexpected condition");
        return DoubleEqual;
    }
}

BOffImm16::BOffImm16(InstImm inst)
  : data(inst.encode() & Imm16Mask)
{
}

bool
Assembler::oom() const
{
    return m_buffer.oom() ||
           !enoughMemory_ ||
           jumpRelocations_.oom() ||
           dataRelocations_.oom() ||
           preBarriers_.oom();
}

bool
Assembler::addCodeLabel(CodeLabel label)
{
    return codeLabels_.append(label);
}

// Size of the instruction stream, in bytes.
size_t
Assembler::size() const
{
    return m_buffer.size();
}

// Size of the relocation table, in bytes.
size_t
Assembler::jumpRelocationTableBytes() const
{
    return jumpRelocations_.length();
}

size_t
Assembler::dataRelocationTableBytes() const
{
    return dataRelocations_.length();
}

size_t
Assembler::preBarrierTableBytes() const
{
    return preBarriers_.length();
}

// Size of the data table, in bytes.
size_t
Assembler::bytesNeeded() const
{
    return size() +
           jumpRelocationTableBytes() +
           dataRelocationTableBytes() +
           preBarrierTableBytes();
}

// write a blob of binary into the instruction stream
BufferOffset
Assembler::writeInst(uint32_t x, uint32_t *dest)
{
    if (dest == nullptr)
        return m_buffer.putInt(x);

    writeInstStatic(x, dest);
    return BufferOffset();
}

void
Assembler::writeInstStatic(uint32_t x, uint32_t *dest)
{
    JS_ASSERT(dest != nullptr);
    *dest = x;
}

BufferOffset
Assembler::align(int alignment)
{
    BufferOffset ret;
    JS_ASSERT(m_buffer.isAligned(4));
    if (alignment == 8) {
        if (!m_buffer.isAligned(alignment)) {
            BufferOffset tmp = as_nop();
            if (!ret.assigned())
                ret = tmp;
        }
    } else {
        JS_ASSERT((alignment & (alignment - 1)) == 0);
        while (size() & (alignment - 1)) {
            BufferOffset tmp = as_nop();
            if (!ret.assigned())
                ret = tmp;
        }
    }
    return ret;
}

BufferOffset
Assembler::as_nop()
{
    return writeInst(op_special | ff_sll);
}

// Logical operations.
BufferOffset
Assembler::as_and(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_and).encode());
}

BufferOffset
Assembler::as_or(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_or).encode());
}

BufferOffset
Assembler::as_xor(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_xor).encode());
}

BufferOffset
Assembler::as_nor(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_nor).encode());
}

BufferOffset
Assembler::as_andi(Register rd, Register rs, int32_t j)
{
    JS_ASSERT(Imm16::isInUnsignedRange(j));
    return writeInst(InstImm(op_andi, rs, rd, Imm16(j)).encode());
}

BufferOffset
Assembler::as_ori(Register rd, Register rs, int32_t j)
{
    JS_ASSERT(Imm16::isInUnsignedRange(j));
    return writeInst(InstImm(op_ori, rs, rd, Imm16(j)).encode());
}

BufferOffset
Assembler::as_xori(Register rd, Register rs, int32_t j)
{
    JS_ASSERT(Imm16::isInUnsignedRange(j));
    return writeInst(InstImm(op_xori, rs, rd, Imm16(j)).encode());
}

// Branch and jump instructions
BufferOffset
Assembler::as_bal(BOffImm16 off)
{
    BufferOffset bo = writeInst(InstImm(op_regimm, zero, rt_bgezal, off).encode());
    return bo;
}

InstImm
Assembler::getBranchCode(JumpOrCall jumpOrCall)
{
    if (jumpOrCall == BranchIsCall)
        return InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0));

    return InstImm(op_beq, zero, zero, BOffImm16(0));
}

InstImm
Assembler::getBranchCode(Register s, Register t, Condition c)
{
    JS_ASSERT(c == Assembler::Equal || c == Assembler::NotEqual);
    return InstImm(c == Assembler::Equal ? op_beq : op_bne, s, t, BOffImm16(0));
}

InstImm
Assembler::getBranchCode(Register s, Condition c)
{
    switch (c) {
      case Assembler::Equal:
      case Assembler::Zero:
      case Assembler::BelowOrEqual:
        return InstImm(op_beq, s, zero, BOffImm16(0));
      case Assembler::NotEqual:
      case Assembler::NonZero:
      case Assembler::Above:
        return InstImm(op_bne, s, zero, BOffImm16(0));
      case Assembler::GreaterThan:
        return InstImm(op_bgtz, s, zero, BOffImm16(0));
      case Assembler::GreaterThanOrEqual:
      case Assembler::NotSigned:
        return InstImm(op_regimm, s, rt_bgez, BOffImm16(0));
      case Assembler::LessThan:
      case Assembler::Signed:
        return InstImm(op_regimm, s, rt_bltz, BOffImm16(0));
      case Assembler::LessThanOrEqual:
        return InstImm(op_blez, s, zero, BOffImm16(0));
      default:
        MOZ_ASSUME_UNREACHABLE("Condition not supported.");
    }
}

InstImm
Assembler::getBranchCode(FloatTestKind testKind, FPConditionBit fcc)
{
    JS_ASSERT(!(fcc && FccMask));
    uint32_t rtField = ((testKind == TestForTrue ? 1 : 0) | (fcc << FccShift)) << RTShift;

    return InstImm(op_cop1, rs_bc1, rtField, BOffImm16(0));
}

BufferOffset
Assembler::as_j(JOffImm26 off)
{
    BufferOffset bo = writeInst(InstJump(op_j, off).encode());
    return bo;
}
BufferOffset
Assembler::as_jal(JOffImm26 off)
{
    BufferOffset bo = writeInst(InstJump(op_jal, off).encode());
    return bo;
}

BufferOffset
Assembler::as_jr(Register rs)
{
    BufferOffset bo = writeInst(InstReg(op_special, rs, zero, zero, ff_jr).encode());
    return bo;
}
BufferOffset
Assembler::as_jalr(Register rs)
{
    BufferOffset bo = writeInst(InstReg(op_special, rs, zero, ra, ff_jalr).encode());
    return bo;
}


// Arithmetic instructions
BufferOffset
Assembler::as_addu(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_addu).encode());
}

BufferOffset
Assembler::as_addiu(Register rd, Register rs, int32_t j)
{
    JS_ASSERT(Imm16::isInSignedRange(j));
    return writeInst(InstImm(op_addiu, rs, rd, Imm16(j)).encode());
}

BufferOffset
Assembler::as_subu(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_subu).encode());
}

BufferOffset
Assembler::as_mult(Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, ff_mult).encode());
}

BufferOffset
Assembler::as_multu(Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, ff_multu).encode());
}

BufferOffset
Assembler::as_div(Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, ff_div).encode());
}

BufferOffset
Assembler::as_divu(Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, ff_divu).encode());
}

BufferOffset
Assembler::as_mul(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special2, rs, rt, rd, ff_mul).encode());
}

BufferOffset
Assembler::as_lui(Register rd, int32_t j)
{
    JS_ASSERT(Imm16::isInUnsignedRange(j));
    return writeInst(InstImm(op_lui, zero, rd, Imm16(j)).encode());
}

// Shift instructions
BufferOffset
Assembler::as_sll(Register rd, Register rt, uint16_t sa)
{
    JS_ASSERT(sa < 32);
    return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_sll).encode());
}

BufferOffset
Assembler::as_sllv(Register rd, Register rt, Register rs)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_sllv).encode());
}

BufferOffset
Assembler::as_srl(Register rd, Register rt, uint16_t sa)
{
    JS_ASSERT(sa < 32);
    return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_srl).encode());
}

BufferOffset
Assembler::as_srlv(Register rd, Register rt, Register rs)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_srlv).encode());
}

BufferOffset
Assembler::as_sra(Register rd, Register rt, uint16_t sa)
{
    JS_ASSERT(sa < 32);
    return writeInst(InstReg(op_special, rs_zero, rt, rd, sa, ff_sra).encode());
}

BufferOffset
Assembler::as_srav(Register rd, Register rt, Register rs)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_srav).encode());
}

BufferOffset
Assembler::as_rotr(Register rd, Register rt, uint16_t sa)
{
    JS_ASSERT(sa < 32);
    return writeInst(InstReg(op_special, rs_one, rt, rd, sa, ff_srl).encode());
}

BufferOffset
Assembler::as_rotrv(Register rd, Register rt, Register rs)
{
    return writeInst(InstReg(op_special, rs, rt, rd, 1, ff_srlv).encode());
}

// Load and store instructions
BufferOffset
Assembler::as_lb(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lb, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lbu(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lbu, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lh(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lh, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lhu(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lhu, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lw(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lw, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lwl(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lwl, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_lwr(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_lwr, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_sb(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_sb, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_sh(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_sh, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_sw(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_sw, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_swl(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_swl, rs, rd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_swr(Register rd, Register rs, int16_t off)
{
    return writeInst(InstImm(op_swr, rs, rd, Imm16(off)).encode());
}

// Move from HI/LO register.
BufferOffset
Assembler::as_mfhi(Register rd)
{
    return writeInst(InstReg(op_special, rd, ff_mfhi).encode());
}

BufferOffset
Assembler::as_mflo(Register rd)
{
    return writeInst(InstReg(op_special, rd, ff_mflo).encode());
}

// Set on less than.
BufferOffset
Assembler::as_slt(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_slt).encode());
}

BufferOffset
Assembler::as_sltu(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_sltu).encode());
}

BufferOffset
Assembler::as_slti(Register rd, Register rs, int32_t j)
{
    JS_ASSERT(Imm16::isInSignedRange(j));
    return writeInst(InstImm(op_slti, rs, rd, Imm16(j)).encode());
}

BufferOffset
Assembler::as_sltiu(Register rd, Register rs, uint32_t j)
{
    JS_ASSERT(Imm16::isInUnsignedRange(j));
    return writeInst(InstImm(op_sltiu, rs, rd, Imm16(j)).encode());
}

// Conditional move.
BufferOffset
Assembler::as_movz(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_movz).encode());
}

BufferOffset
Assembler::as_movn(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special, rs, rt, rd, ff_movn).encode());
}

BufferOffset
Assembler::as_movt(Register rd, Register rs, uint16_t cc)
{
    Register rt;
    rt = Register::FromCode((cc & 0x7) << 2 | 1);
    return writeInst(InstReg(op_special, rs, rt, rd, ff_movci).encode());
}

BufferOffset
Assembler::as_movf(Register rd, Register rs, uint16_t cc)
{
    Register rt;
    rt = Register::FromCode((cc & 0x7) << 2 | 0);
    return writeInst(InstReg(op_special, rs, rt, rd, ff_movci).encode());
}

// Bit twiddling.
BufferOffset
Assembler::as_clz(Register rd, Register rs, Register rt)
{
    return writeInst(InstReg(op_special2, rs, rt, rd, ff_clz).encode());
}

BufferOffset
Assembler::as_ins(Register rt, Register rs, uint16_t pos, uint16_t size)
{
    JS_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size >= 32);
    Register rd;
    rd = Register::FromCode(pos + size - 1);
    return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ins).encode());
}

BufferOffset
Assembler::as_ext(Register rt, Register rs, uint16_t pos, uint16_t size)
{
    JS_ASSERT(pos < 32 && size != 0 && size <= 32 && pos + size != 0 && pos + size >= 32);
    Register rd;
    rd = Register::FromCode(size - 1);
    return writeInst(InstReg(op_special3, rs, rt, rd, pos, ff_ext).encode());
}

// FP instructions
BufferOffset
Assembler::as_ld(FloatRegister fd, Register base, int32_t off)
{
    JS_ASSERT(Imm16::isInSignedRange(off));
    return writeInst(InstImm(op_ldc1, base, fd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_sd(FloatRegister fd, Register base, int32_t off)
{
    JS_ASSERT(Imm16::isInSignedRange(off));
    return writeInst(InstImm(op_sdc1, base, fd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_ls(FloatRegister fd, Register base, int32_t off)
{
    JS_ASSERT(Imm16::isInSignedRange(off));
    return writeInst(InstImm(op_lwc1, base, fd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_ss(FloatRegister fd, Register base, int32_t off)
{
    JS_ASSERT(Imm16::isInSignedRange(off));
    return writeInst(InstImm(op_swc1, base, fd, Imm16(off)).encode());
}

BufferOffset
Assembler::as_movs(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_mov_fmt).encode());
}

BufferOffset
Assembler::as_movd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_mov_fmt).encode());
}

BufferOffset
Assembler::as_mtc1(Register rt, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_mtc1, rt, fs).encode());
}

BufferOffset
Assembler::as_mfc1(Register rt, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_mfc1, rt, fs).encode());
}

// FP convert instructions
BufferOffset
Assembler::as_ceilws(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_ceil_w_fmt).encode());
}

BufferOffset
Assembler::as_floorws(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_floor_w_fmt).encode());
}

BufferOffset
Assembler::as_roundws(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_round_w_fmt).encode());
}

BufferOffset
Assembler::as_truncws(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_trunc_w_fmt).encode());
}

BufferOffset
Assembler::as_ceilwd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_ceil_w_fmt).encode());
}

BufferOffset
Assembler::as_floorwd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_floor_w_fmt).encode());
}

BufferOffset
Assembler::as_roundwd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_round_w_fmt).encode());
}

BufferOffset
Assembler::as_truncwd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_trunc_w_fmt).encode());
}

BufferOffset
Assembler::as_cvtds(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_cvt_d_fmt).encode());
}

BufferOffset
Assembler::as_cvtdw(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_w, zero, fs, fd, ff_cvt_d_fmt).encode());
}

BufferOffset
Assembler::as_cvtsd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_cvt_s_fmt).encode());
}

BufferOffset
Assembler::as_cvtsw(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_w, zero, fs, fd, ff_cvt_s_fmt).encode());
}

BufferOffset
Assembler::as_cvtwd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_cvt_w_fmt).encode());
}

BufferOffset
Assembler::as_cvtws(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_cvt_w_fmt).encode());
}

// FP arithmetic instructions
BufferOffset
Assembler::as_adds(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_add_fmt).encode());
}

BufferOffset
Assembler::as_addd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_add_fmt).encode());
}

BufferOffset
Assembler::as_subs(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_sub_fmt).encode());
}

BufferOffset
Assembler::as_subd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_sub_fmt).encode());
}

BufferOffset
Assembler::as_abss(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_abs_fmt).encode());
}

BufferOffset
Assembler::as_absd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_abs_fmt).encode());
}

BufferOffset
Assembler::as_negd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_neg_fmt).encode());
}

BufferOffset
Assembler::as_muls(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_mul_fmt).encode());
}

BufferOffset
Assembler::as_muld(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_mul_fmt).encode());
}

BufferOffset
Assembler::as_divs(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_s, ft, fs, fd, ff_div_fmt).encode());
}

BufferOffset
Assembler::as_divd(FloatRegister fd, FloatRegister fs, FloatRegister ft)
{
    return writeInst(InstReg(op_cop1, rs_d, ft, fs, fd, ff_div_fmt).encode());
}

BufferOffset
Assembler::as_sqrts(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_s, zero, fs, fd, ff_sqrt_fmt).encode());
}

BufferOffset
Assembler::as_sqrtd(FloatRegister fd, FloatRegister fs)
{
    return writeInst(InstReg(op_cop1, rs_d, zero, fs, fd, ff_sqrt_fmt).encode());
}

// FP compare instructions
BufferOffset
Assembler::as_cf(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_f_fmt).encode());
}

BufferOffset
Assembler::as_cun(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_un_fmt).encode());
}

BufferOffset
Assembler::as_ceq(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_eq_fmt).encode());
}

BufferOffset
Assembler::as_cueq(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ueq_fmt).encode());
}

BufferOffset
Assembler::as_colt(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_olt_fmt).encode());
}

BufferOffset
Assembler::as_cult(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ult_fmt).encode());
}

BufferOffset
Assembler::as_cole(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ole_fmt).encode());
}

BufferOffset
Assembler::as_cule(FloatFormat fmt, FloatRegister fs, FloatRegister ft, FPConditionBit fcc)
{
    RSField rs = fmt == DoubleFloat ? rs_d : rs_s;
    return writeInst(InstReg(op_cop1, rs, ft, fs, fcc << FccShift, ff_c_ule_fmt).encode());
}


void
Assembler::bind(Label *label, BufferOffset boff)
{
    // If our caller didn't give us an explicit target to bind to
    // then we want to bind to the location of the next instruction
    BufferOffset dest = boff.assigned() ? boff : nextOffset();
    if (label->used()) {
        int32_t next;

        // A used label holds a link to branch that uses it.
        BufferOffset b(label);
        do {
            Instruction *inst = editSrc(b);

            // Second word holds a pointer to the next branch in label's chain.
            next = inst[1].encode();
            bind(reinterpret_cast<InstImm *>(inst), b.getOffset(), dest.getOffset());

            b = BufferOffset(next);
        } while (next != LabelBase::INVALID_OFFSET);
    }
    label->bind(dest.getOffset());
}

void
Assembler::bind(InstImm *inst, uint32_t branch, uint32_t target)
{
    int32_t offset = target - branch;
    InstImm inst_bgezal = InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0));
    InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0));

    // If encoded offset is 4, then the jump must be short
    if (BOffImm16(inst[0]).decode() == 4) {
        JS_ASSERT(BOffImm16::isInRange(offset));
        inst[0].setBOffImm16(BOffImm16(offset));
        inst[1].makeNop();
        return;
    }
    if (BOffImm16::isInRange(offset)) {
        bool conditional = (inst[0].encode() != inst_bgezal.encode() &&
                            inst[0].encode() != inst_beq.encode());

        inst[0].setBOffImm16(BOffImm16(offset));
        inst[1].makeNop();

        // Skip the trailing nops in conditional branches.
        if (conditional) {
            inst[2] = InstImm(op_regimm, zero, rt_bgez, BOffImm16(3 * sizeof(void *))).encode();
            // There are 2 nops after this
        }
        return;
    }

    if (inst[0].encode() == inst_bgezal.encode()) {
        // Handle long call.
        addLongJump(BufferOffset(branch));
        writeLuiOriInstructions(inst, &inst[1], ScratchRegister, target);
        inst[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr).encode();
        // There is 1 nop after this.
    } else if (inst[0].encode() == inst_beq.encode()) {
        // Handle long unconditional jump.
        addLongJump(BufferOffset(branch));
        writeLuiOriInstructions(inst, &inst[1], ScratchRegister, target);
        inst[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
        // There is 1 nop after this.
    } else {
        // Handle long conditional jump.
        inst[0] = invertBranch(inst[0], BOffImm16(5 * sizeof(void *)));
        // No need for a "nop" here because we can clobber scratch.
        addLongJump(BufferOffset(branch + sizeof(void *)));
        writeLuiOriInstructions(&inst[1], &inst[2], ScratchRegister, target);
        inst[3] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode();
        // There is 1 nop after this.
    }
}

void
Assembler::bind(RepatchLabel *label)
{
    BufferOffset dest = nextOffset();
    if (label->used()) {
        // If the label has a use, then change this use to refer to
        // the bound label;
        BufferOffset b(label->offset());
        Instruction *inst1 = editSrc(b);
        Instruction *inst2 = inst1->next();

        updateLuiOriValue(inst1, inst2, dest.getOffset());
    }
    label->bind(dest.getOffset());
}

void
Assembler::retarget(Label *label, Label *target)
{
    if (label->used()) {
        if (target->bound()) {
            bind(label, BufferOffset(target));
        } else if (target->used()) {
            // The target is not bound but used. Prepend label's branch list
            // onto target's.
            int32_t next;
            BufferOffset labelBranchOffset(label);

            // Find the head of the use chain for label.
            do {
                Instruction *inst = editSrc(labelBranchOffset);

                // Second word holds a pointer to the next branch in chain.
                next = inst[1].encode();
                labelBranchOffset = BufferOffset(next);
            } while (next != LabelBase::INVALID_OFFSET);

            // Then patch the head of label's use chain to the tail of
            // target's use chain, prepending the entire use chain of target.
            Instruction *inst = editSrc(labelBranchOffset);
            int32_t prev = target->use(label->offset());
            inst[1].setData(prev);
        } else {
            // The target is unbound and unused.  We can just take the head of
            // the list hanging off of label, and dump that into target.
            DebugOnly<uint32_t> prev = target->use(label->offset());
            JS_ASSERT((int32_t)prev == Label::INVALID_OFFSET);
        }
    }
    label->reset();
}

void dbg_break() {}
static int stopBKPT = -1;
void
Assembler::as_break(uint32_t code)
{
    JS_ASSERT(code <= MAX_BREAK_CODE);
    writeInst(op_special | code << RTShift | ff_break);
}

uint32_t
Assembler::patchWrite_NearCallSize()
{
    return 4 * sizeof(uint32_t);
}

void
Assembler::patchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall)
{
    Instruction *inst = (Instruction *) start.raw();
    uint8_t *dest = toCall.raw();

    // Overwrite whatever instruction used to be here with a call.
    // Always use long jump for two reasons:
    // - Jump has to be the same size because of patchWrite_NearCallSize.
    // - Return address has to be at the end of replaced block.
    // Short jump wouldn't be more efficient.
    writeLuiOriInstructions(inst, &inst[1], ScratchRegister, (uint32_t)dest);
    inst[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr);
    inst[3] = InstNOP();

    // Ensure everyone sees the code that was just written into memory.
    AutoFlushICache::flush(uintptr_t(inst), patchWrite_NearCallSize());
}

uint32_t
Assembler::extractLuiOriValue(Instruction *inst0, Instruction *inst1)
{
    InstImm *i0 = (InstImm *) inst0;
    InstImm *i1 = (InstImm *) inst1;
    JS_ASSERT(i0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
    JS_ASSERT(i1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));

    uint32_t value = i0->extractImm16Value() << 16;
    value = value | i1->extractImm16Value();
    return value;
}

void
Assembler::updateLuiOriValue(Instruction *inst0, Instruction *inst1, uint32_t value)
{
    JS_ASSERT(inst0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
    JS_ASSERT(inst1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));

    ((InstImm *) inst0)->setImm16(Imm16::upper(Imm32(value)));
    ((InstImm *) inst1)->setImm16(Imm16::lower(Imm32(value)));
}

void
Assembler::writeLuiOriInstructions(Instruction *inst0, Instruction *inst1,
                                   Register reg, uint32_t value)
{
    *inst0 = InstImm(op_lui, zero, reg, Imm16::upper(Imm32(value)));
    *inst1 = InstImm(op_ori, reg, reg, Imm16::lower(Imm32(value)));
}

void
Assembler::patchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
                                   PatchedImmPtr expectedValue)
{
    Instruction *inst = (Instruction *) label.raw();

    // Extract old Value
    DebugOnly<uint32_t> value = Assembler::extractLuiOriValue(&inst[0], &inst[1]);
    JS_ASSERT(value == uint32_t(expectedValue.value));

    // Replace with new value
    Assembler::updateLuiOriValue(inst, inst->next(), uint32_t(newValue.value));

    AutoFlushICache::flush(uintptr_t(inst), 8);
}

void
Assembler::patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue, ImmPtr expectedValue)
{
    patchDataWithValueCheck(label, PatchedImmPtr(newValue.value),
                            PatchedImmPtr(expectedValue.value));
}

// This just stomps over memory with 32 bits of raw data. Its purpose is to
// overwrite the call of JITed code with 32 bits worth of an offset. This will
// is only meant to function on code that has been invalidated, so it should
// be totally safe. Since that instruction will never be executed again, a
// ICache flush should not be necessary
void
Assembler::patchWrite_Imm32(CodeLocationLabel label, Imm32 imm)
{
    // Raw is going to be the return address.
    uint32_t *raw = (uint32_t*)label.raw();
    // Overwrite the 4 bytes before the return address, which will
    // end up being the call instruction.
    *(raw - 1) = imm.value;
}

uint8_t *
Assembler::nextInstruction(uint8_t *inst_, uint32_t *count)
{
    Instruction *inst = reinterpret_cast<Instruction*>(inst_);
    if (count != nullptr)
        *count += sizeof(Instruction);
    return reinterpret_cast<uint8_t*>(inst->next());
}

// Since there are no pools in MIPS implementation, this should be simple.
Instruction *
Instruction::next()
{
    return this + 1;
}

InstImm Assembler::invertBranch(InstImm branch, BOffImm16 skipOffset)
{
    uint32_t rt = 0;
    Opcode op = (Opcode) (branch.extractOpcode() << OpcodeShift);
    switch(op) {
      case op_beq:
        branch.setBOffImm16(skipOffset);
        branch.setOpcode(op_bne);
        return branch;
      case op_bne:
        branch.setBOffImm16(skipOffset);
        branch.setOpcode(op_beq);
        return branch;
      case op_bgtz:
        branch.setBOffImm16(skipOffset);
        branch.setOpcode(op_blez);
        return branch;
      case op_blez:
        branch.setBOffImm16(skipOffset);
        branch.setOpcode(op_bgtz);
        return branch;
      case op_regimm:
        branch.setBOffImm16(skipOffset);
        rt = branch.extractRT();
        if (rt == (rt_bltz >> RTShift)) {
            branch.setRT(rt_bgez);
            return branch;
        }
        if (rt == (rt_bgez >> RTShift)) {
            branch.setRT(rt_bltz);
            return branch;
        }

        MOZ_ASSUME_UNREACHABLE("Error creating long branch.");
        return branch;

      case op_cop1:
        JS_ASSERT(branch.extractRS() == rs_bc1 >> RSShift);

        branch.setBOffImm16(skipOffset);
        rt = branch.extractRT();
        if (rt & 0x1)
            branch.setRT((RTField) ((rt & ~0x1) << RTShift));
        else
            branch.setRT((RTField) ((rt | 0x1) << RTShift));
        return branch;
    }

    MOZ_ASSUME_UNREACHABLE("Error creating long branch.");
    return branch;
}

void
Assembler::ToggleToJmp(CodeLocationLabel inst_)
{
    InstImm * inst = (InstImm *)inst_.raw();

    JS_ASSERT(inst->extractOpcode() == ((uint32_t)op_andi >> OpcodeShift));
    // We converted beq to andi, so now we restore it.
    inst->setOpcode(op_beq);

    AutoFlushICache::flush(uintptr_t(inst), 4);
}

void
Assembler::ToggleToCmp(CodeLocationLabel inst_)
{
    InstImm * inst = (InstImm *)inst_.raw();

    // toggledJump is allways used for short jumps.
    JS_ASSERT(inst->extractOpcode() == ((uint32_t)op_beq >> OpcodeShift));
    // Replace "beq $zero, $zero, offset" with "andi $zero, $zero, offset"
    inst->setOpcode(op_andi);

    AutoFlushICache::flush(uintptr_t(inst), 4);
}

void
Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled)
{
    Instruction *inst = (Instruction *)inst_.raw();
    InstImm *i0 = (InstImm *) inst;
    InstImm *i1 = (InstImm *) i0->next();
    Instruction *i2 = (Instruction *) i1->next();

    JS_ASSERT(i0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift));
    JS_ASSERT(i1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift));

    if (enabled) {
        InstReg jalr = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr);
        *i2 = jalr;
    } else {
        InstNOP nop;
        *i2 = nop;
    }

    AutoFlushICache::flush(uintptr_t(i2), 4);
}

void Assembler::updateBoundsCheck(uint32_t heapSize, Instruction *inst)
{
    MOZ_ASSUME_UNREACHABLE("NYI");
}
