From: Junyan He <[email protected]> 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 <[email protected]> Signed-off-by: Junyan He <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
