[Beignet] [PATCH V2 1/2] GBE: Add support double to float conversion.

Zhigang Gong zhigang.gong at intel.com
Thu Jun 5 22:36:17 PDT 2014


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 and utest case.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 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 2d380e4..74f2cf5 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()];
         SelectionDAG *dag0, *dag1;
         if (dag->child[0]->insn.getOpcode() == OP_LOADI) {
@@ -3307,7 +3308,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()) {
-- 
1.8.3.2



More information about the Beignet mailing list