broadcom/vc5: Add support for QPU pack/unpack/disasm of small immediates.
authorEric Anholt <eric@anholt.net>
Fri, 5 Jan 2018 06:47:54 +0000 (22:47 -0800)
committerEric Anholt <eric@anholt.net>
Sat, 13 Jan 2018 05:54:18 +0000 (21:54 -0800)
src/broadcom/qpu/qpu_disasm.c
src/broadcom/qpu/qpu_instr.h
src/broadcom/qpu/qpu_pack.c
src/broadcom/qpu/tests/qpu_disasm.c

index 73b43f8c3d63b5d13a5b8c83b51f9bddb45645e4..32e7ba12a4c51e00627e400806d87b0e324ede81 100644 (file)
@@ -62,7 +62,21 @@ v3d_qpu_disasm_raddr(struct disasm_state *disasm,
         if (mux == V3D_QPU_MUX_A) {
                 append(disasm, "rf%d", instr->raddr_a);
         } else if (mux == V3D_QPU_MUX_B) {
-                append(disasm, "rf%d", instr->raddr_b);
+                if (instr->sig.small_imm) {
+                        uint32_t val;
+                        MAYBE_UNUSED bool ok =
+                                v3d_qpu_small_imm_unpack(disasm->devinfo,
+                                                         instr->raddr_b,
+                                                         &val);
+
+                        if ((int)val >= -16 && (int)val <= 15)
+                                append(disasm, "%d", val);
+                        else
+                                append(disasm, "0x%08x", val);
+                        assert(ok);
+                } else {
+                        append(disasm, "rf%d", instr->raddr_b);
+                }
         } else {
                 append(disasm, "r%d", mux);
         }
index cab1885acc4e8e4e437302bf00a0973050c2d682..468fe89facdedaee9791050e047b8554811f59ee 100644 (file)
@@ -394,6 +394,16 @@ v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
                      uint32_t packed_cond,
                      struct v3d_qpu_flags *cond);
 
+bool
+v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo,
+                       uint32_t value,
+                       uint32_t *packed_small_immediate);
+
+bool
+v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
+                         uint32_t packed_small_immediate,
+                         uint32_t *small_immediate);
+
 bool
 v3d_qpu_instr_pack(const struct v3d_device_info *devinfo,
                    const struct v3d_qpu_instr *instr,
index 68df6fe64c49de9c8669b5a4a1187bdab0d2f23c..161e24f03008bdea4d35be5f17e87857fc5638e0 100644 (file)
@@ -255,6 +255,69 @@ v3d_qpu_sig_pack(const struct v3d_device_info *devinfo,
 
         return false;
 }
+static inline unsigned
+fui( float f )
+{
+        union {float f; unsigned ui;} fi;
+   fi.f = f;
+   return fi.ui;
+}
+
+static const uint32_t small_immediates[] = {
+        0, 1, 2, 3,
+        4, 5, 6, 7,
+        8, 9, 10, 11,
+        12, 13, 14, 15,
+        -16, -15, -14, -13,
+        -12, -11, -10, -9,
+        -8, -7, -6, -5,
+        -4, -3, -2, -1,
+        0x3b800000, /* 2.0^-8 */
+        0x3c000000, /* 2.0^-7 */
+        0x3c800000, /* 2.0^-6 */
+        0x3d000000, /* 2.0^-5 */
+        0x3d800000, /* 2.0^-4 */
+        0x3e000000, /* 2.0^-3 */
+        0x3e800000, /* 2.0^-2 */
+        0x3f000000, /* 2.0^-1 */
+        0x3f800000, /* 2.0^0 */
+        0x40000000, /* 2.0^1 */
+        0x40800000, /* 2.0^2 */
+        0x41000000, /* 2.0^3 */
+        0x41800000, /* 2.0^4 */
+        0x42000000, /* 2.0^5 */
+        0x42800000, /* 2.0^6 */
+        0x43000000, /* 2.0^7 */
+};
+
+bool
+v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
+                         uint32_t packed_small_immediate,
+                         uint32_t *small_immediate)
+{
+        if (packed_small_immediate >= ARRAY_SIZE(small_immediates))
+                return false;
+
+        *small_immediate = small_immediates[packed_small_immediate];
+        return true;
+}
+
+bool
+v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo,
+                       uint32_t value,
+                       uint32_t *packed_small_immediate)
+{
+        STATIC_ASSERT(ARRAY_SIZE(small_immediates) == 48);
+
+        for (int i = 0; i < ARRAY_SIZE(small_immediates); i++) {
+                if (small_immediates[i] == value) {
+                        *packed_small_immediate = i;
+                        return true;
+                }
+        }
+
+        return false;
+}
 
 bool
 v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
index 4f6ded73d4889942f3a4c6cad5bce6860ec3dc1d..27dc184f76e88ea8d43c053034367e66f3f6235f 100644 (file)
@@ -46,6 +46,12 @@ static const struct {
         { 33, 0x1c0a0dfde2294000ull, "fcmp.ifna  rf61.h, r4.abs, r2.l; vfmul  rf55, r2.hh, r1" },
         { 33, 0x2011c89b402cc000ull, "fsub.norz  rf27, r4.abs, r1.abs; vfmul.ifa  rf34, r3.swp, r1" },
 
+        /* small immediates */
+        { 33, 0x5de24398bbdc6218ull, "vflb.andnn  rf24     ; fmul  rf14, -8, rf8.h" },
+        { 33, 0x25ef83d8b166f00full, "vfmin.pushn  rf24, 15.ff, r5; smul24.ifnb  rf15, r1, r3" },
+        { 33, 0xadedcdf70839f990ull, "faddnf.pushc  rf55, -16.l, r3.abs; fmul.ifb  rf55.l, rf38.l, r1.h" },
+        { 33, 0x7dff89fa6a01f020ull, "fsub.nornc  rf58.h, 0x3b800000.l, r3.l; fmul.ifnb  rf39, r0.h, r0.h" },
+
         /* branch conditions */
         { 33, 0x02000006002034c0ull, "b.anyap  rf19" },
         { 33, 0x02679356b4201000ull, "b.anyap  -1268280496" },