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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
