Rong, Could you help to test this patchset on haswell? As I don't have a haswell machine in hand, don't know whether the DF_MOV is fully correct on haswell. And I'm also very curious the testing result of the utest double_precision_check on haswell.
> -----Original Message----- > From: Gong, Zhigang > Sent: Friday, June 6, 2014 10:54 AM > To: [email protected] > Cc: Gong, Zhigang > Subject: [PATCH 1/2] GBE: Add support double to float conversion. > > Previous double to float conversion will go to the > int64 to float code path incorrectly. And don't really have double to float > conversion support at gen_encoder. > This patch fix the above issues. > > Signed-off-by: Zhigang Gong <[email protected]> > --- > backend/src/backend/gen75_encoder.cpp | 55 > +++++++++++++++++------------- > backend/src/backend/gen_encoder.cpp | 54 > +++++++++++++++-------------- > backend/src/backend/gen_insn_selection.cpp | 8 +++-- > 3 files changed, 65 insertions(+), 52 deletions(-) > > diff --git a/backend/src/backend/gen75_encoder.cpp > b/backend/src/backend/gen75_encoder.cpp > index 2cda0d7..52d90d8 100644 > --- a/backend/src/backend/gen75_encoder.cpp > +++ b/backend/src/backend/gen75_encoder.cpp > @@ -177,6 +177,7 @@ namespace gbe > msg_length, > response_length); > } > + > void Gen75Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, > double value) { > union { double d; unsigned u[2]; } u; > u.d = value; > @@ -207,38 +208,44 @@ namespace gbe > } > > void Gen75Encoder::MOV_DF(GenRegister dest, GenRegister src0, > GenRegister r) { > + GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() > + && dest.type == GEN_TYPE_F)); > int w = curr.execWidth; > - if (src0.isdf()) { > - GBE_ASSERT(0); // MOV DF is called from convert instruction, > - // We should never convert a df to a df. > + GenRegister r0; > + int factor = 1; > + if (dest.type == GEN_TYPE_F) { > + r0 = r; > + r = GenRegister::h2(r); > + factor = 2; > } else { > - GenRegister r0 = GenRegister::h2(r); > + r0 = GenRegister::h2(r); > + } > + push(); > + curr.execWidth = 4; > + curr.predicate = GEN_PREDICATE_NONE; > + curr.noMask = 1; > + MOV(r0, src0); > + MOV(GenRegister::suboffset(r0, 4 * factor), GenRegister::suboffset(src0, > 4)); > + curr.noMask = 0; > + curr.quarterControl = 0; > + curr.nibControl = 0; > + MOV(dest, r); > + curr.nibControl = 1; > + MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r, 8 / > factor)); > + pop(); > + if (w == 16) { > push(); > curr.execWidth = 4; > curr.predicate = GEN_PREDICATE_NONE; > - MOV(r0, src0); > - MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4)); > - curr.predicate = GEN_PREDICATE_NORMAL; > - curr.quarterControl = 0; > + curr.noMask = 1; > + MOV(r0, GenRegister::suboffset(src0, 8)); > + MOV(GenRegister::suboffset(r0, 4 * factor), > GenRegister::suboffset(src0, 12)); > + curr.noMask = 0; > + curr.quarterControl = 1; > curr.nibControl = 0; > - MOV(dest, r0); > + MOV(GenRegister::suboffset(dest, 8), r); > curr.nibControl = 1; > - MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4)); > + MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r, 8 > + / factor)); > pop(); > - if (w == 16) { > - push(); > - curr.execWidth = 4; > - curr.predicate = GEN_PREDICATE_NONE; > - MOV(r0, GenRegister::suboffset(src0, 8)); > - MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, > 12)); > - curr.predicate = GEN_PREDICATE_NORMAL; > - curr.quarterControl = 1; > - curr.nibControl = 0; > - MOV(GenRegister::suboffset(dest, 8), r0); > - curr.nibControl = 1; > - MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, > 4)); > - pop(); > - } > } > } > } /* End of the name space. */ > diff --git a/backend/src/backend/gen_encoder.cpp > b/backend/src/backend/gen_encoder.cpp > index abb04e6..d836995 100644 > --- a/backend/src/backend/gen_encoder.cpp > +++ b/backend/src/backend/gen_encoder.cpp > @@ -853,40 +853,44 @@ namespace gbe > } > > void GenEncoder::MOV_DF(GenRegister dest, GenRegister src0, > GenRegister r) { > + GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() > + && dest.type == GEN_TYPE_F)); > int w = curr.execWidth; > - if (src0.isdf()) { > - GBE_ASSERT(0); // MOV DF is called from convert instruction, > - // We should never convert a df to a df. > + GenRegister r0; > + int factor = 1; > + if (dest.type == GEN_TYPE_F) { > + r0 = r; > + r = GenRegister::h2(r); > + factor = 2; > } else { > - GenRegister r0 = GenRegister::h2(r); > + r0 = GenRegister::h2(r); > + } > + push(); > + curr.execWidth = 8; > + curr.predicate = GEN_PREDICATE_NONE; > + curr.noMask = 1; > + MOV(r0, src0); > + MOV(GenRegister::suboffset(r0, 4 * factor), GenRegister::suboffset(src0, > 4)); > + curr.noMask = 0; > + curr.quarterControl = 0; > + curr.nibControl = 0; > + MOV(dest, r); > + curr.nibControl = 1; > + MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r, 8 / > factor)); > + pop(); > + if (w == 16) { > push(); > curr.execWidth = 8; > curr.predicate = GEN_PREDICATE_NONE; > curr.noMask = 1; > - MOV(r0, src0); > - MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4)); > - curr.predicate = GEN_PREDICATE_NORMAL; > - curr.quarterControl = 0; > + MOV(r0, GenRegister::suboffset(src0, 8)); > + MOV(GenRegister::suboffset(r0, 4 * factor), > GenRegister::suboffset(src0, 12)); > + curr.noMask = 0; > + curr.quarterControl = 1; > curr.nibControl = 0; > - MOV(dest, r); > + MOV(GenRegister::suboffset(dest, 8), r); > curr.nibControl = 1; > - MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r, 8)); > + MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r, 8 > + / factor)); > pop(); > - if (w == 16) { > - push(); > - curr.execWidth = 8; > - curr.predicate = GEN_PREDICATE_NONE; > - curr.noMask = 1; > - MOV(r0, GenRegister::suboffset(src0, 8)); > - MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, > 12)); > - curr.predicate = GEN_PREDICATE_NORMAL; > - curr.quarterControl = 1; > - curr.nibControl = 0; > - MOV(GenRegister::suboffset(dest, 8), r); > - curr.nibControl = 1; > - MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r, > 8)); > - pop(); > - } > } > } > > diff --git a/backend/src/backend/gen_insn_selection.cpp > b/backend/src/backend/gen_insn_selection.cpp > index 2d380e4..74f2cf5 100644 > --- a/backend/src/backend/gen_insn_selection.cpp > +++ b/backend/src/backend/gen_insn_selection.cpp > @@ -3266,9 +3266,10 @@ namespace gbe > } > if (unpacked.reg() != dst.reg()) > sel.MOV(dst, unpacked); > - } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) && > srcFamily == FAMILY_QWORD) { > + } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) && > + (srcType == ir::TYPE_U64 || srcType == ir::TYPE_S64)) > sel.CONVI64_TO_I(dst, src); > - } else if (dstType == ir::TYPE_FLOAT && srcFamily == FAMILY_QWORD) { > + else if (dstType == ir::TYPE_FLOAT && (srcType == ir::TYPE_U64 || > + srcType == ir::TYPE_S64)) { > auto dag = sel.regDAG[src.reg()]; > SelectionDAG *dag0, *dag1; > if (dag->child[0]->insn.getOpcode() == OP_LOADI) { @@ -3307,7 > +3308,8 @@ namespace gbe > sel.curr.subFlag = 1; > sel.CONVI64_TO_F(dst, src, tmp); > sel.pop(); > - } else if (dst.isdf()) { > + } else if ((dst.isdf() && srcType == ir::TYPE_FLOAT) || > + (src.isdf() && dstType == ir::TYPE_FLOAT)) { > ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD); > sel.MOV_DF(dst, src, sel.selReg(r)); > } else if (dst.isint64()) { > -- > 1.8.3.2 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
