pan/bit: Handle read/write
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 1 Apr 2020 13:50:38 +0000 (09:50 -0400)
committerMarge Bot <eric+marge@anholt.net>
Sun, 5 Apr 2020 23:26:04 +0000 (23:26 +0000)
We case the various sources and destinations to model register file
access and passthrough in particular.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4458>

src/panfrost/bifrost/test/bi_interpret.c
src/panfrost/bifrost/test/bit.h

index fb68752c15d70d03243eab8c9178500600a6f601..608dfea8f715bce73cc29a47892634253022d471 100644 (file)
@@ -39,26 +39,58 @@ typedef union {
 /* Interprets a subset of Bifrost IR required for automated testing */
 
 static uint64_t
-bit_read(struct bit_state *s, bi_instruction *ins, unsigned index, nir_alu_type T)
+bit_read(struct bit_state *s, bi_instruction *ins, unsigned index, nir_alu_type T, bool FMA)
 {
-        /* STUB */
-        return 0;
+        if (index & BIR_INDEX_REGISTER) {
+                uint32_t reg = index & ~BIR_INDEX_REGISTER;
+                assert(reg < 64);
+                return s->r[reg];
+        } else if (index & BIR_INDEX_UNIFORM) {
+                unreachable("Uniform registers to be implemented");
+        } else if (index & BIR_INDEX_CONSTANT) {
+                return ins->constant.u64 >> (index & ~BIR_INDEX_CONSTANT);
+        } else if (index & BIR_INDEX_ZERO) {
+                return 0;
+        } else if (index & (BIR_INDEX_PASS | BIFROST_SRC_STAGE)) {
+                return FMA ? 0 : s->T;
+        } else if (index & (BIR_INDEX_PASS | BIFROST_SRC_PASS_FMA)) {
+                return s->T0;
+        } else if (index & (BIR_INDEX_PASS | BIFROST_SRC_PASS_ADD)) {
+                return s->T1;
+        } else if (!index) {
+                /* Placeholder */
+                return 0;
+        } else {
+                unreachable("Invalid source");
+        }
 }
 
 static void
-bit_write(struct bit_state *s, unsigned index, nir_alu_type T, bit_t value)
+bit_write(struct bit_state *s, unsigned index, nir_alu_type T, bit_t value, bool FMA)
 {
-        /* STUB */
+        /* Always write stage passthrough */
+        if (FMA)
+                s->T = value.u32;
+
+        if (index & BIR_INDEX_REGISTER) {
+                uint32_t reg = index & ~BIR_INDEX_REGISTER;
+                assert(reg < 64);
+                s->r[reg] = value.u32;
+        } else if (!index) {
+                /* Nothing to do */
+        } else {
+                unreachable("Invalid destination");
+        }
 }
 
 void
-bit_step(struct bit_state *s, bi_instruction *ins)
+bit_step(struct bit_state *s, bi_instruction *ins, bool FMA)
 {
         /* First, load sources */
         bit_t srcs[BIR_SRC_COUNT] = { 0 };
 
         bi_foreach_src(ins, src)
-                srcs[src].u64 = bit_read(s, ins, ins->src[src], ins->src_types[src]);
+                srcs[src].u64 = bit_read(s, ins, ins->src[src], ins->src_types[src], FMA);
 
         /* Next, do the action of the instruction */
         bit_t dest = { 0 };
@@ -96,5 +128,11 @@ bit_step(struct bit_state *s, bi_instruction *ins)
         }
 
         /* Finally, store the result */
-        bit_write(s, ins->dest, ins->dest_type, dest);
+        bit_write(s, ins->dest, ins->dest_type, dest, FMA);
+
+        /* For ADD - change out the passthrough */
+        if (!FMA) {
+                s->T0 = s->T;
+                s->T1 = dest.u32;
+        }
 }
index a399c78393dc45f31fbe665569fde99e6585f07d..3a6d9e4336f1e746c177e40033f9d012c9553b03 100644 (file)
@@ -53,11 +53,19 @@ bit_vertex(struct panfrost_device *dev, panfrost_program prog,
 /* BIT interpreter */
 
 struct bit_state {
+        /* Work registers */
         uint32_t r[64];
+
+        /* Passthrough within the bundle */
+        uint32_t T;
+
+        /* Passthrough from last bundle */
+        uint32_t T0;
+        uint32_t T1;
 };
 
 void
-bit_step(struct bit_state *s, bi_instruction *ins);
+bit_step(struct bit_state *s, bi_instruction *ins, bool FMA);
 
 #endif