[Beignet] [PATCH 7/7] Fix double bugs for hsw
junyan.he at inbox.com
junyan.he at inbox.com
Tue Apr 15 17:57:05 PDT 2014
From: Junyan He <junyan.he at linux.intel.com>
In bspec, IVB should use SIMD8 for double ops, but HSW should use SIMD4.
TODO: The long ops maybe also need change.
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/backend/gen75_encoder.cpp | 64 +++++++++++++++++++++++++++++++++
backend/src/backend/gen75_encoder.hpp | 3 ++
backend/src/backend/gen_context.hpp | 2 +-
backend/src/backend/gen_encoder.hpp | 4 +--
4 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index d1d1292..f712639 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -212,4 +212,68 @@ namespace gbe
this->setSrc1(&insn2, GenRegister::immd(jumpDistance));
}
}
+
+ void Gen75Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
+ union { double d; unsigned u[2]; } u;
+ u.d = value;
+ GenRegister r = GenRegister::retype(tmp, GEN_TYPE_UD);
+ push();
+ curr.predicate = GEN_PREDICATE_NONE;
+ curr.execWidth = 1;
+ MOV(r, GenRegister::immud(u.u[0]));
+ MOV(GenRegister::suboffset(r, 1), GenRegister::immud(u.u[1]));
+ pop();
+ r.type = GEN_TYPE_DF;
+ r.vstride = GEN_VERTICAL_STRIDE_0;
+ r.width = GEN_WIDTH_1;
+ r.hstride = GEN_HORIZONTAL_STRIDE_0;
+ push();
+ uint32_t width = curr.execWidth;
+ curr.execWidth = 8;
+ curr.predicate = GEN_PREDICATE_NONE;
+ curr.noMask = 1;
+ curr.quarterControl = GEN_COMPRESSION_Q1;
+ MOV(dest, r);
+ if (width == 16) {
+ curr.quarterControl = GEN_COMPRESSION_Q2;
+ MOV(GenRegister::offset(dest, 2), r);
+ }
+ pop();
+ }
+
+ void Gen75Encoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
+ int w = curr.execWidth;
+ if (src0.isdf()) {
+ GBE_ASSERT(0); // MOV DF is called from convert instruction,
+ // We should never convert a df to a df.
+ } else {
+ GenRegister r0 = GenRegister::h2(r);
+ push();
+ curr.execWidth = 4;
+ curr.predicate = GEN_PREDICATE_NONE;
+ MOV(r0, src0);
+ MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
+ curr.predicate = GEN_PREDICATE_NORMAL;
+ curr.quarterControl = 0;
+ curr.nibControl = 0;
+ MOV(dest, r0);
+ curr.nibControl = 1;
+ MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
+ pop();
+ if (w == 16) {
+ push();
+ curr.execWidth = 4;
+ curr.predicate = GEN_PREDICATE_NONE;
+ MOV(r0, GenRegister::suboffset(src0, 8));
+ MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
+ curr.predicate = GEN_PREDICATE_NORMAL;
+ curr.quarterControl = 1;
+ curr.nibControl = 0;
+ MOV(GenRegister::suboffset(dest, 8), r0);
+ curr.nibControl = 1;
+ MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
+ pop();
+ }
+ }
+ }
} /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 1bbdd2c..75a9299 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -32,6 +32,9 @@ namespace gbe
{
public:
Gen75Encoder(uint32_t simdWidth, uint32_t gen) : GenEncoder(simdWidth, gen) { };
+
+ virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
+ virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum);
virtual void UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum);
virtual void UNTYPED_WRITE(GenRegister src, uint32_t bti, uint32_t elemNum);
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index b27d5e8..a32ce7a 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -71,7 +71,7 @@ namespace gbe
/*! Emit the instructions */
void emitInstructionStream(void);
/*! Set the correct target values for the branches */
- void patchBranches(void);
+ virtual void patchBranches(void);
/*! Forward ir::Function isSpecialReg method */
INLINE bool isSpecialReg(ir::Register reg) const {
return fn.isSpecialReg(reg);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index c82d7c6..21d2d66 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -125,8 +125,8 @@ namespace gbe
#undef ALU1
#undef ALU2
#undef ALU3
- void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
- void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
+ virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
+ virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
void LOAD_INT64_IMM(GenRegister dest, int64_t value);
/*! Barrier message (to synchronize threads of a workgroup) */
void BARRIER(GenRegister src);
--
1.7.9.5
More information about the Beignet
mailing list