/* -*- 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/IonCompartment.h"

using mozilla::DebugOnly;

using namespace js;
using namespace js::jit;

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

ABIArg
ABIArgGenerator::next(MIRType type)
{
    JS_NOT_REACHED("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());

    AutoFlushCache::updateTop(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);
    }

    AutoFlushCache::updateTop((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(IonCode *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 IonCode *
CodeFromJump(Instruction *jump)
{
    uint8_t *target = (uint8_t *)Assembler::extractLuiOriValue(jump, jump->next());
    return IonCode::FromExecutable(target);
}

void
Assembler::TraceJumpRelocations(JSTracer *trc, IonCode *code, CompactBufferReader &reader)
{
    RelocationIterator iter(reader);
    while (iter.read()) {
        IonCode *child = CodeFromJump((Instruction *)(code->raw() + iter.offset()));
        MarkIonCodeUnbarriered(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, IonCode *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::IONCODE) {
            IonCode *code = IonCode::FromExecutable((uint8_t *)rp.target);
            MarkIonCodeUnbarriered(trc, &code, "masmrel32");
            JS_ASSERT(code == IonCode::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:
        JS_NOT_REACHED("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:
        JS_NOT_REACHED("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 == NULL)
        return m_buffer.putInt(x);

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

void
Assembler::writeInstStatic(uint32_t x, uint32_t *dest)
{
    JS_ASSERT(dest != NULL);
    *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:
        JS_NOT_REACHED("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.
    AutoFlushCache::updateTop(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, ImmWord newValue,
                                   ImmWord 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));

    AutoFlushCache::updateTop(uintptr_t(inst), 8);
}

// 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 != NULL)
        *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;
        }

        JS_NOT_REACHED("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;
    }

    JS_NOT_REACHED("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);

    AutoFlushCache::updateTop(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);

    AutoFlushCache::updateTop(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;
    }

    AutoFlushCache::updateTop(uintptr_t(i2), 4);
}

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


