Raise psllq and psrlq to absdbl, support in llvm
[hiphop-php.git] / hphp / doc / ir.specification
blob53afd41e79fd0bd1a2de5faa31785cd515122d6c
1 *******************************************
2 * HipHop Intermediate Representation (HHIR)
3 *******************************************
7 Introduction
8 ------------
10 The HipHop Intermediate Representation (IR) is a typed, in-memory,
11 static-single-assignment, intermediate-level representation of HHBC programs
12 used for just in time compilation, with these goals:
14   1. Complete. The IR represents a program or program fragment entirely,
15      without reference to HHBC or other upstream forms of the program.
17   2. Type-Safe. Since the IR deals directly with refined types and internal VM
18      types, all operations are typesafe. All instruction parameters have a
19      parameter type P, and all variables have a type S. Given an instruction
20      with source parameter type P and variable type S, S must be equal to or
21      more refined than P (S == P or S <: P).
23   3. Machine Independent. Since this IR is intended to be used in a JIT
24      compiler, it will always be used in a machine specific context.
25      Nevertheless, we rely on machine independence in order to separate
26      concerns and increase portability of the VM. Passes which manipulate IR
27      based on PHP or HHBC semantics should be portable. Passes which deal with
28      machine specifics (such as register allocation) should be done in the
29      lower level IR (vasm). Types are machine independent.
31 The unit of compilation is the IRUnit, which is a collection of Blocks
32 containing IRInstructions that produce and consume SSATmp values. Blocks are
33 single-entry, single-exit sequences of instructions (i.e. basic
34 blocks). Instructions may be annotated with Type parameter which modifies the
35 instruction's behavior, or with additional compile-time constant data (see
36 extra-data.h). Each SSATmp has a Type which describes the set of values it may
37 hold, over its entire live range. Instructions may have side effects, which
38 occur in execution order.
40 The static single assignment form guarantees the following two invariants for a
41 well-formed compilation unit:
43   1. Each SSATmp is assigned to by exactly one IRInstruction.
45   2. Definitions dominate uses. Every path to an IRInstruction using an SSATmp
46      first executes the IRInstruction defining the SSATmp.
48 Any pass that generates or manipulates IR must preserve these invariants,
49 however it is possible and expected for the invariants to be temporarily broken
50 during IR generation or during an optimization pass.
53 Control Flow
54 ------------
56 IRUnits have one entry block, zero or more exit blocks, and zero or more catch
57 blocks. Exit blocks leave the compilation unit in the middle of the same PHP
58 function using one of several instructions that exit a compilation unit
59 (e.g. ReqBindJmp). Catch blocks are blocks that are reachable from exceptional
60 control flow edges, and are executed during unwinding if an exception
61 propagates through the instruction that had it as a `taken' edge.
63 No SSATmps are defined on entry to the main Block.
65 Blocks which are join points may start with a DefLabel with destination
66 SSATmps. In that case, each predecessor must be a Jmp passing a matching number
67 of sources. In this case the Jmp acts as a tail-call, passing arguments the
68 same way a plain call would.
70 Together, the sources of the Jmp instructions and the destinations of the
71 DefLabel instructions act as traditional SSA Phi pseudo-functions; The type of
72 the DefLabel's destination is the type-union of the corresponding sources.
73 Because the Jmp sources are at the ends of blocks, they do not violate the SSA
74 dominator rule (rule 2, above).
77 Types
78 -----
80 For an overview of the HHIR type system, see the "Type System" section in
81 hackers-guide/jit-core.md.
84 SSATmps
85 -------
87 An SSATmp represents a virtual register. Since HHIR uses SSA, an SSATmp may
88 only be assigned to by one instruction. The type of an SSATmp represents the
89 set of values it may hold at the point it is defined, which is invariant over
90 the lifetime of the variable (from the definition point to the last use).
93 IRInstructions
94 --------------
96 An instruction is an executable operation with zero or more inputs (sources),
97 zero or one result (destination), and possible side effects such as accessing
98 memory, doing I/O, and which may branch or throw an exception. Some
99 instructions have a Type parameter which modifies its behavior, or other "extra
100 data" in an arbitrary C++ struct (see extra-data.h).
102 Each instruction has a signature which describes its effect, parameter types,
103 and return type, for example:
105   r:Bool = IsType<T> s:Gen
107 By convention we use infix; destinations on the left, = represents assignment,
108 then the opcode name, and source parameters. Types are to the right of the
109 entities they modify, separated by : for results, sources, and variables, or
110 delimited by <> for instruction modifiers.
112 Instruction flags further describe their behavior:
114 HasDest
115 NaryDest
117   The instruction defines exactly one destination variable (HasDest) or a
118   varying number of destination variables (NaryDest). These flags are mutually
119   exclusive. An instruction with neither of these flags set has zero
120   destination variables.
122   Note that an instruction's destination variable may sometimes be a copy of
123   one of the input variables. (For example, AddElem returns the array it took
124   as an input.)
126 CanCSE
128   The instruction is safe to elide through common subexpression elimination.
130 Essential
132   Whether the instruction is essential indicates whether it can be elided
133   through certain types of optimizations.
135   Currently this is just used to flag whether we are allowed to do dead code
136   elimination on it.
138 CallsNative
140   Indicates that the instruction will call a native helper.
142   The register allocator uses this to optimize register spills around native
143   calls and to bias register allocation toward arguments and return values.
145 ConsumesRC
147   The instruction consumes a reference to one or more of its sources, either by
148   decreasing its refcount or storing the reference to memory.
150 KillsSource
152   The instruction calls decref on one or more of its sources. Unless a source
153   is known to have a refcount > 1 before the instruction executes, it cannot
154   safely be used after the instruction has executed.
156 ProducesRC
158   The instruction produces an incref'd value.
160   This flag is currently unused.
162 MayRaiseError
164   The instruction may raise an error, and must have an edge to a catch block.
166 Terminal
168   The instruction has no next instruction; it either jumps, returns, or throws.
170 Branch
172   The instruction has a (sometimes optional) taken edge. Instructions that are
173   conditional branches (i.e. a Branch that is not Terminal) will also have a
174   next edge.
176 Passthrough
178   The value of the instruction's dest is the same as one of its inputs; it
179   differs only in the refcount of the underlying object, the type of the
180   variable, or some other property that doesn't affect the value of the
181   variable itself.
183 ModifiesStack
185   The instruction modifies the in-memory evaluation stack in the process of
186   performing its primary work. It will have a StkPtr destination in addition to
187   its primary destination.
189 HasStackVersion
191   This instruction has a counterpart that returns a StkPtr in addition to any
192   primary destination. The behavior of the stack-modifying version is otherwise
193   identical.
195 MInstrProp
197   The instruction may affect the type and/or value of its base operand,
198   operating on object properties.
200 MInstrElem
202   The instruction may affect the type and/or value of its base operand,
203   operating on array elements.
206 Instruction set
207 ---------------
209 1. Checks and Asserts
211 Note: Instructions that guard or check boxed types only check that the operand
212 is boxed, and they ignore the type of the value inside the box (the inner
213 type). The inner type is normally checked when the value within the box is
214 about to be loaded, using a separate CheckRefInner instruction.
216 | CheckType<T>, DRefineS(0), S(Gen), B|E|P
218   Check that the type of the src S0 is T, and if so copy it to D. If S0 is not
219   type T, branch to block B.
221 | CheckNullptr, ND, S(CountedStr,Nullptr), B|E|CRc
223   If S0 is not a null pointer, branch to block B. This is used to check the
224   return value of a native helper that returns a potentially null StringData*.
226 | AssertType, DRefineS(0), S(Gen,Cls), C|E|P
228   Assert that the type of S0 is T, copying it to D.
230 | CheckTypeMem<T>, ND, S(PtrToGen), B|E
232   If the value pointed to by S0 is not type T, branch to the block B.
234 | GuardLoc<T,localId>, ND, S(FramePtr) S(StkPtr), E
236   Guard that type of the given localId on the frame S0 is a subtype of the type
237   T; if not, make a fallback jump. (A jump to a service request that chains to
238   a retranslation for this tracelet.)
240   Returns a new frame pointer representing the same frame as S0 but with the
241   knowledge that the guarded local has type T.
243 | HintLocInner<T,localId>, ND, S(FramePtr), E
245   Hint that the inner type of a BoxedCell in localId is likely type T, where T
246   is a subtype of BoxedCell. The type must be guarded on before it is known to
247   be true (via LdRef).
249 | CheckLoc<T,localId>, ND, S(FramePtr), B|E
251   Check that type of the given localId on the frame S0 is T; if not, branch to
252   block B.
254   Returns a new frame pointer representing the same frame as S0 but with the
255   knowledge that the checked local has type T.
257 | AssertLoc<T,localId>, ND, S(FramePtr), E
259   Asserts that type of the supplied local on the frame S0 is T. This is used
260   for local type information, and is similar to GuardLoc except it doesn't
261   imply a runtime check (the assertion must've already been proven to be true)
262   and cannot cause control flow.
264   Returns a new frame pointer representing the same frame as S0 but with the
265   knowledge that the asserted local has type T.
267 | GuardStk<T,offset>, D(StkPtr), S(StkPtr) S(FramePtr), E
269   Guard that the type of the cell on the stack pointed to by S0 at offset (in
270   cells) is T. If not, make a fallback jump. (A jump to a service request that
271   chains to a retranslation for this tracelet.)
273   Returns a new StkPtr that represents the same stack but with the knowledge
274   that the slot at the index S1 has type T.
276 | HintStkInner<T,offset>, D(StkPtr), S(StkPtr), E
278   Hint that the inner type of the BoxedInitCell on the stack pointed to by S0
279   at offset (in cells) is T. The type must be guarded on before it is known to
280   be true (via LdRef).
282   Returns a new StkPtr that represents the same stack but with the prediction
283   information.
285 | CheckStk<T,offset>, D(StkPtr), S(StkPtr), B|E
287   Check that the type of the cell on the stack pointed to by S0 at offset (in
288   cells) is T; if not, branch to block B.
290   Returns a new StkPtr that represents the same stack but with the knowledge
291   that the slot at the index S1 has type T.
293 | AssertStk<T,offset>, D(StkPtr), S(StkPtr), E
295   Returns a new StkPtr that represents the same stack as S0, but with the
296   knowledge that the slot at offset (in cells) has type T. This is similar to a
297   GuardStk except that it does not imply a runtime check and cannot cause
298   control flow.
300 | CastStk<T,offset>, D(StkPtr), S(StkPtr), Er
302   Returns a new StkPtr that represents the same stack as S0, but with the slot
303   at offset (in cells) converted to type T.
305 | CastStkIntToDbl<offset>, D(StkPtr), S(StkPtr), E
307   Returns a new StkPtr where the slot at offset has been converted from an
308   integer to double.
311 The following instructions deal with paramater coercion (the standard type
312 conversion for arguments to HNI functions). If parameter coercion fails these
313 functions will throw a TVCoercion exception. They may throw other types of
314 exceptions depending on how coercion is implemented.
316 | CoerceStk<T,offset,fn,argNum>, D(StkPtr), S(StkPtr), Er
318   Returns a new StkPtr that represents the same stack as S0, but with the slot
319   at offset (in cells) converted to type T. May throw an exception in the case
320   of failed paramater coercion. The callee is f, and the position of the
321   argument being coerced is argNum.
323 | CoerceCellToBool<fn,argNum>, D(Bool), S(Cell), Er
325 | CoerceCellToInt<fn,argNum>,  D(Int), S(Cell), Er
327 | CoerceStrToInt<fn,argNum>,   D(Int), S(Str), Er
329 | CoerceCellToDbl<fn,argNum>,  D(Dbl), S(Cell), Er
331 | CoerceStrToDbl<fn,argNum>,   D(Dbl), S(Str), Er
333   These instructions convert either a Cell or a Str to a primitive type (Bool,
334   Int, Dbl) and return the resulting value. They may throw an exception upon
335   failed type coercion. They are encoded along with callee Func, fn, and the
336   integer position of the argument, argNum, being coerced.
338 | CheckInit, ND, S(Gen), B
340   If S0's type is Uninit, branch to block B.
342 | CheckInitMem, ND, S(PtrToGen) C(Int), B
344   If the value at S0 + S1 (in bytes) has type Uninit, branch to block B.
346 | CheckDefinedClsEq<className,classPtr>, ND, NA, B|E
348   Compare the currently defined class of name `className' with `classPtr'; if
349   they aren't equal or if `className' is not defined, branch to block B.
351 | CheckCold<TransID>, ND, NA, B|E
353   Check if the counter associated with translation TransID is cold (i.e. within
354   a fixed threshold). If it's not (i.e. such translation has reached the
355   "hotness threshold"), then branch to block B.
357 | GuardRefs, ND, S(Func) S(Int) C(Int) S(Int) S(Int) S(FramePtr) S(StkPtr), E
359   Perform reffiness guard checks. Operands:
361     S0 - function pointer for the frame
362     S1 - num params expected in the func
363     S2 - first bit to check, must be a multiple of 64
364     S3 - mask to check (RefDeps::Record::m_mask entires)
365     S4 - values to check (RefDeps::Record::m_vals entires)
366     S5 - Pointer to the current frame
367     S6 - Pointer to the current VM stack
369   If any of the checks fail, make a fallback jump. (Jump to a service request
370   that will chain to a retranslation of this tracelet.)
372 | CheckRefs, ND, S(Func) S(Int) C(Int) S(Int) S(Int), B|E
374   Perform reffiness guard checks. Operands:
376     S0 - function pointer for the frame
377     S1 - num params expected in the func
378     S2 - first bit to check, must be a multiple of 64
379     S3 - mask to check (RefDeps::Record::m_mask entires)
380     S4 - values to check (RefDeps::Record::m_vals entires)
382   If any of the checks fail, branch to block B.
384 | EndGuards, ND, NA, E
386   A no-op at runtime, this instruction serves to mark the end of the initial
387   sequence of guards in a trace.
389 | CheckNonNull, DSubtract(0, Nullptr), S(Nullptr,Func,PtrToGen,TCA,Cls), B
391   If the value in S0 is Nullptr, branch to block B.
393 | AssertNonNull, DSubtract(0, Nullptr), S(Nullptr,CountedStr,Func), P
395   Returns S0, with Nullptr removed from its type. This instruction currently
396   supports a very limited range of types but can be expanded if needed.
398 | CheckStaticLocInit, ND, S(BoxedCell), B
400   Check if the static local (RDS) RefData represented by S0 is initialized, and
401   if not branch to block B.
404 2. Arithmetic
407 | AbsDbl, D(Dbl), S(Dbl), C
409 | AddInt, D(Int), S(Int) S(Int), C
411 | SubInt, D(Int), S(Int) S(Int), C
413 | MulInt, D(Int), S(Int) S(Int), C
415 | AndInt, D(Int), S(Int) S(Int), C
417 | AddDbl, D(Dbl), S(Dbl) S(Dbl), C
419 | SubDbl, D(Dbl), S(Dbl) S(Dbl), C
421 | MulDbl, D(Dbl), S(Dbl) S(Dbl), C
423 | DivDbl, D(Dbl), S(Dbl) S(Dbl), B|C
425 | Mod, D(Int), S(Int) S(Int), C
427 | Sqrt, D(Dbl), S(Dbl), C
429 | OrInt, D(Int), S(Int) S(Int), C
431 | XorInt, D(Int), S(Int) S(Int), C
433 | Shl, D(Int), S(Int) S(Int), C
435 | Shr, D(Int), S(Int) S(Int), C
437 | Floor, D(Dbl), S(Dbl), C
439 | Ceil, D(Dbl), S(Dbl), C
441 | AddIntO, D(Int), S(Int) S(Int), B|C
443 | SubIntO, D(Int), S(Int) S(Int), B|C
445 | MulIntO, D(Int), S(Int) S(Int), B|C
447   Double arithmetic, integer arithmetic, and integer bitwise operations.
448   Performs the operation described by the opcode name on S0 and S1, and puts
449   the result in D.
451   Undefined behavior occurs if Mod is given a divisor of zero, or if the
452   divisor is -1 and the dividend is the minimum representable integer.
454   AbsDbl computes the absolute value of a double-precision value.
456   DivDbl will branch to block B when S1 is zero (signed or unsigned). When the
457   result of the division is a real valued number DivDbl conforms to IEEE 754.
458   In particular should the result of a division be zero the sign will follow
459   normal sign rules for division.
461   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
463   Floor and Ceil will return an integral value not greater, or not less
464   than their input respectively. Their use requires SSE 4.1, availability
465   should be checked before they are emitted.
467   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
468   branch to block B on integer overflow.
470 | XorBool, D(Bool), S(Bool) S(Bool), C
472   Logical XOR of the two sources. (Note that && and || do not have
473   corresponding opcodes because they're handled at the bytecode level, to
474   implement short-circuiting.)
477 3. Type conversions
480 To array conversions:
482 | ConvBoolToArr,                D(Arr), S(Bool),                       C|PRc
484 | ConvDblToArr,                 D(Arr), S(Dbl),                        C|PRc
486 | ConvIntToArr,                 D(Arr), S(Int),                        C|PRc
488 | ConvObjToArr,                 D(Arr), S(Obj),                 Er|PRc|CRc|K
490 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
492 | ConvCellToArr,                D(Arr), S(Cell),                Er|PRc|CRc|K
495 To bool conversions:
497 | ConvArrToBool,               D(Bool), S(Arr),                           NF
499 | ConvDblToBool,               D(Bool), S(Dbl),                            C
501 | ConvIntToBool,               D(Bool), S(Int),                            C
503 | ConvStrToBool,               D(Bool), S(Str),                           NF
505 | ConvObjToBool,               D(Bool), S(Obj),                           NF
507 | ConvCellToBool,              D(Bool), S(Cell),                          NF
510 To double conversions:
512 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
514 | ConvBoolToDbl,                D(Dbl), S(Bool),                           C
516 | ConvIntToDbl,                 D(Dbl), S(Int),                            C
518 | ConvObjToDbl,                 D(Dbl), S(Obj),                           Er
520 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
522 | ConvCellToDbl,                D(Dbl), S(Cell),                          Er
525 To int conversions:
527 | ConvArrToInt,                 D(Int), S(Arr),                           NF
529 | ConvBoolToInt,                D(Int), S(Bool),                           C
531 | ConvDblToInt,                 D(Int), S(Dbl),                            C
533 | ConvObjToInt,                 D(Int), S(Obj),                         Er|K
535 | ConvStrToInt,                 D(Int), S(Str),                           NF
537 | ConvCellToInt,                D(Int), S(Cell),                        Er|K
540 To object conversions:
542 | ConvCellToObj, D(Obj), S(Cell), Er|CRc|PRc|K
545 To string conversions:
547 | ConvBoolToStr,          D(StaticStr), S(Bool),                           C
549 | ConvDblToStr,                 D(Str), S(Dbl),                          PRc
551 | ConvIntToStr,                 D(Str), S(Int),                          PRc
553 | ConvObjToStr,                 D(Str), S(Obj),                       PRc|Er
555 | ConvResToStr,                 D(Str), S(Res),                       PRc|Er
557 | ConvCellToStr,                D(Str), S(Cell),                      PRc|Er
560   All the above opcodes convert S0 from its current type to the destination
561   type, according to the PHP semantics of such a conversion.
563 | ConvClsToCctx, D(Cctx), S(Cls), C
565   Convert a class to a class context (i.e. the class with a 1 or'd into the low
566   bit).
568 4. Boolean predicates
570 | Gt,                          D(Bool), S(Gen) S(Gen), C
572 | GtX,                         D(Bool), S(Gen) S(Gen), Er|C
574 | Gte,                         D(Bool), S(Gen) S(Gen), C
576 | GteX,                        D(Bool), S(Gen) S(Gen), Er|C
578 | Lt,                          D(Bool), S(Gen) S(Gen), C
580 | LtX,                         D(Bool), S(Gen) S(Gen), Er|C
582 | Lte,                         D(Bool), S(Gen) S(Gen), C
584 | LteX,                        D(Bool), S(Gen) S(Gen), Er|C
586 | Eq,                          D(Bool), S(Gen) S(Gen), C
588 | EqX,                         D(Bool), S(Gen) S(Gen), Er|C
590 | Neq,                         D(Bool), S(Gen) S(Gen), C
592 | NeqX,                        D(Bool), S(Gen) S(Gen), Er|C
594 | Same,                        D(Bool), S(Gen) S(Gen), C
596 | NSame,                       D(Bool), S(Gen) S(Gen), C
598   Perform comparisons with PHP semantics on S0 and S1, and put the result in D.
599   The -X versions may re-enter the VM when comparing an Object with a string,
600   and therefore may throw exceptions. The non-X versions must not be passed
601   (Object,String) pairs, and do not throw. Note that Same and NSame never
602   re-enter or throw, for any types.
604 | GtInt,                       D(Bool), S(Int) S(Int),                     C
606 | GteInt,                      D(Bool), S(Int) S(Int),                     C
608 | LtInt,                       D(Bool), S(Int) S(Int),                     C
610 | LteInt,                      D(Bool), S(Int) S(Int),                     C
612 | EqInt,                       D(Bool), S(Int) S(Int),                     C
614 | NeqInt,                      D(Bool), S(Int) S(Int),                     C
617   Perform 64-bit integer comparisons.
619 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                     C
621 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                     C
623 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                     C
625 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                     C
627 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                     C
629 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                     C
631   Perform comparisons of doubles. Comparisons that are unordered according to
632   IEEE 754 (such as when at least one operand is NaN) result in false.
634 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), C
636   Sets D based on whether S0 is a descendant of the class, interface, or trait
637   in S1. (Note that this is always false for a trait). S1 may be null at
638   runtime if the class is not defined.
640 | InstanceOfIface, D(Bool), S(Cls) CStr, C
642   Fast path for interface checks. Sets D based on whether S0 implements S1, but
643   S1 must be a unique interface. This should only be used in repo-authoritative
644   mode.
646 | ExtendsClass, D(Bool), S(Cls) C(Cls), C
648   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
649   of the class in S1, where S1 must be a unique class that is not an interface
650   or a trait.
652 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                       C
654 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                       C
656   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
657   of the class named by S1, where S1 must have a bit allocated for it in the
658   fast instance check bitvector (see class.h).
660 | InterfaceSupportsArr,        D(Bool), S(Str), C
662 | InterfaceSupportsStr,        D(Bool), S(Str), C
664 | InterfaceSupportsInt,        D(Bool), S(Str), C
666 | InterfaceSupportsDbl,        D(Bool), S(Str), C
668   Returns whether t instanceof S0 returns true when t is of the given type.
670 | IsType<T>, D(Bool), S(Cell), C
672   Sets D to true iff S0 holds a value that is of type T.
674 | IsNType<T>, D(Bool), S(Cell), C
676   Sets D to true iff S0 holds a value that is not of type T.
678 | IsTypeMem<T>, D(Bool), S(PtrToGen), NF
680   Sets D to true iff the value referenced by S0 is of type T.
682   The value in S0 must not be a pointer into the evaluation stack or frame
683   locals.
685 | IsNTypeMem<T>, D(Bool), S(PtrToGen), NF
687   Sets D to true iff the value referenced by S0 is not of type T.
689 | IsScalarType, D(Bool), S(Cell), C
691   Returns true if S0 is of type Int, Bool, Dbl or Str. Returns false otherwise.
693 | IsWaitHandle, D(Bool), S(Obj), C
695   Sets D to true iff S0 is a subclass of WaitHandle.
698 5. Branches
701 There is a conditional branch instruction for each predicate above, to enable
702 generating efficient compare-and-branch instruction sequences.
705 | JmpGt,                            ND, S(Gen) S(Gen),                   B|E
707 | JmpGte,                           ND, S(Gen) S(Gen),                   B|E
709 | JmpLt,                            ND, S(Gen) S(Gen),                   B|E
711 | JmpLte,                           ND, S(Gen) S(Gen),                   B|E
713 | JmpEq,                            ND, S(Gen) S(Gen),                   B|E
715 | JmpNeq,                           ND, S(Gen) S(Gen),                   B|E
717 | JmpSame,                          ND, S(Gen) S(Gen),                   B|E
719 | JmpNSame,                         ND, S(Gen) S(Gen),                   B|E
721 | JmpGtInt,                         ND, S(Int) S(Int),                   B|E
723 | JmpGteInt,                        ND, S(Int) S(Int),                   B|E
725 | JmpLtInt,                         ND, S(Int) S(Int),                   B|E
727 | JmpLteInt,                        ND, S(Int) S(Int),                   B|E
729 | JmpEqInt,                         ND, S(Int) S(Int),                   B|E
731 | JmpNeqInt,                        ND, S(Int) S(Int),                   B|E
733 | JmpInstanceOfBitmask,             ND, S(Cls) CStr,                     B|E
735 | JmpNInstanceOfBitmask,            ND, S(Cls) CStr,                     B|E
737   Fused jump instructions. These all operate exactly as their corresponding
738   query op, but also take a label to jump to when the condition is true.
740 | JmpZero,                          ND, S(Int,Bool),                     B|E
742 | JmpNZero,                         ND, S(Int,Bool),                     B|E
744   Conditionally jump to based on S0.
746 | JmpSSwitchDest, ND, S(TCA), T|E
748   Jump to the target of a sswitch statement, leaving the tracelet, where the
749   target TCA is S0.
751 | JmpSwitchDest, ND, S(Int), T|E
753   Jump to the target of a switch statement, leaving the tracelet, using table
754   metadata <JmpSwitchData> and index S0.
756 | CheckSurpriseFlags, ND, NA, B|E
758   Tests the implementation-specific surprise flags. If they're true, branches
759   to block B.
761 | FunctionReturnHook, ND, S(FramePtr) S(Gen), Er|E
763   Suprise flag hook for function returns.
765 | FunctionSuspendHook, ND, S(FramePtr) C(Bool), Er|E
767   Suprise flag hook for suspending async functions.
769 | Halt, ND, NA, T|E
771   Halt execution. Used only in tests, as a terminal instruction that does not
772   require any inputs or any successors.
774 | Jmp, ND, SVar(Top), B|T|E
776   Unconditional jump to block B. In the second form, the target block must
777   start with a DefLabel with the same number of destinations as Jmp's number of
778   sources. Jmp parallel-copies its sources to the DefLabel destinations.
780 | DefLabel, DMulti, NA, E
782   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
783   destinations is a no-op, and the predecessor blocks may not necessarily end
784   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
785   instruction with the same number of sources. Ordinary branch instructions may
786   not pass values to a DefLabel.
788 | ClsNeq<class>, D(Bool), S(Cls), C
790     Compare S0 to the class `class', returning true if it is not the same.
793 6. Reference manipulation
796 | Box, DBox(0), S(Gen), E|CRc|PRc
798   Box S0 if it is unboxed, and put the resulting BoxedCell in D.
800 | UnboxPtr, DUnboxPtr, S(PtrToGen), NF
802   If S0 points to a cell that is KindOfRef, dereference the pointer in the
803   TypedValue and return a pointer to the inner-cell in D.
805 | BoxPtr, DBoxPtr, S(PtrToGen), NF
807   Boxes the TypeValue that S0 points to if it is not boxed. The result D points
808   to the same TypedValue as S0 but has a more refined type.
810   S0 may not already point into a RefData (due to VM invariants), although the
811   IR type system does not enforce it.
814 7. Loads
817 | LdStack<T,offset>, DParamMayRelax, S(StkPtr), NF
819   Loads from S0 at offset (in cells), and puts the value in D as type T.
821 | TakeStack, ND, S(StackElem), E
823   Does nothing at runtime. Acts as a hint to the optimizer that the code is
824   taking ownership of a reference to S0.
826 | LdLoc<T,localId>, DParamMayRelax, S(FramePtr), NF
828   Loads local slot localId from the frame S0 and puts the value in D as type T.
830 | LdLocPseudoMain<T,localId>, DParam, S(FramePtr), B
832   Loads local number localId from frame S0 and puts the value in D if the
833   local's type is a subtype of T. If the local's type is not a subtype of T,
834   then the load does not happen, and this instruction branches to B. This
835   instruction is used for loading locals in pseudo-mains, where they can alias
836   globals.
838 | LdStackAddr<T,offset>, DParamPtr(Stk), S(StkPtr), C
840   Loads the address of the stack slot given by the pointer in S0 at the offset
841   (in cells). T must be a subtype of PtrToStkGen.
843 | LdLocAddr<T,localId>, DParamPtr(Frame), S(FramePtr), C
845   Loads the address of the local slot localId from the frame S0 into D. T must
846   be a subtype of PtrToFrameGen.
848 | LdRDSAddr<T,RDSHandle>, DParam, NA, C
850   Load the address of a Gen that lives at the specified RDS handle. The type
851   param must be a subtype of PtrToGen.
853 | LdVectorBase, D(PtrToMembCell), S(Obj), E
855 | LdPairBase, D(PtrToMembCell), S(Obj), E
857   Loads the base pointer to an array of Cells from the given collection
858   instance in S0.
860 | LdMem<T>, DParam, S(PtrToGen) C(Int), NF
862   Loads from S0 + S1 (in bytes) and puts the value in D.
864 | LdContField<T>, DParam, S(Obj) C(Int), NF
866   Loads a property from the object referenced by S0 at the offset given by S1
867   and puts the value in D. S0 must be a Generator.
869 | LdElem, D(Cell), S(PtrToCell) S(Int), NF
871   Loads the element at index S1 from the base pointer in S0. The index in S1 is
872   the number of bytes from the base in S0.
874 | CheckRefInner<T>, ND, S(BoxedCell), B|E
876   TODO(#2939547): this should take BoxedInitCell
878   Check that the inner type of the boxed cell in S0 is T, and if not take the
879   branch to B.
881 | LdRef<T>, DParam, S(BoxedCell), NF
883   TODO(#2939547): this should take BoxedInitCell
885   Loads the value held in the box referenced by S0 and puts the value in D. The
886   inner type of S0 must be a subtype of T (usually ensured with a previous
887   CheckRefInner).
889 | LdCtx, D(Ctx), S(FramePtr), C
891   Loads into D the value of the m_this/m_cls field out of the frame pointer S0,
892   which must be a frame for the function in the LdCtx's Marker. The result
893   could be either an object representing the this pointer or a class context.
895 | CheckCtxThis, ND, S(Ctx), B|E
897   Check that the context (m_this or m_cls) in S0 is a non-null $this
898   pointer. If not, branch to B.
900 | CastCtxThis, DThis, S(Ctx), C
902   Convert a Ctx known to contain a $this pointer to a specific object type,
903   based on the marker func for this instruction.
905 | LdCctx, D(Cctx), S(FramePtr), C
907   Loads into D the value of the m_cls field out of the frame pointer S0. The
908   compiler should generate this only if it can prove that the frame does not
909   contain a $this pointer.
911 | LdClsCtx, D(Cls), S(Ctx), C
913   Loads into D the class representing the current context. Extracts the class
914   from S0, which can be either the this pointer or the context class.
916 | LdClsCctx, D(Cls), S(Cctx), C
918   Loads into D the class representing the current context. Extracts the class
919   from the S0, which is a context class.
921 | LdClsCtor, D(Func), S(Cls), C|Er
923   Loads into D the constructor of class S0. If the constructor cannot be called
924   from the current context, raise an error.
926 | DefConst<T>, DParam, NA, C
928   Define a constant value of type T. D is presumed to be globally available and
929   the DefConst instruction will not actually appear in the IR instruction
930   stream.
932 | Conjure<T>, DParam, NA, NF
934   Define a value of type T. This instruction aborts at runtime; it is meant to
935   be used in tests or code that is known to be unreachable.
937 | LdCls, D(Cls), S(Str) C(Cls), C|E|Er
939   Loads the class named S0 in the context of the class S1. Invokes autoload and
940   may raise an error if the class is not defined. The explicit context
941   parameter allows the compiler to simplify this instruction to a DefConst in
942   some cases. If S0 is constant, this instruction may be simplified to a
943   LdClsCached.
945 | LdClsCached, D(Cls), CStr, C|E|Er
947   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
948   if the class is not defined.
950 | LdClsCachedSafe, D(Cls|Nullptr), CStr, NF
952   Loads the class whose name is S0 out of the RDS. If the class is not defined,
953   returns a null pointer.
955 | LdClsInitData, D(PtrToClsInitCell), S(Cls), C
957   Loads the pointer to the property initializer array for class S0.
959 | LookupClsRDSHandle, D(RDSHandle), S(Str), C
961   Look up the cached-class RDS handle for a given class name.
963 | DerefClsRDSHandle, D(Cls), S(RDSHandle), NF
965   Dereference an RDS handle that points to a cached class slot.
967 | LdCns, DCns, CStr, PRc
969   Load the constant named S0.
971 | LookupCns<T,constName>,   DCns, CStr, E|Er|PRc
973 | LookupCnsE<T,constName>,  DCns, CStr, E|Er|PRc
975   Load a constant via the RDS. Raises an undefined constant notice if the
976   constant cannot be defined. The E variant will instead throw a fatal error if
977   it cannot define the constant.
979 | LookupCnsU<T,constName,fallbackName>, DCns, CStr CStr, E|Er|PRc
981   Load an unqualified constant via the RDS, first by trying constName, then by
982   trying fallbackName. Raises a notice if neither can be found.
984 | LookupClsCns<T,className,constName>, DCns, NA, E|Er|PRc
986   Load a class constant for a class via the RDS, invoking autoload if it is not
987   defined. This instruction may raise an undefined constant error if autoload
988   cannot define the constant.
990 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func|Nullptr), NA, NF
992   Loads the target cache entry for a forwarding call to clsName::methodName.
993   May be Nullptr, if the method does not exist or the cache hasn't been filled
994   yet.
996 | LookupClsMethodFCache<clsName,methodName>,
997 |    D(Func|Nullptr), C(Cls) S(FramePtr),
998 |    E|Er
1000   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1001   the Class named by clsName and S1 should be the current vm frame pointer. May
1002   return Nullptr if lookup fails using a subset of the required lookup paths,
1003   indicating that a more complete lookup path should be taken. May throw if the
1004   method does not exist.
1006 | GetCtxFwdCallDyn<clsName,methodName>, D(Ctx), S(Ctx), PRc
1008   If S0 is a Cctx, return S0. If S0 is an object, check if clsName::methodName
1009   is a static method. If it is, return S0's class as a Ctx pointer. If not,
1010   return S0. If S0 is a Ctx, dynamically check if it is an object or Cctx at
1011   runtime and perform the operations described above.
1013 | GetCtxFwdCall, D(Ctx), S(Ctx) C(Func), PRc
1015   If S0 is an object and S1 is static, this opcode returns S0's class. If S0 is
1016   an object and S1 is not static, this opcode increfs S0 and returns it. If S0
1017   is a Cctx, this opcode returns S0.
1019 | LdClsMethodCacheFunc<clsName,methodName>, D(Func|Nullptr), NA, NF
1021   Loads the target cache entry for the method clsName::methodName. The result
1022   may be Nullptr, if the method does not exist or the cache hasn't been filled
1023   yet.
1025 | LdClsMethodCacheCls<clsName,methodName>, D(Cctx), NA, NF
1027   Loads the target cache class context entry for a call to clsName::methodName
1028   from the current context. This instruction must only be used when the value
1029   is known to not be empty.
1031 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr),
1032 |                                           S(FramePtr),
1033 |                                           E|Er
1035   Lookup a function in the class method targetcache. The class name and method
1036   name are clsName and methodName, respectively. S0 is the current vm frame
1037   pointer. Returns Nullptr if the method cannot be found using a subset of the
1038   required lookup paths, indicating that a more complete lookup path should be
1039   taken. May throw if the method does not exist.
1041 | LdClsMethod, D(Func), S(Cls) C(Int), C
1043   Load a Func* off of the class method table for S0, at offset S1 (in method
1044   slots).
1046 | LookupClsMethod, ND, S(Cls) S(Str) S(StkPtr) S(FramePtr), E|Er
1048   Store a pointer to a class method into an activation record. S0 points to the
1049   class, S1 is the method name, S2 points to the activation record, and S3 is a
1050   pointer to the current frame (used to get the context). May throw or fatal if
1051   method is not accessible.
1053 | LdPropAddr<T>, DParamPtr(Prop), S(Obj) C(Int), C
1055   Load the address of the object property for S0 at offset S1 (in bytes) into
1056   D.  T must be a subtype of PtrToPropGen.
1058 | LdGblAddr, D(PtrToGblGen), S(Str), B
1060   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1061   global is not defined.
1063 | LdGblAddrDef, D(PtrToGblGen), S(Str), E
1065   Loads a pointer to a global. S0 is the global's name. Defines the global if
1066   it is not already defined.
1068 | LdClsPropAddrOrNull, D(PtrToSPropGen|Nullptr),
1069 |                      S(Cls) S(Str) C(Cls),
1070 |                      C|E|Er
1072   Loads a pointer to a static class property. S0 points to the class, S1 is the
1073   property name, and S2 is the class representing the context of the code
1074   accessing the property. If class S0 does not have a visible and accessible
1075   static property named S1, then nullptr is returned.
1077 | LdClsPropAddrOrRaise, D(PtrToSPropGen), S(Cls) S(Str) C(Cls), C|E|Er
1079   Loads a pointer to a static class property. S0 points to the class, S1 is the
1080   property name, and S2 is the class representing the context of the code
1081   accessing the property. If class S0 does not have a visible and accessible
1082   static property named S1, throw a fatal error.
1084 | LdObjMethod<methodName,fatal>, ND, S(Cls) S(StkPtr), E|Er
1086   Stores a pointer to an object's method into an activation record. S0 points
1087   to the object's class, S1 points to the pre-live activation record.  Caches
1088   the mapping in the target cache. If `fatal' is true, raises a fatal if the
1089   class does not have an accessible method with the given name and does not
1090   have a __call method; otherwise (if `fatal' is false), raises a warning and
1091   puts func that does nothing and returns null (SystemLib::s_nullFunc) on the
1092   activation record.
1094 | LdObjInvoke, D(Func), S(Cls), B
1096   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1097   to block B if it is not present.
1099 | LdArrFuncCtx, ND, S(Arr) S(StkPtr) S(FramePtr), E|Er
1101   Try to load an array as a function context. This is for use translating
1102   FPushFunc when the callee is an array. This instruction attempts to populate
1103   a partially created ActRec pointed to by S1.
1105 | LdArrFPushCuf, ND, S(Arr) S(StkPtr) S(FramePtr), E|Er
1107 | LdStrFPushCuf, ND, S(Str) S(StkPtr) S(FramePtr), E|Er
1109   Try to resolve a method target for FPushCuf when the callee is an Arr or Str,
1110   respectively. These instructions mutate a partially created ActRec pointed to
1111   by S1.
1113 | LdObjClass, D(Cls), S(Obj), C
1115   Load the class out of the object in S0 and put it in D.
1117 | LdClsName, D(StaticStr), S(Cls), C
1119   Load the name of the Class* in S0.
1121 | LdFunc, D(Func), S(Str), E|CRc|Er
1123   Loads the Func whose name is S0. Fatal if the named function is not defined,
1124   and the function autoloader fails to define it.
1126 | LdFuncCached<funcName>, D(Func), NA, E|Er
1128   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1129   not defined yet. Fatal if function autoloader fails to define it.
1131 | LdFuncCachedSafe<funcName>, D(Func|Nullptr), NA, NF
1133   Try to load the Func named funcName from the RDS. If the function is not
1134   defined, returns a null pointer.
1136 | LdFuncCachedU<funcName,fallbackName>, D(Func), NA, E|Er
1138   Try to load a Func named funcName from the RDS, if it isn't defined, try to
1139   load a Func named fallbackName. If that also isn't defined, invoke autoload.
1140   If this still doesn't result in a Func, raise a fatal error.
1142 | LdARFuncPtr, D(Func), S(StkPtr,FramePtr) C(Int), C
1144   Loads the m_func member of an ActRec. S0 is the base address, and S1 is an
1145   offset, such that S0 + S1 points to the base of the ActRec.
1147 | LdFuncNumParams, D(Int), S(Func), NF
1149   Returns the value of func->numParams().
1151 | LdStrLen, D(Int), S(Str), NF
1153   Load the length of the string in S0.
1155 | LdStaticLocCached<func,staticLocalName>, D(BoxedCell), NA, NF
1157   Load the address of the static local RefData from the targetcache for
1158   function `func' with the static local variable named `staticLocalName'.
1161 8. Allocation
1164 | AllocObj, DAllocObj, S(Cls), Er
1166   Allocates a new object of class S1.
1168 | RegisterLiveObj, ND, S(Obj), E
1170   When EnableObjDestructCall is on, we need to keep track of objects to be able
1171   to call their destructors when a request exists.  This instruction is
1172   conditionally emitted to implement that.
1174 | CheckInitProps<class>, ND, NA, B|E
1176   Check if the properties for class are initialized and branches if not.
1178 | InitProps<class>, ND, NA, E|Er
1180   Calls the property initializer function (86pinit) for class.  May throw.
1182 | CheckInitSProps<class>, ND, NA, B|E
1184   Check if static properties for class are initialized and branches if not.
1186 | InitSProps<class>, ND, NA, E|Er
1188   Calls the static property initializer function (86sinit) for class. May
1189   throw.
1191 | NewInstanceRaw<class>, DAllocObj, NA, NF
1193   Allocates an instance of class.
1195 | InitObjProps<class>, ND, S(Obj), E
1197   Initializes properties of object S0.
1199 | ConstructInstance<class>, DAllocObj, NA, Er
1201   Call the custom instance constructor of an extension class.
1203 | CustomInstanceInit, DofS(0), S(Obj), Er
1205   Call the custom instance initializer of object S0.
1207 | NewArray, D(Arr), C(Int), PRc
1209   Allocate a new array with the expected capacity S0.
1211 | NewMixedArray, D(Arr), C(Int), PRc
1213   Allocate a new array in mixed mode with the expected capacity S0.
1215 | NewMIArray, D(Arr), C(Int), PRc
1217   Create a new MIArray.
1219 | NewMSArray, D(Arr), C(Int), PRc
1221   Create a new MSArray.
1223 | NewVArray, D(Arr), C(Int), PRc
1225   Create a new VArray.
1227 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1229   Allocate a new array in the same mode as S0 and with expected capacity S1,
1230   unless S1 == 0, in which case the capacity is set to S0's size.
1232 | NewPackedArray, DArrPacked, S(StkPtr), E|PRc|CRc
1234   Allocate a new array by taking the top size elements off the stack given by
1235   S0. Note that this instruction assumes it can take the values from the stack
1236   without increfing them.
1238 | AllocPackedArray<size>, DArrPacked, NA, E|PRc
1240   Allocate a new uninitialized packed array with space for size elements in it.
1241   The array will be initialized with values using either InitPackedArray or
1242   InitPackedArrayLoop.
1244 | InitPackedArray<index>, ND, S(Arr) S(Gen), E|CRc
1246   Store the S1 into the slot at index in array S0. This instruction assumes
1247   that it doesn't have to incref the value being stored. Used to initialize an
1248   array allocated with AllocPackedArray.
1250 | InitPackedArrayLoop<size>, ND, S(Arr) S(StkPtr), E|CRc
1252   Store the top size elements on the stack given by S1 into the array S0.
1253   Assumes that the first element on the stack is the last element in the array.
1254   Used to initialize an array allocated with AllocPackedArray that was too big
1255   to use a series of InitPackedArray instructions.
1257 | NewStructArray<keys...>, D(Arr), S(StkPtr), E|PRc|CRc
1259   Allocate a new key/value array, given N immediate keys and taking the top N
1260   elements off the stack given by S0. This instruction assumes it can take the
1261   values from the stack without increfing them.
1263 | NewCol, D(Obj), C(Int) C(Int), PRc
1265   Create a new collection, with type S0 and size S1.
1267 | Clone, D(Obj), S(Obj), E|PRc|Er
1269   Allocate an object by cloning S0.
1272 9. Call & Return
1274 | SpillFrame<numArgs,invName>, D(StkPtr),
1275 |                              S(StkPtr) S(Func,Nullptr) S(Ctx,Cls,Nullptr),
1276 |                              CRc
1278   Operands:
1280      S0 - caller stack pointer
1281      S1 - callee Func or nullptr
1282      S2 - object (for FPushObjMethod*), class (for FPushClsMethod*), context
1283           (for FPushClsMethodF), or nullptr (for FPushFunc*).
1285   Defines the fields for an activation record and writes them to the stack
1286   pointed to by S1.
1288 | CufIterSpillFrame<numArgs,iterId>, D(StkPtr),
1289 |                                    S(StkPtr) S(FramePtr),
1290 |                                    NF
1292   Operands:
1294      S0 - caller stack pointer
1295      S1 - caller frame pointer
1297   Defines the fields for an activation record using data from the iterator
1298   iterId, and writes them to the stack pointed to by S1
1300 | FreeActRec, D(FramePtr), S(FramePtr), NF
1302   Load the saved frame pointer from the activation record pointed to by S0 into
1303   D.
1305 | DefInlineFP<func,retBCOff,retSPOff>, D(FramePtr),
1306 |                                      S(StkPtr) S(StkPtr) S(FramePtr),
1307 |                                      NF
1309   Defines a frame pointer for an inlined function. S0 is a StkPtr that points
1310   to the ActRec for the callee (i.e. after parameters have been popped). S1 is
1311   a StkPtr that represents what the inlined function will return to (i.e. it
1312   points to the stack after the ActRec in S0 is popped).
1314   `func' is the function being inlined. `retBCOff' and `retSPOff' represent
1315   what the bytecode and stack offsets should be after the FCall instruction in
1316   ther caller.
1318   This instruction is primarily used to represent a frame in the IR in a way
1319   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1320   it is pushed into an unlikely path) it performs callee-side responsibilities
1321   for setting up an activation record (i.e. setting the return ip and m_soff,
1322   storing the frame pointer into D).
1324   The caller frame pointer is passed as S2. This is used to keep track of the
1325   call chain of inlined functions for simplification and dead code elimination.
1327 | InlineReturn, ND, S(FramePtr), E
1329   Unlinks a frame constructed by DefInlineFP.
1331 | CallArray, D(StkPtr), S(StkPtr) S(FramePtr), E|CRc
1333   Invoke function corresponding to the current FPI with array args. S0 points
1334   to the stack resulting after the ActRec for the function and the array of its
1335   arguments is pushed. CallArray pops the array off the stack, pushes the
1336   elements of the array as arguments, and invokes the function in the ActRec.
1338 | Call<numParams,returnOff,funcd,destroyLocals>, D(StkPtr),
1339 |                                                S(StkPtr) S(FramePtr),
1340 |                                                E
1342   Transfer control to a callee, based on the pre-live activation record and set
1343   of args on the stack pointed to by S0. S1 is the current caller frame
1344   pointer. The `funcd' in the extra data is a Func* for the callee if we know
1345   the callee statically.
1347 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), E
1349   Execute a call to the native builtin specified by the current function. S0
1350   and S1 should be the current vmfp and vmsp, respectively.
1352 | CallBuiltin<T>, DBuiltin, S(FramePtr) S(StkPtr) SVar(PtrToGen,Gen), E|Er|PRc
1354   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1355   and vmsp, respectively.
1357   The source and destination types correspond to C++ parameter and return types
1358   as follows:
1360     C++ type            HHIR type         Position
1361     -----------------   ---------         --------
1362     bool                Bool              source, destination
1363     int64_t             Int               source, destination
1364     double              Dbl               source, destination
1365     const String&       PtrToString       source
1366     const Array&        PtrToArray        source
1367     const Object&       PtrToObject       source
1368     const Variant&      PtrToGen          source
1369     Variant&            PtrToGen          source (ref param)
1370     String              {Str|InitNull}    destination
1371     Array               {Arr|InitNull}    destination
1372     Object              {Obj|InitNull}    destination
1373     Variant             {Gen-UninitNull}  destination
1375 | LdRetAddr, D(RetAddr), S(FramePtr), NF
1377   Load the return address off of the activation record pointed to by S0. The
1378   return address D is normally provided to a RetCtrl. Between a LdRetAddr and a
1379   RetCtrl, a FreeActRec is normally emitted to free the activation record S0.
1380   This is the reason why LdRetAddr is a separate instruction from RetCtrl.
1382 | RetCtrl, ND, S(StkPtr) S(FramePtr) S(RetAddr), T|E
1384   Ensure that S0 is stored in rVmSp and S1 is stored in rVmFp and then execute
1385   a hardware procedure-return using the return address specified by S2.
1387 | StRetVal, ND, S(FramePtr) S(Gen), E|CRc
1389   Writes the value in S1 to the return value slot on the activation record
1390   pointed to by S0.
1392 | RetAdjustStack, D(StkPtr), S(FramePtr), E
1394   Loads the new VM stack pointer into the destination. S0 is a pointer to the
1395   current activation record.
1397 | ReleaseVVOrExit, ND, S(FramePtr), B|E
1399   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1400   nothing. If it is an ExtraArgs, deallocates the ExtraArgs structure.
1401   Otherwise jumps to block B.
1403 | GenericRetDecRefs, ND, S(FramePtr), E
1405   Does decrefs of all the current function's locals, where S0 is a pointer to
1406   the relevant activation record.
1408   Semantically similar to a series of DecRefLoc.
1411 10. Stores
1414 | StMem, ND, S(PtrToGen) C(Int) S(Gen), E|CRc
1416   Store S2 into the location S0 + S1 (in bytes).
1418 | StProp, ND, S(Obj) C(Int) S(Gen), E|CRc
1420   Store S2 into the location S0 + S1 (in bytes).
1422 | StElem, ND, S(PtrToCell) S(Int) S(Cell), E|CRc
1424   Store S2 into the location given by the index S1 from base pointer S0. The
1425   index in S1 is the number of bytes from the base in S0.
1427 | StLoc<localId>, ND, S(FramePtr) S(Gen), E|CRc
1429   Store S1 to local number localId on the frame pointed to by S0.
1431 | StLocNT<localId>, ND, S(FramePtr) S(Gen), E|CRc
1433   Store S1 to local number localId on the frame pointed to by S0, without
1434   storing the type.
1436 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Gen), E|CRc
1438   Behaves just like StLoc, except the hard requirement that it is only emitted
1439   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1440   intraprocedural analysis to know whether the store is truly dead.
1442 | StRef, ND, S(BoxedCell) S(Cell), E|CRc
1444   Store the value in S1 into the RefData pointed to by S0. Stores the
1445   RefData::m_type also.
1447 | SpillStack, D(StkPtr), S(StkPtr) C(Int) SVar(StackElem), CRc
1449   SpillStack synchronizes the virtual execution stack with the physical stack
1450   by storing a variadic list of SSATmps to the physical stack.
1452   Operands:
1454      S0      - current stack pointer
1456      S1      - stack deficit; indicates the number of elements that need to be
1457                logically popped before the variadic list is pushed
1459      S2...   - variadic list of elements to spill, with values representing
1460                cells. A temp with type None means to keep the previous value on
1461                the stack.
1463 | ExceptionBarrier, D(StkPtr), S(StkPtr), E
1465   An essential instruciton that consumes and produces a stack.  This is used in
1466   places that need to ensure the stack goes to memory and cannot be DCE'd.
1467   Mostly unnecessary now (catch traces do the same thing), but there are a few
1468   locations that are not updated.
1471 11. Trace exits
1474 | SyncABIRegs, ND, S(FramePtr) S(StkPtr), E
1476   Ensures the cross-tracelet ABI registers are in a consistent state in
1477   preparation for an instruction that may leave the trace.
1479 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), E
1481   Sync the given vmfp and vmsp to their in-memory locations.
1483 | ReqBindJmp<bcOff,transFlags>, ND, NA, T|E
1485   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
1487 | ReqRetranslate<transFlags>, ND, NA, T|E
1489   Emit a jump to a service request that will chain to a retranslation of this
1490   tracelet.
1492   This instruction is used in exit traces for a type prediction that occurs at
1493   the first bytecode offset of a tracelet.
1495 | ReqRetranslateOpt<transId,bcOff>, ND, NA, T|E
1497   Emit a service request to retranslate, with a higher optimization gear,
1498   translation transID, which starts at bcOff. This instruction is used in exit
1499   traces that trigger profile-guided optimizations.
1501 | ReqBindJmpGt,                     ND, S(Gen) S(Gen),                   T|E
1503 | ReqBindJmpGte,                    ND, S(Gen) S(Gen),                   T|E
1505 | ReqBindJmpLt,                     ND, S(Gen) S(Gen),                   T|E
1507 | ReqBindJmpLte,                    ND, S(Gen) S(Gen),                   T|E
1509 | ReqBindJmpEq,                     ND, S(Gen) S(Gen),                   T|E
1511 | ReqBindJmpNeq,                    ND, S(Gen) S(Gen),                   T|E
1513 | ReqBindJmpGtInt,                  ND, S(Int) S(Int),                   T|E
1515 | ReqBindJmpGteInt,                 ND, S(Int) S(Int),                   T|E
1517 | ReqBindJmpLtInt,                  ND, S(Int) S(Int),                   T|E
1519 | ReqBindJmpLteInt,                 ND, S(Int) S(Int),                   T|E
1521 | ReqBindJmpEqInt,                  ND, S(Int) S(Int),                   T|E
1523 | ReqBindJmpNeqInt,                 ND, S(Int) S(Int),                   T|E
1525 | ReqBindJmpSame,                   ND, S(Gen) S(Gen),                   T|E
1527 | ReqBindJmpNSame,                  ND, S(Gen) S(Gen),                   T|E
1529 | ReqBindJmpInstanceOfBitmask,      ND, S(Cls) CStr,                     T|E
1531 | ReqBindJmpNInstanceOfBitmask,     ND, S(Cls) CStr,                     T|E
1533 | ReqBindJmpZero,                   ND, S(Int,Bool),                     T|E
1535 | ReqBindJmpNZero,                  ND, S(Int,Bool),                     T|E
1537   Test the condition based on the Jmp* op of similar name, and then emit a pair
1538   of smashable jumps to a REQ_BIND_JMPCC_FIRST service request.
1540 | SideExitJmpGt,                    ND, S(Gen) S(Gen),                     E
1542 | SideExitJmpGte,                   ND, S(Gen) S(Gen),                     E
1544 | SideExitJmpLt,                    ND, S(Gen) S(Gen),                     E
1546 | SideExitJmpLte,                   ND, S(Gen) S(Gen),                     E
1548 | SideExitJmpEq,                    ND, S(Gen) S(Gen),                     E
1550 | SideExitJmpNeq,                   ND, S(Gen) S(Gen),                     E
1552 | SideExitJmpGtInt,                 ND, S(Int) S(Int),                     E
1554 | SideExitJmpGteInt,                ND, S(Int) S(Int),                     E
1556 | SideExitJmpLtInt,                 ND, S(Int) S(Int),                     E
1558 | SideExitJmpLteInt,                ND, S(Int) S(Int),                     E
1560 | SideExitJmpEqInt,                 ND, S(Int) S(Int),                     E
1562 | SideExitJmpNeqInt,                ND, S(Int) S(Int),                     E
1564 | SideExitJmpSame,                  ND, S(Int) S(Int),                     E
1566 | SideExitJmpNSame,                 ND, S(Int) S(Int),                     E
1568 | SideExitJmpInstanceOfBitmask,     ND, S(Cls) CStr,                       E
1570 | SideExitJmpNInstanceOfBitmask,    ND, S(Cls) CStr,                       E
1572 | SideExitJmpZero,                  ND, S(Int,Bool),                       E
1574 | SideExitJmpNZero,                 ND, S(Int,Bool),                       E
1576   Test the condition based on the Jmp* op of similar name, and then emit a
1577   smashable jump to a REQ_BIND_SIDE_EXIT service request.
1579 | SideExitGuardLoc<T,locId,takenOff>, ND, S(FramePtr), E
1581   Test the type of a local, and if it fails jump to a side exit service
1582   request.
1584 | SideExitGuardStk<T,stackOff,takenOff>, D(StkPtr), S(StkPtr), E
1586   Test the type of a stack cell, and if it fails jump to a side exit service
1587   request.
1590 12. Refcounting and copies
1593 | Mov, DofS(0), S(Top), C|P
1595   Defines D as S0. May imply register-to-register moves at code generation
1596   time. Does not imply an incref or any other manipulation of S0.
1598 | TrackLoc<localId>, ND, S(Gen), E
1600   Defines localId as having value given by S0.  This does not generate code; it
1601   is used by the translator to track values that are stored in locals. It can
1602   be thought of as a store (which does not physically store anything).
1604 | IncRef, ND, S(Gen), E
1606   If S0 is a refcounted type, increment its refcount.
1608 | IncRefCtx, ND, S(Ctx), E
1610   If the Ctx in S0 is a $this pointer, IncRef it.
1612 | DecRefLoc<localId>, ND, S(FramePtr), E
1614   DecRef the local given by localId on the frame S0.
1616 | DecRefStack<T,offset>, ND, S(StkPtr), E
1618   DecRef a value of type T at offset on the stack pointed to by S0.
1620 | DecRefThis, ND, S(FramePtr), E
1622   DecRef the $this pointer in the ActRec S0, if it had one. Does nothing if
1623   there was a class context or null $this on the ActRec.
1625 | DecRef, ND, S(Gen), E|K|CRc
1627   Decrease the reference count of S0 by one, and call a destructor for types
1628   that require it if it goes to zero.
1630   Note that although DecRef takes a Gen, we don't allow it to use information
1631   about the inner types of a BoxedCell. This is because we don't guard on the
1632   inner types of a BoxedCell except when doing LdRef. For any S0 that is a
1633   strict subtype of BoxedCell, the DecRef must just decref it as if it were a
1634   BoxedCell.
1636 | DecRefMem, ND, S(PtrToGen) C(Int), E|CRc
1638   Decref the value pointed to by S0 at offset S1 (in bytes), calling any
1639   appropriate destructor if the refcount goes to zero.
1641 | DecRefNZ, ND, S(Gen), E|CRc
1643   Decrease the reference count of S0 by one, do not check if it goes to zero.
1644   This instruction can be used for more efficient code when it is provable that
1645   the reference count cannot go to zero.
1647 | TakeRef, ND, S(Gen), NF
1649   Produce reference, but do not modify the reference count. Used to inform
1650   refcount optimizer about implicitly owned references.
1653 13. Misc
1656 | DefFP, D(FramePtr), NA, E
1658   Creates a temporary D representing the current vm frame pointer.
1660 | DefSP<stackOff>, D(StkPtr), S(FramePtr), E
1662   Creates a temporary D representing the current vm stack pointer. S0 is a
1663   pointer to the current frame. The 'stackOff' is the logical offset between S0
1664   and the stack pointer, but in the case of generators this is not the
1665   physical offset at runtime.
1667   This instruction is used at the beginning of tracelets to represent the state
1668   of the stack on entry and does not emit code.
1670 | ReDefSP<offset,spansCall>, D(StkPtr), S(StkPtr) S(FramePtr), NF
1672   Re-define a stack in terms of a frame pointer S1 and an offset, putting the
1673   resulting pointer in D. The resulting stack is assumed to give the same view
1674   as S0, which is a previous stack pointer. (I.e. for getStackValue we just
1675   chain to S0.)
1677   This instruction is used when entering or "returning" from an inlined call.
1678   The one used on entry will generally be DCE'd when the actrec can be
1679   eliminated. The one on exit is only needed until TODO(#2288359).
1681   The spansCall boolean is true if there is possibly a Call instructions
1682   between the definition of S0 and this instruction.
1684 | Count, D(Int), S(Cell), Er
1686   Computes the number of elements in S0. The count of an array is the number of
1687   elements it contains, without recursing into containers in the array.
1688   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
1689   count of 0. The count of objects that implement the Countable interface is
1690   computed by returning the value of their count method. Objects that do not
1691   implement Countable have a count of 1.
1693 | CountArray,      D(Int), S(Arr), NF
1695 | CountArrayFast,  D(Int), S(Arr), NF
1697 | CountCollection, D(Int), S(Obj), NF
1699   Computes the number of elements in S0 using the same definition as Count, but
1700   with a restriction on the input type.
1702   CountArray expects any array. CountArrayFast expects an array whose kind is not
1703   kGlobalsKind. CountCollection expects a collection object.
1705 | Nop, ND, NA, NF
1707   Does nothing. It's sometimes useful for the simplifier to insert one of these
1708   in the instruction stream.
1711 14. Runtime helpers
1714 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), E|Er
1716   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
1717   a class) or implement (if S1 is an interface) S1, this instruction will raise
1718   a recoverable fatal error describing the type mismatch.
1720 | VerifyParamCallable, ND, S(Gen) C(Int), E|Er
1722   If S0 is not callable, as defined by the php function is_callable, this
1723   instruction will raise a recoverable fatal error describing the type
1724   mismatch.
1726 | VerifyParamFail, ND, C(Int), E|Er
1728   Assumes that parameter number S0 in the current function has failed its
1729   typehint and raises a recoverable fatal error describing the type mismatch.
1731 | VerifyRetCallable, ND, S(Gen), E|Er
1733   Verify a return type hint.
1735 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), E|Er
1737   Verify a return type hint.
1739 | VerifyRetFail, ND, S(Gen), E|Er
1741   Failure to verify a return type hint.
1743 | RaiseUninitLoc<localId>, ND, S(Str), E|Er
1745   Raise a notice for an uninitialized local variable.
1747 | WarnNonObjProp, ND, NA, E|Er
1749   Raise a warning for property access on a non-object base.
1751 | RaiseUndefProp, ND, S(Obj) CStr, E|Er
1753   Raise a notice for an undefined property named S1 on the class of S0.
1755 | RaiseError, ND, S(Str), E|T|Er
1757   Raises a fatal error with the text in S0 as its message.
1759 | RaiseWarning, ND, S(Str), E|Er
1761   Raises a warning with the text in S0 as its message.
1763 | RaiseNotice, ND, S(Str), E|Er
1765   Raises a notice with the text in S0 as its message.
1767 | RaiseArrayIndexNotice, ND, S(Int), E|Er
1769   Raises a notice that S0 is an undefined index for an array.
1771 | ClosureStaticLocInit, D(BoxedCell), CStr S(FramePtr) S(Cell), E
1773   Get boxed value to initialize static local named S0 in frame S1, where S1
1774   must be either a closure or generatorFromClosure function. If the static
1775   local has not yet been initialized, its value will be set to S2.
1777 | StaticLocInitCached, ND, S(BoxedCell) S(Cell), E
1779   Assuming S0 is an uninitialized static local RDS slot, initialize it by
1780   setting it to the value of S1.
1782 | PrintStr,  ND, S(Str),  E|Er|CRc
1784 | PrintInt,  ND, S(Int),  E|Er|CRc
1786 | PrintBool, ND, S(Bool), E|Er|CRc
1788   Print for various types.
1790 | ConcatIntStr, D(Str), S(Int) S(Str), Er|PRc
1792   Concatenate S0 and S1 after converting S0 to String.
1794 | ConcatStrInt, D(Str), S(Str) S(Int), Er|CRc|PRc
1796   Concatenate S0 and S1 after converting S1 to String.
1798 | ConcatStrStr, D(Str), S(Str) S(Str), Er|CRc|PRc
1800   Concatenate S0 and S1.
1802 | ConcatCellCell, D(Str), S(Cell) S(Cell), Er|CRc|PRc
1804   Concatenate S0 and S1 after converting them to strings in a way that obeys
1805   php semantics. (Calling object __toString methods, etc.)
1807 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), Er|CRc|PRc
1809   Concatenate S0, S1, and S2.
1811 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), Er|CRc|PRc
1813   Concatenate S0, S1, S2, and S3.
1815 | AddElemStrKey, D(Arr), S(Arr) S(Str) S(Cell), Er|CRc|PRc
1817   Add S2 to the array S0 for the key S1, and return the resulting array.
1819 | AddElemIntKey, D(Arr), S(Arr) S(Int) S(Cell), Er|CRc|PRc
1821   Add S2 to the array S0 for the key S1, and return the resulting array.
1823 | AddNewElem, D(Arr), S(Arr) S(Cell), Er|CRc|PRc
1825   Add S1 as a new element to the array S0.  (Note: S1 must actually be a
1826   subtype of InitCell for array invariants, but we can't assert this yet in the
1827   IR because many eval stack slots are not entirely typed wrt initness right
1828   now.)
1830 | ArrayAdd, D(Arr), S(Arr) S(Arr), Er|CRc|PRc
1832   Has the effects of the php + operator on the two source arrays.
1834 | AKExists, D(Bool), S(Cell) S(Cell), NF
1836   Has the effects of array_key_exists(S0, S1). Note that S0 does not need to be
1837   an array---if it is an Obj the ArrayAccess API will be used, etc.
1839 | ArrayIdx, D(Cell), S(Arr) S(Int,Str) S(Cell), E|PRc
1841   Checks if S0 contains the key S1, and returns the result if found. Otherwise
1842   S2 is returned.
1844 | GenericIdx, D(Cell), S(Cell) S(Cell) S(Cell), E|PRc|Er
1846   Checks if S0 contains the key S1, and returns the result if found. Otherwise
1847   S2 is returned. If S0 does not support array or indexed access S2 is
1848   returned.
1850 | LdBindAddr<SrcKey>, D(TCA), NA, NF
1852   Creates a service request to bind the given target address. Returns a TCA
1853   pointing either to the service request (before the service request is
1854   satisfied) or to the native code for the given target address (once the
1855   service request is satisfied).
1857 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
1859 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
1861 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|Er
1863   These instructions are used to determine the target of a switch statement
1864   with target range [S1:S1 + S2), when invoked with the value S0. They call
1865   helper functions to check whether S0 is an numeric integer in the range
1866   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
1867   target of the default target, S2 + 1.
1869 | LdSSwitchDestFast, D(TCA), S(Gen), NF
1871 | LdSSwitchDestSlow, D(TCA), S(Gen), E|Er
1873   Load string switch destinations (two different compilation strategies).
1875 | InterpOne<T,bcOff,numPopped,numPushed>, D(StkPtr),
1876 |                                         S(StkPtr) S(FramePtr),
1877 |                                         E|Er
1879   Call the interpreter implementation function for one opcode. S0 and S1 are,
1880   respectively, the VM stack and frame pointers before this instruction. T is
1881   only present if the instruction pushes to the stack, in which case it is the
1882   type of the top stack element after the call. `bcOff' is the bytecode
1883   offset. `numPopped' is the number of stack cells consumed by the instruction,
1884   and `numPushed' is the number of stack cells produced by the
1885   instruction. This instruction returns the updated VM stack pointer.
1887 | InterpOneCF<T,bcOff,numPopped,numPushed>, D(StkPtr),
1888 |                                           S(StkPtr) S(FramePtr),
1889 |                                           T|E|Er
1891   Similar to InterpOne, but for instructions that may modify vmpc.
1893 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), E|Er
1895   Returns a bool indicating whether the class, interface, or trait named by S0
1896   exists. Invokes autoload if S1 is true.
1899 15. Generators & Closures
1902 | StClosureCtx, ND, S(Obj) S(Ctx,Nullptr), CRc|E
1904   Store the context represented by S1 into the closure object S0. S1 may be a
1905   Nullptr when there is no context (i.e. the closure is being used in a
1906   non-method).
1908 | StClosureFunc<func>, ND, S(Obj), E
1910   Store the Func* clone that should be used for calling this closure into the
1911   closure object S0.
1913 | StClosureArg<offsetBytes>, ND, S(Obj) S(Gen), CRc|E
1915   Store one of the closure environment arguments (i.e. from the closure's use
1916   clause) from S1 into the closure object S0.
1918 | CreateCont, D(Obj), S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), E|PRc
1920   Create a Generator object and suspend the ActRec provided by S0 into its
1921   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
1922   resume address to S2 and resume offset to S3.
1924 | CreateAFWH, D(Obj),
1925 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
1926 |             E|Er|CRc|PRc
1928   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
1929   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
1930   the native resume address to S2, resume offset to S3, and mark it blocked on
1931   non-finished child S4.
1933 | CreateSSWH, D(Obj), S(Cell), CRc|PRc
1935   Call c_StaticWaitHandle::CreateSucceededVM.
1937 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), E|Er
1939   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
1940   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
1941   provided by S0.
1943   Injects S1 into the currently running scheduler instance and performs
1944   cross-scheduler and intra-scheduler cycle detection. Throws if the
1945   dependency cannot be established.
1947 | ContEnter, D(StkPtr),
1948 |            S(StkPtr) S(FramePtr) S(FramePtr) S(TCA) C(Int),
1949 |            E
1951   Enters a generator body. S0 is the current stack pointer pointing to fully
1952   spilled stack, S1 is the current frame pointer, S2 is the generator frame
1953   pointer embedded in the Generator object, S3 is the address to jump to,
1954   and S4 is the bytecode offset in the caller to return to when the generator
1955   suspends or returns.
1957 | ContPreNext, ND, S(Obj) C(Bool), B|E
1959   Performs operations needed for the next() method of Generator object S0.
1960   If the generator is already running or finished, or it was not started yet
1961   and the S1 check-started flag is set, the branch B is taken. Otherwise,
1962   the generator is marked as running.
1964 | ContStartedCheck, ND, S(Obj), B|E
1966   Checks if the Generator object S0 has started, and if not branches to
1967   block B.
1969 | ContValid, D(Bool), S(Obj), E
1971   Return true if a generator is not done, false otherwise.
1973 | ContArIncKey, ND, S(FramePtr), E
1975   Special-case key update for generator, ActRec of which is S0, which
1976   increments the key of a generator if that generator's key is an Int.
1977   This will cause undefined behavior if the generator's key is not an Int.
1979 | ContArIncIdx, D(Int), S(FramePtr), E
1981   Increment the internal index in the Generator in S0, and return the new index
1982   value.
1984 | ContArUpdateIdx, ND, S(FramePtr) S(Int), E
1986   Updates the internal index of generator with S1 if necessary, i.e. if S1
1987   is larger than the index. S0 is the pointer to the embedded ActRec.
1989 | LdContActRec, D(FramePtr), S(Obj), C
1991   Loads the Generator object's ActRec, given a pointer to the generator
1992   object in S0.
1994 | LdContResumeAddr, D(TCA), S(Obj), E
1996   Load the resume addr from the Generator in S0.
1998 | StContArState<state>, ND, S(FramePtr), E
2000   Change the state of the Generator object which has frame pointer S0.
2002 | StContArResume<offset>, ND, S(FramePtr) S(TCA), E
2004   Store the resume address S1 into the Generator whose ActRec is given by S0,
2005   marking the offset to resume at as `offset'.
2007 | LdContArValue, DParam, S(FramePtr), PRc
2009   Loads 'value' from the Generator object ActRec of which is S0.
2011 | StContArValue, ND, S(FramePtr) S(Cell), E|CRc
2013   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2014   new value.
2016 | LdContArKey, DParam, S(FramePtr), PRc
2018   Loads 'key' from the Generator object ActRec of which is S0.
2020 | StContArKey, ND, S(FramePtr) S(Gen), E|CRc
2022   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2023   new value.
2025 | StAsyncArSucceeded, ND, S(FramePtr), E
2027   Mark the AsyncFunctionWaitHandle object whose ActRec is given by S0 as
2028   STATE_SUCCEEDED.
2030 | StAsyncArResume<offset>, ND, S(FramePtr) S(TCA), E
2032   Store the resume address S1 into the AsyncFunctionWaitHandle whose ActRec is
2033   given by S0, marking the offset to resume at as `offset'.
2035 | StAsyncArResult, ND, S(FramePtr) S(Cell), E|CRc
2037   Stores result into the AsyncFunctionWaitHandle object ActRec of which is S0.
2038   S1 is the value.
2040 | LdAsyncArParentChain, D(ABC), S(FramePtr), NF
2042   Loads the first parent of the AsyncFunctionWaitHandle object ActRec of which
2043   is S0.
2045 | AFWHBlockOn, ND, S(FramePtr) S(Obj), E|CRc
2047   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2048   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2050 | ABCUnblock, ND, S(ABC), E
2052   Calls AsioBlockableChain::Unblock.
2054 | LdWHState, D(Int), S(Obj), NF
2056   Loads the state of the WaitHandle in S0, which is a value from the wait
2057   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2058   not a WaitHandle.
2060 | LdWHResult, D(Cell), S(Obj), NF
2062   Loads the result of the WaitHandle in S0. This instruction has undefined
2063   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2065 | LdAFWHActRec, D(FramePtr), S(Obj), C
2067   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2068   AsyncFunctionWaitHandle object in S0.
2070 | LdResumableArObj, D(Obj), S(FramePtr), C
2072   Loads the Resumable object, given a Resumable's frame pointer in S0.
2075 16. Debugging, instrumentation, and profiling
2077 | IncStat, ND, C(Int) C(Int) C(Bool), E
2079   Increment stat counter. S0 is the implementation defined stat counter index,
2080   S1 is the amount to increment the counter (may be negative), and S2 is a
2081   'force' flag. This opcode becomes a noop iff (force == false and runtime
2082   stats are not enabled) at translation time.
2084 | IncTransCounter, ND, NA, E
2086   Increment a translation counter.  This is probably something related to TC
2087   print.
2089 | IncStatGrouped, ND, CStr CStr C(Int), E
2091   Adds the value S2 to the counter named S1, in the category S0.
2093 | IncProfCounter<TransID>, ND, NA, E
2095   Increment the profiling counter associated with translation TransID.
2097 | DbgAssertRefCount, ND, S(Counted,StaticStr,StaticArr), E
2099   Assert that S0 has a valid refcount. S0 must be a type with a valid (counted
2100   or static) _count field. If S0's count is implausible then execute a hardware
2101   trap instruction (int3 on x64).
2103 | DbgAssertPtr, ND, S(PtrToGen), E
2105   Assert that S0 points to plausible TypedValue. If the TypedValue is a type
2106   with a _count field, check that the count field is plausible using the same
2107   logic as DbgAssertRefCount. Internally this uses always_assert(); failures
2108   cause an abort (whatever always_assert does).
2110 | DbgAssertType<T>, ND, S(Cell), E
2112   Assert that S0 is of type T at runtime. If the assertion fails, execution is
2113   aborted via a hardware exception.
2115 | DbgAssertRetAddr, ND, NA, E
2117   Assert that the current hardware return address is the expected value. If the
2118   assertion fails, execution is aborted via a hardware exception.
2120 | RBTrace, ND, NA, E
2122   Ring buffer tracing.
2124 | ZeroErrorLevel, D(Int), NA, E
2126 | RestoreErrorLevel, ND, S(Int), E
2128   Helper instructions for fast implementation of the PHP error silencing
2129   operator (@foo()).
2132 17. Iterators
2135 | IterInit<IterData>,   D(Bool), S(Arr,Obj) S(FramePtr), Er|E|CRc
2137 | IterInitK<IterData>,  D(Bool), S(Arr,Obj) S(FramePtr), Er|E|CRc
2139 | WIterInit<IterData>,  D(Bool), S(Arr,Obj) S(FramePtr), Er|E|CRc
2141 | WIterInitK<IterData>, D(Bool), S(Arr,Obj) S(FramePtr), Er|E|CRc
2143 | MIterInit<T,IterData>,  D(Bool), S(BoxedCell) S(FramePtr), Er|E
2145 | MIterInitK<T,IterData>, D(Bool), S(BoxedCell) S(FramePtr), Er|E
2147   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2148   the index of the iterator variable, keyId and valId are indices of local
2149   variables.
2151   Initializes the iterator variable whose index is given by iterId.
2152   This instruction creates the appropriate iterator for the array or object that
2153   S0 references, and rewinds the new iterator to its start. S0 points to the
2154   stack frame containing the iterator and local variables with the indices
2155   iterId, keyId and valId.
2157   If the new iterator is at its end (i.e., has no elements to iterate over),
2158   this instruction decrements the refcount of S0 and returns false; otheriwse,
2159   it stores a reference to S0 in the new iterator and returns true. If the
2160   iterator is not at its end, then this instruction stores the iterator's first
2161   value (and key) into the local variable with index valId (and keyId,
2162   respectively).
2164   The IterInit and IterInitK instructions always copy the array element by
2165   value.
2167   The WIterInit and WIterInitK instructions copy referenced array elements by
2168   reference, and non-referenced array elements by value.
2170   The MIterInit and MIterInitK instructions always copy the array element by
2171   reference, and take a type parameter indicating the inner type of S0.  (This
2172   must have been proven via guards prior to running this opcode.)  Right now T
2173   must be Obj or Arr.
2175   This instruction has the ConsumesRC property because it either decrements the
2176   reference count of S0 or stores a reference to S0 into the new iterator.
2178 | IterNext<IterData>,   D(Bool), S(FramePtr), Er|E
2180 | IterNextK<IterData>,  D(Bool), S(FramePtr), Er|E
2182 | WIterNext<IterData>,  D(Bool), S(FramePtr), Er|E
2184 | WIterNextK<IterData>, D(Bool), S(FramePtr), Er|E
2186 | MIterNext<IterData>,  D(Bool), S(FramePtr), E
2188 | MIterNextK<IterData>, D(Bool), S(FramePtr), E
2190   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2191   the index of the iterator variable, keyId and valId are indices of local
2192   variables.  S0 points to the stack frame containing the iterator and local
2193   variables with the indices iterId, keyId and valId.
2195   Advances the iterator variable whose index is given by iterId.
2197   If the iterator has reached the end, this instruction frees the iterator
2198   variable and returns false; otherwise, it returns true. If the iterator has
2199   not reached its end, then this instruction stores the iterator's next value
2200   (and key) into the local variable with index valId (and keyId, respectively).
2202   The IterInit and IterInitK instructions always copy the array element by
2203   value. The WIterInit and WIterInitK instructions copy referenced array
2204   elements by reference, and non-referenced array elements by value. The
2205   MIterNext and MIterNextK instructions always copy the array element by
2206   reference.
2208 | IterFree,  ND, S(FramePtr), E
2210 | MIterFree, ND, S(FramePtr), E
2212   Free the iterator variable whose index is given by S1 in the stack frame
2213   pointed to by S0.
2215 | DecodeCufIter<iterId>, D(Bool), S(Arr,Obj,Str)  S(FramePtr), Er|E
2217   Decode S0 as a callable, and write the decoded values to the iterator
2218   specified by IterId. Returns true iff it successfully decoded the callable.
2219   Does not raise warnings, or throw exceptions.
2221 | CIterFree<iterId>, ND, S(FramePtr), E
2223   Free the iterator variable whose index is given by IterId in the stack frame
2224   pointed to by S0.
2227 18. Member instruction support
2230 | DefMIStateBase, D(PtrToMISGen), NA, NF
2232   Declares a base register for MInstrState. Currently this is always %rsp.
2234 | LdMIStateAddr, DofS(0), S(PtrToMISGen) C(Int), C
2236   Load an MInstrState address. Returns a pointer to (S0 + S1) with the same
2237   type as S0. S0 must be the output of a DefMIStateBase.
2239 All of the remaining opcodes in this section are simple wrappers around helper
2240 functions (specified in S0) to perform the corresponding vector operation. If
2241 S1 is a ConstCls it represents the context class for the operation.
2243 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2244 opcode, which almost always pushes its first stack input or a CountedStr as its
2245 stack result. The combinations of input types that cause SetM to push anything
2246 other than those two values are vanishingly rare in correct PHP programs, so
2247 these three instructions have been optimized for the common cases. SetNewElem
2248 and SetProp have no destination, allowing the compiler to predict that the
2249 SetM's output will be the same as its input (and optimize accordingly). If that
2250 turns out to not be the case at runtime, the instruction will throw an
2251 InvalidSetMException. The exception will hold a Cell containing the value the
2252 SetM should push on the stack instead of its input value. The runtime is
2253 responsible for catching this exception, finishing execution of the SetM
2254 instruction, pushing the value from the exception on the stack, and proceeding
2255 as appropriate (most likely with a side exit to the next bytecode instruction,
2256 since it has pushed an unexpected type onto the stack).
2258 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2259 characters within strings. When given a string base and a valid offset, SetElem
2260 returns a string representation of the newly inserted character. In all other
2261 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2262 exception when it detects invalid input types, or when trying to set a string
2263 offset that would grow the string beyond the maximum supported size.
2265 The input types that will cause the errors described above are listed here:
2267 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2268            Bool<false>.
2269 SetElem has the same base constraint as SetNewElem. In addition, the key must
2270         not be a subtype of {Arr|Obj}.
2271 SetProp will fail if the base is not a subtype of {Obj|Null}.
2273 Any instructions that take a pointer to an MInstrState struct use the various
2274 fields of that struct for holding intermediate values.
2276 | BaseG, D(PtrToRMembCell), S(Str), E|Er
2278   Get a base from global named S0.
2280   NB: BaseG returns either a PtrToGblGen, OR a pointer to a ref that is rooted
2281   in a GblGen.  (I.e. the unbox happens in the C++ helper that this instruction
2282   calls.)  If it is not a defining BaseG it can also return the
2283   init_null_variant, so for now it returns a PtrToRMembCell.
2285 | PropX, D(PtrToMemGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), E|Er
2287   Lookup intermediate property in S0, with key S1.
2289 |STK PropDX, D(PtrToMemGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), MProp|E|Er
2291   Like PropX, but used for intermediate element lookups that may modify the
2292   base.
2294 | CGetProp, D(Cell), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), E|PRc|Er
2296   Get property with key S1 from S0.
2298 |STK VGetProp, D(BoxedCell),
2299 |              S(Obj,PtrToGen) S(Cell) S(PtrToMISGen),
2300 |              MProp|E|PRc|Er
2302   Get property with key S1 from base S0 as a reference.
2304 |STK BindProp, ND,
2305 |              S(Obj,PtrToGen) S(Cell) S(BoxedCell) S(PtrToMISGen),
2306 |              MProp|E|Er
2308   Bind property with key S1 in base S0 to the reference in S2.
2310 |STK SetProp, ND, S(Obj,PtrToGen) S(Cell) S(Cell), MProp|E|Er
2312   Set property with key S1 in S0 to S2.
2314 | UnsetProp, ND, S(Obj,PtrToGen) S(Cell), E|Er
2316   Unset an object property.
2318 |STK SetOpProp<op>, D(Cell),
2319 |                   S(Obj,PtrToGen) S(Cell) S(Cell) S(PtrToMISGen),
2320 |                   MProp|E|PRc|Er
2322   Set op propery with key S1 in base S0, using S2 as the right hand side.
2324 |STK IncDecProp<op>, D(Cell),
2325 |                    S(Obj,PtrToGen) S(Cell) S(PtrToMISGen),
2326 |                    MProp|E|PRc|Er
2328   Increment/decrement property with key S1 in base S0.
2330 | EmptyProp, D(Bool), S(Obj,PtrToGen) S(Cell), E|Er
2332   Returns true iff the property with key S1 in base S0 is empty.
2334 | IssetProp, D(Bool), S(Obj,PtrToGen) S(Cell), E|Er
2336   Returns true iff the property with key S1 in base S0 is set.
2338 | ElemX, D(PtrToMemGen), S(PtrToGen) S(Cell) S(PtrToMISGen), E|Er
2340   Get intermediate element with key S1 from base S0. The base will not be
2341   modified.
2343 | ElemArray, D(PtrToMemGen), S(PtrToGen) S(Int,Str), E|Er
2345 | ElemArrayW, D(PtrToMemGen), S(PtrToGen) S(Int,Str), E|Er
2347   Similar to ElemX, but assumes the base S0 is an array and the key S1 is an
2348   int/str.  The ElemArrayW version is for Warn member instrs.
2350 |STK ElemDX, D(PtrToMemGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|E|Er
2352   Like ElemX, but used for intermediate element lookups that may modify the
2353   base.
2355 |STK ElemUX, D(PtrToMemGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|E|Er
2357   Like ElemX, but used for intermediate element lookups that may modify the
2358   base as part of an unset operation.
2360 | ArrayGet, D(Cell), S(Arr) S(Int,Str), PRc|Er
2362   Get element with key S1 from base S0.
2364 | StringGet, D(StaticStr), S(Str) S(Int), PRc|Er
2366   Get string representing character at position S1 from base string S0.
2368 | MapGet, D(Cell), S(Obj) S(Int,Str), E|PRc|Er
2370   Get element with key S1 from base S0.
2372 | CGetElem, D(Cell), S(PtrToGen) S(Cell) S(PtrToMISGen), E|PRc|Er
2374   Get element with key S1 from S0.
2376 |STK VGetElem, D(BoxedCell), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|E|PRc|Er
2378   Get element with key S1 from base S0 as a reference.
2380 |STK BindElem, ND, S(PtrToGen) S(Cell) S(BoxedCell) S(PtrToMISGen), MElem|E|Er
2382   Bind element with key S1 in base S0 to the reference S2.
2384 | ArraySet, D(Arr), S(Arr) S(Int,Str) S(Cell), E|PRc|CRc|K|Er
2386   Set element with key S1 in S0 to S2. The dest will be a new Array that should
2387   replace S0.
2389 | ArraySetRef, ND, S(Arr) S(Int,Str) S(Cell) S(BoxedCell), E|CRc|K|Er
2391   Like ArraySet, but for binding operations on the array. The parameter in S3
2392   must point to a RefData with an array type when this instruction is executed,
2393   and it must be the same array that is in S0.
2395 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), E|Er
2397   Set element with key S1 in S0 to S2.
2399 |STK SetElem, DSetElem, S(PtrToGen) S(Cell) S(Cell), MElem|E|PRc|Er
2401   Set element with key S1 in S0 to S2.
2403 |STK SetWithRefElem, ND,
2404 |                    S(PtrToGen) S(Cell) S(PtrToGen) S(PtrToMISGen),
2405 |                    MElem|E|Er
2407   Set element with key S1 in S0 to S2.
2409 |STK UnsetElem, ND, S(PtrToGen) S(Cell), MElem|E|Er
2411   Unsets the element at key S1 in the base S0.
2413 |STK SetOpElem<op>, D(Cell),
2414 |                   S(PtrToGen) S(Cell) S(Cell) S(PtrToMISGen),
2415 |                   MElem|E|PRc|Er
2417   Set op elem with key S1 in base S0, using S2 as the right hand side.
2419 |STK IncDecElem, D(Cell),
2420 |                S(PtrToGen) S(Cell) S(PtrToMISGen),
2421 |                MElem|E|PRc|Er
2423   Increment/decrement element with key S1 in base S0.
2425 |STK SetNewElem, ND, S(PtrToGen) S(Cell), MElem|E|Er
2427   Append the value in S1 to S0.
2429 |STK SetNewElemArray, ND, S(PtrToGen) S(Cell), MElem|E|Er
2431   Append the value in S1 to S0, where S0 must be a pointer to an array.
2433 |STK SetWithRefNewElem, ND,
2434 |                       S(PtrToGen) S(PtrToGen) S(PtrToMISGen),
2435 |                       MElem|E|Er
2437   AppendWithRef the value in S1 to S0.
2439 |STK BindNewElem, ND,
2440 |                 S(PtrToGen) S(BoxedCell) S(PtrToMISGen),
2441 |                 MElem|E|Er
2443   Append the reference in S1 to S0.
2445 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), E|Er
2447   Returns true iff the element at key S1 in the base S0 is set.
2449 | StringIsset, D(Bool), S(Str) S(Int), NF
2451   Returns true iff the string S0 has a character at position S1.
2453 | VectorIsset, D(Bool), S(Obj) S(Int), E
2455   Returns true iff the element at key S1 in the base S0 is set.
2457 | PairIsset, D(Bool), S(Obj) S(Int), E
2459   Returns true iff the element at key S1 in the base S0 is set.
2461 | MapIsset, D(Bool), S(Obj) S(Int,Str), E
2463   Returns true iff the element at key S1 in the base S0 is set.
2465 | IssetElem, D(Bool), S(PtrToGen) S(Cell) S(PtrToMISGen), E|Er
2467   Returns true iff the element at key S1 in S0 is set.
2469 | EmptyElem, D(Bool), S(PtrToGen) S(Cell) S(PtrToMISGen), E|Er
2471   Returns true iff the element at key S1 in S0 is set and not equal (as defined
2472   by the hhbc Eq instruction) to false.
2474 | CheckBounds, ND, S(Int) S(Int), E|Er
2476   Checks that the index in S0 is between 0 (included) and the values in S1
2477   (excluded). Throws if out of bounds.
2479 | ProfileArray, ND, S(Arr), E
2481   Profile type of array S0 (i.e. whether it is packed or mixed).
2483 | ProfileStr<key>, ND, S(PtrToGen), E
2485   Profile exact type of the value pointed to by S0, which must be known to
2486   point to a string at the time this instruction runs.
2488 | CheckPackedArrayBounds, ND, AK(Packed) S(Int), B|E
2490   Checks that the index in S1 is within the bounds of the packed array in S0.
2491   Branches to B if the index is out of bounds.
2493 | CheckTypePackedArrayElem<T>, ND, AK(Packed) S(Int), B|E
2495   If the array element at S0[S1] is not type T, take the branch.
2497 | IsPackedArrayElemNull, D(Bool), AK(Packed) S(Int), E
2499   Returns true if the element at index S1 of the packed array in S0 is not
2500   null.
2502 | LdPackedArrayElem<T>, DArrElem, AK(Packed) S(Int), E
2504   Loads the element of the packed array in S0 at index S1. If the type param T
2505   is specified, the destination type intersects it with whatever we'd know from
2506   the type of S0.
2508 | LdVectorSize, D(Int), S(Obj), E
2510   Returns the size of the given Vector in S0.
2512 | VectorDoCow, ND, S(Obj), E
2514   Triggers a copy on write for a Vector that has a live ImmVector sharing
2515   the same copy of the elements.
2517 | VectorHasImmCopy, ND, S(Obj), B
2519   Given a vector, check if it has a immutable copy and jump to the taken branch
2520   if so.
2522 | ColAddNewElemC, D(Obj), S(Obj) S(Cell), Er|CRc|P
2524   Adds item S0 to the end of collection S0. Throws a fatal error if S0 is not a
2525   collection. Returns S0.
2527 | ColAddElemC, D(Obj), S(Obj) S(Cell) S(Cell), Er|CRc|P
2529   Adds item to collection. Inserts item S2 into collection S0 at key S1.
2530   Throws a fatal error if S0 is not a collection. Returns S0.
2532 | ColIsEmpty, D(Bool), S(Obj), NF
2534 | ColIsNEmpty, D(Bool), S(Obj), NF
2536   Returns whether a collection instance is empty or not.  S0 must be known to
2537   be an instance of a collection class at compile time.
2539 19. Exception/unwinding support
2541 | BeginCatch, ND, NA, E
2543   Marks the beginning of a catch region. Exact behavior is implementation and
2544   architecture specific.
2546 | EndCatch, ND, S(FramePtr) S(StkPtr), E|T
2548   Marks the end of a catch region and returns control to the unwinder. Exact
2549   behavior is implementation and architecture specific.
2551 | TryEndCatch, ND, S(FramePtr) S(StkPtr), E
2553   Marks a potential end of a catch region and might return control to the
2554   unwinder. Exact behavior is implementation and architecture specific.
2556 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B|E
2558   Branches to B if the currently executing catch region should return control to
2559   the unwinder rather than side exiting.
2561 | LdUnwinderValue<T>, DParam, NA, PRc
2563   Loads the value contained by the current unwinder exception.
2565 | DeleteUnwinderException, ND, NA, E
2567   Deletes the current unwinder exception.
2569 | TypeProfileFunc<paramIndex,functionName>, ND,
2570 |                                           S(Gen) S(Func),
2571 |                                           E
2573   Profiles that function's parameter/return value for a particular parameter
2574   index. Calls into native c++ function.
2577 /* Local Variables: */
2578 /* fill-column: 79 */
2579 /* End: */
2580 vim:textwidth=80