/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* 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/loong64/Assembler-loong64.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
#include "gc/Marking.h"
#include "jit/AutoWritableJitCode.h"
#include "jit/ExecutableAllocator.h"
#include "vm/Realm.h"
using mozilla::DebugOnly;
using namespace js;
using namespace js::jit;
// Note this is used for inter-wasm calls and may pass arguments and results
// in floating point registers even if the system ABI does not.
// TODO(loong64): Inconsistent with LoongArch's calling convention.
// LoongArch floating-point parameters calling convention:
// The first eight floating-point parameters should be passed in f0-f7, and
// the other floating point parameters will be passed like integer parameters.
// But we just pass the other floating-point parameters on stack here.
ABIArg ABIArgGenerator::next(MIRType type) {
switch (type) {
case MIRType::Int32:
case MIRType::Int64:
case MIRType::Pointer:
case MIRType::WasmAnyRef:
case MIRType::WasmArrayData:
case MIRType::StackResults: {
if (intRegIndex_ == NumIntArgRegs) {
current_ = ABIArg(stackOffset_);
stackOffset_ +=
sizeof(uintptr_t);
break;
}
current_ = ABIArg(
Register::FromCode(intRegIndex_ + a0.encoding()));
intRegIndex_++;
break;
}
case MIRType::Float32:
case MIRType::
Double: {
if (floatRegIndex_ == NumFloatArgRegs) {
current_ = ABIArg(stackOffset_);
stackOffset_ +=
sizeof(
double);
break;
}
current_ = ABIArg(FloatRegister(
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
type == MIRType::
Double ? FloatRegisters::
Double
: FloatRegisters::Single));
floatRegIndex_++;
break;
}
case MIRType::Simd128: {
MOZ_CRASH(
"LoongArch does not support simd yet.");
break;
}
default:
MOZ_CRASH(
"Unexpected argument type");
}
return current_;
}
// Encode a standard register when it is being used as rd, the rj, and
// an extra register(rk). These should never be called with an InvalidReg.
uint32_t js::jit::RJ(
Register r) {
MOZ_ASSERT(r != InvalidReg);
return r.encoding() << RJShift;
}
uint32_t js::jit::RK(
Register r) {
MOZ_ASSERT(r != InvalidReg);
return r.encoding() << RKShift;
}
uint32_t js::jit::RD(
Register r) {
MOZ_ASSERT(r != InvalidReg);
return r.encoding() << RDShift;
}
uint32_t js::jit::FJ(FloatRegister r) {
return r.encoding() << RJShift; }
uint32_t js::jit::FK(FloatRegister r) {
return r.encoding() << RKShift; }
uint32_t js::jit::FD(FloatRegister r) {
return r.encoding() << RDShift; }
uint32_t js::jit::FA(FloatRegister r) {
return r.encoding() << FAShift; }
uint32_t js::jit::SA2(uint32_t value) {
MOZ_ASSERT(value < 4);
return (value & SA2Mask) << SAShift;
}
uint32_t js::jit::SA3(uint32_t value) {
MOZ_ASSERT(value < 8);
return (value & SA3Mask) << SAShift;
}
Register js::jit::toRK(Instruction& i) {
return Register::FromCode(((i.encode() >> RKShift) & RKMask));
}
Register js::jit::toRJ(Instruction& i) {
return Register::FromCode(((i.encode() >> RJShift) & RJMask));
}
Register js::jit::toRD(Instruction& i) {
return Register::FromCode(((i.encode() >> RDShift) & RDMask));
}
Register js::jit::toR(Instruction& i) {
return Register::FromCode(i.encode() & RegMask);
}
void InstImm::extractImm16(BOffImm16* dest) { *dest = BOffImm16(*
this); }
void AssemblerLOONG64::finish() {
MOZ_ASSERT(!isFinished);
isFinished =
true;
}
bool AssemblerLOONG64::appendRawCode(
const uint8_t* code, size_t numBytes) {
return m_buffer.appendRawCode(code, numBytes);
}
bool AssemblerLOONG64::reserve(size_t size) {
// This buffer uses fixed-size chunks so there's no point in reserving
// now vs. on-demand.
return !oom();
}
bool AssemblerLOONG64::swapBuffer(wasm::Bytes& bytes) {
// For now, specialize to the one use case. As long as wasm::Bytes is a
// Vector, not a linked-list of chunks, there's not much we can do other
// than copy.
MOZ_ASSERT(bytes.empty());
if (!bytes.resize(bytesNeeded())) {
return false;
}
m_buffer.executableCopy(bytes.begin());
return true;
}
void AssemblerLOONG64::copyJumpRelocationTable(uint8_t* dest) {
if (jumpRelocations_.length()) {
memcpy(dest, jumpRelocations_.buffer(), jumpRelocations_.length());
}
}
void AssemblerLOONG64::copyDataRelocationTable(uint8_t* dest) {
if (dataRelocations_.length()) {
memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
}
}
AssemblerLOONG64::Condition AssemblerLOONG64::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_CRASH(
"unexpected condition");
}
}
AssemblerLOONG64::DoubleCondition AssemblerLOONG64::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_CRASH(
"unexpected condition");
}
}
AssemblerLOONG64::Condition AssemblerLOONG64::InvertCmpCondition(
Condition cond) {
switch (cond) {
case Equal:
case NotEqual:
return cond;
case LessThan:
return GreaterThan;
case LessThanOrEqual:
return GreaterThanOrEqual;
case GreaterThan:
return LessThanOrEqual;
case GreaterThanOrEqual:
return LessThan;
case Above:
return Below;
case AboveOrEqual:
return BelowOrEqual;
case Below:
return Above;
case BelowOrEqual:
return AboveOrEqual;
default:
MOZ_CRASH(
"no meaningful swapped-operand condition");
}
}
BOffImm16::BOffImm16(InstImm inst)
: data((inst.encode() >> Imm16Shift) & Imm16Mask) {}
Instruction* BOffImm16::getDest(Instruction* src)
const {
return &src[(((int32_t)data << 16) >> 16) + 1];
}
bool AssemblerLOONG64::oom()
const {
return AssemblerShared::oom() || m_buffer.oom() || jumpRelocations_.oom() ||
dataRelocations_.oom();
}
// Size of the instruction stream, in bytes.
size_t AssemblerLOONG64::size()
const {
return m_buffer.size(); }
// Size of the relocation table, in bytes.
size_t AssemblerLOONG64::jumpRelocationTableBytes()
const {
return jumpRelocations_.length();
}
size_t AssemblerLOONG64::dataRelocationTableBytes()
const {
return dataRelocations_.length();
}
// Size of the data table, in bytes.
size_t AssemblerLOONG64::bytesNeeded()
const {
return size() + jumpRelocationTableBytes() + dataRelocationTableBytes();
}
// write a blob of binary into the instruction stream
BufferOffset AssemblerLOONG64::writeInst(uint32_t x, uint32_t* dest) {
MOZ_ASSERT(hasCreator());
if (dest == nullptr) {
return m_buffer.putInt(x);
}
WriteInstStatic(x, dest);
return BufferOffset();
}
void AssemblerLOONG64::WriteInstStatic(uint32_t x, uint32_t* dest) {
MOZ_ASSERT(dest != nullptr);
*dest = x;
}
BufferOffset AssemblerLOONG64::haltingAlign(
int alignment) {
// TODO(loong64): Implement a proper halting align.
return nopAlign(alignment);
}
BufferOffset AssemblerLOONG64::nopAlign(
int alignment) {
BufferOffset ret;
MOZ_ASSERT(m_buffer.isAligned(4));
if (alignment == 8) {
if (!m_buffer.isAligned(alignment)) {
BufferOffset tmp = as_nop();
if (!ret.assigned()) {
ret = tmp;
}
}
}
else {
MOZ_ASSERT((alignment & (alignment - 1)) == 0);
while (size() & (alignment - 1)) {
BufferOffset tmp = as_nop();
if (!ret.assigned()) {
ret = tmp;
}
}
}
return ret;
}
// Logical operations.
BufferOffset AssemblerLOONG64::as_and(
Register rd,
Register rj,
Register rk) {
spew(
"and %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_and, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_or(
Register rd,
Register rj,
Register rk) {
spew(
"or %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_or, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_xor(
Register rd,
Register rj,
Register rk) {
spew(
"xor %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_xor, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_nor(
Register rd,
Register rj,
Register rk) {
spew(
"nor %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_nor, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_andn(
Register rd,
Register rj,
Register rk) {
spew(
"andn %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_andn, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_orn(
Register rd,
Register rj,
Register rk) {
spew(
"orn %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_orn, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_andi(
Register rd,
Register rj, int32_t ui12) {
MOZ_ASSERT(is_uintN(ui12, 12));
spew(
"andi %3s,%3s,0x%x", rd.name(), rj.name(), ui12);
return writeInst(InstImm(op_andi, ui12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ori(
Register rd,
Register rj, int32_t ui12) {
MOZ_ASSERT(is_uintN(ui12, 12));
spew(
"ori %3s,%3s,0x%x", rd.name(), rj.name(), ui12);
return writeInst(InstImm(op_ori, ui12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_xori(
Register rd,
Register rj, int32_t ui12) {
MOZ_ASSERT(is_uintN(ui12, 12));
spew(
"xori %3s,%3s,0x%x", rd.name(), rj.name(), ui12);
return writeInst(InstImm(op_xori, ui12, rj, rd, 12).encode());
}
// Branch and jump instructions
BufferOffset AssemblerLOONG64::as_b(JOffImm26 off) {
spew(
"b %d", off.decode());
return writeInst(InstJump(op_b, off).encode());
}
BufferOffset AssemblerLOONG64::as_bl(JOffImm26 off) {
spew(
"bl %d", off.decode());
return writeInst(InstJump(op_bl, off).encode());
}
BufferOffset AssemblerLOONG64::as_jirl(
Register rd,
Register rj,
BOffImm16 off) {
spew(
"jirl %3s, %3s, %d", rd.name(), rj.name(), off.decode());
return writeInst(InstImm(op_jirl, off, rj, rd).encode());
}
InstImm AssemblerLOONG64::getBranchCode(JumpOrCall jumpOrCall) {
// jirl or beq
if (jumpOrCall == BranchIsCall) {
return InstImm(op_jirl, BOffImm16(0), zero, ra);
}
return InstImm(op_beq, BOffImm16(0), zero, zero);
}
InstImm AssemblerLOONG64::getBranchCode(
Register rj,
Register rd, Condition c) {
// beq, bne
MOZ_ASSERT(c == AssemblerLOONG64::Equal || c == AssemblerLOONG64::NotEqual);
return InstImm(c == AssemblerLOONG64::Equal ? op_beq : op_bne, BOffImm16(0),
rj, rd);
}
InstImm AssemblerLOONG64::getBranchCode(
Register rj, Condition c) {
// beq, bne, blt, bge
switch (c) {
case AssemblerLOONG64::Equal:
case AssemblerLOONG64::Zero:
case AssemblerLOONG64::BelowOrEqual:
return InstImm(op_beq, BOffImm16(0), rj, zero);
case AssemblerLOONG64::NotEqual:
case AssemblerLOONG64::NonZero:
case AssemblerLOONG64::Above:
return InstImm(op_bne, BOffImm16(0), rj, zero);
case AssemblerLOONG64::GreaterThan:
return InstImm(op_blt, BOffImm16(0), zero, rj);
case AssemblerLOONG64::GreaterThanOrEqual:
case AssemblerLOONG64::NotSigned:
return InstImm(op_bge, BOffImm16(0), rj, zero);
case AssemblerLOONG64::LessThan:
case AssemblerLOONG64::
Signed:
return InstImm(op_blt, BOffImm16(0), rj, zero);
case AssemblerLOONG64::LessThanOrEqual:
return InstImm(op_bge, BOffImm16(0), zero, rj);
default:
MOZ_CRASH(
"Condition not supported.");
}
}
// Code semantics must conform to compareFloatingpoint
InstImm AssemblerLOONG64::getBranchCode(FPConditionBit cj) {
return InstImm(op_bcz, 0, cj,
true);
// bcnez
}
// Arithmetic instructions
BufferOffset AssemblerLOONG64::as_add_w(
Register rd,
Register rj,
Register rk) {
spew(
"add_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_add_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_add_d(
Register rd,
Register rj,
Register rk) {
spew(
"add_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_add_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_sub_w(
Register rd,
Register rj,
Register rk) {
spew(
"sub_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sub_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_sub_d(
Register rd,
Register rj,
Register rk) {
spew(
"sub_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sub_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_addi_w(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"addi_w %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_addi_w, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_addi_d(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"addi_d %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_addi_d, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_addu16i_d(
Register rd,
Register rj,
int32_t si16) {
MOZ_ASSERT(Imm16::IsInSignedRange(si16));
spew(
"addu16i_d %3s,%3s,0x%x", rd.name(), rj.name(), si16);
return writeInst(InstImm(op_addu16i_d, Imm16(si16), rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_alsl_w(
Register rd,
Register rj,
Register rk,
uint32_t sa2) {
MOZ_ASSERT(sa2 < 4);
spew(
"alsl_w %3s,%3s,0x%x", rd.name(), rj.name(), sa2);
return writeInst(InstReg(op_alsl_w, sa2, rk, rj, rd, 2).encode());
}
BufferOffset AssemblerLOONG64::as_alsl_wu(
Register rd,
Register rj,
Register rk,
uint32_t sa2) {
MOZ_ASSERT(sa2 < 4);
spew(
"alsl_wu %3s,%3s,0x%x", rd.name(), rj.name(), sa2);
return writeInst(InstReg(op_alsl_wu, sa2, rk, rj, rd, 2).encode());
}
BufferOffset AssemblerLOONG64::as_alsl_d(
Register rd,
Register rj,
Register rk,
uint32_t sa2) {
MOZ_ASSERT(sa2 < 4);
spew(
"alsl_d %3s,%3s,%3s,0x%x", rd.name(), rj.name(), rk.name(), sa2);
return writeInst(InstReg(op_alsl_d, sa2, rk, rj, rd, 2).encode());
}
BufferOffset AssemblerLOONG64::as_lu12i_w(
Register rd, int32_t si20) {
spew(
"lu12i_w %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_lu12i_w, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_lu32i_d(
Register rd, int32_t si20) {
spew(
"lu32i_d %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_lu32i_d, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_lu52i_d(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_uintN(si12, 12));
spew(
"lu52i_d %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_lu52i_d, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_slt(
Register rd,
Register rj,
Register rk) {
spew(
"slt %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_slt, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_sltu(
Register rd,
Register rj,
Register rk) {
spew(
"sltu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sltu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_slti(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"slti %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_slti, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_sltui(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"sltui %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_sltui, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_pcaddi(
Register rd, int32_t si20) {
spew(
"pcaddi %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_pcaddi, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_pcaddu12i(
Register rd, int32_t si20) {
spew(
"pcaddu12i %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_pcaddu12i, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_pcaddu18i(
Register rd, int32_t si20) {
spew(
"pcaddu18i %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_pcaddu18i, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_pcalau12i(
Register rd, int32_t si20) {
spew(
"pcalau12i %3s,0x%x", rd.name(), si20);
return writeInst(InstImm(op_pcalau12i, si20, rd,
false).encode());
}
BufferOffset AssemblerLOONG64::as_mul_w(
Register rd,
Register rj,
Register rk) {
spew(
"mul_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mul_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulh_w(
Register rd,
Register rj,
Register rk) {
spew(
"mulh_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulh_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulh_wu(
Register rd,
Register rj,
Register rk) {
spew(
"mulh_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulh_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mul_d(
Register rd,
Register rj,
Register rk) {
spew(
"mul_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mul_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulh_d(
Register rd,
Register rj,
Register rk) {
spew(
"mulh_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulh_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulh_du(
Register rd,
Register rj,
Register rk) {
spew(
"mulh_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulh_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulw_d_w(
Register rd,
Register rj,
Register rk) {
spew(
"mulw_d_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulw_d_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mulw_d_wu(
Register rd,
Register rj,
Register rk) {
spew(
"mulw_d_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mulw_d_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_div_w(
Register rd,
Register rj,
Register rk) {
spew(
"div_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_div_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mod_w(
Register rd,
Register rj,
Register rk) {
spew(
"mod_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mod_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_div_wu(
Register rd,
Register rj,
Register rk) {
spew(
"div_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_div_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mod_wu(
Register rd,
Register rj,
Register rk) {
spew(
"mod_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mod_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_div_d(
Register rd,
Register rj,
Register rk) {
spew(
"div_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_div_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mod_d(
Register rd,
Register rj,
Register rk) {
spew(
"mod_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mod_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_div_du(
Register rd,
Register rj,
Register rk) {
spew(
"div_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_div_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_mod_du(
Register rd,
Register rj,
Register rk) {
spew(
"mod_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_mod_du, rk, rj, rd).encode());
}
// Shift instructions
BufferOffset AssemblerLOONG64::as_sll_w(
Register rd,
Register rj,
Register rk) {
spew(
"sll_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sll_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_srl_w(
Register rd,
Register rj,
Register rk) {
spew(
"srl_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_srl_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_sra_w(
Register rd,
Register rj,
Register rk) {
spew(
"sra_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sra_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_rotr_w(
Register rd,
Register rj,
Register rk) {
spew(
"rotr_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_rotr_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_slli_w(
Register rd,
Register rj,
int32_t ui5) {
MOZ_ASSERT(is_uintN(ui5, 5));
spew(
"slli_w %3s,%3s,0x%x", rd.name(), rj.name(), ui5);
return writeInst(InstImm(op_slli_w, ui5, rj, rd, 5).encode());
}
BufferOffset AssemblerLOONG64::as_srli_w(
Register rd,
Register rj,
int32_t ui5) {
MOZ_ASSERT(is_uintN(ui5, 5));
spew(
"srli_w %3s,%3s,0x%x", rd.name(), rj.name(), ui5);
return writeInst(InstImm(op_srli_w, ui5, rj, rd, 5).encode());
}
BufferOffset AssemblerLOONG64::as_srai_w(
Register rd,
Register rj,
int32_t ui5) {
MOZ_ASSERT(is_uintN(ui5, 5));
spew(
"srai_w %3s,%3s,0x%x", rd.name(), rj.name(), ui5);
return writeInst(InstImm(op_srai_w, ui5, rj, rd, 5).encode());
}
BufferOffset AssemblerLOONG64::as_rotri_w(
Register rd,
Register rj,
int32_t ui5) {
MOZ_ASSERT(is_uintN(ui5, 5));
spew(
"rotri_w %3s,%3s,0x%x", rd.name(), rj.name(), ui5);
return writeInst(InstImm(op_rotri_w, ui5, rj, rd, 5).encode());
}
BufferOffset AssemblerLOONG64::as_sll_d(
Register rd,
Register rj,
Register rk) {
spew(
"sll_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sll_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_srl_d(
Register rd,
Register rj,
Register rk) {
spew(
"srl_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_srl_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_sra_d(
Register rd,
Register rj,
Register rk) {
spew(
"sra_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_sra_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_rotr_d(
Register rd,
Register rj,
Register rk) {
spew(
"rotr_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_rotr_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_slli_d(
Register rd,
Register rj,
int32_t ui6) {
MOZ_ASSERT(is_uintN(ui6, 6));
spew(
"slli_d %3s,%3s,0x%x", rd.name(), rj.name(), ui6);
return writeInst(InstImm(op_slli_d, ui6, rj, rd, 6).encode());
}
BufferOffset AssemblerLOONG64::as_srli_d(
Register rd,
Register rj,
int32_t ui6) {
MOZ_ASSERT(is_uintN(ui6, 6));
spew(
"srli_d %3s,%3s,0x%x", rd.name(), rj.name(), ui6);
return writeInst(InstImm(op_srli_d, ui6, rj, rd, 6).encode());
}
BufferOffset AssemblerLOONG64::as_srai_d(
Register rd,
Register rj,
int32_t ui6) {
MOZ_ASSERT(is_uintN(ui6, 6));
spew(
"srai_d %3s,%3s,0x%x", rd.name(), rj.name(), ui6);
return writeInst(InstImm(op_srai_d, ui6, rj, rd, 6).encode());
}
BufferOffset AssemblerLOONG64::as_rotri_d(
Register rd,
Register rj,
int32_t ui6) {
MOZ_ASSERT(is_uintN(ui6, 6));
spew(
"rotri_d %3s,%3s,0x%x", rd.name(), rj.name(), ui6);
return writeInst(InstImm(op_rotri_d, ui6, rj, rd, 6).encode());
}
// Bit operation instrucitons
BufferOffset AssemblerLOONG64::as_ext_w_b(
Register rd,
Register rj) {
spew(
"ext_w_b %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_ext_w_b, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ext_w_h(
Register rd,
Register rj) {
spew(
"ext_w_h %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_ext_w_h, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_clo_w(
Register rd,
Register rj) {
spew(
"clo_w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_clo_w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_clz_w(
Register rd,
Register rj) {
spew(
"clz_w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_clz_w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_cto_w(
Register rd,
Register rj) {
spew(
"cto_w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_cto_w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ctz_w(
Register rd,
Register rj) {
spew(
"ctz_w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_ctz_w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_clo_d(
Register rd,
Register rj) {
spew(
"clo_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_clo_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_clz_d(
Register rd,
Register rj) {
spew(
"clz_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_clz_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_cto_d(
Register rd,
Register rj) {
spew(
"cto_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_cto_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ctz_d(
Register rd,
Register rj) {
spew(
"ctz_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_ctz_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bytepick_w(
Register rd,
Register rj,
Register rk, int32_t sa2) {
MOZ_ASSERT(sa2 < 4);
spew(
"bytepick_w %3s,%3s,%3s, 0x%x", rd.name(), rj.name(), rk.name(), sa2);
return writeInst(InstReg(op_bytepick_w, sa2, rk, rj, rd, 2).encode());
}
BufferOffset AssemblerLOONG64::as_bytepick_d(
Register rd,
Register rj,
Register rk, int32_t sa3) {
MOZ_ASSERT(sa3 < 8);
spew(
"bytepick_d %3s,%3s,%3s, 0x%x", rd.name(), rj.name(), rk.name(), sa3);
return writeInst(InstReg(op_bytepick_d, sa3, rk, rj, rd, 3).encode());
}
BufferOffset AssemblerLOONG64::as_revb_2h(
Register rd,
Register rj) {
spew(
"revb_2h %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revb_2h, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_revb_4h(
Register rd,
Register rj) {
spew(
"revb_4h %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revb_4h, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_revb_2w(
Register rd,
Register rj) {
spew(
"revb_2w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revb_2w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_revb_d(
Register rd,
Register rj) {
spew(
"revb_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revb_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_revh_2w(
Register rd,
Register rj) {
spew(
"revh_2w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revh_2w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_revh_d(
Register rd,
Register rj) {
spew(
"revh_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_revh_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bitrev_4b(
Register rd,
Register rj) {
spew(
"bitrev_4b %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_bitrev_4b, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bitrev_8b(
Register rd,
Register rj) {
spew(
"bitrev_8b %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_bitrev_8b, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bitrev_w(
Register rd,
Register rj) {
spew(
"bitrev_w %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_bitrev_w, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bitrev_d(
Register rd,
Register rj) {
spew(
"bitrev_d %3s,%3s", rd.name(), rj.name());
return writeInst(InstReg(op_bitrev_d, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bstrins_w(
Register rd,
Register rj,
int32_t msbw, int32_t lsbw) {
MOZ_ASSERT(lsbw <= msbw);
spew(
"bstrins_w %3s,%3s,0x%x,0x%x", rd.name(), rj.name(), msbw, lsbw);
return writeInst(InstImm(op_bstr_w, msbw, lsbw, rj, rd, 5).encode());
}
BufferOffset AssemblerLOONG64::as_bstrins_d(
Register rd,
Register rj,
int32_t msbd, int32_t lsbd) {
MOZ_ASSERT(lsbd <= msbd);
spew(
"bstrins_d %3s,%3s,0x%x,0x%x", rd.name(), rj.name(), msbd, lsbd);
return writeInst(InstImm(op_bstrins_d, msbd, lsbd, rj, rd, 6).encode());
}
BufferOffset AssemblerLOONG64::as_bstrpick_w(
Register rd,
Register rj,
int32_t msbw, int32_t lsbw) {
MOZ_ASSERT(lsbw <= msbw);
spew(
"bstrpick_w %3s,%3s,0x%x,0x%x", rd.name(), rj.name(), msbw, lsbw);
return writeInst(InstImm(op_bstr_w, msbw, lsbw, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_bstrpick_d(
Register rd,
Register rj,
int32_t msbd, int32_t lsbd) {
MOZ_ASSERT(lsbd <= msbd);
spew(
"bstrpick_d %3s,%3s,0x%x,0x%x", rd.name(), rj.name(), msbd, lsbd);
return writeInst(InstImm(op_bstrpick_d, msbd, lsbd, rj, rd, 6).encode());
}
BufferOffset AssemblerLOONG64::as_maskeqz(
Register rd,
Register rj,
Register rk) {
spew(
"maskeqz %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_maskeqz, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_masknez(
Register rd,
Register rj,
Register rk) {
spew(
"masknez %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_masknez, rk, rj, rd).encode());
}
// Load and store instructions
BufferOffset AssemblerLOONG64::as_ld_b(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_b %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_b, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_h(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_h %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_h, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_w(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_w %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_w, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_d(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_d %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_d, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_bu(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_bu %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_bu, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_hu(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_hu %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_hu, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ld_wu(
Register rd,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"ld_wu %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_ld_wu, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_st_b(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"st_b %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_st_b, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_st_h(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"st_h %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_st_h, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_st_w(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"st_w %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_st_w, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_st_d(
Register rd,
Register rj, int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"st_d %3s,%3s,0x%x", rd.name(), rj.name(), si12);
return writeInst(InstImm(op_st_d, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_b(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_b %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_b, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_h(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_h %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_h, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_w(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_d(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_bu(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_bu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_bu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_hu(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_hu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_hu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldx_wu(
Register rd,
Register rj,
Register rk) {
spew(
"ldx_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_stx_b(
Register rd,
Register rj,
Register rk) {
spew(
"stx_b %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_stx_b, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_stx_h(
Register rd,
Register rj,
Register rk) {
spew(
"stx_h %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_stx_h, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_stx_w(
Register rd,
Register rj,
Register rk) {
spew(
"stx_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_stx_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_stx_d(
Register rd,
Register rj,
Register rk) {
spew(
"stx_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_stx_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ldptr_w(
Register rd,
Register rj,
int32_t si14) {
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
spew(
"ldptr_w %3s,%3s,0x%x", rd.name(), rj.name(), si14);
return writeInst(InstImm(op_ldptr_w, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_ldptr_d(
Register rd,
Register rj,
int32_t si14) {
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
spew(
"ldptr_d %3s,%3s,0x%x", rd.name(), rj.name(), si14);
return writeInst(InstImm(op_ldptr_d, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_stptr_w(
Register rd,
Register rj,
int32_t si14) {
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
spew(
"stptr_w %3s,%3s,0x%x", rd.name(), rj.name(), si14);
return writeInst(InstImm(op_stptr_w, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_stptr_d(
Register rd,
Register rj,
int32_t si14) {
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
spew(
"stptr_d %3s,%3s,0x%x", rd.name(), rj.name(), si14);
return writeInst(InstImm(op_stptr_d, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_preld(int32_t hint,
Register rj,
int32_t si12) {
MOZ_ASSERT(is_intN(si12, 12));
spew(
"preld 0x%x,%3s,0x%x", hint, rj.name(), si12);
return writeInst(InstImm(op_preld, si12, rj, hint).encode());
}
// Atomic instructions
BufferOffset AssemblerLOONG64::as_amswap_w(
Register rd,
Register rj,
Register rk) {
spew(
"amswap_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amswap_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amswap_d(
Register rd,
Register rj,
Register rk) {
spew(
"amswap_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amswap_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amadd_w(
Register rd,
Register rj,
Register rk) {
spew(
"amadd_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amadd_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amadd_d(
Register rd,
Register rj,
Register rk) {
spew(
"amadd_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amadd_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amand_w(
Register rd,
Register rj,
Register rk) {
spew(
"amand_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amand_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amand_d(
Register rd,
Register rj,
Register rk) {
spew(
"amand_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amand_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amor_w(
Register rd,
Register rj,
Register rk) {
spew(
"amor_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amor_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amor_d(
Register rd,
Register rj,
Register rk) {
spew(
"amor_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amor_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amxor_w(
Register rd,
Register rj,
Register rk) {
spew(
"amxor_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amxor_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amxor_d(
Register rd,
Register rj,
Register rk) {
spew(
"amxor_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amxor_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_w(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_d(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_w(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_d(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_wu(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_du(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_wu(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_du(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amswap_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"amswap_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amswap_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amswap_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"amswap_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amswap_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amadd_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"amadd_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amadd_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amadd_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"amadd_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amadd_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amand_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"amand_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amand_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amand_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"amand_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amand_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amor_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"amor_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amor_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amor_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"amor_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amor_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amxor_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"amxor_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amxor_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_amxor_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"amxor_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_amxor_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_db_w(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_db_w %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_db_w, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_db_d(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_db_d %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_db_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_db_wu(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_db_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_db_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammax_db_du(
Register rd,
Register rj,
Register rk) {
spew(
"ammax_db_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammax_db_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_db_wu(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_db_wu %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_db_wu, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ammin_db_du(
Register rd,
Register rj,
Register rk) {
spew(
"ammin_db_du %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ammin_db_du, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONG64::as_ll_w(
Register rd,
Register rj, int32_t si14) {
spew(
"ll_w %3s,%3s,0x%x", rd.name(), rj.name(), si14);
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
return writeInst(InstImm(op_ll_w, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_ll_d(
Register rd,
Register rj, int32_t si14) {
spew(
"ll_d %3s,%3s,0x%x", rd.name(), rj.name(), si14);
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
return writeInst(InstImm(op_ll_d, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_sc_w(
Register rd,
Register rj, int32_t si14) {
spew(
"sc_w %3s,%3s,0x%x", rd.name(), rj.name(), si14);
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
return writeInst(InstImm(op_sc_w, si14 >> 2, rj, rd, 14).encode());
}
BufferOffset AssemblerLOONG64::as_sc_d(
Register rd,
Register rj, int32_t si14) {
spew(
"sc_d %3s,%3s,0x%x", rd.name(), rj.name(), si14);
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
return writeInst(InstImm(op_sc_d, si14 >> 2, rj, rd, 14).encode());
}
// Barrier instructions
BufferOffset AssemblerLOONG64::as_dbar(int32_t hint) {
MOZ_ASSERT(is_uintN(hint, 15));
spew(
"dbar 0x%x", hint);
return writeInst(InstImm(op_dbar, hint).encode());
}
BufferOffset AssemblerLOONG64::as_ibar(int32_t hint) {
MOZ_ASSERT(is_uintN(hint, 15));
spew(
"ibar 0x%x", hint);
return writeInst(InstImm(op_ibar, hint).encode());
}
/* =============================================================== */
// FP Arithmetic instructions
BufferOffset AssemblerLOONG64::as_fadd_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fadd_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fadd_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fadd_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fadd_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fadd_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fsub_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fsub_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fsub_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fsub_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fsub_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fsub_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmul_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmul_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmul_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmul_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmul_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmul_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fdiv_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fdiv_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fdiv_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fdiv_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fdiv_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fdiv_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmadd_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fmadd_s %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fmadd_s, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmadd_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fmadd_d %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fmadd_d, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmsub_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fmsub_s %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fmsub_s, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmsub_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fmsub_d %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fmsub_d, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fnmadd_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fnmadd_s %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fnmadd_s, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fnmadd_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fnmadd_d %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fnmadd_d, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fnmsub_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fnmsub_s %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fnmsub_s, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fnmsub_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk, FloatRegister fa) {
spew(
"fnmsub_d %3s,%3s,%3s,%3s", fd.name(), fj.name(), fk.name(),
fa.name());
return writeInst(InstReg(op_fnmsub_d, fa, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmax_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmax_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmax_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmax_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmax_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmax_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmin_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmin_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmin_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmin_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmin_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmin_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmaxa_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmaxa_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmaxa_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmaxa_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmaxa_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmaxa_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmina_s(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmina_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmina_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fmina_d(FloatRegister fd, FloatRegister fj,
FloatRegister fk) {
spew(
"fmina_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fmina_d, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fabs_s(FloatRegister fd, FloatRegister fj) {
spew(
"fabs_s %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fabs_s, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fabs_d(FloatRegister fd, FloatRegister fj) {
spew(
"fabs_d %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fabs_d, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fneg_s(FloatRegister fd, FloatRegister fj) {
spew(
"fneg_s %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fneg_s, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fneg_d(FloatRegister fd, FloatRegister fj) {
spew(
"fneg_d %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fneg_d, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fsqrt_s(FloatRegister fd, FloatRegister fj) {
spew(
"fsqrt_s %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fsqrt_s, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fsqrt_d(FloatRegister fd, FloatRegister fj) {
spew(
"fsqrt_d %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fsqrt_d, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fcopysign_s(FloatRegister fd,
FloatRegister fj,
FloatRegister fk) {
spew(
"fcopysign_s %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fcopysign_s, fk, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fcopysign_d(FloatRegister fd,
FloatRegister fj,
FloatRegister fk) {
spew(
"fcopysign_d %3s,%3s,%3s", fd.name(), fj.name(), fk.name());
return writeInst(InstReg(op_fcopysign_d, fk, fj, fd).encode());
}
// FP compare instructions
// fcmp.cond.s and fcmp.cond.d instructions
BufferOffset AssemblerLOONG64::as_fcmp_cor(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cor_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, COR, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cor_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, COR, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_ceq(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_ceq_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CEQ, fk, fj, cd).encode());
}
else {
spew(
"fcmp_ceq_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CEQ, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cne(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cne_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CNE, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cne_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CNE, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cle(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cle_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CLE, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cle_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CLE, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_clt(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_clt_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CLT, fk, fj, cd).encode());
}
else {
spew(
"fcmp_clt_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CLT, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cun(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cun_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CUN, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cun_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CUN, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cueq(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cueq_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CUEQ, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cueq_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CUEQ, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cune(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cune_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CUNE, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cune_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CUNE, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cule(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cule_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CULE, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cule_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CULE, fk, fj, cd).encode());
}
}
BufferOffset AssemblerLOONG64::as_fcmp_cult(FloatFormat fmt, FloatRegister fj,
FloatRegister fk,
FPConditionBit cd) {
if (fmt == DoubleFloat) {
spew(
"fcmp_cult_d FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_d, CULT, fk, fj, cd).encode());
}
else {
spew(
"fcmp_cult_s FCC%d,%3s,%3s", cd, fj.name(), fk.name());
return writeInst(InstReg(op_fcmp_cond_s, CULT, fk, fj, cd).encode());
}
}
// FP conversion instructions
BufferOffset AssemblerLOONG64::as_fcvt_s_d(FloatRegister fd, FloatRegister fj) {
spew(
"fcvt_s_d %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fcvt_s_d, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_fcvt_d_s(FloatRegister fd, FloatRegister fj) {
spew(
"fcvt_d_s %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_fcvt_d_s, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_ffint_s_w(FloatRegister fd,
FloatRegister fj) {
spew(
"ffint_s_w %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_ffint_s_w, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_ffint_s_l(FloatRegister fd,
FloatRegister fj) {
spew(
"ffint_s_l %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_ffint_s_l, fj, fd).encode());
}
BufferOffset AssemblerLOONG64::as_ffint_d_w(FloatRegister fd,
FloatRegister fj) {
spew(
"ffint_d_w %3s,%3s", fd.name(), fj.name());
return writeInst(InstReg(op_ffint_d_w, fj, fd).encode());
}
--> --------------------
--> maximum size reached
--> --------------------