[Beignet] [PATCH] HSW: Remove the jmpi distance limit of HSW.

Yang Rong rong.r.yang at intel.com
Thu Jun 12 08:22:15 PDT 2014


Because the HSW's jmpi distance's unit is byte, the distance in JMPI instruction should
be S31, so remove S16 restriction.
It can fix luxmark fail when OCL_STRICT_CONFORMANCE=1.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 backend/src/backend/gen75_encoder.cpp | 25 +++++++++++++++++++++++++
 backend/src/backend/gen75_encoder.hpp |  6 +++++-
 backend/src/backend/gen_encoder.cpp   | 22 +++++++++++-----------
 backend/src/backend/gen_encoder.hpp   | 13 ++++++++-----
 4 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index 81364a9..69d2de0 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -241,4 +241,29 @@ namespace gbe
       pop();
     }
   }
+
+  void Gen75Encoder::JMPI(GenRegister src, bool longjmp) {
+    alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
+  }
+
+  void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+    GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
+    GBE_ASSERT(insnID < this->store.size());
+    GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
+               insn.header.opcode == GEN_OPCODE_BRD  ||
+               insn.header.opcode == GEN_OPCODE_ENDIF ||
+               insn.header.opcode == GEN_OPCODE_IF ||
+               insn.header.opcode == GEN_OPCODE_BRC);
+
+    if (insn.header.opcode == GEN_OPCODE_IF) {
+      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+      return;
+    }
+    else if (insn.header.opcode == GEN_OPCODE_JMPI) {
+      //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
+      jumpDistance = (jumpDistance - 2) * 8;
+    }
+
+    this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 01520ed..c10dac9 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -36,8 +36,12 @@ namespace gbe
     virtual ~Gen75Encoder(void) { }
 
     Gen75Encoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID)
-         : GenEncoder(simdWidth, gen, deviceID, 8) { }
+         : GenEncoder(simdWidth, gen, deviceID) { }
 
+    /*! Jump indexed instruction */
+    virtual void JMPI(GenRegister src, bool longjmp = false);
+    /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
+    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
     /*! Get double/long exec width */
     virtual int getDoubleExecWidth(void) { return GEN75_DOUBLE_EXEC_WIDTH; }
     virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index d836995..26337e9 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -218,8 +218,8 @@ namespace gbe
   //////////////////////////////////////////////////////////////////////////
   // Gen Emitter encoding class
   //////////////////////////////////////////////////////////////////////////
-  GenEncoder::GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID, int jump_width) :
-    stateNum(0), gen(gen), deviceID(deviceID), jump_width(jump_width)
+  GenEncoder::GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID) :
+    stateNum(0), gen(gen), deviceID(deviceID)
   {
     this->simdWidth = simdWidth;
     this->curr.execWidth = simdWidth;
@@ -609,8 +609,8 @@ namespace gbe
       }
   }
 
-  INLINE void alu1(GenEncoder *p, uint32_t opcode, GenRegister dst,
-                   GenRegister src, uint32_t condition = 0) {
+  void alu1(GenEncoder *p, uint32_t opcode, GenRegister dst,
+            GenRegister src, uint32_t condition) {
      if (dst.isdf() && src.isdf()) {
        handleDouble(p, opcode, dst, src);
      } else if (dst.isint64() && src.isint64()) { // handle int64
@@ -649,12 +649,12 @@ namespace gbe
      }
   }
 
-  INLINE void alu2(GenEncoder *p,
-                   uint32_t opcode,
-                   GenRegister dst,
-                   GenRegister src0,
-                   GenRegister src1,
-                   uint32_t condition = 0)
+  void alu2(GenEncoder *p,
+            uint32_t opcode,
+            GenRegister dst,
+            GenRegister src0,
+            GenRegister src1,
+            uint32_t condition)
   {
     if (dst.isdf() && src0.isdf() && src1.isdf()) {
        handleDouble(p, opcode, dst, src0, src1);
@@ -1043,7 +1043,7 @@ namespace gbe
              return;
            }
            else if (insn.header.opcode == GEN_OPCODE_JMPI) {
-             jumpDistance = (jumpDistance - 2)* jump_width;
+             jumpDistance = jumpDistance - 2;
            }
 
            this->setSrc1(&insn, GenRegister::immd(jumpDistance));
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 02661d3..eb2d3d7 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -65,7 +65,7 @@ namespace gbe
   {
   public:
     /*! simdWidth is the default width for the instructions */
-    GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID, int jump_width = 1);
+    GenEncoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID);
 
     virtual ~GenEncoder(void) { }
     /*! Size of the stack (should be large enough) */
@@ -88,8 +88,6 @@ namespace gbe
     uint32_t gen;
     /*! Device ID */
     uint32_t deviceID;
-    /*! The constant for jump. */
-    const int jump_width;
     /*! simd width for this codegen */
     uint32_t simdWidth;
     ////////////////////////////////////////////////////////////////////////
@@ -149,7 +147,7 @@ namespace gbe
     /*! Memory fence message (to order loads and stores between threads) */
     void FENCE(GenRegister dst);
     /*! Jump indexed instruction */
-    void JMPI(GenRegister src, bool longjmp = false);
+    virtual void JMPI(GenRegister src, bool longjmp = false);
     /*! IF indexed instruction */
     void IF(GenRegister src);
     /*! ENDIF indexed instruction */
@@ -206,7 +204,7 @@ namespace gbe
     void MATH(GenRegister dst, uint32_t function, GenRegister src);
 
     /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
-    void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
 
     ////////////////////////////////////////////////////////////////////////
     // Helper functions to encode
@@ -230,6 +228,11 @@ namespace gbe
     GBE_CLASS(GenEncoder); //!< Use custom allocators
   };
 
+  void alu1(GenEncoder *p, uint32_t opcode, GenRegister dst,
+            GenRegister src, uint32_t condition = 0);
+
+  void alu2(GenEncoder *p, uint32_t opcode, GenRegister dst,
+            GenRegister src0, GenRegister src1, uint32_t condition = 0);
 } /* namespace gbe */
 
 #endif /* __GBE_GEN_ENCODER_HPP__ */
-- 
1.8.3.2



More information about the Beignet mailing list