[Beignet] [PATCH V2 4/4] add sends support for byte write
Guo, Yejun
yejun.guo at intel.com
Thu Nov 24 04:57:27 UTC 2016
v2: use function setSendsOperands
Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
backend/src/backend/gen9_encoder.cpp | 48 ++++++++++++++++++++++++++++++
backend/src/backend/gen9_encoder.hpp | 2 ++
backend/src/backend/gen_context.cpp | 15 +++++++---
backend/src/backend/gen_encoder.cpp | 14 ++++++++-
backend/src/backend/gen_encoder.hpp | 4 ++-
backend/src/backend/gen_insn_selection.cpp | 26 ++++++++++++----
6 files changed, 97 insertions(+), 12 deletions(-)
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index 867f3f1..f8338ef 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -141,4 +141,52 @@ namespace gbe
gen9_insn->bits2.sends.sel_reg32_desc = 1;
}
}
+
+ unsigned Gen9Encoder::setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize)
+ {
+ Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+ gen9_insn->bits3.sends_byte_rw.header_present = 0;
+ gen9_insn->bits3.sends_byte_rw.response_length = 0;
+ gen9_insn->bits3.sends_byte_rw.end_of_thread = 0;
+ gen9_insn->bits3.sends_byte_rw.msg_type = GEN7_BYTE_SCATTER;
+ gen9_insn->bits3.sends_byte_rw.bti = bti;
+ gen9_insn->bits3.sends_byte_rw.data_size = elemSize;
+
+ if (this->curr.execWidth == 8) {
+ gen9_insn->bits3.sends_byte_rw.src0_length = 1;
+ gen9_insn->bits3.sends_byte_rw.simd_mode = GEN_BYTE_SCATTER_SIMD8;
+ } else if (this->curr.execWidth == 16) {
+ gen9_insn->bits3.sends_byte_rw.src0_length = 2;
+ gen9_insn->bits3.sends_byte_rw.simd_mode = GEN_BYTE_SCATTER_SIMD16;
+ }
+
+ return gen9_insn->bits3.ud;
+ }
+
+ void Gen9Encoder::BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize)
+ {
+ if (addr.reg() == data.reg())
+ Gen8Encoder::BYTE_SCATTER(addr, data, bti, elemSize);
+ else {
+ GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+ Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+ this->setHeader(insn);
+ insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+ setSendsOperands(gen9_insn, GenRegister::null(), addr, data);
+ if (this->curr.execWidth == 8)
+ gen9_insn->bits2.sends.src1_length = 1;
+ else if (this->curr.execWidth == 16)
+ gen9_insn->bits2.sends.src1_length = 2;
+ else
+ assert(!"unsupported");
+
+ if (bti.file == GEN_IMMEDIATE_VALUE) {
+ gen9_insn->bits2.sends.sel_reg32_desc = 0;
+ setByteScatterSendsMessageDesc(insn, bti.value.ud, elemSize);
+ } else
+ gen9_insn->bits2.sends.sel_reg32_desc = 1;
+ }
+ }
} /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index 5b6328d..1c40b92 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -50,6 +50,8 @@ namespace gbe
void setSendsOperands(Gen9NativeInstruction *gen9_insn, GenRegister dst, GenRegister src0, GenRegister src1);
virtual void UNTYPED_WRITE(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemNum);
virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
+ virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize);
+ virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
};
}
#endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 848933e..9505592 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -2220,16 +2220,23 @@ namespace gbe
}
void GenContext::emitByteScatterInstruction(const SelectionInstruction &insn) {
- const GenRegister src = ra->genReg(insn.src(0));
+ const GenRegister addr = ra->genReg(insn.src(0));
+ GenRegister data = ra->genReg(insn.src(1));
+ if (!insn.extra.splitSend)
+ data = addr;
const uint32_t elemSize = insn.extra.elem;
const GenRegister bti = ra->genReg(insn.src(2));
if (bti.file == GEN_IMMEDIATE_VALUE) {
- p->BYTE_SCATTER(src, bti, elemSize);
+ p->BYTE_SCATTER(addr, data, bti, elemSize);
} else {
const GenRegister tmp = ra->genReg(insn.dst(0));
const GenRegister btiTmp = ra->genReg(insn.dst(1));
- unsigned desc = p->generateByteScatterMessageDesc(0, elemSize);
+ unsigned desc = 0;
+ if (insn.extra.splitSend)
+ desc = p->generateByteScatterSendsMessageDesc(0, elemSize);
+ else
+ desc = p->generateByteScatterMessageDesc(0, elemSize);
unsigned jip0 = beforeMessage(insn, bti, tmp, btiTmp, desc);
@@ -2237,7 +2244,7 @@ namespace gbe
p->push();
p->curr.predicate = GEN_PREDICATE_NORMAL;
p->curr.useFlag(insn.state.flag, insn.state.subFlag);
- p->BYTE_SCATTER(src, GenRegister::addr1(0), elemSize);
+ p->BYTE_SCATTER(addr, data, GenRegister::addr1(0), elemSize);
p->pop();
afterMessage(insn, bti, tmp, btiTmp, jip0);
}
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index dc6dc63..1d721a3 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -504,6 +504,18 @@ namespace gbe
return setByteScatterMessageDesc(&insn, bti, elemSize);
}
+ unsigned GenEncoder::generateByteScatterSendsMessageDesc(unsigned bti, unsigned elemSize) {
+ GenNativeInstruction insn;
+ memset(&insn, 0, sizeof(GenNativeInstruction));
+ return setByteScatterSendsMessageDesc(&insn, bti, elemSize);
+ }
+
+ unsigned GenEncoder::setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize)
+ {
+ assert(0);
+ return 0;
+ }
+
unsigned GenEncoder::setByteScatterMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize) {
uint32_t msg_length = 0;
uint32_t response_length = 0;
@@ -524,7 +536,7 @@ namespace gbe
return insn->bits3.ud;
}
- void GenEncoder::BYTE_SCATTER(GenRegister msg, GenRegister bti, uint32_t elemSize) {
+ void GenEncoder::BYTE_SCATTER(GenRegister msg, GenRegister data, GenRegister bti, uint32_t elemSize) {
GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
this->setHeader(insn);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index e6f362b..5e69833 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -185,7 +185,7 @@ namespace gbe
/*! Byte gather (for unaligned bytes, shorts and ints) */
void BYTE_GATHER(GenRegister dst, GenRegister src, GenRegister bti, uint32_t elemSize);
/*! Byte scatter (for unaligned bytes, shorts and ints) */
- void BYTE_SCATTER(GenRegister src, GenRegister bti, uint32_t elemSize);
+ virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize);
/*! Byte gather a64 (for unaligned bytes, shorts and ints) */
virtual void BYTE_GATHERA64(GenRegister dst, GenRegister src, uint32_t elemSize);
/*! Byte scatter a64 (for unaligned bytes, shorts and ints) */
@@ -263,6 +263,7 @@ namespace gbe
virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
unsigned setByteGatherMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
unsigned setByteScatterMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
+ virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
unsigned generateAtomicMessageDesc(unsigned function, unsigned bti, unsigned srcNum);
unsigned generateUntypedReadMessageDesc(unsigned bti, unsigned elemNum);
@@ -270,6 +271,7 @@ namespace gbe
unsigned generateUntypedWriteSendsMessageDesc(unsigned bti, unsigned elemNum);
unsigned generateByteGatherMessageDesc(unsigned bti, unsigned elemSize);
unsigned generateByteScatterMessageDesc(unsigned bti, unsigned elemSize);
+ unsigned generateByteScatterSendsMessageDesc(unsigned bti, unsigned elemSize);
virtual void setHeader(GenNativeInstruction *insn) = 0;
virtual void setDst(GenNativeInstruction *insn, GenRegister dest) = 0;
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index ea385ac..9722423 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1789,7 +1789,6 @@ namespace gbe
GenRegister bti, vector<GenRegister> temps) {
unsigned dstNum = temps.size();
SelectionInstruction *insn = this->appendInsn(SEL_OP_BYTE_SCATTER, dstNum, 3);
- SelectionVector *vector = this->appendVector();
if (bti.file != GEN_IMMEDIATE_VALUE) {
insn->state.flag = 0;
@@ -1806,11 +1805,26 @@ namespace gbe
insn->src(2) = bti;
insn->extra.elem = elemSize;
- // value and address are contiguous in the send
- vector->regNum = 2;
- vector->isSrc = 1;
- vector->offsetID = 0;
- vector->reg = &insn->src(0);
+ if (hasSends()) {
+ insn->extra.splitSend = 1;
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 1;
+ vector->isSrc = 1;
+ vector->offsetID = 0;
+ vector->reg = &insn->src(0);
+
+ vector = this->appendVector();
+ vector->regNum = 1;
+ vector->isSrc = 1;
+ vector->offsetID = 1;
+ vector->reg = &insn->src(1);
+ } else {
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 2;
+ vector->isSrc = 1;
+ vector->offsetID = 0;
+ vector->reg = &insn->src(0);
+ }
}
void Selection::Opaque::BYTE_GATHERA64(Reg dst, Reg addr, uint32_t elemSize) {
--
1.9.1
More information about the Beignet
mailing list