nir: Add extr_agx opcode
authorHampus Linander <hampus.linander@gmail.com>
Thu, 12 Jan 2023 17:38:28 +0000 (18:38 +0100)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 4 Feb 2023 16:13:24 +0000 (11:13 -0500)
The AGX extr instruction extracts a bitfield from two 32bit registers.

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20628>

src/compiler/nir/nir_opcodes.py

index d8b80f6..06d6a2d 100644 (file)
@@ -1278,6 +1278,26 @@ unop("fcos_mdg", tfloat, "cosf(3.141592653589793 * src0)")
 # additional ALU that NIR may be able to optimize.
 unop("fsin_agx", tfloat, "sinf(src0 * (6.2831853/4.0))")
 
+# AGX specific bitfield extraction from a pair of 32bit registers.
+# src0,src1: the two registers
+# src2: bit position of the LSB of the bitfield
+# src3: number of bits in the bitfield if src3 > 0
+#       src3 = 0 is equivalent to src3 = 32
+# NOTE: src3 is a nir constant by contract
+opcode("extr_agx", 0, tuint32,
+       [0, 0, 0, 0], [tuint32, tuint32, tuint32, tuint32], False, "", """
+    uint32_t mask = 0xFFFFFFFF;
+    uint8_t shift = src2 & 0x7F;
+    if (src3 != 0) {
+       mask = (1 << src3) - 1;
+    }
+    if (shift >= 64) {
+        dst = 0;
+    } else {
+        dst = (((((uint64_t) src1) << 32) | (uint64_t) src0) >> shift) & mask;
+    }
+""");
+
 # 24b multiply into 32b result (with sign extension)
 binop("imul24", tint32, _2src_commutative + associative,
       "(((int32_t)src0 << 8) >> 8) * (((int32_t)src1 << 8) >> 8)")