diff options
Diffstat (limited to 'js/src/jit/arm64/CodeGenerator-arm64.cpp')
-rw-r--r-- | js/src/jit/arm64/CodeGenerator-arm64.cpp | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/js/src/jit/arm64/CodeGenerator-arm64.cpp b/js/src/jit/arm64/CodeGenerator-arm64.cpp new file mode 100644 index 000000000..83330a262 --- /dev/null +++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp @@ -0,0 +1,783 @@ +/* -*- 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::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::visitCtzI(LCtzI* lir) +{ + MOZ_CRASH("visitCtzI"); +} + +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::visitCompareBitwise(LCompareBitwise* lir) +{ + MOZ_CRASH("visitCompareBitwise"); +} + +void +CodeGeneratorARM64::visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch* lir) +{ + MOZ_CRASH("visitCompareBitwiseAndBranch"); +} + +void +CodeGeneratorARM64::visitBitAndAndBranch(LBitAndAndBranch* baab) +{ + MOZ_CRASH("visitBitAndAndBranch"); +} + +void +CodeGeneratorARM64::visitWasmUint32ToDouble(LWasmUint32ToDouble* lir) +{ + MOZ_CRASH("visitWasmUint32ToDouble"); +} + +void +CodeGeneratorARM64::visitWasmUint32ToFloat32(LWasmUint32ToFloat32* lir) +{ + MOZ_CRASH("visitWasmUint32ToFloat32"); +} + +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"); +} + +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::visitWasmCall(LWasmCall* ins) +{ + MOZ_CRASH("vistWasmCall"); +} + +void +CodeGeneratorARM64::visitWasmCallI64(LWasmCallI64* ins) +{ + MOZ_CRASH("vistWasmCallI64"); +} + +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::visitWasmStackArg(LWasmStackArg* ins) +{ + MOZ_CRASH("visitWasmStackArg"); +} + +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::visitWasmLoadGlobalVar(LWasmLoadGlobalVar* ins) +{ + MOZ_CRASH("visitWasmLoadGlobalVar"); +} + +void +CodeGeneratorARM64::visitWasmStoreGlobalVar(LWasmStoreGlobalVar* ins) +{ + MOZ_CRASH("visitWasmStoreGlobalVar"); +} + +void +CodeGeneratorARM64::visitNegI(LNegI* ins) +{ + MOZ_CRASH("visitNegI"); +} + +void +CodeGeneratorARM64::visitNegD(LNegD* ins) +{ + MOZ_CRASH("visitNegD"); +} + +void +CodeGeneratorARM64::visitNegF(LNegF* ins) +{ + MOZ_CRASH("visitNegF"); +} + +void +CodeGeneratorARM64::setReturnDoubleRegs(LiveRegisterSet* regs) +{ + MOZ_ASSERT(ReturnFloat32Reg.code_ == FloatRegisters::s0); + MOZ_ASSERT(ReturnDoubleReg.code_ == FloatRegisters::d0); + FloatRegister s1 = {FloatRegisters::s1, FloatRegisters::Single}; + regs->add(ReturnFloat32Reg); + regs->add(s1); + regs->add(ReturnDoubleReg); +} + +void +CodeGeneratorARM64::visitCompareExchangeTypedArrayElement(LCompareExchangeTypedArrayElement* lir) +{ + Register elements = ToRegister(lir->elements()); + AnyRegister output = ToAnyRegister(lir->output()); + Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp()); + + Register oldval = ToRegister(lir->oldval()); + Register newval = ToRegister(lir->newval()); + + Scalar::Type arrayType = lir->mir()->arrayType(); + int width = Scalar::byteSize(arrayType); + + if (lir->index()->isConstant()) { + Address dest(elements, ToInt32(lir->index()) * width); + masm.compareExchangeToTypedIntArray(arrayType, dest, oldval, newval, temp, output); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), ScaleFromElemWidth(width)); + masm.compareExchangeToTypedIntArray(arrayType, dest, oldval, newval, temp, output); + } +} + +void +CodeGeneratorARM64::visitAtomicExchangeTypedArrayElement(LAtomicExchangeTypedArrayElement* lir) +{ + Register elements = ToRegister(lir->elements()); + AnyRegister output = ToAnyRegister(lir->output()); + Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp()); + + Register value = ToRegister(lir->value()); + + Scalar::Type arrayType = lir->mir()->arrayType(); + int width = Scalar::byteSize(arrayType); + + if (lir->index()->isConstant()) { + Address dest(elements, ToInt32(lir->index()) * width); + masm.atomicExchangeToTypedIntArray(arrayType, dest, value, temp, output); + } else { + BaseIndex dest(elements, ToRegister(lir->index()), ScaleFromElemWidth(width)); + masm.atomicExchangeToTypedIntArray(arrayType, dest, value, temp, output); + } +} + |