[Beignet] [Printf v2][PATCH 09/12] Implement ASM generation of printf.

yan.wang at linux.intel.com yan.wang at linux.intel.com
Sun Jan 31 23:42:34 PST 2016


From: Yan Wang <yan.wang at linux.intel.com>

Contributor: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Yan Wang <yan.wang at linux.intel.com>
---
 backend/src/backend/gen8_context.cpp | 36 +++++++++++++++++++
 backend/src/backend/gen8_context.hpp |  1 +
 backend/src/backend/gen_context.cpp  | 70 ++++++++++++++++++++++++++++++++++++
 backend/src/backend/gen_context.hpp  |  1 +
 4 files changed, 108 insertions(+)

diff --git a/backend/src/backend/gen8_context.cpp b/backend/src/backend/gen8_context.cpp
index 7455bfc..2e76f53 100644
--- a/backend/src/backend/gen8_context.cpp
+++ b/backend/src/backend/gen8_context.cpp
@@ -1264,6 +1264,42 @@ namespace gbe
     p->ADD(dst, dst, res);
   }
 
+  void Gen8Context::emitPrintfLongInstruction(GenRegister& addr, GenRegister& data,
+                                             GenRegister& src, uint32_t bti) {
+    GenRegister tempSrc, tempDst;
+    GenRegister nextSrc, nextDst;
+    p->push();
+      tempSrc = GenRegister::h2(GenRegister::retype(src, GEN_TYPE_UD));
+      tempDst = GenRegister::retype(data, GEN_TYPE_UD);
+      p->curr.execWidth = 8;
+      p->curr.quarterControl = GEN_COMPRESSION_Q1;
+      p->MOV(tempDst, tempSrc);
+
+      p->curr.quarterControl = GEN_COMPRESSION_Q2;
+      nextSrc = GenRegister::Qn(tempSrc, 1);
+      nextDst = GenRegister::Qn(tempDst, 1);
+      p->MOV(nextDst, nextSrc);
+    p->pop();
+    p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+    p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+
+    p->push();
+      tempSrc = GenRegister::h2(
+        GenRegister::retype(GenRegister::offset(src, 0, 4), GEN_TYPE_UD));
+      tempDst = GenRegister::retype(data, GEN_TYPE_UD);
+      p->curr.execWidth = 8;
+      p->curr.quarterControl = GEN_COMPRESSION_Q1;
+      p->MOV(tempDst, tempSrc);
+
+      p->curr.quarterControl = GEN_COMPRESSION_Q2;
+      nextSrc = GenRegister::Qn(tempSrc, 1);
+      nextDst = GenRegister::Qn(tempDst, 1);
+      p->MOV(nextDst, nextSrc);
+    p->pop();
+    p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+    p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+  }
+
   void ChvContext::setA0Content(uint16_t new_a0[16], uint16_t max_offset, int sz) {
     if (sz == 0)
       sz = 16;
diff --git a/backend/src/backend/gen8_context.hpp b/backend/src/backend/gen8_context.hpp
index cc415c6..2e6eae5 100644
--- a/backend/src/backend/gen8_context.hpp
+++ b/backend/src/backend/gen8_context.hpp
@@ -82,6 +82,7 @@ namespace gbe
     virtual void setA0Content(uint16_t new_a0[16], uint16_t max_offset = 0, int sz = 0);
     virtual void subTimestamps(GenRegister& t0, GenRegister& t1, GenRegister& tmp);
     virtual void addTimestamps(GenRegister& t0, GenRegister& t1, GenRegister& tmp);
+    virtual void emitPrintfLongInstruction(GenRegister& addr, GenRegister& data, GenRegister& src, uint32_t bti);
     virtual GenEncoder* generateEncoder(void) {
       return GBE_NEW(Gen8Encoder, this->simdWidth, 8, deviceID);
     }
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 7807289..8acf67d 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -3148,7 +3148,77 @@ do { \
       p->patchJMPI(oneThreadJip, (p->n_instruction() - oneThreadJip), 0);
   }
 
+  void GenContext::emitPrintfLongInstruction(GenRegister& addr, GenRegister& data,
+                                             GenRegister& src, uint32_t bti) {
+    p->MOV(GenRegister::retype(data, GEN_TYPE_UD), src.bottom_half());
+    p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+    p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+
+    p->MOV(GenRegister::retype(data, GEN_TYPE_UD), src.top_half(this->simdWidth));
+    p->UNTYPED_WRITE(addr, GenRegister::immud(bti), 1);
+    p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+  }
+
   void GenContext::emitPrintfInstruction(const SelectionInstruction &insn) {
+    const GenRegister dst = ra->genReg(insn.dst(0));
+    const GenRegister tmp0 = ra->genReg(insn.dst(1));
+    GenRegister src;
+    uint32_t srcNum = insn.srcNum;
+    if (insn.extra.continueFlag)
+      srcNum--;
+
+    GenRegister addr = GenRegister::retype(tmp0, GEN_TYPE_UD);
+    GenRegister data = GenRegister::offset(addr, 2);
+
+    if (!insn.extra.continueFlag) {
+      p->push(); {
+        p->curr.predicate = GEN_PREDICATE_NONE;
+        p->curr.noMask = 1;
+        //ptr[0] is the total count of the log size.
+        p->MOV(addr, GenRegister::immud(0));
+        p->MOV(data, GenRegister::immud(insn.extra.printfSize + 12));
+      } p->pop();
+
+      p->ATOMIC(addr, GEN_ATOMIC_OP_ADD, addr, GenRegister::immud(insn.extra.printfBTI), 2);
+      /* Write out the header. */
+      p->MOV(data, GenRegister::immud(0xAABBCCDD));
+      p->UNTYPED_WRITE(addr, GenRegister::immud(insn.extra.printfBTI), 1);
+
+      p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+      p->MOV(data, GenRegister::immud(insn.extra.printfSize + 12));
+      p->UNTYPED_WRITE(addr, GenRegister::immud(insn.extra.printfBTI), 1);
+
+      p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+      p->MOV(data, GenRegister::immud(insn.extra.printfNum));
+      p->UNTYPED_WRITE(addr, GenRegister::immud(insn.extra.printfBTI), 1);
+
+      p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+    }
+
+    // Now, store out every parameter.
+    for(uint32_t i = 0; i < srcNum; i++) {
+      src = ra->genReg(insn.src(i));
+      if (src.type == GEN_TYPE_UD || src.type == GEN_TYPE_D || src.type == GEN_TYPE_F) {
+        p->MOV(GenRegister::retype(data, src.type), src);
+        p->UNTYPED_WRITE(addr, GenRegister::immud(insn.extra.printfBTI), 1);
+        p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+      } else if (src.type == GEN_TYPE_B || src.type == GEN_TYPE_UB ) {
+        p->MOV(GenRegister::retype(data, GEN_TYPE_UD), src);
+        p->UNTYPED_WRITE(addr, GenRegister::immud(insn.extra.printfBTI), 1);
+        p->ADD(addr, addr, GenRegister::immud(sizeof(uint32_t)));
+      } else if (src.type == GEN_TYPE_L || src.type == GEN_TYPE_UL ) {
+        emitPrintfLongInstruction(addr, data, src, insn.extra.printfBTI);
+      }
+    }
+
+    if (dst.hstride == GEN_HORIZONTAL_STRIDE_0) {
+      p->push();
+      p->curr.execWidth = 1;
+    }
+    p->MOV(dst, GenRegister::immd(0));
+    if (dst.hstride == GEN_HORIZONTAL_STRIDE_0) {
+      p->pop();
+    }
   }
 
   void GenContext::setA0Content(uint16_t new_a0[16], uint16_t max_offset, int sz) {
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index 036fa78..6b36227 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -230,6 +230,7 @@ namespace gbe
     void calcGlobalXYZRange(GenRegister& reg, GenRegister& tmp, int flag, int subFlag);
     virtual void subTimestamps(GenRegister& t0, GenRegister& t1, GenRegister& tmp);
     virtual void addTimestamps(GenRegister& t0, GenRegister& t1, GenRegister& tmp);
+    virtual void emitPrintfLongInstruction(GenRegister& addr, GenRegister& data, GenRegister& src, uint32_t bti);
 
   private:
     CompileErrorCode errCode;
-- 
2.4.3



More information about the Beignet mailing list