[Beignet] [PATCH 09/18] GBE: Add if/endif/brc/brd instruction support.

Zhigang Gong zhigang.gong at intel.com
Fri Mar 28 00:10:47 PDT 2014


Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/backend/gen/gen_mesa_disasm.c  |  5 ++--
 backend/src/backend/gen_context.cpp        | 34 ++++++++++++++++++++++++--
 backend/src/backend/gen_context.hpp        | 12 ++++++++++
 backend/src/backend/gen_defs.hpp           |  3 ++-
 backend/src/backend/gen_encoder.cpp        | 19 +++++++++++++--
 backend/src/backend/gen_encoder.hpp        | 12 +++++++++-
 backend/src/backend/gen_insn_selection.cpp | 38 +++++++++++++++++++++++++++++-
 backend/src/backend/gen_insn_selection.hpp |  6 +++++
 backend/src/backend/gen_insn_selection.hxx |  4 ++++
 9 files changed, 124 insertions(+), 9 deletions(-)

diff --git a/backend/src/backend/gen/gen_mesa_disasm.c b/backend/src/backend/gen/gen_mesa_disasm.c
index 1f5adc9..84ef0c8 100644
--- a/backend/src/backend/gen/gen_mesa_disasm.c
+++ b/backend/src/backend/gen/gen_mesa_disasm.c
@@ -100,8 +100,9 @@ static const struct {
   [GEN_OPCODE_SENDC] = { .name = "sendc", .nsrc = 1, .ndst = 1 },
   [GEN_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
   [GEN_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 0, .ndst = 0 },
+  [GEN_OPCODE_BRD] = { .name = "brd", .nsrc = 1, .ndst = 0 },
   [GEN_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
-  [GEN_OPCODE_IFF] = { .name = "iff", .nsrc = 2, .ndst = 1 },
+  [GEN_OPCODE_BRC] = { .name = "brc", .nsrc = 1, .ndst = 0 },
   [GEN_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 },
   [GEN_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
   [GEN_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 },
@@ -113,7 +114,7 @@ static const struct {
   [GEN_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
   [GEN_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
   [GEN_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
-  [GEN_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
+  [GEN_OPCODE_ENDIF] = { .name = "endif", .nsrc = 1, .ndst = 0 },
 };
 
 static const char *conditional_modifier[16] = {
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 88d4866..c46127a 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -213,6 +213,32 @@ namespace gbe
         p->pop();
         break;
        }
+      case SEL_OP_BRC:
+        {
+          const ir::LabelIndex label0(insn.index), label1(insn.index1);
+          const LabelPair labelPair(label0, label1);
+          const GenRegister src = ra->genReg(insn.src(0));
+          this->branchPos3.push_back(std::make_pair(labelPair, p->store.size()));
+          p->BRC(src);
+        }
+        break;
+      case SEL_OP_BRD:
+        insertJumpPos(insn);
+        p->BRD(src);
+        break;
+      case SEL_OP_ENDIF:
+        insertJumpPos(insn);
+        p->ENDIF(src);
+        break;
+      case SEL_OP_IF:
+        {
+          const ir::LabelIndex label0(insn.index), label1(insn.index1);
+          const LabelPair labelPair(label0, label1, insn.offset0, insn.offset1);
+          const GenRegister src = ra->genReg(insn.src(0));
+          this->branchPos3.push_back(std::make_pair(labelPair, p->store.size()));
+          p->IF(src);
+        }
+        break;
       default: NOT_IMPLEMENTED;
     }
   }
@@ -1646,10 +1672,14 @@ namespace gbe
     }
   }
 
-  void GenContext::emitJumpInstruction(const SelectionInstruction &insn) {
+ void GenContext::insertJumpPos(const SelectionInstruction &insn) {
     const ir::LabelIndex label(insn.index);
-    const GenRegister src = ra->genReg(insn.src(0));
     this->branchPos2.push_back(std::make_pair(label, p->store.size()));
+ }
+
+  void GenContext::emitJumpInstruction(const SelectionInstruction &insn) {
+    insertJumpPos(insn);
+    const GenRegister src = ra->genReg(insn.src(0));
     p->JMPI(src);
   }
 
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index 6ec43cc..bd01c49 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -150,8 +150,20 @@ namespace gbe
     virtual Kernel *allocateKernel(void);
     /*! Store the position of each label instruction in the Gen ISA stream */
     map<ir::LabelIndex, uint32_t> labelPos;
+    typedef struct LabelPair {
+      LabelPair(ir::LabelIndex l0, ir::LabelIndex l1,
+                int16_t offset0 = 0, int16_t offset1 = 0) :
+                l0(l0), l1(l1), offset0(offset0), offset1(offset1) {};
+      ir::LabelIndex l0;
+      ir::LabelIndex l1;
+      int16_t offset0;
+      int16_t offset1;
+    } LabelPair;
     /*! Store the Gen instructions to patch */
+    vector<std::pair<LabelPair, uint32_t>> branchPos3;
     vector<std::pair<ir::LabelIndex, uint32_t>> branchPos2;
+
+    void insertJumpPos(const SelectionInstruction &insn);
     /*! Encode Gen ISA */
     GenEncoder *p;
     /*! Instruction selection on Gen ISA (pre-register allocation) */
diff --git a/backend/src/backend/gen_defs.hpp b/backend/src/backend/gen_defs.hpp
index ffa38c0..7c49497 100644
--- a/backend/src/backend/gen_defs.hpp
+++ b/backend/src/backend/gen_defs.hpp
@@ -128,8 +128,9 @@ enum opcode {
   GEN_OPCODE_F32TO16 = 19,
   GEN_OPCODE_F16TO32 = 20,
   GEN_OPCODE_JMPI = 32,
+  GEN_OPCODE_BRD = 33,
   GEN_OPCODE_IF = 34,
-  GEN_OPCODE_IFF = 35,
+  GEN_OPCODE_BRC = 35,
   GEN_OPCODE_ELSE = 36,
   GEN_OPCODE_ENDIF = 37,
   GEN_OPCODE_DO = 38,
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 9853a56..fc7e53d 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -959,6 +959,9 @@ namespace gbe
   ALU2(PLN)
   ALU2(MACH)
   ALU3(MAD)
+ // ALU2(BRC)
+ // ALU1(ENDIF)
+ //  ALU1(IF)
 
   void GenEncoder::SUBB(GenRegister dest, GenRegister src0, GenRegister src1) {
     push();
@@ -1053,12 +1056,24 @@ namespace gbe
     NOP();
   }
 
+#define ALU2_BRA(OP) \
+  void GenEncoder::OP(GenRegister src) { \
+    alu2(this, GEN_OPCODE_##OP, GenRegister::null(), GenRegister::null(), src); \
+  }
+
+  ALU2_BRA(IF)
+  ALU2_BRA(ENDIF)
+  ALU2_BRA(BRD)
+  ALU2_BRA(BRC)
+
   void GenEncoder::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);
+    GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
+               insn.header.opcode == GEN_OPCODE_BRD  ||
+               insn.header.opcode == GEN_OPCODE_ENDIF);
     if ( jumpDistance > -32769 && jumpDistance < 32768 ) {
-        this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+          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.
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 8d9a497..4bb208f 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -122,6 +122,8 @@ namespace gbe
     ALU2(PLN)
     ALU3(MAD)
     //ALU2(MOV_DF);
+    ALU2(BRC)
+    ALU1(BRD)
 #undef ALU1
 #undef ALU2
 #undef ALU3
@@ -134,6 +136,14 @@ namespace gbe
     void FENCE(GenRegister dst);
     /*! Jump indexed instruction */
     void JMPI(GenRegister src);
+    /*! IF indexed instruction */
+    void IF(GenRegister src);
+    /*! ENDIF indexed instruction */
+    void ENDIF(GenRegister src);
+    /*! BRC indexed instruction */
+    void BRC(GenRegister src);
+    /*! BRD indexed instruction */
+    void BRD(GenRegister src);
     /*! Compare instructions */
     void CMP(uint32_t conditional, GenRegister src0, GenRegister src1, GenRegister dst = GenRegister::null());
     /*! Select with embedded compare (like sel.le ...) */
@@ -184,7 +194,7 @@ namespace gbe
     /*! Extended math function (1 source) */
     void MATH(GenRegister dst, uint32_t function, GenRegister src);
 
-    /*! Patch JMPI (located at index insnID) with the given jump distance */
+    /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
     void patchJMPI(uint32_t insnID, int32_t jumpDistance);
 
     ////////////////////////////////////////////////////////////////////////
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 84f3fd4..d86e04c 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -538,6 +538,14 @@ namespace gbe
     void LABEL(ir::LabelIndex label);
     /*! Jump indexed instruction */
     void JMPI(Reg src, ir::LabelIndex target);
+    /*! IF indexed instruction */
+    void IF(Reg src, ir::LabelIndex jip, ir::LabelIndex uip, int16_t offset0, int16_t offset1);
+    /*! ENDIF indexed instruction */
+    void ENDIF(Reg src, ir::LabelIndex jip);
+    /*! BRD indexed instruction */
+    void BRD(Reg src, ir::LabelIndex jip);
+    /*! BRC indexed instruction */
+    void BRC(Reg src, ir::LabelIndex jip, ir::LabelIndex uip);
     /*! Compare instructions */
     void CMP(uint32_t conditional, Reg src0, Reg src1, Reg dst = GenRegister::null());
     /*! Select instruction with embedded comparison */
@@ -960,6 +968,35 @@ namespace gbe
     insn->index = uint16_t(index);
   }
 
+  void Selection::Opaque::BRD(Reg src, ir::LabelIndex jip) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_BRD, 0, 1);
+    insn->src(0) = src;
+    insn->index = uint16_t(jip);
+  }
+
+  void Selection::Opaque::BRC(Reg src, ir::LabelIndex jip, ir::LabelIndex uip) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_BRC, 0, 1);
+    insn->src(0) = src;
+    insn->index = uint16_t(jip);
+    insn->index1 = uint16_t(uip);
+  }
+
+  void Selection::Opaque::IF(Reg src, ir::LabelIndex jip, ir::LabelIndex uip,
+                             int16_t offset0, int16_t offset1) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_IF, 0, 1);
+    insn->src(0) = src;
+    insn->index = uint16_t(jip);
+    insn->index1 = uint16_t(uip);
+    insn->offset0 = offset0;
+    insn->offset1 = offset1;
+  }
+
+  void Selection::Opaque::ENDIF(Reg src, ir::LabelIndex jip) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_IF, 0, 1);
+    insn->src(0) = src;
+    insn->index = uint16_t(jip);
+  }
+
   void Selection::Opaque::CMP(uint32_t conditional, Reg src0, Reg src1, Reg dst) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_CMP, 1, 2);
     insn->src(0) = src0;
