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