[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