diff options
author | Zhigang Gong <zhigang.gong@intel.com> | 2014-05-30 18:19:04 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-09 11:50:20 +0800 |
commit | 71492287f76673fafce73a8aa6524db7c4a39342 (patch) | |
tree | ee273e7ca9341fcf69483ddb8548ed472d96711b | |
parent | 3564ef7589c569f5cf840386c6e29f926a5f407c (diff) |
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 <zhigang.gong@intel.com>
Signed-off-by: Yang Rong <rong.r.yang@intel.com>
Reviewed-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r-- | backend/src/backend/gen75_encoder.cpp | 50 | ||||
-rw-r--r-- | backend/src/backend/gen_encoder.cpp | 54 | ||||
-rw-r--r-- | 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 2cda0d7c..81364a95 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 abb04e6e..d8369950 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 de919117..f680265a 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()) { |