[Beignet] [PATCH 02/19] Backend: Add half float support for immediate.

junyan.he at inbox.com junyan.he at inbox.com
Thu Jun 11 04:24:02 PDT 2015


From: Junyan He <junyan.he at linux.intel.com>

Half will be imm for instructions, so need to add
half support in immediate.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/ir/function.cpp  |  2 +-
 backend/src/ir/immediate.cpp |  5 ++++-
 backend/src/ir/immediate.hpp | 48 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp
index 38355e2..f87f23a 100644
--- a/backend/src/ir/function.cpp
+++ b/backend/src/ir/function.cpp
@@ -156,7 +156,7 @@ namespace ir {
       case TYPE_U32:
       case TYPE_S64: out << imm.getIntegerValue(); break;
       case TYPE_U64: out << (uint64_t)imm.getIntegerValue(); break;
-      case TYPE_HALF: out << "half(" << imm.getIntegerValue() << ")"; break;
+      case TYPE_HALF: out << "half(" << (float)imm.getHalfValue() << ")"; break;
       case TYPE_FLOAT: out << imm.getFloatValue(); break;
       case TYPE_DOUBLE: out << imm.getDoubleValue(); break;
       default:
diff --git a/backend/src/ir/immediate.cpp b/backend/src/ir/immediate.cpp
index 1aac9bc..35fc965 100644
--- a/backend/src/ir/immediate.cpp
+++ b/backend/src/ir/immediate.cpp
@@ -41,6 +41,7 @@ using namespace ir;
         case TYPE_S64:    return Immediate(*this->data.s64 OP *right.data.s64); \
         case TYPE_U64:    return Immediate(*this->data.u64 OP *right.data.u64); \
         case TYPE_FLOAT:  return Immediate(*this->data.f32 OP *right.data.f32); \
+        case TYPE_HALF:   return Immediate(*this->data.f16 OP *right.data.f16); \
         case TYPE_DOUBLE: return Immediate(*this->data.f64 OP *right.data.f64); \
       }\
       return *this;\
@@ -145,6 +146,7 @@ using namespace ir;
         case TYPE_S64:    return Immediate(*left.data.s64 < *right.data.s64);
         case TYPE_U64:    return Immediate(*left.data.u64 < *right.data.u64);
         case TYPE_FLOAT:  return Immediate(*left.data.f32 < *right.data.f32);
+        case TYPE_HALF:   return Immediate(*left.data.f16 < *right.data.f16);
         case TYPE_DOUBLE: return Immediate(*left.data.f64 < *right.data.f64);
       }
     }
@@ -168,6 +170,7 @@ using namespace ir;
           case TYPE_S64:    return Immediate(left.data.s64[index]);
           case TYPE_U64:    return Immediate(left.data.u64[index]);
           case TYPE_FLOAT:  return Immediate(left.data.f32[index]);
+          case TYPE_HALF:   return Immediate(left.data.f16[index]);
           case TYPE_DOUBLE: return Immediate(left.data.f64[index]);
         }
       } else
