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>
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. */
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;
}
}
ALU2_BRA(IF)
ALU2_BRA(ELSE)
ALU2_BRA(ENDIF)
+ ALU2_BRA(WHILE)
ALU2_BRA(BRD)
ALU2_BRA(BRC)
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));
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 */
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);
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 */
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;
} 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;
DECL_SELECTION_IR(ENDIF, UnaryInstruction)
DECL_SELECTION_IR(ELSE, UnaryInstruction)
DECL_SELECTION_IR(READ_ARF, UnaryInstruction)
+DECL_SELECTION_IR(WHILE, UnaryInstruction)
{
Node* p = new SelfLoopNode(node);
- p->canBeHandled = false;
+ p->canBeHandled = true;
return insertNode(p);
}