tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LIR-shared.h (37922B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jit_shared_LIR_shared_h
      8 #define jit_shared_LIR_shared_h
      9 
     10 #include "jit/AtomicOp.h"
     11 #include "jit/shared/Assembler-shared.h"
     12 #include "util/Memory.h"
     13 
     14 // This file declares LIR instructions that are common to every platform.
     15 
     16 namespace js {
     17 namespace jit {
     18 
     19 LIR_OPCODE_CLASS_GENERATED
     20 
     21 template <size_t Temps, size_t ExtraUses = 0>
     22 class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps> {
     23 protected:
     24  explicit LBinaryMath(LNode::Opcode opcode)
     25      : LInstructionHelper<1, 2 + ExtraUses, Temps>(opcode) {}
     26 
     27 public:
     28  const LAllocation* lhs() { return this->getOperand(0); }
     29  const LAllocation* rhs() { return this->getOperand(1); }
     30 };
     31 
     32 // An LOsiPoint captures a snapshot after a call and ensures enough space to
     33 // patch in a call to the invalidation mechanism.
     34 //
     35 // Note: LSafepoints are 1:1 with LOsiPoints, so it holds a reference to the
     36 // corresponding LSafepoint to inform it of the LOsiPoint's masm offset when it
     37 // gets GC'd.
     38 class LOsiPoint : public LInstructionHelper<0, 0, 0> {
     39  LSafepoint* safepoint_;
     40 
     41 public:
     42  LOsiPoint(LSafepoint* safepoint, LSnapshot* snapshot)
     43      : LInstructionHelper(classOpcode), safepoint_(safepoint) {
     44    MOZ_ASSERT(safepoint && snapshot);
     45    assignSnapshot(snapshot);
     46  }
     47 
     48  LSafepoint* associatedSafepoint() { return safepoint_; }
     49 
     50  LIR_HEADER(OsiPoint)
     51 };
     52 
     53 class LMove {
     54  LAllocation from_;
     55  LAllocation to_;
     56  LDefinition::Type type_;
     57 
     58 public:
     59  LMove(LAllocation from, LAllocation to, LDefinition::Type type)
     60      : from_(from), to_(to), type_(type) {}
     61 
     62  LAllocation from() const { return from_; }
     63  LAllocation to() const { return to_; }
     64  LDefinition::Type type() const { return type_; }
     65 };
     66 
     67 class LMoveGroup : public LInstructionHelper<0, 0, 0> {
     68  js::Vector<LMove, 2, JitAllocPolicy> moves_;
     69 
     70 #ifdef JS_CODEGEN_X86
     71  // Optional general register available for use when executing moves.
     72  LAllocation scratchRegister_;
     73 #endif
     74 
     75  explicit LMoveGroup(TempAllocator& alloc)
     76      : LInstructionHelper(classOpcode), moves_(alloc) {}
     77 
     78 public:
     79  LIR_HEADER(MoveGroup)
     80 
     81  static LMoveGroup* New(TempAllocator& alloc) {
     82    return new (alloc) LMoveGroup(alloc);
     83  }
     84 
     85  void printOperands(GenericPrinter& out);
     86 
     87  // Add a move which takes place simultaneously with all others in the group.
     88  bool add(LAllocation from, LAllocation to, LDefinition::Type type);
     89 
     90  // Add a move which takes place after existing moves in the group.
     91  bool addAfter(LAllocation from, LAllocation to, LDefinition::Type type);
     92 
     93  size_t numMoves() const { return moves_.length(); }
     94  const LMove& getMove(size_t i) const { return moves_[i]; }
     95 
     96 #ifdef JS_CODEGEN_X86
     97  void setScratchRegister(Register reg) { scratchRegister_ = LGeneralReg(reg); }
     98  LAllocation maybeScratchRegister() { return scratchRegister_; }
     99 #endif
    100 
    101  bool uses(Register reg) {
    102    for (size_t i = 0; i < numMoves(); i++) {
    103      LMove move = getMove(i);
    104      if (move.from() == LGeneralReg(reg) || move.to() == LGeneralReg(reg)) {
    105        return true;
    106      }
    107    }
    108    return false;
    109  }
    110 };
    111 
    112 // A constant Value.
    113 class LValue : public LInstructionHelper<BOX_PIECES, 0, 0> {
    114  Value v_;
    115 
    116 public:
    117  LIR_HEADER(Value)
    118 
    119  explicit LValue(const Value& v) : LInstructionHelper(classOpcode), v_(v) {}
    120 
    121  Value value() const { return v_; }
    122 };
    123 
    124 // Allocate a new arguments object for an inlined frame.
    125 class LCreateInlinedArgumentsObject : public LVariadicInstruction<1, 2> {
    126 public:
    127  LIR_HEADER(CreateInlinedArgumentsObject)
    128 
    129  static const size_t CallObj = 0;
    130  static const size_t Callee = 1;
    131  static const size_t NumNonArgumentOperands = 2;
    132  static size_t ArgIndex(size_t i) {
    133    return NumNonArgumentOperands + BOX_PIECES * i;
    134  }
    135 
    136  LCreateInlinedArgumentsObject(uint32_t numOperands, const LDefinition& temp1,
    137                                const LDefinition& temp2)
    138      : LVariadicInstruction(classOpcode, numOperands) {
    139    setIsCall();
    140    setTemp(0, temp1);
    141    setTemp(1, temp2);
    142  }
    143 
    144  const LAllocation* getCallObject() { return getOperand(CallObj); }
    145  const LAllocation* getCallee() { return getOperand(Callee); }
    146 
    147  const LDefinition* temp1() { return getTemp(0); }
    148  const LDefinition* temp2() { return getTemp(1); }
    149 
    150  MCreateInlinedArgumentsObject* mir() const {
    151    return mir_->toCreateInlinedArgumentsObject();
    152  }
    153 };
    154 
    155 class LGetInlinedArgument : public LVariadicInstruction<BOX_PIECES, 0> {
    156 public:
    157  LIR_HEADER(GetInlinedArgument)
    158 
    159  static const size_t Index = 0;
    160  static const size_t NumNonArgumentOperands = 1;
    161  static size_t ArgIndex(size_t i) {
    162    return NumNonArgumentOperands + BOX_PIECES * i;
    163  }
    164 
    165  explicit LGetInlinedArgument(uint32_t numOperands)
    166      : LVariadicInstruction(classOpcode, numOperands) {}
    167 
    168  const LAllocation* getIndex() { return getOperand(Index); }
    169 
    170  MGetInlinedArgument* mir() const { return mir_->toGetInlinedArgument(); }
    171 };
    172 
    173 class LGetInlinedArgumentHole : public LVariadicInstruction<BOX_PIECES, 0> {
    174 public:
    175  LIR_HEADER(GetInlinedArgumentHole)
    176 
    177  static const size_t Index = 0;
    178  static const size_t NumNonArgumentOperands = 1;
    179  static size_t ArgIndex(size_t i) {
    180    return NumNonArgumentOperands + BOX_PIECES * i;
    181  }
    182 
    183  explicit LGetInlinedArgumentHole(uint32_t numOperands)
    184      : LVariadicInstruction(classOpcode, numOperands) {}
    185 
    186  const LAllocation* getIndex() { return getOperand(Index); }
    187 
    188  MGetInlinedArgumentHole* mir() const {
    189    return mir_->toGetInlinedArgumentHole();
    190  }
    191 };
    192 
    193 class LInlineArgumentsSlice : public LVariadicInstruction<1, 1> {
    194 public:
    195  LIR_HEADER(InlineArgumentsSlice)
    196 
    197  static const size_t Begin = 0;
    198  static const size_t Count = 1;
    199  static const size_t NumNonArgumentOperands = 2;
    200  static size_t ArgIndex(size_t i) {
    201    return NumNonArgumentOperands + BOX_PIECES * i;
    202  }
    203 
    204  explicit LInlineArgumentsSlice(uint32_t numOperands, const LDefinition& temp)
    205      : LVariadicInstruction(classOpcode, numOperands) {
    206    setTemp(0, temp);
    207  }
    208 
    209  const LAllocation* begin() { return getOperand(Begin); }
    210  const LAllocation* count() { return getOperand(Count); }
    211  const LDefinition* temp() { return getTemp(0); }
    212 
    213  MInlineArgumentsSlice* mir() const { return mir_->toInlineArgumentsSlice(); }
    214 };
    215 
    216 // Common code for LIR descended from MCall.
    217 template <size_t Defs, size_t Operands, size_t Temps>
    218 class LJSCallInstructionHelper
    219    : public LCallInstructionHelper<Defs, Operands, Temps> {
    220 protected:
    221  explicit LJSCallInstructionHelper(LNode::Opcode opcode)
    222      : LCallInstructionHelper<Defs, Operands, Temps>(opcode) {}
    223 
    224 public:
    225  MCall* mir() const { return this->mir_->toCall(); }
    226 
    227  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    228  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    229 
    230  // Does not include |this|.
    231  uint32_t numActualArgs() const { return mir()->numActualArgs(); }
    232 
    233  bool isConstructing() const { return mir()->isConstructing(); }
    234  bool ignoresReturnValue() const { return mir()->ignoresReturnValue(); }
    235 };
    236 
    237 // Generates a polymorphic callsite, wherein the function being called is
    238 // unknown and anticipated to vary.
    239 class LCallGeneric : public LJSCallInstructionHelper<BOX_PIECES, 1, 1> {
    240 public:
    241  LIR_HEADER(CallGeneric)
    242 
    243  LCallGeneric(const LAllocation& callee, const LDefinition& argc)
    244      : LJSCallInstructionHelper(classOpcode) {
    245    setOperand(0, callee);
    246    setTemp(0, argc);
    247  }
    248 
    249  const LAllocation* getCallee() { return getOperand(0); }
    250  const LDefinition* getArgc() { return getTemp(0); }
    251 };
    252 
    253 // Generates a hardcoded callsite for a known, non-native target.
    254 class LCallKnown : public LJSCallInstructionHelper<BOX_PIECES, 1, 1> {
    255 public:
    256  LIR_HEADER(CallKnown)
    257 
    258  LCallKnown(const LAllocation& func, const LDefinition& tmpobjreg)
    259      : LJSCallInstructionHelper(classOpcode) {
    260    setOperand(0, func);
    261    setTemp(0, tmpobjreg);
    262  }
    263 
    264  const LAllocation* getFunction() { return getOperand(0); }
    265  const LDefinition* getTempObject() { return getTemp(0); }
    266 };
    267 
    268 // Generates a hardcoded callsite for a known, native target.
    269 class LCallNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> {
    270 public:
    271  LIR_HEADER(CallNative)
    272 
    273  LCallNative(const LDefinition& argContext, const LDefinition& argUintN,
    274              const LDefinition& argVp, const LDefinition& tmpreg)
    275      : LJSCallInstructionHelper(classOpcode) {
    276    // Registers used for callWithABI().
    277    setTemp(0, argContext);
    278    setTemp(1, argUintN);
    279    setTemp(2, argVp);
    280 
    281    // Temporary registers.
    282    setTemp(3, tmpreg);
    283  }
    284 
    285  const LDefinition* getArgContextReg() { return getTemp(0); }
    286  const LDefinition* getArgUintNReg() { return getTemp(1); }
    287  const LDefinition* getArgVpReg() { return getTemp(2); }
    288  const LDefinition* getTempReg() { return getTemp(3); }
    289 };
    290 
    291 class LCallClassHook : public LCallInstructionHelper<BOX_PIECES, 1, 4> {
    292 public:
    293  LIR_HEADER(CallClassHook)
    294 
    295  LCallClassHook(const LAllocation& callee, const LDefinition& argContext,
    296                 const LDefinition& argUintN, const LDefinition& argVp,
    297                 const LDefinition& tmpreg)
    298      : LCallInstructionHelper(classOpcode) {
    299    setOperand(0, callee);
    300 
    301    // Registers used for callWithABI().
    302    setTemp(0, argContext);
    303    setTemp(1, argUintN);
    304    setTemp(2, argVp);
    305 
    306    // Temporary registers.
    307    setTemp(3, tmpreg);
    308  }
    309 
    310  MCallClassHook* mir() const { return mir_->toCallClassHook(); }
    311 
    312  const LAllocation* getCallee() { return this->getOperand(0); }
    313 
    314  const LDefinition* getArgContextReg() { return getTemp(0); }
    315  const LDefinition* getArgUintNReg() { return getTemp(1); }
    316  const LDefinition* getArgVpReg() { return getTemp(2); }
    317  const LDefinition* getTempReg() { return getTemp(3); }
    318 };
    319 
    320 // Generates a hardcoded callsite for a known, DOM-native target.
    321 class LCallDOMNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> {
    322 public:
    323  LIR_HEADER(CallDOMNative)
    324 
    325  LCallDOMNative(const LDefinition& argJSContext, const LDefinition& argObj,
    326                 const LDefinition& argPrivate, const LDefinition& argArgs)
    327      : LJSCallInstructionHelper(classOpcode) {
    328    setTemp(0, argJSContext);
    329    setTemp(1, argObj);
    330    setTemp(2, argPrivate);
    331    setTemp(3, argArgs);
    332  }
    333 
    334  const LDefinition* getArgJSContext() { return getTemp(0); }
    335  const LDefinition* getArgObj() { return getTemp(1); }
    336  const LDefinition* getArgPrivate() { return getTemp(2); }
    337  const LDefinition* getArgArgs() { return getTemp(3); }
    338 };
    339 
    340 // Generates a polymorphic callsite, wherein the function being called is
    341 // unknown and anticipated to vary.
    342 class LApplyArgsGeneric
    343    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
    344 public:
    345  LIR_HEADER(ApplyArgsGeneric)
    346 
    347  LApplyArgsGeneric(const LAllocation& func, const LAllocation& argc,
    348                    const LBoxAllocation& thisv, const LDefinition& tmpObjReg,
    349                    const LDefinition& tmpCopy)
    350      : LCallInstructionHelper(classOpcode) {
    351    setOperand(0, func);
    352    setOperand(1, argc);
    353    setBoxOperand(ThisIndex, thisv);
    354    setTemp(0, tmpObjReg);
    355    setTemp(1, tmpCopy);
    356  }
    357 
    358  MApplyArgs* mir() const { return mir_->toApplyArgs(); }
    359 
    360  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    361  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    362 
    363  uint32_t numExtraFormals() const { return mir()->numExtraFormals(); }
    364 
    365  const LAllocation* getFunction() { return getOperand(0); }
    366  const LAllocation* getArgc() { return getOperand(1); }
    367  static const size_t ThisIndex = 2;
    368  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    369 
    370  const LDefinition* getTempObject() { return getTemp(0); }
    371  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    372 };
    373 
    374 class LApplyArgsObj
    375    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
    376 public:
    377  LIR_HEADER(ApplyArgsObj)
    378 
    379  LApplyArgsObj(const LAllocation& func, const LAllocation& argsObj,
    380                const LBoxAllocation& thisv, const LDefinition& tmpObjReg,
    381                const LDefinition& tmpCopy)
    382      : LCallInstructionHelper(classOpcode) {
    383    setOperand(0, func);
    384    setOperand(1, argsObj);
    385    setBoxOperand(ThisIndex, thisv);
    386    setTemp(0, tmpObjReg);
    387    setTemp(1, tmpCopy);
    388  }
    389 
    390  MApplyArgsObj* mir() const { return mir_->toApplyArgsObj(); }
    391 
    392  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    393  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    394 
    395  const LAllocation* getFunction() { return getOperand(0); }
    396  const LAllocation* getArgsObj() { return getOperand(1); }
    397  // All registers are calltemps. argc is mapped to the same register as
    398  // ArgsObj. argc becomes live as ArgsObj is dying.
    399  const LAllocation* getArgc() { return getOperand(1); }
    400  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    401  static const size_t ThisIndex = 2;
    402 
    403  const LDefinition* getTempObject() { return getTemp(0); }
    404  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    405 };
    406 
    407 class LApplyArrayGeneric
    408    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> {
    409 public:
    410  LIR_HEADER(ApplyArrayGeneric)
    411 
    412  LApplyArrayGeneric(const LAllocation& func, const LAllocation& elements,
    413                     const LBoxAllocation& thisv, const LDefinition& tmpObjReg,
    414                     const LDefinition& tmpCopy)
    415      : LCallInstructionHelper(classOpcode) {
    416    setOperand(0, func);
    417    setOperand(1, elements);
    418    setBoxOperand(ThisIndex, thisv);
    419    setTemp(0, tmpObjReg);
    420    setTemp(1, tmpCopy);
    421  }
    422 
    423  MApplyArray* mir() const { return mir_->toApplyArray(); }
    424 
    425  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    426  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    427 
    428  const LAllocation* getFunction() { return getOperand(0); }
    429  const LAllocation* getElements() { return getOperand(1); }
    430  // argc is mapped to the same register as elements: argc becomes
    431  // live as elements is dying, all registers are calltemps.
    432  const LAllocation* getArgc() { return getOperand(1); }
    433  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    434  static const size_t ThisIndex = 2;
    435 
    436  const LDefinition* getTempObject() { return getTemp(0); }
    437  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    438 };
    439 
    440 class LConstructArgsGeneric
    441    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 3, 1> {
    442 public:
    443  LIR_HEADER(ConstructArgsGeneric)
    444 
    445  LConstructArgsGeneric(const LAllocation& func, const LAllocation& argc,
    446                        const LAllocation& newTarget,
    447                        const LBoxAllocation& thisv,
    448                        const LDefinition& tmpObjReg)
    449      : LCallInstructionHelper(classOpcode) {
    450    setOperand(0, func);
    451    setOperand(1, argc);
    452    setOperand(2, newTarget);
    453    setBoxOperand(ThisIndex, thisv);
    454    setTemp(0, tmpObjReg);
    455  }
    456 
    457  MConstructArgs* mir() const { return mir_->toConstructArgs(); }
    458 
    459  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    460  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    461 
    462  uint32_t numExtraFormals() const { return mir()->numExtraFormals(); }
    463 
    464  const LAllocation* getFunction() { return getOperand(0); }
    465  const LAllocation* getArgc() { return getOperand(1); }
    466  const LAllocation* getNewTarget() { return getOperand(2); }
    467  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    468 
    469  static const size_t ThisIndex = 3;
    470 
    471  const LDefinition* getTempObject() { return getTemp(0); }
    472 
    473  // tempForArgCopy is mapped to the same register as newTarget:
    474  // tempForArgCopy becomes live as newTarget is dying, all registers are
    475  // calltemps.
    476  const LAllocation* getTempForArgCopy() { return getOperand(2); }
    477 };
    478 
    479 class LConstructArrayGeneric
    480    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 3, 1> {
    481 public:
    482  LIR_HEADER(ConstructArrayGeneric)
    483 
    484  LConstructArrayGeneric(const LAllocation& func, const LAllocation& elements,
    485                         const LAllocation& newTarget,
    486                         const LBoxAllocation& thisv,
    487                         const LDefinition& tmpObjReg)
    488      : LCallInstructionHelper(classOpcode) {
    489    setOperand(0, func);
    490    setOperand(1, elements);
    491    setOperand(2, newTarget);
    492    setBoxOperand(ThisIndex, thisv);
    493    setTemp(0, tmpObjReg);
    494  }
    495 
    496  MConstructArray* mir() const { return mir_->toConstructArray(); }
    497 
    498  bool hasSingleTarget() const { return getSingleTarget() != nullptr; }
    499  WrappedFunction* getSingleTarget() const { return mir()->getSingleTarget(); }
    500 
    501  const LAllocation* getFunction() { return getOperand(0); }
    502  const LAllocation* getElements() { return getOperand(1); }
    503  const LAllocation* getNewTarget() { return getOperand(2); }
    504  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    505 
    506  static const size_t ThisIndex = 3;
    507 
    508  const LDefinition* getTempObject() { return getTemp(0); }
    509 
    510  // argc is mapped to the same register as elements: argc becomes
    511  // live as elements is dying, all registers are calltemps.
    512  const LAllocation* getArgc() { return getOperand(1); }
    513 
    514  // tempForArgCopy is mapped to the same register as newTarget:
    515  // tempForArgCopy becomes live as newTarget is dying, all registers are
    516  // calltemps.
    517  const LAllocation* getTempForArgCopy() { return getOperand(2); }
    518 };
    519 
    520 class LApplyArgsNative
    521    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 1, 3> {
    522 public:
    523  LIR_HEADER(ApplyArgsNative)
    524 
    525  LApplyArgsNative(const LAllocation& argc, const LBoxAllocation& thisv,
    526                   const LDefinition& tmpObjReg, const LDefinition& tmpCopy,
    527                   const LDefinition& tmpExtra)
    528      : LCallInstructionHelper(classOpcode) {
    529    setOperand(0, argc);
    530    setBoxOperand(ThisIndex, thisv);
    531    setTemp(0, tmpObjReg);
    532    setTemp(1, tmpCopy);
    533    setTemp(2, tmpExtra);
    534  }
    535 
    536  static constexpr bool isConstructing() { return false; }
    537 
    538  MApplyArgs* mir() const { return mir_->toApplyArgs(); }
    539 
    540  uint32_t numExtraFormals() const { return mir()->numExtraFormals(); }
    541 
    542  const LAllocation* getArgc() { return getOperand(0); }
    543  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    544 
    545  static const size_t ThisIndex = 1;
    546 
    547  const LDefinition* getTempObject() { return getTemp(0); }
    548  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    549  const LDefinition* getTempExtra() { return getTemp(2); }
    550 };
    551 
    552 class LApplyArgsObjNative
    553    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 1, 3> {
    554 public:
    555  LIR_HEADER(ApplyArgsObjNative)
    556 
    557  LApplyArgsObjNative(const LAllocation& argsObj, const LBoxAllocation& thisv,
    558                      const LDefinition& tmpObjReg, const LDefinition& tmpCopy,
    559                      const LDefinition& tmpExtra)
    560      : LCallInstructionHelper(classOpcode) {
    561    setOperand(0, argsObj);
    562    setBoxOperand(ThisIndex, thisv);
    563    setTemp(0, tmpObjReg);
    564    setTemp(1, tmpCopy);
    565    setTemp(2, tmpExtra);
    566  }
    567 
    568  static constexpr bool isConstructing() { return false; }
    569 
    570  MApplyArgsObj* mir() const { return mir_->toApplyArgsObj(); }
    571 
    572  const LAllocation* getArgsObj() { return getOperand(0); }
    573  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    574 
    575  static const size_t ThisIndex = 1;
    576 
    577  const LDefinition* getTempObject() { return getTemp(0); }
    578  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    579  const LDefinition* getTempExtra() { return getTemp(2); }
    580 
    581  // argc is mapped to the same register as argsObj: argc becomes live as
    582  // argsObj is dying, all registers are calltemps.
    583  const LAllocation* getArgc() { return getOperand(0); }
    584 };
    585 
    586 class LApplyArrayNative
    587    : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 1, 3> {
    588 public:
    589  LIR_HEADER(ApplyArrayNative)
    590 
    591  LApplyArrayNative(const LAllocation& elements, const LBoxAllocation& thisv,
    592                    const LDefinition& tmpObjReg, const LDefinition& tmpCopy,
    593                    const LDefinition& tmpExtra)
    594      : LCallInstructionHelper(classOpcode) {
    595    setOperand(0, elements);
    596    setBoxOperand(ThisIndex, thisv);
    597    setTemp(0, tmpObjReg);
    598    setTemp(1, tmpCopy);
    599    setTemp(2, tmpExtra);
    600  }
    601 
    602  static constexpr bool isConstructing() { return false; }
    603 
    604  MApplyArray* mir() const { return mir_->toApplyArray(); }
    605 
    606  const LAllocation* getElements() { return getOperand(0); }
    607  LBoxAllocation thisValue() const { return getBoxOperand(ThisIndex); }
    608 
    609  static const size_t ThisIndex = 1;
    610 
    611  const LDefinition* getTempObject() { return getTemp(0); }
    612  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    613  const LDefinition* getTempExtra() { return getTemp(2); }
    614 
    615  // argc is mapped to the same register as elements: argc becomes live as
    616  // elements is dying, all registers are calltemps.
    617  const LAllocation* getArgc() { return getOperand(0); }
    618 };
    619 
    620 class LConstructArgsNative : public LCallInstructionHelper<BOX_PIECES, 2, 3> {
    621 public:
    622  LIR_HEADER(ConstructArgsNative)
    623 
    624  LConstructArgsNative(const LAllocation& argc, const LAllocation& newTarget,
    625                       const LDefinition& tmpObjReg, const LDefinition& tmpCopy,
    626                       const LDefinition& tmpExtra)
    627      : LCallInstructionHelper(classOpcode) {
    628    setOperand(0, argc);
    629    setOperand(1, newTarget);
    630    setTemp(0, tmpObjReg);
    631    setTemp(1, tmpCopy);
    632    setTemp(2, tmpExtra);
    633  }
    634 
    635  static constexpr bool isConstructing() { return true; }
    636 
    637  MConstructArgs* mir() const { return mir_->toConstructArgs(); }
    638 
    639  uint32_t numExtraFormals() const { return mir()->numExtraFormals(); }
    640 
    641  const LAllocation* getArgc() { return getOperand(0); }
    642  const LAllocation* getNewTarget() { return getOperand(1); }
    643 
    644  const LDefinition* getTempObject() { return getTemp(0); }
    645  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    646  const LDefinition* getTempExtra() { return getTemp(2); }
    647 };
    648 
    649 class LConstructArrayNative : public LCallInstructionHelper<BOX_PIECES, 2, 3> {
    650 public:
    651  LIR_HEADER(ConstructArrayNative)
    652 
    653  LConstructArrayNative(const LAllocation& elements,
    654                        const LAllocation& newTarget,
    655                        const LDefinition& tmpObjReg,
    656                        const LDefinition& tmpCopy, const LDefinition& tmpExtra)
    657      : LCallInstructionHelper(classOpcode) {
    658    setOperand(0, elements);
    659    setOperand(1, newTarget);
    660    setTemp(0, tmpObjReg);
    661    setTemp(1, tmpCopy);
    662    setTemp(2, tmpExtra);
    663  }
    664 
    665  static constexpr bool isConstructing() { return true; }
    666 
    667  MConstructArray* mir() const { return mir_->toConstructArray(); }
    668 
    669  const LAllocation* getElements() { return getOperand(0); }
    670  const LAllocation* getNewTarget() { return getOperand(1); }
    671 
    672  const LDefinition* getTempObject() { return getTemp(0); }
    673  const LDefinition* getTempForArgCopy() { return getTemp(1); }
    674  const LDefinition* getTempExtra() { return getTemp(2); }
    675 
    676  // argc is mapped to the same register as elements: argc becomes live as
    677  // elements is dying, all registers are calltemps.
    678  const LAllocation* getArgc() { return getOperand(0); }
    679 };
    680 
    681 // Returns from the function being compiled (not used in inlined frames). The
    682 // input must be a box.
    683 class LReturn : public LInstructionHelper<0, BOX_PIECES, 0> {
    684  bool isGenerator_;
    685 
    686 public:
    687  LIR_HEADER(Return)
    688 
    689  explicit LReturn(bool isGenerator)
    690      : LInstructionHelper(classOpcode), isGenerator_(isGenerator) {}
    691 
    692  bool isGenerator() { return isGenerator_; }
    693 };
    694 
    695 class LHypot : public LCallInstructionHelper<1, 4, 0> {
    696  uint32_t numOperands_;
    697 
    698 public:
    699  LIR_HEADER(Hypot)
    700  LHypot(const LAllocation& x, const LAllocation& y)
    701      : LCallInstructionHelper(classOpcode), numOperands_(2) {
    702    setOperand(0, x);
    703    setOperand(1, y);
    704  }
    705 
    706  LHypot(const LAllocation& x, const LAllocation& y, const LAllocation& z)
    707      : LCallInstructionHelper(classOpcode), numOperands_(3) {
    708    setOperand(0, x);
    709    setOperand(1, y);
    710    setOperand(2, z);
    711  }
    712 
    713  LHypot(const LAllocation& x, const LAllocation& y, const LAllocation& z,
    714         const LAllocation& w)
    715      : LCallInstructionHelper(classOpcode), numOperands_(4) {
    716    setOperand(0, x);
    717    setOperand(1, y);
    718    setOperand(2, z);
    719    setOperand(3, w);
    720  }
    721 
    722  uint32_t numArgs() const { return numOperands_; }
    723 
    724  const LAllocation* x() { return getOperand(0); }
    725 
    726  const LAllocation* y() { return getOperand(1); }
    727 };
    728 
    729 // Adds two integers, returning an integer value.
    730 class LAddI : public LBinaryMath<0> {
    731  bool recoversInput_;
    732 
    733 public:
    734  LIR_HEADER(AddI)
    735 
    736  LAddI() : LBinaryMath(classOpcode), recoversInput_(false) {}
    737 
    738  const char* extraName() const {
    739    return snapshot() ? "OverflowCheck" : nullptr;
    740  }
    741 
    742  bool recoversInput() const { return recoversInput_; }
    743  void setRecoversInput() { recoversInput_ = true; }
    744 
    745  MAdd* mir() const { return mir_->toAdd(); }
    746 };
    747 
    748 // Subtracts two integers, returning an integer value.
    749 class LSubI : public LBinaryMath<0> {
    750  bool recoversInput_;
    751 
    752 public:
    753  LIR_HEADER(SubI)
    754 
    755  LSubI() : LBinaryMath(classOpcode), recoversInput_(false) {}
    756 
    757  const char* extraName() const {
    758    return snapshot() ? "OverflowCheck" : nullptr;
    759  }
    760 
    761  bool recoversInput() const { return recoversInput_; }
    762  void setRecoversInput() { recoversInput_ = true; }
    763  MSub* mir() const { return mir_->toSub(); }
    764 };
    765 
    766 inline bool LNode::recoversInput() const {
    767  switch (op()) {
    768    case Opcode::AddI:
    769      return toAddI()->recoversInput();
    770    case Opcode::SubI:
    771      return toSubI()->recoversInput();
    772    default:
    773      return false;
    774  }
    775 }
    776 
    777 // Passed the BaselineFrame address in the OsrFrameReg via the IonOsrTempData
    778 // populated by PrepareOsrTempData.
    779 //
    780 // Forwards this object to the LOsrValues for Value materialization.
    781 class LOsrEntry : public LInstructionHelper<1, 0, 1> {
    782 protected:
    783  Label label_;
    784  uint32_t frameDepth_;
    785 
    786 public:
    787  LIR_HEADER(OsrEntry)
    788 
    789  explicit LOsrEntry(const LDefinition& temp)
    790      : LInstructionHelper(classOpcode), frameDepth_(0) {
    791    setTemp(0, temp);
    792  }
    793 
    794  void setFrameDepth(uint32_t depth) { frameDepth_ = depth; }
    795  uint32_t getFrameDepth() { return frameDepth_; }
    796  Label* label() { return &label_; }
    797  const LDefinition* temp() { return getTemp(0); }
    798 };
    799 
    800 // This is used only with LWasmCall.
    801 class LWasmCallIndirectAdjunctSafepoint : public LInstructionHelper<0, 0, 0> {
    802  CodeOffset offs_;
    803  uint32_t framePushedAtStackMapBase_;
    804 
    805 public:
    806  LIR_HEADER(WasmCallIndirectAdjunctSafepoint);
    807 
    808  LWasmCallIndirectAdjunctSafepoint()
    809      : LInstructionHelper(classOpcode),
    810        offs_(0),
    811        framePushedAtStackMapBase_(0) {
    812    // Ensure that the safepoint does not get live registers associated with it.
    813    setIsCall();
    814  }
    815 
    816  CodeOffset safepointLocation() const {
    817    MOZ_ASSERT(offs_.offset() != 0);
    818    return offs_;
    819  }
    820  uint32_t framePushedAtStackMapBase() const {
    821    MOZ_ASSERT(offs_.offset() != 0);
    822    return framePushedAtStackMapBase_;
    823  }
    824  void recordSafepointInfo(CodeOffset offs, uint32_t framePushed) {
    825    offs_ = offs;
    826    framePushedAtStackMapBase_ = framePushed;
    827  }
    828 };
    829 
    830 // LWasmCall may be generated into two function calls in the case of
    831 // call_indirect, one for the fast path and one for the slow path.  In that
    832 // case, the node carries a pointer to a companion node, the "adjunct
    833 // safepoint", representing the safepoint for the second of the two calls.  The
    834 // dual-call construction is only meaningful for wasm because wasm has no
    835 // invalidation of code; this is not a pattern to be used generally.
    836 class LWasmCall : public LVariadicInstruction<0, 0> {
    837  LWasmCallIndirectAdjunctSafepoint* adjunctSafepoint_;
    838 
    839 public:
    840  LIR_HEADER(WasmCall);
    841 
    842  explicit LWasmCall(uint32_t numOperands)
    843      : LVariadicInstruction(classOpcode, numOperands),
    844        adjunctSafepoint_(nullptr) {
    845    this->setIsCall();
    846  }
    847 
    848  MWasmCallBase* callBase() const {
    849    if (isCatchable() && !isReturnCall()) {
    850      return static_cast<MWasmCallBase*>(mirCatchable());
    851    }
    852    if (isReturnCall()) {
    853      return static_cast<MWasmReturnCall*>(mirReturnCall());
    854    }
    855    return static_cast<MWasmCallBase*>(mirUncatchable());
    856  }
    857  bool isCatchable() const { return mir_->isWasmCallCatchable(); }
    858  bool isReturnCall() const { return mir_->isWasmReturnCall(); }
    859  MWasmCallCatchable* mirCatchable() const {
    860    return mir_->toWasmCallCatchable();
    861  }
    862  MWasmCallUncatchable* mirUncatchable() const {
    863    return mir_->toWasmCallUncatchable();
    864  }
    865  MWasmReturnCall* mirReturnCall() const { return mir_->toWasmReturnCall(); }
    866 
    867  static bool isCallPreserved(AnyRegister reg) {
    868    // All MWasmCalls preserve the TLS register:
    869    //  - internal/indirect calls do by the internal wasm ABI
    870    //  - import calls do by explicitly saving/restoring at the callsite
    871    //  - builtin calls do because the TLS reg is non-volatile
    872    // See also CodeGeneratorShared::emitWasmCall.
    873    //
    874    // All other registers are not preserved. This is is relied upon by
    875    // MWasmCallCatchable which needs all live registers to be spilled before
    876    // a call.
    877    return !reg.isFloat() && reg.gpr() == InstanceReg;
    878  }
    879 
    880  LWasmCallIndirectAdjunctSafepoint* adjunctSafepoint() const {
    881    MOZ_ASSERT(adjunctSafepoint_ != nullptr);
    882    return adjunctSafepoint_;
    883  }
    884  void setAdjunctSafepoint(LWasmCallIndirectAdjunctSafepoint* asp) {
    885    adjunctSafepoint_ = asp;
    886  }
    887 };
    888 
    889 class LWasmRegisterResult : public LInstructionHelper<1, 0, 0> {
    890 public:
    891  LIR_HEADER(WasmRegisterResult);
    892 
    893  LWasmRegisterResult() : LInstructionHelper(classOpcode) {}
    894 
    895  MWasmRegisterResult* mir() const {
    896    if (!mir_->isWasmRegisterResult()) {
    897      return nullptr;
    898    }
    899    return mir_->toWasmRegisterResult();
    900  }
    901 };
    902 
    903 class LWasmRegisterPairResult : public LInstructionHelper<2, 0, 0> {
    904 public:
    905  LIR_HEADER(WasmRegisterPairResult);
    906 
    907  LWasmRegisterPairResult() : LInstructionHelper(classOpcode) {}
    908 
    909  MDefinition* mir() const { return mirRaw(); }
    910 };
    911 
    912 class LWasmSystemFloatRegisterResult : public LInstructionHelper<1, 0, 0> {
    913 public:
    914  LIR_HEADER(WasmSystemFloatRegisterResult);
    915 
    916  LWasmSystemFloatRegisterResult() : LInstructionHelper(classOpcode) {}
    917 
    918  MWasmSystemFloatRegisterResult* mir() const {
    919    return mir_->toWasmSystemFloatRegisterResult();
    920  }
    921 };
    922 
    923 inline uint32_t LStackArea::base() const {
    924  return ins()->toWasmStackResultArea()->mir()->base();
    925 }
    926 inline void LStackArea::setBase(uint32_t base) {
    927  ins()->toWasmStackResultArea()->mir()->setBase(base);
    928 }
    929 inline uint32_t LStackArea::size() const {
    930  return ins()->toWasmStackResultArea()->mir()->byteSize();
    931 }
    932 
    933 inline bool LStackArea::ResultIterator::done() const {
    934  return idx_ == alloc_.ins()->toWasmStackResultArea()->mir()->resultCount();
    935 }
    936 inline void LStackArea::ResultIterator::next() {
    937  MOZ_ASSERT(!done());
    938  idx_++;
    939 }
    940 inline LAllocation LStackArea::ResultIterator::alloc() const {
    941  MOZ_ASSERT(!done());
    942  MWasmStackResultArea* area = alloc_.ins()->toWasmStackResultArea()->mir();
    943  const auto& stackResult = area->result(idx_);
    944  MIRType type = stackResult.type();
    945  auto width =
    946 #ifndef JS_PUNBOX64
    947      type == MIRType::Int64 ? LStackSlot::DoubleWord :
    948 #endif
    949                             LStackSlot::width(LDefinition::TypeFrom(type));
    950  return LStackSlot(area->base() - stackResult.offset(), width);
    951 }
    952 inline bool LStackArea::ResultIterator::isWasmAnyRef() const {
    953  MOZ_ASSERT(!done());
    954  MWasmStackResultArea* area = alloc_.ins()->toWasmStackResultArea()->mir();
    955  MIRType type = area->result(idx_).type();
    956 #ifndef JS_PUNBOX64
    957  // LDefinition::TypeFrom isn't defined for MIRType::Int64 values on
    958  // this platform, so here we have a special case.
    959  if (type == MIRType::Int64) {
    960    return false;
    961  }
    962 #endif
    963  return LDefinition::TypeFrom(type) == LDefinition::WASM_ANYREF;
    964 }
    965 
    966 class LWasmStackResult : public LInstructionHelper<1, 1, 0> {
    967 public:
    968  LIR_HEADER(WasmStackResult);
    969 
    970  LWasmStackResult() : LInstructionHelper(classOpcode) {}
    971 
    972  MWasmStackResult* mir() const { return mir_->toWasmStackResult(); }
    973  LStackSlot result(uint32_t base) const {
    974    auto width = LStackSlot::width(LDefinition::TypeFrom(mir()->type()));
    975    return LStackSlot(base - mir()->result().offset(), width);
    976  }
    977 };
    978 
    979 class LWasmStackResult64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
    980 public:
    981  LIR_HEADER(WasmStackResult64);
    982 
    983  LWasmStackResult64() : LInstructionHelper(classOpcode) {}
    984 
    985  MWasmStackResult* mir() const { return mir_->toWasmStackResult(); }
    986  LStackSlot result(uint32_t base, LDefinition* def) {
    987    uint32_t offset = base - mir()->result().offset();
    988 #if defined(JS_NUNBOX32)
    989    if (def == getDef(INT64LOW_INDEX)) {
    990      offset -= INT64LOW_OFFSET;
    991    } else {
    992      MOZ_ASSERT(def == getDef(INT64HIGH_INDEX));
    993      offset -= INT64HIGH_OFFSET;
    994    }
    995 #else
    996    MOZ_ASSERT(def == getDef(0));
    997 #endif
    998    return LStackSlot(offset, LStackSlot::DoubleWord);
    999  }
   1000 };
   1001 
   1002 inline LStackSlot LStackArea::resultAlloc(LInstruction* lir,
   1003                                          LDefinition* def) const {
   1004  if (lir->isWasmStackResult64()) {
   1005    return lir->toWasmStackResult64()->result(base(), def);
   1006  }
   1007  MOZ_ASSERT(def == lir->getDef(0));
   1008  return lir->toWasmStackResult()->result(base());
   1009 }
   1010 
   1011 inline bool LNode::isCallPreserved(AnyRegister reg) const {
   1012  return isWasmCall() && LWasmCall::isCallPreserved(reg);
   1013 }
   1014 
   1015 template <size_t NumDefs>
   1016 class LIonToWasmCallBase : public LVariadicInstruction<NumDefs, 1> {
   1017  using Base = LVariadicInstruction<NumDefs, 1>;
   1018 
   1019 public:
   1020  explicit LIonToWasmCallBase(LNode::Opcode classOpcode, uint32_t numOperands,
   1021                              const LDefinition& temp)
   1022      : Base(classOpcode, numOperands) {
   1023    this->setIsCall();
   1024    this->setTemp(0, temp);
   1025  }
   1026  MIonToWasmCall* mir() const { return this->mir_->toIonToWasmCall(); }
   1027  const LDefinition* temp() { return this->getTemp(0); }
   1028 };
   1029 
   1030 class LIonToWasmCall : public LIonToWasmCallBase<1> {
   1031 public:
   1032  LIR_HEADER(IonToWasmCall);
   1033  LIonToWasmCall(uint32_t numOperands, const LDefinition& temp)
   1034      : LIonToWasmCallBase<1>(classOpcode, numOperands, temp) {}
   1035 };
   1036 
   1037 class LIonToWasmCallV : public LIonToWasmCallBase<BOX_PIECES> {
   1038 public:
   1039  LIR_HEADER(IonToWasmCallV);
   1040  LIonToWasmCallV(uint32_t numOperands, const LDefinition& temp)
   1041      : LIonToWasmCallBase<BOX_PIECES>(classOpcode, numOperands, temp) {}
   1042 };
   1043 
   1044 class LIonToWasmCallI64 : public LIonToWasmCallBase<INT64_PIECES> {
   1045 public:
   1046  LIR_HEADER(IonToWasmCallI64);
   1047  LIonToWasmCallI64(uint32_t numOperands, const LDefinition& temp)
   1048      : LIonToWasmCallBase<INT64_PIECES>(classOpcode, numOperands, temp) {}
   1049 };
   1050 
   1051 // Definitions for `extraName` methods of generated LIR instructions.
   1052 
   1053 #ifdef JS_JITSPEW
   1054 const char* LBox::extraName() const { return StringFromMIRType(type_); }
   1055 
   1056 const char* LNewArray::extraName() const {
   1057  return mir()->isVMCall() ? "VMCall" : nullptr;
   1058 }
   1059 
   1060 const char* LNewObject::extraName() const {
   1061  return mir()->isVMCall() ? "VMCall" : nullptr;
   1062 }
   1063 
   1064 const char* LCompare::extraName() const { return CodeName(jsop_); }
   1065 
   1066 const char* LCompareI64::extraName() const { return CodeName(jsop_); }
   1067 
   1068 const char* LCompareI64AndBranch::extraName() const { return CodeName(jsop_); }
   1069 
   1070 const char* LCompareAndBranch::extraName() const { return CodeName(jsop_); }
   1071 
   1072 const char* LStrictConstantCompareInt32AndBranch::extraName() const {
   1073  return CodeName(cmpMir()->jsop());
   1074 }
   1075 
   1076 const char* LStrictConstantCompareBooleanAndBranch::extraName() const {
   1077  return CodeName(cmpMir()->jsop());
   1078 }
   1079 
   1080 const char* LMathFunctionD::extraName() const {
   1081  return MMathFunction::FunctionName(mir()->function());
   1082 }
   1083 
   1084 const char* LMathFunctionF::extraName() const {
   1085  return MMathFunction::FunctionName(mir()->function());
   1086 }
   1087 
   1088 const char* LStoreElementV::extraName() const {
   1089  return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
   1090 }
   1091 
   1092 const char* LStoreElementT::extraName() const {
   1093  return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
   1094 }
   1095 
   1096 const char* LArrayPopShift::extraName() const {
   1097  return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift";
   1098 }
   1099 
   1100 const char* LMinMaxI::extraName() const {
   1101  return mir()->isMax() ? "Max" : "Min";
   1102 }
   1103 
   1104 const char* LMinMaxIntPtr::extraName() const {
   1105  return mir()->isMax() ? "Max" : "Min";
   1106 }
   1107 
   1108 const char* LMinMaxD::extraName() const {
   1109  return mir()->isMax() ? "Max" : "Min";
   1110 }
   1111 
   1112 const char* LMinMaxF::extraName() const {
   1113  return mir()->isMax() ? "Max" : "Min";
   1114 }
   1115 
   1116 const char* LMulI::extraName() const {
   1117  return (mir()->mode() == MMul::Integer)
   1118             ? "Integer"
   1119             : (mir()->canBeNegativeZero() ? "CanBeNegativeZero" : nullptr);
   1120 }
   1121 
   1122 const char* LDivI::extraName() const {
   1123  if (mir()->isTruncated()) {
   1124    if (mir()->canBeNegativeZero()) {
   1125      return mir()->canBeNegativeOverflow()
   1126                 ? "Truncate_NegativeZero_NegativeOverflow"
   1127                 : "Truncate_NegativeZero";
   1128    }
   1129    return mir()->canBeNegativeOverflow() ? "Truncate_NegativeOverflow"
   1130                                          : "Truncate";
   1131  }
   1132  if (mir()->canBeNegativeZero()) {
   1133    return mir()->canBeNegativeOverflow() ? "NegativeZero_NegativeOverflow"
   1134                                          : "NegativeZero";
   1135  }
   1136  return mir()->canBeNegativeOverflow() ? "NegativeOverflow" : nullptr;
   1137 }
   1138 
   1139 const char* LModI::extraName() const {
   1140  return mir()->isTruncated() ? "Truncated" : nullptr;
   1141 }
   1142 
   1143 const char* LBitOpI::extraName() const {
   1144  if (bitop() == JSOp::Ursh && mir_->toUrsh()->bailoutsDisabled()) {
   1145    return "ursh:BailoutsDisabled";
   1146  }
   1147  return CodeName(bitop_);
   1148 }
   1149 
   1150 const char* LBitOpI64::extraName() const { return CodeName(bitop_); }
   1151 
   1152 const char* LShiftI::extraName() const { return CodeName(bitop_); }
   1153 
   1154 const char* LShiftIntPtr::extraName() const { return CodeName(bitop_); }
   1155 
   1156 const char* LShiftI64::extraName() const { return CodeName(bitop_); }
   1157 
   1158 const char* LMathD::extraName() const { return CodeName(jsop_); }
   1159 
   1160 const char* LMathF::extraName() const { return CodeName(jsop_); }
   1161 #endif
   1162 
   1163 }  // namespace jit
   1164 }  // namespace js
   1165 
   1166 #endif /* jit_shared_LIR_shared_h */