# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# [SMDOC] LIR Opcodes
# =======================
# This file defines all LIR opcodes as well as LIR opcode class
# definitions. It is parsed by GenerateLIRFiles.py at build time to
# create LIROpsGenerated.h. Each opcode consists of a
# name and a set of attributes that are described below. Unless
# marked as required, attributes are optional.
#
# name [required]
# ====
# Opcode name.
# Possible values:
#   - opcode string: used as the name for LIR opcode.
#
# gen_boilerplate
# ===============
# Used to decide to generate LIR boilerplate.
#   - true (default): auto generate boilerplate for this LIR opcode
#   - false: do not generate boilerplate for this LIR opcode
#
# result_type
# ===========
# Specifies the result type that is produced by this LIR instruction.
# The result type can be any of the following: WordSized, BoxedValue,
# or Int64.
#   - attribute not specified (default): there is no result produced
#     by this LIR instruction
#   - result type: sets result type for this LIR instruction
#
# successors
# ===========
# Specifies the list of successor blocks for control instruction LIR nodes.
# Control instruction nodes inherit from LControlInstructionHelper. The
# "result_type" attribute can't be used when this attribute is present.
#
#   For example:
#     successors: [ifTrue, ifFalse]
#
#   Will generate the following getters:
#     MBasicBlock* ifTrue() const { return getSuccessor(0); }
#     MBasicBlock* ifFalse() const { return getSuccessor(1); }
#
# operands
# ========
# A list of operands to the LIR node. Each operand will be
# passed into and set in the instruction's constructor. A simple getter
# will also be auto generated for the operand. Each operand in the
# following list is defined by its name and an type.
# The type can be WordSized, BoxedValue, or Int64.
#
#   For example:
#     operands:
#       lhs: BoxedValue
#       rhs: WordSized
#
#   Will result in:
#     explicit LInstanceOfV(const LBoxAllocation& lhs, const LAllocation& rhs)
#         : LInstructionHelper(classOpcode) {
#       setBoxOperand(lhsIndex, lhs);
#       setOperand(rhsIndex, rhs);
#     }
#     const LAllocation* rhs() { return getOperand(0); }
#
#     static const size_t lhsIndex = 0;
#     static const size_t rhsIndex = BOX_PIECES;
#
#   - attribute not specified (default): no code generated
#   - list of operand names with their types: operand getters and setters
#     are generated and passed into the constructor
#
# arguments
# =========
# A list of non-LIR node arguments to the LIR op class constructor
# that are passed along with the operands. The arguments require
# both a name and a full type signature for each item in the list.
#
# For example:
#   offset: size_t
#   type: MIRType
#
# For each argument a private variable declaration will be autogenerated
# in the LIR op class, as well as simple accessor for that variable. The
# above arguments list will result in the following declarations and
# accessors:
#
#   size_t offset_;
#   MIRType type_;
#
#   size_t offset() const { return offset_; }
#   MIRType type() const { return type_; }
#
#   - attribute not specified (default): no code generated
#   - argument list: argument names and their full type signature
#
# num_temps, num_temp64s, and num_temp_boxes
# ==========================================
# Specifies the number of temporary virtual registers, LDefinitions, used by
# this LIR op. The temp can be either a single LDefinition, a LInt64Definition,
# or a LBoxDefinition depending on the variant used.
#
#   - attribute not specified (default): number of temps is set to 0
#   - number of LDefinition temps: sets number of temps max 15
#
# call_instruction
# ================
# Used to define call instructions.
#   - attribute not specified (default): no code generated
#   - true: generates a call to setIsCall in the op's constructor
#
# mir_op
# ======
# If a LIR instruction corresponds one-to-one with a particular MIR
# instruction, this will generate a method that returns that MIR
# instruction.
#   - attribute not specified (default): no code generated
#   - true: generates a method to return MIR instruction
#   - mir string: returns this specified MIR instruction
#
# extra_name
# ==========
# Add a declaration for the `extraName` method.
#   - attribute not specified (default): no code generated
#   - true: adds the `inline const char* extraName() const;` declaration
#
# defer_init
# ==========
# Control whether or not operands and temps are initialized outside the
# constructor.
#   - attribute not specified (default): operands and temps are initialized in
#     the constructor.
#   - true: operands and temps are not initialized in the constructor, instead
#     setter definitions are added for manual initialization.

- name: Phi
  gen_boilerplate: false

- name: Box
  result_type: BoxedValue
  operands:
    payload: WordSized
  arguments:
    type: MIRType
  extra_name: true

- name: OsiPoint
  gen_boilerplate: false

- name: MoveGroup
  gen_boilerplate: false

# Constant 32-bit integer.
- name: Integer
  result_type: WordSized
  arguments:
    i32: int32_t

# Constant 64-bit integer.
- name: Integer64
  result_type: Int64
  arguments:
    i64: int64_t

# Constant pointer.
- name: Pointer
  result_type: WordSized
  arguments:
    gcptr: const gc::Cell*

# Constant double.
- name: Double
  result_type: WordSized
  arguments:
    value: double

# Constant float32.
- name: Float32
  result_type: WordSized
  arguments:
    value: float

- name: Value
  gen_boilerplate: false

# Formal argument for a function, returning a box. Formal arguments are
# initially read from the stack.
- name: Parameter
  result_type: BoxedValue

# Jumps to the start of a basic block.
- name: Goto
  successors: [target]

- name: NewArray
  result_type: WordSized
  num_temps: 1
  mir_op: true
  extra_name: true

- name: NewIterator
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewTypedArray
  result_type: WordSized
  call_instruction: true
  num_temps: 4
  mir_op: true

- name: NewTypedArrayInline
  result_type: WordSized
  num_temps: 1
  mir_op: NewTypedArray

- name: BindFunction
  result_type: WordSized
  operands:
    target: WordSized
  call_instruction: true
  num_temps: 2
  mir_op: true

- name: NewObject
  result_type: WordSized
  num_temps: 1
  mir_op: true
  extra_name: true

- name: NewPlainObject
  result_type: WordSized
  num_temps: 3
  mir_op: true

- name: NewArrayObject
  result_type: WordSized
  num_temps: 2
  mir_op: true

# Allocates a new CallObject.
#
# This instruction generates two possible instruction sets:
#   (1) If the call object is extensible, this is a callVM to create the
#       call object.
#   (2) Otherwise, an inline allocation of the call object is attempted.
#
- name: NewCallObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewMapObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewSetObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewStringObject
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: WasmRefAsNonNull
  operands:
    ref: WordSized
  result_type: WordSized
  mir_op: true

- name: WasmRefTestConcrete
  mir_op: true
  operands:
    ref: WordSized
    superSTV: WordSized
  result_type: WordSized
  num_temps: 2

- name: WasmRefTestAbstract
  mir_op: true
  operands:
    ref: WordSized
  result_type: WordSized
  num_temps: 1

- name: WasmRefTestConcreteAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    ref: WordSized
    superSTV: WordSized
  arguments:
    sourceType: wasm::MaybeRefType
    destType: wasm::RefType
  num_temps: 2

- name: WasmRefTestAbstractAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    ref: WordSized
  arguments:
    sourceType: wasm::MaybeRefType
    destType: wasm::RefType
  num_temps: 1

- name: WasmRefCastConcrete
  mir_op: true
  operands:
    ref: WordSized
    superSTV: WordSized
  result_type: WordSized
  num_temps: 2

- name: WasmRefCastAbstract
  mir_op: true
  operands:
    ref: WordSized
  result_type: WordSized
  num_temps: 1

- name: WasmNewStructObject
  mir_op: true
  operands:
    instance: WordSized
    allocSite: WordSized
  result_type: WordSized
  num_temps: 1

- name: WasmNewArrayObject
  mir_op: true
  operands:
    instance: WordSized
    numElements: WordSized
    allocSite: WordSized
  result_type: WordSized
  num_temps: 2

- name: ReinterpretCast
  operands:
    input: WordSized
  result_type: WordSized
  mir_op: ReinterpretCast

- name: ReinterpretCastFromI64
  operands:
    input: Int64
  result_type: WordSized
  mir_op: ReinterpretCast

- name: ReinterpretCastToI64
  operands:
    input: WordSized
  result_type: Int64
  mir_op: ReinterpretCast

- name: Rotate
  result_type: WordSized
  operands:
    input: WordSized
    count: WordSized
  mir_op: true
  defer_init: true

- name: RotateI64
  result_type: Int64
  operands:
    input: Int64
    count: WordSized
  num_temps: 1
  mir_op: Rotate
  defer_init: true

- name: WasmInterruptCheck
  operands:
    instance: WordSized
  mir_op: true

- name: TypeOfV
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: TypeOf

- name: TypeOfO
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: TypeOf

- name: TypeOfIsNonPrimitiveV
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: TypeOfIs

- name: TypeOfIsNonPrimitiveO
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: TypeOfIs

- name: TypeOfIsPrimitive
  result_type: WordSized
  operands:
    input: BoxedValue
  mir_op: TypeOfIs

- name: CreateInlinedArgumentsObject
  gen_boilerplate: false

- name: GetInlinedArgument
  gen_boilerplate: false

- name: GetInlinedArgumentHole
  gen_boilerplate: false

- name: BoxNonStrictThis
  result_type: WordSized
  operands:
    value: BoxedValue
  mir_op: true

# Writes a typed argument for a function call to the frame's argument vector.
- name: StackArgT
  operands:
    arg: WordSized
  arguments:
    # Index into frame-scope argument vector.
    argslot: uint32_t
    type: MIRType

# Writes a typed argument for a function call to the frame's argument vector.
- name: StackArgV
  operands:
    value: BoxedValue
  arguments:
    # Index into frame-scope argument vector.
    argslot: uint32_t

