From 71492287f76673fafce73a8aa6524db7c4a39342 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 30 May 2014 18:19:04 +0800 Subject: [PATCH] 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. v2: fix some bug on HSW platform. Signed-off-by: Zhigang Gong Signed-off-by: Yang Rong Reviewed-by: Yang Rong --- backend/src/backend/gen75_encoder.cpp | 50 +++++++++++++-------------- backend/src/backend/gen_encoder.cpp | 54 ++++++++++++++++-------------- backend/src/backend/gen_insn_selection.cpp | 8 +++-- 3 files changed, 59 insertions(+), 53 deletions(-) diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp index 2cda0d7..81364a9 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,37 @@ 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. - } else { - GenRegister r0 = GenRegister::h2(r); + GenRegister r0; + r0 = GenRegister::h2(r); + push(); + curr.execWidth = 4; + curr.predicate = GEN_PREDICATE_NONE; + curr.noMask = 1; + MOV(r0, src0); + MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4)); + curr.noMask = 0; + curr.quarterControl = 0; + curr.nibControl = 0; + MOV(dest, r0); + curr.nibControl = 1; + MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4)); + 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), GenRegister::suboffset(src0, 12)); + curr.noMask = 0; + curr.quarterControl = 1; curr.nibControl = 0; - MOV(dest, r0); + MOV(GenRegister::suboffset(dest, 8), r0); curr.nibControl = 1; - MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4)); + MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4)); 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 de91911..f680265 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()]; // FIXME, in the future, we need to do a common I64 lower to I32 analysis // at llvm IR layer which could cover more cases then just this one. @@ -3311,7 +3312,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()) { -- 2.7.4