diff options
author | Luo Xionghu <xionghu.luo@intel.com> | 2014-09-15 08:23:39 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-09-26 12:56:53 +0800 |
commit | dacf84d681491f3300a5c2ab97e51b26c973878f (patch) | |
tree | 57ce4c3d778165d9b2cb4e331db077187e40872e | |
parent | d71b2c2131767ccdce44b6cc555d041ff9354651 (diff) |
Use instruction WHILE to manipulate structure.
1. WHILE instruction should be non-schedulable.
2. if this WHILE instruction jumps to an ELSE instruction, the distance
need add 2.
v2:
We also need to take care of HSW for while instruction.
Signed-off-by: Luo Xionghu <xionghu.luo@intel.com>
Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
-rw-r--r-- | backend/src/backend/gen75_encoder.cpp | 22 | ||||
-rw-r--r-- | backend/src/backend/gen_context.cpp | 10 | ||||
-rw-r--r-- | backend/src/backend/gen_encoder.cpp | 11 | ||||
-rw-r--r-- | backend/src/backend/gen_encoder.hpp | 2 | ||||
-rw-r--r-- | backend/src/backend/gen_insn_scheduling.cpp | 2 | ||||
-rw-r--r-- | backend/src/backend/gen_insn_selection.cpp | 20 | ||||
-rw-r--r-- | backend/src/backend/gen_insn_selection.hxx | 1 | ||||
-rw-r--r-- | backend/src/ir/structural_analysis.cpp | 2 |
8 files changed, 61 insertions, 9 deletions
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp index 321e07b..724865b 100644 --- a/backend/src/backend/gen75_encoder.cpp +++ b/backend/src/backend/gen75_encoder.cpp @@ -254,17 +254,25 @@ 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_IF) { - this->setSrc1(&insn, GenRegister::immd(jumpDistance)); - return; + 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]; + if(insn_else.header.opcode == GEN_OPCODE_ELSE){ + jumpDistance += 2; + } } - 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 + + if (insn.header.opcode != GEN_OPCODE_JMPI) + this->setSrc1(&insn, GenRegister::immd(jumpDistance)); + else { + //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)); } - - this->setSrc1(&insn, GenRegister::immd(jumpDistance)); + return; } } /* End of the name space. */ diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index 175878d..8844233 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -255,6 +255,16 @@ namespace gbe p->ELSE(src); } break; + case SEL_OP_WHILE: + { + /*const ir::LabelIndex label0(insn.index), label1(insn.index1); + const LabelPair labelPair(label0, label1); + const GenRegister src = ra->genReg(insn.src(0)); + this->branchPos3.push_back(std::make_pair(labelPair, p->store.size()));*/ + insertJumpPos(insn); + p->WHILE(src); + } + break; default: NOT_IMPLEMENTED; } } diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index c67e85e..295e11d 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -1026,6 +1026,7 @@ namespace gbe ALU2_BRA(IF) ALU2_BRA(ELSE) ALU2_BRA(ENDIF) + ALU2_BRA(WHILE) ALU2_BRA(BRD) ALU2_BRA(BRC) @@ -1037,8 +1038,18 @@ 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+jumpDistance]; + if(insn_else.header.opcode == GEN_OPCODE_ELSE){ + jumpDistance += 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)); diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp index 9844eb8..2c999ce 100644 --- a/backend/src/backend/gen_encoder.hpp +++ b/backend/src/backend/gen_encoder.hpp @@ -154,6 +154,8 @@ namespace gbe void ELSE(GenRegister src); /*! ENDIF indexed instruction */ void ENDIF(GenRegister src); + /*! WHILE indexed instruction */ + void WHILE(GenRegister src); /*! BRC indexed instruction */ void BRC(GenRegister src); /*! BRD indexed instruction */ diff --git a/backend/src/backend/gen_insn_scheduling.cpp b/backend/src/backend/gen_insn_scheduling.cpp index ead3e26..58ab69f 100644 --- a/backend/src/backend/gen_insn_scheduling.cpp +++ b/backend/src/backend/gen_insn_scheduling.cpp @@ -588,7 +588,7 @@ namespace gbe for (int32_t insnID = 0; insnID < insnNum; ++insnID) { ScheduleDAGNode *node = tracker.insnNodes[insnID]; if (node->insn.isBranch() || node->insn.isLabel() - || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF + || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF || node->insn.opcode == SEL_OP_WHILE || node->insn.opcode == SEL_OP_READ_ARF || node->insn.opcode == SEL_OP_BARRIER) tracker.makeBarrier(insnID, insnNum); diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index f284ae1..e3ee35d 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -544,6 +544,8 @@ namespace gbe void ELSE(Reg src, ir::LabelIndex jip, ir::LabelIndex elseLabel); /*! ENDIF indexed instruction */ void ENDIF(Reg src, ir::LabelIndex jip, ir::LabelIndex endifLabel = ir::LabelIndex(0)); + /*! WHILE indexed instruction */ + void WHILE(Reg src, ir::LabelIndex jip); /*! BRD indexed instruction */ void BRD(Reg src, ir::LabelIndex jip); /*! BRC indexed instruction */ @@ -1063,6 +1065,12 @@ namespace gbe insn->index = uint16_t(this->block->endifLabel); } + void Selection::Opaque::WHILE(Reg src, ir::LabelIndex jip) { + SelectionInstruction *insn = this->appendInsn(SEL_OP_WHILE, 0, 1); + insn->src(0) = src; + insn->index = uint16_t(jip); + } + void Selection::Opaque::CMP(uint32_t conditional, Reg src0, Reg src1, Reg dst) { SelectionInstruction *insn = this->appendInsn(SEL_OP_CMP, 1, 2); insn->src(0) = src0; @@ -4217,6 +4225,18 @@ namespace gbe } else if(opcode == OP_ELSE) { const LabelIndex label = insn.getLabelIndex(); sel.ELSE(GenRegister::immd(0), label, insn.getParent()->thisElseLabel); + } else if(opcode == OP_WHILE) { + const Register pred = insn.getPredicateIndex(); + const LabelIndex jip = insn.getLabelIndex(); + sel.push(); + sel.curr.physicalFlag = 0; + sel.curr.flagIndex = (uint64_t)pred; + sel.curr.externFlag = 1; + sel.curr.inversePredicate = insn.getInversePredicated(); + sel.curr.predicate = GEN_PREDICATE_NORMAL; + sel.WHILE(GenRegister::immd(0), jip); + sel.curr.inversePredicate = 0; + sel.pop(); } else NOT_IMPLEMENTED; diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx index 048a844..7511b84 100644 --- a/backend/src/backend/gen_insn_selection.hxx +++ b/backend/src/backend/gen_insn_selection.hxx @@ -86,3 +86,4 @@ DECL_SELECTION_IR(IF, UnaryInstruction) DECL_SELECTION_IR(ENDIF, UnaryInstruction) DECL_SELECTION_IR(ELSE, UnaryInstruction) DECL_SELECTION_IR(READ_ARF, UnaryInstruction) +DECL_SELECTION_IR(WHILE, UnaryInstruction) diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp index 1860ee9..040a7e0 100644 --- a/backend/src/ir/structural_analysis.cpp +++ b/backend/src/ir/structural_analysis.cpp @@ -867,7 +867,7 @@ namespace analysis { Node* p = new SelfLoopNode(node); - p->canBeHandled = false; + p->canBeHandled = true; return insertNode(p); } |