@@ -187,7 +190,7 @@ using namespace ir;
         case IMM_XOR: *this = left ^ right; break;
         case IMM_REM:
         {
-          if (left.getType() > TYPE_BOOL && left.getType() <= TYPE_U64)
+          if (left.getType() > TYPE_BOOL && left.getType() <= TYPE_HALF)
             *this = left % right;
           else if (left.getType() == TYPE_FLOAT && right.getType() == TYPE_FLOAT) {
             *this = Immediate(left);
diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp
index ff37a29..a25895a 100644
--- a/backend/src/ir/immediate.hpp
+++ b/backend/src/ir/immediate.hpp
@@ -27,6 +27,7 @@
 
 #include <string.h>
 #include "ir/type.hpp"
+#include "ir/half.hpp"
 #include "sys/platform.hpp"
 
 namespace gbe {
@@ -57,6 +58,10 @@ namespace ir {
     IMM_FPTOSI,
     IMM_SITOFP,
     IMM_UITOFP,
+    IMM_HFTOUS,
+    IMM_HFTOSS,
+    IMM_SSTOHF,
+    IMM_USTOHF,
     IMM_EXTRACT,
     IMM_SEXT,
     IMM_ZEXT,
@@ -74,6 +79,7 @@ namespace ir {
     IMM_TYPE_S64 = TYPE_S64,
     IMM_TYPE_U64 = TYPE_U64,
     IMM_TYPE_FLOAT = TYPE_FLOAT,
+    IMM_TYPE_HALF = TYPE_HALF,
     IMM_TYPE_DOUBLE = TYPE_DOUBLE,
     IMM_TYPE_COMP             // compond immediate which consist many immediates.
   } ImmType;
@@ -106,6 +112,7 @@ namespace ir {
         case TYPE_S8:
         case TYPE_U8:   return 1;
         case TYPE_S16:
+        case TYPE_HALF:
         case TYPE_U16:  return 2;
         case TYPE_FLOAT:
         case TYPE_S32:
@@ -136,6 +143,7 @@ namespace ir {
     DECL_CONSTRUCTOR(int64_t, s64, TYPE_S64)
     DECL_CONSTRUCTOR(uint64_t, u64, TYPE_U64)
     DECL_CONSTRUCTOR(float, f32, TYPE_FLOAT)
+    DECL_CONSTRUCTOR(half, f16, TYPE_HALF)
     DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE)
 #undef DECL_CONSTRUCTOR
 
@@ -161,6 +169,7 @@ namespace ir {
     DECL_CONSTRUCTOR(int64_t, s64, TYPE_S64, elemNum)
     DECL_CONSTRUCTOR(uint64_t, u64, TYPE_U64, elemNum)
     DECL_CONSTRUCTOR(float, f32, TYPE_FLOAT, elemNum)
+    DECL_CONSTRUCTOR(half, f16, TYPE_HALF, elemNum)
     DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE, elemNum)
 #undef DECL_CONSTRUCTOR
 
@@ -200,7 +209,7 @@ namespace ir {
 
     INLINE float getFloatValue(void) const {
       // we allow bitcast from u32/s32 immediate to float
-      GBE_ASSERT(type == IMM_TYPE_FLOAT || type == IMM_TYPE_U32 || type == IMM_TYPE_S32);
+      GBE_ASSERT(type == IMM_TYPE_FLOAT);
       return *data.f32;
     }
 
@@ -209,6 +218,17 @@ namespace ir {
       return *data.f32;
     }
 
+    INLINE half getHalfValue(void) const {
+      GBE_ASSERT(type == IMM_TYPE_HALF);
+      return *data.f16;
+    }
+
+    INLINE half asHalfValue(void) const {
+      // we allow bitcast from u32/s32 immediate to float
+      GBE_ASSERT(type == IMM_TYPE_HALF || type == IMM_TYPE_U16 || type == IMM_TYPE_S16);
+      return *data.f16;
+    }
+
     INLINE int64_t asIntegerValue(void) const {
       GBE_ASSERT(elemNum == 1);
       return *data.s64;
@@ -245,6 +265,10 @@ namespace ir {
         case IMM_FPTOSI: *this = Immediate((int32_t)*other.data.f32); break;
         case IMM_UITOFP: *this = Immediate((float)*other.data.u32); break;
         case IMM_SITOFP: *this = Immediate((float)*other.data.s32); break;
+        case IMM_HFTOUS: *this = Immediate((uint16_t)*other.data.f16); break;
+        case IMM_HFTOSS: *this = Immediate((int16_t)*other.data.f16); break;
+        case IMM_USTOHF: *this = Immediate(half::convToHalf(*other.data.u16)); break;
+        case IMM_SSTOHF: *this = Immediate(half::convToHalf(*other.data.s16)); break;
         case IMM_SEXT:
         {
           int64_t value = other.getIntegerValue();
@@ -274,9 +298,20 @@ namespace ir {
         }
         case IMM_FPEXT:
         {
-          GBE_ASSERT(other.getType() == TYPE_FLOAT && dstType == TYPE_DOUBLE);
-          double value = other.getFloatValue();
-          *this = Immediate(value);
+          if (other.getType() == TYPE_FLOAT) {
+            GBE_ASSERT(dstType == TYPE_DOUBLE);
+            double value = other.getFloatValue();
+            *this = Immediate(value);
+          } else if (other.getType() == TYPE_HALF) {
+            GBE_ASSERT(dstType == TYPE_DOUBLE || dstType == TYPE_FLOAT);
+            if (dstType == TYPE_FLOAT) {
+              float value = other.getHalfValue();
+              *this = Immediate(value);
+            } else {
+              double value = other.getHalfValue();
+              *this = Immediate(value);
+            }
+          }
           break;
         }
       }
@@ -307,6 +342,7 @@ namespace ir {
       uint64_t *u64;
       float *f32;
       double *f64;
+      half *f16;
       const Immediate *immVec[];
       void *p;
     } data;     //!< Value to store
@@ -338,10 +374,12 @@ namespace ir {
   INLINE bool operator< (const Immediate &imm0, const Immediate &imm1) {
     if (imm0.getType() != imm1.getType())
       return uint32_t(imm0.getType()) < uint32_t(imm1.getType());
-    else if (imm0.getType() == TYPE_FLOAT || imm0.getType() == TYPE_DOUBLE)
+    else if (imm0.getType() == TYPE_FLOAT || imm0.getType() == TYPE_DOUBLE || imm0.getType() == TYPE_HALF)
       return imm0.asIntegerValue() < imm1.asIntegerValue();
     else
       return imm0.getIntegerValue() < imm1.getIntegerValue();
+
+    GBE_ASSERT(0);
   }
 
   /*! A value is stored in a per-function vector. This is the index to it */
-- 
1.9.1



More information about the Beignet mailing list