[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