[Beignet] [PATCH 4/5] BDW: Add Gen8Encoder and Gen7Encoder.

Yang Rong rong.r.yang at intel.com
Sun Sep 28 22:37:18 PDT 2014


Class Gen8Encoder and Gen7Encoder derive from GenEncoder, and Gen75Encoder derive from Gen7Encode.
GenNativeInstruction is handled in class GenEncoder, Gen7NativeInstruction is handled in class
Gen7Encoder and Gen75Encoder, and Gen8NativeInstruction is handled in classe Gen8Encoder.
Disable Gen8's instruction compact temporary, should add compact and disassemble later.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 backend/src/CMakeLists.txt                |   6 +
 backend/src/backend/gen/gen_mesa_disasm.c |  21 +-
 backend/src/backend/gen75_encoder.cpp     |  58 ++--
 backend/src/backend/gen75_encoder.hpp     |   6 +-
 backend/src/backend/gen7_encoder.cpp      | 244 ++++++++++++++++
 backend/src/backend/gen7_encoder.hpp      |  51 ++++
 backend/src/backend/gen8_encoder.cpp      | 459 ++++++++++++++++++++++++++++++
 backend/src/backend/gen8_encoder.hpp      |  66 +++++
 backend/src/backend/gen_context.hpp       |   4 +-
 backend/src/backend/gen_defs.hpp          | 239 +---------------
 backend/src/backend/gen_encoder.cpp       | 212 +-------------
 backend/src/backend/gen_encoder.hpp       |  16 +-
 backend/src/backend/gen_insn_compact.cpp  |  19 +-
 13 files changed, 910 insertions(+), 491 deletions(-)
 create mode 100644 backend/src/backend/gen7_encoder.cpp
 create mode 100644 backend/src/backend/gen7_encoder.hpp
 create mode 100644 backend/src/backend/gen8_encoder.cpp
 create mode 100644 backend/src/backend/gen8_encoder.hpp

diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index e57227a..2daa630 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -99,12 +99,18 @@ set (GBE_SRC
     backend/gen_program.cpp
     backend/gen_program.hpp
     backend/gen_program.h
+    backend/gen7_instruction.hpp
+    backend/gen8_instruction.hpp
     backend/gen_defs.hpp
     backend/gen_insn_compact.cpp
     backend/gen_encoder.hpp
     backend/gen_encoder.cpp
+    backend/gen7_encoder.hpp
+    backend/gen7_encoder.cpp
     backend/gen75_encoder.hpp
     backend/gen75_encoder.cpp
+    backend/gen8_encoder.hpp
+    backend/gen8_encoder.cpp
     )
 
 
diff --git a/backend/src/backend/gen/gen_mesa_disasm.c b/backend/src/backend/gen/gen_mesa_disasm.c
index 266b501..1a53310 100644
--- a/backend/src/backend/gen/gen_mesa_disasm.c
+++ b/backend/src/backend/gen/gen_mesa_disasm.c
@@ -49,6 +49,7 @@
 #include <assert.h>
 
 #include "backend/gen_defs.hpp"
+#include "backend/gen7_instruction.hpp"
 #include "src/cl_device_data.h"
 
 static const struct {
@@ -566,7 +567,7 @@ static int reg (FILE *file, uint32_t _reg_file, uint32_t _reg_nr)
   return err;
 }
 
-static int dest (FILE *file, const union GenNativeInstruction *inst)
+static int dest (FILE *file, const union Gen7NativeInstruction *inst)
 {
   int	err = 0;
 
@@ -622,7 +623,7 @@ static int dest (FILE *file, const union GenNativeInstruction *inst)
   return 0;
 }
 
