Use a separate pattern for simd shuffle instead of binary pattern

Submitted by Guo Yejun on July 15, 2015, 2 p.m.

Details

Message ID 1436968830-30752-1-git-send-email-yejun.guo@intel.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Guo Yejun July 15, 2015, 2 p.m.
the binary pattern assumes the two src operands have the same type,
while simd shuffle is not the case, so add a separate pattern for it.

Signed-off-by: Guo Yejun <yejun.guo@intel.com>
---
 backend/src/backend/gen8_context.cpp               | 38 ++++++------
 backend/src/backend/gen8_context.hpp               |  1 +
 backend/src/backend/gen_context.cpp                | 68 ++++++++++++----------
 backend/src/backend/gen_context.hpp                |  1 +
 .../src/backend/gen_insn_gen7_schedule_info.hxx    |  1 +
 backend/src/backend/gen_insn_selection.cpp         | 55 +++++++++++++----
 backend/src/backend/gen_insn_selection.hxx         |  2 +-
 backend/src/ir/instruction.cpp                     | 24 +++++++-
 backend/src/ir/instruction.hpp                     |  8 +++
 backend/src/ir/instruction.hxx                     |  2 +-
 10 files changed, 136 insertions(+), 64 deletions(-)

Patch hide | download patch | download mbox

diff --git a/backend/src/backend/gen8_context.cpp b/backend/src/backend/gen8_context.cpp
index 69d3916..284e0a3 100644
--- a/backend/src/backend/gen8_context.cpp
+++ b/backend/src/backend/gen8_context.cpp
@@ -236,6 +236,27 @@  namespace gbe
     }
   }
 
+  void Gen8Context::emitSimdShuffleInstruction(const SelectionInstruction &insn) {
+    const GenRegister dst = ra->genReg(insn.dst(0));
+    const GenRegister src0 = ra->genReg(insn.src(0));
+    const GenRegister src1 = ra->genReg(insn.src(1));
+    assert(insn.opcode == SEL_OP_SIMD_SHUFFLE);
+
+    uint32_t simd = p->curr.execWidth;
+    if (src1.file == GEN_IMMEDIATE_VALUE) {
+      uint32_t offset = src1.value.ud % simd;
+      GenRegister reg = GenRegister::suboffset(src0, offset);
+      p->MOV(dst, GenRegister::retype(GenRegister::ud1grf(reg.nr, reg.subnr / typeSize(reg.type)), reg.type));
+    } else {
+      uint32_t base = src0.nr * 32 + src0.subnr * 4;
+      GenRegister baseReg = GenRegister::immuw(base);
+      const GenRegister a0 = GenRegister::addr8(0);
+      p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
+      GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
+      p->MOV(dst, indirect);
+    }
+  }
+
   void Gen8Context::emitBinaryInstruction(const SelectionInstruction &insn) {
     const GenRegister dst = ra->genReg(insn.dst(0));
     const GenRegister src0 = ra->genReg(insn.src(0));
@@ -255,23 +276,6 @@  namespace gbe
         p->ADD(dst, dst, src1);
         break;
       }
-      case SEL_OP_SIMD_SHUFFLE:
-      {
-        uint32_t simd = p->curr.execWidth;
-        if (src1.file == GEN_IMMEDIATE_VALUE) {
-          uint32_t offset = src1.value.ud % simd;
-          GenRegister reg = GenRegister::suboffset(src0, offset);
-          p->MOV(dst, GenRegister::retype(GenRegister::ud1grf(reg.nr, reg.subnr / typeSize(reg.type)), reg.type));
-        } else {
-          uint32_t base = src0.nr * 32 + src0.subnr * 4;
-          GenRegister baseReg = GenRegister::immuw(base);
-          const GenRegister a0 = GenRegister::addr8(0);
-          p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
-          GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
-          p->MOV(dst, indirect);
-        }
-        break;
-      }
       default:
         GenContext::emitBinaryInstruction(insn);
     }
