[Beignet] [PATCH] support 64bit-integer comparing

Zhigang Gong zhigang.gong at linux.intel.com
Tue Aug 13 22:36:35 PDT 2013


Could you also provide a unit test case for this patch? Thanks.

On Wed, Aug 14, 2013 at 09:40:33AM +0800, Homer Hsing wrote:
> support 64bit-integer comparing,
> including EQ(==), NEQ(!=), G(>), GE(>=), L(<), LE(<=)
> 
> Signed-off-by: Homer Hsing <homer.xing at intel.com>
> ---
>  backend/src/backend/gen_context.cpp                | 77 ++++++++++++++++++++++
>  backend/src/backend/gen_context.hpp                |  2 +
>  .../src/backend/gen_insn_gen7_schedule_info.hxx    |  1 +
>  backend/src/backend/gen_insn_selection.cpp         | 19 +++++-
>  backend/src/backend/gen_insn_selection.hxx         |  1 +
>  5 files changed, 99 insertions(+), 1 deletion(-)
> 
> diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
> index 86f3555..482b568 100644
> --- a/backend/src/backend/gen_context.cpp
> +++ b/backend/src/backend/gen_context.cpp
> @@ -498,6 +498,83 @@ namespace gbe
>      }
>    }
>  
> +  void GenContext::saveFlag(GenRegister dest, int flag, int subFlag) {
> +    p->push();
> +    p->curr.execWidth = 1;
> +    p->MOV(dest, GenRegister::flag(flag, subFlag));
> +    p->pop();
> +  }
> +
> +  void GenContext::emitI64CompareInstruction(const SelectionInstruction &insn) {
> +    GenRegister src0 = ra->genReg(insn.src(0));
> +    GenRegister src1 = ra->genReg(insn.src(1));
> +    GenRegister tmp0 = ra->genReg(insn.dst(0));
> +    GenRegister tmp1 = ra->genReg(insn.dst(1));
> +    GenRegister tmp2 = ra->genReg(insn.dst(2));
> +    tmp0.type = (src0.type == GEN_TYPE_L) ? GEN_TYPE_D : GEN_TYPE_UD;
> +    tmp1.type = (src1.type == GEN_TYPE_L) ? GEN_TYPE_D : GEN_TYPE_UD;
> +    int flag = p->curr.flag, subFlag = p->curr.subFlag;
> +    GenRegister f1 = GenRegister::retype(tmp2, GEN_TYPE_UW),
> +                f2 = GenRegister::suboffset(f1, 1),
> +                f3 = GenRegister::suboffset(f1, 2);
> +    p->push();
> +    p->curr.predicate = GEN_PREDICATE_NONE;
> +    p->curr.flag = 0, p->curr.subFlag = 1;
> +    loadTopHalf(tmp0, src0);
> +    loadTopHalf(tmp1, src1);
> +    switch(insn.extra.function) {
> +      case GEN_CONDITIONAL_L:
> +      case GEN_CONDITIONAL_LE:
> +      case GEN_CONDITIONAL_G:
> +      case GEN_CONDITIONAL_GE:
> +        {
> +          int cmpTopHalf = insn.extra.function;
> +          if(insn.extra.function == GEN_CONDITIONAL_LE)
> +            cmpTopHalf = GEN_CONDITIONAL_L;
> +          if(insn.extra.function == GEN_CONDITIONAL_GE)
> +            cmpTopHalf = GEN_CONDITIONAL_G;
> +          p->CMP(cmpTopHalf, tmp0, tmp1);
> +        }
> +        saveFlag(f1, 0, 1);
> +        p->CMP(GEN_CONDITIONAL_EQ, tmp0, tmp1);
> +        saveFlag(f2, 0, 1);
> +        tmp0.type = tmp1.type = GEN_TYPE_UD;
> +        loadBottomHalf(tmp0, src0);
> +        loadBottomHalf(tmp1, src1);
> +        p->CMP(insn.extra.function, tmp0, tmp1);
> +        saveFlag(f3, 0, 1);
> +        p->AND(f2, f2, f3);
> +        p->OR(f1, f1, f2);
> +        break;
> +      case GEN_CONDITIONAL_EQ:
> +        p->CMP(GEN_CONDITIONAL_EQ, tmp0, tmp1);
> +        saveFlag(f1, 0, 1);
> +        tmp0.type = tmp1.type = GEN_TYPE_UD;
> +        loadBottomHalf(tmp0, src0);
> +        loadBottomHalf(tmp1, src1);
> +        p->CMP(GEN_CONDITIONAL_EQ, tmp0, tmp1);
> +        saveFlag(f2, 0, 1);
> +        p->AND(f1, f1, f2);
> +        break;
> +      case GEN_CONDITIONAL_NEQ:
> +        p->CMP(GEN_CONDITIONAL_NEQ, tmp0, tmp1);
> +        saveFlag(f1, 0, 1);
> +        tmp0.type = tmp1.type = GEN_TYPE_UD;
> +        loadBottomHalf(tmp0, src0);
> +        loadBottomHalf(tmp1, src1);
> +        p->CMP(GEN_CONDITIONAL_NEQ, tmp0, tmp1);
> +        saveFlag(f2, 0, 1);
> +        p->OR(f1, f1, f2);
> +        break;
> +      default:
> +        NOT_IMPLEMENTED;
> +    }
> +    saveFlag(f2, flag, subFlag);
> +    p->AND(f1, f1, f2);
> +    p->MOV(GenRegister::flag(flag, subFlag), f1);
> +    p->pop();
> +  }
> +
>    void GenContext::loadTopHalf(GenRegister dest, GenRegister src) {
>      int execWidth = p->curr.execWidth;
>      src = src.top_half();
> diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
> index 9e7b384..8b481d0 100644
> --- a/backend/src/backend/gen_context.hpp
> +++ b/backend/src/backend/gen_context.hpp
> @@ -86,6 +86,7 @@ namespace gbe
>      void addWithCarry(GenRegister dest, GenRegister src0, GenRegister src1);
>      void subWithBorrow(GenRegister dest, GenRegister src0, GenRegister src1);
>      void I32FullMult(GenRegister high, GenRegister low, GenRegister src0, GenRegister src1);
> +    void saveFlag(GenRegister dest, int flag, int subFlag);
>  
>      /*! Final Gen ISA emission helper functions */
>      void emitLabelInstruction(const SelectionInstruction &insn);
> @@ -95,6 +96,7 @@ namespace gbe
>      void emitBinaryWithTempInstruction(const SelectionInstruction &insn);
>      void emitTernaryInstruction(const SelectionInstruction &insn);
>      void emitI64ShiftInstruction(const SelectionInstruction &insn);
> +    void emitI64CompareInstruction(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 7f214ac..2204837 100644
> --- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
> +++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
> @@ -7,6 +7,7 @@ DECL_GEN7_SCHEDULE(BinaryWithTemp,  20,        4,        2)
>  DECL_GEN7_SCHEDULE(Ternary,         20,        4,        2)
>  DECL_GEN7_SCHEDULE(I64Shift,        20,        4,        2)
>  DECL_GEN7_SCHEDULE(Compare,         20,        4,        2)
> +DECL_GEN7_SCHEDULE(I64Compare,      20,        4,        2)
>  DECL_GEN7_SCHEDULE(Jump,            14,        1,        1)
>  DECL_GEN7_SCHEDULE(IndirectMove,    20,        2,        2)
>  DECL_GEN7_SCHEDULE(Eot,             20,        1,        1)
> diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
> index 38f56b5..580c971 100644
> --- a/backend/src/backend/gen_insn_selection.cpp
> +++ b/backend/src/backend/gen_insn_selection.cpp
> @@ -469,6 +469,8 @@ namespace gbe
>  #undef I64Shift
>      /*! Shift a 64-bit integer */
>      void I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[6]);
> +    /*! Compare 64-bit integer */
> +    void I64CMP(uint32_t conditional, Reg src0, Reg src1, GenRegister tmp[3]);
>      /*! Encode a barrier instruction */
>      void BARRIER(GenRegister src);
>      /*! Encode a barrier instruction */
> @@ -1050,6 +1052,15 @@ namespace gbe
>      insn->src(2) = src2;
>    }
>  
> +  void Selection::Opaque::I64CMP(uint32_t conditional, Reg src0, Reg src1, GenRegister tmp[3]) {
> +    SelectionInstruction *insn = this->appendInsn(SEL_OP_I64CMP, 3, 2);
> +    insn->src(0) = src0;
> +    insn->src(1) = src1;
> +    for(int i=0; i<3; i++)
> +      insn->dst(i) = tmp[i];
> +    insn->extra.function = conditional;
> +  }
> +
>    void Selection::Opaque::I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[6]) {
>      SelectionInstruction *insn = this->appendInsn(opcode, 7, 2);
>      insn->dst(0) = dst;
> @@ -2293,7 +2304,13 @@ namespace gbe
>        sel.push();
>          sel.curr.physicalFlag = 0;
>          sel.curr.flagIndex = uint16_t(dst);
> -        sel.CMP(genCmp, src0, src1);
> +        if (type == TYPE_S64 || type == TYPE_U64) {
> +          GenRegister tmp[3];
> +          for(int i=0; i<3; i++)
> +            tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD));
> +          sel.I64CMP(genCmp, src0, src1, tmp);
> +        } else
> +          sel.CMP(genCmp, src0, src1);
>        sel.pop();
>        return true;
>      }
> diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
> index 6ef50b8..cf974af 100644
> --- a/backend/src/backend/gen_insn_selection.hxx
> +++ b/backend/src/backend/gen_insn_selection.hxx
> @@ -34,6 +34,7 @@ DECL_SELECTION_IR(I64MUL, I64MULInstruction)
>  DECL_SELECTION_IR(ATOMIC, AtomicInstruction)
>  DECL_SELECTION_IR(MACH, BinaryInstruction)
>  DECL_SELECTION_IR(CMP, CompareInstruction)
> +DECL_SELECTION_IR(I64CMP, I64CompareInstruction)
>  DECL_SELECTION_IR(SEL_CMP, CompareInstruction)
>  DECL_SELECTION_IR(MAD, TernaryInstruction)
>  DECL_SELECTION_IR(JMPI, JumpInstruction)
> -- 
> 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