mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1173642 - Import unimplemented ARM64 Ion components. r=efaust
This commit is contained in:
parent
c5f5ca821c
commit
9cafe07011
746
js/src/jit/arm64/CodeGenerator-arm64.cpp
Normal file
746
js/src/jit/arm64/CodeGenerator-arm64.cpp
Normal file
@ -0,0 +1,746 @@
|
||||
/* -*- 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/arm64/CodeGenerator-arm64.h"
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsnum.h"
|
||||
|
||||
#include "jit/CodeGenerator.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/MIR.h"
|
||||
#include "jit/MIRGraph.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
#include "jit/shared/CodeGenerator-shared-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::FloorLog2;
|
||||
using mozilla::NegativeInfinity;
|
||||
using JS::GenericNaN;
|
||||
|
||||
// shared
|
||||
CodeGeneratorARM64::CodeGeneratorARM64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm)
|
||||
: CodeGeneratorShared(gen, graph, masm)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM64::generatePrologue()
|
||||
{
|
||||
MOZ_CRASH("generatePrologue");
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM64::generateEpilogue()
|
||||
{
|
||||
MOZ_CRASH("generateEpilogue");
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM64::generateOutOfLineCode()
|
||||
{
|
||||
MOZ_CRASH("generateOutOfLineCode");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::emitBranch(Assembler::Condition cond, MBasicBlock* mirTrue, MBasicBlock* mirFalse)
|
||||
{
|
||||
MOZ_CRASH("emitBranch");
|
||||
}
|
||||
|
||||
void
|
||||
OutOfLineBailout::accept(CodeGeneratorARM64* codegen)
|
||||
{
|
||||
MOZ_CRASH("accept");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitTestIAndBranch(LTestIAndBranch* test)
|
||||
{
|
||||
MOZ_CRASH("visitTestIAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompare(LCompare* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompare");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareAndBranch(LCompareAndBranch* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompareAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::bailoutIf(Assembler::Condition condition, LSnapshot* snapshot)
|
||||
{
|
||||
MOZ_CRASH("bailoutIf");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::bailoutFrom(Label* label, LSnapshot* snapshot)
|
||||
{
|
||||
MOZ_CRASH("bailoutFrom");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::bailout(LSnapshot* snapshot)
|
||||
{
|
||||
MOZ_CRASH("bailout");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitOutOfLineBailout(OutOfLineBailout* ool)
|
||||
{
|
||||
MOZ_CRASH("visitOutOfLineBailout");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitMinMaxD(LMinMaxD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitMinMaxD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitMinMaxF(LMinMaxF* ins)
|
||||
{
|
||||
MOZ_CRASH("visitMinMaxF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAbsD(LAbsD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAbsD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAbsF(LAbsF* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAbsF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitSqrtD(LSqrtD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitSqrtD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitSqrtF(LSqrtF* ins)
|
||||
{
|
||||
MOZ_CRASH("visitSqrtF");
|
||||
}
|
||||
|
||||
// FIXME: Uh, is this a static function? It looks like it is...
|
||||
template <typename T>
|
||||
ARMRegister
|
||||
toWRegister(const T* a)
|
||||
{
|
||||
return ARMRegister(ToRegister(a), 32);
|
||||
}
|
||||
|
||||
// FIXME: Uh, is this a static function? It looks like it is...
|
||||
template <typename T>
|
||||
ARMRegister
|
||||
toXRegister(const T* a)
|
||||
{
|
||||
return ARMRegister(ToRegister(a), 64);
|
||||
}
|
||||
|
||||
js::jit::Operand
|
||||
toWOperand(const LAllocation* a)
|
||||
{
|
||||
MOZ_CRASH("toWOperand");
|
||||
}
|
||||
|
||||
vixl::CPURegister
|
||||
ToCPURegister(const LAllocation* a, Scalar::Type type)
|
||||
{
|
||||
MOZ_CRASH("ToCPURegister");
|
||||
}
|
||||
|
||||
vixl::CPURegister
|
||||
ToCPURegister(const LDefinition* d, Scalar::Type type)
|
||||
{
|
||||
return ToCPURegister(d->output(), type);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAddI(LAddI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAddI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitSubI(LSubI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitSubI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitMulI(LMulI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitMulI");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitDivI(LDivI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitDivI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitDivPowTwoI(LDivPowTwoI* ins)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitDivPowTwoI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::modICommon(MMod* mir, Register lhs, Register rhs, Register output,
|
||||
LSnapshot* snapshot, Label& done)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::modICommon");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitModI(LModI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitModI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitModPowTwoI(LModPowTwoI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitModPowTwoI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitModMaskI(LModMaskI* ins)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitModMaskI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitBitNotI(LBitNotI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitBitNotI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitBitOpI(LBitOpI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitBitOpI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitShiftI(LShiftI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitShiftI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitUrshD(LUrshD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitUrshD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitPowHalfD(LPowHalfD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitPowHalfD");
|
||||
}
|
||||
|
||||
MoveOperand
|
||||
CodeGeneratorARM64::toMoveOperand(const LAllocation a) const
|
||||
{
|
||||
MOZ_CRASH("toMoveOperand");
|
||||
}
|
||||
|
||||
class js::jit::OutOfLineTableSwitch : public OutOfLineCodeBase<CodeGeneratorARM64>
|
||||
{
|
||||
MTableSwitch* mir_;
|
||||
Vector<CodeLabel, 8, JitAllocPolicy> codeLabels_;
|
||||
|
||||
void accept(CodeGeneratorARM64* codegen) {
|
||||
codegen->visitOutOfLineTableSwitch(this);
|
||||
}
|
||||
|
||||
public:
|
||||
OutOfLineTableSwitch(TempAllocator& alloc, MTableSwitch* mir)
|
||||
: mir_(mir),
|
||||
codeLabels_(alloc)
|
||||
{ }
|
||||
|
||||
MTableSwitch* mir() const {
|
||||
return mir_;
|
||||
}
|
||||
|
||||
bool addCodeLabel(CodeLabel label) {
|
||||
return codeLabels_.append(label);
|
||||
}
|
||||
CodeLabel codeLabel(unsigned i) {
|
||||
return codeLabels_[i];
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool)
|
||||
{
|
||||
MOZ_CRASH("visitOutOfLineTableSwitch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::emitTableSwitchDispatch(MTableSwitch* mir, Register index_, Register base_)
|
||||
{
|
||||
MOZ_CRASH("emitTableSwitchDispatch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitMathD(LMathD* math)
|
||||
{
|
||||
MOZ_CRASH("visitMathD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitMathF(LMathF* math)
|
||||
{
|
||||
MOZ_CRASH("visitMathF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitFloor(LFloor* lir)
|
||||
{
|
||||
MOZ_CRASH("visitFloor");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitFloorF(LFloorF* lir)
|
||||
{
|
||||
MOZ_CRASH("visitFloorF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCeil(LCeil* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCeil");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCeilF(LCeilF* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCeilF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitRound(LRound* lir)
|
||||
{
|
||||
MOZ_CRASH("visitRound");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitRoundF(LRoundF* lir)
|
||||
{
|
||||
MOZ_CRASH("visitRoundF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitClzI(LClzI* lir)
|
||||
{
|
||||
MOZ_CRASH("visitClzI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::emitRoundDouble(FloatRegister src, Register dest, Label* fail)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::emitRoundDouble");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitTruncateDToInt32(LTruncateDToInt32* ins)
|
||||
{
|
||||
MOZ_CRASH("visitTruncateDToInt32");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitTruncateFToInt32(LTruncateFToInt32* ins)
|
||||
{
|
||||
MOZ_CRASH("visitTruncateFToInt32");
|
||||
}
|
||||
|
||||
static const uint32_t FrameSizes[] = { 128, 256, 512, 1024 };
|
||||
|
||||
FrameSizeClass
|
||||
FrameSizeClass::FromDepth(uint32_t frameDepth)
|
||||
{
|
||||
return FrameSizeClass::None();
|
||||
}
|
||||
|
||||
FrameSizeClass
|
||||
FrameSizeClass::ClassLimit()
|
||||
{
|
||||
return FrameSizeClass(0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FrameSizeClass::frameSize() const
|
||||
{
|
||||
MOZ_CRASH("arm64 does not use frame size classes");
|
||||
}
|
||||
|
||||
ValueOperand
|
||||
CodeGeneratorARM64::ToValue(LInstruction* ins, size_t pos)
|
||||
{
|
||||
return ValueOperand(ToRegister(ins->getOperand(pos)));
|
||||
}
|
||||
|
||||
ValueOperand
|
||||
CodeGeneratorARM64::ToOutValue(LInstruction* ins)
|
||||
{
|
||||
Register payloadReg = ToRegister(ins->getDef(0));
|
||||
return ValueOperand(payloadReg);
|
||||
}
|
||||
|
||||
ValueOperand
|
||||
CodeGeneratorARM64::ToTempValue(LInstruction* ins, size_t pos)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::ToTempValue");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitValue(LValue* value)
|
||||
{
|
||||
MOZ_CRASH("visitValue");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitBox(LBox* box)
|
||||
{
|
||||
MOZ_CRASH("visitBox");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitUnbox(LUnbox* unbox)
|
||||
{
|
||||
MOZ_CRASH("visitUnbox");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitDouble(LDouble* ins)
|
||||
{
|
||||
MOZ_CRASH("visitDouble");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitFloat32(LFloat32* ins)
|
||||
{
|
||||
MOZ_CRASH("visitFloat32");
|
||||
}
|
||||
|
||||
Register
|
||||
CodeGeneratorARM64::splitTagForTest(const ValueOperand& value)
|
||||
{
|
||||
MOZ_CRASH("splitTagForTest");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitTestDAndBranch(LTestDAndBranch* test)
|
||||
{
|
||||
MOZ_CRASH("visitTestDAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitTestFAndBranch(LTestFAndBranch* test)
|
||||
{
|
||||
MOZ_CRASH("visitTestFAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareD(LCompareD* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompareD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareF(LCompareF* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompareF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareDAndBranch(LCompareDAndBranch* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompareDAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareFAndBranch(LCompareFAndBranch* comp)
|
||||
{
|
||||
MOZ_CRASH("visitCompareFAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareB(LCompareB* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCompareB");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareBAndBranch(LCompareBAndBranch* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCompareBAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareV(LCompareV* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCompareV");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitCompareVAndBranch(LCompareVAndBranch* lir)
|
||||
{
|
||||
MOZ_CRASH("visitCompareVAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitBitAndAndBranch(LBitAndAndBranch* baab)
|
||||
{
|
||||
MOZ_CRASH("visitBitAndAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble* lir)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSUInt32ToDouble");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32* lir)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSUInt32ToFloat32");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitNotI(LNotI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNotI");
|
||||
}
|
||||
|
||||
// NZCV
|
||||
// NAN -> 0011
|
||||
// == -> 0110
|
||||
// < -> 1000
|
||||
// > -> 0010
|
||||
void
|
||||
CodeGeneratorARM64::visitNotD(LNotD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNotD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitNotF(LNotF* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNotF");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitLoadSlotV(LLoadSlotV* load)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitLoadSlotV");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitLoadSlotT(LLoadSlotT* load)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitLoadSlotT");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitStoreSlotT(LStoreSlotT* store)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitStoreSlotT");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitLoadElementT(LLoadElementT* load)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitLoadElementT");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::storeElementTyped(const LAllocation* value, MIRType valueType,
|
||||
MIRType elementType, Register elements,
|
||||
const LAllocation* index)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::storeElementTyped");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
MOZ_CRASH("visitGuardShape");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
MOZ_CRASH("visitGuardObjectGroup");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitGuardClass");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitInterruptCheck(LInterruptCheck* lir)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitInterruptCheck");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::generateInvalidateEpilogue()
|
||||
{
|
||||
MOZ_CRASH("generateInvalidateEpilogue");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitRandom(LRandom* ins)
|
||||
{
|
||||
MOZ_CRASH("visitRandom");
|
||||
}
|
||||
|
||||
template <class U>
|
||||
Register
|
||||
getBase(U* mir)
|
||||
{
|
||||
switch (mir->base()) {
|
||||
case U::Heap: return HeapReg;
|
||||
case U::Global: return GlobalReg;
|
||||
}
|
||||
return InvalidReg;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitLoadTypedArrayElementStatic");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic* ins)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitStoreTypedArrayElementStatic");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSCall(LAsmJSCall* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSCall");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadHeap");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSStoreHeap");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSCompareExchangeHeap");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSAtomicBinopHeap(LAsmJSAtomicBinopHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSAtomicBinopHeap");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSPassStackArg(LAsmJSPassStackArg* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSPassStackArg");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitUDiv(LUDiv* ins)
|
||||
{
|
||||
MOZ_CRASH("visitUDiv");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitUMod(LUMod* ins)
|
||||
{
|
||||
MOZ_CRASH("visitUMod");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitEffectiveAddress(LEffectiveAddress* ins)
|
||||
{
|
||||
MOZ_CRASH("visitEffectiveAddress");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadGlobalVar");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSStoreGlobalVar");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadFuncPtr");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadFFIFunc");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitNegI(LNegI* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNegI");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitNegD(LNegD* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNegD");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitNegF(LNegF* ins)
|
||||
{
|
||||
MOZ_CRASH("visitNegF");
|
||||
}
|
276
js/src/jit/arm64/CodeGenerator-arm64.h
Normal file
276
js/src/jit/arm64/CodeGenerator-arm64.h
Normal file
@ -0,0 +1,276 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef jit_arm64_CodeGenerator_arm64_h
|
||||
#define jit_arm64_CodeGenerator_arm64_h
|
||||
|
||||
#include "jit/arm64/Assembler-arm64.h"
|
||||
#include "jit/shared/CodeGenerator-shared.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class OutOfLineBailout;
|
||||
class OutOfLineTableSwitch;
|
||||
|
||||
class CodeGeneratorARM64 : public CodeGeneratorShared
|
||||
{
|
||||
friend class MoveResolverARM64;
|
||||
|
||||
CodeGeneratorARM64* thisFromCtor() { return this; }
|
||||
|
||||
public:
|
||||
CodeGeneratorARM64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm);
|
||||
|
||||
protected:
|
||||
// Label for the common return path.
|
||||
NonAssertingLabel returnLabel_;
|
||||
NonAssertingLabel deoptLabel_;
|
||||
|
||||
// FIXME: VIXL Operand does not match the platform-agnostic Operand,
|
||||
// which is just a union of possible arguments.
|
||||
inline Operand ToOperand(const LAllocation& a) {
|
||||
MOZ_CRASH("ToOperand");
|
||||
}
|
||||
inline Operand ToOperand(const LAllocation* a) {
|
||||
return ToOperand(*a);
|
||||
}
|
||||
inline Operand ToOperand(const LDefinition* def) {
|
||||
return ToOperand(def->output());
|
||||
}
|
||||
|
||||
MoveOperand toMoveOperand(const LAllocation a) const;
|
||||
|
||||
void bailoutIf(Assembler::Condition condition, LSnapshot* snapshot);
|
||||
void bailoutFrom(Label* label, LSnapshot* snapshot);
|
||||
void bailout(LSnapshot* snapshot);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot* snapshot) {
|
||||
masm.cmpPtr(lhs, rhs);
|
||||
return bailoutIf(c, snapshot);
|
||||
}
|
||||
void bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs, LSnapshot* snapshot) {
|
||||
masm.testPtr(lhs, rhs);
|
||||
return bailoutIf(c, snapshot);
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
void bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot* snapshot) {
|
||||
masm.cmp32(lhs, rhs);
|
||||
return bailoutIf(c, snapshot);
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
void bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot* snapshot) {
|
||||
masm.test32(lhs, rhs);
|
||||
return bailoutIf(c, snapshot);
|
||||
}
|
||||
void bailoutIfFalseBool(Register reg, LSnapshot* snapshot) {
|
||||
masm.test32(reg, Imm32(0xFF));
|
||||
return bailoutIf(Assembler::Zero, snapshot);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool generatePrologue();
|
||||
bool generateEpilogue();
|
||||
bool generateOutOfLineCode();
|
||||
|
||||
void emitRoundDouble(FloatRegister src, Register dest, Label* fail);
|
||||
|
||||
// Emits a branch that directs control flow to the true block if |cond| is
|
||||
// true, and the false block if |cond| is false.
|
||||
void emitBranch(Assembler::Condition cond, MBasicBlock* ifTrue, MBasicBlock* ifFalse);
|
||||
|
||||
void testNullEmitBranch(Assembler::Condition cond, const ValueOperand& value,
|
||||
MBasicBlock* ifTrue, MBasicBlock* ifFalse)
|
||||
{
|
||||
cond = masm.testNull(cond, value);
|
||||
emitBranch(cond, ifTrue, ifFalse);
|
||||
}
|
||||
void testUndefinedEmitBranch(Assembler::Condition cond, const ValueOperand& value,
|
||||
MBasicBlock* ifTrue, MBasicBlock* ifFalse)
|
||||
{
|
||||
cond = masm.testUndefined(cond, value);
|
||||
emitBranch(cond, ifTrue, ifFalse);
|
||||
}
|
||||
void testObjectEmitBranch(Assembler::Condition cond, const ValueOperand& value,
|
||||
MBasicBlock* ifTrue, MBasicBlock* ifFalse)
|
||||
{
|
||||
cond = masm.testObject(cond, value);
|
||||
emitBranch(cond, ifTrue, ifFalse);
|
||||
}
|
||||
void testZeroEmitBranch(Assembler::Condition cond, Register reg,
|
||||
MBasicBlock* ifTrue, MBasicBlock* ifFalse)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
masm.cmpPtr(reg, ImmWord(0));
|
||||
emitBranch(cond, ifTrue, ifFalse);
|
||||
}
|
||||
|
||||
void emitTableSwitchDispatch(MTableSwitch* mir, Register index, Register base);
|
||||
|
||||
public:
|
||||
// Instruction visitors.
|
||||
virtual void visitMinMaxD(LMinMaxD* ins);
|
||||
virtual void visitMinMaxF(LMinMaxF* math);
|
||||
virtual void visitAbsD(LAbsD* ins);
|
||||
virtual void visitAbsF(LAbsF* ins);
|
||||
virtual void visitSqrtD(LSqrtD* ins);
|
||||
virtual void visitSqrtF(LSqrtF* ins);
|
||||
virtual void visitAddI(LAddI* ins);
|
||||
virtual void visitSubI(LSubI* ins);
|
||||
virtual void visitBitNotI(LBitNotI* ins);
|
||||
virtual void visitBitOpI(LBitOpI* ins);
|
||||
|
||||
virtual void visitMulI(LMulI* ins);
|
||||
|
||||
virtual void visitDivI(LDivI* ins);
|
||||
virtual void visitDivPowTwoI(LDivPowTwoI* ins);
|
||||
virtual void visitModI(LModI* ins);
|
||||
virtual void visitModPowTwoI(LModPowTwoI* ins);
|
||||
virtual void visitModMaskI(LModMaskI* ins);
|
||||
virtual void visitPowHalfD(LPowHalfD* ins);
|
||||
virtual void visitShiftI(LShiftI* ins);
|
||||
virtual void visitUrshD(LUrshD* ins);
|
||||
|
||||
virtual void visitTestIAndBranch(LTestIAndBranch* test);
|
||||
virtual void visitCompare(LCompare* comp);
|
||||
virtual void visitCompareAndBranch(LCompareAndBranch* comp);
|
||||
virtual void visitTestDAndBranch(LTestDAndBranch* test);
|
||||
virtual void visitTestFAndBranch(LTestFAndBranch* test);
|
||||
virtual void visitCompareD(LCompareD* comp);
|
||||
virtual void visitCompareF(LCompareF* comp);
|
||||
virtual void visitCompareDAndBranch(LCompareDAndBranch* comp);
|
||||
virtual void visitCompareFAndBranch(LCompareFAndBranch* comp);
|
||||
virtual void visitCompareB(LCompareB* lir);
|
||||
virtual void visitCompareBAndBranch(LCompareBAndBranch* lir);
|
||||
virtual void visitCompareV(LCompareV* lir);
|
||||
virtual void visitCompareVAndBranch(LCompareVAndBranch* lir);
|
||||
virtual void visitBitAndAndBranch(LBitAndAndBranch* baab);
|
||||
virtual void visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble* lir);
|
||||
virtual void visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32* lir);
|
||||
virtual void visitNotI(LNotI* ins);
|
||||
virtual void visitNotD(LNotD* ins);
|
||||
virtual void visitNotF(LNotF* ins);
|
||||
|
||||
virtual void visitMathD(LMathD* math);
|
||||
virtual void visitMathF(LMathF* math);
|
||||
virtual void visitFloor(LFloor* lir);
|
||||
virtual void visitFloorF(LFloorF* lir);
|
||||
virtual void visitCeil(LCeil* lir);
|
||||
virtual void visitCeilF(LCeilF* lir);
|
||||
virtual void visitRound(LRound* lir);
|
||||
virtual void visitRoundF(LRoundF* lir);
|
||||
virtual void visitTruncateDToInt32(LTruncateDToInt32* ins);
|
||||
virtual void visitTruncateFToInt32(LTruncateFToInt32* ins);
|
||||
|
||||
virtual void visitClzI(LClzI* lir);
|
||||
// Out of line visitors.
|
||||
void visitOutOfLineBailout(OutOfLineBailout* ool);
|
||||
void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool);
|
||||
|
||||
protected:
|
||||
ValueOperand ToValue(LInstruction* ins, size_t pos);
|
||||
ValueOperand ToOutValue(LInstruction* ins);
|
||||
ValueOperand ToTempValue(LInstruction* ins, size_t pos);
|
||||
|
||||
// Functions for LTestVAndBranch.
|
||||
Register splitTagForTest(const ValueOperand& value);
|
||||
|
||||
void storeElementTyped(const LAllocation* value, MIRType valueType, MIRType elementType,
|
||||
Register elements, const LAllocation* index);
|
||||
|
||||
void divICommon(MDiv* mir, Register lhs, Register rhs, Register output, LSnapshot* snapshot,
|
||||
Label& done);
|
||||
void modICommon(MMod* mir, Register lhs, Register rhs, Register output, LSnapshot* snapshot,
|
||||
Label& done);
|
||||
|
||||
public:
|
||||
void visitBox(LBox* box);
|
||||
void visitUnbox(LUnbox* unbox);
|
||||
void visitValue(LValue* value);
|
||||
void visitDouble(LDouble* ins);
|
||||
void visitFloat32(LFloat32* ins);
|
||||
|
||||
void visitLoadSlotV(LLoadSlotV* load);
|
||||
void visitLoadSlotT(LLoadSlotT* load);
|
||||
void visitStoreSlotT(LStoreSlotT* load);
|
||||
|
||||
void visitLoadElementT(LLoadElementT* load);
|
||||
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
|
||||
void visitInterruptCheck(LInterruptCheck* lir);
|
||||
|
||||
void visitNegI(LNegI* lir);
|
||||
void visitNegD(LNegD* lir);
|
||||
void visitNegF(LNegF* lir);
|
||||
void visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins);
|
||||
void visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic* ins);
|
||||
void visitAsmJSCall(LAsmJSCall* ins);
|
||||
void visitAsmJSLoadHeap(LAsmJSLoadHeap* ins);
|
||||
void visitAsmJSStoreHeap(LAsmJSStoreHeap* ins);
|
||||
void visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins);
|
||||
void visitAsmJSAtomicBinopHeap(LAsmJSAtomicBinopHeap* ins);
|
||||
void visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar* ins);
|
||||
void visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar* ins);
|
||||
void visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr* ins);
|
||||
void visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins);
|
||||
void visitAsmJSPassStackArg(LAsmJSPassStackArg* ins);
|
||||
|
||||
void generateInvalidateEpilogue();
|
||||
|
||||
void visitRandom(LRandom* ins);
|
||||
|
||||
protected:
|
||||
void postAsmJSCall(LAsmJSCall* lir) {
|
||||
MOZ_CRASH("postAsmJSCall");
|
||||
}
|
||||
|
||||
void visitEffectiveAddress(LEffectiveAddress* ins);
|
||||
void visitUDiv(LUDiv* ins);
|
||||
void visitUMod(LUMod* ins);
|
||||
|
||||
public:
|
||||
// Unimplemented SIMD instructions.
|
||||
void visitSimdSplatX4(LSimdSplatX4* lir) { MOZ_CRASH("NYI"); }
|
||||
void visitInt32x4(LInt32x4* ins) { MOZ_CRASH("NYI"); }
|
||||
void visitFloat32x4(LFloat32x4* ins) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdExtractElementI(LSimdExtractElementI* ins) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdExtractElementF(LSimdExtractElementF* ins) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdSignMaskX4(LSimdSignMaskX4* ins) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdBinaryCompIx4(LSimdBinaryCompIx4* lir) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdBinaryCompFx4(LSimdBinaryCompFx4* lir) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdBinaryArithIx4(LSimdBinaryArithIx4* lir) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdBinaryArithFx4(LSimdBinaryArithFx4* lir) { MOZ_CRASH("NYI"); }
|
||||
void visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4* lir) { MOZ_CRASH("NYI"); }
|
||||
};
|
||||
|
||||
typedef CodeGeneratorARM64 CodeGeneratorSpecific;
|
||||
|
||||
// An out-of-line bailout thunk.
|
||||
class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorARM64>
|
||||
{
|
||||
protected: // Silence Clang warning.
|
||||
LSnapshot* snapshot_;
|
||||
|
||||
public:
|
||||
OutOfLineBailout(LSnapshot* snapshot)
|
||||
: snapshot_(snapshot)
|
||||
{ }
|
||||
|
||||
void accept(CodeGeneratorARM64* codegen);
|
||||
|
||||
LSnapshot* snapshot() const {
|
||||
return snapshot_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_arm64_CodeGenerator_arm64_h */
|
467
js/src/jit/arm64/LIR-arm64.h
Normal file
467
js/src/jit/arm64/LIR-arm64.h
Normal file
@ -0,0 +1,467 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef jit_arm64_LIR_arm64_h
|
||||
#define jit_arm64_LIR_arm64_h
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class LBox : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
MIRType type_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(Box);
|
||||
|
||||
LBox(const LAllocation& in_payload, MIRType type)
|
||||
: type_(type)
|
||||
{
|
||||
setOperand(0, in_payload);
|
||||
}
|
||||
|
||||
MIRType type() const {
|
||||
return type_;
|
||||
}
|
||||
const char* extraName() const {
|
||||
return StringFromMIRType(type_);
|
||||
}
|
||||
};
|
||||
|
||||
class LUnboxBase : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LUnboxBase(const LAllocation& input) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
|
||||
static const size_t Input = 0;
|
||||
|
||||
MUnbox* mir() const {
|
||||
return mir_->toUnbox();
|
||||
}
|
||||
};
|
||||
|
||||
class LUnbox : public LUnboxBase
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(Unbox);
|
||||
|
||||
LUnbox(const LAllocation& input)
|
||||
: LUnboxBase(input)
|
||||
{ }
|
||||
|
||||
const char* extraName() const {
|
||||
return StringFromMIRType(mir()->type());
|
||||
}
|
||||
};
|
||||
|
||||
class LUnboxFloatingPoint : public LUnboxBase
|
||||
{
|
||||
MIRType type_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(UnboxFloatingPoint);
|
||||
|
||||
LUnboxFloatingPoint(const LAllocation& input, MIRType type)
|
||||
: LUnboxBase(input),
|
||||
type_(type)
|
||||
{ }
|
||||
|
||||
MIRType type() const {
|
||||
return type_;
|
||||
}
|
||||
const char* extraName() const {
|
||||
return StringFromMIRType(type_);
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a 32-bit unsigned integer to a double.
|
||||
class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(AsmJSUInt32ToDouble)
|
||||
|
||||
LAsmJSUInt32ToDouble(const LAllocation& input) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a 32-bit unsigned integer to a float32.
|
||||
class LAsmJSUInt32ToFloat32 : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(AsmJSUInt32ToFloat32)
|
||||
|
||||
LAsmJSUInt32ToFloat32(const LAllocation& input) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
};
|
||||
|
||||
class LDivI : public LBinaryMath<1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(DivI);
|
||||
|
||||
LDivI(const LAllocation& lhs, const LAllocation& rhs,
|
||||
const LDefinition& temp)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
setOperand(1, rhs);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
MDiv* mir() const {
|
||||
return mir_->toDiv();
|
||||
}
|
||||
};
|
||||
|
||||
// LSoftDivI is a software divide for ARM cores that don't support a hardware
|
||||
// divide instruction.
|
||||
//
|
||||
// It is implemented as a proper C function so it trashes r0, r1, r2 and r3.
|
||||
// The call also trashes lr, and has the ability to trash ip. The function also
|
||||
// takes two arguments (dividend in r0, divisor in r1). The LInstruction gets
|
||||
// encoded such that the divisor and dividend are passed in their apropriate
|
||||
// registers and end their life at the start of the instruction by the use of
|
||||
// useFixedAtStart. The result is returned in r0 and the other three registers
|
||||
// that can be trashed are marked as temps. For the time being, the link
|
||||
// register is not marked as trashed because we never allocate to the link
|
||||
// register. The FP registers are not trashed.
|
||||
class LSoftDivI : public LBinaryMath<3>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SoftDivI);
|
||||
|
||||
LSoftDivI(const LAllocation& lhs, const LAllocation& rhs,
|
||||
const LDefinition& temp1, const LDefinition& temp2, const LDefinition& temp3) {
|
||||
setOperand(0, lhs);
|
||||
setOperand(1, rhs);
|
||||
setTemp(0, temp1);
|
||||
setTemp(1, temp2);
|
||||
setTemp(2, temp3);
|
||||
}
|
||||
|
||||
MDiv* mir() const {
|
||||
return mir_->toDiv();
|
||||
}
|
||||
};
|
||||
|
||||
class LDivPowTwoI : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
const int32_t shift_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(DivPowTwoI)
|
||||
|
||||
LDivPowTwoI(const LAllocation& lhs, int32_t shift)
|
||||
: shift_(shift)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
}
|
||||
|
||||
const LAllocation* numerator() {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
int32_t shift() {
|
||||
return shift_;
|
||||
}
|
||||
|
||||
MDiv* mir() const {
|
||||
return mir_->toDiv();
|
||||
}
|
||||
};
|
||||
|
||||
class LModI : public LBinaryMath<1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(ModI);
|
||||
|
||||
LModI(const LAllocation& lhs, const LAllocation& rhs,
|
||||
const LDefinition& callTemp)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
setOperand(1, rhs);
|
||||
setTemp(0, callTemp);
|
||||
}
|
||||
|
||||
const LDefinition* callTemp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
|
||||
MMod* mir() const {
|
||||
return mir_->toMod();
|
||||
}
|
||||
};
|
||||
|
||||
class LSoftModI : public LBinaryMath<4>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SoftModI);
|
||||
|
||||
LSoftModI(const LAllocation& lhs, const LAllocation& rhs,
|
||||
const LDefinition& temp1, const LDefinition& temp2, const LDefinition& temp3,
|
||||
const LDefinition& callTemp)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
setOperand(1, rhs);
|
||||
setTemp(0, temp1);
|
||||
setTemp(1, temp2);
|
||||
setTemp(2, temp3);
|
||||
setTemp(3, callTemp);
|
||||
}
|
||||
|
||||
const LDefinition* callTemp() {
|
||||
return getTemp(3);
|
||||
}
|
||||
|
||||
MMod* mir() const {
|
||||
return mir_->toMod();
|
||||
}
|
||||
};
|
||||
|
||||
class LModPowTwoI : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
const int32_t shift_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(ModPowTwoI);
|
||||
int32_t shift()
|
||||
{
|
||||
return shift_;
|
||||
}
|
||||
|
||||
LModPowTwoI(const LAllocation& lhs, int32_t shift)
|
||||
: shift_(shift)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
}
|
||||
|
||||
MMod* mir() const {
|
||||
return mir_->toMod();
|
||||
}
|
||||
};
|
||||
|
||||
class LModMaskI : public LInstructionHelper<1, 1, 1>
|
||||
{
|
||||
const int32_t shift_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(ModMaskI);
|
||||
|
||||
LModMaskI(const LAllocation& lhs, const LDefinition& temp1, int32_t shift)
|
||||
: shift_(shift)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
setTemp(0, temp1);
|
||||
}
|
||||
|
||||
int32_t shift() const {
|
||||
return shift_;
|
||||
}
|
||||
|
||||
MMod* mir() const {
|
||||
return mir_->toMod();
|
||||
}
|
||||
};
|
||||
|
||||
class LPowHalfD : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(PowHalfD);
|
||||
LPowHalfD(const LAllocation& input) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
|
||||
const LAllocation* input() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition* output() {
|
||||
return getDef(0);
|
||||
}
|
||||
};
|
||||
|
||||
// Takes a tableswitch with an integer to decide
|
||||
class LTableSwitch : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(TableSwitch);
|
||||
|
||||
LTableSwitch(const LAllocation& in, const LDefinition& inputCopy, MTableSwitch* ins) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, inputCopy);
|
||||
setMir(ins);
|
||||
}
|
||||
|
||||
MTableSwitch* mir() const {
|
||||
return mir_->toTableSwitch();
|
||||
}
|
||||
|
||||
const LAllocation* index() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
// This is added to share the same CodeGenerator prefixes.
|
||||
const LDefinition* tempPointer() {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Takes a tableswitch with an integer to decide
|
||||
class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(TableSwitchV);
|
||||
|
||||
LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy,
|
||||
MTableSwitch* ins)
|
||||
{
|
||||
setTemp(0, inputCopy);
|
||||
setTemp(1, floatCopy);
|
||||
setMir(ins);
|
||||
}
|
||||
|
||||
MTableSwitch* mir() const {
|
||||
return mir_->toTableSwitch();
|
||||
}
|
||||
|
||||
static const size_t InputValue = 0;
|
||||
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
const LDefinition* tempFloat() {
|
||||
return getTemp(1);
|
||||
}
|
||||
const LDefinition* tempPointer() {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape);
|
||||
|
||||
LGuardShape(const LAllocation& in, const LDefinition& temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup);
|
||||
|
||||
LGuardObjectGroup(const LAllocation& in, const LDefinition& temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(MulI);
|
||||
|
||||
MMul* mir() {
|
||||
return mir_->toMul();
|
||||
}
|
||||
};
|
||||
|
||||
class LUDiv : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(UDiv);
|
||||
|
||||
MDiv* mir() {
|
||||
return mir_->toDiv();
|
||||
}
|
||||
};
|
||||
|
||||
class LUMod : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(UMod);
|
||||
|
||||
MMod* mir() {
|
||||
return mir_->toMod();
|
||||
}
|
||||
};
|
||||
|
||||
// This class performs a simple x86 'div', yielding either a quotient or remainder depending on
|
||||
// whether this instruction is defined to output eax (quotient) or edx (remainder).
|
||||
class LSoftUDivOrMod : public LBinaryMath<3>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SoftUDivOrMod);
|
||||
|
||||
LSoftUDivOrMod(const LAllocation& lhs, const LAllocation& rhs, const LDefinition& temp1,
|
||||
const LDefinition& temp2, const LDefinition& temp3) {
|
||||
setOperand(0, lhs);
|
||||
setOperand(1, rhs);
|
||||
setTemp(0, temp1);
|
||||
setTemp(1, temp2);
|
||||
setTemp(2, temp3);
|
||||
}
|
||||
};
|
||||
|
||||
class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(AsmJSLoadFuncPtr);
|
||||
LAsmJSLoadFuncPtr(const LAllocation& index, const LDefinition& temp) {
|
||||
setOperand(0, index);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MAsmJSLoadFuncPtr* mir() const {
|
||||
return mir_->toAsmJSLoadFuncPtr();
|
||||
}
|
||||
const LAllocation* index() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
// Math.random().
|
||||
class LRandom : public LCallInstructionHelper<1, 0, 2>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(Random)
|
||||
LRandom(const LDefinition& temp, const LDefinition& temp2) {
|
||||
setTemp(0, temp);
|
||||
setTemp(1, temp2);
|
||||
}
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
const LDefinition* temp2() {
|
||||
return getTemp(1);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_arm64_LIR_arm64_h */
|
29
js/src/jit/arm64/LOpcodes-arm64.h
Normal file
29
js/src/jit/arm64/LOpcodes-arm64.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef jit_arm64_LOpcodes_arm64_h
|
||||
#define jit_arm64_LOpcodes_arm64_h
|
||||
|
||||
#define LIR_CPU_OPCODE_LIST(_) \
|
||||
_(Unbox) \
|
||||
_(UnboxFloatingPoint) \
|
||||
_(Box) \
|
||||
_(DivI) \
|
||||
_(SoftDivI) \
|
||||
_(DivPowTwoI) \
|
||||
_(ModI) \
|
||||
_(SoftModI) \
|
||||
_(ModPowTwoI) \
|
||||
_(ModMaskI) \
|
||||
_(PowHalfD) \
|
||||
_(AsmJSUInt32ToDouble) \
|
||||
_(AsmJSUInt32ToFloat32) \
|
||||
_(UDiv) \
|
||||
_(UMod) \
|
||||
_(SoftUDivOrMod) \
|
||||
_(AsmJSLoadFuncPtr)
|
||||
|
||||
#endif /* jit_arm64_LOpcodes_arm64_h */
|
321
js/src/jit/arm64/Lowering-arm64.cpp
Normal file
321
js/src/jit/arm64/Lowering-arm64.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
/* -*- 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 "mozilla/MathAlgorithms.h"
|
||||
|
||||
#include "jit/arm64/Assembler-arm64.h"
|
||||
#include "jit/Lowering.h"
|
||||
#include "jit/MIR.h"
|
||||
|
||||
#include "jit/shared/Lowering-shared-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::FloorLog2;
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::useBox(LInstruction* lir, size_t n, MDefinition* mir,
|
||||
LUse::Policy policy, bool useAtStart)
|
||||
{
|
||||
MOZ_CRASH("useBox");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register)
|
||||
{
|
||||
MOZ_CRASH("useBoxFixed");
|
||||
}
|
||||
|
||||
LAllocation
|
||||
LIRGeneratorARM64::useByteOpRegister(MDefinition* mir)
|
||||
{
|
||||
MOZ_CRASH("useByteOpRegister");
|
||||
}
|
||||
|
||||
LAllocation
|
||||
LIRGeneratorARM64::useByteOpRegisterOrNonDoubleConstant(MDefinition* mir)
|
||||
{
|
||||
MOZ_CRASH("useByteOpRegisterOrNonDoubleConstant");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerConstantDouble(double d, MInstruction* mir)
|
||||
{
|
||||
MOZ_CRASH("lowerConstantDouble");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerConstantFloat32(float d, MInstruction* mir)
|
||||
{
|
||||
MOZ_CRASH("lowerConstantFloat32");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitConstant(MConstant* ins)
|
||||
{
|
||||
MOZ_CRASH("visitConstant");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitBox(MBox* box)
|
||||
{
|
||||
MOZ_CRASH("visitBox");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitUnbox(MUnbox* unbox)
|
||||
{
|
||||
MOZ_CRASH("visitUnbox");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitReturn(MReturn* ret)
|
||||
{
|
||||
MOZ_CRASH("visitReturn");
|
||||
}
|
||||
|
||||
// x = !y
|
||||
void
|
||||
LIRGeneratorARM64::lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input)
|
||||
{
|
||||
MOZ_CRASH("lowerForALU");
|
||||
}
|
||||
|
||||
// z = x+y
|
||||
void
|
||||
LIRGeneratorARM64::lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
MOZ_CRASH("lowerForALU");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input)
|
||||
{
|
||||
MOZ_CRASH("lowerForFPU");
|
||||
}
|
||||
|
||||
template <size_t Temps>
|
||||
void
|
||||
LIRGeneratorARM64::lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
MOZ_CRASH("lowerForFPU");
|
||||
}
|
||||
|
||||
template void LIRGeneratorARM64::lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs);
|
||||
template void LIRGeneratorARM64::lowerForFPU(LInstructionHelper<1, 2, 1>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs);
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
|
||||
MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
MOZ_CRASH("lowerForBitAndAndBranch");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::defineUntypedPhi(MPhi* phi, size_t lirIndex)
|
||||
{
|
||||
MOZ_CRASH("defineUntypedPhi");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition,
|
||||
LBlock* block, size_t lirIndex)
|
||||
{
|
||||
MOZ_CRASH("lowerUntypedPhiInput");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerForShift(LInstructionHelper<1, 2, 0>* ins,
|
||||
MDefinition* mir, MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
MOZ_CRASH("lowerForShift");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerDivI(MDiv* div)
|
||||
{
|
||||
MOZ_CRASH("lowerDivI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
MOZ_CRASH("lowerMulI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerModI(MMod* mod)
|
||||
{
|
||||
MOZ_CRASH("lowerModI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitPowHalf(MPowHalf* ins)
|
||||
{
|
||||
MOZ_CRASH("visitPowHalf");
|
||||
}
|
||||
|
||||
LTableSwitch*
|
||||
LIRGeneratorARM64::newLTableSwitch(const LAllocation& in, const LDefinition& inputCopy,
|
||||
MTableSwitch* tableswitch)
|
||||
{
|
||||
MOZ_CRASH("newLTableSwitch");
|
||||
}
|
||||
|
||||
LTableSwitchV*
|
||||
LIRGeneratorARM64::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
{
|
||||
MOZ_CRASH("newLTableSwitchV");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_CRASH("visitGuardShape");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_CRASH("visitGuardObjectGroup");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerUrshD(MUrsh* mir)
|
||||
{
|
||||
MOZ_CRASH("lowerUrshD");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSNeg(MAsmJSNeg* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSNeg");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerUDiv(MDiv* div)
|
||||
{
|
||||
MOZ_CRASH("lowerUDiv");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerUMod(MMod* mod)
|
||||
{
|
||||
MOZ_CRASH("lowerUMod");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSUnsignedToDouble");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSUnsignedToFloat32");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadHeap");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSStoreHeap");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSLoadFuncPtr");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSCompareExchangeHeap");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
|
||||
{
|
||||
MOZ_CRASH("visitAsmJSAtomicBinopHeap");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerTruncateDToInt32(MTruncateToInt32* ins)
|
||||
{
|
||||
MOZ_CRASH("lowerTruncateDToInt32");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerTruncateFToInt32(MTruncateToInt32* ins)
|
||||
{
|
||||
MOZ_CRASH("lowerTruncateFToInt32");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSimdBinaryArith(MSimdBinaryArith* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSimdSelect(MSimdSelect* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSimdSplatX4(MSimdSplatX4* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSimdValueX4(MSimdValueX4* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSubstr(MSubstr* ins)
|
||||
{
|
||||
MOZ_CRASH("visitSubstr");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitRandom(MRandom* ins)
|
||||
{
|
||||
MOZ_CRASH("visitRandom");
|
||||
}
|
121
js/src/jit/arm64/Lowering-arm64.h
Normal file
121
js/src/jit/arm64/Lowering-arm64.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef jit_arm64_Lowering_arm64_h
|
||||
#define jit_arm64_Lowering_arm64_h
|
||||
|
||||
#include "jit/shared/Lowering-shared.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class LIRGeneratorARM64 : public LIRGeneratorShared
|
||||
{
|
||||
public:
|
||||
LIRGeneratorARM64(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
|
||||
: LIRGeneratorShared(gen, graph, lirGraph)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
// Adds a box input to an instruction, setting operand |n| to the type and
|
||||
// |n+1| to the payload.
|
||||
void useBox(LInstruction* lir, size_t n, MDefinition* mir,
|
||||
LUse::Policy policy = LUse::REGISTER, bool useAtStart = false);
|
||||
void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2);
|
||||
|
||||
LAllocation useByteOpRegister(MDefinition* mir);
|
||||
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition* mir);
|
||||
|
||||
inline LDefinition tempToUnbox() {
|
||||
return temp();
|
||||
}
|
||||
|
||||
bool needTempForPostBarrier() { return true; }
|
||||
|
||||
// ARM64 has a scratch register, so no need for another temp for dispatch ICs.
|
||||
LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) {
|
||||
return LDefinition::BogusTemp();
|
||||
}
|
||||
|
||||
void lowerUntypedPhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex);
|
||||
void defineUntypedPhi(MPhi* phi, size_t lirIndex);
|
||||
void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs,
|
||||
MDefinition* rhs);
|
||||
void lowerUrshD(MUrsh* mir);
|
||||
|
||||
void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input);
|
||||
void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs);
|
||||
|
||||
void lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input);
|
||||
|
||||
template <size_t Temps>
|
||||
void lowerForFPU(LInstructionHelper<1, 2, Temps>* ins, MDefinition* mir,
|
||||
MDefinition* lhs, MDefinition* rhs);
|
||||
|
||||
void lowerForCompIx4(LSimdBinaryCompIx4* ins, MSimdBinaryComp* mir,
|
||||
MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
return lowerForFPU(ins, mir, lhs, rhs);
|
||||
}
|
||||
|
||||
void lowerForCompFx4(LSimdBinaryCompFx4* ins, MSimdBinaryComp* mir,
|
||||
MDefinition* lhs, MDefinition* rhs)
|
||||
{
|
||||
return lowerForFPU(ins, mir, lhs, rhs);
|
||||
}
|
||||
|
||||
void lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir,
|
||||
MDefinition* lhs, MDefinition* rhs);
|
||||
void lowerConstantDouble(double d, MInstruction* ins);
|
||||
void lowerConstantFloat32(float d, MInstruction* ins);
|
||||
void lowerTruncateDToInt32(MTruncateToInt32* ins);
|
||||
void lowerTruncateFToInt32(MTruncateToInt32* ins);
|
||||
void lowerDivI(MDiv* div);
|
||||
void lowerModI(MMod* mod);
|
||||
void lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs);
|
||||
void lowerUDiv(MDiv* div);
|
||||
void lowerUMod(MMod* mod);
|
||||
void visitPowHalf(MPowHalf* ins);
|
||||
void visitAsmJSNeg(MAsmJSNeg* ins);
|
||||
|
||||
LTableSwitchV* newLTableSwitchV(MTableSwitch* ins);
|
||||
LTableSwitch* newLTableSwitch(const LAllocation& in,
|
||||
const LDefinition& inputCopy,
|
||||
MTableSwitch* ins);
|
||||
|
||||
public:
|
||||
void visitConstant(MConstant* ins);
|
||||
void visitBox(MBox* box);
|
||||
void visitUnbox(MUnbox* unbox);
|
||||
void visitReturn(MReturn* ret);
|
||||
void lowerPhi(MPhi* phi);
|
||||
void visitGuardShape(MGuardShape* ins);
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins);
|
||||
void visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble* ins);
|
||||
void visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32* ins);
|
||||
void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins);
|
||||
void visitAsmJSStoreHeap(MAsmJSStoreHeap* ins);
|
||||
void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr* ins);
|
||||
void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins);
|
||||
void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins);
|
||||
void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic* ins);
|
||||
void visitSimdBinaryArith(MSimdBinaryArith* ins);
|
||||
void visitSimdSelect(MSimdSelect* ins);
|
||||
void visitSimdSplatX4(MSimdSplatX4* ins);
|
||||
void visitSimdValueX4(MSimdValueX4* ins);
|
||||
void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement* ins);
|
||||
void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins);
|
||||
void visitSubstr(MSubstr* ins);
|
||||
void visitRandom(MRandom* ins);
|
||||
};
|
||||
|
||||
typedef LIRGeneratorARM64 LIRGeneratorSpecific;
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_arm64_Lowering_arm64_h */
|
Loading…
Reference in New Issue
Block a user