-static int dest_3src (FILE *file, const union GenNativeInstruction *inst)
+static int dest_3src (FILE *file, const union Gen7NativeInstruction *inst)
 {
   int	err = 0;
   const uint32_t reg_file = GEN_GENERAL_REGISTER_FILE;
@@ -755,7 +756,7 @@ static int src_da16 (FILE *file,
   return err;
 }
 
-static int src0_3src (FILE *file, const union GenNativeInstruction *inst)
+static int src0_3src (FILE *file, const union Gen7NativeInstruction *inst)
 {
   int err = 0;
   uint32_t swz_x = (inst->bits2.da3src.src0_swizzle >> 0) & 0x3;
@@ -803,7 +804,7 @@ static int src0_3src (FILE *file, const union GenNativeInstruction *inst)
   return err;
 }
 
-static int src1_3src (FILE *file, const union GenNativeInstruction *inst)
+static int src1_3src (FILE *file, const union Gen7NativeInstruction *inst)
 {
   int err = 0;
   uint32_t swz_x = (inst->bits2.da3src.src1_swizzle >> 0) & 0x3;
@@ -856,7 +857,7 @@ static int src1_3src (FILE *file, const union GenNativeInstruction *inst)
 }
 
 
-static int src2_3src (FILE *file, const union GenNativeInstruction *inst)
+static int src2_3src (FILE *file, const union Gen7NativeInstruction *inst)
 {
   int err = 0;
   uint32_t swz_x = (inst->bits3.da3src.src2_swizzle >> 0) & 0x3;
@@ -906,7 +907,7 @@ static int src2_3src (FILE *file, const union GenNativeInstruction *inst)
   return err;
 }
 
-static int imm (FILE *file, uint32_t type, const union GenNativeInstruction *inst) {
+static int imm (FILE *file, uint32_t type, const union Gen7NativeInstruction *inst) {
   switch (type) {
     case GEN_TYPE_UD:
       format (file, "0x%xUD", inst->bits3.ud);
@@ -935,7 +936,7 @@ static int imm (FILE *file, uint32_t type, const union GenNativeInstruction *ins
   return 0;
 }
 
-static int src0 (FILE *file, const union GenNativeInstruction *inst)
+static int src0 (FILE *file, const union Gen7NativeInstruction *inst)
 {
   if (inst->bits1.da1.src0_reg_file == GEN_IMMEDIATE_VALUE)
     return imm (file, inst->bits1.da1.src0_reg_type,
@@ -995,7 +996,7 @@ static int src0 (FILE *file, const union GenNativeInstruction *inst)
   }
 }
 
-static int src1 (FILE *file, const union GenNativeInstruction *inst)
+static int src1 (FILE *file, const union Gen7NativeInstruction *inst)
 {
   if (inst->bits1.da1.src1_reg_file == GEN_IMMEDIATE_VALUE)
     return imm (file, inst->bits1.da1.src1_reg_type,
@@ -1064,7 +1065,7 @@ static const int esize[6] = {
   [5] = 32,
 };
 
-static int qtr_ctrl(FILE *file, const union GenNativeInstruction *inst)
+static int qtr_ctrl(FILE *file, const union Gen7NativeInstruction *inst)
 {
   int qtr_ctl = inst->header.quarter_control;
   int exec_size = esize[inst->header.execution_size];
@@ -1095,7 +1096,7 @@ static int qtr_ctrl(FILE *file, const union GenNativeInstruction *inst)
 
 int gen_disasm (FILE *file, const void *opaque_insn, uint32_t deviceID, uint32_t compacted)
 {
-  const union GenNativeInstruction *inst = (const union GenNativeInstruction *) opaque_insn;
+  const union Gen7NativeInstruction *inst = (const union Gen7NativeInstruction *) opaque_insn;
   int	err = 0;
   int space = 0;
   int gen = 70;
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index 724865b..dcb0ab2 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -38,27 +38,28 @@ static const uint32_t untypedRWMask[] = {
 namespace gbe
 {
   void Gen75Encoder::setHeader(GenNativeInstruction *insn) {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
     if (this->curr.execWidth == 8)
-      insn->header.execution_size = GEN_WIDTH_8;
+      gen7_insn->header.execution_size = GEN_WIDTH_8;
     else if (this->curr.execWidth == 16)
-      insn->header.execution_size = GEN_WIDTH_16;
+      gen7_insn->header.execution_size = GEN_WIDTH_16;
     else if (this->curr.execWidth == 1)
-      insn->header.execution_size = GEN_WIDTH_1;
+      gen7_insn->header.execution_size = GEN_WIDTH_1;
     else if (this->curr.execWidth == 4)
-      insn->header.execution_size = GEN_WIDTH_4;
+      gen7_insn->header.execution_size = GEN_WIDTH_4;
     else
       NOT_IMPLEMENTED;
-    insn->header.acc_wr_control = this->curr.accWrEnable;
-    insn->header.quarter_control = this->curr.quarterControl;
-    insn->bits1.ia1.nib_ctrl = this->curr.nibControl;
-    insn->header.mask_control = this->curr.noMask;
-    insn->bits2.ia1.flag_reg_nr = this->curr.flag;
-    insn->bits2.ia1.flag_sub_reg_nr = this->curr.subFlag;
+    gen7_insn->header.acc_wr_control = this->curr.accWrEnable;
+    gen7_insn->header.quarter_control = this->curr.quarterControl;
+    gen7_insn->bits1.ia1.nib_ctrl = this->curr.nibControl;
+    gen7_insn->header.mask_control = this->curr.noMask;
+    gen7_insn->bits2.ia1.flag_reg_nr = this->curr.flag;
+    gen7_insn->bits2.ia1.flag_sub_reg_nr = this->curr.subFlag;
     if (this->curr.predicate != GEN_PREDICATE_NONE) {
-      insn->header.predicate_control = this->curr.predicate;
-      insn->header.predicate_inverse = this->curr.inversePredicate;
+      gen7_insn->header.predicate_control = this->curr.predicate;
+      gen7_insn->header.predicate_inverse = this->curr.inversePredicate;
     }
-    insn->header.saturate = this->curr.saturate;
+    gen7_insn->header.saturate = this->curr.saturate;
   }
 
   void Gen75Encoder::setDPUntypedRW(GenNativeInstruction *insn,
@@ -68,15 +69,16 @@ namespace gbe
                                     uint32_t msg_length,
                                     uint32_t response_length)
   {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
     setMessageDescriptor(insn, sfid, msg_length, response_length);
-    insn->bits3.gen7_untyped_rw.msg_type = msg_type;
-    insn->bits3.gen7_untyped_rw.bti = bti;
-    insn->bits3.gen7_untyped_rw.rgba = rgba;
+    gen7_insn->bits3.gen7_untyped_rw.msg_type = msg_type;
+    gen7_insn->bits3.gen7_untyped_rw.bti = bti;
+    gen7_insn->bits3.gen7_untyped_rw.rgba = rgba;
     if (curr.execWidth == 8)
-      insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD8;
+      gen7_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD8;
     else if (curr.execWidth == 16)
-      insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD16;
+      gen7_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD16;
     else
       NOT_SUPPORTED;
   }
@@ -84,17 +86,19 @@ namespace gbe
   void Gen75Encoder::setTypedWriteMessage(GenNativeInstruction *insn, unsigned char bti,
                                           unsigned char msg_type, uint32_t msg_length, bool header_present)
   {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
     setMessageDescriptor(insn, sfid, msg_length, 0, header_present);
-    insn->bits3.gen7_typed_rw.bti = bti;
-    insn->bits3.gen7_typed_rw.msg_type = msg_type;
+    gen7_insn->bits3.gen7_typed_rw.bti = bti;
+    gen7_insn->bits3.gen7_typed_rw.msg_type = msg_type;
 
     /* Always using the low 8 slots here. */
-    insn->bits3.gen7_typed_rw.slot = 1;
+    gen7_insn->bits3.gen7_typed_rw.slot = 1;
   }
 
   void Gen75Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
     uint32_t msg_length = 0;
     uint32_t response_length = 0;
 
@@ -114,15 +118,15 @@ namespace gbe
 
     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
     setMessageDescriptor(insn, sfid, msg_length, response_length);
-    insn->bits3.gen7_atomic_op.msg_type = GEN75_P1_UNTYPED_ATOMIC_OP;
-    insn->bits3.gen7_atomic_op.bti = bti;
-    insn->bits3.gen7_atomic_op.return_data = 1;
-    insn->bits3.gen7_atomic_op.aop_type = function;
+    gen7_insn->bits3.gen7_atomic_op.msg_type = GEN75_P1_UNTYPED_ATOMIC_OP;
+    gen7_insn->bits3.gen7_atomic_op.bti = bti;
+    gen7_insn->bits3.gen7_atomic_op.return_data = 1;
+    gen7_insn->bits3.gen7_atomic_op.aop_type = function;
 
     if (this->curr.execWidth == 8)
-      insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD8;
+      gen7_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD8;
     else if (this->curr.execWidth == 16)
-      insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD16;
+      gen7_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD16;
     else
       NOT_SUPPORTED;
   }
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index c10dac9..5490450 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -23,12 +23,14 @@
 #define __GBE_GEN75_ENCODER_HPP__
 
 #include "backend/gen_encoder.hpp"
+#include "backend/gen7_encoder.hpp"
+
 
 namespace gbe
 {
   /* This class is used to implement the HSW
      specific logic for encoder. */
-  class Gen75Encoder : public GenEncoder
+  class Gen75Encoder : public Gen7Encoder
   {
   public:
     /*! exec width of the double data type */    
@@ -36,7 +38,7 @@ namespace gbe
     virtual ~Gen75Encoder(void) { }
 
     Gen75Encoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID)
-         : GenEncoder(simdWidth, gen, deviceID) { }
+         : Gen7Encoder(simdWidth, gen, deviceID) { }
 
     /*! Jump indexed instruction */
     virtual void JMPI(GenRegister src, bool longjmp = false);
diff --git a/backend/src/backend/gen7_encoder.cpp b/backend/src/backend/gen7_encoder.cpp
new file mode 100644
index 0000000..ecf5b39
--- /dev/null
+++ b/backend/src/backend/gen7_encoder.cpp
@@ -0,0 +1,244 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+
+#include "backend/gen7_encoder.hpp"
+
+
+namespace gbe
+{
+  void Gen7Encoder::setHeader(GenNativeInstruction *insn) {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
+    if (this->curr.execWidth == 8)
+      gen7_insn->header.execution_size = GEN_WIDTH_8;
+    else if (this->curr.execWidth == 16)
+      gen7_insn->header.execution_size = GEN_WIDTH_16;
+    else if (this->curr.execWidth == 4)
+      gen7_insn->header.execution_size = GEN_WIDTH_4;
+    else if (this->curr.execWidth == 1)
+      gen7_insn->header.execution_size = GEN_WIDTH_1;
+    else
+      NOT_IMPLEMENTED;
+    gen7_insn->header.acc_wr_control = this->curr.accWrEnable;
+    gen7_insn->header.quarter_control = this->curr.quarterControl;
+    gen7_insn->bits1.ia1.nib_ctrl = this->curr.nibControl;
+    gen7_insn->header.mask_control = this->curr.noMask;
+    gen7_insn->bits2.ia1.flag_reg_nr = this->curr.flag;
+    gen7_insn->bits2.ia1.flag_sub_reg_nr = this->curr.subFlag;
+    if (this->curr.predicate != GEN_PREDICATE_NONE) {
+      gen7_insn->header.predicate_control = this->curr.predicate;
+      gen7_insn->header.predicate_inverse = this->curr.inversePredicate;
+    }
+    gen7_insn->header.saturate = this->curr.saturate;
+  }
+
+  void Gen7Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
+    if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
+      assert(dest.nr < 128);
+
+    gen7_insn->bits1.da1.dest_reg_file = dest.file;
+    gen7_insn->bits1.da1.dest_reg_type = dest.type;
+    gen7_insn->bits1.da1.dest_address_mode = dest.address_mode;
+    gen7_insn->bits1.da1.dest_reg_nr = dest.nr;
+    gen7_insn->bits1.da1.dest_subreg_nr = dest.subnr;
+    if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
+      if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
+        dest.hstride = GEN_HORIZONTAL_STRIDE_4;
+      else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
+        dest.hstride = GEN_HORIZONTAL_STRIDE_2;
+      else
+        dest.hstride = GEN_HORIZONTAL_STRIDE_1;
+    }
+    gen7_insn->bits1.da1.dest_horiz_stride = dest.hstride;
+  }
+
+  void Gen7Encoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
+    if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
+      assert(reg.nr < 128);
+
+    if (reg.address_mode == GEN_ADDRESS_DIRECT) {
+      gen7_insn->bits1.da1.src0_reg_file = reg.file;
+      gen7_insn->bits1.da1.src0_reg_type = reg.type;
+      gen7_insn->bits2.da1.src0_abs = reg.absolute;
+      gen7_insn->bits2.da1.src0_negate = reg.negation;
+      gen7_insn->bits2.da1.src0_address_mode = reg.address_mode;
+      if (reg.file == GEN_IMMEDIATE_VALUE) {
+        gen7_insn->bits3.ud = reg.value.ud;
+
+        /* Required to set some fields in src1 as well: */
+        gen7_insn->bits1.da1.src1_reg_file = 0; /* arf */
+        gen7_insn->bits1.da1.src1_reg_type = reg.type;
+      }
+      else {
+        if (gen7_insn->header.access_mode == GEN_ALIGN_1) {
+          gen7_insn->bits2.da1.src0_subreg_nr = reg.subnr;
+          gen7_insn->bits2.da1.src0_reg_nr = reg.nr;
+        } else {
+          gen7_insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
+          gen7_insn->bits2.da16.src0_reg_nr = reg.nr;
+        }
+
+        if (reg.width == GEN_WIDTH_1 &&
+            gen7_insn->header.execution_size == GEN_WIDTH_1) {
+          gen7_insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+          gen7_insn->bits2.da1.src0_width = GEN_WIDTH_1;
+          gen7_insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
+        }
+        else {
+          gen7_insn->bits2.da1.src0_horiz_stride = reg.hstride;
+          gen7_insn->bits2.da1.src0_width = reg.width;
+          gen7_insn->bits2.da1.src0_vert_stride = reg.vstride;
+        }
+      }
+    } else {
+      gen7_insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
+      gen7_insn->bits1.ia1.src0_reg_type = reg.type;
+      gen7_insn->bits2.ia1.src0_subreg_nr = 0;
+      gen7_insn->bits2.ia1.src0_indirect_offset = 0;
+      gen7_insn->bits2.ia1.src0_abs = 0;
+      gen7_insn->bits2.ia1.src0_negate = 0;
+      gen7_insn->bits2.ia1.src0_address_mode = reg.address_mode;
+      gen7_insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+      gen7_insn->bits2.ia1.src0_width = GEN_WIDTH_1;
+      gen7_insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
+    }
+  }
+
+  void Gen7Encoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
+    Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
+    assert(reg.nr < 128);
+    assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
+
+    gen7_insn->bits1.da1.src1_reg_file = reg.file;
+    gen7_insn->bits1.da1.src1_reg_type = reg.type;
+    gen7_insn->bits3.da1.src1_abs = reg.absolute;
+    gen7_insn->bits3.da1.src1_negate = reg.negation;
+
+    assert(gen7_insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
+
+    if (reg.file == GEN_IMMEDIATE_VALUE)
+      gen7_insn->bits3.ud = reg.value.ud;
+    else {
+      assert (reg.address_mode == GEN_ADDRESS_DIRECT);
+      if (gen7_insn->header.access_mode == GEN_ALIGN_1) {
+        gen7_insn->bits3.da1.src1_subreg_nr = reg.subnr;
+        gen7_insn->bits3.da1.src1_reg_nr = reg.nr;
+      } else {
+        gen7_insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
+        gen7_insn->bits3.da16.src1_reg_nr = reg.nr;
+      }
+
+      if (reg.width == GEN_WIDTH_1 &&
+          gen7_insn->header.execution_size == GEN_WIDTH_1) {
+        gen7_insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+        gen7_insn->bits3.da1.src1_width = GEN_WIDTH_1;
+        gen7_insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
+      } else {
+        gen7_insn->bits3.da1.src1_horiz_stride = reg.hstride;
+        gen7_insn->bits3.da1.src1_width = reg.width;
+        gen7_insn->bits3.da1.src1_vert_stride = reg.vstride;
+      }
+    }
+  }
+
+#define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
+
+  void Gen7Encoder::alu3(uint32_t opcode,
+                              GenRegister dest,
+                              GenRegister src0,
+                              GenRegister src1,
+                              GenRegister src2)
+  {
+     GenNativeInstruction *insn = this->next(opcode);
+     Gen7NativeInstruction *gen7_insn = &insn->gen7_insn;
+
+     assert(dest.file == GEN_GENERAL_REGISTER_FILE);
+     assert(dest.nr < 128);
+     assert(dest.address_mode == GEN_ADDRESS_DIRECT);
+     assert(dest.type = GEN_TYPE_F);
+     gen7_insn->bits1.da3src.dest_reg_file = 0;
+     gen7_insn->bits1.da3src.dest_reg_nr = dest.nr;
+     gen7_insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
+     gen7_insn->bits1.da3src.dest_writemask = 0xf;
+     this->setHeader(insn);
+     gen7_insn->header.access_mode = GEN_ALIGN_16;
+     gen7_insn->header.execution_size = GEN_WIDTH_8;
+
+     assert(src0.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src0.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src0.nr < 128);
+     assert(src0.type == GEN_TYPE_F);
+     gen7_insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
+     gen7_insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
+     gen7_insn->bits2.da3src.src0_reg_nr = src0.nr;
+     gen7_insn->bits1.da3src.src0_abs = src0.absolute;
+     gen7_insn->bits1.da3src.src0_negate = src0.negation;
+     gen7_insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
+
+     assert(src1.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src1.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src1.nr < 128);
+     assert(src1.type == GEN_TYPE_F);
+     gen7_insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
+     gen7_insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
+     gen7_insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
+     gen7_insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
+     gen7_insn->bits3.da3src.src1_reg_nr = src1.nr;
+     gen7_insn->bits1.da3src.src1_abs = src1.absolute;
+     gen7_insn->bits1.da3src.src1_negate = src1.negation;
+
+     assert(src2.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src2.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src2.nr < 128);
+     assert(src2.type == GEN_TYPE_F);
+     gen7_insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
+     gen7_insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
+     gen7_insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
+     gen7_insn->bits3.da3src.src2_reg_nr = src2.nr;
+     gen7_insn->bits1.da3src.src2_abs = src2.absolute;
+     gen7_insn->bits1.da3src.src2_negate = src2.negation;
+
+     // Emit second half of the instruction
+     if (this->curr.execWidth == 16) {
+      GenNativeInstruction q1Insn = *insn;
+      insn = this->next(opcode);
+      *insn = q1Insn;
+      gen7_insn = &insn->gen7_insn;
+      gen7_insn->header.quarter_control = GEN_COMPRESSION_Q2;
+      gen7_insn->bits1.da3src.dest_reg_nr++;
+      if (gen7_insn->bits2.da3src.src0_rep_ctrl == 0)
+        gen7_insn->bits2.da3src.src0_reg_nr++;
+      if (gen7_insn->bits2.da3src.src1_rep_ctrl == 0)
+        gen7_insn->bits3.da3src.src1_reg_nr++;
+      if (gen7_insn->bits3.da3src.src2_rep_ctrl == 0)
+        gen7_insn->bits3.da3src.src2_reg_nr++;
+     }
+  }
+
+#undef NO_SWIZZLE
+}
diff --git a/backend/src/backend/gen7_encoder.hpp b/backend/src/backend/gen7_encoder.hpp
new file mode 100644
index 0000000..416d6dc
--- /dev/null
+++ b/backend/src/backend/gen7_encoder.hpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file gen7_context.hpp
+ */
+#ifndef __GBE_GEN7_ENCODER_HPP__
+#define __GBE_GEN7_ENCODER_HPP__
+
+#include "backend/gen_encoder.hpp"
+
+namespace gbe
+{
+  /* This class is used to implement the HSW
+     specific logic for encoder. */
+  class Gen7Encoder : public GenEncoder
+  {
+  public:
+    /*! gen7 exec width of the double data type */
+    #define GEN7_DOUBLE_EXEC_WIDTH  8
+    virtual ~Gen7Encoder(void) { }
+
+    Gen7Encoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID)
+         : GenEncoder(simdWidth, gen, deviceID) { }
+
+    /*! Get double/long exec width */
+    virtual int getDoubleExecWidth(void) { return GEN7_DOUBLE_EXEC_WIDTH; }
+    virtual void setHeader(GenNativeInstruction *insn);
+    virtual void setDst(GenNativeInstruction *insn, GenRegister dest);
+    virtual void setSrc0(GenNativeInstruction *insn, GenRegister reg);
+    virtual void setSrc1(GenNativeInstruction *insn, GenRegister reg);
+    virtual void alu3(uint32_t opcode, GenRegister dst,
+                       GenRegister src0, GenRegister src1, GenRegister src2);
+  };
+}
+#endif /* __GBE_GEN7_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
new file mode 100644
index 0000000..6105634
--- /dev/null
+++ b/backend/src/backend/gen8_encoder.cpp
@@ -0,0 +1,459 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+
+#include "backend/gen8_encoder.hpp"
+
+static const uint32_t untypedRWMask[] = {
+  GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN|GEN_UNTYPED_RED,
+  GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN,
+  GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE,
+  GEN_UNTYPED_ALPHA,
+  0
+};
+
+namespace gbe
+{
+  void Gen8Encoder::setHeader(GenNativeInstruction *insn) {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    if (this->curr.execWidth == 8)
+      gen8_insn->header.execution_size = GEN_WIDTH_8;
+    else if (this->curr.execWidth == 16)
+      gen8_insn->header.execution_size = GEN_WIDTH_16;
+    else if (this->curr.execWidth == 1)
+      gen8_insn->header.execution_size = GEN_WIDTH_1;
+    else if (this->curr.execWidth == 4)
+      gen8_insn->header.execution_size = GEN_WIDTH_4;
+    else
+      NOT_IMPLEMENTED;
+    gen8_insn->header.acc_wr_control = this->curr.accWrEnable;
+    gen8_insn->header.quarter_control = this->curr.quarterControl;
+    gen8_insn->header.nib_ctrl = this->curr.nibControl;
+    gen8_insn->bits1.ia1.mask_control = this->curr.noMask;
+    gen8_insn->bits1.ia1.flag_reg_nr = this->curr.flag;
+    gen8_insn->bits1.ia1.flag_sub_reg_nr = this->curr.subFlag;
+    if (this->curr.predicate != GEN_PREDICATE_NONE) {
+      gen8_insn->header.predicate_control = this->curr.predicate;
+      gen8_insn->header.predicate_inverse = this->curr.inversePredicate;
+    }
+    gen8_insn->header.saturate = this->curr.saturate;
+  }
+
+  void Gen8Encoder::setDPUntypedRW(GenNativeInstruction *insn,
+                                    uint32_t bti,
+                                    uint32_t rgba,
+                                    uint32_t msg_type,
+                                    uint32_t msg_length,
+                                    uint32_t response_length)
+  {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
+    setMessageDescriptor(insn, sfid, msg_length, response_length);
+    gen8_insn->bits3.gen7_untyped_rw.msg_type = msg_type;
+    gen8_insn->bits3.gen7_untyped_rw.bti = bti;
+    gen8_insn->bits3.gen7_untyped_rw.rgba = rgba;
+    if (curr.execWidth == 8)
+      gen8_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD8;
+    else if (curr.execWidth == 16)
+      gen8_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD16;
+    else
+      NOT_SUPPORTED;
+  }
+
+  void Gen8Encoder::setTypedWriteMessage(GenNativeInstruction *insn, unsigned char bti,
+                                          unsigned char msg_type, uint32_t msg_length, bool header_present)
+  {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
+    setMessageDescriptor(insn, sfid, msg_length, 0, header_present);
+    gen8_insn->bits3.gen7_typed_rw.bti = bti;
+    gen8_insn->bits3.gen7_typed_rw.msg_type = msg_type;
+
+    /* Always using the low 8 slots here. */
+    gen8_insn->bits3.gen7_typed_rw.slot = 1;
+  }
+
+  void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum) {
+    GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    uint32_t msg_length = 0;
+    uint32_t response_length = 0;
+
+    if (this->curr.execWidth == 8) {
+      msg_length = srcNum;
+      response_length = 1;
+    } else if (this->curr.execWidth == 16) {
+      msg_length = 2 * srcNum;
+      response_length = 2;
+    } else
+      NOT_IMPLEMENTED;
+
+    this->setHeader(insn);
+    this->setDst(insn, GenRegister::uw16grf(dst.nr, 0));
+    this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
+    this->setSrc1(insn, GenRegister::immud(0));
+
+    const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA_CACHE;
+    setMessageDescriptor(insn, sfid, msg_length, response_length);
+    gen8_insn->bits3.gen7_atomic_op.msg_type = GEN75_P1_UNTYPED_ATOMIC_OP;
+    gen8_insn->bits3.gen7_atomic_op.bti = bti;
+    gen8_insn->bits3.gen7_atomic_op.return_data = 1;
+    gen8_insn->bits3.gen7_atomic_op.aop_type = function;
+
+    if (this->curr.execWidth == 8)
+      gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD8;
+    else if (this->curr.execWidth == 16)
+      gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD16;
+    else
+      NOT_SUPPORTED;
+  }
+
+  void Gen8Encoder::UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum) {
+    GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
+    assert(elemNum >= 1 || elemNum <= 4);
+    uint32_t msg_length = 0;
+    uint32_t response_length = 0;
+    if (this->curr.execWidth == 8) {
+      msg_length = 1;
+      response_length = elemNum;
+    } else if (this->curr.execWidth == 16) {
+      msg_length = 2;
+      response_length = 2 * elemNum;
+    } else
+      NOT_IMPLEMENTED;
+
+    this->setHeader(insn);
+    this->setDst(insn,  GenRegister::uw16grf(dst.nr, 0));
+    this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
+    this->setSrc1(insn, GenRegister::immud(0));
+    setDPUntypedRW(insn,
+                   bti,
+                   untypedRWMask[elemNum],
+                   GEN75_P1_UNTYPED_READ,
+                   msg_length,
+                   response_length);
+  }
+
+  void Gen8Encoder::UNTYPED_WRITE(GenRegister msg, uint32_t bti, uint32_t elemNum) {
+    GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
+    assert(elemNum >= 1 || elemNum <= 4);
+    uint32_t msg_length = 0;
+    uint32_t response_length = 0;
+    this->setHeader(insn);
+    if (this->curr.execWidth == 8) {
+      this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD));
+      msg_length = 1 + elemNum;
+    } else if (this->curr.execWidth == 16) {
+      this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UW));
+      msg_length = 2 * (1 + elemNum);
+    }
+    else
+      NOT_IMPLEMENTED;
+    this->setSrc0(insn, GenRegister::ud8grf(msg.nr, 0));
+    this->setSrc1(insn, GenRegister::immud(0));
+    setDPUntypedRW(insn,
+                   bti,
+                   untypedRWMask[elemNum],
+                   GEN75_P1_UNTYPED_SURFACE_WRITE,
+                   msg_length,
+                   response_length);
+  }
+
+  void Gen8Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
+    union { double d; unsigned u[2]; } u;
+    u.d = value;
+    GenRegister r = GenRegister::retype(tmp, GEN_TYPE_UD);
+    push();
+    curr.predicate = GEN_PREDICATE_NONE;
+    curr.noMask = 1;
+    curr.execWidth = 1;
+    MOV(r, GenRegister::immud(u.u[0]));
+    MOV(GenRegister::suboffset(r, 1), GenRegister::immud(u.u[1]));
+    pop();
+    r.type = GEN_TYPE_DF;
+    r.vstride = GEN_VERTICAL_STRIDE_0;
+    r.width = GEN_WIDTH_1;
+    r.hstride = GEN_HORIZONTAL_STRIDE_0;
+    push();
+    uint32_t width = curr.execWidth;
+    curr.execWidth = 8;
+    curr.predicate = GEN_PREDICATE_NONE;
+    curr.noMask = 1;
+    curr.quarterControl = GEN_COMPRESSION_Q1;
+    MOV(dest, r);
+    if (width == 16) {
+      curr.quarterControl = GEN_COMPRESSION_Q2;
+      MOV(GenRegister::offset(dest, 2), r);
+    }
+    pop();
+  }
+
+  void Gen8Encoder::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;
+    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;
+      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(GenRegister::suboffset(dest, 8), r0);
+      curr.nibControl = 1;
+      MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
+      pop();
+    }
+  }
+
+  void Gen8Encoder::JMPI(GenRegister src, bool longjmp) {
+    alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
+  }
+
+  void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jumpDistance) {
+    GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
+    GBE_ASSERT(insnID < this->store.size());
+    GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
+               insn.header.opcode == GEN_OPCODE_BRD  ||
+               insn.header.opcode == GEN_OPCODE_ENDIF ||
+               insn.header.opcode == GEN_OPCODE_IF ||
+               insn.header.opcode == GEN_OPCODE_BRC ||
+               insn.header.opcode == GEN_OPCODE_ELSE);
+
+    if (insn.header.opcode == GEN_OPCODE_IF) {
+      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+      return;
+    }
+    else if (insn.header.opcode == GEN_OPCODE_JMPI) {
+      //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
+      jumpDistance = (jumpDistance - 2) * 8;
+    }
+
+    this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+  }
+
+  void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
+      assert(dest.nr < 128);
+
+    gen8_insn->bits1.da1.dest_reg_file = dest.file;
+    gen8_insn->bits1.da1.dest_reg_type = dest.type;
+    gen8_insn->bits1.da1.dest_address_mode = dest.address_mode;
+    gen8_insn->bits1.da1.dest_reg_nr = dest.nr;
+    gen8_insn->bits1.da1.dest_subreg_nr = dest.subnr;
+    if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
+      if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
+        dest.hstride = GEN_HORIZONTAL_STRIDE_4;
+      else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
+        dest.hstride = GEN_HORIZONTAL_STRIDE_2;
+      else
+        dest.hstride = GEN_HORIZONTAL_STRIDE_1;
+    }
+    gen8_insn->bits1.da1.dest_horiz_stride = dest.hstride;
+  }
+
+  void Gen8Encoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
+      assert(reg.nr < 128);
+
+    if (reg.address_mode == GEN_ADDRESS_DIRECT) {
+      gen8_insn->bits1.da1.src0_reg_file = reg.file;
+      gen8_insn->bits1.da1.src0_reg_type = reg.type;
+      gen8_insn->bits2.da1.src0_abs = reg.absolute;
+      gen8_insn->bits2.da1.src0_negate = reg.negation;
+      gen8_insn->bits2.da1.src0_address_mode = reg.address_mode;
+      if (reg.file == GEN_IMMEDIATE_VALUE) {
+        gen8_insn->bits3.ud = reg.value.ud;
+
+        /* Required to set some fields in src1 as well: */
+        gen8_insn->bits2.da1.src1_reg_file = 0; /* arf */
+        gen8_insn->bits2.da1.src1_reg_type = reg.type;
+      }
+      else {
+        if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
+          gen8_insn->bits2.da1.src0_subreg_nr = reg.subnr;
+          gen8_insn->bits2.da1.src0_reg_nr = reg.nr;
+        } else {
+          gen8_insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
+          gen8_insn->bits2.da16.src0_reg_nr = reg.nr;
+        }
+
+        if (reg.width == GEN_WIDTH_1 &&
+            gen8_insn->header.execution_size == GEN_WIDTH_1) {
+          gen8_insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+          gen8_insn->bits2.da1.src0_width = GEN_WIDTH_1;
+          gen8_insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
+        }
+        else {
+          gen8_insn->bits2.da1.src0_horiz_stride = reg.hstride;
+          gen8_insn->bits2.da1.src0_width = reg.width;
+          gen8_insn->bits2.da1.src0_vert_stride = reg.vstride;
+        }
+      }
+    } else {
+      gen8_insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
+      gen8_insn->bits1.ia1.src0_reg_type = reg.type;
+      gen8_insn->bits2.ia1.src0_subreg_nr = 0;
+      gen8_insn->bits2.ia1.src0_indirect_offset = 0;
+      gen8_insn->bits2.ia1.src0_abs = 0;
+      gen8_insn->bits2.ia1.src0_negate = 0;
+      gen8_insn->bits2.ia1.src0_address_mode = reg.address_mode;
+      gen8_insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+      gen8_insn->bits2.ia1.src0_width = GEN_WIDTH_1;
+      gen8_insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
+    }
+  }
+
+  void Gen8Encoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
+    Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+    assert(reg.nr < 128);
+    assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
+
+    gen8_insn->bits2.da1.src1_reg_file = reg.file;
+    gen8_insn->bits2.da1.src1_reg_type = reg.type;
+    gen8_insn->bits3.da1.src1_abs = reg.absolute;
+    gen8_insn->bits3.da1.src1_negate = reg.negation;
+
+    assert(gen8_insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
+
+    if (reg.file == GEN_IMMEDIATE_VALUE)
+      gen8_insn->bits3.ud = reg.value.ud;
+    else {
+      assert (reg.address_mode == GEN_ADDRESS_DIRECT);
+      if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
+        gen8_insn->bits3.da1.src1_subreg_nr = reg.subnr;
+        gen8_insn->bits3.da1.src1_reg_nr = reg.nr;
+      } else {
+        gen8_insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
+        gen8_insn->bits3.da16.src1_reg_nr = reg.nr;
+      }
+
+      if (reg.width == GEN_WIDTH_1 &&
+          gen8_insn->header.execution_size == GEN_WIDTH_1) {
+        gen8_insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
+        gen8_insn->bits3.da1.src1_width = GEN_WIDTH_1;
+        gen8_insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
+      } else {
+        gen8_insn->bits3.da1.src1_horiz_stride = reg.hstride;
+        gen8_insn->bits3.da1.src1_width = reg.width;
+        gen8_insn->bits3.da1.src1_vert_stride = reg.vstride;
+      }
+    }
+  }
+
+#define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
+
+  void Gen8Encoder::alu3(uint32_t opcode,
+                              GenRegister dest,
+                              GenRegister src0,
+                              GenRegister src1,
+                              GenRegister src2)
+  {
+     GenNativeInstruction *insn = this->next(opcode);
+     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
+
+     assert(dest.file == GEN_GENERAL_REGISTER_FILE);
+     assert(dest.nr < 128);
+     assert(dest.address_mode == GEN_ADDRESS_DIRECT);
+     assert(dest.type = GEN_TYPE_F);
+     //gen8_insn->bits1.da3src.dest_reg_file = 0;
+     gen8_insn->bits1.da3src.dest_reg_nr = dest.nr;
+     gen8_insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
+     gen8_insn->bits1.da3src.dest_writemask = 0xf;
+     this->setHeader(insn);
+     gen8_insn->header.access_mode = GEN_ALIGN_16;
+     gen8_insn->header.execution_size = GEN_WIDTH_8;
+
+     assert(src0.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src0.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src0.nr < 128);
+     assert(src0.type == GEN_TYPE_F);
+     gen8_insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
+     gen8_insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
+     gen8_insn->bits2.da3src.src0_reg_nr = src0.nr;
+     gen8_insn->bits1.da3src.src0_abs = src0.absolute;
+     gen8_insn->bits1.da3src.src0_negate = src0.negation;
+     gen8_insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
+
+     assert(src1.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src1.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src1.nr < 128);
+     assert(src1.type == GEN_TYPE_F);
+     gen8_insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
+     gen8_insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
+     gen8_insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
+     gen8_insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
+     gen8_insn->bits3.da3src.src1_reg_nr = src1.nr;
+     gen8_insn->bits1.da3src.src1_abs = src1.absolute;
+     gen8_insn->bits1.da3src.src1_negate = src1.negation;
+
+     assert(src2.file == GEN_GENERAL_REGISTER_FILE);
+     assert(src2.address_mode == GEN_ADDRESS_DIRECT);
+     assert(src2.nr < 128);
+     assert(src2.type == GEN_TYPE_F);
+     gen8_insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
+     gen8_insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
+     gen8_insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
+     gen8_insn->bits3.da3src.src2_reg_nr = src2.nr;
+     gen8_insn->bits1.da3src.src2_abs = src2.absolute;
+     gen8_insn->bits1.da3src.src2_negate = src2.negation;
+
+     // Emit second half of the instruction
+     if (this->curr.execWidth == 16) {
+      GenNativeInstruction q1Insn = *insn;
+      insn = this->next(opcode);
+      *insn = q1Insn;
+      gen8_insn = &insn->gen8_insn;
+      gen8_insn->header.quarter_control = GEN_COMPRESSION_Q2;
+      gen8_insn->bits1.da3src.dest_reg_nr++;
+      if (gen8_insn->bits2.da3src.src0_rep_ctrl == 0)
+        gen8_insn->bits2.da3src.src0_reg_nr++;
+      if (gen8_insn->bits2.da3src.src1_rep_ctrl == 0)
+        gen8_insn->bits3.da3src.src1_reg_nr++;
+      if (gen8_insn->bits3.da3src.src2_rep_ctrl == 0)
+        gen8_insn->bits3.da3src.src2_reg_nr++;
+     }
+  }
+} /* End of the name space. */
diff --git a/backend/src/backend/gen8_encoder.hpp b/backend/src/backend/gen8_encoder.hpp
new file mode 100644
index 0000000..e962875
--- /dev/null
+++ b/backend/src/backend/gen8_encoder.hpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file gen8_context.hpp
+ */
+#ifndef __GBE_GEN8_ENCODER_HPP__
+#define __GBE_GEN8_ENCODER_HPP__
+
+#include "backend/gen_encoder.hpp"
+
+namespace gbe
+{
+  /* This class is used to implement the HSW
+     specific logic for encoder. */
+  class Gen8Encoder : public GenEncoder
+  {
+  public:
+    /*! exec width of the double data type */
+    #define GEN8_DOUBLE_EXEC_WIDTH  4
+    virtual ~Gen8Encoder(void) { }
+
+    Gen8Encoder(uint32_t simdWidth, uint32_t gen, uint32_t deviceID)
+         : GenEncoder(simdWidth, gen, deviceID) { }
+
+    /*! Jump indexed instruction */
+    virtual void JMPI(GenRegister src, bool longjmp = false);
+    /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
+    virtual void patchJMPI(uint32_t insnID, int32_t jumpDistance);
+    /*! Get double/long exec width */
+    virtual int getDoubleExecWidth(void) { return GEN8_DOUBLE_EXEC_WIDTH; }
+    virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
+    virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum);
+    virtual void UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum);
+    virtual void UNTYPED_WRITE(GenRegister src, uint32_t bti, uint32_t elemNum);
+    virtual void setHeader(GenNativeInstruction *insn);
+    virtual void setDPUntypedRW(GenNativeInstruction *insn, uint32_t bti, uint32_t rgba,
+                   uint32_t msg_type, uint32_t msg_length, uint32_t response_length);
+    virtual void setTypedWriteMessage(GenNativeInstruction *insn, unsigned char bti,
+                                      unsigned char msg_type, uint32_t msg_length,
+                                      bool header_present);
+    virtual void setDst(GenNativeInstruction *insn, GenRegister dest);
+    virtual void setSrc0(GenNativeInstruction *insn, GenRegister reg);
+    virtual void setSrc1(GenNativeInstruction *insn, GenRegister reg);
+    virtual bool disableCompact() { return true; }
+    virtual void alu3(uint32_t opcode, GenRegister dst,
+                       GenRegister src0, GenRegister src1, GenRegister src2);
+  };
+}
+#endif /* __GBE_GEN8_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index 4a01fd5..0e0e728 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -26,7 +26,7 @@
 #define __GBE_GEN_CONTEXT_HPP__
 
 #include "backend/context.hpp"