- name: CallGeneric
  gen_boilerplate: false

- name: CallKnown
  gen_boilerplate: false

- name: CallNative
  gen_boilerplate: false

- name: CallDOMNative
  gen_boilerplate: false

- name: CallClassHook
  gen_boilerplate: false

- name: Unreachable
  successors: []

- name: UnreachableResultV
  result_type: BoxedValue

- name: UnreachableResultT
  result_type: WordSized

- name: GetDOMProperty
  result_type: BoxedValue
  operands:
    object: WordSized
  num_temps: 3
  call_instruction: true
  mir_op: true

- name: GetDOMMemberV
  result_type: BoxedValue
  operands:
    object: WordSized
  mir_op: GetDOMMember

- name: GetDOMMemberT
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: GetDOMMember

- name: SetDOMProperty
  operands:
    object: WordSized
    value: BoxedValue
  num_temps: 3
  call_instruction: true
  mir_op: true

- name: LoadDOMExpandoValueGuardGeneration
  result_type: BoxedValue
  operands:
    proxy: WordSized
  mir_op: true

- name: ApplyArgsGeneric
  gen_boilerplate: false

- name: ApplyArgsObj
  gen_boilerplate: false

- name: ApplyArrayGeneric
  gen_boilerplate: false

- name: ConstructArgsGeneric
  gen_boilerplate: false

- name: ConstructArrayGeneric
  gen_boilerplate: false

- name: ApplyArgsNative
  gen_boilerplate: false

- name: ApplyArgsObjNative
  gen_boilerplate: false

- name: ApplyArrayNative
  gen_boilerplate: false

- name: ConstructArgsNative
  gen_boilerplate: false

- name: ConstructArrayNative
  gen_boilerplate: false

# Takes in either an integer or boolean input and tests it for truthiness.
- name: TestIAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: WordSized

# Takes in intptr input and tests it for truthiness.
- name: TestIPtrAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: WordSized

# Takes in an int64 input and tests it for truthiness.
- name: TestI64AndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: Int64

# Takes in a double input and tests it for truthiness.
- name: TestDAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: WordSized

# Takes in a float32 input and tests it for truthiness.
- name: TestFAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: WordSized

# Takes in a bigint input and tests it for truthiness.
- name: TestBIAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: WordSized

# Takes an object and tests it for truthiness. An object is falsy iff it
# emulates |undefined|; see js::EmulatesUndefined.
- name: TestOAndBranch
  successors: [ifTruthy, ifFalsy]
  operands:
    input: WordSized
  num_temps: 1
  mir_op: Test

# Takes in a boxed value and tests it for truthiness.
- name: TestVAndBranch
  successors: [ifTruthy, ifFalsy]
  operands:
    input: BoxedValue
  num_temps: 3
  mir_op: Test

# Compares two integral values of the same JS type, either integer or object.
# For objects, both operands are in registers.
- name: Compare
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  arguments:
    jsop: JSOp
  mir_op: true
  extra_name: true

- name: CompareI64
  result_type: WordSized
  operands:
    left: Int64
    right: Int64
  arguments:
    jsop: JSOp
  mir_op: Compare
  extra_name: true

- name: CompareI64AndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: Int64
    right: Int64
  arguments:
    cmpMir: MCompare*
    jsop: JSOp
  mir_op: Test
  extra_name: true

# Compares two integral values of the same JS type, either integer or object.
# For objects, both operands are in registers.
- name: CompareAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: WordSized
    right: WordSized
  arguments:
    cmpMir: MCompare*
    jsop: JSOp
  mir_op: Test
  extra_name: true

- name: CompareD
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  mir_op: Compare

- name: CompareF
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  mir_op: Compare

- name: CompareDAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: WordSized
    right: WordSized
  arguments:
    cmpMir: MCompare*

- name: CompareFAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: WordSized
    right: WordSized
  arguments:
    cmpMir: MCompare*

- name: CompareS
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  mir_op: Compare

- name: CompareSInline
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    constant: JSOffThreadAtom*
  mir_op: Compare

- name: CompareSSingle
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    jsop: JSOp
    constant: JSOffThreadAtom*
  num_temps: 1
  mir_op: Compare

- name: CompareBigInt
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  num_temps: 3
  mir_op: Compare

- name: CompareBigIntInt32
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  num_temps: 2
  mir_op: Compare

- name: CompareBigIntDouble
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  call_instruction: true
  mir_op: Compare

- name: CompareBigIntString
  result_type: WordSized
  operands:
    left: WordSized
    right: WordSized
  call_instruction: true
  mir_op: Compare

- name: CompareBigIntInt32AndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: WordSized
    right: WordSized
  arguments:
    cmpMir: MCompare*
  num_temps: 2

# Fused Test and StrictConstantCompareInt32.
- name: StrictConstantCompareInt32AndBranch
  successors: [ifTrue, ifFalse]
  operands:
    value: BoxedValue
  arguments:
    cmpMir: MStrictConstantCompareInt32*
  mir_op: Test
  extra_name: true

# Fused Test and StrictConstantCompareBoolean.
- name: StrictConstantCompareBooleanAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    value: BoxedValue
  arguments:
    cmpMir: MStrictConstantCompareBoolean*
  mir_op: Test
  extra_name: true

- name: BitAndAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: WordSized
    right: WordSized
  arguments:
    cond: Assembler::Condition

- name: BitAnd64AndBranch
  successors: [ifTrue, ifFalse]
  operands:
    left: Int64
    right: Int64
  arguments:
    cond: Assembler::Condition

# Takes a value and tests whether it is null, undefined, or is an object that
# emulates |undefined|, as determined by the JSCLASS_EMULATES_UNDEFINED class
# flag on unwrapped objects.  See also js::EmulatesUndefined.
- name: IsNullOrLikeUndefinedV
  result_type: WordSized
  operands:
    value: BoxedValue
  num_temps: 1
  mir_op: Compare

# Takes an object pointer and tests whether it is an object that emulates
# |undefined|, as above.
- name: IsNullOrLikeUndefinedT
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Compare

# Takes a value and tests whether it is null.
- name: IsNull
  result_type: WordSized
  operands:
    value: BoxedValue
  mir_op: Compare

# Takes a value and tests whether it is undefined.
- name: IsUndefined
  result_type: WordSized
  operands:
    value: BoxedValue
  mir_op: Compare

- name: IsNullOrLikeUndefinedAndBranchV
  successors: [ifTrue, ifFalse]
  operands:
    value: BoxedValue
  arguments:
    cmpMir: MCompare*
  num_temps: 2
  mir_op: Test

- name: IsNullOrLikeUndefinedAndBranchT
  successors: [ifTrue, ifFalse]
  operands:
    value: WordSized
  arguments:
    cmpMir: MCompare*
  num_temps: 1
  mir_op: Test

- name: IsNullAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    value: BoxedValue
  arguments:
    cmpMir: MCompare*

- name: IsUndefinedAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    value: BoxedValue
  arguments:
    cmpMir: MCompare*

# Not operation on an integer.
- name: NotI
  result_type: WordSized
  operands:
    input: WordSized

# Not operation on an intptr.
- name: NotIPtr
  result_type: WordSized
  operands:
    input: WordSized

# Not operation on an int64.
- name: NotI64
  result_type: WordSized
  operands:
    inputI64: Int64

# Not operation on a double.
- name: NotD
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Not

# Not operation on a float32.
- name: NotF
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Not

# Not operation on a BigInt.
- name: NotBI
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Not

# Boolean complement operation on an object.
- name: NotO
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Not

# Boolean complement operation on a value.
- name: NotV
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 2
  mir_op: Not

# Bitwise not operation, takes a 32-bit integer as input and returning
# a 32-bit integer result as an output.
- name: BitNotI
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

- name: BitNotI64
  result_type: Int64
  operands:
    input: Int64
  defer_init: true

# Binary bitwise operation, taking two 32-bit integers as inputs and returning
# a 32-bit integer result as an output.
- name: BitOpI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    bitop: JSOp
  extra_name: true
  defer_init: true

- name: BitOpI64
  result_type: Int64
  operands:
    lhs: Int64
    rhs: Int64
  arguments:
    bitop: JSOp
  extra_name: true
  defer_init: true

# Shift operation, taking two 32-bit integers as inputs and returning
# a 32-bit integer result as an output.
- name: ShiftI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    bitop: JSOp
  mir_op: Instruction
  extra_name: true
  defer_init: true

- name: ShiftIntPtr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    bitop: JSOp
  mir_op: Instruction
  extra_name: true
  defer_init: true

- name: ShiftI64
  result_type: Int64
  operands:
    lhs: Int64
    rhs: WordSized
  arguments:
    bitop: JSOp
  mir_op: Instruction
  extra_name: true
  defer_init: true

- name: SignExtendInt32
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

- name: SignExtendIntPtr
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

- name: SignExtendInt64
  result_type: Int64
  operands:
    input: Int64
  mir_op: true

- name: UrshD
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1

- name: Return
  gen_boilerplate: false

- name: MinMaxI
  result_type: WordSized
  operands:
    first: WordSized
    second: WordSized
  mir_op: MinMax
  extra_name: true

- name: MinMaxIntPtr
  result_type: WordSized
  operands:
    first: WordSized
    second: WordSized
  mir_op: MinMax
  extra_name: true

- name: MinMaxD
  result_type: WordSized
  operands:
    first: WordSized
    second: WordSized
  mir_op: MinMax
  extra_name: true

- name: MinMaxF
  result_type: WordSized
  operands:
    first: WordSized
    second: WordSized
  mir_op: MinMax
  extra_name: true

- name: MinMaxArrayI
  result_type: WordSized
  operands:
    array: WordSized
  num_temps: 3
  mir_op: MinMaxArray

