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.y...@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 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet