1 | NIR ALU Instructions
|
---|
2 | ====================
|
---|
3 |
|
---|
4 | ALU instructions represent simple operations, such as addition, multiplication,
|
---|
5 | comparison, etc., that take a certain number of arguments and return a result
|
---|
6 | that only depends on the arguments. ALU instructions in NIR must be pure in
|
---|
7 | the sense that they have no side effect and that identical inputs yields an
|
---|
8 | identical output. A good rule of thumb is that only things which can be
|
---|
9 | constant folded should be ALU operations. If it can't be constant folded, then
|
---|
10 | it should probably be an intrinsic instead.
|
---|
11 |
|
---|
12 | Each ALU instruction has an opcode, which is a member of the :c:enum:`nir_op`
|
---|
13 | enum, that describes what it does as well as how many arguments it takes.
|
---|
14 | Associated with each opcode is an metadata structure,
|
---|
15 | :c:struct:`nir_op_info`, which shows how many arguments the opcode takes,
|
---|
16 | information about data types, and algebraic properties such as associativity
|
---|
17 | and commutativity. The info structure for each opcode may be accessed through
|
---|
18 | a global :c:var:`nir_op_infos` array that’s indexed by the opcode.
|
---|
19 |
|
---|
20 | ALU operations are typeless, meaning that they're only defined to convert
|
---|
21 | a certain bit-pattern input to another bit-pattern output. The only concrete
|
---|
22 | notion of types for a NIR SSA value or register is that each value has a number
|
---|
23 | of vector components and a bit-size. How that data is interpreted is entirely
|
---|
24 | controlled by the opcode. NIR doesn't have opcodes for ``intBitsToFloat()``
|
---|
25 | and friends because they are implicit.
|
---|
26 |
|
---|
27 | Even though ALU operations are typeless, each opcode also has an "ALU type"
|
---|
28 | metadata for each of the sources and the destination which can be
|
---|
29 | floating-point, boolean, integer, or unsigned integer. The ALU type mainly
|
---|
30 | helps back-ends which want to handle all conversion instructions, for instance,
|
---|
31 | in a single switch case. They're also important when a back-end requests the
|
---|
32 | absolute value, negate, and saturate modifiers (not used by core NIR). In that
|
---|
33 | case, modifiers are interpreted with respect to the ALU type on the source or
|
---|
34 | destination of the instruction. In addition, if an operation takes a boolean
|
---|
35 | argument, then the argument may be assumed to be either ``0`` for false or
|
---|
36 | ``~0`` (a.k.a ``-1``) for true even if it is not a 1-bit value. If an
|
---|
37 | operation’s result has a boolean type, then it may only produce only ``0`` or ``~0``.
|
---|
38 |
|
---|
39 | Most of the common ALU ops in NIR operate per-component, meaning that the
|
---|
40 | operation is defined by what it does on a single scalar value and, when
|
---|
41 | performed on vectors, it performs the same operation on each component. Things
|
---|
42 | like add, multiply, etc. fall into this category. Per-component operations
|
---|
43 | naturally scale to as many components as necessary. Non-per-component ALU ops
|
---|
44 | are things like :nir:alu-op:`vec4` or :nir:alu-op:`pack_64_2x32` where any
|
---|
45 | given component in the result value may be a combination of any component in
|
---|
46 | any source. These ops have a number of destination components and a number of
|
---|
47 | components required by each source which is fixed by the opcode.
|
---|
48 |
|
---|
49 | While most instruction types in NIR require vector sizes to perfectly match on
|
---|
50 | inputs and outputs, ALU instruction sources have an additional
|
---|
51 | :c:member:`nir_alu_src.swizzle` field which allows them to act on vectors
|
---|
52 | which are not the native vector size of the instruction. This is ideal for
|
---|
53 | hardware with a native data type of `vec4` but also means that ALU
|
---|
54 | instructions are often used (and required) for packing/unpacking vectors for
|
---|
55 | use in other instruction types like intrinsics or texture ops.
|
---|
56 |
|
---|
57 | .. c:autostruct:: nir_op_info
|
---|
58 | :file: src/compiler/nir/nir.h
|
---|
59 | :members:
|
---|
60 |
|
---|
61 | .. c:autovar:: nir_op_infos
|
---|
62 |
|
---|
63 | .. c:autostruct:: nir_alu_instr
|
---|
64 | :members:
|
---|
65 |
|
---|
66 | .. c:autostruct:: nir_alu_src
|
---|
67 | :members:
|
---|
68 |
|
---|
69 | NIR ALU Opcode Reference:
|
---|
70 | -------------------------
|
---|
71 |
|
---|
72 | .. nir:alu-opcodes::
|
---|