diff --git a/backend/src/backend/gen8_context.hpp b/backend/src/backend/gen8_context.hpp
index 8827955..364824b 100644
--- a/backend/src/backend/gen8_context.hpp
+++ b/backend/src/backend/gen8_context.hpp
@@ -50,6 +50,7 @@  namespace gbe
 
     virtual void emitUnaryInstruction(const SelectionInstruction &insn);
     virtual void emitUnaryWithTempInstruction(const SelectionInstruction &insn);
+    virtual void emitSimdShuffleInstruction(const SelectionInstruction &insn);
     virtual void emitBinaryInstruction(const SelectionInstruction &insn);
     virtual void emitBinaryWithTempInstruction(const SelectionInstruction &insn);
     virtual void emitI64MULHIInstruction(const SelectionInstruction &insn);
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index db27377..e16b0a9 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -545,6 +545,42 @@  namespace gbe
     }
   }
 
+  void GenContext::emitSimdShuffleInstruction(const SelectionInstruction &insn) {
+    const GenRegister dst = ra->genReg(insn.dst(0));
+    const GenRegister src0 = ra->genReg(insn.src(0));
+    const GenRegister src1 = ra->genReg(insn.src(1));
+    assert(insn.opcode == SEL_OP_SIMD_SHUFFLE);
+
+    uint32_t simd = p->curr.execWidth;
+    if (src1.file == GEN_IMMEDIATE_VALUE) {
+      uint32_t offset = src1.value.ud % simd;
+      GenRegister reg = GenRegister::suboffset(src0, offset);
+      p->MOV(dst, GenRegister::retype(GenRegister::ud1grf(reg.nr, reg.subnr / typeSize(reg.type)), reg.type));
+    } else {
+      uint32_t base = src0.nr * 32 + src0.subnr * 4;
+      GenRegister baseReg = GenRegister::immuw(base);
+      const GenRegister a0 = GenRegister::addr8(0);
+
+      p->push();
+        if (simd == 8) {
+          p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
+          GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
+          p->MOV(dst, indirect);
+        } else if (simd == 16) {
+          p->curr.execWidth = 8;
+          p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
+          GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
+          p->MOV(dst, indirect);
+
+          p->curr.quarterControl = 1;
+          p->ADD(a0, GenRegister::unpacked_uw(src1.nr+1, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
+          p->MOV(GenRegister::offset(dst, 1, 0), indirect);
+        } else
+          NOT_IMPLEMENTED;
+      p->pop();
+    }
+  }
+
   void GenContext::emitBinaryInstruction(const SelectionInstruction &insn) {
     const GenRegister dst = ra->genReg(insn.dst(0));
     const GenRegister src0 = ra->genReg(insn.src(0));
@@ -595,38 +631,6 @@  namespace gbe
           p->MOV(xdst.bottom_half(), xsrc1.bottom_half());
         }
         break;
-      case SEL_OP_SIMD_SHUFFLE:
-        {
-          uint32_t simd = p->curr.execWidth;
-          if (src1.file == GEN_IMMEDIATE_VALUE) {
-            uint32_t offset = src1.value.ud % simd;
-            GenRegister reg = GenRegister::suboffset(src0, offset);
-            p->MOV(dst, GenRegister::retype(GenRegister::ud1grf(reg.nr, reg.subnr / typeSize(reg.type)), reg.type));
-          } else {
-            uint32_t base = src0.nr * 32 + src0.subnr * 4;
-            GenRegister baseReg = GenRegister::immuw(base);
-            const GenRegister a0 = GenRegister::addr8(0);
-
-            p->push();
-              if (simd == 8) {
-                p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
-                GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
-                p->MOV(dst, indirect);
-              } else if (simd == 16) {
-                p->curr.execWidth = 8;
-                p->ADD(a0, GenRegister::unpacked_uw(src1.nr, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
-                GenRegister indirect = GenRegister::to_indirect1xN(src0, 0, 0);
-                p->MOV(dst, indirect);
-
-                p->curr.quarterControl = 1;
-                p->ADD(a0, GenRegister::unpacked_uw(src1.nr+1, src1.subnr / typeSize(GEN_TYPE_UW)), baseReg);
-                p->MOV(GenRegister::offset(dst, 1, 0), indirect);
-              } else
-                NOT_IMPLEMENTED;
-            p->pop();
-          }
-        }
-        break;
       default: NOT_IMPLEMENTED;
     }
   }
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index a85657c..11bea74 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -127,6 +127,7 @@  namespace gbe
     virtual void emitUnaryInstruction(const SelectionInstruction &insn);
     virtual void emitUnaryWithTempInstruction(const SelectionInstruction &insn);
     virtual void emitBinaryInstruction(const SelectionInstruction &insn);
+    virtual void emitSimdShuffleInstruction(const SelectionInstruction &insn);
     virtual void emitBinaryWithTempInstruction(const SelectionInstruction &insn);
     void emitTernaryInstruction(const SelectionInstruction &insn);
     virtual void emitI64MULHIInstruction(const SelectionInstruction &insn);
diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
index d054820..d073770 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -3,6 +3,7 @@  DECL_GEN7_SCHEDULE(Label,           0,         0,        0)
 DECL_GEN7_SCHEDULE(Unary,           20,        4,        2)
 DECL_GEN7_SCHEDULE(UnaryWithTemp,   20,        40,      20)
 DECL_GEN7_SCHEDULE(Binary,          20,        4,        2)
+DECL_GEN7_SCHEDULE(SimdShuffle,     20,        4,        2)
 DECL_GEN7_SCHEDULE(BinaryWithTemp,  20,        40,      20)
 DECL_GEN7_SCHEDULE(Ternary,         20,        4,        2)
 DECL_GEN7_SCHEDULE(I64Shift,        20,        40,      20)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index af5ab9c..dd757a5 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -543,7 +543,6 @@  namespace gbe
     ALU1(RNDD)
     ALU1(RNDU)
     ALU2(MACH)
-    ALU2(SIMD_SHUFFLE)
     ALU1(LZD)
     ALU3(MAD)
     ALU2WithTemp(MUL_HI)
@@ -565,6 +564,8 @@  namespace gbe
 #undef ALU2WithTemp
 #undef ALU3
 #undef I64Shift
+    /*! simd shuffle */
+    void SIMD_SHUFFLE(Reg dst, Reg src0, Reg src1);
     /*! Convert 64-bit integer to 32-bit float */
     void CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[6]);
     /*! Convert 64-bit integer to 32-bit float */
@@ -1652,6 +1653,14 @@  namespace gbe
     insn->src(2) = src2;
   }
 
