LCOV - code coverage report
Current view: top level - js/src/jit/shared - LIR-shared.h (source / functions) Hit Total Coverage
Test: output.info Lines: 788 4043 19.5 %
Date: 2017-07-14 16:53:18 Functions: 450 2265 19.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13