17ec681f3Smrg<!--
27ec681f3Smrg  Copyright (C) 2021 Collabora Ltd.
37ec681f3Smrg
47ec681f3Smrg  Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg  copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg  to deal in the Software without restriction, including without limitation
77ec681f3Smrg  the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg  and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg  Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg
117ec681f3Smrg  The above copyright notice and this permission notice (including the next
127ec681f3Smrg  paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg  Software.
147ec681f3Smrg
157ec681f3Smrg  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
207ec681f3Smrg  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
217ec681f3Smrg  SOFTWARE.
227ec681f3Smrg-->
237ec681f3Smrg
247ec681f3Smrg<valhall>
257ec681f3Smrg  <lut name="Immediates">
267ec681f3Smrg    <desc>
277ec681f3Smrg      This immediates are accessible in (almost) any instruction, provided the
287ec681f3Smrg      immediate mode is kept to the default. They optimize for the most common
297ec681f3Smrg      immediate values; any immediate listed here may be used without taking up
307ec681f3Smrg      a uniform slot or a register. Most integer instructions can access
317ec681f3Smrg      separate half-words and individual bytes via swizzles on the source.
327ec681f3Smrg    </desc>
337ec681f3Smrg    <constant desc="Zero">0x00000000</constant>
347ec681f3Smrg    <constant desc="All ones; integer $-1$">0xFFFFFFFF</constant>
357ec681f3Smrg    <constant desc="Maximum integer; floating-point NaN">0x7FFFFFFF</constant>
367ec681f3Smrg    <constant desc="Integers $(-2, -3, -4, -5)$">0xFAFCFDFE</constant>
377ec681f3Smrg    <constant desc="16-bit integer $2^8$">0x01000000</constant>
387ec681f3Smrg    <constant desc="Multiples of 16 $(0, 32, 0, 128)$">0x80002000</constant>
397ec681f3Smrg    <constant desc="Multiples of 16 $(48, 80, 96, 112)$">0x70605030</constant>
407ec681f3Smrg    <constant desc="Multiples of 16 $(144, 160, 176, 192)$">0xC0B0A090</constant>
417ec681f3Smrg    <constant desc="Integers $(0, 1, 2, 3)$">0x03020100</constant>
427ec681f3Smrg    <constant desc="Integers $(4, 5, 6, 7)$">0x07060504</constant>
437ec681f3Smrg    <constant desc="Integers $(8, 9, 10, 11)$">0x0B0A0908</constant>
447ec681f3Smrg    <constant desc="Integers $(12, 13, 14, 15)$">0x0F0E0D0C</constant>
457ec681f3Smrg    <constant desc="Integers $(16, 17, 18, 19)$">0x13121110</constant>
467ec681f3Smrg    <constant desc="Integers $(20, 21, 22, 23)$">0x17161514</constant>
477ec681f3Smrg    <constant desc="Integers $(24, 25, 26, 27)$">0x1B1A1918</constant>
487ec681f3Smrg    <constant desc="Integers $(28, 29, 30, 31)$">0x1F1E1D1C</constant>
497ec681f3Smrg    <constant desc="Float $1.0$">0x3F800000</constant>
507ec681f3Smrg    <constant desc="Float $0.1$">0x3DCCCCCD</constant>
517ec681f3Smrg    <constant desc="Float $1 / \pi$">0x3EA2F983</constant>
527ec681f3Smrg    <constant desc="Float $\log(2)$">0x3F317218</constant>
537ec681f3Smrg    <constant desc="Float $\pi$">0x40490FDB</constant>
547ec681f3Smrg    <constant desc="Float $0.0$">0x00000000</constant>
557ec681f3Smrg    <constant desc="Float $65535.0 = 2^{16} - 1$">0x477FFF00</constant>
567ec681f3Smrg    <constant desc="Half-float $(255.0, 256.0) = (2^8 - 1, 2^8)$">0x5C005BF8</constant>
577ec681f3Smrg    <constant desc="Half-float $0.1 = 1 / 10$">0x2E660000</constant>
587ec681f3Smrg    <constant desc="Half-float $0.25 = 2^{-2}$">0x34000000</constant>
597ec681f3Smrg    <constant desc="Half-float $0.5 = 2^{-1}$">0x38000000</constant>
607ec681f3Smrg    <constant desc="Half-float $1.0 = 2^0$">0x3C000000</constant>
617ec681f3Smrg    <constant desc="Half-float $2.0 = 2^1$">0x40000000</constant>
627ec681f3Smrg    <constant desc="Half-float $4.0 = 2^2$">0x44000000</constant>
637ec681f3Smrg    <constant desc="Half-float $8.0 = 2^3$">0x48000000</constant>
647ec681f3Smrg    <constant desc="Half-float $\pi$">0x42480000</constant>
657ec681f3Smrg  </lut>
667ec681f3Smrg
677ec681f3Smrg  <enum name="Action">
687ec681f3Smrg    <desc>
697ec681f3Smrg      Every Valhall instruction can perform an action, like wait on dependency
707ec681f3Smrg      slots. A few special actions are available, specified in the instruction
717ec681f3Smrg      metadata from this enum. The `wait0126` action is required to wait on
727ec681f3Smrg      dependency slot #6 and should be set on the instruction immediately
737ec681f3Smrg      preceding `ATEST`. The `barrier` action may be set on any instruction for
747ec681f3Smrg      subgroup barriers, and should particularly be set with the `BARRIER`
757ec681f3Smrg      instruction for global barriers. The `td` action only applies to fragment
767ec681f3Smrg      shaders and is used to terminate helper invocations, it should be set as
777ec681f3Smrg      early as possible after helper invocations are no longer needed as
787ec681f3Smrg      determined by data flow analysis. The `return` action is used to terminate
797ec681f3Smrg      the shader, although it may be overloaded by the `BLEND` instruction.
807ec681f3Smrg
817ec681f3Smrg      The `reconverge` action is required on any instruction immediately
827ec681f3Smrg      preceding a possible change to the mask of active threads in a subgroup.
837ec681f3Smrg      This includes all divergent branches, but it also includes the final
847ec681f3Smrg      instruction at the end of any basic block where the immediate successor
857ec681f3Smrg      (fallthrough) is the target of a divergent branch.
867ec681f3Smrg    </desc>
877ec681f3Smrg    <value name="Wait on all dependency slots">wait0126</value>
887ec681f3Smrg    <value name="Subgroup barrier">barrier</value>
897ec681f3Smrg    <value name="Perform branch reconverge">reconverge</value>
907ec681f3Smrg    <reserved/>
917ec681f3Smrg    <reserved/>
927ec681f3Smrg    <value name="Terminate discarded threads">td</value>
937ec681f3Smrg    <reserved/>
947ec681f3Smrg    <value name="Return from shader">return</value>
957ec681f3Smrg  </enum>
967ec681f3Smrg
977ec681f3Smrg  <enum name="Immediate mode">
987ec681f3Smrg    <desc>Selects how immediates sources are interpreted.</desc>
997ec681f3Smrg    <value desc="No special immediates" default="true">none</value>
1007ec681f3Smrg    <value desc="Thread storage pointers">ts</value>
1017ec681f3Smrg    <reserved/>
1027ec681f3Smrg    <value desc="Thread identification">id</value>
1037ec681f3Smrg  </enum>
1047ec681f3Smrg
1057ec681f3Smrg  <enum name="Thread storage pointers">
1067ec681f3Smrg    <desc>
1077ec681f3Smrg      Situated between the immediates hard-coded in the hardware and the
1087ec681f3Smrg      uniforms defined purely in software, Valhall has a some special
1097ec681f3Smrg      "constants" passing through data structures. These are encoded like the
1107ec681f3Smrg      table of immediates, as if special constant $i$ were lookup table entry
1117ec681f3Smrg      $32 + i$. These special values are selected with the `.ts` modifier.
1127ec681f3Smrg    </desc>
1137ec681f3Smrg    <reserved/>
1147ec681f3Smrg    <reserved/>
1157ec681f3Smrg    <value desc="Thread local storage base pointer (low word)">tls_ptr</value>
1167ec681f3Smrg    <value desc="Thread local storage base pointer (high word)">tls_ptr_hi</value>
1177ec681f3Smrg    <reserved/>
1187ec681f3Smrg    <reserved/>
1197ec681f3Smrg    <value desc="Workgroup local storage base pointer (low word)">wls_ptr</value>
1207ec681f3Smrg    <value desc="Workgroup local storage base pointer (high word)">wls_ptr_hi</value>
1217ec681f3Smrg  </enum>
1227ec681f3Smrg
1237ec681f3Smrg  <enum name="Thread identification">
1247ec681f3Smrg    <desc>
1257ec681f3Smrg      Situated between the immediates hard-coded in the hardware and the
1267ec681f3Smrg      uniforms defined purely in software, Valhall has a some special
1277ec681f3Smrg      "constants" passing through data structures. These are encoded like the
1287ec681f3Smrg      table of immediates, as if special constant $i$ were lookup table entry
1297ec681f3Smrg      $32 + i$. These special values are selected with the `.id` modifier.
1307ec681f3Smrg    </desc>
1317ec681f3Smrg    <reserved/>
1327ec681f3Smrg    <reserved/>
1337ec681f3Smrg    <value desc="Lane ID">lane_id</value>
1347ec681f3Smrg    <reserved/>
1357ec681f3Smrg    <reserved/>
1367ec681f3Smrg    <reserved/>
1377ec681f3Smrg    <value desc="Core ID">core_id</value>
1387ec681f3Smrg    <reserved/>
1397ec681f3Smrg    <reserved/>
1407ec681f3Smrg    <reserved/>
1417ec681f3Smrg    <reserved/>
1427ec681f3Smrg    <reserved/>
1437ec681f3Smrg    <reserved/>
1447ec681f3Smrg    <reserved/>
1457ec681f3Smrg    <reserved/>
1467ec681f3Smrg    <reserved/>
1477ec681f3Smrg    <reserved/>
1487ec681f3Smrg    <reserved/>
1497ec681f3Smrg    <reserved/>
1507ec681f3Smrg    <reserved/>
1517ec681f3Smrg    <reserved/>
1527ec681f3Smrg    <reserved/>
1537ec681f3Smrg    <reserved/>
1547ec681f3Smrg    <reserved/>
1557ec681f3Smrg    <reserved/>
1567ec681f3Smrg    <reserved/>
1577ec681f3Smrg    <reserved/>
1587ec681f3Smrg    <reserved/>
1597ec681f3Smrg    <reserved/>
1607ec681f3Smrg    <reserved/>
1617ec681f3Smrg    <value desc="Program counter">program_counter</value>
1627ec681f3Smrg    <reserved/>
1637ec681f3Smrg  </enum>
1647ec681f3Smrg
1657ec681f3Smrg  <enum name="Swizzles (8-bit)">
1667ec681f3Smrg    <value default="true">b0123</value>
1677ec681f3Smrg    <value>b3210</value>
1687ec681f3Smrg    <value>b0101</value>
1697ec681f3Smrg    <value>b2323</value>
1707ec681f3Smrg    <value>b0000</value>
1717ec681f3Smrg    <value>b1111</value>
1727ec681f3Smrg    <value>b2222</value>
1737ec681f3Smrg    <value>b3333</value>
1747ec681f3Smrg    <value>b2301</value>
1757ec681f3Smrg    <value>b1032</value>
1767ec681f3Smrg    <value>b0011</value>
1777ec681f3Smrg    <value>b2233</value>
1787ec681f3Smrg    <reserved/>
1797ec681f3Smrg    <reserved/>
1807ec681f3Smrg    <reserved/>
1817ec681f3Smrg    <reserved/>
1827ec681f3Smrg  </enum>
1837ec681f3Smrg
1847ec681f3Smrg  <enum name="Lanes (8-bit)">
1857ec681f3Smrg    <desc>Used to select the 2 bytes for shifts of 16-bit vectors</desc>
1867ec681f3Smrg    <value>b02</value>
1877ec681f3Smrg    <reserved/>
1887ec681f3Smrg    <reserved/>
1897ec681f3Smrg    <reserved/>
1907ec681f3Smrg    <value>b00</value>
1917ec681f3Smrg    <value>b11</value>
1927ec681f3Smrg    <value>b22</value>
1937ec681f3Smrg    <value>b33</value>
1947ec681f3Smrg    <reserved/>
1957ec681f3Smrg    <reserved/>
1967ec681f3Smrg    <value>b01</value>
1977ec681f3Smrg    <value>b23</value>
1987ec681f3Smrg    <reserved/>
1997ec681f3Smrg    <reserved/>
2007ec681f3Smrg    <reserved/>
2017ec681f3Smrg    <reserved/>
2027ec681f3Smrg  </enum>
2037ec681f3Smrg
2047ec681f3Smrg  <enum name="Swizzles (16-bit)">
2057ec681f3Smrg    <value>h00</value> <!-- 0,2 -->
2067ec681f3Smrg    <value>h10</value>
2077ec681f3Smrg    <value default="true">h01</value>
2087ec681f3Smrg    <value>h11</value>
2097ec681f3Smrg    <value>b00</value> <!-- 0,0 -->
2107ec681f3Smrg    <value>b20</value> <!-- 1,1 -->
2117ec681f3Smrg    <value>b02</value> <!-- 2,2 -->
2127ec681f3Smrg    <value>b22</value> <!-- 3,3 -->
2137ec681f3Smrg    <value>b11</value>
2147ec681f3Smrg    <value>b31</value>
2157ec681f3Smrg    <value>b13</value> <!-- 0,1 -->
2167ec681f3Smrg    <value>b33</value> <!-- 2,3 -->
2177ec681f3Smrg    <value>b01</value>
2187ec681f3Smrg    <value>b23</value>
2197ec681f3Smrg    <reserved/>
2207ec681f3Smrg    <reserved/>
2217ec681f3Smrg  </enum>
2227ec681f3Smrg
2237ec681f3Smrg  <enum name="Swizzles (32-bit)">
2247ec681f3Smrg    <value default="true">none</value>
2257ec681f3Smrg    <reserved/>
2267ec681f3Smrg    <value>h0</value>
2277ec681f3Smrg    <value>h1</value>
2287ec681f3Smrg    <value>b0</value>
2297ec681f3Smrg    <value>b1</value>
2307ec681f3Smrg    <value>b2</value>
2317ec681f3Smrg    <value>b3</value>
2327ec681f3Smrg  </enum>
2337ec681f3Smrg
2347ec681f3Smrg  <enum name="Swizzles (64-bit)">
2357ec681f3Smrg    <value default="true">none</value>
2367ec681f3Smrg    <reserved/>
2377ec681f3Smrg    <value>h0</value>
2387ec681f3Smrg    <value>h1</value>
2397ec681f3Smrg    <value>b0</value>
2407ec681f3Smrg    <value>b1</value>
2417ec681f3Smrg    <value>b2</value>
2427ec681f3Smrg    <value>b3</value>
2437ec681f3Smrg    <value>w0</value>
2447ec681f3Smrg    <reserved/>
2457ec681f3Smrg    <reserved/>
2467ec681f3Smrg    <reserved/>
2477ec681f3Smrg    <reserved/>
2487ec681f3Smrg    <reserved/>
2497ec681f3Smrg    <reserved/>
2507ec681f3Smrg    <reserved/>
2517ec681f3Smrg  </enum>
2527ec681f3Smrg
2537ec681f3Smrg  <enum name="Lane (8-bit)" implied="true">
2547ec681f3Smrg    <value>b0</value>
2557ec681f3Smrg    <value>b1</value>
2567ec681f3Smrg    <value>b2</value>
2577ec681f3Smrg    <value>b3</value>
2587ec681f3Smrg  </enum>
2597ec681f3Smrg
2607ec681f3Smrg  <enum name="Lane (32-bit)">
2617ec681f3Smrg    <desc>
2627ec681f3Smrg      Used for the lane select of `BRANCHZ`. To use an 8-bit condition, a
2637ec681f3Smrg      separate `ICMP` is required to cast to 16-bit.
2647ec681f3Smrg    </desc>
2657ec681f3Smrg    <value default="true">none</value>
2667ec681f3Smrg    <value>h0</value>
2677ec681f3Smrg    <value>h1</value>
2687ec681f3Smrg    <reserved/>
2697ec681f3Smrg  </enum>
2707ec681f3Smrg
2717ec681f3Smrg  <enum name="Lane (16-bit)" implied="true">
2727ec681f3Smrg    <value>h0</value>
2737ec681f3Smrg    <value>h1</value>
2747ec681f3Smrg  </enum>
2757ec681f3Smrg
2767ec681f3Smrg  <enum name="Load lane (8-bit)">
2777ec681f3Smrg    <value default="true">b0</value>
2787ec681f3Smrg    <value>b1</value>
2797ec681f3Smrg    <value>b2</value>
2807ec681f3Smrg    <value>b3</value>
2817ec681f3Smrg    <value desc="Zero-extend to 16-bit, low-half">h0</value>
2827ec681f3Smrg    <value desc="Zero-extend to 16-bit, high-half">h1</value>
2837ec681f3Smrg    <value desc="Zero-extend to 32-bit">w0</value>
2847ec681f3Smrg    <value desc="Zero-extend to 32-bit">d0</value>
2857ec681f3Smrg  </enum>
2867ec681f3Smrg
2877ec681f3Smrg  <enum name="Load lane (16-bit)">
2887ec681f3Smrg    <value desc="Low half" default="true">h0</value>
2897ec681f3Smrg    <value desc="High half">h1</value>
2907ec681f3Smrg    <value desc="Zero-extend to 32-bit">w0</value>
2917ec681f3Smrg    <value desc="Zero-extend to 64-bit">d0</value>
2927ec681f3Smrg    <reserved/>
2937ec681f3Smrg    <reserved/>
2947ec681f3Smrg    <reserved/>
2957ec681f3Smrg    <reserved/>
2967ec681f3Smrg  </enum>
2977ec681f3Smrg
2987ec681f3Smrg  <enum name="Load lane (24-bit)" implied="true">
2997ec681f3Smrg    <value default="true">identity</value>
3007ec681f3Smrg    <reserved/>
3017ec681f3Smrg    <reserved/>
3027ec681f3Smrg    <reserved/>
3037ec681f3Smrg    <reserved/>
3047ec681f3Smrg    <reserved/>
3057ec681f3Smrg    <reserved/>
3067ec681f3Smrg  </enum>
3077ec681f3Smrg
3087ec681f3Smrg  <enum name="Load lane (32-bit)">
3097ec681f3Smrg    <value default="true">w0</value>
3107ec681f3Smrg    <value desc="Zero-extend to 64-bit">d0</value>
3117ec681f3Smrg    <reserved/>
3127ec681f3Smrg    <reserved/>
3137ec681f3Smrg    <reserved/>
3147ec681f3Smrg    <reserved/>
3157ec681f3Smrg    <reserved/>
3167ec681f3Smrg    <reserved/>
3177ec681f3Smrg  </enum>
3187ec681f3Smrg
3197ec681f3Smrg  <enum name="Load lane (48-bit)">
3207ec681f3Smrg    <reserved/>
3217ec681f3Smrg    <reserved/>
3227ec681f3Smrg    <reserved/>
3237ec681f3Smrg    <reserved/>
3247ec681f3Smrg    <value default="true">identity</value>
3257ec681f3Smrg    <reserved/>
3267ec681f3Smrg    <reserved/>
3277ec681f3Smrg    <reserved/>
3287ec681f3Smrg  </enum>
3297ec681f3Smrg
3307ec681f3Smrg  <enum name="Load lane (64-bit)">
3317ec681f3Smrg    <reserved/>
3327ec681f3Smrg    <reserved/>
3337ec681f3Smrg    <reserved/>
3347ec681f3Smrg    <reserved/>
3357ec681f3Smrg    <reserved/>
3367ec681f3Smrg    <reserved/>
3377ec681f3Smrg    <reserved/>
3387ec681f3Smrg    <value default="true">identity</value>
3397ec681f3Smrg  </enum>
3407ec681f3Smrg
3417ec681f3Smrg  <enum name="Load lane (96-bit)">
3427ec681f3Smrg    <reserved/>
3437ec681f3Smrg    <reserved/>
3447ec681f3Smrg    <reserved/>
3457ec681f3Smrg    <reserved/>
3467ec681f3Smrg    <reserved/>
3477ec681f3Smrg    <reserved/>
3487ec681f3Smrg    <value default="true">identity</value>
3497ec681f3Smrg    <reserved/>
3507ec681f3Smrg  </enum>
3517ec681f3Smrg
3527ec681f3Smrg  <enum name="Load lane (128-bit)">
3537ec681f3Smrg    <reserved/>
3547ec681f3Smrg    <reserved/>
3557ec681f3Smrg    <reserved/>
3567ec681f3Smrg    <reserved/>
3577ec681f3Smrg    <reserved/>
3587ec681f3Smrg    <reserved/>
3597ec681f3Smrg    <reserved/>
3607ec681f3Smrg    <value default="true">identity</value>
3617ec681f3Smrg  </enum>
3627ec681f3Smrg
3637ec681f3Smrg  <enum name="Round mode">
3647ec681f3Smrg    <desc>Corresponds to IEEE 754 rounding modes</desc>
3657ec681f3Smrg    <value desc="Round to nearest even" default="true">rte</value>
3667ec681f3Smrg    <value desc="Round to positive infinity">rtp</value>
3677ec681f3Smrg    <value desc="Round to negative infinity">rtn</value>
3687ec681f3Smrg    <value desc="Round to zero">rtz</value>
3697ec681f3Smrg  </enum>
3707ec681f3Smrg
3717ec681f3Smrg  <enum name="Result type">
3727ec681f3Smrg    <desc>
3737ec681f3Smrg      Comparison instructions like `FCMP` return a boolean but may encode this
3747ec681f3Smrg      boolean in a variety of ways. `i1` gives a OpenGL style `0/1` boolean.
3757ec681f3Smrg      `m1` gives a Direct3D style `0/~0` boolean. `f1` gives a floating-point
3767ec681f3Smrg      `0.0f / 1.0f` boolean. Switching between these modes is useful to fold a
3777ec681f3Smrg      boolean type convert into a comparison. `u1` is used internally to
3787ec681f3Smrg      implement 64-bit comparisons.
3797ec681f3Smrg    </desc>
3807ec681f3Smrg    <value desc="Integer 1">i1</value>
3817ec681f3Smrg    <value desc="Float 1">f1</value>
3827ec681f3Smrg    <value desc="Minus 1">m1</value>
3837ec681f3Smrg    <value desc="Low half of 64-bit compare">u1</value>
3847ec681f3Smrg  </enum>
3857ec681f3Smrg
3867ec681f3Smrg  <enum name="Widen">
3877ec681f3Smrg    <value default="true">none</value>
3887ec681f3Smrg    <value>h0</value>
3897ec681f3Smrg    <value>h1</value>
3907ec681f3Smrg    <reserved/>
3917ec681f3Smrg    <reserved/>
3927ec681f3Smrg    <reserved/>
3937ec681f3Smrg    <reserved/>
3947ec681f3Smrg    <reserved/>
3957ec681f3Smrg  </enum>
3967ec681f3Smrg
3977ec681f3Smrg  <enum name="Clamp">
3987ec681f3Smrg    <desc>
3997ec681f3Smrg      Clamp applied to the destination of a floating-point instruction. Note the
4007ec681f3Smrg      clamps may be decomposed as two independent bits for `clamp_0_inf` and
4017ec681f3Smrg      `clamp_m1_1`, with `clamp_0_1` arising as the composition of `clamp_0_inf`
4027ec681f3Smrg      and `clamp_m1_1` in either order.
4037ec681f3Smrg
4047ec681f3Smrg      Clamps are implemented per the SPIR-V specification:
4057ec681f3Smrg
4067ec681f3Smrg      $$\text{clamp} \; (x, \ell, h) = \min( \max( x, \ell ), h)$$
4077ec681f3Smrg
4087ec681f3Smrg      The min/max functions return the other operand if one operand is NaN, and
4097ec681f3Smrg      compare $-0 &lt; +0$. That means the following identities hold for Valhall
4107ec681f3Smrg      clamps:
4117ec681f3Smrg
4127ec681f3Smrg      \begin{align*}
4137ec681f3Smrg        \text{clamp}(-0.0, 0.0, 1.0) &amp; = +0.0 \\
4147ec681f3Smrg        \text{clamp}(-\text{NaN}, 0.0, 1.0) &amp; = +0.0 \\
4157ec681f3Smrg        \text{clamp}(\text{NaN}, 0.0, 1.0) &amp; = +0.0 \\
4167ec681f3Smrg        &amp; \\
4177ec681f3Smrg        \text{clamp}(-0.0, -1.0, 1.0) &amp; = -0.0 \\
4187ec681f3Smrg        \text{clamp}(\text{NaN}, -1.0, 1.0) &amp; = -1.0 \\
4197ec681f3Smrg        \text{clamp}(-\text{NaN}, -1.0, 1.0) &amp; = -1.0 \\
4207ec681f3Smrg        &amp; \\
4217ec681f3Smrg        \max(\text{NaN}, 0.0) &amp; = +0.0 \\
4227ec681f3Smrg        \max(-\text{NaN}, 0.0) &amp; = +0.0 \\
4237ec681f3Smrg        \max(-0.0, 0.0) &amp; = +0.0 \\
4247ec681f3Smrg      \end{align*}
4257ec681f3Smrg
4267ec681f3Smrg      This behaviour is consistent with the FMin/FMax/FClamp and
4277ec681f3Smrg      NMin/NMax/NClamp rules prescribed by SPIR-V and governed by IEEE-754. As
4287ec681f3Smrg      a consequence, substituting these clamps for equivalent minimum/maximum
4297ec681f3Smrg      exprssions is legal even with strict floating point rules.
4307ec681f3Smrg    </desc>
4317ec681f3Smrg    <value default="true" desc="Identity">none</value>
4327ec681f3Smrg    <value desc="Clamp positive">clamp_0_inf</value>
4337ec681f3Smrg    <value desc="Clamp to $[-1, 1]$">clamp_m1_1</value>
4347ec681f3Smrg    <value desc="Clamp to $[0, 1]$">clamp_0_1</value>
4357ec681f3Smrg  </enum>
4367ec681f3Smrg
4377ec681f3Smrg  <enum name="Condition">
4387ec681f3Smrg    <desc>
4397ec681f3Smrg      Condition code. Type must be inferred from the instruction. IEEE 754 total
4407ec681f3Smrg      ordering only applies to floating point compares. "Not equal" and "greater
4417ec681f3Smrg      than or less than" are distinguished by NaN behaviour conforming to
4427ec681f3Smrg      the IEEE 754 specification.
4437ec681f3Smrg    </desc>
4447ec681f3Smrg    <value desc="Equal">eq</value>
4457ec681f3Smrg    <value desc="Greater than">gt</value>
4467ec681f3Smrg    <value desc="Greater than or equal">ge</value>
4477ec681f3Smrg    <value desc="Not equal">ne</value>
4487ec681f3Smrg    <value desc="Less than">lt</value>
4497ec681f3Smrg    <value desc="Less than or equal">le</value>
4507ec681f3Smrg    <value desc="Greater than or less than">gtlt</value>
4517ec681f3Smrg    <value desc="Totally ordered">total</value>
4527ec681f3Smrg  </enum>
4537ec681f3Smrg
4547ec681f3Smrg  <enum name="Dimension">
4557ec681f3Smrg    <desc>Texture dimension.</desc>
4567ec681f3Smrg    <value desc="1D or buffer">1d</value>
4577ec681f3Smrg    <value desc="2D or 2D array">2d</value>
4587ec681f3Smrg    <value desc="3D or 3D array">3d</value>
4597ec681f3Smrg    <value desc="Cube map or cube map array">cube</value>
4607ec681f3Smrg  </enum>
4617ec681f3Smrg
4627ec681f3Smrg  <enum name="LOD mode">
4637ec681f3Smrg    <desc>Level-of-detail selection mode in a texture instruction.</desc>
4647ec681f3Smrg    <value desc="Set to zero">zero</value>
4657ec681f3Smrg    <value desc="Computed based on neighboring fragments">computed</value>
4667ec681f3Smrg    <reserved/>
4677ec681f3Smrg    <reserved/>
4687ec681f3Smrg    <value desc="Explicitly specified in a register">explicit</value>
4697ec681f3Smrg    <value desc="Computed based on neighboring fragments added with bias in a register">computed_bias</value>
4707ec681f3Smrg    <value desc="Derived from a gradient descriptor in registers">grdesc</value>
4717ec681f3Smrg    <reserved/>
4727ec681f3Smrg  </enum>
4737ec681f3Smrg
4747ec681f3Smrg  <enum name="Register format">
4757ec681f3Smrg    <desc>Format of data loaded to / stored from registers for general memory access.</desc>
4767ec681f3Smrg    <reserved/>
4777ec681f3Smrg    <reserved/>
4787ec681f3Smrg    <value desc="32-bit floats">f32</value>
4797ec681f3Smrg    <value desc="16-bit floats">f16</value>
4807ec681f3Smrg    <value desc="32-bit unsigned integers">u32</value>
4817ec681f3Smrg    <reserved/>
4827ec681f3Smrg    <reserved/>
4837ec681f3Smrg    <reserved/>
4847ec681f3Smrg  </enum>
4857ec681f3Smrg
4867ec681f3Smrg  <enum name="Staging register count" implied="true">
4877ec681f3Smrg    <value>sr0</value>
4887ec681f3Smrg    <value>sr1</value>
4897ec681f3Smrg    <value>sr2</value>
4907ec681f3Smrg    <value>sr3</value>
4917ec681f3Smrg    <value>sr4</value>
4927ec681f3Smrg    <value>sr5</value>
4937ec681f3Smrg    <value>sr6</value>
4947ec681f3Smrg    <value>sr7</value>
4957ec681f3Smrg  </enum>
4967ec681f3Smrg
4977ec681f3Smrg  <enum name="Vector size">
4987ec681f3Smrg    <desc>Number of channels loaded/stored for general memory access.</desc>
4997ec681f3Smrg    <value default="true" desc="Scalar">none</value>
5007ec681f3Smrg    <value desc="2 channels">v2</value>
5017ec681f3Smrg    <value desc="3 channels">v3</value>
5027ec681f3Smrg    <value desc="4 channels">v4</value>
5037ec681f3Smrg  </enum>
5047ec681f3Smrg
5057ec681f3Smrg  <enum name="Slot">
5067ec681f3Smrg    <desc>
5077ec681f3Smrg      Dependency slot set on a message-passing instruction that writes to
5087ec681f3Smrg      registers. Before reading the destination, a future instruction must wait
5097ec681f3Smrg      on the specified slot. Slot #7 is for `BARRIER` instructions only.
5107ec681f3Smrg    </desc>
5117ec681f3Smrg    <value desc="Slot #0">slot0</value>
5127ec681f3Smrg    <value desc="Slot #1">slot1</value>
5137ec681f3Smrg    <value desc="Slot #2">slot2</value>
5147ec681f3Smrg    <reserved/>
5157ec681f3Smrg    <reserved/>
5167ec681f3Smrg    <reserved/>
5177ec681f3Smrg    <reserved/>
5187ec681f3Smrg    <value desc="Slot #7">slot7</value>
5197ec681f3Smrg  </enum>
5207ec681f3Smrg
5217ec681f3Smrg  <enum name="Store segment">
5227ec681f3Smrg    <desc>Memory segment written to by a `STORE` instruction.</desc>
5237ec681f3Smrg    <value desc="Global or workgroup local memory" default="none">global</value>
5247ec681f3Smrg    <value desc="Position output (in a position shader)">pos</value>
5257ec681f3Smrg    <value desc="Varyings with LEA_ATTR computed addresses">vary</value>
5267ec681f3Smrg    <value desc="Thread local storage">tl</value>
5277ec681f3Smrg  </enum>
5287ec681f3Smrg
5297ec681f3Smrg  <enum name="Subgroup size">
5307ec681f3Smrg    <desc>
5317ec681f3Smrg      Selects the effective subgroup size from subgroup operations. The hardware
5327ec681f3Smrg      warps are sixteen threads on Valhall, but subdividing a warp may be useful
5337ec681f3Smrg      for API requirements. In particular, derivatives may be calculated with
5347ec681f3Smrg      quads (four threads).
5357ec681f3Smrg    </desc>
5367ec681f3Smrg    <value desc="Two threads">subgroup2</value>
5377ec681f3Smrg    <value desc="Four threads">subgroup4</value>
5387ec681f3Smrg    <value desc="Eight threads">subgroup8</value>
5397ec681f3Smrg    <value desc="Sixteen threads" default="true">subgroup16</value>
5407ec681f3Smrg  </enum>
5417ec681f3Smrg
5427ec681f3Smrg  <enum name="Lane operation">
5437ec681f3Smrg    <desc>
5447ec681f3Smrg      Acts as a modifier on the lane specificier for a `CLPER` instruction. The
5457ec681f3Smrg      `accumulate` mode is required for efficient subgroup reductions.
5467ec681f3Smrg    </desc>
5477ec681f3Smrg    <value name="No operation" default="true">none</value>
5487ec681f3Smrg    <value name="Exclusive-or">xor</value>
5497ec681f3Smrg    <value name="Accumulate">accumulate</value>
5507ec681f3Smrg    <value name="Shift">shift</value>
5517ec681f3Smrg  </enum>
5527ec681f3Smrg
5537ec681f3Smrg  <enum name="Inactive result">
5547ec681f3Smrg    <desc>
5557ec681f3Smrg      Accesses to inactive lanes (due to divergence) in a subgroup is generally
5567ec681f3Smrg      undefined in APIs. However, the results of permuting with an inactive lane
5577ec681f3Smrg      with `CLPER.i32` are well-defined in Valhall: they return one of the
5587ec681f3Smrg      following values, as specified in the `CLPER.i32` instructions. Sometimes
5597ec681f3Smrg      certain values enable small optimizations.
5607ec681f3Smrg    </desc>
5617ec681f3Smrg    <value name="0x00000000" default="true">zero</value>
5627ec681f3Smrg    <value name="0xFFFFFFFF">umax</value>
5637ec681f3Smrg    <value name="0x00000001">i1</value>
5647ec681f3Smrg    <value name="0x00010001">v2i1</value>
5657ec681f3Smrg    <value name="0x80000000">smin</value>
5667ec681f3Smrg    <value name="0x7FFFFFFF">smax</value>
5677ec681f3Smrg    <value name="0x80008000">v2smin</value>
5687ec681f3Smrg    <value name="0x7FFF7FFF">v2smax</value>
5697ec681f3Smrg    <value name="0x80808080">v4smin</value>
5707ec681f3Smrg    <value name="0x7F7F7F7F">v4smax</value>
5717ec681f3Smrg    <value name="0x3F800000">f1</value>
5727ec681f3Smrg    <value name="0x3C003C00">v2f1</value>
5737ec681f3Smrg    <value name="0xFF800000">infn</value>
5747ec681f3Smrg    <value name="0x7F800000">inf</value>
5757ec681f3Smrg    <value name="0xFC00FC00">v2infn</value>
5767ec681f3Smrg    <value name="0x7C007C00">v2inf</value>
5777ec681f3Smrg  </enum>
5787ec681f3Smrg
5797ec681f3Smrg  <ins name="NOP" title="No operation" dests="0" opcode="0x00">
5807ec681f3Smrg    <desc>
5817ec681f3Smrg      Do nothing. Useful at the start of a block for waiting on slots required
5827ec681f3Smrg      by the first actual instruction of the block, to reconcile dependencies
5837ec681f3Smrg      after a branch. Also useful as the sole instruction of an empty shader.
5847ec681f3Smrg    </desc>
5857ec681f3Smrg  </ins>
5867ec681f3Smrg
5877ec681f3Smrg  <ins name="BRANCHZ" title="Compare to zero and branch" dests="0" opcode="0x1F">
5887ec681f3Smrg    <desc>
5897ec681f3Smrg      Branches to a specified relative offset if its source is nonzero (default)
5907ec681f3Smrg      or if its source is zero (if `.eq` is set). The offset is 27-bits and
5917ec681f3Smrg      sign-extended, giving an effective range of ±26-bits. The offset is
5927ec681f3Smrg      specified in units of instructions, relative to the *next* instruction.
5937ec681f3Smrg      Positive offsets may be interpreted as "number of instructions to skip".
5947ec681f3Smrg      Since Valhall instructions are 8 bytes, this operates as:
5957ec681f3Smrg
5967ec681f3Smrg      $$PC := \begin{cases} PC + 8 \cdot (\text{offset} \; + 1) &amp; \text{if} \;
5977ec681f3Smrg      \text{src} \stackrel{?}{=} 0 \\ PC + 8 &amp; \text{otherwise} \end{cases}$$
5987ec681f3Smrg
5997ec681f3Smrg      Used with comparison instructions to implement control flow. Tie the
6007ec681f3Smrg      source to a nonzero constant to implement a jump. May introduce
6017ec681f3Smrg      divergence, so generally requires `.reconverge` flow control.
6027ec681f3Smrg    </desc>
6037ec681f3Smrg    <src lane="37">Value to compare against zero</src>
6047ec681f3Smrg    <imm name="offset" start="8" size="27" signed="true"/>
6057ec681f3Smrg    <mod name="eq" start="36" size="1"/>
6067ec681f3Smrg  </ins>
6077ec681f3Smrg
6087ec681f3Smrg  <ins name="DISCARD.f32" title="Discard fragment" opcode="0x20">
6097ec681f3Smrg    <desc>
6107ec681f3Smrg      Evaluates the given condition, and if it passes, discards the current
6117ec681f3Smrg      fragment and terminates the thread. The destination should be set to R60.
6127ec681f3Smrg      Only valid in a **fragment** shader.
6137ec681f3Smrg    </desc>
6147ec681f3Smrg    <cmp/>
6157ec681f3Smrg    <dest>Updated coverage mask (set to R60)</dest>
6167ec681f3Smrg    <src absneg="true" swizzle="true">Left value to compare</src>
6177ec681f3Smrg    <src absneg="true" swizzle="true">Right value to compare</src>
6187ec681f3Smrg  </ins>
6197ec681f3Smrg
6207ec681f3Smrg  <ins name="BRANCHZI" title="Compare to zero and branch indirect" opcode="0x2F">
6217ec681f3Smrg    <desc>
6227ec681f3Smrg      Jump to an indirectly specified address. Used to jump to blend shaders at
6237ec681f3Smrg      the end of a fragment shader.
6247ec681f3Smrg    </desc>
6257ec681f3Smrg    <src>Value to compare against zero</src>
6267ec681f3Smrg    <src>Branch target</src>
6277ec681f3Smrg    <mod name="eq" start="36" size="1"/>
6287ec681f3Smrg  </ins>
6297ec681f3Smrg
6307ec681f3Smrg  <ins name="BARRIER" title="Execution and memory barrier" opcode="0x45">
6317ec681f3Smrg    <desc>
6327ec681f3Smrg      General-purpose barrier. Must use slot #7. Must be paired with a
6337ec681f3Smrg      `.barrier` action on the instruction.
6347ec681f3Smrg    </desc>
6357ec681f3Smrg    <slot/>
6367ec681f3Smrg  </ins>
6377ec681f3Smrg
6387ec681f3Smrg  <group name="CSEL" title="Floating-point conditional select" dests="1">
6397ec681f3Smrg    <ins name="CSEL.f32" opcode="0x154"/>
6407ec681f3Smrg    <ins name="CSEL.v2f16" opcode="0x155"/>
6417ec681f3Smrg    <desc>
6427ec681f3Smrg      Evaluates the given condition and outputs either the true source or the
6437ec681f3Smrg      false source.
6447ec681f3Smrg    </desc>
6457ec681f3Smrg    <cmp/>
6467ec681f3Smrg    <src float="true">Left value to compare</src>
6477ec681f3Smrg    <src float="true">Right value to compare</src>
6487ec681f3Smrg    <src float="true">Return value if true</src>
6497ec681f3Smrg    <src float="true">Return value if false</src>
6507ec681f3Smrg  </group>
6517ec681f3Smrg
6527ec681f3Smrg  <group name="CSEL" title="Integer conditional select" dests="1">
6537ec681f3Smrg    <ins name="CSEL.u32" opcode="0x150"/>
6547ec681f3Smrg    <ins name="CSEL.v2u16" opcode="0x151"/>
6557ec681f3Smrg    <ins name="CSEL.i32" opcode="0x158"/>
6567ec681f3Smrg    <ins name="CSEL.v2i16" opcode="0x159"/>
6577ec681f3Smrg    <desc>
6587ec681f3Smrg      Evaluates the given condition and outputs either the true source or the
6597ec681f3Smrg      false source.
6607ec681f3Smrg
6617ec681f3Smrg      Valhall lacks integer minimum/maximum instructions. `CSEL` instructions
6627ec681f3Smrg      with tied operands form the canonical implementations of these
6637ec681f3Smrg      instructions. Similarly, the integer $\text{sign}$ function is canonically
6647ec681f3Smrg      implemented with a pair of `CSEL` instructions.
6657ec681f3Smrg    </desc>
6667ec681f3Smrg    <cmp/>
6677ec681f3Smrg    <src>Left value to compare</src>
6687ec681f3Smrg    <src>Right value to compare</src>
6697ec681f3Smrg    <src>Return value if true</src>
6707ec681f3Smrg    <src>Return value if false</src>
6717ec681f3Smrg  </group>
6727ec681f3Smrg
6737ec681f3Smrg  <ins name="LD_VAR_SPECIAL" title="Load special varying" opcode="0x56">
6747ec681f3Smrg    <sr write="true"/>
6757ec681f3Smrg    <sr_count/>
6767ec681f3Smrg    <vecsize/>
6777ec681f3Smrg    <regfmt/>
6787ec681f3Smrg    <slot/>
6797ec681f3Smrg    <src/>
6807ec681f3Smrg    <imm name="index" start="12" size="4"/> <!-- 0 for pointx, 1 for pointy, 2 for fragw, 3 for fragz -->
6817ec681f3Smrg  </ins>
6827ec681f3Smrg
6837ec681f3Smrg  <group name="LD_VAR_IMM_F32" title="Load immediate varying">
6847ec681f3Smrg    <desc>Interpolates a given varying</desc>
6857ec681f3Smrg    <ins name="LD_VAR_IMM_F32" opcode="0x5C"/>
6867ec681f3Smrg    <ins name="LD_VAR_IMM_F16" opcode="0x5D"/>
6877ec681f3Smrg    <sr write="true"/>
6887ec681f3Smrg    <vecsize/>
6897ec681f3Smrg    <sr_count/>
6907ec681f3Smrg    <regfmt/>
6917ec681f3Smrg    <slot/>
6927ec681f3Smrg    <src/>
6937ec681f3Smrg    <src/>
6947ec681f3Smrg    <imm name="index" start="20" size="4"/>
6957ec681f3Smrg  </group>
6967ec681f3Smrg
6977ec681f3Smrg  <ins name="LD_ATTR_IMM" title="Load immediate attribute" opcode="0x66">
6987ec681f3Smrg    <sr_count/>
6997ec681f3Smrg    <vecsize/>
7007ec681f3Smrg    <regfmt/>
7017ec681f3Smrg    <slot/>
7027ec681f3Smrg    <sr write="true"/>
7037ec681f3Smrg    <src>Vertex ID</src>
7047ec681f3Smrg    <src>Instance ID</src>
7057ec681f3Smrg    <imm name="index" start="20" size="4"/>
7067ec681f3Smrg  </ins>
7077ec681f3Smrg
7087ec681f3Smrg  <ins name="LD_ATTR" title="Load indirect attribute" opcode="0x67">
7097ec681f3Smrg    <desc>The index must not diverge within a warp.</desc>
7107ec681f3Smrg    <vecsize/>
7117ec681f3Smrg    <regfmt/>
7127ec681f3Smrg    <slot/>
7137ec681f3Smrg    <sr_count/>
7147ec681f3Smrg    <sr write="true"/>
7157ec681f3Smrg    <src>Vertex ID</src>
7167ec681f3Smrg    <src>Instance ID</src>
7177ec681f3Smrg    <src>Index</src>
7187ec681f3Smrg  </ins>
7197ec681f3Smrg
7207ec681f3Smrg  <ins name="LEA_ATTR" title="Load effective address" opcode="0x5E">
7217ec681f3Smrg    <desc>
7227ec681f3Smrg      Loads the effective address of the position buffer (in a position shader)
7237ec681f3Smrg      or the varying buffer (in a varying shader). That is, the base pointer
7247ec681f3Smrg      plus the vertex's linear ID (the first source) times the buffer's
7257ec681f3Smrg      per-vertex stride. `LEA_ATTR` should be executed once in a
7267ec681f3Smrg      position/varying shader, with the linear ID preloaded as `r59`. Each
7277ec681f3Smrg      position/varying store can then be constructed as `STORE` with the base
7287ec681f3Smrg      address sourced from the 64-bit destination of `LEA_ATTR` and an
7297ec681f3Smrg      appropriately computed offset. Varying stores bypass the usual conversion
7307ec681f3Smrg      hardware for attributes; this diverges from earlier Mali hardware.
7317ec681f3Smrg    </desc>
7327ec681f3Smrg    <sr write="true"/>
7337ec681f3Smrg    <sr_count/>
7347ec681f3Smrg    <slot/>
7357ec681f3Smrg    <imm name="unk" start="8" size="4"/>
7367ec681f3Smrg    <src>Linear ID</src>
7377ec681f3Smrg  </ins>
7387ec681f3Smrg
7397ec681f3Smrg  <ins name="LOAD.i8" title="Global memory load" opcode="0x60" opcode2="0">
7407ec681f3Smrg    <desc>Loads from main memory</desc>
7417ec681f3Smrg    <sr write="true"/>
7427ec681f3Smrg    <sr_count/>
7437ec681f3Smrg    <mod name="load_lane_8_bit" start="36" size="3"/>
7447ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
7457ec681f3Smrg    <slot/>
7467ec681f3Smrg    <src>Address to load from after adding offset</src>
7477ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
7487ec681f3Smrg  </ins>
7497ec681f3Smrg
7507ec681f3Smrg  <ins name="LOAD.i16" title="Global memory load" opcode="0x60" opcode2="1">
7517ec681f3Smrg    <desc>Loads from main memory</desc>
7527ec681f3Smrg    <sr write="true"/>
7537ec681f3Smrg    <sr_count/>
7547ec681f3Smrg    <mod name="load_lane_16_bit" start="36" size="3"/>
7557ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
7567ec681f3Smrg    <slot/>
7577ec681f3Smrg    <src>Address to load from after adding offset</src>
7587ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
7597ec681f3Smrg  </ins>
7607ec681f3Smrg
7617ec681f3Smrg  <ins name="LOAD.i24" title="Global memory load" opcode="0x60" opcode2="2">
7627ec681f3Smrg    <desc>Loads from main memory</desc>
7637ec681f3Smrg    <sr write="true"/>
7647ec681f3Smrg    <sr_count/>
7657ec681f3Smrg    <mod name="load_lane_24_bit" start="36" size="3"/>
7667ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
7677ec681f3Smrg    <slot/>
7687ec681f3Smrg    <src>Address to load from after adding offset</src>
7697ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
7707ec681f3Smrg  </ins>
7717ec681f3Smrg
7727ec681f3Smrg  <ins name="LOAD.i32" title="Global memory load" opcode="0x60" opcode2="3">
7737ec681f3Smrg    <desc>Loads from main memory</desc>
7747ec681f3Smrg    <sr write="true"/>
7757ec681f3Smrg    <sr_count/>
7767ec681f3Smrg    <mod name="load_lane_32_bit" start="36" size="3"/>
7777ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
7787ec681f3Smrg    <slot/>
7797ec681f3Smrg    <src>Address to load from after adding offset</src>
7807ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
7817ec681f3Smrg  </ins>
7827ec681f3Smrg
7837ec681f3Smrg  <ins name="LOAD.i48" title="Global memory load" opcode="0x60" opcode2="4">
7847ec681f3Smrg    <desc>Loads from main memory</desc>
7857ec681f3Smrg    <sr write="true"/>
7867ec681f3Smrg    <sr_count/>
7877ec681f3Smrg    <mod name="load_lane_48_bit" start="36" size="3"/>
7887ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
7897ec681f3Smrg    <slot/>
7907ec681f3Smrg    <src>Address to load from after adding offset</src>
7917ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
7927ec681f3Smrg  </ins>
7937ec681f3Smrg
7947ec681f3Smrg  <ins name="LOAD.i64" title="Global memory load" opcode="0x60" opcode2="5">
7957ec681f3Smrg    <desc>Loads from main memory</desc>
7967ec681f3Smrg    <sr write="true"/>
7977ec681f3Smrg    <sr_count/>
7987ec681f3Smrg    <mod name="load_lane_64_bit" start="36" size="3"/>
7997ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
8007ec681f3Smrg    <slot/>
8017ec681f3Smrg    <src>Address to load from after adding offset</src>
8027ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
8037ec681f3Smrg  </ins>
8047ec681f3Smrg
8057ec681f3Smrg  <ins name="LOAD.i96" title="Global memory load" opcode="0x60" opcode2="6">
8067ec681f3Smrg    <desc>Loads from main memory</desc>
8077ec681f3Smrg    <sr write="true"/>
8087ec681f3Smrg    <sr_count/>
8097ec681f3Smrg    <mod name="load_lane_96_bit" start="36" size="3"/>
8107ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
8117ec681f3Smrg    <slot/>
8127ec681f3Smrg    <src>Address to load from after adding offset</src>
8137ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
8147ec681f3Smrg  </ins>
8157ec681f3Smrg
8167ec681f3Smrg  <ins name="LOAD.i128" title="Global memory load" opcode="0x60" opcode2="7">
8177ec681f3Smrg    <desc>Loads from main memory</desc>
8187ec681f3Smrg    <sr write="true"/>
8197ec681f3Smrg    <sr_count/>
8207ec681f3Smrg    <mod name="load_lane_128_bit" start="36" size="3"/>
8217ec681f3Smrg    <mod name="unsigned" start="39" size="1"/>
8227ec681f3Smrg    <slot/>
8237ec681f3Smrg    <src>Address to load from after adding offset</src>
8247ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
8257ec681f3Smrg  </ins>
8267ec681f3Smrg
8277ec681f3Smrg  <group name="STORE" title="Global memory store" opcode="0x61">
8287ec681f3Smrg    <desc>Stores to main memory</desc>
8297ec681f3Smrg    <sr read="true"/>
8307ec681f3Smrg    <ins name="STORE.i8" opcode2="0x0"/>
8317ec681f3Smrg    <ins name="STORE.i16" opcode2="0x1"/>
8327ec681f3Smrg    <ins name="STORE.i24" opcode2="0x2"/>
8337ec681f3Smrg    <ins name="STORE.i32" opcode2="0x3"/>
8347ec681f3Smrg    <ins name="STORE.i48" opcode2="0x4"/>
8357ec681f3Smrg    <ins name="STORE.i64" opcode2="0x5"/>
8367ec681f3Smrg    <ins name="STORE.i96" opcode2="0x6"/>
8377ec681f3Smrg    <ins name="STORE.i128" opcode2="0x7"/>
8387ec681f3Smrg    <sr_count/>
8397ec681f3Smrg    <store_segment/>
8407ec681f3Smrg    <slot/>
8417ec681f3Smrg    <src>Address to store to after adding offset</src>
8427ec681f3Smrg    <imm name="offset" start="8" size="16" signed="true"/>
8437ec681f3Smrg  </group>
8447ec681f3Smrg
8457ec681f3Smrg  <ins name="ST_IMAGE" title="Image store" opcode="0x71">
8467ec681f3Smrg    <desc>Stores to images</desc>
8477ec681f3Smrg    <sr read="true"/>
8487ec681f3Smrg    <sr_count/>
8497ec681f3Smrg    <slot/>
8507ec681f3Smrg    <src>Address to store to after adding offset</src>
8517ec681f3Smrg  </ins>
8527ec681f3Smrg
8537ec681f3Smrg  <ins name="LD_TILE" title="Load from tilebuffer" opcode="0x78">
8547ec681f3Smrg    <desc>
8557ec681f3Smrg      Loads a given render target, specified in the pixel indices descriptor, at
8567ec681f3Smrg      a given location and sample, and convert to the format specified in the
8577ec681f3Smrg      internal conversion descriptor. Used to implement EXT_framebuffer_fetch
8587ec681f3Smrg      and internally in blend shaders.
8597ec681f3Smrg    </desc>
8607ec681f3Smrg    <sr write="true"/>
8617ec681f3Smrg    <sr_count/>
8627ec681f3Smrg    <slot/>
8637ec681f3Smrg    <src>Pixel indices descriptor</src>
8647ec681f3Smrg    <src>Coverage mask</src>
8657ec681f3Smrg    <src>Conversion descriptor</src>
8667ec681f3Smrg  </ins>
8677ec681f3Smrg
8687ec681f3Smrg  <ins name="BLEND" title="Blend render target" opcode="0x7F">
8697ec681f3Smrg    <desc>
8707ec681f3Smrg      Blends a given render target. This loads the API-specified blend state for
8717ec681f3Smrg      the render target from the first source. Blend descriptors are available
8727ec681f3Smrg      as special immediates. It then reads the colour to be blended from the
8737ec681f3Smrg      first staging register, with the specified vector size and register format
8747ec681f3Smrg      as desired. The resulting coverage mask is stored to the second set of
8757ec681f3Smrg      staging registers.
8767ec681f3Smrg
8777ec681f3Smrg      In the fixed-function path, `BLEND` sends the colour to the blender to be
8787ec681f3Smrg      written to the tilebuffer. Then, if the instruction's flow control
8797ec681f3Smrg      specifies termination, the fragment program is ended. If it does not
8807ec681f3Smrg      specify termination, `BLEND` acts as a relative branch, branching with the
8817ec681f3Smrg      offset specified as `target`. This allows the subsequent instructions to
8827ec681f3Smrg      be skipped when fixed-function blending is used. Note this implicit branch
8837ec681f3Smrg      can never introduce divergence, so `.reconverge` is not required.
8847ec681f3Smrg
8857ec681f3Smrg      In the blend shader path, `BLEND` ignores the specified flow control and
8867ec681f3Smrg      does not branch to the specified offset. Instead, execution considers
8877ec681f3Smrg      normally with the next instruction. The compiler should insert code for
8887ec681f3Smrg      calling a blend shader after the `BLEND` instruction unless it is known
8897ec681f3Smrg      that a blend shader will never be required.
8907ec681f3Smrg
8917ec681f3Smrg      The indirection is required to support both fixed-function and blend
8927ec681f3Smrg      shaders efficiently and without shader variants.
8937ec681f3Smrg    </desc>
8947ec681f3Smrg    <sr read="true"/>
8957ec681f3Smrg    <sr write="true" count="1" flags="false"/>
8967ec681f3Smrg    <src>Blend descriptor</src>
8977ec681f3Smrg    <imm name="target" start="8" size="8"/>
8987ec681f3Smrg    <slot/>
8997ec681f3Smrg    <sr_count/>
9007ec681f3Smrg    <vecsize/>
9017ec681f3Smrg    <regfmt/>
9027ec681f3Smrg  </ins>
9037ec681f3Smrg
9047ec681f3Smrg  <ins name="ATEST" title="Alpha test" opcode="0x7D">
9057ec681f3Smrg    <desc>
9067ec681f3Smrg      Does alpha-to-coverage testing, updating the sample coverage mask. ATEST
9077ec681f3Smrg      does not do an implicit discard. It should be executed before the first
9087ec681f3Smrg      ZS_EMIT or BLEND instruction.
9097ec681f3Smrg    </desc>
9107ec681f3Smrg    <sr write="true">Updated coverage mask</sr>
9117ec681f3Smrg    <src>Input coverage mask</src>
9127ec681f3Smrg    <src swizzle="true">Alpha value (render target 0)</src>
9137ec681f3Smrg    <src/>
9147ec681f3Smrg    <sr_count/>
9157ec681f3Smrg  </ins>
9167ec681f3Smrg
9177ec681f3Smrg  <ins name="ZS_EMIT" title="Depth/stencil write" opcode="0x7E">
9187ec681f3Smrg    <desc>
9197ec681f3Smrg      Programatically writes out depth, stencil, or both, depending on which
9207ec681f3Smrg      modifiers are set. Used to implement gl_FragDepth and gl_FragStencil.
9217ec681f3Smrg    </desc>
9227ec681f3Smrg    <mod name="z" start="25" size="1"/>
9237ec681f3Smrg    <mod name="stencil" start="24" size="1"/>
9247ec681f3Smrg    <dest>Updated coverage mask</dest>
9257ec681f3Smrg    <src>Depth value</src>
9267ec681f3Smrg    <src>Stencil value</src>
9277ec681f3Smrg    <src>Input coverage mask</src>
9287ec681f3Smrg  </ins>
9297ec681f3Smrg
9307ec681f3Smrg  <group name="CONVERT" title="Data conversions" dests="1" opcode="0x90">
9317ec681f3Smrg    <desc>
9327ec681f3Smrg      Performs the given data conversion. Note that floating-point rounding is
9337ec681f3Smrg      handled via the same hardware and therefore shares an encoding. Round mode
9347ec681f3Smrg      is specified where it makes sense.
9357ec681f3Smrg    </desc>
9367ec681f3Smrg
9377ec681f3Smrg    <ins name="S16_TO_S32" opcode2="0x4"/>
9387ec681f3Smrg    <ins name="S16_TO_F32" opcode2="0x5"/>
9397ec681f3Smrg    <ins name="V2S16_TO_V2F16" opcode2="0x7"/>
9407ec681f3Smrg
9417ec681f3Smrg    <ins name="S32_TO_F32" opcode2="0x9"/>
9427ec681f3Smrg
9437ec681f3Smrg    <ins name="U16_TO_U32" opcode2="0x14"/>
9447ec681f3Smrg    <ins name="U16_TO_F32" opcode2="0x15"/>
9457ec681f3Smrg    <ins name="V2U16_TO_V2F16" opcode2="0x17"/>
9467ec681f3Smrg
9477ec681f3Smrg    <ins name="U32_TO_F32" opcode2="0x19"/>
9487ec681f3Smrg
9497ec681f3Smrg    <roundmode/>
9507ec681f3Smrg    <src widen="true">Value to convert</src>
9517ec681f3Smrg  </group>
9527ec681f3Smrg
9537ec681f3Smrg  <group name="CONVERT" title="Float-to-int data conversions" dests="1" opcode="0x90">
9547ec681f3Smrg    <desc>Performs the given data conversion.</desc>
9557ec681f3Smrg    <ins name="F32_TO_S32" opcode2="0xC"/>
9567ec681f3Smrg    <ins name="F32_TO_U32" opcode2="0x1C"/>
9577ec681f3Smrg    <roundmode/>
9587ec681f3Smrg    <src absneg="true">Value to convert</src>
9597ec681f3Smrg  </group>
9607ec681f3Smrg
9617ec681f3Smrg  <group name="CONVERT" title="Float-to-int data conversions" dests="1" opcode="0x90">
9627ec681f3Smrg    <desc>Performs the given data conversion.</desc>
9637ec681f3Smrg    <ins name="V2F16_TO_V2S16" opcode2="0xE"/>
9647ec681f3Smrg    <ins name="V2F16_TO_V2U16" opcode2="0x1E"/>
9657ec681f3Smrg    <ins name="F16_TO_S32" opcode2="0xA"/>
9667ec681f3Smrg    <ins name="F16_TO_U32" opcode2="0x1A"/>
9677ec681f3Smrg    <roundmode/>
9687ec681f3Smrg    <src swizzle="true" absneg="true" size="16">Value to convert</src>
9697ec681f3Smrg  </group>
9707ec681f3Smrg
9717ec681f3Smrg  <ins name="F16_TO_F32" title="16-bit float to 32-bit float conversion" dests="1" opcode="0x90" opcode2="0xB">
9727ec681f3Smrg    <desc>Converts up with the specified round mode.</desc>
9737ec681f3Smrg    <roundmode/>
9747ec681f3Smrg    <src lane="28" size="16" absneg="true">Value to convert</src>
9757ec681f3Smrg  </ins>
9767ec681f3Smrg
9777ec681f3Smrg  <group name="CONVERT" title="8-bit data conversions" dests="1" opcode="0x90">
9787ec681f3Smrg    <desc>
9797ec681f3Smrg      Performs the given data conversion.
9807ec681f3Smrg    </desc>
9817ec681f3Smrg
9827ec681f3Smrg    <ins name="S8_TO_S32" opcode2="0x0"/>
9837ec681f3Smrg    <ins name="S8_TO_F32" opcode2="0x1"/>
9847ec681f3Smrg    <ins name="S8_TO_S16" opcode2="0x2"/>
9857ec681f3Smrg    <ins name="S8_TO_F16" opcode2="0x3"/>
9867ec681f3Smrg
9877ec681f3Smrg    <ins name="U8_TO_U32" opcode2="0x10"/>
9887ec681f3Smrg    <ins name="U8_TO_F32" opcode2="0x11"/>
9897ec681f3Smrg    <ins name="U8_TO_U16" opcode2="0x12"/>
9907ec681f3Smrg    <ins name="U8_TO_F16" opcode2="0x13"/>
9917ec681f3Smrg
9927ec681f3Smrg    <src lane="28" size="8">Value to convert</src>
9937ec681f3Smrg  </group>
9947ec681f3Smrg
9957ec681f3Smrg  <group name="FROUND" title="Floating-point rounding" dests="1" opcode="0x90">
9967ec681f3Smrg    <desc>
9977ec681f3Smrg      Performs the given rounding, using the convert unit.
9987ec681f3Smrg    </desc>
9997ec681f3Smrg
10007ec681f3Smrg    <ins name="FROUND.f32" opcode2="0xD"/>
10017ec681f3Smrg    <ins name="FROUND.v2f16" opcode2="0xF"/>
10027ec681f3Smrg
10037ec681f3Smrg    <roundmode/>
10047ec681f3Smrg    <src swizzle="true" absneg="true">Value to convert</src>
10057ec681f3Smrg  </group>
10067ec681f3Smrg
10077ec681f3Smrg  <ins name="MOV.i32" title="Register move" dests="1" opcode="0x91" opcode2="0x0">
10087ec681f3Smrg    <desc>Canonical register-to-register move.</desc>
10097ec681f3Smrg    <src/>
10107ec681f3Smrg  </ins>
10117ec681f3Smrg
10127ec681f3Smrg  <ins name="CLZ.u32" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x4">
10137ec681f3Smrg    <desc>
10147ec681f3Smrg      Used as a primitive for various bitwise operations.
10157ec681f3Smrg    </desc>
10167ec681f3Smrg    <src/>
10177ec681f3Smrg  </ins>
10187ec681f3Smrg
10197ec681f3Smrg  <ins name="CLZ.v2u16" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x5">
10207ec681f3Smrg    <desc>
10217ec681f3Smrg      Used as a primitive for various bitwise operations.
10227ec681f3Smrg    </desc>
10237ec681f3Smrg    <src/>
10247ec681f3Smrg  </ins>
10257ec681f3Smrg
10267ec681f3Smrg  <ins name="CLZ.v4u8" title="Count leading zeroes" dests="1" opcode="0x91" opcode2="0x6">
10277ec681f3Smrg    <desc>
10287ec681f3Smrg      Used as a primitive for various bitwise operations.
10297ec681f3Smrg    </desc>
10307ec681f3Smrg    <src/>
10317ec681f3Smrg  </ins>
10327ec681f3Smrg
10337ec681f3Smrg  <ins name="IABS.s32" title="Absolute value" dests="1" opcode="0x91" opcode2="0x8">
10347ec681f3Smrg    <desc>
10357ec681f3Smrg      64-bit abs may be constructed in 4 instructions (5 clocks) by checking the
10367ec681f3Smrg      sign with `ICMP.s32.lt.m1 hi, 0` and negating based on the result with
10377ec681f3Smrg      `IADD.s64` and `LSHIFT_XOR.i32` on each half.
10387ec681f3Smrg    </desc>
10397ec681f3Smrg    <src widen="true"/>
10407ec681f3Smrg  </ins>
10417ec681f3Smrg
10427ec681f3Smrg  <ins name="IABS.v2s16" title="Absolute value" dests="1" opcode="0x91" opcode2="0x9">
10437ec681f3Smrg    <src widen="true"/>
10447ec681f3Smrg  </ins>
10457ec681f3Smrg
10467ec681f3Smrg  <ins name="IABS.v4s8" title="Absolute value" dests="1" opcode="0x91" opcode2="0xa">
10477ec681f3Smrg    <src/>
10487ec681f3Smrg  </ins>
10497ec681f3Smrg
10507ec681f3Smrg  <ins name="POPCOUNT.i32" title="Population count" dests="1" opcode="0x91" opcode2="0xC">
10517ec681f3Smrg    <desc>
10527ec681f3Smrg      Only available as 32-bit. Smaller bitsizes require explicit conversions.
10537ec681f3Smrg      64-bit popcount may be constructed in 3 clocks by separate 32-bit
10547ec681f3Smrg      popcounts of each half and a 32-bit add, which is guaranteed not to
10557ec681f3Smrg      overflow.
10567ec681f3Smrg    </desc>
10577ec681f3Smrg    <src/>
10587ec681f3Smrg  </ins>
10597ec681f3Smrg
10607ec681f3Smrg  <ins name="BITREV.i32" title="Bitwise reverse" dests="1" opcode="0x91" opcode2="0xD">
10617ec681f3Smrg    <desc>
10627ec681f3Smrg      Only available as 32-bit. Other bitsizes may be derived with swizzles.
10637ec681f3Smrg    </desc>
10647ec681f3Smrg    <src/>
10657ec681f3Smrg  </ins>
10667ec681f3Smrg
10677ec681f3Smrg  <ins name="NOT.i32" title="Bitwise complement" dests="1" opcode="0x91" opcode2="0xE">
10687ec681f3Smrg    <desc>
10697ec681f3Smrg      For fully featured bitwise operation, see the shift opcodes.
10707ec681f3Smrg    </desc>
10717ec681f3Smrg    <src/>
10727ec681f3Smrg  </ins>
10737ec681f3Smrg
10747ec681f3Smrg  <ins name="NOT.i64" title="Bitwise complement" dests="1" opcode="0x191" opcode2="0xE">
10757ec681f3Smrg    <desc>
10767ec681f3Smrg      For fully featured bitwise operation, see the shift opcodes.
10777ec681f3Smrg    </desc>
10787ec681f3Smrg    <src/>
10797ec681f3Smrg  </ins>
10807ec681f3Smrg
10817ec681f3Smrg  <ins name="WMASK" title="Warp mask" dests="1" opcode="0x95">
10827ec681f3Smrg    <desc>
10837ec681f3Smrg      Returns the mask of lanes ever active within the warp (subgroup), such
10847ec681f3Smrg      that the source is nonzero. The number of work-items in a subgroup is
10857ec681f3Smrg      given as the popcount of this value with a nonzero input.
10867ec681f3Smrg
10877ec681f3Smrg      An `all()` subgroup operation may be constructed as `WMASK` of the input
10887ec681f3Smrg      compared for equality with `WMASK` of an nonzero value.
10897ec681f3Smrg
10907ec681f3Smrg      An `any()` subgroup operation may be constructed as `WMASK` of the input
10917ec681f3Smrg      compared against zero.
10927ec681f3Smrg    </desc>
10937ec681f3Smrg    <src/>
10947ec681f3Smrg    <subgroup/>
10957ec681f3Smrg  </ins>
10967ec681f3Smrg
10977ec681f3Smrg  <group name="FREXP" title="Fraction/exponent extract" dests="1" opcode="0x99">
10987ec681f3Smrg    <ins name="FREXPM.f32" opcode2="0"/>
10997ec681f3Smrg    <ins name="FREXPM.v2f16" opcode2="1"/>
11007ec681f3Smrg    <ins name="FREXPE.f32" opcode2="2"/>
11017ec681f3Smrg    <ins name="FREXPE.v2f16" opcode2="3"/>
11027ec681f3Smrg    <desc>
11037ec681f3Smrg      Breaks up the floating-point input into its fractional (mantissa) and
11047ec681f3Smrg      exponent parts. By default, this is compatible with the `frexp()` function
11057ec681f3Smrg      in APIs. With the log modifier, the floating point format is adjusted to
11067ec681f3Smrg      be compatible with Valhall's argument reduction for logarithm computation.
11077ec681f3Smrg    </desc>
11087ec681f3Smrg    <mod name="log" start="25" size="1"/>
11097ec681f3Smrg    <src float="true" swizzle="true"/>
11107ec681f3Smrg  </group>
11117ec681f3Smrg
11127ec681f3Smrg  <group name="SFU" title="Special function unit" dests="1" opcode="0x9C">
11137ec681f3Smrg    <ins name="FRCP.f32" opcode2="0"/>
11147ec681f3Smrg    <ins name="FRCP.f16" opcode2="1"/>
11157ec681f3Smrg    <ins name="FRSQ.f32" opcode2="2"/>
11167ec681f3Smrg    <ins name="FRSQ.f16" opcode2="3"/>
11177ec681f3Smrg    <ins name="FLOGD.f32" opcode2="8"/>
11187ec681f3Smrg    <desc>
11197ec681f3Smrg      Performs a given special function. The floating-point reciprocal (`FRCP`)
11207ec681f3Smrg      and reciprocal square root (`FRSQ`) instructions may be freely used as-is.
11217ec681f3Smrg      The logarithm instruction (`FLOGD.f32`) requires an argument reduction. See the
11227ec681f3Smrg      transcendentals section for more information.
11237ec681f3Smrg    </desc>
11247ec681f3Smrg    <src float="true" swizzle="true"/>
11257ec681f3Smrg  </group>
11267ec681f3Smrg
11277ec681f3Smrg  <group name="SFU" title="Special function unit" dests="1" opcode="0x9C">
11287ec681f3Smrg    <ins name="FSIN_TABLE.u6" opcode2="4"/>
11297ec681f3Smrg    <ins name="FCOS_TABLE.u6" opcode2="5"/>
11307ec681f3Smrg    <desc>
11317ec681f3Smrg      Performs a given special function.The trigonometric tables (`FSIN_TABLE.u6` and `FCOS_TABLE.u6`) are crude,
11327ec681f3Smrg      requiring both an argument reduction and postprocessing.
11337ec681f3Smrg    </desc>
11347ec681f3Smrg    <src/>
11357ec681f3Smrg  </group>
11367ec681f3Smrg
11377ec681f3Smrg  <group name="FADD" title="Floating-point add" dests="1" opcode2="0">
11387ec681f3Smrg    <ins name="FADD.f32" opcode="0xA4"/>
11397ec681f3Smrg    <ins name="FADD.v2f16" opcode="0xA5"/>
11407ec681f3Smrg    <desc>$A + B$</desc>
11417ec681f3Smrg    <clamp/>
11427ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
11437ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
11447ec681f3Smrg  </group>
11457ec681f3Smrg
11467ec681f3Smrg  <group name="FMIN" title="Floating-point minimum" dests="1" opcode2="2">
11477ec681f3Smrg    <ins name="FMIN.f32" opcode="0xA4"/>
11487ec681f3Smrg    <ins name="FMIN.v2f16" opcode="0xA5"/>
11497ec681f3Smrg    <desc>$\min \{ A, B \}$</desc>
11507ec681f3Smrg    <clamp/>
11517ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
11527ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
11537ec681f3Smrg  </group>
11547ec681f3Smrg
11557ec681f3Smrg  <group name="FMAX" title="Floating-point maximum" dests="1" opcode2="3">
11567ec681f3Smrg    <ins name="FMAX.f32" opcode="0xA4"/>
11577ec681f3Smrg    <ins name="FMAX.v2f16" opcode="0xA5"/>
11587ec681f3Smrg    <desc>$\max \{ A, B \}$</desc>
11597ec681f3Smrg    <clamp/>
11607ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
11617ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
11627ec681f3Smrg  </group>
11637ec681f3Smrg
11647ec681f3Smrg  <group name="V2F32_TO_V2F16" title="Vectorized floating-point conversion" dests="1" opcode2="4">
11657ec681f3Smrg    <ins name="V2F32_TO_V2F16" opcode="0xA5"/>
11667ec681f3Smrg    <desc>
11677ec681f3Smrg      Given a pair of 32-bit floats, output a pair of 16-bit floats packed into
11687ec681f3Smrg      a 32-bit destination.
11697ec681f3Smrg    </desc>
11707ec681f3Smrg    <src>A</src>
11717ec681f3Smrg    <src>B</src>
11727ec681f3Smrg  </group>
11737ec681f3Smrg
11747ec681f3Smrg  <group name="FRSCALE" title="Floating-point rescaling" dests="1" opcode2="6">
11757ec681f3Smrg    <ins name="FRSCALE.f32" opcode="0xA4"/>
11767ec681f3Smrg    <ins name="FRSCALE.v2f16" opcode="0xA5"/>
11777ec681f3Smrg    <desc>
11787ec681f3Smrg      Computes $A \cdot 2^B$ by adding B to the exponent of A. Used to calculate
11797ec681f3Smrg      various special functions, particularly base-2 exponents. Special case
11807ec681f3Smrg      handling differs from an actual floating-point multiply, so this should
11817ec681f3Smrg      not be used outside fixed instruction sequences.
11827ec681f3Smrg    </desc>
11837ec681f3Smrg    <clamp/>
11847ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
11857ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
11867ec681f3Smrg  </group>
11877ec681f3Smrg
11887ec681f3Smrg  <ins name="FEXP.f32" title="Floating-point exponent" dests="1" opcode="0xA4" opcode2="8">
11897ec681f3Smrg    <desc>
11907ec681f3Smrg      Calculates the base-2 exponent of an argument specified as a 8:24
11917ec681f3Smrg      fixed-point. The original argument is passed as well for correct handling
11927ec681f3Smrg      of special cases.
11937ec681f3Smrg    </desc>
11947ec681f3Smrg    <clamp/>
11957ec681f3Smrg    <src>Input as 8:24 fixed-point</src>
11967ec681f3Smrg    <src absneg="true">Input as 32-bit float</src>
11977ec681f3Smrg  </ins>
11987ec681f3Smrg
11997ec681f3Smrg  <ins name="FADD_LSCALE.f32" title="Floating-point add with logarithm scale" dests="1" opcode="0xA4" opcode2="9">
12007ec681f3Smrg    <desc>
12017ec681f3Smrg      Performs a floating-point addition specialized for logarithm computation.
12027ec681f3Smrg    </desc>
12037ec681f3Smrg    <clamp/>
12047ec681f3Smrg    <src absneg="true">A</src>
12057ec681f3Smrg    <src absneg="true">B</src>
12067ec681f3Smrg  </ins>
12077ec681f3Smrg
12087ec681f3Smrg  <group name="IADD" title="Integer addition" dests="1" opcode2="0">
12097ec681f3Smrg    <desc>
12107ec681f3Smrg      $A + B$ with optional saturation.
12117ec681f3Smrg
12127ec681f3Smrg      As Valhall lacks swizzle instructions, `IADD.v2i16` with zero is the
12137ec681f3Smrg      canonical lowering for swizzles.
12147ec681f3Smrg    </desc>
12157ec681f3Smrg    <ins name="IADD.u32" opcode="0xA0"/>
12167ec681f3Smrg    <ins name="IADD.v2u16" opcode="0xA1"/>
12177ec681f3Smrg    <ins name="IADD.v4u8" opcode="0xA2"/>
12187ec681f3Smrg    <ins name="IADD.s32" opcode="0xA8"/>
12197ec681f3Smrg    <ins name="IADD.v2s16" opcode="0xA9"/>
12207ec681f3Smrg    <ins name="IADD.v4s8" opcode="0x1A2"/>
12217ec681f3Smrg    <ins name="IADD.u64" opcode="0x1A3"/>
12227ec681f3Smrg    <ins name="IADD.s64" opcode="0x1AB"/>
12237ec681f3Smrg    <!-- <ins name="IADD.s32" opcode="0x1A0"/> -->
12247ec681f3Smrg    <src widen="true">A</src>
12257ec681f3Smrg    <src widen="true">B</src>
12267ec681f3Smrg    <saturate/>
12277ec681f3Smrg  </group>
12287ec681f3Smrg
12297ec681f3Smrg  <ins name="MKVEC.v2i16" title="Make 16-bit vector" dests="1" opcode="0xA1" opcode2="0x5">
12307ec681f3Smrg    <desc>Calculates $A | (B \ll 16)$. Used to implement `(ushort2)(A, B)`</desc>
12317ec681f3Smrg    <src widen="true">A</src>
12327ec681f3Smrg    <src widen="true">B</src>
12337ec681f3Smrg  </ins>
12347ec681f3Smrg
12357ec681f3Smrg  <group name="ISUB" title="Integer subtract" dests="1" opcode2="1">
12367ec681f3Smrg    <ins name="ISUB.u32" opcode="0xA0"/>
12377ec681f3Smrg    <ins name="ISUB.v2u16" opcode="0xA1"/>
12387ec681f3Smrg    <ins name="ISUB.v4u8" opcode="0xA2"/>
12397ec681f3Smrg    <ins name="ISUB.s32" opcode="0xA8"/>
12407ec681f3Smrg    <ins name="ISUB.v2s16" opcode="0xA9"/>
12417ec681f3Smrg    <ins name="ISUB.v4s8" opcode="0x1A2"/>
12427ec681f3Smrg    <ins name="ISUB.u64" opcode="0x1A3"/>
12437ec681f3Smrg    <ins name="ISUB.s64" opcode="0x1AB"/>
12447ec681f3Smrg    <desc>$A - B$ with optional saturation</desc>
12457ec681f3Smrg    <src widen="true">A</src>
12467ec681f3Smrg    <src widen="true">B</src>
12477ec681f3Smrg    <saturate/>
12487ec681f3Smrg  </group>
12497ec681f3Smrg
12507ec681f3Smrg  <group name="SHADDX" title="Shift, extend, and 64-bit add" dests="1" opcode2="7">
12517ec681f3Smrg    <desc>
12527ec681f3Smrg      Sign or zero extend B to 64-bits, left-shift by `shift`, and add the
12537ec681f3Smrg      64-bit value A. These instructions accelerate address arithmetic, but may
12547ec681f3Smrg      be used in full generality for 64-bit integer arithmetic.
12557ec681f3Smrg    </desc>
12567ec681f3Smrg    <ins name="SHADDX.u64" opcode="0x1A3"/>
12577ec681f3Smrg    <ins name="SHADDX.s64" opcode="0x1AB"/>
12587ec681f3Smrg    <imm name="shift" start="20" size="3"/>
12597ec681f3Smrg    <src>A</src>
12607ec681f3Smrg    <src widen="true">B</src>
12617ec681f3Smrg  </group>
12627ec681f3Smrg
12637ec681f3Smrg  <group name="IMUL" title="Integer multiply" dests="1" opcode2="0x0A">
12647ec681f3Smrg    <ins name="IMUL.i32" opcode="0xA0"/>
12657ec681f3Smrg    <ins name="IMUL.v2i16" opcode="0xA1"/>
12667ec681f3Smrg    <ins name="IMUL.v4i8" opcode="0xA2"/>
12677ec681f3Smrg    <ins name="IMUL.s32" opcode="0xA8"/>
12687ec681f3Smrg    <ins name="IMUL.v2s16" opcode="0xA9"/>
12697ec681f3Smrg    <ins name="IMUL.v4s8" opcode="0x1A2"/>
12707ec681f3Smrg    <ins name="IMULD.u64" opcode="0x1A3"/>
12717ec681f3Smrg    <!-- <ins name="IMUL.s32" opcode="0x1A0"/> -->
12727ec681f3Smrg    <desc>
12737ec681f3Smrg      $A \cdot B$ with optional saturation. Note the multipliers can only handle up to
12747ec681f3Smrg      32-bit by 32-bit multiplies. The 64-bit "multiply" acts like IMUL.u32 but
12757ec681f3Smrg      additionally writes the high half of the product to the high half of the
12767ec681f3Smrg      64-bit destination. Along with IADD.u32 and IADD.u64, this allows the
12777ec681f3Smrg      construction of a 64-bit multiply in 5 instructions (6 clocks).
12787ec681f3Smrg    </desc>
12797ec681f3Smrg    <src widen="true">A</src>
12807ec681f3Smrg    <src widen="true">B</src>
12817ec681f3Smrg    <saturate/>
12827ec681f3Smrg  </group>
12837ec681f3Smrg
12847ec681f3Smrg  <group name="HADD" title="Integer half-add" dests="1" opcode2="0x0B">
12857ec681f3Smrg    <ins name="HADD.u32" opcode="0xA0"/>
12867ec681f3Smrg    <ins name="HADD.v2u16" opcode="0xA1"/>
12877ec681f3Smrg    <ins name="HADD.v4u8" opcode="0xA2"/>
12887ec681f3Smrg    <ins name="HADD.s32" opcode="0xA8"/>
12897ec681f3Smrg    <ins name="HADD.v2s16" opcode="0xA9"/>
12907ec681f3Smrg    <ins name="HADD.v4s8" opcode="0x1A2"/>
12917ec681f3Smrg    <mod name="rhadd" start="30" size="1"/>
12927ec681f3Smrg    <src widen="true">A</src>
12937ec681f3Smrg    <src widen="true">B</src>
12947ec681f3Smrg    <desc>
12957ec681f3Smrg      $(A + B) \gg 1$ without intermediate overflow, corresponding to `hadd()` in
12967ec681f3Smrg      OpenCL. With the `.rhadd` modifier set, it instead calculates
12977ec681f3Smrg      $(A + B + 1) \gg 1$ corresponding to `rhadd()` in OpenCL.
12987ec681f3Smrg    </desc>
12997ec681f3Smrg  </group>
13007ec681f3Smrg
13017ec681f3Smrg  <group name="CLPER" title="Cross-lane permute" dests="1" opcode2="0xF">
13027ec681f3Smrg    <ins name="CLPER.i32" opcode="0xA0"/>
13037ec681f3Smrg    <ins name="CLPER.v2u16" opcode="0xA1"/>
13047ec681f3Smrg    <ins name="CLPER.v4u8" opcode="0xA2"/>
13057ec681f3Smrg    <ins name="CLPER.s32" opcode="0xA8"/>
13067ec681f3Smrg    <ins name="CLPER.v2s16" opcode="0xA9"/>
13077ec681f3Smrg    <ins name="CLPER.v4s8" opcode="0x1A2"/>
13087ec681f3Smrg    <ins name="CLPER.u64" opcode="0x1A3"/>
13097ec681f3Smrg    <ins name="CLPER.s64" opcode="0x1AB"/>
13107ec681f3Smrg    <!-- <ins name="CLPER.s32" opcode="0x1A0"/> -->
13117ec681f3Smrg    <desc>
13127ec681f3Smrg      Selects the value of A in the subgroup lane given by B. This implements
13137ec681f3Smrg      subgroup broadcasts. It may be used as a primitive for screen space
13147ec681f3Smrg      derivatives in fragment shaders.
13157ec681f3Smrg    </desc>
13167ec681f3Smrg    <src>A</src>
13177ec681f3Smrg    <src widen="true">B</src>
13187ec681f3Smrg    <subgroup/>
13197ec681f3Smrg    <lane_op/>
13207ec681f3Smrg    <inactive_result/>
13217ec681f3Smrg  </group>
13227ec681f3Smrg
13237ec681f3Smrg  <group name="FMA" title="Fused floating-point multiply add" dests="1">
13247ec681f3Smrg    <ins name="FMA.f32" opcode="0xB2"/>
13257ec681f3Smrg    <ins name="FMA.v2f16" opcode="0xB3"/>
13267ec681f3Smrg    <desc>$A \cdot B + C$</desc>
13277ec681f3Smrg    <clamp/>
13287ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
13297ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
13307ec681f3Smrg    <src absneg="true" swizzle="true">C</src>
13317ec681f3Smrg  </group>
13327ec681f3Smrg
13337ec681f3Smrg  <group name="LSHIFT_AND" title="Left shift and bitwise AND" dests="1" opcode2="0x100">
13347ec681f3Smrg    <ins name="LSHIFT_AND.i32" opcode="0xB4"/>
13357ec681f3Smrg    <ins name="LSHIFT_AND.v2i16" opcode="0xB5"/>
13367ec681f3Smrg    <ins name="LSHIFT_AND.v4i8" opcode="0xB6"/>
13377ec681f3Smrg    <ins name="LSHIFT_AND.i64" opcode="0x1B7"/>
13387ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
13397ec681f3Smrg    <desc>
13407ec681f3Smrg      Left shifts its first source by a specified amount and bitwise ANDs it with the
13417ec681f3Smrg      second source, optionally inverting the second source or the result.
13427ec681f3Smrg    </desc>
13437ec681f3Smrg    <not_result/>
13447ec681f3Smrg    <src widen="true">A</src>
13457ec681f3Smrg    <src lanes="true" size="8">shift</src>
13467ec681f3Smrg    <src not="true">B</src>
13477ec681f3Smrg  </group>
13487ec681f3Smrg
13497ec681f3Smrg  <group name="RSHIFT_AND" title="Right shift and bitwise AND" dests="1" opcode2="0x000">
13507ec681f3Smrg    <ins name="RSHIFT_AND.i32" opcode="0xB4"/>
13517ec681f3Smrg    <ins name="RSHIFT_AND.v2i16" opcode="0xB5"/>
13527ec681f3Smrg    <ins name="RSHIFT_AND.v4i8" opcode="0xB6"/>
13537ec681f3Smrg    <ins name="RSHIFT_AND.i64" opcode="0x1B7"/>
13547ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
13557ec681f3Smrg    <desc>
13567ec681f3Smrg      Right shifts its first source by a specified amount and bitwise ANDs it with the
13577ec681f3Smrg      second source, optionally inverting the second source or the result.
13587ec681f3Smrg    </desc>
13597ec681f3Smrg    <not_result/>
13607ec681f3Smrg    <src widen="true">A</src>
13617ec681f3Smrg    <src lanes="true" size="8">shift</src>
13627ec681f3Smrg    <src not="true">B</src>
13637ec681f3Smrg  </group>
13647ec681f3Smrg
13657ec681f3Smrg  <group name="LSHIFT_OR" title="Left shift and bitwise OR" dests="1" opcode2="0x101">
13667ec681f3Smrg    <ins name="LSHIFT_OR.i32" opcode="0xB4"/>
13677ec681f3Smrg    <ins name="LSHIFT_OR.v2i16" opcode="0xB5"/>
13687ec681f3Smrg    <ins name="LSHIFT_OR.v4i8" opcode="0xB6"/>
13697ec681f3Smrg    <ins name="LSHIFT_OR.i64" opcode="0x1B7"/>
13707ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
13717ec681f3Smrg    <desc>
13727ec681f3Smrg      Left shifts its first source by a specified amount and bitwise ORs it with the
13737ec681f3Smrg      second source, optionally inverting the second source or the result.
13747ec681f3Smrg    </desc>
13757ec681f3Smrg    <not_result/>
13767ec681f3Smrg    <src widen="true">A</src>
13777ec681f3Smrg    <src lanes="true" size="8">shift</src>
13787ec681f3Smrg    <src not="true">B</src>
13797ec681f3Smrg  </group>
13807ec681f3Smrg
13817ec681f3Smrg  <group name="RSHIFT_OR" title="Right shift and bitwise OR" dests="1" opcode2="0x001">
13827ec681f3Smrg    <ins name="RSHIFT_OR.i32" opcode="0xB4"/>
13837ec681f3Smrg    <ins name="RSHIFT_OR.v2i16" opcode="0xB5"/>
13847ec681f3Smrg    <ins name="RSHIFT_OR.v4i8" opcode="0xB6"/>
13857ec681f3Smrg    <ins name="RSHIFT_OR.i64" opcode="0x1B7"/>
13867ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
13877ec681f3Smrg    <desc>
13887ec681f3Smrg      Right shifts its first source by a specified amount and bitwise ORs it with the
13897ec681f3Smrg      second source, optionally inverting the second source or the result.
13907ec681f3Smrg    </desc>
13917ec681f3Smrg    <not_result/>
13927ec681f3Smrg    <src widen="true">A</src>
13937ec681f3Smrg    <src lanes="true" size="8">shift</src>
13947ec681f3Smrg    <src not="true">B</src>
13957ec681f3Smrg  </group>
13967ec681f3Smrg
13977ec681f3Smrg  <group name="LSHIFT_XOR" title="Left shift and bitwise XOR" dests="1" opcode2="0x102">
13987ec681f3Smrg    <ins name="LSHIFT_XOR.i32" opcode="0xB4"/>
13997ec681f3Smrg    <ins name="LSHIFT_XOR.v2i16" opcode="0xB5"/>
14007ec681f3Smrg    <ins name="LSHIFT_XOR.v4i8" opcode="0xB6"/>
14017ec681f3Smrg    <ins name="LSHIFT_XOR.i64" opcode="0x1B7"/>
14027ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
14037ec681f3Smrg    <desc>
14047ec681f3Smrg      Left shifts its first source by a specified amount and bitwise XORs it with the
14057ec681f3Smrg      second source, optionally inverting the second source or the result.
14067ec681f3Smrg    </desc>
14077ec681f3Smrg    <not_result/>
14087ec681f3Smrg    <src widen="true">A</src>
14097ec681f3Smrg    <src lanes="true" size="8">shift</src>
14107ec681f3Smrg    <src not="true">B</src>
14117ec681f3Smrg  </group>
14127ec681f3Smrg
14137ec681f3Smrg  <group name="RSHIFT_XOR" title="Right shift and bitwise XOR" dests="1" opcode2="0x002">
14147ec681f3Smrg    <ins name="RSHIFT_XOR.i32" opcode="0xB4"/>
14157ec681f3Smrg    <ins name="RSHIFT_XOR.v2i16" opcode="0xB5"/>
14167ec681f3Smrg    <ins name="RSHIFT_XOR.v4i8" opcode="0xB6"/>
14177ec681f3Smrg    <ins name="RSHIFT_XOR.i64" opcode="0x1B7"/>
14187ec681f3Smrg    <mod name="left" start="128" size="1" implied="true"/>
14197ec681f3Smrg    <desc>
14207ec681f3Smrg      Right shifts its first source by a specified amount and bitwise XORs it with the
14217ec681f3Smrg      second source, optionally inverting the second source or the result.
14227ec681f3Smrg    </desc>
14237ec681f3Smrg    <not_result/>
14247ec681f3Smrg    <src widen="true">A</src>
14257ec681f3Smrg    <src lanes="true" size="8">shift</src>
14267ec681f3Smrg    <src not="true">B</src>
14277ec681f3Smrg  </group>
14287ec681f3Smrg
14297ec681f3Smrg  <ins name="MUX.i32" title="Mux" dests="1" opcode="0xB8">
14307ec681f3Smrg    <desc>
14317ec681f3Smrg      Mux between A and B based on the provided mask. Equivalent to
14327ec681f3Smrg      `bitselect()` in OpenCL. `(A &amp; mask) | (A &amp; ~mask)`
14337ec681f3Smrg    </desc>
14347ec681f3Smrg    <src>A</src>
14357ec681f3Smrg    <src>B</src>
14367ec681f3Smrg    <src>Mask</src>
14377ec681f3Smrg  </ins>
14387ec681f3Smrg
14397ec681f3Smrg  <ins name="CUBE_SSEL" title="Cube S-coordinate select" dests="1" opcode="0xBC" opcode2="0">
14407ec681f3Smrg    <desc>During a cube map transform, select the S coordinate given a selected face.</desc>
14417ec681f3Smrg    <src absneg="true">Z coordinate as 32-bit floating point</src>
14427ec681f3Smrg    <src absneg="true">X coordinate as 32-bit floating point</src>
14437ec681f3Smrg    <src>Cube face index</src>
14447ec681f3Smrg  </ins>
14457ec681f3Smrg
14467ec681f3Smrg  <ins name="CUBE_TSEL" title="Cube T-coordinate select" dests="1" opcode="0xBC" opcode2="1">
14477ec681f3Smrg    <desc>During a cube map transform, select the T coordinate given a selected face.</desc>
14487ec681f3Smrg    <src absneg="true">Y coordinate as 32-bit floating point</src>
14497ec681f3Smrg    <src absneg="true">Z coordinate as 32-bit floating point</src>
14507ec681f3Smrg    <src>Cube face index</src>
14517ec681f3Smrg  </ins>
14527ec681f3Smrg
14537ec681f3Smrg  <ins name="MKVEC.v4i8" title="Make 8-bit vector" dests="1" opcode="0xBD">
14547ec681f3Smrg    <desc>
14557ec681f3Smrg      Calculates $A | (B \ll 8) | (CD \ll 16)$ for 8-bit A and B and 16-bit CD.
14567ec681f3Smrg
14577ec681f3Smrg      To implement `(uchar4) (A, B, C, D)` in full generality, use the sequence
14587ec681f3Smrg      `MKVEC.v4i8 CD, C, D, #0; MKVEC.v4i8 out, A, B, CD`
14597ec681f3Smrg
14607ec681f3Smrg      `MKVEC.v4i8` also allows zero extending arbitrary 8-bit lanes. For
14617ec681f3Smrg      example, to extend `r0.b3` to `r1`, use `MKVEC.v4i8 r1, r0.b3, 0x0.b0, 0x0`.
14627ec681f3Smrg    </desc>
14637ec681f3Smrg    <src lane="true">A</src>
14647ec681f3Smrg    <src lane="true">B</src>
14657ec681f3Smrg    <src>CD</src>
14667ec681f3Smrg  </ins>
14677ec681f3Smrg
14687ec681f3Smrg  <ins name="CUBEFACE1" title="Cube map transform step 1" dests="1" opcode="0xC0">
14697ec681f3Smrg    <desc>Select the maximum absolute value of its arguments.</desc>
14707ec681f3Smrg    <src absneg="true">X coordinate as 32-bit floating point</src>
14717ec681f3Smrg    <src absneg="true">Y coordinate as 32-bit floating point</src>
14727ec681f3Smrg    <src absneg="true">Z coordinate as 32-bit floating point</src>
14737ec681f3Smrg  </ins>
14747ec681f3Smrg
14757ec681f3Smrg  <ins name="CUBEFACE2" title="Cube map transform step 2" dests="1" opcode="0xC1">
14767ec681f3Smrg    <desc>Select the cube face index corresponding to the arguments.</desc>
14777ec681f3Smrg    <src absneg="true">X coordinate as 32-bit floating point</src>
14787ec681f3Smrg    <src absneg="true">Y coordinate as 32-bit floating point</src>
14797ec681f3Smrg    <src absneg="true">Z coordinate as 32-bit floating point</src>
14807ec681f3Smrg  </ins>
14817ec681f3Smrg
14827ec681f3Smrg  <group name="IDP" title="8-bit dot product" dests="1" opcode="0xC2">
14837ec681f3Smrg    <desc>
14847ec681f3Smrg      8-bit integer dot product between 4 channel vectors, intended for machine
14857ec681f3Smrg      learning. Available in both unsigned and signed variants, controlling
14867ec681f3Smrg      sign-extension/zero-extension behaviour to the final 32-bit destination.
14877ec681f3Smrg      Saturation is available. Corresponds to the `cl_arm_integer_dot_product_*`
14887ec681f3Smrg      family of OpenCL extensions. Not for actual use, just for completeness.
14897ec681f3Smrg      Instead, use your platform's neural accelerator.
14907ec681f3Smrg
14917ec681f3Smrg      For $A, B \in \{ 0, \ldots, 255 \}^4$ and $\text{Accumulator} \in
14927ec681f3Smrg      \mathbb{Z}$, calculates $(A \cdot B) + \text{Accumulator}$ and optionally
14937ec681f3Smrg      saturates.
14947ec681f3Smrg    </desc>
14957ec681f3Smrg    <ins name="IDP.v4s8" opcode2="0"/>
14967ec681f3Smrg    <ins name="IDP.v4u8" opcode2="1"/>
14977ec681f3Smrg    <src>A</src>
14987ec681f3Smrg    <src>B</src>
14997ec681f3Smrg    <src>Accumulator</src>
15007ec681f3Smrg    <saturate/>
15017ec681f3Smrg  </group>
15027ec681f3Smrg
15037ec681f3Smrg  <group name="ICMP" title="Unsigned integer compare" dests="1">
15047ec681f3Smrg    <desc>
15057ec681f3Smrg      Evaluates the given condition, do a logical and/or with the condition in
15067ec681f3Smrg      the result source, and return in the given result type (integer
15077ec681f3Smrg      one, integer minus one, or floating-point one). The third source is useful
15087ec681f3Smrg      for chaining together conditions without intermediate bitwise arithmetic;
15097ec681f3Smrg      when this is not desired, tie it to zero and use the OR combine mode (do
15107ec681f3Smrg      not set the `.and` modifier).
15117ec681f3Smrg
15127ec681f3Smrg      The sequence modifier `.seq` is used to construct 64-bit compares in 2
15137ec681f3Smrg      `ICMP.u32` instructions, in conjunction with the `u1` result type on the
15147ec681f3Smrg      low half, the `m1` result type on the high half, and the result of the low
15157ec681f3Smrg      half comparison passed as the third source. For comparisons other than
15167ec681f3Smrg      64-bit, do not set the `.seq` modifier and do not use the `u1` result
15177ec681f3Smrg      type.
15187ec681f3Smrg    </desc>
15197ec681f3Smrg    <ins name="ICMP.u32" opcode="0xF0"/>
15207ec681f3Smrg    <ins name="ICMP.v2u16" opcode="0xF1"/>
15217ec681f3Smrg    <ins name="ICMP.v4u8" opcode="0xF2"/>
15227ec681f3Smrg    <cmp/>
15237ec681f3Smrg    <result_type/>
15247ec681f3Smrg    <mod name="and" start="24" size="1"/>
15257ec681f3Smrg    <mod name="seq" start="25" size="1"/>
15267ec681f3Smrg    <src widen="true">A</src>
15277ec681f3Smrg    <src widen="true">B</src>
15287ec681f3Smrg    <src>C</src>
15297ec681f3Smrg  </group>
15307ec681f3Smrg
15317ec681f3Smrg  <group name="FCMP" title="Floating-point compare" dests="1">
15327ec681f3Smrg    <desc>
15337ec681f3Smrg      Evaluates the given condition, do a logical and/or with the condition in
15347ec681f3Smrg      the result source, and return in the given result type (integer
15357ec681f3Smrg      one, integer minus one, or floating-point one). The third source is useful
15367ec681f3Smrg      for chaining together conditions without intermediate bitwise arithmetic;
15377ec681f3Smrg      when this is not desired, tie it to zero and use the OR combine mode (do
15387ec681f3Smrg      not set the `.and` modifier).
15397ec681f3Smrg    </desc>
15407ec681f3Smrg    <ins name="FCMP.f32" opcode="0xF4"/>
15417ec681f3Smrg    <ins name="FCMP.v2f16" opcode="0xF5"/>
15427ec681f3Smrg    <cmp/>
15437ec681f3Smrg    <result_type/>
15447ec681f3Smrg    <mod name="and" start="24" size="1"/>
15457ec681f3Smrg    <src absneg="true" swizzle="true">A</src>
15467ec681f3Smrg    <src absneg="true" swizzle="true">B</src>
15477ec681f3Smrg    <src>C</src>
15487ec681f3Smrg  </group>
15497ec681f3Smrg
15507ec681f3Smrg  <group name="ICMP" title="Signed integer compare" dests="1">
15517ec681f3Smrg    <desc>
15527ec681f3Smrg      Evaluates the given condition, do a logical and/or with the condition in
15537ec681f3Smrg      the result source, and return in the given result type (integer
15547ec681f3Smrg      one, integer minus one, or floating-point one). The third source is useful
15557ec681f3Smrg      for chaining together conditions without intermediate bitwise arithmetic;
15567ec681f3Smrg      when this is not desired, tie it to zero and use the OR combine mode (do
15577ec681f3Smrg      not set the `.and` modifier).
15587ec681f3Smrg
15597ec681f3Smrg      The sequence modifier `.seq` is used to construct signed 64-bit compares
15607ec681f3Smrg      in 1 `ICMP.u32` and 1 `ICMP.s32` instruction, in conjunction with the `u1`
15617ec681f3Smrg      result type on the low half, the `m1` result type on the high half, and
15627ec681f3Smrg      the result of the low half comparison passed as the third source. For
15637ec681f3Smrg      comparisons other than 64-bit, do not set the `.seq` modifier and do not
15647ec681f3Smrg      use the `u1` result type.
15657ec681f3Smrg    </desc>
15667ec681f3Smrg    <ins name="ICMP.s32" opcode="0xF8"/>
15677ec681f3Smrg    <ins name="ICMP.v2s16" opcode="0xF9"/>
15687ec681f3Smrg    <ins name="ICMP.v4s8" opcode="0xFA"/>
15697ec681f3Smrg    <cmp/>
15707ec681f3Smrg    <result_type/>
15717ec681f3Smrg    <mod name="and" start="24" size="1"/>
15727ec681f3Smrg    <mod name="seq" start="25" size="1"/>
15737ec681f3Smrg    <src widen="true">A</src>
15747ec681f3Smrg    <src widen="true">B</src>
15757ec681f3Smrg    <src>C</src>
15767ec681f3Smrg  </group>
15777ec681f3Smrg
15787ec681f3Smrg  <ins name="IADD_IMM.i32" title="Integer addition with immediate" dests="1" opcode="0x110">
15797ec681f3Smrg    <desc>
15807ec681f3Smrg      Adds an arbitrary 32-bit immediate embedded within the instruction stream.
15817ec681f3Smrg      If no modifiers are required, this is preferred to `IADD.i32` with a
15827ec681f3Smrg      constant accessed as a uniform. However, if the constant is available
15837ec681f3Smrg      inline, `IADD.f32` is preferred.
15847ec681f3Smrg
15857ec681f3Smrg      `IADD_IMM.i32` with the source tied to zero is the canonical immediate move.
15867ec681f3Smrg    </desc>
15877ec681f3Smrg    <src>A</src>
15887ec681f3Smrg    <imm name="constant" start="8" size="32"/>
15897ec681f3Smrg  </ins>
15907ec681f3Smrg
15917ec681f3Smrg  <ins name="IADD_IMM.v2i16" title="Integer addition with immediate" dests="1" opcode="0x111">
15927ec681f3Smrg    <desc>
15937ec681f3Smrg      Adds an arbitrary pair of 16-bit immediates embedded within the
15947ec681f3Smrg      instruction stream. If no modifiers are required, this is preferred to
15957ec681f3Smrg      `IADD.v2i16` with a constant accessed as a uniform. However, if the
15967ec681f3Smrg      constant is available inline, `IADD.v2i16` is preferred. Adding only a
15977ec681f3Smrg      single 16-bit constant requires replication of the constant.
15987ec681f3Smrg    </desc>
15997ec681f3Smrg    <src>A</src>
16007ec681f3Smrg    <imm name="constant" start="8" size="32"/>
16017ec681f3Smrg  </ins>
16027ec681f3Smrg
16037ec681f3Smrg  <ins name="IADD_IMM.v4i8" title="Integer addition with immediate" dests="1" opcode="0x112">
16047ec681f3Smrg    <desc>
16057ec681f3Smrg      Adds an arbitrary quad of 8-bit immediates embedded within the
16067ec681f3Smrg      instruction stream. If no modifiers are required, this is preferred to
16077ec681f3Smrg      `IADD.v4i8` with a constant accessed as a uniform. However, if the
16087ec681f3Smrg      constant is available inline, `IADD.v4i8` is preferred. Adding only a
16097ec681f3Smrg      single 8-bit constant requires replication of the constant.
16107ec681f3Smrg    </desc>
16117ec681f3Smrg    <src>A</src>
16127ec681f3Smrg    <imm name="constant" start="8" size="32"/>
16137ec681f3Smrg  </ins>
16147ec681f3Smrg
16157ec681f3Smrg  <ins name="FADD_IMM.f32" title="Floating-point addition with immediate" dests="1" opcode="0x114">
16167ec681f3Smrg    <desc>
16177ec681f3Smrg      Adds an arbitrary 32-bit immediate embedded within the instruction stream.
16187ec681f3Smrg      If no modifiers are required, this is preferred to `FADD.f32` with a
16197ec681f3Smrg      constant accessed as a uniform. However, if the constant is available
16207ec681f3Smrg      inline, `FADD.f32` is preferred.
16217ec681f3Smrg    </desc>
16227ec681f3Smrg    <src>A</src>
16237ec681f3Smrg    <imm name="constant" start="8" size="32"/>
16247ec681f3Smrg  </ins>
16257ec681f3Smrg
16267ec681f3Smrg  <ins name="FADD_IMM.v2f16" title="Floating-point addition with immediate" dests="1" opcode="0x115">
16277ec681f3Smrg    <desc>
16287ec681f3Smrg      Adds an arbitrary pair of 16-bit immediates embedded within the
16297ec681f3Smrg      instruction stream. If no modifiers are required, this is preferred to
16307ec681f3Smrg      `FADD.v2f16` with a constant accessed as a uniform. However, if the
16317ec681f3Smrg      constant is available inline, `FADD.v2f16` is preferred. Adding only a
16327ec681f3Smrg      single 16-bit constant requires replication of the constant.
16337ec681f3Smrg    </desc>
16347ec681f3Smrg    <src float="true">A</src>
16357ec681f3Smrg    <imm name="constant" start="8" size="32"/>
16367ec681f3Smrg  </ins>
16377ec681f3Smrg
16387ec681f3Smrg  <ins name="TODO.ATOM_C1" title="Atomic operations on memory with 1" opcode="0x69">
16397ec681f3Smrg    <!-- TODO -->
16407ec681f3Smrg    <mod name="i32" start="17" size="1"/>
16417ec681f3Smrg    <mod name="unk" start="23" size="1"/>
16427ec681f3Smrg    <sr write="true"/>
16437ec681f3Smrg    <src/>
16447ec681f3Smrg    <imm name="operation" start="24" size="6"/>
16457ec681f3Smrg    <sr_count/>
16467ec681f3Smrg    <slot/>
16477ec681f3Smrg  </ins>
16487ec681f3Smrg
16497ec681f3Smrg  <ins name="TODO.ATOM_C" title="Atomic operations on memory" opcode="0x120">
16507ec681f3Smrg    <!-- TODO -->
16517ec681f3Smrg    <mod name="i32" start="17" size="1"/>
16527ec681f3Smrg    <mod name="unk" start="23" size="1"/>
16537ec681f3Smrg    <sr read="true" write="true"/>
16547ec681f3Smrg    <src/>
16557ec681f3Smrg    <imm name="operation" start="24" size="6"/>
16567ec681f3Smrg    <sr_count/>
16577ec681f3Smrg    <slot/>
16587ec681f3Smrg  </ins>
16597ec681f3Smrg
16607ec681f3Smrg  <ins name="TEX_FETCH" title="Texel fetch" opcode="0x125">
16617ec681f3Smrg    <desc>Unfiltered textured instruction.</desc>
16627ec681f3Smrg    <sr read="true"/>
16637ec681f3Smrg    <sr write="true" count="4"/>
16647ec681f3Smrg    <mod name="explicit_offset" start="11" size="1"/>
16657ec681f3Smrg    <mod name="dimension" start="28" size="2"/>
16667ec681f3Smrg    <mod name="skip" start="39" size="1"/>
16677ec681f3Smrg    <sr_count/>
16687ec681f3Smrg    <slot/>
16697ec681f3Smrg    <src>Image to read from</src>
16707ec681f3Smrg  </ins>
16717ec681f3Smrg
16727ec681f3Smrg  <ins name="TEX" title="Texture load" opcode="0x128">
16737ec681f3Smrg    <desc>Ordinary texturing instruction using a sampler.</desc>
16747ec681f3Smrg    <sr read="true"/>
16757ec681f3Smrg    <sr write="true" count="4"/>
16767ec681f3Smrg    <src>Image to read from</src>
16777ec681f3Smrg    <mod name="explicit_offset" start="11" size="1"/>
16787ec681f3Smrg    <mod name="shadow" start="12" size="1"/>
16797ec681f3Smrg    <mod name="lod_mode" start="13" size="3"/>
16807ec681f3Smrg    <mod name="dimension" start="28" size="2"/>
16817ec681f3Smrg    <mod name="skip" start="39" size="1"/>
16827ec681f3Smrg    <sr_count/>
16837ec681f3Smrg    <slot/>
16847ec681f3Smrg  </ins>
16857ec681f3Smrg
16867ec681f3Smrg  <ins name="TODO.VAR_TEX" title="Fused varying-texturing" opcode="0x130">
16877ec681f3Smrg    <desc>Only works for FP32 varyings.</desc>
16887ec681f3Smrg    <sr write="true" count="4"/>
16897ec681f3Smrg    <mod name="dimension" start="28" size="2"/>
16907ec681f3Smrg    <mod name="skip" start="39" size="1"/>
16917ec681f3Smrg    <slot/>
16927ec681f3Smrg    <src>Image to read from</src>
16937ec681f3Smrg  </ins>
16947ec681f3Smrg
16957ec681f3Smrg  <ins name="FMA_RSCALE.f32" title="Fused floating-point multiply add with exponent bias" dests="1" opcode="0x160">
16967ec681f3Smrg    <desc>
16977ec681f3Smrg      First calculates $A \cdot B + C$ and then biases the exponent by D. Used in
16987ec681f3Smrg      special transcendental function sequences. It should not be used for
16997ec681f3Smrg      general code as its special case handling differs from two back-to-back
17007ec681f3Smrg      `FMA.f32` operations. Equivalent to `FMA.f32` back-to-back with
17017ec681f3Smrg      `RSCALE.f32`
17027ec681f3Smrg    </desc>
17037ec681f3Smrg    <clamp/>
17047ec681f3Smrg    <src absneg="true">A</src>
17057ec681f3Smrg    <src absneg="true">B</src>
17067ec681f3Smrg    <src absneg="true">C</src>
17077ec681f3Smrg    <src>D</src>
17087ec681f3Smrg  </ins>
17097ec681f3Smrg
17107ec681f3Smrg</valhall>
1711