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>
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. */
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());
//////////////////////////////////////////////////////////////////////////
// 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;
}
}
- 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
}
}
- 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);
return;
}
else if (insn.header.opcode == GEN_OPCODE_JMPI) {
- jumpDistance = (jumpDistance - 2)* jump_width;
+ jumpDistance = jumpDistance - 2;
}
this->setSrc1(&insn, GenRegister::immd(jumpDistance));
{
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) */
uint32_t gen;
/*! Device ID */
uint32_t deviceID;
- /*! The constant for jump. */
- const int jump_width;
/*! simd width for this codegen */
uint32_t simdWidth;
////////////////////////////////////////////////////////////////////////
/*! 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 */
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
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__ */