[Beignet] [PATCH 7/7] Fix double bugs for hsw

junyan.he at inbox.com junyan.he at inbox.com
Tue Apr 15 17:57:05 PDT 2014


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

In bspec, IVB should use SIMD8 for double ops, but HSW should use SIMD4.
TODO: The long ops maybe also need change.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen75_encoder.cpp |   64 +++++++++++++++++++++++++++++++++
 backend/src/backend/gen75_encoder.hpp |    3 ++
 backend/src/backend/gen_context.hpp   |    2 +-
 backend/src/backend/gen_encoder.hpp   |    4 +--
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index d1d1292..f712639 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -212,4 +212,68 @@ namespace gbe
       this->setSrc1(&insn2, GenRegister::immd(jumpDistance));
     }
   }
+
+  void Gen75Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
+    union { double d; unsigned u[2]; } u;
+    u.d = value;
+    GenRegister r = GenRegister::retype(tmp, GEN_TYPE_UD);
+    push();
+    curr.predicate = GEN_PREDICATE_NONE;
+    curr.execWidth = 1;
+    MOV(r, GenRegister::immud(u.u[0]));
+    MOV(GenRegister::suboffset(r, 1), GenRegister::immud(u.u[1]));
+    pop();
+    r.type = GEN_TYPE_DF;
+    r.vstride = GEN_VERTICAL_STRIDE_0;
+    r.width = GEN_WIDTH_1;
+    r.hstride = GEN_HORIZONTAL_STRIDE_0;
+    push();
+    uint32_t width = curr.execWidth;
+    curr.execWidth = 8;
+    curr.predicate = GEN_PREDICATE_NONE;
+    curr.noMask = 1;
+    curr.quarterControl = GEN_COMPRESSION_Q1;
+    MOV(dest, r);
+    if (width == 16) {
+      curr.quarterControl = GEN_COMPRESSION_Q2;
+      MOV(GenRegister::offset(dest, 2), r);
+    }
+    pop();
+  }
+
+  void Gen75Encoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
+    int w = curr.execWidth;
+    if (src0.isdf()) {
+      GBE_ASSERT(0); // MOV DF is called from convert instruction,
+                     // We should never convert a df to a df.
+    } else {
+      GenRegister r0 = GenRegister::h2(r);
+      push();
+      curr.execWidth = 4;
+      curr.predicate = GEN_PREDICATE_NONE;
+      MOV(r0, src0);
+      MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
+      curr.predicate = GEN_PREDICATE_NORMAL;
+      curr.quarterControl = 0;
+      curr.nibControl = 0;
+      MOV(dest, r0);
+      curr.nibControl = 1;
+      MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
+      pop();
+      if (w == 16) {
+        push();
+        curr.execWidth = 4;
+        curr.predicate = GEN_PREDICATE_NONE;
+        MOV(r0, GenRegister::suboffset(src0, 8));
+        MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
+        curr.predicate = GEN_PREDICATE_NORMAL;
+        curr.quarterControl = 1;
+        curr.nibControl = 0;
+        MOV(GenRegister::suboffset(dest, 8), r0);
+        curr.nibControl = 1;
+        MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
+        pop();
+      }
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 1bbdd2c..75a9299 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -32,6 +32,9 @@ namespace gbe
   {
   public:
     Gen75Encoder(uint32_t simdWidth, uint32_t gen) : GenEncoder(simdWidth, gen) { };
+
+    virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
+    virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
     virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum);
     virtual void UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum);
     virtual void UNTYPED_WRITE(GenRegister src, uint32_t bti, uint32_t elemNum);
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index b27d5e8..a32ce7a 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -71,7 +71,7 @@ namespace gbe
     /*! Emit the instructions */
     void emitInstructionStream(void);
     /*! Set the correct target values for the branches */
-    void patchBranches(void);
+    virtual void patchBranches(void);
     /*! Forward ir::Function isSpecialReg method */
     INLINE bool isSpecialReg(ir::Register reg) const {
       return fn.isSpecialReg(reg);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index c82d7c6..21d2d66 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -125,8 +125,8 @@ namespace gbe
 #undef ALU1
 #undef ALU2
 #undef ALU3
-    void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
-    void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
+    virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
+    virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
     void LOAD_INT64_IMM(GenRegister dest, int64_t value);
     /*! Barrier message (to synchronize threads of a workgroup) */
     void BARRIER(GenRegister src);
-- 
1.7.9.5





More information about the Beignet mailing list