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