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