1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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 #ifndef jit_shared_LIR_shared_h
8 #define jit_shared_LIR_shared_h
9 
10 #include "jit/AtomicOp.h"
11 #include "jit/shared/Assembler-shared.h"
12 #include "util/Memory.h"
13 
14 // This file declares LIR instructions that are common to every platform.
15 
16 namespace js {
17 namespace jit {
18 
19 class LBox : public LInstructionHelper<BOX_PIECES, 1, 0> {
20   MIRType type_;
21 
22  public:
23   LIR_HEADER(Box);
24 
LBox(const LAllocation & payload,MIRType type)25   LBox(const LAllocation& payload, MIRType type)
26       : LInstructionHelper(classOpcode), type_(type) {
27     setOperand(0, payload);
28   }
29 
type()30   MIRType type() const { return type_; }
extraName()31   const char* extraName() const { return StringFromMIRType(type_); }
32 };
33 
34 template <size_t Temps, size_t ExtraUses = 0>
35 class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps> {
36  protected:
LBinaryMath(LNode::Opcode opcode)37   explicit LBinaryMath(LNode::Opcode opcode)
38       : LInstructionHelper<1, 2 + ExtraUses, Temps>(opcode) {}
39 
40  public:
lhs()41   const LAllocation* lhs() { return this->getOperand(0); }
rhs()42   const LAllocation* rhs() { return this->getOperand(1); }
43 };
44 
45 template <size_t Temps, size_t ExtraUses = 0>
46 class LUnaryMath : public LInstructionHelper<1, 1 + ExtraUses, Temps> {
47  protected:
LUnaryMath(LNode::Opcode opcode)48   explicit LUnaryMath(LNode::Opcode opcode)
49       : LInstructionHelper<1, 1 + ExtraUses, Temps>(opcode) {}
50 
51  public:
input()52   const LAllocation* input() { return this->getOperand(0); }
53 };
54 
55 // An LOsiPoint captures a snapshot after a call and ensures enough space to
56 // patch in a call to the invalidation mechanism.
57 //
58 // Note: LSafepoints are 1:1 with LOsiPoints, so it holds a reference to the
59 // corresponding LSafepoint to inform it of the LOsiPoint's masm offset when it
60 // gets GC'd.
61 class LOsiPoint : public LInstructionHelper<0, 0, 0> {
62   LSafepoint* safepoint_;
63 
64  public:
LOsiPoint(LSafepoint * safepoint,LSnapshot * snapshot)65   LOsiPoint(LSafepoint* safepoint, LSnapshot* snapshot)
66       : LInstructionHelper(classOpcode), safepoint_(safepoint) {
67     MOZ_ASSERT(safepoint && snapshot);
68     assignSnapshot(snapshot);
69   }
70 
associatedSafepoint()71   LSafepoint* associatedSafepoint() { return safepoint_; }
72 
73   LIR_HEADER(OsiPoint)
74 };
75 
76 class LMove {
77   LAllocation from_;
78   LAllocation to_;
79   LDefinition::Type type_;
80 
81  public:
LMove(LAllocation from,LAllocation to,LDefinition::Type type)82   LMove(LAllocation from, LAllocation to, LDefinition::Type type)
83       : from_(from), to_(to), type_(type) {}
84 
from()85   LAllocation from() const { return from_; }
to()86   LAllocation to() const { return to_; }
type()87   LDefinition::Type type() const { return type_; }
88 };
89 
90 class LMoveGroup : public LInstructionHelper<0, 0, 0> {
91   js::Vector<LMove, 2, JitAllocPolicy> moves_;
92 
93 #ifdef JS_CODEGEN_X86
94   // Optional general register available for use when executing moves.
95   LAllocation scratchRegister_;
96 #endif
97 
LMoveGroup(TempAllocator & alloc)98   explicit LMoveGroup(TempAllocator& alloc)
99       : LInstructionHelper(classOpcode), moves_(alloc) {}
100 
101  public:
LIR_HEADER(MoveGroup)102   LIR_HEADER(MoveGroup)
103 
104   static LMoveGroup* New(TempAllocator& alloc) {
105     return new (alloc) LMoveGroup(alloc);
106   }
107 
108   void printOperands(GenericPrinter& out);
109 
110   // Add a move which takes place simultaneously with all others in the group.
111   bool add(LAllocation from, LAllocation to, LDefinition::Type type);
112 
113   // Add a move which takes place after existing moves in the group.
114   bool addAfter(LAllocation from, LAllocation to, LDefinition::Type type);
115 
numMoves()116   size_t numMoves() const { return moves_.length(); }
getMove(size_t i)117   const LMove& getMove(size_t i) const { return moves_[i]; }
118 
119 #ifdef JS_CODEGEN_X86
setScratchRegister(Register reg)120   void setScratchRegister(Register reg) { scratchRegister_ = LGeneralReg(reg); }
maybeScratchRegister()121   LAllocation maybeScratchRegister() { return scratchRegister_; }
122 #endif
123 
uses(Register reg)124   bool uses(Register reg) {
125     for (size_t i = 0; i < numMoves(); i++) {
126       LMove move = getMove(i);
127       if (move.from() == LGeneralReg(reg) || move.to() == LGeneralReg(reg)) {
128         return true;
129       }
130     }
131     return false;
132   }
133 };
134 
135 // Constant 32-bit integer.
136 class LInteger : public LInstructionHelper<1, 0, 0> {
137   int32_t i32_;
138 
139  public:
LIR_HEADER(Integer)140   LIR_HEADER(Integer)
141 
142   explicit LInteger(int32_t i32) : LInstructionHelper(classOpcode), i32_(i32) {}
143 
getValue()144   int32_t getValue() const { return i32_; }
145 };
146 
147 // Constant 64-bit integer.
148 class LInteger64 : public LInstructionHelper<INT64_PIECES, 0, 0> {
149   int64_t i64_;
150 
151  public:
LIR_HEADER(Integer64)152   LIR_HEADER(Integer64)
153 
154   explicit LInteger64(int64_t i64)
155       : LInstructionHelper(classOpcode), i64_(i64) {}
156 
getValue()157   int64_t getValue() const { return i64_; }
158 };
159 
160 // Constant pointer.
161 class LPointer : public LInstructionHelper<1, 0, 0> {
162   gc::Cell* ptr_;
163 
164  public:
LIR_HEADER(Pointer)165   LIR_HEADER(Pointer)
166 
167   explicit LPointer(gc::Cell* ptr)
168       : LInstructionHelper(classOpcode), ptr_(ptr) {}
169 
gcptr()170   gc::Cell* gcptr() const { return ptr_; }
171 };
172 
173 // Constant double.
174 class LDouble : public LInstructionHelper<1, 0, 0> {
175   double d_;
176 
177  public:
178   LIR_HEADER(Double);
179 
LDouble(double d)180   explicit LDouble(double d) : LInstructionHelper(classOpcode), d_(d) {}
181 
getDouble()182   const double& getDouble() const { return d_; }
183 };
184 
185 // Constant float32.
186 class LFloat32 : public LInstructionHelper<1, 0, 0> {
187   float f_;
188 
189  public:
190   LIR_HEADER(Float32);
191 
LFloat32(float f)192   explicit LFloat32(float f) : LInstructionHelper(classOpcode), f_(f) {}
193 
getFloat()194   const float& getFloat() const { return f_; }
195 };
196 
197 // A constant Value.
198 class LValue : public LInstructionHelper<BOX_PIECES, 0, 0> {
199   Value v_;
200 
201  public:
LIR_HEADER(Value)202   LIR_HEADER(Value)
203 
204   explicit LValue(const Value& v) : LInstructionHelper(classOpcode), v_(v) {}
205 
value()206   Value value() const { return v_; }
207 };
208 
209 class LNurseryObject : public LInstructionHelper<1, 0, 0> {
210  public:
211   LIR_HEADER(NurseryObject);
212 
LNurseryObject()213   LNurseryObject() : LInstructionHelper(classOpcode) {}
214 
mir()215   MNurseryObject* mir() const { return mir_->toNurseryObject(); }
216 };
217 
218 // Formal argument for a function, returning a box. Formal arguments are
219 // initially read from the stack.
220 class LParameter : public LInstructionHelper<BOX_PIECES, 0, 0> {
221  public:
LIR_HEADER(Parameter)222   LIR_HEADER(Parameter)
223 
224   LParameter() : LInstructionHelper(classOpcode) {}
225 };
226 
227 // Stack offset for a word-sized immutable input value to a frame.
228 class LCallee : public LInstructionHelper<1, 0, 0> {
229  public:
LIR_HEADER(Callee)230   LIR_HEADER(Callee)
231 
232   LCallee() : LInstructionHelper(classOpcode) {}
233 };
234 
235 class LIsConstructing : public LInstructionHelper<1, 0, 0> {
236  public:
LIR_HEADER(IsConstructing)237   LIR_HEADER(IsConstructing)
238 
239   LIsConstructing() : LInstructionHelper(classOpcode) {}
240 };
241 
242 // Base class for control instructions (goto, branch, etc.)
243 template <size_t Succs, size_t Operands, size_t Temps>
244 class LControlInstructionHelper
245     : public LInstructionHelper<0, Operands, Temps> {
246   mozilla::Array<MBasicBlock*, Succs> successors_;
247 
248  protected:
LControlInstructionHelper(LNode::Opcode opcode)249   explicit LControlInstructionHelper(LNode::Opcode opcode)
250       : LInstructionHelper<0, Operands, Temps>(opcode) {}
251 
252  public:
numSuccessors()253   size_t numSuccessors() const { return Succs; }
getSuccessor(size_t i)254   MBasicBlock* getSuccessor(size_t i) const { return successors_[i]; }
255 
setSuccessor(size_t i,MBasicBlock * successor)256   void setSuccessor(size_t i, MBasicBlock* successor) {
257     successors_[i] = successor;
258   }
259 };
260 
261 // Jumps to the start of a basic block.
262 class LGoto : public LControlInstructionHelper<1, 0, 0> {
263  public:
LIR_HEADER(Goto)264   LIR_HEADER(Goto)
265 
266   explicit LGoto(MBasicBlock* block) : LControlInstructionHelper(classOpcode) {
267     setSuccessor(0, block);
268   }
269 
target()270   MBasicBlock* target() const { return getSuccessor(0); }
271 };
272 
273 class LNewArray : public LInstructionHelper<1, 0, 1> {
274  public:
LIR_HEADER(NewArray)275   LIR_HEADER(NewArray)
276 
277   explicit LNewArray(const LDefinition& temp)
278       : LInstructionHelper(classOpcode) {
279     setTemp(0, temp);
280   }
281 
extraName()282   const char* extraName() const {
283     return mir()->isVMCall() ? "VMCall" : nullptr;
284   }
285 
temp()286   const LDefinition* temp() { return getTemp(0); }
287 
mir()288   MNewArray* mir() const { return mir_->toNewArray(); }
289 };
290 
291 class LNewArrayDynamicLength : public LInstructionHelper<1, 1, 1> {
292  public:
LIR_HEADER(NewArrayDynamicLength)293   LIR_HEADER(NewArrayDynamicLength)
294 
295   explicit LNewArrayDynamicLength(const LAllocation& length,
296                                   const LDefinition& temp)
297       : LInstructionHelper(classOpcode) {
298     setOperand(0, length);
299     setTemp(0, temp);
300   }
301 
length()302   const LAllocation* length() { return getOperand(0); }
temp()303   const LDefinition* temp() { return getTemp(0); }
304 
mir()305   MNewArrayDynamicLength* mir() const {
306     return mir_->toNewArrayDynamicLength();
307   }
308 };
309 
310 class LNewIterator : public LInstructionHelper<1, 0, 1> {
311  public:
LIR_HEADER(NewIterator)312   LIR_HEADER(NewIterator)
313 
314   explicit LNewIterator(const LDefinition& temp)
315       : LInstructionHelper(classOpcode) {
316     setTemp(0, temp);
317   }
318 
temp()319   const LDefinition* temp() { return getTemp(0); }
320 
mir()321   MNewIterator* mir() const { return mir_->toNewIterator(); }
322 };
323 
324 class LNewTypedArray : public LInstructionHelper<1, 0, 2> {
325  public:
LIR_HEADER(NewTypedArray)326   LIR_HEADER(NewTypedArray)
327 
328   LNewTypedArray(const LDefinition& temp1, const LDefinition& temp2)
329       : LInstructionHelper(classOpcode) {
330     setTemp(0, temp1);
331     setTemp(1, temp2);
332   }
333 
temp1()334   const LDefinition* temp1() { return getTemp(0); }
335 
temp2()336   const LDefinition* temp2() { return getTemp(1); }
337 
mir()338   MNewTypedArray* mir() const { return mir_->toNewTypedArray(); }
339 };
340 
341 class LNewTypedArrayDynamicLength : public LInstructionHelper<1, 1, 1> {
342  public:
LIR_HEADER(NewTypedArrayDynamicLength)343   LIR_HEADER(NewTypedArrayDynamicLength)
344 
345   LNewTypedArrayDynamicLength(const LAllocation& length,
346                               const LDefinition& temp)
347       : LInstructionHelper(classOpcode) {
348     setOperand(0, length);
349     setTemp(0, temp);
350   }
351 
length()352   const LAllocation* length() { return getOperand(0); }
temp()353   const LDefinition* temp() { return getTemp(0); }
354 
mir()355   MNewTypedArrayDynamicLength* mir() const {
356     return mir_->toNewTypedArrayDynamicLength();
357   }
358 };
359 
360 class LNewTypedArrayFromArray : public LCallInstructionHelper<1, 1, 0> {
361  public:
LIR_HEADER(NewTypedArrayFromArray)362   LIR_HEADER(NewTypedArrayFromArray)
363 
364   explicit LNewTypedArrayFromArray(const LAllocation& array)
365       : LCallInstructionHelper(classOpcode) {
366     setOperand(0, array);
367   }
368 
array()369   const LAllocation* array() { return getOperand(0); }
370 
mir()371   MNewTypedArrayFromArray* mir() const {
372     return mir_->toNewTypedArrayFromArray();
373   }
374 };
375 
376 class LNewTypedArrayFromArrayBuffer
377     : public LCallInstructionHelper<1, 1 + 2 * BOX_PIECES, 0> {
378  public:
LIR_HEADER(NewTypedArrayFromArrayBuffer)379   LIR_HEADER(NewTypedArrayFromArrayBuffer)
380 
381   LNewTypedArrayFromArrayBuffer(const LAllocation& arrayBuffer,
382                                 const LBoxAllocation& byteOffset,
383                                 const LBoxAllocation& length)
384       : LCallInstructionHelper(classOpcode) {
385     setOperand(0, arrayBuffer);
386     setBoxOperand(ByteOffsetIndex, byteOffset);
387     setBoxOperand(LengthIndex, length);
388   }
389 
390   static const size_t ByteOffsetIndex = 1;
391   static const size_t LengthIndex = 1 + BOX_PIECES;
392 
arrayBuffer()393   const LAllocation* arrayBuffer() { return getOperand(0); }
394 
mir()395   MNewTypedArrayFromArrayBuffer* mir() const {
396     return mir_->toNewTypedArrayFromArrayBuffer();
397   }
398 };
399 
400 class LNewObject : public LInstructionHelper<1, 0, 1> {
401  public:
LIR_HEADER(NewObject)402   LIR_HEADER(NewObject)
403 
404   explicit LNewObject(const LDefinition& temp)
405       : LInstructionHelper(classOpcode) {
406     setTemp(0, temp);
407   }
408 
extraName()409   const char* extraName() const {
410     return mir()->isVMCall() ? "VMCall" : nullptr;
411   }
412 
temp()413   const LDefinition* temp() { return getTemp(0); }
414 
mir()415   MNewObject* mir() const { return mir_->toNewObject(); }
416 };
417 
418 class LNewPlainObject : public LInstructionHelper<1, 0, 3> {
419  public:
LIR_HEADER(NewPlainObject)420   LIR_HEADER(NewPlainObject)
421 
422   explicit LNewPlainObject(const LDefinition& temp0, const LDefinition& temp1,
423                            const LDefinition& temp2)
424       : LInstructionHelper(classOpcode) {
425     setTemp(0, temp0);
426     setTemp(1, temp1);
427     setTemp(2, temp2);
428   }
429 
temp0()430   const LDefinition* temp0() { return getTemp(0); }
temp1()431   const LDefinition* temp1() { return getTemp(1); }
temp2()432   const LDefinition* temp2() { return getTemp(2); }
433 
mir()434   MNewPlainObject* mir() const { return mir_->toNewPlainObject(); }
435 };
436 
437 class LNewArrayObject : public LInstructionHelper<1, 0, 2> {
438  public:
LIR_HEADER(NewArrayObject)439   LIR_HEADER(NewArrayObject)
440 
441   explicit LNewArrayObject(const LDefinition& temp0, const LDefinition& temp1)
442       : LInstructionHelper(classOpcode) {
443     setTemp(0, temp0);
444     setTemp(1, temp1);
445   }
446 
temp0()447   const LDefinition* temp0() { return getTemp(0); }
temp1()448   const LDefinition* temp1() { return getTemp(1); }
449 
mir()450   MNewArrayObject* mir() const { return mir_->toNewArrayObject(); }
451 };
452 
453 // Allocates a new NamedLambdaObject.
454 //
455 // This instruction generates two possible instruction sets:
456 //   (1) An inline allocation of the call object is attempted.
457 //   (2) Otherwise, a callVM create a new object.
458 //
459 class LNewNamedLambdaObject : public LInstructionHelper<1, 0, 1> {
460  public:
461   LIR_HEADER(NewNamedLambdaObject);
462 
LNewNamedLambdaObject(const LDefinition & temp)463   explicit LNewNamedLambdaObject(const LDefinition& temp)
464       : LInstructionHelper(classOpcode) {
465     setTemp(0, temp);
466   }
467 
temp()468   const LDefinition* temp() { return getTemp(0); }
469 
mir()470   MNewNamedLambdaObject* mir() const { return mir_->toNewNamedLambdaObject(); }
471 };
472 
473 // Allocates a new CallObject.
474 //
475 // This instruction generates two possible instruction sets:
476 //   (1) If the call object is extensible, this is a callVM to create the
477 //       call object.
478 //   (2) Otherwise, an inline allocation of the call object is attempted.
479 //
480 class LNewCallObject : public LInstructionHelper<1, 0, 1> {
481  public:
LIR_HEADER(NewCallObject)482   LIR_HEADER(NewCallObject)
483 
484   explicit LNewCallObject(const LDefinition& temp)
485       : LInstructionHelper(classOpcode) {
486     setTemp(0, temp);
487   }
488 
temp()489   const LDefinition* temp() { return getTemp(0); }
490 
mir()491   MNewCallObject* mir() const { return mir_->toNewCallObject(); }
492 };
493 
494 class LNewStringObject : public LInstructionHelper<1, 1, 1> {
495  public:
LIR_HEADER(NewStringObject)496   LIR_HEADER(NewStringObject)
497 
498   LNewStringObject(const LAllocation& input, const LDefinition& temp)
499       : LInstructionHelper(classOpcode) {
500     setOperand(0, input);
501     setTemp(0, temp);
502   }
503 
input()504   const LAllocation* input() { return getOperand(0); }
temp()505   const LDefinition* temp() { return getTemp(0); }
mir()506   MNewStringObject* mir() const { return mir_->toNewStringObject(); }
507 };
508 
509 class LInitElemGetterSetter
510     : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0> {
511  public:
LIR_HEADER(InitElemGetterSetter)512   LIR_HEADER(InitElemGetterSetter)
513 
514   LInitElemGetterSetter(const LAllocation& object, const LBoxAllocation& id,
515                         const LAllocation& value)
516       : LCallInstructionHelper(classOpcode) {
517     setOperand(0, object);
518     setOperand(1, value);
519     setBoxOperand(IdIndex, id);
520   }
521 
522   static const size_t IdIndex = 2;
523 
object()524   const LAllocation* object() { return getOperand(0); }
value()525   const LAllocation* value() { return getOperand(1); }
mir()526   MInitElemGetterSetter* mir() const { return mir_->toInitElemGetterSetter(); }
527 };
528 
529 // Takes in an Object and a Value.
530 class LMutateProto : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> {
531  public:
LIR_HEADER(MutateProto)532   LIR_HEADER(MutateProto)
533 
534   LMutateProto(const LAllocation& object, const LBoxAllocation& value)
535       : LCallInstructionHelper(classOpcode) {
536     setOperand(0, object);
537     setBoxOperand(ValueIndex, value);
538   }
539 
540   static const size_t ValueIndex = 1;
541 
getObject()542   const LAllocation* getObject() { return getOperand(0); }
getValue()543   const LAllocation* getValue() { return getOperand(1); }
544 };
545 
546 class LInitPropGetterSetter : public LCallInstructionHelper<0, 2, 0> {
547  public:
LIR_HEADER(InitPropGetterSetter)548   LIR_HEADER(InitPropGetterSetter)
549 
550   LInitPropGetterSetter(const LAllocation& object, const LAllocation& value)
551       : LCallInstructionHelper(classOpcode) {
552     setOperand(0, object);
553     setOperand(1, value);
554   }
555 
object()556   const LAllocation* object() { return getOperand(0); }
value()557   const LAllocation* value() { return getOperand(1); }
558 
mir()559   MInitPropGetterSetter* mir() const { return mir_->toInitPropGetterSetter(); }
560 };
561 
562 class LCheckOverRecursed : public LInstructionHelper<0, 0, 0> {
563  public:
LIR_HEADER(CheckOverRecursed)564   LIR_HEADER(CheckOverRecursed)
565 
566   LCheckOverRecursed() : LInstructionHelper(classOpcode) {}
567 
mir()568   MCheckOverRecursed* mir() const { return mir_->toCheckOverRecursed(); }
569 };
570 
571 class LWasmTrap : public LInstructionHelper<0, 0, 0> {
572  public:
573   LIR_HEADER(WasmTrap);
574 
LWasmTrap()575   LWasmTrap() : LInstructionHelper(classOpcode) {}
576 
mir()577   const MWasmTrap* mir() const { return mir_->toWasmTrap(); }
578 };
579 
580 template <size_t Defs, size_t Ops>
581 class LWasmReinterpretBase : public LInstructionHelper<Defs, Ops, 0> {
582   typedef LInstructionHelper<Defs, Ops, 0> Base;
583 
584  protected:
LWasmReinterpretBase(LNode::Opcode opcode)585   explicit LWasmReinterpretBase(LNode::Opcode opcode) : Base(opcode) {}
586 
587  public:
input()588   const LAllocation* input() { return Base::getOperand(0); }
mir()589   MWasmReinterpret* mir() const { return Base::mir_->toWasmReinterpret(); }
590 };
591 
592 class LWasmReinterpret : public LWasmReinterpretBase<1, 1> {
593  public:
594   LIR_HEADER(WasmReinterpret);
LWasmReinterpret(const LAllocation & input)595   explicit LWasmReinterpret(const LAllocation& input)
596       : LWasmReinterpretBase(classOpcode) {
597     setOperand(0, input);
598   }
599 };
600 
601 class LWasmReinterpretFromI64 : public LWasmReinterpretBase<1, INT64_PIECES> {
602  public:
603   static const size_t Input = 0;
604 
605   LIR_HEADER(WasmReinterpretFromI64);
LWasmReinterpretFromI64(const LInt64Allocation & input)606   explicit LWasmReinterpretFromI64(const LInt64Allocation& input)
607       : LWasmReinterpretBase(classOpcode) {
608     setInt64Operand(Input, input);
609   }
610 };
611 
612 class LWasmReinterpretToI64 : public LWasmReinterpretBase<INT64_PIECES, 1> {
613  public:
614   LIR_HEADER(WasmReinterpretToI64);
LWasmReinterpretToI64(const LAllocation & input)615   explicit LWasmReinterpretToI64(const LAllocation& input)
616       : LWasmReinterpretBase(classOpcode) {
617     setOperand(0, input);
618   }
619 };
620 
621 namespace details {
622 template <size_t Defs, size_t Ops, size_t Temps>
623 class RotateBase : public LInstructionHelper<Defs, Ops, Temps> {
624   typedef LInstructionHelper<Defs, Ops, Temps> Base;
625 
626  protected:
RotateBase(LNode::Opcode opcode)627   explicit RotateBase(LNode::Opcode opcode) : Base(opcode) {}
628 
629  public:
mir()630   MRotate* mir() { return Base::mir_->toRotate(); }
631 };
632 }  // namespace details
633 
634 class LRotate : public details::RotateBase<1, 2, 0> {
635  public:
636   LIR_HEADER(Rotate);
637 
LRotate()638   LRotate() : RotateBase(classOpcode) {}
639 
input()640   const LAllocation* input() { return getOperand(0); }
count()641   LAllocation* count() { return getOperand(1); }
642 };
643 
644 class LRotateI64
645     : public details::RotateBase<INT64_PIECES, INT64_PIECES + 1, 1> {
646  public:
647   LIR_HEADER(RotateI64);
648 
LRotateI64()649   LRotateI64() : RotateBase(classOpcode) {
650     setTemp(0, LDefinition::BogusTemp());
651   }
652 
653   static const size_t Input = 0;
654   static const size_t Count = INT64_PIECES;
655 
input()656   const LInt64Allocation input() { return getInt64Operand(Input); }
temp()657   const LDefinition* temp() { return getTemp(0); }
count()658   LAllocation* count() { return getOperand(Count); }
659 };
660 
661 class LInterruptCheck : public LInstructionHelper<0, 0, 0> {
662  public:
LIR_HEADER(InterruptCheck)663   LIR_HEADER(InterruptCheck)
664 
665   LInterruptCheck() : LInstructionHelper(classOpcode) {}
mir()666   MInterruptCheck* mir() const { return mir_->toInterruptCheck(); }
667 };
668 
669 class LWasmInterruptCheck : public LInstructionHelper<0, 1, 0> {
670  public:
LIR_HEADER(WasmInterruptCheck)671   LIR_HEADER(WasmInterruptCheck)
672 
673   explicit LWasmInterruptCheck(const LAllocation& tlsData)
674       : LInstructionHelper(classOpcode) {
675     setOperand(0, tlsData);
676   }
mir()677   MWasmInterruptCheck* mir() const { return mir_->toWasmInterruptCheck(); }
tlsPtr()678   const LAllocation* tlsPtr() { return getOperand(0); }
679 };
680 
681 class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 1> {
682  public:
LIR_HEADER(TypeOfV)683   LIR_HEADER(TypeOfV)
684 
685   LTypeOfV(const LBoxAllocation& input, const LDefinition& tempToUnbox)
686       : LInstructionHelper(classOpcode) {
687     setBoxOperand(Input, input);
688     setTemp(0, tempToUnbox);
689   }
690 
691   static const size_t Input = 0;
692 
tempToUnbox()693   const LDefinition* tempToUnbox() { return getTemp(0); }
694 
mir()695   MTypeOf* mir() const { return mir_->toTypeOf(); }
696 };
697 
698 class LTypeOfO : public LInstructionHelper<1, 1, 0> {
699  public:
LIR_HEADER(TypeOfO)700   LIR_HEADER(TypeOfO)
701 
702   explicit LTypeOfO(const LAllocation& obj) : LInstructionHelper(classOpcode) {
703     setOperand(0, obj);
704   }
705 
object()706   const LAllocation* object() { return getOperand(0); }
707 
mir()708   MTypeOf* mir() const { return mir_->toTypeOf(); }
709 };
710 
711 class LToAsyncIter : public LCallInstructionHelper<1, 1 + BOX_PIECES, 0> {
712  public:
LIR_HEADER(ToAsyncIter)713   LIR_HEADER(ToAsyncIter)
714 
715   explicit LToAsyncIter(const LAllocation& iterator,
716                         const LBoxAllocation& nextMethod)
717       : LCallInstructionHelper(classOpcode) {
718     setOperand(0, iterator);
719     setBoxOperand(NextMethodIndex, nextMethod);
720   }
721 
722   static const size_t NextMethodIndex = 1;
723 
iterator()724   const LAllocation* iterator() { return getOperand(0); }
725 };
726 
727 class LToPropertyKeyCache
728     : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0> {
729  public:
LIR_HEADER(ToPropertyKeyCache)730   LIR_HEADER(ToPropertyKeyCache)
731 
732   explicit LToPropertyKeyCache(const LBoxAllocation& input)
733       : LInstructionHelper(classOpcode) {
734     setBoxOperand(Input, input);
735   }
736 
mir()737   const MToPropertyKeyCache* mir() const {
738     return mir_->toToPropertyKeyCache();
739   }
740 
input()741   const LAllocation* input() { return getOperand(Input); }
742 
743   static const size_t Input = 0;
744 };
745 
746 // Allocate an object for |new| on the caller-side,
747 // when there is no templateObject or prototype known
748 class LCreateThis : public LCallInstructionHelper<BOX_PIECES, 2, 0> {
749  public:
LIR_HEADER(CreateThis)750   LIR_HEADER(CreateThis)
751 
752   LCreateThis(const LAllocation& callee, const LAllocation& newTarget)
753       : LCallInstructionHelper(classOpcode) {
754     setOperand(0, callee);
755     setOperand(1, newTarget);
756   }
757 
getCallee()758   const LAllocation* getCallee() { return getOperand(0); }
getNewTarget()759   const LAllocation* getNewTarget() { return getOperand(1); }
760 
mir()761   MCreateThis* mir() const { return mir_->toCreateThis(); }
762 };
763 
764 // Allocate an object for |new| on the caller-side.
765 // Always performs object initialization with a fast path.
766 class LCreateThisWithTemplate : public LInstructionHelper<1, 0, 1> {
767  public:
LIR_HEADER(CreateThisWithTemplate)768   LIR_HEADER(CreateThisWithTemplate)
769 
770   explicit LCreateThisWithTemplate(const LDefinition& temp)
771       : LInstructionHelper(classOpcode) {
772     setTemp(0, temp);
773   }
774 
mir()775   MCreateThisWithTemplate* mir() const {
776     return mir_->toCreateThisWithTemplate();
777   }
778 
temp()779   const LDefinition* temp() { return getTemp(0); }
780 };
781 
782 // Allocate a new arguments object for the frame.
783 class LCreateArgumentsObject : public LCallInstructionHelper<1, 1, 3> {
784  public:
LIR_HEADER(CreateArgumentsObject)785   LIR_HEADER(CreateArgumentsObject)
786 
787   LCreateArgumentsObject(const LAllocation& callObj, const LDefinition& temp0,
788                          const LDefinition& temp1, const LDefinition& temp2)
789       : LCallInstructionHelper(classOpcode) {
790     setOperand(0, callObj);
791     setTemp(0, temp0);
792     setTemp(1, temp1);
793     setTemp(2, temp2);
794   }
795 
temp0()796   const LDefinition* temp0() { return getTemp(0); }
temp1()797   const LDefinition* temp1() { return getTemp(1); }
temp2()798   const LDefinition* temp2() { return getTemp(2); }
799 
getCallObject()800   const LAllocation* getCallObject() { return getOperand(0); }
801 
mir()802   MCreateArgumentsObject* mir() const {
803     return mir_->toCreateArgumentsObject();
804   }
805 };
806 
807 // Allocate a new arguments object for an inlined frame.
808 class LCreateInlinedArgumentsObject : public LVariadicInstruction<1, 1> {
809  public:
810   LIR_HEADER(CreateInlinedArgumentsObject)
811 
812   static const size_t CallObj = 0;
813   static const size_t Callee = 1;
814   static const size_t NumNonArgumentOperands = 2;
ArgIndex(size_t i)815   static size_t ArgIndex(size_t i) {
816     return NumNonArgumentOperands + BOX_PIECES * i;
817   }
818 
LCreateInlinedArgumentsObject(uint32_t numOperands,const LDefinition & temp)819   LCreateInlinedArgumentsObject(uint32_t numOperands, const LDefinition& temp)
820       : LVariadicInstruction(classOpcode, numOperands) {
821     setIsCall();
822     setTemp(0, temp);
823   }
824 
getCallObject()825   const LAllocation* getCallObject() { return getOperand(CallObj); }
getCallee()826   const LAllocation* getCallee() { return getOperand(Callee); }
827 
temp()828   const LDefinition* temp() { return getTemp(0); }
829 
mir()830   MCreateInlinedArgumentsObject* mir() const {
831     return mir_->toCreateInlinedArgumentsObject();
832   }
833 };
834 
835 class LGetInlinedArgument : public LVariadicInstruction<BOX_PIECES, 0> {
836  public:
837   LIR_HEADER(GetInlinedArgument)
838 
839   static const size_t Index = 0;
840   static const size_t NumNonArgumentOperands = 1;
ArgIndex(size_t i)841   static size_t ArgIndex(size_t i) {
842     return NumNonArgumentOperands + BOX_PIECES * i;
843   }
844 
LGetInlinedArgument(uint32_t numOperands)845   explicit LGetInlinedArgument(uint32_t numOperands)
846       : LVariadicInstruction(classOpcode, numOperands) {}
847 
getIndex()848   const LAllocation* getIndex() { return getOperand(Index); }
849 
mir()850   MGetInlinedArgument* mir() const { return mir_->toGetInlinedArgument(); }
851 };
852 
853 // Get argument from arguments object.
854 class LGetArgumentsObjectArg : public LInstructionHelper<BOX_PIECES, 1, 1> {
855  public:
LIR_HEADER(GetArgumentsObjectArg)856   LIR_HEADER(GetArgumentsObjectArg)
857 
858   LGetArgumentsObjectArg(const LAllocation& argsObj, const LDefinition& temp)
859       : LInstructionHelper(classOpcode) {
860     setOperand(0, argsObj);
861     setTemp(0, temp);
862   }
863 
getArgsObject()864   const LAllocation* getArgsObject() { return getOperand(0); }
865 
mir()866   MGetArgumentsObjectArg* mir() const {
867     return mir_->toGetArgumentsObjectArg();
868   }
869 };
870 
871 // Set argument on arguments object.
872 class LSetArgumentsObjectArg : public LInstructionHelper<0, 1 + BOX_PIECES, 1> {
873  public:
LIR_HEADER(SetArgumentsObjectArg)874   LIR_HEADER(SetArgumentsObjectArg)
875 
876   LSetArgumentsObjectArg(const LAllocation& argsObj,
877                          const LBoxAllocation& value, const LDefinition& temp)
878       : LInstructionHelper(classOpcode) {
879     setOperand(0, argsObj);
880     setBoxOperand(ValueIndex, value);
881     setTemp(0, temp);
882   }
883 
getArgsObject()884   const LAllocation* getArgsObject() { return getOperand(0); }
885 
mir()886   MSetArgumentsObjectArg* mir() const {
887     return mir_->toSetArgumentsObjectArg();
888   }
889 
890   static const size_t ValueIndex = 1;
891 };
892 
893 // Load an element from an arguments object.
894 class LLoadArgumentsObjectArg : public LInstructionHelper<BOX_PIECES, 2, 1> {
895  public:
LIR_HEADER(LoadArgumentsObjectArg)896   LIR_HEADER(LoadArgumentsObjectArg)
897 
898   LLoadArgumentsObjectArg(const LAllocation& argsObj, const LAllocation& index,
899                           const LDefinition& temp)
900       : LInstructionHelper(classOpcode) {
901     setOperand(0, argsObj);
902     setOperand(1, index);
903     setTemp(0, temp);
904   }
905 
getArgsObject()906   const LAllocation* getArgsObject() { return getOperand(0); }
index()907   const LAllocation* index() { return getOperand(1); }
temp()908   const LDefinition* temp() { return this->getTemp(0); }
909 };
910 
911 // Return |arguments.length| unless it has been overridden.
912 class LArgumentsObjectLength : public LInstructionHelper<1, 1, 0> {
913  public:
LIR_HEADER(ArgumentsObjectLength)914   LIR_HEADER(ArgumentsObjectLength)
915 
916   explicit LArgumentsObjectLength(const LAllocation& argsObj)
917       : LInstructionHelper(classOpcode) {
918     setOperand(0, argsObj);
919   }
920 
getArgsObject()921   const LAllocation* getArgsObject() { return getOperand(0); }
922 };
923 
924 // Guard that the given flags are not set on the arguments object.
925 class LGuardArgumentsObjectFlags : public LInstructionHelper<0, 1, 1> {
926  public:
LIR_HEADER(GuardArgumentsObjectFlags)927   LIR_HEADER(GuardArgumentsObjectFlags)
928 
929   explicit LGuardArgumentsObjectFlags(const LAllocation& argsObj,
930                                       const LDefinition& temp)
931       : LInstructionHelper(classOpcode) {
932     setOperand(0, argsObj);
933     setTemp(0, temp);
934   }
935 
getArgsObject()936   const LAllocation* getArgsObject() { return getOperand(0); }
temp()937   const LDefinition* temp() { return this->getTemp(0); }
938 
mir()939   MGuardArgumentsObjectFlags* mir() const {
940     return mir_->toGuardArgumentsObjectFlags();
941   }
942 };
943 
944 // If the Value is an Object, return unbox(Value).
945 // Otherwise, return the other Object.
946 class LReturnFromCtor : public LInstructionHelper<1, BOX_PIECES + 1, 0> {
947  public:
LIR_HEADER(ReturnFromCtor)948   LIR_HEADER(ReturnFromCtor)
949 
950   LReturnFromCtor(const LBoxAllocation& value, const LAllocation& object)
951       : LInstructionHelper(classOpcode) {
952     setBoxOperand(ValueIndex, value);
953     setOperand(ObjectIndex, object);
954   }
955 
getObject()956   const LAllocation* getObject() { return getOperand(ObjectIndex); }
957 
958   static const size_t ValueIndex = 0;
959   static const size_t ObjectIndex = BOX_PIECES;
960 };
961 
962 class LBoxNonStrictThis : public LInstructionHelper<1, BOX_PIECES, 0> {
963  public:
964   LIR_HEADER(BoxNonStrictThis)
965 
966   static const size_t ValueIndex = 0;
967 
LBoxNonStrictThis(const LBoxAllocation & value)968   explicit LBoxNonStrictThis(const LBoxAllocation& value)
969       : LInstructionHelper(classOpcode) {
970     setBoxOperand(ValueIndex, value);
971   }
972 
mir()973   MBoxNonStrictThis* mir() const { return mir_->toBoxNonStrictThis(); }
974 };
975 
976 class LImplicitThis : public LCallInstructionHelper<BOX_PIECES, 1, 0> {
977  public:
LIR_HEADER(ImplicitThis)978   LIR_HEADER(ImplicitThis)
979 
980   explicit LImplicitThis(const LAllocation& env)
981       : LCallInstructionHelper(classOpcode) {
982     setOperand(0, env);
983   }
984 
env()985   const LAllocation* env() { return getOperand(0); }
986 
mir()987   MImplicitThis* mir() const { return mir_->toImplicitThis(); }
988 };
989 
990 // Writes a typed argument for a function call to the frame's argument vector.
991 class LStackArgT : public LInstructionHelper<0, 1, 0> {
992   uint32_t argslot_;  // Index into frame-scope argument vector.
993   MIRType type_;
994 
995  public:
LIR_HEADER(StackArgT)996   LIR_HEADER(StackArgT)
997 
998   LStackArgT(uint32_t argslot, MIRType type, const LAllocation& arg)
999       : LInstructionHelper(classOpcode), argslot_(argslot), type_(type) {
1000     setOperand(0, arg);
1001   }
argslot()1002   uint32_t argslot() const { return argslot_; }
type()1003   MIRType type() const { return type_; }
getArgument()1004   const LAllocation* getArgument() { return getOperand(0); }
1005 };
1006 
1007 // Writes an untyped argument for a function call to the frame's argument
1008 // vector.
1009 class LStackArgV : public LInstructionHelper<0, BOX_PIECES, 0> {
1010   uint32_t argslot_;  // Index into frame-scope argument vector.
1011 
1012  public:
LIR_HEADER(StackArgV)1013   LIR_HEADER(StackArgV)
1014 
1015   LStackArgV(uint32_t argslot, const LBoxAllocation& value)
1016       : LInstructionHelper(classOpcode), argslot_(argslot) {
1017     setBoxOperand(0, value);
1018   }
1019 
argslot()1020   uint32_t argslot() const { return argslot_; }
1021 };
1022 
1023 // Common code for LIR descended from MCall.
1024 template <size_t Defs, size_t Operands, size_t Temps>
1025 class LJSCallInstructionHelper
1026     : public LCallInstructionHelper<Defs, Operands, Temps> {
1027  protected:
LJSCallInstructionHelper(LNode::Opcode opcode)1028   explicit LJSCallInstructionHelper(LNode::Opcode opcode)
1029       : LCallInstructionHelper<Defs, Operands, Temps>(opcode) {}
1030 
1031  public:
argslot()1032   uint32_t argslot() const {
1033     if (JitStackValueAlignment > 1) {
1034       return AlignBytes(mir()->numStackArgs(), JitStackValueAlignment);
1035     }
1036     return mir()->numStackArgs();
1037   }
mir()1038   MCall* mir() const { return this->mir_->toCall(); }
1039 
hasSingleTarget()1040   bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
getSingleTarget()1041   WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
1042 
1043   // Does not include |this|.
numActualArgs()1044   uint32_t numActualArgs() const { return mir()->numActualArgs(); }
1045 
isConstructing()1046   bool isConstructing() const { return mir()->isConstructing(); }
ignoresReturnValue()1047   bool ignoresReturnValue() const { return mir()->ignoresReturnValue(); }
1048 };
1049 
1050 // Generates a polymorphic callsite, wherein the function being called is
1051 // unknown and anticipated to vary.
1052 class LCallGeneric : public LJSCallInstructionHelper<BOX_PIECES, 1, 2> {
1053  public:
LIR_HEADER(CallGeneric)1054   LIR_HEADER(CallGeneric)
1055 
1056   LCallGeneric(const LAllocation& func, const LDefinition& nargsreg,
1057                const LDefinition& tmpobjreg)
1058       : LJSCallInstructionHelper(classOpcode) {
1059     setOperand(0, func);
1060     setTemp(0, nargsreg);
1061     setTemp(1, tmpobjreg);
1062   }
1063 
getFunction()1064   const LAllocation* getFunction() { return getOperand(0); }
getNargsReg()1065   const LDefinition* getNargsReg() { return getTemp(0); }
getTempObject()1066   const LDefinition* getTempObject() { return getTemp(1); }
1067 };
1068 
1069 // Generates a hardcoded callsite for a known, non-native target.
1070 class LCallKnown : public LJSCallInstructionHelper<BOX_PIECES, 1, 1> {
1071  public:
LIR_HEADER(CallKnown)1072   LIR_HEADER(CallKnown)
1073 
1074   LCallKnown(const LAllocation& func, const LDefinition& tmpobjreg)
1075       : LJSCallInstructionHelper(classOpcode) {
1076     setOperand(0, func);
1077     setTemp(0, tmpobjreg);
1078   }
1079 
getFunction()1080   const LAllocation* getFunction() { return getOperand(0); }
getTempObject()1081   const LDefinition* getTempObject() { return getTemp(0); }
1082 };
1083 
1084 // Generates a hardcoded callsite for a known, native target.
1085 class LCallNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> {
1086  public:
LIR_HEADER(CallNative)1087   LIR_HEADER(CallNative)
1088 
1089   LCallNative(const LDefinition& argContext, const LDefinition& argUintN,
1090               const LDefinition& argVp, const LDefinition& tmpreg)
1091       : LJSCallInstructionHelper(classOpcode) {
1092     // Registers used for callWithABI().
1093     setTemp(0, argContext);
1094     setTemp(1, argUintN);
1095     setTemp(2, argVp);
1096 
1097     // Temporary registers.
1098     setTemp(3, tmpreg);
1099   }
1100 
getArgContextReg()1101   const LDefinition* getArgContextReg() { return getTemp(0); }
getArgUintNReg()1102   const LDefinition* getArgUintNReg() { return getTemp(1); }
getArgVpReg()1103   const LDefinition* getArgVpReg() { return getTemp(2); }
getTempReg()1104   const LDefinition* getTempReg() { return getTemp(3); }
1105 };
1106 
1107 // Generates a hardcoded callsite for a known, DOM-native target.
1108 class LCallDOMNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> {
1109  public:
LIR_HEADER(CallDOMNative)1110   LIR_HEADER(CallDOMNative)
1111 
1112   LCallDOMNative(const LDefinition& argJSContext, const LDefinition& argObj,
1113                  const LDefinition& argPrivate, const LDefinition& argArgs)
1114       : LJSCallInstructionHelper(classOpcode) {
1115     setTemp(0, argJSContext);
1116     setTemp(1, argObj);
1117     setTemp(2, argPrivate);
1118     setTemp(3, argArgs);
1119   }
1120 
getArgJSContext()1121   const LDefinition* getArgJSContext() { return getTemp(0); }
getArgObj()1122   const LDefinition* getArgObj() { return getTemp(1); }
getArgPrivate()1123   const LDefinition* getArgPrivate() { return getTemp(2); }
getArgArgs()1124   const LDefinition* getArgArgs() { return getTemp(3); }
1125 };
1126 
1127 class LBail : public LInstructionHelper<0, 0, 0> {
1128  public:
LIR_HEADER(Bail)1129   LIR_HEADER(Bail)
1130 
1131   LBail() : LInstructionHelper(classOpcode) {}
1132 };
1133 
1134 class LUnreachable : public LControlInstructionHelper<0, 0, 0> {
1135  public:
LIR_HEADER(Unreachable)1136   LIR_HEADER(Unreachable)
1137 
1138   LUnreachable() : LControlInstructionHelper(classOpcode) {}
1139 };
1140 
1141 class LEncodeSnapshot : public LInstructionHelper<0, 0, 0> {
1142  public:
LIR_HEADER(EncodeSnapshot)1143   LIR_HEADER(EncodeSnapshot)
1144 
1145   LEncodeSnapshot() : LInstructionHelper(classOpcode) {}
1146 };
1147 
1148 class LUnreachableResultV : public LInstructionHelper<BOX_PIECES, 0, 0> {
1149  public:
LIR_HEADER(UnreachableResultV)1150   LIR_HEADER(UnreachableResultV)
1151 
1152   LUnreachableResultV() : LInstructionHelper(classOpcode) {}
1153 };
1154 
1155 class LUnreachableResultT : public LInstructionHelper<1, 0, 0> {
1156  public:
LIR_HEADER(UnreachableResultT)1157   LIR_HEADER(UnreachableResultT)
1158 
1159   LUnreachableResultT() : LInstructionHelper(classOpcode) {}
1160 };
1161 
1162 template <size_t defs, size_t ops>
1163 class LDOMPropertyInstructionHelper
1164     : public LCallInstructionHelper<defs, 1 + ops, 3> {
1165  protected:
LDOMPropertyInstructionHelper(LNode::Opcode opcode,const LDefinition & JSContextReg,const LAllocation & ObjectReg,const LDefinition & PrivReg,const LDefinition & ValueReg)1166   LDOMPropertyInstructionHelper(LNode::Opcode opcode,
1167                                 const LDefinition& JSContextReg,
1168                                 const LAllocation& ObjectReg,
1169                                 const LDefinition& PrivReg,
1170                                 const LDefinition& ValueReg)
1171       : LCallInstructionHelper<defs, 1 + ops, 3>(opcode) {
1172     this->setOperand(0, ObjectReg);
1173     this->setTemp(0, JSContextReg);
1174     this->setTemp(1, PrivReg);
1175     this->setTemp(2, ValueReg);
1176   }
1177 
1178  public:
getJSContextReg()1179   const LDefinition* getJSContextReg() { return this->getTemp(0); }
getObjectReg()1180   const LAllocation* getObjectReg() { return this->getOperand(0); }
getPrivReg()1181   const LDefinition* getPrivReg() { return this->getTemp(1); }
getValueReg()1182   const LDefinition* getValueReg() { return this->getTemp(2); }
1183 };
1184 
1185 class LGetDOMProperty : public LDOMPropertyInstructionHelper<BOX_PIECES, 0> {
1186  public:
LIR_HEADER(GetDOMProperty)1187   LIR_HEADER(GetDOMProperty)
1188 
1189   LGetDOMProperty(const LDefinition& JSContextReg, const LAllocation& ObjectReg,
1190                   const LDefinition& PrivReg, const LDefinition& ValueReg)
1191       : LDOMPropertyInstructionHelper<BOX_PIECES, 0>(
1192             classOpcode, JSContextReg, ObjectReg, PrivReg, ValueReg) {}
1193 
mir()1194   MGetDOMProperty* mir() const { return mir_->toGetDOMProperty(); }
1195 };
1196 
1197 class LGetDOMMemberV : public LInstructionHelper<BOX_PIECES, 1, 0> {
1198  public:
1199   LIR_HEADER(GetDOMMemberV);
LGetDOMMemberV(const LAllocation & object)1200   explicit LGetDOMMemberV(const LAllocation& object)
1201       : LInstructionHelper(classOpcode) {
1202     setOperand(0, object);
1203   }
1204 
object()1205   const LAllocation* object() { return getOperand(0); }
1206 
mir()1207   MGetDOMMember* mir() const { return mir_->toGetDOMMember(); }
1208 };
1209 
1210 class LGetDOMMemberT : public LInstructionHelper<1, 1, 0> {
1211  public:
1212   LIR_HEADER(GetDOMMemberT);
LGetDOMMemberT(const LAllocation & object)1213   explicit LGetDOMMemberT(const LAllocation& object)
1214       : LInstructionHelper(classOpcode) {
1215     setOperand(0, object);
1216   }
1217 
object()1218   const LAllocation* object() { return getOperand(0); }
1219 
mir()1220   MGetDOMMember* mir() const { return mir_->toGetDOMMember(); }
1221 };
1222 
1223 class LSetDOMProperty : public LDOMPropertyInstructionHelper<0, BOX_PIECES> {
1224  public:
LIR_HEADER(SetDOMProperty)1225   LIR_HEADER(SetDOMProperty)
1226 
1227   LSetDOMProperty(const LDefinition& JSContextReg, const LAllocation& ObjectReg,
1228                   const LBoxAllocation& value, const LDefinition& PrivReg,
1229                   const LDefinition& ValueReg)
1230       : LDOMPropertyInstructionHelper<0, BOX_PIECES>(
1231             classOpcode, JSContextReg, ObjectReg, PrivReg, ValueReg) {
1232     setBoxOperand(Value, value);
1233   }
1234 
1235   static const size_t Value = 1;
1236 
mir()1237   MSetDOMProperty* mir() const { return mir_->toSetDOMProperty(); }
1238 };
1239 
1240 class LLoadDOMExpandoValue : public LInstructionHelper<BOX_PIECES, 1, 0> {
1241  public:
LIR_HEADER(LoadDOMExpandoValue)1242   LIR_HEADER(LoadDOMExpandoValue)
1243 
1244   explicit LLoadDOMExpandoValue(const LAllocation& proxy)
1245       : LInstructionHelper(classOpcode) {
1246     setOperand(0, proxy);
1247   }
1248 
proxy()1249   const LAllocation* proxy() { return getOperand(0); }
1250 
mir()1251   const MLoadDOMExpandoValue* mir() const {
1252     return mir_->toLoadDOMExpandoValue();
1253   }
1254 };
1255 
1256 class LLoadDOMExpandoValueGuardGeneration
1257     : public LInstructionHelper<BOX_PIECES, 1, 0> {
1258  public:
LIR_HEADER(LoadDOMExpandoValueGuardGeneration)1259   LIR_HEADER(LoadDOMExpandoValueGuardGeneration)
1260 
1261   explicit LLoadDOMExpandoValueGuardGeneration(const LAllocation& proxy)
1262       : LInstructionHelper(classOpcode) {
1263     setOperand(0, proxy);
1264   }
1265 
proxy()1266   const LAllocation* proxy() { return getOperand(0); }
1267 
mir()1268   const MLoadDOMExpandoValueGuardGeneration* mir() const {
1269     return mir_->toLoadDOMExpandoValueGuardGeneration();
1270   }
1271 };
1272 
1273 class LLoadDOMExpandoValueIgnoreGeneration
1274     : public LInstructionHelper<BOX_PIECES, 1, 0> {
1275  public:
LIR_HEADER(LoadDOMExpandoValueIgnoreGeneration)1276   LIR_HEADER(LoadDOMExpandoValueIgnoreGeneration)
1277 
1278   explicit LLoadDOMExpandoValueIgnoreGeneration(const LAllocation& proxy)
1279       : LInstructionHelper(classOpcode) {
1280     setOperand(0, proxy);
1281   }
1282 
proxy()1283   const LAllocation* proxy() { return getOperand(0); }
1284 };
1285 
1286 class LGuardDOMExpandoMissingOrGuardShape
1287     : public LInstructionHelper<0, BOX_PIECES, 1> {
1288  public:
LIR_HEADER(GuardDOMExpandoMissingOrGuardShape)1289   LIR_HEADER(GuardDOMExpandoMissingOrGuardShape)
1290 
1291   explicit LGuardDOMExpandoMissingOrGuardShape(const LBoxAllocation& input,
1292                                                const LDefinition& temp)
1293       : LInstructionHelper(classOpcode) {
1294     setBoxOperand(Input, input);
1295     setTemp(0, temp);
1296   }
1297 
temp()1298   const LDefinition* temp() { return getTemp(0); }
1299 
1300   static const size_t Input = 0;
1301 
mir()1302   MGuardDOMExpandoMissingOrGuardShape* mir() {
1303     return mir_->toGuardDOMExpandoMissingOrGuardShape();
1304   }
1305 };
1306 
1307 // Generates a polymorphic callsite, wherein the function being called is
1308 // unknown and anticipated to vary.
1309 class LApplyArgsGeneric
1310     : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
1311  public:
LIR_HEADER(ApplyArgsGeneric)1312   LIR_HEADER(ApplyArgsGeneric)
1313 
1314   LApplyArgsGeneric(const LAllocation& func, const LAllocation& argc,
1315                     const LBoxAllocation& thisv, const LDefinition& tmpobjreg,
1316                     const LDefinition& tmpcopy)
1317       : LCallInstructionHelper(classOpcode) {
1318     setOperand(0, func);
1319     setOperand(1, argc);
1320     setBoxOperand(ThisIndex, thisv);
1321     setTemp(0, tmpobjreg);
1322     setTemp(1, tmpcopy);
1323   }
1324 
mir()1325   MApplyArgs* mir() const { return mir_->toApplyArgs(); }
1326 
hasSingleTarget()1327   bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
getSingleTarget()1328   WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
1329 
getFunction()1330   const LAllocation* getFunction() { return getOperand(0); }
getArgc()1331   const LAllocation* getArgc() { return getOperand(1); }
1332   static const size_t ThisIndex = 2;
1333 
getTempObject()1334   const LDefinition* getTempObject() { return getTemp(0); }
getTempStackCounter()1335   const LDefinition* getTempStackCounter() { return getTemp(1); }
1336 };
1337 
1338 class LApplyArgsObj
1339     : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
1340  public:
LIR_HEADER(ApplyArgsObj)1341   LIR_HEADER(ApplyArgsObj)
1342 
1343   LApplyArgsObj(const LAllocation& func, const LAllocation& argsObj,
1344                 const LBoxAllocation& thisv, const LDefinition& tmpObjReg,
1345                 const LDefinition& tmpCopy)
1346       : LCallInstructionHelper(classOpcode) {
1347     setOperand(0, func);
1348     setOperand(1, argsObj);
1349     setBoxOperand(ThisIndex, thisv);
1350     setTemp(0, tmpObjReg);
1351     setTemp(1, tmpCopy);
1352   }
1353 
mir()1354   MApplyArgsObj* mir() const { return mir_->toApplyArgsObj(); }
1355 
hasSingleTarget()1356   bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
getSingleTarget()1357   WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
1358 
getFunction()1359   const LAllocation* getFunction() { return getOperand(0); }
getArgsObj()1360   const LAllocation* getArgsObj() { return getOperand(1); }
1361   // All registers are calltemps. argc is mapped to the same register as
1362   // ArgsObj. argc becomes live as ArgsObj is dying.
getArgc()1363   const LAllocation* getArgc() { return getOperand(1); }
1364   static const size_t ThisIndex = 2;
1365 
getTempObject()1366   const LDefinition* getTempObject() { return getTemp(0); }
getTempStackCounter()1367   const LDefinition* getTempStackCounter() { return getTemp(1); }
1368 };
1369 
1370 class LApplyArrayGeneric
1371     : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
1372  public:
LIR_HEADER(ApplyArrayGeneric)1373   LIR_HEADER(ApplyArrayGeneric)
1374 
1375   LApplyArrayGeneric(const LAllocation& func, const LAllocation& elements,
1376                      const LBoxAllocation& thisv, const LDefinition& tmpobjreg,
1377                      const LDefinition& tmpcopy)
1378       : LCallInstructionHelper(classOpcode) {
1379     setOperand(0, func);
1380     setOperand(1, elements);
1381     setBoxOperand(ThisIndex, thisv);
1382     setTemp(0, tmpobjreg);
1383     setTemp(1, tmpcopy);
1384   }
1385 
mir()1386   MApplyArray* mir() const { return mir_->toApplyArray(); }
1387 
hasSingleTarget()1388   bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
getSingleTarget()1389   WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
1390 
getFunction()1391   const LAllocation* getFunction() { return getOperand(0); }
getElements()1392   const LAllocation* getElements() { return getOperand(1); }
1393   // argc is mapped to the same register as elements: argc becomes
1394   // live as elements is dying, all registers are calltemps.
getArgc()1395   const LAllocation* getArgc() { return getOperand(1); }
1396   static const size_t ThisIndex = 2;
1397 
getTempObject()1398   const LDefinition* getTempObject() { return getTemp(0); }
getTempStackCounter()1399   const LDefinition* getTempStackCounter() { return getTemp(1); }
1400 };
1401 
1402 class LConstructArrayGeneric
1403     : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 3, 1> {
1404  public:
LIR_HEADER(ConstructArrayGeneric)1405   LIR_HEADER(ConstructArrayGeneric)
1406 
1407   LConstructArrayGeneric(const LAllocation& func, const LAllocation& elements,
1408                          const LAllocation& newTarget,
1409                          const LBoxAllocation& thisv,
1410                          const LDefinition& tmpobjreg)
1411       : LCallInstructionHelper(classOpcode) {
1412     setOperand(0, func);
1413     setOperand(1, elements);
1414     setOperand(2, newTarget);
1415     setBoxOperand(ThisIndex, thisv);
1416     setTemp(0, tmpobjreg);
1417   }
1418 
mir()1419   MConstructArray* mir() const { return mir_->toConstructArray(); }
1420 
hasSingleTarget()1421   bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
getSingleTarget()1422   WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
1423 
getFunction()1424   const LAllocation* getFunction() { return getOperand(0); }
getElements()1425   const LAllocation* getElements() { return getOperand(1); }
getNewTarget()1426   const LAllocation* getNewTarget() { return getOperand(2); }
1427 
1428   static const size_t ThisIndex = 3;
1429 
getTempObject()1430   const LDefinition* getTempObject() { return getTemp(0); }
1431 
1432   // argc is mapped to the same register as elements: argc becomes
1433   // live as elements is dying, all registers are calltemps.
getArgc()1434   const LAllocation* getArgc() { return getOperand(1); }
1435 
1436   // tempStackCounter is mapped to the same register as newTarget:
1437   // tempStackCounter becomes live as newTarget is dying, all registers are
1438   // calltemps.
getTempStackCounter()1439   const LAllocation* getTempStackCounter() { return getOperand(2); }
1440 };
1441 
1442 // Takes in either an integer or boolean input and tests it for truthiness.
1443 class LTestIAndBranch : public LControlInstructionHelper<2, 1, 0> {
1444  public:
LIR_HEADER(TestIAndBranch)1445   LIR_HEADER(TestIAndBranch)
1446 
1447   LTestIAndBranch(const LAllocation& in, MBasicBlock* ifTrue,
1448                   MBasicBlock* ifFalse)
1449       : LControlInstructionHelper(classOpcode) {
1450     setOperand(0, in);
1451     setSuccessor(0, ifTrue);
1452     setSuccessor(1, ifFalse);
1453   }
1454 
ifTrue()1455   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1456   MBasicBlock* ifFalse() const { return getSuccessor(1); }
1457 };
1458 
1459 // Takes in an int64 input and tests it for truthiness.
1460 class LTestI64AndBranch : public LControlInstructionHelper<2, INT64_PIECES, 0> {
1461  public:
LIR_HEADER(TestI64AndBranch)1462   LIR_HEADER(TestI64AndBranch)
1463 
1464   LTestI64AndBranch(const LInt64Allocation& in, MBasicBlock* ifTrue,
1465                     MBasicBlock* ifFalse)
1466       : LControlInstructionHelper(classOpcode) {
1467     setInt64Operand(0, in);
1468     setSuccessor(0, ifTrue);
1469     setSuccessor(1, ifFalse);
1470   }
1471 
ifTrue()1472   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1473   MBasicBlock* ifFalse() const { return getSuccessor(1); }
1474 };
1475 
1476 // Takes in a double input and tests it for truthiness.
1477 class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0> {
1478  public:
LIR_HEADER(TestDAndBranch)1479   LIR_HEADER(TestDAndBranch)
1480 
1481   LTestDAndBranch(const LAllocation& in, MBasicBlock* ifTrue,
1482                   MBasicBlock* ifFalse)
1483       : LControlInstructionHelper(classOpcode) {
1484     setOperand(0, in);
1485     setSuccessor(0, ifTrue);
1486     setSuccessor(1, ifFalse);
1487   }
1488 
ifTrue()1489   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1490   MBasicBlock* ifFalse() const { return getSuccessor(1); }
1491 };
1492 
1493 // Takes in a float32 input and tests it for truthiness.
1494 class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0> {
1495  public:
LIR_HEADER(TestFAndBranch)1496   LIR_HEADER(TestFAndBranch)
1497 
1498   LTestFAndBranch(const LAllocation& in, MBasicBlock* ifTrue,
1499                   MBasicBlock* ifFalse)
1500       : LControlInstructionHelper(classOpcode) {
1501     setOperand(0, in);
1502     setSuccessor(0, ifTrue);
1503     setSuccessor(1, ifFalse);
1504   }
1505 
ifTrue()1506   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1507   MBasicBlock* ifFalse() const { return getSuccessor(1); }
1508 };
1509 
1510 // Takes in a bigint input and tests it for truthiness.
1511 class LTestBIAndBranch : public LControlInstructionHelper<2, 1, 0> {
1512  public:
LIR_HEADER(TestBIAndBranch)1513   LIR_HEADER(TestBIAndBranch)
1514 
1515   LTestBIAndBranch(const LAllocation& in, MBasicBlock* ifTrue,
1516                    MBasicBlock* ifFalse)
1517       : LControlInstructionHelper(classOpcode) {
1518     setOperand(0, in);
1519     setSuccessor(0, ifTrue);
1520     setSuccessor(1, ifFalse);
1521   }
1522 
ifTrue()1523   MBasicBlock* ifTrue() { return getSuccessor(0); }
ifFalse()1524   MBasicBlock* ifFalse() { return getSuccessor(1); }
1525 };
1526 
1527 // Takes an object and tests it for truthiness.  An object is falsy iff it
1528 // emulates |undefined|; see js::EmulatesUndefined.
1529 class LTestOAndBranch : public LControlInstructionHelper<2, 1, 1> {
1530  public:
LIR_HEADER(TestOAndBranch)1531   LIR_HEADER(TestOAndBranch)
1532 
1533   LTestOAndBranch(const LAllocation& input, MBasicBlock* ifTruthy,
1534                   MBasicBlock* ifFalsy, const LDefinition& temp)
1535       : LControlInstructionHelper(classOpcode) {
1536     setOperand(0, input);
1537     setSuccessor(0, ifTruthy);
1538     setSuccessor(1, ifFalsy);
1539     setTemp(0, temp);
1540   }
1541 
temp()1542   const LDefinition* temp() { return getTemp(0); }
1543 
ifTruthy()1544   MBasicBlock* ifTruthy() { return getSuccessor(0); }
ifFalsy()1545   MBasicBlock* ifFalsy() { return getSuccessor(1); }
1546 
mir()1547   MTest* mir() { return mir_->toTest(); }
1548 };
1549 
1550 // Takes in a boxed value and tests it for truthiness.
1551 class LTestVAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 3> {
1552  public:
LIR_HEADER(TestVAndBranch)1553   LIR_HEADER(TestVAndBranch)
1554 
1555   LTestVAndBranch(MBasicBlock* ifTruthy, MBasicBlock* ifFalsy,
1556                   const LBoxAllocation& input, const LDefinition& temp0,
1557                   const LDefinition& temp1, const LDefinition& temp2)
1558       : LControlInstructionHelper(classOpcode) {
1559     setSuccessor(0, ifTruthy);
1560     setSuccessor(1, ifFalsy);
1561     setBoxOperand(Input, input);
1562     setTemp(0, temp0);
1563     setTemp(1, temp1);
1564     setTemp(2, temp2);
1565   }
1566 
1567   static const size_t Input = 0;
1568 
tempFloat()1569   const LDefinition* tempFloat() { return getTemp(0); }
1570 
temp1()1571   const LDefinition* temp1() { return getTemp(1); }
1572 
temp2()1573   const LDefinition* temp2() { return getTemp(2); }
1574 
ifTruthy()1575   MBasicBlock* ifTruthy() { return getSuccessor(0); }
ifFalsy()1576   MBasicBlock* ifFalsy() { return getSuccessor(1); }
1577 
mir()1578   MTest* mir() const { return mir_->toTest(); }
1579 };
1580 
1581 // Compares two integral values of the same JS type, either integer or object.
1582 // For objects, both operands are in registers.
1583 class LCompare : public LInstructionHelper<1, 2, 0> {
1584   JSOp jsop_;
1585 
1586  public:
LIR_HEADER(Compare)1587   LIR_HEADER(Compare)
1588   LCompare(JSOp jsop, const LAllocation& left, const LAllocation& right)
1589       : LInstructionHelper(classOpcode), jsop_(jsop) {
1590     setOperand(0, left);
1591     setOperand(1, right);
1592   }
1593 
jsop()1594   JSOp jsop() const { return jsop_; }
left()1595   const LAllocation* left() { return getOperand(0); }
right()1596   const LAllocation* right() { return getOperand(1); }
mir()1597   MCompare* mir() { return mir_->toCompare(); }
extraName()1598   const char* extraName() const { return CodeName(jsop_); }
1599 };
1600 
1601 class LCompareI64 : public LInstructionHelper<1, 2 * INT64_PIECES, 0> {
1602   JSOp jsop_;
1603 
1604  public:
1605   LIR_HEADER(CompareI64)
1606 
1607   static const size_t Lhs = 0;
1608   static const size_t Rhs = INT64_PIECES;
1609 
LCompareI64(JSOp jsop,const LInt64Allocation & left,const LInt64Allocation & right)1610   LCompareI64(JSOp jsop, const LInt64Allocation& left,
1611               const LInt64Allocation& right)
1612       : LInstructionHelper(classOpcode), jsop_(jsop) {
1613     setInt64Operand(Lhs, left);
1614     setInt64Operand(Rhs, right);
1615   }
1616 
jsop()1617   JSOp jsop() const { return jsop_; }
mir()1618   MCompare* mir() { return mir_->toCompare(); }
extraName()1619   const char* extraName() const { return CodeName(jsop_); }
1620 };
1621 
1622 class LCompareI64AndBranch
1623     : public LControlInstructionHelper<2, 2 * INT64_PIECES, 0> {
1624   MCompare* cmpMir_;
1625   JSOp jsop_;
1626 
1627  public:
1628   LIR_HEADER(CompareI64AndBranch)
1629 
1630   static const size_t Lhs = 0;
1631   static const size_t Rhs = INT64_PIECES;
1632 
LCompareI64AndBranch(MCompare * cmpMir,JSOp jsop,const LInt64Allocation & left,const LInt64Allocation & right,MBasicBlock * ifTrue,MBasicBlock * ifFalse)1633   LCompareI64AndBranch(MCompare* cmpMir, JSOp jsop,
1634                        const LInt64Allocation& left,
1635                        const LInt64Allocation& right, MBasicBlock* ifTrue,
1636                        MBasicBlock* ifFalse)
1637       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir), jsop_(jsop) {
1638     setInt64Operand(Lhs, left);
1639     setInt64Operand(Rhs, right);
1640     setSuccessor(0, ifTrue);
1641     setSuccessor(1, ifFalse);
1642   }
1643 
jsop()1644   JSOp jsop() const { return jsop_; }
ifTrue()1645   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1646   MBasicBlock* ifFalse() const { return getSuccessor(1); }
mir()1647   MTest* mir() const { return mir_->toTest(); }
cmpMir()1648   MCompare* cmpMir() const { return cmpMir_; }
extraName()1649   const char* extraName() const { return CodeName(jsop_); }
1650 };
1651 
1652 // Compares two integral values of the same JS type, either integer or object.
1653 // For objects, both operands are in registers.
1654 class LCompareAndBranch : public LControlInstructionHelper<2, 2, 0> {
1655   MCompare* cmpMir_;
1656   JSOp jsop_;
1657 
1658  public:
LIR_HEADER(CompareAndBranch)1659   LIR_HEADER(CompareAndBranch)
1660   LCompareAndBranch(MCompare* cmpMir, JSOp jsop, const LAllocation& left,
1661                     const LAllocation& right, MBasicBlock* ifTrue,
1662                     MBasicBlock* ifFalse)
1663       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir), jsop_(jsop) {
1664     setOperand(0, left);
1665     setOperand(1, right);
1666     setSuccessor(0, ifTrue);
1667     setSuccessor(1, ifFalse);
1668   }
1669 
jsop()1670   JSOp jsop() const { return jsop_; }
ifTrue()1671   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1672   MBasicBlock* ifFalse() const { return getSuccessor(1); }
left()1673   const LAllocation* left() { return getOperand(0); }
right()1674   const LAllocation* right() { return getOperand(1); }
mir()1675   MTest* mir() const { return mir_->toTest(); }
cmpMir()1676   MCompare* cmpMir() const { return cmpMir_; }
extraName()1677   const char* extraName() const { return CodeName(jsop_); }
1678 };
1679 
1680 class LCompareD : public LInstructionHelper<1, 2, 0> {
1681  public:
LIR_HEADER(CompareD)1682   LIR_HEADER(CompareD)
1683   LCompareD(const LAllocation& left, const LAllocation& right)
1684       : LInstructionHelper(classOpcode) {
1685     setOperand(0, left);
1686     setOperand(1, right);
1687   }
1688 
left()1689   const LAllocation* left() { return getOperand(0); }
right()1690   const LAllocation* right() { return getOperand(1); }
mir()1691   MCompare* mir() { return mir_->toCompare(); }
1692 };
1693 
1694 class LCompareF : public LInstructionHelper<1, 2, 0> {
1695  public:
LIR_HEADER(CompareF)1696   LIR_HEADER(CompareF)
1697 
1698   LCompareF(const LAllocation& left, const LAllocation& right)
1699       : LInstructionHelper(classOpcode) {
1700     setOperand(0, left);
1701     setOperand(1, right);
1702   }
1703 
left()1704   const LAllocation* left() { return getOperand(0); }
right()1705   const LAllocation* right() { return getOperand(1); }
mir()1706   MCompare* mir() { return mir_->toCompare(); }
1707 };
1708 
1709 class LCompareDAndBranch : public LControlInstructionHelper<2, 2, 0> {
1710   MCompare* cmpMir_;
1711 
1712  public:
LIR_HEADER(CompareDAndBranch)1713   LIR_HEADER(CompareDAndBranch)
1714 
1715   LCompareDAndBranch(MCompare* cmpMir, const LAllocation& left,
1716                      const LAllocation& right, MBasicBlock* ifTrue,
1717                      MBasicBlock* ifFalse)
1718       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir) {
1719     setOperand(0, left);
1720     setOperand(1, right);
1721     setSuccessor(0, ifTrue);
1722     setSuccessor(1, ifFalse);
1723   }
1724 
ifTrue()1725   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1726   MBasicBlock* ifFalse() const { return getSuccessor(1); }
left()1727   const LAllocation* left() { return getOperand(0); }
right()1728   const LAllocation* right() { return getOperand(1); }
mir()1729   MTest* mir() const { return mir_->toTest(); }
cmpMir()1730   MCompare* cmpMir() const { return cmpMir_; }
1731 };
1732 
1733 class LCompareFAndBranch : public LControlInstructionHelper<2, 2, 0> {
1734   MCompare* cmpMir_;
1735 
1736  public:
LIR_HEADER(CompareFAndBranch)1737   LIR_HEADER(CompareFAndBranch)
1738   LCompareFAndBranch(MCompare* cmpMir, const LAllocation& left,
1739                      const LAllocation& right, MBasicBlock* ifTrue,
1740                      MBasicBlock* ifFalse)
1741       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir) {
1742     setOperand(0, left);
1743     setOperand(1, right);
1744     setSuccessor(0, ifTrue);
1745     setSuccessor(1, ifFalse);
1746   }
1747 
ifTrue()1748   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1749   MBasicBlock* ifFalse() const { return getSuccessor(1); }
left()1750   const LAllocation* left() { return getOperand(0); }
right()1751   const LAllocation* right() { return getOperand(1); }
mir()1752   MTest* mir() const { return mir_->toTest(); }
cmpMir()1753   MCompare* cmpMir() const { return cmpMir_; }
1754 };
1755 
1756 class LCompareS : public LInstructionHelper<1, 2, 0> {
1757  public:
LIR_HEADER(CompareS)1758   LIR_HEADER(CompareS)
1759 
1760   LCompareS(const LAllocation& left, const LAllocation& right)
1761       : LInstructionHelper(classOpcode) {
1762     setOperand(0, left);
1763     setOperand(1, right);
1764   }
1765 
left()1766   const LAllocation* left() { return getOperand(0); }
right()1767   const LAllocation* right() { return getOperand(1); }
mir()1768   MCompare* mir() { return mir_->toCompare(); }
1769 };
1770 
1771 class LCompareBigInt : public LInstructionHelper<1, 2, 3> {
1772  public:
LIR_HEADER(CompareBigInt)1773   LIR_HEADER(CompareBigInt)
1774 
1775   LCompareBigInt(const LAllocation& left, const LAllocation& right,
1776                  const LDefinition& temp1, const LDefinition& temp2,
1777                  const LDefinition& temp3)
1778       : LInstructionHelper(classOpcode) {
1779     setOperand(0, left);
1780     setOperand(1, right);
1781     setTemp(0, temp1);
1782     setTemp(1, temp2);
1783     setTemp(2, temp3);
1784   }
1785 
left()1786   const LAllocation* left() { return getOperand(0); }
right()1787   const LAllocation* right() { return getOperand(1); }
temp1()1788   const LDefinition* temp1() { return getTemp(0); }
temp2()1789   const LDefinition* temp2() { return getTemp(1); }
temp3()1790   const LDefinition* temp3() { return getTemp(2); }
mir()1791   MCompare* mir() { return mir_->toCompare(); }
1792 };
1793 
1794 class LCompareBigIntInt32 : public LInstructionHelper<1, 2, 2> {
1795  public:
LIR_HEADER(CompareBigIntInt32)1796   LIR_HEADER(CompareBigIntInt32)
1797 
1798   LCompareBigIntInt32(const LAllocation& left, const LAllocation& right,
1799                       const LDefinition& temp1, const LDefinition& temp2)
1800       : LInstructionHelper(classOpcode) {
1801     setOperand(0, left);
1802     setOperand(1, right);
1803     setTemp(0, temp1);
1804     setTemp(1, temp2);
1805   }
1806 
left()1807   const LAllocation* left() { return getOperand(0); }
right()1808   const LAllocation* right() { return getOperand(1); }
temp1()1809   const LDefinition* temp1() { return getTemp(0); }
temp2()1810   const LDefinition* temp2() { return getTemp(1); }
mir()1811   MCompare* mir() { return mir_->toCompare(); }
1812 };
1813 
1814 class LCompareBigIntDouble : public LCallInstructionHelper<1, 2, 1> {
1815  public:
LIR_HEADER(CompareBigIntDouble)1816   LIR_HEADER(CompareBigIntDouble)
1817 
1818   LCompareBigIntDouble(const LAllocation& left, const LAllocation& right,
1819                        const LDefinition& temp)
1820       : LCallInstructionHelper(classOpcode) {
1821     setOperand(0, left);
1822     setOperand(1, right);
1823     setTemp(0, temp);
1824   }
1825 
left()1826   const LAllocation* left() { return getOperand(0); }
right()1827   const LAllocation* right() { return getOperand(1); }
temp()1828   const LDefinition* temp() { return getTemp(0); }
mir()1829   MCompare* mir() { return mir_->toCompare(); }
1830 };
1831 
1832 class LCompareBigIntString : public LCallInstructionHelper<1, 2, 0> {
1833  public:
LIR_HEADER(CompareBigIntString)1834   LIR_HEADER(CompareBigIntString)
1835 
1836   LCompareBigIntString(const LAllocation& left, const LAllocation& right)
1837       : LCallInstructionHelper(classOpcode) {
1838     setOperand(0, left);
1839     setOperand(1, right);
1840   }
1841 
left()1842   const LAllocation* left() { return getOperand(0); }
right()1843   const LAllocation* right() { return getOperand(1); }
mir()1844   MCompare* mir() { return mir_->toCompare(); }
1845 };
1846 
1847 class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0> {
1848   Assembler::Condition cond_;
1849 
1850  public:
LIR_HEADER(BitAndAndBranch)1851   LIR_HEADER(BitAndAndBranch)
1852   LBitAndAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse,
1853                    Assembler::Condition cond = Assembler::NonZero)
1854       : LControlInstructionHelper(classOpcode), cond_(cond) {
1855     setSuccessor(0, ifTrue);
1856     setSuccessor(1, ifFalse);
1857   }
1858 
ifTrue()1859   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1860   MBasicBlock* ifFalse() const { return getSuccessor(1); }
left()1861   const LAllocation* left() { return getOperand(0); }
right()1862   const LAllocation* right() { return getOperand(1); }
cond()1863   Assembler::Condition cond() const {
1864     MOZ_ASSERT(cond_ == Assembler::Zero || cond_ == Assembler::NonZero);
1865     return cond_;
1866   }
1867 };
1868 
1869 // Takes a value and tests whether it is null, undefined, or is an object that
1870 // emulates |undefined|, as determined by the JSCLASS_EMULATES_UNDEFINED class
1871 // flag on unwrapped objects.  See also js::EmulatesUndefined.
1872 class LIsNullOrLikeUndefinedV : public LInstructionHelper<1, BOX_PIECES, 2> {
1873  public:
LIR_HEADER(IsNullOrLikeUndefinedV)1874   LIR_HEADER(IsNullOrLikeUndefinedV)
1875 
1876   LIsNullOrLikeUndefinedV(const LBoxAllocation& value, const LDefinition& temp,
1877                           const LDefinition& tempToUnbox)
1878       : LInstructionHelper(classOpcode) {
1879     setBoxOperand(Value, value);
1880     setTemp(0, temp);
1881     setTemp(1, tempToUnbox);
1882   }
1883 
1884   static const size_t Value = 0;
1885 
mir()1886   MCompare* mir() { return mir_->toCompare(); }
1887 
temp()1888   const LDefinition* temp() { return getTemp(0); }
1889 
tempToUnbox()1890   const LDefinition* tempToUnbox() { return getTemp(1); }
1891 };
1892 
1893 // Takes an object pointer and tests whether it is an object that emulates
1894 // |undefined|, as above.
1895 class LIsNullOrLikeUndefinedT : public LInstructionHelper<1, 1, 0> {
1896  public:
LIR_HEADER(IsNullOrLikeUndefinedT)1897   LIR_HEADER(IsNullOrLikeUndefinedT)
1898 
1899   explicit LIsNullOrLikeUndefinedT(const LAllocation& input)
1900       : LInstructionHelper(classOpcode) {
1901     setOperand(0, input);
1902   }
1903 
mir()1904   MCompare* mir() { return mir_->toCompare(); }
1905 };
1906 
1907 class LIsNullOrLikeUndefinedAndBranchV
1908     : public LControlInstructionHelper<2, BOX_PIECES, 2> {
1909   MCompare* cmpMir_;
1910 
1911  public:
LIR_HEADER(IsNullOrLikeUndefinedAndBranchV)1912   LIR_HEADER(IsNullOrLikeUndefinedAndBranchV)
1913 
1914   LIsNullOrLikeUndefinedAndBranchV(MCompare* cmpMir, MBasicBlock* ifTrue,
1915                                    MBasicBlock* ifFalse,
1916                                    const LBoxAllocation& value,
1917                                    const LDefinition& temp,
1918                                    const LDefinition& tempToUnbox)
1919       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir) {
1920     setSuccessor(0, ifTrue);
1921     setSuccessor(1, ifFalse);
1922     setBoxOperand(Value, value);
1923     setTemp(0, temp);
1924     setTemp(1, tempToUnbox);
1925   }
1926 
1927   static const size_t Value = 0;
1928 
ifTrue()1929   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1930   MBasicBlock* ifFalse() const { return getSuccessor(1); }
mir()1931   MTest* mir() const { return mir_->toTest(); }
cmpMir()1932   MCompare* cmpMir() const { return cmpMir_; }
temp()1933   const LDefinition* temp() { return getTemp(0); }
tempToUnbox()1934   const LDefinition* tempToUnbox() { return getTemp(1); }
1935 };
1936 
1937 class LIsNullOrLikeUndefinedAndBranchT
1938     : public LControlInstructionHelper<2, 1, 1> {
1939   MCompare* cmpMir_;
1940 
1941  public:
LIR_HEADER(IsNullOrLikeUndefinedAndBranchT)1942   LIR_HEADER(IsNullOrLikeUndefinedAndBranchT)
1943 
1944   LIsNullOrLikeUndefinedAndBranchT(MCompare* cmpMir, const LAllocation& input,
1945                                    MBasicBlock* ifTrue, MBasicBlock* ifFalse,
1946                                    const LDefinition& temp)
1947       : LControlInstructionHelper(classOpcode), cmpMir_(cmpMir) {
1948     setOperand(0, input);
1949     setSuccessor(0, ifTrue);
1950     setSuccessor(1, ifFalse);
1951     setTemp(0, temp);
1952   }
1953 
ifTrue()1954   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()1955   MBasicBlock* ifFalse() const { return getSuccessor(1); }
mir()1956   MTest* mir() const { return mir_->toTest(); }
cmpMir()1957   MCompare* cmpMir() const { return cmpMir_; }
temp()1958   const LDefinition* temp() { return getTemp(0); }
1959 };
1960 
1961 class LSameValueDouble : public LInstructionHelper<1, 2, 1> {
1962  public:
LIR_HEADER(SameValueDouble)1963   LIR_HEADER(SameValueDouble)
1964   LSameValueDouble(const LAllocation& left, const LAllocation& right,
1965                    const LDefinition& temp)
1966       : LInstructionHelper(classOpcode) {
1967     setOperand(0, left);
1968     setOperand(1, right);
1969     setTemp(0, temp);
1970   }
1971 
left()1972   const LAllocation* left() { return getOperand(0); }
right()1973   const LAllocation* right() { return getOperand(1); }
tempFloat()1974   const LDefinition* tempFloat() { return getTemp(0); }
1975 };
1976 
1977 class LSameValue : public LInstructionHelper<1, 2 * BOX_PIECES, 0> {
1978  public:
LIR_HEADER(SameValue)1979   LIR_HEADER(SameValue)
1980   LSameValue(const LBoxAllocation& lhs, const LBoxAllocation& rhs)
1981       : LInstructionHelper(classOpcode) {
1982     setBoxOperand(LhsIndex, lhs);
1983     setBoxOperand(RhsIndex, rhs);
1984   }
1985 
1986   static const size_t LhsIndex = 0;
1987   static const size_t RhsIndex = BOX_PIECES;
1988 };
1989 
1990 // Not operation on an integer.
1991 class LNotI : public LInstructionHelper<1, 1, 0> {
1992  public:
LIR_HEADER(NotI)1993   LIR_HEADER(NotI)
1994 
1995   explicit LNotI(const LAllocation& input) : LInstructionHelper(classOpcode) {
1996     setOperand(0, input);
1997   }
1998 };
1999 
2000 // Not operation on an int64.
2001 class LNotI64 : public LInstructionHelper<1, INT64_PIECES, 0> {
2002  public:
LIR_HEADER(NotI64)2003   LIR_HEADER(NotI64)
2004 
2005   explicit LNotI64(const LInt64Allocation& input)
2006       : LInstructionHelper(classOpcode) {
2007     setInt64Operand(0, input);
2008   }
2009 };
2010 
2011 // Not operation on a double.
2012 class LNotD : public LInstructionHelper<1, 1, 0> {
2013  public:
LIR_HEADER(NotD)2014   LIR_HEADER(NotD)
2015 
2016   explicit LNotD(const LAllocation& input) : LInstructionHelper(classOpcode) {
2017     setOperand(0, input);
2018   }
2019 
mir()2020   MNot* mir() { return mir_->toNot(); }
2021 };
2022 
2023 // Not operation on a float32.
2024 class LNotF : public LInstructionHelper<1, 1, 0> {
2025  public:
LIR_HEADER(NotF)2026   LIR_HEADER(NotF)
2027 
2028   explicit LNotF(const LAllocation& input) : LInstructionHelper(classOpcode) {
2029     setOperand(0, input);
2030   }
2031 
mir()2032   MNot* mir() { return mir_->toNot(); }
2033 };
2034 
2035 // Not operation on a BigInt.
2036 class LNotBI : public LInstructionHelper<1, 1, 0> {
2037  public:
LIR_HEADER(NotBI)2038   LIR_HEADER(NotBI)
2039 
2040   explicit LNotBI(const LAllocation& input) : LInstructionHelper(classOpcode) {
2041     setOperand(0, input);
2042   }
2043 
mir()2044   MNot* mir() { return mir_->toNot(); }
2045 };
2046 
2047 // Boolean complement operation on an object.
2048 class LNotO : public LInstructionHelper<1, 1, 0> {
2049  public:
LIR_HEADER(NotO)2050   LIR_HEADER(NotO)
2051 
2052   explicit LNotO(const LAllocation& input) : LInstructionHelper(classOpcode) {
2053     setOperand(0, input);
2054   }
2055 
mir()2056   MNot* mir() { return mir_->toNot(); }
2057 };
2058 
2059 // Boolean complement operation on a value.
2060 class LNotV : public LInstructionHelper<1, BOX_PIECES, 3> {
2061  public:
2062   LIR_HEADER(NotV)
2063 
2064   static const size_t Input = 0;
LNotV(const LBoxAllocation & input,const LDefinition & temp0,const LDefinition & temp1,const LDefinition & temp2)2065   LNotV(const LBoxAllocation& input, const LDefinition& temp0,
2066         const LDefinition& temp1, const LDefinition& temp2)
2067       : LInstructionHelper(classOpcode) {
2068     setBoxOperand(Input, input);
2069     setTemp(0, temp0);
2070     setTemp(1, temp1);
2071     setTemp(2, temp2);
2072   }
2073 
tempFloat()2074   const LDefinition* tempFloat() { return getTemp(0); }
2075 
temp1()2076   const LDefinition* temp1() { return getTemp(1); }
2077 
temp2()2078   const LDefinition* temp2() { return getTemp(2); }
2079 
mir()2080   MNot* mir() { return mir_->toNot(); }
2081 };
2082 
2083 // Bitwise not operation, takes a 32-bit integer as input and returning
2084 // a 32-bit integer result as an output.
2085 class LBitNotI : public LInstructionHelper<1, 1, 0> {
2086  public:
LIR_HEADER(BitNotI)2087   LIR_HEADER(BitNotI)
2088 
2089   LBitNotI() : LInstructionHelper(classOpcode) {}
2090 };
2091 
2092 // Binary bitwise operation, taking two 32-bit integers as inputs and returning
2093 // a 32-bit integer result as an output.
2094 class LBitOpI : public LInstructionHelper<1, 2, 0> {
2095   JSOp op_;
2096 
2097  public:
LIR_HEADER(BitOpI)2098   LIR_HEADER(BitOpI)
2099 
2100   explicit LBitOpI(JSOp op) : LInstructionHelper(classOpcode), op_(op) {}
2101 
extraName()2102   const char* extraName() const {
2103     if (bitop() == JSOp::Ursh && mir_->toUrsh()->bailoutsDisabled()) {
2104       return "ursh:BailoutsDisabled";
2105     }
2106     return CodeName(op_);
2107   }
2108 
bitop()2109   JSOp bitop() const { return op_; }
2110 };
2111 
2112 class LBitOpI64 : public LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0> {
2113   JSOp op_;
2114 
2115  public:
2116   LIR_HEADER(BitOpI64)
2117 
2118   static const size_t Lhs = 0;
2119   static const size_t Rhs = INT64_PIECES;
2120 
LBitOpI64(JSOp op)2121   explicit LBitOpI64(JSOp op) : LInstructionHelper(classOpcode), op_(op) {}
2122 
extraName()2123   const char* extraName() const { return CodeName(op_); }
2124 
bitop()2125   JSOp bitop() const { return op_; }
2126 };
2127 
2128 // Shift operation, taking two 32-bit integers as inputs and returning
2129 // a 32-bit integer result as an output.
2130 class LShiftI : public LBinaryMath<0> {
2131   JSOp op_;
2132 
2133  public:
LIR_HEADER(ShiftI)2134   LIR_HEADER(ShiftI)
2135 
2136   explicit LShiftI(JSOp op) : LBinaryMath(classOpcode), op_(op) {}
2137 
bitop()2138   JSOp bitop() { return op_; }
2139 
mir()2140   MInstruction* mir() { return mir_->toInstruction(); }
2141 
extraName()2142   const char* extraName() const { return CodeName(op_); }
2143 };
2144 
2145 class LShiftI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES + 1, 0> {
2146   JSOp op_;
2147 
2148  public:
LIR_HEADER(ShiftI64)2149   LIR_HEADER(ShiftI64)
2150 
2151   explicit LShiftI64(JSOp op) : LInstructionHelper(classOpcode), op_(op) {}
2152 
2153   static const size_t Lhs = 0;
2154   static const size_t Rhs = INT64_PIECES;
2155 
bitop()2156   JSOp bitop() { return op_; }
2157 
mir()2158   MInstruction* mir() { return mir_->toInstruction(); }
2159 
extraName()2160   const char* extraName() const { return CodeName(op_); }
2161 };
2162 
2163 // Sign extension
2164 class LSignExtendInt32 : public LInstructionHelper<1, 1, 0> {
2165   MSignExtendInt32::Mode mode_;
2166 
2167  public:
2168   LIR_HEADER(SignExtendInt32);
2169 
LSignExtendInt32(const LAllocation & num,MSignExtendInt32::Mode mode)2170   explicit LSignExtendInt32(const LAllocation& num, MSignExtendInt32::Mode mode)
2171       : LInstructionHelper(classOpcode), mode_(mode) {
2172     setOperand(0, num);
2173   }
2174 
mode()2175   MSignExtendInt32::Mode mode() { return mode_; }
2176 };
2177 
2178 class LSignExtendInt64
2179     : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 0> {
2180  public:
LIR_HEADER(SignExtendInt64)2181   LIR_HEADER(SignExtendInt64)
2182 
2183   explicit LSignExtendInt64(const LInt64Allocation& input)
2184       : LInstructionHelper(classOpcode) {
2185     setInt64Operand(0, input);
2186   }
2187 
mir()2188   const MSignExtendInt64* mir() const { return mir_->toSignExtendInt64(); }
2189 
mode()2190   MSignExtendInt64::Mode mode() const { return mir()->mode(); }
2191 };
2192 
2193 class LUrshD : public LBinaryMath<1> {
2194  public:
LIR_HEADER(UrshD)2195   LIR_HEADER(UrshD)
2196 
2197   LUrshD(const LAllocation& lhs, const LAllocation& rhs,
2198          const LDefinition& temp)
2199       : LBinaryMath(classOpcode) {
2200     setOperand(0, lhs);
2201     setOperand(1, rhs);
2202     setTemp(0, temp);
2203   }
temp()2204   const LDefinition* temp() { return getTemp(0); }
2205 };
2206 
2207 // Returns from the function being compiled (not used in inlined frames). The
2208 // input must be a box.
2209 class LReturn : public LInstructionHelper<0, BOX_PIECES, 0> {
2210   bool isGenerator_;
2211 
2212  public:
LIR_HEADER(Return)2213   LIR_HEADER(Return)
2214 
2215   explicit LReturn(bool isGenerator)
2216       : LInstructionHelper(classOpcode), isGenerator_(isGenerator) {}
2217 
isGenerator()2218   bool isGenerator() { return isGenerator_; }
2219 };
2220 
2221 class LThrow : public LCallInstructionHelper<0, BOX_PIECES, 0> {
2222  public:
2223   LIR_HEADER(Throw)
2224 
2225   static const size_t Value = 0;
2226 
LThrow(const LBoxAllocation & value)2227   explicit LThrow(const LBoxAllocation& value)
2228       : LCallInstructionHelper(classOpcode) {
2229     setBoxOperand(Value, value);
2230   }
2231 };
2232 
2233 class LMinMaxBase : public LInstructionHelper<1, 2, 0> {
2234  protected:
LMinMaxBase(LNode::Opcode opcode,const LAllocation & first,const LAllocation & second)2235   LMinMaxBase(LNode::Opcode opcode, const LAllocation& first,
2236               const LAllocation& second)
2237       : LInstructionHelper(opcode) {
2238     setOperand(0, first);
2239     setOperand(1, second);
2240   }
2241 
2242  public:
first()2243   const LAllocation* first() { return this->getOperand(0); }
second()2244   const LAllocation* second() { return this->getOperand(1); }
output()2245   const LDefinition* output() { return this->getDef(0); }
mir()2246   MMinMax* mir() const { return mir_->toMinMax(); }
extraName()2247   const char* extraName() const { return mir()->isMax() ? "Max" : "Min"; }
2248 };
2249 
2250 class LMinMaxI : public LMinMaxBase {
2251  public:
LIR_HEADER(MinMaxI)2252   LIR_HEADER(MinMaxI)
2253   LMinMaxI(const LAllocation& first, const LAllocation& second)
2254       : LMinMaxBase(classOpcode, first, second) {}
2255 };
2256 
2257 class LMinMaxD : public LMinMaxBase {
2258  public:
LIR_HEADER(MinMaxD)2259   LIR_HEADER(MinMaxD)
2260   LMinMaxD(const LAllocation& first, const LAllocation& second)
2261       : LMinMaxBase(classOpcode, first, second) {}
2262 };
2263 
2264 class LMinMaxF : public LMinMaxBase {
2265  public:
LIR_HEADER(MinMaxF)2266   LIR_HEADER(MinMaxF)
2267   LMinMaxF(const LAllocation& first, const LAllocation& second)
2268       : LMinMaxBase(classOpcode, first, second) {}
2269 };
2270 
2271 class LMinMaxArrayI : public LInstructionHelper<1, 1, 3> {
2272  public:
2273   LIR_HEADER(MinMaxArrayI);
LMinMaxArrayI(const LAllocation & array,const LDefinition & temp0,const LDefinition & temp1,const LDefinition & temp2)2274   LMinMaxArrayI(const LAllocation& array, const LDefinition& temp0,
2275                 const LDefinition& temp1, const LDefinition& temp2)
2276       : LInstructionHelper(classOpcode) {
2277     setOperand(0, array);
2278     setTemp(0, temp0);
2279     setTemp(1, temp1);
2280     setTemp(2, temp2);
2281   }
2282 
array()2283   const LAllocation* array() { return getOperand(0); }
temp1()2284   const LDefinition* temp1() { return getTemp(0); }
temp2()2285   const LDefinition* temp2() { return getTemp(1); }
temp3()2286   const LDefinition* temp3() { return getTemp(2); }
2287 
isMax()2288   bool isMax() const { return mir_->toMinMaxArray()->isMax(); }
2289 };
2290 
2291 class LMinMaxArrayD : public LInstructionHelper<1, 1, 3> {
2292  public:
2293   LIR_HEADER(MinMaxArrayD);
LMinMaxArrayD(const LAllocation & array,const LDefinition & floatTemp,const LDefinition & temp1,const LDefinition & temp2)2294   LMinMaxArrayD(const LAllocation& array, const LDefinition& floatTemp,
2295                 const LDefinition& temp1, const LDefinition& temp2)
2296       : LInstructionHelper(classOpcode) {
2297     setOperand(0, array);
2298     setTemp(0, floatTemp);
2299     setTemp(1, temp1);
2300     setTemp(2, temp2);
2301   }
2302 
array()2303   const LAllocation* array() { return getOperand(0); }
floatTemp()2304   const LDefinition* floatTemp() { return getTemp(0); }
temp1()2305   const LDefinition* temp1() { return getTemp(1); }
temp2()2306   const LDefinition* temp2() { return getTemp(2); }
2307 
isMax()2308   bool isMax() const { return mir_->toMinMaxArray()->isMax(); }
2309 };
2310 
2311 // Negative of an integer
2312 class LNegI : public LInstructionHelper<1, 1, 0> {
2313  public:
2314   LIR_HEADER(NegI);
LNegI(const LAllocation & num)2315   explicit LNegI(const LAllocation& num) : LInstructionHelper(classOpcode) {
2316     setOperand(0, num);
2317   }
2318 };
2319 
2320 // Negative of an int64
2321 class LNegI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 0> {
2322  public:
2323   LIR_HEADER(NegI64);
LNegI64(const LInt64Allocation & num)2324   explicit LNegI64(const LInt64Allocation& num)
2325       : LInstructionHelper(classOpcode) {
2326     setInt64Operand(0, num);
2327   }
2328 };
2329 
2330 // Negative of a double.
2331 class LNegD : public LInstructionHelper<1, 1, 0> {
2332  public:
LIR_HEADER(NegD)2333   LIR_HEADER(NegD)
2334   explicit LNegD(const LAllocation& num) : LInstructionHelper(classOpcode) {
2335     setOperand(0, num);
2336   }
2337 };
2338 
2339 // Negative of a float32.
2340 class LNegF : public LInstructionHelper<1, 1, 0> {
2341  public:
LIR_HEADER(NegF)2342   LIR_HEADER(NegF)
2343   explicit LNegF(const LAllocation& num) : LInstructionHelper(classOpcode) {
2344     setOperand(0, num);
2345   }
2346 };
2347 
2348 // Absolute value of an integer.
2349 class LAbsI : public LInstructionHelper<1, 1, 0> {
2350  public:
LIR_HEADER(AbsI)2351   LIR_HEADER(AbsI)
2352   explicit LAbsI(const LAllocation& num) : LInstructionHelper(classOpcode) {
2353     setOperand(0, num);
2354   }
2355 
mir()2356   MAbs* mir() const { return mir_->toAbs(); }
2357 };
2358 
2359 // Absolute value of a double.
2360 class LAbsD : public LInstructionHelper<1, 1, 0> {
2361  public:
LIR_HEADER(AbsD)2362   LIR_HEADER(AbsD)
2363   explicit LAbsD(const LAllocation& num) : LInstructionHelper(classOpcode) {
2364     setOperand(0, num);
2365   }
2366 };
2367 
2368 // Absolute value of a float32.
2369 class LAbsF : public LInstructionHelper<1, 1, 0> {
2370  public:
LIR_HEADER(AbsF)2371   LIR_HEADER(AbsF)
2372   explicit LAbsF(const LAllocation& num) : LInstructionHelper(classOpcode) {
2373     setOperand(0, num);
2374   }
2375 };
2376 
2377 // Copysign for doubles.
2378 class LCopySignD : public LInstructionHelper<1, 2, 2> {
2379  public:
LIR_HEADER(CopySignD)2380   LIR_HEADER(CopySignD)
2381   explicit LCopySignD() : LInstructionHelper(classOpcode) {}
2382 };
2383 
2384 // Copysign for float32.
2385 class LCopySignF : public LInstructionHelper<1, 2, 2> {
2386  public:
LIR_HEADER(CopySignF)2387   LIR_HEADER(CopySignF)
2388   explicit LCopySignF() : LInstructionHelper(classOpcode) {}
2389 };
2390 
2391 // Count leading zeroes on an int32.
2392 class LClzI : public LInstructionHelper<1, 1, 0> {
2393  public:
LIR_HEADER(ClzI)2394   LIR_HEADER(ClzI)
2395   explicit LClzI(const LAllocation& num) : LInstructionHelper(classOpcode) {
2396     setOperand(0, num);
2397   }
2398 
mir()2399   MClz* mir() const { return mir_->toClz(); }
2400 };
2401 
2402 // Count leading zeroes on an int64.
2403 class LClzI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 0> {
2404  public:
LIR_HEADER(ClzI64)2405   LIR_HEADER(ClzI64)
2406   explicit LClzI64(const LInt64Allocation& num)
2407       : LInstructionHelper(classOpcode) {
2408     setInt64Operand(0, num);
2409   }
2410 
mir()2411   MClz* mir() const { return mir_->toClz(); }
2412 };
2413 
2414 // Count trailing zeroes on an int32.
2415 class LCtzI : public LInstructionHelper<1, 1, 0> {
2416  public:
LIR_HEADER(CtzI)2417   LIR_HEADER(CtzI)
2418   explicit LCtzI(const LAllocation& num) : LInstructionHelper(classOpcode) {
2419     setOperand(0, num);
2420   }
2421 
mir()2422   MCtz* mir() const { return mir_->toCtz(); }
2423 };
2424 
2425 // Count trailing zeroes on an int64.
2426 class LCtzI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 0> {
2427  public:
LIR_HEADER(CtzI64)2428   LIR_HEADER(CtzI64)
2429   explicit LCtzI64(const LInt64Allocation& num)
2430       : LInstructionHelper(classOpcode) {
2431     setInt64Operand(0, num);
2432   }
2433 
mir()2434   MCtz* mir() const { return mir_->toCtz(); }
2435 };
2436 
2437 // Count population on an int32.
2438 class LPopcntI : public LInstructionHelper<1, 1, 1> {
2439  public:
LIR_HEADER(PopcntI)2440   LIR_HEADER(PopcntI)
2441   explicit LPopcntI(const LAllocation& num, const LDefinition& temp)
2442       : LInstructionHelper(classOpcode) {
2443     setOperand(0, num);
2444     setTemp(0, temp);
2445   }
2446 
mir()2447   MPopcnt* mir() const { return mir_->toPopcnt(); }
2448 
temp()2449   const LDefinition* temp() { return getTemp(0); }
2450 };
2451 
2452 // Count population on an int64.
2453 class LPopcntI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 1> {
2454  public:
LIR_HEADER(PopcntI64)2455   LIR_HEADER(PopcntI64)
2456   explicit LPopcntI64(const LInt64Allocation& num, const LDefinition& temp)
2457       : LInstructionHelper(classOpcode) {
2458     setInt64Operand(0, num);
2459     setTemp(0, temp);
2460   }
2461 
mir()2462   MPopcnt* mir() const { return mir_->toPopcnt(); }
2463 };
2464 
2465 // Square root of a double.
2466 class LSqrtD : public LInstructionHelper<1, 1, 0> {
2467  public:
LIR_HEADER(SqrtD)2468   LIR_HEADER(SqrtD)
2469   explicit LSqrtD(const LAllocation& num) : LInstructionHelper(classOpcode) {
2470     setOperand(0, num);
2471   }
2472 };
2473 
2474 // Square root of a float32.
2475 class LSqrtF : public LInstructionHelper<1, 1, 0> {
2476  public:
LIR_HEADER(SqrtF)2477   LIR_HEADER(SqrtF)
2478   explicit LSqrtF(const LAllocation& num) : LInstructionHelper(classOpcode) {
2479     setOperand(0, num);
2480   }
2481 };
2482 
2483 class LAtan2D : public LCallInstructionHelper<1, 2, 1> {
2484  public:
LIR_HEADER(Atan2D)2485   LIR_HEADER(Atan2D)
2486   LAtan2D(const LAllocation& y, const LAllocation& x, const LDefinition& temp)
2487       : LCallInstructionHelper(classOpcode) {
2488     setOperand(0, y);
2489     setOperand(1, x);
2490     setTemp(0, temp);
2491   }
2492 
y()2493   const LAllocation* y() { return getOperand(0); }
2494 
x()2495   const LAllocation* x() { return getOperand(1); }
2496 
temp()2497   const LDefinition* temp() { return getTemp(0); }
2498 
output()2499   const LDefinition* output() { return getDef(0); }
2500 };
2501 
2502 class LHypot : public LCallInstructionHelper<1, 4, 1> {
2503   uint32_t numOperands_;
2504 
2505  public:
LIR_HEADER(Hypot)2506   LIR_HEADER(Hypot)
2507   LHypot(const LAllocation& x, const LAllocation& y, const LDefinition& temp)
2508       : LCallInstructionHelper(classOpcode), numOperands_(2) {
2509     setOperand(0, x);
2510     setOperand(1, y);
2511     setTemp(0, temp);
2512   }
2513 
LHypot(const LAllocation & x,const LAllocation & y,const LAllocation & z,const LDefinition & temp)2514   LHypot(const LAllocation& x, const LAllocation& y, const LAllocation& z,
2515          const LDefinition& temp)
2516       : LCallInstructionHelper(classOpcode), numOperands_(3) {
2517     setOperand(0, x);
2518     setOperand(1, y);
2519     setOperand(2, z);
2520     setTemp(0, temp);
2521   }
2522 
LHypot(const LAllocation & x,const LAllocation & y,const LAllocation & z,const LAllocation & w,const LDefinition & temp)2523   LHypot(const LAllocation& x, const LAllocation& y, const LAllocation& z,
2524          const LAllocation& w, const LDefinition& temp)
2525       : LCallInstructionHelper(classOpcode), numOperands_(4) {
2526     setOperand(0, x);
2527     setOperand(1, y);
2528     setOperand(2, z);
2529     setOperand(3, w);
2530     setTemp(0, temp);
2531   }
2532 
numArgs()2533   uint32_t numArgs() const { return numOperands_; }
2534 
x()2535   const LAllocation* x() { return getOperand(0); }
2536 
y()2537   const LAllocation* y() { return getOperand(1); }
2538 
temp()2539   const LDefinition* temp() { return getTemp(0); }
2540 
output()2541   const LDefinition* output() { return getDef(0); }
2542 };
2543 
2544 // Double raised to an integer power.
2545 class LPowI : public LCallInstructionHelper<1, 2, 1> {
2546  public:
LIR_HEADER(PowI)2547   LIR_HEADER(PowI)
2548   LPowI(const LAllocation& value, const LAllocation& power,
2549         const LDefinition& temp)
2550       : LCallInstructionHelper(classOpcode) {
2551     setOperand(0, value);
2552     setOperand(1, power);
2553     setTemp(0, temp);
2554   }
2555 
value()2556   const LAllocation* value() { return getOperand(0); }
power()2557   const LAllocation* power() { return getOperand(1); }
temp()2558   const LDefinition* temp() { return getTemp(0); }
2559 };
2560 
2561 // Integer raised to an integer power.
2562 class LPowII : public LInstructionHelper<1, 2, 2> {
2563  public:
LIR_HEADER(PowII)2564   LIR_HEADER(PowII)
2565   LPowII(const LAllocation& value, const LAllocation& power,
2566          const LDefinition& temp1, const LDefinition& temp2)
2567       : LInstructionHelper(classOpcode) {
2568     setOperand(0, value);
2569     setOperand(1, power);
2570     setTemp(0, temp1);
2571     setTemp(1, temp2);
2572   }
2573 
value()2574   const LAllocation* value() { return getOperand(0); }
power()2575   const LAllocation* power() { return getOperand(1); }
temp1()2576   const LDefinition* temp1() { return getTemp(0); }
temp2()2577   const LDefinition* temp2() { return getTemp(1); }
2578 
mir()2579   MPow* mir() const { return mir_->toPow(); }
2580 };
2581 
2582 // Double raised to a double power.
2583 class LPowD : public LCallInstructionHelper<1, 2, 1> {
2584  public:
LIR_HEADER(PowD)2585   LIR_HEADER(PowD)
2586   LPowD(const LAllocation& value, const LAllocation& power,
2587         const LDefinition& temp)
2588       : LCallInstructionHelper(classOpcode) {
2589     setOperand(0, value);
2590     setOperand(1, power);
2591     setTemp(0, temp);
2592   }
2593 
value()2594   const LAllocation* value() { return getOperand(0); }
power()2595   const LAllocation* power() { return getOperand(1); }
temp()2596   const LDefinition* temp() { return getTemp(0); }
2597 };
2598 
2599 // Constant of a power of two raised to an integer power.
2600 class LPowOfTwoI : public LInstructionHelper<1, 1, 0> {
2601   uint32_t base_;
2602 
2603  public:
LIR_HEADER(PowOfTwoI)2604   LIR_HEADER(PowOfTwoI)
2605   LPowOfTwoI(uint32_t base, const LAllocation& power)
2606       : LInstructionHelper(classOpcode), base_(base) {
2607     setOperand(0, power);
2608   }
2609 
base()2610   uint32_t base() const { return base_; }
power()2611   const LAllocation* power() { return getOperand(0); }
2612 };
2613 
2614 // Sign value of an integer.
2615 class LSignI : public LInstructionHelper<1, 1, 0> {
2616  public:
LIR_HEADER(SignI)2617   LIR_HEADER(SignI)
2618   explicit LSignI(const LAllocation& input) : LInstructionHelper(classOpcode) {
2619     setOperand(0, input);
2620   }
2621 };
2622 
2623 // Sign value of a double.
2624 class LSignD : public LInstructionHelper<1, 1, 0> {
2625  public:
LIR_HEADER(SignD)2626   LIR_HEADER(SignD)
2627   explicit LSignD(const LAllocation& input) : LInstructionHelper(classOpcode) {
2628     setOperand(0, input);
2629   }
2630 };
2631 
2632 // Sign value of a double with expected int32 result.
2633 class LSignDI : public LInstructionHelper<1, 1, 1> {
2634  public:
LIR_HEADER(SignDI)2635   LIR_HEADER(SignDI)
2636   explicit LSignDI(const LAllocation& input, const LDefinition& temp)
2637       : LInstructionHelper(classOpcode) {
2638     setOperand(0, input);
2639     setTemp(0, temp);
2640   }
2641 
temp()2642   const LDefinition* temp() { return getTemp(0); }
2643 };
2644 
2645 class LMathFunctionD : public LCallInstructionHelper<1, 1, 1> {
2646  public:
LIR_HEADER(MathFunctionD)2647   LIR_HEADER(MathFunctionD)
2648   LMathFunctionD(const LAllocation& input, const LDefinition& temp)
2649       : LCallInstructionHelper(classOpcode) {
2650     setOperand(0, input);
2651     setTemp(0, temp);
2652   }
2653 
temp()2654   const LDefinition* temp() { return getTemp(0); }
mir()2655   MMathFunction* mir() const { return mir_->toMathFunction(); }
extraName()2656   const char* extraName() const {
2657     return MMathFunction::FunctionName(mir()->function());
2658   }
2659 };
2660 
2661 class LMathFunctionF : public LCallInstructionHelper<1, 1, 1> {
2662  public:
LIR_HEADER(MathFunctionF)2663   LIR_HEADER(MathFunctionF)
2664   LMathFunctionF(const LAllocation& input, const LDefinition& temp)
2665       : LCallInstructionHelper(classOpcode) {
2666     setOperand(0, input);
2667     setTemp(0, temp);
2668   }
2669 
temp()2670   const LDefinition* temp() { return getTemp(0); }
mir()2671   MMathFunction* mir() const { return mir_->toMathFunction(); }
extraName()2672   const char* extraName() const {
2673     return MMathFunction::FunctionName(mir()->function());
2674   }
2675 };
2676 
2677 // Adds two integers, returning an integer value.
2678 class LAddI : public LBinaryMath<0> {
2679   bool recoversInput_;
2680 
2681  public:
LIR_HEADER(AddI)2682   LIR_HEADER(AddI)
2683 
2684   LAddI() : LBinaryMath(classOpcode), recoversInput_(false) {}
2685 
extraName()2686   const char* extraName() const {
2687     return snapshot() ? "OverflowCheck" : nullptr;
2688   }
2689 
recoversInput()2690   bool recoversInput() const { return recoversInput_; }
setRecoversInput()2691   void setRecoversInput() { recoversInput_ = true; }
2692 
mir()2693   MAdd* mir() const { return mir_->toAdd(); }
2694 };
2695 
2696 class LAddI64 : public LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0> {
2697  public:
LIR_HEADER(AddI64)2698   LIR_HEADER(AddI64)
2699 
2700   LAddI64() : LInstructionHelper(classOpcode) {}
2701 
2702   static const size_t Lhs = 0;
2703   static const size_t Rhs = INT64_PIECES;
2704 };
2705 
2706 // Subtracts two integers, returning an integer value.
2707 class LSubI : public LBinaryMath<0> {
2708   bool recoversInput_;
2709 
2710  public:
LIR_HEADER(SubI)2711   LIR_HEADER(SubI)
2712 
2713   LSubI() : LBinaryMath(classOpcode), recoversInput_(false) {}
2714 
extraName()2715   const char* extraName() const {
2716     return snapshot() ? "OverflowCheck" : nullptr;
2717   }
2718 
recoversInput()2719   bool recoversInput() const { return recoversInput_; }
setRecoversInput()2720   void setRecoversInput() { recoversInput_ = true; }
mir()2721   MSub* mir() const { return mir_->toSub(); }
2722 };
2723 
recoversInput()2724 inline bool LNode::recoversInput() const {
2725   switch (op()) {
2726     case Opcode::AddI:
2727       return toAddI()->recoversInput();
2728     case Opcode::SubI:
2729       return toSubI()->recoversInput();
2730     default:
2731       return false;
2732   }
2733 }
2734 
2735 class LSubI64 : public LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0> {
2736  public:
2737   LIR_HEADER(SubI64)
2738 
2739   static const size_t Lhs = 0;
2740   static const size_t Rhs = INT64_PIECES;
2741 
LSubI64()2742   LSubI64() : LInstructionHelper(classOpcode) {}
2743 };
2744 
2745 class LMulI64 : public LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 1> {
2746  public:
LIR_HEADER(MulI64)2747   LIR_HEADER(MulI64)
2748 
2749   explicit LMulI64() : LInstructionHelper(classOpcode) {
2750     setTemp(0, LDefinition());
2751   }
2752 
temp()2753   const LDefinition* temp() { return getTemp(0); }
2754 
2755   static const size_t Lhs = 0;
2756   static const size_t Rhs = INT64_PIECES;
2757 };
2758 
2759 // Performs an add, sub, mul, or div on two double values.
2760 class LMathD : public LBinaryMath<0> {
2761   JSOp jsop_;
2762 
2763  public:
LIR_HEADER(MathD)2764   LIR_HEADER(MathD)
2765 
2766   explicit LMathD(JSOp jsop) : LBinaryMath(classOpcode), jsop_(jsop) {}
2767 
jsop()2768   JSOp jsop() const { return jsop_; }
2769 
extraName()2770   const char* extraName() const { return CodeName(jsop_); }
2771 };
2772 
2773 // Performs an add, sub, mul, or div on two double values.
2774 class LMathF : public LBinaryMath<0> {
2775   JSOp jsop_;
2776 
2777  public:
LIR_HEADER(MathF)2778   LIR_HEADER(MathF)
2779 
2780   explicit LMathF(JSOp jsop) : LBinaryMath(classOpcode), jsop_(jsop) {}
2781 
jsop()2782   JSOp jsop() const { return jsop_; }
2783 
extraName()2784   const char* extraName() const { return CodeName(jsop_); }
2785 };
2786 
2787 class LModD : public LBinaryMath<1> {
2788  public:
LIR_HEADER(ModD)2789   LIR_HEADER(ModD)
2790 
2791   LModD(const LAllocation& lhs, const LAllocation& rhs, const LDefinition& temp)
2792       : LBinaryMath(classOpcode) {
2793     setOperand(0, lhs);
2794     setOperand(1, rhs);
2795     setTemp(0, temp);
2796     setIsCall();
2797   }
temp()2798   const LDefinition* temp() { return getTemp(0); }
mir()2799   MMod* mir() const { return mir_->toMod(); }
2800 };
2801 
2802 class LModPowTwoD : public LInstructionHelper<1, 1, 0> {
2803   const uint32_t divisor_;
2804 
2805  public:
LIR_HEADER(ModPowTwoD)2806   LIR_HEADER(ModPowTwoD)
2807 
2808   LModPowTwoD(const LAllocation& lhs, uint32_t divisor)
2809       : LInstructionHelper(classOpcode), divisor_(divisor) {
2810     setOperand(0, lhs);
2811   }
2812 
divisor()2813   uint32_t divisor() const { return divisor_; }
lhs()2814   const LAllocation* lhs() { return getOperand(0); }
mir()2815   MMod* mir() const { return mir_->toMod(); }
2816 };
2817 
2818 class LWasmBuiltinModD : public LInstructionHelper<1, 3, 0> {
2819   static const size_t LhsIndex = 0;
2820   static const size_t RhsIndex = 1;
2821   static const size_t TlsIndex = 2;
2822 
2823  public:
LIR_HEADER(WasmBuiltinModD)2824   LIR_HEADER(WasmBuiltinModD)
2825 
2826   LWasmBuiltinModD(const LAllocation& lhs, const LAllocation& rhs,
2827                    const LAllocation& tls)
2828       : LInstructionHelper(classOpcode) {
2829     setOperand(LhsIndex, lhs);
2830     setOperand(RhsIndex, rhs);
2831     setOperand(TlsIndex, tls);
2832     setIsCall();
2833   }
2834 
lhs()2835   const LAllocation* lhs() { return this->getOperand(LhsIndex); }
rhs()2836   const LAllocation* rhs() { return this->getOperand(RhsIndex); }
tls()2837   const LAllocation* tls() { return this->getOperand(TlsIndex); }
2838 
mir()2839   MWasmBuiltinModD* mir() const { return mir_->toWasmBuiltinModD(); }
2840 };
2841 
2842 class LBigIntAdd : public LBinaryMath<2> {
2843  public:
LIR_HEADER(BigIntAdd)2844   LIR_HEADER(BigIntAdd)
2845 
2846   LBigIntAdd(const LAllocation& lhs, const LAllocation& rhs,
2847              const LDefinition& temp1, const LDefinition& temp2)
2848       : LBinaryMath(classOpcode) {
2849     setOperand(0, lhs);
2850     setOperand(1, rhs);
2851     setTemp(0, temp1);
2852     setTemp(1, temp2);
2853   }
2854 
temp1()2855   const LDefinition* temp1() { return getTemp(0); }
temp2()2856   const LDefinition* temp2() { return getTemp(1); }
2857 };
2858 
2859 class LBigIntSub : public LBinaryMath<2> {
2860  public:
LIR_HEADER(BigIntSub)2861   LIR_HEADER(BigIntSub)
2862 
2863   LBigIntSub(const LAllocation& lhs, const LAllocation& rhs,
2864              const LDefinition& temp1, const LDefinition& temp2)
2865       : LBinaryMath(classOpcode) {
2866     setOperand(0, lhs);
2867     setOperand(1, rhs);
2868     setTemp(0, temp1);
2869     setTemp(1, temp2);
2870   }
2871 
temp1()2872   const LDefinition* temp1() { return getTemp(0); }
temp2()2873   const LDefinition* temp2() { return getTemp(1); }
2874 };
2875 
2876 class LBigIntMul : public LBinaryMath<2> {
2877  public:
LIR_HEADER(BigIntMul)2878   LIR_HEADER(BigIntMul)
2879 
2880   LBigIntMul(const LAllocation& lhs, const LAllocation& rhs,
2881              const LDefinition& temp1, const LDefinition& temp2)
2882       : LBinaryMath(classOpcode) {
2883     setOperand(0, lhs);
2884     setOperand(1, rhs);
2885     setTemp(0, temp1);
2886     setTemp(1, temp2);
2887   }
2888 
temp1()2889   const LDefinition* temp1() { return getTemp(0); }
temp2()2890   const LDefinition* temp2() { return getTemp(1); }
2891 };
2892 
2893 class LBigIntDiv : public LBinaryMath<2> {
2894  public:
LIR_HEADER(BigIntDiv)2895   LIR_HEADER(BigIntDiv)
2896 
2897   LBigIntDiv(const LAllocation& lhs, const LAllocation& rhs,
2898              const LDefinition& temp1, const LDefinition& temp2)
2899       : LBinaryMath(classOpcode) {
2900     setOperand(0, lhs);
2901     setOperand(1, rhs);
2902     setTemp(0, temp1);
2903     setTemp(1, temp2);
2904   }
2905 
temp1()2906   const LDefinition* temp1() { return getTemp(0); }
temp2()2907   const LDefinition* temp2() { return getTemp(1); }
2908 
mir()2909   const MBigIntDiv* mir() const { return mirRaw()->toBigIntDiv(); }
2910 };
2911 
2912 class LBigIntMod : public LBinaryMath<2> {
2913  public:
LIR_HEADER(BigIntMod)2914   LIR_HEADER(BigIntMod)
2915 
2916   LBigIntMod(const LAllocation& lhs, const LAllocation& rhs,
2917              const LDefinition& temp1, const LDefinition& temp2)
2918       : LBinaryMath(classOpcode) {
2919     setOperand(0, lhs);
2920     setOperand(1, rhs);
2921     setTemp(0, temp1);
2922     setTemp(1, temp2);
2923   }
2924 
temp1()2925   const LDefinition* temp1() { return getTemp(0); }
temp2()2926   const LDefinition* temp2() { return getTemp(1); }
2927 
mir()2928   const MBigIntMod* mir() const { return mirRaw()->toBigIntMod(); }
2929 };
2930 
2931 class LBigIntPow : public LBinaryMath<2> {
2932  public:
LIR_HEADER(BigIntPow)2933   LIR_HEADER(BigIntPow)
2934 
2935   LBigIntPow(const LAllocation& lhs, const LAllocation& rhs,
2936              const LDefinition& temp1, const LDefinition& temp2)
2937       : LBinaryMath(classOpcode) {
2938     setOperand(0, lhs);
2939     setOperand(1, rhs);
2940     setTemp(0, temp1);
2941     setTemp(1, temp2);
2942   }
2943 
temp1()2944   const LDefinition* temp1() { return getTemp(0); }
temp2()2945   const LDefinition* temp2() { return getTemp(1); }
2946 
mir()2947   const MBigIntPow* mir() const { return mirRaw()->toBigIntPow(); }
2948 };
2949 
2950 class LBigIntBitAnd : public LBinaryMath<2> {
2951  public:
LIR_HEADER(BigIntBitAnd)2952   LIR_HEADER(BigIntBitAnd)
2953 
2954   LBigIntBitAnd(const LAllocation& lhs, const LAllocation& rhs,
2955                 const LDefinition& temp1, const LDefinition& temp2)
2956       : LBinaryMath(classOpcode) {
2957     setOperand(0, lhs);
2958     setOperand(1, rhs);
2959     setTemp(0, temp1);
2960     setTemp(1, temp2);
2961   }
2962 
temp1()2963   const LDefinition* temp1() { return getTemp(0); }
temp2()2964   const LDefinition* temp2() { return getTemp(1); }
2965 };
2966 
2967 class LBigIntBitOr : public LBinaryMath<2> {
2968  public:
LIR_HEADER(BigIntBitOr)2969   LIR_HEADER(BigIntBitOr)
2970 
2971   LBigIntBitOr(const LAllocation& lhs, const LAllocation& rhs,
2972                const LDefinition& temp1, const LDefinition& temp2)
2973       : LBinaryMath(classOpcode) {
2974     setOperand(0, lhs);
2975     setOperand(1, rhs);
2976     setTemp(0, temp1);
2977     setTemp(1, temp2);
2978   }
2979 
temp1()2980   const LDefinition* temp1() { return getTemp(0); }
temp2()2981   const LDefinition* temp2() { return getTemp(1); }
2982 };
2983 
2984 class LBigIntBitXor : public LBinaryMath<2> {
2985  public:
LIR_HEADER(BigIntBitXor)2986   LIR_HEADER(BigIntBitXor)
2987 
2988   LBigIntBitXor(const LAllocation& lhs, const LAllocation& rhs,
2989                 const LDefinition& temp1, const LDefinition& temp2)
2990       : LBinaryMath(classOpcode) {
2991     setOperand(0, lhs);
2992     setOperand(1, rhs);
2993     setTemp(0, temp1);
2994     setTemp(1, temp2);
2995   }
2996 
temp1()2997   const LDefinition* temp1() { return getTemp(0); }
temp2()2998   const LDefinition* temp2() { return getTemp(1); }
2999 };
3000 
3001 class LBigIntLsh : public LBinaryMath<3> {
3002  public:
LIR_HEADER(BigIntLsh)3003   LIR_HEADER(BigIntLsh)
3004 
3005   LBigIntLsh(const LAllocation& lhs, const LAllocation& rhs,
3006              const LDefinition& temp1, const LDefinition& temp2,
3007              const LDefinition& temp3)
3008       : LBinaryMath(classOpcode) {
3009     setOperand(0, lhs);
3010     setOperand(1, rhs);
3011     setTemp(0, temp1);
3012     setTemp(1, temp2);
3013     setTemp(2, temp3);
3014   }
3015 
temp1()3016   const LDefinition* temp1() { return getTemp(0); }
temp2()3017   const LDefinition* temp2() { return getTemp(1); }
temp3()3018   const LDefinition* temp3() { return getTemp(2); }
3019 };
3020 
3021 class LBigIntRsh : public LBinaryMath<3> {
3022  public:
LIR_HEADER(BigIntRsh)3023   LIR_HEADER(BigIntRsh)
3024 
3025   LBigIntRsh(const LAllocation& lhs, const LAllocation& rhs,
3026              const LDefinition& temp1, const LDefinition& temp2,
3027              const LDefinition& temp3)
3028       : LBinaryMath(classOpcode) {
3029     setOperand(0, lhs);
3030     setOperand(1, rhs);
3031     setTemp(0, temp1);
3032     setTemp(1, temp2);
3033     setTemp(2, temp3);
3034   }
3035 
temp1()3036   const LDefinition* temp1() { return getTemp(0); }
temp2()3037   const LDefinition* temp2() { return getTemp(1); }
temp3()3038   const LDefinition* temp3() { return getTemp(2); }
3039 };
3040 
3041 class LBigIntIncrement : public LUnaryMath<2> {
3042  public:
LIR_HEADER(BigIntIncrement)3043   LIR_HEADER(BigIntIncrement)
3044 
3045   LBigIntIncrement(const LAllocation& input, const LDefinition& temp1,
3046                    const LDefinition& temp2)
3047       : LUnaryMath(classOpcode) {
3048     setOperand(0, input);
3049     setTemp(0, temp1);
3050     setTemp(1, temp2);
3051   }
3052 
temp1()3053   const LDefinition* temp1() { return getTemp(0); }
temp2()3054   const LDefinition* temp2() { return getTemp(1); }
3055 };
3056 
3057 class LBigIntDecrement : public LUnaryMath<2> {
3058  public:
LIR_HEADER(BigIntDecrement)3059   LIR_HEADER(BigIntDecrement)
3060 
3061   LBigIntDecrement(const LAllocation& input, const LDefinition& temp1,
3062                    const LDefinition& temp2)
3063       : LUnaryMath(classOpcode) {
3064     setOperand(0, input);
3065     setTemp(0, temp1);
3066     setTemp(1, temp2);
3067   }
3068 
temp1()3069   const LDefinition* temp1() { return getTemp(0); }
temp2()3070   const LDefinition* temp2() { return getTemp(1); }
3071 };
3072 
3073 class LBigIntNegate : public LUnaryMath<1> {
3074  public:
LIR_HEADER(BigIntNegate)3075   LIR_HEADER(BigIntNegate)
3076 
3077   LBigIntNegate(const LAllocation& input, const LDefinition& temp)
3078       : LUnaryMath(classOpcode) {
3079     setOperand(0, input);
3080     setTemp(0, temp);
3081   }
3082 
temp()3083   const LDefinition* temp() { return getTemp(0); }
3084 };
3085 
3086 class LBigIntBitNot : public LUnaryMath<2> {
3087  public:
LIR_HEADER(BigIntBitNot)3088   LIR_HEADER(BigIntBitNot)
3089 
3090   LBigIntBitNot(const LAllocation& input, const LDefinition& temp1,
3091                 const LDefinition& temp2)
3092       : LUnaryMath(classOpcode) {
3093     setOperand(0, input);
3094     setTemp(0, temp1);
3095     setTemp(1, temp2);
3096   }
3097 
temp1()3098   const LDefinition* temp1() { return getTemp(0); }
temp2()3099   const LDefinition* temp2() { return getTemp(1); }
3100 };
3101 
3102 // Adds two string, returning a string.
3103 class LConcat : public LInstructionHelper<1, 2, 5> {
3104  public:
LIR_HEADER(Concat)3105   LIR_HEADER(Concat)
3106 
3107   LConcat(const LAllocation& lhs, const LAllocation& rhs,
3108           const LDefinition& temp1, const LDefinition& temp2,
3109           const LDefinition& temp3, const LDefinition& temp4,
3110           const LDefinition& temp5)
3111       : LInstructionHelper(classOpcode) {
3112     setOperand(0, lhs);
3113     setOperand(1, rhs);
3114     setTemp(0, temp1);
3115     setTemp(1, temp2);
3116     setTemp(2, temp3);
3117     setTemp(3, temp4);
3118     setTemp(4, temp5);
3119   }
3120 
lhs()3121   const LAllocation* lhs() { return this->getOperand(0); }
rhs()3122   const LAllocation* rhs() { return this->getOperand(1); }
temp1()3123   const LDefinition* temp1() { return this->getTemp(0); }
temp2()3124   const LDefinition* temp2() { return this->getTemp(1); }
temp3()3125   const LDefinition* temp3() { return this->getTemp(2); }
temp4()3126   const LDefinition* temp4() { return this->getTemp(3); }
temp5()3127   const LDefinition* temp5() { return this->getTemp(4); }
3128 };
3129 
3130 // Get uint16 character code from a string.
3131 class LCharCodeAt : public LInstructionHelper<1, 2, 1> {
3132  public:
LIR_HEADER(CharCodeAt)3133   LIR_HEADER(CharCodeAt)
3134 
3135   LCharCodeAt(const LAllocation& str, const LAllocation& index,
3136               const LDefinition& temp)
3137       : LInstructionHelper(classOpcode) {
3138     setOperand(0, str);
3139     setOperand(1, index);
3140     setTemp(0, temp);
3141   }
3142 
str()3143   const LAllocation* str() { return this->getOperand(0); }
index()3144   const LAllocation* index() { return this->getOperand(1); }
temp()3145   const LDefinition* temp() { return getTemp(0); }
3146 };
3147 
3148 // Convert uint16 character code to a string.
3149 class LFromCharCode : public LInstructionHelper<1, 1, 0> {
3150  public:
LIR_HEADER(FromCharCode)3151   LIR_HEADER(FromCharCode)
3152 
3153   explicit LFromCharCode(const LAllocation& code)
3154       : LInstructionHelper(classOpcode) {
3155     setOperand(0, code);
3156   }
3157 
code()3158   const LAllocation* code() { return this->getOperand(0); }
3159 };
3160 
3161 // Convert uint32 code point to a string.
3162 class LFromCodePoint : public LInstructionHelper<1, 1, 2> {
3163  public:
LIR_HEADER(FromCodePoint)3164   LIR_HEADER(FromCodePoint)
3165 
3166   explicit LFromCodePoint(const LAllocation& codePoint,
3167                           const LDefinition& temp1, const LDefinition& temp2)
3168       : LInstructionHelper(classOpcode) {
3169     setOperand(0, codePoint);
3170     setTemp(0, temp1);
3171     setTemp(1, temp2);
3172   }
3173 
codePoint()3174   const LAllocation* codePoint() { return this->getOperand(0); }
3175 
temp1()3176   const LDefinition* temp1() { return this->getTemp(0); }
3177 
temp2()3178   const LDefinition* temp2() { return this->getTemp(1); }
3179 };
3180 
3181 // Calls the ToLowerCase or ToUpperCase case conversion function.
3182 class LStringConvertCase : public LCallInstructionHelper<1, 1, 0> {
3183  public:
LIR_HEADER(StringConvertCase)3184   LIR_HEADER(StringConvertCase)
3185 
3186   explicit LStringConvertCase(const LAllocation& string)
3187       : LCallInstructionHelper(classOpcode) {
3188     setOperand(0, string);
3189   }
3190 
mir()3191   const MStringConvertCase* mir() const { return mir_->toStringConvertCase(); }
3192 
string()3193   const LAllocation* string() { return this->getOperand(0); }
3194 };
3195 
3196 class LStringSplit : public LCallInstructionHelper<1, 2, 0> {
3197  public:
LIR_HEADER(StringSplit)3198   LIR_HEADER(StringSplit)
3199 
3200   LStringSplit(const LAllocation& string, const LAllocation& separator)
3201       : LCallInstructionHelper(classOpcode) {
3202     setOperand(0, string);
3203     setOperand(1, separator);
3204   }
string()3205   const LAllocation* string() { return getOperand(0); }
separator()3206   const LAllocation* separator() { return getOperand(1); }
mir()3207   const MStringSplit* mir() const { return mir_->toStringSplit(); }
3208 };
3209 
3210 class LSubstr : public LInstructionHelper<1, 3, 3> {
3211  public:
LIR_HEADER(Substr)3212   LIR_HEADER(Substr)
3213 
3214   LSubstr(const LAllocation& string, const LAllocation& begin,
3215           const LAllocation& length, const LDefinition& temp,
3216           const LDefinition& temp2, const LDefinition& temp3)
3217       : LInstructionHelper(classOpcode) {
3218     setOperand(0, string);
3219     setOperand(1, begin);
3220     setOperand(2, length);
3221     setTemp(0, temp);
3222     setTemp(1, temp2);
3223     setTemp(2, temp3);
3224   }
string()3225   const LAllocation* string() { return getOperand(0); }
begin()3226   const LAllocation* begin() { return getOperand(1); }
length()3227   const LAllocation* length() { return getOperand(2); }
temp()3228   const LDefinition* temp() { return getTemp(0); }
temp2()3229   const LDefinition* temp2() { return getTemp(1); }
temp3()3230   const LDefinition* temp3() { return getTemp(2); }
mir()3231   const MStringSplit* mir() const { return mir_->toStringSplit(); }
3232 };
3233 
3234 // Convert a 32-bit integer to a double.
3235 class LInt32ToDouble : public LInstructionHelper<1, 1, 0> {
3236  public:
LIR_HEADER(Int32ToDouble)3237   LIR_HEADER(Int32ToDouble)
3238 
3239   explicit LInt32ToDouble(const LAllocation& input)
3240       : LInstructionHelper(classOpcode) {
3241     setOperand(0, input);
3242   }
3243 };
3244 
3245 // Convert a 32-bit float to a double.
3246 class LFloat32ToDouble : public LInstructionHelper<1, 1, 0> {
3247  public:
LIR_HEADER(Float32ToDouble)3248   LIR_HEADER(Float32ToDouble)
3249 
3250   explicit LFloat32ToDouble(const LAllocation& input)
3251       : LInstructionHelper(classOpcode) {
3252     setOperand(0, input);
3253   }
3254 };
3255 
3256 // Convert a double to a 32-bit float.
3257 class LDoubleToFloat32 : public LInstructionHelper<1, 1, 0> {
3258  public:
LIR_HEADER(DoubleToFloat32)3259   LIR_HEADER(DoubleToFloat32)
3260 
3261   explicit LDoubleToFloat32(const LAllocation& input)
3262       : LInstructionHelper(classOpcode) {
3263     setOperand(0, input);
3264   }
3265 };
3266 
3267 // Convert a 32-bit integer to a float32.
3268 class LInt32ToFloat32 : public LInstructionHelper<1, 1, 0> {
3269  public:
LIR_HEADER(Int32ToFloat32)3270   LIR_HEADER(Int32ToFloat32)
3271 
3272   explicit LInt32ToFloat32(const LAllocation& input)
3273       : LInstructionHelper(classOpcode) {
3274     setOperand(0, input);
3275   }
3276 };
3277 
3278 // Convert a value to a double.
3279 class LValueToDouble : public LInstructionHelper<1, BOX_PIECES, 0> {
3280  public:
3281   LIR_HEADER(ValueToDouble)
3282   static const size_t Input = 0;
3283 
LValueToDouble(const LBoxAllocation & input)3284   explicit LValueToDouble(const LBoxAllocation& input)
3285       : LInstructionHelper(classOpcode) {
3286     setBoxOperand(Input, input);
3287   }
3288 
mir()3289   MToDouble* mir() { return mir_->toToDouble(); }
3290 };
3291 
3292 // Convert a value to a float32.
3293 class LValueToFloat32 : public LInstructionHelper<1, BOX_PIECES, 0> {
3294  public:
3295   LIR_HEADER(ValueToFloat32)
3296   static const size_t Input = 0;
3297 
LValueToFloat32(const LBoxAllocation & input)3298   explicit LValueToFloat32(const LBoxAllocation& input)
3299       : LInstructionHelper(classOpcode) {
3300     setBoxOperand(Input, input);
3301   }
3302 
mir()3303   MToFloat32* mir() { return mir_->toToFloat32(); }
3304 };
3305 
3306 // Convert a value to an int32.
3307 //   Input: components of a Value
3308 //   Output: 32-bit integer
3309 //   Bailout: undefined, string, object, or non-int32 double
3310 //   Temps: one float register, one GP register
3311 //
3312 // This instruction requires a temporary float register.
3313 class LValueToInt32 : public LInstructionHelper<1, BOX_PIECES, 2> {
3314  public:
3315   enum Mode { NORMAL, TRUNCATE, TRUNCATE_NOWRAP };
3316 
3317  private:
3318   Mode mode_;
3319 
3320  public:
LIR_HEADER(ValueToInt32)3321   LIR_HEADER(ValueToInt32)
3322 
3323   LValueToInt32(const LBoxAllocation& input, const LDefinition& temp0,
3324                 const LDefinition& temp1, Mode mode)
3325       : LInstructionHelper(classOpcode), mode_(mode) {
3326     setBoxOperand(Input, input);
3327     setTemp(0, temp0);
3328     setTemp(1, temp1);
3329   }
3330 
extraName()3331   const char* extraName() const {
3332     return mode() == NORMAL     ? "Normal"
3333            : mode() == TRUNCATE ? "Truncate"
3334                                 : "TruncateNoWrap";
3335   }
3336 
3337   static const size_t Input = 0;
3338 
mode()3339   Mode mode() const { return mode_; }
tempFloat()3340   const LDefinition* tempFloat() { return getTemp(0); }
temp()3341   const LDefinition* temp() { return getTemp(1); }
mirNormal()3342   MToNumberInt32* mirNormal() const {
3343     MOZ_ASSERT(mode_ == NORMAL);
3344     return mir_->toToNumberInt32();
3345   }
mirTruncate()3346   MTruncateToInt32* mirTruncate() const {
3347     MOZ_ASSERT(mode_ == TRUNCATE);
3348     return mir_->toTruncateToInt32();
3349   }
mirTruncateNoWrap()3350   MToIntegerInt32* mirTruncateNoWrap() const {
3351     MOZ_ASSERT(mode_ == TRUNCATE_NOWRAP);
3352     return mir_->toToIntegerInt32();
3353   }
mir()3354   MInstruction* mir() const { return mir_->toInstruction(); }
3355 };
3356 
3357 // Convert a value to a BigInt.
3358 class LValueToBigInt : public LInstructionHelper<1, BOX_PIECES, 0> {
3359  public:
3360   LIR_HEADER(ValueToBigInt)
3361   static const size_t Input = 0;
3362 
LValueToBigInt(const LBoxAllocation & input)3363   explicit LValueToBigInt(const LBoxAllocation& input)
3364       : LInstructionHelper(classOpcode) {
3365     setBoxOperand(Input, input);
3366   }
3367 
mir()3368   MToBigInt* mir() const { return mir_->toToBigInt(); }
3369 };
3370 
3371 // Convert a double to an int32.
3372 //   Input: floating-point register
3373 //   Output: 32-bit integer
3374 //   Bailout: if the double cannot be converted to an integer.
3375 class LDoubleToInt32 : public LInstructionHelper<1, 1, 0> {
3376  public:
LIR_HEADER(DoubleToInt32)3377   LIR_HEADER(DoubleToInt32)
3378 
3379   explicit LDoubleToInt32(const LAllocation& in)
3380       : LInstructionHelper(classOpcode) {
3381     setOperand(0, in);
3382   }
3383 
mir()3384   MToNumberInt32* mir() const { return mir_->toToNumberInt32(); }
3385 };
3386 
3387 // Convert a float32 to an int32.
3388 //   Input: floating-point register
3389 //   Output: 32-bit integer
3390 //   Bailout: if the float32 cannot be converted to an integer.
3391 class LFloat32ToInt32 : public LInstructionHelper<1, 1, 0> {
3392  public:
LIR_HEADER(Float32ToInt32)3393   LIR_HEADER(Float32ToInt32)
3394 
3395   explicit LFloat32ToInt32(const LAllocation& in)
3396       : LInstructionHelper(classOpcode) {
3397     setOperand(0, in);
3398   }
3399 
mir()3400   MToNumberInt32* mir() const { return mir_->toToNumberInt32(); }
3401 };
3402 
3403 // Truncates a double to an int32.
3404 //   Input: floating-point register
3405 //   Output: 32-bit integer
3406 //   Bailout: if the double when converted to an integer exceeds the int32
3407 //            bounds. No bailout for NaN or negative zero.
3408 class LDoubleToIntegerInt32 : public LInstructionHelper<1, 1, 0> {
3409  public:
LIR_HEADER(DoubleToIntegerInt32)3410   LIR_HEADER(DoubleToIntegerInt32)
3411 
3412   explicit LDoubleToIntegerInt32(const LAllocation& in)
3413       : LInstructionHelper(classOpcode) {
3414     setOperand(0, in);
3415   }
3416 
mir()3417   MToIntegerInt32* mir() const { return mir_->toToIntegerInt32(); }
3418 };
3419 
3420 // Truncates a float to an int32.
3421 //   Input: floating-point register
3422 //   Output: 32-bit integer
3423 //   Bailout: if the double when converted to an integer exceeds the int32
3424 //            bounds. No bailout for NaN or negative zero.
3425 class LFloat32ToIntegerInt32 : public LInstructionHelper<1, 1, 0> {
3426  public:
LIR_HEADER(Float32ToIntegerInt32)3427   LIR_HEADER(Float32ToIntegerInt32)
3428 
3429   explicit LFloat32ToIntegerInt32(const LAllocation& in)
3430       : LInstructionHelper(classOpcode) {
3431     setOperand(0, in);
3432   }
3433 
mir()3434   MToIntegerInt32* mir() const { return mir_->toToIntegerInt32(); }
3435 };
3436 
3437 // Convert a double to a truncated int32.
3438 //   Input: floating-point register
3439 //   Output: 32-bit integer
3440 class LTruncateDToInt32 : public LInstructionHelper<1, 1, 1> {
3441  public:
LIR_HEADER(TruncateDToInt32)3442   LIR_HEADER(TruncateDToInt32)
3443 
3444   LTruncateDToInt32(const LAllocation& in, const LDefinition& temp)
3445       : LInstructionHelper(classOpcode) {
3446     setOperand(0, in);
3447     setTemp(0, temp);
3448   }
3449 
tempFloat()3450   const LDefinition* tempFloat() { return getTemp(0); }
3451 
mir()3452   MTruncateToInt32* mir() const { return mir_->toTruncateToInt32(); }
3453 };
3454 
3455 // Convert a double to a truncated int32 with tls offset because we need it for
3456 // the slow ool path.
3457 class LWasmBuiltinTruncateDToInt32 : public LInstructionHelper<1, 2, 1> {
3458  public:
LIR_HEADER(WasmBuiltinTruncateDToInt32)3459   LIR_HEADER(WasmBuiltinTruncateDToInt32)
3460 
3461   LWasmBuiltinTruncateDToInt32(const LAllocation& in, const LAllocation& tls,
3462                                const LDefinition& temp)
3463       : LInstructionHelper(classOpcode) {
3464     setOperand(0, in);
3465     setOperand(1, tls);
3466     setTemp(0, temp);
3467   }
3468 
tempFloat()3469   const LDefinition* tempFloat() { return getTemp(0); }
3470 
mir()3471   MWasmBuiltinTruncateToInt32* mir() const {
3472     return mir_->toWasmBuiltinTruncateToInt32();
3473   }
3474 };
3475 
3476 // Convert a float32 to a truncated int32.
3477 //   Input: floating-point register
3478 //   Output: 32-bit integer
3479 class LTruncateFToInt32 : public LInstructionHelper<1, 1, 1> {
3480  public:
LIR_HEADER(TruncateFToInt32)3481   LIR_HEADER(TruncateFToInt32)
3482 
3483   LTruncateFToInt32(const LAllocation& in, const LDefinition& temp)
3484       : LInstructionHelper(classOpcode) {
3485     setOperand(0, in);
3486     setTemp(0, temp);
3487   }
3488 
tempFloat()3489   const LDefinition* tempFloat() { return getTemp(0); }
3490 
mir()3491   MTruncateToInt32* mir() const { return mir_->toTruncateToInt32(); }
3492 };
3493 
3494 // Convert a float32 to a truncated int32 with tls offset because we need it for
3495 // the slow ool path.
3496 class LWasmBuiltinTruncateFToInt32 : public LInstructionHelper<1, 2, 1> {
3497  public:
LIR_HEADER(WasmBuiltinTruncateFToInt32)3498   LIR_HEADER(WasmBuiltinTruncateFToInt32)
3499 
3500   LWasmBuiltinTruncateFToInt32(const LAllocation& in, const LAllocation& tls,
3501                                const LDefinition& temp)
3502       : LInstructionHelper(classOpcode) {
3503     setOperand(0, in);
3504     setOperand(1, tls);
3505     setTemp(0, temp);
3506   }
3507 
tempFloat()3508   const LDefinition* tempFloat() { return getTemp(0); }
3509 
mir()3510   MWasmBuiltinTruncateToInt32* mir() const {
3511     return mir_->toWasmBuiltinTruncateToInt32();
3512   }
3513 };
3514 
3515 class LWasmTruncateToInt32 : public LInstructionHelper<1, 1, 0> {
3516  public:
LIR_HEADER(WasmTruncateToInt32)3517   LIR_HEADER(WasmTruncateToInt32)
3518 
3519   explicit LWasmTruncateToInt32(const LAllocation& in)
3520       : LInstructionHelper(classOpcode) {
3521     setOperand(0, in);
3522   }
3523 
mir()3524   MWasmTruncateToInt32* mir() const { return mir_->toWasmTruncateToInt32(); }
3525 };
3526 
3527 class LWrapInt64ToInt32 : public LInstructionHelper<1, INT64_PIECES, 0> {
3528  public:
3529   LIR_HEADER(WrapInt64ToInt32)
3530 
3531   static const size_t Input = 0;
3532 
LWrapInt64ToInt32(const LInt64Allocation & input)3533   explicit LWrapInt64ToInt32(const LInt64Allocation& input)
3534       : LInstructionHelper(classOpcode) {
3535     setInt64Operand(Input, input);
3536   }
3537 
mir()3538   const MWrapInt64ToInt32* mir() { return mir_->toWrapInt64ToInt32(); }
3539 };
3540 
3541 class LExtendInt32ToInt64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
3542  public:
LIR_HEADER(ExtendInt32ToInt64)3543   LIR_HEADER(ExtendInt32ToInt64)
3544 
3545   explicit LExtendInt32ToInt64(const LAllocation& input)
3546       : LInstructionHelper(classOpcode) {
3547     setOperand(0, input);
3548   }
3549 
mir()3550   const MExtendInt32ToInt64* mir() { return mir_->toExtendInt32ToInt64(); }
3551 };
3552 
3553 // Convert a boolean value to a string.
3554 class LBooleanToString : public LInstructionHelper<1, 1, 0> {
3555  public:
LIR_HEADER(BooleanToString)3556   LIR_HEADER(BooleanToString)
3557 
3558   explicit LBooleanToString(const LAllocation& input)
3559       : LInstructionHelper(classOpcode) {
3560     setOperand(0, input);
3561   }
3562 
mir()3563   const MToString* mir() { return mir_->toToString(); }
3564 };
3565 
3566 // Convert an integer hosted on one definition to a string with a function call.
3567 class LIntToString : public LInstructionHelper<1, 1, 0> {
3568  public:
LIR_HEADER(IntToString)3569   LIR_HEADER(IntToString)
3570 
3571   explicit LIntToString(const LAllocation& input)
3572       : LInstructionHelper(classOpcode) {
3573     setOperand(0, input);
3574   }
3575 
mir()3576   const MToString* mir() { return mir_->toToString(); }
3577 };
3578 
3579 // Convert a double hosted on one definition to a string with a function call.
3580 class LDoubleToString : public LInstructionHelper<1, 1, 1> {
3581  public:
LIR_HEADER(DoubleToString)3582   LIR_HEADER(DoubleToString)
3583 
3584   LDoubleToString(const LAllocation& input, const LDefinition& temp)
3585       : LInstructionHelper(classOpcode) {
3586     setOperand(0, input);
3587     setTemp(0, temp);
3588   }
3589 
tempInt()3590   const LDefinition* tempInt() { return getTemp(0); }
mir()3591   const MToString* mir() { return mir_->toToString(); }
3592 };
3593 
3594 // Convert a primitive to a string with a function call.
3595 class LValueToString : public LInstructionHelper<1, BOX_PIECES, 1> {
3596  public:
LIR_HEADER(ValueToString)3597   LIR_HEADER(ValueToString)
3598 
3599   LValueToString(const LBoxAllocation& input, const LDefinition& tempToUnbox)
3600       : LInstructionHelper(classOpcode) {
3601     setBoxOperand(Input, input);
3602     setTemp(0, tempToUnbox);
3603   }
3604 
3605   static const size_t Input = 0;
3606 
mir()3607   const MToString* mir() { return mir_->toToString(); }
3608 
tempToUnbox()3609   const LDefinition* tempToUnbox() { return getTemp(0); }
3610 };
3611 
3612 // Double raised to a half power.
3613 class LPowHalfD : public LInstructionHelper<1, 1, 0> {
3614  public:
3615   LIR_HEADER(PowHalfD);
LPowHalfD(const LAllocation & input)3616   explicit LPowHalfD(const LAllocation& input)
3617       : LInstructionHelper(classOpcode) {
3618     setOperand(0, input);
3619   }
3620 
input()3621   const LAllocation* input() { return getOperand(0); }
output()3622   const LDefinition* output() { return getDef(0); }
mir()3623   MPowHalf* mir() const { return mir_->toPowHalf(); }
3624 };
3625 
3626 class LNaNToZero : public LInstructionHelper<1, 1, 1> {
3627  public:
LIR_HEADER(NaNToZero)3628   LIR_HEADER(NaNToZero)
3629 
3630   explicit LNaNToZero(const LAllocation& input, const LDefinition& tempDouble)
3631       : LInstructionHelper(classOpcode) {
3632     setOperand(0, input);
3633     setTemp(0, tempDouble);
3634   }
3635 
mir()3636   const MNaNToZero* mir() { return mir_->toNaNToZero(); }
input()3637   const LAllocation* input() { return getOperand(0); }
output()3638   const LDefinition* output() { return getDef(0); }
tempDouble()3639   const LDefinition* tempDouble() { return getTemp(0); }
3640 };
3641 
3642 // Passed the BaselineFrame address in the OsrFrameReg via the IonOsrTempData
3643 // populated by PrepareOsrTempData.
3644 //
3645 // Forwards this object to the LOsrValues for Value materialization.
3646 class LOsrEntry : public LInstructionHelper<1, 0, 1> {
3647  protected:
3648   Label label_;
3649   uint32_t frameDepth_;
3650 
3651  public:
LIR_HEADER(OsrEntry)3652   LIR_HEADER(OsrEntry)
3653 
3654   explicit LOsrEntry(const LDefinition& temp)
3655       : LInstructionHelper(classOpcode), frameDepth_(0) {
3656     setTemp(0, temp);
3657   }
3658 
setFrameDepth(uint32_t depth)3659   void setFrameDepth(uint32_t depth) { frameDepth_ = depth; }
getFrameDepth()3660   uint32_t getFrameDepth() { return frameDepth_; }
label()3661   Label* label() { return &label_; }
temp()3662   const LDefinition* temp() { return getTemp(0); }
3663 };
3664 
3665 // Materialize a Value stored in an interpreter frame for OSR.
3666 class LOsrValue : public LInstructionHelper<BOX_PIECES, 1, 0> {
3667  public:
LIR_HEADER(OsrValue)3668   LIR_HEADER(OsrValue)
3669 
3670   explicit LOsrValue(const LAllocation& entry)
3671       : LInstructionHelper(classOpcode) {
3672     setOperand(0, entry);
3673   }
3674 
mir()3675   const MOsrValue* mir() { return mir_->toOsrValue(); }
3676 };
3677 
3678 // Materialize a JSObject env chain stored in an interpreter frame for OSR.
3679 class LOsrEnvironmentChain : public LInstructionHelper<1, 1, 0> {
3680  public:
LIR_HEADER(OsrEnvironmentChain)3681   LIR_HEADER(OsrEnvironmentChain)
3682 
3683   explicit LOsrEnvironmentChain(const LAllocation& entry)
3684       : LInstructionHelper(classOpcode) {
3685     setOperand(0, entry);
3686   }
3687 
mir()3688   const MOsrEnvironmentChain* mir() { return mir_->toOsrEnvironmentChain(); }
3689 };
3690 
3691 // Materialize a JSObject env chain stored in an interpreter frame for OSR.
3692 class LOsrReturnValue : public LInstructionHelper<BOX_PIECES, 1, 0> {
3693  public:
LIR_HEADER(OsrReturnValue)3694   LIR_HEADER(OsrReturnValue)
3695 
3696   explicit LOsrReturnValue(const LAllocation& entry)
3697       : LInstructionHelper(classOpcode) {
3698     setOperand(0, entry);
3699   }
3700 
mir()3701   const MOsrReturnValue* mir() { return mir_->toOsrReturnValue(); }
3702 };
3703 
3704 // Materialize a JSObject ArgumentsObject stored in an interpreter frame for
3705 // OSR.
3706 class LOsrArgumentsObject : public LInstructionHelper<1, 1, 0> {
3707  public:
LIR_HEADER(OsrArgumentsObject)3708   LIR_HEADER(OsrArgumentsObject)
3709 
3710   explicit LOsrArgumentsObject(const LAllocation& entry)
3711       : LInstructionHelper(classOpcode) {
3712     setOperand(0, entry);
3713   }
3714 
mir()3715   const MOsrArgumentsObject* mir() { return mir_->toOsrArgumentsObject(); }
3716 };
3717 
3718 class LRegExp : public LInstructionHelper<1, 0, 1> {
3719  public:
LIR_HEADER(RegExp)3720   LIR_HEADER(RegExp)
3721 
3722   explicit LRegExp(const LDefinition& temp) : LInstructionHelper(classOpcode) {
3723     setTemp(0, temp);
3724   }
temp()3725   const LDefinition* temp() { return getTemp(0); }
mir()3726   const MRegExp* mir() const { return mir_->toRegExp(); }
3727 };
3728 
3729 class LRegExpMatcher : public LCallInstructionHelper<BOX_PIECES, 3, 0> {
3730  public:
LIR_HEADER(RegExpMatcher)3731   LIR_HEADER(RegExpMatcher)
3732 
3733   LRegExpMatcher(const LAllocation& regexp, const LAllocation& string,
3734                  const LAllocation& lastIndex)
3735       : LCallInstructionHelper(classOpcode) {
3736     setOperand(0, regexp);
3737     setOperand(1, string);
3738     setOperand(2, lastIndex);
3739   }
3740 
regexp()3741   const LAllocation* regexp() { return getOperand(0); }
string()3742   const LAllocation* string() { return getOperand(1); }
lastIndex()3743   const LAllocation* lastIndex() { return getOperand(2); }
3744 
mir()3745   const MRegExpMatcher* mir() const { return mir_->toRegExpMatcher(); }
3746 };
3747 
3748 class LRegExpSearcher : public LCallInstructionHelper<1, 3, 0> {
3749  public:
LIR_HEADER(RegExpSearcher)3750   LIR_HEADER(RegExpSearcher)
3751 
3752   LRegExpSearcher(const LAllocation& regexp, const LAllocation& string,
3753                   const LAllocation& lastIndex)
3754       : LCallInstructionHelper(classOpcode) {
3755     setOperand(0, regexp);
3756     setOperand(1, string);
3757     setOperand(2, lastIndex);
3758   }
3759 
regexp()3760   const LAllocation* regexp() { return getOperand(0); }
string()3761   const LAllocation* string() { return getOperand(1); }
lastIndex()3762   const LAllocation* lastIndex() { return getOperand(2); }
3763 
mir()3764   const MRegExpSearcher* mir() const { return mir_->toRegExpSearcher(); }
3765 };
3766 
3767 class LRegExpTester : public LCallInstructionHelper<1, 3, 0> {
3768  public:
LIR_HEADER(RegExpTester)3769   LIR_HEADER(RegExpTester)
3770 
3771   LRegExpTester(const LAllocation& regexp, const LAllocation& string,
3772                 const LAllocation& lastIndex)
3773       : LCallInstructionHelper(classOpcode) {
3774     setOperand(0, regexp);
3775     setOperand(1, string);
3776     setOperand(2, lastIndex);
3777   }
3778 
regexp()3779   const LAllocation* regexp() { return getOperand(0); }
string()3780   const LAllocation* string() { return getOperand(1); }
lastIndex()3781   const LAllocation* lastIndex() { return getOperand(2); }
3782 
mir()3783   const MRegExpTester* mir() const { return mir_->toRegExpTester(); }
3784 };
3785 
3786 class LRegExpPrototypeOptimizable : public LInstructionHelper<1, 1, 1> {
3787  public:
3788   LIR_HEADER(RegExpPrototypeOptimizable);
LRegExpPrototypeOptimizable(const LAllocation & object,const LDefinition & temp)3789   LRegExpPrototypeOptimizable(const LAllocation& object,
3790                               const LDefinition& temp)
3791       : LInstructionHelper(classOpcode) {
3792     setOperand(0, object);
3793     setTemp(0, temp);
3794   }
3795 
object()3796   const LAllocation* object() { return getOperand(0); }
temp()3797   const LDefinition* temp() { return getTemp(0); }
mir()3798   MRegExpPrototypeOptimizable* mir() const {
3799     return mir_->toRegExpPrototypeOptimizable();
3800   }
3801 };
3802 
3803 class LRegExpInstanceOptimizable : public LInstructionHelper<1, 2, 1> {
3804  public:
3805   LIR_HEADER(RegExpInstanceOptimizable);
LRegExpInstanceOptimizable(const LAllocation & object,const LAllocation & proto,const LDefinition & temp)3806   LRegExpInstanceOptimizable(const LAllocation& object,
3807                              const LAllocation& proto, const LDefinition& temp)
3808       : LInstructionHelper(classOpcode) {
3809     setOperand(0, object);
3810     setOperand(1, proto);
3811     setTemp(0, temp);
3812   }
3813 
object()3814   const LAllocation* object() { return getOperand(0); }
proto()3815   const LAllocation* proto() { return getOperand(1); }
temp()3816   const LDefinition* temp() { return getTemp(0); }
mir()3817   MRegExpInstanceOptimizable* mir() const {
3818     return mir_->toRegExpInstanceOptimizable();
3819   }
3820 };
3821 
3822 class LGetFirstDollarIndex : public LInstructionHelper<1, 1, 3> {
3823  public:
3824   LIR_HEADER(GetFirstDollarIndex);
LGetFirstDollarIndex(const LAllocation & str,const LDefinition & temp0,const LDefinition & temp1,const LDefinition & temp2)3825   LGetFirstDollarIndex(const LAllocation& str, const LDefinition& temp0,
3826                        const LDefinition& temp1, const LDefinition& temp2)
3827       : LInstructionHelper(classOpcode) {
3828     setOperand(0, str);
3829     setTemp(0, temp0);
3830     setTemp(1, temp1);
3831     setTemp(2, temp2);
3832   }
3833 
str()3834   const LAllocation* str() { return getOperand(0); }
temp0()3835   const LDefinition* temp0() { return getTemp(0); }
temp1()3836   const LDefinition* temp1() { return getTemp(1); }
temp2()3837   const LDefinition* temp2() { return getTemp(2); }
3838 };
3839 
3840 class LStringReplace : public LCallInstructionHelper<1, 3, 0> {
3841  public:
3842   LIR_HEADER(StringReplace);
3843 
LStringReplace(const LAllocation & string,const LAllocation & pattern,const LAllocation & replacement)3844   LStringReplace(const LAllocation& string, const LAllocation& pattern,
3845                  const LAllocation& replacement)
3846       : LCallInstructionHelper(classOpcode) {
3847     setOperand(0, string);
3848     setOperand(1, pattern);
3849     setOperand(2, replacement);
3850   }
3851 
mir()3852   const MStringReplace* mir() const { return mir_->toStringReplace(); }
3853 
string()3854   const LAllocation* string() { return getOperand(0); }
pattern()3855   const LAllocation* pattern() { return getOperand(1); }
replacement()3856   const LAllocation* replacement() { return getOperand(2); }
3857 };
3858 
3859 class LBinaryValueCache
3860     : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 2> {
3861  public:
LIR_HEADER(BinaryValueCache)3862   LIR_HEADER(BinaryValueCache)
3863 
3864   // Takes two temps: these are intendend to be FloatReg0 and FloatReg1
3865   // To allow the actual cache code to safely clobber those values without
3866   // save and restore.
3867   LBinaryValueCache(const LBoxAllocation& lhs, const LBoxAllocation& rhs,
3868                     const LDefinition& temp0, const LDefinition& temp1)
3869       : LInstructionHelper(classOpcode) {
3870     setBoxOperand(LhsInput, lhs);
3871     setBoxOperand(RhsInput, rhs);
3872     setTemp(0, temp0);
3873     setTemp(1, temp1);
3874   }
3875 
mir()3876   const MBinaryCache* mir() const { return mir_->toBinaryCache(); }
3877 
3878   static const size_t LhsInput = 0;
3879   static const size_t RhsInput = BOX_PIECES;
3880 };
3881 
3882 class LBinaryBoolCache : public LInstructionHelper<1, 2 * BOX_PIECES, 2> {
3883  public:
LIR_HEADER(BinaryBoolCache)3884   LIR_HEADER(BinaryBoolCache)
3885 
3886   // Takes two temps: these are intendend to be FloatReg0 and FloatReg1
3887   // To allow the actual cache code to safely clobber those values without
3888   // save and restore.
3889   LBinaryBoolCache(const LBoxAllocation& lhs, const LBoxAllocation& rhs,
3890                    const LDefinition& temp0, const LDefinition& temp1)
3891       : LInstructionHelper(classOpcode) {
3892     setBoxOperand(LhsInput, lhs);
3893     setBoxOperand(RhsInput, rhs);
3894     setTemp(0, temp0);
3895     setTemp(1, temp1);
3896   }
3897 
mir()3898   const MBinaryCache* mir() const { return mir_->toBinaryCache(); }
3899 
3900   static const size_t LhsInput = 0;
3901   static const size_t RhsInput = BOX_PIECES;
3902 };
3903 
3904 class LUnaryCache : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0> {
3905  public:
LIR_HEADER(UnaryCache)3906   LIR_HEADER(UnaryCache)
3907 
3908   explicit LUnaryCache(const LBoxAllocation& input)
3909       : LInstructionHelper(classOpcode) {
3910     setBoxOperand(Input, input);
3911   }
3912 
mir()3913   const MUnaryCache* mir() const { return mir_->toUnaryCache(); }
3914 
input()3915   const LAllocation* input() { return getOperand(Input); }
3916 
3917   static const size_t Input = 0;
3918 };
3919 
3920 class LModuleMetadata : public LCallInstructionHelper<1, 0, 0> {
3921  public:
LIR_HEADER(ModuleMetadata)3922   LIR_HEADER(ModuleMetadata)
3923 
3924   const MModuleMetadata* mir() const { return mir_->toModuleMetadata(); }
3925 
LModuleMetadata()3926   LModuleMetadata() : LCallInstructionHelper(classOpcode) {}
3927 };
3928 
3929 class LDynamicImport : public LCallInstructionHelper<1, BOX_PIECES, 0> {
3930  public:
3931   LIR_HEADER(DynamicImport)
3932 
3933   static const size_t SpecifierIndex = 0;
3934 
LDynamicImport(const LBoxAllocation & specifier)3935   explicit LDynamicImport(const LBoxAllocation& specifier)
3936       : LCallInstructionHelper(classOpcode) {
3937     setBoxOperand(SpecifierIndex, specifier);
3938   }
3939 
mir()3940   const MDynamicImport* mir() const { return mir_->toDynamicImport(); }
3941 };
3942 
3943 class LLambda : public LInstructionHelper<1, 1, 1> {
3944  public:
LIR_HEADER(Lambda)3945   LIR_HEADER(Lambda)
3946 
3947   LLambda(const LAllocation& envChain, const LDefinition& temp)
3948       : LInstructionHelper(classOpcode) {
3949     setOperand(0, envChain);
3950     setTemp(0, temp);
3951   }
environmentChain()3952   const LAllocation* environmentChain() { return getOperand(0); }
temp()3953   const LDefinition* temp() { return getTemp(0); }
mir()3954   const MLambda* mir() const { return mir_->toLambda(); }
3955 };
3956 
3957 class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1> {
3958  public:
3959   LIR_HEADER(LambdaArrow)
3960 
3961   static const size_t NewTargetValue = 1;
3962 
LLambdaArrow(const LAllocation & envChain,const LBoxAllocation & newTarget,const LDefinition & temp)3963   LLambdaArrow(const LAllocation& envChain, const LBoxAllocation& newTarget,
3964                const LDefinition& temp)
3965       : LInstructionHelper(classOpcode) {
3966     setOperand(0, envChain);
3967     setBoxOperand(NewTargetValue, newTarget);
3968     setTemp(0, temp);
3969   }
environmentChain()3970   const LAllocation* environmentChain() { return getOperand(0); }
temp()3971   const LDefinition* temp() { return getTemp(0); }
mir()3972   const MLambdaArrow* mir() const { return mir_->toLambdaArrow(); }
3973 };
3974 
3975 class LFunctionWithProto : public LCallInstructionHelper<1, 2, 0> {
3976  public:
LIR_HEADER(FunctionWithProto)3977   LIR_HEADER(FunctionWithProto)
3978 
3979   LFunctionWithProto(const LAllocation& envChain, const LAllocation& prototype)
3980       : LCallInstructionHelper(classOpcode) {
3981     setOperand(0, envChain);
3982     setOperand(1, prototype);
3983   }
environmentChain()3984   const LAllocation* environmentChain() { return getOperand(0); }
prototype()3985   const LAllocation* prototype() { return getOperand(1); }
mir()3986   const MFunctionWithProto* mir() const { return mir_->toFunctionWithProto(); }
3987 };
3988 
3989 class LSetFunName : public LCallInstructionHelper<1, 1 + BOX_PIECES, 0> {
3990  public:
3991   LIR_HEADER(SetFunName)
3992 
3993   static const size_t NameValue = 1;
3994 
LSetFunName(const LAllocation & fun,const LBoxAllocation & name)3995   LSetFunName(const LAllocation& fun, const LBoxAllocation& name)
3996       : LCallInstructionHelper(classOpcode) {
3997     setOperand(0, fun);
3998     setBoxOperand(NameValue, name);
3999   }
fun()4000   const LAllocation* fun() { return getOperand(0); }
mir()4001   const MSetFunName* mir() const { return mir_->toSetFunName(); }
4002 };
4003 
4004 class LKeepAliveObject : public LInstructionHelper<0, 1, 0> {
4005  public:
LIR_HEADER(KeepAliveObject)4006   LIR_HEADER(KeepAliveObject)
4007 
4008   explicit LKeepAliveObject(const LAllocation& object)
4009       : LInstructionHelper(classOpcode) {
4010     setOperand(0, object);
4011   }
4012 
object()4013   const LAllocation* object() { return getOperand(0); }
4014 };
4015 
4016 // Load the "slots" member out of a JSObject.
4017 //   Input: JSObject pointer
4018 //   Output: slots pointer
4019 class LSlots : public LInstructionHelper<1, 1, 0> {
4020  public:
LIR_HEADER(Slots)4021   LIR_HEADER(Slots)
4022 
4023   explicit LSlots(const LAllocation& object) : LInstructionHelper(classOpcode) {
4024     setOperand(0, object);
4025   }
4026 
object()4027   const LAllocation* object() { return getOperand(0); }
4028 };
4029 
4030 // Load the "elements" member out of a JSObject.
4031 //   Input: JSObject pointer
4032 //   Output: elements pointer
4033 class LElements : public LInstructionHelper<1, 1, 0> {
4034  public:
LIR_HEADER(Elements)4035   LIR_HEADER(Elements)
4036 
4037   explicit LElements(const LAllocation& object)
4038       : LInstructionHelper(classOpcode) {
4039     setOperand(0, object);
4040   }
4041 
object()4042   const LAllocation* object() { return getOperand(0); }
4043 
mir()4044   const MElements* mir() const { return mir_->toElements(); }
4045 };
4046 
4047 // Load the initialized length from an elements header.
4048 class LInitializedLength : public LInstructionHelper<1, 1, 0> {
4049  public:
LIR_HEADER(InitializedLength)4050   LIR_HEADER(InitializedLength)
4051 
4052   explicit LInitializedLength(const LAllocation& elements)
4053       : LInstructionHelper(classOpcode) {
4054     setOperand(0, elements);
4055   }
4056 
elements()4057   const LAllocation* elements() { return getOperand(0); }
4058 };
4059 
4060 // Store to the initialized length in an elements header. Note the input is an
4061 // *index*, one less than the desired initialized length.
4062 class LSetInitializedLength : public LInstructionHelper<0, 2, 0> {
4063  public:
LIR_HEADER(SetInitializedLength)4064   LIR_HEADER(SetInitializedLength)
4065 
4066   LSetInitializedLength(const LAllocation& elements, const LAllocation& index)
4067       : LInstructionHelper(classOpcode) {
4068     setOperand(0, elements);
4069     setOperand(1, index);
4070   }
4071 
elements()4072   const LAllocation* elements() { return getOperand(0); }
index()4073   const LAllocation* index() { return getOperand(1); }
4074 };
4075 
4076 // Load the length from an elements header.
4077 class LArrayLength : public LInstructionHelper<1, 1, 0> {
4078  public:
LIR_HEADER(ArrayLength)4079   LIR_HEADER(ArrayLength)
4080 
4081   explicit LArrayLength(const LAllocation& elements)
4082       : LInstructionHelper(classOpcode) {
4083     setOperand(0, elements);
4084   }
4085 
elements()4086   const LAllocation* elements() { return getOperand(0); }
4087 };
4088 
4089 // Store to the length in an elements header. Note the input is an *index*,
4090 // one less than the desired length.
4091 class LSetArrayLength : public LInstructionHelper<0, 2, 0> {
4092  public:
LIR_HEADER(SetArrayLength)4093   LIR_HEADER(SetArrayLength)
4094 
4095   LSetArrayLength(const LAllocation& elements, const LAllocation& index)
4096       : LInstructionHelper(classOpcode) {
4097     setOperand(0, elements);
4098     setOperand(1, index);
4099   }
4100 
elements()4101   const LAllocation* elements() { return getOperand(0); }
index()4102   const LAllocation* index() { return getOperand(1); }
4103 };
4104 
4105 // Load the "length" property of a function.
4106 class LFunctionLength : public LInstructionHelper<1, 1, 0> {
4107  public:
LIR_HEADER(FunctionLength)4108   LIR_HEADER(FunctionLength)
4109 
4110   explicit LFunctionLength(const LAllocation& function)
4111       : LInstructionHelper(classOpcode) {
4112     setOperand(0, function);
4113   }
4114 
function()4115   const LAllocation* function() { return getOperand(0); }
4116 };
4117 
4118 // Load the "name" property of a function.
4119 class LFunctionName : public LInstructionHelper<1, 1, 0> {
4120  public:
LIR_HEADER(FunctionName)4121   LIR_HEADER(FunctionName)
4122 
4123   explicit LFunctionName(const LAllocation& function)
4124       : LInstructionHelper(classOpcode) {
4125     setOperand(0, function);
4126   }
4127 
function()4128   const LAllocation* function() { return getOperand(0); }
4129 };
4130 
4131 class LGetNextEntryForIterator : public LInstructionHelper<1, 2, 3> {
4132  public:
LIR_HEADER(GetNextEntryForIterator)4133   LIR_HEADER(GetNextEntryForIterator)
4134 
4135   explicit LGetNextEntryForIterator(const LAllocation& iter,
4136                                     const LAllocation& result,
4137                                     const LDefinition& temp0,
4138                                     const LDefinition& temp1,
4139                                     const LDefinition& temp2)
4140       : LInstructionHelper(classOpcode) {
4141     setOperand(0, iter);
4142     setOperand(1, result);
4143     setTemp(0, temp0);
4144     setTemp(1, temp1);
4145     setTemp(2, temp2);
4146   }
4147 
mir()4148   const MGetNextEntryForIterator* mir() const {
4149     return mir_->toGetNextEntryForIterator();
4150   }
iter()4151   const LAllocation* iter() { return getOperand(0); }
result()4152   const LAllocation* result() { return getOperand(1); }
temp0()4153   const LDefinition* temp0() { return getTemp(0); }
temp1()4154   const LDefinition* temp1() { return getTemp(1); }
temp2()4155   const LDefinition* temp2() { return getTemp(2); }
4156 };
4157 
4158 class LArrayBufferByteLength : public LInstructionHelper<1, 1, 0> {
4159  public:
LIR_HEADER(ArrayBufferByteLength)4160   LIR_HEADER(ArrayBufferByteLength)
4161 
4162   explicit LArrayBufferByteLength(const LAllocation& obj)
4163       : LInstructionHelper(classOpcode) {
4164     setOperand(0, obj);
4165   }
4166 
object()4167   const LAllocation* object() { return getOperand(0); }
4168 };
4169 
4170 // Read the length of an array buffer view.
4171 class LArrayBufferViewLength : public LInstructionHelper<1, 1, 0> {
4172  public:
LIR_HEADER(ArrayBufferViewLength)4173   LIR_HEADER(ArrayBufferViewLength)
4174 
4175   explicit LArrayBufferViewLength(const LAllocation& obj)
4176       : LInstructionHelper(classOpcode) {
4177     setOperand(0, obj);
4178   }
4179 
object()4180   const LAllocation* object() { return getOperand(0); }
4181 
mir()4182   const MArrayBufferViewLength* mir() const {
4183     return mir_->toArrayBufferViewLength();
4184   }
4185 };
4186 
4187 // Read the byteOffset of an array buffer view.
4188 class LArrayBufferViewByteOffset : public LInstructionHelper<1, 1, 0> {
4189  public:
LIR_HEADER(ArrayBufferViewByteOffset)4190   LIR_HEADER(ArrayBufferViewByteOffset)
4191 
4192   explicit LArrayBufferViewByteOffset(const LAllocation& obj)
4193       : LInstructionHelper(classOpcode) {
4194     setOperand(0, obj);
4195   }
4196 
object()4197   const LAllocation* object() { return getOperand(0); }
4198 };
4199 
4200 // Load an array buffer view's elements vector.
4201 class LArrayBufferViewElements : public LInstructionHelper<1, 1, 0> {
4202  public:
LIR_HEADER(ArrayBufferViewElements)4203   LIR_HEADER(ArrayBufferViewElements)
4204 
4205   explicit LArrayBufferViewElements(const LAllocation& object)
4206       : LInstructionHelper(classOpcode) {
4207     setOperand(0, object);
4208   }
object()4209   const LAllocation* object() { return getOperand(0); }
4210 };
4211 
4212 // Return the element size of a typed array.
4213 class LTypedArrayElementSize : public LInstructionHelper<1, 1, 0> {
4214  public:
LIR_HEADER(TypedArrayElementSize)4215   LIR_HEADER(TypedArrayElementSize)
4216 
4217   explicit LTypedArrayElementSize(const LAllocation& obj)
4218       : LInstructionHelper(classOpcode) {
4219     setOperand(0, obj);
4220   }
4221 
object()4222   const LAllocation* object() { return getOperand(0); }
4223 };
4224 
4225 class LGuardHasAttachedArrayBuffer : public LInstructionHelper<0, 1, 1> {
4226  public:
LIR_HEADER(GuardHasAttachedArrayBuffer)4227   LIR_HEADER(GuardHasAttachedArrayBuffer)
4228 
4229   LGuardHasAttachedArrayBuffer(const LAllocation& obj, const LDefinition& temp)
4230       : LInstructionHelper(classOpcode) {
4231     setOperand(0, obj);
4232     setTemp(0, temp);
4233   }
4234 
object()4235   const LAllocation* object() { return getOperand(0); }
temp()4236   const LDefinition* temp() { return getTemp(0); }
4237 };
4238 
4239 // Double to IntPtr, eligible for accessing into a TypedArray or DataView. If
4240 // the index isn't exactly representable as an IntPtr, depending on the
4241 // supportOOB flag on the MIR instruction, either bail out or produce an IntPtr
4242 // which is equivalent to an OOB access.
4243 class LGuardNumberToIntPtrIndex : public LInstructionHelper<1, 1, 0> {
4244  public:
LIR_HEADER(GuardNumberToIntPtrIndex)4245   LIR_HEADER(GuardNumberToIntPtrIndex)
4246 
4247   explicit LGuardNumberToIntPtrIndex(const LAllocation& obj)
4248       : LInstructionHelper(classOpcode) {
4249     setOperand(0, obj);
4250   }
4251 
mir()4252   const MGuardNumberToIntPtrIndex* mir() const {
4253     return mir_->toGuardNumberToIntPtrIndex();
4254   }
4255 };
4256 
4257 // Bailout if index >= length.
4258 class LBoundsCheck : public LInstructionHelper<0, 2, 0> {
4259  public:
LIR_HEADER(BoundsCheck)4260   LIR_HEADER(BoundsCheck)
4261 
4262   LBoundsCheck(const LAllocation& index, const LAllocation& length)
4263       : LInstructionHelper(classOpcode) {
4264     setOperand(0, index);
4265     setOperand(1, length);
4266   }
mir()4267   const MBoundsCheck* mir() const { return mir_->toBoundsCheck(); }
index()4268   const LAllocation* index() { return getOperand(0); }
length()4269   const LAllocation* length() { return getOperand(1); }
4270 };
4271 
4272 // Bailout if index + minimum < 0 or index + maximum >= length.
4273 class LBoundsCheckRange : public LInstructionHelper<0, 2, 1> {
4274  public:
LIR_HEADER(BoundsCheckRange)4275   LIR_HEADER(BoundsCheckRange)
4276 
4277   LBoundsCheckRange(const LAllocation& index, const LAllocation& length,
4278                     const LDefinition& temp)
4279       : LInstructionHelper(classOpcode) {
4280     setOperand(0, index);
4281     setOperand(1, length);
4282     setTemp(0, temp);
4283   }
mir()4284   const MBoundsCheck* mir() const { return mir_->toBoundsCheck(); }
index()4285   const LAllocation* index() { return getOperand(0); }
length()4286   const LAllocation* length() { return getOperand(1); }
4287 };
4288 
4289 // Bailout if index < minimum.
4290 class LBoundsCheckLower : public LInstructionHelper<0, 1, 0> {
4291  public:
LIR_HEADER(BoundsCheckLower)4292   LIR_HEADER(BoundsCheckLower)
4293 
4294   explicit LBoundsCheckLower(const LAllocation& index)
4295       : LInstructionHelper(classOpcode) {
4296     setOperand(0, index);
4297   }
mir()4298   MBoundsCheckLower* mir() const { return mir_->toBoundsCheckLower(); }
index()4299   const LAllocation* index() { return getOperand(0); }
4300 };
4301 
4302 class LSpectreMaskIndex : public LInstructionHelper<1, 2, 0> {
4303  public:
LIR_HEADER(SpectreMaskIndex)4304   LIR_HEADER(SpectreMaskIndex)
4305 
4306   LSpectreMaskIndex(const LAllocation& index, const LAllocation& length)
4307       : LInstructionHelper(classOpcode) {
4308     setOperand(0, index);
4309     setOperand(1, length);
4310   }
index()4311   const LAllocation* index() { return getOperand(0); }
length()4312   const LAllocation* length() { return getOperand(1); }
4313 
mir()4314   const MSpectreMaskIndex* mir() const { return mir_->toSpectreMaskIndex(); }
4315 };
4316 
4317 // Load a value from a dense array's elements vector. Bail out if it's the hole
4318 // value.
4319 class LLoadElementV : public LInstructionHelper<BOX_PIECES, 2, 0> {
4320  public:
LIR_HEADER(LoadElementV)4321   LIR_HEADER(LoadElementV)
4322 
4323   LLoadElementV(const LAllocation& elements, const LAllocation& index)
4324       : LInstructionHelper(classOpcode) {
4325     setOperand(0, elements);
4326     setOperand(1, index);
4327   }
4328 
extraName()4329   const char* extraName() const {
4330     return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
4331   }
4332 
mir()4333   const MLoadElement* mir() const { return mir_->toLoadElement(); }
elements()4334   const LAllocation* elements() { return getOperand(0); }
index()4335   const LAllocation* index() { return getOperand(1); }
4336 };
4337 
4338 class LInArray : public LInstructionHelper<1, 3, 0> {
4339  public:
LIR_HEADER(InArray)4340   LIR_HEADER(InArray)
4341 
4342   LInArray(const LAllocation& elements, const LAllocation& index,
4343            const LAllocation& initLength)
4344       : LInstructionHelper(classOpcode) {
4345     setOperand(0, elements);
4346     setOperand(1, index);
4347     setOperand(2, initLength);
4348   }
mir()4349   const MInArray* mir() const { return mir_->toInArray(); }
elements()4350   const LAllocation* elements() { return getOperand(0); }
index()4351   const LAllocation* index() { return getOperand(1); }
initLength()4352   const LAllocation* initLength() { return getOperand(2); }
4353 };
4354 
4355 class LGuardElementNotHole : public LInstructionHelper<0, 2, 0> {
4356  public:
LIR_HEADER(GuardElementNotHole)4357   LIR_HEADER(GuardElementNotHole)
4358 
4359   LGuardElementNotHole(const LAllocation& elements, const LAllocation& index)
4360       : LInstructionHelper(classOpcode) {
4361     setOperand(0, elements);
4362     setOperand(1, index);
4363   }
elements()4364   const LAllocation* elements() { return getOperand(0); }
index()4365   const LAllocation* index() { return getOperand(1); }
4366 };
4367 
4368 // Load a value from an array's elements vector, loading |undefined| if we hit a
4369 // hole. Bail out if we get a negative index.
4370 class LLoadElementHole : public LInstructionHelper<BOX_PIECES, 3, 0> {
4371  public:
LIR_HEADER(LoadElementHole)4372   LIR_HEADER(LoadElementHole)
4373 
4374   LLoadElementHole(const LAllocation& elements, const LAllocation& index,
4375                    const LAllocation& initLength)
4376       : LInstructionHelper(classOpcode) {
4377     setOperand(0, elements);
4378     setOperand(1, index);
4379     setOperand(2, initLength);
4380   }
4381 
extraName()4382   const char* extraName() const {
4383     return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
4384   }
4385 
mir()4386   const MLoadElementHole* mir() const { return mir_->toLoadElementHole(); }
elements()4387   const LAllocation* elements() { return getOperand(0); }
index()4388   const LAllocation* index() { return getOperand(1); }
initLength()4389   const LAllocation* initLength() { return getOperand(2); }
4390 };
4391 
4392 // Store a boxed value to a dense array's element vector.
4393 class LStoreElementV : public LInstructionHelper<0, 2 + BOX_PIECES, 0> {
4394  public:
LIR_HEADER(StoreElementV)4395   LIR_HEADER(StoreElementV)
4396 
4397   LStoreElementV(const LAllocation& elements, const LAllocation& index,
4398                  const LBoxAllocation& value)
4399       : LInstructionHelper(classOpcode) {
4400     setOperand(0, elements);
4401     setOperand(1, index);
4402     setBoxOperand(Value, value);
4403   }
4404 
extraName()4405   const char* extraName() const {
4406     return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
4407   }
4408 
4409   static const size_t Value = 2;
4410 
mir()4411   const MStoreElement* mir() const { return mir_->toStoreElement(); }
elements()4412   const LAllocation* elements() { return getOperand(0); }
index()4413   const LAllocation* index() { return getOperand(1); }
4414 };
4415 
4416 // Store a typed value to a dense array's elements vector. Compared to
4417 // LStoreElementV, this instruction can store doubles and constants directly,
4418 // and does not store the type tag if the array is monomorphic and known to
4419 // be packed.
4420 class LStoreElementT : public LInstructionHelper<0, 3, 0> {
4421  public:
LIR_HEADER(StoreElementT)4422   LIR_HEADER(StoreElementT)
4423 
4424   LStoreElementT(const LAllocation& elements, const LAllocation& index,
4425                  const LAllocation& value)
4426       : LInstructionHelper(classOpcode) {
4427     setOperand(0, elements);
4428     setOperand(1, index);
4429     setOperand(2, value);
4430   }
4431 
extraName()4432   const char* extraName() const {
4433     return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
4434   }
4435 
mir()4436   const MStoreElement* mir() const { return mir_->toStoreElement(); }
elements()4437   const LAllocation* elements() { return getOperand(0); }
index()4438   const LAllocation* index() { return getOperand(1); }
value()4439   const LAllocation* value() { return getOperand(2); }
4440 };
4441 
4442 class LStoreHoleValueElement : public LInstructionHelper<0, 2, 0> {
4443  public:
LIR_HEADER(StoreHoleValueElement)4444   LIR_HEADER(StoreHoleValueElement)
4445 
4446   LStoreHoleValueElement(const LAllocation& elements, const LAllocation& index)
4447       : LInstructionHelper(classOpcode) {
4448     setOperand(0, elements);
4449     setOperand(1, index);
4450   }
4451 
elements()4452   const LAllocation* elements() { return getOperand(0); }
index()4453   const LAllocation* index() { return getOperand(1); }
4454 };
4455 
4456 // Like LStoreElementV, but supports indexes >= initialized length.
4457 class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> {
4458  public:
LIR_HEADER(StoreElementHoleV)4459   LIR_HEADER(StoreElementHoleV)
4460 
4461   LStoreElementHoleV(const LAllocation& object, const LAllocation& elements,
4462                      const LAllocation& index, const LBoxAllocation& value,
4463                      const LDefinition& spectreTemp)
4464       : LInstructionHelper(classOpcode) {
4465     setOperand(0, object);
4466     setOperand(1, elements);
4467     setOperand(2, index);
4468     setBoxOperand(Value, value);
4469     setTemp(0, spectreTemp);
4470   }
4471 
4472   static const size_t Value = 3;
4473 
mir()4474   const MStoreElementHole* mir() const { return mir_->toStoreElementHole(); }
object()4475   const LAllocation* object() { return getOperand(0); }
elements()4476   const LAllocation* elements() { return getOperand(1); }
index()4477   const LAllocation* index() { return getOperand(2); }
spectreTemp()4478   const LDefinition* spectreTemp() { return getTemp(0); }
4479 };
4480 
4481 // Like LStoreElementT, but supports indexes >= initialized length.
4482 class LStoreElementHoleT : public LInstructionHelper<0, 4, 1> {
4483  public:
LIR_HEADER(StoreElementHoleT)4484   LIR_HEADER(StoreElementHoleT)
4485 
4486   LStoreElementHoleT(const LAllocation& object, const LAllocation& elements,
4487                      const LAllocation& index, const LAllocation& value,
4488                      const LDefinition& spectreTemp)
4489       : LInstructionHelper(classOpcode) {
4490     setOperand(0, object);
4491     setOperand(1, elements);
4492     setOperand(2, index);
4493     setOperand(3, value);
4494     setTemp(0, spectreTemp);
4495   }
4496 
mir()4497   const MStoreElementHole* mir() const { return mir_->toStoreElementHole(); }
object()4498   const LAllocation* object() { return getOperand(0); }
elements()4499   const LAllocation* elements() { return getOperand(1); }
index()4500   const LAllocation* index() { return getOperand(2); }
value()4501   const LAllocation* value() { return getOperand(3); }
spectreTemp()4502   const LDefinition* spectreTemp() { return getTemp(0); }
4503 };
4504 
4505 class LArrayPopShift : public LInstructionHelper<BOX_PIECES, 1, 2> {
4506  public:
LIR_HEADER(ArrayPopShift)4507   LIR_HEADER(ArrayPopShift)
4508 
4509   LArrayPopShift(const LAllocation& object, const LDefinition& temp0,
4510                  const LDefinition& temp1)
4511       : LInstructionHelper(classOpcode) {
4512     setOperand(0, object);
4513     setTemp(0, temp0);
4514     setTemp(1, temp1);
4515   }
4516 
extraName()4517   const char* extraName() const {
4518     return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift";
4519   }
4520 
mir()4521   const MArrayPopShift* mir() const { return mir_->toArrayPopShift(); }
object()4522   const LAllocation* object() { return getOperand(0); }
temp0()4523   const LDefinition* temp0() { return getTemp(0); }
temp1()4524   const LDefinition* temp1() { return getTemp(1); }
4525 };
4526 
4527 class LArrayPush : public LInstructionHelper<1, 1 + BOX_PIECES, 2> {
4528  public:
LIR_HEADER(ArrayPush)4529   LIR_HEADER(ArrayPush)
4530 
4531   LArrayPush(const LAllocation& object, const LBoxAllocation& value,
4532              const LDefinition& temp, const LDefinition& spectreTemp)
4533       : LInstructionHelper(classOpcode) {
4534     setOperand(0, object);
4535     setBoxOperand(Value, value);
4536     setTemp(0, temp);
4537     setTemp(1, spectreTemp);
4538   }
4539 
4540   static const size_t Value = 1;
4541 
mir()4542   const MArrayPush* mir() const { return mir_->toArrayPush(); }
object()4543   const LAllocation* object() { return getOperand(0); }
temp()4544   const LDefinition* temp() { return getTemp(0); }
spectreTemp()4545   const LDefinition* spectreTemp() { return getTemp(1); }
4546 };
4547 
4548 class LArraySlice : public LCallInstructionHelper<1, 3, 2> {
4549  public:
LIR_HEADER(ArraySlice)4550   LIR_HEADER(ArraySlice)
4551 
4552   LArraySlice(const LAllocation& obj, const LAllocation& begin,
4553               const LAllocation& end, const LDefinition& temp1,
4554               const LDefinition& temp2)
4555       : LCallInstructionHelper(classOpcode) {
4556     setOperand(0, obj);
4557     setOperand(1, begin);
4558     setOperand(2, end);
4559     setTemp(0, temp1);
4560     setTemp(1, temp2);
4561   }
mir()4562   const MArraySlice* mir() const { return mir_->toArraySlice(); }
object()4563   const LAllocation* object() { return getOperand(0); }
begin()4564   const LAllocation* begin() { return getOperand(1); }
end()4565   const LAllocation* end() { return getOperand(2); }
temp1()4566   const LDefinition* temp1() { return getTemp(0); }
temp2()4567   const LDefinition* temp2() { return getTemp(1); }
4568 };
4569 
4570 class LArrayJoin : public LCallInstructionHelper<1, 2, 1> {
4571  public:
LIR_HEADER(ArrayJoin)4572   LIR_HEADER(ArrayJoin)
4573 
4574   LArrayJoin(const LAllocation& array, const LAllocation& sep,
4575              const LDefinition& temp)
4576       : LCallInstructionHelper(classOpcode) {
4577     setOperand(0, array);
4578     setOperand(1, sep);
4579     setTemp(0, temp);
4580   }
4581 
mir()4582   const MArrayJoin* mir() const { return mir_->toArrayJoin(); }
output()4583   const LDefinition* output() { return getDef(0); }
array()4584   const LAllocation* array() { return getOperand(0); }
separator()4585   const LAllocation* separator() { return getOperand(1); }
temp()4586   const LDefinition* temp() { return getTemp(0); }
4587 };
4588 
4589 class LLoadUnboxedScalar : public LInstructionHelper<1, 2, 1> {
4590  public:
LIR_HEADER(LoadUnboxedScalar)4591   LIR_HEADER(LoadUnboxedScalar)
4592 
4593   LLoadUnboxedScalar(const LAllocation& elements, const LAllocation& index,
4594                      const LDefinition& temp)
4595       : LInstructionHelper(classOpcode) {
4596     setOperand(0, elements);
4597     setOperand(1, index);
4598     setTemp(0, temp);
4599   }
mir()4600   const MLoadUnboxedScalar* mir() const { return mir_->toLoadUnboxedScalar(); }
elements()4601   const LAllocation* elements() { return getOperand(0); }
index()4602   const LAllocation* index() { return getOperand(1); }
temp()4603   const LDefinition* temp() { return getTemp(0); }
4604 };
4605 
4606 class LLoadUnboxedBigInt : public LInstructionHelper<1, 2, 1 + INT64_PIECES> {
4607  public:
LIR_HEADER(LoadUnboxedBigInt)4608   LIR_HEADER(LoadUnboxedBigInt)
4609 
4610   LLoadUnboxedBigInt(const LAllocation& elements, const LAllocation& index,
4611                      const LDefinition& temp, const LInt64Definition& temp64)
4612       : LInstructionHelper(classOpcode) {
4613     setOperand(0, elements);
4614     setOperand(1, index);
4615     setTemp(0, temp);
4616     setInt64Temp(1, temp64);
4617   }
mir()4618   const MLoadUnboxedScalar* mir() const { return mir_->toLoadUnboxedScalar(); }
elements()4619   const LAllocation* elements() { return getOperand(0); }
index()4620   const LAllocation* index() { return getOperand(1); }
temp()4621   const LDefinition* temp() { return getTemp(0); }
temp64()4622   const LInt64Definition temp64() { return getInt64Temp(1); }
4623 };
4624 
4625 class LLoadDataViewElement : public LInstructionHelper<1, 3, 1 + INT64_PIECES> {
4626  public:
LIR_HEADER(LoadDataViewElement)4627   LIR_HEADER(LoadDataViewElement)
4628 
4629   LLoadDataViewElement(const LAllocation& elements, const LAllocation& index,
4630                        const LAllocation& littleEndian, const LDefinition& temp,
4631                        const LInt64Definition& temp64)
4632       : LInstructionHelper(classOpcode) {
4633     setOperand(0, elements);
4634     setOperand(1, index);
4635     setOperand(2, littleEndian);
4636     setTemp(0, temp);
4637     setInt64Temp(1, temp64);
4638   }
mir()4639   const MLoadDataViewElement* mir() const {
4640     return mir_->toLoadDataViewElement();
4641   }
elements()4642   const LAllocation* elements() { return getOperand(0); }
index()4643   const LAllocation* index() { return getOperand(1); }
littleEndian()4644   const LAllocation* littleEndian() { return getOperand(2); }
temp()4645   const LDefinition* temp() { return getTemp(0); }
temp64()4646   const LInt64Definition temp64() { return getInt64Temp(1); }
4647 };
4648 
4649 class LLoadTypedArrayElementHole : public LInstructionHelper<BOX_PIECES, 2, 1> {
4650  public:
LIR_HEADER(LoadTypedArrayElementHole)4651   LIR_HEADER(LoadTypedArrayElementHole)
4652 
4653   LLoadTypedArrayElementHole(const LAllocation& object,
4654                              const LAllocation& index, const LDefinition& temp)
4655       : LInstructionHelper(classOpcode) {
4656     setOperand(0, object);
4657     setOperand(1, index);
4658     setTemp(0, temp);
4659   }
mir()4660   const MLoadTypedArrayElementHole* mir() const {
4661     return mir_->toLoadTypedArrayElementHole();
4662   }
object()4663   const LAllocation* object() { return getOperand(0); }
index()4664   const LAllocation* index() { return getOperand(1); }
temp()4665   const LDefinition* temp() { return getTemp(0); }
4666 };
4667 
4668 class LLoadTypedArrayElementHoleBigInt
4669     : public LInstructionHelper<BOX_PIECES, 2, 1 + INT64_PIECES> {
4670  public:
LIR_HEADER(LoadTypedArrayElementHoleBigInt)4671   LIR_HEADER(LoadTypedArrayElementHoleBigInt)
4672 
4673   LLoadTypedArrayElementHoleBigInt(const LAllocation& object,
4674                                    const LAllocation& index,
4675                                    const LDefinition& temp,
4676                                    const LInt64Definition& temp64)
4677       : LInstructionHelper(classOpcode) {
4678     setOperand(0, object);
4679     setOperand(1, index);
4680     setTemp(0, temp);
4681     setInt64Temp(1, temp64);
4682   }
mir()4683   const MLoadTypedArrayElementHole* mir() const {
4684     return mir_->toLoadTypedArrayElementHole();
4685   }
object()4686   const LAllocation* object() { return getOperand(0); }
index()4687   const LAllocation* index() { return getOperand(1); }
temp()4688   const LDefinition* temp() { return getTemp(0); }
temp64()4689   const LInt64Definition temp64() { return getInt64Temp(1); }
4690 };
4691 
4692 class LStoreUnboxedScalar : public LInstructionHelper<0, 3, 0> {
4693  public:
LIR_HEADER(StoreUnboxedScalar)4694   LIR_HEADER(StoreUnboxedScalar)
4695 
4696   LStoreUnboxedScalar(const LAllocation& elements, const LAllocation& index,
4697                       const LAllocation& value)
4698       : LInstructionHelper(classOpcode) {
4699     setOperand(0, elements);
4700     setOperand(1, index);
4701     setOperand(2, value);
4702   }
4703 
mir()4704   const MStoreUnboxedScalar* mir() const {
4705     return mir_->toStoreUnboxedScalar();
4706   }
elements()4707   const LAllocation* elements() { return getOperand(0); }
index()4708   const LAllocation* index() { return getOperand(1); }
value()4709   const LAllocation* value() { return getOperand(2); }
4710 };
4711 
4712 class LStoreUnboxedBigInt : public LInstructionHelper<0, 3, INT64_PIECES> {
4713  public:
LIR_HEADER(StoreUnboxedBigInt)4714   LIR_HEADER(StoreUnboxedBigInt)
4715 
4716   LStoreUnboxedBigInt(const LAllocation& elements, const LAllocation& index,
4717                       const LAllocation& value, const LInt64Definition& temp)
4718       : LInstructionHelper(classOpcode) {
4719     setOperand(0, elements);
4720     setOperand(1, index);
4721     setOperand(2, value);
4722     setInt64Temp(0, temp);
4723   }
4724 
mir()4725   const MStoreUnboxedScalar* mir() const {
4726     return mir_->toStoreUnboxedScalar();
4727   }
elements()4728   const LAllocation* elements() { return getOperand(0); }
index()4729   const LAllocation* index() { return getOperand(1); }
value()4730   const LAllocation* value() { return getOperand(2); }
temp()4731   LInt64Definition temp() { return getInt64Temp(0); }
4732 };
4733 
4734 class LStoreDataViewElement
4735     : public LInstructionHelper<0, 4, 1 + INT64_PIECES> {
4736  public:
LIR_HEADER(StoreDataViewElement)4737   LIR_HEADER(StoreDataViewElement)
4738 
4739   LStoreDataViewElement(const LAllocation& elements, const LAllocation& index,
4740                         const LAllocation& value,
4741                         const LAllocation& littleEndian,
4742                         const LDefinition& temp, const LInt64Definition& temp64)
4743       : LInstructionHelper(classOpcode) {
4744     setOperand(0, elements);
4745     setOperand(1, index);
4746     setOperand(2, value);
4747     setOperand(3, littleEndian);
4748     setTemp(0, temp);
4749     setInt64Temp(1, temp64);
4750   }
4751 
mir()4752   const MStoreDataViewElement* mir() const {
4753     return mir_->toStoreDataViewElement();
4754   }
elements()4755   const LAllocation* elements() { return getOperand(0); }
index()4756   const LAllocation* index() { return getOperand(1); }
value()4757   const LAllocation* value() { return getOperand(2); }
littleEndian()4758   const LAllocation* littleEndian() { return getOperand(3); }
temp()4759   const LDefinition* temp() { return getTemp(0); }
temp64()4760   const LInt64Definition temp64() { return getInt64Temp(1); }
4761 };
4762 
4763 class LStoreTypedArrayElementHole : public LInstructionHelper<0, 4, 1> {
4764  public:
LIR_HEADER(StoreTypedArrayElementHole)4765   LIR_HEADER(StoreTypedArrayElementHole)
4766 
4767   LStoreTypedArrayElementHole(const LAllocation& elements,
4768                               const LAllocation& length,
4769                               const LAllocation& index,
4770                               const LAllocation& value,
4771                               const LDefinition& spectreTemp)
4772       : LInstructionHelper(classOpcode) {
4773     setOperand(0, elements);
4774     setOperand(1, length);
4775     setOperand(2, index);
4776     setOperand(3, value);
4777     setTemp(0, spectreTemp);
4778   }
4779 
mir()4780   const MStoreTypedArrayElementHole* mir() const {
4781     return mir_->toStoreTypedArrayElementHole();
4782   }
elements()4783   const LAllocation* elements() { return getOperand(0); }
length()4784   const LAllocation* length() { return getOperand(1); }
index()4785   const LAllocation* index() { return getOperand(2); }
value()4786   const LAllocation* value() { return getOperand(3); }
spectreTemp()4787   const LDefinition* spectreTemp() { return getTemp(0); }
4788 };
4789 
4790 class LStoreTypedArrayElementHoleBigInt
4791     : public LInstructionHelper<0, 4, INT64_PIECES> {
4792  public:
LIR_HEADER(StoreTypedArrayElementHoleBigInt)4793   LIR_HEADER(StoreTypedArrayElementHoleBigInt)
4794 
4795   LStoreTypedArrayElementHoleBigInt(const LAllocation& elements,
4796                                     const LAllocation& length,
4797                                     const LAllocation& index,
4798                                     const LAllocation& value,
4799                                     const LInt64Definition& temp)
4800       : LInstructionHelper(classOpcode) {
4801     setOperand(0, elements);
4802     setOperand(1, length);
4803     setOperand(2, index);
4804     setOperand(3, value);
4805     setInt64Temp(0, temp);
4806   }
4807 
mir()4808   const MStoreTypedArrayElementHole* mir() const {
4809     return mir_->toStoreTypedArrayElementHole();
4810   }
elements()4811   const LAllocation* elements() { return getOperand(0); }
length()4812   const LAllocation* length() { return getOperand(1); }
index()4813   const LAllocation* index() { return getOperand(2); }
value()4814   const LAllocation* value() { return getOperand(3); }
temp()4815   LInt64Definition temp() { return getInt64Temp(0); }
4816 };
4817 
4818 class LAtomicIsLockFree : public LInstructionHelper<1, 1, 0> {
4819  public:
LIR_HEADER(AtomicIsLockFree)4820   LIR_HEADER(AtomicIsLockFree)
4821 
4822   explicit LAtomicIsLockFree(const LAllocation& value)
4823       : LInstructionHelper(classOpcode) {
4824     setOperand(0, value);
4825   }
value()4826   const LAllocation* value() { return getOperand(0); }
4827 };
4828 
4829 class LCompareExchangeTypedArrayElement : public LInstructionHelper<1, 4, 4> {
4830  public:
LIR_HEADER(CompareExchangeTypedArrayElement)4831   LIR_HEADER(CompareExchangeTypedArrayElement)
4832 
4833   // ARM, ARM64, x86, x64
4834   LCompareExchangeTypedArrayElement(const LAllocation& elements,
4835                                     const LAllocation& index,
4836                                     const LAllocation& oldval,
4837                                     const LAllocation& newval,
4838                                     const LDefinition& temp)
4839       : LInstructionHelper(classOpcode) {
4840     setOperand(0, elements);
4841     setOperand(1, index);
4842     setOperand(2, oldval);
4843     setOperand(3, newval);
4844     setTemp(0, temp);
4845   }
4846   // MIPS32, MIPS64
LCompareExchangeTypedArrayElement(const LAllocation & elements,const LAllocation & index,const LAllocation & oldval,const LAllocation & newval,const LDefinition & temp,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)4847   LCompareExchangeTypedArrayElement(
4848       const LAllocation& elements, const LAllocation& index,
4849       const LAllocation& oldval, const LAllocation& newval,
4850       const LDefinition& temp, const LDefinition& valueTemp,
4851       const LDefinition& offsetTemp, const LDefinition& maskTemp)
4852       : LInstructionHelper(classOpcode) {
4853     setOperand(0, elements);
4854     setOperand(1, index);
4855     setOperand(2, oldval);
4856     setOperand(3, newval);
4857     setTemp(0, temp);
4858     setTemp(1, valueTemp);
4859     setTemp(2, offsetTemp);
4860     setTemp(3, maskTemp);
4861   }
4862 
elements()4863   const LAllocation* elements() { return getOperand(0); }
index()4864   const LAllocation* index() { return getOperand(1); }
oldval()4865   const LAllocation* oldval() { return getOperand(2); }
newval()4866   const LAllocation* newval() { return getOperand(3); }
temp()4867   const LDefinition* temp() { return getTemp(0); }
4868 
4869   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()4870   const LDefinition* valueTemp() { return getTemp(1); }
offsetTemp()4871   const LDefinition* offsetTemp() { return getTemp(2); }
maskTemp()4872   const LDefinition* maskTemp() { return getTemp(3); }
4873 
mir()4874   const MCompareExchangeTypedArrayElement* mir() const {
4875     return mir_->toCompareExchangeTypedArrayElement();
4876   }
4877 };
4878 
4879 class LAtomicExchangeTypedArrayElement : public LInstructionHelper<1, 3, 4> {
4880  public:
LIR_HEADER(AtomicExchangeTypedArrayElement)4881   LIR_HEADER(AtomicExchangeTypedArrayElement)
4882 
4883   // ARM, ARM64, x86, x64
4884   LAtomicExchangeTypedArrayElement(const LAllocation& elements,
4885                                    const LAllocation& index,
4886                                    const LAllocation& value,
4887                                    const LDefinition& temp)
4888       : LInstructionHelper(classOpcode) {
4889     setOperand(0, elements);
4890     setOperand(1, index);
4891     setOperand(2, value);
4892     setTemp(0, temp);
4893   }
4894   // MIPS32, MIPS64
LAtomicExchangeTypedArrayElement(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LDefinition & temp,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)4895   LAtomicExchangeTypedArrayElement(const LAllocation& elements,
4896                                    const LAllocation& index,
4897                                    const LAllocation& value,
4898                                    const LDefinition& temp,
4899                                    const LDefinition& valueTemp,
4900                                    const LDefinition& offsetTemp,
4901                                    const LDefinition& maskTemp)
4902       : LInstructionHelper(classOpcode) {
4903     setOperand(0, elements);
4904     setOperand(1, index);
4905     setOperand(2, value);
4906     setTemp(0, temp);
4907     setTemp(1, valueTemp);
4908     setTemp(2, offsetTemp);
4909     setTemp(3, maskTemp);
4910   }
4911 
elements()4912   const LAllocation* elements() { return getOperand(0); }
index()4913   const LAllocation* index() { return getOperand(1); }
value()4914   const LAllocation* value() { return getOperand(2); }
temp()4915   const LDefinition* temp() { return getTemp(0); }
4916 
4917   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()4918   const LDefinition* valueTemp() { return getTemp(1); }
offsetTemp()4919   const LDefinition* offsetTemp() { return getTemp(2); }
maskTemp()4920   const LDefinition* maskTemp() { return getTemp(3); }
4921 
mir()4922   const MAtomicExchangeTypedArrayElement* mir() const {
4923     return mir_->toAtomicExchangeTypedArrayElement();
4924   }
4925 };
4926 
4927 class LAtomicTypedArrayElementBinop : public LInstructionHelper<1, 3, 5> {
4928  public:
4929   LIR_HEADER(AtomicTypedArrayElementBinop)
4930 
4931   static const int32_t valueOp = 2;
4932 
4933   // ARM, ARM64, x86, x64
LAtomicTypedArrayElementBinop(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LDefinition & temp1,const LDefinition & temp2)4934   LAtomicTypedArrayElementBinop(const LAllocation& elements,
4935                                 const LAllocation& index,
4936                                 const LAllocation& value,
4937                                 const LDefinition& temp1,
4938                                 const LDefinition& temp2)
4939       : LInstructionHelper(classOpcode) {
4940     setOperand(0, elements);
4941     setOperand(1, index);
4942     setOperand(2, value);
4943     setTemp(0, temp1);
4944     setTemp(1, temp2);
4945   }
4946   // MIPS32, MIPS64
LAtomicTypedArrayElementBinop(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LDefinition & temp2,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)4947   LAtomicTypedArrayElementBinop(const LAllocation& elements,
4948                                 const LAllocation& index,
4949                                 const LAllocation& value,
4950                                 const LDefinition& temp2,
4951                                 const LDefinition& valueTemp,
4952                                 const LDefinition& offsetTemp,
4953                                 const LDefinition& maskTemp)
4954       : LInstructionHelper(classOpcode) {
4955     setOperand(0, elements);
4956     setOperand(1, index);
4957     setOperand(2, value);
4958     setTemp(0, LDefinition::BogusTemp());
4959     setTemp(1, temp2);
4960     setTemp(2, valueTemp);
4961     setTemp(3, offsetTemp);
4962     setTemp(4, maskTemp);
4963   }
4964 
elements()4965   const LAllocation* elements() { return getOperand(0); }
index()4966   const LAllocation* index() { return getOperand(1); }
value()4967   const LAllocation* value() {
4968     MOZ_ASSERT(valueOp == 2);
4969     return getOperand(2);
4970   }
temp1()4971   const LDefinition* temp1() { return getTemp(0); }
temp2()4972   const LDefinition* temp2() { return getTemp(1); }
4973 
4974   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()4975   const LDefinition* valueTemp() { return getTemp(2); }
offsetTemp()4976   const LDefinition* offsetTemp() { return getTemp(3); }
maskTemp()4977   const LDefinition* maskTemp() { return getTemp(4); }
4978 
mir()4979   const MAtomicTypedArrayElementBinop* mir() const {
4980     return mir_->toAtomicTypedArrayElementBinop();
4981   }
4982 };
4983 
4984 // Atomic binary operation where the result is discarded.
4985 class LAtomicTypedArrayElementBinopForEffect
4986     : public LInstructionHelper<0, 3, 4> {
4987  public:
LIR_HEADER(AtomicTypedArrayElementBinopForEffect)4988   LIR_HEADER(AtomicTypedArrayElementBinopForEffect)
4989 
4990   // ARM, ARM64, x86, x64
4991   LAtomicTypedArrayElementBinopForEffect(
4992       const LAllocation& elements, const LAllocation& index,
4993       const LAllocation& value,
4994       const LDefinition& flagTemp = LDefinition::BogusTemp())
4995       : LInstructionHelper(classOpcode) {
4996     setOperand(0, elements);
4997     setOperand(1, index);
4998     setOperand(2, value);
4999     setTemp(0, flagTemp);
5000   }
5001   // MIPS32, MIPS64
LAtomicTypedArrayElementBinopForEffect(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)5002   LAtomicTypedArrayElementBinopForEffect(const LAllocation& elements,
5003                                          const LAllocation& index,
5004                                          const LAllocation& value,
5005                                          const LDefinition& valueTemp,
5006                                          const LDefinition& offsetTemp,
5007                                          const LDefinition& maskTemp)
5008       : LInstructionHelper(classOpcode) {
5009     setOperand(0, elements);
5010     setOperand(1, index);
5011     setOperand(2, value);
5012     setTemp(0, LDefinition::BogusTemp());
5013     setTemp(1, valueTemp);
5014     setTemp(2, offsetTemp);
5015     setTemp(3, maskTemp);
5016   }
5017 
elements()5018   const LAllocation* elements() { return getOperand(0); }
index()5019   const LAllocation* index() { return getOperand(1); }
value()5020   const LAllocation* value() { return getOperand(2); }
5021 
5022   // Temp that may be used on LL/SC platforms for the flag result of the store.
flagTemp()5023   const LDefinition* flagTemp() { return getTemp(0); }
5024   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()5025   const LDefinition* valueTemp() { return getTemp(1); }
offsetTemp()5026   const LDefinition* offsetTemp() { return getTemp(2); }
maskTemp()5027   const LDefinition* maskTemp() { return getTemp(3); }
5028 
mir()5029   const MAtomicTypedArrayElementBinop* mir() const {
5030     return mir_->toAtomicTypedArrayElementBinop();
5031   }
5032 };
5033 
5034 class LAtomicLoad64 : public LInstructionHelper<1, 2, 1 + INT64_PIECES> {
5035  public:
LIR_HEADER(AtomicLoad64)5036   LIR_HEADER(AtomicLoad64)
5037 
5038   LAtomicLoad64(const LAllocation& elements, const LAllocation& index,
5039                 const LDefinition& temp, const LInt64Definition& temp64)
5040       : LInstructionHelper(classOpcode) {
5041     setOperand(0, elements);
5042     setOperand(1, index);
5043     setTemp(0, temp);
5044     setInt64Temp(1, temp64);
5045   }
mir()5046   const MLoadUnboxedScalar* mir() const { return mir_->toLoadUnboxedScalar(); }
elements()5047   const LAllocation* elements() { return getOperand(0); }
index()5048   const LAllocation* index() { return getOperand(1); }
temp()5049   const LDefinition* temp() { return getTemp(0); }
temp64()5050   LInt64Definition temp64() { return getInt64Temp(1); }
5051 };
5052 
5053 class LAtomicStore64 : public LInstructionHelper<0, 3, 2 * INT64_PIECES + 1> {
5054  public:
LIR_HEADER(AtomicStore64)5055   LIR_HEADER(AtomicStore64)
5056 
5057   // x64, ARM64
5058   LAtomicStore64(const LAllocation& elements, const LAllocation& index,
5059                  const LAllocation& value, const LInt64Definition& temp1)
5060       : LInstructionHelper(classOpcode) {
5061     setOperand(0, elements);
5062     setOperand(1, index);
5063     setOperand(2, value);
5064     setInt64Temp(0, temp1);
5065     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5066     setTemp(2 * INT64_PIECES, LDefinition::BogusTemp());
5067   }
5068 
5069   // ARM32
LAtomicStore64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp1,const LInt64Definition & temp2)5070   LAtomicStore64(const LAllocation& elements, const LAllocation& index,
5071                  const LAllocation& value, const LInt64Definition& temp1,
5072                  const LInt64Definition& temp2)
5073       : LInstructionHelper(classOpcode) {
5074     setOperand(0, elements);
5075     setOperand(1, index);
5076     setOperand(2, value);
5077     setInt64Temp(0, temp1);
5078     setInt64Temp(INT64_PIECES, temp2);
5079     setTemp(2 * INT64_PIECES, LDefinition::BogusTemp());
5080   }
5081 
5082   // x86
LAtomicStore64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp1,const LDefinition & tempLow)5083   LAtomicStore64(const LAllocation& elements, const LAllocation& index,
5084                  const LAllocation& value, const LInt64Definition& temp1,
5085                  const LDefinition& tempLow)
5086       : LInstructionHelper(classOpcode) {
5087     setOperand(0, elements);
5088     setOperand(1, index);
5089     setOperand(2, value);
5090     setInt64Temp(0, temp1);
5091     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5092     setTemp(2 * INT64_PIECES, tempLow);
5093   }
5094 
mir()5095   const MStoreUnboxedScalar* mir() const {
5096     return mir_->toStoreUnboxedScalar();
5097   }
elements()5098   const LAllocation* elements() { return getOperand(0); }
index()5099   const LAllocation* index() { return getOperand(1); }
value()5100   const LAllocation* value() { return getOperand(2); }
temp1()5101   LInt64Definition temp1() { return getInt64Temp(0); }
temp2()5102   LInt64Definition temp2() { return getInt64Temp(INT64_PIECES); }
tempLow()5103   const LDefinition* tempLow() { return getTemp(2 * INT64_PIECES); }
5104 };
5105 
5106 class LCompareExchangeTypedArrayElement64
5107     : public LInstructionHelper<1, 4, 3 * INT64_PIECES + 1> {
5108  public:
LIR_HEADER(CompareExchangeTypedArrayElement64)5109   LIR_HEADER(CompareExchangeTypedArrayElement64)
5110 
5111   // x64, ARM64
5112   LCompareExchangeTypedArrayElement64(const LAllocation& elements,
5113                                       const LAllocation& index,
5114                                       const LAllocation& oldval,
5115                                       const LAllocation& newval,
5116                                       const LInt64Definition& temp1,
5117                                       const LInt64Definition& temp2)
5118       : LInstructionHelper(classOpcode) {
5119     setOperand(0, elements);
5120     setOperand(1, index);
5121     setOperand(2, oldval);
5122     setOperand(3, newval);
5123     setInt64Temp(0, temp1);
5124     setInt64Temp(INT64_PIECES, temp2);
5125     setInt64Temp(2 * INT64_PIECES, LInt64Definition::BogusTemp());
5126     setTemp(3 * INT64_PIECES, LDefinition::BogusTemp());
5127   }
5128 
5129   // x86
LCompareExchangeTypedArrayElement64(const LAllocation & elements,const LAllocation & index,const LAllocation & oldval,const LAllocation & newval,const LDefinition & tempLow)5130   LCompareExchangeTypedArrayElement64(const LAllocation& elements,
5131                                       const LAllocation& index,
5132                                       const LAllocation& oldval,
5133                                       const LAllocation& newval,
5134                                       const LDefinition& tempLow)
5135       : LInstructionHelper(classOpcode) {
5136     setOperand(0, elements);
5137     setOperand(1, index);
5138     setOperand(2, oldval);
5139     setOperand(3, newval);
5140     setInt64Temp(0, LInt64Definition::BogusTemp());
5141     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5142     setInt64Temp(2 * INT64_PIECES, LInt64Definition::BogusTemp());
5143     setTemp(3 * INT64_PIECES, tempLow);
5144   }
5145 
5146   // ARM
LCompareExchangeTypedArrayElement64(const LAllocation & elements,const LAllocation & index,const LAllocation & oldval,const LAllocation & newval,const LInt64Definition & temp1,const LInt64Definition & temp2,const LInt64Definition & temp3)5147   LCompareExchangeTypedArrayElement64(const LAllocation& elements,
5148                                       const LAllocation& index,
5149                                       const LAllocation& oldval,
5150                                       const LAllocation& newval,
5151                                       const LInt64Definition& temp1,
5152                                       const LInt64Definition& temp2,
5153                                       const LInt64Definition& temp3)
5154       : LInstructionHelper(classOpcode) {
5155     setOperand(0, elements);
5156     setOperand(1, index);
5157     setOperand(2, oldval);
5158     setOperand(3, newval);
5159     setInt64Temp(0, temp1);
5160     setInt64Temp(INT64_PIECES, temp2);
5161     setInt64Temp(2 * INT64_PIECES, temp3);
5162     setTemp(3 * INT64_PIECES, LDefinition::BogusTemp());
5163   }
5164 
mir()5165   const MCompareExchangeTypedArrayElement* mir() const {
5166     return mir_->toCompareExchangeTypedArrayElement();
5167   }
elements()5168   const LAllocation* elements() { return getOperand(0); }
index()5169   const LAllocation* index() { return getOperand(1); }
oldval()5170   const LAllocation* oldval() { return getOperand(2); }
newval()5171   const LAllocation* newval() { return getOperand(3); }
temp1()5172   LInt64Definition temp1() { return getInt64Temp(0); }
temp2()5173   LInt64Definition temp2() { return getInt64Temp(INT64_PIECES); }
temp3()5174   LInt64Definition temp3() { return getInt64Temp(2 * INT64_PIECES); }
tempLow()5175   const LDefinition* tempLow() { return getTemp(3 * INT64_PIECES); }
5176 };
5177 
5178 class LAtomicExchangeTypedArrayElement64
5179     : public LInstructionHelper<1, 3, INT64_PIECES + 1> {
5180  public:
LIR_HEADER(AtomicExchangeTypedArrayElement64)5181   LIR_HEADER(AtomicExchangeTypedArrayElement64)
5182 
5183   // ARM, ARM64, x64
5184   LAtomicExchangeTypedArrayElement64(const LAllocation& elements,
5185                                      const LAllocation& index,
5186                                      const LAllocation& value,
5187                                      const LInt64Definition& temp1,
5188                                      const LDefinition& temp2)
5189       : LInstructionHelper(classOpcode) {
5190     setOperand(0, elements);
5191     setOperand(1, index);
5192     setOperand(2, value);
5193     setInt64Temp(0, temp1);
5194     setTemp(INT64_PIECES, temp2);
5195   }
5196 
5197   // x86
LAtomicExchangeTypedArrayElement64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp)5198   LAtomicExchangeTypedArrayElement64(const LAllocation& elements,
5199                                      const LAllocation& index,
5200                                      const LAllocation& value,
5201                                      const LInt64Definition& temp)
5202       : LInstructionHelper(classOpcode) {
5203     setOperand(0, elements);
5204     setOperand(1, index);
5205     setOperand(2, value);
5206     setInt64Temp(0, temp);
5207     setTemp(INT64_PIECES, LDefinition::BogusTemp());
5208   }
5209 
elements()5210   const LAllocation* elements() { return getOperand(0); }
index()5211   const LAllocation* index() { return getOperand(1); }
value()5212   const LAllocation* value() { return getOperand(2); }
temp1()5213   LInt64Definition temp1() { return getInt64Temp(0); }
temp2()5214   const LDefinition* temp2() { return getTemp(INT64_PIECES); }
5215 
mir()5216   const MAtomicExchangeTypedArrayElement* mir() const {
5217     return mir_->toAtomicExchangeTypedArrayElement();
5218   }
5219 };
5220 
5221 class LAtomicTypedArrayElementBinop64
5222     : public LInstructionHelper<1, 3, 3 * INT64_PIECES> {
5223  public:
LIR_HEADER(AtomicTypedArrayElementBinop64)5224   LIR_HEADER(AtomicTypedArrayElementBinop64)
5225 
5226   // x86
5227   LAtomicTypedArrayElementBinop64(const LAllocation& elements,
5228                                   const LAllocation& index,
5229                                   const LAllocation& value,
5230                                   const LInt64Definition& temp1)
5231       : LInstructionHelper(classOpcode) {
5232     setOperand(0, elements);
5233     setOperand(1, index);
5234     setOperand(2, value);
5235     setInt64Temp(0, temp1);
5236     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5237     setInt64Temp(2 * INT64_PIECES, LInt64Definition::BogusTemp());
5238   }
5239 
5240   // ARM64, x64
LAtomicTypedArrayElementBinop64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp1,const LInt64Definition & temp2)5241   LAtomicTypedArrayElementBinop64(const LAllocation& elements,
5242                                   const LAllocation& index,
5243                                   const LAllocation& value,
5244                                   const LInt64Definition& temp1,
5245                                   const LInt64Definition& temp2)
5246       : LInstructionHelper(classOpcode) {
5247     setOperand(0, elements);
5248     setOperand(1, index);
5249     setOperand(2, value);
5250     setInt64Temp(0, temp1);
5251     setInt64Temp(INT64_PIECES, temp2);
5252     setInt64Temp(2 * INT64_PIECES, LInt64Definition::BogusTemp());
5253   }
5254 
5255   // ARM
LAtomicTypedArrayElementBinop64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp1,const LInt64Definition & temp2,const LInt64Definition & temp3)5256   LAtomicTypedArrayElementBinop64(const LAllocation& elements,
5257                                   const LAllocation& index,
5258                                   const LAllocation& value,
5259                                   const LInt64Definition& temp1,
5260                                   const LInt64Definition& temp2,
5261                                   const LInt64Definition& temp3)
5262       : LInstructionHelper(classOpcode) {
5263     setOperand(0, elements);
5264     setOperand(1, index);
5265     setOperand(2, value);
5266     setInt64Temp(0, temp1);
5267     setInt64Temp(INT64_PIECES, temp2);
5268     setInt64Temp(2 * INT64_PIECES, temp3);
5269   }
5270 
elements()5271   const LAllocation* elements() { return getOperand(0); }
index()5272   const LAllocation* index() { return getOperand(1); }
value()5273   const LAllocation* value() { return getOperand(2); }
temp1()5274   LInt64Definition temp1() { return getInt64Temp(0); }
temp2()5275   LInt64Definition temp2() { return getInt64Temp(INT64_PIECES); }
temp3()5276   LInt64Definition temp3() { return getInt64Temp(2 * INT64_PIECES); }
5277 
mir()5278   const MAtomicTypedArrayElementBinop* mir() const {
5279     return mir_->toAtomicTypedArrayElementBinop();
5280   }
5281 };
5282 
5283 // Atomic binary operation where the result is discarded.
5284 class LAtomicTypedArrayElementBinopForEffect64
5285     : public LInstructionHelper<0, 3, 2 * INT64_PIECES + 1> {
5286  public:
LIR_HEADER(AtomicTypedArrayElementBinopForEffect64)5287   LIR_HEADER(AtomicTypedArrayElementBinopForEffect64)
5288 
5289   // x86
5290   LAtomicTypedArrayElementBinopForEffect64(const LAllocation& elements,
5291                                            const LAllocation& index,
5292                                            const LAllocation& value,
5293                                            const LInt64Definition& temp,
5294                                            const LDefinition& tempLow)
5295       : LInstructionHelper(classOpcode) {
5296     setOperand(0, elements);
5297     setOperand(1, index);
5298     setOperand(2, value);
5299     setInt64Temp(0, temp);
5300     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5301     setTemp(2 * INT64_PIECES, tempLow);
5302   }
5303 
5304   // x64
LAtomicTypedArrayElementBinopForEffect64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp)5305   LAtomicTypedArrayElementBinopForEffect64(const LAllocation& elements,
5306                                            const LAllocation& index,
5307                                            const LAllocation& value,
5308                                            const LInt64Definition& temp)
5309       : LInstructionHelper(classOpcode) {
5310     setOperand(0, elements);
5311     setOperand(1, index);
5312     setOperand(2, value);
5313     setInt64Temp(0, temp);
5314     setInt64Temp(INT64_PIECES, LInt64Definition::BogusTemp());
5315     setTemp(2 * INT64_PIECES, LDefinition::BogusTemp());
5316   }
5317 
5318   // ARM64
LAtomicTypedArrayElementBinopForEffect64(const LAllocation & elements,const LAllocation & index,const LAllocation & value,const LInt64Definition & temp1,const LInt64Definition & temp2)5319   LAtomicTypedArrayElementBinopForEffect64(const LAllocation& elements,
5320                                            const LAllocation& index,
5321                                            const LAllocation& value,
5322                                            const LInt64Definition& temp1,
5323                                            const LInt64Definition& temp2)
5324       : LInstructionHelper(classOpcode) {
5325     setOperand(0, elements);
5326     setOperand(1, index);
5327     setOperand(2, value);
5328     setInt64Temp(0, temp1);
5329     setInt64Temp(INT64_PIECES, temp2);
5330     setTemp(2 * INT64_PIECES, LDefinition::BogusTemp());
5331   }
5332 
elements()5333   const LAllocation* elements() { return getOperand(0); }
index()5334   const LAllocation* index() { return getOperand(1); }
value()5335   const LAllocation* value() { return getOperand(2); }
temp1()5336   LInt64Definition temp1() { return getInt64Temp(0); }
temp2()5337   LInt64Definition temp2() { return getInt64Temp(INT64_PIECES); }
tempLow()5338   const LDefinition* tempLow() { return getTemp(2 * INT64_PIECES); }
5339 
mir()5340   const MAtomicTypedArrayElementBinop* mir() const {
5341     return mir_->toAtomicTypedArrayElementBinop();
5342   }
5343 };
5344 
5345 class LEffectiveAddress : public LInstructionHelper<1, 2, 0> {
5346  public:
5347   LIR_HEADER(EffectiveAddress);
5348 
LEffectiveAddress(const LAllocation & base,const LAllocation & index)5349   LEffectiveAddress(const LAllocation& base, const LAllocation& index)
5350       : LInstructionHelper(classOpcode) {
5351     setOperand(0, base);
5352     setOperand(1, index);
5353   }
mir()5354   const MEffectiveAddress* mir() const { return mir_->toEffectiveAddress(); }
base()5355   const LAllocation* base() { return getOperand(0); }
index()5356   const LAllocation* index() { return getOperand(1); }
5357 };
5358 
5359 class LClampIToUint8 : public LInstructionHelper<1, 1, 0> {
5360  public:
LIR_HEADER(ClampIToUint8)5361   LIR_HEADER(ClampIToUint8)
5362 
5363   explicit LClampIToUint8(const LAllocation& in)
5364       : LInstructionHelper(classOpcode) {
5365     setOperand(0, in);
5366   }
5367 };
5368 
5369 class LClampDToUint8 : public LInstructionHelper<1, 1, 1> {
5370  public:
LIR_HEADER(ClampDToUint8)5371   LIR_HEADER(ClampDToUint8)
5372 
5373   LClampDToUint8(const LAllocation& in, const LDefinition& temp)
5374       : LInstructionHelper(classOpcode) {
5375     setOperand(0, in);
5376     setTemp(0, temp);
5377   }
5378 };
5379 
5380 class LClampVToUint8 : public LInstructionHelper<1, BOX_PIECES, 1> {
5381  public:
LIR_HEADER(ClampVToUint8)5382   LIR_HEADER(ClampVToUint8)
5383 
5384   LClampVToUint8(const LBoxAllocation& input, const LDefinition& tempFloat)
5385       : LInstructionHelper(classOpcode) {
5386     setBoxOperand(Input, input);
5387     setTemp(0, tempFloat);
5388   }
5389 
5390   static const size_t Input = 0;
5391 
tempFloat()5392   const LDefinition* tempFloat() { return getTemp(0); }
mir()5393   const MClampToUint8* mir() const { return mir_->toClampToUint8(); }
5394 };
5395 
5396 // Load a boxed value from an object's fixed slot.
5397 class LLoadFixedSlotV : public LInstructionHelper<BOX_PIECES, 1, 0> {
5398  public:
LIR_HEADER(LoadFixedSlotV)5399   LIR_HEADER(LoadFixedSlotV)
5400 
5401   explicit LLoadFixedSlotV(const LAllocation& object)
5402       : LInstructionHelper(classOpcode) {
5403     setOperand(0, object);
5404   }
mir()5405   const MLoadFixedSlot* mir() const { return mir_->toLoadFixedSlot(); }
5406 };
5407 
5408 // Load a typed value from an object's fixed slot.
5409 class LLoadFixedSlotT : public LInstructionHelper<1, 1, 0> {
5410  public:
LIR_HEADER(LoadFixedSlotT)5411   LIR_HEADER(LoadFixedSlotT)
5412 
5413   explicit LLoadFixedSlotT(const LAllocation& object)
5414       : LInstructionHelper(classOpcode) {
5415     setOperand(0, object);
5416   }
mir()5417   const MLoadFixedSlot* mir() const { return mir_->toLoadFixedSlot(); }
5418 };
5419 
5420 class LLoadFixedSlotAndUnbox : public LInstructionHelper<1, 1, 0> {
5421  public:
LIR_HEADER(LoadFixedSlotAndUnbox)5422   LIR_HEADER(LoadFixedSlotAndUnbox)
5423 
5424   explicit LLoadFixedSlotAndUnbox(const LAllocation& object)
5425       : LInstructionHelper(classOpcode) {
5426     setOperand(0, object);
5427   }
5428 
object()5429   const LAllocation* object() { return getOperand(0); }
5430 
mir()5431   const MLoadFixedSlotAndUnbox* mir() const {
5432     return mir_->toLoadFixedSlotAndUnbox();
5433   }
5434 };
5435 
5436 class LLoadDynamicSlotAndUnbox : public LInstructionHelper<1, 1, 0> {
5437  public:
LIR_HEADER(LoadDynamicSlotAndUnbox)5438   LIR_HEADER(LoadDynamicSlotAndUnbox)
5439 
5440   explicit LLoadDynamicSlotAndUnbox(const LAllocation& slots)
5441       : LInstructionHelper(classOpcode) {
5442     setOperand(0, slots);
5443   }
5444 
slots()5445   const LAllocation* slots() { return getOperand(0); }
5446 
mir()5447   const MLoadDynamicSlotAndUnbox* mir() const {
5448     return mir_->toLoadDynamicSlotAndUnbox();
5449   }
5450 };
5451 
5452 class LLoadElementAndUnbox : public LInstructionHelper<1, 2, 0> {
5453  public:
LIR_HEADER(LoadElementAndUnbox)5454   LIR_HEADER(LoadElementAndUnbox)
5455 
5456   LLoadElementAndUnbox(const LAllocation& elements, const LAllocation& index)
5457       : LInstructionHelper(classOpcode) {
5458     setOperand(0, elements);
5459     setOperand(1, index);
5460   }
5461 
elements()5462   const LAllocation* elements() { return getOperand(0); }
index()5463   const LAllocation* index() { return getOperand(1); }
5464 
mir()5465   const MLoadElementAndUnbox* mir() const {
5466     return mir_->toLoadElementAndUnbox();
5467   }
5468 };
5469 
5470 class LAddAndStoreSlot : public LInstructionHelper<0, 1 + BOX_PIECES, 1> {
5471  public:
LIR_HEADER(AddAndStoreSlot)5472   LIR_HEADER(AddAndStoreSlot)
5473 
5474   LAddAndStoreSlot(const LAllocation& obj, const LBoxAllocation& value,
5475                    const LDefinition& temp)
5476       : LInstructionHelper(classOpcode) {
5477     setOperand(0, obj);
5478     setBoxOperand(Value, value);
5479     setTemp(0, temp);
5480   }
5481 
5482   static const size_t Value = 1;
5483 
mir()5484   const MAddAndStoreSlot* mir() const { return mir_->toAddAndStoreSlot(); }
5485 };
5486 
5487 class LAllocateAndStoreSlot
5488     : public LCallInstructionHelper<0, 1 + BOX_PIECES, 2> {
5489  public:
LIR_HEADER(AllocateAndStoreSlot)5490   LIR_HEADER(AllocateAndStoreSlot)
5491 
5492   LAllocateAndStoreSlot(const LAllocation& obj, const LBoxAllocation& value,
5493                         const LDefinition& temp1, const LDefinition& temp2)
5494       : LCallInstructionHelper(classOpcode) {
5495     setOperand(0, obj);
5496     setBoxOperand(Value, value);
5497     setTemp(0, temp1);
5498     setTemp(1, temp2);
5499   }
5500 
5501   static const size_t Value = 1;
5502 
mir()5503   const MAllocateAndStoreSlot* mir() const {
5504     return mir_->toAllocateAndStoreSlot();
5505   }
5506 };
5507 
5508 // Store a boxed value to an object's fixed slot.
5509 class LStoreFixedSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> {
5510  public:
LIR_HEADER(StoreFixedSlotV)5511   LIR_HEADER(StoreFixedSlotV)
5512 
5513   LStoreFixedSlotV(const LAllocation& obj, const LBoxAllocation& value)
5514       : LInstructionHelper(classOpcode) {
5515     setOperand(0, obj);
5516     setBoxOperand(Value, value);
5517   }
5518 
5519   static const size_t Value = 1;
5520 
mir()5521   const MStoreFixedSlot* mir() const { return mir_->toStoreFixedSlot(); }
obj()5522   const LAllocation* obj() { return getOperand(0); }
5523 };
5524 
5525 // Store a typed value to an object's fixed slot.
5526 class LStoreFixedSlotT : public LInstructionHelper<0, 2, 0> {
5527  public:
LIR_HEADER(StoreFixedSlotT)5528   LIR_HEADER(StoreFixedSlotT)
5529 
5530   LStoreFixedSlotT(const LAllocation& obj, const LAllocation& value)
5531       : LInstructionHelper(classOpcode) {
5532     setOperand(0, obj);
5533     setOperand(1, value);
5534   }
mir()5535   const MStoreFixedSlot* mir() const { return mir_->toStoreFixedSlot(); }
obj()5536   const LAllocation* obj() { return getOperand(0); }
value()5537   const LAllocation* value() { return getOperand(1); }
5538 };
5539 
5540 // Note, Name ICs always return a Value. There are no V/T variants.
5541 class LGetNameCache : public LInstructionHelper<BOX_PIECES, 1, 1> {
5542  public:
LIR_HEADER(GetNameCache)5543   LIR_HEADER(GetNameCache)
5544 
5545   LGetNameCache(const LAllocation& envObj, const LDefinition& temp)
5546       : LInstructionHelper(classOpcode) {
5547     setOperand(0, envObj);
5548     setTemp(0, temp);
5549   }
envObj()5550   const LAllocation* envObj() { return getOperand(0); }
temp()5551   const LDefinition* temp() { return getTemp(0); }
mir()5552   const MGetNameCache* mir() const { return mir_->toGetNameCache(); }
5553 };
5554 
5555 class LCallGetIntrinsicValue : public LCallInstructionHelper<BOX_PIECES, 0, 0> {
5556  public:
LIR_HEADER(CallGetIntrinsicValue)5557   LIR_HEADER(CallGetIntrinsicValue)
5558 
5559   const MCallGetIntrinsicValue* mir() const {
5560     return mir_->toCallGetIntrinsicValue();
5561   }
5562 
LCallGetIntrinsicValue()5563   LCallGetIntrinsicValue() : LCallInstructionHelper(classOpcode) {}
5564 };
5565 
5566 class LGetPropSuperCache
5567     : public LInstructionHelper<BOX_PIECES, 1 + 2 * BOX_PIECES, 0> {
5568  public:
5569   LIR_HEADER(GetPropSuperCache)
5570 
5571   static const size_t Receiver = 1;
5572   static const size_t Id = Receiver + BOX_PIECES;
5573 
LGetPropSuperCache(const LAllocation & obj,const LBoxAllocation & receiver,const LBoxAllocation & id)5574   LGetPropSuperCache(const LAllocation& obj, const LBoxAllocation& receiver,
5575                      const LBoxAllocation& id)
5576       : LInstructionHelper(classOpcode) {
5577     setOperand(0, obj);
5578     setBoxOperand(Receiver, receiver);
5579     setBoxOperand(Id, id);
5580   }
obj()5581   const LAllocation* obj() { return getOperand(0); }
mir()5582   const MGetPropSuperCache* mir() const { return mir_->toGetPropSuperCache(); }
5583 };
5584 
5585 // Patchable jump to stubs generated for a GetProperty cache, which loads a
5586 // boxed value.
5587 class LGetPropertyCache
5588     : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0> {
5589  public:
5590   LIR_HEADER(GetPropertyCache)
5591 
5592   static const size_t Value = 0;
5593   static const size_t Id = BOX_PIECES;
5594 
LGetPropertyCache(const LBoxAllocation & value,const LBoxAllocation & id)5595   LGetPropertyCache(const LBoxAllocation& value, const LBoxAllocation& id)
5596       : LInstructionHelper(classOpcode) {
5597     setBoxOperand(Value, value);
5598     setBoxOperand(Id, id);
5599   }
mir()5600   const MGetPropertyCache* mir() const { return mir_->toGetPropertyCache(); }
5601 };
5602 
5603 class LBindNameCache : public LInstructionHelper<1, 1, 1> {
5604  public:
LIR_HEADER(BindNameCache)5605   LIR_HEADER(BindNameCache)
5606 
5607   LBindNameCache(const LAllocation& envChain, const LDefinition& temp)
5608       : LInstructionHelper(classOpcode) {
5609     setOperand(0, envChain);
5610     setTemp(0, temp);
5611   }
environmentChain()5612   const LAllocation* environmentChain() { return getOperand(0); }
temp()5613   const LDefinition* temp() { return getTemp(0); }
mir()5614   const MBindNameCache* mir() const { return mir_->toBindNameCache(); }
5615 };
5616 
5617 class LCallBindVar : public LInstructionHelper<1, 1, 0> {
5618  public:
LIR_HEADER(CallBindVar)5619   LIR_HEADER(CallBindVar)
5620 
5621   explicit LCallBindVar(const LAllocation& envChain)
5622       : LInstructionHelper(classOpcode) {
5623     setOperand(0, envChain);
5624   }
environmentChain()5625   const LAllocation* environmentChain() { return getOperand(0); }
mir()5626   const MCallBindVar* mir() const { return mir_->toCallBindVar(); }
5627 };
5628 
5629 // Load a value from an object's dslots or a slots vector.
5630 class LLoadDynamicSlotV : public LInstructionHelper<BOX_PIECES, 1, 0> {
5631  public:
LIR_HEADER(LoadDynamicSlotV)5632   LIR_HEADER(LoadDynamicSlotV)
5633 
5634   explicit LLoadDynamicSlotV(const LAllocation& in)
5635       : LInstructionHelper(classOpcode) {
5636     setOperand(0, in);
5637   }
mir()5638   const MLoadDynamicSlot* mir() const { return mir_->toLoadDynamicSlot(); }
5639 };
5640 
5641 // Store a value to an object's dslots or a slots vector.
5642 class LStoreDynamicSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> {
5643  public:
LIR_HEADER(StoreDynamicSlotV)5644   LIR_HEADER(StoreDynamicSlotV)
5645 
5646   LStoreDynamicSlotV(const LAllocation& slots, const LBoxAllocation& value)
5647       : LInstructionHelper(classOpcode) {
5648     setOperand(0, slots);
5649     setBoxOperand(Value, value);
5650   }
5651 
5652   static const size_t Value = 1;
5653 
mir()5654   const MStoreDynamicSlot* mir() const { return mir_->toStoreDynamicSlot(); }
slots()5655   const LAllocation* slots() { return getOperand(0); }
5656 };
5657 
5658 // Store a typed value to an object's dslots or a slots vector. This has a
5659 // few advantages over LStoreDynamicSlotV:
5660 // 1) We can bypass storing the type tag if the slot has the same type as
5661 //    the value.
5662 // 2) Better register allocation: we can store constants and FP regs directly
5663 //    without requiring a second register for the value.
5664 class LStoreDynamicSlotT : public LInstructionHelper<0, 2, 0> {
5665  public:
LIR_HEADER(StoreDynamicSlotT)5666   LIR_HEADER(StoreDynamicSlotT)
5667 
5668   LStoreDynamicSlotT(const LAllocation& slots, const LAllocation& value)
5669       : LInstructionHelper(classOpcode) {
5670     setOperand(0, slots);
5671     setOperand(1, value);
5672   }
mir()5673   const MStoreDynamicSlot* mir() const { return mir_->toStoreDynamicSlot(); }
slots()5674   const LAllocation* slots() { return getOperand(0); }
value()5675   const LAllocation* value() { return getOperand(1); }
5676 };
5677 
5678 // Read length field of a JSString*.
5679 class LStringLength : public LInstructionHelper<1, 1, 0> {
5680  public:
LIR_HEADER(StringLength)5681   LIR_HEADER(StringLength)
5682 
5683   explicit LStringLength(const LAllocation& string)
5684       : LInstructionHelper(classOpcode) {
5685     setOperand(0, string);
5686   }
5687 
string()5688   const LAllocation* string() { return getOperand(0); }
5689 };
5690 
5691 // Take the floor of a double precision number and converts it to an int32.
5692 // Implements Math.floor().
5693 class LFloor : public LInstructionHelper<1, 1, 0> {
5694  public:
LIR_HEADER(Floor)5695   LIR_HEADER(Floor)
5696 
5697   explicit LFloor(const LAllocation& num) : LInstructionHelper(classOpcode) {
5698     setOperand(0, num);
5699   }
5700 };
5701 
5702 // Take the floor of a single precision number and converts it to an int32.
5703 // Implements Math.floor().
5704 class LFloorF : public LInstructionHelper<1, 1, 0> {
5705  public:
LIR_HEADER(FloorF)5706   LIR_HEADER(FloorF)
5707 
5708   explicit LFloorF(const LAllocation& num) : LInstructionHelper(classOpcode) {
5709     setOperand(0, num);
5710   }
5711 };
5712 
5713 // Take the ceiling of a double precision number and converts it to an int32.
5714 // Implements Math.ceil().
5715 class LCeil : public LInstructionHelper<1, 1, 0> {
5716  public:
LIR_HEADER(Ceil)5717   LIR_HEADER(Ceil)
5718 
5719   explicit LCeil(const LAllocation& num) : LInstructionHelper(classOpcode) {
5720     setOperand(0, num);
5721   }
5722 };
5723 
5724 // Take the ceiling of a single precision number and converts it to an int32.
5725 // Implements Math.ceil().
5726 class LCeilF : public LInstructionHelper<1, 1, 0> {
5727  public:
LIR_HEADER(CeilF)5728   LIR_HEADER(CeilF)
5729 
5730   explicit LCeilF(const LAllocation& num) : LInstructionHelper(classOpcode) {
5731     setOperand(0, num);
5732   }
5733 };
5734 
5735 // Round a double precision number and converts it to an int32.
5736 // Implements Math.round().
5737 class LRound : public LInstructionHelper<1, 1, 1> {
5738  public:
LIR_HEADER(Round)5739   LIR_HEADER(Round)
5740 
5741   LRound(const LAllocation& num, const LDefinition& temp)
5742       : LInstructionHelper(classOpcode) {
5743     setOperand(0, num);
5744     setTemp(0, temp);
5745   }
5746 
temp()5747   const LDefinition* temp() { return getTemp(0); }
mir()5748   MRound* mir() const { return mir_->toRound(); }
5749 };
5750 
5751 // Round a single precision number and converts it to an int32.
5752 // Implements Math.round().
5753 class LRoundF : public LInstructionHelper<1, 1, 1> {
5754  public:
LIR_HEADER(RoundF)5755   LIR_HEADER(RoundF)
5756 
5757   LRoundF(const LAllocation& num, const LDefinition& temp)
5758       : LInstructionHelper(classOpcode) {
5759     setOperand(0, num);
5760     setTemp(0, temp);
5761   }
5762 
temp()5763   const LDefinition* temp() { return getTemp(0); }
mir()5764   MRound* mir() const { return mir_->toRound(); }
5765 };
5766 
5767 // Truncates a double precision number and converts it to an int32.
5768 // Implements Math.trunc().
5769 class LTrunc : public LInstructionHelper<1, 1, 0> {
5770  public:
LIR_HEADER(Trunc)5771   LIR_HEADER(Trunc)
5772 
5773   explicit LTrunc(const LAllocation& num) : LInstructionHelper(classOpcode) {
5774     setOperand(0, num);
5775   }
5776 };
5777 
5778 // Truncates a single precision number and converts it to an int32.
5779 // Implements Math.trunc().
5780 class LTruncF : public LInstructionHelper<1, 1, 0> {
5781  public:
LIR_HEADER(TruncF)5782   LIR_HEADER(TruncF)
5783 
5784   explicit LTruncF(const LAllocation& num) : LInstructionHelper(classOpcode) {
5785     setOperand(0, num);
5786   }
5787 };
5788 
5789 // Rounds a double precision number accordingly to mir()->roundingMode(),
5790 // and keeps a double output.
5791 class LNearbyInt : public LInstructionHelper<1, 1, 0> {
5792  public:
LIR_HEADER(NearbyInt)5793   LIR_HEADER(NearbyInt)
5794 
5795   explicit LNearbyInt(const LAllocation& num)
5796       : LInstructionHelper(classOpcode) {
5797     setOperand(0, num);
5798   }
mir()5799   MNearbyInt* mir() const { return mir_->toNearbyInt(); }
5800 };
5801 
5802 // Rounds a single precision number accordingly to mir()->roundingMode(),
5803 // and keeps a single output.
5804 class LNearbyIntF : public LInstructionHelper<1, 1, 0> {
5805  public:
LIR_HEADER(NearbyIntF)5806   LIR_HEADER(NearbyIntF)
5807 
5808   explicit LNearbyIntF(const LAllocation& num)
5809       : LInstructionHelper(classOpcode) {
5810     setOperand(0, num);
5811   }
mir()5812   MNearbyInt* mir() const { return mir_->toNearbyInt(); }
5813 };
5814 
5815 // Load a function's call environment.
5816 class LFunctionEnvironment : public LInstructionHelper<1, 1, 0> {
5817  public:
LIR_HEADER(FunctionEnvironment)5818   LIR_HEADER(FunctionEnvironment)
5819 
5820   explicit LFunctionEnvironment(const LAllocation& function)
5821       : LInstructionHelper(classOpcode) {
5822     setOperand(0, function);
5823   }
function()5824   const LAllocation* function() { return getOperand(0); }
5825 };
5826 
5827 class LHomeObject : public LInstructionHelper<1, 1, 0> {
5828  public:
LIR_HEADER(HomeObject)5829   LIR_HEADER(HomeObject)
5830 
5831   explicit LHomeObject(const LAllocation& function)
5832       : LInstructionHelper(classOpcode) {
5833     setOperand(0, function);
5834   }
function()5835   const LAllocation* function() { return getOperand(0); }
5836 };
5837 
5838 class LHomeObjectSuperBase : public LInstructionHelper<1, 1, 0> {
5839  public:
LIR_HEADER(HomeObjectSuperBase)5840   LIR_HEADER(HomeObjectSuperBase)
5841 
5842   explicit LHomeObjectSuperBase(const LAllocation& homeObject)
5843       : LInstructionHelper(classOpcode) {
5844     setOperand(0, homeObject);
5845   }
5846 
homeObject()5847   const LAllocation* homeObject() { return getOperand(0); }
5848 };
5849 
5850 // Allocate a new LexicalEnvironmentObject.
5851 class LNewLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0> {
5852  public:
LIR_HEADER(NewLexicalEnvironmentObject)5853   LIR_HEADER(NewLexicalEnvironmentObject)
5854 
5855   explicit LNewLexicalEnvironmentObject(const LAllocation& enclosing)
5856       : LCallInstructionHelper(classOpcode) {
5857     setOperand(0, enclosing);
5858   }
enclosing()5859   const LAllocation* enclosing() { return getOperand(0); }
5860 
mir()5861   MNewLexicalEnvironmentObject* mir() const {
5862     return mir_->toNewLexicalEnvironmentObject();
5863   }
5864 };
5865 
5866 // Copy a LexicalEnvironmentObject.
5867 class LCopyLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0> {
5868  public:
LIR_HEADER(CopyLexicalEnvironmentObject)5869   LIR_HEADER(CopyLexicalEnvironmentObject)
5870 
5871   explicit LCopyLexicalEnvironmentObject(const LAllocation& env)
5872       : LCallInstructionHelper(classOpcode) {
5873     setOperand(0, env);
5874   }
env()5875   const LAllocation* env() { return getOperand(0); }
5876 
mir()5877   MCopyLexicalEnvironmentObject* mir() const {
5878     return mir_->toCopyLexicalEnvironmentObject();
5879   }
5880 };
5881 
5882 // Allocate a new ClassBodyLexicalEnvironmentObject.
5883 class LNewClassBodyEnvironmentObject : public LCallInstructionHelper<1, 1, 0> {
5884  public:
LIR_HEADER(NewClassBodyEnvironmentObject)5885   LIR_HEADER(NewClassBodyEnvironmentObject)
5886 
5887   explicit LNewClassBodyEnvironmentObject(const LAllocation& enclosing)
5888       : LCallInstructionHelper(classOpcode) {
5889     setOperand(0, enclosing);
5890   }
enclosing()5891   const LAllocation* enclosing() { return getOperand(0); }
5892 
mir()5893   MNewClassBodyEnvironmentObject* mir() const {
5894     return mir_->toNewClassBodyEnvironmentObject();
5895   }
5896 };
5897 
5898 class LCallSetElement
5899     : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0> {
5900  public:
5901   LIR_HEADER(CallSetElement)
5902 
5903   static const size_t Index = 1;
5904   static const size_t Value = 1 + BOX_PIECES;
5905 
LCallSetElement(const LAllocation & obj,const LBoxAllocation & index,const LBoxAllocation & value)5906   LCallSetElement(const LAllocation& obj, const LBoxAllocation& index,
5907                   const LBoxAllocation& value)
5908       : LCallInstructionHelper(classOpcode) {
5909     setOperand(0, obj);
5910     setBoxOperand(Index, index);
5911     setBoxOperand(Value, value);
5912   }
5913 
mir()5914   const MCallSetElement* mir() const { return mir_->toCallSetElement(); }
5915 };
5916 
5917 class LCallDeleteProperty : public LCallInstructionHelper<1, BOX_PIECES, 0> {
5918  public:
5919   LIR_HEADER(CallDeleteProperty)
5920 
5921   static const size_t Value = 0;
5922 
LCallDeleteProperty(const LBoxAllocation & value)5923   explicit LCallDeleteProperty(const LBoxAllocation& value)
5924       : LCallInstructionHelper(classOpcode) {
5925     setBoxOperand(Value, value);
5926   }
5927 
mir()5928   MDeleteProperty* mir() const { return mir_->toDeleteProperty(); }
5929 };
5930 
5931 class LCallDeleteElement : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> {
5932  public:
5933   LIR_HEADER(CallDeleteElement)
5934 
5935   static const size_t Value = 0;
5936   static const size_t Index = BOX_PIECES;
5937 
LCallDeleteElement(const LBoxAllocation & value,const LBoxAllocation & index)5938   LCallDeleteElement(const LBoxAllocation& value, const LBoxAllocation& index)
5939       : LCallInstructionHelper(classOpcode) {
5940     setBoxOperand(Value, value);
5941     setBoxOperand(Index, index);
5942   }
5943 
mir()5944   MDeleteElement* mir() const { return mir_->toDeleteElement(); }
5945 };
5946 
5947 // Patchable jump to stubs generated for a SetProperty cache.
5948 class LSetPropertyCache : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 2> {
5949  public:
LIR_HEADER(SetPropertyCache)5950   LIR_HEADER(SetPropertyCache)
5951 
5952   // Takes an additional temp: this is intendend to be FloatReg0 to allow the
5953   // actual cache code to safely clobber that value without save and restore.
5954   LSetPropertyCache(const LAllocation& object, const LBoxAllocation& id,
5955                     const LBoxAllocation& value, const LDefinition& temp,
5956                     const LDefinition& tempDouble)
5957       : LInstructionHelper(classOpcode) {
5958     setOperand(0, object);
5959     setBoxOperand(Id, id);
5960     setBoxOperand(Value, value);
5961     setTemp(0, temp);
5962     setTemp(1, tempDouble);
5963   }
5964 
5965   static const size_t Id = 1;
5966   static const size_t Value = 1 + BOX_PIECES;
5967 
mir()5968   const MSetPropertyCache* mir() const { return mir_->toSetPropertyCache(); }
5969 
temp()5970   const LDefinition* temp() { return getTemp(0); }
5971 };
5972 
5973 class LGetIteratorCache : public LInstructionHelper<1, BOX_PIECES, 2> {
5974  public:
5975   LIR_HEADER(GetIteratorCache)
5976 
5977   static const size_t Value = 0;
5978 
LGetIteratorCache(const LBoxAllocation & value,const LDefinition & temp1,const LDefinition & temp2)5979   LGetIteratorCache(const LBoxAllocation& value, const LDefinition& temp1,
5980                     const LDefinition& temp2)
5981       : LInstructionHelper(classOpcode) {
5982     setBoxOperand(Value, value);
5983     setTemp(0, temp1);
5984     setTemp(1, temp2);
5985   }
mir()5986   const MGetIteratorCache* mir() const { return mir_->toGetIteratorCache(); }
temp1()5987   const LDefinition* temp1() { return getTemp(0); }
temp2()5988   const LDefinition* temp2() { return getTemp(1); }
5989 };
5990 
5991 class LOptimizeSpreadCallCache : public LInstructionHelper<1, BOX_PIECES, 1> {
5992  public:
5993   LIR_HEADER(OptimizeSpreadCallCache)
5994 
5995   static const size_t Value = 0;
5996 
LOptimizeSpreadCallCache(const LBoxAllocation & value,const LDefinition & temp)5997   LOptimizeSpreadCallCache(const LBoxAllocation& value, const LDefinition& temp)
5998       : LInstructionHelper(classOpcode) {
5999     setBoxOperand(Value, value);
6000     setTemp(0, temp);
6001   }
mir()6002   const MOptimizeSpreadCallCache* mir() const {
6003     return mir_->toOptimizeSpreadCallCache();
6004   }
temp()6005   const LDefinition* temp() { return getTemp(0); }
6006 };
6007 
6008 class LIteratorMore : public LInstructionHelper<BOX_PIECES, 1, 1> {
6009  public:
LIR_HEADER(IteratorMore)6010   LIR_HEADER(IteratorMore)
6011 
6012   LIteratorMore(const LAllocation& iterator, const LDefinition& temp)
6013       : LInstructionHelper(classOpcode) {
6014     setOperand(0, iterator);
6015     setTemp(0, temp);
6016   }
object()6017   const LAllocation* object() { return getOperand(0); }
temp()6018   const LDefinition* temp() { return getTemp(0); }
mir()6019   MIteratorMore* mir() const { return mir_->toIteratorMore(); }
6020 };
6021 
6022 class LIsNoIterAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 0> {
6023  public:
LIR_HEADER(IsNoIterAndBranch)6024   LIR_HEADER(IsNoIterAndBranch)
6025 
6026   LIsNoIterAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse,
6027                      const LBoxAllocation& input)
6028       : LControlInstructionHelper(classOpcode) {
6029     setSuccessor(0, ifTrue);
6030     setSuccessor(1, ifFalse);
6031     setBoxOperand(Input, input);
6032   }
6033 
6034   static const size_t Input = 0;
6035 
ifTrue()6036   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()6037   MBasicBlock* ifFalse() const { return getSuccessor(1); }
6038 };
6039 
6040 class LIteratorEnd : public LInstructionHelper<0, 1, 3> {
6041  public:
LIR_HEADER(IteratorEnd)6042   LIR_HEADER(IteratorEnd)
6043 
6044   LIteratorEnd(const LAllocation& iterator, const LDefinition& temp1,
6045                const LDefinition& temp2, const LDefinition& temp3)
6046       : LInstructionHelper(classOpcode) {
6047     setOperand(0, iterator);
6048     setTemp(0, temp1);
6049     setTemp(1, temp2);
6050     setTemp(2, temp3);
6051   }
object()6052   const LAllocation* object() { return getOperand(0); }
temp1()6053   const LDefinition* temp1() { return getTemp(0); }
temp2()6054   const LDefinition* temp2() { return getTemp(1); }
temp3()6055   const LDefinition* temp3() { return getTemp(2); }
mir()6056   MIteratorEnd* mir() const { return mir_->toIteratorEnd(); }
6057 };
6058 
6059 // Read the number of actual arguments.
6060 class LArgumentsLength : public LInstructionHelper<1, 0, 0> {
6061  public:
LIR_HEADER(ArgumentsLength)6062   LIR_HEADER(ArgumentsLength)
6063 
6064   LArgumentsLength() : LInstructionHelper(classOpcode) {}
6065 };
6066 
6067 // Load a value from the actual arguments.
6068 class LGetFrameArgument : public LInstructionHelper<BOX_PIECES, 1, 0> {
6069  public:
LIR_HEADER(GetFrameArgument)6070   LIR_HEADER(GetFrameArgument)
6071 
6072   explicit LGetFrameArgument(const LAllocation& index)
6073       : LInstructionHelper(classOpcode) {
6074     setOperand(0, index);
6075   }
index()6076   const LAllocation* index() { return getOperand(0); }
6077 };
6078 
6079 // Create the rest parameter.
6080 class LRest : public LCallInstructionHelper<1, 1, 3> {
6081  public:
LIR_HEADER(Rest)6082   LIR_HEADER(Rest)
6083 
6084   LRest(const LAllocation& numActuals, const LDefinition& temp1,
6085         const LDefinition& temp2, const LDefinition& temp3)
6086       : LCallInstructionHelper(classOpcode) {
6087     setOperand(0, numActuals);
6088     setTemp(0, temp1);
6089     setTemp(1, temp2);
6090     setTemp(2, temp3);
6091   }
numActuals()6092   const LAllocation* numActuals() { return getOperand(0); }
mir()6093   MRest* mir() const { return mir_->toRest(); }
6094 };
6095 
6096 class LInt32ToIntPtr : public LInstructionHelper<1, 1, 0> {
6097  public:
LIR_HEADER(Int32ToIntPtr)6098   LIR_HEADER(Int32ToIntPtr)
6099 
6100   explicit LInt32ToIntPtr(const LAllocation& input)
6101       : LInstructionHelper(classOpcode) {
6102     setOperand(0, input);
6103   }
6104 
mir()6105   MInt32ToIntPtr* mir() const { return mir_->toInt32ToIntPtr(); }
6106 };
6107 
6108 class LNonNegativeIntPtrToInt32 : public LInstructionHelper<1, 1, 0> {
6109  public:
LIR_HEADER(NonNegativeIntPtrToInt32)6110   LIR_HEADER(NonNegativeIntPtrToInt32)
6111 
6112   explicit LNonNegativeIntPtrToInt32(const LAllocation& input)
6113       : LInstructionHelper(classOpcode) {
6114     setOperand(0, input);
6115   }
6116 };
6117 
6118 class LIntPtrToDouble : public LInstructionHelper<1, 1, 0> {
6119  public:
LIR_HEADER(IntPtrToDouble)6120   LIR_HEADER(IntPtrToDouble)
6121 
6122   explicit LIntPtrToDouble(const LAllocation& input)
6123       : LInstructionHelper(classOpcode) {
6124     setOperand(0, input);
6125   }
6126 };
6127 
6128 class LAdjustDataViewLength : public LInstructionHelper<1, 1, 0> {
6129  public:
LIR_HEADER(AdjustDataViewLength)6130   LIR_HEADER(AdjustDataViewLength)
6131 
6132   explicit LAdjustDataViewLength(const LAllocation& input)
6133       : LInstructionHelper(classOpcode) {
6134     setOperand(0, input);
6135   }
6136 
mir()6137   const MAdjustDataViewLength* mir() const {
6138     return mir_->toAdjustDataViewLength();
6139   }
6140 };
6141 
6142 // Convert a Boolean to an Int64, following ToBigInt.
6143 class LBooleanToInt64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
6144  public:
LIR_HEADER(BooleanToInt64)6145   LIR_HEADER(BooleanToInt64)
6146 
6147   explicit LBooleanToInt64(const LAllocation& input)
6148       : LInstructionHelper(classOpcode) {
6149     setOperand(Input, input);
6150   }
6151 
6152   static const size_t Input = 0;
6153 
mir()6154   const MToInt64* mir() const { return mir_->toToInt64(); }
6155 };
6156 
6157 // Convert a String to an Int64, following ToBigInt.
6158 class LStringToInt64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
6159  public:
LIR_HEADER(StringToInt64)6160   LIR_HEADER(StringToInt64)
6161 
6162   explicit LStringToInt64(const LAllocation& input)
6163       : LInstructionHelper(classOpcode) {
6164     setOperand(Input, input);
6165   }
6166 
6167   static const size_t Input = 0;
6168 
mir()6169   const MToInt64* mir() const { return mir_->toToInt64(); }
6170 };
6171 
6172 // Simulate ToBigInt on a Value and produce a matching Int64.
6173 class LValueToInt64 : public LInstructionHelper<INT64_PIECES, BOX_PIECES, 1> {
6174  public:
LIR_HEADER(ValueToInt64)6175   LIR_HEADER(ValueToInt64)
6176 
6177   explicit LValueToInt64(const LBoxAllocation& input, const LDefinition& temp)
6178       : LInstructionHelper(classOpcode) {
6179     setBoxOperand(Input, input);
6180     setTemp(0, temp);
6181   }
6182 
6183   static const size_t Input = 0;
6184 
mir()6185   const MToInt64* mir() const { return mir_->toToInt64(); }
temp()6186   const LDefinition* temp() { return getTemp(0); }
6187 };
6188 
6189 // Truncate a BigInt to an unboxed int64.
6190 class LTruncateBigIntToInt64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
6191  public:
LIR_HEADER(TruncateBigIntToInt64)6192   LIR_HEADER(TruncateBigIntToInt64)
6193 
6194   explicit LTruncateBigIntToInt64(const LAllocation& input)
6195       : LInstructionHelper(classOpcode) {
6196     setOperand(Input, input);
6197   }
6198 
6199   static const size_t Input = 0;
6200 
mir()6201   const MTruncateBigIntToInt64* mir() const {
6202     return mir_->toTruncateBigIntToInt64();
6203   }
6204 };
6205 
6206 // Create a new BigInt* from an unboxed int64.
6207 class LInt64ToBigInt : public LInstructionHelper<1, INT64_PIECES, 1> {
6208  public:
LIR_HEADER(Int64ToBigInt)6209   LIR_HEADER(Int64ToBigInt)
6210 
6211   LInt64ToBigInt(const LInt64Allocation& input, const LDefinition& temp)
6212       : LInstructionHelper(classOpcode) {
6213     setInt64Operand(Input, input);
6214     setTemp(0, temp);
6215   }
6216 
6217   static const size_t Input = 0;
6218 
mir()6219   const MInt64ToBigInt* mir() const { return mir_->toInt64ToBigInt(); }
input()6220   const LInt64Allocation input() { return getInt64Operand(Input); }
temp()6221   const LDefinition* temp() { return getTemp(0); }
6222 };
6223 
6224 // Generational write barrier used when writing an object to another object.
6225 class LPostWriteBarrierO : public LInstructionHelper<0, 2, 1> {
6226  public:
LIR_HEADER(PostWriteBarrierO)6227   LIR_HEADER(PostWriteBarrierO)
6228 
6229   LPostWriteBarrierO(const LAllocation& obj, const LAllocation& value,
6230                      const LDefinition& temp)
6231       : LInstructionHelper(classOpcode) {
6232     setOperand(0, obj);
6233     setOperand(1, value);
6234     setTemp(0, temp);
6235   }
6236 
mir()6237   const MPostWriteBarrier* mir() const { return mir_->toPostWriteBarrier(); }
object()6238   const LAllocation* object() { return getOperand(0); }
value()6239   const LAllocation* value() { return getOperand(1); }
temp()6240   const LDefinition* temp() { return getTemp(0); }
6241 };
6242 
6243 // Generational write barrier used when writing a string to an object.
6244 class LPostWriteBarrierS : public LInstructionHelper<0, 2, 1> {
6245  public:
LIR_HEADER(PostWriteBarrierS)6246   LIR_HEADER(PostWriteBarrierS)
6247 
6248   LPostWriteBarrierS(const LAllocation& obj, const LAllocation& value,
6249                      const LDefinition& temp)
6250       : LInstructionHelper(classOpcode) {
6251     setOperand(0, obj);
6252     setOperand(1, value);
6253     setTemp(0, temp);
6254   }
6255 
mir()6256   const MPostWriteBarrier* mir() const { return mir_->toPostWriteBarrier(); }
object()6257   const LAllocation* object() { return getOperand(0); }
value()6258   const LAllocation* value() { return getOperand(1); }
temp()6259   const LDefinition* temp() { return getTemp(0); }
6260 };
6261 
6262 // Generational write barrier used when writing a BigInt to an object.
6263 class LPostWriteBarrierBI : public LInstructionHelper<0, 2, 1> {
6264  public:
LIR_HEADER(PostWriteBarrierBI)6265   LIR_HEADER(PostWriteBarrierBI)
6266 
6267   LPostWriteBarrierBI(const LAllocation& obj, const LAllocation& value,
6268                       const LDefinition& temp)
6269       : LInstructionHelper(classOpcode) {
6270     setOperand(0, obj);
6271     setOperand(1, value);
6272     setTemp(0, temp);
6273   }
6274 
mir()6275   const MPostWriteBarrier* mir() const { return mir_->toPostWriteBarrier(); }
object()6276   const LAllocation* object() { return getOperand(0); }
value()6277   const LAllocation* value() { return getOperand(1); }
temp()6278   const LDefinition* temp() { return getTemp(0); }
6279 };
6280 
6281 // Generational write barrier used when writing a value to another object.
6282 class LPostWriteBarrierV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> {
6283  public:
LIR_HEADER(PostWriteBarrierV)6284   LIR_HEADER(PostWriteBarrierV)
6285 
6286   LPostWriteBarrierV(const LAllocation& obj, const LBoxAllocation& value,
6287                      const LDefinition& temp)
6288       : LInstructionHelper(classOpcode) {
6289     setOperand(0, obj);
6290     setBoxOperand(Input, value);
6291     setTemp(0, temp);
6292   }
6293 
6294   static const size_t Input = 1;
6295 
mir()6296   const MPostWriteBarrier* mir() const { return mir_->toPostWriteBarrier(); }
object()6297   const LAllocation* object() { return getOperand(0); }
temp()6298   const LDefinition* temp() { return getTemp(0); }
6299 };
6300 
6301 // Generational write barrier used when writing an object to another object's
6302 // elements.
6303 class LPostWriteElementBarrierO : public LInstructionHelper<0, 3, 1> {
6304  public:
LIR_HEADER(PostWriteElementBarrierO)6305   LIR_HEADER(PostWriteElementBarrierO)
6306 
6307   LPostWriteElementBarrierO(const LAllocation& obj, const LAllocation& value,
6308                             const LAllocation& index, const LDefinition& temp)
6309       : LInstructionHelper(classOpcode) {
6310     setOperand(0, obj);
6311     setOperand(1, value);
6312     setOperand(2, index);
6313     setTemp(0, temp);
6314   }
6315 
mir()6316   const MPostWriteElementBarrier* mir() const {
6317     return mir_->toPostWriteElementBarrier();
6318   }
6319 
object()6320   const LAllocation* object() { return getOperand(0); }
6321 
value()6322   const LAllocation* value() { return getOperand(1); }
6323 
index()6324   const LAllocation* index() { return getOperand(2); }
6325 
temp()6326   const LDefinition* temp() { return getTemp(0); }
6327 };
6328 
6329 // Generational write barrier used when writing a string to an object's
6330 // elements.
6331 class LPostWriteElementBarrierS : public LInstructionHelper<0, 3, 1> {
6332  public:
LIR_HEADER(PostWriteElementBarrierS)6333   LIR_HEADER(PostWriteElementBarrierS)
6334 
6335   LPostWriteElementBarrierS(const LAllocation& obj, const LAllocation& value,
6336                             const LAllocation& index, const LDefinition& temp)
6337       : LInstructionHelper(classOpcode) {
6338     setOperand(0, obj);
6339     setOperand(1, value);
6340     setOperand(2, index);
6341     setTemp(0, temp);
6342   }
6343 
mir()6344   const MPostWriteElementBarrier* mir() const {
6345     return mir_->toPostWriteElementBarrier();
6346   }
6347 
object()6348   const LAllocation* object() { return getOperand(0); }
6349 
value()6350   const LAllocation* value() { return getOperand(1); }
6351 
index()6352   const LAllocation* index() { return getOperand(2); }
6353 
temp()6354   const LDefinition* temp() { return getTemp(0); }
6355 };
6356 
6357 // Generational write barrier used when writing a BigInt to an object's
6358 // elements.
6359 class LPostWriteElementBarrierBI : public LInstructionHelper<0, 3, 1> {
6360  public:
LIR_HEADER(PostWriteElementBarrierBI)6361   LIR_HEADER(PostWriteElementBarrierBI)
6362 
6363   LPostWriteElementBarrierBI(const LAllocation& obj, const LAllocation& value,
6364                              const LAllocation& index, const LDefinition& temp)
6365       : LInstructionHelper(classOpcode) {
6366     setOperand(0, obj);
6367     setOperand(1, value);
6368     setOperand(2, index);
6369     setTemp(0, temp);
6370   }
6371 
mir()6372   const MPostWriteElementBarrier* mir() const {
6373     return mir_->toPostWriteElementBarrier();
6374   }
6375 
object()6376   const LAllocation* object() { return getOperand(0); }
6377 
value()6378   const LAllocation* value() { return getOperand(1); }
6379 
index()6380   const LAllocation* index() { return getOperand(2); }
6381 
temp()6382   const LDefinition* temp() { return getTemp(0); }
6383 };
6384 
6385 // Generational write barrier used when writing a value to another object's
6386 // elements.
6387 class LPostWriteElementBarrierV
6388     : public LInstructionHelper<0, 2 + BOX_PIECES, 1> {
6389  public:
LIR_HEADER(PostWriteElementBarrierV)6390   LIR_HEADER(PostWriteElementBarrierV)
6391 
6392   LPostWriteElementBarrierV(const LAllocation& obj, const LAllocation& index,
6393                             const LBoxAllocation& value,
6394                             const LDefinition& temp)
6395       : LInstructionHelper(classOpcode) {
6396     setOperand(0, obj);
6397     setOperand(1, index);
6398     setBoxOperand(Input, value);
6399     setTemp(0, temp);
6400   }
6401 
6402   static const size_t Input = 2;
6403 
mir()6404   const MPostWriteElementBarrier* mir() const {
6405     return mir_->toPostWriteElementBarrier();
6406   }
6407 
object()6408   const LAllocation* object() { return getOperand(0); }
6409 
index()6410   const LAllocation* index() { return getOperand(1); }
6411 
temp()6412   const LDefinition* temp() { return getTemp(0); }
6413 };
6414 
6415 // Guard against an object's identity.
6416 class LGuardObjectIdentity : public LInstructionHelper<0, 2, 0> {
6417  public:
LIR_HEADER(GuardObjectIdentity)6418   LIR_HEADER(GuardObjectIdentity)
6419 
6420   LGuardObjectIdentity(const LAllocation& in, const LAllocation& expected)
6421       : LInstructionHelper(classOpcode) {
6422     setOperand(0, in);
6423     setOperand(1, expected);
6424   }
input()6425   const LAllocation* input() { return getOperand(0); }
expected()6426   const LAllocation* expected() { return getOperand(1); }
mir()6427   const MGuardObjectIdentity* mir() const {
6428     return mir_->toGuardObjectIdentity();
6429   }
6430 };
6431 
6432 // Guard against an function's identity.
6433 class LGuardSpecificFunction : public LInstructionHelper<0, 2, 0> {
6434  public:
LIR_HEADER(GuardSpecificFunction)6435   LIR_HEADER(GuardSpecificFunction)
6436 
6437   LGuardSpecificFunction(const LAllocation& in, const LAllocation& expected)
6438       : LInstructionHelper(classOpcode) {
6439     setOperand(0, in);
6440     setOperand(1, expected);
6441   }
input()6442   const LAllocation* input() { return getOperand(0); }
expected()6443   const LAllocation* expected() { return getOperand(1); }
6444 };
6445 
6446 class LGuardSpecificAtom : public LInstructionHelper<0, 1, 1> {
6447  public:
LIR_HEADER(GuardSpecificAtom)6448   LIR_HEADER(GuardSpecificAtom)
6449 
6450   LGuardSpecificAtom(const LAllocation& str, const LDefinition& temp)
6451       : LInstructionHelper(classOpcode) {
6452     setOperand(0, str);
6453     setTemp(0, temp);
6454   }
str()6455   const LAllocation* str() { return getOperand(0); }
temp()6456   const LDefinition* temp() { return getTemp(0); }
6457 
mir()6458   const MGuardSpecificAtom* mir() const { return mir_->toGuardSpecificAtom(); }
6459 };
6460 
6461 class LGuardSpecificSymbol : public LInstructionHelper<0, 1, 0> {
6462  public:
LIR_HEADER(GuardSpecificSymbol)6463   LIR_HEADER(GuardSpecificSymbol)
6464 
6465   explicit LGuardSpecificSymbol(const LAllocation& symbol)
6466       : LInstructionHelper(classOpcode) {
6467     setOperand(0, symbol);
6468   }
symbol()6469   const LAllocation* symbol() { return getOperand(0); }
mir()6470   const MGuardSpecificSymbol* mir() const {
6471     return mir_->toGuardSpecificSymbol();
6472   }
6473 };
6474 
6475 class LGuardStringToIndex : public LInstructionHelper<1, 1, 0> {
6476  public:
LIR_HEADER(GuardStringToIndex)6477   LIR_HEADER(GuardStringToIndex)
6478 
6479   explicit LGuardStringToIndex(const LAllocation& str)
6480       : LInstructionHelper(classOpcode) {
6481     setOperand(0, str);
6482   }
6483 
string()6484   const LAllocation* string() { return getOperand(0); }
6485 };
6486 
6487 class LGuardStringToInt32 : public LInstructionHelper<1, 1, 1> {
6488  public:
LIR_HEADER(GuardStringToInt32)6489   LIR_HEADER(GuardStringToInt32)
6490 
6491   LGuardStringToInt32(const LAllocation& str, const LDefinition& temp)
6492       : LInstructionHelper(classOpcode) {
6493     setOperand(0, str);
6494     setTemp(0, temp);
6495   }
6496 
string()6497   const LAllocation* string() { return getOperand(0); }
temp()6498   const LDefinition* temp() { return getTemp(0); }
6499 };
6500 
6501 class LGuardStringToDouble : public LInstructionHelper<1, 1, 2> {
6502  public:
LIR_HEADER(GuardStringToDouble)6503   LIR_HEADER(GuardStringToDouble)
6504 
6505   LGuardStringToDouble(const LAllocation& str, const LDefinition& temp1,
6506                        const LDefinition& temp2)
6507       : LInstructionHelper(classOpcode) {
6508     setOperand(0, str);
6509     setTemp(0, temp1);
6510     setTemp(1, temp2);
6511   }
6512 
string()6513   const LAllocation* string() { return getOperand(0); }
temp1()6514   const LDefinition* temp1() { return getTemp(0); }
temp2()6515   const LDefinition* temp2() { return getTemp(1); }
6516 };
6517 
6518 class LGuardShape : public LInstructionHelper<1, 1, 1> {
6519  public:
LIR_HEADER(GuardShape)6520   LIR_HEADER(GuardShape)
6521 
6522   LGuardShape(const LAllocation& in, const LDefinition& temp)
6523       : LInstructionHelper(classOpcode) {
6524     setOperand(0, in);
6525     setTemp(0, temp);
6526   }
temp()6527   const LDefinition* temp() { return getTemp(0); }
mir()6528   const MGuardShape* mir() const { return mir_->toGuardShape(); }
6529 };
6530 
6531 class LGuardProto : public LInstructionHelper<0, 2, 1> {
6532  public:
LIR_HEADER(GuardProto)6533   LIR_HEADER(GuardProto)
6534 
6535   LGuardProto(const LAllocation& obj, const LAllocation& expected,
6536               const LDefinition& temp)
6537       : LInstructionHelper(classOpcode) {
6538     setOperand(0, obj);
6539     setOperand(1, expected);
6540     setTemp(0, temp);
6541   }
6542 
object()6543   const LAllocation* object() { return getOperand(0); }
expected()6544   const LAllocation* expected() { return getOperand(1); }
temp()6545   const LDefinition* temp() { return getTemp(0); }
6546 };
6547 
6548 class LGuardNullProto : public LInstructionHelper<0, 1, 1> {
6549  public:
LIR_HEADER(GuardNullProto)6550   LIR_HEADER(GuardNullProto)
6551 
6552   LGuardNullProto(const LAllocation& obj, const LDefinition& temp)
6553       : LInstructionHelper(classOpcode) {
6554     setOperand(0, obj);
6555     setTemp(0, temp);
6556   }
6557 
object()6558   const LAllocation* object() { return getOperand(0); }
temp()6559   const LDefinition* temp() { return getTemp(0); }
6560 };
6561 
6562 class LGuardIsNativeObject : public LInstructionHelper<0, 1, 1> {
6563  public:
LIR_HEADER(GuardIsNativeObject)6564   LIR_HEADER(GuardIsNativeObject)
6565 
6566   LGuardIsNativeObject(const LAllocation& obj, const LDefinition& temp)
6567       : LInstructionHelper(classOpcode) {
6568     setOperand(0, obj);
6569     setTemp(0, temp);
6570   }
6571 
object()6572   const LAllocation* object() { return getOperand(0); }
temp()6573   const LDefinition* temp() { return getTemp(0); }
6574 };
6575 
6576 class LGuardIsProxy : public LInstructionHelper<0, 1, 1> {
6577  public:
LIR_HEADER(GuardIsProxy)6578   LIR_HEADER(GuardIsProxy)
6579 
6580   LGuardIsProxy(const LAllocation& obj, const LDefinition& temp)
6581       : LInstructionHelper(classOpcode) {
6582     setOperand(0, obj);
6583     setTemp(0, temp);
6584   }
6585 
object()6586   const LAllocation* object() { return getOperand(0); }
temp()6587   const LDefinition* temp() { return getTemp(0); }
6588 };
6589 
6590 class LGuardIsNotProxy : public LInstructionHelper<0, 1, 1> {
6591  public:
LIR_HEADER(GuardIsNotProxy)6592   LIR_HEADER(GuardIsNotProxy)
6593 
6594   LGuardIsNotProxy(const LAllocation& obj, const LDefinition& temp)
6595       : LInstructionHelper(classOpcode) {
6596     setOperand(0, obj);
6597     setTemp(0, temp);
6598   }
6599 
object()6600   const LAllocation* object() { return getOperand(0); }
temp()6601   const LDefinition* temp() { return getTemp(0); }
6602 };
6603 
6604 class LGuardIsNotDOMProxy : public LInstructionHelper<0, 1, 1> {
6605  public:
LIR_HEADER(GuardIsNotDOMProxy)6606   LIR_HEADER(GuardIsNotDOMProxy)
6607 
6608   LGuardIsNotDOMProxy(const LAllocation& proxy, const LDefinition& temp)
6609       : LInstructionHelper(classOpcode) {
6610     setOperand(0, proxy);
6611     setTemp(0, temp);
6612   }
6613 
proxy()6614   const LAllocation* proxy() { return getOperand(0); }
temp()6615   const LDefinition* temp() { return getTemp(0); }
6616 };
6617 
6618 class LProxyGet : public LCallInstructionHelper<BOX_PIECES, 1, 1> {
6619  public:
LIR_HEADER(ProxyGet)6620   LIR_HEADER(ProxyGet)
6621 
6622   LProxyGet(const LAllocation& proxy, const LDefinition& temp)
6623       : LCallInstructionHelper(classOpcode) {
6624     setOperand(0, proxy);
6625     setTemp(0, temp);
6626   }
6627 
proxy()6628   const LAllocation* proxy() { return getOperand(0); }
temp()6629   const LDefinition* temp() { return getTemp(0); }
6630 
mir()6631   MProxyGet* mir() const { return mir_->toProxyGet(); }
6632 };
6633 
6634 class LProxyGetByValue
6635     : public LCallInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 0> {
6636  public:
LIR_HEADER(ProxyGetByValue)6637   LIR_HEADER(ProxyGetByValue)
6638 
6639   LProxyGetByValue(const LAllocation& proxy, const LBoxAllocation& idVal)
6640       : LCallInstructionHelper(classOpcode) {
6641     setOperand(0, proxy);
6642     setBoxOperand(IdIndex, idVal);
6643   }
6644 
6645   static const size_t IdIndex = 1;
6646 
proxy()6647   const LAllocation* proxy() { return getOperand(0); }
6648 };
6649 
6650 class LProxyHasProp
6651     : public LCallInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 0> {
6652  public:
LIR_HEADER(ProxyHasProp)6653   LIR_HEADER(ProxyHasProp)
6654 
6655   LProxyHasProp(const LAllocation& proxy, const LBoxAllocation& idVal)
6656       : LCallInstructionHelper(classOpcode) {
6657     setOperand(0, proxy);
6658     setBoxOperand(IdIndex, idVal);
6659   }
6660 
6661   static const size_t IdIndex = 1;
6662 
proxy()6663   const LAllocation* proxy() { return getOperand(0); }
6664 
mir()6665   MProxyHasProp* mir() const { return mir_->toProxyHasProp(); }
6666 };
6667 
6668 class LProxySet : public LCallInstructionHelper<0, 1 + BOX_PIECES, 1> {
6669  public:
LIR_HEADER(ProxySet)6670   LIR_HEADER(ProxySet)
6671 
6672   LProxySet(const LAllocation& proxy, const LBoxAllocation& rhs,
6673             const LDefinition& temp)
6674       : LCallInstructionHelper(classOpcode) {
6675     setOperand(0, proxy);
6676     setBoxOperand(RhsIndex, rhs);
6677     setTemp(0, temp);
6678   }
6679 
6680   static const size_t RhsIndex = 1;
6681 
proxy()6682   const LAllocation* proxy() { return getOperand(0); }
temp()6683   const LDefinition* temp() { return getTemp(0); }
6684 
mir()6685   MProxySet* mir() const { return mir_->toProxySet(); }
6686 };
6687 
6688 class LProxySetByValue
6689     : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0> {
6690  public:
LIR_HEADER(ProxySetByValue)6691   LIR_HEADER(ProxySetByValue)
6692 
6693   LProxySetByValue(const LAllocation& proxy, const LBoxAllocation& idVal,
6694                    const LBoxAllocation& rhs)
6695       : LCallInstructionHelper(classOpcode) {
6696     setOperand(0, proxy);
6697     setBoxOperand(IdIndex, idVal);
6698     setBoxOperand(RhsIndex, rhs);
6699   }
6700 
6701   static const size_t IdIndex = 1;
6702   static const size_t RhsIndex = 1 + BOX_PIECES;
6703 
proxy()6704   const LAllocation* proxy() { return getOperand(0); }
6705 
mir()6706   MProxySetByValue* mir() const { return mir_->toProxySetByValue(); }
6707 };
6708 
6709 class LCallSetArrayLength
6710     : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> {
6711  public:
LIR_HEADER(CallSetArrayLength)6712   LIR_HEADER(CallSetArrayLength)
6713 
6714   LCallSetArrayLength(const LAllocation& obj, const LBoxAllocation& rhs)
6715       : LCallInstructionHelper(classOpcode) {
6716     setOperand(0, obj);
6717     setBoxOperand(RhsIndex, rhs);
6718   }
6719 
6720   static const size_t RhsIndex = 1;
6721 
obj()6722   const LAllocation* obj() { return getOperand(0); }
6723 
mir()6724   MCallSetArrayLength* mir() const { return mir_->toCallSetArrayLength(); }
6725 };
6726 
6727 class LMegamorphicLoadSlot : public LCallInstructionHelper<BOX_PIECES, 1, 3> {
6728  public:
LIR_HEADER(MegamorphicLoadSlot)6729   LIR_HEADER(MegamorphicLoadSlot)
6730 
6731   LMegamorphicLoadSlot(const LAllocation& obj, const LDefinition& temp1,
6732                        const LDefinition& temp2, const LDefinition& temp3)
6733       : LCallInstructionHelper(classOpcode) {
6734     setOperand(0, obj);
6735     setTemp(0, temp1);
6736     setTemp(1, temp2);
6737     setTemp(2, temp3);
6738   }
6739 
object()6740   const LAllocation* object() { return getOperand(0); }
temp1()6741   const LDefinition* temp1() { return getTemp(0); }
temp2()6742   const LDefinition* temp2() { return getTemp(1); }
temp3()6743   const LDefinition* temp3() { return getTemp(2); }
6744 
mir()6745   MMegamorphicLoadSlot* mir() const { return mir_->toMegamorphicLoadSlot(); }
6746 };
6747 
6748 class LMegamorphicLoadSlotByValue
6749     : public LCallInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 2> {
6750  public:
LIR_HEADER(MegamorphicLoadSlotByValue)6751   LIR_HEADER(MegamorphicLoadSlotByValue)
6752 
6753   LMegamorphicLoadSlotByValue(const LAllocation& obj,
6754                               const LBoxAllocation& idVal,
6755                               const LDefinition& temp1,
6756                               const LDefinition& temp2)
6757       : LCallInstructionHelper(classOpcode) {
6758     setOperand(0, obj);
6759     setBoxOperand(IdIndex, idVal);
6760     setTemp(0, temp1);
6761     setTemp(1, temp2);
6762   }
6763 
6764   static const size_t IdIndex = 1;
6765 
object()6766   const LAllocation* object() { return getOperand(0); }
temp1()6767   const LDefinition* temp1() { return getTemp(0); }
temp2()6768   const LDefinition* temp2() { return getTemp(1); }
6769 
mir()6770   MMegamorphicLoadSlotByValue* mir() const {
6771     return mir_->toMegamorphicLoadSlotByValue();
6772   }
6773 };
6774 
6775 class LMegamorphicStoreSlot
6776     : public LCallInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 3> {
6777  public:
LIR_HEADER(MegamorphicStoreSlot)6778   LIR_HEADER(MegamorphicStoreSlot)
6779 
6780   LMegamorphicStoreSlot(const LAllocation& obj, const LBoxAllocation& rhs,
6781                         const LDefinition& temp1, const LDefinition& temp2,
6782                         const LDefinition& temp3)
6783       : LCallInstructionHelper(classOpcode) {
6784     setOperand(0, obj);
6785     setBoxOperand(RhsIndex, rhs);
6786     setTemp(0, temp1);
6787     setTemp(1, temp2);
6788     setTemp(2, temp3);
6789   }
6790 
6791   static const size_t RhsIndex = 1;
6792 
object()6793   const LAllocation* object() { return getOperand(0); }
temp1()6794   const LDefinition* temp1() { return getTemp(0); }
temp2()6795   const LDefinition* temp2() { return getTemp(1); }
temp3()6796   const LDefinition* temp3() { return getTemp(2); }
6797 
mir()6798   MMegamorphicStoreSlot* mir() const { return mir_->toMegamorphicStoreSlot(); }
6799 };
6800 
6801 class LMegamorphicHasProp
6802     : public LCallInstructionHelper<1, 1 + BOX_PIECES, 2> {
6803  public:
LIR_HEADER(MegamorphicHasProp)6804   LIR_HEADER(MegamorphicHasProp)
6805 
6806   LMegamorphicHasProp(const LAllocation& obj, const LBoxAllocation& idVal,
6807                       const LDefinition& temp1, const LDefinition& temp2)
6808       : LCallInstructionHelper(classOpcode) {
6809     setOperand(0, obj);
6810     setBoxOperand(IdIndex, idVal);
6811     setTemp(0, temp1);
6812     setTemp(1, temp2);
6813   }
6814 
6815   static const size_t IdIndex = 1;
6816 
object()6817   const LAllocation* object() { return getOperand(0); }
temp1()6818   const LDefinition* temp1() { return getTemp(0); }
temp2()6819   const LDefinition* temp2() { return getTemp(1); }
6820 
mir()6821   MMegamorphicHasProp* mir() const { return mir_->toMegamorphicHasProp(); }
6822 };
6823 
6824 class LGuardIsNotArrayBufferMaybeShared : public LInstructionHelper<0, 1, 1> {
6825  public:
LIR_HEADER(GuardIsNotArrayBufferMaybeShared)6826   LIR_HEADER(GuardIsNotArrayBufferMaybeShared)
6827 
6828   LGuardIsNotArrayBufferMaybeShared(const LAllocation& obj,
6829                                     const LDefinition& temp)
6830       : LInstructionHelper(classOpcode) {
6831     setOperand(0, obj);
6832     setTemp(0, temp);
6833   }
6834 
object()6835   const LAllocation* object() { return getOperand(0); }
temp()6836   const LDefinition* temp() { return getTemp(0); }
6837 };
6838 
6839 class LGuardIsTypedArray : public LInstructionHelper<0, 1, 1> {
6840  public:
LIR_HEADER(GuardIsTypedArray)6841   LIR_HEADER(GuardIsTypedArray)
6842 
6843   LGuardIsTypedArray(const LAllocation& obj, const LDefinition& temp)
6844       : LInstructionHelper(classOpcode) {
6845     setOperand(0, obj);
6846     setTemp(0, temp);
6847   }
6848 
object()6849   const LAllocation* object() { return getOperand(0); }
temp()6850   const LDefinition* temp() { return getTemp(0); }
6851 };
6852 
6853 class LGuardNoDenseElements : public LInstructionHelper<0, 1, 1> {
6854  public:
LIR_HEADER(GuardNoDenseElements)6855   LIR_HEADER(GuardNoDenseElements)
6856 
6857   LGuardNoDenseElements(const LAllocation& in, const LDefinition& temp)
6858       : LInstructionHelper(classOpcode) {
6859     setOperand(0, in);
6860     setTemp(0, temp);
6861   }
6862 
temp()6863   const LDefinition* temp() { return getTemp(0); }
6864 };
6865 
6866 class LInCache : public LInstructionHelper<1, BOX_PIECES + 1, 1> {
6867  public:
LIR_HEADER(InCache)6868   LIR_HEADER(InCache)
6869   LInCache(const LBoxAllocation& lhs, const LAllocation& rhs,
6870            const LDefinition& temp)
6871       : LInstructionHelper(classOpcode) {
6872     setBoxOperand(LHS, lhs);
6873     setOperand(RHS, rhs);
6874     setTemp(0, temp);
6875   }
6876 
lhs()6877   const LAllocation* lhs() { return getOperand(LHS); }
rhs()6878   const LAllocation* rhs() { return getOperand(RHS); }
temp()6879   const LDefinition* temp() { return getTemp(0); }
mir()6880   const MInCache* mir() const { return mir_->toInCache(); }
6881 
6882   static const size_t LHS = 0;
6883   static const size_t RHS = BOX_PIECES;
6884 };
6885 
6886 class LHasOwnCache : public LInstructionHelper<1, 2 * BOX_PIECES, 0> {
6887  public:
6888   LIR_HEADER(HasOwnCache)
6889 
6890   static const size_t Value = 0;
6891   static const size_t Id = BOX_PIECES;
6892 
LHasOwnCache(const LBoxAllocation & value,const LBoxAllocation & id)6893   LHasOwnCache(const LBoxAllocation& value, const LBoxAllocation& id)
6894       : LInstructionHelper(classOpcode) {
6895     setBoxOperand(Value, value);
6896     setBoxOperand(Id, id);
6897   }
6898 
mir()6899   const MHasOwnCache* mir() const { return mir_->toHasOwnCache(); }
6900 };
6901 
6902 class LCheckPrivateFieldCache
6903     : public LInstructionHelper<1, 2 * BOX_PIECES, 0> {
6904  public:
6905   LIR_HEADER(CheckPrivateFieldCache)
6906 
6907   static const size_t Value = 0;
6908   static const size_t Id = BOX_PIECES;
6909 
LCheckPrivateFieldCache(const LBoxAllocation & value,const LBoxAllocation & id)6910   LCheckPrivateFieldCache(const LBoxAllocation& value, const LBoxAllocation& id)
6911       : LInstructionHelper(classOpcode) {
6912     setBoxOperand(Value, value);
6913     setBoxOperand(Id, id);
6914   }
6915 
mir()6916   const MCheckPrivateFieldCache* mir() const {
6917     return mir_->toCheckPrivateFieldCache();
6918   }
6919 };
6920 
6921 class LInstanceOfO : public LInstructionHelper<1, 2, 0> {
6922  public:
LIR_HEADER(InstanceOfO)6923   LIR_HEADER(InstanceOfO)
6924   explicit LInstanceOfO(const LAllocation& lhs, const LAllocation& rhs)
6925       : LInstructionHelper(classOpcode) {
6926     setOperand(0, lhs);
6927     setOperand(1, rhs);
6928   }
6929 
mir()6930   MInstanceOf* mir() const { return mir_->toInstanceOf(); }
6931 
lhs()6932   const LAllocation* lhs() { return getOperand(0); }
rhs()6933   const LAllocation* rhs() { return getOperand(1); }
6934 };
6935 
6936 class LInstanceOfV : public LInstructionHelper<1, BOX_PIECES + 1, 0> {
6937  public:
LIR_HEADER(InstanceOfV)6938   LIR_HEADER(InstanceOfV)
6939   explicit LInstanceOfV(const LBoxAllocation& lhs, const LAllocation& rhs)
6940       : LInstructionHelper(classOpcode) {
6941     setBoxOperand(LHS, lhs);
6942     setOperand(RHS, rhs);
6943   }
6944 
mir()6945   MInstanceOf* mir() const { return mir_->toInstanceOf(); }
6946 
rhs()6947   const LAllocation* rhs() { return getOperand(RHS); }
6948 
6949   static const size_t LHS = 0;
6950   static const size_t RHS = BOX_PIECES;
6951 };
6952 
6953 class LInstanceOfCache : public LInstructionHelper<1, BOX_PIECES + 1, 0> {
6954  public:
LIR_HEADER(InstanceOfCache)6955   LIR_HEADER(InstanceOfCache)
6956   LInstanceOfCache(const LBoxAllocation& lhs, const LAllocation& rhs)
6957       : LInstructionHelper(classOpcode) {
6958     setBoxOperand(LHS, lhs);
6959     setOperand(RHS, rhs);
6960   }
6961 
output()6962   const LDefinition* output() { return this->getDef(0); }
rhs()6963   const LAllocation* rhs() { return getOperand(RHS); }
6964 
6965   static const size_t LHS = 0;
6966   static const size_t RHS = BOX_PIECES;
6967 };
6968 
6969 class LIsCallableO : public LInstructionHelper<1, 1, 0> {
6970  public:
6971   LIR_HEADER(IsCallableO);
LIsCallableO(const LAllocation & object)6972   explicit LIsCallableO(const LAllocation& object)
6973       : LInstructionHelper(classOpcode) {
6974     setOperand(0, object);
6975   }
6976 
object()6977   const LAllocation* object() { return getOperand(0); }
mir()6978   MIsCallable* mir() const { return mir_->toIsCallable(); }
6979 };
6980 
6981 class LIsCallableV : public LInstructionHelper<1, BOX_PIECES, 1> {
6982  public:
6983   LIR_HEADER(IsCallableV);
6984   static const size_t Value = 0;
6985 
LIsCallableV(const LBoxAllocation & value,const LDefinition & temp)6986   LIsCallableV(const LBoxAllocation& value, const LDefinition& temp)
6987       : LInstructionHelper(classOpcode) {
6988     setBoxOperand(0, value);
6989     setTemp(0, temp);
6990   }
temp()6991   const LDefinition* temp() { return getTemp(0); }
mir()6992   MIsCallable* mir() const { return mir_->toIsCallable(); }
6993 };
6994 
6995 class LIsConstructor : public LInstructionHelper<1, 1, 0> {
6996  public:
6997   LIR_HEADER(IsConstructor);
LIsConstructor(const LAllocation & object)6998   explicit LIsConstructor(const LAllocation& object)
6999       : LInstructionHelper(classOpcode) {
7000     setOperand(0, object);
7001   }
7002 
object()7003   const LAllocation* object() { return getOperand(0); }
mir()7004   MIsConstructor* mir() const { return mir_->toIsConstructor(); }
7005 };
7006 
7007 class LIsCrossRealmArrayConstructor : public LInstructionHelper<1, 1, 0> {
7008  public:
7009   LIR_HEADER(IsCrossRealmArrayConstructor);
LIsCrossRealmArrayConstructor(const LAllocation & object)7010   explicit LIsCrossRealmArrayConstructor(const LAllocation& object)
7011       : LInstructionHelper(classOpcode) {
7012     setOperand(0, object);
7013   }
7014 
object()7015   const LAllocation* object() { return getOperand(0); }
7016 };
7017 
7018 class LIsArrayO : public LInstructionHelper<1, 1, 0> {
7019  public:
7020   LIR_HEADER(IsArrayO);
7021 
LIsArrayO(const LAllocation & object)7022   explicit LIsArrayO(const LAllocation& object)
7023       : LInstructionHelper(classOpcode) {
7024     setOperand(0, object);
7025   }
object()7026   const LAllocation* object() { return getOperand(0); }
mir()7027   MIsArray* mir() const { return mir_->toIsArray(); }
7028 };
7029 
7030 class LIsArrayV : public LInstructionHelper<1, BOX_PIECES, 1> {
7031  public:
7032   LIR_HEADER(IsArrayV);
7033   static const size_t Value = 0;
7034 
LIsArrayV(const LBoxAllocation & value,const LDefinition & temp)7035   LIsArrayV(const LBoxAllocation& value, const LDefinition& temp)
7036       : LInstructionHelper(classOpcode) {
7037     setBoxOperand(0, value);
7038     setTemp(0, temp);
7039   }
temp()7040   const LDefinition* temp() { return getTemp(0); }
mir()7041   MIsArray* mir() const { return mir_->toIsArray(); }
7042 };
7043 
7044 class LIsTypedArray : public LInstructionHelper<1, 1, 0> {
7045  public:
7046   LIR_HEADER(IsTypedArray);
7047 
LIsTypedArray(const LAllocation & object)7048   explicit LIsTypedArray(const LAllocation& object)
7049       : LInstructionHelper(classOpcode) {
7050     setOperand(0, object);
7051   }
object()7052   const LAllocation* object() { return getOperand(0); }
mir()7053   MIsTypedArray* mir() const { return mir_->toIsTypedArray(); }
7054 };
7055 
7056 class LIsObject : public LInstructionHelper<1, BOX_PIECES, 0> {
7057  public:
7058   LIR_HEADER(IsObject);
7059   static const size_t Input = 0;
7060 
LIsObject(const LBoxAllocation & input)7061   explicit LIsObject(const LBoxAllocation& input)
7062       : LInstructionHelper(classOpcode) {
7063     setBoxOperand(Input, input);
7064   }
7065 
mir()7066   MIsObject* mir() const { return mir_->toIsObject(); }
7067 };
7068 
7069 class LIsObjectAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 0> {
7070  public:
LIR_HEADER(IsObjectAndBranch)7071   LIR_HEADER(IsObjectAndBranch)
7072 
7073   LIsObjectAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse,
7074                      const LBoxAllocation& input)
7075       : LControlInstructionHelper(classOpcode) {
7076     setSuccessor(0, ifTrue);
7077     setSuccessor(1, ifFalse);
7078     setBoxOperand(Input, input);
7079   }
7080 
7081   static const size_t Input = 0;
7082 
ifTrue()7083   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()7084   MBasicBlock* ifFalse() const { return getSuccessor(1); }
7085 };
7086 
7087 class LIsNullOrUndefined : public LInstructionHelper<1, BOX_PIECES, 0> {
7088  public:
7089   LIR_HEADER(IsNullOrUndefined);
7090   static const size_t Input = 0;
7091 
LIsNullOrUndefined(const LBoxAllocation & input)7092   explicit LIsNullOrUndefined(const LBoxAllocation& input)
7093       : LInstructionHelper(classOpcode) {
7094     setBoxOperand(Input, input);
7095   }
7096 
mir()7097   MIsNullOrUndefined* mir() const { return mir_->toIsNullOrUndefined(); }
7098 };
7099 
7100 class LIsNullOrUndefinedAndBranch
7101     : public LControlInstructionHelper<2, BOX_PIECES, 0> {
7102   MIsNullOrUndefined* isNullOrUndefined_;
7103 
7104  public:
7105   LIR_HEADER(IsNullOrUndefinedAndBranch)
7106   static const size_t Input = 0;
7107 
LIsNullOrUndefinedAndBranch(MIsNullOrUndefined * isNullOrUndefined,MBasicBlock * ifTrue,MBasicBlock * ifFalse,const LBoxAllocation & input)7108   LIsNullOrUndefinedAndBranch(MIsNullOrUndefined* isNullOrUndefined,
7109                               MBasicBlock* ifTrue, MBasicBlock* ifFalse,
7110                               const LBoxAllocation& input)
7111       : LControlInstructionHelper(classOpcode),
7112         isNullOrUndefined_(isNullOrUndefined) {
7113     setSuccessor(0, ifTrue);
7114     setSuccessor(1, ifFalse);
7115     setBoxOperand(Input, input);
7116   }
7117 
ifTrue()7118   MBasicBlock* ifTrue() const { return getSuccessor(0); }
ifFalse()7119   MBasicBlock* ifFalse() const { return getSuccessor(1); }
7120 
isNullOrUndefinedMir()7121   MIsNullOrUndefined* isNullOrUndefinedMir() const {
7122     return isNullOrUndefined_;
7123   }
7124 };
7125 
7126 class LHasClass : public LInstructionHelper<1, 1, 0> {
7127  public:
7128   LIR_HEADER(HasClass);
LHasClass(const LAllocation & lhs)7129   explicit LHasClass(const LAllocation& lhs) : LInstructionHelper(classOpcode) {
7130     setOperand(0, lhs);
7131   }
7132 
lhs()7133   const LAllocation* lhs() { return getOperand(0); }
mir()7134   MHasClass* mir() const { return mir_->toHasClass(); }
7135 };
7136 
7137 class LGuardToClass : public LInstructionHelper<1, 1, 1> {
7138  public:
7139   LIR_HEADER(GuardToClass);
LGuardToClass(const LAllocation & lhs,const LDefinition & temp)7140   explicit LGuardToClass(const LAllocation& lhs, const LDefinition& temp)
7141       : LInstructionHelper(classOpcode) {
7142     setOperand(0, lhs);
7143     setTemp(0, temp);
7144   }
7145 
lhs()7146   const LAllocation* lhs() { return getOperand(0); }
7147 
temp()7148   const LDefinition* temp() { return getTemp(0); }
7149 
mir()7150   MGuardToClass* mir() const { return mir_->toGuardToClass(); }
7151 };
7152 
7153 class LObjectClassToString : public LCallInstructionHelper<1, 1, 1> {
7154  public:
7155   LIR_HEADER(ObjectClassToString);
7156 
LObjectClassToString(const LAllocation & lhs,const LDefinition & temp)7157   LObjectClassToString(const LAllocation& lhs, const LDefinition& temp)
7158       : LCallInstructionHelper(classOpcode) {
7159     setOperand(0, lhs);
7160     setTemp(0, temp);
7161   }
object()7162   const LAllocation* object() { return getOperand(0); }
temp()7163   const LDefinition* temp() { return getTemp(0); }
mir()7164   MObjectClassToString* mir() const { return mir_->toObjectClassToString(); }
7165 };
7166 
7167 template <size_t Defs, size_t Ops>
7168 class LWasmSelectBase : public LInstructionHelper<Defs, Ops, 0> {
7169   typedef LInstructionHelper<Defs, Ops, 0> Base;
7170 
7171  protected:
LWasmSelectBase(LNode::Opcode opcode)7172   explicit LWasmSelectBase(LNode::Opcode opcode) : Base(opcode) {}
7173 
7174  public:
mir()7175   MWasmSelect* mir() const { return Base::mir_->toWasmSelect(); }
7176 };
7177 
7178 class LWasmSelect : public LWasmSelectBase<1, 3> {
7179  public:
7180   LIR_HEADER(WasmSelect);
7181 
7182   static const size_t TrueExprIndex = 0;
7183   static const size_t FalseExprIndex = 1;
7184   static const size_t CondIndex = 2;
7185 
LWasmSelect(const LAllocation & trueExpr,const LAllocation & falseExpr,const LAllocation & cond)7186   LWasmSelect(const LAllocation& trueExpr, const LAllocation& falseExpr,
7187               const LAllocation& cond)
7188       : LWasmSelectBase(classOpcode) {
7189     setOperand(TrueExprIndex, trueExpr);
7190     setOperand(FalseExprIndex, falseExpr);
7191     setOperand(CondIndex, cond);
7192   }
7193 
trueExpr()7194   const LAllocation* trueExpr() { return getOperand(TrueExprIndex); }
falseExpr()7195   const LAllocation* falseExpr() { return getOperand(FalseExprIndex); }
condExpr()7196   const LAllocation* condExpr() { return getOperand(CondIndex); }
7197 };
7198 
7199 class LWasmSelectI64
7200     : public LWasmSelectBase<INT64_PIECES, 2 * INT64_PIECES + 1> {
7201  public:
7202   LIR_HEADER(WasmSelectI64);
7203 
7204   static const size_t TrueExprIndex = 0;
7205   static const size_t FalseExprIndex = INT64_PIECES;
7206   static const size_t CondIndex = INT64_PIECES * 2;
7207 
LWasmSelectI64(const LInt64Allocation & trueExpr,const LInt64Allocation & falseExpr,const LAllocation & cond)7208   LWasmSelectI64(const LInt64Allocation& trueExpr,
7209                  const LInt64Allocation& falseExpr, const LAllocation& cond)
7210       : LWasmSelectBase(classOpcode) {
7211     setInt64Operand(TrueExprIndex, trueExpr);
7212     setInt64Operand(FalseExprIndex, falseExpr);
7213     setOperand(CondIndex, cond);
7214   }
7215 
trueExpr()7216   const LInt64Allocation trueExpr() { return getInt64Operand(TrueExprIndex); }
falseExpr()7217   const LInt64Allocation falseExpr() { return getInt64Operand(FalseExprIndex); }
condExpr()7218   const LAllocation* condExpr() { return getOperand(CondIndex); }
7219 };
7220 
7221 class LWasmCompareAndSelect : public LWasmSelectBase<1, 4> {
7222   MCompare::CompareType compareType_;
7223   JSOp jsop_;
7224 
7225  public:
7226   LIR_HEADER(WasmCompareAndSelect);
7227 
7228   static const size_t LeftExprIndex = 0;
7229   static const size_t RightExprIndex = 1;
7230   static const size_t IfTrueExprIndex = 2;
7231   static const size_t IfFalseExprIndex = 3;
7232 
LWasmCompareAndSelect(const LAllocation & leftExpr,const LAllocation & rightExpr,MCompare::CompareType compareType,JSOp jsop,const LAllocation & ifTrueExpr,const LAllocation & ifFalseExpr)7233   LWasmCompareAndSelect(const LAllocation& leftExpr,
7234                         const LAllocation& rightExpr,
7235                         MCompare::CompareType compareType, JSOp jsop,
7236                         const LAllocation& ifTrueExpr,
7237                         const LAllocation& ifFalseExpr)
7238       : LWasmSelectBase(classOpcode), compareType_(compareType), jsop_(jsop) {
7239     setOperand(LeftExprIndex, leftExpr);
7240     setOperand(RightExprIndex, rightExpr);
7241     setOperand(IfTrueExprIndex, ifTrueExpr);
7242     setOperand(IfFalseExprIndex, ifFalseExpr);
7243   }
7244 
leftExpr()7245   const LAllocation* leftExpr() { return getOperand(LeftExprIndex); }
rightExpr()7246   const LAllocation* rightExpr() { return getOperand(RightExprIndex); }
ifTrueExpr()7247   const LAllocation* ifTrueExpr() { return getOperand(IfTrueExprIndex); }
ifFalseExpr()7248   const LAllocation* ifFalseExpr() { return getOperand(IfFalseExprIndex); }
7249 
compareType()7250   MCompare::CompareType compareType() { return compareType_; }
jsop()7251   JSOp jsop() { return jsop_; }
7252 };
7253 
7254 class LWasmAddOffset : public LInstructionHelper<1, 1, 0> {
7255  public:
7256   LIR_HEADER(WasmAddOffset);
LWasmAddOffset(const LAllocation & base)7257   explicit LWasmAddOffset(const LAllocation& base)
7258       : LInstructionHelper(classOpcode) {
7259     setOperand(0, base);
7260   }
mir()7261   MWasmAddOffset* mir() const { return mir_->toWasmAddOffset(); }
base()7262   const LAllocation* base() { return getOperand(0); }
7263 };
7264 
7265 class LWasmBoundsCheck : public LInstructionHelper<1, 2, 0> {
7266  public:
7267   LIR_HEADER(WasmBoundsCheck);
LWasmBoundsCheck(const LAllocation & ptr,const LAllocation & boundsCheckLimit)7268   explicit LWasmBoundsCheck(const LAllocation& ptr,
7269                             const LAllocation& boundsCheckLimit)
7270       : LInstructionHelper(classOpcode) {
7271     setOperand(0, ptr);
7272     setOperand(1, boundsCheckLimit);
7273   }
mir()7274   MWasmBoundsCheck* mir() const { return mir_->toWasmBoundsCheck(); }
ptr()7275   const LAllocation* ptr() { return getOperand(0); }
boundsCheckLimit()7276   const LAllocation* boundsCheckLimit() { return getOperand(1); }
7277 };
7278 
7279 class LWasmBoundsCheck64
7280     : public LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0> {
7281  public:
7282   LIR_HEADER(WasmBoundsCheck64);
LWasmBoundsCheck64(const LInt64Allocation & ptr,const LInt64Allocation & boundsCheckLimit)7283   explicit LWasmBoundsCheck64(const LInt64Allocation& ptr,
7284                               const LInt64Allocation& boundsCheckLimit)
7285       : LInstructionHelper(classOpcode) {
7286     setInt64Operand(0, ptr);
7287     setInt64Operand(INT64_PIECES, boundsCheckLimit);
7288   }
mir()7289   MWasmBoundsCheck* mir() const { return mir_->toWasmBoundsCheck(); }
ptr()7290   LInt64Allocation ptr() { return getInt64Operand(0); }
boundsCheckLimit()7291   LInt64Allocation boundsCheckLimit() { return getInt64Operand(INT64_PIECES); }
7292 };
7293 
7294 class LWasmExtendU32Index : public LInstructionHelper<1, 1, 0> {
7295  public:
LIR_HEADER(WasmExtendU32Index)7296   LIR_HEADER(WasmExtendU32Index)
7297 
7298   explicit LWasmExtendU32Index(const LAllocation& input)
7299       : LInstructionHelper(classOpcode) {
7300     setOperand(0, input);
7301   }
7302 
mir()7303   MWasmExtendU32Index* mir() const { return mir_->toWasmExtendU32Index(); }
7304 };
7305 
7306 class LWasmWrapU32Index : public LInstructionHelper<1, 1, 0> {
7307  public:
LIR_HEADER(WasmWrapU32Index)7308   LIR_HEADER(WasmWrapU32Index)
7309 
7310   explicit LWasmWrapU32Index(const LAllocation& input)
7311       : LInstructionHelper(classOpcode) {
7312     setOperand(0, input);
7313   }
7314 
mir()7315   MWasmWrapU32Index* mir() const { return mir_->toWasmWrapU32Index(); }
7316 };
7317 
7318 class LWasmAlignmentCheck : public LInstructionHelper<0, 1, 0> {
7319  public:
7320   LIR_HEADER(WasmAlignmentCheck);
LWasmAlignmentCheck(const LAllocation & ptr)7321   explicit LWasmAlignmentCheck(const LAllocation& ptr)
7322       : LInstructionHelper(classOpcode) {
7323     setOperand(0, ptr);
7324   }
mir()7325   MWasmAlignmentCheck* mir() const { return mir_->toWasmAlignmentCheck(); }
ptr()7326   const LAllocation* ptr() { return getOperand(0); }
7327 };
7328 
7329 class LWasmLoadTls : public LInstructionHelper<1, 1, 0> {
7330  public:
7331   LIR_HEADER(WasmLoadTls);
LWasmLoadTls(const LAllocation & tlsPtr)7332   explicit LWasmLoadTls(const LAllocation& tlsPtr)
7333       : LInstructionHelper(classOpcode) {
7334     setOperand(0, tlsPtr);
7335   }
mir()7336   MWasmLoadTls* mir() const { return mir_->toWasmLoadTls(); }
tlsPtr()7337   const LAllocation* tlsPtr() { return getOperand(0); }
7338 };
7339 
7340 class LWasmHeapBase : public LInstructionHelper<1, 1, 0> {
7341  public:
7342   LIR_HEADER(WasmHeapBase);
LWasmHeapBase(const LAllocation & tlsPtr)7343   explicit LWasmHeapBase(const LAllocation& tlsPtr)
7344       : LInstructionHelper(classOpcode) {
7345     setOperand(0, tlsPtr);
7346   }
mir()7347   MWasmHeapBase* mir() const { return mir_->toWasmHeapBase(); }
tlsPtr()7348   const LAllocation* tlsPtr() { return getOperand(0); }
7349 };
7350 
7351 namespace details {
7352 
7353 // This is a base class for LWasmLoad/LWasmLoadI64.
7354 template <size_t Defs, size_t Temp>
7355 class LWasmLoadBase : public LInstructionHelper<Defs, 2, Temp> {
7356  public:
7357   typedef LInstructionHelper<Defs, 2, Temp> Base;
LWasmLoadBase(LNode::Opcode opcode,const LAllocation & ptr,const LAllocation & memoryBase)7358   explicit LWasmLoadBase(LNode::Opcode opcode, const LAllocation& ptr,
7359                          const LAllocation& memoryBase)
7360       : Base(opcode) {
7361     Base::setOperand(0, ptr);
7362     Base::setOperand(1, memoryBase);
7363   }
mir()7364   MWasmLoad* mir() const { return Base::mir_->toWasmLoad(); }
ptr()7365   const LAllocation* ptr() { return Base::getOperand(0); }
memoryBase()7366   const LAllocation* memoryBase() { return Base::getOperand(1); }
7367 };
7368 
7369 }  // namespace details
7370 
7371 class LWasmLoad : public details::LWasmLoadBase<1, 1> {
7372  public:
7373   explicit LWasmLoad(const LAllocation& ptr,
7374                      const LAllocation& memoryBase = LAllocation())
LWasmLoadBase(classOpcode,ptr,memoryBase)7375       : LWasmLoadBase(classOpcode, ptr, memoryBase) {
7376     setTemp(0, LDefinition::BogusTemp());
7377   }
7378 
ptrCopy()7379   const LDefinition* ptrCopy() { return Base::getTemp(0); }
7380 
7381   LIR_HEADER(WasmLoad);
7382 };
7383 
7384 class LWasmLoadI64 : public details::LWasmLoadBase<INT64_PIECES, 1> {
7385  public:
7386   explicit LWasmLoadI64(const LAllocation& ptr,
7387                         const LAllocation& memoryBase = LAllocation())
LWasmLoadBase(classOpcode,ptr,memoryBase)7388       : LWasmLoadBase(classOpcode, ptr, memoryBase) {
7389     setTemp(0, LDefinition::BogusTemp());
7390   }
7391 
ptrCopy()7392   const LDefinition* ptrCopy() { return Base::getTemp(0); }
7393 
7394   LIR_HEADER(WasmLoadI64);
7395 };
7396 
7397 class LWasmStore : public LInstructionHelper<0, 3, 1> {
7398  public:
7399   LIR_HEADER(WasmStore);
7400 
7401   static const size_t PtrIndex = 0;
7402   static const size_t ValueIndex = 1;
7403   static const size_t MemoryBaseIndex = 2;
7404 
7405   LWasmStore(const LAllocation& ptr, const LAllocation& value,
7406              const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7407       : LInstructionHelper(classOpcode) {
7408     setOperand(PtrIndex, ptr);
7409     setOperand(ValueIndex, value);
7410     setOperand(MemoryBaseIndex, memoryBase);
7411     setTemp(0, LDefinition::BogusTemp());
7412   }
mir()7413   MWasmStore* mir() const { return mir_->toWasmStore(); }
ptr()7414   const LAllocation* ptr() { return getOperand(PtrIndex); }
ptrCopy()7415   const LDefinition* ptrCopy() { return getTemp(0); }
value()7416   const LAllocation* value() { return getOperand(ValueIndex); }
memoryBase()7417   const LAllocation* memoryBase() { return getOperand(MemoryBaseIndex); }
7418 };
7419 
7420 class LWasmStoreI64 : public LInstructionHelper<0, INT64_PIECES + 2, 1> {
7421  public:
7422   LIR_HEADER(WasmStoreI64);
7423 
7424   static const size_t PtrIndex = 0;
7425   static const size_t MemoryBaseIndex = 1;
7426   static const size_t ValueIndex = 2;
7427 
7428   LWasmStoreI64(const LAllocation& ptr, const LInt64Allocation& value,
7429                 const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7430       : LInstructionHelper(classOpcode) {
7431     setOperand(PtrIndex, ptr);
7432     setOperand(MemoryBaseIndex, memoryBase);
7433     setInt64Operand(ValueIndex, value);
7434     setTemp(0, LDefinition::BogusTemp());
7435   }
mir()7436   MWasmStore* mir() const { return mir_->toWasmStore(); }
ptr()7437   const LAllocation* ptr() { return getOperand(PtrIndex); }
memoryBase()7438   const LAllocation* memoryBase() { return getOperand(MemoryBaseIndex); }
ptrCopy()7439   const LDefinition* ptrCopy() { return getTemp(0); }
value()7440   const LInt64Allocation value() { return getInt64Operand(ValueIndex); }
7441 };
7442 
7443 class LAsmJSLoadHeap : public LInstructionHelper<1, 3, 0> {
7444  public:
7445   LIR_HEADER(AsmJSLoadHeap);
7446   explicit LAsmJSLoadHeap(const LAllocation& ptr,
7447                           const LAllocation& boundsCheckLimit,
7448                           const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7449       : LInstructionHelper(classOpcode) {
7450     setOperand(0, ptr);
7451     setOperand(1, boundsCheckLimit);
7452     setOperand(2, memoryBase);
7453   }
mir()7454   MAsmJSLoadHeap* mir() const { return mir_->toAsmJSLoadHeap(); }
ptr()7455   const LAllocation* ptr() { return getOperand(0); }
boundsCheckLimit()7456   const LAllocation* boundsCheckLimit() { return getOperand(1); }
memoryBase()7457   const LAllocation* memoryBase() { return getOperand(2); }
7458 };
7459 
7460 class LAsmJSStoreHeap : public LInstructionHelper<0, 4, 0> {
7461  public:
7462   LIR_HEADER(AsmJSStoreHeap);
7463   LAsmJSStoreHeap(const LAllocation& ptr, const LAllocation& value,
7464                   const LAllocation& boundsCheckLimit,
7465                   const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7466       : LInstructionHelper(classOpcode) {
7467     setOperand(0, ptr);
7468     setOperand(1, value);
7469     setOperand(2, boundsCheckLimit);
7470     setOperand(3, memoryBase);
7471   }
mir()7472   MAsmJSStoreHeap* mir() const { return mir_->toAsmJSStoreHeap(); }
ptr()7473   const LAllocation* ptr() { return getOperand(0); }
value()7474   const LAllocation* value() { return getOperand(1); }
boundsCheckLimit()7475   const LAllocation* boundsCheckLimit() { return getOperand(2); }
memoryBase()7476   const LAllocation* memoryBase() { return getOperand(3); }
7477 };
7478 
7479 class LWasmCompareExchangeHeap : public LInstructionHelper<1, 4, 4> {
7480  public:
7481   LIR_HEADER(WasmCompareExchangeHeap);
7482 
7483   // ARM, ARM64, x86, x64
7484   LWasmCompareExchangeHeap(const LAllocation& ptr, const LAllocation& oldValue,
7485                            const LAllocation& newValue,
7486                            const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7487       : LInstructionHelper(classOpcode) {
7488     setOperand(0, ptr);
7489     setOperand(1, oldValue);
7490     setOperand(2, newValue);
7491     setOperand(3, memoryBase);
7492     setTemp(0, LDefinition::BogusTemp());
7493   }
7494   // MIPS32, MIPS64
LWasmCompareExchangeHeap(const LAllocation & ptr,const LAllocation & oldValue,const LAllocation & newValue,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)7495   LWasmCompareExchangeHeap(const LAllocation& ptr, const LAllocation& oldValue,
7496                            const LAllocation& newValue,
7497                            const LDefinition& valueTemp,
7498                            const LDefinition& offsetTemp,
7499                            const LDefinition& maskTemp)
7500       : LInstructionHelper(classOpcode) {
7501     setOperand(0, ptr);
7502     setOperand(1, oldValue);
7503     setOperand(2, newValue);
7504     setOperand(3, LAllocation());
7505     setTemp(0, LDefinition::BogusTemp());
7506     setTemp(1, valueTemp);
7507     setTemp(2, offsetTemp);
7508     setTemp(3, maskTemp);
7509   }
7510 
ptr()7511   const LAllocation* ptr() { return getOperand(0); }
oldValue()7512   const LAllocation* oldValue() { return getOperand(1); }
newValue()7513   const LAllocation* newValue() { return getOperand(2); }
memoryBase()7514   const LAllocation* memoryBase() { return getOperand(3); }
addrTemp()7515   const LDefinition* addrTemp() { return getTemp(0); }
7516 
setAddrTemp(const LDefinition & addrTemp)7517   void setAddrTemp(const LDefinition& addrTemp) { setTemp(0, addrTemp); }
7518 
7519   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()7520   const LDefinition* valueTemp() { return getTemp(1); }
offsetTemp()7521   const LDefinition* offsetTemp() { return getTemp(2); }
maskTemp()7522   const LDefinition* maskTemp() { return getTemp(3); }
7523 
mir()7524   MWasmCompareExchangeHeap* mir() const {
7525     return mir_->toWasmCompareExchangeHeap();
7526   }
7527 };
7528 
7529 class LWasmFence : public LInstructionHelper<0, 0, 0> {
7530  public:
7531   LIR_HEADER(WasmFence);
LWasmFence()7532   explicit LWasmFence() : LInstructionHelper(classOpcode) {}
7533 };
7534 
7535 class LWasmAtomicExchangeHeap : public LInstructionHelper<1, 3, 4> {
7536  public:
7537   LIR_HEADER(WasmAtomicExchangeHeap);
7538 
7539   // ARM, ARM64, x86, x64
7540   LWasmAtomicExchangeHeap(const LAllocation& ptr, const LAllocation& value,
7541                           const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7542       : LInstructionHelper(classOpcode) {
7543     setOperand(0, ptr);
7544     setOperand(1, value);
7545     setOperand(2, memoryBase);
7546     setTemp(0, LDefinition::BogusTemp());
7547   }
7548   // MIPS32, MIPS64
LWasmAtomicExchangeHeap(const LAllocation & ptr,const LAllocation & value,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)7549   LWasmAtomicExchangeHeap(const LAllocation& ptr, const LAllocation& value,
7550                           const LDefinition& valueTemp,
7551                           const LDefinition& offsetTemp,
7552                           const LDefinition& maskTemp)
7553       : LInstructionHelper(classOpcode) {
7554     setOperand(0, ptr);
7555     setOperand(1, value);
7556     setOperand(2, LAllocation());
7557     setTemp(0, LDefinition::BogusTemp());
7558     setTemp(1, valueTemp);
7559     setTemp(2, offsetTemp);
7560     setTemp(3, maskTemp);
7561   }
7562 
ptr()7563   const LAllocation* ptr() { return getOperand(0); }
value()7564   const LAllocation* value() { return getOperand(1); }
memoryBase()7565   const LAllocation* memoryBase() { return getOperand(2); }
addrTemp()7566   const LDefinition* addrTemp() { return getTemp(0); }
7567 
setAddrTemp(const LDefinition & addrTemp)7568   void setAddrTemp(const LDefinition& addrTemp) { setTemp(0, addrTemp); }
7569 
7570   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()7571   const LDefinition* valueTemp() { return getTemp(1); }
offsetTemp()7572   const LDefinition* offsetTemp() { return getTemp(2); }
maskTemp()7573   const LDefinition* maskTemp() { return getTemp(3); }
7574 
mir()7575   MWasmAtomicExchangeHeap* mir() const {
7576     return mir_->toWasmAtomicExchangeHeap();
7577   }
7578 };
7579 
7580 class LWasmAtomicBinopHeap : public LInstructionHelper<1, 3, 6> {
7581  public:
7582   LIR_HEADER(WasmAtomicBinopHeap);
7583 
7584   static const int32_t valueOp = 1;
7585 
7586   // ARM, ARM64, x86, x64
7587   LWasmAtomicBinopHeap(const LAllocation& ptr, const LAllocation& value,
7588                        const LDefinition& temp,
7589                        const LDefinition& flagTemp = LDefinition::BogusTemp(),
7590                        const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7591       : LInstructionHelper(classOpcode) {
7592     setOperand(0, ptr);
7593     setOperand(1, value);
7594     setOperand(2, memoryBase);
7595     setTemp(0, temp);
7596     setTemp(1, LDefinition::BogusTemp());
7597     setTemp(2, flagTemp);
7598   }
7599   // MIPS32, MIPS64
LWasmAtomicBinopHeap(const LAllocation & ptr,const LAllocation & value,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)7600   LWasmAtomicBinopHeap(const LAllocation& ptr, const LAllocation& value,
7601                        const LDefinition& valueTemp,
7602                        const LDefinition& offsetTemp,
7603                        const LDefinition& maskTemp)
7604       : LInstructionHelper(classOpcode) {
7605     setOperand(0, ptr);
7606     setOperand(1, value);
7607     setOperand(2, LAllocation());
7608     setTemp(0, LDefinition::BogusTemp());
7609     setTemp(1, LDefinition::BogusTemp());
7610     setTemp(2, LDefinition::BogusTemp());
7611     setTemp(3, valueTemp);
7612     setTemp(4, offsetTemp);
7613     setTemp(5, maskTemp);
7614   }
ptr()7615   const LAllocation* ptr() { return getOperand(0); }
value()7616   const LAllocation* value() {
7617     MOZ_ASSERT(valueOp == 1);
7618     return getOperand(1);
7619   }
memoryBase()7620   const LAllocation* memoryBase() { return getOperand(2); }
temp()7621   const LDefinition* temp() { return getTemp(0); }
7622 
7623   // Temp that may be used on some platforms to hold a computed address.
addrTemp()7624   const LDefinition* addrTemp() { return getTemp(1); }
setAddrTemp(const LDefinition & addrTemp)7625   void setAddrTemp(const LDefinition& addrTemp) { setTemp(1, addrTemp); }
7626 
7627   // Temp that may be used on LL/SC platforms for the flag result of the store.
flagTemp()7628   const LDefinition* flagTemp() { return getTemp(2); }
7629   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()7630   const LDefinition* valueTemp() { return getTemp(3); }
offsetTemp()7631   const LDefinition* offsetTemp() { return getTemp(4); }
maskTemp()7632   const LDefinition* maskTemp() { return getTemp(5); }
7633 
mir()7634   MWasmAtomicBinopHeap* mir() const { return mir_->toWasmAtomicBinopHeap(); }
7635 };
7636 
7637 // Atomic binary operation where the result is discarded.
7638 class LWasmAtomicBinopHeapForEffect : public LInstructionHelper<0, 3, 5> {
7639  public:
7640   LIR_HEADER(WasmAtomicBinopHeapForEffect);
7641   // ARM, ARM64, x86, x64
7642   LWasmAtomicBinopHeapForEffect(
7643       const LAllocation& ptr, const LAllocation& value,
7644       const LDefinition& flagTemp = LDefinition::BogusTemp(),
7645       const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)7646       : LInstructionHelper(classOpcode) {
7647     setOperand(0, ptr);
7648     setOperand(1, value);
7649     setOperand(2, memoryBase);
7650     setTemp(0, LDefinition::BogusTemp());
7651     setTemp(1, flagTemp);
7652   }
7653   // MIPS32, MIPS64
LWasmAtomicBinopHeapForEffect(const LAllocation & ptr,const LAllocation & value,const LDefinition & valueTemp,const LDefinition & offsetTemp,const LDefinition & maskTemp)7654   LWasmAtomicBinopHeapForEffect(const LAllocation& ptr,
7655                                 const LAllocation& value,
7656                                 const LDefinition& valueTemp,
7657                                 const LDefinition& offsetTemp,
7658                                 const LDefinition& maskTemp)
7659       : LInstructionHelper(classOpcode) {
7660     setOperand(0, ptr);
7661     setOperand(1, value);
7662     setOperand(2, LAllocation());
7663     setTemp(0, LDefinition::BogusTemp());
7664     setTemp(1, LDefinition::BogusTemp());
7665     setTemp(2, valueTemp);
7666     setTemp(3, offsetTemp);
7667     setTemp(4, maskTemp);
7668   }
ptr()7669   const LAllocation* ptr() { return getOperand(0); }
value()7670   const LAllocation* value() { return getOperand(1); }
memoryBase()7671   const LAllocation* memoryBase() { return getOperand(2); }
7672 
7673   // Temp that may be used on some platforms to hold a computed address.
addrTemp()7674   const LDefinition* addrTemp() { return getTemp(0); }
setAddrTemp(const LDefinition & addrTemp)7675   void setAddrTemp(const LDefinition& addrTemp) { setTemp(0, addrTemp); }
7676 
7677   // Temp that may be used on LL/SC platforms for the flag result of the store.
flagTemp()7678   const LDefinition* flagTemp() { return getTemp(1); }
7679   // Temp that may be used on LL/SC platforms for extract/insert bits of word.
valueTemp()7680   const LDefinition* valueTemp() { return getTemp(2); }
offsetTemp()7681   const LDefinition* offsetTemp() { return getTemp(3); }
maskTemp()7682   const LDefinition* maskTemp() { return getTemp(4); }
7683 
mir()7684   MWasmAtomicBinopHeap* mir() const { return mir_->toWasmAtomicBinopHeap(); }
7685 };
7686 
7687 class LWasmLoadSlot : public LInstructionHelper<1, 1, 0> {
7688   size_t offset_;
7689   MIRType type_;
7690 
7691  public:
7692   LIR_HEADER(WasmLoadSlot);
LWasmLoadSlot(const LAllocation & containerRef,size_t offset,MIRType type)7693   explicit LWasmLoadSlot(const LAllocation& containerRef, size_t offset,
7694                          MIRType type)
7695       : LInstructionHelper(classOpcode), offset_(offset), type_(type) {
7696     setOperand(0, containerRef);
7697   }
containerRef()7698   const LAllocation* containerRef() { return getOperand(0); }
offset()7699   size_t offset() const { return offset_; }
type()7700   MIRType type() const { return type_; }
7701 };
7702 
7703 class LWasmLoadSlotI64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
7704   size_t offset_;
7705 
7706  public:
7707   LIR_HEADER(WasmLoadSlotI64);
LWasmLoadSlotI64(const LAllocation & containerRef,size_t offset)7708   explicit LWasmLoadSlotI64(const LAllocation& containerRef, size_t offset)
7709       : LInstructionHelper(classOpcode), offset_(offset) {
7710     setOperand(0, containerRef);
7711   }
containerRef()7712   const LAllocation* containerRef() { return getOperand(0); }
offset()7713   size_t offset() const { return offset_; }
7714 };
7715 
7716 class LWasmStoreSlot : public LInstructionHelper<0, 2, 0> {
7717   size_t offset_;
7718   MIRType type_;
7719 
7720  public:
7721   LIR_HEADER(WasmStoreSlot);
LWasmStoreSlot(const LAllocation & value,const LAllocation & containerRef,size_t offset,MIRType type)7722   LWasmStoreSlot(const LAllocation& value, const LAllocation& containerRef,
7723                  size_t offset, MIRType type)
7724       : LInstructionHelper(classOpcode), offset_(offset), type_(type) {
7725     setOperand(0, value);
7726     setOperand(1, containerRef);
7727   }
value()7728   const LAllocation* value() { return getOperand(0); }
containerRef()7729   const LAllocation* containerRef() { return getOperand(1); }
offset()7730   size_t offset() const { return offset_; }
type()7731   MIRType type() const { return type_; }
7732 };
7733 
7734 class LWasmStoreSlotI64 : public LInstructionHelper<0, INT64_PIECES + 1, 0> {
7735   size_t offset_;
7736 
7737  public:
7738   LIR_HEADER(WasmStoreSlotI64);
LWasmStoreSlotI64(const LInt64Allocation & value,const LAllocation & containerRef,size_t offset)7739   LWasmStoreSlotI64(const LInt64Allocation& value,
7740                     const LAllocation& containerRef, size_t offset)
7741       : LInstructionHelper(classOpcode), offset_(offset) {
7742     setInt64Operand(0, value);
7743     setOperand(INT64_PIECES, containerRef);
7744   }
value()7745   const LInt64Allocation value() { return getInt64Operand(0); }
containerRef()7746   const LAllocation* containerRef() { return getOperand(INT64_PIECES); }
offset()7747   size_t offset() const { return offset_; }
7748 };
7749 
7750 class LWasmDerivedPointer : public LInstructionHelper<1, 1, 0> {
7751  public:
7752   LIR_HEADER(WasmDerivedPointer);
LWasmDerivedPointer(const LAllocation & base)7753   explicit LWasmDerivedPointer(const LAllocation& base)
7754       : LInstructionHelper(classOpcode) {
7755     setOperand(0, base);
7756   }
base()7757   const LAllocation* base() { return getOperand(0); }
offset()7758   size_t offset() { return mirRaw()->toWasmDerivedPointer()->offset(); }
7759 };
7760 
7761 class LWasmStoreRef : public LInstructionHelper<0, 3, 1> {
7762  public:
7763   LIR_HEADER(WasmStoreRef);
LWasmStoreRef(const LAllocation & tls,const LAllocation & valueAddr,const LAllocation & value,const LDefinition & temp)7764   LWasmStoreRef(const LAllocation& tls, const LAllocation& valueAddr,
7765                 const LAllocation& value, const LDefinition& temp)
7766       : LInstructionHelper(classOpcode) {
7767     setOperand(0, tls);
7768     setOperand(1, valueAddr);
7769     setOperand(2, value);
7770     setTemp(0, temp);
7771   }
mir()7772   MWasmStoreRef* mir() const { return mirRaw()->toWasmStoreRef(); }
tls()7773   const LAllocation* tls() { return getOperand(0); }
valueAddr()7774   const LAllocation* valueAddr() { return getOperand(1); }
value()7775   const LAllocation* value() { return getOperand(2); }
temp()7776   const LDefinition* temp() { return getTemp(0); }
7777 };
7778 
7779 class LWasmParameter : public LInstructionHelper<1, 0, 0> {
7780  public:
7781   LIR_HEADER(WasmParameter);
7782 
LWasmParameter()7783   LWasmParameter() : LInstructionHelper(classOpcode) {}
7784 };
7785 
7786 class LWasmParameterI64 : public LInstructionHelper<INT64_PIECES, 0, 0> {
7787  public:
7788   LIR_HEADER(WasmParameterI64);
7789 
LWasmParameterI64()7790   LWasmParameterI64() : LInstructionHelper(classOpcode) {}
7791 };
7792 
7793 class LWasmReturn : public LInstructionHelper<0, 2, 0> {
7794  public:
7795   LIR_HEADER(WasmReturn);
7796 
LWasmReturn()7797   LWasmReturn() : LInstructionHelper(classOpcode) {}
7798 };
7799 
7800 // +1 for tls.
7801 class LWasmReturnI64 : public LInstructionHelper<0, INT64_PIECES + 1, 0> {
7802  public:
LIR_HEADER(WasmReturnI64)7803   LIR_HEADER(WasmReturnI64)
7804 
7805   LWasmReturnI64(const LInt64Allocation& input, const LAllocation& tls)
7806       : LInstructionHelper(classOpcode) {
7807     setInt64Operand(0, input);
7808     setOperand(INT64_PIECES, tls);
7809   }
7810 };
7811 
7812 class LWasmReturnVoid : public LInstructionHelper<0, 1, 0> {
7813  public:
7814   LIR_HEADER(WasmReturnVoid);
7815 
LWasmReturnVoid()7816   LWasmReturnVoid() : LInstructionHelper(classOpcode) {}
7817 };
7818 
7819 class LWasmStackArg : public LInstructionHelper<0, 1, 0> {
7820  public:
7821   LIR_HEADER(WasmStackArg);
LWasmStackArg(const LAllocation & arg)7822   explicit LWasmStackArg(const LAllocation& arg)
7823       : LInstructionHelper(classOpcode) {
7824     setOperand(0, arg);
7825   }
mir()7826   MWasmStackArg* mir() const { return mirRaw()->toWasmStackArg(); }
arg()7827   const LAllocation* arg() { return getOperand(0); }
7828 };
7829 
7830 class LWasmStackArgI64 : public LInstructionHelper<0, INT64_PIECES, 0> {
7831  public:
7832   LIR_HEADER(WasmStackArgI64);
LWasmStackArgI64(const LInt64Allocation & arg)7833   explicit LWasmStackArgI64(const LInt64Allocation& arg)
7834       : LInstructionHelper(classOpcode) {
7835     setInt64Operand(0, arg);
7836   }
mir()7837   MWasmStackArg* mir() const { return mirRaw()->toWasmStackArg(); }
arg()7838   const LInt64Allocation arg() { return getInt64Operand(0); }
7839 };
7840 
7841 class LWasmNullConstant : public LInstructionHelper<1, 0, 0> {
7842  public:
7843   LIR_HEADER(WasmNullConstant);
LWasmNullConstant()7844   explicit LWasmNullConstant() : LInstructionHelper(classOpcode) {}
7845 };
7846 
7847 class LWasmCall : public LVariadicInstruction<0, 0> {
7848   bool needsBoundsCheck_;
7849 
7850  public:
7851   LIR_HEADER(WasmCall);
7852 
LWasmCall(uint32_t numOperands,bool needsBoundsCheck)7853   LWasmCall(uint32_t numOperands, bool needsBoundsCheck)
7854       : LVariadicInstruction(classOpcode, numOperands),
7855         needsBoundsCheck_(needsBoundsCheck) {
7856     this->setIsCall();
7857   }
7858 
mir()7859   MWasmCall* mir() const { return mir_->toWasmCall(); }
7860 
isCallPreserved(AnyRegister reg)7861   static bool isCallPreserved(AnyRegister reg) {
7862     // All MWasmCalls preserve the TLS register:
7863     //  - internal/indirect calls do by the internal wasm ABI
7864     //  - import calls do by explicitly saving/restoring at the callsite
7865     //  - builtin calls do because the TLS reg is non-volatile
7866     // See also CodeGeneratorShared::emitWasmCall.
7867     return !reg.isFloat() && reg.gpr() == WasmTlsReg;
7868   }
7869 
needsBoundsCheck()7870   bool needsBoundsCheck() const { return needsBoundsCheck_; }
7871 };
7872 
7873 class LWasmRegisterResult : public LInstructionHelper<1, 0, 0> {
7874  public:
7875   LIR_HEADER(WasmRegisterResult);
7876 
LWasmRegisterResult()7877   LWasmRegisterResult() : LInstructionHelper(classOpcode) {}
7878 
mir()7879   MWasmRegisterResult* mir() const {
7880     if (!mir_->isWasmRegisterResult()) {
7881       return nullptr;
7882     }
7883     return mir_->toWasmRegisterResult();
7884   }
7885 };
7886 
7887 class LWasmRegisterPairResult : public LInstructionHelper<2, 0, 0> {
7888  public:
7889   LIR_HEADER(WasmRegisterPairResult);
7890 
LWasmRegisterPairResult()7891   LWasmRegisterPairResult() : LInstructionHelper(classOpcode) {}
7892 
mir()7893   MDefinition* mir() const { return mirRaw(); }
7894 };
7895 
7896 class LWasmStackResultArea : public LInstructionHelper<1, 0, 1> {
7897  public:
7898   LIR_HEADER(WasmStackResultArea);
7899 
LWasmStackResultArea(const LDefinition & temp)7900   explicit LWasmStackResultArea(const LDefinition& temp)
7901       : LInstructionHelper(classOpcode) {
7902     setTemp(0, temp);
7903   }
7904 
mir()7905   MWasmStackResultArea* mir() const { return mir_->toWasmStackResultArea(); }
temp()7906   const LDefinition* temp() { return getTemp(0); }
7907 };
7908 
base()7909 inline uint32_t LStackArea::base() const {
7910   return ins()->toWasmStackResultArea()->mir()->base();
7911 }
setBase(uint32_t base)7912 inline void LStackArea::setBase(uint32_t base) {
7913   ins()->toWasmStackResultArea()->mir()->setBase(base);
7914 }
size()7915 inline uint32_t LStackArea::size() const {
7916   return ins()->toWasmStackResultArea()->mir()->byteSize();
7917 }
7918 
done()7919 inline bool LStackArea::ResultIterator::done() const {
7920   return idx_ == alloc_.ins()->toWasmStackResultArea()->mir()->resultCount();
7921 }
next()7922 inline void LStackArea::ResultIterator::next() {
7923   MOZ_ASSERT(!done());
7924   idx_++;
7925 }
alloc()7926 inline LAllocation LStackArea::ResultIterator::alloc() const {
7927   MOZ_ASSERT(!done());
7928   MWasmStackResultArea* area = alloc_.ins()->toWasmStackResultArea()->mir();
7929   return LStackSlot(area->base() - area->result(idx_).offset());
7930 }
isGcPointer()7931 inline bool LStackArea::ResultIterator::isGcPointer() const {
7932   MOZ_ASSERT(!done());
7933   MWasmStackResultArea* area = alloc_.ins()->toWasmStackResultArea()->mir();
7934   MIRType type = area->result(idx_).type();
7935 #ifndef JS_PUNBOX64
7936   // LDefinition::TypeFrom isn't defined for MIRType::Int64 values on
7937   // this platform, so here we have a special case.
7938   if (type == MIRType::Int64) {
7939     return false;
7940   }
7941 #endif
7942   return LDefinition::TypeFrom(type) == LDefinition::OBJECT;
7943 }
7944 
7945 class LWasmStackResult : public LInstructionHelper<1, 1, 0> {
7946  public:
7947   LIR_HEADER(WasmStackResult);
7948 
LWasmStackResult()7949   LWasmStackResult() : LInstructionHelper(classOpcode) {}
7950 
mir()7951   MWasmStackResult* mir() const { return mir_->toWasmStackResult(); }
result(uint32_t base)7952   LStackSlot result(uint32_t base) const {
7953     return LStackSlot(base - mir()->result().offset());
7954   }
7955 };
7956 
7957 class LWasmStackResult64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
7958  public:
7959   LIR_HEADER(WasmStackResult64);
7960 
LWasmStackResult64()7961   LWasmStackResult64() : LInstructionHelper(classOpcode) {}
7962 
mir()7963   MWasmStackResult* mir() const { return mir_->toWasmStackResult(); }
result(uint32_t base,LDefinition * def)7964   LStackSlot result(uint32_t base, LDefinition* def) {
7965     uint32_t offset = base - mir()->result().offset();
7966 #if defined(JS_NUNBOX32)
7967     if (def == getDef(INT64LOW_INDEX)) {
7968       offset -= INT64LOW_OFFSET;
7969     } else {
7970       MOZ_ASSERT(def == getDef(INT64HIGH_INDEX));
7971       offset -= INT64HIGH_OFFSET;
7972     }
7973 #else
7974     MOZ_ASSERT(def == getDef(0));
7975 #endif
7976     return LStackSlot(offset);
7977   }
7978 };
7979 
resultAlloc(LInstruction * lir,LDefinition * def)7980 inline LStackSlot LStackArea::resultAlloc(LInstruction* lir,
7981                                           LDefinition* def) const {
7982   if (lir->isWasmStackResult64()) {
7983     return lir->toWasmStackResult64()->result(base(), def);
7984   }
7985   MOZ_ASSERT(def == lir->getDef(0));
7986   return lir->toWasmStackResult()->result(base());
7987 }
7988 
isCallPreserved(AnyRegister reg)7989 inline bool LNode::isCallPreserved(AnyRegister reg) const {
7990   return isWasmCall() && LWasmCall::isCallPreserved(reg);
7991 }
7992 
7993 class LAssertRangeI : public LInstructionHelper<0, 1, 0> {
7994  public:
LIR_HEADER(AssertRangeI)7995   LIR_HEADER(AssertRangeI)
7996 
7997   explicit LAssertRangeI(const LAllocation& input)
7998       : LInstructionHelper(classOpcode) {
7999     setOperand(0, input);
8000   }
8001 
input()8002   const LAllocation* input() { return getOperand(0); }
8003 
mir()8004   MAssertRange* mir() { return mir_->toAssertRange(); }
range()8005   const Range* range() { return mir()->assertedRange(); }
8006 };
8007 
8008 class LAssertRangeD : public LInstructionHelper<0, 1, 1> {
8009  public:
LIR_HEADER(AssertRangeD)8010   LIR_HEADER(AssertRangeD)
8011 
8012   LAssertRangeD(const LAllocation& input, const LDefinition& temp)
8013       : LInstructionHelper(classOpcode) {
8014     setOperand(0, input);
8015     setTemp(0, temp);
8016   }
8017 
input()8018   const LAllocation* input() { return getOperand(0); }
8019 
temp()8020   const LDefinition* temp() { return getTemp(0); }
8021 
mir()8022   MAssertRange* mir() { return mir_->toAssertRange(); }
range()8023   const Range* range() { return mir()->assertedRange(); }
8024 };
8025 
8026 class LAssertRangeF : public LInstructionHelper<0, 1, 2> {
8027  public:
LIR_HEADER(AssertRangeF)8028   LIR_HEADER(AssertRangeF)
8029   LAssertRangeF(const LAllocation& input, const LDefinition& temp,
8030                 const LDefinition& temp2)
8031       : LInstructionHelper(classOpcode) {
8032     setOperand(0, input);
8033     setTemp(0, temp);
8034     setTemp(1, temp2);
8035   }
8036 
input()8037   const LAllocation* input() { return getOperand(0); }
temp()8038   const LDefinition* temp() { return getTemp(0); }
temp2()8039   const LDefinition* temp2() { return getTemp(1); }
8040 
mir()8041   MAssertRange* mir() { return mir_->toAssertRange(); }
range()8042   const Range* range() { return mir()->assertedRange(); }
8043 };
8044 
8045 class LAssertRangeV : public LInstructionHelper<0, BOX_PIECES, 3> {
8046  public:
LIR_HEADER(AssertRangeV)8047   LIR_HEADER(AssertRangeV)
8048 
8049   LAssertRangeV(const LBoxAllocation& input, const LDefinition& temp,
8050                 const LDefinition& floatTemp1, const LDefinition& floatTemp2)
8051       : LInstructionHelper(classOpcode) {
8052     setBoxOperand(Input, input);
8053     setTemp(0, temp);
8054     setTemp(1, floatTemp1);
8055     setTemp(2, floatTemp2);
8056   }
8057 
8058   static const size_t Input = 0;
8059 
temp()8060   const LDefinition* temp() { return getTemp(0); }
floatTemp1()8061   const LDefinition* floatTemp1() { return getTemp(1); }
floatTemp2()8062   const LDefinition* floatTemp2() { return getTemp(2); }
8063 
mir()8064   MAssertRange* mir() { return mir_->toAssertRange(); }
range()8065   const Range* range() { return mir()->assertedRange(); }
8066 };
8067 
8068 class LAssertClass : public LInstructionHelper<0, 1, 1> {
8069  public:
LIR_HEADER(AssertClass)8070   LIR_HEADER(AssertClass)
8071 
8072   explicit LAssertClass(const LAllocation& input, const LDefinition& temp)
8073       : LInstructionHelper(classOpcode) {
8074     setOperand(0, input);
8075     setTemp(0, temp);
8076   }
8077 
input()8078   const LAllocation* input() { return getOperand(0); }
8079 
mir()8080   MAssertClass* mir() { return mir_->toAssertClass(); }
8081 };
8082 
8083 class LAssertShape : public LInstructionHelper<0, 1, 0> {
8084  public:
LIR_HEADER(AssertShape)8085   LIR_HEADER(AssertShape)
8086 
8087   explicit LAssertShape(const LAllocation& input)
8088       : LInstructionHelper(classOpcode) {
8089     setOperand(0, input);
8090   }
8091 
input()8092   const LAllocation* input() { return getOperand(0); }
8093 
mir()8094   MAssertShape* mir() { return mir_->toAssertShape(); }
8095 };
8096 
8097 class LAssertResultT : public LInstructionHelper<0, 1, 0> {
8098  public:
LIR_HEADER(AssertResultT)8099   LIR_HEADER(AssertResultT)
8100 
8101   explicit LAssertResultT(const LAllocation& input)
8102       : LInstructionHelper(classOpcode) {
8103     setOperand(0, input);
8104   }
8105 
input()8106   const LAllocation* input() { return getOperand(0); }
8107 };
8108 
8109 class LAssertResultV : public LInstructionHelper<0, BOX_PIECES, 0> {
8110  public:
8111   LIR_HEADER(AssertResultV)
8112 
8113   static const size_t Input = 0;
8114 
LAssertResultV(const LBoxAllocation & input)8115   explicit LAssertResultV(const LBoxAllocation& input)
8116       : LInstructionHelper(classOpcode) {
8117     setBoxOperand(Input, input);
8118   }
8119 };
8120 
8121 class LGuardValue : public LInstructionHelper<0, BOX_PIECES, 0> {
8122  public:
LIR_HEADER(GuardValue)8123   LIR_HEADER(GuardValue)
8124 
8125   explicit LGuardValue(const LBoxAllocation& input)
8126       : LInstructionHelper(classOpcode) {
8127     setBoxOperand(Input, input);
8128   }
8129 
8130   static const size_t Input = 0;
8131 
mir()8132   MGuardValue* mir() { return mir_->toGuardValue(); }
8133 };
8134 
8135 class LGuardNullOrUndefined : public LInstructionHelper<0, BOX_PIECES, 0> {
8136  public:
LIR_HEADER(GuardNullOrUndefined)8137   LIR_HEADER(GuardNullOrUndefined)
8138 
8139   explicit LGuardNullOrUndefined(const LBoxAllocation& input)
8140       : LInstructionHelper(classOpcode) {
8141     setBoxOperand(Input, input);
8142   }
8143 
8144   static const size_t Input = 0;
8145 
mir()8146   MGuardNullOrUndefined* mir() { return mir_->toGuardNullOrUndefined(); }
8147 };
8148 
8149 class LGuardFunctionFlags : public LInstructionHelper<0, 1, 0> {
8150  public:
LIR_HEADER(GuardFunctionFlags)8151   LIR_HEADER(GuardFunctionFlags)
8152 
8153   explicit LGuardFunctionFlags(const LAllocation& fun)
8154       : LInstructionHelper(classOpcode) {
8155     setOperand(0, fun);
8156   }
8157 
function()8158   const LAllocation* function() { return getOperand(0); }
8159 
mir()8160   MGuardFunctionFlags* mir() { return mir_->toGuardFunctionFlags(); }
8161 };
8162 
8163 class LGuardFunctionIsNonBuiltinCtor : public LInstructionHelper<0, 1, 1> {
8164  public:
LIR_HEADER(GuardFunctionIsNonBuiltinCtor)8165   LIR_HEADER(GuardFunctionIsNonBuiltinCtor)
8166 
8167   LGuardFunctionIsNonBuiltinCtor(const LAllocation& fun,
8168                                  const LDefinition& temp)
8169       : LInstructionHelper(classOpcode) {
8170     setOperand(0, fun);
8171     setTemp(0, temp);
8172   }
8173 
function()8174   const LAllocation* function() { return getOperand(0); }
temp()8175   const LDefinition* temp() { return getTemp(0); }
8176 };
8177 
8178 class LGuardFunctionKind : public LInstructionHelper<0, 1, 1> {
8179  public:
LIR_HEADER(GuardFunctionKind)8180   LIR_HEADER(GuardFunctionKind)
8181 
8182   explicit LGuardFunctionKind(const LAllocation& fun, const LDefinition& temp)
8183       : LInstructionHelper(classOpcode) {
8184     setOperand(0, fun);
8185     setTemp(0, temp);
8186   }
8187 
function()8188   const LAllocation* function() { return getOperand(0); }
temp()8189   const LDefinition* temp() { return getTemp(0); }
8190 
mir()8191   MGuardFunctionKind* mir() { return mir_->toGuardFunctionKind(); }
8192 };
8193 
8194 class LGuardFunctionScript : public LInstructionHelper<0, 1, 0> {
8195  public:
LIR_HEADER(GuardFunctionScript)8196   LIR_HEADER(GuardFunctionScript)
8197 
8198   explicit LGuardFunctionScript(const LAllocation& fun)
8199       : LInstructionHelper(classOpcode) {
8200     setOperand(0, fun);
8201   }
8202 
function()8203   const LAllocation* function() { return getOperand(0); }
8204 
mir()8205   MGuardFunctionScript* mir() { return mir_->toGuardFunctionScript(); }
8206 };
8207 
8208 class LIncrementWarmUpCounter : public LInstructionHelper<0, 0, 1> {
8209  public:
LIR_HEADER(IncrementWarmUpCounter)8210   LIR_HEADER(IncrementWarmUpCounter)
8211 
8212   explicit LIncrementWarmUpCounter(const LDefinition& scratch)
8213       : LInstructionHelper(classOpcode) {
8214     setTemp(0, scratch);
8215   }
8216 
scratch()8217   const LDefinition* scratch() { return getTemp(0); }
mir()8218   MIncrementWarmUpCounter* mir() { return mir_->toIncrementWarmUpCounter(); }
8219 };
8220 
8221 class LLexicalCheck : public LInstructionHelper<0, BOX_PIECES, 0> {
8222  public:
LIR_HEADER(LexicalCheck)8223   LIR_HEADER(LexicalCheck)
8224 
8225   explicit LLexicalCheck(const LBoxAllocation& input)
8226       : LInstructionHelper(classOpcode) {
8227     setBoxOperand(Input, input);
8228   }
8229 
mir()8230   MLexicalCheck* mir() { return mir_->toLexicalCheck(); }
8231 
8232   static const size_t Input = 0;
8233 };
8234 
8235 class LThrowRuntimeLexicalError : public LCallInstructionHelper<0, 0, 0> {
8236  public:
LIR_HEADER(ThrowRuntimeLexicalError)8237   LIR_HEADER(ThrowRuntimeLexicalError)
8238 
8239   LThrowRuntimeLexicalError() : LCallInstructionHelper(classOpcode) {}
8240 
mir()8241   MThrowRuntimeLexicalError* mir() {
8242     return mir_->toThrowRuntimeLexicalError();
8243   }
8244 };
8245 
8246 class LThrowMsg : public LCallInstructionHelper<0, 0, 0> {
8247  public:
LIR_HEADER(ThrowMsg)8248   LIR_HEADER(ThrowMsg)
8249 
8250   LThrowMsg() : LCallInstructionHelper(classOpcode) {}
8251 
mir()8252   MThrowMsg* mir() { return mir_->toThrowMsg(); }
8253 };
8254 
8255 class LGlobalDeclInstantiation : public LInstructionHelper<0, 0, 0> {
8256  public:
LIR_HEADER(GlobalDeclInstantiation)8257   LIR_HEADER(GlobalDeclInstantiation)
8258 
8259   LGlobalDeclInstantiation() : LInstructionHelper(classOpcode) {}
8260 
mir()8261   MGlobalDeclInstantiation* mir() { return mir_->toGlobalDeclInstantiation(); }
8262 };
8263 
8264 class LMemoryBarrier : public LInstructionHelper<0, 0, 0> {
8265  private:
8266   const MemoryBarrierBits type_;
8267 
8268  public:
LIR_HEADER(MemoryBarrier)8269   LIR_HEADER(MemoryBarrier)
8270 
8271   // The parameter 'type' is a bitwise 'or' of the barrier types needed,
8272   // see AtomicOp.h.
8273   explicit LMemoryBarrier(MemoryBarrierBits type)
8274       : LInstructionHelper(classOpcode), type_(type) {
8275     MOZ_ASSERT((type_ & ~MembarAllbits) == MembarNobits);
8276   }
8277 
type()8278   MemoryBarrierBits type() const { return type_; }
8279 };
8280 
8281 class LDebugger : public LCallInstructionHelper<0, 0, 2> {
8282  public:
LIR_HEADER(Debugger)8283   LIR_HEADER(Debugger)
8284 
8285   LDebugger(const LDefinition& temp1, const LDefinition& temp2)
8286       : LCallInstructionHelper(classOpcode) {
8287     setTemp(0, temp1);
8288     setTemp(1, temp2);
8289   }
8290 };
8291 
8292 class LNewTarget : public LInstructionHelper<BOX_PIECES, 0, 0> {
8293  public:
LIR_HEADER(NewTarget)8294   LIR_HEADER(NewTarget)
8295 
8296   LNewTarget() : LInstructionHelper(classOpcode) {}
8297 };
8298 
8299 class LArrowNewTarget : public LInstructionHelper<BOX_PIECES, 1, 0> {
8300  public:
LArrowNewTarget(const LAllocation & callee)8301   explicit LArrowNewTarget(const LAllocation& callee)
8302       : LInstructionHelper(classOpcode) {
8303     setOperand(0, callee);
8304   }
8305 
LIR_HEADER(ArrowNewTarget)8306   LIR_HEADER(ArrowNewTarget)
8307 
8308   const LAllocation* callee() { return getOperand(0); }
8309 };
8310 
8311 // Math.random().
8312 class LRandom : public LInstructionHelper<1, 0, 1 + 2 * INT64_PIECES> {
8313  public:
LIR_HEADER(Random)8314   LIR_HEADER(Random)
8315   LRandom(const LDefinition& temp0, const LInt64Definition& temp1,
8316           const LInt64Definition& temp2)
8317       : LInstructionHelper(classOpcode) {
8318     setTemp(0, temp0);
8319     setInt64Temp(1, temp1);
8320     setInt64Temp(1 + INT64_PIECES, temp2);
8321   }
temp0()8322   const LDefinition* temp0() { return getTemp(0); }
temp1()8323   LInt64Definition temp1() { return getInt64Temp(1); }
temp2()8324   LInt64Definition temp2() { return getInt64Temp(1 + INT64_PIECES); }
8325 
mir()8326   MRandom* mir() const { return mir_->toRandom(); }
8327 };
8328 
8329 class LCheckReturn : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0> {
8330  public:
LIR_HEADER(CheckReturn)8331   LIR_HEADER(CheckReturn)
8332 
8333   LCheckReturn(const LBoxAllocation& retVal, const LBoxAllocation& thisVal)
8334       : LInstructionHelper(classOpcode) {
8335     setBoxOperand(ReturnValue, retVal);
8336     setBoxOperand(ThisValue, thisVal);
8337   }
8338 
8339   static const size_t ReturnValue = 0;
8340   static const size_t ThisValue = BOX_PIECES;
8341 };
8342 
8343 class LCheckIsObj : public LInstructionHelper<1, BOX_PIECES, 0> {
8344  public:
8345   LIR_HEADER(CheckIsObj)
8346 
8347   static const size_t ValueIndex = 0;
8348 
LCheckIsObj(const LBoxAllocation & value)8349   explicit LCheckIsObj(const LBoxAllocation& value)
8350       : LInstructionHelper(classOpcode) {
8351     setBoxOperand(ValueIndex, value);
8352   }
8353 
mir()8354   MCheckIsObj* mir() const { return mir_->toCheckIsObj(); }
8355 };
8356 
8357 class LCheckObjCoercible : public LInstructionHelper<0, BOX_PIECES, 0> {
8358  public:
8359   LIR_HEADER(CheckObjCoercible)
8360 
8361   static const size_t CheckValue = 0;
8362 
LCheckObjCoercible(const LBoxAllocation & value)8363   explicit LCheckObjCoercible(const LBoxAllocation& value)
8364       : LInstructionHelper(classOpcode) {
8365     setBoxOperand(CheckValue, value);
8366   }
8367 };
8368 
8369 class LCheckClassHeritage : public LInstructionHelper<0, BOX_PIECES, 2> {
8370  public:
8371   LIR_HEADER(CheckClassHeritage)
8372 
8373   static const size_t Heritage = 0;
8374 
LCheckClassHeritage(const LBoxAllocation & value,const LDefinition & temp1,const LDefinition & temp2)8375   LCheckClassHeritage(const LBoxAllocation& value, const LDefinition& temp1,
8376                       const LDefinition& temp2)
8377       : LInstructionHelper(classOpcode) {
8378     setBoxOperand(Heritage, value);
8379     setTemp(0, temp1);
8380     setTemp(1, temp2);
8381   }
8382 
temp1()8383   const LDefinition* temp1() { return getTemp(0); }
temp2()8384   const LDefinition* temp2() { return getTemp(1); }
8385 };
8386 
8387 class LCheckThis : public LInstructionHelper<0, BOX_PIECES, 0> {
8388  public:
8389   LIR_HEADER(CheckThis)
8390 
8391   static const size_t ThisValue = 0;
8392 
LCheckThis(const LBoxAllocation & value)8393   explicit LCheckThis(const LBoxAllocation& value)
8394       : LInstructionHelper(classOpcode) {
8395     setBoxOperand(ThisValue, value);
8396   }
8397 };
8398 
8399 class LCheckThisReinit : public LInstructionHelper<0, BOX_PIECES, 0> {
8400  public:
8401   LIR_HEADER(CheckThisReinit)
8402 
8403   static const size_t ThisValue = 0;
8404 
LCheckThisReinit(const LBoxAllocation & value)8405   explicit LCheckThisReinit(const LBoxAllocation& value)
8406       : LInstructionHelper(classOpcode) {
8407     setBoxOperand(ThisValue, value);
8408   }
8409 };
8410 
8411 class LGenerator
8412     : public LCallInstructionHelper</* defs = */ 1, /* operands = */ 3,
8413                                     /* temps = */ 0> {
8414  public:
8415   LIR_HEADER(Generator)
8416 
8417   static const size_t CalleeInput = 0;
8418   static const size_t EnvInput = 1;
8419   static const size_t ArgsInput = 2;
8420 
LGenerator(const LAllocation & callee,const LAllocation & environmentChain,const LAllocation & argsObject)8421   LGenerator(const LAllocation& callee, const LAllocation& environmentChain,
8422              const LAllocation& argsObject)
8423       : LCallInstructionHelper(classOpcode) {
8424     setOperand(CalleeInput, callee);
8425     setOperand(EnvInput, environmentChain);
8426     setOperand(ArgsInput, argsObject);
8427   }
8428 
mir()8429   MGenerator* mir() const { return mir_->toGenerator(); }
callee()8430   const LAllocation* callee() { return getOperand(CalleeInput); }
environmentChain()8431   const LAllocation* environmentChain() { return getOperand(EnvInput); }
argsObject()8432   const LAllocation* argsObject() { return getOperand(ArgsInput); }
8433 };
8434 
8435 class LAsyncResolve : public LCallInstructionHelper<1, 1 + BOX_PIECES, 0> {
8436  public:
8437   LIR_HEADER(AsyncResolve)
8438 
8439   static const size_t GeneratorInput = 0;
8440   static const size_t ValueOrReasonInput = 1;
8441 
LAsyncResolve(const LAllocation & generator,const LBoxAllocation & valueOrReason)8442   LAsyncResolve(const LAllocation& generator,
8443                 const LBoxAllocation& valueOrReason)
8444       : LCallInstructionHelper(classOpcode) {
8445     setOperand(GeneratorInput, generator);
8446     setBoxOperand(ValueOrReasonInput, valueOrReason);
8447   }
8448 
mir()8449   MAsyncResolve* mir() const { return mir_->toAsyncResolve(); }
generator()8450   const LAllocation* generator() { return getOperand(GeneratorInput); }
8451 };
8452 
8453 class LAsyncAwait
8454     : public LCallInstructionHelper</* defs= */ 1,
8455                                     /*operands = */ BOX_PIECES + 1,
8456                                     /* temps = */ 0> {
8457  public:
8458   LIR_HEADER(AsyncAwait)
8459 
8460   static const size_t ValueInput = 0;
8461   static const size_t GenInput = BOX_PIECES;
8462 
LAsyncAwait(const LBoxAllocation & value,const LAllocation & generator)8463   explicit LAsyncAwait(const LBoxAllocation& value,
8464                        const LAllocation& generator)
8465       : LCallInstructionHelper(classOpcode) {
8466     setBoxOperand(ValueInput, value);
8467     setOperand(GenInput, generator);
8468   }
8469 
mir()8470   MAsyncAwait* mir() { return mir_->toAsyncAwait(); }
generator()8471   const LAllocation* generator() { return getOperand(GenInput); }
8472 };
8473 
8474 class LCanSkipAwait
8475     : public LCallInstructionHelper</* defs= */ 1, /* defs= */ BOX_PIECES,
8476                                     /* temps = */ 0> {
8477  public:
8478   LIR_HEADER(CanSkipAwait)
8479 
8480   static const size_t ValueInput = 0;
8481 
LCanSkipAwait(const LBoxAllocation & value)8482   explicit LCanSkipAwait(const LBoxAllocation& value)
8483       : LCallInstructionHelper(classOpcode) {
8484     setBoxOperand(ValueInput, value);
8485   }
8486 
mir()8487   MCanSkipAwait* mir() { return mir_->toCanSkipAwait(); }
8488 };
8489 
8490 class LMaybeExtractAwaitValue
8491     : public LCallInstructionHelper</* defs= */ BOX_PIECES,
8492                                     /* defs= */ BOX_PIECES + 1,
8493                                     /* temps = */ 0> {
8494  public:
8495   LIR_HEADER(MaybeExtractAwaitValue);
8496 
8497   static const size_t ValueInput = 0;
8498   static const size_t CanSkipInput = BOX_PIECES;
8499 
LMaybeExtractAwaitValue(const LBoxAllocation & value,const LAllocation & canSkip)8500   explicit LMaybeExtractAwaitValue(const LBoxAllocation& value,
8501                                    const LAllocation& canSkip)
8502       : LCallInstructionHelper(classOpcode) {
8503     setBoxOperand(ValueInput, value);
8504     setOperand(CanSkipInput, canSkip);
8505   }
8506 
mir()8507   MMaybeExtractAwaitValue* mir() { return mir_->toMaybeExtractAwaitValue(); }
canSkip()8508   const LAllocation* canSkip() { return getOperand(CanSkipInput); }
8509 };
8510 
8511 class LDebugCheckSelfHosted : public LCallInstructionHelper<0, BOX_PIECES, 0> {
8512  public:
8513   LIR_HEADER(DebugCheckSelfHosted)
8514 
8515   static const size_t CheckValue = 0;
8516 
LDebugCheckSelfHosted(const LBoxAllocation & value)8517   explicit LDebugCheckSelfHosted(const LBoxAllocation& value)
8518       : LCallInstructionHelper(classOpcode) {
8519     setBoxOperand(CheckValue, value);
8520   }
8521 };
8522 
8523 class LFinishBoundFunctionInit : public LInstructionHelper<0, 3, 2> {
8524  public:
LIR_HEADER(FinishBoundFunctionInit)8525   LIR_HEADER(FinishBoundFunctionInit)
8526 
8527   LFinishBoundFunctionInit(const LAllocation& bound, const LAllocation& target,
8528                            const LAllocation& argCount,
8529                            const LDefinition& temp1, const LDefinition& temp2)
8530       : LInstructionHelper(classOpcode) {
8531     setOperand(0, bound);
8532     setOperand(1, target);
8533     setOperand(2, argCount);
8534     setTemp(0, temp1);
8535     setTemp(1, temp2);
8536   }
8537 
bound()8538   const LAllocation* bound() { return getOperand(0); }
target()8539   const LAllocation* target() { return getOperand(1); }
argCount()8540   const LAllocation* argCount() { return getOperand(2); }
temp1()8541   const LDefinition* temp1() { return getTemp(0); }
temp2()8542   const LDefinition* temp2() { return getTemp(1); }
8543 };
8544 
8545 class LIsPackedArray : public LInstructionHelper<1, 1, 1> {
8546  public:
LIR_HEADER(IsPackedArray)8547   LIR_HEADER(IsPackedArray)
8548 
8549   LIsPackedArray(const LAllocation& object, const LDefinition& temp)
8550       : LInstructionHelper(classOpcode) {
8551     setOperand(0, object);
8552     setTemp(0, temp);
8553   }
8554 
object()8555   const LAllocation* object() { return getOperand(0); }
temp()8556   const LDefinition* temp() { return getTemp(0); }
8557 };
8558 
8559 class LGuardArrayIsPacked : public LInstructionHelper<0, 1, 2> {
8560  public:
LIR_HEADER(GuardArrayIsPacked)8561   LIR_HEADER(GuardArrayIsPacked)
8562 
8563   explicit LGuardArrayIsPacked(const LAllocation& array,
8564                                const LDefinition& temp1,
8565                                const LDefinition& temp2)
8566       : LInstructionHelper(classOpcode) {
8567     setOperand(0, array);
8568     setTemp(0, temp1);
8569     setTemp(1, temp2);
8570   }
8571 
array()8572   const LAllocation* array() { return getOperand(0); }
temp1()8573   const LDefinition* temp1() { return getTemp(0); }
temp2()8574   const LDefinition* temp2() { return getTemp(1); }
8575 
mir()8576   MGuardArrayIsPacked* mir() { return mir_->toGuardArrayIsPacked(); }
8577 };
8578 
8579 class LGetPrototypeOf : public LInstructionHelper<BOX_PIECES, 1, 0> {
8580  public:
LIR_HEADER(GetPrototypeOf)8581   LIR_HEADER(GetPrototypeOf)
8582 
8583   explicit LGetPrototypeOf(const LAllocation& target)
8584       : LInstructionHelper(classOpcode) {
8585     setOperand(0, target);
8586   }
8587 
target()8588   const LAllocation* target() { return getOperand(0); }
8589 };
8590 
8591 class LObjectWithProto : public LCallInstructionHelper<1, BOX_PIECES, 0> {
8592  public:
8593   LIR_HEADER(ObjectWithProto)
8594 
8595   static const size_t PrototypeValue = 0;
8596 
LObjectWithProto(const LBoxAllocation & prototype)8597   explicit LObjectWithProto(const LBoxAllocation& prototype)
8598       : LCallInstructionHelper(classOpcode) {
8599     setBoxOperand(PrototypeValue, prototype);
8600   }
8601 };
8602 
8603 class LObjectStaticProto : public LInstructionHelper<1, 1, 0> {
8604  public:
LIR_HEADER(ObjectStaticProto)8605   LIR_HEADER(ObjectStaticProto)
8606 
8607   explicit LObjectStaticProto(const LAllocation& object)
8608       : LInstructionHelper(classOpcode) {
8609     setOperand(0, object);
8610   }
8611 };
8612 
8613 class LBuiltinObject : public LCallInstructionHelper<1, 0, 0> {
8614  public:
LIR_HEADER(BuiltinObject)8615   LIR_HEADER(BuiltinObject)
8616 
8617   LBuiltinObject() : LCallInstructionHelper(classOpcode) {}
8618 
mir()8619   MBuiltinObject* mir() const { return mir_->toBuiltinObject(); }
8620 };
8621 
8622 class LSuperFunction : public LInstructionHelper<BOX_PIECES, 1, 1> {
8623  public:
LIR_HEADER(SuperFunction)8624   LIR_HEADER(SuperFunction)
8625 
8626   explicit LSuperFunction(const LAllocation& callee, const LDefinition& temp)
8627       : LInstructionHelper(classOpcode) {
8628     setOperand(0, callee);
8629     setTemp(0, temp);
8630   }
8631 
callee()8632   const LAllocation* callee() { return getOperand(0); }
temp()8633   const LDefinition* temp() { return this->getTemp(0); }
8634 };
8635 
8636 class LInitHomeObject : public LInstructionHelper<0, 1 + BOX_PIECES, 0> {
8637  public:
8638   LIR_HEADER(InitHomeObject)
8639 
8640   static const size_t HomeObjectValue = 1;
8641 
LInitHomeObject(const LAllocation & function,const LBoxAllocation & homeObject)8642   LInitHomeObject(const LAllocation& function, const LBoxAllocation& homeObject)
8643       : LInstructionHelper(classOpcode) {
8644     setOperand(0, function);
8645     setBoxOperand(HomeObjectValue, homeObject);
8646   }
8647 
function()8648   const LAllocation* function() { return getOperand(0); }
8649 };
8650 
8651 class LIsTypedArrayConstructor : public LInstructionHelper<1, 1, 0> {
8652  public:
LIR_HEADER(IsTypedArrayConstructor)8653   LIR_HEADER(IsTypedArrayConstructor)
8654 
8655   explicit LIsTypedArrayConstructor(const LAllocation& object)
8656       : LInstructionHelper(classOpcode) {
8657     setOperand(0, object);
8658   }
8659 
object()8660   const LAllocation* object() { return getOperand(0); }
8661 };
8662 
8663 class LLoadValueTag : public LInstructionHelper<1, BOX_PIECES, 0> {
8664  public:
8665   LIR_HEADER(LoadValueTag)
8666 
8667   static const size_t Value = 0;
8668 
LLoadValueTag(const LBoxAllocation & value)8669   explicit LLoadValueTag(const LBoxAllocation& value)
8670       : LInstructionHelper(classOpcode) {
8671     setBoxOperand(Value, value);
8672   }
8673 };
8674 
8675 class LGuardTagNotEqual : public LInstructionHelper<0, 2, 0> {
8676  public:
LIR_HEADER(GuardTagNotEqual)8677   LIR_HEADER(GuardTagNotEqual)
8678 
8679   LGuardTagNotEqual(const LAllocation& lhs, const LAllocation& rhs)
8680       : LInstructionHelper(classOpcode) {
8681     setOperand(0, lhs);
8682     setOperand(1, rhs);
8683   }
8684 
lhs()8685   const LAllocation* lhs() { return getOperand(0); }
rhs()8686   const LAllocation* rhs() { return getOperand(1); }
8687 };
8688 
8689 class LLoadWrapperTarget : public LInstructionHelper<1, 1, 0> {
8690  public:
LIR_HEADER(LoadWrapperTarget)8691   LIR_HEADER(LoadWrapperTarget)
8692 
8693   explicit LLoadWrapperTarget(const LAllocation& object)
8694       : LInstructionHelper(classOpcode) {
8695     setOperand(0, object);
8696   }
8697 
object()8698   const LAllocation* object() { return getOperand(0); }
8699 };
8700 
8701 class LGuardHasGetterSetter : public LCallInstructionHelper<0, 1, 3> {
8702  public:
LIR_HEADER(GuardHasGetterSetter)8703   LIR_HEADER(GuardHasGetterSetter)
8704 
8705   LGuardHasGetterSetter(const LAllocation& object, const LDefinition& temp1,
8706                         const LDefinition& temp2, const LDefinition& temp3)
8707       : LCallInstructionHelper(classOpcode) {
8708     setOperand(0, object);
8709     setTemp(0, temp1);
8710     setTemp(1, temp2);
8711     setTemp(2, temp3);
8712   }
8713 
object()8714   const LAllocation* object() { return getOperand(0); }
temp1()8715   const LDefinition* temp1() { return getTemp(0); }
temp2()8716   const LDefinition* temp2() { return getTemp(1); }
temp3()8717   const LDefinition* temp3() { return getTemp(2); }
8718 
mir()8719   MGuardHasGetterSetter* mir() const { return mir_->toGuardHasGetterSetter(); }
8720 };
8721 
8722 class LGuardIsExtensible : public LInstructionHelper<0, 1, 1> {
8723  public:
LIR_HEADER(GuardIsExtensible)8724   LIR_HEADER(GuardIsExtensible)
8725 
8726   LGuardIsExtensible(const LAllocation& object, const LDefinition& temp)
8727       : LInstructionHelper(classOpcode) {
8728     setOperand(0, object);
8729     setTemp(0, temp);
8730   }
8731 
object()8732   const LAllocation* object() { return getOperand(0); }
temp()8733   const LDefinition* temp() { return getTemp(0); }
8734 };
8735 
8736 class LGuardInt32IsNonNegative : public LInstructionHelper<0, 1, 0> {
8737  public:
LIR_HEADER(GuardInt32IsNonNegative)8738   LIR_HEADER(GuardInt32IsNonNegative)
8739 
8740   explicit LGuardInt32IsNonNegative(const LAllocation& index)
8741       : LInstructionHelper(classOpcode) {
8742     setOperand(0, index);
8743   }
8744 
index()8745   const LAllocation* index() { return getOperand(0); }
8746 };
8747 
8748 class LGuardIndexGreaterThanDenseInitLength
8749     : public LInstructionHelper<0, 2, 2> {
8750  public:
LIR_HEADER(GuardIndexGreaterThanDenseInitLength)8751   LIR_HEADER(GuardIndexGreaterThanDenseInitLength)
8752 
8753   LGuardIndexGreaterThanDenseInitLength(const LAllocation& object,
8754                                         const LAllocation& index,
8755                                         const LDefinition& temp,
8756                                         const LDefinition& spectreTemp)
8757       : LInstructionHelper(classOpcode) {
8758     setOperand(0, object);
8759     setOperand(1, index);
8760     setTemp(0, temp);
8761     setTemp(1, spectreTemp);
8762   }
8763 
object()8764   const LAllocation* object() { return getOperand(0); }
index()8765   const LAllocation* index() { return getOperand(1); }
temp()8766   const LDefinition* temp() { return getTemp(0); }
spectreTemp()8767   const LDefinition* spectreTemp() { return getTemp(1); }
8768 };
8769 
8770 class LGuardIndexIsValidUpdateOrAdd : public LInstructionHelper<0, 2, 2> {
8771  public:
LIR_HEADER(GuardIndexIsValidUpdateOrAdd)8772   LIR_HEADER(GuardIndexIsValidUpdateOrAdd)
8773 
8774   LGuardIndexIsValidUpdateOrAdd(const LAllocation& object,
8775                                 const LAllocation& index,
8776                                 const LDefinition& temp,
8777                                 const LDefinition& spectreTemp)
8778       : LInstructionHelper(classOpcode) {
8779     setOperand(0, object);
8780     setOperand(1, index);
8781     setTemp(0, temp);
8782     setTemp(1, spectreTemp);
8783   }
8784 
object()8785   const LAllocation* object() { return getOperand(0); }
index()8786   const LAllocation* index() { return getOperand(1); }
temp()8787   const LDefinition* temp() { return getTemp(0); }
spectreTemp()8788   const LDefinition* spectreTemp() { return getTemp(1); }
8789 };
8790 
8791 class LCallAddOrUpdateSparseElement
8792     : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0> {
8793  public:
LIR_HEADER(CallAddOrUpdateSparseElement)8794   LIR_HEADER(CallAddOrUpdateSparseElement)
8795 
8796   LCallAddOrUpdateSparseElement(const LAllocation& object,
8797                                 const LAllocation& index,
8798                                 const LBoxAllocation& value)
8799       : LCallInstructionHelper(classOpcode) {
8800     setOperand(0, object);
8801     setOperand(1, index);
8802     setBoxOperand(ValueIndex, value);
8803   }
8804 
8805   static const size_t ValueIndex = 2;
8806 
object()8807   const LAllocation* object() { return getOperand(0); }
index()8808   const LAllocation* index() { return getOperand(1); }
8809 
mir()8810   MCallAddOrUpdateSparseElement* mir() const {
8811     return mir_->toCallAddOrUpdateSparseElement();
8812   }
8813 };
8814 
8815 class LCallGetSparseElement : public LCallInstructionHelper<BOX_PIECES, 2, 0> {
8816  public:
LIR_HEADER(CallGetSparseElement)8817   LIR_HEADER(CallGetSparseElement)
8818 
8819   LCallGetSparseElement(const LAllocation& object, const LAllocation& index)
8820       : LCallInstructionHelper(classOpcode) {
8821     setOperand(0, object);
8822     setOperand(1, index);
8823   }
8824 
object()8825   const LAllocation* object() { return getOperand(0); }
index()8826   const LAllocation* index() { return getOperand(1); }
8827 };
8828 
8829 class LCallNativeGetElement : public LCallInstructionHelper<BOX_PIECES, 2, 0> {
8830  public:
LIR_HEADER(CallNativeGetElement)8831   LIR_HEADER(CallNativeGetElement)
8832 
8833   LCallNativeGetElement(const LAllocation& object, const LAllocation& index)
8834       : LCallInstructionHelper(classOpcode) {
8835     setOperand(0, object);
8836     setOperand(1, index);
8837   }
8838 
object()8839   const LAllocation* object() { return getOperand(0); }
index()8840   const LAllocation* index() { return getOperand(1); }
8841 };
8842 
8843 class LCallObjectHasSparseElement : public LCallInstructionHelper<1, 2, 2> {
8844  public:
LIR_HEADER(CallObjectHasSparseElement)8845   LIR_HEADER(CallObjectHasSparseElement)
8846 
8847   LCallObjectHasSparseElement(const LAllocation& object,
8848                               const LAllocation& index,
8849                               const LDefinition& temp1,
8850                               const LDefinition& temp2)
8851       : LCallInstructionHelper(classOpcode) {
8852     setOperand(0, object);
8853     setOperand(1, index);
8854     setTemp(0, temp1);
8855     setTemp(1, temp2);
8856   }
8857 
object()8858   const LAllocation* object() { return getOperand(0); }
index()8859   const LAllocation* index() { return getOperand(1); }
temp1()8860   const LDefinition* temp1() { return getTemp(0); }
temp2()8861   const LDefinition* temp2() { return getTemp(1); }
8862 };
8863 
8864 class LBigIntAsIntN : public LCallInstructionHelper<1, 2, 0> {
8865  public:
LIR_HEADER(BigIntAsIntN)8866   LIR_HEADER(BigIntAsIntN)
8867 
8868   LBigIntAsIntN(const LAllocation& bits, const LAllocation& input)
8869       : LCallInstructionHelper(classOpcode) {
8870     setOperand(0, bits);
8871     setOperand(1, input);
8872   }
8873 
bits()8874   const LAllocation* bits() { return getOperand(0); }
input()8875   const LAllocation* input() { return getOperand(1); }
8876 };
8877 
8878 class LBigIntAsIntN64 : public LInstructionHelper<1, 1, 1 + INT64_PIECES> {
8879  public:
LIR_HEADER(BigIntAsIntN64)8880   LIR_HEADER(BigIntAsIntN64)
8881 
8882   LBigIntAsIntN64(const LAllocation& input, const LDefinition& temp,
8883                   const LInt64Definition& temp64)
8884       : LInstructionHelper(classOpcode) {
8885     setOperand(0, input);
8886     setTemp(0, temp);
8887     setInt64Temp(1, temp64);
8888   }
8889 
input()8890   const LAllocation* input() { return getOperand(0); }
temp()8891   const LDefinition* temp() { return getTemp(0); }
temp64()8892   LInt64Definition temp64() { return getInt64Temp(1); }
8893 };
8894 
8895 class LBigIntAsIntN32 : public LInstructionHelper<1, 1, 1 + INT64_PIECES> {
8896  public:
LIR_HEADER(BigIntAsIntN32)8897   LIR_HEADER(BigIntAsIntN32)
8898 
8899   LBigIntAsIntN32(const LAllocation& input, const LDefinition& temp,
8900                   const LInt64Definition& temp64)
8901       : LInstructionHelper(classOpcode) {
8902     setOperand(0, input);
8903     setTemp(0, temp);
8904     setInt64Temp(1, temp64);
8905   }
8906 
input()8907   const LAllocation* input() { return getOperand(0); }
temp()8908   const LDefinition* temp() { return getTemp(0); }
temp64()8909   LInt64Definition temp64() { return getInt64Temp(1); }
8910 };
8911 
8912 class LBigIntAsUintN : public LCallInstructionHelper<1, 2, 0> {
8913  public:
LIR_HEADER(BigIntAsUintN)8914   LIR_HEADER(BigIntAsUintN)
8915 
8916   LBigIntAsUintN(const LAllocation& bits, const LAllocation& input)
8917       : LCallInstructionHelper(classOpcode) {
8918     setOperand(0, bits);
8919     setOperand(1, input);
8920   }
8921 
bits()8922   const LAllocation* bits() { return getOperand(0); }
input()8923   const LAllocation* input() { return getOperand(1); }
8924 };
8925 
8926 class LBigIntAsUintN64 : public LInstructionHelper<1, 1, 1 + INT64_PIECES> {
8927  public:
LIR_HEADER(BigIntAsUintN64)8928   LIR_HEADER(BigIntAsUintN64)
8929 
8930   LBigIntAsUintN64(const LAllocation& input, const LDefinition& temp,
8931                    const LInt64Definition& temp64)
8932       : LInstructionHelper(classOpcode) {
8933     setOperand(0, input);
8934     setTemp(0, temp);
8935     setInt64Temp(1, temp64);
8936   }
8937 
input()8938   const LAllocation* input() { return getOperand(0); }
temp()8939   const LDefinition* temp() { return getTemp(0); }
temp64()8940   LInt64Definition temp64() { return getInt64Temp(1); }
8941 };
8942 
8943 class LBigIntAsUintN32 : public LInstructionHelper<1, 1, 1 + INT64_PIECES> {
8944  public:
LIR_HEADER(BigIntAsUintN32)8945   LIR_HEADER(BigIntAsUintN32)
8946 
8947   LBigIntAsUintN32(const LAllocation& input, const LDefinition& temp,
8948                    const LInt64Definition& temp64)
8949       : LInstructionHelper(classOpcode) {
8950     setOperand(0, input);
8951     setTemp(0, temp);
8952     setInt64Temp(1, temp64);
8953   }
8954 
input()8955   const LAllocation* input() { return getOperand(0); }
temp()8956   const LDefinition* temp() { return getTemp(0); }
temp64()8957   LInt64Definition temp64() { return getInt64Temp(1); }
8958 };
8959 
8960 template <size_t NumDefs>
8961 class LIonToWasmCallBase : public LVariadicInstruction<NumDefs, 2> {
8962   using Base = LVariadicInstruction<NumDefs, 2>;
8963 
8964  public:
LIonToWasmCallBase(LNode::Opcode classOpcode,uint32_t numOperands,const LDefinition & temp,const LDefinition & fp)8965   explicit LIonToWasmCallBase(LNode::Opcode classOpcode, uint32_t numOperands,
8966                               const LDefinition& temp, const LDefinition& fp)
8967       : Base(classOpcode, numOperands) {
8968     this->setIsCall();
8969     this->setTemp(0, temp);
8970     this->setTemp(1, fp);
8971   }
mir()8972   MIonToWasmCall* mir() const { return this->mir_->toIonToWasmCall(); }
temp()8973   const LDefinition* temp() { return this->getTemp(0); }
8974 };
8975 
8976 class LIonToWasmCall : public LIonToWasmCallBase<1> {
8977  public:
8978   LIR_HEADER(IonToWasmCall);
LIonToWasmCall(uint32_t numOperands,const LDefinition & temp,const LDefinition & fp)8979   LIonToWasmCall(uint32_t numOperands, const LDefinition& temp,
8980                  const LDefinition& fp)
8981       : LIonToWasmCallBase<1>(classOpcode, numOperands, temp, fp) {}
8982 };
8983 
8984 class LIonToWasmCallV : public LIonToWasmCallBase<BOX_PIECES> {
8985  public:
8986   LIR_HEADER(IonToWasmCallV);
LIonToWasmCallV(uint32_t numOperands,const LDefinition & temp,const LDefinition & fp)8987   LIonToWasmCallV(uint32_t numOperands, const LDefinition& temp,
8988                   const LDefinition& fp)
8989       : LIonToWasmCallBase<BOX_PIECES>(classOpcode, numOperands, temp, fp) {}
8990 };
8991 
8992 class LIonToWasmCallI64 : public LIonToWasmCallBase<INT64_PIECES> {
8993  public:
8994   LIR_HEADER(IonToWasmCallI64);
LIonToWasmCallI64(uint32_t numOperands,const LDefinition & temp,const LDefinition & fp)8995   LIonToWasmCallI64(uint32_t numOperands, const LDefinition& temp,
8996                     const LDefinition& fp)
8997       : LIonToWasmCallBase<INT64_PIECES>(classOpcode, numOperands, temp, fp) {}
8998 };
8999 
9000 class LWasmBoxValue : public LInstructionHelper<1, BOX_PIECES, 0> {
9001  public:
LIR_HEADER(WasmBoxValue)9002   LIR_HEADER(WasmBoxValue)
9003 
9004   explicit LWasmBoxValue(const LBoxAllocation& input)
9005       : LInstructionHelper(classOpcode) {
9006     setBoxOperand(Input, input);
9007   }
9008 
9009   static const size_t Input = 0;
9010 };
9011 
9012 class LWasmAnyRefFromJSObject : public LInstructionHelper<1, 1, 0> {
9013  public:
LIR_HEADER(WasmAnyRefFromJSObject)9014   LIR_HEADER(WasmAnyRefFromJSObject)
9015 
9016   explicit LWasmAnyRefFromJSObject(const LAllocation& input)
9017       : LInstructionHelper(classOpcode) {
9018     setOperand(Input, input);
9019   }
9020 
9021   static const size_t Input = 0;
9022 };
9023 
9024 // Wasm SIMD.
9025 
9026 // Constant Simd128
9027 class LSimd128 : public LInstructionHelper<1, 0, 0> {
9028   SimdConstant v_;
9029 
9030  public:
9031   LIR_HEADER(Simd128);
9032 
LSimd128(SimdConstant v)9033   explicit LSimd128(SimdConstant v) : LInstructionHelper(classOpcode), v_(v) {}
9034 
getSimd128()9035   const SimdConstant& getSimd128() const { return v_; }
9036 };
9037 
9038 // (v128, v128, v128) -> v128 effect-free operation.
9039 // temp is FPR (and always in use).
9040 class LWasmBitselectSimd128 : public LInstructionHelper<1, 3, 1> {
9041  public:
9042   LIR_HEADER(WasmBitselectSimd128)
9043 
9044   static constexpr uint32_t Lhs = 0;
9045   static constexpr uint32_t LhsDest = 0;
9046   static constexpr uint32_t Rhs = 1;
9047   static constexpr uint32_t Control = 2;
9048 
LWasmBitselectSimd128(const LAllocation & lhs,const LAllocation & rhs,const LAllocation & control,const LDefinition & temp)9049   LWasmBitselectSimd128(const LAllocation& lhs, const LAllocation& rhs,
9050                         const LAllocation& control, const LDefinition& temp)
9051       : LInstructionHelper(classOpcode) {
9052     setOperand(Lhs, lhs);
9053     setOperand(Rhs, rhs);
9054     setOperand(Control, control);
9055     setTemp(0, temp);
9056   }
9057 
lhs()9058   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9059   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9060   const LAllocation* rhs() { return getOperand(Rhs); }
control()9061   const LAllocation* control() { return getOperand(Control); }
temp()9062   const LDefinition* temp() { return getTemp(0); }
9063 };
9064 
9065 // (v128, v128) -> v128 effect-free operations
9066 // lhs and dest are the same.
9067 // temps (if in use) are FPR.
9068 // The op may differ from the MIR node's op.
9069 class LWasmBinarySimd128 : public LInstructionHelper<1, 2, 2> {
9070   wasm::SimdOp op_;
9071 
9072  public:
9073   LIR_HEADER(WasmBinarySimd128)
9074 
9075   static constexpr uint32_t Lhs = 0;
9076   static constexpr uint32_t LhsDest = 0;
9077   static constexpr uint32_t Rhs = 1;
9078 
LWasmBinarySimd128(wasm::SimdOp op,const LAllocation & lhs,const LAllocation & rhs,const LDefinition & temp0,const LDefinition & temp1)9079   LWasmBinarySimd128(wasm::SimdOp op, const LAllocation& lhs,
9080                      const LAllocation& rhs, const LDefinition& temp0,
9081                      const LDefinition& temp1)
9082       : LInstructionHelper(classOpcode), op_(op) {
9083     setOperand(Lhs, lhs);
9084     setOperand(Rhs, rhs);
9085     setTemp(0, temp0);
9086     setTemp(1, temp1);
9087   }
9088 
lhs()9089   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9090   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9091   const LAllocation* rhs() { return getOperand(Rhs); }
simdOp()9092   wasm::SimdOp simdOp() const { return op_; }
9093 
9094   static bool SpecializeForConstantRhs(wasm::SimdOp op);
9095 };
9096 
9097 class LWasmBinarySimd128WithConstant : public LInstructionHelper<1, 1, 0> {
9098   SimdConstant rhs_;
9099 
9100  public:
9101   LIR_HEADER(WasmBinarySimd128WithConstant)
9102 
9103   static constexpr uint32_t Lhs = 0;
9104   static constexpr uint32_t LhsDest = 0;
9105 
LWasmBinarySimd128WithConstant(const LAllocation & lhs,const SimdConstant & rhs)9106   LWasmBinarySimd128WithConstant(const LAllocation& lhs,
9107                                  const SimdConstant& rhs)
9108       : LInstructionHelper(classOpcode), rhs_(rhs) {
9109     setOperand(Lhs, lhs);
9110   }
9111 
lhs()9112   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9113   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9114   const SimdConstant& rhs() { return rhs_; }
simdOp()9115   wasm::SimdOp simdOp() const {
9116     return mir_->toWasmBinarySimd128WithConstant()->simdOp();
9117   }
9118 };
9119 
9120 // (v128, i32) -> v128 effect-free variable-width shift operations
9121 // lhs and dest are the same.
9122 // temp0 is a GPR (if in use).
9123 // temp1 is an FPR (if in use).
9124 class LWasmVariableShiftSimd128 : public LInstructionHelper<1, 2, 2> {
9125  public:
9126   LIR_HEADER(WasmVariableShiftSimd128)
9127 
9128   static constexpr uint32_t Lhs = 0;
9129   static constexpr uint32_t LhsDest = 0;
9130   static constexpr uint32_t Rhs = 1;
9131 
LWasmVariableShiftSimd128(const LAllocation & lhs,const LAllocation & rhs,const LDefinition & temp0,const LDefinition & temp1)9132   LWasmVariableShiftSimd128(const LAllocation& lhs, const LAllocation& rhs,
9133                             const LDefinition& temp0, const LDefinition& temp1)
9134       : LInstructionHelper(classOpcode) {
9135     setOperand(Lhs, lhs);
9136     setOperand(Rhs, rhs);
9137     setTemp(0, temp0);
9138     setTemp(1, temp1);
9139   }
9140 
lhs()9141   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9142   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9143   const LAllocation* rhs() { return getOperand(Rhs); }
simdOp()9144   wasm::SimdOp simdOp() const { return mir_->toWasmShiftSimd128()->simdOp(); }
9145 };
9146 
9147 // (v128, i32) -> v128 effect-free constant-width shift operations
9148 class LWasmConstantShiftSimd128 : public LInstructionHelper<1, 1, 0> {
9149   int32_t shift_;
9150 
9151  public:
9152   LIR_HEADER(WasmConstantShiftSimd128)
9153 
9154   static constexpr uint32_t Src = 0;
9155 
LWasmConstantShiftSimd128(const LAllocation & src,int32_t shift)9156   LWasmConstantShiftSimd128(const LAllocation& src, int32_t shift)
9157       : LInstructionHelper(classOpcode), shift_(shift) {
9158     setOperand(Src, src);
9159   }
9160 
src()9161   const LAllocation* src() { return getOperand(Src); }
shift()9162   int32_t shift() { return shift_; }
simdOp()9163   wasm::SimdOp simdOp() const { return mir_->toWasmShiftSimd128()->simdOp(); }
9164 };
9165 
9166 // (v128) -> v128 sign replication operation.
9167 class LWasmSignReplicationSimd128 : public LInstructionHelper<1, 1, 0> {
9168  public:
9169   LIR_HEADER(WasmSignReplicationSimd128)
9170 
9171   static constexpr uint32_t Src = 0;
9172 
LWasmSignReplicationSimd128(const LAllocation & src)9173   explicit LWasmSignReplicationSimd128(const LAllocation& src)
9174       : LInstructionHelper(classOpcode) {
9175     setOperand(Src, src);
9176   }
9177 
src()9178   const LAllocation* src() { return getOperand(Src); }
simdOp()9179   wasm::SimdOp simdOp() const { return mir_->toWasmShiftSimd128()->simdOp(); }
9180 };
9181 
9182 // (v128, v128, imm_simd) -> v128 effect-free operation.
9183 // temp is FPR (and always in use).
9184 class LWasmShuffleSimd128 : public LInstructionHelper<1, 2, 1> {
9185  public:
9186   // Shuffle operations.  NOTE: these may still be x86-centric, but the set can
9187   // accomodate operations from other architectures.
9188   enum Op {
9189     // Blend bytes.  control_ has the blend mask as an I8x16: 0 to select from
9190     // the lhs, -1 to select from the rhs.
9191     BLEND_8x16,
9192 
9193     // Blend words.  control_ has the blend mask as an I16x8: 0 to select from
9194     // the lhs, -1 to select from the rhs.
9195     BLEND_16x8,
9196 
9197     // Concat the lhs in front of the rhs and shift right by bytes, extracting
9198     // the low 16 bytes; control_[0] has the shift count.
9199     CONCAT_RIGHT_SHIFT_8x16,
9200 
9201     // Interleave qwords/dwords/words/bytes from high/low halves of operands.
9202     // The low-order item in the result comes from the lhs, then the next from
9203     // the rhs, and so on.  control_ is ignored.
9204     INTERLEAVE_HIGH_8x16,
9205     INTERLEAVE_HIGH_16x8,
9206     INTERLEAVE_HIGH_32x4,
9207     INTERLEAVE_HIGH_64x2,
9208     INTERLEAVE_LOW_8x16,
9209     INTERLEAVE_LOW_16x8,
9210     INTERLEAVE_LOW_32x4,
9211     INTERLEAVE_LOW_64x2,
9212 
9213     // Fully general shuffle+blend.  control_ has the shuffle mask.
9214     SHUFFLE_BLEND_8x16,
9215   };
9216 
9217  private:
9218   Op op_;
9219   SimdConstant control_;
9220 
9221  public:
9222   LIR_HEADER(WasmShuffleSimd128)
9223 
9224   static constexpr uint32_t Lhs = 0;
9225   static constexpr uint32_t LhsDest = 0;
9226   static constexpr uint32_t Rhs = 1;
9227 
LWasmShuffleSimd128(const LAllocation & lhs,const LAllocation & rhs,const LDefinition & temp,Op op,SimdConstant control)9228   LWasmShuffleSimd128(const LAllocation& lhs, const LAllocation& rhs,
9229                       const LDefinition& temp, Op op, SimdConstant control)
9230       : LInstructionHelper(classOpcode), op_(op), control_(control) {
9231     setOperand(Lhs, lhs);
9232     setOperand(Rhs, rhs);
9233     setTemp(0, temp);
9234   }
9235 
lhs()9236   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9237   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9238   const LAllocation* rhs() { return getOperand(Rhs); }
temp()9239   const LDefinition* temp() { return getTemp(0); }
op()9240   Op op() { return op_; }
control()9241   SimdConstant control() { return control_; }
9242 };
9243 
9244 // (v128, imm_simd) -> v128 effect-free operation.
9245 class LWasmPermuteSimd128 : public LInstructionHelper<1, 1, 0> {
9246  public:
9247   // Permutation operations.  NOTE: these may still be x86-centric, but the set
9248   // can accomodate operations from other architectures.
9249   //
9250   // The "low-order" byte is in lane 0 of an 8x16 datum, the "high-order" byte
9251   // in lane 15.  The low-order byte is also the "rightmost".  In wasm, the
9252   // constant (v128.const i8x16 0 1 2 ... 15) has 0 in the low-order byte and 15
9253   // in the high-order byte.
9254   enum Op {
9255     // A single byte lane is copied into all the other byte lanes.  control_[0]
9256     // has the source lane.
9257     BROADCAST_8x16,
9258 
9259     // A single word lane is copied into all the other word lanes.  control_[0]
9260     // has the source lane.
9261     BROADCAST_16x8,
9262 
9263     // Copy input to output.
9264     MOVE,
9265 
9266     // control_ has bytes in range 0..15 s.t. control_[i] holds the source lane
9267     // for output lane i.
9268     PERMUTE_8x16,
9269 
9270     // control_ has int16s in range 0..7, as for 8x16.  In addition, the high
9271     // byte of control_[0] has flags detailing the operation, values taken
9272     // from the Perm16x8Action enum below.
9273     PERMUTE_16x8,
9274 
9275     // control_ has int32s in range 0..3, as for 8x16.
9276     PERMUTE_32x4,
9277 
9278     // control_[0] has the number of places to rotate by.
9279     ROTATE_RIGHT_8x16,
9280 
9281     // Zeroes are shifted into high-order bytes and low-order bytes are lost.
9282     // control_[0] has the number of places to shift by.
9283     SHIFT_RIGHT_8x16,
9284 
9285     // Zeroes are shifted into low-order bytes and high-order bytes are lost.
9286     // control_[0] has the number of places to shift by.
9287     SHIFT_LEFT_8x16,
9288   };
9289 
9290  private:
9291   Op op_;
9292   SimdConstant control_;
9293 
9294  public:
9295   LIR_HEADER(WasmPermuteSimd128)
9296 
9297   static constexpr uint32_t Src = 0;
9298 
LWasmPermuteSimd128(const LAllocation & src,Op op,SimdConstant control)9299   LWasmPermuteSimd128(const LAllocation& src, Op op, SimdConstant control)
9300       : LInstructionHelper(classOpcode), op_(op), control_(control) {
9301     setOperand(Src, src);
9302   }
9303 
src()9304   const LAllocation* src() { return getOperand(Src); }
op()9305   Op op() { return op_; }
control()9306   SimdConstant control() { return control_; }
9307 };
9308 
9309 class LWasmReplaceLaneSimd128 : public LInstructionHelper<1, 2, 0> {
9310  public:
9311   LIR_HEADER(WasmReplaceLaneSimd128)
9312 
9313   static constexpr uint32_t Lhs = 0;
9314   static constexpr uint32_t LhsDest = 0;
9315   static constexpr uint32_t Rhs = 1;
9316 
LWasmReplaceLaneSimd128(const LAllocation & lhs,const LAllocation & rhs)9317   LWasmReplaceLaneSimd128(const LAllocation& lhs, const LAllocation& rhs)
9318       : LInstructionHelper(classOpcode) {
9319     setOperand(Lhs, lhs);
9320     setOperand(Rhs, rhs);
9321   }
9322 
lhs()9323   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9324   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9325   const LAllocation* rhs() { return getOperand(Rhs); }
laneIndex()9326   uint32_t laneIndex() const {
9327     return mir_->toWasmReplaceLaneSimd128()->laneIndex();
9328   }
simdOp()9329   wasm::SimdOp simdOp() const {
9330     return mir_->toWasmReplaceLaneSimd128()->simdOp();
9331   }
9332 };
9333 
9334 class LWasmReplaceInt64LaneSimd128
9335     : public LInstructionHelper<1, INT64_PIECES + 1, 0> {
9336  public:
9337   LIR_HEADER(WasmReplaceInt64LaneSimd128)
9338 
9339   static constexpr uint32_t Lhs = 0;
9340   static constexpr uint32_t LhsDest = 0;
9341   static constexpr uint32_t Rhs = 1;
9342 
LWasmReplaceInt64LaneSimd128(const LAllocation & lhs,const LInt64Allocation & rhs)9343   LWasmReplaceInt64LaneSimd128(const LAllocation& lhs,
9344                                const LInt64Allocation& rhs)
9345       : LInstructionHelper(classOpcode) {
9346     setOperand(Lhs, lhs);
9347     setInt64Operand(Rhs, rhs);
9348   }
9349 
lhs()9350   const LAllocation* lhs() { return getOperand(Lhs); }
lhsDest()9351   const LAllocation* lhsDest() { return getOperand(LhsDest); }
rhs()9352   const LInt64Allocation rhs() { return getInt64Operand(Rhs); }
laneIndex()9353   uint32_t laneIndex() const {
9354     return mir_->toWasmReplaceLaneSimd128()->laneIndex();
9355   }
simdOp()9356   wasm::SimdOp simdOp() const {
9357     return mir_->toWasmReplaceLaneSimd128()->simdOp();
9358   }
9359 };
9360 
9361 // (scalar) -> v128 effect-free operations, scalar != int64
9362 class LWasmScalarToSimd128 : public LInstructionHelper<1, 1, 0> {
9363  public:
9364   LIR_HEADER(WasmScalarToSimd128)
9365 
9366   static constexpr uint32_t Src = 0;
9367 
LWasmScalarToSimd128(const LAllocation & src)9368   explicit LWasmScalarToSimd128(const LAllocation& src)
9369       : LInstructionHelper(classOpcode) {
9370     setOperand(Src, src);
9371   }
9372 
src()9373   const LAllocation* src() { return getOperand(Src); }
simdOp()9374   wasm::SimdOp simdOp() const {
9375     return mir_->toWasmScalarToSimd128()->simdOp();
9376   }
9377 };
9378 
9379 // (int64) -> v128 effect-free operations
9380 class LWasmInt64ToSimd128 : public LInstructionHelper<1, INT64_PIECES, 0> {
9381  public:
9382   LIR_HEADER(WasmInt64ToSimd128)
9383 
9384   static constexpr uint32_t Src = 0;
9385 
LWasmInt64ToSimd128(const LInt64Allocation & src)9386   explicit LWasmInt64ToSimd128(const LInt64Allocation& src)
9387       : LInstructionHelper(classOpcode) {
9388     setInt64Operand(Src, src);
9389   }
9390 
src()9391   const LInt64Allocation src() { return getInt64Operand(Src); }
simdOp()9392   wasm::SimdOp simdOp() const {
9393     return mir_->toWasmScalarToSimd128()->simdOp();
9394   }
9395 };
9396 
9397 // (v128) -> v128 effect-free operations
9398 // temp is FPR (if in use).
9399 class LWasmUnarySimd128 : public LInstructionHelper<1, 1, 1> {
9400  public:
9401   LIR_HEADER(WasmUnarySimd128)
9402 
9403   static constexpr uint32_t Src = 0;
9404 
LWasmUnarySimd128(const LAllocation & src,const LDefinition & temp)9405   LWasmUnarySimd128(const LAllocation& src, const LDefinition& temp)
9406       : LInstructionHelper(classOpcode) {
9407     setOperand(Src, src);
9408     setTemp(0, temp);
9409   }
9410 
src()9411   const LAllocation* src() { return getOperand(Src); }
temp()9412   const LDefinition* temp() { return getTemp(0); }
simdOp()9413   wasm::SimdOp simdOp() const { return mir_->toWasmUnarySimd128()->simdOp(); }
9414 };
9415 
9416 // (v128, imm) -> scalar effect-free operations.
9417 // temp is FPR (if in use).
9418 class LWasmReduceSimd128 : public LInstructionHelper<1, 1, 1> {
9419  public:
9420   LIR_HEADER(WasmReduceSimd128)
9421 
9422   static constexpr uint32_t Src = 0;
9423 
LWasmReduceSimd128(const LAllocation & src,const LDefinition & temp)9424   explicit LWasmReduceSimd128(const LAllocation& src, const LDefinition& temp)
9425       : LInstructionHelper(classOpcode) {
9426     setOperand(Src, src);
9427     setTemp(0, temp);
9428   }
9429 
src()9430   const LAllocation* src() { return getOperand(Src); }
imm()9431   uint32_t imm() const { return mir_->toWasmReduceSimd128()->imm(); }
simdOp()9432   wasm::SimdOp simdOp() const { return mir_->toWasmReduceSimd128()->simdOp(); }
9433 };
9434 
9435 // (v128, onTrue, onFalse) test-and-branch operations.
9436 class LWasmReduceAndBranchSimd128 : public LControlInstructionHelper<2, 1, 0> {
9437   wasm::SimdOp op_;
9438 
9439  public:
9440   LIR_HEADER(WasmReduceAndBranchSimd128)
9441 
9442   static constexpr uint32_t Src = 0;
9443   static constexpr uint32_t IfTrue = 0;
9444   static constexpr uint32_t IfFalse = 1;
9445 
LWasmReduceAndBranchSimd128(const LAllocation & src,wasm::SimdOp op,MBasicBlock * ifTrue,MBasicBlock * ifFalse)9446   LWasmReduceAndBranchSimd128(const LAllocation& src, wasm::SimdOp op,
9447                               MBasicBlock* ifTrue, MBasicBlock* ifFalse)
9448       : LControlInstructionHelper(classOpcode), op_(op) {
9449     setOperand(Src, src);
9450     setSuccessor(IfTrue, ifTrue);
9451     setSuccessor(IfFalse, ifFalse);
9452   }
9453 
src()9454   const LAllocation* src() { return getOperand(Src); }
simdOp()9455   wasm::SimdOp simdOp() const { return op_; }
ifTrue()9456   MBasicBlock* ifTrue() const { return getSuccessor(IfTrue); }
ifFalse()9457   MBasicBlock* ifFalse() const { return getSuccessor(IfFalse); }
9458 };
9459 
9460 // (v128, imm) -> i64 effect-free operations
9461 class LWasmReduceSimd128ToInt64
9462     : public LInstructionHelper<INT64_PIECES, 1, 0> {
9463  public:
9464   LIR_HEADER(WasmReduceSimd128ToInt64)
9465 
9466   static constexpr uint32_t Src = 0;
9467 
LWasmReduceSimd128ToInt64(const LAllocation & src)9468   explicit LWasmReduceSimd128ToInt64(const LAllocation& src)
9469       : LInstructionHelper(classOpcode) {
9470     setOperand(Src, src);
9471   }
9472 
src()9473   const LAllocation* src() { return getOperand(Src); }
imm()9474   uint32_t imm() const { return mir_->toWasmReduceSimd128()->imm(); }
simdOp()9475   wasm::SimdOp simdOp() const { return mir_->toWasmReduceSimd128()->simdOp(); }
9476 };
9477 
9478 class LWasmLoadLaneSimd128 : public LInstructionHelper<1, 3, 1> {
9479  public:
9480   LIR_HEADER(WasmLoadLaneSimd128);
9481 
9482   static constexpr uint32_t Src = 2;
9483 
9484   explicit LWasmLoadLaneSimd128(const LAllocation& ptr, const LAllocation& src,
9485                                 const LDefinition& temp,
9486                                 const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)9487       : LInstructionHelper(classOpcode) {
9488     setOperand(0, ptr);
9489     setOperand(1, memoryBase);
9490     setOperand(Src, src);
9491     setTemp(0, temp);
9492   }
9493 
ptr()9494   const LAllocation* ptr() { return getOperand(0); }
memoryBase()9495   const LAllocation* memoryBase() { return getOperand(1); }
src()9496   const LAllocation* src() { return getOperand(Src); }
temp()9497   const LDefinition* temp() { return getTemp(0); }
mir()9498   MWasmLoadLaneSimd128* mir() const { return mir_->toWasmLoadLaneSimd128(); }
laneSize()9499   uint32_t laneSize() const {
9500     return mir_->toWasmLoadLaneSimd128()->laneSize();
9501   }
laneIndex()9502   uint32_t laneIndex() const {
9503     return mir_->toWasmLoadLaneSimd128()->laneIndex();
9504   }
9505 };
9506 
9507 class LWasmStoreLaneSimd128 : public LInstructionHelper<1, 3, 1> {
9508  public:
9509   LIR_HEADER(WasmStoreLaneSimd128);
9510 
9511   static constexpr uint32_t Src = 2;
9512 
9513   explicit LWasmStoreLaneSimd128(const LAllocation& ptr, const LAllocation& src,
9514                                  const LDefinition& temp,
9515                                  const LAllocation& memoryBase = LAllocation())
LInstructionHelper(classOpcode)9516       : LInstructionHelper(classOpcode) {
9517     setOperand(0, ptr);
9518     setOperand(1, memoryBase);
9519     setOperand(Src, src);
9520     setTemp(0, temp);
9521   }
9522 
ptr()9523   const LAllocation* ptr() { return getOperand(0); }
memoryBase()9524   const LAllocation* memoryBase() { return getOperand(1); }
src()9525   const LAllocation* src() { return getOperand(Src); }
temp()9526   const LDefinition* temp() { return getTemp(0); }
mir()9527   MWasmStoreLaneSimd128* mir() const { return mir_->toWasmStoreLaneSimd128(); }
laneSize()9528   uint32_t laneSize() const {
9529     return mir_->toWasmStoreLaneSimd128()->laneSize();
9530   }
laneIndex()9531   uint32_t laneIndex() const {
9532     return mir_->toWasmStoreLaneSimd128()->laneIndex();
9533   }
9534 };
9535 
9536 // End Wasm SIMD
9537 
9538 }  // namespace jit
9539 }  // namespace js
9540 
9541 #endif /* jit_shared_LIR_shared_h */
9542