@@ -3197,7 +3234,6 @@ namespace gbe
       using namespace ir;
       const GenRegister ip = sel.selReg(ocl::blockip, TYPE_U16);
       const LabelIndex jip = sel.ctx.getLabelIndex(&insn);
-      const uint32_t simdWidth = sel.ctx.getSimdWidth();
 
       // We will not emit any jump if we must go the next block anyway
       const BasicBlock *curr = insn.getParent();
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 0fde1df..04fbb9f 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -132,6 +132,12 @@ namespace gbe
     uint8_t srcNum:4;
     /*! To store various indices */
     uint16_t index;
+    /*! For BRC/IF to store the UIP */
+    uint16_t index1;
+    /*! For IF instruction to adjust the corresponding ENDIF's position. */
+    /*! as endif is not at the begining of any BBs.*/
+    uint16_t offset0;
+    uint16_t offset1;
     /*! instruction ID used for vector allocation. */
     uint32_t ID;
     /*! Variable sized. Destinations and sources go here */
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 564dbc5..d318f8e 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -80,3 +80,7 @@ DECL_SELECTION_IR(CONVI64_TO_I, UnaryInstruction)
 DECL_SELECTION_IR(CONVI64_TO_F, I64ToFloatInstruction)
 DECL_SELECTION_IR(CONVF_TO_I64, FloatToI64Instruction)
 DECL_SELECTION_IR(I64MADSAT, I64MADSATInstruction)
+DECL_SELECTION_IR(BRC, BinaryInstruction)
+DECL_SELECTION_IR(BRD, UnaryInstruction)
+DECL_SELECTION_IR(IF, UnaryInstruction)
+DECL_SELECTION_IR(ENDIF, UnaryInstruction)
-- 
1.8.3.2



More information about the Beignet mailing list