- name: MinMaxArrayD
  result_type: WordSized
  operands:
    array: WordSized
  num_temps: 3
  mir_op: MinMaxArray

# Negative of integer
- name: NegI
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

# Negative of an int64
- name: NegI64
  result_type: Int64
  operands:
    input: Int64
  defer_init: true

# Negative of double
- name: NegD
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

# Negative of float32
- name: NegF
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

# Absolute value of an integer.
- name: AbsI
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true
  mir_op: Abs

# Absolute value of a double.
- name: AbsD
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

# Absolute value of a float32.
- name: AbsF
  result_type: WordSized
  operands:
    input: WordSized
  defer_init: true

# Copysign for doubles.
- name: CopySignD
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  defer_init: true

# Copysign for float32.
- name: CopySignF
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  defer_init: true

# Count leading zeroes on an int32.
- name: ClzI
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Clz

# Count leading zeroes on an int64.
- name: ClzI64
  result_type: Int64
  operands:
    input: Int64
  mir_op: Clz

# Count trailing zeroes on an int32.
- name: CtzI
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: Ctz

# Count trailing zeroes on an int64.
- name: CtzI64
  result_type: Int64
  operands:
    input: Int64
  mir_op: Ctz

# Count population on an int32.
- name: PopcntI
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: Popcnt

# Count population on an int64.
- name: PopcntI64
  result_type: Int64
  operands:
    input: Int64
  num_temps: 1
  mir_op: Popcnt

- name: SqrtD
  result_type: WordSized
  operands:
    input: WordSized

- name: SqrtF
  result_type: WordSized
  operands:
    input: WordSized

- name: Atan2D
  result_type: WordSized
  operands:
    y: WordSized
    x: WordSized
  call_instruction: true

- name: Hypot
  gen_boilerplate: false

# Double raised to an integer power.
- name: PowI
  result_type: WordSized
  operands:
    value: WordSized
    power: WordSized
  call_instruction: true

# Integer raised to an integer power.
- name: PowII
  result_type: WordSized
  operands:
    value: WordSized
    power: WordSized
  num_temps: 2
  mir_op: Pow

# Double raised to a double power.
- name: PowD
  result_type: WordSized
  operands:
    value: WordSized
    power: WordSized
  call_instruction: true

# Constant of a power of two raised to an integer power.
- name: PowOfTwoI
  result_type: WordSized
  operands:
    power: WordSized
  arguments:
    base: uint32_t

# Sign value of an integer.
- name: SignI
  result_type: WordSized
  operands:
    input: WordSized

# Sign value of an integer.
- name: SignD
  result_type: WordSized
  operands:
    input: WordSized

# Sign value of a double with expected int32 result.
- name: SignDI
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

# Sign value of a int32 with expected double result.
- name: SignID
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

- name: MathFunctionD
  result_type: WordSized
  operands:
    input: WordSized
  call_instruction: true
  mir_op: MathFunction
  extra_name: true

- name: MathFunctionF
  result_type: WordSized
  operands:
    input: WordSized
  call_instruction: true
  mir_op: MathFunction
  extra_name: true

- name: AddI
  gen_boilerplate: false

- name: AddI64
  result_type: Int64
  operands:
    lhs: Int64
    rhs: Int64
  defer_init: true

- name: AddIntPtr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  defer_init: true

- name: SubI
  gen_boilerplate: false

- name: SubI64
  result_type: Int64
  operands:
    lhs: Int64
    rhs: Int64
  defer_init: true

- name: SubIntPtr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  defer_init: true

- name: MulI64
  result_type: Int64
  operands:
    lhs: Int64
    rhs: Int64
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
  num_temps: 1
#endif
  defer_init: true

- name: MulIntPtr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  defer_init: true

# Performs an add, sub, mul, or div on two double values.
- name: MathD
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    jsop: JSOp
  extra_name: true
  defer_init: true

# Performs an add, sub, mul, or div on two float values.
- name: MathF
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    jsop: JSOp
  extra_name: true
  defer_init: true

- name: ModD
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: Mod

- name: ModPowTwoD
  result_type: WordSized
  operands:
    lhs: WordSized
  arguments:
    divisor: uint32_t
  mir_op: Mod

- name: WasmBuiltinModD
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
    instance: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntAdd
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntSub
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntMul
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntPow
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntBitAnd
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntBitOr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntBitXor
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntLsh
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntRsh
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntIncrement
  result_type: WordSized
  operands:
    input: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntDecrement
  result_type: WordSized
  operands:
    input: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntNegate
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: BigIntBitNot
  result_type: WordSized
  operands:
    input: WordSized
  call_instruction: true
  mir_op: true

- name: BigIntPtrAdd
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrSub
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrMul
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 2
  mir_op: true

- name: BigIntPtrDivPowTwo
  result_type: WordSized
  operands:
    lhs: WordSized
  arguments:
    shift: int32_t
    negativeDivisor: bool

- name: BigIntPtrMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 2
  mir_op: true

- name: BigIntPtrModPowTwo
  result_type: WordSized
  operands:
    lhs: WordSized
  arguments:
    shift: int32_t
  num_temps: 1

- name: BigIntPtrPow
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 2
  mir_op: true

- name: BigIntPtrBitAnd
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrBitOr
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrBitXor
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: BigIntPtrLsh
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 2
  mir_op: true

- name: BigIntPtrRsh
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 2
  mir_op: true

- name: BigIntPtrBitNot
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Adds two string, returning a string.
- name: Concat
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 5

# Test if a string includes the constant search string.
- name: StringIncludesSIMD
  result_type: WordSized
  operands:
    string: WordSized
  arguments:
    searchString: JSOffThreadAtom*
  num_temps: 3

# Search for the first index of the constant search string.
- name: StringIndexOfSIMD
  result_type: WordSized
  operands:
    string: WordSized
  arguments:
    searchString: JSOffThreadAtom*
  num_temps: 3

# Test if a string starts with the constant search string
- name: StringStartsWithInline
  result_type: WordSized
  operands:
    string: WordSized
  arguments:
    searchString: JSOffThreadAtom*
  num_temps: 1

# Test if a string ends with the constant search string
- name: StringEndsWithInline
  result_type: WordSized
  operands:
    string: WordSized
  arguments:
    searchString: JSOffThreadAtom*
  num_temps: 1

# Calls the ToLowerCase case conversion function. Inlines the case conversion
# when possible.
- name: StringToLowerCase
  result_type: WordSized
  operands:
    string: WordSized
  num_temps: 5
  mir_op: StringConvertCase

# Calls the ToLowerCase case conversion function. Inlines the case conversion
# when possible.
- name: CharCodeToLowerCase
  result_type: WordSized
  operands:
    code: WordSized
  num_temps: 1
  mir_op: CharCodeConvertCase

# Calls the ToUpperCase case conversion function.
- name: StringToUpperCase
  result_type: WordSized
  operands:
    string: WordSized
  call_instruction: true
  mir_op: StringConvertCase

# Calls the ToUpperCase case conversion function. Inlines the case conversion
# when possible.
- name: CharCodeToUpperCase
  result_type: WordSized
  operands:
    code: WordSized
  num_temps: 1
  mir_op: CharCodeConvertCase

- name: Int32ToDouble
  result_type: WordSized
  operands:
    input: WordSized

- name: Float32ToDouble
  result_type: WordSized
  operands:
    input: WordSized

- name: DoubleToFloat32
  result_type: WordSized
  operands:
    input: WordSized

- name: Int32ToFloat32
  result_type: WordSized
  operands:
    input: WordSized

- name: DoubleToFloat16
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

- name: DoubleToFloat32ToFloat16
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 2

- name: Float32ToFloat16
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

- name: Int32ToFloat16
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

# Convert a value to a double.
- name: ValueToDouble
  result_type: WordSized
  operands:
    input: BoxedValue
  mir_op: ToDouble

# Convert a value to a float32.
- name: ValueToFloat32
  result_type: WordSized
  operands:
    input: BoxedValue
  mir_op: ToFloat32

# Convert a value to a float16.
- name: ValueToFloat16
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: ToFloat16

# Convert a value to an int32.
- name: ValueToNumberInt32
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: ToNumberInt32

# Convert a value to an int32 with truncation.
- name: ValueTruncateToInt32
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 2
  mir_op: TruncateToInt32

# Convert a value to a BigInt.
- name: ValueToBigInt
  result_type: WordSized
  operands:
    input: BoxedValue
  mir_op: ToBigInt

# Convert a double to an int32.
#   Input: floating-point Register
#   Output: 32-bit integer
#   Bailout: if the double cannot be converted to an integer.
- name: DoubleToInt32
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: ToNumberInt32

# Convert a float32 to an int32.
#   Input: floating-point Register
#   Output: 32-bit integer
#   Bailout: if the float32 cannot be converted to an integer.
- name: Float32ToInt32
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: ToNumberInt32

# Convert a double to a truncated int32.
#   Input: floating-point Register
#   Output: 32-bit integer
- name: TruncateDToInt32
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: TruncateToInt32

# Convert a double to a truncated int32 with instance offset because we need it
# for the slow ool path.
- name: WasmBuiltinTruncateDToInt32
  result_type: WordSized
  operands:
    input: WordSized
    instance: WordSized
  num_temps: 1
  mir_op: WasmBuiltinTruncateToInt32

# Convert a float32 to a truncated int32.
#   Input: floating-point Register
#   Output: 32-bit integer
- name: TruncateFToInt32
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: TruncateToInt32

# Convert a float32 to a truncated int32 with instance offset because we need
# it for the slow ool path.
- name: WasmBuiltinTruncateFToInt32
  result_type: WordSized
  operands:
    input: WordSized
    instance: WordSized
  num_temps: 1
  mir_op: WasmBuiltinTruncateToInt32