-#include "backend/gen_encoder.hpp"
+#include "backend/gen7_encoder.hpp"
 #include "backend/program.h"
 #include "backend/gen_register.hpp"
 #include "ir/function.hpp"
@@ -198,7 +198,7 @@ namespace gbe
 
   protected:
     virtual GenEncoder* generateEncoder(void) {
-      return GBE_NEW(GenEncoder, this->simdWidth, 7, deviceID);
+      return GBE_NEW(Gen7Encoder, this->simdWidth, 7, deviceID);
     }
     /*! allocate a new curbe register and insert to curbe pool. */
     void allocCurbeReg(ir::Register reg, gbe_curbe_type value, uint32_t subValue = 0);
diff --git a/backend/src/backend/gen_defs.hpp b/backend/src/backend/gen_defs.hpp
index 19aad95..9b9dcb8 100644
--- a/backend/src/backend/gen_defs.hpp
+++ b/backend/src/backend/gen_defs.hpp
@@ -52,6 +52,8 @@
 #define __GEN_DEFS_HPP__
 
 #include <stdint.h>
+#include "backend/gen7_instruction.hpp"
+#include "backend/gen8_instruction.hpp"
 
 /////////////////////////////////////////////////////////////////////////////
 // Gen EU defines
@@ -501,13 +503,16 @@ union GenNativeInstruction
     struct GenInstruction low;
     struct GenInstruction high;
   };
