[Beignet] [PATCH 1/2] GBE: Add support double to float conversion.
Gong, Zhigang
zhigang.gong at intel.com
Thu Jun 5 20:42:17 PDT 2014
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: beignet at lists.freedesktop.org
> 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 <zhigang.gong at intel.com>
> ---
> 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
More information about the Beignet
mailing list