js/src/jit/LIR-Common.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     7 #ifndef jit_LIR_Common_h
     8 #define jit_LIR_Common_h
    10 #include "jit/shared/Assembler-shared.h"
    12 // This file declares LIR instructions that are common to every platform.
    14 namespace js {
    15 namespace jit {
    17 class Range;
    19 template <size_t Temps, size_t ExtraUses = 0>
    20 class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps>
    21 {
    22   public:
    23     const LAllocation *lhs() {
    24         return this->getOperand(0);
    25     }
    26     const LAllocation *rhs() {
    27         return this->getOperand(1);
    28     }
    29 };
    31 // Simplifies register allocation since the first instruction of a block is
    32 // guaranteed to have no uses.
    33 class LLabel : public LInstructionHelper<0, 0, 0>
    34 {
    35   public:
    36     LIR_HEADER(Label)
    37 };
    39 class LNop : public LInstructionHelper<0, 0, 0>
    40 {
    41   public:
    42     LIR_HEADER(Nop)
    43 };
    45 // An LOsiPoint captures a snapshot after a call and ensures enough space to
    46 // patch in a call to the invalidation mechanism.
    47 //
    48 // Note: LSafepoints are 1:1 with LOsiPoints, so it holds a reference to the
    49 // corresponding LSafepoint to inform it of the LOsiPoint's masm offset when it
    50 // gets CG'd.
    51 class LOsiPoint : public LInstructionHelper<0, 0, 0>
    52 {
    53     LSafepoint *safepoint_;
    55   public:
    56     LOsiPoint(LSafepoint *safepoint, LSnapshot *snapshot)
    57       : safepoint_(safepoint)
    58     {
    59         JS_ASSERT(safepoint && snapshot);
    60         assignSnapshot(snapshot);
    61     }
    63     LSafepoint *associatedSafepoint() {
    64         return safepoint_;
    65     }
    67     LIR_HEADER(OsiPoint)
    68 };
    70 class LMove
    71 {
    72     LAllocation *from_;
    73     LAllocation *to_;
    74     LDefinition::Type type_;
    76   public:
    77     LMove(LAllocation *from, LAllocation *to, LDefinition::Type type)
    78       : from_(from),
    79         to_(to),
    80         type_(type)
    81     { }
    83     LAllocation *from() {
    84         return from_;
    85     }
    86     const LAllocation *from() const {
    87         return from_;
    88     }
    89     LAllocation *to() {
    90         return to_;
    91     }
    92     const LAllocation *to() const {
    93         return to_;
    94     }
    95     LDefinition::Type type() const {
    96         return type_;
    97     }
    98 };
   100 class LMoveGroup : public LInstructionHelper<0, 0, 0>
   101 {
   102     js::Vector<LMove, 2, IonAllocPolicy> moves_;
   104     LMoveGroup(TempAllocator &alloc)
   105       : moves_(alloc)
   106     { }
   108   public:
   109     LIR_HEADER(MoveGroup)
   111     static LMoveGroup *New(TempAllocator &alloc) {
   112         return new(alloc) LMoveGroup(alloc);
   113     }
   115     void printOperands(FILE *fp);
   117     // Add a move which takes place simultaneously with all others in the group.
   118     bool add(LAllocation *from, LAllocation *to, LDefinition::Type type);
   120     // Add a move which takes place after existing moves in the group.
   121     bool addAfter(LAllocation *from, LAllocation *to, LDefinition::Type type);
   123     size_t numMoves() const {
   124         return moves_.length();
   125     }
   126     const LMove &getMove(size_t i) const {
   127         return moves_[i];
   128     }
   129 };
   131 // Constant 32-bit integer.
   132 class LInteger : public LInstructionHelper<1, 0, 0>
   133 {
   134     int32_t i32_;
   136   public:
   137     LIR_HEADER(Integer)
   139     LInteger(int32_t i32)
   140       : i32_(i32)
   141     { }
   143     int32_t getValue() const {
   144         return i32_;
   145     }
   146 };
   148 // Constant pointer.
   149 class LPointer : public LInstructionHelper<1, 0, 0>
   150 {
   151   public:
   152     enum Kind {
   153         GC_THING,
   154         NON_GC_THING
   155     };
   157   private:
   158     void *ptr_;
   159     Kind kind_;
   161   public:
   162     LIR_HEADER(Pointer)
   164     LPointer(gc::Cell *ptr)
   165       : ptr_(ptr), kind_(GC_THING)
   166     { }
   168     LPointer(void *ptr, Kind kind)
   169       : ptr_(ptr), kind_(kind)
   170     { }
   172     void *ptr() const {
   173         return ptr_;
   174     }
   175     Kind kind() const {
   176         return kind_;
   177     }
   178     const char *extraName() const {
   179         return kind_ == GC_THING ? "GC_THING" : "NON_GC_THING";
   180     }
   182     gc::Cell *gcptr() const {
   183         JS_ASSERT(kind() == GC_THING);
   184         return (gc::Cell *) ptr_;
   185     }
   186 };
   188 // Constant double.
   189 class LDouble : public LInstructionHelper<1, 0, 0>
   190 {
   191     double d_;
   192   public:
   193     LIR_HEADER(Double);
   195     LDouble(double d) : d_(d)
   196     { }
   197     double getDouble() const {
   198         return d_;
   199     }
   200 };
   202 // Constant float32.
   203 class LFloat32 : public LInstructionHelper<1, 0, 0>
   204 {
   205     float f_;
   206   public:
   207     LIR_HEADER(Float32);
   209     LFloat32(float f)
   210       : f_(f)
   211     { }
   213     float getFloat() const {
   214         return f_;
   215     }
   216 };
   218 // A constant Value.
   219 class LValue : public LInstructionHelper<BOX_PIECES, 0, 0>
   220 {
   221     Value v_;
   223   public:
   224     LIR_HEADER(Value)
   226     LValue(const Value &v)
   227       : v_(v)
   228     { }
   230     Value value() const {
   231         return v_;
   232     }
   233 };
   235 // Clone an object literal such as we are not modifying the object contained in
   236 // the sources.
   237 class LCloneLiteral : public LCallInstructionHelper<1, 1, 0>
   238 {
   239   public:
   240     LIR_HEADER(CloneLiteral)
   242     LCloneLiteral(const LAllocation &obj)
   243     {
   244         setOperand(0, obj);
   245     }
   247     const LAllocation *getObjectLiteral() {
   248         return getOperand(0);
   249     }
   251     MCloneLiteral *mir() const {
   252         return mir_->toCloneLiteral();
   253     }
   254 };
   256 // Formal argument for a function, returning a box. Formal arguments are
   257 // initially read from the stack.
   258 class LParameter : public LInstructionHelper<BOX_PIECES, 0, 0>
   259 {
   260   public:
   261     LIR_HEADER(Parameter)
   262 };
   264 // Stack offset for a word-sized immutable input value to a frame.
   265 class LCallee : public LInstructionHelper<1, 0, 0>
   266 {
   267   public:
   268     LIR_HEADER(Callee)
   269 };
   271 // Base class for control instructions (goto, branch, etc.)
   272 template <size_t Succs, size_t Operands, size_t Temps>
   273 class LControlInstructionHelper : public LInstructionHelper<0, Operands, Temps> {
   275     mozilla::Array<MBasicBlock *, Succs> successors_;
   277   public:
   278     virtual size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; }
   280     virtual MBasicBlock *getSuccessor(size_t i) const MOZ_FINAL MOZ_OVERRIDE {
   281         return successors_[i];
   282     }
   284     virtual void setSuccessor(size_t i, MBasicBlock *successor) MOZ_FINAL MOZ_OVERRIDE {
   285         successors_[i] = successor;
   286     }
   287 };
   289 // Jumps to the start of a basic block.
   290 class LGoto : public LControlInstructionHelper<1, 0, 0>
   291 {
   292   public:
   293     LIR_HEADER(Goto)
   295     LGoto(MBasicBlock *block)
   296     {
   297          setSuccessor(0, block);
   298     }
   300     MBasicBlock *target() const {
   301         return getSuccessor(0);
   302     }
   303 };
   305 class LNewSlots : public LCallInstructionHelper<1, 0, 3>
   306 {
   307   public:
   308     LIR_HEADER(NewSlots)
   310     LNewSlots(const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) {
   311         setTemp(0, temp1);
   312         setTemp(1, temp2);
   313         setTemp(2, temp3);
   314     }
   316     const LDefinition *temp1() {
   317         return getTemp(0);
   318     }
   319     const LDefinition *temp2() {
   320         return getTemp(1);
   321     }
   322     const LDefinition *temp3() {
   323         return getTemp(2);
   324     }
   326     MNewSlots *mir() const {
   327         return mir_->toNewSlots();
   328     }
   329 };
   331 class LNewArray : public LInstructionHelper<1, 0, 1>
   332 {
   333   public:
   334     LIR_HEADER(NewArray)
   336     LNewArray(const LDefinition &temp) {
   337         setTemp(0, temp);
   338     }
   340     const char *extraName() const {
   341         return mir()->shouldUseVM() ? "VMCall" : nullptr;
   342     }
   344     const LDefinition *temp() {
   345         return getTemp(0);
   346     }
   348     MNewArray *mir() const {
   349         return mir_->toNewArray();
   350     }
   351 };
   353 class LNewObject : public LInstructionHelper<1, 0, 1>
   354 {
   355   public:
   356     LIR_HEADER(NewObject)
   358     LNewObject(const LDefinition &temp) {
   359         setTemp(0, temp);
   360     }
   362     const char *extraName() const {
   363         return mir()->shouldUseVM() ? "VMCall" : nullptr;
   364     }
   366     const LDefinition *temp() {
   367         return getTemp(0);
   368     }
   370     MNewObject *mir() const {
   371         return mir_->toNewObject();
   372     }
   373 };
   375 class LNewPar : public LInstructionHelper<1, 1, 2>
   376 {
   377   public:
   378     LIR_HEADER(NewPar);
   380     LNewPar(const LAllocation &cx, const LDefinition &temp1, const LDefinition &temp2) {
   381         setOperand(0, cx);
   382         setTemp(0, temp1);
   383         setTemp(1, temp2);
   384     }
   386     MNewPar *mir() const {
   387         return mir_->toNewPar();
   388     }
   390     const LAllocation *forkJoinContext() {
   391         return getOperand(0);
   392     }
   394     const LDefinition *getTemp0() {
   395         return getTemp(0);
   396     }
   398     const LDefinition *getTemp1() {
   399         return getTemp(1);
   400     }
   401 };
   403 class LNewDenseArrayPar : public LCallInstructionHelper<1, 2, 3>
   404 {
   405   public:
   406     LIR_HEADER(NewDenseArrayPar);
   408     LNewDenseArrayPar(const LAllocation &cx, const LAllocation &length,
   409                       const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3)
   410     {
   411         setOperand(0, cx);
   412         setOperand(1, length);
   413         setTemp(0, temp1);
   414         setTemp(1, temp2);
   415         setTemp(2, temp3);
   416     }
   418     MNewDenseArrayPar *mir() const {
   419         return mir_->toNewDenseArrayPar();
   420     }
   422     const LAllocation *forkJoinContext() {
   423         return getOperand(0);
   424     }
   426     const LAllocation *length() {
   427         return getOperand(1);
   428     }
   430     const LDefinition *getTemp0() {
   431         return getTemp(0);
   432     }
   434     const LDefinition *getTemp1() {
   435         return getTemp(1);
   436     }
   438     const LDefinition *getTemp2() {
   439         return getTemp(2);
   440     }
   441 };
   443 // Allocates a new DeclEnvObject.
   444 //
   445 // This instruction generates two possible instruction sets:
   446 //   (1) An inline allocation of the call object is attempted.
   447 //   (2) Otherwise, a callVM create a new object.
   448 //
   449 class LNewDeclEnvObject : public LInstructionHelper<1, 0, 1>
   450 {
   451   public:
   452     LIR_HEADER(NewDeclEnvObject);
   454     LNewDeclEnvObject(const LDefinition &temp) {
   455         setTemp(0, temp);
   456     }
   458     const LDefinition *temp() {
   459         return getTemp(0);
   460     }
   462     MNewDeclEnvObject *mir() const {
   463         return mir_->toNewDeclEnvObject();
   464     }
   465 };
   467 // Allocates a new CallObject. The inputs are:
   468 //      slots: either a reg representing a HeapSlot *, or a placeholder
   469 //             meaning that no slots pointer is needed.
   470 //
   471 // This instruction generates two possible instruction sets:
   472 //   (1) If the call object is extensible, this is a callVM to create the
   473 //       call object.
   474 //   (2) Otherwise, an inline allocation of the call object is attempted.
   475 //
   476 class LNewCallObject : public LInstructionHelper<1, 1, 1>
   477 {
   478   public:
   479     LIR_HEADER(NewCallObject)
   481     LNewCallObject(const LAllocation &slots, const LDefinition &temp) {
   482         setOperand(0, slots);
   483         setTemp(0, temp);
   484     }
   486     const LDefinition *temp() {
   487         return getTemp(0);
   488     }
   490     const LAllocation *slots() {
   491         return getOperand(0);
   492     }
   494     MNewCallObject *mir() const {
   495         return mir_->toNewCallObject();
   496     }
   497 };
   499 // Allocates a new CallObject with singleton type through an out-of-line VM
   500 // call. The inputs are:
   501 //      slots: either a reg representing a HeapSlot *, or a placeholder
   502 //             meaning that no slots pointer is needed.
   503 //
   504 class LNewSingletonCallObject : public LInstructionHelper<1, 1, 0>
   505 {
   506   public:
   507     LIR_HEADER(NewSingletonCallObject)
   509     LNewSingletonCallObject(const LAllocation &slots) {
   510         setOperand(0, slots);
   511     }
   513     const LAllocation *slots() {
   514         return getOperand(0);
   515     }
   517     MNewCallObjectBase * mir() const {
   518         MOZ_ASSERT(mir_->isNewCallObject() || mir_->isNewRunOnceCallObject());
   519         return static_cast<MNewCallObjectBase *>(mir_);
   520     }
   521 };
   523 class LNewCallObjectPar : public LInstructionHelper<1, 2, 2>
   524 {
   525     LNewCallObjectPar(const LAllocation &cx, const LAllocation &slots,
   526                       const LDefinition &temp1, const LDefinition &temp2)
   527     {
   528         setOperand(0, cx);
   529         setOperand(1, slots);
   530         setTemp(0, temp1);
   531         setTemp(1, temp2);
   532     }
   534 public:
   535     LIR_HEADER(NewCallObjectPar);
   537     static LNewCallObjectPar *NewWithSlots(TempAllocator &alloc,
   538                                            const LAllocation &cx, const LAllocation &slots,
   539                                            const LDefinition &temp1, const LDefinition &temp2)
   540     {
   541         return new(alloc) LNewCallObjectPar(cx, slots, temp1, temp2);
   542     }
   544     static LNewCallObjectPar *NewSansSlots(TempAllocator &alloc,
   545                                            const LAllocation &cx,
   546                                            const LDefinition &temp1, const LDefinition &temp2)
   547     {
   548         LAllocation slots = LConstantIndex::Bogus();
   549         return new(alloc) LNewCallObjectPar(cx, slots, temp1, temp2);
   550     }
   552     const LAllocation *forkJoinContext() {
   553         return getOperand(0);
   554     }
   556     const LAllocation *slots() {
   557         return getOperand(1);
   558     }
   560     const bool hasDynamicSlots() {
   561         // TO INVESTIGATE: Felix tried using isRegister() method here,
   562         // but for useFixed(_, CallTempN), isRegister() is false (and
   563         // isUse() is true).  So for now ignore that and try to match
   564         // the LConstantIndex::Bogus() generated above instead.
   565         return slots() && ! slots()->isConstant();
   566     }
   568     const MNewCallObjectPar *mir() const {
   569         return mir_->toNewCallObjectPar();
   570     }
   572     const LDefinition *getTemp0() {
   573         return getTemp(0);
   574     }
   576     const LDefinition *getTemp1() {
   577         return getTemp(1);
   578     }
   579 };
   581 class LNewDerivedTypedObject : public LCallInstructionHelper<1, 3, 0>
   582 {
   583   public:
   584     LIR_HEADER(NewDerivedTypedObject);
   586     LNewDerivedTypedObject(const LAllocation &type,
   587                            const LAllocation &owner,
   588                            const LAllocation &offset) {
   589         setOperand(0, type);
   590         setOperand(1, owner);
   591         setOperand(2, offset);
   592     }
   594     const LAllocation *type() {
   595         return getOperand(0);
   596     }
   598     const LAllocation *owner() {
   599         return getOperand(1);
   600     }
   602     const LAllocation *offset() {
   603         return getOperand(2);
   604     }
   605 };
   607 class LNewStringObject : public LInstructionHelper<1, 1, 1>
   608 {
   609   public:
   610     LIR_HEADER(NewStringObject)
   612     LNewStringObject(const LAllocation &input, const LDefinition &temp) {
   613         setOperand(0, input);
   614         setTemp(0, temp);
   615     }
   617     const LAllocation *input() {
   618         return getOperand(0);
   619     }
   620     const LDefinition *temp() {
   621         return getTemp(0);
   622     }
   623     MNewStringObject *mir() const {
   624         return mir_->toNewStringObject();
   625     }
   626 };
   628 class LAbortPar : public LInstructionHelper<0, 0, 0>
   629 {
   630   public:
   631     LIR_HEADER(AbortPar);
   632 };
   634 class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0>
   635 {
   636   public:
   637     LIR_HEADER(InitElem)
   639     LInitElem(const LAllocation &object) {
   640         setOperand(0, object);
   641     }
   643     static const size_t IdIndex = 1;
   644     static const size_t ValueIndex = 1 + BOX_PIECES;
   646     const LAllocation *getObject() {
   647         return getOperand(0);
   648     }
   649     MInitElem *mir() const {
   650         return mir_->toInitElem();
   651     }
   652 };
   654 class LInitElemGetterSetter : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0>
   655 {
   656   public:
   657     LIR_HEADER(InitElemGetterSetter)
   659     LInitElemGetterSetter(const LAllocation &object, const LAllocation &value) {
   660         setOperand(0, object);
   661         setOperand(1, value);
   662     }
   664     static const size_t IdIndex = 2;
   666     const LAllocation *object() {
   667         return getOperand(0);
   668     }
   669     const LAllocation *value() {
   670         return getOperand(1);
   671     }
   672     MInitElemGetterSetter *mir() const {
   673         return mir_->toInitElemGetterSetter();
   674     }
   675 };
   677 // Takes in an Object and a Value.
   678 class LMutateProto : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
   679 {
   680   public:
   681     LIR_HEADER(MutateProto)
   683     LMutateProto(const LAllocation &object) {
   684         setOperand(0, object);
   685     }
   687     static const size_t ValueIndex = 1;
   689     const LAllocation *getObject() {
   690         return getOperand(0);
   691     }
   692     const LAllocation *getValue() {
   693         return getOperand(1);
   694     }
   695 };
   697 // Takes in an Object and a Value.
   698 class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
   699 {
   700   public:
   701     LIR_HEADER(InitProp)
   703     LInitProp(const LAllocation &object) {
   704         setOperand(0, object);
   705     }
   707     static const size_t ValueIndex = 1;
   709     const LAllocation *getObject() {
   710         return getOperand(0);
   711     }
   712     const LAllocation *getValue() {
   713         return getOperand(1);
   714     }
   716     MInitProp *mir() const {
   717         return mir_->toInitProp();
   718     }
   719 };
   721 class LInitPropGetterSetter : public LCallInstructionHelper<0, 2, 0>
   722 {
   723   public:
   724     LIR_HEADER(InitPropGetterSetter)
   726     LInitPropGetterSetter(const LAllocation &object, const LAllocation &value) {
   727         setOperand(0, object);
   728         setOperand(1, value);
   729     }
   731     const LAllocation *object() {
   732         return getOperand(0);
   733     }
   734     const LAllocation *value() {
   735         return getOperand(1);
   736     }
   738     MInitPropGetterSetter *mir() const {
   739         return mir_->toInitPropGetterSetter();
   740     }
   741 };
   743 class LCheckOverRecursed : public LInstructionHelper<0, 0, 0>
   744 {
   745   public:
   746     LIR_HEADER(CheckOverRecursed)
   748     LCheckOverRecursed()
   749     { }
   750 };
   752 class LCheckOverRecursedPar : public LInstructionHelper<0, 1, 1>
   753 {
   754   public:
   755     LIR_HEADER(CheckOverRecursedPar);
   757     LCheckOverRecursedPar(const LAllocation &cx, const LDefinition &tempReg) {
   758         setOperand(0, cx);
   759         setTemp(0, tempReg);
   760     }
   762     const LAllocation *forkJoinContext() {
   763         return getOperand(0);
   764     }
   766     const LDefinition *getTempReg() {
   767         return getTemp(0);
   768     }
   769 };
   771 // Alternative to LInterruptCheck which does not emit an explicit check of the
   772 // interrupt flag but relies on the loop backedge being patched via a signal
   773 // handler.
   774 class LInterruptCheckImplicit : public LInstructionHelper<0, 0, 0>
   775 {
   776     Label *oolEntry_;
   778   public:
   779     LIR_HEADER(InterruptCheckImplicit)
   781     LInterruptCheckImplicit()
   782       : oolEntry_(nullptr)
   783     {}
   785     Label *oolEntry() {
   786         return oolEntry_;
   787     }
   789     void setOolEntry(Label *oolEntry) {
   790         oolEntry_ = oolEntry;
   791     }
   792 };
   794 class LInterruptCheckPar : public LInstructionHelper<0, 1, 1>
   795 {
   796   public:
   797     LIR_HEADER(InterruptCheckPar);
   799     LInterruptCheckPar(const LAllocation &cx, const LDefinition &tempReg) {
   800         setOperand(0, cx);
   801         setTemp(0, tempReg);
   802     }
   804     const LAllocation *forkJoinContext() {
   805         return getOperand(0);
   806     }
   808     const LDefinition *getTempReg() {
   809         return getTemp(0);
   810     }
   811 };
   813 class LDefVar : public LCallInstructionHelper<0, 1, 0>
   814 {
   815   public:
   816     LIR_HEADER(DefVar)
   818     LDefVar(const LAllocation &scopeChain)
   819     {
   820         setOperand(0, scopeChain);
   821     }
   823     const LAllocation *scopeChain() {
   824         return getOperand(0);
   825     }
   826     MDefVar *mir() const {
   827         return mir_->toDefVar();
   828     }
   829 };
   831 class LDefFun : public LCallInstructionHelper<0, 1, 0>
   832 {
   833   public:
   834     LIR_HEADER(DefFun)
   836     LDefFun(const LAllocation &scopeChain)
   837     {
   838         setOperand(0, scopeChain);
   839     }
   841     const LAllocation *scopeChain() {
   842         return getOperand(0);
   843     }
   844     MDefFun *mir() const {
   845         return mir_->toDefFun();
   846     }
   847 };
   849 class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 1>
   850 {
   851   public:
   852     LIR_HEADER(TypeOfV)
   854     LTypeOfV(const LDefinition &tempToUnbox) {
   855         setTemp(0, tempToUnbox);
   856     }
   858     static const size_t Input = 0;
   860     const LDefinition *tempToUnbox() {
   861         return getTemp(0);
   862     }
   864     MTypeOf *mir() const {
   865         return mir_->toTypeOf();
   866     }
   867 };
   869 class LToIdV : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 1>
   870 {
   871   public:
   872     LIR_HEADER(ToIdV)
   874     LToIdV(const LDefinition &temp)
   875     {
   876         setTemp(0, temp);
   877     }
   879     static const size_t Object = 0;
   880     static const size_t Index = BOX_PIECES;
   882     MToId *mir() const {
   883         return mir_->toToId();
   884     }
   886     const LDefinition *tempFloat() {
   887         return getTemp(0);
   888     }
   889 };
   891 // Allocate an object for |new| on the caller-side,
   892 // when there is no templateObject or prototype known
   893 class LCreateThis : public LCallInstructionHelper<BOX_PIECES, 1, 0>
   894 {
   895   public:
   896     LIR_HEADER(CreateThis)
   898     LCreateThis(const LAllocation &callee)
   899     {
   900         setOperand(0, callee);
   901     }
   903     const LAllocation *getCallee() {
   904         return getOperand(0);
   905     }
   907     MCreateThis *mir() const {
   908         return mir_->toCreateThis();
   909     }
   910 };
   912 // Allocate an object for |new| on the caller-side,
   913 // when the prototype is known.
   914 class LCreateThisWithProto : public LCallInstructionHelper<1, 2, 0>
   915 {
   916   public:
   917     LIR_HEADER(CreateThisWithProto)
   919     LCreateThisWithProto(const LAllocation &callee, const LAllocation &prototype)
   920     {
   921         setOperand(0, callee);
   922         setOperand(1, prototype);
   923     }
   925     const LAllocation *getCallee() {
   926         return getOperand(0);
   927     }
   928     const LAllocation *getPrototype() {
   929         return getOperand(1);
   930     }
   932     MCreateThis *mir() const {
   933         return mir_->toCreateThis();
   934     }
   935 };
   937 // Allocate an object for |new| on the caller-side.
   938 // Always performs object initialization with a fast path.
   939 class LCreateThisWithTemplate : public LInstructionHelper<1, 0, 1>
   940 {
   941   public:
   942     LIR_HEADER(CreateThisWithTemplate)
   944     LCreateThisWithTemplate(const LDefinition &temp) {
   945         setTemp(0, temp);
   946     }
   948     MCreateThisWithTemplate *mir() const {
   949         return mir_->toCreateThisWithTemplate();
   950     }
   952     const LDefinition *temp() {
   953         return getTemp(0);
   954     }
   955 };
   957 // Allocate a new arguments object for the frame.
   958 class LCreateArgumentsObject : public LCallInstructionHelper<1, 1, 1>
   959 {
   960   public:
   961     LIR_HEADER(CreateArgumentsObject)
   963     LCreateArgumentsObject(const LAllocation &callObj, const LDefinition &temp)
   964     {
   965         setOperand(0, callObj);
   966         setTemp(0, temp);
   967     }
   969     const LAllocation *getCallObject() {
   970         return getOperand(0);
   971     }
   973     MCreateArgumentsObject *mir() const {
   974         return mir_->toCreateArgumentsObject();
   975     }
   976 };
   978 // Get argument from arguments object.
   979 class LGetArgumentsObjectArg : public LInstructionHelper<BOX_PIECES, 1, 1>
   980 {
   981   public:
   982     LIR_HEADER(GetArgumentsObjectArg)
   984     LGetArgumentsObjectArg(const LAllocation &argsObj, const LDefinition &temp)
   985     {
   986         setOperand(0, argsObj);
   987         setTemp(0, temp);
   988     }
   990     const LAllocation *getArgsObject() {
   991         return getOperand(0);
   992     }
   994     MGetArgumentsObjectArg *mir() const {
   995         return mir_->toGetArgumentsObjectArg();
   996     }
   997 };
   999 // Set argument on arguments object.
  1000 class LSetArgumentsObjectArg : public LInstructionHelper<0, 1 + BOX_PIECES, 1>
  1002   public:
  1003     LIR_HEADER(SetArgumentsObjectArg)
  1005     LSetArgumentsObjectArg(const LAllocation &argsObj, const LDefinition &temp)
  1007         setOperand(0, argsObj);
  1008         setTemp(0, temp);
  1011     const LAllocation *getArgsObject() {
  1012         return getOperand(0);
  1015     MSetArgumentsObjectArg *mir() const {
  1016         return mir_->toSetArgumentsObjectArg();
  1019     static const size_t ValueIndex = 1;
  1020 };
  1022 // If the Value is an Object, return unbox(Value).
  1023 // Otherwise, return the other Object.
  1024 class LReturnFromCtor : public LInstructionHelper<1, BOX_PIECES + 1, 0>
  1026   public:
  1027     LIR_HEADER(ReturnFromCtor)
  1029     LReturnFromCtor(const LAllocation &object)
  1031         // Value set by useBox() during lowering.
  1032         setOperand(LReturnFromCtor::ObjectIndex, object);
  1035     const LAllocation *getObject() {
  1036         return getOperand(LReturnFromCtor::ObjectIndex);
  1039     static const size_t ValueIndex = 0;
  1040     static const size_t ObjectIndex = BOX_PIECES;
  1041 };
  1043 class LComputeThis : public LInstructionHelper<1, BOX_PIECES, 0>
  1045   public:
  1046     LIR_HEADER(ComputeThis)
  1048     static const size_t ValueIndex = 0;
  1050     const LDefinition *output() {
  1051         return getDef(0);
  1054     MComputeThis *mir() const {
  1055         return mir_->toComputeThis();
  1057 };
  1059 class LLoadArrowThis : public LInstructionHelper<BOX_PIECES, 1, 0>
  1061   public:
  1062     LLoadArrowThis(const LAllocation &callee) {
  1063         setOperand(0, callee);
  1066     LIR_HEADER(LoadArrowThis)
  1068     const LAllocation *callee() {
  1069         return getOperand(0);
  1071 };
  1073 // Writes a typed argument for a function call to the frame's argument vector.
  1074 class LStackArgT : public LInstructionHelper<0, 1, 0>
  1076     uint32_t argslot_; // Index into frame-scope argument vector.
  1077     MIRType type_;
  1079   public:
  1080     LIR_HEADER(StackArgT)
  1082     LStackArgT(uint32_t argslot, MIRType type, const LAllocation &arg)
  1083       : argslot_(argslot),
  1084         type_(type)
  1086         setOperand(0, arg);
  1088     uint32_t argslot() const {
  1089         return argslot_;
  1091     MIRType type() const {
  1092         return type_;
  1094     const LAllocation *getArgument() {
  1095         return getOperand(0);
  1097 };
  1099 // Writes an untyped argument for a function call to the frame's argument vector.
  1100 class LStackArgV : public LInstructionHelper<0, BOX_PIECES, 0>
  1102     uint32_t argslot_; // Index into frame-scope argument vector.
  1104   public:
  1105     LIR_HEADER(StackArgV)
  1107     LStackArgV(uint32_t argslot)
  1108       : argslot_(argslot)
  1109     { }
  1111     uint32_t argslot() const {
  1112         return argslot_;
  1114 };
  1116 // Common code for LIR descended from MCall.
  1117 template <size_t Defs, size_t Operands, size_t Temps>
  1118 class LJSCallInstructionHelper : public LCallInstructionHelper<Defs, Operands, Temps>
  1120   public:
  1121     uint32_t argslot() const {
  1122         return mir()->numStackArgs();
  1124     MCall *mir() const {
  1125         return this->mir_->toCall();
  1128     bool hasSingleTarget() const {
  1129         return getSingleTarget() != nullptr;
  1131     JSFunction *getSingleTarget() const {
  1132         return mir()->getSingleTarget();
  1135     // The number of stack arguments is the max between the number of formal
  1136     // arguments and the number of actual arguments. The number of stack
  1137     // argument includes the |undefined| padding added in case of underflow.
  1138     // Does not include |this|.
  1139     uint32_t numStackArgs() const {
  1140         JS_ASSERT(mir()->numStackArgs() >= 1);
  1141         return mir()->numStackArgs() - 1; // |this| is not a formal argument.
  1143     // Does not include |this|.
  1144     uint32_t numActualArgs() const {
  1145         return mir()->numActualArgs();
  1147 };
  1149 // Generates a polymorphic callsite, wherein the function being called is
  1150 // unknown and anticipated to vary.
  1151 class LCallGeneric : public LJSCallInstructionHelper<BOX_PIECES, 1, 2>
  1153   public:
  1154     LIR_HEADER(CallGeneric)
  1156     LCallGeneric(const LAllocation &func, const LDefinition &nargsreg,
  1157                  const LDefinition &tmpobjreg)
  1159         setOperand(0, func);
  1160         setTemp(0, nargsreg);
  1161         setTemp(1, tmpobjreg);
  1164     const LAllocation *getFunction() {
  1165         return getOperand(0);
  1167     const LDefinition *getNargsReg() {
  1168         return getTemp(0);
  1170     const LDefinition *getTempObject() {
  1171         return getTemp(1);
  1173 };
  1175 // Generates a hardcoded callsite for a known, non-native target.
  1176 class LCallKnown : public LJSCallInstructionHelper<BOX_PIECES, 1, 1>
  1178   public:
  1179     LIR_HEADER(CallKnown)
  1181     LCallKnown(const LAllocation &func, const LDefinition &tmpobjreg)
  1183         setOperand(0, func);
  1184         setTemp(0, tmpobjreg);
  1187     const LAllocation *getFunction() {
  1188         return getOperand(0);
  1190     const LDefinition *getTempObject() {
  1191         return getTemp(0);
  1193 };
  1195 // Generates a hardcoded callsite for a known, native target.
  1196 class LCallNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4>
  1198   public:
  1199     LIR_HEADER(CallNative)
  1201     LCallNative(const LDefinition &argContext, const LDefinition &argUintN,
  1202                 const LDefinition &argVp, const LDefinition &tmpreg)
  1204         // Registers used for callWithABI().
  1205         setTemp(0, argContext);
  1206         setTemp(1, argUintN);
  1207         setTemp(2, argVp);
  1209         // Temporary registers.
  1210         setTemp(3, tmpreg);
  1213     const LDefinition *getArgContextReg() {
  1214         return getTemp(0);
  1216     const LDefinition *getArgUintNReg() {
  1217         return getTemp(1);
  1219     const LDefinition *getArgVpReg() {
  1220         return getTemp(2);
  1222     const LDefinition *getTempReg() {
  1223         return getTemp(3);
  1225 };
  1227 // Generates a hardcoded callsite for a known, DOM-native target.
  1228 class LCallDOMNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4>
  1230   public:
  1231     LIR_HEADER(CallDOMNative)
  1233     LCallDOMNative(const LDefinition &argJSContext, const LDefinition &argObj,
  1234                    const LDefinition &argPrivate, const LDefinition &argArgs)
  1236         setTemp(0, argJSContext);
  1237         setTemp(1, argObj);
  1238         setTemp(2, argPrivate);
  1239         setTemp(3, argArgs);
  1242     const LDefinition *getArgJSContext() {
  1243         return getTemp(0);
  1245     const LDefinition *getArgObj() {
  1246         return getTemp(1);
  1248     const LDefinition *getArgPrivate() {
  1249         return getTemp(2);
  1251     const LDefinition *getArgArgs() {
  1252         return getTemp(3);
  1254 };
  1256 class LBail : public LInstructionHelper<0, 0, 0>
  1258   public:
  1259     LIR_HEADER(Bail)
  1260 };
  1262 template <size_t defs, size_t ops>
  1263 class LDOMPropertyInstructionHelper : public LCallInstructionHelper<defs, 1 + ops, 3>
  1265   protected:
  1266     LDOMPropertyInstructionHelper(const LDefinition &JSContextReg, const LAllocation &ObjectReg,
  1267                                   const LDefinition &PrivReg, const LDefinition &ValueReg)
  1269         this->setOperand(0, ObjectReg);
  1270         this->setTemp(0, JSContextReg);
  1271         this->setTemp(1, PrivReg);
  1272         this->setTemp(2, ValueReg);
  1275   public:
  1276     const LDefinition *getJSContextReg() {
  1277         return this->getTemp(0);
  1279     const LAllocation *getObjectReg() {
  1280         return this->getOperand(0);
  1282     const LDefinition *getPrivReg() {
  1283         return this->getTemp(1);
  1285     const LDefinition *getValueReg() {
  1286         return this->getTemp(2);
  1288 };
  1291 class LGetDOMProperty : public LDOMPropertyInstructionHelper<BOX_PIECES, 0>
  1293   public:
  1294     LIR_HEADER(GetDOMProperty)
  1296     LGetDOMProperty(const LDefinition &JSContextReg, const LAllocation &ObjectReg,
  1297                     const LDefinition &PrivReg, const LDefinition &ValueReg)
  1298       : LDOMPropertyInstructionHelper<BOX_PIECES, 0>(JSContextReg, ObjectReg,
  1299                                                      PrivReg, ValueReg)
  1300     { }
  1302     MGetDOMProperty *mir() const {
  1303         return mir_->toGetDOMProperty();
  1305 };
  1307 class LGetDOMMember : public LInstructionHelper<BOX_PIECES, 1, 0>
  1309   public:
  1310     LIR_HEADER(GetDOMMember);
  1311     LGetDOMMember(const LAllocation &object) {
  1312         setOperand(0, object);
  1315     const LAllocation *object() {
  1316         return getOperand(0);
  1319     MGetDOMMember *mir() const {
  1320         return mir_->toGetDOMMember();
  1322 };
  1324 class LSetDOMProperty : public LDOMPropertyInstructionHelper<0, BOX_PIECES>
  1326   public:
  1327     LIR_HEADER(SetDOMProperty)
  1329     LSetDOMProperty(const LDefinition &JSContextReg, const LAllocation &ObjectReg,
  1330                     const LDefinition &PrivReg, const LDefinition &ValueReg)
  1331       : LDOMPropertyInstructionHelper<0, BOX_PIECES>(JSContextReg, ObjectReg,
  1332                                                      PrivReg, ValueReg)
  1333     { }
  1335     static const size_t Value = 1;
  1337     MSetDOMProperty *mir() const {
  1338         return mir_->toSetDOMProperty();
  1340 };
  1342 // Generates a polymorphic callsite, wherein the function being called is
  1343 // unknown and anticipated to vary.
  1344 class LApplyArgsGeneric : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2>
  1346   public:
  1347     LIR_HEADER(ApplyArgsGeneric)
  1349     LApplyArgsGeneric(const LAllocation &func, const LAllocation &argc,
  1350                       const LDefinition &tmpobjreg, const LDefinition &tmpcopy)
  1352         setOperand(0, func);
  1353         setOperand(1, argc);
  1354         setTemp(0, tmpobjreg);
  1355         setTemp(1, tmpcopy);
  1358     MApplyArgs *mir() const {
  1359         return mir_->toApplyArgs();
  1362     bool hasSingleTarget() const {
  1363         return getSingleTarget() != nullptr;
  1365     JSFunction *getSingleTarget() const {
  1366         return mir()->getSingleTarget();
  1369     const LAllocation *getFunction() {
  1370         return getOperand(0);
  1372     const LAllocation *getArgc() {
  1373         return getOperand(1);
  1375     static const size_t ThisIndex = 2;
  1377     const LDefinition *getTempObject() {
  1378         return getTemp(0);
  1380     const LDefinition *getTempCopy() {
  1381         return getTemp(1);
  1383 };
  1385 class LArraySplice : public LCallInstructionHelper<0, 3, 0>
  1387   public:
  1388     LIR_HEADER(ArraySplice)
  1390     LArraySplice(const LAllocation &object, const LAllocation &start,
  1391                  const LAllocation &deleteCount)
  1393         setOperand(0, object);
  1394         setOperand(1, start);
  1395         setOperand(2, deleteCount);
  1398     MArraySplice *mir() const {
  1399         return mir_->toArraySplice();
  1402     const LAllocation *getObject() {
  1403         return getOperand(0);
  1405     const LAllocation *getStart() {
  1406         return getOperand(1);
  1408     const LAllocation *getDeleteCount() {
  1409         return getOperand(2);
  1411 };
  1413 class LGetDynamicName : public LCallInstructionHelper<BOX_PIECES, 2, 3>
  1415   public:
  1416     LIR_HEADER(GetDynamicName)
  1418     LGetDynamicName(const LAllocation &scopeChain, const LAllocation &name,
  1419                     const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3)
  1421         setOperand(0, scopeChain);
  1422         setOperand(1, name);
  1423         setTemp(0, temp1);
  1424         setTemp(1, temp2);
  1425         setTemp(2, temp3);
  1428     MGetDynamicName *mir() const {
  1429         return mir_->toGetDynamicName();
  1432     const LAllocation *getScopeChain() {
  1433         return getOperand(0);
  1435     const LAllocation *getName() {
  1436         return getOperand(1);
  1439     const LDefinition *temp1() {
  1440         return getTemp(0);
  1442     const LDefinition *temp2() {
  1443         return getTemp(1);
  1445     const LDefinition *temp3() {
  1446         return getTemp(2);
  1448 };
  1450 class LFilterArgumentsOrEvalS : public LCallInstructionHelper<0, 1, 2>
  1452   public:
  1453     LIR_HEADER(FilterArgumentsOrEvalS)
  1455     LFilterArgumentsOrEvalS(const LAllocation &string, const LDefinition &temp1,
  1456                             const LDefinition &temp2)
  1458         setOperand(0, string);
  1459         setTemp(0, temp1);
  1460         setTemp(1, temp2);
  1463     MFilterArgumentsOrEval *mir() const {
  1464         return mir_->toFilterArgumentsOrEval();
  1467     const LAllocation *getString() {
  1468         return getOperand(0);
  1470     const LDefinition *temp1() {
  1471         return getTemp(0);
  1473     const LDefinition *temp2() {
  1474         return getTemp(1);
  1476 };
  1478 class LFilterArgumentsOrEvalV : public LCallInstructionHelper<0, BOX_PIECES, 3>
  1480   public:
  1481     LIR_HEADER(FilterArgumentsOrEvalV)
  1483     LFilterArgumentsOrEvalV(const LDefinition &temp1, const LDefinition &temp2,
  1484                             const LDefinition &temp3)
  1486         setTemp(0, temp1);
  1487         setTemp(1, temp2);
  1488         setTemp(2, temp3);
  1491     static const size_t Input = 0;
  1493     MFilterArgumentsOrEval *mir() const {
  1494         return mir_->toFilterArgumentsOrEval();
  1497     const LDefinition *temp1() {
  1498         return getTemp(0);
  1500     const LDefinition *temp2() {
  1501         return getTemp(1);
  1503     const LDefinition *temp3() {
  1504         return getTemp(2);
  1506 };
  1508 class LCallDirectEvalS : public LCallInstructionHelper<BOX_PIECES, 2 + BOX_PIECES, 0>
  1510   public:
  1511     LIR_HEADER(CallDirectEvalS)
  1513     LCallDirectEvalS(const LAllocation &scopeChain, const LAllocation &string)
  1515         setOperand(0, scopeChain);
  1516         setOperand(1, string);
  1519     static const size_t ThisValue = 2;
  1521     MCallDirectEval *mir() const {
  1522         return mir_->toCallDirectEval();
  1525     const LAllocation *getScopeChain() {
  1526         return getOperand(0);
  1528     const LAllocation *getString() {
  1529         return getOperand(1);
  1531 };
  1533 class LCallDirectEvalV : public LCallInstructionHelper<BOX_PIECES, 1 + (2 * BOX_PIECES), 0>
  1535   public:
  1536     LIR_HEADER(CallDirectEvalV)
  1538     LCallDirectEvalV(const LAllocation &scopeChain)
  1540         setOperand(0, scopeChain);
  1543     static const size_t Argument = 1;
  1544     static const size_t ThisValue = 1 + BOX_PIECES;
  1546     MCallDirectEval *mir() const {
  1547         return mir_->toCallDirectEval();
  1550     const LAllocation *getScopeChain() {
  1551         return getOperand(0);
  1553 };
  1555 // Takes in either an integer or boolean input and tests it for truthiness.
  1556 class LTestIAndBranch : public LControlInstructionHelper<2, 1, 0>
  1558   public:
  1559     LIR_HEADER(TestIAndBranch)
  1561     LTestIAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1563         setOperand(0, in);
  1564         setSuccessor(0, ifTrue);
  1565         setSuccessor(1, ifFalse);
  1568     MBasicBlock *ifTrue() const {
  1569         return getSuccessor(0);
  1571     MBasicBlock *ifFalse() const {
  1572         return getSuccessor(1);
  1574 };
  1576 // Takes in either an integer or boolean input and tests it for truthiness.
  1577 class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0>
  1579   public:
  1580     LIR_HEADER(TestDAndBranch)
  1582     LTestDAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1584         setOperand(0, in);
  1585         setSuccessor(0, ifTrue);
  1586         setSuccessor(1, ifFalse);
  1589     MBasicBlock *ifTrue() const {
  1590         return getSuccessor(0);
  1592     MBasicBlock *ifFalse() const {
  1593         return getSuccessor(1);
  1595 };
  1597 // Takes in either an integer or boolean input and tests it for truthiness.
  1598 class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0>
  1600   public:
  1601     LIR_HEADER(TestFAndBranch)
  1603     LTestFAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1605         setOperand(0, in);
  1606         setSuccessor(0, ifTrue);
  1607         setSuccessor(1, ifFalse);
  1610     MBasicBlock *ifTrue() const {
  1611         return getSuccessor(0);
  1613     MBasicBlock *ifFalse() const {
  1614         return getSuccessor(1);
  1616 };
  1618 // Takes an object and tests it for truthiness.  An object is falsy iff it
  1619 // emulates |undefined|; see js::EmulatesUndefined.
  1620 class LTestOAndBranch : public LControlInstructionHelper<2, 1, 1>
  1622   public:
  1623     LIR_HEADER(TestOAndBranch)
  1625     LTestOAndBranch(const LAllocation &input, MBasicBlock *ifTruthy, MBasicBlock *ifFalsy,
  1626                     const LDefinition &temp)
  1628         setOperand(0, input);
  1629         setSuccessor(0, ifTruthy);
  1630         setSuccessor(1, ifFalsy);
  1631         setTemp(0, temp);
  1634     const LDefinition *temp() {
  1635         return getTemp(0);
  1638     MBasicBlock *ifTruthy() {
  1639         return getSuccessor(0);
  1641     MBasicBlock *ifFalsy() {
  1642         return getSuccessor(1);
  1645     MTest *mir() {
  1646         return mir_->toTest();
  1648 };
  1650 // Takes in a boxed value and tests it for truthiness.
  1651 class LTestVAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 3>
  1653   public:
  1654     LIR_HEADER(TestVAndBranch)
  1656     LTestVAndBranch(MBasicBlock *ifTruthy, MBasicBlock *ifFalsy, const LDefinition &temp0,
  1657                     const LDefinition &temp1, const LDefinition &temp2)
  1659         setSuccessor(0, ifTruthy);
  1660         setSuccessor(1, ifFalsy);
  1661         setTemp(0, temp0);
  1662         setTemp(1, temp1);
  1663         setTemp(2, temp2);
  1666     const char *extraName() const {
  1667         return mir()->operandMightEmulateUndefined() ? "MightEmulateUndefined" : nullptr;
  1670     static const size_t Input = 0;
  1672     const LDefinition *tempFloat() {
  1673         return getTemp(0);
  1676     const LDefinition *temp1() {
  1677         return getTemp(1);
  1680     const LDefinition *temp2() {
  1681         return getTemp(2);
  1684     MBasicBlock *ifTruthy() {
  1685         return getSuccessor(0);
  1687     MBasicBlock *ifFalsy() {
  1688         return getSuccessor(1);
  1691     MTest *mir() const {
  1692         return mir_->toTest();
  1694 };
  1696 // Dispatches control flow to a successor based on incoming JSFunction*.
  1697 // Used to implemenent polymorphic inlining.
  1698 class LFunctionDispatch : public LInstructionHelper<0, 1, 0>
  1700     // Dispatch is performed based on a function -> block map
  1701     // stored in the MIR.
  1703   public:
  1704     LIR_HEADER(FunctionDispatch);
  1706     LFunctionDispatch(const LAllocation &in) {
  1707         setOperand(0, in);
  1710     MFunctionDispatch *mir() {
  1711         return mir_->toFunctionDispatch();
  1713 };
  1715 class LTypeObjectDispatch : public LInstructionHelper<0, 1, 1>
  1717     // Dispatch is performed based on a TypeObject -> block
  1718     // map inferred by the MIR.
  1720   public:
  1721     LIR_HEADER(TypeObjectDispatch);
  1723     LTypeObjectDispatch(const LAllocation &in, const LDefinition &temp) {
  1724         setOperand(0, in);
  1725         setTemp(0, temp);
  1728     const LDefinition *temp() {
  1729         return getTemp(0);
  1732     MTypeObjectDispatch *mir() {
  1733         return mir_->toTypeObjectDispatch();
  1735 };
  1737 // Compares two integral values of the same JS type, either integer or object.
  1738 // For objects, both operands are in registers.
  1739 class LCompare : public LInstructionHelper<1, 2, 0>
  1741     JSOp jsop_;
  1743   public:
  1744     LIR_HEADER(Compare)
  1745     LCompare(JSOp jsop, const LAllocation &left, const LAllocation &right)
  1746       : jsop_(jsop)
  1748         setOperand(0, left);
  1749         setOperand(1, right);
  1752     JSOp jsop() const {
  1753         return jsop_;
  1755     const LAllocation *left() {
  1756         return getOperand(0);
  1758     const LAllocation *right() {
  1759         return getOperand(1);
  1761     MCompare *mir() {
  1762         return mir_->toCompare();
  1764     const char *extraName() const {
  1765         return js_CodeName[jsop_];
  1767 };
  1769 // Compares two integral values of the same JS type, either integer or object.
  1770 // For objects, both operands are in registers.
  1771 class LCompareAndBranch : public LControlInstructionHelper<2, 2, 0>
  1773     MCompare *cmpMir_;
  1774     JSOp jsop_;
  1776   public:
  1777     LIR_HEADER(CompareAndBranch)
  1778     LCompareAndBranch(MCompare *cmpMir, JSOp jsop,
  1779                       const LAllocation &left, const LAllocation &right,
  1780                       MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1781       : cmpMir_(cmpMir), jsop_(jsop)
  1783         setOperand(0, left);
  1784         setOperand(1, right);
  1785         setSuccessor(0, ifTrue);
  1786         setSuccessor(1, ifFalse);
  1789     JSOp jsop() const {
  1790         return jsop_;
  1792     MBasicBlock *ifTrue() const {
  1793         return getSuccessor(0);
  1795     MBasicBlock *ifFalse() const {
  1796         return getSuccessor(1);
  1798     const LAllocation *left() {
  1799         return getOperand(0);
  1801     const LAllocation *right() {
  1802         return getOperand(1);
  1804     MTest *mir() const {
  1805         return mir_->toTest();
  1807     MCompare *cmpMir() const {
  1808         return cmpMir_;
  1810     const char *extraName() const {
  1811         return js_CodeName[jsop_];
  1813 };
  1815 class LCompareD : public LInstructionHelper<1, 2, 0>
  1817   public:
  1818     LIR_HEADER(CompareD)
  1819     LCompareD(const LAllocation &left, const LAllocation &right) {
  1820         setOperand(0, left);
  1821         setOperand(1, right);
  1824     const LAllocation *left() {
  1825         return getOperand(0);
  1827     const LAllocation *right() {
  1828         return getOperand(1);
  1830     MCompare *mir() {
  1831         return mir_->toCompare();
  1833 };
  1835 class LCompareF : public LInstructionHelper<1, 2, 0>
  1837   public:
  1838     LIR_HEADER(CompareF)
  1839     LCompareF(const LAllocation &left, const LAllocation &right) {
  1840         setOperand(0, left);
  1841         setOperand(1, right);
  1844     const LAllocation *left() {
  1845         return getOperand(0);
  1847     const LAllocation *right() {
  1848         return getOperand(1);
  1850     MCompare *mir() {
  1851         return mir_->toCompare();
  1853 };
  1855 class LCompareDAndBranch : public LControlInstructionHelper<2, 2, 0>
  1857     MCompare *cmpMir_;
  1859   public:
  1860     LIR_HEADER(CompareDAndBranch)
  1861     LCompareDAndBranch(MCompare *cmpMir, const LAllocation &left, const LAllocation &right,
  1862                        MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1863       : cmpMir_(cmpMir)
  1865         setOperand(0, left);
  1866         setOperand(1, right);
  1867         setSuccessor(0, ifTrue);
  1868         setSuccessor(1, ifFalse);
  1871     MBasicBlock *ifTrue() const {
  1872         return getSuccessor(0);
  1874     MBasicBlock *ifFalse() const {
  1875         return getSuccessor(1);
  1877     const LAllocation *left() {
  1878         return getOperand(0);
  1880     const LAllocation *right() {
  1881         return getOperand(1);
  1883     MTest *mir() const {
  1884         return mir_->toTest();
  1886     MCompare *cmpMir() const {
  1887         return cmpMir_;
  1889 };
  1891 class LCompareFAndBranch : public LControlInstructionHelper<2, 2, 0>
  1893     MCompare *cmpMir_;
  1895   public:
  1896     LIR_HEADER(CompareFAndBranch)
  1897     LCompareFAndBranch(MCompare *cmpMir, const LAllocation &left, const LAllocation &right,
  1898                        MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  1899       : cmpMir_(cmpMir)
  1901         setOperand(0, left);
  1902         setOperand(1, right);
  1903         setSuccessor(0, ifTrue);
  1904         setSuccessor(1, ifFalse);
  1907     MBasicBlock *ifTrue() const {
  1908         return getSuccessor(0);
  1910     MBasicBlock *ifFalse() const {
  1911         return getSuccessor(1);
  1913     const LAllocation *left() {
  1914         return getOperand(0);
  1916     const LAllocation *right() {
  1917         return getOperand(1);
  1919     MTest *mir() const {
  1920         return mir_->toTest();
  1922     MCompare *cmpMir() const {
  1923         return cmpMir_;
  1925 };
  1927 class LCompareS : public LInstructionHelper<1, 2, 1>
  1929   public:
  1930     LIR_HEADER(CompareS)
  1931     LCompareS(const LAllocation &left, const LAllocation &right,
  1932               const LDefinition &temp) {
  1933         setOperand(0, left);
  1934         setOperand(1, right);
  1935         setTemp(0, temp);
  1938     const LAllocation *left() {
  1939         return getOperand(0);
  1941     const LAllocation *right() {
  1942         return getOperand(1);
  1944     const LDefinition *temp() {
  1945         return getTemp(0);
  1947     MCompare *mir() {
  1948         return mir_->toCompare();
  1950 };
  1952 // strict-equality between value and string.
  1953 class LCompareStrictS : public LInstructionHelper<1, BOX_PIECES + 1, 2>
  1955   public:
  1956     LIR_HEADER(CompareStrictS)
  1957     LCompareStrictS(const LAllocation &rhs, const LDefinition &temp0,
  1958                     const LDefinition &temp1) {
  1959         setOperand(BOX_PIECES, rhs);
  1960         setTemp(0, temp0);
  1961         setTemp(1, temp1);
  1964     static const size_t Lhs = 0;
  1966     const LAllocation *right() {
  1967         return getOperand(BOX_PIECES);
  1969     const LDefinition *temp() {
  1970         return getTemp(0);
  1972     const LDefinition *tempToUnbox() {
  1973         return getTemp(1);
  1975     MCompare *mir() {
  1976         return mir_->toCompare();
  1978 };
  1980 // Used for strict-equality comparisons where one side is a boolean
  1981 // and the other is a value. Note that CompareI is used to compare
  1982 // two booleans.
  1983 class LCompareB : public LInstructionHelper<1, BOX_PIECES + 1, 0>
  1985   public:
  1986     LIR_HEADER(CompareB)
  1988     LCompareB(const LAllocation &rhs) {
  1989         setOperand(BOX_PIECES, rhs);
  1992     static const size_t Lhs = 0;
  1994     const LAllocation *rhs() {
  1995         return getOperand(BOX_PIECES);
  1998     MCompare *mir() {
  1999         return mir_->toCompare();
  2001 };
  2003 class LCompareBAndBranch : public LControlInstructionHelper<2, BOX_PIECES + 1, 0>
  2005     MCompare *cmpMir_;
  2007   public:
  2008     LIR_HEADER(CompareBAndBranch)
  2010     LCompareBAndBranch(MCompare *cmpMir, const LAllocation &rhs,
  2011                        MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  2012       : cmpMir_(cmpMir)
  2014         setOperand(BOX_PIECES, rhs);
  2015         setSuccessor(0, ifTrue);
  2016         setSuccessor(1, ifFalse);
  2019     static const size_t Lhs = 0;
  2021     const LAllocation *rhs() {
  2022         return getOperand(BOX_PIECES);
  2025     MBasicBlock *ifTrue() const {
  2026         return getSuccessor(0);
  2028     MBasicBlock *ifFalse() const {
  2029         return getSuccessor(1);
  2031     MTest *mir() const {
  2032         return mir_->toTest();
  2034     MCompare *cmpMir() const {
  2035         return cmpMir_;
  2037 };
  2039 class LCompareV : public LInstructionHelper<1, 2 * BOX_PIECES, 0>
  2041   public:
  2042     LIR_HEADER(CompareV)
  2044     static const size_t LhsInput = 0;
  2045     static const size_t RhsInput = BOX_PIECES;
  2047     MCompare *mir() const {
  2048         return mir_->toCompare();
  2050 };
  2052 class LCompareVAndBranch : public LControlInstructionHelper<2, 2 * BOX_PIECES, 0>
  2054     MCompare *cmpMir_;
  2056   public:
  2057     LIR_HEADER(CompareVAndBranch)
  2059     static const size_t LhsInput = 0;
  2060     static const size_t RhsInput = BOX_PIECES;
  2062     LCompareVAndBranch(MCompare *cmpMir, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  2063       : cmpMir_(cmpMir)
  2065         setSuccessor(0, ifTrue);
  2066         setSuccessor(1, ifFalse);
  2069     MBasicBlock *ifTrue() const {
  2070         return getSuccessor(0);
  2072     MBasicBlock *ifFalse() const {
  2073         return getSuccessor(1);
  2075     MTest *mir() const {
  2076         return mir_->toTest();
  2078     MCompare *cmpMir() const {
  2079         return cmpMir_;
  2081 };
  2083 class LCompareVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
  2085   public:
  2086     LIR_HEADER(CompareVM)
  2088     static const size_t LhsInput = 0;
  2089     static const size_t RhsInput = BOX_PIECES;
  2091     MCompare *mir() const {
  2092         return mir_->toCompare();
  2094 };
  2096 class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0>
  2098   public:
  2099     LIR_HEADER(BitAndAndBranch)
  2100     LBitAndAndBranch(MBasicBlock *ifTrue, MBasicBlock *ifFalse)
  2102         setSuccessor(0, ifTrue);
  2103         setSuccessor(1, ifFalse);
  2106     MBasicBlock *ifTrue() const {
  2107         return getSuccessor(0);
  2109     MBasicBlock *ifFalse() const {
  2110         return getSuccessor(1);
  2112     const LAllocation *left() {
  2113         return getOperand(0);
  2115     const LAllocation *right() {
  2116         return getOperand(1);
  2118 };
  2120 class LIsNullOrLikeUndefined : public LInstructionHelper<1, BOX_PIECES, 2>
  2122   public:
  2123     LIR_HEADER(IsNullOrLikeUndefined)
  2125     LIsNullOrLikeUndefined(const LDefinition &temp, const LDefinition &tempToUnbox)
  2127         setTemp(0, temp);
  2128         setTemp(1, tempToUnbox);
  2131     static const size_t Value = 0;
  2133     MCompare *mir() {
  2134         return mir_->toCompare();
  2137     const LDefinition *temp() {
  2138         return getTemp(0);
  2141     const LDefinition *tempToUnbox() {
  2142         return getTemp(1);
  2144 };
  2146 class LIsNullOrLikeUndefinedAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 2>
  2148     MCompare *cmpMir_;
  2150   public:
  2151     LIR_HEADER(IsNullOrLikeUndefinedAndBranch)
  2153     LIsNullOrLikeUndefinedAndBranch(MCompare *cmpMir, MBasicBlock *ifTrue, MBasicBlock *ifFalse,
  2154                                     const LDefinition &temp, const LDefinition &tempToUnbox)
  2155       : cmpMir_(cmpMir)
  2157         setSuccessor(0, ifTrue);
  2158         setSuccessor(1, ifFalse);
  2159         setTemp(0, temp);
  2160         setTemp(1, tempToUnbox);
  2163     static const size_t Value = 0;
  2165     MBasicBlock *ifTrue() const {
  2166         return getSuccessor(0);
  2168     MBasicBlock *ifFalse() const {
  2169         return getSuccessor(1);
  2171     MTest *mir() const {
  2172         return mir_->toTest();
  2174     MCompare *cmpMir() const {
  2175         return cmpMir_;
  2177     const LDefinition *temp() {
  2178         return getTemp(0);
  2180     const LDefinition *tempToUnbox() {
  2181         return getTemp(1);
  2183 };
  2185 // Takes an object and tests whether it emulates |undefined|, as determined by
  2186 // the JSCLASS_EMULATES_UNDEFINED class flag on unwrapped objects.  See also
  2187 // js::EmulatesUndefined.
  2188 class LEmulatesUndefined : public LInstructionHelper<1, 1, 0>
  2190   public:
  2191     LIR_HEADER(EmulatesUndefined)
  2193     LEmulatesUndefined(const LAllocation &input)
  2195         setOperand(0, input);
  2198     MCompare *mir() {
  2199         return mir_->toCompare();
  2201 };
  2203 class LEmulatesUndefinedAndBranch : public LControlInstructionHelper<2, 1, 1>
  2205     MCompare *cmpMir_;
  2207   public:
  2208     LIR_HEADER(EmulatesUndefinedAndBranch)
  2210     LEmulatesUndefinedAndBranch(MCompare *cmpMir, const LAllocation &input,
  2211                                 MBasicBlock *ifTrue, MBasicBlock *ifFalse,
  2212                                 const LDefinition &temp)
  2213       : cmpMir_(cmpMir)
  2215         setOperand(0, input);
  2216         setSuccessor(0, ifTrue);
  2217         setSuccessor(1, ifFalse);
  2218         setTemp(0, temp);
  2221     MBasicBlock *ifTrue() const {
  2222         return getSuccessor(0);
  2224     MBasicBlock *ifFalse() const {
  2225         return getSuccessor(1);
  2227     MTest *mir() const {
  2228         return mir_->toTest();
  2230     MCompare *cmpMir() const {
  2231         return cmpMir_;
  2233     const LDefinition *temp() {
  2234         return getTemp(0);
  2236 };
  2238 // Not operation on an integer.
  2239 class LNotI : public LInstructionHelper<1, 1, 0>
  2241   public:
  2242     LIR_HEADER(NotI)
  2244     LNotI(const LAllocation &input) {
  2245         setOperand(0, input);
  2247 };
  2249 // Not operation on a double.
  2250 class LNotD : public LInstructionHelper<1, 1, 0>
  2252   public:
  2253     LIR_HEADER(NotD)
  2255     LNotD(const LAllocation &input) {
  2256         setOperand(0, input);
  2259     MNot *mir() {
  2260         return mir_->toNot();
  2262 };
  2264 // Not operation on a float32.
  2265 class LNotF : public LInstructionHelper<1, 1, 0>
  2267   public:
  2268     LIR_HEADER(NotF)
  2270     LNotF(const LAllocation &input) {
  2271         setOperand(0, input);
  2274     MNot *mir() {
  2275         return mir_->toNot();
  2277 };
  2279 // Boolean complement operation on an object.
  2280 class LNotO : public LInstructionHelper<1, 1, 0>
  2282   public:
  2283     LIR_HEADER(NotO)
  2285     LNotO(const LAllocation &input)
  2287         setOperand(0, input);
  2290     MNot *mir() {
  2291         return mir_->toNot();
  2293 };
  2295 // Boolean complement operation on a value.
  2296 class LNotV : public LInstructionHelper<1, BOX_PIECES, 3>
  2298   public:
  2299     LIR_HEADER(NotV)
  2301     static const size_t Input = 0;
  2302     LNotV(const LDefinition &temp0, const LDefinition &temp1, const LDefinition &temp2)
  2304         setTemp(0, temp0);
  2305         setTemp(1, temp1);
  2306         setTemp(2, temp2);
  2309     const LDefinition *tempFloat() {
  2310         return getTemp(0);
  2313     const LDefinition *temp1() {
  2314         return getTemp(1);
  2317     const LDefinition *temp2() {
  2318         return getTemp(2);
  2321     MNot *mir() {
  2322         return mir_->toNot();
  2324 };
  2326 // Bitwise not operation, takes a 32-bit integer as input and returning
  2327 // a 32-bit integer result as an output.
  2328 class LBitNotI : public LInstructionHelper<1, 1, 0>
  2330   public:
  2331     LIR_HEADER(BitNotI)
  2332 };
  2334 // Call a VM function to perform a BITNOT operation.
  2335 class LBitNotV : public LCallInstructionHelper<1, BOX_PIECES, 0>
  2337   public:
  2338     LIR_HEADER(BitNotV)
  2340     static const size_t Input = 0;
  2341 };
  2343 // Binary bitwise operation, taking two 32-bit integers as inputs and returning
  2344 // a 32-bit integer result as an output.
  2345 class LBitOpI : public LInstructionHelper<1, 2, 0>
  2347     JSOp op_;
  2349   public:
  2350     LIR_HEADER(BitOpI)
  2352     LBitOpI(JSOp op)
  2353       : op_(op)
  2354     { }
  2356     const char *extraName() const {
  2357         if (bitop() == JSOP_URSH && mir_->toUrsh()->bailoutsDisabled())
  2358             return "ursh:BailoutsDisabled";
  2359         return js_CodeName[op_];
  2362     JSOp bitop() const {
  2363         return op_;
  2365 };
  2367 // Call a VM function to perform a bitwise operation.
  2368 class LBitOpV : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
  2370     JSOp jsop_;
  2372   public:
  2373     LIR_HEADER(BitOpV)
  2375     LBitOpV(JSOp jsop)
  2376       : jsop_(jsop)
  2377     { }
  2379     JSOp jsop() const {
  2380         return jsop_;
  2383     const char *extraName() const {
  2384         return js_CodeName[jsop_];
  2387     static const size_t LhsInput = 0;
  2388     static const size_t RhsInput = BOX_PIECES;
  2389 };
  2391 // Shift operation, taking two 32-bit integers as inputs and returning
  2392 // a 32-bit integer result as an output.
  2393 class LShiftI : public LBinaryMath<0>
  2395     JSOp op_;
  2397   public:
  2398     LIR_HEADER(ShiftI)
  2400     LShiftI(JSOp op)
  2401       : op_(op)
  2402     { }
  2404     JSOp bitop() {
  2405         return op_;
  2408     MInstruction *mir() {
  2409         return mir_->toInstruction();
  2412     const char *extraName() const {
  2413         return js_CodeName[op_];
  2415 };
  2417 class LUrshD : public LBinaryMath<1>
  2419   public:
  2420     LIR_HEADER(UrshD)
  2422     LUrshD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
  2423         setOperand(0, lhs);
  2424         setOperand(1, rhs);
  2425         setTemp(0, temp);
  2427     const LDefinition *temp() {
  2428         return getTemp(0);
  2430 };
  2432 // Returns from the function being compiled (not used in inlined frames). The
  2433 // input must be a box.
  2434 class LReturn : public LInstructionHelper<0, BOX_PIECES, 0>
  2436   public:
  2437     LIR_HEADER(Return)
  2438 };
  2440 class LThrow : public LCallInstructionHelper<0, BOX_PIECES, 0>
  2442   public:
  2443     LIR_HEADER(Throw)
  2445     static const size_t Value = 0;
  2446 };
  2448 class LMinMaxI : public LInstructionHelper<1, 2, 0>
  2450   public:
  2451     LIR_HEADER(MinMaxI)
  2452     LMinMaxI(const LAllocation &first, const LAllocation &second)
  2454         setOperand(0, first);
  2455         setOperand(1, second);
  2458     const LAllocation *first() {
  2459         return this->getOperand(0);
  2461     const LAllocation *second() {
  2462         return this->getOperand(1);
  2464     const LDefinition *output() {
  2465         return this->getDef(0);
  2467     MMinMax *mir() const {
  2468         return mir_->toMinMax();
  2470     const char *extraName() const {
  2471         return mir()->isMax() ? "Max" : "Min";
  2473 };
  2475 class LMinMaxD : public LInstructionHelper<1, 2, 0>
  2477   public:
  2478     LIR_HEADER(MinMaxD)
  2479     LMinMaxD(const LAllocation &first, const LAllocation &second)
  2481         setOperand(0, first);
  2482         setOperand(1, second);
  2485     const LAllocation *first() {
  2486         return this->getOperand(0);
  2488     const LAllocation *second() {
  2489         return this->getOperand(1);
  2491     const LDefinition *output() {
  2492         return this->getDef(0);
  2494     MMinMax *mir() const {
  2495         return mir_->toMinMax();
  2497     const char *extraName() const {
  2498         return mir()->isMax() ? "Max" : "Min";
  2500 };
  2502 // Negative of an integer
  2503 class LNegI : public LInstructionHelper<1, 1, 0>
  2505   public:
  2506     LIR_HEADER(NegI);
  2507     LNegI(const LAllocation &num) {
  2508         setOperand(0, num);
  2510 };
  2512 // Negative of a double.
  2513 class LNegD : public LInstructionHelper<1, 1, 0>
  2515   public:
  2516     LIR_HEADER(NegD)
  2517     LNegD(const LAllocation &num) {
  2518         setOperand(0, num);
  2520 };
  2522 // Negative of a float32.
  2523 class LNegF : public LInstructionHelper<1, 1, 0>
  2525   public:
  2526     LIR_HEADER(NegF)
  2527     LNegF(const LAllocation &num) {
  2528         setOperand(0, num);
  2530 };
  2532 // Absolute value of an integer.
  2533 class LAbsI : public LInstructionHelper<1, 1, 0>
  2535   public:
  2536     LIR_HEADER(AbsI)
  2537     LAbsI(const LAllocation &num) {
  2538         setOperand(0, num);
  2540 };
  2542 // Absolute value of a double.
  2543 class LAbsD : public LInstructionHelper<1, 1, 0>
  2545   public:
  2546     LIR_HEADER(AbsD)
  2547     LAbsD(const LAllocation &num) {
  2548         setOperand(0, num);
  2550 };
  2552 // Absolute value of a float32.
  2553 class LAbsF : public LInstructionHelper<1, 1, 0>
  2555   public:
  2556     LIR_HEADER(AbsF)
  2557     LAbsF(const LAllocation &num) {
  2558         setOperand(0, num);
  2560 };
  2562 // Square root of a double.
  2563 class LSqrtD : public LInstructionHelper<1, 1, 0>
  2565   public:
  2566     LIR_HEADER(SqrtD)
  2567     LSqrtD(const LAllocation &num) {
  2568         setOperand(0, num);
  2570 };
  2572 // Square root of a float32.
  2573 class LSqrtF : public LInstructionHelper<1, 1, 0>
  2575   public:
  2576     LIR_HEADER(SqrtF)
  2577     LSqrtF(const LAllocation &num) {
  2578         setOperand(0, num);
  2580 };
  2582 class LAtan2D : public LCallInstructionHelper<1, 2, 1>
  2584   public:
  2585     LIR_HEADER(Atan2D)
  2586     LAtan2D(const LAllocation &y, const LAllocation &x, const LDefinition &temp) {
  2587         setOperand(0, y);
  2588         setOperand(1, x);
  2589         setTemp(0, temp);
  2592     const LAllocation *y() {
  2593         return getOperand(0);
  2596     const LAllocation *x() {
  2597         return getOperand(1);
  2600     const LDefinition *temp() {
  2601         return getTemp(0);
  2604     const LDefinition *output() {
  2605         return getDef(0);
  2607 };
  2609 class LHypot : public LCallInstructionHelper<1, 2, 1>
  2611   public:
  2612     LIR_HEADER(Hypot)
  2613     LHypot(const LAllocation &x, const LAllocation &y, const LDefinition &temp) {
  2614         setOperand(0, x);
  2615         setOperand(1, y);
  2616         setTemp(0, temp);
  2619     const LAllocation *x() {
  2620         return getOperand(0);
  2623     const LAllocation *y() {
  2624         return getOperand(1);
  2627     const LDefinition *temp() {
  2628         return getTemp(0);
  2631     const LDefinition *output() {
  2632         return getDef(0);
  2634 };
  2636 // Double raised to an integer power.
  2637 class LPowI : public LCallInstructionHelper<1, 2, 1>
  2639   public:
  2640     LIR_HEADER(PowI)
  2641     LPowI(const LAllocation &value, const LAllocation &power, const LDefinition &temp) {
  2642         setOperand(0, value);
  2643         setOperand(1, power);
  2644         setTemp(0, temp);
  2647     const LAllocation *value() {
  2648         return getOperand(0);
  2650     const LAllocation *power() {
  2651         return getOperand(1);
  2653     const LDefinition *temp() {
  2654         return getTemp(0);
  2656 };
  2658 // Double raised to a double power.
  2659 class LPowD : public LCallInstructionHelper<1, 2, 1>
  2661   public:
  2662     LIR_HEADER(PowD)
  2663     LPowD(const LAllocation &value, const LAllocation &power, const LDefinition &temp) {
  2664         setOperand(0, value);
  2665         setOperand(1, power);
  2666         setTemp(0, temp);
  2669     const LAllocation *value() {
  2670         return getOperand(0);
  2672     const LAllocation *power() {
  2673         return getOperand(1);
  2675     const LDefinition *temp() {
  2676         return getTemp(0);
  2678 };
  2680 // Math.random().
  2681 class LRandom : public LCallInstructionHelper<1, 0, 2>
  2683   public:
  2684     LIR_HEADER(Random)
  2685     LRandom(const LDefinition &temp, const LDefinition &temp2) {
  2686         setTemp(0, temp);
  2687         setTemp(1, temp2);
  2689     const LDefinition *temp() {
  2690         return getTemp(0);
  2692     const LDefinition *temp2() {
  2693         return getTemp(1);
  2695 };
  2697 class LMathFunctionD : public LCallInstructionHelper<1, 1, 1>
  2699   public:
  2700     LIR_HEADER(MathFunctionD)
  2701     LMathFunctionD(const LAllocation &input, const LDefinition &temp) {
  2702         setOperand(0, input);
  2703         setTemp(0, temp);
  2706     const LDefinition *temp() {
  2707         return getTemp(0);
  2709     MMathFunction *mir() const {
  2710         return mir_->toMathFunction();
  2712     const char *extraName() const {
  2713         return MMathFunction::FunctionName(mir()->function());
  2715 };
  2717 class LMathFunctionF : public LCallInstructionHelper<1, 1, 1>
  2719   public:
  2720     LIR_HEADER(MathFunctionF)
  2721     LMathFunctionF(const LAllocation &input, const LDefinition &temp) {
  2722         setOperand(0, input);
  2723         setTemp(0, temp);
  2726     const LDefinition *temp() {
  2727         return getTemp(0);
  2729     MMathFunction *mir() const {
  2730         return mir_->toMathFunction();
  2732     const char *extraName() const {
  2733         return MMathFunction::FunctionName(mir()->function());
  2735 };
  2737 // Adds two integers, returning an integer value.
  2738 class LAddI : public LBinaryMath<0>
  2740     bool recoversInput_;
  2742   public:
  2743     LIR_HEADER(AddI)
  2745     LAddI()
  2746       : recoversInput_(false)
  2747     { }
  2749     const char *extraName() const {
  2750         return snapshot() ? "OverflowCheck" : nullptr;
  2753     virtual bool recoversInput() const {
  2754         return recoversInput_;
  2756     void setRecoversInput() {
  2757         recoversInput_ = true;
  2759 };
  2761 // Subtracts two integers, returning an integer value.
  2762 class LSubI : public LBinaryMath<0>
  2764     bool recoversInput_;
  2766   public:
  2767     LIR_HEADER(SubI)
  2769     LSubI()
  2770       : recoversInput_(false)
  2771     { }
  2773     const char *extraName() const {
  2774         return snapshot() ? "OverflowCheck" : nullptr;
  2777     virtual bool recoversInput() const {
  2778         return recoversInput_;
  2780     void setRecoversInput() {
  2781         recoversInput_ = true;
  2783 };
  2785 // Performs an add, sub, mul, or div on two double values.
  2786 class LMathD : public LBinaryMath<0>
  2788     JSOp jsop_;
  2790   public:
  2791     LIR_HEADER(MathD)
  2793     LMathD(JSOp jsop)
  2794       : jsop_(jsop)
  2795     { }
  2797     JSOp jsop() const {
  2798         return jsop_;
  2801     const char *extraName() const {
  2802         return js_CodeName[jsop_];
  2804 };
  2806 // Performs an add, sub, mul, or div on two double values.
  2807 class LMathF: public LBinaryMath<0>
  2809     JSOp jsop_;
  2811   public:
  2812     LIR_HEADER(MathF)
  2814     LMathF(JSOp jsop)
  2815       : jsop_(jsop)
  2816     { }
  2818     JSOp jsop() const {
  2819         return jsop_;
  2822     const char *extraName() const {
  2823         return js_CodeName[jsop_];
  2825 };
  2827 class LModD : public LBinaryMath<1>
  2829   public:
  2830     LIR_HEADER(ModD)
  2832     LModD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
  2833         setOperand(0, lhs);
  2834         setOperand(1, rhs);
  2835         setTemp(0, temp);
  2837     const LDefinition *temp() {
  2838         return getTemp(0);
  2840     bool isCall() const {
  2841         return true;
  2843 };
  2845 // Call a VM function to perform a binary operation.
  2846 class LBinaryV : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0>
  2848     JSOp jsop_;
  2850   public:
  2851     LIR_HEADER(BinaryV)
  2853     LBinaryV(JSOp jsop)
  2854       : jsop_(jsop)
  2855     { }
  2857     JSOp jsop() const {
  2858         return jsop_;
  2861     const char *extraName() const {
  2862         return js_CodeName[jsop_];
  2865     static const size_t LhsInput = 0;
  2866     static const size_t RhsInput = BOX_PIECES;
  2867 };
  2869 // Adds two string, returning a string.
  2870 class LConcat : public LInstructionHelper<1, 2, 5>
  2872   public:
  2873     LIR_HEADER(Concat)
  2875     LConcat(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp1,
  2876             const LDefinition &temp2, const LDefinition &temp3, const LDefinition &temp4,
  2877             const LDefinition &temp5)
  2879         setOperand(0, lhs);
  2880         setOperand(1, rhs);
  2881         setTemp(0, temp1);
  2882         setTemp(1, temp2);
  2883         setTemp(2, temp3);
  2884         setTemp(3, temp4);
  2885         setTemp(4, temp5);
  2888     const LAllocation *lhs() {
  2889         return this->getOperand(0);
  2891     const LAllocation *rhs() {
  2892         return this->getOperand(1);
  2894     const LDefinition *temp1() {
  2895         return this->getTemp(0);
  2897     const LDefinition *temp2() {
  2898         return this->getTemp(1);
  2900     const LDefinition *temp3() {
  2901         return this->getTemp(2);
  2903     const LDefinition *temp4() {
  2904         return this->getTemp(3);
  2906     const LDefinition *temp5() {
  2907         return this->getTemp(4);
  2909 };
  2911 class LConcatPar : public LInstructionHelper<1, 3, 4>
  2913   public:
  2914     LIR_HEADER(ConcatPar)
  2916     LConcatPar(const LAllocation &cx, const LAllocation &lhs, const LAllocation &rhs,
  2917                const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3,
  2918                const LDefinition &temp4)
  2920         setOperand(0, cx);
  2921         setOperand(1, lhs);
  2922         setOperand(2, rhs);
  2923         setTemp(0, temp1);
  2924         setTemp(1, temp2);
  2925         setTemp(2, temp3);
  2926         setTemp(3, temp4);
  2929     const LAllocation *forkJoinContext() {
  2930         return this->getOperand(0);
  2932     const LAllocation *lhs() {
  2933         return this->getOperand(1);
  2935     const LAllocation *rhs() {
  2936         return this->getOperand(2);
  2938     const LDefinition *temp1() {
  2939         return this->getTemp(0);
  2941     const LDefinition *temp2() {
  2942         return this->getTemp(1);
  2944     const LDefinition *temp3() {
  2945         return this->getTemp(2);
  2947     const LDefinition *temp4() {
  2948         return this->getTemp(3);
  2950 };
  2952 // Get uint16 character code from a string.
  2953 class LCharCodeAt : public LInstructionHelper<1, 2, 0>
  2955   public:
  2956     LIR_HEADER(CharCodeAt)
  2958     LCharCodeAt(const LAllocation &str, const LAllocation &index) {
  2959         setOperand(0, str);
  2960         setOperand(1, index);
  2963     const LAllocation *str() {
  2964         return this->getOperand(0);
  2966     const LAllocation *index() {
  2967         return this->getOperand(1);
  2969 };
  2971 // Convert uint16 character code to a string.
  2972 class LFromCharCode : public LInstructionHelper<1, 1, 0>
  2974   public:
  2975     LIR_HEADER(FromCharCode)
  2977     LFromCharCode(const LAllocation &code) {
  2978         setOperand(0, code);
  2981     const LAllocation *code() {
  2982         return this->getOperand(0);
  2984 };
  2986 class LStringSplit : public LCallInstructionHelper<1, 2, 0>
  2988   public:
  2989     LIR_HEADER(StringSplit)
  2991     LStringSplit(const LAllocation &string, const LAllocation &separator) {
  2992         setOperand(0, string);
  2993         setOperand(1, separator);
  2995     const LAllocation *string() {
  2996         return getOperand(0);
  2998     const LAllocation *separator() {
  2999         return getOperand(1);
  3001     const MStringSplit *mir() const {
  3002         return mir_->toStringSplit();
  3004 };
  3006 // Convert a 32-bit integer to a double.
  3007 class LInt32ToDouble : public LInstructionHelper<1, 1, 0>
  3009   public:
  3010     LIR_HEADER(Int32ToDouble)
  3012     LInt32ToDouble(const LAllocation &input) {
  3013         setOperand(0, input);
  3015 };
  3017 // Convert a 32-bit float to a double.
  3018 class LFloat32ToDouble : public LInstructionHelper<1, 1, 0>
  3020   public:
  3021     LIR_HEADER(Float32ToDouble)
  3023     LFloat32ToDouble(const LAllocation &input) {
  3024         setOperand(0, input);
  3026 };
  3028 // Convert a double to a 32-bit float.
  3029 class LDoubleToFloat32 : public LInstructionHelper<1, 1, 0>
  3031   public:
  3032     LIR_HEADER(DoubleToFloat32)
  3034     LDoubleToFloat32(const LAllocation &input) {
  3035         setOperand(0, input);
  3037 };
  3039 // Convert a 32-bit integer to a float32.
  3040 class LInt32ToFloat32 : public LInstructionHelper<1, 1, 0>
  3042   public:
  3043     LIR_HEADER(Int32ToFloat32)
  3045     LInt32ToFloat32(const LAllocation &input) {
  3046         setOperand(0, input);
  3048 };
  3050 // Convert a value to a double.
  3051 class LValueToDouble : public LInstructionHelper<1, BOX_PIECES, 0>
  3053   public:
  3054     LIR_HEADER(ValueToDouble)
  3055     static const size_t Input = 0;
  3057     MToDouble *mir() {
  3058         return mir_->toToDouble();
  3060 };
  3062 // Convert a value to a float32.
  3063 class LValueToFloat32 : public LInstructionHelper<1, BOX_PIECES, 0>
  3065   public:
  3066     LIR_HEADER(ValueToFloat32)
  3067     static const size_t Input = 0;
  3069     MToFloat32 *mir() {
  3070         return mir_->toToFloat32();
  3072 };
  3074 // Convert a value to an int32.
  3075 //   Input: components of a Value
  3076 //   Output: 32-bit integer
  3077 //   Bailout: undefined, string, object, or non-int32 double
  3078 //   Temps: one float register, one GP register
  3079 //
  3080 // This instruction requires a temporary float register.
  3081 class LValueToInt32 : public LInstructionHelper<1, BOX_PIECES, 2>
  3083   public:
  3084     enum Mode {
  3085         NORMAL,
  3086         TRUNCATE
  3087     };
  3089   private:
  3090     Mode mode_;
  3092   public:
  3093     LIR_HEADER(ValueToInt32)
  3095     LValueToInt32(const LDefinition &temp0, const LDefinition &temp1, Mode mode)
  3096       : mode_(mode)
  3098         setTemp(0, temp0);
  3099         setTemp(1, temp1);
  3102     const char *extraName() const {
  3103         return mode() == NORMAL ? "Normal" : "Truncate";
  3106     static const size_t Input = 0;
  3108     Mode mode() const {
  3109         return mode_;
  3111     const LDefinition *tempFloat() {
  3112         return getTemp(0);
  3114     const LDefinition *temp() {
  3115         return getTemp(1);
  3117     MToInt32 *mirNormal() const {
  3118         JS_ASSERT(mode_ == NORMAL);
  3119         return mir_->toToInt32();
  3121     MTruncateToInt32 *mirTruncate() const {
  3122         JS_ASSERT(mode_ == TRUNCATE);
  3123         return mir_->toTruncateToInt32();
  3125 };
  3127 // Convert a double to an int32.
  3128 //   Input: floating-point register
  3129 //   Output: 32-bit integer
  3130 //   Bailout: if the double cannot be converted to an integer.
  3131 class LDoubleToInt32 : public LInstructionHelper<1, 1, 0>
  3133   public:
  3134     LIR_HEADER(DoubleToInt32)
  3136     LDoubleToInt32(const LAllocation &in) {
  3137         setOperand(0, in);
  3140     MToInt32 *mir() const {
  3141         return mir_->toToInt32();
  3143 };
  3145 // Convert a float32 to an int32.
  3146 //   Input: floating-point register
  3147 //   Output: 32-bit integer
  3148 //   Bailout: if the float32 cannot be converted to an integer.
  3149 class LFloat32ToInt32 : public LInstructionHelper<1, 1, 0>
  3151   public:
  3152     LIR_HEADER(Float32ToInt32)
  3154     LFloat32ToInt32(const LAllocation &in) {
  3155         setOperand(0, in);
  3158     MToInt32 *mir() const {
  3159         return mir_->toToInt32();
  3161 };
  3163 // Convert a double to a truncated int32.
  3164 //   Input: floating-point register
  3165 //   Output: 32-bit integer
  3166 class LTruncateDToInt32 : public LInstructionHelper<1, 1, 1>
  3168   public:
  3169     LIR_HEADER(TruncateDToInt32)
  3171     LTruncateDToInt32(const LAllocation &in, const LDefinition &temp) {
  3172         setOperand(0, in);
  3173         setTemp(0, temp);
  3176     const LDefinition *tempFloat() {
  3177         return getTemp(0);
  3179 };
  3181 // Convert a float32 to a truncated int32.
  3182 //   Input: floating-point register
  3183 //   Output: 32-bit integer
  3184 class LTruncateFToInt32 : public LInstructionHelper<1, 1, 1>
  3186   public:
  3187     LIR_HEADER(TruncateFToInt32)
  3189     LTruncateFToInt32(const LAllocation &in, const LDefinition &temp) {
  3190         setOperand(0, in);
  3191         setTemp(0, temp);
  3194     const LDefinition *tempFloat() {
  3195         return getTemp(0);
  3197 };
  3199 // Convert a boolean value to a string.
  3200 class LBooleanToString : public LInstructionHelper<1, 1, 0>
  3202   public:
  3203     LIR_HEADER(BooleanToString)
  3205     LBooleanToString(const LAllocation &input) {
  3206         setOperand(0, input);
  3209     const MToString *mir() {
  3210         return mir_->toToString();
  3212 };
  3214 // Convert an integer hosted on one definition to a string with a function call.
  3215 class LIntToString : public LInstructionHelper<1, 1, 0>
  3217   public:
  3218     LIR_HEADER(IntToString)
  3220     LIntToString(const LAllocation &input) {
  3221         setOperand(0, input);
  3224     const MToString *mir() {
  3225         return mir_->toToString();
  3227 };
  3229 // Convert a double hosted on one definition to a string with a function call.
  3230 class LDoubleToString : public LInstructionHelper<1, 1, 1>
  3232   public:
  3233     LIR_HEADER(DoubleToString)
  3235     LDoubleToString(const LAllocation &input, const LDefinition &temp) {
  3236         setOperand(0, input);
  3237         setTemp(0, temp);
  3240     const LDefinition *tempInt() {
  3241         return getTemp(0);
  3243     const MToString *mir() {
  3244         return mir_->toToString();
  3246 };
  3248 // Convert a primitive to a string with a function call.
  3249 class LPrimitiveToString : public LInstructionHelper<1, BOX_PIECES, 1>
  3251   public:
  3252     LIR_HEADER(PrimitiveToString)
  3254     LPrimitiveToString(const LDefinition &tempToUnbox)
  3256         setTemp(0, tempToUnbox);
  3259     static const size_t Input = 0;
  3261     const MToString *mir() {
  3262         return mir_->toToString();
  3265     const LDefinition *tempToUnbox() {
  3266         return getTemp(0);
  3268 };
  3270 // No-op instruction that is used to hold the entry snapshot. This simplifies
  3271 // register allocation as it doesn't need to sniff the snapshot out of the
  3272 // LIRGraph.
  3273 class LStart : public LInstructionHelper<0, 0, 0>
  3275   public:
  3276     LIR_HEADER(Start)
  3277 };
  3279 // Passed the BaselineFrame address in the OsrFrameReg by SideCannon().
  3280 // Forwards this object to the LOsrValues for Value materialization.
  3281 class LOsrEntry : public LInstructionHelper<1, 0, 0>
  3283   protected:
  3284     Label label_;
  3285     uint32_t frameDepth_;
  3287   public:
  3288     LIR_HEADER(OsrEntry)
  3290     LOsrEntry()
  3291       : frameDepth_(0)
  3292     { }
  3294     void setFrameDepth(uint32_t depth) {
  3295         frameDepth_ = depth;
  3297     uint32_t getFrameDepth() {
  3298         return frameDepth_;
  3300     Label *label() {
  3301         return &label_;
  3304 };
  3306 // Materialize a Value stored in an interpreter frame for OSR.
  3307 class LOsrValue : public LInstructionHelper<BOX_PIECES, 1, 0>
  3309   public:
  3310     LIR_HEADER(OsrValue)
  3312     LOsrValue(const LAllocation &entry)
  3314         setOperand(0, entry);
  3317     const MOsrValue *mir() {
  3318         return mir_->toOsrValue();
  3320 };
  3322 // Materialize a JSObject scope chain stored in an interpreter frame for OSR.
  3323 class LOsrScopeChain : public LInstructionHelper<1, 1, 0>
  3325   public:
  3326     LIR_HEADER(OsrScopeChain)
  3328     LOsrScopeChain(const LAllocation &entry)
  3330         setOperand(0, entry);
  3333     const MOsrScopeChain *mir() {
  3334         return mir_->toOsrScopeChain();
  3336 };
  3338 // Materialize a JSObject scope chain stored in an interpreter frame for OSR.
  3339 class LOsrReturnValue : public LInstructionHelper<BOX_PIECES, 1, 0>
  3341   public:
  3342     LIR_HEADER(OsrReturnValue)
  3344     LOsrReturnValue(const LAllocation &entry)
  3346         setOperand(0, entry);
  3349     const MOsrReturnValue *mir() {
  3350         return mir_->toOsrReturnValue();
  3352 };
  3354 // Materialize a JSObject ArgumentsObject stored in an interpreter frame for OSR.
  3355 class LOsrArgumentsObject : public LInstructionHelper<1, 1, 0>
  3357   public:
  3358     LIR_HEADER(OsrArgumentsObject)
  3360     LOsrArgumentsObject(const LAllocation &entry)
  3362         setOperand(0, entry);
  3365     const MOsrArgumentsObject *mir() {
  3366         return mir_->toOsrArgumentsObject();
  3368 };
  3370 class LRegExp : public LCallInstructionHelper<1, 0, 0>
  3372   public:
  3373     LIR_HEADER(RegExp)
  3375     const MRegExp *mir() const {
  3376         return mir_->toRegExp();
  3378 };
  3380 class LRegExpExec : public LCallInstructionHelper<BOX_PIECES, 2, 0>
  3382   public:
  3383     LIR_HEADER(RegExpExec)
  3385     LRegExpExec(const LAllocation &regexp, const LAllocation &string)
  3387         setOperand(0, regexp);
  3388         setOperand(1, string);
  3391     const LAllocation *regexp() {
  3392         return getOperand(0);
  3394     const LAllocation *string() {
  3395         return getOperand(1);
  3398     const MRegExpExec *mir() const {
  3399         return mir_->toRegExpExec();
  3401 };
  3403 class LRegExpTest : public LCallInstructionHelper<1, 2, 0>
  3405   public:
  3406     LIR_HEADER(RegExpTest)
  3408     LRegExpTest(const LAllocation &regexp, const LAllocation &string)
  3410         setOperand(0, regexp);
  3411         setOperand(1, string);
  3414     const LAllocation *regexp() {
  3415         return getOperand(0);
  3417     const LAllocation *string() {
  3418         return getOperand(1);
  3421     const MRegExpTest *mir() const {
  3422         return mir_->toRegExpTest();
  3424 };
  3427 class LStrReplace : public LCallInstructionHelper<1, 3, 0>
  3429   public:
  3430     LStrReplace(const LAllocation &string, const LAllocation &pattern,
  3431                    const LAllocation &replacement)
  3433         setOperand(0, string);
  3434         setOperand(1, pattern);
  3435         setOperand(2, replacement);
  3438     const LAllocation *string() {
  3439         return getOperand(0);
  3441     const LAllocation *pattern() {
  3442         return getOperand(1);
  3444     const LAllocation *replacement() {
  3445         return getOperand(2);
  3447 };
  3449 class LRegExpReplace: public LStrReplace
  3451   public:
  3452     LIR_HEADER(RegExpReplace);
  3454     LRegExpReplace(const LAllocation &string, const LAllocation &pattern,
  3455                    const LAllocation &replacement)
  3456       : LStrReplace(string, pattern, replacement)
  3460     const MRegExpReplace *mir() const {
  3461         return mir_->toRegExpReplace();
  3463 };
  3465 class LStringReplace: public LStrReplace
  3467   public:
  3468     LIR_HEADER(StringReplace);
  3470     LStringReplace(const LAllocation &string, const LAllocation &pattern,
  3471                    const LAllocation &replacement)
  3472       : LStrReplace(string, pattern, replacement)
  3476     const MStringReplace *mir() const {
  3477         return mir_->toStringReplace();
  3479 };
  3481 class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
  3483   public:
  3484     LIR_HEADER(LambdaForSingleton)
  3486     LLambdaForSingleton(const LAllocation &scopeChain)
  3488         setOperand(0, scopeChain);
  3490     const LAllocation *scopeChain() {
  3491         return getOperand(0);
  3493     const MLambda *mir() const {
  3494         return mir_->toLambda();
  3496 };
  3498 class LLambda : public LInstructionHelper<1, 1, 1>
  3500   public:
  3501     LIR_HEADER(Lambda)
  3503     LLambda(const LAllocation &scopeChain, const LDefinition &temp) {
  3504         setOperand(0, scopeChain);
  3505         setTemp(0, temp);
  3507     const LAllocation *scopeChain() {
  3508         return getOperand(0);
  3510     const LDefinition *temp() {
  3511         return getTemp(0);
  3513     const MLambda *mir() const {
  3514         return mir_->toLambda();
  3516 };
  3518 class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1>
  3520   public:
  3521     LIR_HEADER(LambdaArrow)
  3523     static const size_t ThisValue = 1;
  3525     LLambdaArrow(const LAllocation &scopeChain, const LDefinition &temp) {
  3526         setOperand(0, scopeChain);
  3527         setTemp(0, temp);
  3529     const LAllocation *scopeChain() {
  3530         return getOperand(0);
  3532     const LDefinition *temp() {
  3533         return getTemp(0);
  3535     const MLambdaArrow *mir() const {
  3536         return mir_->toLambdaArrow();
  3538 };
  3540 class LLambdaPar : public LInstructionHelper<1, 2, 2>
  3542   public:
  3543     LIR_HEADER(LambdaPar);
  3545     LLambdaPar(const LAllocation &cx, const LAllocation &scopeChain,
  3546                const LDefinition &temp1, const LDefinition &temp2)
  3548         setOperand(0, cx);
  3549         setOperand(1, scopeChain);
  3550         setTemp(0, temp1);
  3551         setTemp(1, temp2);
  3553     const LAllocation *forkJoinContext() {
  3554         return getOperand(0);
  3556     const LAllocation *scopeChain() {
  3557         return getOperand(1);
  3559     const MLambdaPar *mir() const {
  3560         return mir_->toLambdaPar();
  3562     const LDefinition *getTemp0() {
  3563         return getTemp(0);
  3565     const LDefinition *getTemp1() {
  3566         return getTemp(1);
  3568 };
  3570 // Determines the implicit |this| value for function calls.
  3571 class LImplicitThis : public LInstructionHelper<BOX_PIECES, 1, 0>
  3573   public:
  3574     LIR_HEADER(ImplicitThis)
  3576     LImplicitThis(const LAllocation &callee) {
  3577         setOperand(0, callee);
  3580     const MImplicitThis *mir() const {
  3581         return mir_->toImplicitThis();
  3583     const LAllocation *callee() {
  3584         return getOperand(0);
  3586 };
  3588 // Load the "slots" member out of a JSObject.
  3589 //   Input: JSObject pointer
  3590 //   Output: slots pointer
  3591 class LSlots : public LInstructionHelper<1, 1, 0>
  3593   public:
  3594     LIR_HEADER(Slots)
  3596     LSlots(const LAllocation &object) {
  3597         setOperand(0, object);
  3600     const LAllocation *object() {
  3601         return getOperand(0);
  3603 };
  3605 // Load the "elements" member out of a JSObject.
  3606 //   Input: JSObject pointer
  3607 //   Output: elements pointer
  3608 class LElements : public LInstructionHelper<1, 1, 0>
  3610   public:
  3611     LIR_HEADER(Elements)
  3613     LElements(const LAllocation &object) {
  3614         setOperand(0, object);
  3617     const LAllocation *object() {
  3618         return getOperand(0);
  3620 };
  3622 // If necessary, convert any int32 elements in a vector into doubles.
  3623 class LConvertElementsToDoubles : public LInstructionHelper<0, 1, 0>
  3625   public:
  3626     LIR_HEADER(ConvertElementsToDoubles)
  3628     LConvertElementsToDoubles(const LAllocation &elements) {
  3629         setOperand(0, elements);
  3632     const LAllocation *elements() {
  3633         return getOperand(0);
  3635 };
  3637 // If |elements| has the CONVERT_DOUBLE_ELEMENTS flag, convert int32 value to
  3638 // double. Else return the original value.
  3639 class LMaybeToDoubleElement : public LInstructionHelper<BOX_PIECES, 2, 1>
  3641   public:
  3642     LIR_HEADER(MaybeToDoubleElement)
  3644     LMaybeToDoubleElement(const LAllocation &elements, const LAllocation &value,
  3645                           const LDefinition &tempFloat) {
  3646         setOperand(0, elements);
  3647         setOperand(1, value);
  3648         setTemp(0, tempFloat);
  3651     const LAllocation *elements() {
  3652         return getOperand(0);
  3654     const LAllocation *value() {
  3655         return getOperand(1);
  3657     const LDefinition *tempFloat() {
  3658         return getTemp(0);
  3660 };
  3662 // Load the initialized length from an elements header.
  3663 class LInitializedLength : public LInstructionHelper<1, 1, 0>
  3665   public:
  3666     LIR_HEADER(InitializedLength)
  3668     LInitializedLength(const LAllocation &elements) {
  3669         setOperand(0, elements);
  3672     const LAllocation *elements() {
  3673         return getOperand(0);
  3675 };
  3677 // Store to the initialized length in an elements header. Note the input is an
  3678 // *index*, one less than the desired initialized length.
  3679 class LSetInitializedLength : public LInstructionHelper<0, 2, 0>
  3681   public:
  3682     LIR_HEADER(SetInitializedLength)
  3684     LSetInitializedLength(const LAllocation &elements, const LAllocation &index) {
  3685         setOperand(0, elements);
  3686         setOperand(1, index);
  3689     const LAllocation *elements() {
  3690         return getOperand(0);
  3692     const LAllocation *index() {
  3693         return getOperand(1);
  3695 };
  3697 // Load the length from an elements header.
  3698 class LArrayLength : public LInstructionHelper<1, 1, 0>
  3700   public:
  3701     LIR_HEADER(ArrayLength)
  3703     LArrayLength(const LAllocation &elements) {
  3704         setOperand(0, elements);
  3707     const LAllocation *elements() {
  3708         return getOperand(0);
  3710 };
  3712 // Store to the length in an elements header. Note the input is an *index*,
  3713 // one less than the desired length.
  3714 class LSetArrayLength : public LInstructionHelper<0, 2, 0>
  3716   public:
  3717     LIR_HEADER(SetArrayLength)
  3719     LSetArrayLength(const LAllocation &elements, const LAllocation &index) {
  3720         setOperand(0, elements);
  3721         setOperand(1, index);
  3724     const LAllocation *elements() {
  3725         return getOperand(0);
  3727     const LAllocation *index() {
  3728         return getOperand(1);
  3730 };
  3732 // Read the length of a typed array.
  3733 class LTypedArrayLength : public LInstructionHelper<1, 1, 0>
  3735   public:
  3736     LIR_HEADER(TypedArrayLength)
  3738     LTypedArrayLength(const LAllocation &obj) {
  3739         setOperand(0, obj);
  3742     const LAllocation *object() {
  3743         return getOperand(0);
  3745 };
  3747 // Load a typed array's elements vector.
  3748 class LTypedArrayElements : public LInstructionHelper<1, 1, 0>
  3750   public:
  3751     LIR_HEADER(TypedArrayElements)
  3753     LTypedArrayElements(const LAllocation &object) {
  3754         setOperand(0, object);
  3756     const LAllocation *object() {
  3757         return getOperand(0);
  3759 };
  3761 // Load a typed array's elements vector.
  3762 class LTypedObjectElements : public LInstructionHelper<1, 1, 0>
  3764   public:
  3765     LIR_HEADER(TypedObjectElements)
  3767     LTypedObjectElements(const LAllocation &object) {
  3768         setOperand(0, object);
  3770     const LAllocation *object() {
  3771         return getOperand(0);
  3773     const MTypedObjectElements *mir() const {
  3774         return mir_->toTypedObjectElements();
  3776 };
  3778 // Load a typed array's elements vector.
  3779 class LSetTypedObjectOffset : public LInstructionHelper<0, 2, 1>
  3781   public:
  3782     LIR_HEADER(SetTypedObjectOffset)
  3784     LSetTypedObjectOffset(const LAllocation &object,
  3785                           const LAllocation &offset,
  3786                           const LDefinition &temp0)
  3788         setOperand(0, object);
  3789         setOperand(1, offset);
  3790         setTemp(0, temp0);
  3792     const LAllocation *object() {
  3793         return getOperand(0);
  3795     const LAllocation *offset() {
  3796         return getOperand(1);
  3798     const LDefinition *temp0() {
  3799         return getTemp(0);
  3801 };
  3803 // Check whether a typed object has a neutered owner buffer.
  3804 class LNeuterCheck : public LInstructionHelper<0, 1, 1>
  3806   public:
  3807     LIR_HEADER(NeuterCheck)
  3809     LNeuterCheck(const LAllocation &object, const LDefinition &temp) {
  3810         setOperand(0, object);
  3811         setTemp(0, temp);
  3813     const LAllocation *object() {
  3814         return getOperand(0);
  3816     const LDefinition *temp() {
  3817         return getTemp(0);
  3819 };
  3821 // Bailout if index >= length.
  3822 class LBoundsCheck : public LInstructionHelper<0, 2, 0>
  3824   public:
  3825     LIR_HEADER(BoundsCheck)
  3827     LBoundsCheck(const LAllocation &index, const LAllocation &length) {
  3828         setOperand(0, index);
  3829         setOperand(1, length);
  3831     const MBoundsCheck *mir() const {
  3832         return mir_->toBoundsCheck();
  3834     const LAllocation *index() {
  3835         return getOperand(0);
  3837     const LAllocation *length() {
  3838         return getOperand(1);
  3840 };
  3842 // Bailout if index + minimum < 0 or index + maximum >= length.
  3843 class LBoundsCheckRange : public LInstructionHelper<0, 2, 1>
  3845   public:
  3846     LIR_HEADER(BoundsCheckRange)
  3848     LBoundsCheckRange(const LAllocation &index, const LAllocation &length,
  3849                       const LDefinition &temp)
  3851         setOperand(0, index);
  3852         setOperand(1, length);
  3853         setTemp(0, temp);
  3855     const MBoundsCheck *mir() const {
  3856         return mir_->toBoundsCheck();
  3858     const LAllocation *index() {
  3859         return getOperand(0);
  3861     const LAllocation *length() {
  3862         return getOperand(1);
  3864 };
  3866 // Bailout if index < minimum.
  3867 class LBoundsCheckLower : public LInstructionHelper<0, 1, 0>
  3869   public:
  3870     LIR_HEADER(BoundsCheckLower)
  3872     LBoundsCheckLower(const LAllocation &index)
  3874         setOperand(0, index);
  3876     MBoundsCheckLower *mir() const {
  3877         return mir_->toBoundsCheckLower();
  3879     const LAllocation *index() {
  3880         return getOperand(0);
  3882 };
  3884 // Load a value from a dense array's elements vector. Bail out if it's the hole value.
  3885 class LLoadElementV : public LInstructionHelper<BOX_PIECES, 2, 0>
  3887   public:
  3888     LIR_HEADER(LoadElementV)
  3890     LLoadElementV(const LAllocation &elements, const LAllocation &index) {
  3891         setOperand(0, elements);
  3892         setOperand(1, index);
  3895     const char *extraName() const {
  3896         return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
  3899     const MLoadElement *mir() const {
  3900         return mir_->toLoadElement();
  3902     const LAllocation *elements() {
  3903         return getOperand(0);
  3905     const LAllocation *index() {
  3906         return getOperand(1);
  3908 };
  3910 class LInArray : public LInstructionHelper<1, 4, 0>
  3912   public:
  3913     LIR_HEADER(InArray)
  3915     LInArray(const LAllocation &elements, const LAllocation &index,
  3916              const LAllocation &initLength, const LAllocation &object)
  3918         setOperand(0, elements);
  3919         setOperand(1, index);
  3920         setOperand(2, initLength);
  3921         setOperand(3, object);
  3923     const MInArray *mir() const {
  3924         return mir_->toInArray();
  3926     const LAllocation *elements() {
  3927         return getOperand(0);
  3929     const LAllocation *index() {
  3930         return getOperand(1);
  3932     const LAllocation *initLength() {
  3933         return getOperand(2);
  3935     const LAllocation *object() {
  3936         return getOperand(3);
  3938 };
  3941 // Load a value from a dense array's elements vector. Bail out if it's the hole value.
  3942 class LLoadElementHole : public LInstructionHelper<BOX_PIECES, 3, 0>
  3944   public:
  3945     LIR_HEADER(LoadElementHole)
  3947     LLoadElementHole(const LAllocation &elements, const LAllocation &index, const LAllocation &initLength) {
  3948         setOperand(0, elements);
  3949         setOperand(1, index);
  3950         setOperand(2, initLength);
  3953     const char *extraName() const {
  3954         return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
  3957     const MLoadElementHole *mir() const {
  3958         return mir_->toLoadElementHole();
  3960     const LAllocation *elements() {
  3961         return getOperand(0);
  3963     const LAllocation *index() {
  3964         return getOperand(1);
  3966     const LAllocation *initLength() {
  3967         return getOperand(2);
  3969 };
  3971 // Load a typed value from a dense array's elements vector. The array must be
  3972 // known to be packed, so that we don't have to check for the hole value.
  3973 // This instruction does not load the type tag and can directly load into a
  3974 // FP register.
  3975 class LLoadElementT : public LInstructionHelper<1, 2, 0>
  3977   public:
  3978     LIR_HEADER(LoadElementT)
  3980     LLoadElementT(const LAllocation &elements, const LAllocation &index) {
  3981         setOperand(0, elements);
  3982         setOperand(1, index);
  3985     const char *extraName() const {
  3986         return mir()->needsHoleCheck() ? "HoleCheck"
  3987                                        : (mir()->loadDoubles() ? "Doubles" : nullptr);
  3990     const MLoadElement *mir() const {
  3991         return mir_->toLoadElement();
  3993     const LAllocation *elements() {
  3994         return getOperand(0);
  3996     const LAllocation *index() {
  3997         return getOperand(1);
  3999 };
  4001 // Store a boxed value to a dense array's element vector.
  4002 class LStoreElementV : public LInstructionHelper<0, 2 + BOX_PIECES, 0>
  4004   public:
  4005     LIR_HEADER(StoreElementV)
  4007     LStoreElementV(const LAllocation &elements, const LAllocation &index) {
  4008         setOperand(0, elements);
  4009         setOperand(1, index);
  4012     const char *extraName() const {
  4013         return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
  4016     static const size_t Value = 2;
  4018     const MStoreElement *mir() const {
  4019         return mir_->toStoreElement();
  4021     const LAllocation *elements() {
  4022         return getOperand(0);
  4024     const LAllocation *index() {
  4025         return getOperand(1);
  4027 };
  4029 // Store a typed value to a dense array's elements vector. Compared to
  4030 // LStoreElementV, this instruction can store doubles and constants directly,
  4031 // and does not store the type tag if the array is monomorphic and known to
  4032 // be packed.
  4033 class LStoreElementT : public LInstructionHelper<0, 3, 0>
  4035   public:
  4036     LIR_HEADER(StoreElementT)
  4038     LStoreElementT(const LAllocation &elements, const LAllocation &index, const LAllocation &value) {
  4039         setOperand(0, elements);
  4040         setOperand(1, index);
  4041         setOperand(2, value);
  4044     const char *extraName() const {
  4045         return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
  4048     const MStoreElement *mir() const {
  4049         return mir_->toStoreElement();
  4051     const LAllocation *elements() {
  4052         return getOperand(0);
  4054     const LAllocation *index() {
  4055         return getOperand(1);
  4057     const LAllocation *value() {
  4058         return getOperand(2);
  4060 };
  4062 // Like LStoreElementV, but supports indexes >= initialized length.
  4063 class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 0>
  4065   public:
  4066     LIR_HEADER(StoreElementHoleV)
  4068     LStoreElementHoleV(const LAllocation &object, const LAllocation &elements,
  4069                        const LAllocation &index) {
  4070         setOperand(0, object);
  4071         setOperand(1, elements);
  4072         setOperand(2, index);
  4075     static const size_t Value = 3;
  4077     const MStoreElementHole *mir() const {
  4078         return mir_->toStoreElementHole();
  4080     const LAllocation *object() {
  4081         return getOperand(0);
  4083     const LAllocation *elements() {
  4084         return getOperand(1);
  4086     const LAllocation *index() {
  4087         return getOperand(2);
  4089 };
  4091 // Like LStoreElementT, but supports indexes >= initialized length.
  4092 class LStoreElementHoleT : public LInstructionHelper<0, 4, 0>
  4094   public:
  4095     LIR_HEADER(StoreElementHoleT)
  4097     LStoreElementHoleT(const LAllocation &object, const LAllocation &elements,
  4098                        const LAllocation &index, const LAllocation &value) {
  4099         setOperand(0, object);
  4100         setOperand(1, elements);
  4101         setOperand(2, index);
  4102         setOperand(3, value);
  4105     const MStoreElementHole *mir() const {
  4106         return mir_->toStoreElementHole();
  4108     const LAllocation *object() {
  4109         return getOperand(0);
  4111     const LAllocation *elements() {
  4112         return getOperand(1);
  4114     const LAllocation *index() {
  4115         return getOperand(2);
  4117     const LAllocation *value() {
  4118         return getOperand(3);
  4120 };
  4122 class LArrayPopShiftV : public LInstructionHelper<BOX_PIECES, 1, 2>
  4124   public:
  4125     LIR_HEADER(ArrayPopShiftV)
  4127     LArrayPopShiftV(const LAllocation &object, const LDefinition &temp0, const LDefinition &temp1) {
  4128         setOperand(0, object);
  4129         setTemp(0, temp0);
  4130         setTemp(1, temp1);
  4133     const char *extraName() const {
  4134         return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift";
  4137     const MArrayPopShift *mir() const {
  4138         return mir_->toArrayPopShift();
  4140     const LAllocation *object() {
  4141         return getOperand(0);
  4143     const LDefinition *temp0() {
  4144         return getTemp(0);
  4146     const LDefinition *temp1() {
  4147         return getTemp(1);
  4149 };
  4151 class LArrayPopShiftT : public LInstructionHelper<1, 1, 2>
  4153   public:
  4154     LIR_HEADER(ArrayPopShiftT)
  4156     LArrayPopShiftT(const LAllocation &object, const LDefinition &temp0, const LDefinition &temp1) {
  4157         setOperand(0, object);
  4158         setTemp(0, temp0);
  4159         setTemp(1, temp1);
  4162     const char *extraName() const {
  4163         return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift";
  4166     const MArrayPopShift *mir() const {
  4167         return mir_->toArrayPopShift();
  4169     const LAllocation *object() {
  4170         return getOperand(0);
  4172     const LDefinition *temp0() {
  4173         return getTemp(0);
  4175     const LDefinition *temp1() {
  4176         return getTemp(1);
  4178 };
  4180 class LArrayPushV : public LInstructionHelper<1, 1 + BOX_PIECES, 1>
  4182   public:
  4183     LIR_HEADER(ArrayPushV)
  4185     LArrayPushV(const LAllocation &object, const LDefinition &temp) {
  4186         setOperand(0, object);
  4187         setTemp(0, temp);
  4190     static const size_t Value = 1;
  4192     const MArrayPush *mir() const {
  4193         return mir_->toArrayPush();
  4195     const LAllocation *object() {
  4196         return getOperand(0);
  4198     const LDefinition *temp() {
  4199         return getTemp(0);
  4201 };
  4203 class LArrayPushT : public LInstructionHelper<1, 2, 1>
  4205   public:
  4206     LIR_HEADER(ArrayPushT)
  4208     LArrayPushT(const LAllocation &object, const LAllocation &value, const LDefinition &temp) {
  4209         setOperand(0, object);
  4210         setOperand(1, value);
  4211         setTemp(0, temp);
  4214     const MArrayPush *mir() const {
  4215         return mir_->toArrayPush();
  4217     const LAllocation *object() {
  4218         return getOperand(0);
  4220     const LAllocation *value() {
  4221         return getOperand(1);
  4223     const LDefinition *temp() {
  4224         return getTemp(0);
  4226 };
  4228 class LArrayConcat : public LCallInstructionHelper<1, 2, 2>
  4230   public:
  4231     LIR_HEADER(ArrayConcat)
  4233     LArrayConcat(const LAllocation &lhs, const LAllocation &rhs,
  4234                  const LDefinition &temp1, const LDefinition &temp2) {
  4235         setOperand(0, lhs);
  4236         setOperand(1, rhs);
  4237         setTemp(0, temp1);
  4238         setTemp(1, temp2);
  4240     const MArrayConcat *mir() const {
  4241         return mir_->toArrayConcat();
  4243     const LAllocation *lhs() {
  4244         return getOperand(0);
  4246     const LAllocation *rhs() {
  4247         return getOperand(1);
  4249     const LDefinition *temp1() {
  4250         return getTemp(0);
  4252     const LDefinition *temp2() {
  4253         return getTemp(1);
  4255 };
  4257 // Load a typed value from a typed array's elements vector.
  4258 class LLoadTypedArrayElement : public LInstructionHelper<1, 2, 1>
  4260   public:
  4261     LIR_HEADER(LoadTypedArrayElement)
  4263     LLoadTypedArrayElement(const LAllocation &elements, const LAllocation &index,
  4264                            const LDefinition &temp) {
  4265         setOperand(0, elements);
  4266         setOperand(1, index);
  4267         setTemp(0, temp);
  4269     const MLoadTypedArrayElement *mir() const {
  4270         return mir_->toLoadTypedArrayElement();
  4272     const LAllocation *elements() {
  4273         return getOperand(0);
  4275     const LAllocation *index() {
  4276         return getOperand(1);
  4278     const LDefinition *temp() {
  4279         return getTemp(0);
  4281 };
  4283 class LLoadTypedArrayElementHole : public LInstructionHelper<BOX_PIECES, 2, 0>
  4285   public:
  4286     LIR_HEADER(LoadTypedArrayElementHole)
  4288     LLoadTypedArrayElementHole(const LAllocation &object, const LAllocation &index) {
  4289         setOperand(0, object);
  4290         setOperand(1, index);
  4292     const MLoadTypedArrayElementHole *mir() const {
  4293         return mir_->toLoadTypedArrayElementHole();
  4295     const LAllocation *object() {
  4296         return getOperand(0);
  4298     const LAllocation *index() {
  4299         return getOperand(1);
  4301 };
  4303 class LLoadTypedArrayElementStatic : public LInstructionHelper<1, 1, 0>
  4305   public:
  4306     LIR_HEADER(LoadTypedArrayElementStatic);
  4307     LLoadTypedArrayElementStatic(const LAllocation &ptr) {
  4308         setOperand(0, ptr);
  4310     MLoadTypedArrayElementStatic *mir() const {
  4311         return mir_->toLoadTypedArrayElementStatic();
  4313     const LAllocation *ptr() {
  4314         return getOperand(0);
  4316 };
  4318 class LStoreTypedArrayElement : public LInstructionHelper<0, 3, 0>
  4320   public:
  4321     LIR_HEADER(StoreTypedArrayElement)
  4323     LStoreTypedArrayElement(const LAllocation &elements, const LAllocation &index,
  4324                             const LAllocation &value) {
  4325         setOperand(0, elements);
  4326         setOperand(1, index);
  4327         setOperand(2, value);
  4330     const MStoreTypedArrayElement *mir() const {
  4331         return mir_->toStoreTypedArrayElement();
  4333     const LAllocation *elements() {
  4334         return getOperand(0);
  4336     const LAllocation *index() {
  4337         return getOperand(1);
  4339     const LAllocation *value() {
  4340         return getOperand(2);
  4342 };
  4344 class LStoreTypedArrayElementHole : public LInstructionHelper<0, 4, 0>
  4346   public:
  4347     LIR_HEADER(StoreTypedArrayElementHole)
  4349     LStoreTypedArrayElementHole(const LAllocation &elements, const LAllocation &length,
  4350                                 const LAllocation &index, const LAllocation &value)
  4352         setOperand(0, elements);
  4353         setOperand(1, length);
  4354         setOperand(2, index);
  4355         setOperand(3, value);
  4358     const MStoreTypedArrayElementHole *mir() const {
  4359         return mir_->toStoreTypedArrayElementHole();
  4361     const LAllocation *elements() {
  4362         return getOperand(0);
  4364     const LAllocation *length() {
  4365         return getOperand(1);
  4367     const LAllocation *index() {
  4368         return getOperand(2);
  4370     const LAllocation *value() {
  4371         return getOperand(3);
  4373 };
  4375 class LStoreTypedArrayElementStatic : public LInstructionHelper<0, 2, 0>
  4377   public:
  4378     LIR_HEADER(StoreTypedArrayElementStatic);
  4379     LStoreTypedArrayElementStatic(const LAllocation &ptr, const LAllocation &value) {
  4380         setOperand(0, ptr);
  4381         setOperand(1, value);
  4383     MStoreTypedArrayElementStatic *mir() const {
  4384         return mir_->toStoreTypedArrayElementStatic();
  4386     const LAllocation *ptr() {
  4387         return getOperand(0);
  4389     const LAllocation *value() {
  4390         return getOperand(1);
  4392 };
  4394 class LEffectiveAddress : public LInstructionHelper<1, 2, 0>
  4396   public:
  4397     LIR_HEADER(EffectiveAddress);
  4399     LEffectiveAddress(const LAllocation &base, const LAllocation &index) {
  4400         setOperand(0, base);
  4401         setOperand(1, index);
  4403     const MEffectiveAddress *mir() const {
  4404         return mir_->toEffectiveAddress();
  4406     const LAllocation *base() {
  4407         return getOperand(0);
  4409     const LAllocation *index() {
  4410         return getOperand(1);
  4412 };
  4414 class LClampIToUint8 : public LInstructionHelper<1, 1, 0>
  4416   public:
  4417     LIR_HEADER(ClampIToUint8)
  4419     LClampIToUint8(const LAllocation &in) {
  4420         setOperand(0, in);
  4422 };
  4424 class LClampDToUint8 : public LInstructionHelper<1, 1, 1>
  4426   public:
  4427     LIR_HEADER(ClampDToUint8)
  4429     LClampDToUint8(const LAllocation &in, const LDefinition &temp) {
  4430         setOperand(0, in);
  4431         setTemp(0, temp);
  4433 };
  4435 class LClampVToUint8 : public LInstructionHelper<1, BOX_PIECES, 1>
  4437   public:
  4438     LIR_HEADER(ClampVToUint8)
  4440     LClampVToUint8(const LDefinition &tempFloat) {
  4441         setTemp(0, tempFloat);
  4444     static const size_t Input = 0;
  4446     const LDefinition *tempFloat() {
  4447         return getTemp(0);
  4449     const MClampToUint8 *mir() const {
  4450         return mir_->toClampToUint8();
  4452 };
  4454 // Load a boxed value from an object's fixed slot.
  4455 class LLoadFixedSlotV : public LInstructionHelper<BOX_PIECES, 1, 0>
  4457   public:
  4458     LIR_HEADER(LoadFixedSlotV)
  4460     LLoadFixedSlotV(const LAllocation &object) {
  4461         setOperand(0, object);
  4463     const MLoadFixedSlot *mir() const {
  4464         return mir_->toLoadFixedSlot();
  4466 };
  4468 // Load a typed value from an object's fixed slot.
  4469 class LLoadFixedSlotT : public LInstructionHelper<1, 1, 0>
  4471   public:
  4472     LIR_HEADER(LoadFixedSlotT)
  4474     LLoadFixedSlotT(const LAllocation &object) {
  4475         setOperand(0, object);
  4477     const MLoadFixedSlot *mir() const {
  4478         return mir_->toLoadFixedSlot();
  4480 };
  4482 // Store a boxed value to an object's fixed slot.
  4483 class LStoreFixedSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0>
  4485   public:
  4486     LIR_HEADER(StoreFixedSlotV)
  4488     LStoreFixedSlotV(const LAllocation &obj) {
  4489         setOperand(0, obj);
  4492     static const size_t Value = 1;
  4494     const MStoreFixedSlot *mir() const {
  4495         return mir_->toStoreFixedSlot();
  4497     const LAllocation *obj() {
  4498         return getOperand(0);
  4500 };
  4502 // Store a typed value to an object's fixed slot.
  4503 class LStoreFixedSlotT : public LInstructionHelper<0, 2, 0>
  4505   public:
  4506     LIR_HEADER(StoreFixedSlotT)
  4508     LStoreFixedSlotT(const LAllocation &obj, const LAllocation &value)
  4510         setOperand(0, obj);
  4511         setOperand(1, value);
  4513     const MStoreFixedSlot *mir() const {
  4514         return mir_->toStoreFixedSlot();
  4516     const LAllocation *obj() {
  4517         return getOperand(0);
  4519     const LAllocation *value() {
  4520         return getOperand(1);
  4522 };
  4524 // Note, Name ICs always return a Value. There are no V/T variants.
  4525 class LGetNameCache : public LInstructionHelper<BOX_PIECES, 1, 0>
  4527   public:
  4528     LIR_HEADER(GetNameCache)
  4530     LGetNameCache(const LAllocation &scopeObj) {
  4531         setOperand(0, scopeObj);
  4533     const LAllocation *scopeObj() {
  4534         return getOperand(0);
  4536     const MGetNameCache *mir() const {
  4537         return mir_->toGetNameCache();
  4539 };
  4541 class LCallGetIntrinsicValue : public LCallInstructionHelper<BOX_PIECES, 0, 0>
  4543   public:
  4544     LIR_HEADER(CallGetIntrinsicValue)
  4546     const MCallGetIntrinsicValue *mir() const {
  4547         return mir_->toCallGetIntrinsicValue();
  4549 };
  4551 class LCallsiteCloneCache : public LInstructionHelper<1, 1, 0>
  4553   public:
  4554     LIR_HEADER(CallsiteCloneCache);
  4556     LCallsiteCloneCache(const LAllocation &callee) {
  4557         setOperand(0, callee);
  4559     const LAllocation *callee() {
  4560         return getOperand(0);
  4562     const MCallsiteCloneCache *mir() const {
  4563         return mir_->toCallsiteCloneCache();
  4565 };
  4567 // Patchable jump to stubs generated for a GetProperty cache, which loads a
  4568 // boxed value.
  4569 class LGetPropertyCacheV : public LInstructionHelper<BOX_PIECES, 1, 0>
  4571   public:
  4572     LIR_HEADER(GetPropertyCacheV)
  4574     LGetPropertyCacheV(const LAllocation &object) {
  4575         setOperand(0, object);
  4577     const MGetPropertyCache *mir() const {
  4578         return mir_->toGetPropertyCache();
  4580 };
  4582 // Patchable jump to stubs generated for a GetProperty cache, which loads a
  4583 // value of a known type, possibly into an FP register.
  4584 class LGetPropertyCacheT : public LInstructionHelper<1, 1, 1>
  4586   public:
  4587     LIR_HEADER(GetPropertyCacheT)
  4589     LGetPropertyCacheT(const LAllocation &object, const LDefinition &temp) {
  4590         setOperand(0, object);
  4591         setTemp(0, temp);
  4593     const LDefinition *temp() {
  4594         return getTemp(0);
  4596     const MGetPropertyCache *mir() const {
  4597         return mir_->toGetPropertyCache();
  4599 };
  4601 // Emit code to load a boxed value from an object's slots if its shape matches
  4602 // one of the shapes observed by the baseline IC, else bails out.
  4603 class LGetPropertyPolymorphicV : public LInstructionHelper<BOX_PIECES, 1, 0>
  4605   public:
  4606     LIR_HEADER(GetPropertyPolymorphicV)
  4608     LGetPropertyPolymorphicV(const LAllocation &obj) {
  4609         setOperand(0, obj);
  4611     const LAllocation *obj() {
  4612         return getOperand(0);
  4614     const MGetPropertyPolymorphic *mir() const {
  4615         return mir_->toGetPropertyPolymorphic();
  4617 };
  4619 // Emit code to load a typed value from an object's slots if its shape matches
  4620 // one of the shapes observed by the baseline IC, else bails out.
  4621 class LGetPropertyPolymorphicT : public LInstructionHelper<1, 1, 1>
  4623   public:
  4624     LIR_HEADER(GetPropertyPolymorphicT)
  4626     LGetPropertyPolymorphicT(const LAllocation &obj, const LDefinition &temp) {
  4627         setOperand(0, obj);
  4628         setTemp(0, temp);
  4630     const LAllocation *obj() {
  4631         return getOperand(0);
  4633     const LDefinition *temp() {
  4634         return getTemp(0);
  4636     const MGetPropertyPolymorphic *mir() const {
  4637         return mir_->toGetPropertyPolymorphic();
  4639 };
  4641 // Emit code to store a boxed value to an object's slots if its shape matches
  4642 // one of the shapes observed by the baseline IC, else bails out.
  4643 class LSetPropertyPolymorphicV : public LInstructionHelper<0, 1 + BOX_PIECES, 1>
  4645   public:
  4646     LIR_HEADER(SetPropertyPolymorphicV)
  4648     LSetPropertyPolymorphicV(const LAllocation &obj, const LDefinition &temp) {
  4649         setOperand(0, obj);
  4650         setTemp(0, temp);
  4653     static const size_t Value = 1;
  4655     const LAllocation *obj() {
  4656         return getOperand(0);
  4658     const LDefinition *temp() {
  4659         return getTemp(0);
  4661     const MSetPropertyPolymorphic *mir() const {
  4662         return mir_->toSetPropertyPolymorphic();
  4664 };
  4666 // Emit code to store a typed value to an object's slots if its shape matches
  4667 // one of the shapes observed by the baseline IC, else bails out.
  4668 class LSetPropertyPolymorphicT : public LInstructionHelper<0, 2, 1>
  4670     MIRType valueType_;
  4672   public:
  4673     LIR_HEADER(SetPropertyPolymorphicT)
  4675     LSetPropertyPolymorphicT(const LAllocation &obj, const LAllocation &value, MIRType valueType,
  4676                              const LDefinition &temp)
  4677       : valueType_(valueType)
  4679         setOperand(0, obj);
  4680         setOperand(1, value);
  4681         setTemp(0, temp);
  4684     const LAllocation *obj() {
  4685         return getOperand(0);
  4687     const LAllocation *value() {
  4688         return getOperand(1);
  4690     const LDefinition *temp() {
  4691         return getTemp(0);
  4693     MIRType valueType() const {
  4694         return valueType_;
  4696     const MSetPropertyPolymorphic *mir() const {
  4697         return mir_->toSetPropertyPolymorphic();
  4699     const char *extraName() const {
  4700         return StringFromMIRType(valueType_);
  4702 };
  4704 class LGetElementCacheV : public LInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 0>
  4706   public:
  4707     LIR_HEADER(GetElementCacheV)
  4709     static const size_t Index = 1;
  4711     LGetElementCacheV(const LAllocation &object) {
  4712         setOperand(0, object);
  4714     const LAllocation *object() {
  4715         return getOperand(0);
  4717     const MGetElementCache *mir() const {
  4718         return mir_->toGetElementCache();
  4720 };
  4722 class LGetElementCacheT : public LInstructionHelper<1, 2, 1>
  4724   public:
  4725     LIR_HEADER(GetElementCacheT)
  4727     LGetElementCacheT(const LAllocation &object, const LAllocation &index,
  4728                       const LDefinition &temp) {
  4729         setOperand(0, object);
  4730         setOperand(1, index);
  4731         setTemp(0, temp);
  4733     const LAllocation *object() {
  4734         return getOperand(0);
  4736     const LAllocation *index() {
  4737         return getOperand(1);
  4739     const LDefinition *output() {
  4740         return getDef(0);
  4742     const LDefinition *temp() {
  4743         return getTemp(0);
  4745     const MGetElementCache *mir() const {
  4746         return mir_->toGetElementCache();
  4748 };
  4750 class LBindNameCache : public LInstructionHelper<1, 1, 0>
  4752   public:
  4753     LIR_HEADER(BindNameCache)
  4755     LBindNameCache(const LAllocation &scopeChain) {
  4756         setOperand(0, scopeChain);
  4758     const LAllocation *scopeChain() {
  4759         return getOperand(0);
  4761     const MBindNameCache *mir() const {
  4762         return mir_->toBindNameCache();
  4764 };
  4766 // Load a value from an object's dslots or a slots vector.
  4767 class LLoadSlotV : public LInstructionHelper<BOX_PIECES, 1, 0>
  4769   public:
  4770     LIR_HEADER(LoadSlotV)
  4772     LLoadSlotV(const LAllocation &in) {
  4773         setOperand(0, in);
  4775     const MLoadSlot *mir() const {
  4776         return mir_->toLoadSlot();
  4778 };
  4780 // Load a typed value from an object's dslots or a slots vector. Unlike
  4781 // LLoadSlotV, this can bypass extracting a type tag, directly retrieving a
  4782 // pointer, integer, or double.
  4783 class LLoadSlotT : public LInstructionHelper<1, 1, 0>
  4785   public:
  4786     LIR_HEADER(LoadSlotT)
  4788     LLoadSlotT(const LAllocation &in) {
  4789         setOperand(0, in);
  4791     const MLoadSlot *mir() const {
  4792         return mir_->toLoadSlot();
  4794 };
  4796 // Store a value to an object's dslots or a slots vector.
  4797 class LStoreSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0>
  4799   public:
  4800     LIR_HEADER(StoreSlotV)
  4802     LStoreSlotV(const LAllocation &slots) {
  4803         setOperand(0, slots);
  4806     static const size_t Value = 1;
  4808     const MStoreSlot *mir() const {
  4809         return mir_->toStoreSlot();
  4811     const LAllocation *slots() {
  4812         return getOperand(0);
  4814 };
  4816 // Store a typed value to an object's dslots or a slots vector. This has a
  4817 // few advantages over LStoreSlotV:
  4818 // 1) We can bypass storing the type tag if the slot has the same type as
  4819 //    the value.
  4820 // 2) Better register allocation: we can store constants and FP regs directly
  4821 //    without requiring a second register for the value.
  4822 class LStoreSlotT : public LInstructionHelper<0, 2, 0>
  4824   public:
  4825     LIR_HEADER(StoreSlotT)
  4827     LStoreSlotT(const LAllocation &slots, const LAllocation &value) {
  4828         setOperand(0, slots);
  4829         setOperand(1, value);
  4831     const MStoreSlot *mir() const {
  4832         return mir_->toStoreSlot();
  4834     const LAllocation *slots() {
  4835         return getOperand(0);
  4837     const LAllocation *value() {
  4838         return getOperand(1);
  4840 };
  4842 // Read length field of a JSString*.
  4843 class LStringLength : public LInstructionHelper<1, 1, 0>
  4845   public:
  4846     LIR_HEADER(StringLength)
  4848     LStringLength(const LAllocation &string) {
  4849         setOperand(0, string);
  4852     const LAllocation *string() {
  4853         return getOperand(0);
  4855 };
  4857 // Take the floor of a double precision number. Implements Math.floor().
  4858 class LFloor : public LInstructionHelper<1, 1, 0>
  4860   public:
  4861     LIR_HEADER(Floor)
  4863     LFloor(const LAllocation &num) {
  4864         setOperand(0, num);
  4866 };
  4868 // Take the floor of a single precision number. Implements Math.floor().
  4869 class LFloorF : public LInstructionHelper<1, 1, 0>
  4871   public:
  4872     LIR_HEADER(FloorF)
  4874     LFloorF(const LAllocation &num) {
  4875         setOperand(0, num);
  4877 };
  4879 // Round a double precision number. Implements Math.round().
  4880 class LRound : public LInstructionHelper<1, 1, 1>
  4882   public:
  4883     LIR_HEADER(Round)
  4885     LRound(const LAllocation &num, const LDefinition &temp) {
  4886         setOperand(0, num);
  4887         setTemp(0, temp);
  4890     const LDefinition *temp() {
  4891         return getTemp(0);
  4893     MRound *mir() const {
  4894         return mir_->toRound();
  4896 };
  4898 // Round a single precision number. Implements Math.round().
  4899 class LRoundF : public LInstructionHelper<1, 1, 1>
  4901   public:
  4902     LIR_HEADER(RoundF)
  4904     LRoundF(const LAllocation &num, const LDefinition &temp) {
  4905         setOperand(0, num);
  4906         setTemp(0, temp);
  4909     const LDefinition *temp() {
  4910         return getTemp(0);
  4912     MRound *mir() const {
  4913         return mir_->toRound();
  4915 };
  4917 // Load a function's call environment.
  4918 class LFunctionEnvironment : public LInstructionHelper<1, 1, 0>
  4920   public:
  4921     LIR_HEADER(FunctionEnvironment)
  4923     LFunctionEnvironment(const LAllocation &function) {
  4924         setOperand(0, function);
  4926     const LAllocation *function() {
  4927         return getOperand(0);
  4929 };
  4931 class LForkJoinContext : public LCallInstructionHelper<1, 0, 1>
  4933   public:
  4934     LIR_HEADER(ForkJoinContext);
  4936     LForkJoinContext(const LDefinition &temp1) {
  4937         setTemp(0, temp1);
  4940     const LDefinition *getTempReg() {
  4941         return getTemp(0);
  4943 };
  4945 class LForkJoinGetSlice : public LInstructionHelper<1, 1, 4>
  4947   public:
  4948     LIR_HEADER(ForkJoinGetSlice);
  4950     LForkJoinGetSlice(const LAllocation &cx,
  4951                       const LDefinition &temp1, const LDefinition &temp2,
  4952                       const LDefinition &temp3, const LDefinition &temp4) {
  4953         setOperand(0, cx);
  4954         setTemp(0, temp1);
  4955         setTemp(1, temp2);
  4956         setTemp(2, temp3);
  4957         setTemp(3, temp4);
  4960     const LAllocation *forkJoinContext() {
  4961         return getOperand(0);
  4963     const LDefinition *temp1() {
  4964         return getTemp(0);
  4966     const LDefinition *temp2() {
  4967         return getTemp(1);
  4969     const LDefinition *temp3() {
  4970         return getTemp(2);
  4972     const LDefinition *temp4() {
  4973         return getTemp(3);
  4975 };
  4977 class LCallGetProperty : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
  4979   public:
  4980     LIR_HEADER(CallGetProperty)
  4982     static const size_t Value = 0;
  4984     MCallGetProperty *mir() const {
  4985         return mir_->toCallGetProperty();
  4987 };
  4989 // Call js::GetElement.
  4990 class LCallGetElement : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0>
  4992   public:
  4993     LIR_HEADER(CallGetElement)
  4995     static const size_t LhsInput = 0;
  4996     static const size_t RhsInput = BOX_PIECES;
  4998     MCallGetElement *mir() const {
  4999         return mir_->toCallGetElement();
  5001 };
  5003 // Call js::SetElement.
  5004 class LCallSetElement : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0>
  5006   public:
  5007     LIR_HEADER(CallSetElement)
  5009     static const size_t Index = 1;
  5010     static const size_t Value = 1 + BOX_PIECES;
  5011 };
  5013 // Call js::InitElementArray.
  5014 class LCallInitElementArray : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
  5016 public:
  5017     LIR_HEADER(CallInitElementArray)
  5019     static const size_t Value = 1;
  5021     const MCallInitElementArray *mir() const {
  5022         return mir_->toCallInitElementArray();
  5024 };
  5026 // Call a VM function to perform a property or name assignment of a generic value.
  5027 class LCallSetProperty : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
  5029   public:
  5030     LIR_HEADER(CallSetProperty)
  5032     LCallSetProperty(const LAllocation &obj) {
  5033         setOperand(0, obj);
  5036     static const size_t Value = 1;
  5038     const MCallSetProperty *mir() const {
  5039         return mir_->toCallSetProperty();
  5041 };
  5043 class LCallDeleteProperty : public LCallInstructionHelper<1, BOX_PIECES, 0>
  5045   public:
  5046     LIR_HEADER(CallDeleteProperty)
  5048     static const size_t Value = 0;
  5050     MDeleteProperty *mir() const {
  5051         return mir_->toDeleteProperty();
  5053 };
  5055 class LCallDeleteElement : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
  5057   public:
  5058     LIR_HEADER(CallDeleteElement)
  5060     static const size_t Value = 0;
  5061     static const size_t Index = BOX_PIECES;
  5063     MDeleteElement *mir() const {
  5064         return mir_->toDeleteElement();
  5066 };
  5068 // Patchable jump to stubs generated for a SetProperty cache, which stores a
  5069 // boxed value.
  5070 class LSetPropertyCacheV : public LInstructionHelper<0, 1 + BOX_PIECES, 2>
  5072   public:
  5073     LIR_HEADER(SetPropertyCacheV)
  5075     LSetPropertyCacheV(const LAllocation &object, const LDefinition &slots,
  5076                        const LDefinition &temp) {
  5077         setOperand(0, object);
  5078         setTemp(0, slots);
  5079         setTemp(1, temp);
  5082     static const size_t Value = 1;
  5084     const MSetPropertyCache *mir() const {
  5085         return mir_->toSetPropertyCache();
  5088     const LDefinition *tempForDispatchCache() {
  5089         return getTemp(1);
  5091 };
  5093 // Patchable jump to stubs generated for a SetProperty cache, which stores a
  5094 // value of a known type.
  5095 class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2>
  5097     MIRType valueType_;
  5099   public:
  5100     LIR_HEADER(SetPropertyCacheT)
  5102     LSetPropertyCacheT(const LAllocation &object, const LDefinition &slots,
  5103                        const LAllocation &value, const LDefinition &temp,
  5104                        MIRType valueType)
  5105         : valueType_(valueType)
  5107         setOperand(0, object);
  5108         setOperand(1, value);
  5109         setTemp(0, slots);
  5110         setTemp(1, temp);
  5113     const MSetPropertyCache *mir() const {
  5114         return mir_->toSetPropertyCache();
  5116     MIRType valueType() {
  5117         return valueType_;
  5119     const char *extraName() const {
  5120         return StringFromMIRType(valueType_);
  5123     const LDefinition *tempForDispatchCache() {
  5124         return getTemp(1);
  5126 };
  5128 class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3>
  5130   public:
  5131     LIR_HEADER(SetElementCacheV);
  5133     static const size_t Index = 1;
  5134     static const size_t Value = 1 + BOX_PIECES;
  5136     LSetElementCacheV(const LAllocation &object, const LDefinition &tempToUnboxIndex,
  5137                       const LDefinition &temp, const LDefinition &tempFloat)
  5139         setOperand(0, object);
  5140         setTemp(0, tempToUnboxIndex);
  5141         setTemp(1, temp);
  5142         setTemp(2, tempFloat);
  5144     const MSetElementCache *mir() const {
  5145         return mir_->toSetElementCache();
  5148     const LAllocation *object() {
  5149         return getOperand(0);
  5151     const LDefinition *tempToUnboxIndex() {
  5152         return getTemp(0);
  5154     const LDefinition *temp() {
  5155         return getTemp(1);
  5157     const LDefinition *tempFloat() {
  5158         return getTemp(2);
  5160 };
  5162 class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 3>
  5164   public:
  5165     LIR_HEADER(SetElementCacheT);
  5167     static const size_t Index = 2;
  5169     LSetElementCacheT(const LAllocation &object, const LAllocation &value,
  5170                       const LDefinition &tempToUnboxIndex,
  5171                       const LDefinition &temp, const LDefinition &tempFloat) {
  5172         setOperand(0, object);
  5173         setOperand(1, value);
  5174         setTemp(0, tempToUnboxIndex);
  5175         setTemp(1, temp);
  5176         setTemp(2, tempFloat);
  5178     const MSetElementCache *mir() const {
  5179         return mir_->toSetElementCache();
  5182     const LAllocation *object() {
  5183         return getOperand(0);
  5185     const LAllocation *value() {
  5186         return getOperand(1);
  5188     const LDefinition *tempToUnboxIndex() {
  5189         return getTemp(0);
  5191     const LDefinition *temp() {
  5192         return getTemp(1);
  5194     const LDefinition *tempFloat() {
  5195         return getTemp(2);
  5197 };
  5199 class LCallIteratorStart : public LCallInstructionHelper<1, 1, 0>
  5201   public:
  5202     LIR_HEADER(CallIteratorStart)
  5204     LCallIteratorStart(const LAllocation &object) {
  5205         setOperand(0, object);
  5207     const LAllocation *object() {
  5208         return getOperand(0);
  5210     MIteratorStart *mir() const {
  5211         return mir_->toIteratorStart();
  5213 };
  5215 class LIteratorStart : public LInstructionHelper<1, 1, 3>
  5217   public:
  5218     LIR_HEADER(IteratorStart)
  5220     LIteratorStart(const LAllocation &object, const LDefinition &temp1,
  5221                    const LDefinition &temp2, const LDefinition &temp3) {
  5222         setOperand(0, object);
  5223         setTemp(0, temp1);
  5224         setTemp(1, temp2);
  5225         setTemp(2, temp3);
  5227     const LAllocation *object() {
  5228         return getOperand(0);
  5230     const LDefinition *temp1() {
  5231         return getTemp(0);
  5233     const LDefinition *temp2() {
  5234         return getTemp(1);
  5236     const LDefinition *temp3() {
  5237         return getTemp(2);
  5239     MIteratorStart *mir() const {
  5240         return mir_->toIteratorStart();
  5242 };
  5244 class LIteratorNext : public LInstructionHelper<BOX_PIECES, 1, 1>
  5246   public:
  5247     LIR_HEADER(IteratorNext)
  5249     LIteratorNext(const LAllocation &iterator, const LDefinition &temp) {
  5250         setOperand(0, iterator);
  5251         setTemp(0, temp);
  5253     const LAllocation *object() {
  5254         return getOperand(0);
  5256     const LDefinition *temp() {
  5257         return getTemp(0);
  5259     MIteratorNext *mir() const {
  5260         return mir_->toIteratorNext();
  5262 };
  5264 class LIteratorMore : public LInstructionHelper<1, 1, 1>
  5266   public:
  5267     LIR_HEADER(IteratorMore)
  5269     LIteratorMore(const LAllocation &iterator, const LDefinition &temp) {
  5270         setOperand(0, iterator);
  5271         setTemp(0, temp);
  5273     const LAllocation *object() {
  5274         return getOperand(0);
  5276     const LDefinition *temp() {
  5277         return getTemp(0);
  5279     MIteratorMore *mir() const {
  5280         return mir_->toIteratorMore();
  5282 };
  5284 class LIteratorEnd : public LInstructionHelper<0, 1, 3>
  5286   public:
  5287     LIR_HEADER(IteratorEnd)
  5289     LIteratorEnd(const LAllocation &iterator, const LDefinition &temp1,
  5290                  const LDefinition &temp2, const LDefinition &temp3) {
  5291         setOperand(0, iterator);
  5292         setTemp(0, temp1);
  5293         setTemp(1, temp2);
  5294         setTemp(2, temp3);
  5296     const LAllocation *object() {
  5297         return getOperand(0);
  5299     const LDefinition *temp1() {
  5300         return getTemp(0);
  5302     const LDefinition *temp2() {
  5303         return getTemp(1);
  5305     const LDefinition *temp3() {
  5306         return getTemp(2);
  5308     MIteratorEnd *mir() const {
  5309         return mir_->toIteratorEnd();
  5311 };
  5313 // Read the number of actual arguments.
  5314 class LArgumentsLength : public LInstructionHelper<1, 0, 0>
  5316   public:
  5317     LIR_HEADER(ArgumentsLength)
  5318 };
  5320 // Load a value from the actual arguments.
  5321 class LGetFrameArgument : public LInstructionHelper<BOX_PIECES, 1, 0>
  5323   public:
  5324     LIR_HEADER(GetFrameArgument)
  5326     LGetFrameArgument(const LAllocation &index) {
  5327         setOperand(0, index);
  5329     const LAllocation *index() {
  5330         return getOperand(0);
  5332 };
  5334 // Load a value from the actual arguments.
  5335 class LSetFrameArgumentT : public LInstructionHelper<0, 1, 0>
  5337   public:
  5338     LIR_HEADER(SetFrameArgumentT)
  5340     LSetFrameArgumentT(const LAllocation &input) {
  5341         setOperand(0, input);
  5343     MSetFrameArgument *mir() const {
  5344         return mir_->toSetFrameArgument();
  5346     const LAllocation *input() {
  5347         return getOperand(0);
  5349 };
  5351 // Load a value from the actual arguments.
  5352 class LSetFrameArgumentC : public LInstructionHelper<0, 0, 0>
  5354     Value val_;
  5356   public:
  5357     LIR_HEADER(SetFrameArgumentC)
  5359     LSetFrameArgumentC(const Value &val) {
  5360         val_ = val;
  5362     MSetFrameArgument *mir() const {
  5363         return mir_->toSetFrameArgument();
  5365     const Value &val() const {
  5366         return val_;
  5368 };
  5370 // Load a value from the actual arguments.
  5371 class LSetFrameArgumentV : public LInstructionHelper<0, BOX_PIECES, 0>
  5373   public:
  5374     LIR_HEADER(SetFrameArgumentV)
  5376     LSetFrameArgumentV() {}
  5378     static const size_t Input = 0;
  5380     MSetFrameArgument *mir() const {
  5381         return mir_->toSetFrameArgument();
  5383 };
  5385 class LRunOncePrologue : public LCallInstructionHelper<0, 0, 0>
  5387   public:
  5388     LIR_HEADER(RunOncePrologue)
  5390     MRunOncePrologue *mir() const {
  5391         return mir_->toRunOncePrologue();
  5393 };
  5395 // Create the rest parameter.
  5396 class LRest : public LCallInstructionHelper<1, 1, 3>
  5398   public:
  5399     LIR_HEADER(Rest)
  5401     LRest(const LAllocation &numActuals, const LDefinition &temp1, const LDefinition &temp2,
  5402           const LDefinition &temp3)
  5404         setOperand(0, numActuals);
  5405         setTemp(0, temp1);
  5406         setTemp(1, temp2);
  5407         setTemp(2, temp3);
  5409     const LAllocation *numActuals() {
  5410         return getOperand(0);
  5412     MRest *mir() const {
  5413         return mir_->toRest();
  5415 };
  5417 class LRestPar : public LCallInstructionHelper<1, 2, 3>
  5419   public:
  5420     LIR_HEADER(RestPar);
  5422     LRestPar(const LAllocation &cx, const LAllocation &numActuals,
  5423              const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3)
  5425         setOperand(0, cx);
  5426         setOperand(1, numActuals);
  5427         setTemp(0, temp1);
  5428         setTemp(1, temp2);
  5429         setTemp(2, temp3);
  5431     const LAllocation *forkJoinContext() {
  5432         return getOperand(0);
  5434     const LAllocation *numActuals() {
  5435         return getOperand(1);
  5437     MRestPar *mir() const {
  5438         return mir_->toRestPar();
  5440 };
  5442 class LGuardThreadExclusive : public LCallInstructionHelper<0, 2, 1>
  5444   public:
  5445     LIR_HEADER(GuardThreadExclusive);
  5447     LGuardThreadExclusive(const LAllocation &cx, const LAllocation &object, const LDefinition &temp1) {
  5448         setOperand(0, cx);
  5449         setOperand(1, object);
  5450         setTemp(0, temp1);
  5453     const LAllocation *forkJoinContext() {
  5454         return getOperand(0);
  5457     const LAllocation *object() {
  5458         return getOperand(1);
  5461     const LDefinition *getTempReg() {
  5462         return getTemp(0);
  5464 };
  5466 // Guard that a value is in a TypeSet.
  5467 class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1>
  5469   public:
  5470     LIR_HEADER(TypeBarrierV)
  5472     LTypeBarrierV(const LDefinition &temp) {
  5473         setTemp(0, temp);
  5476     static const size_t Input = 0;
  5478     const MTypeBarrier *mir() const {
  5479         return mir_->toTypeBarrier();
  5481     const LDefinition *temp() {
  5482         return getTemp(0);
  5484 };
  5486 // Guard that a object is in a TypeSet.
  5487 class LTypeBarrierO : public LInstructionHelper<0, 1, 1>
  5489   public:
  5490     LIR_HEADER(TypeBarrierO)
  5492     LTypeBarrierO(const LAllocation &obj, const LDefinition &temp) {
  5493         setOperand(0, obj);
  5494         setTemp(0, temp);
  5496     const MTypeBarrier *mir() const {
  5497         return mir_->toTypeBarrier();
  5499     const LAllocation *object() {
  5500         return getOperand(0);
  5502     const LDefinition *temp() {
  5503         return getTemp(0);
  5505 };
  5507 // Guard that a value is in a TypeSet.
  5508 class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1>
  5510   public:
  5511     LIR_HEADER(MonitorTypes)
  5513     LMonitorTypes(const LDefinition &temp) {
  5514         setTemp(0, temp);
  5517     static const size_t Input = 0;
  5519     const MMonitorTypes *mir() const {
  5520         return mir_->toMonitorTypes();
  5522     const LDefinition *temp() {
  5523         return getTemp(0);
  5525 };
  5527 // Generational write barrier used when writing an object to another object.
  5528 class LPostWriteBarrierO : public LInstructionHelper<0, 2, 1>
  5530   public:
  5531     LIR_HEADER(PostWriteBarrierO)
  5533     LPostWriteBarrierO(const LAllocation &obj, const LAllocation &value,
  5534                        const LDefinition &temp) {
  5535         setOperand(0, obj);
  5536         setOperand(1, value);
  5537         setTemp(0, temp);
  5540     const MPostWriteBarrier *mir() const {
  5541         return mir_->toPostWriteBarrier();
  5543     const LAllocation *object() {
  5544         return getOperand(0);
  5546     const LAllocation *value() {
  5547         return getOperand(1);
  5549     const LDefinition *temp() {
  5550         return getTemp(0);
  5552 };
  5554 // Generational write barrier used when writing a value to another object.
  5555 class LPostWriteBarrierV : public LInstructionHelper<0, 1 + BOX_PIECES, 1>
  5557   public:
  5558     LIR_HEADER(PostWriteBarrierV)
  5560     LPostWriteBarrierV(const LAllocation &obj, const LDefinition &temp) {
  5561         setOperand(0, obj);
  5562         setTemp(0, temp);
  5565     static const size_t Input = 1;
  5567     const MPostWriteBarrier *mir() const {
  5568         return mir_->toPostWriteBarrier();
  5570     const LAllocation *object() {
  5571         return getOperand(0);
  5573     const LDefinition *temp() {
  5574         return getTemp(0);
  5576 };
  5578 // Guard against an object's identity.
  5579 class LGuardObjectIdentity : public LInstructionHelper<0, 1, 0>
  5581   public:
  5582     LIR_HEADER(GuardObjectIdentity)
  5584     LGuardObjectIdentity(const LAllocation &in) {
  5585         setOperand(0, in);
  5587     const MGuardObjectIdentity *mir() const {
  5588         return mir_->toGuardObjectIdentity();
  5590 };
  5592 // Guard against an object's class.
  5593 class LGuardClass : public LInstructionHelper<0, 1, 1>
  5595   public:
  5596     LIR_HEADER(GuardClass)
  5598     LGuardClass(const LAllocation &in, const LDefinition &temp) {
  5599         setOperand(0, in);
  5600         setTemp(0, temp);
  5602     const MGuardClass *mir() const {
  5603         return mir_->toGuardClass();
  5605     const LDefinition *tempInt() {
  5606         return getTemp(0);
  5608 };
  5610 class MPhi;
  5612 // Phi is a pseudo-instruction that emits no code, and is an annotation for the
  5613 // register allocator. Like its equivalent in MIR, phis are collected at the
  5614 // top of blocks and are meant to be executed in parallel, choosing the input
  5615 // corresponding to the predecessor taken in the control flow graph.
  5616 class LPhi MOZ_FINAL : public LInstruction
  5618     LAllocation *inputs_;
  5619     LDefinition def_;
  5621     LPhi()
  5622     { }
  5624   public:
  5625     LIR_HEADER(Phi)
  5627     static LPhi *New(MIRGenerator *gen, MPhi *phi);
  5629     size_t numDefs() const {
  5630         return 1;
  5632     LDefinition *getDef(size_t index) {
  5633         JS_ASSERT(index == 0);
  5634         return &def_;
  5636     void setDef(size_t index, const LDefinition &def) {
  5637         JS_ASSERT(index == 0);
  5638         def_ = def;
  5640     size_t numOperands() const {
  5641         return mir_->toPhi()->numOperands();
  5643     LAllocation *getOperand(size_t index) {
  5644         JS_ASSERT(index < numOperands());
  5645         return &inputs_[index];
  5647     void setOperand(size_t index, const LAllocation &a) {
  5648         JS_ASSERT(index < numOperands());
  5649         inputs_[index] = a;
  5651     size_t numTemps() const {
  5652         return 0;
  5654     LDefinition *getTemp(size_t index) {
  5655         MOZ_ASSUME_UNREACHABLE("no temps");
  5657     void setTemp(size_t index, const LDefinition &temp) {
  5658         MOZ_ASSUME_UNREACHABLE("no temps");
  5660     size_t numSuccessors() const {
  5661         return 0;
  5663     MBasicBlock *getSuccessor(size_t i) const {
  5664         MOZ_ASSUME_UNREACHABLE("no successors");
  5666     void setSuccessor(size_t i, MBasicBlock *) {
  5667         MOZ_ASSUME_UNREACHABLE("no successors");
  5670     virtual void printInfo(FILE *fp) {
  5671         printOperands(fp);
  5673 };
  5675 class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0>
  5677   public:
  5678     LIR_HEADER(In)
  5679     LIn(const LAllocation &rhs) {
  5680         setOperand(RHS, rhs);
  5683     const LAllocation *lhs() {
  5684         return getOperand(LHS);
  5686     const LAllocation *rhs() {
  5687         return getOperand(RHS);
  5690     static const size_t LHS = 0;
  5691     static const size_t RHS = BOX_PIECES;
  5692 };
  5694 class LInstanceOfO : public LInstructionHelper<1, 1, 0>
  5696   public:
  5697     LIR_HEADER(InstanceOfO)
  5698     LInstanceOfO(const LAllocation &lhs) {
  5699         setOperand(0, lhs);
  5702     MInstanceOf *mir() const {
  5703         return mir_->toInstanceOf();
  5706     const LAllocation *lhs() {
  5707         return getOperand(0);
  5709 };
  5711 class LInstanceOfV : public LInstructionHelper<1, BOX_PIECES, 0>
  5713   public:
  5714     LIR_HEADER(InstanceOfV)
  5715     LInstanceOfV() {
  5718     MInstanceOf *mir() const {
  5719         return mir_->toInstanceOf();
  5722     const LAllocation *lhs() {
  5723         return getOperand(LHS);
  5726     static const size_t LHS = 0;
  5727 };
  5729 class LCallInstanceOf : public LCallInstructionHelper<1, BOX_PIECES+1, 0>
  5731   public:
  5732     LIR_HEADER(CallInstanceOf)
  5733     LCallInstanceOf(const LAllocation &rhs) {
  5734         setOperand(RHS, rhs);
  5737     const LDefinition *output() {
  5738         return this->getDef(0);
  5740     const LAllocation *lhs() {
  5741         return getOperand(LHS);
  5743     const LAllocation *rhs() {
  5744         return getOperand(RHS);
  5747     static const size_t LHS = 0;
  5748     static const size_t RHS = BOX_PIECES;
  5749 };
  5751 class LProfilerStackOp : public LInstructionHelper<0, 0, 1>
  5753   public:
  5754     LIR_HEADER(ProfilerStackOp)
  5756     LProfilerStackOp(const LDefinition &temp) {
  5757         setTemp(0, temp);
  5760     const LDefinition *temp() {
  5761         return getTemp(0);
  5764     JSScript *script() {
  5765         return mir_->toProfilerStackOp()->script();
  5768     MProfilerStackOp::Type type() {
  5769         return mir_->toProfilerStackOp()->type();
  5772     unsigned inlineLevel() {
  5773         return mir_->toProfilerStackOp()->inlineLevel();
  5775 };
  5777 class LIsCallable : public LInstructionHelper<1, 1, 0>
  5779   public:
  5780     LIR_HEADER(IsCallable);
  5781     LIsCallable(const LAllocation &object) {
  5782         setOperand(0, object);
  5785     const LAllocation *object() {
  5786         return getOperand(0);
  5788     MIsCallable *mir() const {
  5789         return mir_->toIsCallable();
  5791 };
  5793 class LHaveSameClass : public LInstructionHelper<1, 2, 1>
  5795   public:
  5796     LIR_HEADER(HaveSameClass);
  5797     LHaveSameClass(const LAllocation &left, const LAllocation &right,
  5798                    const LDefinition &temp) {
  5799         setOperand(0, left);
  5800         setOperand(1, right);
  5801         setTemp(0, temp);
  5804     const LAllocation *lhs() {
  5805         return getOperand(0);
  5807     const LAllocation *rhs() {
  5808         return getOperand(1);
  5810     MHaveSameClass *mir() const {
  5811         return mir_->toHaveSameClass();
  5813 };
  5815 class LHasClass : public LInstructionHelper<1, 1, 0>
  5817   public:
  5818     LIR_HEADER(HasClass);
  5819     LHasClass(const LAllocation &lhs) {
  5820         setOperand(0, lhs);
  5823     const LAllocation *lhs() {
  5824         return getOperand(0);
  5826     MHasClass *mir() const {
  5827         return mir_->toHasClass();
  5829 };
  5831 class LAsmJSLoadHeap : public LInstructionHelper<1, 1, 0>
  5833   public:
  5834     LIR_HEADER(AsmJSLoadHeap);
  5835     LAsmJSLoadHeap(const LAllocation &ptr) {
  5836         setOperand(0, ptr);
  5838     MAsmJSLoadHeap *mir() const {
  5839         return mir_->toAsmJSLoadHeap();
  5841     const LAllocation *ptr() {
  5842         return getOperand(0);
  5844 };
  5846 class LAsmJSStoreHeap : public LInstructionHelper<0, 2, 0>
  5848   public:
  5849     LIR_HEADER(AsmJSStoreHeap);
  5850     LAsmJSStoreHeap(const LAllocation &ptr, const LAllocation &value) {
  5851         setOperand(0, ptr);
  5852         setOperand(1, value);
  5854     MAsmJSStoreHeap *mir() const {
  5855         return mir_->toAsmJSStoreHeap();
  5857     const LAllocation *ptr() {
  5858         return getOperand(0);
  5860     const LAllocation *value() {
  5861         return getOperand(1);
  5863 };
  5865 class LAsmJSLoadGlobalVar : public LInstructionHelper<1, 0, 0>
  5867   public:
  5868     LIR_HEADER(AsmJSLoadGlobalVar);
  5869     MAsmJSLoadGlobalVar *mir() const {
  5870         return mir_->toAsmJSLoadGlobalVar();
  5872 };
  5874 class LAsmJSStoreGlobalVar : public LInstructionHelper<0, 1, 0>
  5876   public:
  5877     LIR_HEADER(AsmJSStoreGlobalVar);
  5878     LAsmJSStoreGlobalVar(const LAllocation &value) {
  5879         setOperand(0, value);
  5881     MAsmJSStoreGlobalVar *mir() const {
  5882         return mir_->toAsmJSStoreGlobalVar();
  5884     const LAllocation *value() {
  5885         return getOperand(0);
  5887 };
  5889 class LAsmJSLoadFFIFunc : public LInstructionHelper<1, 0, 0>
  5891   public:
  5892     LIR_HEADER(AsmJSLoadFFIFunc);
  5893     MAsmJSLoadFFIFunc *mir() const {
  5894         return mir_->toAsmJSLoadFFIFunc();
  5896 };
  5898 class LAsmJSParameter : public LInstructionHelper<1, 0, 0>
  5900   public:
  5901     LIR_HEADER(AsmJSParameter);
  5902 };
  5904 class LAsmJSReturn : public LInstructionHelper<0, 1, 0>
  5906   public:
  5907     LIR_HEADER(AsmJSReturn);
  5908 };
  5910 class LAsmJSVoidReturn : public LInstructionHelper<0, 0, 0>
  5912   public:
  5913     LIR_HEADER(AsmJSVoidReturn);
  5914 };
  5916 class LAsmJSPassStackArg : public LInstructionHelper<0, 1, 0>
  5918   public:
  5919     LIR_HEADER(AsmJSPassStackArg);
  5920     LAsmJSPassStackArg(const LAllocation &arg) {
  5921         setOperand(0, arg);
  5923     MAsmJSPassStackArg *mir() const {
  5924         return mirRaw()->toAsmJSPassStackArg();
  5926     const LAllocation *arg() {
  5927         return getOperand(0);
  5929 };
  5931 class LAsmJSCall MOZ_FINAL : public LInstruction
  5933     LAllocation *operands_;
  5934     uint32_t numOperands_;
  5935     LDefinition def_;
  5937   public:
  5938     LIR_HEADER(AsmJSCall);
  5940     LAsmJSCall(LAllocation *operands, uint32_t numOperands)
  5941       : operands_(operands),
  5942         numOperands_(numOperands),
  5943         def_(LDefinition::BogusTemp())
  5944     {}
  5946     MAsmJSCall *mir() const {
  5947         return mir_->toAsmJSCall();
  5950     bool isCall() const {
  5951         return true;
  5954     // LInstruction interface
  5955     size_t numDefs() const {
  5956         return def_.isBogusTemp() ? 0 : 1;
  5958     LDefinition *getDef(size_t index) {
  5959         JS_ASSERT(numDefs() == 1);
  5960         JS_ASSERT(index == 0);
  5961         return &def_;
  5963     void setDef(size_t index, const LDefinition &def) {
  5964         JS_ASSERT(index == 0);
  5965         def_ = def;
  5967     size_t numOperands() const {
  5968         return numOperands_;
  5970     LAllocation *getOperand(size_t index) {
  5971         JS_ASSERT(index < numOperands_);
  5972         return &operands_[index];
  5974     void setOperand(size_t index, const LAllocation &a) {
  5975         JS_ASSERT(index < numOperands_);
  5976         operands_[index] = a;
  5978     size_t numTemps() const {
  5979         return 0;
  5981     LDefinition *getTemp(size_t index) {
  5982         MOZ_ASSUME_UNREACHABLE("no temps");
  5984     void setTemp(size_t index, const LDefinition &a) {
  5985         MOZ_ASSUME_UNREACHABLE("no temps");
  5987     size_t numSuccessors() const {
  5988         return 0;
  5990     MBasicBlock *getSuccessor(size_t i) const {
  5991         MOZ_ASSUME_UNREACHABLE("no successors");
  5993     void setSuccessor(size_t i, MBasicBlock *) {
  5994         MOZ_ASSUME_UNREACHABLE("no successors");
  5996 };
  5998 class LAssertRangeI : public LInstructionHelper<0, 1, 0>
  6000   public:
  6001     LIR_HEADER(AssertRangeI)
  6003     LAssertRangeI(const LAllocation &input) {
  6004         setOperand(0, input);
  6007     const LAllocation *input() {
  6008         return getOperand(0);
  6011     MAssertRange *mir() {
  6012         return mir_->toAssertRange();
  6014     const Range *range() {
  6015         return mir()->assertedRange();
  6017 };
  6019 class LAssertRangeD : public LInstructionHelper<0, 1, 1>
  6021   public:
  6022     LIR_HEADER(AssertRangeD)
  6024     LAssertRangeD(const LAllocation &input, const LDefinition &temp) {
  6025         setOperand(0, input);
  6026         setTemp(0, temp);
  6029     const LAllocation *input() {
  6030         return getOperand(0);
  6033     const LDefinition *temp() {
  6034         return getTemp(0);
  6037     MAssertRange *mir() {
  6038         return mir_->toAssertRange();
  6040     const Range *range() {
  6041         return mir()->assertedRange();
  6043 };
  6045 class LAssertRangeF : public LInstructionHelper<0, 1, 1>
  6047   public:
  6048     LIR_HEADER(AssertRangeF)
  6050     LAssertRangeF(const LAllocation &input, const LDefinition &temp) {
  6051         setOperand(0, input);
  6052         setTemp(0, temp);
  6055     const LAllocation *input() {
  6056         return getOperand(0);
  6059     const LDefinition *temp() {
  6060         return getTemp(0);
  6063     MAssertRange *mir() {
  6064         return mir_->toAssertRange();
  6066     const Range *range() {
  6067         return mir()->assertedRange();
  6069 };
  6071 class LAssertRangeV : public LInstructionHelper<0, BOX_PIECES, 3>
  6073   public:
  6074     LIR_HEADER(AssertRangeV)
  6076     LAssertRangeV(const LDefinition &temp, const LDefinition &floatTemp1,
  6077                   const LDefinition &floatTemp2)
  6079         setTemp(0, temp);
  6080         setTemp(1, floatTemp1);
  6081         setTemp(2, floatTemp2);
  6084     static const size_t Input = 0;
  6086     const LDefinition *temp() {
  6087         return getTemp(0);
  6089     const LDefinition *floatTemp1() {
  6090         return getTemp(1);
  6092     const LDefinition *floatTemp2() {
  6093         return getTemp(2);
  6096     MAssertRange *mir() {
  6097         return mir_->toAssertRange();
  6099     const Range *range() {
  6100         return mir()->assertedRange();
  6102 };
  6104 class LRecompileCheck : public LInstructionHelper<0, 0, 1>
  6106   public:
  6107     LIR_HEADER(RecompileCheck)
  6109     LRecompileCheck(const LDefinition &scratch) {
  6110         setTemp(0, scratch);
  6113     const LDefinition *scratch() {
  6114         return getTemp(0);
  6116     MRecompileCheck *mir() {
  6117         return mir_->toRecompileCheck();
  6119 };
  6121 } // namespace jit
  6122 } // namespace js
  6124 #endif /* jit_LIR_Common_h */

mercurial