Module: Mesa
Branch: main
Commit: cf43a1cc5810d5d03c882620a1cf64ee4ec8017d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=cf43a1cc5810d5d03c882620a1cf64ee4ec8017d

Author: Alyssa Rosenzweig <[email protected]>
Date:   Sun Mar 13 13:49:18 2022 -0400

pan/va: Rewrite FAU handling in dis/assembler

FAU pages do not need to be specified explicitly in the assembly. Rather, they
should be inferred by the assembler by the instructions used. Rewrite the code
handling this in alignment with new information about the hardware.

Signed-off-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15364>

---

 src/panfrost/bifrost/valhall/asm.py                | 90 +++++++++-------------
 src/panfrost/bifrost/valhall/disasm.py             |  2 -
 .../bifrost/valhall/test/assembler-cases.txt       |  8 +-
 .../bifrost/valhall/test/negative-cases.txt        | 15 +---
 4 files changed, 44 insertions(+), 71 deletions(-)

diff --git a/src/panfrost/bifrost/valhall/asm.py 
b/src/panfrost/bifrost/valhall/asm.py
index 4e7aee29c94..413932bee77 100644
--- a/src/panfrost/bifrost/valhall/asm.py
+++ b/src/panfrost/bifrost/valhall/asm.py
@@ -33,53 +33,37 @@ class ParseError(Exception):
         self.error = error
 
 class FAUState:
-    def __init__(self, mode, single_uniform_slot = True):
-        self.mode = mode
-        self.single_uniform_slot = single_uniform_slot
-        self.uniform_slot = None
-        self.special = None
+    def __init__(self, message = False):
+        self.message = message
+        self.page = None
+        self.words = set()
         self.buffer = set()
 
-    def push(self, s):
-        self.buffer.add(s)
-        die_if(len(self.buffer) > 2, "Overflowed FAU buffer")
-
-    def push_special(self, s):
-        die_if(self.special is not None and self.special != s,
-                'Multiple special immediates')
-        self.special = s
-        self.push(s)
-
-    def descriptor(self, s):
-        die_if(self.mode != 'none', f'Expected no modifier with {s}')
-        self.push_special(s)
-
-    def uniform(self, v):
-        slot = v >> 1
-
-        die_if(self.mode != 'none',
-                'Expected uniform with default immediate mode')
-        die_if(self.uniform_slot is not None and self.uniform_slot != slot,
-                'Overflowed uniform slots')
+    def set_page(self, page):
+        assert(page <= 3)
+        die_if(self.page is not None and self.page != page, 'Mismatched pages')
+        self.page = page
 
-        if self.single_uniform_slot:
-            self.uniform_slot = slot
+    def push(self, source):
+        if not (source & (1 << 7)):
+            # Skip registers
+            return
 
-        self.push(f'uniform{v}')
+        self.buffer.add(source)
+        die_if(len(self.buffer) > 2, "Overflowed FAU buffer")
 
-    def id(self, s):
-        die_if(self.mode != 'id',
-                'Expected .id modifier with thread storage pointer')
+        if (source >> 5) == 0b110:
+            # Small constants need to check if the buffer overflows but no else
+            return
 
-        self.push_special(f'id{s}')
+        slot = (source >> 1)
 
-    def ts(self, s):
-        die_if(self.mode != 'ts',
-                'Expected .ts modifier with thread pointer')
-        self.push_special(f'ts{s}')
+        self.words.add(source)
 
