14514f5e3Sopenharmony_ci# Circuit IR Specification
24514f5e3Sopenharmony_ci
34514f5e3Sopenharmony_ci## General Design
44514f5e3Sopenharmony_ci
54514f5e3Sopenharmony_ciCircuit IR is like a circuit diagram, which is good at representing the intrinsic logic of a computation process. The circuit diagram is a directed graph: [logic gates](https://en.wikipedia.org/wiki/Logic_gate) are nodes, wires are directed edges. For every gate, inputs are ordered, outputs are unordered. Circuit IR describes semantic of programs in a language-neutral and target-neutral way, targeting multi-language and multi-target support. The design of Circuit IR has a great emphasis on compilation speed (for JIT), code optimization (on both high and low levels), and canonicalization (unique representation for same intrinsic logic).
64514f5e3Sopenharmony_ci
74514f5e3Sopenharmony_ciCircuit IR splits a program into two major parts: [sequential logic](https://en.wikipedia.org/wiki/Sequential_logic) part and [combinational logic](https://en.wikipedia.org/wiki/Combinational_logic) part:
84514f5e3Sopenharmony_ci
94514f5e3Sopenharmony_ci* The **sequential logic** part is a subgraph of Circuit IR which is similar to the underlying control flow graph (CFG) of the program, and gates in this part are named **state gates** (since they acted like a [finite state machine](https://en.wikipedia.org/wiki/Finite-state_machine) (FSM)). Wires that connect two state gates represent possible state transitions of the FSM, and they are named **state wires**. Note that every gates that have output state wires are state gates.
104514f5e3Sopenharmony_ci
114514f5e3Sopenharmony_ci* The **combinational logic** part is the other subgraph of Circuit IR which represents all computations in a program using a directed acyclic graph (DAG), and gates in this part are named **computation gates**. A computation gate can do simple things such as adding two integer values, or complex things such as calling a function (and thus make a change to the global memory). Most of **computation gates** will take some values as input and output a value. These values can be transferred by **data wires**. Some computation gates will load from or store to the global memory, so they should be executed non-simultaneously and in some order that will not violate memory dependencies (such as RAW, WAR and WAW). Addressing this issue, **dependency wires** are introduced to constrain the possible execution order of such computations. When a computation gate has multiple dependencies, an auxiliary gate `DEPEND_SELECTOR` is used to merge dependencies. Note that dependency wires are treated like data wires during the scheduling phase, since dependency wires can be viewed as special data wires that transfer huge values representing the whole memory.
124514f5e3Sopenharmony_ci
134514f5e3Sopenharmony_ciIn traditional [SSA](https://en.wikipedia.org/wiki/Static_single_assignment_form) form IR (e.g. LLVM IR), each instruction is placed inside a node of CFG (basic block), and all instructions in a basic block are [linearly ordered](https://en.wikipedia.org/wiki/Total_order). However, in Circuit IR, computation gates are not tied to state gates, and they are [partially ordered](https://en.wikipedia.org/wiki/Partially_ordered_set) by wires. Sequential logic part and combinational logic part are loosely coupled, they only interact in three ways:
144514f5e3Sopenharmony_ci
154514f5e3Sopenharmony_ci* State gates that have multiple transitions (corresponding to multiple control flow branches) such as `IF_BRANCH` and `SWITCH_BRANCH` will need an input value computed from combinational logic part to select which next state the FSM will transit to.
164514f5e3Sopenharmony_ci
174514f5e3Sopenharmony_ci* Similar to the Φ functions in traditional SSA form IR, there are **[selector](https://en.wikipedia.org/wiki/Multiplexer) gates** such as `VALUE_SELECTOR` and `DEPEND_SELECTOR` that select a data or dependency path based on the state transition action of the FSM. Selector gates are affiliated (many-to-one) to `MERGE` state gates (which have several transition sources), and take several values or dependencies from computation part as input, and will select a value or dependency from input as output, based on which state transition action is taken.
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci* In some cases, a computation gate with side effect (i.e. may store to the global memory) should not be executed before a specific branch state transition action is taken. Addressing this problem, **[relay](https://en.wikipedia.org/wiki/Relay) gates** `DEPEND_RELAY` are introduced. They take a state gate (the target of action) as input, and reinterpret it as a kind of memory dependency that can be used by computation gates with side effect.
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ciLoose coupling of sequential logic part and combinational logic part can benefit compilation speed, code optimization. Firstly, most of IR passes can focus on only one part and will not be interfered by the other part, so the implementation will be simpler. In addition, some special and important code optimizations such as (register pressure sensitive) loop invariant code motion and code sink can be done in the IR scheduling phrase (without furthermore IR analysis or modification), thus they will not couple with other code optimizations and can be done perfectly. Last but not least, less coupling means more canonicalization, this implies fewer branches in the implementation of IR optimization algorithms.
224514f5e3Sopenharmony_ci
234514f5e3Sopenharmony_ciThere are several nodes named **root nodes** in Circuit IR. They are not called "gates" since they do not contribute to the logic of circuit, but they have the same data structure as gates. Root nodes are representing starting/ending vertices of the IR graph, or registering lists of starting/ending vertices of the IR graph. IR Passes usually traverse a part of all gates (forwardly or reversely) starting from root nodes. Explanations of root nodes are listed below:
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ci* `CIRCUIT_ROOT`: A very special gate located at zero offset. It is the only gate that does not have any inputs. Every root nodes listed below take this gate as theirs only input.
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_ci* `STATE_ENTRY`: Representing the initial state of the sequential logic part. (for traversing forwardly from beginning to ending)
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ci* `DEPEND_ENTRY`: The origin of dependency flows of the entire circuit.
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_ci* `RETURN_LIST`: Registering all terminal states of the function. (for traversing reversely from ending to beginning)
324514f5e3Sopenharmony_ci
334514f5e3Sopenharmony_ci* `CONSTANT_LIST` `ARG_LIST`: Registering all value origins such as constants and arguments. (they are special computation gates that do not depend on other values)
344514f5e3Sopenharmony_ci
354514f5e3Sopenharmony_ciThe offsets of root nodes are fixed, so they can be accessed instantly via `GateRef Circuit::GetRoot()`.
364514f5e3Sopenharmony_ci
374514f5e3Sopenharmony_ci## Type system
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ci### Levels of types
404514f5e3Sopenharmony_ci
414514f5e3Sopenharmony_ciThere are two levels of types of values in Circuit IR:
424514f5e3Sopenharmony_ci
434514f5e3Sopenharmony_ci* Primary types: This level of types are **low level** (closer to target architectures) and **fundamental** for Circuit IR, and are determined by the opcode of gates. They describe the bit width of values, and which type of registers (integer or float) should such values be put into. Circuit IR can be translated to correct machine code with only primary types. All primary types are `NOVALUE` `I1` `I8` `I16` `INT32` `INT64` `F32` `F64`. Note that pointer type is not included in primary types, since pointers are not different from integers in common ISAs. The concept of pointers should be expressed in secondary types.
444514f5e3Sopenharmony_ci
454514f5e3Sopenharmony_ci* Secondary types: This level of types are **high level** (closer to languages) and **optional**. They can provide information for program analysis, code optimization and garbage collection (generating stack maps). Secondary types can represent categories of possible bit vectors the value can be (e.g. `JS_ANY` `JS_BOOLEAN` `JS_NULL` `JS_UNDEFINED` `JS_NUMBER` `JS_SMI` etc. builtin categories and user defined bit vectors categories), and possible classes of objects the value points to as a pointer (e.g. `JS_HEAP_OBJECT` `JS_STRING` `JS_OBJECT` `JS_ARRAY` `JS_TYPED_ARRAY` `JS_UINT8_ARRAY` etc. builtin classes and user defined classes).
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ciValidation rules of primary type are already builtin for Circuit IR. Validation rules of secondary types need to be additionally provided.
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ci### Layout of type representation bits (GateType)
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_ciGateType is represented by 32 bits:
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ci* The 31st bit is used to distinguish between MIR type and TS type, `0` means TS type, `1` means MIR type.
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ci* The 30th and 29th bits are used to indicate whether the output values of the MIR gates are GC related (when within the category of tagged values) as follows:
564514f5e3Sopenharmony_ci    * `00` means GC may or may not occur (within the `GC` or `NOGC` tagged value category)
574514f5e3Sopenharmony_ci    * `01` means GC will occur (within the `GC` tagged value category)
584514f5e3Sopenharmony_ci    * `10` means GC will not occur (within the `NOGC` tagged value category)
594514f5e3Sopenharmony_ci    * `11` means not within the category of tagged values (within the C++ world category)
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ci* In the case of MIR type, the 1st bit in GateType is used to indicate whether there are output values. When MachineType is `NOVALUE`, GateType is always `EMPTY`.
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci### Type inference
644514f5e3Sopenharmony_ci
654514f5e3Sopenharmony_ciPrimary types are all set during construction of Circuit IR, so no furthermore type inference is required. Circuit IR verifier will verify consistency of primary types. Secondary types can be not precisely set during construction (e.g. leaving many intermediate values as `JS_ANY`), and the compiler should be able to do type inference and check type consistency following data flow paths (e.g. `c:<JS_ANY>=JS_ADD(a:<JS_NUMBER>, b:<JS_STRING>) -> c:<JS_STRING>=JS_ADD(a:<JS_NUMBER>, b:<JS_STRING>)` and `c:<JS_ANY>=VALUE_SELECTOR(a:<JS_STRING>, b:<JS_ARRAY>) -> c:<JS_HEAP_OBJECT>=JS_ADD(a:<JS_STRING>, b:<JS_ARRAY>)`), thus the secondary types will be more precise than initially set at the end.
664514f5e3Sopenharmony_ci
674514f5e3Sopenharmony_ci## Instructions
684514f5e3Sopenharmony_ci
694514f5e3Sopenharmony_ciThere are three levels of instructions in Circuit IR: high-level instructions (HIR), middle-level instructions (MIR) and low-level instructions (LIR). They have the same underlying basic structure, so they can co-occur in the same Circuit IR graphs, and the semantics are still consistent. Instructions are not necessarily computational gates. Some instructions may throw an exception and lead to state transition, so they are state gates doing computations. There are also some "pure" state gates that do not do computation, they are compatible with all levels of instructions.
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci* HIR instructions represent language-related computational process, which usually correspond to the bytecodes of specific languages.
724514f5e3Sopenharmony_ci* MIR instructions are language-independent and target-independent, which are similar to LLVM IR, but having a completely different type system. The type system is very lightweight, designed to better support fast compilation and garbage collection.
734514f5e3Sopenharmony_ci* LIR instructions are target-related, which usually correspond to the machine instructions of target architecture.
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ci### Notations
764514f5e3Sopenharmony_ci
774514f5e3Sopenharmony_ci* `ANY_STATE` means any state gates.
784514f5e3Sopenharmony_ci* `GENERAL_STATE` means any one of `IF_TRUE`, `IF_FALSE`, `IF_SUCCESS`, `IF_EXCEPTION`,`SWITCH_CASE`, `DEFAULT_CASE`, `MERGE`, `LOOP_BEGIN`, `STATE_ENTRY`, `ORDINARY_BLOCK` gates.
794514f5e3Sopenharmony_ci* `ANYVALUE` means any one of `I1` `I8` `I16` `I32` `INT64` `F32` `F64` `ARCH`.
804514f5e3Sopenharmony_ci* `ANYINT` means any one of `I1` `I8` `I16` `I32` `I64` `ARCH`.
814514f5e3Sopenharmony_ci* `ANYFLOAT` means any one of `F32` `F64`.
824514f5e3Sopenharmony_ci* `ARCH` means architecture-related integer type (`INTx` on `x` bits architecture).
834514f5e3Sopenharmony_ci* `FLEX` means flexible primary type of output value (could be `ARCH`).
844514f5e3Sopenharmony_ci* <<...>> means occurring any times (maybe zero)
854514f5e3Sopenharmony_ci
864514f5e3Sopenharmony_ci### Pure state gates
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_ci#### RETURN
894514f5e3Sopenharmony_ci
904514f5e3Sopenharmony_ciReturn a value from a non-void function.
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_ci|        | state wires       | #dependency wires  | data wires   |
934514f5e3Sopenharmony_ci|--------|-------------------|--------------------|--------------|
944514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`] | 1                  | [`ANYVALUE`] |
954514f5e3Sopenharmony_ci| output | {}                | 0                  | {}           |
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_ci| Root          | Bitfield |
984514f5e3Sopenharmony_ci|---------------|----------|
994514f5e3Sopenharmony_ci| `RETURN_LIST` | not used |
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ci#### THROW
1024514f5e3Sopenharmony_ci
1034514f5e3Sopenharmony_ciThrow an exception value out of function scope.
1044514f5e3Sopenharmony_ci
1054514f5e3Sopenharmony_ci|        | state wires       | #dependency wires | data wires   |
1064514f5e3Sopenharmony_ci|--------|-------------------|-------------------|--------------|
1074514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`] | 1                 | [`ANYVALUE`] |
1084514f5e3Sopenharmony_ci| output | {}                | 0                 | {}           |
1094514f5e3Sopenharmony_ci
1104514f5e3Sopenharmony_ci| Root         | Bitfield |
1114514f5e3Sopenharmony_ci|--------------|----------|
1124514f5e3Sopenharmony_ci| `THROW_LIST` | not used |
1134514f5e3Sopenharmony_ci
1144514f5e3Sopenharmony_ci#### ORDINARY_BLOCK
1154514f5e3Sopenharmony_ci
1164514f5e3Sopenharmony_ciAn ordinary state. Usually used as a placeholder. It will be eliminated by IR optimization.
1174514f5e3Sopenharmony_ci
1184514f5e3Sopenharmony_ci|        | state wires                       | #dependency wires | data wires |
1194514f5e3Sopenharmony_ci|--------|-----------------------------------|-------------------|------------|
1204514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`]                 | 0                 | []         |
1214514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ci| Root      | Bitfield |
1244514f5e3Sopenharmony_ci|-----------|----------|
1254514f5e3Sopenharmony_ci| not used  | not used |
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ci#### IF_BRANCH
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ciThis state has two possible transitions (branches) based on its input value.
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_ci|        | state wires             | #dependency wires | data wires |
1324514f5e3Sopenharmony_ci|--------|-------------------------|-------------------|------------|
1334514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`]       | 0                 | [`I1`]   |
1344514f5e3Sopenharmony_ci| output | {`IF_TRUE`, `IF_FALSE`} | 0                 | {}         |
1354514f5e3Sopenharmony_ci
1364514f5e3Sopenharmony_ci| Root      | Bitfield |
1374514f5e3Sopenharmony_ci|-----------|----------|
1384514f5e3Sopenharmony_ci| not used  | not used |
1394514f5e3Sopenharmony_ci
1404514f5e3Sopenharmony_ci#### SWITCH_BRANCH
1414514f5e3Sopenharmony_ci
1424514f5e3Sopenharmony_ciThis state has multiple possible transitions (branches) based on its input value.
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ci|        | state wires                         | #dependency wires | data wires   |
1454514f5e3Sopenharmony_ci|--------|-------------------------------------|-------------------|--------------|
1464514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`]                   | 0                 | [`ANYVALUE`] |
1474514f5e3Sopenharmony_ci| output | {<<`SWITCH_CASE`>>, `DEFAULT_CASE`} | 0                 | {}           |
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci| Root      | Bitfield |
1504514f5e3Sopenharmony_ci|-----------|----------|
1514514f5e3Sopenharmony_ci| not used  | not used |
1524514f5e3Sopenharmony_ci
1534514f5e3Sopenharmony_ci#### IF_TRUE | IF_FALSE
1544514f5e3Sopenharmony_ci
1554514f5e3Sopenharmony_ciSuccessor states of `IF_BRANCH`.
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci|        | state wires                       | #dependency wires | data wires |
1584514f5e3Sopenharmony_ci|--------|-----------------------------------|-------------------|------------|
1594514f5e3Sopenharmony_ci| input  | [`IF_BRANCH`]                     | 0                 | []         |
1604514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
1614514f5e3Sopenharmony_ci
1624514f5e3Sopenharmony_ci| Root      | Bitfield |
1634514f5e3Sopenharmony_ci|-----------|----------|
1644514f5e3Sopenharmony_ci| not used  | not used |
1654514f5e3Sopenharmony_ci
1664514f5e3Sopenharmony_ci#### IF_SUCCESS | IF_EXCEPTION
1674514f5e3Sopenharmony_ci
1684514f5e3Sopenharmony_ciSuccessor states of instructions (usually HIR) that may throw an exception.
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ci|        | state wires                       | #dependency wires | data wires |
1714514f5e3Sopenharmony_ci|--------|-----------------------------------|-------------------|------------|
1724514f5e3Sopenharmony_ci| input  | [`ANY_STATE`]                     | 0                 | []         |
1734514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ci| Root      | Bitfield |
1764514f5e3Sopenharmony_ci|-----------|----------|
1774514f5e3Sopenharmony_ci| not used  | not used |
1784514f5e3Sopenharmony_ci
1794514f5e3Sopenharmony_ci#### SWITCH_CASE | DEFAULT_CASE
1804514f5e3Sopenharmony_ci
1814514f5e3Sopenharmony_ciSuccessor state of `SWITCH_BRANCH`.
1824514f5e3Sopenharmony_ci
1834514f5e3Sopenharmony_ci|        | state wires                       | #dependency wires | data wires |
1844514f5e3Sopenharmony_ci|--------|-----------------------------------|-------------------|------------|
1854514f5e3Sopenharmony_ci| input  | [`SWITCH_BRANCH`]                 | 0                 | []         |
1864514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
1874514f5e3Sopenharmony_ci
1884514f5e3Sopenharmony_ci| Root      | Bitfield                                                               |
1894514f5e3Sopenharmony_ci|-----------|------------------------------------------------------------------------|
1904514f5e3Sopenharmony_ci| not used  | represent case value for `SWITCH_CASE` and not used for `DEFAULT_CASE` |
1914514f5e3Sopenharmony_ci
1924514f5e3Sopenharmony_ci#### MERGE
1934514f5e3Sopenharmony_ci
1944514f5e3Sopenharmony_ciState that have multiple possible predicate states.
1954514f5e3Sopenharmony_ci
1964514f5e3Sopenharmony_ci|        | state wires                                                | #dependency wires | data wires |
1974514f5e3Sopenharmony_ci|--------|------------------------------------------------------------|-------------------|------------|
1984514f5e3Sopenharmony_ci| input  | [<<`GENERAL_STATE`>>(N)]                                   | 0                 | []         |
1994514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_SELECTOR`>>, <<`VALUE_SELECTOR`>>} | 0                 | {}         |
2004514f5e3Sopenharmony_ci
2014514f5e3Sopenharmony_ci| Root      | Bitfield                   |
2024514f5e3Sopenharmony_ci|-----------|----------------------------|
2034514f5e3Sopenharmony_ci| not used  | number of state inputs (N) |
2044514f5e3Sopenharmony_ci
2054514f5e3Sopenharmony_ci#### LOOP_BEGIN
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_ciRepresents loop begin.
2084514f5e3Sopenharmony_ci
2094514f5e3Sopenharmony_ci|        | state wires                                                | #dependency wires | data wires |
2104514f5e3Sopenharmony_ci|--------|------------------------------------------------------------|-------------------|------------|
2114514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`, `LOOP_BACK`]                             | 0                 | []         |
2124514f5e3Sopenharmony_ci| output | {`ANY_STATE`, <<`DEPEND_SELECTOR`>>, <<`VALUE_SELECTOR`>>} | 0                 | {}         |
2134514f5e3Sopenharmony_ci
2144514f5e3Sopenharmony_ci| Root      | Bitfield |
2154514f5e3Sopenharmony_ci|-----------|----------|
2164514f5e3Sopenharmony_ci| not used  | not used |
2174514f5e3Sopenharmony_ci
2184514f5e3Sopenharmony_ci#### LOOP_BACK
2194514f5e3Sopenharmony_ci
2204514f5e3Sopenharmony_ciRepresents loop back.
2214514f5e3Sopenharmony_ci
2224514f5e3Sopenharmony_ci|        | state wires       | #dependency wires | data wires |
2234514f5e3Sopenharmony_ci|--------|-------------------|-------------------|------------|
2244514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`] | 0                 | []         |
2254514f5e3Sopenharmony_ci| output | {`LOOP_BEGIN`}    | 0                 | {}         |
2264514f5e3Sopenharmony_ci
2274514f5e3Sopenharmony_ci| Root      | Bitfield |
2284514f5e3Sopenharmony_ci|-----------|----------|
2294514f5e3Sopenharmony_ci| not used  | not used |
2304514f5e3Sopenharmony_ci
2314514f5e3Sopenharmony_ci### Intermediate gates and auxiliary gates
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ciIntermediate gates are gates that connect sequential logic and combinational logic parts (relays and selectors). Currently, there is only one type of auxiliary gates, which is used to represent multiple memory dependencies.
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_ci#### VALUE_SELECTOR
2364514f5e3Sopenharmony_ci
2374514f5e3Sopenharmony_ciRepresents value selector.
2384514f5e3Sopenharmony_ci
2394514f5e3Sopenharmony_ci|        | state wires               | #dependency wires | data wires      |
2404514f5e3Sopenharmony_ci|--------|---------------------------|-------------------|-----------------|
2414514f5e3Sopenharmony_ci| input  | [`MERGE` or `LOOP_BEGIN`] | 0                 | [<<`FLEX`>>(N)] |
2424514f5e3Sopenharmony_ci| output | {}                        | 0                 | {<<`FLEX`>>}    |
2434514f5e3Sopenharmony_ci
2444514f5e3Sopenharmony_ci| Root     | Bitfield                  |
2454514f5e3Sopenharmony_ci|----------|---------------------------|
2464514f5e3Sopenharmony_ci| not used | number of data inputs (N) |
2474514f5e3Sopenharmony_ci
2484514f5e3Sopenharmony_ci#### DEPEND_SELECTOR
2494514f5e3Sopenharmony_ci
2504514f5e3Sopenharmony_ciRepresents dependency selector.
2514514f5e3Sopenharmony_ci
2524514f5e3Sopenharmony_ci|        | state wires               | #dependency wires | data wires |
2534514f5e3Sopenharmony_ci|--------|---------------------------|-------------------|------------|
2544514f5e3Sopenharmony_ci| input  | [`MERGE` or `LOOP_BEGIN`] | N                 | []         |
2554514f5e3Sopenharmony_ci| output | {}                        | any               | {}         |
2564514f5e3Sopenharmony_ci
2574514f5e3Sopenharmony_ci| Root     | Bitfield                        |
2584514f5e3Sopenharmony_ci|----------|---------------------------------|
2594514f5e3Sopenharmony_ci| not used | number of dependency inputs (N) |
2604514f5e3Sopenharmony_ci
2614514f5e3Sopenharmony_ci#### DEPEND_RELAY
2624514f5e3Sopenharmony_ci
2634514f5e3Sopenharmony_ciRepresents dependency relay.
2644514f5e3Sopenharmony_ci
2654514f5e3Sopenharmony_ci|        | state wires                                                                                                        | #dependency wires | data wires |
2664514f5e3Sopenharmony_ci|--------|--------------------------------------------------------------------------------------------------------------------|-------------------|------------|
2674514f5e3Sopenharmony_ci| input  | [`IF_TRUE` or `IF_FALSE` or `IF_SUCCESS` or `IF_EXCEPTION` or `SWITCH_CASE` or `DEFAULT_CASE` or `ORDINARY_BLOCK`] | 1                 | []         |
2684514f5e3Sopenharmony_ci| output | {}                                                                                                                 | any               | {}         |
2694514f5e3Sopenharmony_ci
2704514f5e3Sopenharmony_ci| Root      | Bitfield |
2714514f5e3Sopenharmony_ci|-----------|----------|
2724514f5e3Sopenharmony_ci| not used  | not used |
2734514f5e3Sopenharmony_ci
2744514f5e3Sopenharmony_ci### HIR instructions
2754514f5e3Sopenharmony_ci
2764514f5e3Sopenharmony_ci#### JS_BYTECODE
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_ciRepresents JavaScript bytecode.
2794514f5e3Sopenharmony_ci
2804514f5e3Sopenharmony_ci|        | state wires                    | #dependency wires | data wires       |
2814514f5e3Sopenharmony_ci|--------|--------------------------------|-------------------|------------------|
2824514f5e3Sopenharmony_ci| input  | [`GENERAL_STATE`]              | 1                 | [<<`I64`>>(N)] |
2834514f5e3Sopenharmony_ci| output | {`IF_SUCCESS`, `IF_EXCEPTION`} | any               | {<<`I64`>>}    |
2844514f5e3Sopenharmony_ci
2854514f5e3Sopenharmony_ci| Root     | Bitfield                   |
2864514f5e3Sopenharmony_ci|----------|----------------------------|
2874514f5e3Sopenharmony_ci| not used | number of value inputs (N) |
2884514f5e3Sopenharmony_ci
2894514f5e3Sopenharmony_ci### MIR instructions
2904514f5e3Sopenharmony_ci
2914514f5e3Sopenharmony_ci#### Special instructions
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci##### CALL
2944514f5e3Sopenharmony_ci
2954514f5e3Sopenharmony_ciRepresents a simple function call (would not get an exception).
2964514f5e3Sopenharmony_ci
2974514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires                  |
2984514f5e3Sopenharmony_ci|--------|-------------|-------------------|-----------------------------|
2994514f5e3Sopenharmony_ci| input  | []          | 1                 | [`ARCH`, <<`ANYVALUE`>>(N)] |
3004514f5e3Sopenharmony_ci| output | {}          | any               | {<<`FLEX`>>}                |
3014514f5e3Sopenharmony_ci
3024514f5e3Sopenharmony_ci| Root      | Bitfield                    |
3034514f5e3Sopenharmony_ci|-----------|-----------------------------|
3044514f5e3Sopenharmony_ci| not used  | number of function args (N) |
3054514f5e3Sopenharmony_ci
3064514f5e3Sopenharmony_ci#### Floating point unary arithmetic operations
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ci* **FNEG**: returns the negation of its floating-point operand.
3094514f5e3Sopenharmony_ci
3104514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
3114514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
3124514f5e3Sopenharmony_ci| input  | []          | 0                 | [`FLEX`]     |
3134514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>} |
3144514f5e3Sopenharmony_ci
3154514f5e3Sopenharmony_ci| Root      | Bitfield |
3164514f5e3Sopenharmony_ci|-----------|----------|
3174514f5e3Sopenharmony_ci| not used  | not used |
3184514f5e3Sopenharmony_ci
3194514f5e3Sopenharmony_ci#### Integer binary arithmetic operations
3204514f5e3Sopenharmony_ci
3214514f5e3Sopenharmony_ci* **ADD**: returns the sum of its two integer operands.
3224514f5e3Sopenharmony_ci* **SUB**: returns the difference of its two integer operands. It is used to implement the "-" unary operation.
3234514f5e3Sopenharmony_ci* **MUL**: returns the product of its two integer operands.
3244514f5e3Sopenharmony_ci* **EXP**: returns the first integer operand raised to the power of the second integer operand.
3254514f5e3Sopenharmony_ci* **SDIV**: returns the signed quotient of its two integer operands.
3264514f5e3Sopenharmony_ci* **SREM**: returns the remainder from the signed division of its two integer operands.
3274514f5e3Sopenharmony_ci* **UDIV**: returns the unsigned quotient of its two integer operands.
3284514f5e3Sopenharmony_ci* **UREM**: returns the remainder from the unsigned division of its two integer operands.
3294514f5e3Sopenharmony_ci* **AND**: returns the bitwise logical and of its two operands.
3304514f5e3Sopenharmony_ci* **XOR**: returns the bitwise logical exclusive or of its two operands. It is used to implement the "~" unary operation.
3314514f5e3Sopenharmony_ci* **OR**: returns the bitwise logical inclusive or of its two operands.
3324514f5e3Sopenharmony_ci* **SHL**: returns the first integer operand shifted to the left a specified number of bits.
3334514f5e3Sopenharmony_ci* **LSHR**: returns the first integer operand shifted to the right a specified number of bits with zero fill.
3344514f5e3Sopenharmony_ci* **ASHR**: returns the first integer operand shifted to the right a specified number of bits with sign extension.
3354514f5e3Sopenharmony_ci
3364514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires       |
3374514f5e3Sopenharmony_ci|--------|-------------|-------------------|------------------|
3384514f5e3Sopenharmony_ci| input  | []          | 0                 | [`FLEX`, `FLEX`] |
3394514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>}     |
3404514f5e3Sopenharmony_ci
3414514f5e3Sopenharmony_ci| Root      | Bitfield |
3424514f5e3Sopenharmony_ci|-----------|----------|
3434514f5e3Sopenharmony_ci| not used  | not used |
3444514f5e3Sopenharmony_ci
3454514f5e3Sopenharmony_ci#### Floating-point binary arithmetic operations
3464514f5e3Sopenharmony_ci
3474514f5e3Sopenharmony_ci* **FADD**: returns the sum of its two floating-point operands.
3484514f5e3Sopenharmony_ci* **FSUB**: returns the difference of its two floating-point operands.
3494514f5e3Sopenharmony_ci* **FMUL**: returns the product of its two floating-point operands.
3504514f5e3Sopenharmony_ci* **FEXP**: returns the first floating-point operand raised to the power of the second floating-point operand.
3514514f5e3Sopenharmony_ci* **FDIV**: returns the quotient of its two floating-point operands.
3524514f5e3Sopenharmony_ci* **FMOD**: returns the remainder from the division of its two floating-point operands.
3534514f5e3Sopenharmony_ci
3544514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires       |
3554514f5e3Sopenharmony_ci|--------|-------------|-------------------|------------------|
3564514f5e3Sopenharmony_ci| input  | []          | 0                 | [`FLEX`, `FLEX`] |
3574514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>}     |
3584514f5e3Sopenharmony_ci
3594514f5e3Sopenharmony_ci| Root      | Bitfield |
3604514f5e3Sopenharmony_ci|-----------|----------|
3614514f5e3Sopenharmony_ci| not used  | not used |
3624514f5e3Sopenharmony_ci
3634514f5e3Sopenharmony_ci#### Integer binary compare operations
3644514f5e3Sopenharmony_ci
3654514f5e3Sopenharmony_ci* **ICMP**: returns a boolean (`I1`) value based on comparison of its two integer operands. Condition code indicating the kind of comparison to perform is stored in the bitfield. The possible condition codes are:
3664514f5e3Sopenharmony_ci  * `0001` `EQ`: yields true if the operands are equal, false otherwise. No sign interpretation is necessary or performed.
3674514f5e3Sopenharmony_ci  * `0010` `UGT`: interprets the operands as unsigned values and yields true if op1 is greater than op2.
3684514f5e3Sopenharmony_ci  * `0011` `UGE`: interprets the operands as unsigned values and yields true if op1 is greater than or equal to op2.
3694514f5e3Sopenharmony_ci  * `0100` `ULT`: interprets the operands as unsigned values and yields true if op1 is less than op2.
3704514f5e3Sopenharmony_ci  * `0101` `ULE`: interprets the operands as unsigned values and yields true if op1 is less than or equal to op2.
3714514f5e3Sopenharmony_ci  * `0110` `NE`: yields true if the operands are unequal, false otherwise. No sign interpretation is necessary or performed.
3724514f5e3Sopenharmony_ci  * `1010` `SGT`: interprets the operands as signed values and yields true if op1 is greater than op2.
3734514f5e3Sopenharmony_ci  * `1011` `SGE`: interprets the operands as signed values and yields true if op1 is greater than or equal to op2.
3744514f5e3Sopenharmony_ci  * `1100` `SLT`: interprets the operands as signed values and yields true if op1 is less than op2.
3754514f5e3Sopenharmony_ci  * `1101` `SLE`: interprets the operands as signed values and yields true if op1 is less than or equal to op2.
3764514f5e3Sopenharmony_ci
3774514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires               |
3784514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------------------|
3794514f5e3Sopenharmony_ci| input  | []          | 0                 | [`ANYVALUE`, `ANYVALUE`] |
3804514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`I1`>>}             |
3814514f5e3Sopenharmony_ci
3824514f5e3Sopenharmony_ci| Root      | Bitfield       |
3834514f5e3Sopenharmony_ci|-----------|----------------|
3844514f5e3Sopenharmony_ci| not used  | condition code |
3854514f5e3Sopenharmony_ci
3864514f5e3Sopenharmony_ci#### Floating-point binary compare operations
3874514f5e3Sopenharmony_ci
3884514f5e3Sopenharmony_ciNote: **ordered** means there is no NaN in the operands.
3894514f5e3Sopenharmony_ci
3904514f5e3Sopenharmony_ci* **FCMP**: returns a boolean (`I1`) value based on comparison of its two floating-point operands. Condition code indicating the kind of comparison to perform is stored in the bitfield. The possible condition codes are:
3914514f5e3Sopenharmony_ci  * `0000` `FALSE`: always returns false (no comparison)
3924514f5e3Sopenharmony_ci  * `0001` `OEQ`: ordered and equal
3934514f5e3Sopenharmony_ci  * `0010` `OGT`: ordered and greater than
3944514f5e3Sopenharmony_ci  * `0011` `OGE`: ordered and greater than or equal
3954514f5e3Sopenharmony_ci  * `0100` `OLT`: ordered and less than
3964514f5e3Sopenharmony_ci  * `0101` `OLE`: ordered and less than or equal
3974514f5e3Sopenharmony_ci  * `0110` `ONE`: ordered and not equal
3984514f5e3Sopenharmony_ci  * `0111` `ORD`: ordered (no nans)
3994514f5e3Sopenharmony_ci  * `1000` `UNO`: unordered (either nans)
4004514f5e3Sopenharmony_ci  * `1001` `UEQ`: unordered or equal
4014514f5e3Sopenharmony_ci  * `1010` `UGT`: unordered or greater than
4024514f5e3Sopenharmony_ci  * `1011` `UGE`: unordered or greater than or equal
4034514f5e3Sopenharmony_ci  * `1100` `ULT`: unordered or less than
4044514f5e3Sopenharmony_ci  * `1101` `ULE`: unordered or less than or equal
4054514f5e3Sopenharmony_ci  * `1110` `UNE`: unordered or not equal
4064514f5e3Sopenharmony_ci  * `1111` `TRUE`: always returns true (no comparison)
4074514f5e3Sopenharmony_ci
4084514f5e3Sopenharmony_ci
4094514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires               |
4104514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------------------|
4114514f5e3Sopenharmony_ci| input  | []          | 0                 | [`ANYVALUE`, `ANYVALUE`] |
4124514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`I1`>>}             |
4134514f5e3Sopenharmony_ci
4144514f5e3Sopenharmony_ci| Root      | Bitfield       |
4154514f5e3Sopenharmony_ci|-----------|----------------|
4164514f5e3Sopenharmony_ci| not used  | condition code |
4174514f5e3Sopenharmony_ci
4184514f5e3Sopenharmony_ci#### Conversion operations
4194514f5e3Sopenharmony_ci
4204514f5e3Sopenharmony_ci* **TRUNC**: truncates its integer operand.
4214514f5e3Sopenharmony_ci* **ZEXT**: zero extends its integer operand.
4224514f5e3Sopenharmony_ci* **SEXT**: sign extends its integer operand.
4234514f5e3Sopenharmony_ci* **SITOFP**: regards value as a signed integer and converts that value to floating-point type.
4244514f5e3Sopenharmony_ci* **UITOFP**: regards value as an unsigned integer and converts that value to floating-point type.
4254514f5e3Sopenharmony_ci* **FPTOSI**: converts a floating-point value to its signed integer equivalent.
4264514f5e3Sopenharmony_ci* **FPTOUI**: converts a floating-point value to its unsigned integer equivalent.
4274514f5e3Sopenharmony_ci* **BITCAST**: converts value to another type without changing any bits.
4284514f5e3Sopenharmony_ci
4294514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
4304514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
4314514f5e3Sopenharmony_ci| input  | []          | 0                 | [`ANYVALUE`] |
4324514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>} |
4334514f5e3Sopenharmony_ci
4344514f5e3Sopenharmony_ci| Root      | Bitfield |
4354514f5e3Sopenharmony_ci|-----------|----------|
4364514f5e3Sopenharmony_ci| not used  | not used |
4374514f5e3Sopenharmony_ci
4384514f5e3Sopenharmony_ci#### Memory operations
4394514f5e3Sopenharmony_ci
4404514f5e3Sopenharmony_ci##### Load
4414514f5e3Sopenharmony_ci
4424514f5e3Sopenharmony_ciThis instruction is used to read from memory.
4434514f5e3Sopenharmony_ci
4444514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
4454514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
4464514f5e3Sopenharmony_ci| input  | []          | 1                 | [`ARCH`]     |
4474514f5e3Sopenharmony_ci| output | {}          | any               | {<<`FLEX`>>} |
4484514f5e3Sopenharmony_ci
4494514f5e3Sopenharmony_ci| Root      | Bitfield |
4504514f5e3Sopenharmony_ci|-----------|----------|
4514514f5e3Sopenharmony_ci| not used  | not used |
4524514f5e3Sopenharmony_ci
4534514f5e3Sopenharmony_ci##### Store
4544514f5e3Sopenharmony_ci
4554514f5e3Sopenharmony_ciThis instruction is used to write to memory.
4564514f5e3Sopenharmony_ci
4574514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires           |
4584514f5e3Sopenharmony_ci|--------|-------------|-------------------|----------------------|
4594514f5e3Sopenharmony_ci| input  | []          | 1                 | [`ANYVALUE`, `ARCH`] |
4604514f5e3Sopenharmony_ci| output | {}          | any               | {}                   |
4614514f5e3Sopenharmony_ci
4624514f5e3Sopenharmony_ci| Root      | Bitfield |
4634514f5e3Sopenharmony_ci|-----------|----------|
4644514f5e3Sopenharmony_ci| not used  | not used |
4654514f5e3Sopenharmony_ci
4664514f5e3Sopenharmony_ci#### Prologue values
4674514f5e3Sopenharmony_ci
4684514f5e3Sopenharmony_ci##### ALLOCA
4694514f5e3Sopenharmony_ci
4704514f5e3Sopenharmony_ciThis instruction allocates memory on the stack frame of the currently executing function, to be automatically released when this function returns to its caller.
4714514f5e3Sopenharmony_ci
4724514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
4734514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
4744514f5e3Sopenharmony_ci| input  | []          | 0                 | []           |
4754514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`ARCH`>>} |
4764514f5e3Sopenharmony_ci
4774514f5e3Sopenharmony_ci| Root          | Bitfield                  |
4784514f5e3Sopenharmony_ci|---------------|---------------------------|
4794514f5e3Sopenharmony_ci| `ALLOCA_LIST` | number of allocated bytes |
4804514f5e3Sopenharmony_ci
4814514f5e3Sopenharmony_ci##### ARG
4824514f5e3Sopenharmony_ci
4834514f5e3Sopenharmony_ciThis instruction is used to represent an argument of the function.
4844514f5e3Sopenharmony_ci
4854514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
4864514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
4874514f5e3Sopenharmony_ci| input  | []          | 0                 | []           |
4884514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>} |
4894514f5e3Sopenharmony_ci
4904514f5e3Sopenharmony_ci| Root        | Bitfield         |
4914514f5e3Sopenharmony_ci|-------------|------------------|
4924514f5e3Sopenharmony_ci| `ARG_LIST`  | order of the arg |
4934514f5e3Sopenharmony_ci
4944514f5e3Sopenharmony_ci##### CONSTANT
4954514f5e3Sopenharmony_ci
4964514f5e3Sopenharmony_ciThis instruction directly returns a specified constant.
4974514f5e3Sopenharmony_ci
4984514f5e3Sopenharmony_ci|        | state wires | #dependency wires | data wires   |
4994514f5e3Sopenharmony_ci|--------|-------------|-------------------|--------------|
5004514f5e3Sopenharmony_ci| input  | []          | 0                 | []           |
5014514f5e3Sopenharmony_ci| output | {}          | 0                 | {<<`FLEX`>>} |
5024514f5e3Sopenharmony_ci
5034514f5e3Sopenharmony_ci| Root            | Bitfield                            |
5044514f5e3Sopenharmony_ci|-----------------|-------------------------------------|
5054514f5e3Sopenharmony_ci| `CONSTANT_LIST` | bits representation of the constant |
5064514f5e3Sopenharmony_ci
5074514f5e3Sopenharmony_ci### LIR instructions
5084514f5e3Sopenharmony_ci
5094514f5e3Sopenharmony_ciCurrently, LIR instructions are not implemented. They will be added later for JIT compilation.
510