[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