| <!-- |
| Copyright (C) 2021 Collabora Ltd. |
| |
| Permission is hereby granted, free of charge, to any person obtaining a |
| copy of this software and associated documentation files (the "Software"), |
| to deal in the Software without restriction, including without limitation |
| the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| and/or sell copies of the Software, and to permit persons to whom the |
| Software is furnished to do so, subject to the following conditions: |
| |
| The above copyright notice and this permission notice (including the next |
| paragraph) shall be included in all copies or substantial portions of the |
| Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| SOFTWARE. |
| --> |
| |
| <valhall> |
| <lut name="Immediates"> |
| <desc> |
| This immediates are accessible in (almost) any instruction, provided the |
| immediate mode is kept to the default. They optimize for the most common |
| immediate values; any immediate listed here may be used without taking up |
| a uniform slot or a register. Most integer instructions can access |
| separate half-words and individual bytes via swizzles on the source. |
| </desc> |
| <constant desc="Zero">0x00000000</constant> |
| <constant desc="All ones; integer $-1$">0xFFFFFFFF</constant> |
| <constant desc="Maximum integer; floating-point NaN">0x7FFFFFFF</constant> |
| <constant desc="Integers $(-2, -3, -4, -6)$">0xFAFCFDFE</constant> |
| <constant desc="16-bit integer $2^8$">0x01000000</constant> |
| <constant desc="Multiples of 16 $(0, 32, 0, 128)$">0x80002000</constant> |
| <constant desc="Multiples of 16 $(48, 80, 96, 112)$">0x70605030</constant> |
| <constant desc="Multiples of 16 $(144, 160, 176, 192)$">0xC0B0A090</constant> |
| <constant desc="Integers $(0, 1, 2, 3)$">0x03020100</constant> |
| <constant desc="Integers $(4, 5, 6, 7)$">0x07060504</constant> |
| <constant desc="Integers $(8, 9, 10, 11)$">0x0B0A0908</constant> |
| <constant desc="Integers $(12, 13, 14, 15)$">0x0F0E0D0C</constant> |
| <constant desc="Integers $(16, 17, 18, 19)$">0x13121110</constant> |
| <constant desc="Integers $(20, 21, 22, 23)$">0x17161514</constant> |
| <constant desc="Integers $(24, 25, 26, 27)$">0x1B1A1918</constant> |
| <constant desc="Integers $(28, 29, 30, 31)$">0x1F1E1D1C</constant> |
| <constant desc="Float $1.0$">0x3F800000</constant> |
| <constant desc="Float $0.1$">0x3DCCCCCD</constant> |
| <constant desc="Float $1 / \pi$">0x3EA2F983</constant> |
| <constant desc="Float $\log(2)$">0x3F317218</constant> |
| <constant desc="Float $\pi$">0x40490FDB</constant> |
| <constant desc="Float $0.0$">0x00000000</constant> |
| <constant desc="Float $65535.0 = 2^{16} - 1$">0x477FFF00</constant> |
| <constant desc="Half-float $(255.0, 256.0) = (2^8 - 1, 2^8)$">0x5C005BF8</constant> |
| <constant desc="Half-float $0.1 = 1 / 10$">0x2E660000</constant> |
| <constant desc="Half-float $0.25 = 2^{-2}$">0x34000000</constant> |
| <constant desc="Half-float $0.5 = 2^{-1}$">0x38000000</constant> |
| <constant desc="Half-float $1.0 = 2^0$">0x3C000000</constant> |
| <constant desc="Half-float $2.0 = 2^1$">0x40000000</constant> |
| <constant desc="Half-float $4.0 = 2^2$">0x44000000</constant> |
| <constant desc="Half-float $8.0 = 2^3$">0x48000000</constant> |
| <constant desc="Half-float $\pi$">0x42480000</constant> |
| </lut> |
| |
| <enum name="Flow"> |
| <desc> |
| Every Valhall instruction can wait on dependency |
| slots. A few special flows are available, specified in the instruction |
| metadata from this enum. The `wait0126` flow is required to wait on |
| dependency slot #6 and should be set on the instruction immediately |
| preceding `ATEST`. The `wait` flow should be set for barriers. |
| The `discard` flow only applies to fragment shaders and is used to |
| terminate helper invocations, it should be set as early as possible after |
| helper invocations are no longer needed as determined by data flow |
| analysis. The `end` flow is used to terminate the shader, although it |
| may be overloaded by the `BLEND` instruction. |
| |
| The `reconverge` flow is required on any instruction immediately |
| preceding a possible change to the mask of active threads in a subgroup. |
| This includes all divergent branches, but it also includes the final |
| instruction at the end of any basic block where the immediate successor |
| (fallthrough) is the target of a divergent branch. |
| </desc> |
| <value name="None" default="true">none</value> |
| <value name="Wait on slot 0">wait0</value> |
| <value name="Wait on slot 1">wait1</value> |
| <value name="Wait on slots 0, 1">wait01</value> |
| <value name="Wait on slot 2">wait2</value> |
| <value name="Wait on slots 0, 2">wait02</value> |
| <value name="Wait on slots 1, 2">wait12</value> |
| <value name="Wait on slots 0, 1, 2">wait012</value> |
| <value name="Wait on slots 0, 1, 2, 6">wait0126</value> |
| <value name="Wait on slots 0, 1, 2, 6, 7">wait</value> |
| <value name="Perform branch reconverge">reconverge</value> |
| <reserved/> |
| <reserved/> |
| <value name="Terminate discarded threads">discard</value> |
| <reserved/> |
| <value name="Return from shader">end</value> |
| </enum> |
| |
| <enum name="FAU special page 0"> |
| <desc> |
| Situated between the immediates hard-coded in the hardware and the |
| uniforms defined purely in software, Valhall has a some special |
| "constants" passing through data structures. These are encoded like the |
| table of immediates, as if special constant $i$ were lookup table entry |
| $32 + i$. |
| </desc> |
| <reserved/> |
| <reserved/> |
| <value desc="Warp ID and warps/core - 1">warp_id</value> |
| <reserved/> |
| <value desc="Bounding box maximum X/Y">framebuffer_size</value> |
| <value desc="ATEST datum">atest_datum</value> |
| <value desc="Sample positions">sample</value> |
| <reserved/> |
| <value desc="Blend descriptor 0">blend_descriptor_0</value> |
| <value desc="Blend descriptor 1">blend_descriptor_1</value> |
| <value desc="Blend descriptor 2">blend_descriptor_2</value> |
| <value desc="Blend descriptor 3">blend_descriptor_3</value> |
| <value desc="Blend descriptor 4">blend_descriptor_4</value> |
| <value desc="Blend descriptor 5">blend_descriptor_5</value> |
| <value desc="Blend descriptor 6">blend_descriptor_6</value> |
| <value desc="Blend descriptor 7">blend_descriptor_7</value> |
| </enum> |
| |
| <enum name="FAU special page 1"> |
| <desc> |
| Situated between the immediates hard-coded in the hardware and the |
| uniforms defined purely in software, Valhall has a some special |
| "constants" passing through data structures. These are encoded like the |
| table of immediates, as if special constant $i$ were lookup table entry |
| $32 + i$. |
| </desc> |
| <reserved/> |
| <value desc="Thread local storage base pointer">thread_local_pointer</value> |
| <reserved/> |
| <value desc="Workgroup local storage base pointer">workgroup_local_pointer</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value desc="Shader resource table base pointer">resource_table_pointer</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="FAU special page 3"> |
| <desc> |
| Situated between the immediates hard-coded in the hardware and the |
| uniforms defined purely in software, Valhall has a some special |
| "constants" passing through data structures. These are encoded like the |
| table of immediates, as if special constant $i$ were lookup table entry |
| $32 + i$. |
| </desc> |
| <reserved/> |
| <value desc="Lane ID">lane_id</value> |
| <reserved/> |
| <value desc="Core ID">core_id</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value desc="Program counter">program_counter</value> |
| </enum> |
| |
| <enum name="Swizzles (8-bit)"> |
| <value default="true">b0123</value> |
| <value>b3210</value> |
| <value>b0101</value> |
| <value>b2323</value> |
| <value>b0000</value> |
| <value>b1111</value> |
| <value>b2222</value> |
| <value>b3333</value> |
| <value>b2301</value> |
| <value>b1032</value> |
| <value>b0011</value> |
| <value>b2233</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Lanes (8-bit)"> |
| <desc>Used to select the 2 bytes for shifts of 16-bit vectors</desc> |
| <value>b02</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value>b00</value> |
| <value>b11</value> |
| <value>b22</value> |
| <value>b33</value> |
| <reserved/> |
| <reserved/> |
| <value>b01</value> |
| <value>b23</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Half-swizzles (8-bit)"> |
| <desc> |
| Used to select the 2 bytes to convert for conversions from 8-bit vectors |
| to 16-bit vectors |
| </desc> |
| <value>b00</value> |
| <value>b10</value> |
| <value>b20</value> |
| <value>b30</value> |
| <value>b01</value> |
| <value>b11</value> |
| <value>b21</value> |
| <value>b31</value> |
| <value>b02</value> |
| <value>b12</value> |
| <value>b22</value> |
| <value>b32</value> |
| <value>b03</value> |
| <value>b13</value> |
| <value>b23</value> |
| <value>b33</value> |
| </enum> |
| |
| <enum name="Swizzles (16-bit)"> |
| <value>h00</value> <!-- 0,2 --> |
| <value>h10</value> |
| <value default="true">h01</value> |
| <value>h11</value> |
| <value>b00</value> <!-- 0,0 --> |
| <value>b20</value> <!-- 1,1 --> |
| <value>b02</value> <!-- 2,2 --> |
| <value>b22</value> <!-- 3,3 --> |
| <value>b11</value> |
| <value>b31</value> |
| <value>b13</value> <!-- 0,1 --> |
| <value>b33</value> <!-- 2,3 --> |
| <value>b01</value> |
| <value>b23</value> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Swizzles (32-bit)"> |
| <value default="true">none</value> |
| <reserved/> |
| <value>h0</value> |
| <value>h1</value> |
| <value>b0</value> |
| <value>b1</value> |
| <value>b2</value> |
| <value>b3</value> |
| </enum> |
| |
| <enum name="Swizzles (64-bit)"> |
| <value default="true">none</value> |
| <reserved/> |
| <value>h0</value> |
| <value>h1</value> |
| <value>b0</value> |
| <value>b1</value> |
| <value>b2</value> |
| <value>b3</value> |
| <value>w0</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Lane (8-bit)" implied="true"> |
| <value>b0</value> |
| <value>b1</value> |
| <value>b2</value> |
| <value>b3</value> |
| </enum> |
| |
| <enum name="Combine"> |
| <desc> |
| Used for the lane select of `BRANCHZ`. To use an 8-bit condition, a |
| separate `ICMP` is required to cast to 16-bit. |
| </desc> |
| <value default="true">none</value> |
| <value>h0</value> |
| <value>h1</value> |
| <value>and</value> |
| <value>lowbits</value> |
| </enum> |
| |
| <enum name="Lane (16-bit)" implied="true"> |
| <value>h0</value> |
| <value>h1</value> |
| </enum> |
| |
| <enum name="Load lane (8-bit)"> |
| <value default="true">b0</value> |
| <value>b1</value> |
| <value>b2</value> |
| <value>b3</value> |
| <value desc="Zero-extend to 16-bit, low-half">h0</value> |
| <value desc="Zero-extend to 16-bit, high-half">h1</value> |
| <value desc="Zero-extend to 32-bit">w0</value> |
| <value desc="Zero-extend to 64-bit">d0</value> |
| </enum> |
| |
| <enum name="Load lane (16-bit)"> |
| <value desc="Low half" default="true">h0</value> |
| <value desc="High half">h1</value> |
| <value desc="Zero-extend to 32-bit">w0</value> |
| <value desc="Zero-extend to 64-bit">d0</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Load lane (24-bit)" implied="true"> |
| <value default="true">identity</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Load lane (32-bit)"> |
| <value default="true">w0</value> |
| <value desc="Zero-extend to 64-bit">d0</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Load lane (48-bit)"> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value default="true">identity</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Load lane (64-bit)"> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value default="true">identity</value> |
| </enum> |
| |
| <enum name="Load lane (96-bit)"> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value default="true">identity</value> |
| <reserved/> |
| </enum> |
| |
| <enum name="Load lane (128-bit)"> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value default="true">identity</value> |
| </enum> |
| |
| <enum name="Round mode"> |
| <desc>Corresponds to IEEE 754 rounding modes</desc> |
| <value desc="Round to nearest even" default="true">rte</value> |
| <value desc="Round to positive infinity">rtp</value> |
| <value desc="Round to negative infinity">rtn</value> |
| <value desc="Round to zero">rtz</value> |
| </enum> |
| |
| <enum name="Result type"> |
| <desc> |
| Comparison instructions like `FCMP` return a boolean but may encode this |
| boolean in a variety of ways. `i1` gives a OpenGL style `0/1` boolean. |
| `m1` gives a Direct3D style `0/~0` boolean. `f1` gives a floating-point |
| `0.0f / 1.0f` boolean. Switching between these modes is useful to fold a |
| boolean type convert into a comparison. `u1` is used internally to |
| implement 64-bit comparisons. |
| </desc> |
| <value desc="Integer 1">i1</value> |
| <value desc="Float 1">f1</value> |
| <value desc="Minus 1">m1</value> |
| <value desc="Low half of 64-bit compare">u1</value> |
| </enum> |
| |
| <enum name="Widen"> |
| <value default="true">none</value> |
| <value>h0</value> |
| <value>h1</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| </enum> |
| |
| <enum name="Clamp"> |
| <desc> |
| Clamp applied to the destination of a floating-point instruction. Note the |
| clamps may be decomposed as two independent bits for `clamp_0_inf` and |
| `clamp_m1_1`, with `clamp_0_1` arising as the composition of `clamp_0_inf` |
| and `clamp_m1_1` in either order. |
| |
| Clamps are implemented per the SPIR-V specification: |
| |
| $$\text{clamp} \; (x, \ell, h) = \min( \max( x, \ell ), h)$$ |
| |
| The min/max functions return the other operand if one operand is NaN, and |
| compare $-0 < +0$. That means the following identities hold for Valhall |
| clamps: |
| |
| \begin{align*} |
| \text{clamp}(-0.0, 0.0, 1.0) & = +0.0 \\ |
| \text{clamp}(-\text{NaN}, 0.0, 1.0) & = +0.0 \\ |
| \text{clamp}(\text{NaN}, 0.0, 1.0) & = +0.0 \\ |
| & \\ |
| \text{clamp}(-0.0, -1.0, 1.0) & = -0.0 \\ |
| \text{clamp}(\text{NaN}, -1.0, 1.0) & = -1.0 \\ |
| \text{clamp}(-\text{NaN}, -1.0, 1.0) & = -1.0 \\ |
| & \\ |
| \max(\text{NaN}, 0.0) & = +0.0 \\ |
| \max(-\text{NaN}, 0.0) & = +0.0 \\ |
| \max(-0.0, 0.0) & = +0.0 \\ |
| \end{align*} |
| |
| This behaviour is consistent with the FMin/FMax/FClamp and |
| NMin/NMax/NClamp rules prescribed by SPIR-V and governed by IEEE-754. As |
| a consequence, substituting these clamps for equivalent minimum/maximum |
| exprssions is legal even with strict floating point rules. |
| </desc> |
| <value default="true" desc="Identity">none</value> |
| <value desc="Clamp positive">clamp_0_inf</value> |
| <value desc="Clamp to $[-1, 1]$">clamp_m1_1</value> |
| <value desc="Clamp to $[0, 1]$">clamp_0_1</value> |
| </enum> |
| |
| <enum name="Condition"> |
| <desc> |
| Condition code. Type must be inferred from the instruction. IEEE 754 total |
| ordering only applies to floating point compares. "Not equal" and "greater |
| than or less than" are distinguished by NaN behaviour conforming to |
| the IEEE 754 specification. |
| </desc> |
| <value desc="Equal">eq</value> |
| <value desc="Greater than">gt</value> |
| <value desc="Greater than or equal">ge</value> |
| <value desc="Not equal">ne</value> |
| <value desc="Less than">lt</value> |
| <value desc="Less than or equal">le</value> |
| <value desc="Greater than or less than">gtlt</value> |
| <value desc="Totally ordered">total</value> |
| </enum> |
| |
| <enum name="Dimension"> |
| <desc>Texture dimension.</desc> |
| <value desc="1D or buffer">1d</value> |
| <value desc="2D or 2D array">2d</value> |
| <value desc="3D or 3D array">3d</value> |
| <value desc="Cube map or cube map array">cube</value> |
| </enum> |
| |
| <enum name="LOD mode"> |
| <desc>Level-of-detail selection mode in a texture instruction.</desc> |
| <value desc="Set to zero">zero</value> |
| <value desc="Computed based on neighboring fragments">computed</value> |
| <reserved/> |
| <reserved/> |
| <value desc="Explicitly specified in a register">explicit</value> |
| <value desc="Computed based on neighboring fragments added with bias in a register">computed_bias</value> |
| <value desc="Derived from a gradient descriptor in registers">grdesc</value> |
| <reserved/> |
| </enum> |
| |
| <enum name="Register format"> |
| <desc>Format of data loaded to / stored from registers for general memory access.</desc> |
| <value desc="32-bit type based on descriptor format">auto</value> |
| <reserved/> |
| <value desc="32-bit floats">f32</value> |
| <value desc="16-bit floats">f16</value> |
| <value desc="32-bit signed integers">s32</value> |
| <value desc="16-bit signed integers">s16</value> |
| <value desc="32-bit unsigned integers">u32</value> |
| <value desc="16-bit unsigned integers">u16</value> |
| </enum> |
| |
| <enum name="Staging register count" implied="true"> |
| <value>sr0</value> |
| <value>sr1</value> |
| <value>sr2</value> |
| <value>sr3</value> |
| <value>sr4</value> |
| <value>sr5</value> |
| <value>sr6</value> |
| <value>sr7</value> |
| </enum> |
| |
| <enum name="Staging register write count" implied="true"> |
| <value>write1</value> |
| <value>write2</value> |
| <value>write3</value> |
| <value>write4</value> |
| <value>write5</value> |
| <value>write6</value> |
| <value>write7</value> |
| <value>write8</value> |
| </enum> |
| |
| <enum name="Write mask"> |
| <reserved/> |
| <value>r</value> |
| <value>g</value> |
| <value>rg</value> |
| <value>b</value> |
| <value>rb</value> |
| <value>gb</value> |
| <value>rgb</value> |
| <value>a</value> |
| <value>ra</value> |
| <value>ga</value> |
| <value>rga</value> |
| <value>ba</value> |
| <value>rba</value> |
| <value>gba</value> |
| <value default="true">rgba</value> |
| </enum> |
| |
| <enum name="Fetch component"> |
| <value desc="Red">gather4_r</value> |
| <value desc="Green">gather4_g</value> |
| <value desc="Blue">gather4_b</value> |
| <value desc="Alpha">gather4_a</value> |
| </enum> |
| |
| <enum name="Register type"> |
| <desc>Unsized type, part of a register format.</desc> |
| <reserved/> |
| <value name="Float">f</value> |
| <value name="Unsigned">u</value> |
| <value name="Signed">s</value> |
| </enum> |
| |
| <enum name="Register width"> |
| <desc>Untyped size, part of a register format.</desc> |
| <value>16</value> |
| <value>32</value> |
| </enum> |
| |
| <enum name="Varying texture register width"> |
| <desc> |
| Size of results for varying texture instructions. For dual 16-bit results |
| use "16-bit". |
| </desc> |
| <value desc="16-bit">16</value> |
| <value desc="32-bit">32</value> |
| <value desc="16-bit, 32-bit">16.32</value> |
| <value desc="32-bit, 32-bit">32.32</value> |
| </enum> |
| |
| <enum name="Vector size"> |
| <desc>Number of channels loaded/stored for general memory access.</desc> |
| <value default="true" desc="Scalar">none</value> |
| <value desc="2 channels">v2</value> |
| <value desc="3 channels">v3</value> |
| <value desc="4 channels">v4</value> |
| </enum> |
| |
| <enum name="Slot"> |
| <desc> |
| Dependency slot set on a message-passing instruction that writes to |
| registers. Before reading the destination, a future instruction must wait |
| on the specified slot. Slot #7 is for `BARRIER` instructions only. |
| </desc> |
| <value desc="Slot #0">slot0</value> |
| <value desc="Slot #1">slot1</value> |
| <value desc="Slot #2">slot2</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value desc="Slot #7">slot7</value> |
| </enum> |
| |
| <enum name="Memory access"> |
| <desc>Memory access hint for a `LOAD` or `STORE` instruction.</desc> |
| <value desc="No hint (global)" default="true">none</value> |
| <value desc="Internally streaming (position output)">istream</value> |
| <value desc="Externally streaming (varying output)">estream</value> |
| <value desc="Force access in discarded threads (thread local storage)">force</value> |
| </enum> |
| |
| <enum name="Subgroup size"> |
| <desc> |
| Selects the effective subgroup size from subgroup operations. The hardware |
| warps are sixteen threads on Valhall, but subdividing a warp may be useful |
| for API requirements. In particular, derivatives may be calculated with |
| quads (four threads). |
| </desc> |
| <value desc="Two threads">subgroup2</value> |
| <value desc="Four threads">subgroup4</value> |
| <value desc="Eight threads">subgroup8</value> |
| <value desc="Sixteen threads" default="true">subgroup16</value> |
| </enum> |
| |
| <enum name="Lane operation"> |
| <desc> |
| Acts as a modifier on the lane specificier for a `CLPER` instruction. The |
| `accumulate` mode is required for efficient subgroup reductions. |
| </desc> |
| <value name="No operation" default="true">none</value> |
| <value name="Exclusive-or">xor</value> |
| <value name="Accumulate">accumulate</value> |
| <value name="Shift">shift</value> |
| </enum> |
| |
| <enum name="Inactive result"> |
| <desc> |
| Accesses to inactive lanes (due to divergence) in a subgroup is generally |
| undefined in APIs. However, the results of permuting with an inactive lane |
| with `CLPER.i32` are well-defined in Valhall: they return one of the |
| following values, as specified in the `CLPER.i32` instructions. Sometimes |
| certain values enable small optimizations. |
| </desc> |
| <value name="0x00000000" default="true">zero</value> |
| <value name="0xFFFFFFFF">umax</value> |
| <value name="0x00000001">i1</value> |
| <value name="0x00010001">v2i1</value> |
| <value name="0x80000000">smin</value> |
| <value name="0x7FFFFFFF">smax</value> |
| <value name="0x80008000">v2smin</value> |
| <value name="0x7FFF7FFF">v2smax</value> |
| <value name="0x80808080">v4smin</value> |
| <value name="0x7F7F7F7F">v4smax</value> |
| <value name="0x3F800000">f1</value> |
| <value name="0x3C003C00">v2f1</value> |
| <value name="0xFF800000">infn</value> |
| <value name="0x7F800000">inf</value> |
| <value name="0xFC00FC00">v2infn</value> |
| <value name="0x7C007C00">v2inf</value> |
| </enum> |
| |
| <enum name="Mux"> |
| <desc> |
| Condition to use for a `MUX` instruction. `neg` checks the sign bit, |
| `int_zero` compares to `0x00000000`, `fp_zero` compares to $\pm 0.0$ as |
| an IEEE 754 float, and `bit` checks each bit separately. The `bit` mode |
| acts like an imaginary `CSEL.v32u1` instruction, and implements |
| `bitselect()` in OpenCL. |
| </desc> |
| <value desc="Negative">neg</value> |
| <value desc="Integer zero" default="true">int_zero</value> |
| <value desc="Floating point zero">fp_zero</value> |
| <value desc="Bitwise">bit</value> |
| </enum> |
| |
| <enum name="Sample mode"> |
| <desc> |
| Varying interpolation mode, for choosing the correct sample to |
| interpolate at, allowing the `sample` and `centroid` qualifiers to be |
| implemented, as well as the `interpolateAt*` functions. |
| </desc> |
| <value desc="Center">center</value> |
| <value desc="Centroid">centroid</value> |
| <value desc="Sample">sample</value> |
| <value desc="Explicit">explicit</value> |
| </enum> |
| |
| <enum name="Update mode"> |
| <desc> |
| The Valhall GPU maintains hidden state when interpolating varyings, to |
| allow reusing sample location calculations. The update mode of a varying |
| load controls this hidden state. |
| </desc> |
| <value desc="Store interpolation position">store</value> |
| <value desc="Retrieve interpolation position">retrieve</value> |
| <reserved/> |
| <value desc="Clobber saved position">clobber</value> |
| </enum> |
| |
| <enum name="Sample and update mode"> |
| <desc> |
| For fused varying/texture instructions, only the following specific |
| combinations of sample and update modes are permitted. |
| </desc> |
| <value desc="Center, store">center_store</value> |
| <value desc="Centroid, store">centroid_store</value> |
| <value desc="Sample, store">sample_store</value> |
| <value desc="Explicit, store">explicit_store</value> |
| <value desc="Center, clobber">center_clobber</value> |
| <reserved/> |
| <value desc="Sample, clobber">sample_clobber</value> |
| <value desc="Retrieve previous state">retrieve</value> |
| </enum> |
| |
| <enum name="Source format"> |
| <desc> |
| In-memory format of varyings. |
| |
| Note: src_flat32 is only valid with 32-bit varying instructions and |
| src_flat16 is only valid with 16-bit varying instructions. |
| </desc> |
| <value desc="Uninterpreted 32-bit values">src_flat32</value> |
| <value desc="Uninterpreted 16-bit values">src_flat16</value> |
| <value desc="Interpolated 32-bit floats">src_f32</value> |
| <value desc="Interpolated 16-bit floats">src_f16</value> |
| </enum> |
| |
| <enum name="Atomic operation"> |
| <desc> |
| Operation performed in a general computational atomic instruction. |
| </desc> |
| <reserved/> |
| <reserved/> |
| <value desc="Add">aadd</value> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <reserved/> |
| <value desc="Signed minimum">asmin</value> |
| <value desc="Signed maximum">asmax</value> |
| <value desc="Unsigned minimum">aumin</value> |
| <value desc="Unsigned maximum">aumax</value> |
| <value desc="Bitwise and">aand</value> |
| <value desc="Bitwise or">aor</value> |
| <value desc="Bitwise exclusive-or">axor</value> |
| <value desc="Exchange (must return the value)">axchg</value> |
| </enum> |
| |
| <enum name="Atomic operation with 1"> |
| <desc> |
| Operation performed in a computational atomic-with-1 instruction. |
| </desc> |
| <value desc="Increment">ainc</value> |
| <value desc="Decrement">adec</value> |
| <value desc="Unsigned maximum with 1">aumax1</value> |
| <value desc="Signed maximum with 1">asmax1</value> |
| <value desc="Set bottom bit">aor1</value> |
| </enum> |
| |
| <ins name="NOP" title="No operation" dests="0" opcode="0x00" unit="CVT"> |
| <desc> |
| Do nothing. Useful at the start of a block for waiting on slots required |
| by the first actual instruction of the block, to reconcile dependencies |
| after a branch. Also useful as the sole instruction of an empty shader. |
| </desc> |
| </ins> |
| |
| <ins name="BRANCHZ" title="Compare to zero and branch" dests="0" opcode="0x1F" unit="CVT"> |
| <desc> |
| Branches to a specified relative offset if its source is nonzero (default) |
| or if its source is zero (if `.eq` is set). The offset is 27-bits and |
| sign-extended, giving an effective range of ±26-bits. The offset is |
| specified in units of instructions, relative to the *next* instruction. |
| Positive offsets may be interpreted as "number of instructions to skip". |
| Since Valhall instructions are 8 bytes, this operates as: |
| |
| $$PC := \begin{cases} PC + 8 \cdot (\text{offset} \; + 1) & \text{if} \; |
| \text{src} \stackrel{?}{=} 0 \\ PC + 8 & \text{otherwise} \end{cases}$$ |
| |
| Used with comparison instructions to implement control flow. Tie the |
| source to a nonzero constant to implement a jump. May introduce |
| divergence, so generally requires `.reconverge` flow control. |
| </desc> |
| <src combine="true">Value to compare against zero</src> |
| <imm name="offset" start="8" size="27" signed="true"/> |
| <conservative/> |
| <mod name="eq" start="36" size="1"/> |
| </ins> |
| |
| <ins name="DISCARD.f32" title="Discard fragment" dests="0" opcode="0x20" unit="CVT"> |
| <desc> |
| Evaluates the given condition, and if it passes, discards the current |
| fragment and terminates the thread. Only valid in a **fragment** shader. |
| </desc> |
| <cmp/> |
| <src absneg="true" swizzle="true">Left value to compare</src> |
| <src absneg="true" swizzle="true">Right value to compare</src> |
| </ins> |
| |
| <ins name="BRANCHZI" title="Compare to zero and branch indirect" opcode="0x2F" unit="CVT"> |
| <desc> |
| Jump to an indirectly specified (absolute or relative) address. Used to |
| jump to blend shaders at the end of a fragment shader. |
| </desc> |
| <src combine="true">Value to compare against zero</src> |
| <src>Branch target</src> |
| <conservative/> |
| <mod name="eq" start="36" size="1"/> |
| <mod name="absolute" start="40" size="1"/> |
| </ins> |
| |
| <ins name="BARRIER" title="Execution and memory barrier" opcode="0x45" unit="NONE"> |
| <desc> |
| General-purpose barrier. Must use slot #7. Must be paired with a |
| `.wait` flow on the instruction. |
| </desc> |
| <slot/> |
| </ins> |
| |
| <group name="CSEL" title="Floating-point conditional select" dests="1" unit="CVT"> |
| <ins name="CSEL.f32" opcode="0x154"/> |
| <ins name="CSEL.v2f16" opcode="0x155"/> |
| <desc> |
| Evaluates the given condition and outputs either the true source or the |
| false source. |
| </desc> |
| <cmp/> |
| <src float="true">Left value to compare</src> |
| <src float="true">Right value to compare</src> |
| <src float="true">Return value if true</src> |
| <src float="true">Return value if false</src> |
| </group> |
| |
| <group name="CSEL" title="Integer conditional select" dests="1" unit="CVT"> |
| <ins name="CSEL.u32" opcode="0x150"/> |
| <ins name="CSEL.v2u16" opcode="0x151"/> |
| <ins name="CSEL.s32" opcode="0x158"/> |
| <ins name="CSEL.v2s16" opcode="0x159"/> |
| <desc> |
| Evaluates the given condition and outputs either the true source or the |
| false source. |
| |
| Valhall lacks integer minimum/maximum instructions. `CSEL` instructions |
| with tied operands form the canonical implementations of these |
| instructions. Similarly, the integer $\text{sign}$ function is canonically |
| implemented with a pair of `CSEL` instructions. |
| </desc> |
| <cmp/> |
| <src>Left value to compare</src> |
| <src>Right value to compare</src> |
| <src>Return value if true</src> |
| <src>Return value if false</src> |
| </group> |
| |
| <ins name="LD_VAR_SPECIAL" title="Load special varying" opcode="0x56" unit="V"> |
| <sr write="true"/> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <sample/> |
| <update/> |
| <slot/> |
| <src/> |
| <imm name="index" start="12" size="4"/> <!-- 0 for pointx, 1 for pointy, 2 for fragw, 3 for fragz --> |
| </ins> |
| |
| <group name="LD_VAR_BUF_IMM" title="Load immediate varying" unit="V"> |
| <desc>Interpolates a given varying from hardware buffer</desc> |
| <ins name="LD_VAR_BUF_IMM.f32" opcode="0x5C"/> |
| <ins name="LD_VAR_BUF_IMM.f16" opcode="0x5D"/> |
| <slot/> |
| <vecsize/> |
| <source_format/> |
| <sample/> |
| <update/> |
| <sr write="true"/> |
| <sr_count/> |
| <src/> |
| <imm name="index" start="16" size="8"/> |
| </group> |
| |
| <group name="LD_VAR_BUF" title="Load indirect varying" unit="V"> |
| <desc>Interpolates a given varying from hardware buffer</desc> |
| <ins name="LD_VAR_BUF.f32" opcode="0x6C"/> |
| <ins name="LD_VAR_BUF.f16" opcode="0x6D"/> |
| <slot/> |
| <vecsize/> |
| <source_format/> |
| <sample/> |
| <update/> |
| <sr write="true"/> |
| <sr_count/> |
| <src/> |
| <src/> |
| </group> |
| |
| <ins name="LD_VAR" title="Load indirect varying" unit="V" opcode="0x64"> |
| <desc>Interpolates a given varying from a software buffer</desc> |
| <slot/> |
| <vecsize/> |
| <regfmt/> |
| <sample/> |
| <update/> |
| <sr write="true"/> |
| <sr_count/> |
| <src/> |
| <src>Varying index and table</src> |
| </ins> |
| |
| <ins name="LD_VAR_IMM" title="Load immediate varying" unit="V" opcode="0x54"> |
| <desc>Interpolates a given varying from a software buffer</desc> |
| <slot/> |
| <vecsize/> |
| <regfmt/> |
| <sample/> |
| <update/> |
| <sr write="true"/> |
| <sr_count/> |
| <src/> |
| <imm name="table" start="8" size="4"/> |
| <imm name="index" start="12" size="8"/> |
| </ins> |
| |
| <ins name="LD_VAR_FLAT" title="Load indirect varying" unit="V" opcode="0x55"> |
| <desc>Fetches a given varying from a software buffer</desc> |
| <slot/> |
| <vecsize/> |
| <regfmt/> |
| <sr write="true"/> |
| <sr_count/> |
| <src>Varying index and table</src> |
| </ins> |
| |
| <ins name="LD_VAR_FLAT_IMM" title="Load immediate varying" unit="V" opcode="0x41"> |
| <desc>Fetches a given varying from a software buffer</desc> |
| <slot/> |
| <vecsize/> |
| <regfmt/> |
| <sr write="true"/> |
| <sr_count/> |
| <imm name="table" start="8" size="4"/> |
| <imm name="index" start="12" size="8"/> |
| </ins> |
| |
| <ins name="LD_ATTR_IMM" title="Load immediate attribute" opcode="0x66" opcode2="0" unit="LS"> |
| <desc> |
| Load `vecsize` components from the attribute descriptor at entry `index` |
| of resource table `table` at index (vertex ID, instance ID), converting |
| to the specified register format. |
| </desc> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>Vertex ID</src> |
| <src>Instance ID</src> |
| <imm name="index" start="20" size="4"/> |
| <imm name="table" start="16" size="4"/> |
| </ins> |
| |
| <ins name="LD_ATTR" title="Load indirect attribute" opcode="0x76" opcode2="0" unit="LS"> |
| <desc> |
| Load `vecsize` components from the attribute descriptor at the specified |
| location at index (vertex ID, instance ID), converting |
| to the specified register format. |
| |
| The index must not diverge within a warp. |
| </desc> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>Vertex ID</src> |
| <src>Instance ID</src> |
| <src>Index and table</src> |
| </ins> |
| |
| <ins name="LD_TEX_IMM" title="Load immediate texture" opcode="0x66" opcode2="1" unit="LS"> |
| <desc> |
| Load `vecsize` components from the texture descriptor at entry `index` |
| of resource table `table`, converting |
| to the specified register format. |
| </desc> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>X/Y coordinates (16:16)</src> |
| <src>Z/W coordinates (16:16)</src> |
| <imm name="index" start="20" size="4"/> |
| <imm name="table" start="16" size="4"/> |
| </ins> |
| |
| <ins name="LD_TEX" title="Load indirect texture" opcode="0x76" opcode2="1" unit="LS"> |
| <desc> |
| Load `vecsize` components from the texture descriptor at the specified |
| location at index, converting |
| to the specified register format. |
| </desc> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>X/Y coordinates (16:16)</src> |
| <src>Z/W coordinates (16:16)</src> |
| <src>Index and table</src> |
| </ins> |
| |
| <ins name="LEA_ATTR_IMM" title="Load effective address of image texel" opcode="0x67" opcode2="0" unit="LS"> |
| <desc> |
| Load the effective address of an attribute specified with the |
| given immediate index. Returns three staging register: the low/high |
| 32-bits of the address and the internal conversion descriptor. |
| </desc> |
| <slot/> |
| <sr_count/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>Vertex index</src> |
| <src>Instance index</src> |
| <imm name="table" start="16" size="4"/> |
| <imm name="index" start="20" size="4"/> |
| </ins> |
| |
| <ins name="LEA_ATTR" title="Load effective address of image texel" opcode="0x77" opcode2="0" unit="LS"> |
| <desc> |
| Load the effective address of an attribute specified with the |
| given index. Returns three staging register: the low/high |
| 32-bits of the address and the internal conversion descriptor. |
| </desc> |
| <vecsize/> |
| <slot/> |
| <sr_count/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>Vertex index</src> |
| <src>Instance index</src> |
| <src>Attribute index and table</src> |
| </ins> |
| |
| <ins name="LEA_TEX_IMM" title="Load effective address of image texel" opcode="0x67" opcode2="1" unit="LS"> |
| <desc> |
| Load the effective address of a texel from the image specified with the |
| given immediate index. Returns three staging registers: the low/high |
| 32-bits of the address and the internal conversion descriptor. The format |
| of the internal conversion descriptor is compatible with Bifrost but |
| omits the register format, as this is specified with the ST_CVT |
| instruction on Valhall. |
| |
| Coordinates are specified as 16-bit integers, packed into 32-bit sources. |
| </desc> |
| <slot/> |
| <sr_count/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src>X/Y coordinates (16:16)</src> |
| <src>Z/W coordinates (16:16)</src> |
| <imm name="table" start="16" size="4"/> |
| <imm name="index" start="20" size="4"/> |
| </ins> |
| |
| <ins name="LEA_TEX" title="Load effective address of image texel" opcode="0x77" opcode2="1" unit="LS"> |
| <desc> |
| Load the effective address of a texel from the image specified with the |
| given index. Returns three staging register: the low/high |
| 32-bits of the address and the internal conversion descriptor. The format |
| of the internal conversion descriptor is compatible with Bifrost but |
| omits the register format, as this is specified with the ST_CVT |
| instruction on Valhall. |
| |
| Coordinates are specified as 16-bit integers, packed into 32-bit sources. |
| </desc> |
| <vecsize/> |
| <slot/> |
| <sr_count/> |
| <mod name="descriptor_type" start="128" size="1" implied="true"/> |
| <sr write="true"/> |
| <src size="16">X/Y coordinates (16:16)</src> |
| <src>Z/W coordinates (16:16)</src> |
| <src>Index and table</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i8" title="Global memory load" opcode="0x6a" opcode2="0" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_8_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Address to load from after adding offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i16" title="Global memory load" opcode="0x6a" opcode2="1" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_16_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i24" title="Global memory load" opcode="0x6a" opcode2="2" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_24_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i32" title="Global memory load" opcode="0x6a" opcode2="3" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_32_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i48" title="Global memory load" opcode="0x6a" opcode2="4" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_48_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i64" title="Global memory load" opcode="0x6a" opcode2="5" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_64_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i96" title="Global memory load" opcode="0x6a" opcode2="6" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_96_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LD_BUFFER.i128" title="Global memory load" opcode="0x6a" opcode2="7" unit="LS"> |
| <desc> |
| Loads a buffer descriptor. If bits 25...31 of the mode descriptor are |
| all-ones, load from the buffer descriptors in the table indexed by the |
| bottom byte of the mode descriptor. If they are all zeroes, load the |
| contents of the buffer in the first table indexed by the bottom byte of |
| the mode descriptor. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <mod name="load_lane_128_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="32">Byte offset</src> |
| <src size="32">Mode descriptor</src> |
| </ins> |
| |
| <ins name="LEA_BUF_IMM" title="Load buffer effective address" opcode="0x5E" unit="LS"> |
| <desc> |
| Load effective address of a buffer with an immediate offset added. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <slot/> |
| <imm name="table" start="8" size="4"/> |
| <imm name="index" start="12" size="8"/> |
| <src>Linear ID</src> |
| </ins> |
| |
| <ins name="LOAD.i8" title="Global memory load" opcode="0x60" opcode2="0" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_8_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i16" title="Global memory load" opcode="0x60" opcode2="1" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_16_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i24" title="Global memory load" opcode="0x60" opcode2="2" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_24_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i32" title="Global memory load" opcode="0x60" opcode2="3" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_32_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i48" title="Global memory load" opcode="0x60" opcode2="4" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_48_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i64" title="Global memory load" opcode="0x60" opcode2="5" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_64_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i96" title="Global memory load" opcode="0x60" opcode2="6" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_96_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <ins name="LOAD.i128" title="Global memory load" opcode="0x60" opcode2="7" unit="LS"> |
| <desc>Loads from main memory</desc> |
| <sr write="true"/> |
| <memory_access/> |
| <sr_count/> |
| <mod name="load_lane_128_bit" start="36" size="3"/> |
| <mod name="unsigned" start="39" size="1"/> |
| <slot/> |
| <src size="64">Address to load from after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </ins> |
| |
| <group name="STORE" title="Global memory store" opcode="0x61" unit="LS"> |
| <desc>Stores to main memory</desc> |
| <sr read="true"/> |
| <ins name="STORE.i8" opcode2="0x0"/> |
| <ins name="STORE.i16" opcode2="0x1"/> |
| <ins name="STORE.i24" opcode2="0x2"/> |
| <ins name="STORE.i32" opcode2="0x3"/> |
| <ins name="STORE.i48" opcode2="0x4"/> |
| <ins name="STORE.i64" opcode2="0x5"/> |
| <ins name="STORE.i96" opcode2="0x6"/> |
| <ins name="STORE.i128" opcode2="0x7"/> |
| <sr_count/> |
| <memory_access/> |
| <slot/> |
| <src size="64">Address to store to after adding offset</src> |
| <imm name="offset" start="8" size="16" signed="true"/> |
| </group> |
| |
| <ins name="ST_CVT" title="Store with conversion" opcode="0x71" unit="LS"> |
| <desc> |
| Store to memory with data conversion. The address to store to is given in |
| the first source, which must be a 64-bit register (a pair of 32-bit |
| registers). The other source is the conversion descriptor used for the store. |
| |
| Used with LEA_TEX_IMM to implement image stores. |
| </desc> |
| <slot/> |
| <mod name="memory_access" start="37" size="3"/> |
| <vecsize/> |
| <regfmt/> |
| <sr read="true"/> |
| <sr_count/> |
| <src size="64">64-bit address to store to</src> |
| <imm name="offset" start="8" size="8"/> |
| <src>Internal conversion descriptor</src> |
| </ins> |
| |
| <ins name="LD_TILE" title="Load from tilebuffer" opcode="0x78" unit="NONE"> |
| <desc> |
| Loads a given render target, specified in the pixel indices descriptor, at |
| a given location and sample, and convert to the format specified in the |
| internal conversion descriptor. Used to implement EXT_framebuffer_fetch |
| and internally in blend shaders. |
| </desc> |
| <sr write="true"/> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <src>Pixel indices descriptor</src> |
| <src>Coverage mask</src> |
| <src>Conversion descriptor</src> |
| </ins> |
| |
| <ins name="ST_TILE" title="Store to tilebuffer" opcode="0x79" unit="NONE"> |
| <desc> |
| Store to given render target, specified in the pixel indices descriptor, at |
| a given location and sample, and convert to the format specified in the |
| internal conversion descriptor. Used internally in blend shaders. |
| </desc> |
| <sr read="true"/> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| <slot/> |
| <src>Pixel indices descriptor</src> |
| <src>Coverage mask</src> |
| <src>Conversion descriptor</src> |
| </ins> |
| |
| <ins name="BLEND" title="Blend render target" opcode="0x7F" unit="NONE"> |
| <desc> |
| Blends a given render target. This loads the API-specified blend state for |
| the render target from the first source. Blend descriptors are available |
| as special immediates. It then reads the colour to be blended from the |
| first staging register, with the specified vector size and register format |
| as desired. The resulting coverage mask is stored to the second set of |
| staging registers. |
| |
| In the fixed-function path, `BLEND` sends the colour to the blender to be |
| written to the tilebuffer. Then, if the instruction's flow control |
| specifies termination, the fragment program is ended. If it does not |
| specify termination, `BLEND` acts as a relative branch, branching with the |
| offset specified as `target`. This allows the subsequent instructions to |
| be skipped when fixed-function blending is used. Note this implicit branch |
| can never introduce divergence, so `.reconverge` is not required. |
| |
| In the blend shader path, `BLEND` ignores the specified flow control and |
| does not branch to the specified offset. Instead, execution continues |
| normally with the next instruction. The compiler should insert code for |
| calling a blend shader after the `BLEND` instruction unless it is known |
| that a blend shader will never be required. |
| |
| The indirection is required to support both fixed-function and blend |
| shaders efficiently and without shader variants. |
| </desc> |
| <sr read="true"/> |
| <src size="64">Blend descriptor</src> |
| <src>Sample coverage</src> |
| <imm name="target" start="8" size="8"/> |
| <slot/> |
| <sr_count/> |
| <vecsize/> |
| <regfmt/> |
| </ins> |
| |
| <ins name="ATEST" title="Alpha test" opcode="0x7D" unit="NONE"> |
| <desc> |
| Does alpha-to-coverage testing, updating the sample coverage mask. ATEST |
| does not do an implicit discard. It should be executed before the first |
| ZS_EMIT or BLEND instruction. |
| </desc> |
| <sr write="true">Updated coverage mask</sr> |
| <src>Input coverage mask</src> |
| <src swizzle="true">Alpha value (render target 0)</src> |
| <src/> |
| <sr_count/> |
| </ins> |
| |
| <ins name="ZS_EMIT" title="Depth/stencil write" opcode="0x7E" unit="NONE"> |
| <desc> |
| Programatically writes out depth, stencil, or both, depending on which |
| modifiers are set. Used to implement gl_FragDepth and gl_FragStencil. |
| </desc> |
| <mod name="z" start="25" size="1"/> |
| <mod name="stencil" start="24" size="1"/> |
| <sr write="true">Updated coverage mask</sr> |
| <src>Depth value</src> |
| <src>Stencil value</src> |
| <src>Input coverage mask</src> |
| <sr_count/> |
| <slot/> |
| </ins> |
| |
| <group name="CONVERT" title="Data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc> |
| Performs the given data conversion. Note that floating-point rounding is |
| handled via the same hardware and therefore shares an encoding. Round mode |
| is specified where it makes sense. |
| </desc> |
| |
| <ins name="V2S16_TO_V2F16" opcode2="0x7"/> |
| |
| <ins name="S32_TO_F32" opcode2="0x9"/> |
| |
| <ins name="V2U16_TO_V2F16" opcode2="0x17"/> |
| |
| <ins name="U32_TO_F32" opcode2="0x19"/> |
| |
| <roundmode/> |
| <src widen="true">Value to convert</src> |
| </group> |
| |
| <group name="CONVERT" title="16->32 integer data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc> |
| Performs the given data conversion. |
| </desc> |
| |
| <ins name="S16_TO_S32" opcode2="0x4"/> |
| <ins name="S16_TO_F32" opcode2="0x5"/> |
| <ins name="U16_TO_U32" opcode2="0x14"/> |
| <ins name="U16_TO_F32" opcode2="0x15"/> |
| |
| <src swizzle="true" size="16">Value to convert</src> |
| </group> |
| |
| <group name="CONVERT" title="Float-to-int data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc>Performs the given data conversion.</desc> |
| <ins name="F32_TO_S32" opcode2="0xC"/> |
| <ins name="F32_TO_U32" opcode2="0x1C"/> |
| <roundmode/> |
| <src absneg="true">Value to convert</src> |
| </group> |
| |
| <group name="CONVERT" title="Float-to-int data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc>Performs the given data conversion.</desc> |
| <ins name="V2F16_TO_V2S16" opcode2="0xE"/> |
| <ins name="V2F16_TO_V2U16" opcode2="0x1E"/> |
| <ins name="F16_TO_S32" opcode2="0xA"/> |
| <ins name="F16_TO_U32" opcode2="0x1A"/> |
| <roundmode/> |
| <src swizzle="true" absneg="true" size="16">Value to convert</src> |
| </group> |
| |
| <ins name="F16_TO_F32" title="16-bit float to 32-bit float conversion" dests="1" opcode="0x90" opcode2="0xB" unit="CVT"> |
| <desc>Converts up with the specified round mode.</desc> |
| <roundmode/> |
| <src lane="28" size="16" absneg="true">Value to convert</src> |
| </ins> |
| |
| <group name="CONVERT" title="8-bit to 32-bit data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc> |
| Performs the given data conversion. |
| </desc> |
| |
| <ins name="S8_TO_S32" opcode2="0x0"/> |
| <ins name="S8_TO_F32" opcode2="0x1"/> |
| |
| <ins name="U8_TO_U32" opcode2="0x10"/> |
| <ins name="U8_TO_F32" opcode2="0x11"/> |
| |
| <src lane="28" size="8">Value to convert</src> |
| </group> |
| |
| <group name="CONVERT" title="8-bit to 16-bit data conversions" dests="1" opcode="0x90" unit="CVT"> |
| <desc> |
| Performs the given data conversion. |
| </desc> |
| |
| <ins name="V2S8_TO_V2S16" opcode2="0x2"/> |
| <ins name="V2S8_TO_V2F16" opcode2="0x3"/> |
| |
| <ins name="V2U8_TO_V2U16" opcode2="0x12"/> |
| <ins name="V2U8_TO_V2F16" opcode2="0x13"/> |
| |
| <src halfswizzle="true" size="8">Value to convert</src> |
| </group> |
| |
| <group name="FROUND" title="Floating-point rounding" dests="1" opcode="0x90" unit="CVT"> |
| <desc> |
| Performs the given rounding, using the convert unit. |
| </desc> |
| |
| <ins name="FROUND.f32" opcode2="0xD"/> |
| <ins name="FROUND.v2f16" opcode2="0xF"/> |
| |
| <roundmode/> |
| <src swizzle="true" absneg="true">Value to convert</src> |
| </group> |
| |
| <ins name="MOV.i32" title="Register move" dests="1" opcode="0x91" opcode2="0x0" unit="CVT"> |
| <desc>Canonical register-to-register move.</desc> |
| <src/> |
| </ins> |
| |
| <ins name="CLZ.u32" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x4" unit="CVT"> |
| <desc> |
| Used as a primitive for various bitwise operations. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="CLZ.v2u16" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x5" unit="CVT"> |
| <desc> |
| Used as a primitive for various bitwise operations. |
| </desc> |
| <src swizzle="true"/> |
| </ins> |
| |
| <ins name="CLZ.v4u8" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x6" unit="CVT"> |
| <desc> |
| Used as a primitive for various bitwise operations. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="IABS.s32" title="Absolute value" dests="1" opcode="0x91" opcode2="0x8" unit="CVT"> |
| <desc> |
| 64-bit abs may be constructed in 4 instructions (5 clocks) by checking the |
| sign with `ICMP.s32.lt.m1 hi, 0` and negating based on the result with |
| `IADD.s64` and `LSHIFT_XOR.i32` on each half. |
| </desc> |
| <src widen="true"/> |
| </ins> |
| |
| <ins name="IABS.v2s16" title="Absolute value" dests="1" opcode="0x91" opcode2="0x9" unit="CVT"> |
| <src widen="true"/> |
| </ins> |
| |
| <ins name="IABS.v4s8" title="Absolute value" dests="1" opcode="0x91" opcode2="0xa" unit="CVT"> |
| <src/> |
| </ins> |
| |
| <ins name="POPCOUNT.i32" title="Population count" dests="1" opcode="0x91" opcode2="0xC" unit="SFU"> |
| <desc> |
| Only available as 32-bit. Smaller bitsizes require explicit conversions. |
| 64-bit popcount may be constructed in 3 clocks by separate 32-bit |
| popcounts of each half and a 32-bit add, which is guaranteed not to |
| overflow. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="BITREV.i32" title="Bitwise reverse" dests="1" opcode="0x91" opcode2="0xD" unit="SFU"> |
| <desc> |
| Only available as 32-bit. Other bitsizes may be derived with swizzles. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="NOT_OLD.i32" title="Bitwise complement" dests="1" opcode="0x91" opcode2="0xE" unit="SFU"> |
| <desc> |
| For fully featured bitwise operation, see the shift opcodes. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="NOT_OLD.i64" title="Bitwise complement" dests="1" opcode="0x191" opcode2="0xE" unit="SFU"> |
| <desc> |
| For fully featured bitwise operation, see the shift opcodes. |
| </desc> |
| <src/> |
| </ins> |
| |
| <ins name="WMASK" title="Warp mask" dests="1" opcode="0x95" unit="CVT"> |
| <desc> |
| Returns the mask of lanes ever active within the warp (subgroup), such |
| that the source is nonzero. The number of work-items in a subgroup is |
| given as the popcount of this value with a nonzero input. |
| |
| An `all()` subgroup operation may be constructed as `WMASK` of the input |
| compared for equality with `WMASK` of an nonzero value. |
| |
| An `any()` subgroup operation may be constructed as `WMASK` of the input |
| compared against zero. |
| </desc> |
| <src/> |
| <subgroup/> |
| </ins> |
| |
| <group name="FREXP" title="Fraction/exponent extract" dests="1" opcode="0x99" unit="CVT"> |
| <ins name="FREXPM.f32" opcode2="0"/> |
| <ins name="FREXPM.v2f16" opcode2="1"/> |
| <ins name="FREXPE.f32" opcode2="2"/> |
| <ins name="FREXPE.v2f16" opcode2="3"/> |
| <desc> |
| Breaks up the floating-point input into its fractional (mantissa) and |
| exponent parts. By default, this is compatible with the `frexp()` function |
| in APIs. With the log/sqrt modifiers, the floating point format is |
| adjusted to be compatible with Valhall's argument reduction for logarithm |
| and square root computation respectively. |
| </desc> |
| <mod name="sqrt" start="24" size="1"/> |
| <mod name="log" start="25" size="1"/> |
| <src float="true" swizzle="true"/> |
| </group> |
| |
| <group name="SFU" title="Special function unit" dests="1" opcode="0x9C" unit="SFU"> |
| <ins name="FRCP.f32" opcode2="0"/> |
| <ins name="FRCP.f16" opcode2="1"/> |
| <ins name="FRSQ.f32" opcode2="2"/> |
| <ins name="FRSQ.f16" opcode2="3"/> |
| <ins name="FLOGD.f32" opcode2="8"/> |
| <ins name="FPCLASS.f32" opcode2="10"/> |
| <ins name="FPCLASS.f16" opcode2="11"/> |
| <ins name="FLOG_TABLE.f32" opcode2="12"/> |
| <ins name="FRCP_APPROX.f32" opcode2="14"/> |
| <ins name="FRSQ_APPROX.f32" opcode2="15"/> |
| <desc> |
| Performs a given special function. The floating-point reciprocal (`FRCP`) |
| and reciprocal square root (`FRSQ`) instructions may be freely used as-is. |
| The logarithm instruction (`FLOGD.f32`) requires an argument |
| reduction. See the transcendentals section for more information. Like the |
| Bifrost op, `FRSQ_APPROX.f32` does an implicit `FREXPM.f32.sqrt` on the |
| source. |
| </desc> |
| <src float="true" swizzle="true" absneg="true"/> |
| </group> |
| |
| <group name="SFU" title="Special function unit" dests="1" opcode="0x9C" unit="SFU"> |
| <ins name="FSIN_TABLE.u6" opcode2="4"/> |
| <ins name="FCOS_TABLE.u6" opcode2="5"/> |
| <ins name="FSINCOS_OFFSET.u6" opcode2="6"/> |
| <ins name="FEXP_TABLE.u4" opcode2="13"/> |
| <desc> |
| Performs a given special function. The trigonometric tables |
| (`FSIN_TABLE.u6` and `FCOS_TABLE.u6`) are crude, requiring both an |
| argument reduction and postprocessing. |
| </desc> |
| <src/> |
| </group> |
| |
| <group name="FADD" title="Floating-point add" dests="1" opcode2="0" unit="FMA"> |
| <ins name="FADD.f32" opcode="0xA4"/> |
| <ins name="FADD.v2f16" opcode="0xA5"/> |
| <desc>$A + B$</desc> |
| <clamp/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| </group> |
| |
| <group name="FMIN" title="Floating-point minimum" dests="1" opcode2="2" unit="CVT"> |
| <ins name="FMIN.f32" opcode="0xA4"/> |
| <ins name="FMIN.v2f16" opcode="0xA5"/> |
| <desc>$\min \{ A, B \}$</desc> |
| <clamp/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| </group> |
| |
| <group name="FMAX" title="Floating-point maximum" dests="1" opcode2="3" unit="CVT"> |
| <ins name="FMAX.f32" opcode="0xA4"/> |
| <ins name="FMAX.v2f16" opcode="0xA5"/> |
| <desc>$\max \{ A, B \}$</desc> |
| <clamp/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| </group> |
| |
| <group name="V2F32_TO_V2F16" title="Vectorized floating-point conversion" dests="1" opcode2="4" unit="CVT"> |
| <ins name="V2F32_TO_V2F16" opcode="0xA5"/> |
| <desc> |
| Given a pair of 32-bit floats, output a pair of 16-bit floats packed into |
| a 32-bit destination. |
| </desc> |
| <clamp/> |
| <roundmode/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| </group> |
| |
| <group name="LDEXP" title="Floating-point rescaling" dests="1" opcode2="6" unit="FMA"> |
| <ins name="LDEXP.f32" opcode="0xA4"/> |
| <ins name="LDEXP.v2f16" opcode="0xA5"/> |
| <desc> |
| Computes $A \cdot 2^B$ by adding B to the exponent of A. Used to calculate |
| various special functions, particularly base-2 exponents. Special case |
| handling differs from an actual floating-point multiply, so this should |
| not be used outside fixed instruction sequences. |
| </desc> |
| <src absneg="true" swizzle="true">A</src> |
| <src/> |
| <roundmode/> <!-- Also has rtna --> |
| <!-- Also has infinity handling for arctan --> |
| </group> |
| |
| <ins name="FEXP.f32" title="Floating-point exponent" dests="1" opcode="0xA4" opcode2="8" unit="SFU"> |
| <desc> |
| Calculates the base-2 exponent of an argument specified as a 8:24 |
| fixed-point. The original argument is passed as well for correct handling |
| of special cases. |
| </desc> |
| <clamp/> |
| <src>Input as 8:24 fixed-point</src> |
| <src absneg="true">Input as 32-bit float</src> |
| </ins> |
| |
| <ins name="FADD_LSCALE.f32" title="Floating-point add with logarithm scale" dests="1" opcode="0xA4" opcode2="9" unit="FMA"> |
| <desc> |
| Performs a floating-point addition specialized for logarithm computation. |
| </desc> |
| <clamp/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| </ins> |
| |
| <ins name="FATAN_ASSIST.f32" title="ATAN calculation helper" dests="1" opcode="0xA4" opcode2="14" unit="SFU"> |
| <desc> |
| Used for `atan2()` implementation. Destination is two 16-bit |
| values (int and float) for the first form, and a single 32-bit float when |
| `.second` is set (indicating the FATAN_TABLE.f32 instruction). |
| </desc> |
| <mod name="second" start="24" size="1"/> |
| <src>A</src> |
| <src>B</src> |
| </ins> |
| |
| <group name="IADD" title="Integer addition" dests="1" opcode2="0" unit="CVT"> |
| <desc> |
| $A + B$ with optional saturation. |
| |
| As Valhall lacks swizzle instructions, `IADD.v2i16` with zero is the |
| canonical lowering for swizzles. |
| </desc> |
| <ins name="IADD.u32" opcode="0xA0"/> |
| <ins name="IADD.v2u16" opcode="0xA1"/> |
| <ins name="IADD.v4u8" opcode="0xA2"/> |
| <ins name="IADD.s32" opcode="0xA8"/> |
| <ins name="IADD.v2s16" opcode="0xA9"/> |
| <ins name="IADD.v4s8" opcode="0xAA"/> |
| <ins name="IADD.u64" opcode="0x1A3"/> |
| <ins name="IADD.s64" opcode="0x1AB"/> |
| <!-- <ins name="IADD.s32" opcode="0x1A0"/> --> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <saturate/> |
| </group> |
| |
| <ins name="MKVEC.v2i16" title="Make 16-bit vector" dests="1" opcode="0xA1" opcode2="0x5" unit="CVT"> |
| <desc>Calculates $A | (B \ll 16)$. Used to implement `(ushort2)(A, B)`</desc> |
| <src swizzle="true">A</src> |
| <src swizzle="true">B</src> |
| </ins> |
| |
| <group name="ISUB" title="Integer subtract" dests="1" opcode2="1" unit="CVT"> |
| <ins name="ISUB.u32" opcode="0xA0"/> |
| <ins name="ISUB.v2u16" opcode="0xA1"/> |
| <ins name="ISUB.v4u8" opcode="0xA2"/> |
| <ins name="ISUB.s32" opcode="0xA8"/> |
| <ins name="ISUB.v2s16" opcode="0xA9"/> |
| <ins name="ISUB.v4s8" opcode="0xAA"/> |
| <ins name="ISUB.u64" opcode="0x1A3"/> |
| <ins name="ISUB.s64" opcode="0x1AB"/> |
| <desc>$A - B$ with optional saturation</desc> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <saturate/> |
| </group> |
| |
| <group name="SEG_ADD" title="Segment addition" dests="1" opcode2="6" unit="CVT"> |
| <desc> |
| Similar to SHADDX, but especially used for loading offsets into |
| WLS. Usually this is only required for atomic operations, which cannot |
| directly use wls_pointer as an address. |
| |
| .neg indicates SEG_SUB instead. |
| </desc> |
| <ins name="SEG_ADD.u64" opcode="0x1A3"/> |
| <mod name="neg" start="38" size="1"/> |
| <mod name="preserve_null" start="39" size="1"/> |
| <src>A</src> |
| <src widen="true">B</src> |
| </group> |
| |
| <group name="SHADDX" title="Shift, extend, and 64-bit add" dests="1" opcode2="7" unit="CVT"> |
| <desc> |
| Sign or zero extend B to 64-bits, left-shift by `shift`, and add the |
| 64-bit value A. These instructions accelerate address arithmetic, but may |
| be used in full generality for 64-bit integer arithmetic. |
| </desc> |
| <ins name="SHADDX.u64" opcode="0x1A3"/> |
| <ins name="SHADDX.s64" opcode="0x1AB"/> |
| <imm name="shift" start="20" size="3"/> |
| <src>A</src> |
| <src widen="true">B</src> |
| </group> |
| |
| <group name="IMUL" title="Integer multiply" dests="1" opcode2="0x0A" unit="SFU"> |
| <ins name="IMUL.i32" opcode="0xA0"/> |
| <ins name="IMUL.v2i16" opcode="0xA1"/> |
| <ins name="IMUL.v4i8" opcode="0xA2"/> |
| <ins name="IMUL.s32" opcode="0xA8"/> |
| <ins name="IMUL.v2s16" opcode="0xA9"/> |
| <ins name="IMUL.v4s8" opcode="0xAA"/> |
| <ins name="IMULD.u64" opcode="0x1A3"/> |
| <!-- <ins name="IMUL.s32" opcode="0x1A0"/> --> |
| <desc> |
| $A \cdot B$ with optional saturation. Note the multipliers can only handle up to |
| 32-bit by 32-bit multiplies. The 64-bit "multiply" acts like IMUL.u32 but |
| additionally writes the high half of the product to the high half of the |
| 64-bit destination. Along with IADD.u32 and IADD.u64, this allows the |
| construction of a 64-bit multiply in 5 instructions (6 clocks). |
| </desc> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <saturate/> |
| </group> |
| |
| <group name="HADD" title="Integer half-add" dests="1" opcode2="0x0B" unit="CVT"> |
| <ins name="HADD.u32" opcode="0xA0"/> |
| <ins name="HADD.v2u16" opcode="0xA1"/> |
| <ins name="HADD.v4u8" opcode="0xA2"/> |
| <ins name="HADD.s32" opcode="0xA8"/> |
| <ins name="HADD.v2s16" opcode="0xA9"/> |
| <ins name="HADD.v4s8" opcode="0xAA"/> |
| <mod name="rhadd" start="30" size="1"/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <desc> |
| $(A + B) \gg 1$ without intermediate overflow, corresponding to `hadd()` in |
| OpenCL. With the `.rhadd` modifier set, it instead calculates |
| $(A + B + 1) \gg 1$ corresponding to `rhadd()` in OpenCL. |
| </desc> |
| </group> |
| |
| <group name="CLPER" title="Cross-lane permute" dests="1" opcode2="0xF" unit="SFU"> |
| <ins name="CLPER.i32" opcode="0xA0"/> |
| <ins name="CLPER.v2u16" opcode="0xA1"/> |
| <ins name="CLPER.v4u8" opcode="0xA2"/> |
| <ins name="CLPER.s32" opcode="0xA8"/> |
| <ins name="CLPER.v2s16" opcode="0xA9"/> |
| <ins name="CLPER.v4s8" opcode="0xAA"/> |
| <ins name="CLPER.u64" opcode="0x1A3"/> |
| <ins name="CLPER.s64" opcode="0x1AB"/> |
| <!-- <ins name="CLPER.s32" opcode="0x1A0"/> --> |
| <desc> |
| Selects the value of A in the subgroup lane given by B. This implements |
| subgroup broadcasts. It may be used as a primitive for screen space |
| derivatives in fragment shaders. |
| </desc> |
| <src>A</src> |
| <src widen="true">B</src> |
| <subgroup/> |
| <lane_op/> |
| <inactive_result/> |
| </group> |
| |
| <group name="FMA" title="Fused floating-point multiply add" dests="1" unit="FMA"> |
| <ins name="FMA.f32" opcode="0xB2"/> |
| <ins name="FMA.v2f16" opcode="0xB3"/> |
| <desc>$A \cdot B + C$</desc> |
| <clamp/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| <src absneg="true" swizzle="true">C</src> |
| </group> |
| |
| <group name="LSHIFT_AND" title="Left shift and bitwise AND" dests="1" opcode2="0x100" unit="SFU"> |
| <ins name="LSHIFT_AND.i32" opcode="0xB4"/> |
| <ins name="LSHIFT_AND.v2i16" opcode="0xB5"/> |
| <ins name="LSHIFT_AND.v4i8" opcode="0xB6"/> |
| <ins name="LSHIFT_AND.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Left shifts its first source by a specified amount and bitwise ANDs it with the |
| second source, optionally inverting the second source or the result. |
| </desc> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <group name="RSHIFT_AND" title="Right shift and bitwise AND" dests="1" opcode2="0x000" unit="SFU"> |
| <ins name="RSHIFT_AND.i32" opcode="0xB4"/> |
| <ins name="RSHIFT_AND.v2i16" opcode="0xB5"/> |
| <ins name="RSHIFT_AND.v4i8" opcode="0xB6"/> |
| <ins name="RSHIFT_AND.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Right shifts its first source by a specified amount and bitwise ANDs it with the |
| second source, optionally inverting the second source or the result. If |
| `signed` is set, the hardware performs an arithmetic right shift; otherwise, |
| it performs an unsigned right shift. |
| </desc> |
| <mod name="signed" start="34" size="1"/> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <group name="LSHIFT_OR" title="Left shift and bitwise OR" dests="1" opcode2="0x101" unit="SFU"> |
| <ins name="LSHIFT_OR.i32" opcode="0xB4"/> |
| <ins name="LSHIFT_OR.v2i16" opcode="0xB5"/> |
| <ins name="LSHIFT_OR.v4i8" opcode="0xB6"/> |
| <ins name="LSHIFT_OR.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Left shifts its first source by a specified amount and bitwise ORs it with the |
| second source, optionally inverting the second source or the result. |
| </desc> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <group name="RSHIFT_OR" title="Right shift and bitwise OR" dests="1" opcode2="0x001" unit="SFU"> |
| <ins name="RSHIFT_OR.i32" opcode="0xB4"/> |
| <ins name="RSHIFT_OR.v2i16" opcode="0xB5"/> |
| <ins name="RSHIFT_OR.v4i8" opcode="0xB6"/> |
| <ins name="RSHIFT_OR.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Right shifts its first source by a specified amount and bitwise ORs it with the |
| second source, optionally inverting the second source or the result. If |
| `signed` is set, the hardware performs an arithmetic right shift; otherwise, |
| it performs an unsigned right shift. |
| </desc> |
| <mod name="signed" start="34" size="1"/> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <group name="LSHIFT_XOR" title="Left shift and bitwise XOR" dests="1" opcode2="0x102" unit="SFU"> |
| <ins name="LSHIFT_XOR.i32" opcode="0xB4"/> |
| <ins name="LSHIFT_XOR.v2i16" opcode="0xB5"/> |
| <ins name="LSHIFT_XOR.v4i8" opcode="0xB6"/> |
| <ins name="LSHIFT_XOR.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Left shifts its first source by a specified amount and bitwise XORs it with the |
| second source, optionally inverting the second source or the result. |
| </desc> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <group name="RSHIFT_XOR" title="Right shift and bitwise XOR" dests="1" opcode2="0x002" unit="SFU"> |
| <ins name="RSHIFT_XOR.i32" opcode="0xB4"/> |
| <ins name="RSHIFT_XOR.v2i16" opcode="0xB5"/> |
| <ins name="RSHIFT_XOR.v4i8" opcode="0xB6"/> |
| <ins name="RSHIFT_XOR.i64" opcode="0x1B7"/> |
| <mod name="left" start="128" size="1" implied="true"/> |
| <desc> |
| Right shifts its first source by a specified amount and bitwise XORs it with the |
| second source, optionally inverting the second source or the result. If |
| `signed` is set, the hardware performs an arithmetic right shift; otherwise, |
| it performs an unsigned right shift. |
| </desc> |
| <mod name="signed" start="34" size="1"/> |
| <not_result/> |
| <src widen="true">A</src> |
| <src lanes="true" size="8">shift</src> |
| <src not="true">B</src> |
| </group> |
| |
| <ins name="MUX.i32" title="Mux" dests="1" opcode="0xB8" unit="SFU"> |
| <desc> |
| Mux between A and B based on the provided mask. The condition specified |
| as the `mux` modifier is evaluated on the mask. If true, `A` is chosen, |
| else `B` is chosen. The `bit` modifier acts bitwise, equivalent to |
| `bitselect()` in OpenCL, so `MUX.i32.bit A, B, mask` calculates |
| `(A & mask) | (B & ~mask)`. |
| </desc> |
| <mod name="mux" start="32" size="2"/> |
| <src>A</src> |
| <src>B</src> |
| <src>Mask</src> |
| </ins> |
| |
| <ins name="MUX.v2i16" title="Mux" dests="1" opcode="0xB9" unit="SFU"> |
| <desc> |
| Mux between A and B based on the provided mask. The condition specified |
| as the `mux` modifier is evaluated on the mask. If true, `A` is chosen, |
| else `B` is chosen. The `bit` modifier acts bitwise, equivalent to |
| `bitselect()` in OpenCL, so `MUX.v2i16.bit A, B, mask` calculates |
| `(A & mask) | (B & ~mask)`. |
| </desc> |
| <mod name="mux" start="32" size="2"/> |
| <src swizzle="true">A</src> |
| <src swizzle="true">B</src> |
| <src swizzle="true">Mask</src> |
| </ins> |
| |
| <ins name="MUX.v4i8" title="Mux" dests="1" opcode="0xBA" unit="SFU"> |
| <desc> |
| Mux between A and B based on the provided mask. The condition specified |
| as the `mux` modifier is evaluated on the mask. If true, `A` is chosen, |
| else `B` is chosen. The `bit` modifier acts bitwise, equivalent to |
| `bitselect()` in OpenCL, so `MUX.v4i8.bit A, B, mask` calculates |
| `(A & mask) | (B & ~mask)`. |
| </desc> |
| <mod name="mux" start="32" size="2"/> |
| <src>A</src> |
| <src>B</src> |
| <src>Mask</src> |
| </ins> |
| |
| <ins name="CUBE_SSEL" title="Cube S-coordinate select" dests="1" opcode="0xBC" opcode2="0" unit="SFU"> |
| <desc>During a cube map transform, select the S coordinate given a selected face.</desc> |
| <src absneg="true">Z coordinate as 32-bit floating point</src> |
| <src absneg="true">X coordinate as 32-bit floating point</src> |
| <src>Cube face index</src> |
| </ins> |
| |
| <ins name="CUBE_TSEL" title="Cube T-coordinate select" dests="1" opcode="0xBC" opcode2="1" unit="SFU"> |
| <desc>During a cube map transform, select the T coordinate given a selected face.</desc> |
| <src absneg="true">Y coordinate as 32-bit floating point</src> |
| <src absneg="true">Z coordinate as 32-bit floating point</src> |
| <src>Cube face index</src> |
| </ins> |
| |
| <ins name="MKVEC.v2i8" title="Make 8-bit vector" dests="1" opcode="0xBD" unit="CVT"> |
| <desc> |
| Calculates $A | (B \ll 8) | (CD \ll 16)$ for 8-bit A and B and 16-bit CD. |
| |
| To implement `(uchar4) (A, B, C, D)` in full generality, use the sequence |
| `MKVEC.v2i8 CD, C, D, #0; MKVEC.v2i8 out, A, B, CD` |
| |
| `MKVEC.v2i8` also allows zero extending arbitrary 8-bit lanes. For |
| example, to extend `r0.b3` to `r1`, use `MKVEC.v2i8 r1, r0.b3, 0x0.b0, 0x0`. |
| </desc> |
| <src lane="true">A</src> |
| <src lane="true">B</src> |
| <src>CD</src> |
| </ins> |
| |
| <ins name="CUBEFACE1" title="Cube map transform step 1" dests="1" opcode="0xC0" unit="SFU"> |
| <desc>Select the maximum absolute value of its arguments.</desc> |
| <src absneg="true">X coordinate as 32-bit floating point</src> |
| <src absneg="true">Y coordinate as 32-bit floating point</src> |
| <src absneg="true">Z coordinate as 32-bit floating point</src> |
| </ins> |
| |
| <ins name="CUBEFACE2" title="Cube map transform step 2" dests="1" opcode="0xC1" unit="SFU"> |
| <desc>Select the cube face index corresponding to the arguments.</desc> |
| <src absneg="true">X coordinate as 32-bit floating point</src> |
| <src absneg="true">Y coordinate as 32-bit floating point</src> |
| <src absneg="true">Z coordinate as 32-bit floating point</src> |
| </ins> |
| |
| <group name="IDP" title="8-bit dot product" dests="1" opcode="0xC2" unit="FMA"> |
| <desc> |
| 8-bit integer dot product between 4 channel vectors, intended for machine |
| learning. Available in both unsigned and signed variants, controlling |
| sign-extension/zero-extension behaviour to the final 32-bit destination. |
| Saturation is available. Corresponds to the `cl_arm_integer_dot_product_*` |
| family of OpenCL extensions. Not for actual use, just for completeness. |
| Instead, use your platform's neural accelerator. |
| |
| For $A, B \in \{ 0, \ldots, 255 \}^4$ and $\text{Accumulator} \in |
| \mathbb{Z}$, calculates $(A \cdot B) + \text{Accumulator}$ and optionally |
| saturates. |
| </desc> |
| <ins name="IDP.v4s8" opcode2="0"/> |
| <ins name="IDP.v4u8" opcode2="1"/> |
| <src>A</src> |
| <src>B</src> |
| <src>Accumulator</src> |
| <saturate/> |
| </group> |
| |
| <group name="ICMP_OR" title="Unsigned integer compare" dests="1" unit="CVT" opcode2="0"> |
| <desc> |
| Evaluates the given condition, do a logical or with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic; |
| when this is not desired, tie it to zero. |
| </desc> |
| <ins name="ICMP_OR.u32" opcode="0xF0"/> |
| <ins name="ICMP_OR.v2u16" opcode="0xF1"/> |
| <ins name="ICMP_OR.v4u8" opcode="0xF2"/> |
| <cmp/> |
| <result_type/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="ICMP_AND" title="Unsigned integer compare" dests="1" unit="CVT" opcode2="1"> |
| <desc> |
| Evaluates the given condition, do a logical and with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic. |
| </desc> |
| <ins name="ICMP_AND.u32" opcode="0xF0"/> |
| <ins name="ICMP_AND.v2u16" opcode="0xF1"/> |
| <ins name="ICMP_AND.v4u8" opcode="0xF2"/> |
| <cmp/> |
| <result_type/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="FCMP_OR" title="Floating-point compare" dests="1" unit="CVT" opcode2="0"> |
| <desc> |
| Evaluates the given condition, do a logical or with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic; |
| when this is not desired, tie it to zero. |
| </desc> |
| <ins name="FCMP_OR.f32" opcode="0xF4"/> |
| <ins name="FCMP_OR.v2f16" opcode="0xF5"/> |
| <cmp/> |
| <result_type/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="FCMP_AND" title="Floating-point compare" dests="1" unit="CVT" opcode2="1"> |
| <desc> |
| Evaluates the given condition, do a logical and/or with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic. |
| </desc> |
| <ins name="FCMP_AND.f32" opcode="0xF4"/> |
| <ins name="FCMP_AND.v2f16" opcode="0xF5"/> |
| <cmp/> |
| <result_type/> |
| <src absneg="true" swizzle="true">A</src> |
| <src absneg="true" swizzle="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="ICMP_OR" title="Signed integer compare" dests="1" unit="CVT" opcode2="0"> |
| <desc> |
| Evaluates the given condition, do a logical or with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic. |
| </desc> |
| <ins name="ICMP_OR.s32" opcode="0xF8"/> |
| <ins name="ICMP_OR.v2s16" opcode="0xF9"/> |
| <ins name="ICMP_OR.v4s8" opcode="0xFA"/> |
| <cmp/> |
| <result_type/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="ICMP_AND" title="Signed integer compare" dests="1" unit="CVT" opcode2="1"> |
| <desc> |
| Evaluates the given condition, do a logical and with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic. |
| </desc> |
| <ins name="ICMP_AND.s32" opcode="0xF8"/> |
| <ins name="ICMP_AND.v2s16" opcode="0xF9"/> |
| <ins name="ICMP_AND.v4s8" opcode="0xFA"/> |
| <cmp/> |
| <result_type/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <group name="ICMP_MULTI" title="Integer compare" dests="1" unit="CVT" opcode2="2"> |
| <desc> |
| Evaluates the given condition, do a logical and/or with the condition in |
| the result source, and return in the given result type (integer |
| one, integer minus one, or floating-point one). The third source is useful |
| for chaining together conditions without intermediate bitwise arithmetic; |
| when this is not desired, tie it to zero and use the OR combine mode (do |
| not set the `.and` modifier). |
| |
| Used to construct signed 64-bit compares |
| in 1 `ICMP.u32` and 1 `ICMP.s32` instruction, in conjunction with the `u1` |
| result type on the low half, the `m1` result type on the high half, and |
| the result of the low half comparison passed as the third source. |
| </desc> |
| <ins name="ICMP_MULTI.u32" opcode="0xF0"/> |
| <ins name="ICMP_MULTI.s32" opcode="0xF8"/> |
| <cmp/> |
| <result_type/> |
| <src widen="true">A</src> |
| <src widen="true">B</src> |
| <src>C</src> |
| </group> |
| |
| <ins name="IADD_IMM.i32" title="Integer addition with immediate" dests="1" opcode="0x110" unit="CVT"> |
| <desc> |
| Adds an arbitrary 32-bit immediate embedded within the instruction stream. |
| If no modifiers are required, this is preferred to `IADD.i32` with a |
| constant accessed as a uniform. However, if the constant is available |
| inline, `IADD.i32` is preferred. |
| |
| `IADD_IMM.i32` with the source tied to zero is the canonical immediate move. |
| </desc> |
| <src>A</src> |
| <imm name="constant" start="8" size="32"/> |
| </ins> |
| |
| <ins name="IADD_IMM.v2i16" title="Integer addition with immediate" dests="1" opcode="0x111" unit="CVT"> |
| <desc> |
| Adds an arbitrary pair of 16-bit immediates embedded within the |
| instruction stream. If no modifiers are required, this is preferred to |
| `IADD.v2i16` with a constant accessed as a uniform. However, if the |
| constant is available inline, `IADD.v2i16` is preferred. Adding only a |
| single 16-bit constant requires replication of the constant. |
| </desc> |
| <src>A</src> |
| <imm name="constant" start="8" size="32"/> |
| </ins> |
| |
| <ins name="IADD_IMM.v4i8" title="Integer addition with immediate" dests="1" opcode="0x112" unit="CVT"> |
| <desc> |
| Adds an arbitrary quad of 8-bit immediates embedded within the |
| instruction stream. If no modifiers are required, this is preferred to |
| `IADD.v4i8` with a constant accessed as a uniform. However, if the |
| constant is available inline, `IADD.v4i8` is preferred. Adding only a |
| single 8-bit constant requires replication of the constant. |
| </desc> |
| <src>A</src> |
| <imm name="constant" start="8" size="32"/> |
| </ins> |
| |
| <ins name="FADD_IMM.f32" title="Floating-point addition with immediate" dests="1" opcode="0x114" unit="FMA"> |
| <desc> |
| Adds an arbitrary 32-bit immediate embedded within the instruction stream. |
| If no modifiers are required, this is preferred to `FADD.f32` with a |
| constant accessed as a uniform. However, if the constant is available |
| inline, `FADD.f32` is preferred. |
| </desc> |
| <src>A</src> |
| <imm name="constant" start="8" size="32"/> |
| </ins> |
| |
| <ins name="FADD_IMM.v2f16" title="Floating-point addition with immediate" dests="1" opcode="0x115" unit="FMA"> |
| <desc> |
| Adds an arbitrary pair of 16-bit immediates embedded within the |
| instruction stream. If no modifiers are required, this is preferred to |
| `FADD.v2f16` with a constant accessed as a uniform. However, if the |
| constant is available inline, `FADD.v2f16` is preferred. Adding only a |
| single 16-bit constant requires replication of the constant. |
| </desc> |
| <src float="true">A</src> |
| <imm name="constant" start="8" size="32"/> |
| </ins> |
| |
| <ins name="ATOM1_RETURN.i32" title="Atomic operations on memory with 1" opcode="0x69" opcode2="3" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <atom_opc_1/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <!-- Optional for ATOM1.i32, in which sr_count must be 0 --> |
| <sr write="true"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="ATOM1_RETURN.i64" title="Atomic operations on memory with 1" opcode="0x69" opcode2="5" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <atom_opc_1/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <!-- Optional for ATOM1.i64, in which sr_count must be 0 --> |
| <sr write="true"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="ATOM.i32" title="Atomic operations on memory" opcode="0x68" opcode2="3" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <atom_opc/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <sr read="true"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="ATOM.i64" title="Atomic operations on memory" opcode="0x68" opcode2="5" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <atom_opc/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <sr read="true"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="ATOM_RETURN.i32" title="Atomic operations on memory" opcode="0x120" opcode2="3" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <sr_write_count/> |
| |
| <!-- Only valid with .xchg to implement ACMPXCHG --> |
| <mod name="compare" start="26" size="1"/> |
| |
| <atom_opc/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="rw"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="ATOM_RETURN.i64" title="Atomic operations on memory" opcode="0x120" opcode2="5" unit="LS"> |
| <slot/> |
| <sr_count/> |
| <sr_write_count/> |
| <mod name="compare" start="26" size="1"/> |
| <atom_opc/> |
| <mod name="memory_width" start="128" size="1" implied="true"/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="rw"/> |
| <src size="64">64-bit address to operate on</src> |
| <imm name="offset" start="8" size="8"/> |
| </ins> |
| |
| <ins name="TEX_FETCH" title="Texel fetch" opcode="0x125" unit="T"> |
| <desc>Unfiltered textured instruction.</desc> |
| <slot/> |
| <skip/> |
| <register_type/> |
| <register_width/> |
| <write_mask/> |
| <dimension/> |
| <wide_indices/> |
| <array_enable/> |
| <texel_offset/> |
| |
| <!-- Leave secondary_register_width as 0 --> |
| <sr_count/> |
| <sr_write_count/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="false"/> |
| <src size="64">Image to read from</src> |
| </ins> |
| |
| <ins name="TEX_SINGLE" title="Texture load" opcode="0x128" unit="T"> |
| <desc>Ordinary texturing instruction using a sampler.</desc> |
| <slot/> |
| <skip/> |
| <register_type/> |
| <register_width/> |
| <write_mask/> |
| <dimension/> |
| <wide_indices/> |
| <array_enable/> |
| <texel_offset/> |
| <shadow/> |
| <lod_mode/> |
| |
| <!-- Leave secondary_register_width as 0 --> |
| <sr_count/> |
| <sr_write_count/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="false"/> |
| <src size="64">Image to read from</src> |
| </ins> |
| |
| <ins name="TEX_GATHER" title="Texel gather" opcode="0x129" unit="T"> |
| <desc>Texture gather instruction.</desc> |
| <slot/> |
| <skip/> |
| <register_type/> |
| <register_width/> |
| <write_mask/> |
| <dimension/> |
| <wide_indices/> |
| <array_enable/> |
| <texel_offset/> |
| <integer_coordinates/> |
| <fetch_component/> |
| <shadow/> |
| |
| <!-- Leave secondary_register_width as 0 --> |
| <sr_count/> |
| <sr_write_count/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="false"/> |
| <src size="64">Image to read from</src> |
| </ins> |
| |
| <ins name="TEX_DUAL" title="Dual texture" opcode="0x12F" unit="T"> |
| <desc>Pair of texture instructions.</desc> |
| <slot/> |
| <skip/> |
| <register_type/> |
| <register_width/> |
| <secondary_register_width/> |
| <write_mask/> |
| <dimension/> |
| <wide_indices/> |
| <array_enable/> |
| <texel_offset/> |
| <shadow/> |
| <lod_mode/> |
| |
| <sr_count/> |
| <sr_write_count/> |
| |
| <sr write="true" flags="false"/> |
| <sr read="true" flags="false"/> |
| <src size="64">Image to read from</src> |
| </ins> |
| |
| <ins name="VAR_TEX_BUF_SINGLE" title="Fused varying-texturing" opcode="0x130" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_BUF_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_mode/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_BUF_GATHER" title="Fused varying-texturing" opcode="0x131" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_BUF_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <integer_coordinates/> |
| <fetch_component/> |
| <shadow/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_BUF_GRADIENT" title="Fused varying-texturing" opcode="0x132" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_BUF_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_bias_disable/> |
| <lod_clamp_disable/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_BUF_DUAL" title="Fused varying-texturing" opcode="0x137" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_BUF_IMM_F32.v2.f32 followed by TEX_DUAL, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_mode/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_SINGLE" title="Fused varying-texturing" opcode="0x138" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_mode/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_GATHER" title="Fused varying-texturing" opcode="0x139" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <integer_coordinates/> |
| <fetch_component/> |
| <shadow/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_GRADIENT" title="Fused varying-texturing" opcode="0x13A" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_IMM_F32.v2.f32 followed by TEX, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_bias_disable/> |
| <lod_clamp_disable/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="VAR_TEX_DUAL" title="Fused varying-texturing" opcode="0x13F" unit="VT"> |
| <desc> |
| Only works for FP32 varyings. Performance characteristics are similar |
| to LD_VAR_IMM_F32.v2.f32 followed by TEX_DUAL, using both V and T units. |
| </desc> |
| <slot/> |
| <skip/> |
| <sample_and_update/> |
| <register_type/> |
| <vartex_register_width/> |
| <dimension/> |
| <array_enable/> |
| <shadow/> |
| <lod_mode/> |
| |
| <sr_write_count/> |
| |
| <sr write="true"/> |
| <src size="64">Image to read from</src> |
| <src>Varying offset</src> |
| </ins> |
| |
| <ins name="FMA_RSCALE.f32" title="Fused floating-point multiply add with exponent bias" dests="1" opcode="0x160" unit="FMA"> |
| <desc> |
| First calculates $A \cdot B + C$ and then biases the exponent by D. Used in |
| special transcendental function sequences. It should not be used for |
| general code as its special case handling differs from two back-to-back |
| `FMA.f32` operations. Equivalent to `FMA.f32` back-to-back with |
| `LDEXP.f32` |
| </desc> |
| <clamp/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| <src absneg="true">C</src> |
| <src>D</src> |
| </ins> |
| |
| <ins name="FMA_RSCALE_N.f32" title="Fused floating-point multiply add with exponent bias and zero override" dests="1" opcode="0x161" unit="FMA"> |
| <desc> |
| First calculates $A \cdot B + C$ and then biases the exponent by D. If $A |
| = 0$ or $B = 0$, the multiply $A \cdot B$ is treated as zero even if an |
| ordinary multiply would return NaN. Used in special transcendental |
| function sequences. It should not be used for general code as its special |
| case handling differs from two back-to-back `FMA.f32` operations. |
| Equivalent to `FMA.f32` back-to-back with `LDEXP.f32` |
| </desc> |
| <clamp/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| <src absneg="true">C</src> |
| <src>D</src> |
| </ins> |
| |
| <ins name="FMA_RSCALE_LEFT.f32" title="Fused floating-point multiply add with exponent bias and asymmetric zero handling" dests="1" opcode="0x162" unit="FMA"> |
| <desc> |
| First calculates $A \cdot B + C$ and then biases the exponent by D. If $A |
| = 0$ or $B = 0$, the multiply is treated as $A$ even if an |
| ordinary multiply would return NaN. Used in special transcendental |
| function sequences. It should not be used for general code as its special |
| case handling differs from two back-to-back `FMA.f32` operations. |
| Equivalent to `FMA.f32` back-to-back with `LDEXP.f32` |
| </desc> |
| <clamp/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| <src absneg="true">C</src> |
| <src>D</src> |
| </ins> |
| |
| <ins name="FMA_RSCALE_SCALE16.f32" title="Fused floating-point multiply add with 16-bit exponent bias" dests="1" opcode="0x163" unit="FMA"> |
| <desc> |
| First calculates $A \cdot B + C$ and then biases the exponent by D, |
| interpreted as a 16-bit value. Used in special transcendental function |
| sequences. It should not be used for general code as its special case |
| handling differs from two back-to-back `FMA.f32` operations. Equivalent |
| to `FMA.f32` back-to-back with `LDEXP.f32` |
| </desc> |
| <clamp/> |
| <src absneg="true">A</src> |
| <src absneg="true">B</src> |
| <src absneg="true">C</src> |
| <src>D</src> |
| </ins> |
| |
| </valhall> |