summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Rong <rong.r.yang@intel.com>2014-06-12 23:22:15 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-06-12 16:04:37 +0800
commit60b8e884a3dbac3175a97c8b6abcf7c7aa271bff (patch)
tree4004cb1448f9abd8054197e519ff00dbf7191b62
parent13f5296c3ba2edf026483c3e5780f4c76281bbea (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.cpp25
-rw-r--r--backend/src/backend/gen75_encoder.hpp6
-rw-r--r--backend/src/backend/gen_encoder.cpp22
-rw-r--r--backend/src/backend/gen_encoder.hpp13
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__ */