diff options
author | Yang Rong <rong.r.yang@intel.com> | 2014-06-12 23:22:15 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-12 16:04:37 +0800 |
commit | 60b8e884a3dbac3175a97c8b6abcf7c7aa271bff (patch) | |
tree | 4004cb1448f9abd8054197e519ff00dbf7191b62 | |
parent | 13f5296c3ba2edf026483c3e5780f4c76281bbea (diff) |
HSW: Remove the jmpi distance limit of HSW.
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@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Tested-by: Li, Peng <peng.li@intel.com>
-rw-r--r-- | backend/src/backend/gen75_encoder.cpp | 25 | ||||
-rw-r--r-- | backend/src/backend/gen75_encoder.hpp | 6 | ||||
-rw-r--r-- | backend/src/backend/gen_encoder.cpp | 22 | ||||
-rw-r--r-- | 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 81364a95..69d2de05 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 01520ed0..c10dac98 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 d8369950..26337e9f 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 02661d38..eb2d3d72 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__ */ |