1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "jit/arm64/CodeGenerator-arm64.h"
8 
9 #include "mozilla/MathAlgorithms.h"
10 
11 #include "jscntxt.h"
12 #include "jscompartment.h"
13 #include "jsnum.h"
14 
15 #include "jit/CodeGenerator.h"
16 #include "jit/JitCompartment.h"
17 #include "jit/JitFrames.h"
18 #include "jit/MIR.h"
19 #include "jit/MIRGraph.h"
20 #include "vm/Shape.h"
21 #include "vm/TraceLogging.h"
22 
23 #include "jsscriptinlines.h"
24 
25 #include "jit/shared/CodeGenerator-shared-inl.h"
26 
27 using namespace js;
28 using namespace js::jit;
29 
30 using mozilla::FloorLog2;
31 using mozilla::NegativeInfinity;
32 using JS::GenericNaN;
33 
34 // shared
CodeGeneratorARM64(MIRGenerator * gen,LIRGraph * graph,MacroAssembler * masm)35 CodeGeneratorARM64::CodeGeneratorARM64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm)
36   : CodeGeneratorShared(gen, graph, masm)
37 {
38 }
39 
40 bool
generateOutOfLineCode()41 CodeGeneratorARM64::generateOutOfLineCode()
42 {
43     MOZ_CRASH("generateOutOfLineCode");
44 }
45 
46 void
emitBranch(Assembler::Condition cond,MBasicBlock * mirTrue,MBasicBlock * mirFalse)47 CodeGeneratorARM64::emitBranch(Assembler::Condition cond, MBasicBlock* mirTrue, MBasicBlock* mirFalse)
48 {
49     MOZ_CRASH("emitBranch");
50 }
51 
52 void
accept(CodeGeneratorARM64 * codegen)53 OutOfLineBailout::accept(CodeGeneratorARM64* codegen)
54 {
55     MOZ_CRASH("accept");
56 }
57 
58 void
visitTestIAndBranch(LTestIAndBranch * test)59 CodeGeneratorARM64::visitTestIAndBranch(LTestIAndBranch* test)
60 {
61     MOZ_CRASH("visitTestIAndBranch");
62 }
63 
64 void
visitCompare(LCompare * comp)65 CodeGeneratorARM64::visitCompare(LCompare* comp)
66 {
67     MOZ_CRASH("visitCompare");
68 }
69 
70 void
visitCompareAndBranch(LCompareAndBranch * comp)71 CodeGeneratorARM64::visitCompareAndBranch(LCompareAndBranch* comp)
72 {
73     MOZ_CRASH("visitCompareAndBranch");
74 }
75 
76 void
bailoutIf(Assembler::Condition condition,LSnapshot * snapshot)77 CodeGeneratorARM64::bailoutIf(Assembler::Condition condition, LSnapshot* snapshot)
78 {
79     MOZ_CRASH("bailoutIf");
80 }
81 
82 void
bailoutFrom(Label * label,LSnapshot * snapshot)83 CodeGeneratorARM64::bailoutFrom(Label* label, LSnapshot* snapshot)
84 {
85     MOZ_CRASH("bailoutFrom");
86 }
87 
88 void
bailout(LSnapshot * snapshot)89 CodeGeneratorARM64::bailout(LSnapshot* snapshot)
90 {
91     MOZ_CRASH("bailout");
92 }
93 
94 void
visitOutOfLineBailout(OutOfLineBailout * ool)95 CodeGeneratorARM64::visitOutOfLineBailout(OutOfLineBailout* ool)
96 {
97     MOZ_CRASH("visitOutOfLineBailout");
98 }
99 
100 void
visitMinMaxD(LMinMaxD * ins)101 CodeGeneratorARM64::visitMinMaxD(LMinMaxD* ins)
102 {
103     MOZ_CRASH("visitMinMaxD");
104 }
105 
106 void
visitMinMaxF(LMinMaxF * ins)107 CodeGeneratorARM64::visitMinMaxF(LMinMaxF* ins)
108 {
109     MOZ_CRASH("visitMinMaxF");
110 }
111 
112 void
visitAbsD(LAbsD * ins)113 CodeGeneratorARM64::visitAbsD(LAbsD* ins)
114 {
115     MOZ_CRASH("visitAbsD");
116 }
117 
118 void
visitAbsF(LAbsF * ins)119 CodeGeneratorARM64::visitAbsF(LAbsF* ins)
120 {
121     MOZ_CRASH("visitAbsF");
122 }
123 
124 void
visitSqrtD(LSqrtD * ins)125 CodeGeneratorARM64::visitSqrtD(LSqrtD* ins)
126 {
127     MOZ_CRASH("visitSqrtD");
128 }
129 
130 void
visitSqrtF(LSqrtF * ins)131 CodeGeneratorARM64::visitSqrtF(LSqrtF* ins)
132 {
133     MOZ_CRASH("visitSqrtF");
134 }
135 
136 // FIXME: Uh, is this a static function? It looks like it is...
137 template <typename T>
138 ARMRegister
toWRegister(const T * a)139 toWRegister(const T* a)
140 {
141     return ARMRegister(ToRegister(a), 32);
142 }
143 
144 // FIXME: Uh, is this a static function? It looks like it is...
145 template <typename T>
146 ARMRegister
toXRegister(const T * a)147 toXRegister(const T* a)
148 {
149     return ARMRegister(ToRegister(a), 64);
150 }
151 
152 js::jit::Operand
toWOperand(const LAllocation * a)153 toWOperand(const LAllocation* a)
154 {
155     MOZ_CRASH("toWOperand");
156 }
157 
158 vixl::CPURegister
ToCPURegister(const LAllocation * a,Scalar::Type type)159 ToCPURegister(const LAllocation* a, Scalar::Type type)
160 {
161     MOZ_CRASH("ToCPURegister");
162 }
163 
164 vixl::CPURegister
ToCPURegister(const LDefinition * d,Scalar::Type type)165 ToCPURegister(const LDefinition* d, Scalar::Type type)
166 {
167     return ToCPURegister(d->output(), type);
168 }
169 
170 void
visitAddI(LAddI * ins)171 CodeGeneratorARM64::visitAddI(LAddI* ins)
172 {
173     MOZ_CRASH("visitAddI");
174 }
175 
176 void
visitSubI(LSubI * ins)177 CodeGeneratorARM64::visitSubI(LSubI* ins)
178 {
179     MOZ_CRASH("visitSubI");
180 }
181 
182 void
visitMulI(LMulI * ins)183 CodeGeneratorARM64::visitMulI(LMulI* ins)
184 {
185     MOZ_CRASH("visitMulI");
186 }
187 
188 
189 void
visitDivI(LDivI * ins)190 CodeGeneratorARM64::visitDivI(LDivI* ins)
191 {
192     MOZ_CRASH("visitDivI");
193 }
194 
195 void
visitDivPowTwoI(LDivPowTwoI * ins)196 CodeGeneratorARM64::visitDivPowTwoI(LDivPowTwoI* ins)
197 {
198     MOZ_CRASH("CodeGeneratorARM64::visitDivPowTwoI");
199 }
200 
201 void
modICommon(MMod * mir,Register lhs,Register rhs,Register output,LSnapshot * snapshot,Label & done)202 CodeGeneratorARM64::modICommon(MMod* mir, Register lhs, Register rhs, Register output,
203                                LSnapshot* snapshot, Label& done)
204 {
205     MOZ_CRASH("CodeGeneratorARM64::modICommon");
206 }
207 
208 void
visitModI(LModI * ins)209 CodeGeneratorARM64::visitModI(LModI* ins)
210 {
211     MOZ_CRASH("visitModI");
212 }
213 
214 void
visitModPowTwoI(LModPowTwoI * ins)215 CodeGeneratorARM64::visitModPowTwoI(LModPowTwoI* ins)
216 {
217     MOZ_CRASH("visitModPowTwoI");
218 }
219 
220 void
visitModMaskI(LModMaskI * ins)221 CodeGeneratorARM64::visitModMaskI(LModMaskI* ins)
222 {
223     MOZ_CRASH("CodeGeneratorARM64::visitModMaskI");
224 }
225 
226 void
visitBitNotI(LBitNotI * ins)227 CodeGeneratorARM64::visitBitNotI(LBitNotI* ins)
228 {
229     MOZ_CRASH("visitBitNotI");
230 }
231 
232 void
visitBitOpI(LBitOpI * ins)233 CodeGeneratorARM64::visitBitOpI(LBitOpI* ins)
234 {
235     MOZ_CRASH("visitBitOpI");
236 }
237 
238 void
visitShiftI(LShiftI * ins)239 CodeGeneratorARM64::visitShiftI(LShiftI* ins)
240 {
241     MOZ_CRASH("visitShiftI");
242 }
243 
244 void
visitUrshD(LUrshD * ins)245 CodeGeneratorARM64::visitUrshD(LUrshD* ins)
246 {
247     MOZ_CRASH("visitUrshD");
248 }
249 
250 void
visitPowHalfD(LPowHalfD * ins)251 CodeGeneratorARM64::visitPowHalfD(LPowHalfD* ins)
252 {
253     MOZ_CRASH("visitPowHalfD");
254 }
255 
256 MoveOperand
toMoveOperand(const LAllocation a) const257 CodeGeneratorARM64::toMoveOperand(const LAllocation a) const
258 {
259     MOZ_CRASH("toMoveOperand");
260 }
261 
262 class js::jit::OutOfLineTableSwitch : public OutOfLineCodeBase<CodeGeneratorARM64>
263 {
264     MTableSwitch* mir_;
265     Vector<CodeLabel, 8, JitAllocPolicy> codeLabels_;
266 
accept(CodeGeneratorARM64 * codegen)267     void accept(CodeGeneratorARM64* codegen) {
268         codegen->visitOutOfLineTableSwitch(this);
269     }
270 
271   public:
OutOfLineTableSwitch(TempAllocator & alloc,MTableSwitch * mir)272     OutOfLineTableSwitch(TempAllocator& alloc, MTableSwitch* mir)
273       : mir_(mir),
274         codeLabels_(alloc)
275     { }
276 
mir() const277     MTableSwitch* mir() const {
278         return mir_;
279     }
280 
addCodeLabel(CodeLabel label)281     bool addCodeLabel(CodeLabel label) {
282         return codeLabels_.append(label);
283     }
codeLabel(unsigned i)284     CodeLabel codeLabel(unsigned i) {
285         return codeLabels_[i];
286     }
287 };
288 
289 void
visitOutOfLineTableSwitch(OutOfLineTableSwitch * ool)290 CodeGeneratorARM64::visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool)
291 {
292     MOZ_CRASH("visitOutOfLineTableSwitch");
293 }
294 
295 void
emitTableSwitchDispatch(MTableSwitch * mir,Register index_,Register base_)296 CodeGeneratorARM64::emitTableSwitchDispatch(MTableSwitch* mir, Register index_, Register base_)
297 {
298     MOZ_CRASH("emitTableSwitchDispatch");
299 }
300 
301 void
visitMathD(LMathD * math)302 CodeGeneratorARM64::visitMathD(LMathD* math)
303 {
304     MOZ_CRASH("visitMathD");
305 }
306 
307 void
visitMathF(LMathF * math)308 CodeGeneratorARM64::visitMathF(LMathF* math)
309 {
310     MOZ_CRASH("visitMathF");
311 }
312 
313 void
visitFloor(LFloor * lir)314 CodeGeneratorARM64::visitFloor(LFloor* lir)
315 {
316     MOZ_CRASH("visitFloor");
317 }
318 
319 void
visitFloorF(LFloorF * lir)320 CodeGeneratorARM64::visitFloorF(LFloorF* lir)
321 {
322     MOZ_CRASH("visitFloorF");
323 }
324 
325 void
visitCeil(LCeil * lir)326 CodeGeneratorARM64::visitCeil(LCeil* lir)
327 {
328     MOZ_CRASH("visitCeil");
329 }
330 
331 void
visitCeilF(LCeilF * lir)332 CodeGeneratorARM64::visitCeilF(LCeilF* lir)
333 {
334     MOZ_CRASH("visitCeilF");
335 }
336 
337 void
visitRound(LRound * lir)338 CodeGeneratorARM64::visitRound(LRound* lir)
339 {
340     MOZ_CRASH("visitRound");
341 }
342 
343 void
visitRoundF(LRoundF * lir)344 CodeGeneratorARM64::visitRoundF(LRoundF* lir)
345 {
346     MOZ_CRASH("visitRoundF");
347 }
348 
349 void
visitClzI(LClzI * lir)350 CodeGeneratorARM64::visitClzI(LClzI* lir)
351 {
352     MOZ_CRASH("visitClzI");
353 }
354 
355 void
visitCtzI(LCtzI * lir)356 CodeGeneratorARM64::visitCtzI(LCtzI* lir)
357 {
358     MOZ_CRASH("visitCtzI");
359 }
360 
361 void
emitRoundDouble(FloatRegister src,Register dest,Label * fail)362 CodeGeneratorARM64::emitRoundDouble(FloatRegister src, Register dest, Label* fail)
363 {
364     MOZ_CRASH("CodeGeneratorARM64::emitRoundDouble");
365 }
366 
367 void
visitTruncateDToInt32(LTruncateDToInt32 * ins)368 CodeGeneratorARM64::visitTruncateDToInt32(LTruncateDToInt32* ins)
369 {
370     MOZ_CRASH("visitTruncateDToInt32");
371 }
372 
373 void
visitTruncateFToInt32(LTruncateFToInt32 * ins)374 CodeGeneratorARM64::visitTruncateFToInt32(LTruncateFToInt32* ins)
375 {
376     MOZ_CRASH("visitTruncateFToInt32");
377 }
378 
379 static const uint32_t FrameSizes[] = { 128, 256, 512, 1024 };
380 
381 FrameSizeClass
FromDepth(uint32_t frameDepth)382 FrameSizeClass::FromDepth(uint32_t frameDepth)
383 {
384     return FrameSizeClass::None();
385 }
386 
387 FrameSizeClass
ClassLimit()388 FrameSizeClass::ClassLimit()
389 {
390     return FrameSizeClass(0);
391 }
392 
393 uint32_t
frameSize() const394 FrameSizeClass::frameSize() const
395 {
396     MOZ_CRASH("arm64 does not use frame size classes");
397 }
398 
399 ValueOperand
ToValue(LInstruction * ins,size_t pos)400 CodeGeneratorARM64::ToValue(LInstruction* ins, size_t pos)
401 {
402     return ValueOperand(ToRegister(ins->getOperand(pos)));
403 }
404 
405 ValueOperand
ToOutValue(LInstruction * ins)406 CodeGeneratorARM64::ToOutValue(LInstruction* ins)
407 {
408     Register payloadReg = ToRegister(ins->getDef(0));
409     return ValueOperand(payloadReg);
410 }
411 
412 ValueOperand
ToTempValue(LInstruction * ins,size_t pos)413 CodeGeneratorARM64::ToTempValue(LInstruction* ins, size_t pos)
414 {
415     MOZ_CRASH("CodeGeneratorARM64::ToTempValue");
416 }
417 
418 void
visitValue(LValue * value)419 CodeGeneratorARM64::visitValue(LValue* value)
420 {
421     MOZ_CRASH("visitValue");
422 }
423 
424 void
visitBox(LBox * box)425 CodeGeneratorARM64::visitBox(LBox* box)
426 {
427     MOZ_CRASH("visitBox");
428 }
429 
430 void
visitUnbox(LUnbox * unbox)431 CodeGeneratorARM64::visitUnbox(LUnbox* unbox)
432 {
433     MOZ_CRASH("visitUnbox");
434 }
435 
436 void
visitDouble(LDouble * ins)437 CodeGeneratorARM64::visitDouble(LDouble* ins)
438 {
439     MOZ_CRASH("visitDouble");
440 }
441 
442 void
visitFloat32(LFloat32 * ins)443 CodeGeneratorARM64::visitFloat32(LFloat32* ins)
444 {
445     MOZ_CRASH("visitFloat32");
446 }
447 
448 Register
splitTagForTest(const ValueOperand & value)449 CodeGeneratorARM64::splitTagForTest(const ValueOperand& value)
450 {
451     MOZ_CRASH("splitTagForTest");
452 }
453 
454 void
visitTestDAndBranch(LTestDAndBranch * test)455 CodeGeneratorARM64::visitTestDAndBranch(LTestDAndBranch* test)
456 {
457     MOZ_CRASH("visitTestDAndBranch");
458 }
459 
460 void
visitTestFAndBranch(LTestFAndBranch * test)461 CodeGeneratorARM64::visitTestFAndBranch(LTestFAndBranch* test)
462 {
463     MOZ_CRASH("visitTestFAndBranch");
464 }
465 
466 void
visitCompareD(LCompareD * comp)467 CodeGeneratorARM64::visitCompareD(LCompareD* comp)
468 {
469     MOZ_CRASH("visitCompareD");
470 }
471 
472 void
visitCompareF(LCompareF * comp)473 CodeGeneratorARM64::visitCompareF(LCompareF* comp)
474 {
475     MOZ_CRASH("visitCompareF");
476 }
477 
478 void
visitCompareDAndBranch(LCompareDAndBranch * comp)479 CodeGeneratorARM64::visitCompareDAndBranch(LCompareDAndBranch* comp)
480 {
481     MOZ_CRASH("visitCompareDAndBranch");
482 }
483 
484 void
visitCompareFAndBranch(LCompareFAndBranch * comp)485 CodeGeneratorARM64::visitCompareFAndBranch(LCompareFAndBranch* comp)
486 {
487     MOZ_CRASH("visitCompareFAndBranch");
488 }
489 
490 void
visitCompareB(LCompareB * lir)491 CodeGeneratorARM64::visitCompareB(LCompareB* lir)
492 {
493     MOZ_CRASH("visitCompareB");
494 }
495 
496 void
visitCompareBAndBranch(LCompareBAndBranch * lir)497 CodeGeneratorARM64::visitCompareBAndBranch(LCompareBAndBranch* lir)
498 {
499     MOZ_CRASH("visitCompareBAndBranch");
500 }
501 
502 void
visitCompareBitwise(LCompareBitwise * lir)503 CodeGeneratorARM64::visitCompareBitwise(LCompareBitwise* lir)
504 {
505     MOZ_CRASH("visitCompareBitwise");
506 }
507 
508 void
visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch * lir)509 CodeGeneratorARM64::visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch* lir)
510 {
511     MOZ_CRASH("visitCompareBitwiseAndBranch");
512 }
513 
514 void
visitBitAndAndBranch(LBitAndAndBranch * baab)515 CodeGeneratorARM64::visitBitAndAndBranch(LBitAndAndBranch* baab)
516 {
517     MOZ_CRASH("visitBitAndAndBranch");
518 }
519 
520 void
visitWasmUint32ToDouble(LWasmUint32ToDouble * lir)521 CodeGeneratorARM64::visitWasmUint32ToDouble(LWasmUint32ToDouble* lir)
522 {
523     MOZ_CRASH("visitWasmUint32ToDouble");
524 }
525 
526 void
visitWasmUint32ToFloat32(LWasmUint32ToFloat32 * lir)527 CodeGeneratorARM64::visitWasmUint32ToFloat32(LWasmUint32ToFloat32* lir)
528 {
529     MOZ_CRASH("visitWasmUint32ToFloat32");
530 }
531 
532 void
visitNotI(LNotI * ins)533 CodeGeneratorARM64::visitNotI(LNotI* ins)
534 {
535     MOZ_CRASH("visitNotI");
536 }
537 
538 //        NZCV
539 // NAN -> 0011
540 // ==  -> 0110
541 // <   -> 1000
542 // >   -> 0010
543 void
visitNotD(LNotD * ins)544 CodeGeneratorARM64::visitNotD(LNotD* ins)
545 {
546     MOZ_CRASH("visitNotD");
547 }
548 
549 void
visitNotF(LNotF * ins)550 CodeGeneratorARM64::visitNotF(LNotF* ins)
551 {
552     MOZ_CRASH("visitNotF");
553 }
554 
555 void
visitLoadSlotV(LLoadSlotV * load)556 CodeGeneratorARM64::visitLoadSlotV(LLoadSlotV* load)
557 {
558     MOZ_CRASH("CodeGeneratorARM64::visitLoadSlotV");
559 }
560 
561 void
visitLoadSlotT(LLoadSlotT * load)562 CodeGeneratorARM64::visitLoadSlotT(LLoadSlotT* load)
563 {
564     MOZ_CRASH("CodeGeneratorARM64::visitLoadSlotT");
565 }
566 
567 void
visitStoreSlotT(LStoreSlotT * store)568 CodeGeneratorARM64::visitStoreSlotT(LStoreSlotT* store)
569 {
570     MOZ_CRASH("CodeGeneratorARM64::visitStoreSlotT");
571 }
572 
573 void
visitLoadElementT(LLoadElementT * load)574 CodeGeneratorARM64::visitLoadElementT(LLoadElementT* load)
575 {
576     MOZ_CRASH("CodeGeneratorARM64::visitLoadElementT");
577 }
578 
579 void
storeElementTyped(const LAllocation * value,MIRType valueType,MIRType elementType,Register elements,const LAllocation * index)580 CodeGeneratorARM64::storeElementTyped(const LAllocation* value, MIRType valueType,
581                                       MIRType elementType, Register elements,
582                                       const LAllocation* index)
583 {
584     MOZ_CRASH("CodeGeneratorARM64::storeElementTyped");
585 }
586 
587 void
visitGuardShape(LGuardShape * guard)588 CodeGeneratorARM64::visitGuardShape(LGuardShape* guard)
589 {
590     MOZ_CRASH("visitGuardShape");
591 }
592 
593 void
visitGuardObjectGroup(LGuardObjectGroup * guard)594 CodeGeneratorARM64::visitGuardObjectGroup(LGuardObjectGroup* guard)
595 {
596     MOZ_CRASH("visitGuardObjectGroup");
597 }
598 
599 void
visitGuardClass(LGuardClass * guard)600 CodeGeneratorARM64::visitGuardClass(LGuardClass* guard)
601 {
602     MOZ_CRASH("CodeGeneratorARM64::visitGuardClass");
603 }
604 
605 void
visitInterruptCheck(LInterruptCheck * lir)606 CodeGeneratorARM64::visitInterruptCheck(LInterruptCheck* lir)
607 {
608     MOZ_CRASH("CodeGeneratorARM64::visitInterruptCheck");
609 }
610 
611 void
generateInvalidateEpilogue()612 CodeGeneratorARM64::generateInvalidateEpilogue()
613 {
614     MOZ_CRASH("generateInvalidateEpilogue");
615 }
616 
617 template <class U>
618 Register
getBase(U * mir)619 getBase(U* mir)
620 {
621     switch (mir->base()) {
622       case U::Heap: return HeapReg;
623       case U::Global: return GlobalReg;
624     }
625     return InvalidReg;
626 }
627 
628 void
visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic * ins)629 CodeGeneratorARM64::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins)
630 {
631     MOZ_CRASH("CodeGeneratorARM64::visitLoadTypedArrayElementStatic");
632 }
633 
634 void
visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic * ins)635 CodeGeneratorARM64::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic* ins)
636 {
637     MOZ_CRASH("CodeGeneratorARM64::visitStoreTypedArrayElementStatic");
638 }
639 
640 void
visitWasmCall(LWasmCall * ins)641 CodeGeneratorARM64::visitWasmCall(LWasmCall* ins)
642 {
643     MOZ_CRASH("vistWasmCall");
644 }
645 
646 void
visitWasmCallI64(LWasmCallI64 * ins)647 CodeGeneratorARM64::visitWasmCallI64(LWasmCallI64* ins)
648 {
649     MOZ_CRASH("vistWasmCallI64");
650 }
651 
652 void
visitAsmJSLoadHeap(LAsmJSLoadHeap * ins)653 CodeGeneratorARM64::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins)
654 {
655     MOZ_CRASH("visitAsmJSLoadHeap");
656 }
657 
658 void
visitAsmJSStoreHeap(LAsmJSStoreHeap * ins)659 CodeGeneratorARM64::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins)
660 {
661     MOZ_CRASH("visitAsmJSStoreHeap");
662 }
663 
664 void
visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap * ins)665 CodeGeneratorARM64::visitAsmJSCompareExchangeHeap(LAsmJSCompareExchangeHeap* ins)
666 {
667     MOZ_CRASH("visitAsmJSCompareExchangeHeap");
668 }
669 
670 void
visitAsmJSAtomicBinopHeap(LAsmJSAtomicBinopHeap * ins)671 CodeGeneratorARM64::visitAsmJSAtomicBinopHeap(LAsmJSAtomicBinopHeap* ins)
672 {
673     MOZ_CRASH("visitAsmJSAtomicBinopHeap");
674 }
675 
676 void
visitWasmStackArg(LWasmStackArg * ins)677 CodeGeneratorARM64::visitWasmStackArg(LWasmStackArg* ins)
678 {
679     MOZ_CRASH("visitWasmStackArg");
680 }
681 
682 void
visitUDiv(LUDiv * ins)683 CodeGeneratorARM64::visitUDiv(LUDiv* ins)
684 {
685     MOZ_CRASH("visitUDiv");
686 }
687 
688 void
visitUMod(LUMod * ins)689 CodeGeneratorARM64::visitUMod(LUMod* ins)
690 {
691     MOZ_CRASH("visitUMod");
692 }
693 
694 void
visitEffectiveAddress(LEffectiveAddress * ins)695 CodeGeneratorARM64::visitEffectiveAddress(LEffectiveAddress* ins)
696 {
697     MOZ_CRASH("visitEffectiveAddress");
698 }
699 
700 void
visitWasmLoadGlobalVar(LWasmLoadGlobalVar * ins)701 CodeGeneratorARM64::visitWasmLoadGlobalVar(LWasmLoadGlobalVar* ins)
702 {
703     MOZ_CRASH("visitWasmLoadGlobalVar");
704 }
705 
706 void
visitWasmStoreGlobalVar(LWasmStoreGlobalVar * ins)707 CodeGeneratorARM64::visitWasmStoreGlobalVar(LWasmStoreGlobalVar* ins)
708 {
709     MOZ_CRASH("visitWasmStoreGlobalVar");
710 }
711 
712 void
visitNegI(LNegI * ins)713 CodeGeneratorARM64::visitNegI(LNegI* ins)
714 {
715     MOZ_CRASH("visitNegI");
716 }
717 
718 void
visitNegD(LNegD * ins)719 CodeGeneratorARM64::visitNegD(LNegD* ins)
720 {
721     MOZ_CRASH("visitNegD");
722 }
723 
724 void
visitNegF(LNegF * ins)725 CodeGeneratorARM64::visitNegF(LNegF* ins)
726 {
727     MOZ_CRASH("visitNegF");
728 }
729 
730 void
setReturnDoubleRegs(LiveRegisterSet * regs)731 CodeGeneratorARM64::setReturnDoubleRegs(LiveRegisterSet* regs)
732 {
733     MOZ_ASSERT(ReturnFloat32Reg.code_ == FloatRegisters::s0);
734     MOZ_ASSERT(ReturnDoubleReg.code_ == FloatRegisters::d0);
735     FloatRegister s1 = {FloatRegisters::s1, FloatRegisters::Single};
736     regs->add(ReturnFloat32Reg);
737     regs->add(s1);
738     regs->add(ReturnDoubleReg);
739 }
740 
741 void
visitCompareExchangeTypedArrayElement(LCompareExchangeTypedArrayElement * lir)742 CodeGeneratorARM64::visitCompareExchangeTypedArrayElement(LCompareExchangeTypedArrayElement* lir)
743 {
744     Register elements = ToRegister(lir->elements());
745     AnyRegister output = ToAnyRegister(lir->output());
746     Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp());
747 
748     Register oldval = ToRegister(lir->oldval());
749     Register newval = ToRegister(lir->newval());
750 
751     Scalar::Type arrayType = lir->mir()->arrayType();
752     int width = Scalar::byteSize(arrayType);
753 
754     if (lir->index()->isConstant()) {
755         Address dest(elements, ToInt32(lir->index()) * width);
756         masm.compareExchangeToTypedIntArray(arrayType, dest, oldval, newval, temp, output);
757     } else {
758         BaseIndex dest(elements, ToRegister(lir->index()), ScaleFromElemWidth(width));
759         masm.compareExchangeToTypedIntArray(arrayType, dest, oldval, newval, temp, output);
760     }
761 }
762 
763 void
visitAtomicExchangeTypedArrayElement(LAtomicExchangeTypedArrayElement * lir)764 CodeGeneratorARM64::visitAtomicExchangeTypedArrayElement(LAtomicExchangeTypedArrayElement* lir)
765 {
766     Register elements = ToRegister(lir->elements());
767     AnyRegister output = ToAnyRegister(lir->output());
768     Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp());
769 
770     Register value = ToRegister(lir->value());
771 
772     Scalar::Type arrayType = lir->mir()->arrayType();
773     int width = Scalar::byteSize(arrayType);
774 
775     if (lir->index()->isConstant()) {
776         Address dest(elements, ToInt32(lir->index()) * width);
777         masm.atomicExchangeToTypedIntArray(arrayType, dest, value, temp, output);
778     } else {
779         BaseIndex dest(elements, ToRegister(lir->index()), ScaleFromElemWidth(width));
780         masm.atomicExchangeToTypedIntArray(arrayType, dest, value, temp, output);
781     }
782 }
783 
784