- name: WasmTruncateToInt32
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Convert a boolean value to a string.
- name: BooleanToString
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: ToString

# Convert an integer hosted on one definition to a string with a function call.
- name: IntToString
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: ToString

# Convert a double hosted on one definition to a string with a function call.
- name: DoubleToString
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: ToString

# Convert a primitive to a string with a function call.
- name: ValueToString
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: ToString

# Double raised to a half power.
- name: PowHalfD
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: PowHalf

- name: NaNToZero
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: OsrEntry
  gen_boilerplate: false

# Materialize a Value stored in an interpreter frame for OSR.
- name: OsrValue
  result_type: BoxedValue
  operands:
    entry: WordSized
  mir_op: true

# Materialize a JSObject env chain stored in an interpreter frame for OSR.
- name: OsrEnvironmentChain
  result_type: WordSized
  operands:
    entry: WordSized
  mir_op: true

# Materialize a JSObject env chain stored in an interpreter frame for OSR.
- name: OsrReturnValue
  result_type: BoxedValue
  operands:
    entry: WordSized
  mir_op: true

- name: OsrArgumentsObject
  result_type: WordSized
  operands:
    entry: WordSized
  mir_op: true

- name: RegExp
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: RegExpHasCaptureGroups
  result_type: WordSized
  operands:
    regexp: WordSized
    input: WordSized
  mir_op: true

- name: GetFirstDollarIndex
  result_type: WordSized
  operands:
    str: WordSized
  num_temps: 3

- name: StringReplace
  result_type: WordSized
  operands:
    string: WordSized
    pattern: WordSized
    replacement: WordSized
  call_instruction: true
  mir_op: true

- name: BinaryValueCache
  result_type: BoxedValue
  operands:
    lhs: BoxedValue
    rhs: BoxedValue
  # Takes two temps: these are intended to be FloatReg0 and FloatReg1
  # to allow the actual cache code to safely clobber those values without
  # save and restore.
  num_temps: 2
  mir_op: BinaryCache

- name: BinaryBoolCache
  result_type: WordSized
  operands:
    lhs: BoxedValue
    rhs: BoxedValue
  # Takes two temps: these are intendend to be FloatReg0 and FloatReg1
  # To allow the actual cache code to safely clobber those values without
  # save and restore.
  num_temps: 2
  mir_op: BinaryCache

- name: Lambda
  result_type: WordSized
  operands:
    environmentChain: WordSized
  num_temps: 1
  mir_op: true

- name: FunctionWithProto
  result_type: WordSized
  operands:
    envChain: WordSized
    prototype: WordSized
  call_instruction: true
  mir_op: true

- name: GetNextEntryForIterator
  result_type: WordSized
  operands:
    iter: WordSized
    result: WordSized
  num_temps: 3
  mir_op: true

# Double to IntPtr, eligible for accessing into a TypedArray or DataView. If
# the index isn't exactly representable as an IntPtr, depending on the
# supportOOB flag on the MIR instruction, either bail out or produce an IntPtr
# which is equivalent to an OOB access.
- name: GuardNumberToIntPtrIndex
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Bailout if index >= length.
- name: BoundsCheck
  operands:
    index: WordSized
    length: WordSized
  mir_op: true

# Bailout if index + minimum < 0 or index + maximum >= length.
- name: BoundsCheckRange
  operands:
    index: WordSized
    length: WordSized
  num_temps: 1
  mir_op: BoundsCheck

# Bailout if index < minimum.
- name: BoundsCheckLower
  operands:
    index: WordSized
  mir_op: true

- name: SpectreMaskIndex
  result_type: WordSized
  operands:
    index: WordSized
    length: WordSized
  mir_op: true

# Load a value from a dense array's elements vector. Bail out if it's the hole
# value.
- name: LoadElementV
  result_type: BoxedValue
  operands:
    elements: WordSized
    index: WordSized
  mir_op: LoadElement

- name: InArray
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
    initLength: WordSized
  mir_op: true

# Load a value from an array's elements vector, loading |undefined| if we hit a
# hole. Bail out if we get a negative index.
- name: LoadElementHole
  result_type: BoxedValue
  operands:
    elements: WordSized
    index: WordSized
    initLength: WordSized
  mir_op: true

# Store a boxed value to a dense array's element vector.
- name: StoreElementV
  operands:
    elements: WordSized
    index: WordSized
    value: BoxedValue
  mir_op: StoreElement
  extra_name: true

# Store a typed value to a dense array's elements vector. Compared to
# LStoreElementV, this instruction can store doubles and constants directly,
# and does not store the type tag if the array is monomorphic and known to
# be packed.
- name: StoreElementT
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
  mir_op: StoreElement
  extra_name: true

- name: StoreHoleValueElement
  operands:
    elements: WordSized
    index: WordSized

# Like LStoreElementV, but supports indexes >= initialized length.
- name: StoreElementHoleV
  operands:
    object: WordSized
    elements: WordSized
    index: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: StoreElementHole

# Like LStoreElementT, but supports indexes >= initialized length.
- name: StoreElementHoleT
  operands:
    object: WordSized
    elements: WordSized
    index: WordSized
    value: WordSized
  num_temps: 1
  mir_op: StoreElementHole

- name: ArrayPopShift
  result_type: BoxedValue
  operands:
    object: WordSized
  num_temps: 2
  mir_op: true
  extra_name: true

- name: FrameArgumentsSlice
  result_type: WordSized
  operands:
    begin: WordSized
    count: WordSized
  num_temps: 1
  mir_op: true

- name: InlineArgumentsSlice
  gen_boilerplate: false

- name: LoadUnboxedScalar
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
  num_temps: 2
  mir_op: true

- name: LoadUnboxedInt64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
  mir_op: LoadUnboxedScalar

- name: LoadDataViewElement
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
    littleEndian: WordSized
  num_temps: 2
  num_temps64: 1
  mir_op: true

- name: LoadDataViewElement64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
    littleEndian: WordSized
  mir_op: LoadDataViewElement

- name: LoadTypedArrayElementHole
  result_type: BoxedValue
  operands:
    elements: WordSized
    index: WordSized
    length: WordSized
  num_temps: 1
  mir_op: true

- name: LoadTypedArrayElementHoleBigInt
  result_type: BoxedValue
  operands:
    elements: WordSized
    index: WordSized
    length: WordSized
  num_temps: 1
  num_temps64: 1
  mir_op: LoadTypedArrayElementHole

- name: StoreUnboxedScalar
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
  num_temps: 1
  mir_op: true

- name: StoreUnboxedInt64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
  mir_op: StoreUnboxedScalar

- name: StoreDataViewElement
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
    littleEndian: WordSized
  num_temps: 1
  num_temps64: 1
  mir_op: true

- name: StoreDataViewElement64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
    littleEndian: WordSized
  num_temps64: 1
  mir_op: StoreDataViewElement

- name: StoreTypedArrayElementHole
  operands:
    elements: WordSized
    length: WordSized
    index: WordSized
    value: WordSized
  num_temps: 1
  mir_op: true

- name: StoreTypedArrayElementHoleInt64
  operands:
    elements: WordSized
    length: WordSized
    index: WordSized
    value: Int64
  num_temps: 1
  mir_op: StoreTypedArrayElementHole

- name: TypedArraySubarray
  result_type: WordSized
  operands:
    object: WordSized
    start: WordSized
    length: WordSized
  call_instruction: true
  mir_op: true

- name: TypedArrayFill
  operands:
    object: WordSized
    value: WordSized
    start: WordSized
    end: WordSized
  call_instruction: true
  mir_op: true

- name: TypedArrayFill64
  operands:
    object: WordSized
    value: Int64
    start: WordSized
    end: WordSized
  call_instruction: true
  mir_op: TypedArrayFill

- name: AtomicIsLockFree
  result_type: WordSized
  operands:
    value: WordSized

- name: CompareExchangeTypedArrayElement
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
    oldval: WordSized
    newval: WordSized
  # Needs additional temps on LL/SC platforms to extract/insert bits of word.
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  num_temps: 4
#else
  num_temps: 1
#endif
  mir_op: true

- name: AtomicExchangeTypedArrayElement
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
  # Needs additional temps on LL/SC platforms to extract/insert bits of word.
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  num_temps: 4
#else
  num_temps: 1
#endif
  mir_op: true

- name: AtomicTypedArrayElementBinop
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
  # Needs additional temps on LL/SC platforms to extract/insert bits of word.
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  num_temps: 4
#else
  num_temps: 2
#endif
  mir_op: true

# Atomic binary operation where the result is discarded.
- name: AtomicTypedArrayElementBinopForEffect
  operands:
    elements: WordSized
    index: WordSized
    value: WordSized
  # Additional temp that may be used on LL/SC platforms for the flag result of the store.
  # Needs additional temps on LL/SC platforms to extract/insert bits of word.
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
  num_temps: 1
#elif defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  num_temps: 3
#endif
  mir_op: AtomicTypedArrayElementBinop

- name: AtomicLoad64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
#ifdef JS_CODEGEN_X86
  num_temps64: 1
#endif
  mir_op: LoadUnboxedScalar

- name: AtomicStore64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
  num_temps64: 1
#endif
  mir_op: StoreUnboxedScalar

- name: CompareExchangeTypedArrayElement64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
    oldval: Int64
    newval: Int64
  mir_op: CompareExchangeTypedArrayElement

- name: AtomicExchangeTypedArrayElement64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
  mir_op: AtomicExchangeTypedArrayElement

- name: AtomicTypedArrayElementBinop64
  result_type: Int64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
#ifndef JS_CODEGEN_X86
  num_temps64: 1
#endif
  mir_op: AtomicTypedArrayElementBinop