+  void Selection::Opaque::SIMD_SHUFFLE(Reg dst, Reg src0, Reg src1)
+  {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_SIMD_SHUFFLE, 1, 2);
+    insn->dst(0) = dst;
+    insn->src(0) = src0;
+    insn->src(1) = src1;
+  }
+
   void Selection::Opaque::I64CMP(uint32_t conditional, Reg src0, Reg src1, GenRegister tmp[3]) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_I64CMP, 3, 2);
     insn->src(0) = src0;
@@ -2815,17 +2824,6 @@  namespace gbe
         case OP_UPSAMPLE_LONG:
           sel.UPSAMPLE_LONG(dst, src0, src1);
           break;
-        case OP_SIMD_SHUFFLE:
-          {
-            if (src1.file == GEN_IMMEDIATE_VALUE)
-              sel.SIMD_SHUFFLE(dst, src0, src1);
-            else {
-              GenRegister shiftL = GenRegister::udxgrf(sel.curr.execWidth, sel.reg(FAMILY_DWORD));
-              sel.SHL(shiftL, src1, GenRegister::immud(0x2));
-              sel.SIMD_SHUFFLE(dst, src0, shiftL);
-            }
-          }
-          break;
         default: NOT_IMPLEMENTED;
       }
       sel.pop();
@@ -4973,6 +4971,38 @@  namespace gbe
     }
   };
 
