[Beignet] [PATCH 1/2] Fix float to ulong/long fail.

Zhigang Gong zhigang.gong at linux.intel.com
Wed Dec 4 02:46:11 PST 2013


LGTM, pushed, thanks.

On Mon, Dec 02, 2013 at 05:10:26PM +0800, Yang Rong wrote:
> 
> Signed-off-by: Yang Rong <rong.r.yang at intel.com>
> ---
>  backend/src/backend/gen_context.cpp                | 51 ++++++++++++++++------
>  backend/src/backend/gen_context.hpp                |  1 +
>  .../src/backend/gen_insn_gen7_schedule_info.hxx    |  1 +
>  backend/src/backend/gen_insn_selection.cpp         | 18 +++++++-
>  backend/src/backend/gen_insn_selection.hxx         |  2 +-
>  5 files changed, 57 insertions(+), 16 deletions(-)
> 
> diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
> index 4902085..599a6d6 100644
> --- a/backend/src/backend/gen_context.cpp
> +++ b/backend/src/backend/gen_context.cpp
> @@ -191,20 +191,6 @@ namespace gbe
>        case SEL_OP_MOV_DF:
>          p->MOV_DF(dst, src, tmp);
>          break;
> -      case SEL_OP_CONVF_TO_I64:
> -       {
> -        tmp.type = GEN_TYPE_F;
> -        GenRegister d = GenRegister::retype(tmp, GEN_TYPE_D);
> -        float c = (1.f / 65536.f) * (1.f / 65536.f);
> -        p->MUL(tmp, src, GenRegister::immf(c));
> -        p->RNDZ(tmp, tmp);
> -        p->MOV(d, tmp);
> -        storeTopHalf(dst, d);
> -        d.type = GEN_TYPE_UD;
> -        p->MOV(d, GenRegister::abs(src));
> -        storeBottomHalf(dst, d);
> -        break;
> -       }
>        case SEL_OP_CONVI_TO_I64: {
>          GenRegister middle;
>          if (src.type == GEN_TYPE_B || src.type == GEN_TYPE_D) {
> @@ -876,6 +862,43 @@ namespace gbe
>      }
>    }
>  
> +
> +  void GenContext::emitFloatToI64Instruction(const SelectionInstruction &insn) {
> +    GenRegister src = ra->genReg(insn.src(0));
> +    GenRegister dst = ra->genReg(insn.dst(0));
> +    GenRegister high = ra->genReg(insn.dst(1));
> +    GenRegister tmp = ra->genReg(insn.dst(2));
> +    GenRegister flag0 = ra->genReg(insn.dst(3));
> +
> +    if(dst.is_signed_int())
> +      high = GenRegister::retype(high, GEN_TYPE_D);
> +    GenRegister low = GenRegister::retype(tmp, GEN_TYPE_UD);
> +    float c = (1.f / 65536.f) * (1.f / 65536.f);
> +    p->MUL(tmp, src, GenRegister::immf(c));
> +    p->RNDZ(tmp, tmp);
> +    p->MOV(high, tmp);
> +    c = 65536.f * 65536.f;
> +    p->MOV(tmp, high);  //result may not equal to tmp
> +    //mov float to int/uint is sat, so must sub high*0xffffffff
> +    p->MUL(tmp, tmp, GenRegister::immf(c));
> +    p->ADD(tmp, src, GenRegister::negate(tmp));
> +    p->MOV(low, GenRegister::abs(tmp));
> +    if(dst.is_signed_int()) {
> +      p->push();
> +      p->curr.predicate = GEN_PREDICATE_NONE;
> +      p->curr.useFlag(flag0.flag_nr(), flag0.flag_subnr());
> +      p->CMP(GEN_CONDITIONAL_L, src, GenRegister::immf(0x0));
> +      p->curr.predicate = GEN_PREDICATE_NORMAL;
> +      p->CMP(GEN_CONDITIONAL_NEQ, low, GenRegister::immud(0x0));
> +      p->ADD(high, high, GenRegister::immd(-1));
> +      p->NOT(low, low);
> +      p->ADD(low, low, GenRegister::immud(1));
> +      p->pop();
> +    }
> +    storeTopHalf(dst, high);
> +    storeBottomHalf(dst, low);
> +  }
> +
>    void GenContext::emitI64CompareInstruction(const SelectionInstruction &insn) {
>      GenRegister src0 = ra->genReg(insn.src(0));
>      GenRegister src1 = ra->genReg(insn.src(1));
> diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
> index 10e0603..f8ef8e0 100644
> --- a/backend/src/backend/gen_context.hpp
> +++ b/backend/src/backend/gen_context.hpp
> @@ -110,6 +110,7 @@ namespace gbe
>      void emitI64SATADDInstruction(const SelectionInstruction &insn);
>      void emitI64SATSUBInstruction(const SelectionInstruction &insn);
>      void emitI64ToFloatInstruction(const SelectionInstruction &insn);
> +    void emitFloatToI64Instruction(const SelectionInstruction &insn);
>      void emitCompareInstruction(const SelectionInstruction &insn);
>      void emitJumpInstruction(const SelectionInstruction &insn);
>      void emitIndirectMoveInstruction(const SelectionInstruction &insn);
> diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
> index b33112c..bb70b16 100644
> --- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
> +++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
> @@ -9,6 +9,7 @@ DECL_GEN7_SCHEDULE(I64Shift,        20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64HADD,         20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64RHADD,        20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64ToFloat,      20,        4,        2)
> +DECL_GEN7_SCHEDULE(FloatToI64,      20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64MULHI,        20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64MADSAT,       20,        4,        2)
>  DECL_GEN7_SCHEDULE(Compare,         20,        4,        2)
> diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
> index 9f6e615..23e9da7 100644
> --- a/backend/src/backend/gen_insn_selection.cpp
> +++ b/backend/src/backend/gen_insn_selection.cpp
> @@ -474,6 +474,8 @@ namespace gbe
>  #undef I64Shift
>      /*! Convert 64-bit integer to 32-bit float */
>      void CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[4]);
> +    /*! Convert 64-bit integer to 32-bit float */
> +    void CONVF_TO_I64(Reg dst, Reg src, GenRegister tmp[3]);
>      /*! Saturated 64bit x*y + z */
>      void I64MADSAT(Reg dst, Reg src0, Reg src1, Reg src2, GenRegister tmp[10]);
>      /*! High 64bit of x*y */
> @@ -1138,6 +1140,14 @@ namespace gbe
>        insn->dst(i + 1) = tmp[i];
>    }
>  
> +  void Selection::Opaque::CONVF_TO_I64(Reg dst, Reg src, GenRegister tmp[3]) {
> +    SelectionInstruction *insn = this->appendInsn(SEL_OP_CONVF_TO_I64, 4, 1);
> +    insn->dst(0) = dst;
> +    insn->src(0) = src;
> +    for(int i = 0; i < 3; i ++)
> +      insn->dst(i + 1) = tmp[i];
> +  }
> +
>    void Selection::Opaque::I64MADSAT(Reg dst, Reg src0, Reg src1, Reg src2, GenRegister tmp[10]) {
>      SelectionInstruction *insn = this->appendInsn(SEL_OP_I64MADSAT, 11, 3);
>      insn->dst(0) = dst;
> @@ -2700,8 +2710,14 @@ namespace gbe
>        } else if (dst.isint64()) {
>          switch(src.type) {
>            case GEN_TYPE_F:
> -            sel.CONVF_TO_I64(dst, src, sel.selReg(sel.reg(FAMILY_DWORD)));
> +          {
> +            GenRegister tmp[3];
> +            tmp[0] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
> +            tmp[1] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_FLOAT);
> +            tmp[2] = sel.selReg(sel.reg(FAMILY_BOOL), TYPE_BOOL);
> +            sel.CONVF_TO_I64(dst, src, tmp);
>              break;
> +          }
>            case GEN_TYPE_DF:
>              NOT_IMPLEMENTED;
>            default:
> diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
> index 9fb5da7..0118619 100644
> --- a/backend/src/backend/gen_insn_selection.hxx
> +++ b/backend/src/backend/gen_insn_selection.hxx
> @@ -75,7 +75,7 @@ DECL_SELECTION_IR(UPSAMPLE_SHORT, BinaryInstruction)
>  DECL_SELECTION_IR(UPSAMPLE_INT, BinaryInstruction)
>  DECL_SELECTION_IR(UPSAMPLE_LONG, BinaryInstruction)
>  DECL_SELECTION_IR(CONVI_TO_I64, UnaryWithTempInstruction)
> -DECL_SELECTION_IR(CONVF_TO_I64, UnaryWithTempInstruction)
>  DECL_SELECTION_IR(CONVI64_TO_I, UnaryInstruction)
>  DECL_SELECTION_IR(CONVI64_TO_F, I64ToFloatInstruction)
> +DECL_SELECTION_IR(CONVF_TO_I64, FloatToI64Instruction)
>  DECL_SELECTION_IR(I64MADSAT, I64MADSATInstruction)
> -- 
> 1.8.1.2
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list