| /* -*- 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::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::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"); |
| } |
| |
| 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"); |
| } |
| |
| 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); |
| } |
| } |
| |