summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2014-05-30 18:19:04 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-06-09 11:50:20 +0800
commit71492287f76673fafce73a8aa6524db7c4a39342 (patch)
treeee273e7ca9341fcf69483ddb8548ed472d96711b
parent3564ef7589c569f5cf840386c6e29f926a5f407c (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.cpp50
-rw-r--r--backend/src/backend/gen_encoder.cpp54
-rw-r--r--backend/src/backend/gen_insn_selection.cpp8
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()) {