[Beignet] [PATCH 5/7] HSW: correct jump distance of hsw's jmpi.

junyan.he at inbox.com junyan.he at inbox.com
Tue Apr 15 17:56:20 PDT 2014


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

Gen5+ bspec: the jump distance is in number of eight-byte units.
Gen7.5+: the offset is in unit of 8bits for JMPI, 64bits for other flow control instructions.
So need multiple all jump distance with 8 in jmpi.

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_context.cpp |    9 +++++++++
 backend/src/backend/gen75_context.hpp |    2 ++
 backend/src/backend/gen75_encoder.cpp |   34 +++++++++++++++++++++++++++++++++
 backend/src/backend/gen75_encoder.hpp |    1 +
 backend/src/backend/gen_context.cpp   |    8 ++++----
 backend/src/backend/gen_encoder.hpp   |    2 +-
 6 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/backend/src/backend/gen75_context.cpp b/backend/src/backend/gen75_context.cpp
index e101815..ba2468c 100644
--- a/backend/src/backend/gen75_context.cpp
+++ b/backend/src/backend/gen75_context.cpp
@@ -25,6 +25,15 @@
 
 namespace gbe
 {
+  void Gen75Context::patchBranches(void) {
+    using namespace ir;
+    for (auto pair : branchPos2) {
+      const LabelIndex label = pair.first;
+      const int32_t insnID = pair.second;
+      const int32_t targetID = labelPos.find(label)->second;
+      p->patchJMPI(insnID, (targetID-insnID-1) * 16);
+    }
+  }
 
 }
 
diff --git a/backend/src/backend/gen75_context.hpp b/backend/src/backend/gen75_context.hpp
index 1f7ec76..201bafc 100644
--- a/backend/src/backend/gen75_context.hpp
+++ b/backend/src/backend/gen75_context.hpp
@@ -36,6 +36,8 @@ namespace gbe
     	: GenContext(unit, name, limitRegisterPressure, 16, false) {
       this->p = GBE_NEW(Gen75Encoder, simdWidth, 75);
     };
+
+    virtual void patchBranches(void);
   };
 }
 #endif /* __GBE_GEN75_CONTEXT_HPP__ */
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index dabe599..bb6d622 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -62,4 +62,38 @@ namespace gbe
     insn->bits3.gen7_typed_rw.slot = 1;
   }
 
+  void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+    GenInstruction &insn = this->store[insnID];
+    GBE_ASSERT(insnID < this->store.size());
+    GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI);
+    if ( jumpDistance > -32769 && jumpDistance < 32768 ) {
+      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+    } 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.
+      // A little hacky as we need to change the nop instruction to add
+      // instruction manually.
+      // If this is a unconditional jump, we just need to add the IP directly.
+      // FIXME there is an optimization method which we can insert a
+      // ADD instruction on demand. But that will need some extra analysis
+      // for all the branching instruction. And need to adjust the distance
+      // for those branch instruction's start point and end point contains
+      // this instruction.
+      insn.header.opcode = GEN_OPCODE_ADD;
+      this->setDst(&insn, GenRegister::ip());
+      this->setSrc0(&insn, GenRegister::ip());
+      this->setSrc1(&insn, GenRegister::immd((jumpDistance + 16)));
+    } else {
+      insn.header.predicate_inverse ^= 1;
+      this->setSrc1(&insn, GenRegister::immd(16));
+      GenInstruction &insn2 = this->store[insnID+1];
+      GBE_ASSERT(insn2.header.opcode == GEN_OPCODE_NOP);
+      GBE_ASSERT(insnID < this->store.size());
+      insn2.header.predicate_control = GEN_PREDICATE_NONE;
+      insn2.header.opcode = GEN_OPCODE_ADD;
+      this->setDst(&insn2, GenRegister::ip());
+      this->setSrc0(&insn2, GenRegister::ip());
+      this->setSrc1(&insn2, GenRegister::immd(jumpDistance));
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 57e9060..bdd294a 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -37,6 +37,7 @@ namespace gbe
     virtual void setTypedWriteMessage(GenInstruction *insn, unsigned char bti,
                                       unsigned char msg_type, uint32_t msg_length,
                                       bool header_present);
+    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
   };
 }
 #endif /* __GBE_GEN75_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 3faed98..75e0777 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -88,7 +88,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-1) * 2);
+      p->patchJMPI(insnID, (targetID-insnID-1) * jump_width);
     }
   }
 
@@ -932,7 +932,7 @@ namespace gbe
       p->SHL(high, low, tmp);
       p->MOV(low, GenRegister::immud(0));
 
-      p->patchJMPI(jip1, (p->n_instruction() - (jip1 + 1)) * 2);
+      p->patchJMPI(jip1, (p->n_instruction() - (jip1 + 1)) * jump_width);
       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;
@@ -946,7 +946,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 + 1)) * 2);
+      p->patchJMPI(jip0, (p->n_instruction() - (jip0 + 1)) * jump_width);
 
     p->pop();
 
@@ -1461,7 +1461,7 @@ namespace gbe
         p->curr.predicate = GEN_PREDICATE_ALIGN1_ANY16H;
       else
         NOT_IMPLEMENTED;
-      int jip = -(int)(p->n_instruction() - loop_start + 1) * 2;
+      int jip = -(int)(p->n_instruction() - loop_start + 1) * jump_width;
       p->JMPI(zero);
       p->patchJMPI(p->n_instruction()-2, jip);
       p->pop();
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index a323d94..cd3dfdd 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -185,7 +185,7 @@ namespace gbe
     void MATH(GenRegister dst, uint32_t function, GenRegister src);
 
     /*! Patch JMPI (located at index insnID) with the given jump distance */
-    void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
 
     ////////////////////////////////////////////////////////////////////////
     // Helper functions to encode
-- 
1.7.9.5





More information about the Beignet mailing list