[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