# Atomic binary operation where the result is discarded.
- name: AtomicTypedArrayElementBinopForEffect64
  operands:
    elements: WordSized
    index: WordSized
    value: Int64
#ifndef JS_CODEGEN_X64
  num_temps64: 1
#endif
  mir_op: AtomicTypedArrayElementBinop

- name: EffectiveAddress3
  result_type: WordSized
  operands:
    base: WordSized
    index: WordSized
  mir_op: true

- name: EffectiveAddress2
  result_type: WordSized
  operands:
    index: WordSized
  mir_op: true

- name: ClampIToUint8
  result_type: WordSized
  operands:
    input: WordSized

- name: ClampDToUint8
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1

- name: ClampVToUint8
  result_type: WordSized
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: ClampToUint8

# Load a boxed value from an object's fixed slot.
- name: LoadFixedSlotV
  result_type: BoxedValue
  operands:
    object: WordSized
  mir_op: LoadFixedSlot

# Load a boxed value from an object's fixed slot.
# If it is a non-atom string, atomize it and update the slot.
- name: LoadFixedSlotAndAtomize
  result_type: BoxedValue
  operands:
    object: WordSized
  num_temps: 1
  mir_op: LoadFixedSlot

# Load a typed value from an object's fixed slot.
- name: LoadFixedSlotT
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: LoadFixedSlot

- name: LoadFixedSlotAndUnbox
  result_type: WordSized
  operands:
    object: WordSized
  num_temps64: 1
  mir_op: true

- name: LoadDynamicSlotAndUnbox
  result_type: WordSized
  operands:
    slots: WordSized
  num_temps64: 1
  mir_op: true

- name: LoadElementAndUnbox
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized
  num_temps64: 1
  mir_op: true

- name: LoadFixedSlotUnboxAndAtomize
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: LoadFixedSlotAndUnbox

- name: LoadDynamicSlotUnboxAndAtomize
  result_type: WordSized
  operands:
    slots: WordSized
  mir_op: LoadDynamicSlotAndUnbox

- name: AddAndStoreSlot
  operands:
    object: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: true

- name: AddAndStoreSlotPreserveWrapper
  operands:
    object: WordSized
    value: BoxedValue
  num_temps: 2
  mir_op: AddAndStoreSlot

# Store a boxed value to an object's fixed slot.
- name: StoreFixedSlotV
  operands:
    obj: WordSized
    value: BoxedValue
  mir_op: StoreFixedSlot

# Store a typed value to an object's fixed slot.
- name: StoreFixedSlotT
  operands:
    obj: WordSized
    value: WordSized
  mir_op: StoreFixedSlot

- name: StoreFixedSlotFromOffsetV
  operands:
    object: WordSized
    offset: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: StoreFixedSlotFromOffset

- name: StoreFixedSlotFromOffsetT
  operands:
    object: WordSized
    offset: WordSized
    value: WordSized
  num_temps: 1
  mir_op: StoreFixedSlotFromOffset

- name: GetPropSuperCache
  result_type: BoxedValue
  operands:
    obj: WordSized
    receiver: BoxedValue
    id: BoxedValue
  mir_op: true

# Patchable jump to stubs generated for a GetProperty cache, which loads a
# boxed value.
- name: GetPropertyCache
  result_type: BoxedValue
  operands:
    value: BoxedValue
    id: BoxedValue
  mir_op: true

# Load a value from an object's dslots or a slots vector.
- name: LoadDynamicSlotV
  result_type: BoxedValue
  operands:
    input: WordSized
  mir_op: LoadDynamicSlot

# Load a value from an object's dslots or a slots vector.
# If it is a non-atom string, atomize it and update the slot.
- name: LoadDynamicSlotAndAtomize
  result_type: BoxedValue
  operands:
    input: WordSized
  num_temps: 1
  mir_op: LoadDynamicSlot

# Store a value to an object's dslots or a slots vector.
- name: StoreDynamicSlotV
  operands:
    slots: WordSized
    value: BoxedValue
  mir_op: StoreDynamicSlot

# Store a typed value to an object's dslots or a slots vector. This has a
# few advantages over LStoreDynamicSlotV:
# 1) We can bypass storing the type tag if the slot has the same type as
#    the value.
# 2) Better Register allocation: we can store constants and FP regs directly
#    without requiring a second Register for the value.
- name: StoreDynamicSlotT
  operands:
    slots: WordSized
    value: WordSized
  mir_op: StoreDynamicSlot

- name: StoreDynamicSlotFromOffsetV
  operands:
    slots: WordSized
    offset: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: StoreDynamicSlotFromOffset

- name: StoreDynamicSlotFromOffsetT
  operands:
    slots: WordSized
    offset: WordSized
    value: WordSized
  num_temps: 1
  mir_op: StoreDynamicSlotFromOffset

# Take the floor of a double precision number and converts it to an int32.
# Implements Math.floor().
- name: Floor
  result_type: WordSized
  operands:
    input: WordSized

# Take the floor of a single precision number and converts it to an int32.
# Implements Math.floor().
- name: FloorF
  result_type: WordSized
  operands:
    input: WordSized

# Take the ceiling of a double precision number and converts it to an int32.
# Implements Math.ceil().
- name: Ceil
  result_type: WordSized
  operands:
    input: WordSized

# Take the ceiling of a single precision number and converts it to an int32.
# Implements Math.ceil().
- name: CeilF
  result_type: WordSized
  operands:
    input: WordSized

# Round a double precision number and converts it to an int32.
# Implements Math.round().
- name: Round
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

# Round a single precision number and converts it to an int32.
# Implements Math.round().
- name: RoundF
  result_type: WordSized
  operands:
    input: WordSized
  num_temps: 1
  mir_op: Round

# Truncates a double precision number and converts it to an int32.
# Implements Math.trunc().
- name: Trunc
  result_type: WordSized
  operands:
    input: WordSized

# Truncates a single precision number and converts it to an int32.
# Implements Math.trunc().
- name: TruncF
  result_type: WordSized
  operands:
    input: WordSized

# Rounds a double precision number accordingly to mir()->roundingMode(),
# and keeps a double output.
- name: NearbyInt
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Rounds a single precision number accordingly to mir()->roundingMode(),
# and keeps a single output.
- name: NearbyIntF
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: NearbyInt

# Rounds a double precision number and keeps a double output.
# Implements Math.round().
- name: RoundToDouble
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Rounds a single precision number and keeps a single output.
# Implements Math.round().
- name: RoundToFloat32
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: RoundToDouble

- name: NewLexicalEnvironmentObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewClassBodyEnvironmentObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: NewVarEnvironmentObject
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: MegamorphicSetElement
  operands:
    object: WordSized
    index: BoxedValue
    value: BoxedValue
  # On x86 we do not have enough registers to use 3 temps for this *and* take
  # five words worth of operands. Since it's 32-bit, though, we get two
  # registers from pushing `value`, which doesn't get used until the end
  # anyway. This is somewhat klunky, but oh well.
#ifdef JS_CODEGEN_X86
  num_temps: 1
#else
  num_temps: 3
#endif
  call_instruction: true
  mir_op: true

- name: ObjectToIterator
  result_type: WordSized
  operands:
    object: WordSized
  num_temps: 3
  mir_op: true

- name: IteratorHasIndicesAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    object: WordSized
    iterator: WordSized
  num_temps: 2

- name: IteratorsMatchAndHaveIndicesAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    object: WordSized
    iterator: WordSized
    otherIterator: WordSized
  num_temps: 2

# Patchable jump to stubs generated for a SetProperty cache.
- name: SetPropertyCache
  operands:
    object: WordSized
    id: BoxedValue
    value: BoxedValue
  # Takes an additional temp: this is intendend to be FloatReg0 to allow the
  # actual cache code to safely clobber that value without save and restore.
  num_temps: 2
  mir_op: true

- name: GetIteratorCache
  result_type: WordSized
  operands:
    value: BoxedValue
  num_temps: 2
  mir_op: true

- name: IsNoIterAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: BoxedValue

- name: CloseIterCache
  operands:
    iter: WordSized
  num_temps: 1
  mir_op: true

- name: Int32ToIntPtr
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

- name: AdjustDataViewLength
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

# Convert a Boolean to an Int64, following ToBigInt.
- name: BooleanToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: ToInt64

# Convert a String to an Int64, following ToBigInt.
- name: StringToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: ToInt64

# Simulate ToBigInt on a Value and produce a matching Int64.
- name: ValueToInt64
  result_type: Int64
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: ToInt64

# Create a new BigInt* from an unboxed uint64.
- name: Uint64ToBigInt
  result_type: WordSized
  operands:
    input: Int64
  num_temps: 1
  mir_op: Int64ToBigInt

# Generational write barrier used when writing an object to another object.
- name: PostWriteBarrierO
  operands:
    object: WordSized
    value: WordSized
  num_temps: 1
  mir_op: PostWriteBarrier

# Generational write barrier used when writing a string to an object.
- name: PostWriteBarrierS
  operands:
    object: WordSized
    value: WordSized
  num_temps: 1
  mir_op: PostWriteBarrier

# Generational write barrier used when writing a BigInt to an object.
- name: PostWriteBarrierBI
  operands:
    object: WordSized
    value: WordSized
  num_temps: 1
  mir_op: PostWriteBarrier

# Generational write barrier used when writing a value to another object.
- name: PostWriteBarrierV
  operands:
    object: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: PostWriteBarrier

# Generational write barrier used when writing an object to another object's
# elements.
- name: PostWriteElementBarrierO
  operands:
    object: WordSized
    value: WordSized
    index: WordSized
  num_temps: 1
  mir_op: PostWriteElementBarrier

# Generational write barrier used when writing a string to an object's
# elements.
- name: PostWriteElementBarrierS
  operands:
    object: WordSized
    value: WordSized
    index: WordSized
  num_temps: 1
  mir_op: PostWriteElementBarrier