-    def constant(self, cons):
-        self.push(cons)
+        # Check the encoded slots
+        slots = set([(x >> 1) for x in self.words])
+        die_if(len(slots) > (2 if self.message else 1), 'Too many FAU slots')
+        die_if(len(self.words) > (3 if self.message else 2), 'Too many FAU 
words')
 
 # When running standalone, exit with the error since we're dealing with a
 # human. Otherwise raise a Python exception so the test harness can handle it.
@@ -108,10 +92,11 @@ def parse_int(s, minimum, maximum):
 
 def encode_source(op, fau):
     if op == 'atest_datum':
-        fau.descriptor(op)
+        fau.set_page(0)
         return 0x2A | 0xC0
     elif op.startswith('blend_descriptor_'):
-        fau.descriptor(op)
+        fau.set_page(0)
+
         fin = op[len('blend_descriptor_'):]
         die_if(len(fin) != 3, 'Bad syntax')
         die_if(fin[1] != '_', 'Bad syntax')
@@ -127,17 +112,17 @@ def encode_source(op, fau):
         return parse_int(op[1:], 0, 63)
     elif op[0] == 'u':
         val = parse_int(op[1:], 0, 63)
-        fau.uniform(val)
+        fau.set_page(val >> 6)
         return val | 0x80
     elif op[0] == 'i':
         return int(op[3:]) | 0xC0
     elif op in enums['thread_storage_pointers'].bare_values:
-        fau.ts(op)
         idx = 32 + enums['thread_storage_pointers'].bare_values.index(op)
+        fau.set_page(1)
         return idx | 0xC0
     elif op in enums['thread_identification'].bare_values:
-        fau.id(op)
         idx = 32 + enums['thread_identification'].bare_values.index(op)
+        fau.set_page(3)
         return idx | 0xC0
     elif op.startswith('0x'):
         try:
@@ -146,7 +131,6 @@ def encode_source(op, fau):
             die('Expected value')
 
         die_if(val not in immediates, 'Unexpected immediate value')
-        fau.constant(val)
         return immediates.index(val) | 0xC0
     else:
         die('Invalid operand')
@@ -251,14 +235,14 @@ def parse_asm(line):
         # Set a placeholder writemask to prevent encoding faults
         encoded |= (0xC0 << 40)
 
-    # TODO: Determine which instructions can only have address a single uniform
-    single_uniform_slot = not ins.name.startswith('LD_BUFFER')
-
-    fau = FAUState(immediate_mode, single_uniform_slot = single_uniform_slot)
+    # TODO: Other messages
+    fau = FAUState(message = ins.name.startswith('LD_BUFFER'))
 
     for i, (op, src) in enumerate(zip(operands, ins.srcs)):
         parts = op.split('.')
-        encoded |= encode_source(parts[0], fau) << src.start
+        encoded_src = encode_source(parts[0], fau)
+        encoded |= encoded_src << src.start
+        fau.push(encoded_src)
 
         # Has a swizzle been applied yet?
         swizzled = False
@@ -357,6 +341,10 @@ def parse_asm(line):
     encoded |= (ins.opcode << 48)
     encoded |= (ins.opcode2 << ins.secondary_shift)
 
+    # Encode FAU page
+    if fau.page:
+        encoded |= (fau.page << 57)
+
     # Encode modifiers
     has_action = False
     for mod in mods:
@@ -387,8 +375,6 @@ def parse_asm(line):
                 encoded |= (1 << 60)
             if 2 in slots:
                 encoded |= (1 << 61)
-        elif mod in enums['immediate_mode'].bare_values:
-            pass # handled specially
         else:
             candidates = [c for c in ins.modifiers if mod in c.bare_values]
 
diff --git a/src/panfrost/bifrost/valhall/disasm.py 
b/src/panfrost/bifrost/valhall/disasm.py
index ada4ac25708..a05c6b8b657 100644
--- a/src/panfrost/bifrost/valhall/disasm.py
+++ b/src/panfrost/bifrost/valhall/disasm.py
@@ -57,8 +57,6 @@ va_print_metadata(FILE *fp, uint8_t meta)
        struct va_metadata m;
        memcpy(&m, &meta, 1);
 
-    fputs(valhall_immediate_mode[m.immediate_mode], fp);
-
        if (m.do_action) {
         fputs(valhall_action[m.action], fp);
        } else if (m.action) {
diff --git a/src/panfrost/bifrost/valhall/test/assembler-cases.txt 
b/src/panfrost/bifrost/valhall/test/assembler-cases.txt
index 1a3087ddf61..dc79559bbff 100644
--- a/src/panfrost/bifrost/valhall/test/assembler-cases.txt
+++ b/src/panfrost/bifrost/valhall/test/assembler-cases.txt
@@ -1,9 +1,9 @@
 02 00 00 00 00 c1 91 00    MOV.i32 r1, r2
 8a 00 00 00 00 c1 91 00    MOV.i32 r1, u10
-e3 00 00 00 00 c1 91 02    MOV.i32.ts r1, tls_ptr_hi
-e6 00 00 00 00 c1 91 02    MOV.i32.ts r1, wls_ptr
-e2 00 00 00 00 c1 91 06    MOV.i32.id r1, lane_id
-e6 00 00 00 00 c1 91 06    MOV.i32.id r1, core_id
+e3 00 00 00 00 c1 91 02    MOV.i32 r1, tls_ptr_hi
+e6 00 00 00 00 c1 91 02    MOV.i32 r1, wls_ptr
+e2 00 00 00 00 c1 91 06    MOV.i32 r1, lane_id
+e6 00 00 00 00 c1 91 06    MOV.i32 r1, core_id
 01 02 00 00 00 c0 a4 00    FADD.f32 r0, r1, r2
 01 02 00 00 20 c0 a4 00    FADD.f32 r0, r1, r2.abs
 01 02 00 00 10 c0 a4 00    FADD.f32 r0, r1, r2.neg
diff --git a/src/panfrost/bifrost/valhall/test/negative-cases.txt 
b/src/panfrost/bifrost/valhall/test/negative-cases.txt
index 71e12aab8c0..4669ca00bd5 100644
--- a/src/panfrost/bifrost/valhall/test/negative-cases.txt
+++ b/src/panfrost/bifrost/valhall/test/negative-cases.txt
@@ -1,7 +1,3 @@
-MOV.i32.ts r1, lane_id
-MOV.i32.id r1, wls_ptr
-MOV.i32 r1, lane_id
-MOV.i32 r1, wls_ptr
 FADD.f32 r0, r1
 TEX.computed.2d.slot0 @r2, @r4:r5:r6:r7
 BRANCH
@@ -26,17 +22,10 @@ FMA.f32 r0, u0, u1, 0x0
 FMA.f32 r0, u0, 0x40490FDB, 0x0
 FMA.f32 r0, 0x3F317218, 0x40490FDB, 0x0
 
-# An instruction may only access uniforms in the default immediate mode.
-MOV.i32.id r0, u0
-MOV.i32.ts r0, u1
-
 # An instruction may access no more than a single special immediate (e.g. 
lane_id).
 IADD.u32 r0, lane_id, core_id
-IADD.u32.id r0, lane_id, core_id
-IADD.u32.ts r0, tls_ptr, wls_ptr
-IADD.u32.ts r0, tls_ptr, tls_ptr_hi
-IADD.u32.id r0, tls_ptr, tls_ptr_hi
-IADD.u32.id r0, tls_ptr, 0x40490FDB
+IADD.u32 r0, lane_id, core_id
+IADD.u32 r0, tls_ptr, wls_ptr
 
 # If an instruction accesses multiple staging registers, they must be aligned
 # to a register pair.

Reply via email to