+  class SimdShuffleInstructionPattern : public SelectionPattern
+  {
+  public:
+    SimdShuffleInstructionPattern(void) : SelectionPattern(1,1) {
+      this->opcodes.push_back(ir::OP_SIMD_SHUFFLE);
+    }
+    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {
+      using namespace ir;
+      const ir::SimdShuffleInstruction &insn = cast<SimdShuffleInstruction>(dag.insn);
+      assert(insn.getOpcode() == OP_SIMD_SHUFFLE);
+      const Type type = insn.getType();
+      GenRegister dst  = sel.selReg(insn.getDst(0), type);
+
+      sel.push();
+
+      GenRegister src0, src1;
+      bool inverse = false;
+      sel.getSrcGenRegImm(dag, src0, src1, type, inverse);
+
+      if (src1.file == GEN_IMMEDIATE_VALUE)
+        sel.SIMD_SHUFFLE(dst, src0, src1);
+      else {
+        GenRegister shiftL = GenRegister::udxgrf(sel.curr.execWidth, sel.reg(FAMILY_DWORD));
+        sel.SHL(shiftL, src1, GenRegister::immud(0x2));
+        sel.SIMD_SHUFFLE(dst, src0, shiftL);
+      }
+
+      sel.pop();
+      return true;
+    }
+  };
+
   /*! Get a region of a register */
   class RegionInstructionPattern : public SelectionPattern
   {
@@ -5247,6 +5277,7 @@  namespace gbe
     this->insert<GetImageInfoInstructionPattern>();
     this->insert<ReadARFInstructionPattern>();
     this->insert<RegionInstructionPattern>();
+    this->insert<SimdShuffleInstructionPattern>();
     this->insert<IndirectMovInstructionPattern>();
     this->insert<NullaryInstructionPattern>();
 
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 79f2ce1..adbb137 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -26,7 +26,7 @@  DECL_SELECTION_IR(SHL, BinaryInstruction)
 DECL_SELECTION_IR(RSR, BinaryInstruction)
 DECL_SELECTION_IR(RSL, BinaryInstruction)
 DECL_SELECTION_IR(ASR, BinaryInstruction)
-DECL_SELECTION_IR(SIMD_SHUFFLE, BinaryInstruction)
+DECL_SELECTION_IR(SIMD_SHUFFLE, SimdShuffleInstruction)
 DECL_SELECTION_IR(I64SHR, I64ShiftInstruction)
 DECL_SELECTION_IR(I64SHL, I64ShiftInstruction)
 DECL_SELECTION_IR(I64ASR, I64ShiftInstruction)
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 12d70a6..a31d04c 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -741,6 +741,21 @@  namespace ir {
       Register src[0];
     };
 
+    class ALIGNED_INSTRUCTION SimdShuffleInstruction : public NaryInstruction<2>
+    {
+    public:
+      SimdShuffleInstruction(Type type,
+                        Register dst,
+                        Register src0,
+                        Register src1) {
+        this->opcode = OP_SIMD_SHUFFLE;
+        this->type = type;
+        this->dst[0] = dst;
+        this->src[0] = src0;
+        this->src[1] = src1;
+      }
+    };
+
     class ALIGNED_INSTRUCTION RegionInstruction :
       public BasePolicy,
       public NSrcPolicy<RegionInstruction, 1>,
@@ -1461,6 +1476,10 @@  START_INTROSPECTION(RegionInstruction)
 #include "ir/instruction.hxx"
 END_INTROSPECTION(RegionInstruction)
 
+START_INTROSPECTION(SimdShuffleInstruction)
+#include "ir/instruction.hxx"
+END_INTROSPECTION(SimdShuffleInstruction)
+
 START_INTROSPECTION(IndirectMovInstruction)
 #include "ir/instruction.hxx"
 END_INTROSPECTION(IndirectMovInstruction)
@@ -1652,6 +1671,7 @@  DECL_MEM_FN(BranchInstruction, LabelIndex, getLabelIndex(void), getLabelIndex())
 DECL_MEM_FN(SyncInstruction, uint32_t, getParameters(void), getParameters())
 DECL_MEM_FN(ReadARFInstruction, Type, getType(void), getType())
 DECL_MEM_FN(ReadARFInstruction, ARFRegister, getARFRegister(void), getARFRegister())
+DECL_MEM_FN(SimdShuffleInstruction, Type, getType(void), getType())
 DECL_MEM_FN(RegionInstruction, uint32_t, getOffset(void), getOffset())
 DECL_MEM_FN(IndirectMovInstruction, uint32_t, getOffset(void), getOffset())
 DECL_MEM_FN(IndirectMovInstruction, Type, getType(void), getType())
@@ -1751,7 +1771,6 @@  DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void), getImageIndex
   DECL_EMIT_FUNCTION(RHADD)
   DECL_EMIT_FUNCTION(I64HADD)
   DECL_EMIT_FUNCTION(I64RHADD)
