[Beignet] [PATCH 11/27] Add functions for conversion between native and fake long.

junyan.he at inbox.com junyan.he at inbox.com
Tue Jan 6 02:01:20 PST 2015


From: Junyan He <junyan.he at linux.intel.com>

Because on BDW, the native long's store and load need A64
instruction set. This instruction set is specially added to
support 64 bits read and write but has a big limtation, in
which the BTI parameter should refer to a stateless surface.
This is unaccepitable for us because it can cause overwrite
problems. We fallback to use the old manner which read and
write the long as the vec2 of int into/from top and bottom
halves. The pack/unpacked functions here play the role of
assembling/disassmebling the data before/after the write/read.

UnPack before writing like this:
  mov(8)      g108<1>:UD      g112<8,4,2>:UD        { align1 WE_normal 1Q };
  mov(8)      g110<1>:UD      g112.1<8,4,2>:UD      { align1 WE_normal 1Q };
  mov(8)      g109<1>:UD      g114<8,4,2>:UD        { align1 WE_normal 2Q };
  mov(8)      g111<1>:UD      g114.1<8,4,2>:UD      { align1 WE_normal 2Q };
  send(16)    null:UW         g106<8,8,1>:UD

and Pack after reading like this:
  send(16)    g120<1>:UW      g124<8,8,1>:UD
  mov(8)      g116<2>:UD      g120<4,4,1>:UD        { align1 WE_normal 1Q };
  mov(8)      g118<2>:UD      g121<4,4,1>:UD        { align1 WE_normal 1Q };
  mov(8)      g116.1<2>:UD    g122<4,4,1>:UD        { align1 WE_normal 1Q };
  mov(8)      g118.1<2>:UD    g123<4,4,1>:UD        { align1 WE_normal 1Q };

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen8_context.cpp | 59 ++++++++++++++++++++++++++++++++++++
 backend/src/backend/gen8_context.hpp |  2 ++
 2 files changed, 61 insertions(+)

diff --git a/backend/src/backend/gen8_context.cpp b/backend/src/backend/gen8_context.cpp
index 776c92b..85896df 100644
--- a/backend/src/backend/gen8_context.cpp
+++ b/backend/src/backend/gen8_context.cpp
@@ -50,4 +50,63 @@ namespace gbe
   void Gen8Context::newSelection(void) {
     this->sel = GBE_NEW(Selection8, *this);
   }
+
+  void Gen8Context::packLongVec(GenRegister unpacked, GenRegister packed, uint32_t simd)
+  {
+    GBE_ASSERT(packed.subnr == 0);
+    GBE_ASSERT(unpacked.subnr == 0);
+
+    unpacked = GenRegister::retype(unpacked, GEN_TYPE_UD);
+    packed = GenRegister::retype(packed, GEN_TYPE_UD);
+
+    if (simd == 16) {
+      p->push();
+      p->curr.execWidth = 8;
+      p->MOV(GenRegister::h2(packed), unpacked);
+      p->MOV(GenRegister::h2(GenRegister::offset(packed, 0, typeSize(GEN_TYPE_UD))),
+             GenRegister::offset(unpacked, 2));
+      p->curr.quarterControl = 1;
+      p->MOV(GenRegister::h2(GenRegister::offset(packed, 2, 0)), GenRegister::offset(unpacked, 1));
+      p->MOV(GenRegister::h2(GenRegister::offset(packed, 2, typeSize(GEN_TYPE_UD))),
+             GenRegister::offset(unpacked, 3));
+      p->pop();
+    } else {
+      GBE_ASSERT(simd == 8);
+      p->MOV(GenRegister::h2(packed), unpacked);
+      p->MOV(GenRegister::h2(GenRegister::offset(packed, 0, typeSize(GEN_TYPE_UD))),
+             GenRegister::offset(unpacked, 1));
+    }
+  }
+
+  void Gen8Context::unpackLongVec(GenRegister packed, GenRegister unpacked, uint32_t simd)
+  {
+    GBE_ASSERT(packed.subnr == 0);
+    GBE_ASSERT(unpacked.subnr == 0);
+
+    unpacked = GenRegister::retype(unpacked, GEN_TYPE_UD);
+    packed = GenRegister::retype(packed, GEN_TYPE_UD);
+
+    packed.vstride = GEN_VERTICAL_STRIDE_8;
+    packed.width = GEN_WIDTH_4;
+
+    p->push();
+    p->curr.execWidth = 8;
+    if (simd == 16) {
+      p->MOV(unpacked, GenRegister::h2(packed));
+      p->MOV(GenRegister::offset(unpacked, 2),
+             GenRegister::h2(GenRegister::offset(packed, 0, typeSize(GEN_TYPE_UD))));
+
+      p->curr.quarterControl = 1;
+      p->MOV(GenRegister::offset(unpacked, 1), GenRegister::h2(GenRegister::offset(packed, 2)));
+      p->MOV(GenRegister::offset(unpacked, 3),
+             GenRegister::h2(GenRegister::offset(packed, 2, typeSize(GEN_TYPE_UD))));
+    } else {
+      GBE_ASSERT(simd == 8);
+      p->MOV(unpacked, GenRegister::h2(packed));
+      p->MOV(GenRegister::offset(unpacked, 1),
+             GenRegister::h2(GenRegister::offset(packed, 0, typeSize(GEN_TYPE_UD))));
+    }
+    p->pop();
+  }
+
 }
diff --git a/backend/src/backend/gen8_context.hpp b/backend/src/backend/gen8_context.hpp
index 49193f5..1b9125b 100644
--- a/backend/src/backend/gen8_context.hpp
+++ b/backend/src/backend/gen8_context.hpp
@@ -56,6 +56,8 @@ namespace gbe
   private:
     virtual void emitSLMOffset(void);
     virtual void newSelection(void);
+    void packLongVec(GenRegister unpacked, GenRegister packed, uint32_t simd);
+    void unpackLongVec(GenRegister packed, GenRegister unpacked, uint32_t simd);
   };
 }
 #endif /* __GBE_GEN8_CONTEXT_HPP__ */
-- 
1.9.1



More information about the Beignet mailing list