GBE: Add if/endif/brc/brd instruction support.
authorZhigang Gong <zhigang.gong@intel.com>
Mon, 17 Mar 2014 10:08:17 +0000 (18:08 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Tue, 8 Apr 2014 08:21:32 +0000 (16:21 +0800)
Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
Reviewed-by: "Song, Ruiling" <ruiling.song@intel.com>
backend/src/backend/gen/gen_mesa_disasm.c
backend/src/backend/gen_context.cpp
backend/src/backend/gen_context.hpp
backend/src/backend/gen_defs.hpp
backend/src/backend/gen_encoder.cpp
backend/src/backend/gen_encoder.hpp
backend/src/backend/gen_insn_selection.cpp
backend/src/backend/gen_insn_selection.hpp
backend/src/backend/gen_insn_selection.hxx

index 1f5adc9..84ef0c8 100644 (file)
@@ -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] = {
index 88d4866..c46127a 100644 (file)
@@ -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);
   }
 
index 6ec43cc..bd01c49 100644 (file)
@@ -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) */
index ffa38c0..7c49497 100644 (file)
@@ -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,
index 9853a56..fc7e53d 100644 (file)
@@ -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.
index 8d9a497..4bb208f 100644 (file)
@@ -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);
 
     ////////////////////////////////////////////////////////////////////////
index 84f3fd4..d86e04c 100644 (file)
@@ -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();
index 0fde1df..04fbb9f 100644 (file)
@@ -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 */
index 564dbc5..d318f8e 100644 (file)
@@ -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)