# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

doc: |
  opcode
    Opcode of the instruction

  signature
    Describes signature of the instruction. Properties of the operands are separated by '-' symbol.
    For info about operand tokens see the 'legend' section

    Note: any check instructions might be eliminated by optimizer, thus operand checks (nc, zc, bc, ngc) qualifiers have
          not mandatory meaning.

  base
    C++ base that represent this opcode. In far future if we managed to generate also instruction classes,
    this field become redundant

  flags
    Properties of the instruction, such as: arithmetic, binop, throw, etc

  modes
    Modes which the instruction can be used in

templates:
  # Templates aim to reduce boilerplate in instruction description.
  # Templates are denoted by a '$' symbol in the first character of the string.
  verify_unary:
    - equal_common_types
    - float_src_eq_dst_size
    - integer_src_ge_dst_size
  verify_binary_int:
    - equal_common_types
    - integer_src_ge_dst_size
  verify_binary:
    - equal_common_types
    - integer_src_ge_dst_size
    - float_src_eq_dst_size

instructions:
  - opcode: Compare
    base: CompareInst
    signature: [d-bool, real, real]
    flags: [acc_read, acc_write, ifcvt]
    description: Compare two integer or reference values according to condition code(for reference only CC_EQ).

  - opcode: Cmp
    base: CmpInst
    signature: [d-int, number, number]
    flags: [acc_read, acc_write, ifcvt]
    description:  Compare two float or integer values.

  - opcode: CompareAnyType
    base: CompareAnyTypeInst
    signature: [d-bool, any]
    flags: [acc_read, acc_write, ifcvt]
    description:  Compare any type value and type.

  - opcode: CastAnyTypeValue
    base: CastAnyTypeValueInst
    signature: [d-real, any]
    flags: [acc_read, acc_write]
    description:  Cast any dynamic type value to compiler type value.

  - opcode: CastValueToAnyType
    base: CastValueToAnyTypeInst
    signature: [d-any, real]
    flags: [acc_read, acc_write, no_cse]
    description:  Cast compiler type value to any dynamic type value.

  - opcode: Constant
    base: ConstantInst
    signature: [d-i32-i64-f32-f64]
    flags: [no_cse, ifcvt]
    description: Constant value.
    verification:
      - start_block_instruction

  - opcode: Parameter
    base: ParameterInst
    signature: [d-real-any]
    flags: [no_cse, no_hoist]
    description: Method's parameter.
    verification:
      - start_block_instruction

  - opcode: LoadString
    base: LoadFromPool
    signature: [d-ref, save_state]
    flags: [load, can_throw, no_hoist, no_cse, require_state, runtime_call, acc_write]
    description: Load string from pool.

  - opcode: Return
    base: FixedInputsInst1
    signature: [real-any]
    flags: [cf, no_dce, no_hoist, no_cse, barrier, acc_read, terminator]
    description: Return value from method.

  - opcode: Intrinsic
    base: IntrinsicInst
    signature: [d-real-void, real-dyn]
    flags: [no_dce, no_hoist, no_cse, barrier, require_state, runtime_call]
    description: Call runtime intrinsics directly.

    ##############################################################################
    # Special pseudo instructions
    #
  - opcode: Phi
    base: PhiInst
    signature: [d-real-ref, real-ref-dyn]
    flags: [no_cse, no_hoist]
    description: Phi instruction

  - opcode: SpillFill
    base: SpillFillInst
    signature: []
    flags: [no_cse, no_dce]
    description: Pseudo instruction that inserted by Register Allocator.

  - opcode: SaveState
    base: SaveStateInst
    signature: [d-real-pseudo, real-dyn]
    flags: [no_hoist, no_cse]
    description: >-
      Contains information about virtual registers that must be saved before leaving compiled code. Constructed for all
      call instructions and all instructions that can throw.

  - opcode: If
    base: IfInst
    signature: [real, real]
    flags: [cf, no_dce, no_hoist, no_cse, barrier, low_level, acc_read]
    description: Performs compare and jump.

  - opcode: IfImm
    base: IfImmInst
    signature: [real]
    flags: [cf, no_dce, no_hoist, no_cse, barrier, acc_read]
    description: Performs compare with immediate and jump.

  - opcode: Try
    base: TryInst
    signature: []
    flags: [no_dce, no_hoist, no_cse, barrier]
    modes: [jit_aot, bytecode_opt]
    description: Pseudo instruction, inserted in the beginning of try-block.

  - opcode: CatchPhi
    base: CatchPhiInst
    signature: [d-real-ref, real-ref-dyn]
    flags: [no_hoist, no_cse]
    modes: [jit_aot, bytecode_opt]
    description: >-
      Pseudo instruction, which is inserted in the Catch handler basic block, and defines virtual registers at each throwing
      instruction of the appropriate try-block.

