#ifndef jit_shared_CodeGenerator_shared_inl_h
#define jit_shared_CodeGenerator_shared_inl_h
#include "jit/shared/CodeGenerator-shared.h"
#include "jit/MacroAssembler-inl.h"
namespace js {
namespace jit {
static inline bool IsConstant(const LInt64Allocation& a) {
#if JS_BITS_PER_WORD == 32
if (a.high().isConstantValue()) {
return true;
}
if (a.high().isConstantIndex()) {
return true;
}
#else
if (a.value().isConstantValue()) {
return true;
}
if (a.value().isConstantIndex()) {
return true;
}
#endif
return false;
}
static inline int32_t ToInt32(const LAllocation* a) {
if (a->isConstantValue()) {
return a->toConstant()->toInt32();
}
if (a->isConstantIndex()) {
return a->toConstantIndex()->index();
}
MOZ_CRASH("this is not a constant!");
}
static inline int64_t ToInt64(const LAllocation* a) {
if (a->isConstantValue()) {
return a->toConstant()->toInt64();
}
if (a->isConstantIndex()) {
return a->toConstantIndex()->index();
}
MOZ_CRASH("this is not a constant!");
}
static inline int64_t ToInt64(const LInt64Allocation& a) {
#if JS_BITS_PER_WORD == 32
if (a.high().isConstantValue()) {
return a.high().toConstant()->toInt64();
}
if (a.high().isConstantIndex()) {
return a.high().toConstantIndex()->index();
}
#else
if (a.value().isConstantValue()) {
return a.value().toConstant()->toInt64();
}
if (a.value().isConstantIndex()) {
return a.value().toConstantIndex()->index();
}
#endif
MOZ_CRASH("this is not a constant!");
}
static inline double ToDouble(const LAllocation* a) {
return a->toConstant()->numberToDouble();
}
static inline Register ToRegister(const LAllocation& a) {
MOZ_ASSERT(a.isGeneralReg());
return a.toGeneralReg()->reg();
}
static inline Register ToRegister(const LAllocation* a) {
return ToRegister(*a);
}
static inline Register ToRegister(const LDefinition* def) {
return ToRegister(*def->output());
}
static inline Register64 ToOutRegister64(LInstruction* ins) {
#if JS_BITS_PER_WORD == 32
Register loReg = ToRegister(ins->getDef(INT64LOW_INDEX));
Register hiReg = ToRegister(ins->getDef(INT64HIGH_INDEX));
return Register64(hiReg, loReg);
#else
return Register64(ToRegister(ins->getDef(0)));
#endif
}
static inline Register64 ToRegister64(const LInt64Allocation& a) {
#if JS_BITS_PER_WORD == 32
return Register64(ToRegister(a.high()), ToRegister(a.low()));
#else
return Register64(ToRegister(a.value()));
#endif
}
static inline Register ToTempRegisterOrInvalid(const LDefinition* def) {
if (def->isBogusTemp()) {
return InvalidReg;
}
return ToRegister(def);
}
static inline Register ToTempUnboxRegister(const LDefinition* def) {
return ToTempRegisterOrInvalid(def);
}
static inline Register ToRegisterOrInvalid(const LDefinition* a) {
return a ? ToRegister(a) : InvalidReg;
}
static inline FloatRegister ToFloatRegister(const LAllocation& a) {
MOZ_ASSERT(a.isFloatReg());
return a.toFloatReg()->reg();
}
static inline FloatRegister ToFloatRegister(const LAllocation* a) {
return ToFloatRegister(*a);
}
static inline FloatRegister ToFloatRegister(const LDefinition* def) {
return ToFloatRegister(*def->output());
}
static inline FloatRegister ToTempFloatRegisterOrInvalid(
const LDefinition* def) {
if (def->isBogusTemp()) {
return InvalidFloatReg;
}
return ToFloatRegister(def);
}
static inline AnyRegister ToAnyRegister(const LAllocation& a) {
MOZ_ASSERT(a.isGeneralReg() || a.isFloatReg());
if (a.isGeneralReg()) {
return AnyRegister(ToRegister(a));
}
return AnyRegister(ToFloatRegister(a));
}
static inline AnyRegister ToAnyRegister(const LAllocation* a) {
return ToAnyRegister(*a);
}
static inline AnyRegister ToAnyRegister(const LDefinition* def) {
return ToAnyRegister(def->output());
}
static inline ValueOperand ToOutValue(LInstruction* ins) {
#if defined(JS_NUNBOX32)
return ValueOperand(ToRegister(ins->getDef(TYPE_INDEX)),
ToRegister(ins->getDef(PAYLOAD_INDEX)));
#elif defined(JS_PUNBOX64)
return ValueOperand(ToRegister(ins->getDef(0)));
#else
# error "Unknown"
#endif
}
static inline ValueOperand GetTempValue(Register type, Register payload) {
#if defined(JS_NUNBOX32)
return ValueOperand(type, payload);
#elif defined(JS_PUNBOX64)
(void)type;
return ValueOperand(payload);
#else
# error "Unknown"
#endif
}
int32_t CodeGeneratorShared::ArgToStackOffset(int32_t slot) const {
return masm.framePushed() +
(gen->compilingWasm() ? sizeof(wasm::Frame) : sizeof(JitFrameLayout)) +
slot;
}
int32_t CodeGeneratorShared::SlotToStackOffset(int32_t slot) const {
MOZ_ASSERT(slot > 0 && slot <= int32_t(graph.localSlotCount()));
int32_t offset = masm.framePushed() - slot;
MOZ_ASSERT(offset >= 0);
return offset;
}
int32_t CodeGeneratorShared::StackOffsetToSlot(int32_t offset) const {
return masm.framePushed() - offset;
}
int32_t CodeGeneratorShared::StackOffsetOfPassedArg(int32_t slot) const {
MOZ_ASSERT(slot >= 0 && slot <= int32_t(graph.argumentSlotCount()));
int32_t offset = masm.framePushed() - graph.paddedLocalSlotsSize() -
(slot * sizeof(Value));
MOZ_ASSERT(offset >= 0);
MOZ_ASSERT(offset % sizeof(Value) == 0);
return offset;
}
int32_t CodeGeneratorShared::ToStackOffset(LAllocation a) const {
if (a.isArgument()) {
return ArgToStackOffset(a.toArgument()->index());
}
return SlotToStackOffset(a.toStackSlot()->slot());
}
int32_t CodeGeneratorShared::ToStackOffset(const LAllocation* a) const {
return ToStackOffset(*a);
}
Address CodeGeneratorShared::ToAddress(const LAllocation& a) {
MOZ_ASSERT(a.isMemory());
return Address(masm.getStackPointer(), ToStackOffset(&a));
}
Address CodeGeneratorShared::ToAddress(const LAllocation* a) {
return ToAddress(*a);
}
void CodeGeneratorShared::saveLive(LInstruction* ins) {
MOZ_ASSERT(!ins->isCall());
LSafepoint* safepoint = ins->safepoint();
masm.PushRegsInMask(safepoint->liveRegs());
}
void CodeGeneratorShared::restoreLive(LInstruction* ins) {
MOZ_ASSERT(!ins->isCall());
LSafepoint* safepoint = ins->safepoint();
masm.PopRegsInMask(safepoint->liveRegs());
}
void CodeGeneratorShared::restoreLiveIgnore(LInstruction* ins,
LiveRegisterSet ignore) {
MOZ_ASSERT(!ins->isCall());
LSafepoint* safepoint = ins->safepoint();
masm.PopRegsInMaskIgnore(safepoint->liveRegs(), ignore);
}
void CodeGeneratorShared::saveLiveVolatile(LInstruction* ins) {
MOZ_ASSERT(!ins->isCall());
LSafepoint* safepoint = ins->safepoint();
LiveRegisterSet regs;
regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(),
RegisterSet::Volatile());
masm.PushRegsInMask(regs);
}
void CodeGeneratorShared::restoreLiveVolatile(LInstruction* ins) {
MOZ_ASSERT(!ins->isCall());
LSafepoint* safepoint = ins->safepoint();
LiveRegisterSet regs;
regs.set() = RegisterSet::Intersect(safepoint->liveRegs().set(),
RegisterSet::Volatile());
masm.PopRegsInMask(regs);
}
inline bool CodeGeneratorShared::isGlobalObject(JSObject* object) {
return object == gen->realm->maybeGlobal();
}
} }
#endif