# Generational write barrier used when writing a BigInt to an object's
# elements.
- name: PostWriteElementBarrierBI
  operands:
    object: WordSized
    value: WordSized
    index: WordSized
  num_temps: 1
  mir_op: PostWriteElementBarrier

# Generational write barrier used when writing a value to another object's
# elements.
- name: PostWriteElementBarrierV
  operands:
    object: WordSized
    index: WordSized
    value: BoxedValue
  num_temps: 1
  mir_op: PostWriteElementBarrier

# Guard against an object's identity.
- name: GuardObjectIdentity
  operands:
    input: WordSized
    expected: WordSized
  mir_op: true

# Guard against an function's identity.
- name: GuardSpecificFunction
  operands:
    input: WordSized
    expected: WordSized

- name: GuardSpecificSymbol
  operands:
    symbol: WordSized
  mir_op: true

- name: GuardMultipleShapesToOffset
  result_type: WordSized
  operands:
    object: WordSized
    shapeList: WordSized
  num_temps: 3
  mir_op: true

- name: GuardProto
  operands:
    object: WordSized
    expected: WordSized
  num_temps: 1

- name: GuardNullProto
  operands:
    object: WordSized
  num_temps: 1

- name: ProxyHasProp
  result_type: BoxedValue
  operands:
    proxy: WordSized
    id: BoxedValue
  call_instruction: true
  mir_op: true

- name: InCache
  result_type: WordSized
  operands:
    lhs: BoxedValue
    rhs: WordSized
  num_temps: 1
  mir_op: true

- name: HasOwnCache
  result_type: WordSized
  operands:
    value: BoxedValue
    id: BoxedValue
  mir_op: true

- name: CheckPrivateFieldCache
  result_type: WordSized
  operands:
    value: BoxedValue
    id: BoxedValue
  mir_op: true

- name: InstanceOfO
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: InstanceOf

- name: InstanceOfV
  result_type: WordSized
  operands:
    lhs: BoxedValue
    rhs: WordSized
  mir_op: InstanceOf

- name: IsCallableO
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: IsCallable

- name: IsCallableV
  result_type: WordSized
  operands:
    object: BoxedValue
  num_temps: 1
  mir_op: IsCallable

- name: IsArrayO
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: IsArray

- name: IsArrayV
  result_type: WordSized
  operands:
    value: BoxedValue
  num_temps: 1
  mir_op: IsArray

- name: IsTypedArray
  result_type: WordSized
  operands:
    object: WordSized
  mir_op: true

- name: IsObjectAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: BoxedValue

- name: IsNullOrUndefinedAndBranch
  successors: [ifTrue, ifFalse]
  operands:
    input: BoxedValue

- name: HasClass
  result_type: WordSized
  operands:
    lhs: WordSized
  mir_op: true

- name: GuardToClass
  result_type: WordSized
  operands:
    lhs: WordSized
  num_temps: 1
  mir_op: true

- name: GuardToFunction
  result_type: WordSized
  operands:
    lhs: WordSized
  num_temps: 1
  mir_op: true

- name: WasmSelect
  result_type: WordSized
  operands:
    trueExpr: WordSized
    falseExpr: WordSized
    condExpr: WordSized
  mir_op: true

- name: WasmSelectI64
  result_type: Int64
  operands:
    trueExpr: Int64
    falseExpr: Int64
    condExpr: WordSized
  mir_op: WasmSelect

- name: WasmCompareAndSelect
  result_type: WordSized
  operands:
    leftExpr: WordSized
    rightExpr: WordSized
    ifTrueExpr: WordSized
    ifFalseExpr: WordSized
  arguments:
    compareType: MCompare::CompareType
    jsop: JSOp
  mir_op: WasmSelect

- name: WasmAddOffset
  result_type: WordSized
  operands:
    base: WordSized
  mir_op: true

- name: WasmAddOffset64
  result_type: Int64
  operands:
    base: Int64
  mir_op: WasmAddOffset

- name: WasmBoundsCheck
  result_type: WordSized
  operands:
    ptr: WordSized
    boundsCheckLimit: WordSized
  mir_op: true

- name: WasmBoundsCheck64
  result_type: Int64
  operands:
    ptr: Int64
    boundsCheckLimit: Int64
  mir_op: WasmBoundsCheck

- name: WasmBoundsCheckInstanceField
  result_type: WordSized
  operands:
    instance: WordSized
    ptr: WordSized
  arguments:
    offset: uint32_t
  mir_op: WasmBoundsCheck

- name: WasmBoundsCheckInstanceField64
  result_type: Int64
  operands:
    instance: WordSized
    ptr: Int64
  arguments:
    offset: uint32_t
  mir_op: WasmBoundsCheck

- name: WasmExtendU32Index
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

- name: WasmWrapU32Index
  result_type: WordSized
  operands:
    input: WordSized
  mir_op: true

- name: WasmAlignmentCheck
  operands:
    ptr: WordSized
  mir_op: true

- name: WasmAlignmentCheck64
  operands:
    ptr: Int64
  mir_op: WasmAlignmentCheck

- name: WasmLoadInstance
  result_type: WordSized
  operands:
    instance: WordSized
  mir_op: true

- name: WasmLoadInstance64
  result_type: Int64
  operands:
    instance: WordSized
  mir_op: WasmLoadInstance

- name: WasmHeapReg
  result_type: WordSized
  mir_op: true

- name: WasmLoad
  result_type: WordSized
  operands:
    ptr: WordSized
    memoryBase: WordSized
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64)
  num_temps: 1
#endif
  mir_op: true

- name: WasmLoadI64
  result_type: Int64
  operands:
    ptr: WordSized
    memoryBase: WordSized
#ifdef JS_CODEGEN_ARM
  num_temps: 2
#elif defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64)
  num_temps: 1
#endif
  mir_op: WasmLoad

- name: WasmStore
  operands:
    ptr: WordSized
    value: WordSized
    memoryBase: WordSized
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64)
  num_temps: 1
#endif
  mir_op: true

- name: WasmStoreI64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64)
  num_temps: 1
#endif
  mir_op: WasmStore

- name: WasmCompareExchangeHeap
  result_type: WordSized
  operands:
    ptr: WordSized
    oldValue: WordSized
    newValue: WordSized
    memoryBase: WordSized
#ifdef JS_CODEGEN_X86
  num_temps: 1
#elif defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  # Temp that may be used on LL/SC platforms for extract/insert bits of word.
  num_temps: 3
#endif
  mir_op: true

- name: WasmAtomicExchangeHeap
  result_type: WordSized
  operands:
    ptr: WordSized
    value: WordSized
    memoryBase: WordSized
#ifdef JS_CODEGEN_X86
  num_temps: 1
#elif defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  # Temp that may be used on LL/SC platforms for extract/insert bits of word.
  num_temps: 3
#endif
  mir_op: true

- name: WasmAtomicBinopHeap
  result_type: WordSized
  operands:
    ptr: WordSized
    value: WordSized
    memoryBase: WordSized
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  # Temp that may be used on LL/SC platforms for extract/insert bits of word.
  num_temps: 3
#elifdef JS_CODEGEN_X86
  # Additional temp to hold a computed address.
  num_temps: 2
#else
  num_temps: 1
#endif
  mir_op: true

# Atomic binary operation where the result is discarded.
- name: WasmAtomicBinopHeapForEffect
  operands:
    ptr: WordSized
    value: WordSized
    memoryBase: WordSized
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
  # Temp that may be used on LL/SC platforms for extract/insert bits of word.
  num_temps: 3
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
  num_temps: 1
#endif
  mir_op: WasmAtomicBinopHeap

- name: WasmLoadSlot
  result_type: WordSized
  operands:
    containerRef: WordSized
  arguments:
    offset: size_t
    type: MIRType
    wideningOp: MWideningOp
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmLoadElement
  result_type: WordSized
  operands:
    base: WordSized
    index: WordSized
  arguments:
    type: MIRType
    wideningOp: MWideningOp
    scale: Scale
    maybeTrap: wasm::MaybeTrapSiteDesc
  num_temps: 1

- name: WasmLoadSlotI64
  result_type: Int64
  operands:
    containerRef: WordSized
  arguments:
    offset: size_t
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmLoadElementI64
  result_type: Int64
  operands:
    base: WordSized
    index: WordSized
  arguments:
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmStoreSlot
  operands:
    value: WordSized
    containerRef: WordSized
  arguments:
    offset: size_t
    type: MIRType
    narrowingOp: MNarrowingOp
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmStoreSlotI64
  operands:
    value: Int64
    containerRef: WordSized
  arguments:
    offset: size_t
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmStoreStackResult
  operands:
    value: WordSized
    stackResultsArea: WordSized
  arguments:
    offset: size_t
    type: MIRType

- name: WasmStoreStackResultI64
  operands:
    value: Int64
    stackResultsArea: WordSized
  arguments:
    offset: size_t

- name: WasmStoreElement
  operands:
    base: WordSized
    index: WordSized
    value: WordSized
  arguments:
    type: MIRType
    narrowingOp: MNarrowingOp
    scale: Scale
    maybeTrap: wasm::MaybeTrapSiteDesc
  num_temps: 1

- name: WasmStoreElementI64
  operands:
    base: WordSized
    index: WordSized
    value: Int64
  arguments:
    maybeTrap: wasm::MaybeTrapSiteDesc

- name: WasmStoreElementRef
  operands:
    instance: WordSized
    base: WordSized
    index: WordSized
    value: WordSized
  arguments:
    maybeTrap: wasm::MaybeTrapSiteDesc
    preBarrierKind: WasmPreBarrierKind
  num_temps: 2

- name: WasmLoadTableElement
  result_type: WordSized
  operands:
    elements: WordSized
    index: WordSized