+  union Gen7NativeInstruction gen7_insn;
+  union Gen8NativeInstruction gen8_insn;
+
+  //Gen7 & Gen8 common field
   struct {
     struct {
       uint32_t opcode:7;
       uint32_t pad:1;
       uint32_t access_mode:1;
-      uint32_t mask_control:1;
-      uint32_t dependency_control:2;
+      uint32_t pad1:3;
       uint32_t quarter_control:2;
       uint32_t thread_control:2;
       uint32_t predicate_control:4;
@@ -520,222 +525,16 @@ union GenNativeInstruction
       uint32_t saturate:1;
     } header;
 
-    union {
-      struct {
-        uint32_t dest_reg_file:2;
-        uint32_t dest_reg_type:3;
-        uint32_t src0_reg_file:2;
-        uint32_t src0_reg_type:3;
-        uint32_t src1_reg_file:2;
-        uint32_t src1_reg_type:3;
-        uint32_t nib_ctrl:1;
-        uint32_t dest_subreg_nr:5;
-        uint32_t dest_reg_nr:8;
-        uint32_t dest_horiz_stride:2;
-        uint32_t dest_address_mode:1;
-      } da1;
-
-      struct {
-        uint32_t dest_reg_file:2;
-        uint32_t dest_reg_type:3;
-        uint32_t src0_reg_file:2;
-        uint32_t src0_reg_type:3;
-        uint32_t src1_reg_file:2;        /* 0x00000c00 */
-        uint32_t src1_reg_type:3;        /* 0x00007000 */
-        uint32_t nib_ctrl:1;
-        int dest_indirect_offset:10;        /* offset against the deref'd address reg */
-        uint32_t dest_subreg_nr:3; /* subnr for the address reg a0.x */
-        uint32_t dest_horiz_stride:2;
-        uint32_t dest_address_mode:1;
-      } ia1;
-
-      struct {
-        uint32_t dest_reg_file:2;
-        uint32_t dest_reg_type:3;
-        uint32_t src0_reg_file:2;
-        uint32_t src0_reg_type:3;
-        uint32_t src1_reg_file:2;
-        uint32_t src1_reg_type:3;
-        uint32_t nib_ctrl:1;
-        uint32_t dest_writemask:4;
-        uint32_t dest_subreg_nr:1;
-        uint32_t dest_reg_nr:8;
-        uint32_t dest_horiz_stride:2;
-        uint32_t dest_address_mode:1;
-      } da16;
-
-      struct {
-        uint32_t dest_reg_file:2;
-        uint32_t dest_reg_type:3;
-        uint32_t src0_reg_file:2;
-        uint32_t src0_reg_type:3;
-        uint32_t nib_ctrl:1;
-        uint32_t dest_writemask:4;
-        int dest_indirect_offset:6;
-        uint32_t dest_subreg_nr:3;
-        uint32_t dest_horiz_stride:2;
-        uint32_t dest_address_mode:1;
-      } ia16;
-
-      struct {
-        uint32_t dest_reg_file:2;
-        uint32_t dest_reg_type:3;
-        uint32_t src0_reg_file:2;
-        uint32_t src0_reg_type:3;
-        uint32_t src1_reg_file:2;
-        uint32_t src1_reg_type:3;
-        uint32_t pad:1;
-        int jump_count:16;
-      } branch_gen6;
-
-      struct {
-        uint32_t dest_reg_file:1;
-        uint32_t flag_subreg_num:1;
-        uint32_t pad0:2;
-        uint32_t src0_abs:1;
-        uint32_t src0_negate:1;
-        uint32_t src1_abs:1;
-        uint32_t src1_negate:1;
-        uint32_t src2_abs:1;
-        uint32_t src2_negate:1;
-        uint32_t pad1:7;
-        uint32_t dest_writemask:4;
-        uint32_t dest_subreg_nr:3;
-        uint32_t dest_reg_nr:8;
-      } da3src;
+    struct {
+      uint32_t pad1:32;
     } bits1;
 
-    union {
-      struct {
-        uint32_t src0_subreg_nr:5;
-        uint32_t src0_reg_nr:8;
-        uint32_t src0_abs:1;
-        uint32_t src0_negate:1;
-        uint32_t src0_address_mode:1;
-        uint32_t src0_horiz_stride:2;
-        uint32_t src0_width:3;
-        uint32_t src0_vert_stride:4;
-        uint32_t flag_sub_reg_nr:1;
-        uint32_t flag_reg_nr:1;
-        uint32_t pad:5;
-      } da1;
-
-      struct {
-        int src0_indirect_offset:10;
-        uint32_t src0_subreg_nr:3;
-        uint32_t src0_abs:1;
-        uint32_t src0_negate:1;
-        uint32_t src0_address_mode:1;
-        uint32_t src0_horiz_stride:2;
-        uint32_t src0_width:3;
-        uint32_t src0_vert_stride:4;
-        uint32_t flag_sub_reg_nr:1;
-        uint32_t flag_reg_nr:1;
-        uint32_t pad:5;
-      } ia1;
-
-      struct {
-        uint32_t src0_swz_x:2;
-        uint32_t src0_swz_y:2;
-        uint32_t src0_subreg_nr:1;
-        uint32_t src0_reg_nr:8;
-        uint32_t src0_abs:1;
-        uint32_t src0_negate:1;
-        uint32_t src0_address_mode:1;
-        uint32_t src0_swz_z:2;
-        uint32_t src0_swz_w:2;
-        uint32_t pad0:1;
-        uint32_t src0_vert_stride:4;
-        uint32_t flag_sub_reg_nr:1;
-        uint32_t flag_reg_nr:1;
-        uint32_t pad:5;
-      } da16;
-
-      struct {
-        uint32_t src0_swz_x:2;
-        uint32_t src0_swz_y:2;
-        int src0_indirect_offset:6;
-        uint32_t src0_subreg_nr:3;
-        uint32_t src0_abs:1;
-        uint32_t src0_negate:1;
-        uint32_t src0_address_mode:1;
-        uint32_t src0_swz_z:2;
-        uint32_t src0_swz_w:2;
-        uint32_t pad0:1;
-        uint32_t src0_vert_stride:4;
-        uint32_t flag_sub_reg_nr:1;
-        uint32_t flag_reg_nr:1;
-        uint32_t pad:5;
-      } ia16;
-
-      struct {
-        uint32_t src0_rep_ctrl:1;
-        uint32_t src0_swizzle:8;
-        uint32_t src0_subreg_nr:3;
-        uint32_t src0_reg_nr:8;
-        uint32_t pad0:1;
-        uint32_t src1_rep_ctrl:1;
-        uint32_t src1_swizzle:8;
-        uint32_t src1_subreg_nr_low:2;
-      } da3src;
+    struct {
+      uint32_t pad2:32;
     } bits2;
 
     union {
       struct {
-        uint32_t src1_subreg_nr:5;
-        uint32_t src1_reg_nr:8;
-        uint32_t src1_abs:1;
-        uint32_t src1_negate:1;
-        uint32_t src1_address_mode:1;
-        uint32_t src1_horiz_stride:2;
-        uint32_t src1_width:3;
-        uint32_t src1_vert_stride:4;
-        uint32_t pad0:7;
-      } da1;
-
-      struct {
-        uint32_t src1_swz_x:2;
-        uint32_t src1_swz_y:2;
-        uint32_t src1_subreg_nr:1;
-        uint32_t src1_reg_nr:8;
-        uint32_t src1_abs:1;
-        uint32_t src1_negate:1;
-        uint32_t src1_address_mode:1;
-        uint32_t src1_swz_z:2;
-        uint32_t src1_swz_w:2;
-        uint32_t pad1:1;
-        uint32_t src1_vert_stride:4;
-        uint32_t pad2:7;
-      } da16;
-
-      struct {
-        int  src1_indirect_offset:10;
-        uint32_t src1_subreg_nr:3;
-        uint32_t src1_abs:1;
-        uint32_t src1_negate:1;
-        uint32_t src1_address_mode:1;
-        uint32_t src1_horiz_stride:2;
-        uint32_t src1_width:3;
-        uint32_t src1_vert_stride:4;
-        uint32_t pad1:7;
-      } ia1;
-
-      struct {
-        uint32_t src1_swz_x:2;
-        uint32_t src1_swz_y:2;
-        int  src1_indirect_offset:6;
-        uint32_t src1_subreg_nr:3;
-        uint32_t src1_abs:1;
-        uint32_t src1_negate:1;
-        uint32_t pad0:1;
-        uint32_t src1_swz_z:2;
-        uint32_t src1_swz_w:2;
-        uint32_t pad1:1;
-        uint32_t src1_vert_stride:4;
-        uint32_t pad2:7;
-      } ia16;
-
-      struct {
         uint32_t function_control:19;
         uint32_t header_present:1;
         uint32_t response_length:5;
@@ -934,17 +733,6 @@ union GenNativeInstruction
         uint32_t end_of_thread:1;
       } gen7_atomic_op;
 
-      struct {
-        uint32_t src1_subreg_nr_high:1;
-        uint32_t src1_reg_nr:8;
-        uint32_t pad0:1;
-        uint32_t src2_rep_ctrl:1;
-        uint32_t src2_swizzle:8;
-        uint32_t src2_subreg_nr:3;
-        uint32_t src2_reg_nr:8;
-        uint32_t pad1:2;
-      } da3src;
-
       /*! Message gateway */
       struct {
         uint32_t subfunc:3;
@@ -960,9 +748,8 @@ union GenNativeInstruction
       } gen7_msg_gw;
 
       struct {
-        uint32_t jip:16;
-        uint32_t uip:16;
-      } gen7_branch;
+        uint32_t jip:32;
+      } gen8_branch;
 
       int d;
       uint32_t ud;
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 295e11d..9b84d5b 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -241,139 +241,6 @@ namespace gbe
     curr = stack[--stateNum];
   }
 
-  void GenEncoder::setHeader(GenNativeInstruction *insn) {
-    if (this->curr.execWidth == 8)
-      insn->header.execution_size = GEN_WIDTH_8;
-    else if (this->curr.execWidth == 16)
-      insn->header.execution_size = GEN_WIDTH_16;
-    else if (this->curr.execWidth == 4)
-      insn->header.execution_size = GEN_WIDTH_4;
-    else if (this->curr.execWidth == 1)
-      insn->header.execution_size = GEN_WIDTH_1;
-    else
-      NOT_IMPLEMENTED;
-    insn->header.acc_wr_control = this->curr.accWrEnable;
-    insn->header.quarter_control = this->curr.quarterControl;
-    insn->bits1.ia1.nib_ctrl = this->curr.nibControl;
-    insn->header.mask_control = this->curr.noMask;
-    insn->bits2.ia1.flag_reg_nr = this->curr.flag;
-    insn->bits2.ia1.flag_sub_reg_nr = this->curr.subFlag;
-    if (this->curr.predicate != GEN_PREDICATE_NONE) {
-      insn->header.predicate_control = this->curr.predicate;
-      insn->header.predicate_inverse = this->curr.inversePredicate;
-    }
-    insn->header.saturate = this->curr.saturate;
-  }
-
-  void GenEncoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
-     if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
-        assert(dest.nr < 128);
-
-     insn->bits1.da1.dest_reg_file = dest.file;
-     insn->bits1.da1.dest_reg_type = dest.type;
-     insn->bits1.da1.dest_address_mode = dest.address_mode;
-     insn->bits1.da1.dest_reg_nr = dest.nr;
-     insn->bits1.da1.dest_subreg_nr = dest.subnr;
-     if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
-       if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
-         dest.hstride = GEN_HORIZONTAL_STRIDE_4;
-       else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
-         dest.hstride = GEN_HORIZONTAL_STRIDE_2;
-       else
-         dest.hstride = GEN_HORIZONTAL_STRIDE_1;
-     }
-     insn->bits1.da1.dest_horiz_stride = dest.hstride;
-  }
-
-  void GenEncoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
-     if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
-        assert(reg.nr < 128);
-
-     if (reg.address_mode == GEN_ADDRESS_DIRECT) {
-       insn->bits1.da1.src0_reg_file = reg.file;
-       insn->bits1.da1.src0_reg_type = reg.type;
-       insn->bits2.da1.src0_abs = reg.absolute;
-       insn->bits2.da1.src0_negate = reg.negation;
-       insn->bits2.da1.src0_address_mode = reg.address_mode;
-
-       if (reg.file == GEN_IMMEDIATE_VALUE) {
-          insn->bits3.ud = reg.value.ud;
-
-          /* Required to set some fields in src1 as well: */
-          insn->bits1.da1.src1_reg_file = 0; /* arf */
-          insn->bits1.da1.src1_reg_type = reg.type;
-       }
-       else {
-         if (insn->header.access_mode == GEN_ALIGN_1) {
-           insn->bits2.da1.src0_subreg_nr = reg.subnr;
-           insn->bits2.da1.src0_reg_nr = reg.nr;
-         } else {
-           insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
-           insn->bits2.da16.src0_reg_nr = reg.nr;
-         }
-
-         if (reg.width == GEN_WIDTH_1 &&
-             insn->header.execution_size == GEN_WIDTH_1) {
-           insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
-           insn->bits2.da1.src0_width = GEN_WIDTH_1;
-           insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
-         }
-         else {
-           insn->bits2.da1.src0_horiz_stride = reg.hstride;
-           insn->bits2.da1.src0_width = reg.width;
-           insn->bits2.da1.src0_vert_stride = reg.vstride;
-         }
-       }
-    } else {
-       insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
-       insn->bits1.ia1.src0_reg_type = reg.type;
-       insn->bits2.ia1.src0_subreg_nr = 0;
-       insn->bits2.ia1.src0_indirect_offset = 0;
-       insn->bits2.ia1.src0_abs = 0;
-       insn->bits2.ia1.src0_negate = 0;
-       insn->bits2.ia1.src0_address_mode = reg.address_mode;
-       insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
-       insn->bits2.ia1.src0_width = GEN_WIDTH_1;
-       insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
-    }
-  }
-
-  void GenEncoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
-     assert(reg.nr < 128);
-     assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
-
-     insn->bits1.da1.src1_reg_file = reg.file;
-     insn->bits1.da1.src1_reg_type = reg.type;
-     insn->bits3.da1.src1_abs = reg.absolute;
-     insn->bits3.da1.src1_negate = reg.negation;
-
-     assert(insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
-
-     if (reg.file == GEN_IMMEDIATE_VALUE)
-       insn->bits3.ud = reg.value.ud;
-     else {
-       assert (reg.address_mode == GEN_ADDRESS_DIRECT);
-       if (insn->header.access_mode == GEN_ALIGN_1) {
-         insn->bits3.da1.src1_subreg_nr = reg.subnr;
-         insn->bits3.da1.src1_reg_nr = reg.nr;
-       } else {
-         insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
-         insn->bits3.da16.src1_reg_nr = reg.nr;
-       }
-
-       if (reg.width == GEN_WIDTH_1 &&
-           insn->header.execution_size == GEN_WIDTH_1) {
-         insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
-         insn->bits3.da1.src1_width = GEN_WIDTH_1;
-         insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
-       } else {
-         insn->bits3.da1.src1_horiz_stride = reg.hstride;
-         insn->bits3.da1.src1_width = reg.width;
-         insn->bits3.da1.src1_vert_stride = reg.vstride;
-       }
-     }
-  }
-
   static const uint32_t untypedRWMask[] = {
     GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN|GEN_UNTYPED_RED,
     GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN,
@@ -695,83 +562,6 @@ namespace gbe
     }
   }
 
