[Beignet] [PATCH 2/9 V3] Backend: Add functions to set a0 register.

junyan.he at inbox.com junyan.he at inbox.com
Mon Mar 9 01:10:50 PDT 2015


From: Junyan He <junyan.he at linux.intel.com>

a0 as a address register acts a very important role in
indirect mode access. We add auxiliary functions to set
its content correctly and effectively.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/backend/gen_context.cpp |   43 +++++++++++++++++++++++++++++++++++
 backend/src/backend/gen_context.hpp |    3 +++
 2 files changed, 46 insertions(+)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index f8748ad..411cf3f 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -51,6 +51,7 @@ namespace gbe
     this->ra = NULL;
     this->ifEndifFix = false;
     this->regSpillTick = 0;
+    memset(a0, 0, sizeof(a0));
   }
 
   GenContext::~GenContext(void) {
@@ -1801,6 +1802,48 @@ namespace gbe
     p->TYPED_WRITE(header, true, bti);
   }
 
+  void GenContext::setA0Content(uint16_t new_a0[16], uint16_t max_offset, int sz) {
+    int16_t diff = new_a0[0] - this->a0[0];
+
+    if (sz == 0)
+      sz = 8;
+    GBE_ASSERT(sz%4 == 0);
+    GBE_ASSERT(new_a0[0] >= 0 && new_a0[0] < 4096);
+    bool need_reset = false;
+    for (int i = 1; i < sz; i++) {
+      GBE_ASSERT(new_a0[i] >= 0 && new_a0[0] < 4096);
+      int16_t d = new_a0[i] - this->a0[i];
+      if (diff != d) {
+        need_reset = true;
+        break;
+      }
+    }
+
+    GBE_ASSERT(a0[0] + diff < 4096 && a0[0] + diff >= 0);
+    if (!need_reset && diff >= -512 && diff + max_offset <= 511) {
+      return;
+    } else if (!need_reset && sz == 8) {
+      p->push();
+      p->curr.execWidth = 8;
+      p->curr.predicate = GEN_PREDICATE_NONE;
+      p->curr.noMask = 1;
+      p->ADD(GenRegister::retype(GenRegister::addr8(0), GEN_TYPE_W),
+          GenRegister::retype(GenRegister::addr8(0), GEN_TYPE_W), GenRegister::immw(diff));
+      p->pop();
+    } else {
+      p->push();
+      p->curr.execWidth = 1;
+      p->curr.predicate = GEN_PREDICATE_NONE;
+      p->curr.noMask = 1;
+      for (int i = 0; i < sz/2; i++) {
+        p->MOV(GenRegister::retype(GenRegister::addr1(i*2), GEN_TYPE_UD),
+            GenRegister::immud(new_a0[i*2 + 1] << 16 | new_a0[i*2]));
+      }
+      p->pop();
+    }
+    memcpy(this->a0, new_a0, sizeof(uint16_t)*sz);
+  }
+
   BVAR(OCL_OUTPUT_REG_ALLOC, false);
   BVAR(OCL_OUTPUT_ASM, false);
 
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index f64b916..6ca88db 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -208,6 +208,9 @@ namespace gbe
     /*! allocate a new curbe register and insert to curbe pool. */
     void allocCurbeReg(ir::Register reg, gbe_curbe_type value, uint32_t subValue = 0);
 
+    uint16_t a0[16];
+    virtual void setA0Content(uint16_t new_a0[16], uint16_t max_offset = 0, int sz = 0);
+
   private:
     CompileErrorCode errCode;
     bool ifEndifFix;
-- 
1.7.9.5



More information about the Beignet mailing list