[Beignet] [PATCH 5/7] HSW: correct jump distance of hsw's jmpi.
junyan.he at inbox.com
junyan.he at inbox.com
Tue Apr 15 17:56:20 PDT 2014
From: Junyan He <junyan.he at linux.intel.com>
Gen5+ bspec: the jump distance is in number of eight-byte units.
Gen7.5+: the offset is in unit of 8bits for JMPI, 64bits for other flow control instructions.
So need multiple all jump distance with 8 in jmpi.
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/backend/gen75_context.cpp | 9 +++++++++
backend/src/backend/gen75_context.hpp | 2 ++
backend/src/backend/gen75_encoder.cpp | 34 +++++++++++++++++++++++++++++++++
backend/src/backend/gen75_encoder.hpp | 1 +
backend/src/backend/gen_context.cpp | 8 ++++----
backend/src/backend/gen_encoder.hpp | 2 +-
6 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/backend/src/backend/gen75_context.cpp b/backend/src/backend/gen75_context.cpp
index e101815..ba2468c 100644
--- a/backend/src/backend/gen75_context.cpp
+++ b/backend/src/backend/gen75_context.cpp
@@ -25,6 +25,15 @@
namespace gbe
{
+ void Gen75Context::patchBranches(void) {
+ using namespace ir;
+ for (auto pair : branchPos2) {
+ const LabelIndex label = pair.first;
+ const int32_t insnID = pair.second;
+ const int32_t targetID = labelPos.find(label)->second;
+ p->patchJMPI(insnID, (targetID-insnID-1) * 16);
+ }
+ }
}
diff --git a/backend/src/backend/gen75_context.hpp b/backend/src/backend/gen75_context.hpp
index 1f7ec76..201bafc 100644
--- a/backend/src/backend/gen75_context.hpp
+++ b/backend/src/backend/gen75_context.hpp
@@ -36,6 +36,8 @@ namespace gbe
: GenContext(unit, name, limitRegisterPressure, 16, false) {
this->p = GBE_NEW(Gen75Encoder, simdWidth, 75);
};
+
+ virtual void patchBranches(void);
};
}
#endif /* __GBE_GEN75_CONTEXT_HPP__ */
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index dabe599..bb6d622 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -62,4 +62,38 @@ namespace gbe
insn->bits3.gen7_typed_rw.slot = 1;
}
+ void Gen75Encoder::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);
+ if ( jumpDistance > -32769 && jumpDistance < 32768 ) {
+ 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.
+ // A little hacky as we need to change the nop instruction to add
+ // instruction manually.
+ // If this is a unconditional jump, we just need to add the IP directly.
+ // FIXME there is an optimization method which we can insert a
+ // ADD instruction on demand. But that will need some extra analysis
+ // for all the branching instruction. And need to adjust the distance
+ // for those branch instruction's start point and end point contains
+ // this instruction.
+ insn.header.opcode = GEN_OPCODE_ADD;
+ this->setDst(&insn, GenRegister::ip());
+ this->setSrc0(&insn, GenRegister::ip());
+ this->setSrc1(&insn, GenRegister::immd((jumpDistance + 16)));
+ } else {
+ insn.header.predicate_inverse ^= 1;
+ this->setSrc1(&insn, GenRegister::immd(16));
+ GenInstruction &insn2 = this->store[insnID+1];
+ GBE_ASSERT(insn2.header.opcode == GEN_OPCODE_NOP);
+ GBE_ASSERT(insnID < this->store.size());
+ insn2.header.predicate_control = GEN_PREDICATE_NONE;
+ insn2.header.opcode = GEN_OPCODE_ADD;
+ this->setDst(&insn2, GenRegister::ip());
+ this->setSrc0(&insn2, GenRegister::ip());
+ this->setSrc1(&insn2, GenRegister::immd(jumpDistance));
+ }
+ }
} /* End of the name space. */
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 57e9060..bdd294a 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -37,6 +37,7 @@ namespace gbe
virtual void setTypedWriteMessage(GenInstruction *insn, unsigned char bti,
unsigned char msg_type, uint32_t msg_length,
bool header_present);
+ virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
};
}
#endif /* __GBE_GEN75_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 3faed98..75e0777 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -88,7 +88,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-1) * 2);
+ p->patchJMPI(insnID, (targetID-insnID-1) * jump_width);
}
}
@@ -932,7 +932,7 @@ namespace gbe
p->SHL(high, low, tmp);
p->MOV(low, GenRegister::immud(0));
- p->patchJMPI(jip1, (p->n_instruction() - (jip1 + 1)) * 2);
+ p->patchJMPI(jip1, (p->n_instruction() - (jip1 + 1)) * jump_width);
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;
@@ -946,7 +946,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 + 1)) * 2);
+ p->patchJMPI(jip0, (p->n_instruction() - (jip0 + 1)) * jump_width);
p->pop();
@@ -1461,7 +1461,7 @@ namespace gbe
p->curr.predicate = GEN_PREDICATE_ALIGN1_ANY16H;
else
NOT_IMPLEMENTED;
- int jip = -(int)(p->n_instruction() - loop_start + 1) * 2;
+ int jip = -(int)(p->n_instruction() - loop_start + 1) * jump_width;
p->JMPI(zero);
p->patchJMPI(p->n_instruction()-2, jip);
p->pop();
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index a323d94..cd3dfdd 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -185,7 +185,7 @@ namespace gbe
void MATH(GenRegister dst, uint32_t function, GenRegister src);
/*! Patch JMPI (located at index insnID) with the given jump distance */
- void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+ virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
////////////////////////////////////////////////////////////////////////
// Helper functions to encode
--
1.7.9.5
More information about the Beignet
mailing list