-  DECL_EMIT_FUNCTION(SIMD_SHUFFLE)
 
 #undef DECL_EMIT_FUNCTION
 
@@ -1881,6 +1900,9 @@  DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void), getImageIndex
   Instruction REGION(Register dst, Register src, uint32_t offset) {
     return internal::RegionInstruction(dst, src, offset).convert();
   }
+  Instruction SIMD_SHUFFLE(Type type, Register dst, Register src0, Register src1) {
+    return internal::SimdShuffleInstruction(type, dst, src0, src1).convert();
+  }
 
   Instruction INDIRECT_MOV(Type type, Register dst, Register src0, Register src1, uint32_t offset) {
     return internal::IndirectMovInstruction(type, dst, src0, src1, offset).convert();
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index ec4d00d..cf8d839 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -522,6 +522,14 @@  namespace ir {
     static bool isClassOf(const Instruction &insn);
   };
 
+  /*! simd shuffle */
+  class SimdShuffleInstruction : public Instruction {
+  public:
+    Type getType(void) const;
+    /*! Return true if the given instruction is an instance of this class */
+    static bool isClassOf(const Instruction &insn);
+  };
+
   /*! return a region of a register, make sure the offset does not exceed the register size */
   class RegionInstruction : public Instruction {
   public:
diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx
index 1001837..81548c9 100644
--- a/backend/src/ir/instruction.hxx
+++ b/backend/src/ir/instruction.hxx
@@ -59,7 +59,7 @@  DECL_INSN(BSB, BinaryInstruction)
 DECL_INSN(OR, BinaryInstruction)
 DECL_INSN(XOR, BinaryInstruction)
 DECL_INSN(AND, BinaryInstruction)
-DECL_INSN(SIMD_SHUFFLE, BinaryInstruction)
+DECL_INSN(SIMD_SHUFFLE, SimdShuffleInstruction)
 DECL_INSN(SEL, SelectInstruction)
 DECL_INSN(EQ, CompareInstruction)
 DECL_INSN(NE, CompareInstruction)

Comments

> +  class SimdShuffleInstructionPattern : public SelectionPattern  {

> +  public:

> +    SimdShuffleInstructionPattern(void) : SelectionPattern(1,1) {

> +      this->opcodes.push_back(ir::OP_SIMD_SHUFFLE);

> +    }

> +    INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const {

> +      using namespace ir;

> +      const ir::SimdShuffleInstruction &insn =

> cast<SimdShuffleInstruction>(dag.insn);

> +      assert(insn.getOpcode() == OP_SIMD_SHUFFLE);

> +      const Type type = insn.getType();

> +      GenRegister dst  = sel.selReg(insn.getDst(0), type);

> +

> +      sel.push();

> +

> +      GenRegister src0, src1;

> +      bool inverse = false;

> +      sel.getSrcGenRegImm(dag, src0, src1, type, inverse);


getSrcGenRegImm is for binary instruction, you'd better refine the function naming,
And write a new piece of code to do the imm optimization for simd-shuffle.

> +

> +      if (src1.file == GEN_IMMEDIATE_VALUE)

> +        sel.SIMD_SHUFFLE(dst, src0, src1);

> +      else {

 sel.selReg() should be enough for here, we should try to avoid using xxxgrf directly.

> +        GenRegister shiftL = GenRegister::udxgrf(sel.curr.execWidth,

> sel.reg(FAMILY_DWORD));

> +        sel.SHL(shiftL, src1, GenRegister::immud(0x2));

> +        sel.SIMD_SHUFFLE(dst, src0, shiftL);

> +      }

> +

> +      sel.pop();

> +      return true;

> +    }

> +  };

> +

>    /*! Get a region of a register */

>    class RegionInstructionPattern : public SelectionPattern

>    {

> @@ -5247,6 +5277,7 @@ namespace gbe

>      this->insert<GetImageInfoInstructionPattern>();

>      this->insert<ReadARFInstructionPattern>();

>      this->insert<RegionInstructionPattern>();

> +    this->insert<SimdShuffleInstructionPattern>();

>      this->insert<IndirectMovInstructionPattern>();

>      this->insert<NullaryInstructionPattern>();

> 

> diff --git a/backend/src/backend/gen_insn_selection.hxx

> b/backend/src/backend/gen_insn_selection.hxx

> index 79f2ce1..adbb137 100644

> --- a/backend/src/backend/gen_insn_selection.hxx

> +++ b/backend/src/backend/gen_insn_selection.hxx

> @@ -26,7 +26,7 @@ DECL_SELECTION_IR(SHL, BinaryInstruction)

> DECL_SELECTION_IR(RSR, BinaryInstruction)  DECL_SELECTION_IR(RSL,

> BinaryInstruction)  DECL_SELECTION_IR(ASR, BinaryInstruction)

> -DECL_SELECTION_IR(SIMD_SHUFFLE, BinaryInstruction)

> +DECL_SELECTION_IR(SIMD_SHUFFLE, SimdShuffleInstruction)

>  DECL_SELECTION_IR(I64SHR, I64ShiftInstruction)

> DECL_SELECTION_IR(I64SHL, I64ShiftInstruction)

> DECL_SELECTION_IR(I64ASR, I64ShiftInstruction) diff --git

> a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index

> 12d70a6..a31d04c 100644

> --- a/backend/src/ir/instruction.cpp

> +++ b/backend/src/ir/instruction.cpp

> @@ -741,6 +741,21 @@ namespace ir {

>        Register src[0];

>      };

> 

> +    class ALIGNED_INSTRUCTION SimdShuffleInstruction : public

> NaryInstruction<2>

> +    {

> +    public:

> +      SimdShuffleInstruction(Type type,

> +                        Register dst,

> +                        Register src0,

> +                        Register src1) {

> +        this->opcode = OP_SIMD_SHUFFLE;

> +        this->type = type;

> +        this->dst[0] = dst;

> +        this->src[0] = src0;

> +        this->src[1] = src1;

> +      }

> +    };

> +


Seems like you missed SimdShuffleInstruction::wellformed()?

>      class ALIGNED_INSTRUCTION RegionInstruction :

>        public BasePolicy,

>        public NSrcPolicy<RegionInstruction, 1>, @@ -1461,6 +1476,10

> @@ START_INTROSPECTION(RegionInstruction)

>  #include "ir/instruction.hxx"

>  END_INTROSPECTION(RegionInstruction)

> 

> +START_INTROSPECTION(SimdShuffleInstruction)

> +#include "ir/instruction.hxx"

> +END_INTROSPECTION(SimdShuffleInstruction)

> +

>  START_INTROSPECTION(IndirectMovInstruction)

>  #include "ir/instruction.hxx"

>  END_INTROSPECTION(IndirectMovInstruction)

> @@ -1652,6 +1671,7 @@ DECL_MEM_FN(BranchInstruction, LabelIndex,

> getLabelIndex(void), getLabelIndex())  DECL_MEM_FN(SyncInstruction,

> uint32_t, getParameters(void), getParameters())

> DECL_MEM_FN(ReadARFInstruction, Type, getType(void), getType())

> DECL_MEM_FN(ReadARFInstruction, ARFRegister, getARFRegister(void),

> getARFRegister())

> +DECL_MEM_FN(SimdShuffleInstruction, Type, getType(void), getType())

>  DECL_MEM_FN(RegionInstruction, uint32_t, getOffset(void), getOffset())

> DECL_MEM_FN(IndirectMovInstruction, uint32_t, getOffset(void),

> getOffset())  DECL_MEM_FN(IndirectMovInstruction, Type, getType(void),

> getType()) @@ -1751,7 +1771,6 @@

> DECL_MEM_FN(GetImageInfoInstruction, uint8_t, getImageIndex(void),

> getImageIndex

>    DECL_EMIT_FUNCTION(RHADD)

>    DECL_EMIT_FUNCTION(I64HADD)

>    DECL_EMIT_FUNCTION(I64RHADD)

> -  DECL_EMIT_FUNCTION(SIMD_SHUFFLE)

> 

>  #undef DECL_EMIT_FUNCTION

> 

> @@ -1881,6 +1900,9 @@ DECL_MEM_FN(GetImageInfoInstruction, uint8_t,

> getImageIndex(void), getImageIndex

>    Instruction REGION(Register dst, Register src, uint32_t offset) {

>      return internal::RegionInstruction(dst, src, offset).convert();

>    }

> +  Instruction SIMD_SHUFFLE(Type type, Register dst, Register src0,

> Register src1) {

> +    return internal::SimdShuffleInstruction(type, dst, src0,

> + src1).convert();  }

> 

>    Instruction INDIRECT_MOV(Type type, Register dst, Register src0,

> Register src1, uint32_t offset) {

>      return internal::IndirectMovInstruction(type, dst, src0, src1,

> offset).convert(); diff --git a/backend/src/ir/instruction.hpp

> b/backend/src/ir/instruction.hpp index ec4d00d..cf8d839 100644

> --- a/backend/src/ir/instruction.hpp

> +++ b/backend/src/ir/instruction.hpp

> @@ -522,6 +522,14 @@ namespace ir {

>      static bool isClassOf(const Instruction &insn);

>    };

> 

> +  /*! simd shuffle */

> +  class SimdShuffleInstruction : public Instruction {

> +  public:

> +    Type getType(void) const;

> +    /*! Return true if the given instruction is an instance of this class */

> +    static bool isClassOf(const Instruction &insn);  };

> +

>    /*! return a region of a register, make sure the offset does not exceed

> the register size */

>    class RegionInstruction : public Instruction {

>    public:

> diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx

> index 1001837..81548c9 100644

> --- a/backend/src/ir/instruction.hxx

> +++ b/backend/src/ir/instruction.hxx

> @@ -59,7 +59,7 @@ DECL_INSN(BSB, BinaryInstruction)  DECL_INSN(OR,

> BinaryInstruction)  DECL_INSN(XOR, BinaryInstruction)  DECL_INSN(AND,

> BinaryInstruction) -DECL_INSN(SIMD_SHUFFLE, BinaryInstruction)

> +DECL_INSN(SIMD_SHUFFLE, SimdShuffleInstruction)

>  DECL_INSN(SEL, SelectInstruction)

>  DECL_INSN(EQ, CompareInstruction)

>  DECL_INSN(NE, CompareInstruction)

> --

> 1.9.1

> 

> _______________________________________________

> Beignet mailing list

> Beignet@lists.freedesktop.org

> http://lists.freedesktop.org/mailman/listinfo/beignet