-#define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
-
-  static GenNativeInstruction *alu3(GenEncoder *p,
-                              uint32_t opcode,
-                              GenRegister dest,
-                              GenRegister src0,
-                              GenRegister src1,
-                              GenRegister src2)
-  {
-     GenNativeInstruction *insn = p->next(opcode);
-
-     assert(dest.file == GEN_GENERAL_REGISTER_FILE);
-     assert(dest.nr < 128);
-     assert(dest.address_mode == GEN_ADDRESS_DIRECT);
-     assert(dest.type = GEN_TYPE_F);
-     insn->bits1.da3src.dest_reg_file = 0;
-     insn->bits1.da3src.dest_reg_nr = dest.nr;
-     insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
-     insn->bits1.da3src.dest_writemask = 0xf;
-     p->setHeader(insn);
-     insn->header.access_mode = GEN_ALIGN_16;
-     insn->header.execution_size = GEN_WIDTH_8;
-
-     assert(src0.file == GEN_GENERAL_REGISTER_FILE);
-     assert(src0.address_mode == GEN_ADDRESS_DIRECT);
-     assert(src0.nr < 128);
-     assert(src0.type == GEN_TYPE_F);
-     insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
-     insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
-     insn->bits2.da3src.src0_reg_nr = src0.nr;
-     insn->bits1.da3src.src0_abs = src0.absolute;
-     insn->bits1.da3src.src0_negate = src0.negation;
-     insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
-
-     assert(src1.file == GEN_GENERAL_REGISTER_FILE);
-     assert(src1.address_mode == GEN_ADDRESS_DIRECT);
-     assert(src1.nr < 128);
-     assert(src1.type == GEN_TYPE_F);
-     insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
-     insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
-     insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
-     insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
-     insn->bits3.da3src.src1_reg_nr = src1.nr;
-     insn->bits1.da3src.src1_abs = src1.absolute;
-     insn->bits1.da3src.src1_negate = src1.negation;
-
-     assert(src2.file == GEN_GENERAL_REGISTER_FILE);
-     assert(src2.address_mode == GEN_ADDRESS_DIRECT);
-     assert(src2.nr < 128);
-     assert(src2.type == GEN_TYPE_F);
-     insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
-     insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
-     insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
-     insn->bits3.da3src.src2_reg_nr = src2.nr;
-     insn->bits1.da3src.src2_abs = src2.absolute;
-     insn->bits1.da3src.src2_negate = src2.negation;
-
-     // Emit second half of the instruction
-     if (p->curr.execWidth == 16) {
-      GenNativeInstruction q1Insn = *insn;
-      insn = p->next(opcode);
-      *insn = q1Insn;
-      insn->header.quarter_control = GEN_COMPRESSION_Q2;
-      insn->bits1.da3src.dest_reg_nr++;
-      if (insn->bits2.da3src.src0_rep_ctrl == 0)
-        insn->bits2.da3src.src0_reg_nr++;
-      if (insn->bits2.da3src.src1_rep_ctrl == 0)
-        insn->bits3.da3src.src1_reg_nr++;
-      if (insn->bits3.da3src.src2_rep_ctrl == 0)
-        insn->bits3.da3src.src2_reg_nr++;
-     }
-
-     return insn;
-  }
-
-#undef NO_SWIZZLE
-
 #define ALU1(OP) \
   void GenEncoder::OP(GenRegister dest, GenRegister src0, uint32_t condition) { \
     alu1(this, GEN_OPCODE_##OP, dest, src0, condition); \
@@ -790,7 +580,7 @@ namespace gbe
 
 #define ALU3(OP) \
   void GenEncoder::OP(GenRegister dest, GenRegister src0, GenRegister src1, GenRegister src2) { \
-    alu3(this, GEN_OPCODE_##OP, dest, src0, src1, src2); \
+    this->alu3(GEN_OPCODE_##OP, dest, src0, src1, src2); \
   }
 
   void GenEncoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 2c999ce..c8dc113 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -70,8 +70,6 @@ namespace gbe
     virtual ~GenEncoder(void) { }
     /*! Size of the stack (should be large enough) */
     enum { MAX_STATE_NUM = 16 };
-    /*! gen7 exec width of the double data type */
-    #define GEN7_DOUBLE_EXEC_WIDTH  8
     /*! Push the current instruction state */
     void push(void);
     /*! Pop the latest pushed state */
@@ -138,7 +136,7 @@ namespace gbe
 #undef ALU2_MOD
 #undef ALU3
     /*! Get double/long exec width */
-    virtual int getDoubleExecWidth(void) { return GEN7_DOUBLE_EXEC_WIDTH; }
+    virtual int getDoubleExecWidth(void) = 0;
     virtual void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
     virtual void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
     void LOAD_INT64_IMM(GenRegister dest, int64_t value);
@@ -214,7 +212,6 @@ namespace gbe
     ////////////////////////////////////////////////////////////////////////
     // Helper functions to encode
     ////////////////////////////////////////////////////////////////////////
-    virtual void setHeader(GenNativeInstruction *insn);
     virtual void setDPUntypedRW(GenNativeInstruction *insn, uint32_t bti, uint32_t rgba,
                                 uint32_t msg_type, uint32_t msg_length,
                                 uint32_t response_length);
@@ -224,13 +221,18 @@ namespace gbe
     void setMessageDescriptor(GenNativeInstruction *inst, enum GenMessageTarget sfid,
                               unsigned msg_length, unsigned response_length,
                               bool header_present = false, bool end_of_thread = false);
-    void setDst(GenNativeInstruction *insn, GenRegister dest);
-    void setSrc0(GenNativeInstruction *insn, GenRegister reg);
-    void setSrc1(GenNativeInstruction *insn, GenRegister reg);
+    virtual void setHeader(GenNativeInstruction *insn) = 0;
+    virtual void setDst(GenNativeInstruction *insn, GenRegister dest) = 0;
+    virtual void setSrc0(GenNativeInstruction *insn, GenRegister reg) = 0;
+    virtual void setSrc1(GenNativeInstruction *insn, GenRegister reg) = 0;
     GenCompactInstruction *nextCompact(uint32_t opcode);
+    virtual bool disableCompact() { return false; }
     GenNativeInstruction *next(uint32_t opcode);
     uint32_t n_instruction(void) const { return store.size(); }
     GBE_CLASS(GenEncoder); //!< Use custom allocators
+
+    virtual void alu3(uint32_t opcode, GenRegister dst,
+                       GenRegister src0, GenRegister src1, GenRegister src2) = 0;
   };
 
   void alu1(GenEncoder *p, uint32_t opcode, GenRegister dst,
diff --git a/backend/src/backend/gen_insn_compact.cpp b/backend/src/backend/gen_insn_compact.cpp
index 17b3e55..d5e1597 100644
--- a/backend/src/backend/gen_insn_compact.cpp
+++ b/backend/src/backend/gen_insn_compact.cpp
@@ -261,12 +261,13 @@ namespace gbe {
   };
 
   void decompactInstruction(GenCompactInstruction * p, void *insn) {
-    GenNativeInstruction *pOut = (union GenNativeInstruction *) insn;
+    Gen7NativeInstruction *pOut = (union Gen7NativeInstruction *) insn;
+    GenNativeInstruction *pNative = (union GenNativeInstruction *) insn;
 
-    memset(pOut, 0, sizeof(GenNativeInstruction));
+    memset(pOut, 0, sizeof(Gen7NativeInstruction));
     union ControlBits control_bits;
     control_bits.data = control_table[(uint32_t)p->bits1.control_index].bit_pattern;
-    pOut->low.low = (uint32_t)p->bits1.opcode | ((control_bits.data & 0xffff) << 8);
+    pNative->low.low = (uint32_t)p->bits1.opcode | ((control_bits.data & 0xffff) << 8);
     pOut->header.destreg_or_condmod = p->bits1.destreg_or_condmod;
     pOut->header.saturate = control_bits.saturate;
     pOut->header.acc_wr_control = p->bits1.acc_wr_control;
@@ -280,7 +281,7 @@ namespace gbe {
     subreg_bits.data = subreg_table[(uint32_t)p->bits1.sub_reg_index].bit_pattern;
     src0_bits.data = srcreg_table[p->bits1.src0_index_lo | p->bits2.src0_index_hi << 2].bit_pattern;
 
-    pOut->low.high |= data_type_bits.data & 0x7fff;
+    pNative->low.high |= data_type_bits.data & 0x7fff;
     pOut->bits1.da1.dest_horiz_stride = data_type_bits.dest_horiz_stride;
     pOut->bits1.da1.dest_address_mode = data_type_bits.dest_address_mode;
     pOut->bits1.da1.dest_reg_nr = p->bits2.dest_reg_nr;
@@ -288,7 +289,7 @@ namespace gbe {
 
     pOut->bits2.da1.src0_subreg_nr = subreg_bits.src0_subreg_nr;
     pOut->bits2.da1.src0_reg_nr = p->bits2.src0_reg_nr;
-    pOut->high.low |= (src0_bits.data << 13);
+    pNative->high.low |= (src0_bits.data << 13);
     pOut->bits2.da1.flag_sub_reg_nr = control_bits.flag_sub_reg_nr;
     pOut->bits2.da1.flag_reg_nr = control_bits.flag_reg_nr;
 
@@ -300,7 +301,7 @@ namespace gbe {
       src1_bits.data = srcreg_table[p->bits2.src1_index].bit_pattern;
       pOut->bits3.da1.src1_subreg_nr = subreg_bits.src1_subreg_nr;
       pOut->bits3.da1.src1_reg_nr = p->bits2.src1_reg_nr;
-      pOut->high.high |= (src1_bits.data << 13);
+      pNative->high.high |= (src1_bits.data << 13);
     }
   }
 
@@ -439,6 +440,9 @@ namespace gbe {
   }
 
   bool compactAlu1(GenEncoder *p, uint32_t opcode, GenRegister dst, GenRegister src, uint32_t condition, bool split) {
+    if(p->disableCompact())
+      return false;
+
     if(split) {
       // TODO support it
       return false;
@@ -474,6 +478,9 @@ namespace gbe {
   }
 
   bool compactAlu2(GenEncoder *p, uint32_t opcode, GenRegister dst, GenRegister src0, GenRegister src1, uint32_t condition, bool split) {
+    if(p->disableCompact())
+      return false;
+
     if(split) {
       // TODO support it
       return false;
-- 
1.8.3.2



More information about the Beignet mailing list