[Beignet] [PATCH 1/3] BDW: Pass Jip and Uip when patchJMPI.

Yang Rong rong.r.yang at intel.com
Sun Sep 28 22:38:10 PDT 2014


Do not like GEN7, BDW's Jip is in bits4 and Uip is in bits3, so should set Jip
and Uip independently.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 backend/src/backend/gen75_encoder.cpp | 14 ++++++--------
 backend/src/backend/gen75_encoder.hpp |  2 +-
 backend/src/backend/gen8_encoder.cpp  | 24 ++++++++++++++++++++----
 backend/src/backend/gen8_encoder.hpp  |  2 +-
 backend/src/backend/gen_context.cpp   | 10 +++++-----
 backend/src/backend/gen_encoder.cpp   | 31 ++++++++++++++-----------------
 backend/src/backend/gen_encoder.hpp   |  2 +-
 7 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index dcb0ab2..10a9b5c 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -250,7 +250,7 @@ namespace gbe
     alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
   }
 
-  void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+  void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
     GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
     GBE_ASSERT(insnID < this->store.size());
     GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -264,19 +264,17 @@ namespace gbe
     if( insn.header.opcode == GEN_OPCODE_WHILE ){
       // if this WHILE instruction jump back to an ELSE instruction,
       // need add distance to go to the next instruction.
-      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance];
+      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
       if(insn_else.header.opcode == GEN_OPCODE_ELSE){
-        jumpDistance += 2;
+        jip += 2;
       }
     }
 
-    if (insn.header.opcode != GEN_OPCODE_JMPI)
-      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
-    else {
+    if (insn.header.opcode == GEN_OPCODE_JMPI) {
       //jumpDistance'unit is Qword, and the HSW's JMPI offset of jmpi is in byte, so multi 8
-      jumpDistance = (jumpDistance - 2) * 8;
-      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+      jip = (jip - 2) * 8;
     }
+    this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
     return;
   }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 5490450..f601d61 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -43,7 +43,7 @@ namespace gbe
     /*! 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);
+    virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
     /*! 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());
diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
index 6105634..f50ce47 100644
--- a/backend/src/backend/gen8_encoder.cpp
+++ b/backend/src/backend/gen8_encoder.cpp
@@ -250,7 +250,7 @@ namespace gbe
     alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
   }
 
-  void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+  void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
     GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
     GBE_ASSERT(insnID < this->store.size());
     GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -258,18 +258,34 @@ namespace gbe
                insn.header.opcode == GEN_OPCODE_ENDIF ||
                insn.header.opcode == GEN_OPCODE_IF ||
                insn.header.opcode == GEN_OPCODE_BRC ||
+               insn.header.opcode == GEN_OPCODE_WHILE ||
                insn.header.opcode == GEN_OPCODE_ELSE);
 
+    if( insn.header.opcode == GEN_OPCODE_WHILE ) {
+      // if this WHILE instruction jump back to an ELSE instruction,
+      // need add distance to go to the next instruction.
+      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
+      if(insn_else.header.opcode == GEN_OPCODE_ELSE) {
+        jip += 2;
+      }
+    }
+
+    if(insn.header.opcode == GEN_OPCODE_ELSE)
+      uip = jip;
+
     if (insn.header.opcode == GEN_OPCODE_IF) {
-      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+      Gen8NativeInstruction *gen8_insn = &insn.gen8_insn;
+      this->setSrc0(&insn, GenRegister::immud(0));
+      gen8_insn->bits2.gen8_branch.uip = uip*8;
+      gen8_insn->bits3.gen8_branch.jip = jip*8;
       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;
+      jip = (jip - 2);
     }
 
-    this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+    this->setSrc1(&insn, GenRegister::immd(jip*8));
   }
 
   void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
diff --git a/backend/src/backend/gen8_encoder.hpp b/backend/src/backend/gen8_encoder.hpp
index e962875..6ca3b41 100644
--- a/backend/src/backend/gen8_encoder.hpp
+++ b/backend/src/backend/gen8_encoder.hpp
@@ -41,7 +41,7 @@ namespace gbe
     /*! 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);
+    virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
     /*! Get double/long exec width */
     virtual int getDoubleExecWidth(void) { return GEN8_DOUBLE_EXEC_WIDTH; }
     virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 78f21ad..1d0cf10 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -115,7 +115,7 @@ namespace gbe
       const LabelIndex label = pair.first;
       const int32_t insnID = pair.second;
       const int32_t targetID = labelPos.find(label)->second;
-      p->patchJMPI(insnID, (targetID - insnID));
+      p->patchJMPI(insnID, (targetID - insnID), 0);
     }
     for (auto pair : branchPos3) {
       const LabelPair labelPair = pair.first;
@@ -128,7 +128,7 @@ namespace gbe
         errCode = OUT_OF_RANGE_IF_ENDIF; 
         return false;
       }
