• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Circuit IR Specification
2
3## General Design
4
5Circuit 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).
6
7Circuit 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:
8
9* 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.
10
11* 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_AND` 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.
12
13In 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:
14
15* 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.
16
17* 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.
18
19* 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.
20
21Loose 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.
22
23There 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:
24
25* `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.
26
27* `STATE_ENTRY`: Representing the initial state of the sequential logic part. (for traversing forwardly from beginning to ending)
28
29* `DEPEND_ENTRY`: The origin of dependency flows of the entire circuit.
30
31* `RETURN_LIST`: Registering all terminal states of the function. (for traversing reversely from ending to beginning)
32
33* `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)
34
35The offsets of root nodes are fixed, so they can be accessed instantly via `GateRef Circuit::GetRoot()`.
36
37## Type system
38
39### Levels of types
40
41There are two levels of types of values in Circuit IR:
42
43* 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.
44
45* 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).
46
47Validation rules of primary type are already builtin for Circuit IR. Validation rules of secondary types need to be additionally provided.
48
49### Layout of type representation bits (GateType)
50
51GateType is represented by 32 bits:
52
53* The 31st bit is used to distinguish between MIR type and TS type, `0` means TS type, `1` means MIR type.
54
55* 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:
56    * `00` means GC may or may not occur (within the `GC` or `NOGC` tagged value category)
57    * `01` means GC will occur (within the `GC` tagged value category)
58    * `10` means GC will not occur (within the `NOGC` tagged value category)
59    * `11` means not within the category of tagged values (within the C++ world category)
60
61* 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`.
62
63### Type inference
64
65Primary 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.
66
67## Instructions
68
69There 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.
70
71* HIR instructions represent language-related computational process, which usually correspond to the bytecodes of specific languages.
72* 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.
73* LIR instructions are target-related, which usually correspond to the machine instructions of target architecture.
74
75### Notations
76
77* `ANY_STATE` means any state gates.
78* `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.
79* `ANYVALUE` means any one of `I1` `I8` `I16` `I32` `INT64` `F32` `F64` `ARCH`.
80* `ANYINT` means any one of `I1` `I8` `I16` `I32` `I64` `ARCH`.
81* `ANYFLOAT` means any one of `F32` `F64`.
82* `ARCH` means architecture-related integer type (`INTx` on `x` bits architecture).
83* `FLEX` means flexible primary type of output value (could be `ARCH`).
84* <<...>> means occurring any times (maybe zero)
85
86### Pure state gates
87
88#### RETURN
89
90Return a value from a non-void function.
91
92|        | state wires       | #dependency wires  | data wires   |
93|--------|-------------------|--------------------|--------------|
94| input  | [`GENERAL_STATE`] | 1                  | [`ANYVALUE`] |
95| output | {}                | 0                  | {}           |
96
97| Root          | Bitfield |
98|---------------|----------|
99| `RETURN_LIST` | not used |
100
101#### THROW
102
103Throw an exception value out of function scope.
104
105|        | state wires       | #dependency wires | data wires   |
106|--------|-------------------|-------------------|--------------|
107| input  | [`GENERAL_STATE`] | 1                 | [`ANYVALUE`] |
108| output | {}                | 0                 | {}           |
109
110| Root         | Bitfield |
111|--------------|----------|
112| `THROW_LIST` | not used |
113
114#### ORDINARY_BLOCK
115
116An ordinary state. Usually used as a placeholder. It will be eliminated by IR optimization.
117
118|        | state wires                       | #dependency wires | data wires |
119|--------|-----------------------------------|-------------------|------------|
120| input  | [`GENERAL_STATE`]                 | 0                 | []         |
121| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
122
123| Root      | Bitfield |
124|-----------|----------|
125| not used  | not used |
126
127#### IF_BRANCH
128
129This state has two possible transitions (branches) based on its input value.
130
131|        | state wires             | #dependency wires | data wires |
132|--------|-------------------------|-------------------|------------|
133| input  | [`GENERAL_STATE`]       | 0                 | [`I1`]   |
134| output | {`IF_TRUE`, `IF_FALSE`} | 0                 | {}         |
135
136| Root      | Bitfield |
137|-----------|----------|
138| not used  | not used |
139
140#### SWITCH_BRANCH
141
142This state has multiple possible transitions (branches) based on its input value.
143
144|        | state wires                         | #dependency wires | data wires   |
145|--------|-------------------------------------|-------------------|--------------|
146| input  | [`GENERAL_STATE`]                   | 0                 | [`ANYVALUE`] |
147| output | {<<`SWITCH_CASE`>>, `DEFAULT_CASE`} | 0                 | {}           |
148
149| Root      | Bitfield |
150|-----------|----------|
151| not used  | not used |
152
153#### IF_TRUE | IF_FALSE
154
155Successor states of `IF_BRANCH`.
156
157|        | state wires                       | #dependency wires | data wires |
158|--------|-----------------------------------|-------------------|------------|
159| input  | [`IF_BRANCH`]                     | 0                 | []         |
160| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
161
162| Root      | Bitfield |
163|-----------|----------|
164| not used  | not used |
165
166#### IF_SUCCESS | IF_EXCEPTION
167
168Successor states of instructions (usually HIR) that may throw an exception.
169
170|        | state wires                       | #dependency wires | data wires |
171|--------|-----------------------------------|-------------------|------------|
172| input  | [`ANY_STATE`]                     | 0                 | []         |
173| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
174
175| Root      | Bitfield |
176|-----------|----------|
177| not used  | not used |
178
179#### SWITCH_CASE | DEFAULT_CASE
180
181Successor state of `SWITCH_BRANCH`.
182
183|        | state wires                       | #dependency wires | data wires |
184|--------|-----------------------------------|-------------------|------------|
185| input  | [`SWITCH_BRANCH`]                 | 0                 | []         |
186| output | {`ANY_STATE`, <<`DEPEND_RELAY`>>} | 0                 | {}         |
187
188| Root      | Bitfield                                                               |
189|-----------|------------------------------------------------------------------------|
190| not used  | represent case value for `SWITCH_CASE` and not used for `DEFAULT_CASE` |
191
192#### MERGE
193
194State that have multiple possible predicate states.
195
196|        | state wires                                                | #dependency wires | data wires |
197|--------|------------------------------------------------------------|-------------------|------------|
198| input  | [<<`GENERAL_STATE`>>(N)]                                   | 0                 | []         |
199| output | {`ANY_STATE`, <<`DEPEND_SELECTOR`>>, <<`VALUE_SELECTOR`>>} | 0                 | {}         |
200
201| Root      | Bitfield                   |
202|-----------|----------------------------|
203| not used  | number of state inputs (N) |
204
205#### LOOP_BEGIN
206
207Represents loop begin.
208
209|        | state wires                                                | #dependency wires | data wires |
210|--------|------------------------------------------------------------|-------------------|------------|
211| input  | [`GENERAL_STATE`, `LOOP_BACK`]                             | 0                 | []         |
212| output | {`ANY_STATE`, <<`DEPEND_SELECTOR`>>, <<`VALUE_SELECTOR`>>} | 0                 | {}         |
213
214| Root      | Bitfield |
215|-----------|----------|
216| not used  | not used |
217
218#### LOOP_BACK
219
220Represents loop back.
221
222|        | state wires       | #dependency wires | data wires |
223|--------|-------------------|-------------------|------------|
224| input  | [`GENERAL_STATE`] | 0                 | []         |
225| output | {`LOOP_BEGIN`}    | 0                 | {}         |
226
227| Root      | Bitfield |
228|-----------|----------|
229| not used  | not used |
230
231### Intermediate gates and auxiliary gates
232
233Intermediate 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.
234
235#### VALUE_SELECTOR
236
237Represents value selector.
238
239|        | state wires               | #dependency wires | data wires      |
240|--------|---------------------------|-------------------|-----------------|
241| input  | [`MERGE` or `LOOP_BEGIN`] | 0                 | [<<`FLEX`>>(N)] |
242| output | {}                        | 0                 | {<<`FLEX`>>}    |
243
244| Root     | Bitfield                  |
245|----------|---------------------------|
246| not used | number of data inputs (N) |
247
248#### DEPEND_SELECTOR
249
250Represents dependency selector.
251
252|        | state wires               | #dependency wires | data wires |
253|--------|---------------------------|-------------------|------------|
254| input  | [`MERGE` or `LOOP_BEGIN`] | N                 | []         |
255| output | {}                        | any               | {}         |
256
257| Root     | Bitfield                        |
258|----------|---------------------------------|
259| not used | number of dependency inputs (N) |
260
261#### DEPEND_RELAY
262
263Represents dependency relay.
264
265|        | state wires                                                                                                        | #dependency wires | data wires |
266|--------|--------------------------------------------------------------------------------------------------------------------|-------------------|------------|
267| input  | [`IF_TRUE` or `IF_FALSE` or `IF_SUCCESS` or `IF_EXCEPTION` or `SWITCH_CASE` or `DEFAULT_CASE` or `ORDINARY_BLOCK`] | 1                 | []         |
268| output | {}                                                                                                                 | any               | {}         |
269
270| Root      | Bitfield |
271|-----------|----------|
272| not used  | not used |
273
274#### DEPEND_AND
275
276Represents dependency and operator.
277
278|        | state wires | #dependency wires | data wires |
279|--------|-------------|-------------------|------------|
280| input  | []          | N                 | []         |
281| output | {}          | any               | {}         |
282
283| Root     | Bitfield                        |
284|----------|---------------------------------|
285| not used | number of dependency inputs (N) |
286
287### HIR instructions
288
289#### JS_BYTECODE
290
291Represents JavaScript bytecode.
292
293|        | state wires                    | #dependency wires | data wires       |
294|--------|--------------------------------|-------------------|------------------|
295| input  | [`GENERAL_STATE`]              | 1                 | [<<`I64`>>(N)] |
296| output | {`IF_SUCCESS`, `IF_EXCEPTION`} | any               | {<<`I64`>>}    |
297
298| Root     | Bitfield                   |
299|----------|----------------------------|
300| not used | number of value inputs (N) |
301
302### MIR instructions
303
304#### Special instructions
305
306##### CALL
307
308Represents a simple function call (would not get an exception).
309
310|        | state wires | #dependency wires | data wires                  |
311|--------|-------------|-------------------|-----------------------------|
312| input  | []          | 1                 | [`ARCH`, <<`ANYVALUE`>>(N)] |
313| output | {}          | any               | {<<`FLEX`>>}                |
314
315| Root      | Bitfield                    |
316|-----------|-----------------------------|
317| not used  | number of function args (N) |
318
319#### Floating point unary arithmetic operations
320
321* **FNEG**: returns the negation of its floating-point operand.
322
323|        | state wires | #dependency wires | data wires   |
324|--------|-------------|-------------------|--------------|
325| input  | []          | 0                 | [`FLEX`]     |
326| output | {}          | 0                 | {<<`FLEX`>>} |
327
328| Root      | Bitfield |
329|-----------|----------|
330| not used  | not used |
331
332#### Integer binary arithmetic operations
333
334* **ADD**: returns the sum of its two integer operands.
335* **SUB**: returns the difference of its two integer operands. It is used to implement the "-" unary operation.
336* **MUL**: returns the product of its two integer operands.
337* **EXP**: returns the first integer operand raised to the power of the second integer operand.
338* **SDIV**: returns the signed quotient of its two integer operands.
339* **SREM**: returns the remainder from the signed division of its two integer operands.
340* **UDIV**: returns the unsigned quotient of its two integer operands.
341* **UREM**: returns the remainder from the unsigned division of its two integer operands.
342* **AND**: returns the bitwise logical and of its two operands.
343* **XOR**: returns the bitwise logical exclusive or of its two operands. It is used to implement the "~" unary operation.
344* **OR**: returns the bitwise logical inclusive or of its two operands.
345* **SHL**: returns the first integer operand shifted to the left a specified number of bits.
346* **LSHR**: returns the first integer operand shifted to the right a specified number of bits with zero fill.
347* **ASHR**: returns the first integer operand shifted to the right a specified number of bits with sign extension.
348
349|        | state wires | #dependency wires | data wires       |
350|--------|-------------|-------------------|------------------|
351| input  | []          | 0                 | [`FLEX`, `FLEX`] |
352| output | {}          | 0                 | {<<`FLEX`>>}     |
353
354| Root      | Bitfield |
355|-----------|----------|
356| not used  | not used |
357
358#### Floating-point binary arithmetic operations
359
360* **FADD**: returns the sum of its two floating-point operands.
361* **FSUB**: returns the difference of its two floating-point operands.
362* **FMUL**: returns the product of its two floating-point operands.
363* **FEXP**: returns the first floating-point operand raised to the power of the second floating-point operand.
364* **FDIV**: returns the quotient of its two floating-point operands.
365* **FMOD**: returns the remainder from the division of its two floating-point operands.
366
367|        | state wires | #dependency wires | data wires       |
368|--------|-------------|-------------------|------------------|
369| input  | []          | 0                 | [`FLEX`, `FLEX`] |
370| output | {}          | 0                 | {<<`FLEX`>>}     |
371
372| Root      | Bitfield |
373|-----------|----------|
374| not used  | not used |
375
376#### Integer binary compare operations
377
378* **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:
379  * `0001` `EQ`: yields true if the operands are equal, false otherwise. No sign interpretation is necessary or performed.
380  * `0010` `UGT`: interprets the operands as unsigned values and yields true if op1 is greater than op2.
381  * `0011` `UGE`: interprets the operands as unsigned values and yields true if op1 is greater than or equal to op2.
382  * `0100` `ULT`: interprets the operands as unsigned values and yields true if op1 is less than op2.
383  * `0101` `ULE`: interprets the operands as unsigned values and yields true if op1 is less than or equal to op2.
384  * `0110` `NE`: yields true if the operands are unequal, false otherwise. No sign interpretation is necessary or performed.
385  * `1010` `SGT`: interprets the operands as signed values and yields true if op1 is greater than op2.
386  * `1011` `SGE`: interprets the operands as signed values and yields true if op1 is greater than or equal to op2.
387  * `1100` `SLT`: interprets the operands as signed values and yields true if op1 is less than op2.
388  * `1101` `SLE`: interprets the operands as signed values and yields true if op1 is less than or equal to op2.
389
390|        | state wires | #dependency wires | data wires               |
391|--------|-------------|-------------------|--------------------------|
392| input  | []          | 0                 | [`ANYVALUE`, `ANYVALUE`] |
393| output | {}          | 0                 | {<<`I1`>>}             |
394
395| Root      | Bitfield       |
396|-----------|----------------|
397| not used  | condition code |
398
399#### Floating-point binary compare operations
400
401Note: **ordered** means there is no NaN in the operands.
402
403* **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:
404  * `0000` `FALSE`: always returns false (no comparison)
405  * `0001` `OEQ`: ordered and equal
406  * `0010` `OGT`: ordered and greater than
407  * `0011` `OGE`: ordered and greater than or equal
408  * `0100` `OLT`: ordered and less than
409  * `0101` `OLE`: ordered and less than or equal
410  * `0110` `ONE`: ordered and not equal
411  * `0111` `ORD`: ordered (no nans)
412  * `1000` `UNO`: unordered (either nans)
413  * `1001` `UEQ`: unordered or equal
414  * `1010` `UGT`: unordered or greater than
415  * `1011` `UGE`: unordered or greater than or equal
416  * `1100` `ULT`: unordered or less than
417  * `1101` `ULE`: unordered or less than or equal
418  * `1110` `UNE`: unordered or not equal
419  * `1111` `TRUE`: always returns true (no comparison)
420
421
422|        | state wires | #dependency wires | data wires               |
423|--------|-------------|-------------------|--------------------------|
424| input  | []          | 0                 | [`ANYVALUE`, `ANYVALUE`] |
425| output | {}          | 0                 | {<<`I1`>>}             |
426
427| Root      | Bitfield       |
428|-----------|----------------|
429| not used  | condition code |
430
431#### Conversion operations
432
433* **TRUNC**: truncates its integer operand.
434* **ZEXT**: zero extends its integer operand.
435* **SEXT**: sign extends its integer operand.
436* **SITOFP**: regards value as a signed integer and converts that value to floating-point type.
437* **UITOFP**: regards value as an unsigned integer and converts that value to floating-point type.
438* **FPTOSI**: converts a floating-point value to its signed integer equivalent.
439* **FPTOUI**: converts a floating-point value to its unsigned integer equivalent.
440* **BITCAST**: converts value to another type without changing any bits.
441
442|        | state wires | #dependency wires | data wires   |
443|--------|-------------|-------------------|--------------|
444| input  | []          | 0                 | [`ANYVALUE`] |
445| output | {}          | 0                 | {<<`FLEX`>>} |
446
447| Root      | Bitfield |
448|-----------|----------|
449| not used  | not used |
450
451#### Memory operations
452
453##### Load
454
455This instruction is used to read from memory.
456
457|        | state wires | #dependency wires | data wires   |
458|--------|-------------|-------------------|--------------|
459| input  | []          | 1                 | [`ARCH`]     |
460| output | {}          | any               | {<<`FLEX`>>} |
461
462| Root      | Bitfield |
463|-----------|----------|
464| not used  | not used |
465
466##### Store
467
468This instruction is used to write to memory.
469
470|        | state wires | #dependency wires | data wires           |
471|--------|-------------|-------------------|----------------------|
472| input  | []          | 1                 | [`ANYVALUE`, `ARCH`] |
473| output | {}          | any               | {}                   |
474
475| Root      | Bitfield |
476|-----------|----------|
477| not used  | not used |
478
479#### Prologue values
480
481##### ALLOCA
482
483This instruction allocates memory on the stack frame of the currently executing function, to be automatically released when this function returns to its caller.
484
485|        | state wires | #dependency wires | data wires   |
486|--------|-------------|-------------------|--------------|
487| input  | []          | 0                 | []           |
488| output | {}          | 0                 | {<<`ARCH`>>} |
489
490| Root          | Bitfield                  |
491|---------------|---------------------------|
492| `ALLOCA_LIST` | number of allocated bytes |
493
494##### ARG
495
496This instruction is used to represent an argument of the function.
497
498|        | state wires | #dependency wires | data wires   |
499|--------|-------------|-------------------|--------------|
500| input  | []          | 0                 | []           |
501| output | {}          | 0                 | {<<`FLEX`>>} |
502
503| Root        | Bitfield         |
504|-------------|------------------|
505| `ARG_LIST`  | order of the arg |
506
507##### CONSTANT
508
509This instruction directly returns a specified constant.
510
511|        | state wires | #dependency wires | data wires   |
512|--------|-------------|-------------------|--------------|
513| input  | []          | 0                 | []           |
514| output | {}          | 0                 | {<<`FLEX`>>} |
515
516| Root            | Bitfield                            |
517|-----------------|-------------------------------------|
518| `CONSTANT_LIST` | bits representation of the constant |
519
520### LIR instructions
521
522Currently, LIR instructions are not implemented. They will be added later for JIT compilation.
523