[Beignet] [PATCH V2 4/4] add sends support for byte write

Guo, Yejun yejun.guo at intel.com
Thu Nov 24 04:57:27 UTC 2016


v2: use function setSendsOperands
Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen9_encoder.cpp       | 48 ++++++++++++++++++++++++++++++
 backend/src/backend/gen9_encoder.hpp       |  2 ++
 backend/src/backend/gen_context.cpp        | 15 +++++++---
 backend/src/backend/gen_encoder.cpp        | 14 ++++++++-
 backend/src/backend/gen_encoder.hpp        |  4 ++-
 backend/src/backend/gen_insn_selection.cpp | 26 ++++++++++++----
 6 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index 867f3f1..f8338ef 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -141,4 +141,52 @@ namespace gbe
         gen9_insn->bits2.sends.sel_reg32_desc = 1;
     }
   }
+
+  unsigned Gen9Encoder::setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize)
+  {
+    Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+    gen9_insn->bits3.sends_byte_rw.header_present = 0;
+    gen9_insn->bits3.sends_byte_rw.response_length = 0;
+    gen9_insn->bits3.sends_byte_rw.end_of_thread = 0;
+    gen9_insn->bits3.sends_byte_rw.msg_type = GEN7_BYTE_SCATTER;
+    gen9_insn->bits3.sends_byte_rw.bti = bti;
+    gen9_insn->bits3.sends_byte_rw.data_size = elemSize;
+
+    if (this->curr.execWidth == 8) {
+      gen9_insn->bits3.sends_byte_rw.src0_length = 1;
+      gen9_insn->bits3.sends_byte_rw.simd_mode = GEN_BYTE_SCATTER_SIMD8;
+    } else if (this->curr.execWidth == 16) {
+      gen9_insn->bits3.sends_byte_rw.src0_length = 2;
+      gen9_insn->bits3.sends_byte_rw.simd_mode = GEN_BYTE_SCATTER_SIMD16;
+    }
+
+    return gen9_insn->bits3.ud;
+  }
+
+  void Gen9Encoder::BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize)
+  {
+    if (addr.reg() == data.reg())
+      Gen8Encoder::BYTE_SCATTER(addr, data, bti, elemSize);
+    else {
+      GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+      Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+      this->setHeader(insn);
+      insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+      setSendsOperands(gen9_insn, GenRegister::null(), addr, data);
+      if (this->curr.execWidth == 8)
+        gen9_insn->bits2.sends.src1_length = 1;
+      else if (this->curr.execWidth == 16)
+        gen9_insn->bits2.sends.src1_length = 2;
+      else
+        assert(!"unsupported");
+
+      if (bti.file == GEN_IMMEDIATE_VALUE) {
+        gen9_insn->bits2.sends.sel_reg32_desc = 0;
+        setByteScatterSendsMessageDesc(insn, bti.value.ud, elemSize);
+      } else
+        gen9_insn->bits2.sends.sel_reg32_desc = 1;
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index 5b6328d..1c40b92 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -50,6 +50,8 @@ namespace gbe
     void setSendsOperands(Gen9NativeInstruction *gen9_insn, GenRegister dst, GenRegister src0, GenRegister src1);
     virtual void UNTYPED_WRITE(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemNum);
     virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
+    virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize);
+    virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
   };
 }
 #endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 848933e..9505592 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -2220,16 +2220,23 @@ namespace gbe
   }
 
   void GenContext::emitByteScatterInstruction(const SelectionInstruction &insn) {
-    const GenRegister src = ra->genReg(insn.src(0));
+    const GenRegister addr = ra->genReg(insn.src(0));
+    GenRegister data = ra->genReg(insn.src(1));
+    if (!insn.extra.splitSend)
+      data = addr;
     const uint32_t elemSize = insn.extra.elem;
     const GenRegister bti = ra->genReg(insn.src(2));
 
     if (bti.file == GEN_IMMEDIATE_VALUE) {
-      p->BYTE_SCATTER(src, bti, elemSize);
+      p->BYTE_SCATTER(addr, data, bti, elemSize);
     } else {
       const GenRegister tmp = ra->genReg(insn.dst(0));
       const GenRegister btiTmp = ra->genReg(insn.dst(1));
-      unsigned desc = p->generateByteScatterMessageDesc(0, elemSize);
+      unsigned desc = 0;
+      if (insn.extra.splitSend)
+        desc = p->generateByteScatterSendsMessageDesc(0, elemSize);
+      else
+        desc = p->generateByteScatterMessageDesc(0, elemSize);
 
       unsigned jip0 = beforeMessage(insn, bti, tmp, btiTmp, desc);
 
@@ -2237,7 +2244,7 @@ namespace gbe
       p->push();
         p->curr.predicate = GEN_PREDICATE_NORMAL;
         p->curr.useFlag(insn.state.flag, insn.state.subFlag);
-        p->BYTE_SCATTER(src, GenRegister::addr1(0), elemSize);
+        p->BYTE_SCATTER(addr, data, GenRegister::addr1(0), elemSize);
       p->pop();
       afterMessage(insn, bti, tmp, btiTmp, jip0);
     }
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index dc6dc63..1d721a3 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -504,6 +504,18 @@ namespace gbe
     return setByteScatterMessageDesc(&insn, bti, elemSize);
   }
 