-      p->patchJMPI(insnID, ((uip - insnID) << 16) | (0x0000ffff & (jip - insnID)));
+      p->patchJMPI(insnID, jip - insnID, uip - insnID);
     }
     return true;
   }
@@ -928,7 +928,7 @@ namespace gbe
       p->SHL(high, low, tmp);
       p->MOV(low, GenRegister::immud(0));
 
-      p->patchJMPI(jip1, (p->n_instruction() - jip1) );
+      p->patchJMPI(jip1, (p->n_instruction() - jip1), 0);
       p->curr.predicate = GEN_PREDICATE_NONE;
       p->CMP(GEN_CONDITIONAL_LE, exp, GenRegister::immud(31));  //update dst where high != 0
       p->curr.predicate = GEN_PREDICATE_NORMAL;
@@ -942,7 +942,7 @@ namespace gbe
       p->CMP(GEN_CONDITIONAL_EQ, high, GenRegister::immud(0x80000000));
       p->CMP(GEN_CONDITIONAL_EQ, low, GenRegister::immud(0x0));
       p->AND(dst_ud, dst_ud, GenRegister::immud(0xfffffffe));
-      p->patchJMPI(jip0, (p->n_instruction() - jip0));
+      p->patchJMPI(jip0, (p->n_instruction() - jip0), 0);
 
     p->pop();
 
@@ -1427,7 +1427,7 @@ namespace gbe
       p->curr.noMask = 1;
       jip0 = p->n_instruction();
       p->JMPI(zero);
-      p->patchJMPI(jip0, distance);
+      p->patchJMPI(jip0, distance, 0);
       p->pop();
       // end of loop
     }
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 9b84d5b..6bb6226 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -820,7 +820,7 @@ namespace gbe
   ALU2_BRA(BRD)
   ALU2_BRA(BRC)
 
-  void GenEncoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+  void GenEncoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
     GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
     GBE_ASSERT(insnID < this->store.size());
     GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -834,24 +834,21 @@ namespace gbe
     if( insn.header.opcode == GEN_OPCODE_WHILE ){
       // if this WHILE instruction jump back to an ELSE instruction,
       // need add distance to go to the next instruction.
-      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance];
+      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
       if(insn_else.header.opcode == GEN_OPCODE_ELSE){
-        jumpDistance += 2;
+        jip += 2;
       }
     }
 
-    if (insn.header.opcode != GEN_OPCODE_JMPI || (jumpDistance > -32769 && jumpDistance < 32768))  {
-           if (insn.header.opcode == GEN_OPCODE_IF) {
-             this->setSrc1(&insn, GenRegister::immd(jumpDistance));
-             return;
-           }
-           else if (insn.header.opcode == GEN_OPCODE_JMPI){
-             jumpDistance = jumpDistance - 2;
-           }
-           else if(insn.header.opcode == GEN_OPCODE_ENDIF)
-             jumpDistance += 2;
-
-           this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+    if (insn.header.opcode != GEN_OPCODE_JMPI || (jip > -32769 && jip < 32768))  {
+      if (insn.header.opcode == GEN_OPCODE_IF) {
+        this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
+        return;
+      } else if (insn.header.opcode == GEN_OPCODE_JMPI) {
+        jip = jip - 2;
+      } else if(insn.header.opcode == GEN_OPCODE_ENDIF)
+        jip += 2;
+       this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
     } else if ( insn.header.predicate_control == GEN_PREDICATE_NONE ) {
       // For the conditional jump distance out of S15 range, we need to use an
       // inverted jmp followed by a add ip, ip, distance to implement.
@@ -867,7 +864,7 @@ namespace gbe
       insn.header.opcode = GEN_OPCODE_ADD;
       this->setDst(&insn, GenRegister::ip());
       this->setSrc0(&insn, GenRegister::ip());
-      this->setSrc1(&insn, GenRegister::immd(jumpDistance * 8));
+      this->setSrc1(&insn, GenRegister::immd(jip * 8));
     } else {
       GenNativeInstruction &insn2 = *(GenNativeInstruction *)&this->store[insnID+2];
       insn.header.predicate_inverse ^= 1;
@@ -878,7 +875,7 @@ namespace gbe
       insn2.header.opcode = GEN_OPCODE_ADD;
       this->setDst(&insn2, GenRegister::ip());
       this->setSrc0(&insn2, GenRegister::ip());
-      this->setSrc1(&insn2, GenRegister::immd((jumpDistance - 2) * 8));
+      this->setSrc1(&insn2, GenRegister::immd((jip - 2) * 8));
     }
   }
 
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index c8dc113..0b6154d 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -207,7 +207,7 @@ namespace gbe
     void MATH(GenRegister dst, uint32_t function, GenRegister src);
 
     /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
-    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+    virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
 
     ////////////////////////////////////////////////////////////////////////
     // Helper functions to encode
-- 
1.8.3.2



More information about the Beignet mailing list