[Beignet] [PATCH] Backend: Refine ConvertInstruction logic in insn_selection
Yang, Rong R
rong.r.yang at intel.com
Sun Oct 18 22:36:45 PDT 2015
LGTM, pushed, thanks.
> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> He Junyan
> Sent: Wednesday, October 14, 2015 14:49
> To: beignet at lists.freedesktop.org
> Subject: Re: [Beignet] [PATCH] Backend: Refine ConvertInstruction logic in
> insn_selection
>
> Ping for review.
>
> On Tue, Sep 22, 2015 at 06:29:23PM +0800, junyan.he at inbox.com wrote:
> > Date: Tue, 22 Sep 2015 18:29:23 +0800
> > From: junyan.he at inbox.com
> > To: beignet at lists.freedesktop.org
> > Subject: [Beignet] [PATCH] Backend: Refine ConvertInstruction logic in
> > insn_selection
> > X-Mailer: git-send-email 1.7.9.5
> >
> > From: Junyan He <junyan.he at linux.intel.com>
> >
> > The ConvertInstruction now need to handle a lot of special cases
> > instead of simple MOV. The judgement of native long support, half
> > support and reg restriction of long type and the situation very
> > complicated. The current code logic is too verbose and hard to read.
> > We now use sub routine functions to make it clear and readable.
> >
> > Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> > ---
> > backend/src/backend/gen_insn_selection.cpp | 780
> > +++++++++++++++++-----------
> > 1 file changed, 475 insertions(+), 305 deletions(-)
> >
> > diff --git a/backend/src/backend/gen_insn_selection.cpp
> > b/backend/src/backend/gen_insn_selection.cpp
> > index ab00269..4800f7f 100644
> > --- a/backend/src/backend/gen_insn_selection.cpp
> > +++ b/backend/src/backend/gen_insn_selection.cpp
> > @@ -4124,148 +4124,132 @@ namespace gbe
> > return false;
> > }
> >
> > - INLINE bool emitOne(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + INLINE void convertBetweenHalfFloat(Selection::Opaque &sel, const
> > + ir::ConvertInstruction &insn, bool &markChildren) const
> > {
> > using namespace ir;
> > const Type dstType = insn.getDstType();
> > const Type srcType = insn.getSrcType();
> > - const RegisterFamily dstFamily = getFamily(dstType);
> > - const RegisterFamily srcFamily = getFamily(srcType);
> > const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > const Opcode opcode = insn.getOpcode();
> > - sel.push();
> > - if (sel.isScalarReg(insn.getDst(0)) == true) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - if(opcode == ir::OP_SAT_CVT)
> > - sel.curr.saturate = 1;
> >
> > - // We need two instructions to make the conversion
> > if (opcode == OP_F16TO32) {
> > sel.F16TO32(dst, src);
> > } else if (opcode == OP_F32TO16) {
> > + // We need two instructions to make the conversion
> > GenRegister unpacked;
> > unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.F32TO16(unpacked, src);
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + sel.F32TO16(unpacked, src);
> > sel.pop();
> > sel.MOV(dst, unpacked);
> > - } else if (dstFamily != FAMILY_DWORD && dstFamily !=
> FAMILY_QWORD && srcFamily == FAMILY_DWORD) {//convert i32 to small
> int and half
> > - GenRegister unpacked;
> > - if (dstFamily == FAMILY_WORD) {
> > - uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> GEN_TYPE_W;
> > -
> > - /* The special case, when dst is half, float->word->half will lose
> accuracy. */
> > - if (dstType == TYPE_HALF) {
> > - GBE_ASSERT(sel.hasHalfType());
> > - type = GEN_TYPE_HF;
> > - }
> > + } else {
> > + GBE_ASSERT("Not conversion between float and half\n");
> > + }
> > + }
> >
> > - if (!sel.isScalarReg(dst.reg())) {
> > - unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, type);
> > - } else
> > - unpacked = GenRegister::retype(sel.unpacked_uw(dst.reg()), type);
> > - } else {
> > - const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> GEN_TYPE_B;
> > - if (!sel.isScalarReg(dst.reg())) {
> > - unpacked = sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, type);
> > - } else
> > - unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > - }
> > + INLINE void convert32bitsToSmall(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + GenRegister unpacked;
> > + const RegisterFamily dstFamily = getFamily(dstType);
> >
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.MOV(unpacked, src);
> > - sel.pop();
> > + if (dstFamily == FAMILY_WORD) {
> > + uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> > + GEN_TYPE_W;
> >
> > - if (unpacked.reg() != dst.reg())
> > - sel.MOV(dst, unpacked);
> > - } else if (dstFamily == FAMILY_WORD && srcFamily == FAMILY_QWORD)
> { //convert i64 to i16 and half.
> > + /* The special case, when dst is half, float->word->half will
> > + lose accuracy. */
> > if (dstType == TYPE_HALF) {
> > - /* There is no MOV for Long <---> Half. So Long-->Float-->half. */
> > - GBE_ASSERT(sel.hasLongType());
> > GBE_ASSERT(sel.hasHalfType());
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > + type = GEN_TYPE_HF;
> > + }
> >
> > - GenRegister funpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - funpacked = GenRegister::retype(funpacked, GEN_TYPE_F);
> > - sel.MOV(funpacked, src);
> > - GenRegister ftmp = sel.selReg(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - ftmp = GenRegister::retype(ftmp, GEN_TYPE_F);
> > - sel.MOV(ftmp, funpacked);
> > - GenRegister unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, GEN_TYPE_HF);
> > - sel.MOV(unpacked, ftmp);
> > - sel.pop();
> > - sel.MOV(dst, unpacked);
> > - } else {
> > - uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> GEN_TYPE_W;
> > + if (!sel.isScalarReg(dst.reg())) {
> > + unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, type);
> > + } else
> > + unpacked = GenRegister::retype(sel.unpacked_uw(dst.reg()), type);
> > + } else {
> > + const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> GEN_TYPE_B;
> > + if (!sel.isScalarReg(dst.reg())) {
> > + unpacked = sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, type);
> > + } else
> > + unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > + }
> >
> > - GenRegister unpacked;
> > - if (!sel.isScalarReg(dst.reg())) {
> > - if (sel.hasLongType()) {
> > - unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - } else {
> > - unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - }
> > - unpacked = GenRegister::retype(unpacked, type);
> > - } else {
> > - unpacked = GenRegister::retype(sel.unpacked_uw(dst.reg()), type);
> > - }
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + sel.MOV(unpacked, src);
> > + sel.pop();
> >
> > - if(!sel.hasLongType()) {
> > - GenRegister tmp = sel.selReg(sel.reg(FAMILY_DWORD));
> > - tmp.type = GEN_TYPE_D;
> > - sel.CONVI64_TO_I(tmp, src);
> > - sel.MOV(unpacked, tmp);
> > - } else {
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.MOV(unpacked, src);
> > - sel.pop();
> > - }
> > + if (unpacked.reg() != dst.reg())
> > + sel.MOV(dst, unpacked);
> > + }
> >
> > - if (unpacked.reg() != dst.reg()) {
> > - sel.MOV(dst, unpacked);
> > - }
> > + INLINE void convertI64To16bits(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > +
> > + if (dstType == TYPE_HALF) {
> > + /* There is no MOV for Long <---> Half. So Long-->Float-->half. */
> > + GBE_ASSERT(sel.hasLongType());
> > + GBE_ASSERT(sel.hasHalfType());
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > }
> > - } else if (dstFamily == FAMILY_BYTE && srcFamily == FAMILY_QWORD)
> { //convert i64 to i8
> > - GenRegister unpacked;
> > - const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> GEN_TYPE_B;
> >
> > - if (sel.hasLongType()) { // handle the native long logic.
> > - if (!sel.isScalarReg(dst.reg())) {
> > - /* When convert i64 to i8, the hstride should be 8, but the hstride do
> not
> > - support more than 4, so we need to split it to 2 steps. */
> > + GenRegister funpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + funpacked = GenRegister::retype(funpacked, GEN_TYPE_F);
> > + sel.MOV(funpacked, src);
> > + GenRegister ftmp = sel.selReg(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + ftmp = GenRegister::retype(ftmp, GEN_TYPE_F);
> > + sel.MOV(ftmp, funpacked);
> > + GenRegister unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, GEN_TYPE_HF);
> > + sel.MOV(unpacked, ftmp);
> > + sel.pop();
> > + sel.MOV(dst, unpacked);
> > + } else {
> > + uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> > + GEN_TYPE_W;
> > +
> > + GenRegister unpacked;
> > + if (!sel.isScalarReg(dst.reg())) {
> > + if (sel.hasLongType()) {
> > unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, dstType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > } else {
> > - unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > + unpacked = sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> > + sel.isScalarReg(insn.getSrc(0))));
> > }
> > + unpacked = GenRegister::retype(unpacked, type);
> > + } else {
> > + unpacked = GenRegister::retype(sel.unpacked_uw(dst.reg()), type);
> > + }
> >
> > + if(!sel.hasLongType()) {
> > + GenRegister tmp = sel.selReg(sel.reg(FAMILY_DWORD));
> > + tmp.type = GEN_TYPE_D;
> > + sel.CONVI64_TO_I(tmp, src);
> > + sel.MOV(unpacked, tmp);
> > + } else {
> > sel.push();
> > if (sel.isScalarReg(insn.getSrc(0))) {
> > sel.curr.execWidth = 1;
> > @@ -4274,229 +4258,263 @@ namespace gbe
> > }
> > sel.MOV(unpacked, src);
> > sel.pop();
> > + }
> >
> > - if (unpacked.reg() != dst.reg()) {
> > - sel.MOV(dst, unpacked);
> > - }
> > - } else { // Do not have native long
> > - if (!sel.isScalarReg(dst.reg())) {
> > - unpacked = sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, type);
> > - } else {
> > - unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > - }
> > + if (unpacked.reg() != dst.reg()) {
> > + sel.MOV(dst, unpacked);
> > + }
> > + }
> > + }
> >
> > - GenRegister tmp = sel.selReg(sel.reg(FAMILY_DWORD));
> > - tmp.type = GEN_TYPE_D;
> > - sel.CONVI64_TO_I(tmp, src);
> > - sel.MOV(unpacked, tmp);
> > + INLINE void convertI64ToI8(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + GenRegister unpacked;
> > + const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> > + GEN_TYPE_B;
> > +
> > + if (sel.hasLongType()) { // handle the native long logic.
> > + if (!sel.isScalarReg(dst.reg())) {
> > + /* When convert i64 to i8, the hstride should be 8, but the hstride do
> not
> > + support more than 4, so we need to split it to 2 steps. */
> > + unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, dstType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > + } else {
> > + unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > + }
> >
> > - if (unpacked.reg() != dst.reg()) {
> > - sel.MOV(dst, unpacked);
> > - }
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > }
> > - } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) &&
> > - (srcType == ir::TYPE_U64 || srcType == ir::TYPE_S64)) {// Convert
> i64 to i32
> > - if (sel.hasLongType()) {
> > - GenRegister unpacked;
> > - const uint32_t type = dstType == TYPE_U32 ? GEN_TYPE_UD :
> GEN_TYPE_D;
> > - if (!sel.isScalarReg(dst.reg())) {
> > - unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, dstType == TYPE_U32 ?
> GEN_TYPE_UD : GEN_TYPE_D);
> > - } else {
> > - unpacked = GenRegister::retype(sel.unpacked_ud(dst.reg()), type);
> > - }
> > + sel.MOV(unpacked, src);
> > + sel.pop();
> >
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.MOV(unpacked, src);
> > - sel.pop();
> > + if (unpacked.reg() != dst.reg()) {
> > + sel.MOV(dst, unpacked);
> > + }
> > + } else { // Do not have native long
> > + if (!sel.isScalarReg(dst.reg())) {
> > + unpacked = sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, type);
> > + } else {
> > + unpacked = GenRegister::retype(sel.unpacked_ub(dst.reg()), type);
> > + }
> >
> > - if (unpacked.reg() != dst.reg()) {
> > - sel.MOV(dst, unpacked);
> > - }
> > + GenRegister tmp = sel.selReg(sel.reg(FAMILY_DWORD));
> > + tmp.type = GEN_TYPE_D;
> > + sel.CONVI64_TO_I(tmp, src);
> > + sel.MOV(unpacked, tmp);
> > +
> > + if (unpacked.reg() != dst.reg()) {
> > + sel.MOV(dst, unpacked);
> > + }
> > + }
> > + }
> > +
> > + INLINE void convertI64ToI32(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + if (sel.hasLongType()) {
> > + GenRegister unpacked;
> > + const uint32_t type = dstType == TYPE_U32 ? GEN_TYPE_UD :
> GEN_TYPE_D;
> > + if (!sel.isScalarReg(dst.reg())) {
> > + unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, dstType ==
> > + TYPE_U32 ? GEN_TYPE_UD : GEN_TYPE_D);
> > } else {
> > - sel.CONVI64_TO_I(dst, src);
> > + unpacked = GenRegister::retype(sel.unpacked_ud(dst.reg()),
> > + type);
> > }
> > - } else if (dstType == ir::TYPE_FLOAT && (srcType == ir::TYPE_U64 ||
> srcType == ir::TYPE_S64)) { //i64 to float
> > - auto dag = sel.regDAG[src.reg()];
> > - // FIXME, in the future, we need to do a common I64 lower to I32
> analysis
> > - // at llvm IR layer which could cover more cases then just this one.
> > - SelectionDAG *dag0, *dag1;
> > - if (dag && dag->child[0] && dag->child[1]) {
> > - if (dag->child[0]->insn.getOpcode() == OP_LOADI) {
> > - dag0 = dag->child[1];
> > - dag1 = dag->child[0];
> > - } else {
> > - dag0 = dag->child[0];
> > - dag1 = dag->child[1];
> > - }
> > - GBE_ASSERT(!(dag->child[0]->insn.getOpcode() == OP_LOADI &&
> > - dag->child[1]->insn.getOpcode() == OP_LOADI));
> > - if (dag->insn.getOpcode() == OP_AND ||
> > - dag->insn.getOpcode() == OP_OR ||
> > - dag->insn.getOpcode() == OP_XOR) {
> > - GenRegister src0;
> > - GenRegister src1;
> > - if (lowerI64Reg(sel, dag0, src0, GEN_TYPE_UD) &&
> > - lowerI64Reg(sel, dag1, src1, GEN_TYPE_UD)) {
> > - switch (dag->insn.getOpcode()) {
> > - default:
> > - case OP_AND: sel.AND(GenRegister::retype(dst, GEN_TYPE_UD),
> src0, src1); break;
> > - case OP_OR: sel.OR(GenRegister::retype(dst, GEN_TYPE_UD),
> src0, src1); break;
> > - case OP_XOR: sel.XOR(GenRegister::retype(dst, GEN_TYPE_UD),
> src0, src1); break;
> > - }
> > - sel.MOV(dst, GenRegister::retype(dst, GEN_TYPE_UD));
> > - markChildren = false;
> > - return true;
> > +
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + sel.MOV(unpacked, src);
> > + sel.pop();
> > +
> > + if (unpacked.reg() != dst.reg()) {
> > + sel.MOV(dst, unpacked);
> > + }
> > + } else {
> > + sel.CONVI64_TO_I(dst, src);
> > + }
> > + }
> > +
> > + INLINE void convertI64ToFloat(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + auto dag = sel.regDAG[src.reg()];
> > +
> > + // FIXME, in the future, we need to do a common I64 lower to I32
> analysis
> > + // at llvm IR layer which could cover more cases then just this one.
> > + SelectionDAG *dag0, *dag1;
> > + if (dag && dag->child[0] && dag->child[1]) {
> > + if (dag->child[0]->insn.getOpcode() == OP_LOADI) {
> > + dag0 = dag->child[1];
> > + dag1 = dag->child[0];
> > + } else {
> > + dag0 = dag->child[0];
> > + dag1 = dag->child[1];
> > + }
> > + GBE_ASSERT(!(dag->child[0]->insn.getOpcode() == OP_LOADI &&
> > + dag->child[1]->insn.getOpcode() == OP_LOADI));
> > + if (dag->insn.getOpcode() == OP_AND ||
> > + dag->insn.getOpcode() == OP_OR ||
> > + dag->insn.getOpcode() == OP_XOR) {
> > + GenRegister src0;
> > + GenRegister src1;
> > + if (lowerI64Reg(sel, dag0, src0, GEN_TYPE_UD) &&
> > + lowerI64Reg(sel, dag1, src1, GEN_TYPE_UD)) {
> > + switch (dag->insn.getOpcode()) {
> > + default:
> > + case OP_AND: sel.AND(GenRegister::retype(dst, GEN_TYPE_UD),
> src0, src1); break;
> > + case OP_OR: sel.OR(GenRegister::retype(dst, GEN_TYPE_UD),
> src0, src1); break;
> > + case OP_XOR: sel.XOR(GenRegister::retype(dst,
> > + GEN_TYPE_UD), src0, src1); break;
> > }
> > + sel.MOV(dst, GenRegister::retype(dst, GEN_TYPE_UD));
> > + markChildren = false;
> > + return;
> > }
> > }
> > + }
> >
> > - if (!sel.hasLongType()) {
> > - GenRegister tmp[6];
> > - for(int i=0; i<6; i++) {
> > - tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
> > - }
> > - sel.push();
> > - sel.curr.flag = 0;
> > - sel.curr.subFlag = 1;
> > - sel.CONVI64_TO_F(dst, src, tmp);
> > - sel.pop();
> > - } else {
> > - GenRegister unpacked;
> > - const uint32_t type = GEN_TYPE_F;
> > - unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, type);
> > + if (!sel.hasLongType()) {
> > + GenRegister tmp[6];
> > + for(int i=0; i<6; i++) {
> > + tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
> > + }
> > + sel.push();
> > + sel.curr.flag = 0;
> > + sel.curr.subFlag = 1;
> > + sel.CONVI64_TO_F(dst, src, tmp);
> > + sel.pop();
> > + } else {
> > + GenRegister unpacked;
> > + const uint32_t type = GEN_TYPE_F;
> > + unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, type);
> >
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.MOV(unpacked, src);
> > - sel.pop();
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + sel.MOV(unpacked, src);
> > + sel.pop();
> >
> > - if (unpacked.reg() != dst.reg()) {
> > - sel.MOV(dst, unpacked);
> > - }
> > + if (unpacked.reg() != dst.reg()) {
> > + sel.MOV(dst, unpacked);
> > }
> > - } else if (sel.hasLongType() && sel.hasLongRegRestrict() && dstFamily
> == FAMILY_QWORD && srcFamily != FAMILY_QWORD) {
> > - // Convert i32/i16/i8/float to i64/double if hasLongRegRestrict(src and
> dst hstride must be aligned to the same qword).
> > + }
> > + }
> > +
> > + INLINE void convertSmallIntsToI64(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + const RegisterFamily srcFamily = getFamily(srcType);
> > +
> > + if (sel.hasLongType() && sel.hasLongRegRestrict()) {
> > + // Convert i32/i16/i8 to i64 if hasLongRegRestrict(src and dst hstride
> must be aligned to the same qword).
> > GenRegister unpacked;
> > GenRegister unpacked_src = src;
> >
> > sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> >
> > - if (srcType == ir::TYPE_FLOAT) {
> > - unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, GEN_TYPE_F);
> > - } else if(srcFamily == FAMILY_DWORD) {
> > - unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, srcType == TYPE_U32 ?
> GEN_TYPE_UD : GEN_TYPE_D);
> > - } else if(srcFamily == FAMILY_WORD) {
> > - unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, srcType == TYPE_U16 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > - } else if(srcFamily == FAMILY_BYTE) {
> > - GenRegister tmp = sel.selReg(sel.reg(FAMILY_WORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - tmp = GenRegister::retype(tmp, srcType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > - unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > - unpacked = GenRegister::retype(unpacked, srcType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > - sel.MOV(tmp, src);
> > - unpacked_src = tmp;
> > - } else
> > - GBE_ASSERT(0);
> > + if(srcFamily == FAMILY_DWORD) {
> > + unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, srcType == TYPE_U32 ?
> GEN_TYPE_UD : GEN_TYPE_D);
> > + } else if(srcFamily == FAMILY_WORD) {
> > + unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, srcType == TYPE_U16 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > + } else if(srcFamily == FAMILY_BYTE) {
> > + GenRegister tmp = sel.selReg(sel.reg(FAMILY_WORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + tmp = GenRegister::retype(tmp, srcType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > + unpacked = sel.unpacked_uw(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, srcType == TYPE_U8 ?
> GEN_TYPE_UW : GEN_TYPE_W);
> > + sel.MOV(tmp, src);
> > + unpacked_src = tmp;
> > + } else
> > + GBE_ASSERT(0);
> >
> > - sel.MOV(unpacked, unpacked_src);
> > + sel.MOV(unpacked, unpacked_src);
> > sel.pop();
> > sel.MOV(dst, unpacked);
> > - }else if ((dst.isdf() && srcType == ir::TYPE_FLOAT) ||
> > - (src.isdf() && dstType == ir::TYPE_FLOAT)) { // float and double
> conversion
> > - ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD);
> > - sel.MOV_DF(dst, src, sel.selReg(r, TYPE_U64));
> > - } else if (dst.isint64()) { // promote to i64
> > - switch(src.type) {
> > - case GEN_TYPE_F:
> > - {
> > - if (!sel.hasLongType()) {
> > - GenRegister tmp[2];
> > - tmp[0] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
> > - tmp[1] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_FLOAT);
> > - sel.push();
> > - sel.curr.flag = 0;
> > - sel.curr.subFlag = 1;
> > - sel.CONVF_TO_I64(dst, src, tmp);
> > - sel.pop();
> > - } else {
> > - sel.MOV(dst, src);
> > - }
> > - break;
> > - }
> > - case GEN_TYPE_HF:
> > - {
> > - GBE_ASSERT(sel.hasLongType());
> > - GBE_ASSERT(sel.hasHalfType());
> > - uint32_t type = dstType == TYPE_U64 ? GEN_TYPE_UD :
> GEN_TYPE_D;
> > - GenRegister tmp =
> GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0))), TYPE_U32), type);
> > - sel.push();
> > - if (sel.isScalarReg(insn.getSrc(0))) {
> > - sel.curr.execWidth = 1;
> > - sel.curr.predicate = GEN_PREDICATE_NONE;
> > - sel.curr.noMask = 1;
> > - }
> > - sel.MOV(tmp, src);
> > - sel.pop();
> > - sel.MOV(dst, tmp);
> > - break;
> > - }
> > - case GEN_TYPE_DF:
> > - NOT_IMPLEMENTED;
> > - default:
> > - if (sel.hasLongType()) {
> > - sel.MOV(dst, src);
> > - } else {
> > - sel.CONVI_TO_I64(dst, src, sel.selReg(sel.reg(FAMILY_DWORD)));
> > - }
> > - }
> > - } else if (srcType == ir::TYPE_HALF && (dstFamily == FAMILY_BYTE ||
> dstFamily == FAMILY_WORD)) {
> > - // Special case, half -> char/short.
> > - /* [DevBDW+]: Format conversion to or from HF (Half Float) must be
> DWord-aligned and
> > - strided by a DWord on the destination. */
> > - GBE_ASSERT(sel.hasHalfType());
> > - GenRegister tmp;
> > + } else if (sel.hasLongType()) {
> > + sel.MOV(dst, src);
> > + } else {
> > + sel.CONVI_TO_I64(dst, src, sel.selReg(sel.reg(FAMILY_DWORD)));
> > + }
> > + }
> > +
> > + INLINE void convertFToI64(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > +
> > + if (sel.hasLongType() && sel.hasLongRegRestrict() && srcType ==
> ir::TYPE_FLOAT) { // typical bsw float->long case
> > + // Convert float to i64 if hasLongRegRestrict(src and dst hstride must
> be aligned to the same qword).
> > + GenRegister unpacked;
> > + GenRegister unpacked_src = src;
> > +
> > sel.push();
> > if (sel.isScalarReg(insn.getSrc(0))) {
> > sel.curr.execWidth = 1;
> > sel.curr.predicate = GEN_PREDICATE_NONE;
> > sel.curr.noMask = 1;
> > }
> > - if (dstFamily == FAMILY_BYTE) {
> > - const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> GEN_TYPE_B;
> > - tmp =
> GenRegister::retype(sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), type);
> > - sel.MOV(tmp, src);
> > - } else {
> > - const uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> GEN_TYPE_W;
> > - tmp =
> GenRegister::retype(sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), type);
> > - sel.MOV(tmp, src);
> > - }
> > +
> > + unpacked = sel.unpacked_ud(sel.reg(FAMILY_QWORD,
> sel.isScalarReg(insn.getSrc(0))));
> > + unpacked = GenRegister::retype(unpacked, GEN_TYPE_F);
> > + sel.MOV(unpacked, unpacked_src);
> > sel.pop();
> > - sel.MOV(dst, tmp);
> > - } else if (dstType == ir::TYPE_HALF && (srcFamily == FAMILY_BYTE ||
> srcFamily == FAMILY_WORD)) {
> > - // Special case, char/uchar -> half
> > - /* [DevBDW+]: Format conversion to or from HF (Half Float) must be
> DWord-aligned and
> > - strided by a DWord on the destination. */
> > + sel.MOV(dst, unpacked);
> > + } else if (srcType == ir::TYPE_FLOAT) {
> > + if (sel.hasLongType()) { // typical bdw float->long case
> > + sel.MOV(dst, src);
> > + } else { // typical old platform float->long case
> > + GenRegister tmp[2];
> > + tmp[0] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
> > + tmp[1] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_FLOAT);
> > + sel.push();
> > + sel.curr.flag = 0;
> > + sel.curr.subFlag = 1;
> > + sel.CONVF_TO_I64(dst, src, tmp);
> > + sel.pop();
> > + }
> > + } else if (srcType == ir::TYPE_HALF) { // TODO: We may consider bsw's
> hasLongRegRestrict case here.
> > + /* No need to consider old platform. if we support half, we must have
> native long. */
> > + GBE_ASSERT(sel.hasLongType());
> > GBE_ASSERT(sel.hasHalfType());
> > - GenRegister tmp =
> GenRegister::retype(sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), GEN_TYPE_HF);
> > + uint32_t type = dstType == TYPE_U64 ? GEN_TYPE_UD : GEN_TYPE_D;
> > + GenRegister tmp =
> > + GenRegister::retype(sel.selReg(sel.reg(FAMILY_DWORD,
> > + sel.isScalarReg(insn.getSrc(0))), TYPE_U32), type);
> > sel.push();
> > if (sel.isScalarReg(insn.getSrc(0))) {
> > sel.curr.execWidth = 1;
> > @@ -4506,11 +4524,163 @@ namespace gbe
> > sel.MOV(tmp, src);
> > sel.pop();
> > sel.MOV(dst, tmp);
> > - } else
> > - sel.MOV(dst, src);
> > + } else if (src.type == GEN_TYPE_DF) {
> > + //TODO:
> > + GBE_ASSERT(0);
> > + } else {
> > + /* Invalid case. */
> > + GBE_ASSERT(0);
> > + }
> > + }
> > +
> > + INLINE void convertBetweenFloatDouble(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > +
> > +
> > + //TODO:
> > + ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD);
> > + sel.MOV_DF(dst, src, sel.selReg(r, TYPE_U64));
> > + }
> > +
> > + INLINE void convertBetweenHalfDouble(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> >
> > + //TODO:
> > + ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD);
> > + sel.MOV_DF(dst, src, sel.selReg(r, TYPE_U64));
> > + }
> > +
> > + INLINE void convertHalfToSmallInts(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + const RegisterFamily dstFamily = getFamily(dstType);
> > +
> > + // Special case, half -> char/short.
> > + /* [DevBDW+]: Format conversion to or from HF (Half Float) must be
> DWord-aligned and
> > + strided by a DWord on the destination. */
> > + GBE_ASSERT(sel.hasHalfType());
> > + GenRegister tmp;
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + if (dstFamily == FAMILY_BYTE) {
> > + const uint32_t type = dstType == TYPE_U8 ? GEN_TYPE_UB :
> GEN_TYPE_B;
> > + tmp =
> GenRegister::retype(sel.unpacked_ub(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), type);
> > + sel.MOV(tmp, src);
> > + } else {
> > + const uint32_t type = dstType == TYPE_U16 ? GEN_TYPE_UW :
> GEN_TYPE_W;
> > + tmp =
> GenRegister::retype(sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), type);
> > + sel.MOV(tmp, src);
> > + }
> > sel.pop();
> > + sel.MOV(dst, tmp);
> > + }
> >
> > + INLINE void convertSmallIntsToHalf(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > +
> > + // Special case, char/uchar -> half
> > + /* [DevBDW+]: Format conversion to or from HF (Half Float) must be
> DWord-aligned and
> > + strided by a DWord on the destination. */
> > + GBE_ASSERT(sel.hasHalfType());
> > + GenRegister tmp =
> GenRegister::retype(sel.unpacked_uw(sel.reg(FAMILY_DWORD,
> sel.isScalarReg(insn.getSrc(0)))), GEN_TYPE_HF);
> > + sel.push();
> > + if (sel.isScalarReg(insn.getSrc(0))) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + sel.MOV(tmp, src);
> > + sel.pop();
> > + sel.MOV(dst, tmp);
> > + }
> > +
> > + INLINE bool emitOne(Selection::Opaque &sel, const
> ir::ConvertInstruction &insn, bool &markChildren) const
> > + {
> > + using namespace ir;
> > + const Type dstType = insn.getDstType();
> > + const Type srcType = insn.getSrcType();
> > + const RegisterFamily dstFamily = getFamily(dstType);
> > + const RegisterFamily srcFamily = getFamily(srcType);
> > + const GenRegister dst = sel.selReg(insn.getDst(0), dstType);
> > + const GenRegister src = sel.selReg(insn.getSrc(0), srcType);
> > + const Opcode opcode = insn.getOpcode();
> > + sel.push();
> > + if (sel.isScalarReg(insn.getDst(0)) == true) {
> > + sel.curr.execWidth = 1;
> > + sel.curr.predicate = GEN_PREDICATE_NONE;
> > + sel.curr.noMask = 1;
> > + }
> > + if(opcode == ir::OP_SAT_CVT)
> > + sel.curr.saturate = 1;
> > +
> > + if (opcode == OP_F16TO32 || opcode == OP_F32TO16) { /* Conversion
> between float and half. */
> > + convertBetweenHalfFloat(sel, insn, markChildren);
> > + } else if (dstFamily != FAMILY_DWORD && dstFamily !=
> FAMILY_QWORD && srcFamily == FAMILY_DWORD) {
> > + //convert i32/float to small int/half
> > + convert32bitsToSmall(sel, insn, markChildren);
> > + } else if (dstFamily == FAMILY_WORD && srcFamily ==
> FAMILY_QWORD && srcType != ir::TYPE_DOUBLE) {
> > + //convert i64 to i16 and half.
> > + convertI64To16bits(sel, insn, markChildren);
> > + } else if (dstFamily == FAMILY_BYTE && srcFamily == FAMILY_QWORD
> && srcType != ir::TYPE_DOUBLE) {
> > + //convert i64 to i8
> > + convertI64ToI8(sel, insn, markChildren);
> > + } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) &&
> > + (srcType == ir::TYPE_U64 || srcType == ir::TYPE_S64)) {// Convert i64
> to i32
> > + convertI64ToI32(sel, insn, markChildren);
> > + } else if (dstType == ir::TYPE_FLOAT && (srcType == ir::TYPE_U64 ||
> srcType == ir::TYPE_S64)) {
> > + convertI64ToFloat(sel, insn, markChildren);
> > + } else if (dstType == ir::TYPE_DOUBLE && (srcType == ir::TYPE_U64 ||
> srcType == ir::TYPE_S64)) {
> > + // TODO: long -> double
> > + GBE_ASSERT(0);
> > + } else if ((dstType == ir::TYPE_U64 || dstType == ir::TYPE_S64)
> > + && (srcFamily != FAMILY_QWORD && srcType != ir::TYPE_FLOAT &&
> srcType != ir::TYPE_HALF)) {
> > + convertSmallIntsToI64(sel, insn, markChildren);
> > + } else if ((dstType == ir::TYPE_U64 || dstType == ir::TYPE_S64)
> > + && (srcType == ir::TYPE_FLOAT || srcType == ir::TYPE_HALF ||
> srcType == ir::TYPE_DOUBLE)) {
> > + convertFToI64(sel, insn, markChildren);
> > + } else if ((srcType == ir::TYPE_FLOAT && dstType == ir::TYPE_DOUBLE)
> ||
> > + (dstType == ir::TYPE_FLOAT && srcType == ir::TYPE_DOUBLE)) {
> > + // float and double conversion
> > + convertBetweenFloatDouble(sel, insn, markChildren);
> > + } else if ((srcType == ir::TYPE_HALF && dstType == ir::TYPE_DOUBLE) ||
> > + (dstType == ir::TYPE_HALF && srcType == ir::TYPE_DOUBLE)) {
> > + // float and double conversion
> > + convertBetweenHalfDouble(sel, insn, markChildren);
> > + } else if (srcType == ir::TYPE_HALF && (dstFamily == FAMILY_BYTE ||
> dstFamily == FAMILY_WORD)) {
> > + // Convert half to small int
> > + convertHalfToSmallInts(sel, insn, markChildren);
> > + } else if (dstType == ir::TYPE_HALF && (srcFamily == FAMILY_BYTE ||
> srcFamily == FAMILY_WORD)) {
> > + // Convert small int to half
> > + convertSmallIntsToHalf(sel, insn, markChildren);
> > + } else {
> > + /* All special cases has been handled, just MOV. */
> > + sel.MOV(dst, src);
> > + }
> > +
> > + sel.pop();
> > return true;
> > }
> > DECL_CTOR(ConvertInstruction, 1, 1);
> > --
> > 1.7.9.5
> >
> >
> >
> > _______________________________________________
> > Beignet mailing list
> > Beignet at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/beignet
>
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list