- name: WasmDerivedPointer
  result_type: WordSized
  operands:
    base: WordSized
  mir_op: true

- name: WasmDerivedIndexPointer
  result_type: WordSized
  operands:
    base: WordSized
    index: WordSized
  mir_op: true

- name: WasmStoreRef
  operands:
    instance: WordSized
    valueBase: WordSized
    value: WordSized
  arguments:
    offset: uint32_t
    maybeTrap: wasm::MaybeTrapSiteDesc
    preBarrierKind: WasmPreBarrierKind
  num_temps: 1
  mir_op: true

# Generational write barrier used when writing an object to another object.
- name: WasmPostWriteBarrierWholeCell
  operands:
    instance: WordSized
    object: WordSized
    value: WordSized
  num_temps: 1
  mir_op: true

# Ditto, but with a scaled index instead of a constant offset.
- name: WasmPostWriteBarrierEdgeAtIndex
  operands:
    instance: WordSized
    object: WordSized
    valueBase: WordSized
    index: WordSized
    value: WordSized
  arguments:
    elemSize: uint32_t
  num_temps: 1
  mir_op: true

- name: WasmParameter
  result_type: WordSized

- name: WasmParameterI64
  result_type: Int64

- name: WasmReturn
  operands:
    rval: WordSized
    instance: WordSized

- name: WasmReturnI64
  operands:
    rval: Int64
    instance: WordSized

- name: WasmReturnVoid
  operands:
    rval: WordSized

- name: WasmStackArg
  operands:
    arg: WordSized
  mir_op: true

- name: WasmStackArgI64
  operands:
    arg: Int64
  mir_op: WasmStackArg

- name: WasmNullConstant
  result_type: WordSized

- name: WasmCallIndirectAdjunctSafepoint
  gen_boilerplate: false

- name: WasmCall
  gen_boilerplate: false

- name: WasmRegisterResult
  gen_boilerplate: false

- name: WasmRegisterPairResult
  gen_boilerplate: false

- name: WasmSystemFloatRegisterResult
  gen_boilerplate: false

- name: WasmStackResultArea
  result_type: WordSized
  num_temps: 1
  mir_op: true

- name: WasmStackResult
  gen_boilerplate: false

- name: WasmStackResult64
  gen_boilerplate: false

#ifdef ENABLE_WASM_JSPI
- name: WasmResume
  gen_boilerplate: false
#endif

- name: AssertRangeI
  operands:
    input: WordSized
  mir_op: AssertRange

- name: AssertRangeD
  operands:
    input: WordSized
  num_temps: 1
  mir_op: AssertRange

- name: AssertRangeF
  operands:
    input: WordSized
  num_temps: 2
  mir_op: AssertRange

- name: AssertRangeV
  operands:
    input: BoxedValue
  num_temps: 3
  mir_op: AssertRange

- name: AssertClass
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: GuardValue
  operands:
    input: BoxedValue
  num_temps: 1
  mir_op: true

- name: GuardFunctionFlags
  operands:
    function: WordSized
  mir_op: true

- name: LexicalCheck
  operands:
    input: BoxedValue
  mir_op: true

- name: MemoryBarrier
  arguments:
    barrier: jit::MemoryBarrier

- name: Debugger
  num_temps: 1
  call_instruction: true

- name: Generator
  result_type: WordSized
  operands:
    callee: WordSized
    environmentChain: WordSized
    argsObject: WordSized
  call_instruction: true
  mir_op: true

- name: MaybeExtractAwaitValue
  result_type: BoxedValue
  operands:
    value: BoxedValue
    canSkip: WordSized
  call_instruction: true
  mir_op: true

- name: ObjectStaticProto
  result_type: WordSized
  operands:
    object: WordSized

- name: GuardTagNotEqual
  operands:
    lhs: WordSized
    rhs: WordSized

# Canonicalize a double value.
- name: CanonicalizeNaND
  result_type: WordSized
  operands:
    input: WordSized

# Canonicalize a float32 value.
- name: CanonicalizeNaNF
  result_type: WordSized
  operands:
    input: WordSized

- name: IonToWasmCall
  gen_boilerplate: false

- name: IonToWasmCallV
  gen_boilerplate: false

- name: IonToWasmCallI64
  gen_boilerplate: false

- name: WasmNewI31Ref
  mir_op: true
  result_type: WordSized
  operands:
    value: WordSized

# Constant Simd128
- name: Simd128
  result_type: WordSized
  arguments:
    simd128: SimdConstant

# (v128, v128, v128) -> v128 effect-free operation.
# temp is FPR.
- name: WasmTernarySimd128
  result_type: WordSized
  operands:
    v0: WordSized
    v1: WordSized
    v2: WordSized
  arguments:
    simdOp: wasm::SimdOp
  num_temps: 1

# (v128, v128) -> v128 effect-free operations
# lhs and dest are the same.
# temps (if in use) are FPR.
# The op may differ from the MIR node's op.
- name: WasmBinarySimd128
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    simdOp: wasm::SimdOp
  num_temps: 2

- name: WasmBinarySimd128WithConstant
  result_type: WordSized
  operands:
    lhs: WordSized
  arguments:
    rhs: SimdConstant
  num_temps: 1
  mir_op: true

# (v128, i32) -> v128 effect-free variable-width shift operations
# lhs and dest are the same.
- name: WasmVariableShiftSimd128
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
  # temp is an FPR (if in use).
  num_temps: 1
#endif
  mir_op: WasmShiftSimd128

# (v128, i32) -> v128 effect-free constant-width shift operations
- name: WasmConstantShiftSimd128
  result_type: WordSized
  operands:
    src: WordSized
  arguments:
    shift: int32_t
  mir_op: WasmShiftSimd128

# (v128) -> v128 sign replication operation.
- name: WasmSignReplicationSimd128
  result_type: WordSized
  operands:
    src: WordSized
  mir_op: WasmShiftSimd128

# // (v128, v128, imm_simd) -> v128 effect-free operation.
- name: WasmShuffleSimd128
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    op: SimdShuffleOp
    control: SimdConstant
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
  # temp is FPR (and always in use).
  num_temps: 1
#endif

# (v128, imm_simd) -> v128 effect-free operation.
- name: WasmPermuteSimd128
  result_type: WordSized
  operands:
    src: WordSized
  arguments:
    op: SimdPermuteOp
    control: SimdConstant

- name: WasmReplaceLaneSimd128
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: true

- name: WasmReplaceInt64LaneSimd128
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: Int64
  mir_op: WasmReplaceLaneSimd128

# (scalar) -> v128 effect-free operations, scalar != int64
- name: WasmScalarToSimd128
  result_type: WordSized
  operands:
    src: WordSized
  mir_op: true

# (int64) -> v128 effect-free operations
- name: WasmInt64ToSimd128
  result_type: WordSized
  operands:
    src: Int64
  mir_op: WasmScalarToSimd128

# // (v128, imm) -> scalar effect-free operations.
- name: WasmReduceSimd128
  result_type: WordSized
  operands:
    src: WordSized
#ifdef JS_CODEGEN_ARM64
  # temp is FPR (if in use).
  num_temps: 1
#endif
  mir_op: true

# (v128, onTrue, onFalse) test-and-branch operations.
- name: WasmReduceAndBranchSimd128
  successors: [ifTrue, ifFalse]
  operands:
    src: WordSized
  arguments:
    simdOp: wasm::SimdOp

# (v128, imm) -> i64 effect-free operations
- name: WasmReduceSimd128ToInt64
  result_type: Int64
  operands:
    src: WordSized
  mir_op: WasmReduceSimd128

- name: WasmLoadLaneSimd128
  result_type: WordSized
  operands:
    ptr: WordSized
    src: WordSized
    memoryBase: WordSized
#ifdef JS_CODEGEN_ARM64
  num_temps: 1
#endif
  mir_op: true

- name: WasmStoreLaneSimd128
  operands:
    ptr: WordSized
    src: WordSized
    memoryBase: WordSized
#ifdef JS_CODEGEN_ARM64
  num_temps: 1
#endif
  mir_op: true

- name: Unbox
  gen_boilerplate: false

- name: UnboxFloatingPoint
  result_type: WordSized
  operands:
    input: BoxedValue
  mir_op: Unbox

# Convert a 32-bit unsigned integer to a double.
- name: WasmUint32ToDouble
  result_type: WordSized
  operands:
    input: WordSized
#ifdef JS_CODEGEN_X86
  num_temps: 1
#endif

# Convert a 32-bit unsigned integer to a float32.
- name: WasmUint32ToFloat32
  result_type: WordSized
  operands:
    input: WordSized
#ifdef JS_CODEGEN_X86
  num_temps: 1
#endif

- name: DivI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Div
  extra_name: true

- name: ModI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
  num_temps: 1
#endif
  mir_op: Mod
  extra_name: true

# Signed division by a power-of-two constant.
- name: DivPowTwoI
  result_type: WordSized
  operands:
    numerator: WordSized
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
    numeratorCopy: WordSized
#endif
  arguments:
    shift: int32_t
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_RISCV64)
    # Negative divisor case not implemented for all targets.
    negativeDivisor: bool
#endif
#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64)
  num_temps: 1
#endif
  mir_op: Div

- name: ModPowTwoI
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  mir_op: Mod

# Takes a tableswitch with an integer to decide.
- name: TableSwitch
  operands:
    index: WordSized
  num_temps: 2
  mir_op: true

# Takes a tableswitch with a value to decide.
- name: TableSwitchV
  operands:
    input: BoxedValue
  num_temps: 3
  mir_op: TableSwitch

- name: MulI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
    lhsCopy: WordSized
#endif
  mir_op: Mul
  extra_name: true
#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64)
  defer_init: true
