}
}
- void GenContext::emitFenceInstruction(const ir::FenceInstruction &insn) {}
+ void GenContext::emitFenceInstruction(const ir::FenceInstruction &insn) {
+ NOT_IMPLEMENTED;
+ }
+
void GenContext::emitLabelInstruction(const ir::LabelInstruction &insn) {
using namespace ir;
const LabelIndex label = insn.getLabelIndex();
});
}
+ void GenContext::emitInstructionStream2(void) {
+ // Emit Gen ISA
+ sel->foreachInstruction([&](const SelectionInstruction &insn) {
+ const uint32_t opcode = insn.opcode;
+ switch (opcode) {
+#define DECL_SELECTION_IR(OPCODE, FAMILY) \
+ case SEL_OP_##OPCODE: this->emit##FAMILY(insn); break;
+#include "backend/gen_insn_selection.hxx"
+#undef DECL_INSN
+ }
+ });
+ }
+
void GenContext::patchBranches(void) {
using namespace ir;
for (auto pair : branchPos) {
}
}
+ void GenContext::patchBranches2(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) * 2);
+ }
+ }
+
///////////////////// XXX ///////////////////////
void GenContext::emitLabelInstruction(const SelectionInstruction &insn) {
const ir::LabelIndex label(insn.index);
this->labelPos.insert(std::make_pair(label, p->insnNum));
}
+ /*! XXX Make both structures the same! */
+ INLINE void setInstructionState(GenInstructionState &dst,
+ const SelectionState &src)
+ {
+ dst.execWidth = src.execWidth;
+ dst.quarterControl = src.quarterControl;
+ dst.noMask = src.noMask;
+ dst.flag = src.flag;
+ dst.subFlag = src.subFlag;
+ dst.predicate = src.predicate;
+ dst.inversePredicate = src.inversePredicate;
+ }
+
void GenContext::emitUnaryInstruction(const SelectionInstruction &insn) {
+ const GenReg dst = ra->genReg(insn.dst[0]);
+ const GenReg src = ra->genReg(insn.src[0]);
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ switch (insn.opcode) {
+ case SEL_OP_MOV: p->MOV(dst, src); break;
+ default: NOT_IMPLEMENTED;
+ }
+ p->pop();
+ }
+
+ void GenContext::emitBinaryInstruction(const SelectionInstruction &insn) {
+ const GenReg dst = ra->genReg(insn.dst[0]);
+ const GenReg src0 = ra->genReg(insn.src[0]);
+ const GenReg src1 = ra->genReg(insn.src[1]);
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ switch (insn.opcode) {
+ case SEL_OP_AND: p->AND(dst, src0, src1); break;
+ case SEL_OP_OR: p->OR(dst, src0, src1); break;
+ case SEL_OP_XOR: p->XOR(dst, src0, src1); break;
+ case SEL_OP_SHR: p->SHR(dst, src0, src1); break;
+ case SEL_OP_SHL: p->SHL(dst, src0, src1); break;
+ case SEL_OP_RSR: p->RSR(dst, src0, src1); break;
+ case SEL_OP_RSL: p->RSL(dst, src0, src1); break;
+ case SEL_OP_ASR: p->ASR(dst, src0, src1); break;
+ case SEL_OP_ADD: p->ADD(dst, src0, src1); break;
+ case SEL_OP_MUL: p->MUL(dst, src0, src1); break;
+ case SEL_OP_MACH: p->MACH(dst, src0, src1); break;
+ default: NOT_IMPLEMENTED;
+ }
+ p->pop();
+ }
+ void GenContext::emitSelectInstruction(const SelectionInstruction &insn) {
+ NOT_IMPLEMENTED;
}
- void GenContext::emitBinaryInstruction(const SelectionInstruction &insn){}
- void GenContext::emitSelectInstruction(const SelectionInstruction &insn){}
- void GenContext::emitCompareInstruction(const SelectionInstruction &insn){}
- void GenContext::emitJumpInstruction(const SelectionInstruction &insn){}
- void GenContext::emitEotInstruction(const SelectionInstruction &insn){}
- void GenContext::emitNoOpInstruction(const SelectionInstruction &insn){}
- void GenContext::emitWaitInstruction(const SelectionInstruction &insn){}
- void GenContext::emitMathInstruction(const SelectionInstruction &insn){}
- void GenContext::emitUntypedReadInstruction(const SelectionInstruction &insn){}
- void GenContext::emitUntypedWriteInstruction(const SelectionInstruction &insn){}
- void GenContext::emitByteGatherInstruction(const SelectionInstruction &insn){}
- void GenContext::emitByteScatterInstruction(const SelectionInstruction &insn){}
+ void GenContext::emitNoOpInstruction(const SelectionInstruction &insn) {
+ NOT_IMPLEMENTED;
+ }
+
+ void GenContext::emitWaitInstruction(const SelectionInstruction &insn) {
+ NOT_IMPLEMENTED;
+ }
+
+ void GenContext::emitMathInstruction(const SelectionInstruction &insn) {
+ NOT_IMPLEMENTED;
+ }
+
+ void GenContext::emitCompareInstruction(const SelectionInstruction &insn) {
+ const GenReg src0 = ra->genReg(insn.src[0]);
+ const GenReg src1 = ra->genReg(insn.src[1]);
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->CMP(insn.function, src0, src1);
+ p->pop();
+ }
+
+ void GenContext::emitJumpInstruction(const SelectionInstruction &insn) {
+ const ir::LabelIndex label(insn.index);
+ const GenReg src = ra->genReg(insn.src[0]);
+ this->branchPos2.push_back(std::make_pair(label, p->insnNum));
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->JMPI(src);
+ p->pop();
+ }
+
+ void GenContext::emitEotInstruction(const SelectionInstruction &insn) {
+ p->push();
+ p->curr.predicate = GEN_PREDICATE_NONE;
+ p->curr.execWidth = 8;
+ p->curr.noMask = 1;
+ p->MOV(GenReg::f8grf(127,0), GenReg::f8grf(0,0));
+ p->EOT(127);
+ p->pop();
+ }
+
+ void GenContext::emitUntypedReadInstruction(const SelectionInstruction &insn) {
+ const GenReg dst = ra->genReg(insn.dst[0]);
+ const GenReg src = ra->genReg(insn.src[0]);
+ const uint32_t bti = insn.function;
+ const uint32_t elemNum = insn.elem;
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->UNTYPED_READ(dst, src, bti, elemNum);
+ p->pop();
+ }
+
+ void GenContext::emitUntypedWriteInstruction(const SelectionInstruction &insn) {
+ const GenReg src = ra->genReg(insn.src[0]);
+ const uint32_t bti = insn.function;
+ const uint32_t elemNum = insn.elem;
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->UNTYPED_WRITE(src, bti, elemNum);
+ p->pop();
+ }
+
+ void GenContext::emitByteGatherInstruction(const SelectionInstruction &insn) {
+ const GenReg dst = ra->genReg(insn.dst[0]);
+ const GenReg src = ra->genReg(insn.src[0]);
+ const uint32_t bti = insn.function;
+ const uint32_t elemSize = insn.elem;
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->BYTE_GATHER(dst, src, bti, elemSize);
+ p->pop();
+ }
+
+ void GenContext::emitByteScatterInstruction(const SelectionInstruction &insn) {
+ const GenReg src = ra->genReg(insn.src[0]);
+ const uint32_t bti = insn.function;
+ const uint32_t elemSize = insn.elem;
+ p->push();
+ setInstructionState(p->curr, insn.state);
+ p->BYTE_SCATTER(src, bti, elemSize);
+ p->pop();
+ }
BVAR(OCL_OUTPUT_ASM, false);
void GenContext::emitCode(void) {
class GenEmitter; // Helps emitting Gen ISA
class GenRegAllocator; // Handle the register allocation
class Selection; // Performs instruction selection
- class SelectionInstruction; // Pre-RA GEN instruction
+ class SelectionInstruction; // Pre-RA Gen instruction
+ class SelectionReg; // Pre-RA Gen register
/*! Context is the helper structure to build the Gen ISA or simulation code
* from GenIR
void emitStackPointer(void);
/*! Emit the instructions */
void emitInstructionStream(void);
+ /*! Emit the instructions */
+ void emitInstructionStream2(void);
/*! Set the correct target values for the branches */
void patchBranches(void);
+ /*! Set the correct target values for the branches */
+ void patchBranches2(void);
/*! Bool registers will use scalar words. So we will consider them as
* scalars in Gen backend
*/
INLINE bool isSpecialReg(ir::Register reg) const {
return fn.isSpecialReg(reg);
}
- /*! Build the final physical register */
- GenReg getGenReg(ir::Register reg, const SelectionReg &selReg) const;
/*! Emit instruction per family */
void emitUnaryInstruction(const ir::UnaryInstruction &insn);
/*! Implements base class */
virtual Kernel *allocateKernel(void);
- /*! Simplistic allocation to start with */
- // map<ir::Register, GenReg> RA;
/*! Store the position of each label instruction in the Gen ISA stream */
map<ir::LabelIndex, uint32_t> labelPos;
/*! Store the position of each branch instruction in the Gen ISA stream */
map<const ir::Instruction*, uint32_t> branchPos;
+ /*! Store the Gen instructions to patch */
+ vector<std::pair<ir::LabelIndex, uint32_t>> branchPos2;
/*! Encode Gen ISA */
GenEmitter *p;
/*! Instruction selection on Gen ISA (pre-register allocation) */