+  unsigned GenEncoder::generateByteScatterSendsMessageDesc(unsigned bti, unsigned elemSize) {
+    GenNativeInstruction insn;
+    memset(&insn, 0, sizeof(GenNativeInstruction));
+    return setByteScatterSendsMessageDesc(&insn, bti, elemSize);
+  }
+
+  unsigned GenEncoder::setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize)
+  {
+    assert(0);
+    return 0;
+  }
+
   unsigned GenEncoder::setByteScatterMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize) {
     uint32_t msg_length = 0;
     uint32_t response_length = 0;
@@ -524,7 +536,7 @@ namespace gbe
     return insn->bits3.ud;
   }
 
-  void GenEncoder::BYTE_SCATTER(GenRegister msg, GenRegister bti, uint32_t elemSize) {
+  void GenEncoder::BYTE_SCATTER(GenRegister msg, GenRegister data, GenRegister bti, uint32_t elemSize) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index e6f362b..5e69833 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -185,7 +185,7 @@ namespace gbe
     /*! Byte gather (for unaligned bytes, shorts and ints) */
     void BYTE_GATHER(GenRegister dst, GenRegister src, GenRegister bti, uint32_t elemSize);
     /*! Byte scatter (for unaligned bytes, shorts and ints) */
-    void BYTE_SCATTER(GenRegister src, GenRegister bti, uint32_t elemSize);
+    virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize);
     /*! Byte gather a64 (for unaligned bytes, shorts and ints) */
     virtual void BYTE_GATHERA64(GenRegister dst, GenRegister src, uint32_t elemSize);
     /*! Byte scatter a64 (for unaligned bytes, shorts and ints) */
@@ -263,6 +263,7 @@ namespace gbe
     virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
     unsigned setByteGatherMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
     unsigned setByteScatterMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
+    virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
 
     unsigned generateAtomicMessageDesc(unsigned function, unsigned bti, unsigned srcNum);
     unsigned generateUntypedReadMessageDesc(unsigned bti, unsigned elemNum);
@@ -270,6 +271,7 @@ namespace gbe
     unsigned generateUntypedWriteSendsMessageDesc(unsigned bti, unsigned elemNum);
     unsigned generateByteGatherMessageDesc(unsigned bti, unsigned elemSize);
     unsigned generateByteScatterMessageDesc(unsigned bti, unsigned elemSize);
+    unsigned generateByteScatterSendsMessageDesc(unsigned bti, unsigned elemSize);
 
     virtual void setHeader(GenNativeInstruction *insn) = 0;
     virtual void setDst(GenNativeInstruction *insn, GenRegister dest) = 0;
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index ea385ac..9722423 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1789,7 +1789,6 @@ namespace gbe
                                        GenRegister bti, vector<GenRegister> temps) {
     unsigned dstNum = temps.size();
     SelectionInstruction *insn = this->appendInsn(SEL_OP_BYTE_SCATTER, dstNum, 3);
-    SelectionVector *vector = this->appendVector();
 
     if (bti.file != GEN_IMMEDIATE_VALUE) {
       insn->state.flag = 0;
@@ -1806,11 +1805,26 @@ namespace gbe
     insn->src(2) = bti;
     insn->extra.elem = elemSize;
 
-    // value and address are contiguous in the send
-    vector->regNum = 2;
-    vector->isSrc = 1;
-    vector->offsetID = 0;
-    vector->reg = &insn->src(0);
+    if (hasSends()) {
+      insn->extra.splitSend = 1;
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1;
+      vector->isSrc = 1;
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+
+      vector = this->appendVector();
+      vector->regNum = 1;
+      vector->isSrc = 1;
+      vector->offsetID = 1;
+      vector->reg = &insn->src(1);
+    } else {
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 2;
+      vector->isSrc = 1;
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+    }
   }
 
   void Selection::Opaque::BYTE_GATHERA64(Reg dst, Reg addr, uint32_t elemSize) {
-- 
1.9.1



More information about the Beignet mailing list