types:
  - name: i8
  - name: i16
  - name: i32
  - name: i64
  - name: u8
  - name: u16
  - name: u32
  - name: u64
  - name: f32
  - name: f64
  - name: bool
  - name: ref
  - name: ptr
  - name: void
  - name: any

arch_info:
- name: arm64
  regs_count: 32
  temp_regs: [16, 17, 20]
  fp_regs_count: 32
  fp_temp_regs: [30, 31]

- name: arm32
  regs_count: 16
  temp_regs: [8, 9, 12]
  fp_regs_count: 32
  fp_temp_regs: [14, 15]

- name: x86_64
  regs_count: 16
  temp_regs: [12, 13, 14]
  fp_regs_count: 16
  fp_temp_regs: [13, 14, 15]

legend:
  "Operand tokens":
    d: operand is a destination, operand is a source when 'd' is not specified
    i8: signed 8-bit integer
    i16: signed 16-bit integer
    i32: signed 32-bit integer
    i64: signed 64-bit integer
    u8: unsigned 8-bit integer
    u16: unsigned 16-bit integer
    u32: unsigned 32-bit integer
    u64: unsigned 64-bit integer
    f32: single precision float
    f64: double precision float
    bool: boolean type
    ref: object reference type
    ptr: pointer type
    void: void type
    int: type union of [bool, i8, i16, i32, i64, u8, u16, u32, u64]
    float: type union of [f32, f64]
    number: type union of [int, float]
    real: type union of [number, ref]
    any: the type is not statically defined(For dynamic languages)
    pseudo: pseudo destination - instruction doesn't actually write to the register
    zc: zero check - input must be the ZeroCheck instruction
    bc: bounds check - input must be the BoundsCheck instruction
    nc: null check - input must be the NullCheck instruction
    ngc: negative check - input should be the NegativeCheck instruction
    save_state: definition of the given input must be SaveState instruction
    dyn: dynamic operands, means that operand can repeat zero or more times

verification:
  equal_type_classes: |
    Type classes of instruction's operands are equal. Type classes are int, float, ref (see operand_tokens for info)
  float_src_eq_dst_size: |
    If instrucion's type is float then size of source operands shall be equal to size of destination.
  integer_src_ge_dst_size: |
    If instrucion's type is integer then size of source operands shall be greater than or equal to size of destination.
  start_block_instruction: |
    Instruction can only reside in start basic block.

flags:
  cf: Instruction affects control flow
  terminator: Execution will be terminated at the given instruction
  load: Instruction loads from memory
  store: Instruction stores into memory
  can_throw: Instruction can throw exception
  call: Call instruction.
  is_check: Instruction has runtime-checks and has `can_throw` flag
  no_dce: Instruction that can't be deleted on DCE
  no_cse: Instruction has unique vn class and CSE can't be applied
  no_dst: Instruction has no destination operand
  pseudo_dst: Instruction has pseudo destination operand, i.e. it doesn't affect on dataflow
  implicit_runtime_call: Instruction may call runtime before loading source, which can be moved by GC during that call
  low_level: Low level instruction
  no_hoist: Instruction can't be hoisted
  barrier: Instruction is a barrier for scheduling
  ref_special: Instruction which can not be moved throught runtime calls
  ifcvt: Instruction can be used in if-conversion
  require_state: Instruction may call runtime, thus, it requires SaveState in the inputs
  runtime_call: Instruction must call runtime
  commutative: Instruction is commutative(Add, OR, And e.t.c.)
  alloc: Instruction that allocates a new object on the heap
  acc_read: Read the accumulator register
  acc_write: Write the accumulator register
  heap_inv: Invalidates heap
  mem_barrier: we need encode memory barrier after the instruction(for return.void before)
  native: Instruction is used to generate unmanaged (native) code
  can_deoptimize: deoptimization may occur with jump to the interpreter

modes:
  jit_aot: JIT or AOT compiler
  bytecode_opt: Bytecode optimizer
  irtoc: Ir-To-Code tool
