GBE: Add support double to float conversion.
authorZhigang Gong <zhigang.gong@intel.com>
Fri, 30 May 2014 10:19:04 +0000 (18:19 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Mon, 9 Jun 2014 03:50:20 +0000 (11:50 +0800)
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>
backend/src/backend/gen75_encoder.cpp
backend/src/backend/gen_encoder.cpp
backend/src/backend/gen_insn_selection.cpp

index 2cda0d7..81364a9 100644 (file)
@@ -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. */
index abb04e6..d836995 100644 (file)
@@ -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();
-      }
     }
   }
 
index de91911..f680265 100644 (file)
@@ -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()) {