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