[Beignet] [PATCH 1/3] BDW: Pass Jip and Uip when patchJMPI.
Yang Rong
rong.r.yang at intel.com
Sun Sep 28 22:38:10 PDT 2014
Do not like GEN7, BDW's Jip is in bits4 and Uip is in bits3, so should set Jip
and Uip independently.
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
backend/src/backend/gen75_encoder.cpp | 14 ++++++--------
backend/src/backend/gen75_encoder.hpp | 2 +-
backend/src/backend/gen8_encoder.cpp | 24 ++++++++++++++++++++----
backend/src/backend/gen8_encoder.hpp | 2 +-
backend/src/backend/gen_context.cpp | 10 +++++-----
backend/src/backend/gen_encoder.cpp | 31 ++++++++++++++-----------------
backend/src/backend/gen_encoder.hpp | 2 +-
7 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index dcb0ab2..10a9b5c 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -250,7 +250,7 @@ namespace gbe
alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
}
- void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+ void Gen75Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
GBE_ASSERT(insnID < this->store.size());
GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -264,19 +264,17 @@ namespace gbe
if( insn.header.opcode == GEN_OPCODE_WHILE ){
// if this WHILE instruction jump back to an ELSE instruction,
// need add distance to go to the next instruction.
- GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance];
+ GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
if(insn_else.header.opcode == GEN_OPCODE_ELSE){
- jumpDistance += 2;
+ jip += 2;
}
}
- if (insn.header.opcode != GEN_OPCODE_JMPI)
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
- else {
+ if (insn.header.opcode == GEN_OPCODE_JMPI) {
//jumpDistance'unit is Qword, and the HSW's JMPI offset of jmpi is in byte, so multi 8
- jumpDistance = (jumpDistance - 2) * 8;
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ jip = (jip - 2) * 8;
}
+ this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
return;
}
} /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 5490450..f601d61 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -43,7 +43,7 @@ namespace gbe
/*! Jump indexed instruction */
virtual void JMPI(GenRegister src, bool longjmp = false);
/*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
- virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+ virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
/*! Get double/long exec width */
virtual int getDoubleExecWidth(void) { return GEN75_DOUBLE_EXEC_WIDTH; }
virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
index 6105634..f50ce47 100644
--- a/backend/src/backend/gen8_encoder.cpp
+++ b/backend/src/backend/gen8_encoder.cpp
@@ -250,7 +250,7 @@ namespace gbe
alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
}
- void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+ void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
GBE_ASSERT(insnID < this->store.size());
GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -258,18 +258,34 @@ namespace gbe
insn.header.opcode == GEN_OPCODE_ENDIF ||
insn.header.opcode == GEN_OPCODE_IF ||
insn.header.opcode == GEN_OPCODE_BRC ||
+ insn.header.opcode == GEN_OPCODE_WHILE ||
insn.header.opcode == GEN_OPCODE_ELSE);
+ if( insn.header.opcode == GEN_OPCODE_WHILE ) {
+ // if this WHILE instruction jump back to an ELSE instruction,
+ // need add distance to go to the next instruction.
+ GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
+ if(insn_else.header.opcode == GEN_OPCODE_ELSE) {
+ jip += 2;
+ }
+ }
+
+ if(insn.header.opcode == GEN_OPCODE_ELSE)
+ uip = jip;
+
if (insn.header.opcode == GEN_OPCODE_IF) {
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ Gen8NativeInstruction *gen8_insn = &insn.gen8_insn;
+ this->setSrc0(&insn, GenRegister::immud(0));
+ gen8_insn->bits2.gen8_branch.uip = uip*8;
+ gen8_insn->bits3.gen8_branch.jip = jip*8;
return;
}
else if (insn.header.opcode == GEN_OPCODE_JMPI) {
//jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
- jumpDistance = (jumpDistance - 2) * 8;
+ jip = (jip - 2);
}
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ this->setSrc1(&insn, GenRegister::immd(jip*8));
}
void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
diff --git a/backend/src/backend/gen8_encoder.hpp b/backend/src/backend/gen8_encoder.hpp
index e962875..6ca3b41 100644
--- a/backend/src/backend/gen8_encoder.hpp
+++ b/backend/src/backend/gen8_encoder.hpp
@@ -41,7 +41,7 @@ namespace gbe
/*! Jump indexed instruction */
virtual void JMPI(GenRegister src, bool longjmp = false);
/*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
- virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+ virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
/*! Get double/long exec width */
virtual int getDoubleExecWidth(void) { return GEN8_DOUBLE_EXEC_WIDTH; }
virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 78f21ad..1d0cf10 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -115,7 +115,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));
+ p->patchJMPI(insnID, (targetID - insnID), 0);
}
for (auto pair : branchPos3) {
const LabelPair labelPair = pair.first;
@@ -128,7 +128,7 @@ namespace gbe
errCode = OUT_OF_RANGE_IF_ENDIF;
return false;
}
- p->patchJMPI(insnID, ((uip - insnID) << 16) | (0x0000ffff & (jip - insnID)));
+ p->patchJMPI(insnID, jip - insnID, uip - insnID);
}
return true;
}
@@ -928,7 +928,7 @@ namespace gbe
p->SHL(high, low, tmp);
p->MOV(low, GenRegister::immud(0));
- p->patchJMPI(jip1, (p->n_instruction() - jip1) );
+ p->patchJMPI(jip1, (p->n_instruction() - jip1), 0);
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;
@@ -942,7 +942,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));
+ p->patchJMPI(jip0, (p->n_instruction() - jip0), 0);
p->pop();
@@ -1427,7 +1427,7 @@ namespace gbe
p->curr.noMask = 1;
jip0 = p->n_instruction();
p->JMPI(zero);
- p->patchJMPI(jip0, distance);
+ p->patchJMPI(jip0, distance, 0);
p->pop();
// end of loop
}
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 9b84d5b..6bb6226 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -820,7 +820,7 @@ namespace gbe
ALU2_BRA(BRD)
ALU2_BRA(BRC)
- void GenEncoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+ void GenEncoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
GBE_ASSERT(insnID < this->store.size());
GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
@@ -834,24 +834,21 @@ namespace gbe
if( insn.header.opcode == GEN_OPCODE_WHILE ){
// if this WHILE instruction jump back to an ELSE instruction,
// need add distance to go to the next instruction.
- GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance];
+ GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
if(insn_else.header.opcode == GEN_OPCODE_ELSE){
- jumpDistance += 2;
+ jip += 2;
}
}
- if (insn.header.opcode != GEN_OPCODE_JMPI || (jumpDistance > -32769 && jumpDistance < 32768)) {
- if (insn.header.opcode == GEN_OPCODE_IF) {
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
- return;
- }
- else if (insn.header.opcode == GEN_OPCODE_JMPI){
- jumpDistance = jumpDistance - 2;
- }
- else if(insn.header.opcode == GEN_OPCODE_ENDIF)
- jumpDistance += 2;
-
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ if (insn.header.opcode != GEN_OPCODE_JMPI || (jip > -32769 && jip < 32768)) {
+ if (insn.header.opcode == GEN_OPCODE_IF) {
+ this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
+ return;
+ } else if (insn.header.opcode == GEN_OPCODE_JMPI) {
+ jip = jip - 2;
+ } else if(insn.header.opcode == GEN_OPCODE_ENDIF)
+ jip += 2;
+ this->setSrc1(&insn, GenRegister::immd((jip & 0xffff) | uip<<16));
} 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.
@@ -867,7 +864,7 @@ namespace gbe
insn.header.opcode = GEN_OPCODE_ADD;
this->setDst(&insn, GenRegister::ip());
this->setSrc0(&insn, GenRegister::ip());
- this->setSrc1(&insn, GenRegister::immd(jumpDistance * 8));
+ this->setSrc1(&insn, GenRegister::immd(jip * 8));
} else {
GenNativeInstruction &insn2 = *(GenNativeInstruction *)&this->store[insnID+2];
insn.header.predicate_inverse ^= 1;
@@ -878,7 +875,7 @@ namespace gbe
insn2.header.opcode = GEN_OPCODE_ADD;
this->setDst(&insn2, GenRegister::ip());
this->setSrc0(&insn2, GenRegister::ip());
- this->setSrc1(&insn2, GenRegister::immd((jumpDistance - 2) * 8));
+ this->setSrc1(&insn2, GenRegister::immd((jip - 2) * 8));
}
}
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index c8dc113..0b6154d 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -207,7 +207,7 @@ namespace gbe
void MATH(GenRegister dst, uint32_t function, GenRegister src);
/*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
- virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+ virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
////////////////////////////////////////////////////////////////////////
// Helper functions to encode
--
1.8.3.2
More information about the Beignet
mailing list