support 64bit-integer immediate value
authorHomer Hsing <homer.xing@intel.com>
Wed, 7 Aug 2013 04:19:52 +0000 (12:19 +0800)
committerZhigang Gong <zhigang.gong@linux.intel.com>
Wed, 7 Aug 2013 06:51:18 +0000 (14:51 +0800)
v3: folded similar code into a "for-loop"

Signed-off-by: Homer Hsing <homer.xing@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
backend/src/backend/gen_context.cpp
backend/src/backend/gen_encoder.cpp
backend/src/backend/gen_encoder.hpp
backend/src/backend/gen_insn_selection.cpp
backend/src/backend/gen_insn_selection.hxx
backend/src/backend/gen_register.hpp

index 97a9527..ff13302 100644 (file)
@@ -146,6 +146,7 @@ namespace gbe
       case SEL_OP_RNDU: p->RNDU(dst, src); break;
       case SEL_OP_RNDE: p->RNDE(dst, src); break;
       case SEL_OP_RNDZ: p->RNDZ(dst, src); break;
+      case SEL_OP_LOAD_INT64_IMM: p->LOAD_INT64_IMM(dst, src.value.i64); break;
       default: NOT_IMPLEMENTED;
     }
   }
index 64b5bd1..3793d8b 100644 (file)
@@ -821,6 +821,20 @@ namespace gbe
     MOV(dest, src0);
   }
 
+  void GenEncoder::LOAD_INT64_IMM(GenRegister dest, int64_t value) {
+    GenRegister u0 = GenRegister::immd((int)value), u1 = GenRegister::immd(value >> 32);
+    int execWidth = curr.execWidth;
+    push();
+    curr.execWidth = 8;
+    for(int nib = 0; nib < execWidth/4; nib ++) {
+      curr.chooseNib(nib);
+      MOV(dest.top_half(), u1);
+      MOV(dest.bottom_half(), u0);
+      dest = GenRegister::suboffset(dest, 4);
+    }
+    pop();
+  }
+
   void GenEncoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
     int w = curr.execWidth;
     if (src0.isdf()) {
index 083bd8c..54674d3 100644 (file)
@@ -125,6 +125,7 @@ namespace gbe
 #undef ALU3
     void MOV_DF(GenRegister dest, GenRegister src0, GenRegister tmp = GenRegister::null());
     void LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value);
+    void LOAD_INT64_IMM(GenRegister dest, int64_t value);
     /*! Barrier message (to synchronize threads of a workgroup) */
     void BARRIER(GenRegister src);
     /*! Memory fence message (to order loads and stores between threads) */
index eca62b4..66cfa31 100644 (file)
@@ -415,6 +415,7 @@ namespace gbe
     ALU1(MOV)
     ALU2(MOV_DF)
     ALU2(LOAD_DF_IMM)
+    ALU1(LOAD_INT64_IMM)
     ALU1(RNDZ)
     ALU1(RNDE)
     ALU2(SEL)
@@ -1806,6 +1807,8 @@ namespace gbe
         case TYPE_U8:  sel.MOV(dst, GenRegister::immuw(imm.data.u8)); break;
         case TYPE_S8:  sel.MOV(dst, GenRegister::immw(imm.data.s8)); break;
         case TYPE_DOUBLE: sel.LOAD_DF_IMM(dst, GenRegister::immdf(imm.data.f64), sel.selReg(sel.reg(FAMILY_QWORD))); break;
+        case TYPE_S64: sel.LOAD_INT64_IMM(dst, GenRegister::immint64(imm.data.s64)); break;
+        case TYPE_U64: sel.LOAD_INT64_IMM(dst, GenRegister::immint64(imm.data.u64)); break;
         default: NOT_SUPPORTED;
       }
       sel.pop();
index f2b86c4..8eeb19f 100644 (file)
@@ -2,6 +2,7 @@ DECL_SELECTION_IR(LABEL, LabelInstruction)
 DECL_SELECTION_IR(MOV, UnaryInstruction)
 DECL_SELECTION_IR(MOV_DF, BinaryInstruction)
 DECL_SELECTION_IR(LOAD_DF_IMM, BinaryInstruction)
+DECL_SELECTION_IR(LOAD_INT64_IMM, UnaryInstruction)
 DECL_SELECTION_IR(NOT, UnaryInstruction)
 DECL_SELECTION_IR(LZD, UnaryInstruction)
 DECL_SELECTION_IR(RNDZ, UnaryInstruction)
index fda2e6c..2cad4c0 100644 (file)
@@ -136,6 +136,28 @@ namespace gbe
     uint32_t predicate:4;
     uint32_t inversePredicate:1;
     uint32_t saturate:1;
+    void chooseNib(int nib) {
+      switch (nib) {
+        case 0:
+          quarterControl = 0;
+          nibControl = 0;
+          break;
+        case 1:
+          quarterControl = 0;
+          nibControl = 1;
+          break;
+        case 2:
+          quarterControl = 1;
+          nibControl = 0;
+          break;
+        case 3:
+          quarterControl = 1;
+          nibControl = 1;
+          break;
+        default:
+          NOT_IMPLEMENTED;
+      }
+    }
   };
 
   /*! This is a book-keeping structure used to encode both virtual and physical
@@ -202,6 +224,7 @@ namespace gbe
       int32_t d;
       uint32_t ud;
       uint16_t reg;
+      int64_t i64;
     } value;
 
     uint32_t nr:8;         //!< Just for some physical registers (acc, null)
@@ -434,6 +457,12 @@ namespace gbe
                          GEN_HORIZONTAL_STRIDE_0);
     }
 
+    static INLINE GenRegister immint64(int64_t i) {
+      GenRegister immediate = imm(GEN_TYPE_L);
+      immediate.value.i64 = i;
+      return immediate;
+    }
+
     static INLINE GenRegister immdf(double df) {
       GenRegister immediate = imm(GEN_TYPE_DF);
       immediate.value.df = df;