#endif

- name: TimeClipCall
  result_type: WordSized
  operands:
    time: WordSized
  num_temps: 1
  mir_op: TimeClip

#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
- name: DivConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  num_temps: 1
  mir_op: Div

- name: ModConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  num_temps: 1
  mir_op: Mod

- name: UDivConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  num_temps: 1
  mir_op: Div

- name: UModConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  num_temps: 1
  mir_op: Mod

- name: UDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Div

- name: UMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Mod
#endif

#ifdef JS_CODEGEN_X86
- name: BoxFloatingPoint
  result_type: BoxedValue
  operands:
    input: WordSized
  arguments:
    type: MIRType
  num_temps: 2
  extra_name: true

- name: DivOrModI64
  gen_boilerplate: false

- name: UDivOrModI64
  gen_boilerplate: false

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  num_temps: 1
  mir_op: true

- name: WasmAtomicLoadI64
  result_type: Int64
  operands:
    ptr: WordSized
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmLoad

- name: WasmAtomicStoreI64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmStore

- name: WasmCompareExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    expected: Int64
    replacement: Int64
    memoryBase: WordSized
  mir_op: WasmCompareExchangeHeap

- name: WasmAtomicBinopI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  arguments:
    access: const wasm::MemoryAccessDesc&
    operation: AtomicOp

- name: WasmAtomicExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  arguments:
    access: const wasm::MemoryAccessDesc&
#endif

#ifdef JS_CODEGEN_X64
- name: DivI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Div

- name: ModI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Mod

- name: UDivI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Div

- name: UModI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  mir_op: Mod

- name: DivPowTwoI64
  result_type: WordSized
  operands:
    numerator: WordSized
    numeratorCopy: WordSized
  arguments:
    shift: int32_t
    negativeDivisor: bool
  mir_op: Div

- name: ModPowTwoI64
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  mir_op: Mod

- name: DivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  num_temps: 1
  mir_op: Div

- name: ModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  num_temps: 1
  mir_op: Mod

- name: UDivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  num_temps: 1
  mir_op: Div

- name: UModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  num_temps: 1
  mir_op: Mod

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  num_temps: 1
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  num_temps: 1
  mir_op: true
#endif

#ifdef JS_CODEGEN_ARM
- name: BoxFloatingPoint
  result_type: BoxedValue
  operands:
    input: WordSized
  arguments:
    type: MIRType
  num_temps: 1
  extra_name: true

- name: DivOrModI64
  gen_boilerplate: false

- name: UDivOrModI64
  gen_boilerplate: false

# LSoftDivI is a software divide for ARM cores that don't support a hardware
# divide instruction, implemented as a C++ native call.
- name: SoftDivI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: Div

- name: SoftModI
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  num_temps: 1
  call_instruction: true
  mir_op: Mod

- name: ModMaskI
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  num_temps: 2
  mir_op: Mod

- name: UDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: UMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: SoftUDivOrMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  call_instruction: true
  mir_op: Instruction

- name: Int64ToFloatingPointCall
  result_type: WordSized
  operands:
    input: Int64
    instance: WordSized
  call_instruction: true
  mir_op: BuiltinInt64ToFloatingPoint

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
    instance: WordSized
  call_instruction: true
  mir_op: WasmBuiltinTruncateToInt64

- name: WasmAtomicLoadI64
  result_type: Int64
  operands:
    ptr: WordSized
    memoryBase: WordSized
  mir_op: WasmLoad

- name: WasmAtomicStoreI64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmStore

- name: WasmCompareExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    expected: Int64
    replacement: Int64
    memoryBase: WordSized
  mir_op: WasmCompareExchangeHeap

- name: WasmAtomicBinopI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  arguments:
    access: const wasm::MemoryAccessDesc&
    operation: AtomicOp
  num_temps64: 1

- name: WasmAtomicExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  arguments:
    access: const wasm::MemoryAccessDesc&
#endif

#ifdef JS_CODEGEN_ARM64
- name: DivI64
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: ModI64
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: UDivI64
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: UModI64
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: DivConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  mir_op: Div

- name: UDivConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  mir_op: Div

- name: ModConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  mir_op: Mod

- name: UModConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  mir_op: Mod

- name: DivPowTwoI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    shift: int32_t
    negativeDivisor: bool
  mir_op: Div

- name: ModPowTwoI64
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  mir_op: Mod

- name: DivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  mir_op: Div

- name: ModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  mir_op: Mod

- name: UDivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  mir_op: Div

- name: UModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  mir_op: Mod

- name: UDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: UMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  mir_op: true
#endif

#ifdef JS_CODEGEN_MIPS64
- name: DivOrModI64
  gen_boilerplate: false

- name: UDivOrMod
  gen_boilerplate: false

- name: UDivOrModI64
  gen_boilerplate: false

- name: ModMaskI
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  num_temps: 2
  mir_op: Mod

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  mir_op: true

- name: WasmUnalignedLoad
  result_type: WordSized
  operands:
    ptr: WordSized
    memoryBase: WordSized
  num_temps: 2
  mir_op: WasmLoad

- name: WasmUnalignedLoadI64
  result_type: Int64
  operands:
    ptr: WordSized
    memoryBase: WordSized
  num_temps: 2
  mir_op: WasmLoad

- name: WasmUnalignedStore
  operands:
    ptr: WordSized
    value: WordSized
    memoryBase: WordSized
  num_temps: 2
  mir_op: WasmStore

- name: WasmUnalignedStoreI64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps: 2
  mir_op: WasmStore

- name: WasmCompareExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    oldValue: Int64
    newValue: Int64
    memoryBase: WordSized
  mir_op: WasmCompareExchangeHeap

- name: WasmAtomicBinopI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmAtomicBinopHeap

- name: WasmAtomicExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  mir_op: WasmAtomicExchangeHeap
#endif

#ifdef JS_CODEGEN_LOONG64
- name: DivOrModI64
  gen_boilerplate: false

- name: UDivOrMod
  gen_boilerplate: false

- name: UDivOrModI64
  gen_boilerplate: false

- name: ModMaskI
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  num_temps: 2
  mir_op: Mod

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  mir_op: true

- name: WasmCompareExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    oldValue: Int64
    newValue: Int64
    memoryBase: WordSized
  mir_op: WasmCompareExchangeHeap

- name: WasmAtomicBinopI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmAtomicBinopHeap

- name: WasmAtomicExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  mir_op: WasmAtomicExchangeHeap
#endif

#ifdef JS_CODEGEN_RISCV64
- name: DivConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  mir_op: Div

- name: ModConstantI
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int32_t
  mir_op: Mod

- name: UDiv
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: UDivConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  mir_op: Div

- name: UMod
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: UModConstant
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint32_t
  mir_op: Mod

- name: DivI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: DivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  mir_op: Div

- name: DivPowTwoI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    shift: int32_t
    negativeDivisor: bool
  mir_op: Div

- name: ModI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: ModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: int64_t
  mir_op: Mod

- name: ModPowTwoI64
  result_type: WordSized
  operands:
    input: WordSized
  arguments:
    shift: int32_t
  mir_op: Mod

- name: UDivI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Div

- name: UDivConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  mir_op: Div

- name: UModI64
  result_type: Int64
  operands:
    lhs: WordSized
    rhs: WordSized
  mir_op: Mod

- name: UModConstantI64
  result_type: WordSized
  operands:
    numerator: WordSized
  arguments:
    denominator: uint64_t
  mir_op: Mod

- name: WasmTruncateToInt64
  result_type: Int64
  operands:
    input: WordSized
  mir_op: true

- name: Int64ToFloatingPoint
  result_type: WordSized
  operands:
    input: Int64
  mir_op: true

- name: WasmCompareExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    oldValue: Int64
    newValue: Int64
    memoryBase: WordSized
  mir_op: WasmCompareExchangeHeap

- name: WasmAtomicBinopI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  num_temps64: 1
  mir_op: WasmAtomicBinopHeap

- name: WasmAtomicExchangeI64
  result_type: Int64
  operands:
    ptr: WordSized
    value: Int64
    memoryBase: WordSized
  mir_op: WasmAtomicExchangeHeap
#endif

#ifdef JS_64BIT
- name: WasmAddSubI128HI64
  result_type: WordSized
  operands:
    lhsLo: WordSized
    lhsHi: WordSized
    rhsLo: WordSized
    rhsHi: WordSized
  arguments:
    isAdd: bool
  mir_op: WasmAddSubI128HI64

- name: WasmMulI64WideHI64
  result_type: WordSized
  operands:
    lhs: WordSized
    rhs: WordSized
  arguments:
    isSigned: bool
#ifdef JS_CODEGEN_X64
  num_temps: 2
#endif
  mir_op: WasmMulI64WideHI64
#endif

#ifndef JS_64BIT
- name: WasmLoadInstanceScratch2xI32
  result_type: Int64
  operands:
    instance: WordSized
  arguments:
    byteOffset: uint32_t
  mir_op: WasmLoadInstanceScratch2xI32

- name: WasmStoreInstanceScratch2xI32
  operands:
    value: Int64
    instance: WordSized
  arguments:
    byteOffset: uint32_t
  mir_op: WasmStoreInstanceScratch2xI32
#endif

#ifdef FUZZING_JS_FUZZILLI
- name: FuzzilliHashT
  result_type: WordSized
  operands:
    value: WordSized
  num_temps: 2
  mir_op: FuzzilliHash

- name: FuzzilliHashV
  result_type: WordSized
  operands:
    value: BoxedValue
  num_temps: 2
  mir_op: FuzzilliHash

- name: FuzzilliHashStore
  operands:
    value: WordSized
  num_temps: 2
  mir_op: FuzzilliHashStore
#endif
