harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hinde...@apache.org
Subject svn commit: r952017 [2/5] - in /harmony/enhanced/java/trunk/drlvm: make/vm/ vm/jitrino/config/em64t/ vm/jitrino/config/ia32/ vm/jitrino/src/codegenerator/ vm/jitrino/src/codegenerator/ia32/ vm/jitrino/src/jet/ vm/jitrino/src/optimizer/ vm/jitrino/src/o...
Date Sun, 06 Jun 2010 22:47:41 GMT
Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Sun Jun  6 22:47:40 2010
@@ -77,6 +77,8 @@ CompareOp::Types getCompareOpTypesFromCo
         case CompareZeroOp::I:          return CompareOp::I;
         case CompareZeroOp::Ref:        return CompareOp::Ref;
         case CompareZeroOp::CompRef:    return CompareOp::CompRef;
+        default:
+          ;
     }
     assert(0);
     return CompareOp::I4;
@@ -565,6 +567,7 @@ Opnd * InstCodeSelector::convert(CG_Opnd
             dstOpnd=convertFpToFp(srcOpnd, dstType, dstOpnd);
             converted=true;
         }   
+    } else if (srcType->tag == Type::Vector) {
     } else if (srcType->isUnmanagedPtr() && !dstType->isUnmanagedPtr()) {
         dstOpnd = convertUnmanagedPtr(srcOpnd, dstType, dstOpnd);
         converted = true;
@@ -633,6 +636,162 @@ CG_OpndHandle*  InstCodeSelector::convTo
 }
 
 //_______________________________________________________________________________________________________________
+//  Convert to vectors
+
+Opnd*  InstCodeSelector::vectorExtension (VectorType* dst_type,
+                                          CG_OpndHandle* src,
+                                          Type::Tag src_elem_tag,
+                                          bool is_zero_extend)
+{
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Type *dst_elem_type = dst_type->getElemType ();
+  Opnd *elem = (Opnd*)src;
+  Mnemonic mn;
+
+  switch (src_elem_tag)
+    {
+    case Type::Int8:
+    case Type::UInt8:
+      switch (dst_elem_type->tag)
+        {
+        case Type::Int16:
+        case Type::UInt16:
+          mn = Mnemonic_PMOVSXBW;
+          break;
+        case Type::Int32:
+        case Type::UInt32:
+          mn = Mnemonic_PMOVSXBD;
+          break;
+        case Type::Int64:
+        case Type::UInt64:
+          mn = Mnemonic_PMOVSXBQ;
+          break;
+        default:
+          assert (0);
+        }
+      break;
+    case Type::Int16:
+    case Type::UInt16:
+      switch (dst_elem_type->tag)
+        {
+        case Type::Int32:
+        case Type::UInt32:
+          mn = Mnemonic_PMOVSXWD;
+          break;
+        case Type::Int64:
+        case Type::UInt64:
+          mn = Mnemonic_PMOVSXWQ;
+          break;
+        default:
+          assert (0);
+        }
+      break;
+    case Type::Int32:
+    case Type::UInt32:
+      switch (dst_elem_type->tag)
+        {
+        case Type::Int64:
+        case Type::UInt64:
+          mn = Mnemonic_PMOVSXDQ;
+          break;
+        default:
+          assert (0);
+        }
+      break;
+
+    default:
+      assert (0);
+    }
+
+  appendInsts (irManager.newInstEx ((Mnemonic)(mn + is_zero_extend),
+                                    1, dst, elem));
+
+  return dst;
+}
+
+CG_OpndHandle*  InstCodeSelector::convToVector (VectorType* dst_type,
+                                                CG_OpndHandle* src,
+                                                bool is_zero_extend)
+{
+  Opnd *elem = (Opnd*)src;
+  Type *dst_elem_type = dst_type->getElemType ();
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Opnd *all_zero;
+
+  if (VectorType *vec_type = elem->getType()->asVectorType ())
+    {
+      Type *src_elem_type = vec_type->getElemType ();
+      if (dst_elem_type->tag == Type::Int32
+	  && src_elem_type->tag == Type::Single)
+	appendInsts (irManager.newInstEx (Mnemonic_CVTPS2DQ, 1, dst, elem));
+      else if (dst_elem_type->tag == Type::Single
+	       && src_elem_type->tag == Type::Int32)
+	appendInsts (irManager.newInstEx (Mnemonic_CVTDQ2PS, 1, dst, elem));
+      else
+	assert (0);
+
+      // // Sign/zero extend an integer vector.
+      // return vectorExtension (dst_type, src,
+      // 			      vec_type->getElemType()->tag,
+      // 			      is_zero_extend);
+    }
+
+  // Duplicate a scalar to a vector
+  switch (dst_elem_type->tag)
+    {
+    case Type::Int8:
+    case Type::UInt8:
+      elem = (Opnd*)convert (src, typeManager.getInt32Type ());
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, dst, elem));
+      all_zero = irManager.newOpnd (dst_type);
+      appendInsts (irManager.newInstEx (Mnemonic_PCMPGTB, 1, all_zero,
+                                        dst, dst));
+      appendInsts (irManager.newInstEx (Mnemonic_PSHUFB, 1, dst, dst, all_zero));
+      break;
+
+    case Type::Int16:
+    case Type::UInt16:
+      elem = (Opnd*)convert (src, typeManager.getInt32Type ());
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, dst, elem));
+      appendInsts (irManager.newInstEx (Mnemonic_PSHUFLW, 1, dst, dst,
+                                        irManager.newImmOpnd (typeManager.getInt8Type (), 0)));
+      appendInsts (irManager.newInstEx (Mnemonic_MOVDDUP, 1, dst, dst));
+      break;
+
+    case Type::Int32:
+    case Type::UInt32:
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, dst, elem));
+      appendInsts (irManager.newInstEx (Mnemonic_PSHUFD, 1, dst, dst,
+                                        irManager.newImmOpnd (typeManager.getInt8Type (), 0)));
+      break;
+
+    case Type::Single:
+      appendInsts (irManager.newInstEx (Mnemonic_PSHUFD, 1, dst, elem,
+                                        irManager.newImmOpnd (typeManager.getInt8Type (), 0)));
+      break;
+
+    case Type::Int64:
+    case Type::UInt64:
+#ifndef _EM64T_
+      appendInsts (irManager.newI8PseudoInst (Mnemonic_MOVDDUP, 1, dst, elem));
+#else
+      appendInsts (irManager.newInstEx (Mnemonic_MOVQ, 1, dst, elem));
+      appendInsts (irManager.newInstEx (Mnemonic_MOVDDUP, 1, dst, dst));
+#endif
+      break;
+
+    case Type::Double:
+      appendInsts (irManager.newInstEx (Mnemonic_MOVDDUP, 1, dst, elem));
+      break;
+ 
+    default:
+      assert (0);
+    }
+
+  return dst;
+}
+
+//_______________________________________________________________________________________________________________
 //  Convert to objects to unmanaged pointers and via versa
 
 /// convert unmanaged pointer to object. Boxing
@@ -706,6 +865,19 @@ Opnd * InstCodeSelector::simpleOp_I4(Mne
 }
 
 //_______________________________________________________________________________________________________________
+Opnd * InstCodeSelector::vecBinaryOp(Mnemonic mn, Opnd * src1, Opnd * src2)
+{
+    Type *type = src1->getType ();
+    Opnd *dst = irManager.newOpnd (type);
+    Opnd *srcOpnd1 = (Opnd*)convert (src1, type);
+    Opnd *srcOpnd2 = (Opnd*)convert (src2, type);
+
+    appendInsts (irManager.newInstEx(mn, 1, dst, srcOpnd1, srcOpnd2));
+
+    return dst;
+}
+
+//_______________________________________________________________________________________________________________
 //  Add numeric values
 
 CG_OpndHandle* InstCodeSelector::add(ArithmeticOp::Types opType, 
@@ -725,6 +897,18 @@ CG_OpndHandle* InstCodeSelector::add(Ari
             return fpOp(Mnemonic_ADDSD, irManager.getTypeFromTag(Type::Double), (Opnd*)src1, (Opnd*)src2);
         case ArithmeticOp::S:
             return fpOp(Mnemonic_ADDSS, irManager.getTypeFromTag(Type::Single), (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI1_16:
+            return vecBinaryOp (Mnemonic_PADDB, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI2_8:
+            return vecBinaryOp (Mnemonic_PADDW, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI4_4:
+            return vecBinaryOp (Mnemonic_PADDD, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI8_2:
+            return vecBinaryOp (Mnemonic_PADDQ, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VS_4:
+            return vecBinaryOp (Mnemonic_ADDPS, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VD_2:
+            return vecBinaryOp (Mnemonic_ADDPD, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -751,6 +935,18 @@ CG_OpndHandle* InstCodeSelector::sub(Ari
             return fpOp(Mnemonic_SUBSD, irManager.getTypeFromTag(Type::Double), (Opnd*)src1, (Opnd*)src2);
         case ArithmeticOp::S:
             return fpOp(Mnemonic_SUBSS, irManager.getTypeFromTag(Type::Single), (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI1_16:
+            return vecBinaryOp (Mnemonic_PSUBB, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI2_8:
+            return vecBinaryOp (Mnemonic_PSUBW, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI4_4:
+            return vecBinaryOp (Mnemonic_PSUBD, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI8_2:
+            return vecBinaryOp (Mnemonic_PSUBQ, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VS_4:
+            return vecBinaryOp (Mnemonic_SUBPS, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VD_2:
+            return vecBinaryOp (Mnemonic_SUBPD, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -827,6 +1023,20 @@ CG_OpndHandle* InstCodeSelector::mul(Ari
             return fpOp(Mnemonic_MULSD, irManager.getTypeFromTag(Type::Double), (Opnd*)src1, (Opnd*)src2);
         case ArithmeticOp::S:
             return fpOp(Mnemonic_MULSS, irManager.getTypeFromTag(Type::Single), (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VI2_8:
+            return vecBinaryOp (Mnemonic_PMULLW, (Opnd*)src1, (Opnd*)src2);
+         case ArithmeticOp::VI4_4:
+            return vecBinaryOp (Mnemonic_PMULLD, (Opnd*)src1, (Opnd*)src2);;
+        case ArithmeticOp::VI8_2:
+            // FIXME: SSE doesn't support 64-bit multiplication.  The
+            // PMULUDQ only multiplies the low 32-bit of each part, so
+            // the middle end must ensure that the high 32-bits of
+            // each part are all zero.
+            return vecBinaryOp (Mnemonic_PMULUDQ, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VS_4:
+            return vecBinaryOp (Mnemonic_MULPS, (Opnd*)src1, (Opnd*)src2);
+        case ArithmeticOp::VD_2:
+            return vecBinaryOp (Mnemonic_MULPD, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -922,6 +1132,10 @@ Opnd * InstCodeSelector::divOp(DivOp::Ty
                 return fpOp(Mnemonic_DIVSS, irManager.getTypeFromTag(Type::Single), src1, src2);
             }
             break;
+        case DivOp::VS_4:
+            return vecBinaryOp (Mnemonic_DIVPS, (Opnd*)src1, (Opnd*)src2);
+        case DivOp::VD_2:
+            return vecBinaryOp (Mnemonic_DIVPD, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -1022,6 +1236,41 @@ Opnd * InstCodeSelector::minMaxOp(NegOp:
         case NegOp::F:
         case NegOp::S:
             ICS_ASSERT(0);      
+        case NegOp::VI1_16:
+        {
+            dst = irManager.newOpnd (src1->getType ());
+            appendInsts (irManager.newInstEx (max ? Mnemonic_PMAXSB : Mnemonic_PMINSB,
+                                              1, dst, src1, src2));
+            break;
+        }
+        case NegOp::VI2_8:
+        {
+            dst = irManager.newOpnd (src1->getType ());
+            appendInsts (irManager.newInstEx (max ? Mnemonic_PMAXSW : Mnemonic_PMINSW,
+                                              1, dst, src1, src2));
+            break;
+        }
+        case NegOp::VI4_4:
+        {
+            dst = irManager.newOpnd (src1->getType ());
+            appendInsts (irManager.newInstEx (max ? Mnemonic_PMAXSD : Mnemonic_PMINSD,
+                                              1, dst, src1, src2));
+            break;
+        }
+        case NegOp::VS_4:
+        {
+            dst = irManager.newOpnd (src1->getType ());
+            appendInsts (irManager.newInstEx (max ? Mnemonic_MAXPS : Mnemonic_MINPS,
+                                              1, dst, src1, src2));
+            break;
+        }
+        case NegOp::VD_2:
+        {
+            dst = irManager.newOpnd (src1->getType ());
+            appendInsts (irManager.newInstEx (max ? Mnemonic_MAXPD : Mnemonic_MINPD,
+                                              1, dst, src1, src2));
+            break;
+        }
         default:
             ICS_ASSERT(0);
     }
@@ -1072,6 +1321,24 @@ CG_OpndHandle* InstCodeSelector::abs_op(
         case NegOp::F:
         case NegOp::S:
             ICS_ASSERT(0);      
+        case NegOp::VI1_16:
+        {
+            dst = irManager.newOpnd (((Opnd*)src)->getType ());
+            appendInsts (irManager.newInstEx (Mnemonic_PABSB, 1, dst, (Opnd*)src));
+            break;
+        }
+        case NegOp::VI2_8:
+        {
+            dst = irManager.newOpnd (((Opnd*)src)->getType ());
+            appendInsts (irManager.newInstEx (Mnemonic_PABSW, 1, dst, (Opnd*)src));
+            break;
+        }
+        case NegOp::VI4_4:
+        {
+            dst = irManager.newOpnd (((Opnd*)src)->getType ());
+            appendInsts (irManager.newInstEx (Mnemonic_PABSD, 1, dst, (Opnd*)src));
+            break;
+        }
         default:
             ICS_ASSERT(0);
     }
@@ -1102,6 +1369,11 @@ CG_OpndHandle* InstCodeSelector::and_(In
         }
         case IntegerOp::I8:
             return simpleOp_I8(Mnemonic_AND, irManager.getTypeFromTag(Type::Int64), (Opnd*)src1, (Opnd*)src2);
+        case IntegerOp::VI1_16:
+        case IntegerOp::VI2_8:
+        case IntegerOp::VI4_4:
+        case IntegerOp::VI8_2:
+            return vecBinaryOp (Mnemonic_PAND, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -1123,6 +1395,11 @@ CG_OpndHandle* InstCodeSelector::or_(Int
         }
         case IntegerOp::I8:
             return simpleOp_I8(Mnemonic_OR, irManager.getTypeFromTag(Type::Int64), (Opnd*)src1, (Opnd*)src2);
+        case IntegerOp::VI1_16:
+        case IntegerOp::VI2_8:
+        case IntegerOp::VI4_4:
+        case IntegerOp::VI8_2:
+            return vecBinaryOp (Mnemonic_POR, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -1144,6 +1421,30 @@ CG_OpndHandle*    InstCodeSelector::xor_
         }
         case IntegerOp::I8:
             return simpleOp_I8(Mnemonic_XOR, irManager.getTypeFromTag(Type::Int64), (Opnd*)src1, (Opnd*)src2);
+        case IntegerOp::VI1_16:
+        case IntegerOp::VI2_8:
+        case IntegerOp::VI4_4:
+        case IntegerOp::VI8_2:
+            return vecBinaryOp (Mnemonic_PXOR, (Opnd*)src1, (Opnd*)src2);
+        default:
+            ICS_ASSERT(0);
+    }
+    return NULL;
+}
+
+//_______________________________________________________________________________________________________________
+//  Logical andnot
+
+CG_OpndHandle* InstCodeSelector::andnot_(IntegerOp::Types opType,
+                                         CG_OpndHandle*   src1,
+                                         CG_OpndHandle*   src2) 
+{
+    switch(opType){
+        case IntegerOp::VI1_16:
+        case IntegerOp::VI2_8:
+        case IntegerOp::VI4_4:
+        case IntegerOp::VI8_2:
+            return vecBinaryOp (Mnemonic_PANDN, (Opnd*)src1, (Opnd*)src2);
         default:
             ICS_ASSERT(0);
     }
@@ -1193,6 +1494,26 @@ Opnd * InstCodeSelector::shiftOp(Integer
             appendInsts(irManager.newInstEx(mn,1,dst,(Opnd*)convert(value, dstType),(Opnd*)convert(shiftAmount, typeManager.getInt32Type())));
 #endif
             return dst;
+        case IntegerOp::VI2_8:
+        case IntegerOp::VI4_4:
+        case IntegerOp::VI8_2:
+        {
+            dst = irManager.newOpnd (value->getType ());
+            Opnd *shift_num;
+            if (shiftAmount->isPlacedIn (OpndKind_Imm))
+              shift_num = irManager.newImmOpnd (typeManager.getInt8Type(),
+						shiftAmount->getImmValue ());
+            else if (shiftAmount->getType()->tag == Type::Vector)
+              shift_num = shiftAmount;
+            else
+              {
+                shift_num = irManager.newOpnd (value->getType ());
+                appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, shift_num,
+                                                  (Opnd*)convert (shiftAmount, typeManager.getInt32Type())));
+              }
+            appendInsts (irManager.newInstEx (mn, 1, dst, value, shift_num));
+            break;
+        }
         default:
             ICS_ASSERT(0);
     }
@@ -1245,7 +1566,24 @@ CG_OpndHandle*    InstCodeSelector::shl(
                                              CG_OpndHandle*   value,
                                              CG_OpndHandle*   shiftAmount) 
 {
-    return shiftOp(opType, Mnemonic_SHL, (Opnd*)value, (Opnd*)shiftAmount);
+  Mnemonic mn;
+
+  switch (opType)
+    {
+    case IntegerOp::VI2_8:
+      mn = Mnemonic_PSLLW;
+      break;
+    case IntegerOp::VI4_4:
+      mn = Mnemonic_PSLLD;
+      break;
+    case IntegerOp::VI8_2:
+      mn = Mnemonic_PSLLQ;
+      break;
+    default:
+      mn = Mnemonic_SHL;
+    }
+
+  return shiftOp (opType, mn, (Opnd*)value, (Opnd*)shiftAmount);
 }
 
 //_______________________________________________________________________________________________________________
@@ -1255,7 +1593,24 @@ CG_OpndHandle* InstCodeSelector::shr(Int
                                         CG_OpndHandle*   value,
                                         CG_OpndHandle*   shiftAmount) 
 {
-    return shiftOp(opType, Mnemonic_SAR, (Opnd*)value, (Opnd*)shiftAmount);
+  Mnemonic mn;
+
+  switch (opType)
+    {
+    case IntegerOp::VI2_8:
+      mn = Mnemonic_PSRAW;
+      break;
+    case IntegerOp::VI4_4:
+      mn = Mnemonic_PSRAD;
+      break;
+    case IntegerOp::VI8_2:
+      assert (0);
+      break;
+    default:
+      mn = Mnemonic_SAR;
+    }
+
+  return shiftOp (opType, mn, (Opnd*)value, (Opnd*)shiftAmount);
 }
 
 //_______________________________________________________________________________________________________________
@@ -1265,7 +1620,24 @@ CG_OpndHandle*    InstCodeSelector::shru
                                             CG_OpndHandle* value,
                                             CG_OpndHandle* shiftAmount) 
 {
-    return shiftOp(opType, Mnemonic_SHR, (Opnd*)value, (Opnd*)shiftAmount);
+  Mnemonic mn;
+
+  switch (opType)
+    {
+    case IntegerOp::VI2_8:
+      mn = Mnemonic_PSRLW;
+      break;
+    case IntegerOp::VI4_4:
+      mn = Mnemonic_PSRLD;
+      break;
+    case IntegerOp::VI8_2:
+      mn = Mnemonic_PSRLQ;
+      break;
+    default:
+      mn = Mnemonic_SHR;
+    }
+
+  return shiftOp (opType, mn, (Opnd*)value, (Opnd*)shiftAmount);
 }
 
 //_______________________________________________________________________________________________________________
@@ -1276,6 +1648,20 @@ CG_OpndHandle*  InstCodeSelector::select
                                             CG_OpndHandle*       src2,
                                             CG_OpndHandle*       src3) 
 {
+  Type *src_type = ((Opnd*)src1)->getType ();
+
+  if (src_type->tag == Type::Vector)
+    {
+      Opnd *dst = irManager.newOpnd (src_type);
+      Opnd *masked_src2 = irManager.newOpnd (src_type);
+      Opnd *masked_src3 = irManager.newOpnd (src_type);
+      appendInsts (irManager.newInstEx (Mnemonic_PAND, 1, masked_src2, (Opnd*)src1, (Opnd*)src2));
+      appendInsts (irManager.newInstEx (Mnemonic_PANDN, 1, masked_src3, (Opnd*)src1, (Opnd*)src3));
+      appendInsts (irManager.newInstEx (Mnemonic_POR, 1, dst, masked_src2, masked_src3));
+
+      return dst;
+    }
+
     ICS_ASSERT(0);
     return 0;
 }
@@ -1288,6 +1674,93 @@ CG_OpndHandle*  InstCodeSelector::cmp(Co
                                          CG_OpndHandle*       src1,
                                          CG_OpndHandle*       src2, int ifNaNResult) 
 {
+  Type *src_type = ((Opnd*)src1)->getType ();
+
+  if (src_type->tag == Type::Vector)
+    {
+      Opnd *dst = irManager.newOpnd (src_type);
+      Mnemonic mn;
+
+      switch (opType)
+        {
+        case CompareOp::VI1_16:
+        case CompareOp::VI2_8:
+        case CompareOp::VI4_4:
+        case CompareOp::VI8_2:
+          {
+            int cmp_offset = opType - CompareOp::VI1_16;
+            bool need_reverse = false;
+
+            switch (cmpOp)
+              {
+              case CompareOp::Eq:
+                mn = (Mnemonic)(Mnemonic_PCMPEQB + cmp_offset);
+                break;
+              case CompareOp::Ne:
+                mn = (Mnemonic)(Mnemonic_PCMPEQB + cmp_offset);
+                need_reverse = true;
+                break;
+              case CompareOp::Gt:
+                mn = (Mnemonic)(Mnemonic_PCMPGTB + cmp_offset);
+                break;
+              case CompareOp::Ge:
+                mn = (Mnemonic)(Mnemonic_PCMPGTB + cmp_offset);
+                need_reverse = true;
+                break;
+              default:
+                assert (0);
+              }
+
+            if (need_reverse)
+              {
+                Opnd *tmp = irManager.newOpnd (src_type);
+                appendInsts (irManager.newInstEx (mn, 1, tmp, (Opnd*)src2, (Opnd*)src1));
+                Opnd *all_one = irManager.newOpnd (src_type);
+                appendInsts (irManager.newInstEx (Mnemonic_PCMPEQB, 1, all_one,
+                                                  (Opnd*)src1, (Opnd*)src1));
+                appendInsts (irManager.newInstEx (Mnemonic_PANDN, 1, dst, tmp, all_one));
+              }
+            else
+              appendInsts (irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2));
+
+            return dst;
+          }
+
+        case CompareOp::VS_4:
+        case CompareOp::VD_2:
+          {
+            int op_imm;
+
+            switch (cmpOp)
+              {
+              case CompareOp::Eq:
+                op_imm = 0;
+                break;
+              case CompareOp::Ne:
+                op_imm = 4;
+                break;
+              case CompareOp::Gt:
+                op_imm = 6;
+                break;
+              case CompareOp::Ge:
+                op_imm = 5;
+                break;
+              default:
+                assert (0);
+              }
+
+            mn = opType == CompareOp::VS_4 ? Mnemonic_CMPPS : Mnemonic_CMPPD;
+            Opnd *imm = irManager.newImmOpnd (typeManager.getInt8Type (), op_imm);
+            appendInsts (irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2, imm));
+
+            return dst;
+          }
+
+        default:
+          ;
+        }
+    }
+
     Opnd * dst=irManager.newOpnd(typeManager.getInt32Type());
     bool swapped=cmpToEflags(cmpOp, opType, (Opnd*)src1, (Opnd*)src2);
     ConditionMnemonic cm=getConditionMnemonicFromCompareOperator(cmpOp, opType);
@@ -2155,7 +2628,7 @@ void InstCodeSelector::simpleStInd(Opnd 
     if(irManager.refsAreCompressed() && memType > Type::Float && !src->getType()->isUnmanagedPtr()) {
         Type * unmanagedPtrType = typeManager.getUnmanagedPtrType(typeManager.getInt8Type());
         Opnd * heap_base = heapBaseOpnd(unmanagedPtrType, (POINTER_SIZE_INT)VMInterface::getHeapBase());
-        Opnd * compressed_src = irManager.newOpnd(typeManager.compressType(src->getType()));
+        Opnd * compressed_src = irManager.newOpnd(src->getType());
         Opnd * opnd = irManager.newMemOpndAutoKind(typeManager.compressType(src->getType()), addr);
         appendInsts(irManager.newInstEx(Mnemonic_SUB, 1, compressed_src, src, heap_base));
         appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, opnd, compressed_src));
@@ -2169,6 +2642,39 @@ void InstCodeSelector::simpleStInd(Opnd 
 } 
 
 //_______________________________________________________________________________________________________________
+//  Vector load indirect -- load primitive value
+
+CG_OpndHandle* InstCodeSelector::vectorLdInd (Type *dstType, Opnd *addr)
+{
+    PtrType *ptr_type = addr->getType()->asPtrType ();
+    VectorType *dst_vec_type = dstType->asVectorType ();
+    assert (ptr_type && dst_vec_type);
+    Type *pointed_to_type = ptr_type->getPointedToType ();
+    Opnd *opnd = irManager.newMemOpndAutoKind (dstType, addr);
+    Opnd *dst;
+
+    if (pointed_to_type->tag == dst_vec_type->getElemType()->tag)
+      {
+        dst = irManager.newOpnd (dstType);
+        appendInsts (irManager.newInstEx (Mnemonic_MOVUPD, 1, dst, opnd));
+      }
+    else
+      dst = vectorExtension (dst_vec_type, opnd, pointed_to_type->tag, false);
+
+    return dst;
+}
+
+//_______________________________________________________________________________________________________________
+//  Vector store indirect -- store primitive value
+
+void InstCodeSelector::vectorStInd (Opnd *addr, Opnd *src)
+{
+    Opnd *dst = irManager.newMemOpndAutoKind (src->getType (), addr);
+
+    appendInsts (irManager.newInstEx (Mnemonic_MOVUPD, 1, dst, src));
+} 
+
+//_______________________________________________________________________________________________________________
 //  Load static field
 
 CG_OpndHandle* InstCodeSelector::ldStatic(Type *     dstType, 
@@ -2261,7 +2767,10 @@ CG_OpndHandle* InstCodeSelector::tau_ldI
                                           CG_OpndHandle* tauBaseNonNull,
                                           CG_OpndHandle* tauAddressInRange) 
 {
-    return simpleLdInd(dstType, (Opnd*)ptr, memType, (Opnd*)tauBaseNonNull, (Opnd*)tauAddressInRange);
+    if (memType == Type::Vector)
+        return vectorLdInd (dstType, (Opnd*)ptr);
+    else
+        return simpleLdInd (dstType, (Opnd*)ptr, memType, (Opnd*)tauBaseNonNull, (Opnd*)tauAddressInRange);
 }
 
 //_______________________________________________________________________________________________________________
@@ -2275,7 +2784,10 @@ void InstCodeSelector::tau_stInd(CG_Opnd
                                     CG_OpndHandle* tauAddressInRange, 
                                     CG_OpndHandle* tauElemTypeChecked) 
 {
-    return simpleStInd((Opnd*)ptr, (Opnd*)src, memType, autoCompressRef, (Opnd*)tauBaseNonNull, (Opnd*)tauElemTypeChecked);
+    if (memType == Type::Vector)
+        return vectorStInd ((Opnd*)ptr, (Opnd*)src);
+    else
+        return simpleStInd ((Opnd*)ptr, (Opnd*)src, memType, autoCompressRef, (Opnd*)tauBaseNonNull, (Opnd*)tauElemTypeChecked);
 }
 
 void InstCodeSelector::tau_stRef(CG_OpndHandle* src,
@@ -3280,6 +3792,298 @@ void InstCodeSelector::prefetch(CG_OpndH
 }
 
 //_______________________________________________________________________________________________________________
+//  Special vector operations
+
+CG_OpndHandle* InstCodeSelector::vecAddSub(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2)
+{
+  VectorType *vec_type = dst_type->asVectorType ();
+  assert (vec_type);
+
+  Type::Tag elem_tag = vec_type->getElemType()->tag;
+  assert (elem_tag == Type::Double || elem_tag == Type::Single);
+
+  Mnemonic mn = elem_tag == Type::Double ? Mnemonic_ADDSUBPD : Mnemonic_ADDSUBPS;
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2);
+
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecHadd(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2)
+{
+  VectorType *vec_type = dst_type->asVectorType ();
+  assert (vec_type);
+
+  Type::Tag elem_tag = vec_type->getElemType()->tag;
+  assert (elem_tag == Type::Double || elem_tag == Type::Single);
+
+  Mnemonic mn = elem_tag == Type::Double ? Mnemonic_HADDPD : Mnemonic_HADDPS;
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2);
+
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecHsub(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2)
+{
+  VectorType *vec_type = dst_type->asVectorType ();
+  assert (vec_type);
+
+  Type::Tag elem_tag = vec_type->getElemType()->tag;
+  assert (elem_tag == Type::Double || elem_tag == Type::Single);
+
+  Mnemonic mn = elem_tag == Type::Double ? Mnemonic_HSUBPD : Mnemonic_HSUBPS;
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2);
+
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecInterleave(bool high, Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2)
+{
+  VectorType *vec_type = dst_type->asVectorType ();
+  assert (vec_type);
+
+  Mnemonic mn;
+
+  switch (vec_type->getLength ())
+    {
+    case 2:
+      mn = high ? Mnemonic_PUNPCKHQDQ : Mnemonic_PUNPCKLQDQ;
+      break;
+
+    case 4:
+      mn = high ? Mnemonic_PUNPCKHDQ : Mnemonic_PUNPCKLDQ;
+      break;
+
+    case 8:
+      mn = high ? Mnemonic_PUNPCKHWD : Mnemonic_PUNPCKLWD;
+      break;
+
+    case 16:
+      mn = high ? Mnemonic_PUNPCKHBW : Mnemonic_PUNPCKLBW;
+      break;
+
+    default:
+      assert (0);
+    }
+
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2);
+
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecShuffle(Type *dst_type, CG_OpndHandle* src1,
+                                            CG_OpndHandle* src2, CG_OpndHandle* pattern)
+{
+  VectorType *vec_type = dst_type->asVectorType ();
+  assert (vec_type);
+
+  int elem_num = vec_type->getLength ();
+  assert (elem_num == 2 || elem_num == 4);
+
+  Mnemonic mn = elem_num == 2 ? Mnemonic_SHUFPD : Mnemonic_SHUFPS;
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src1, (Opnd*)src2,
+                                    (Opnd*)pattern, NULL, NULL, NULL, NULL);
+
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecExtract(Type *dst_type, CG_OpndHandle* src, CG_OpndHandle* index)
+{
+  //  VectorType *src_type = ((Opnd*)src)->getType()->asVectorType ();
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Inst *inst = NULL;
+  int idx = ((Opnd*)index)->getImmValue ();
+
+  switch (dst_type->tag)
+    {
+    case Type::Single:
+      inst = irManager.newInstEx (Mnemonic_PSHUFD, 1, dst, (Opnd*)src,
+                                  irManager.newImmOpnd (typeManager.getInt8Type (), idx));
+      break;
+
+    case Type::Double:
+      {
+//      if (idx == 0)
+//        inst = irManager.newCopyPseudoInst (Mnemonic_MOV, dst, (Opnd*)src);
+//      else
+          {
+            Mnemonic mn = idx == 0 ? Mnemonic_MOVAPD : Mnemonic_MOVHLPS;
+            inst = irManager.newInstEx (mn, 1, dst, (Opnd*)src);
+          }
+        break;
+      }
+
+    case Type::UInt32:
+    case Type::Int32:
+      inst = irManager.newInstEx (Mnemonic_PEXTRD, 1, dst, (Opnd*)src, (Opnd*)index);
+      break;
+
+    case Type::UInt64:
+    case Type::Int64:
+#ifndef _EM64T_
+      inst = irManager.newI8PseudoInst (Mnemonic_PEXTRQ, 1, dst, (Opnd*)src, (Opnd*)index);
+#else
+      inst = irManager.newInstEx (Mnemonic_PEXTRQ, 1, dst, (Opnd*)src, (Opnd*)index);
+#endif
+      break;
+
+    case Type::Vector:
+      {
+        VectorType *vec_type = dst_type->asVectorType ();
+        Type::Tag elem_tag = vec_type->getElemType()->tag;
+
+        if (elem_tag == Type::Int64 || elem_tag == Type::UInt64)
+          // FIXME: The 64-bit values must be andded with 0xffffffff
+          // before they are used.
+          {
+            assert (idx == 0 || idx == 2);
+            Opnd *select = irManager.newImmOpnd (typeManager.getInt8Type(),
+                                                 idx | ((idx + 1) << 4));
+            inst = irManager.newInstEx (Mnemonic_PSHUFD, 1, dst, (Opnd*)src, select);
+          }
+
+        break;
+      }
+
+    default:
+      assert (0);
+    }
+
+  assert (inst);
+  appendInsts (inst);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecPackScalars(Type *dst_type, U_32 numSrcs, CG_OpndHandle** srcs)
+{
+  Opnd *dst = irManager.newOpnd (dst_type);
+  Type *src_type = ((Opnd*)srcs[0])->getType ();
+
+  if (src_type->isDouble ())
+    {
+      assert (numSrcs == 2);
+      // TODO: it should be implemented by UNPCKLPD, but it seems
+      // impossible in current backend design.
+      appendInsts (irManager.newInstEx (Mnemonic_MOVAPD, 1, dst, (Opnd*)srcs[0]));
+      appendInsts (irManager.newInstEx (Mnemonic_MOVLHPS, 1, dst, dst, (Opnd*)srcs[1]));
+    }
+  else if (src_type->isSingle ())
+    {
+      Opnd *tmp = irManager.newOpnd (dst_type);
+      appendInsts (irManager.newInstEx (Mnemonic_MOVAPD, 1, tmp, (Opnd*)srcs[2]));
+      appendInsts (irManager.newInstEx (Mnemonic_UNPCKLPS, 1, tmp, tmp, (Opnd*)srcs[3]));
+      appendInsts (irManager.newInstEx (Mnemonic_MOVAPD, 1, dst, (Opnd*)srcs[0]));
+      appendInsts (irManager.newInstEx (Mnemonic_UNPCKLPS, 1, dst, dst, (Opnd*)srcs[1]));
+      appendInsts (irManager.newInstEx (Mnemonic_MOVLHPS, 1, dst, dst, tmp));
+    }
+#ifndef _EM64T_
+  else if (src_type->isInt8 () || src_type->isUInt8 ())
+    {
+      appendInsts (irManager.newI8PseudoInst (Mnemonic_UNPCKLPD, 1, dst, (Opnd*)srcs[0], (Opnd*)srcs[1]));
+    }
+#endif
+  else if (src_type->isInteger ())
+    {
+      if (src_type->isInt8 () || src_type->isUInt8 ())
+        appendInsts (irManager.newInstEx (Mnemonic_MOVQ, 1, dst, (Opnd*)srcs[0]));
+      else
+        appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, dst, (Opnd*)srcs[0]));
+
+      Mnemonic insr_mn;
+
+      switch (numSrcs)
+        {
+	case 2:
+          insr_mn = Mnemonic_PINSRQ;
+          break;
+        case 4:
+          insr_mn = Mnemonic_PINSRD;
+          break;
+        case 8:
+          insr_mn = Mnemonic_PINSRW;
+          break;
+        case 16:
+          insr_mn = Mnemonic_PINSRB;
+          break;
+        default:
+          assert (0);
+        }
+
+#ifdef _HAVE_SIMD_4_2_
+      // Generates SSE4 instructions
+      for (unsigned i = 1; i < numSrcs; i++)
+        {
+          Opnd *cnt = irManager.newImmOpnd (irManager.getTypeManager().getInt8Type(), i);
+          appendInsts (irManager.newInstEx (insr_mn, 1, dst, dst, (Opnd*)srcs[i], cnt));
+        }
+#else
+      // For processors that don't support SSE4
+      Opnd *temp = irManager.newOpnd (dst_type);
+      Opnd *cnt1 = irManager.newImmOpnd (irManager.getTypeManager().getInt8Type(), 4);
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, temp, (Opnd*)srcs[1]));
+      appendInsts (irManager.newInstEx (Mnemonic_PSLLDQ, 1, temp, temp, cnt1));
+      appendInsts (irManager.newInstEx (Mnemonic_POR, 1, dst, dst, temp));
+      Opnd *cnt2 = irManager.newImmOpnd (irManager.getTypeManager().getInt8Type(), 8);
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, temp, (Opnd*)srcs[2]));
+      appendInsts (irManager.newInstEx (Mnemonic_PSLLDQ, 1, temp, temp, cnt2));
+      appendInsts (irManager.newInstEx (Mnemonic_POR, 1, dst, dst, temp));
+      Opnd *cnt3 = irManager.newImmOpnd (irManager.getTypeManager().getInt8Type(), 12);
+      appendInsts (irManager.newInstEx (Mnemonic_MOVD, 1, temp, (Opnd*)srcs[3]));
+      appendInsts (irManager.newInstEx (Mnemonic_PSLLDQ, 1, temp, temp, cnt3));
+      appendInsts (irManager.newInstEx (Mnemonic_POR, 1, dst, dst, temp));
+#endif
+    }
+  else
+    assert (0);
+
+  return dst;
+}
+
+CG_OpndHandle* InstCodeSelector::vecCmpStr(Type *dst_type, U_32 numSrcs, CG_OpndHandle** srcs)
+{
+  Opnd *dst = irManager.newOpnd (dst_type);
+
+  switch (numSrcs)
+    {
+    case 3:
+      // Implicit string length
+      appendInsts (irManager.newInstEx ((dst_type->tag == Type::Vector
+                                         ? Mnemonic_PCMPISTRM : Mnemonic_PCMPISTRI),
+                                        1, dst, (Opnd*)srcs[0], (Opnd*)srcs[1],
+                                        (Opnd*)srcs[2]));
+      break;
+
+    case 5:
+      // Explicit string length
+      appendInsts (irManager.newInstEx ((dst_type->tag == Type::Vector
+                                         ? Mnemonic_PCMPESTRM : Mnemonic_PCMPESTRI),
+                                        1, dst, (Opnd*)srcs[1], (Opnd*)srcs[3],
+                                        (Opnd*)srcs[0], (Opnd*)srcs[2], (Opnd*)srcs[4]));
+      break;
+
+    default:
+      assert (0);
+    }
+
+  return dst;
+}
+
+//_______________________________________________________________________________________________________________
 //    Create a tau point definition indicating that control flow reached the current point
 
 CG_OpndHandle*  InstCodeSelector::tauPoint() 

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.h Sun Jun  6 22:47:40 2010
@@ -89,6 +89,7 @@ public:
     CG_OpndHandle* and_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
     CG_OpndHandle* or_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
     CG_OpndHandle* xor_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
+    CG_OpndHandle* andnot_(IntegerOp::Types,CG_OpndHandle* src1,CG_OpndHandle* src2);
     CG_OpndHandle* not_(IntegerOp::Types,CG_OpndHandle* src);
     CG_OpndHandle* shladd(IntegerOp::Types,CG_OpndHandle* value,
                           U_32 shiftAmount, CG_OpndHandle* addto);
@@ -111,6 +112,9 @@ public:
     CG_OpndHandle* convToInt(ConvertToIntOp::Types,bool isSigned, bool isZeroExtend,
                               ConvertToIntOp::OverflowMod,Type* dstType, CG_OpndHandle* src);
     CG_OpndHandle* convToFp(ConvertToFpOp::Types, Type* dstType, CG_OpndHandle* src);
+    Opnd*          vectorExtension (VectorType* dst_type, CG_OpndHandle* src,
+                                    Type::Tag src_elem_tag, bool is_zero_extend);
+    CG_OpndHandle* convToVector(VectorType* dstType, CG_OpndHandle* src, bool is_zero_extend);
 
     /// convert unmanaged pointer to object. Boxing
     CG_OpndHandle*  convUPtrToObject(ObjectType * dstType, CG_OpndHandle* val);
@@ -257,6 +261,16 @@ public:
     CG_OpndHandle* copy(CG_OpndHandle *src);
     void prefetch(CG_OpndHandle *addr);
 
+    CG_OpndHandle*  vecAddSub(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2);
+    CG_OpndHandle*  vecHadd(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2);
+    CG_OpndHandle*  vecHsub(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2);
+    CG_OpndHandle*  vecShuffle(Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2,
+                               CG_OpndHandle* pattern);
+    CG_OpndHandle*  vecExtract(Type *dst_type, CG_OpndHandle* src, CG_OpndHandle* index);
+    CG_OpndHandle*  vecPackScalars(Type *dst_type, U_32 numSrcs, CG_OpndHandle** srcs);
+    CG_OpndHandle*  vecInterleave(bool high, Type *dst_type, CG_OpndHandle* src1, CG_OpndHandle* src2);
+    CG_OpndHandle*  vecCmpStr(Type *dst_type, U_32 numSrcs, CG_OpndHandle** srcs);
+
     void pseudoInst();
 
     void methodEntry(MethodDesc* mDesc);
@@ -327,6 +341,8 @@ private: 
     
     Opnd * fpOp(Mnemonic mn, Type * dstType, Opnd * src1, Opnd * src2); 
 
+    Opnd * vecBinaryOp(Mnemonic mn, Opnd * src1, Opnd * src2);
+
     Opnd * createResultOpnd(Type * dstType);
 
     Opnd * divOp(DivOp::Types   op, bool rem, Opnd * src1, Opnd * src2);
@@ -383,6 +399,8 @@ private: 
                                     Opnd *baseTau, Opnd *offsetTau);
     void                simpleStInd(Opnd *addr, Opnd *src, Type::Tag memType, 
                                     bool autoCompressRef, Opnd *baseTau, Opnd *offsetAndTypeTau);
+    CG_OpndHandle*      vectorLdInd(Type *dstType, Opnd *addr);
+    void                vectorStInd(Opnd *addr, Opnd *src);
     Type *              getFieldRefType(Type *dstType, Type::Tag memType);
     void                simplifyTypeTag(Type::Tag& tag,Type *ptr);
     Opnd **         createReturnArray(Type * retType, U_32& numRegRet);

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp Sun Jun  6 22:47:40 2010
@@ -350,7 +350,7 @@ void StackLayouter::createProlog()
     offset &= ~(stackSizeAlignment - 1);
     
     if (cConvention->getStackAlignment() == STACK_ALIGN_HALF16 &&
-        (offset & ~(STACK_ALIGN16 - 1)) == 0) {
+        (offset & (STACK_ALIGN16 - 1)) == 0) {
         // Need to align size of callee save area on half of 16-bytes
         // thus resulting stack pointer will be 16-bytes aligned.
         offset -= STACK_ALIGN_HALF16; 

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/jet/cg_fld_arr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/jet/cg_fld_arr.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/jet/cg_fld_arr.cpp Sun Jun  6 22:47:40 2010
@@ -31,6 +31,7 @@
 
 #include "trace.h"
 #include "VMMagic.h"
+#include "SIMD.h"
 
 namespace Jitrino {
 namespace Jet {
@@ -270,6 +271,8 @@ void CodeGen::do_field_op(const FieldOpI
     
     const char* fieldDescName = class_cp_get_entry_descriptor(fieldOp.enclClass, fieldOp.cpIndex);
     bool fieldIsMagic = VMMagicUtils::isVMMagicClass(fieldDescName);
+    fieldIsMagic = fieldIsMagic || SIMDUtils::isSIMDClass(fieldDescName);
+    
     if (fieldIsMagic) {
         jt = iplatf;
     }

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/CodeSelectors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/CodeSelectors.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/CodeSelectors.cpp Sun Jun  6 22:47:40 2010
@@ -105,6 +105,38 @@ ArithmeticOp::Types _BlockCodeSelector::
             return ArithmeticOp::S;
         case Type::Double:
             return ArithmeticOp::D;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return ArithmeticOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return ArithmeticOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return ArithmeticOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return ArithmeticOp::VI8_2;
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return ArithmeticOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return ArithmeticOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -199,6 +231,38 @@ DivOp::Types _BlockCodeSelector::mapToDi
             return DivOp::S;
         case Type::Double:
             return DivOp::D;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return DivOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return DivOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return DivOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return DivOp::VI8_2;
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return DivOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return DivOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -238,6 +302,38 @@ NegOp::Types _BlockCodeSelector::mapToNe
             return NegOp::S;
         case Type::Double:
             return NegOp::D;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return NegOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return NegOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return NegOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return NegOp::VI8_2;
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return NegOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return NegOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -257,6 +353,32 @@ IntegerOp::Types _BlockCodeSelector::map
         case Type::IntPtr:
         case Type::UIntPtr:
             return IntegerOp::I;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return IntegerOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return IntegerOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return IntegerOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return IntegerOp::VI8_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -282,6 +404,38 @@ CompareOp::Types _BlockCodeSelector::map
             return CompareOp::S;
         case Type::Double:
             return CompareOp::D;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return CompareOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return CompareOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return CompareOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return CompareOp::VI8_2;
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return CompareOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return CompareOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: 
 
             assert(Type::isReference(type));
@@ -301,6 +455,38 @@ CompareZeroOp::Types _BlockCodeSelector:
             return CompareZeroOp::I8;
         case Type::IntPtr:
             return CompareZeroOp::I;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return CompareZeroOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return CompareZeroOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return CompareZeroOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return CompareZeroOp::VI8_2;
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return CompareZeroOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return CompareZeroOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default:
             assert(Type::isReference(type));
             return CompareZeroOp::Ref;
@@ -337,6 +523,26 @@ ConvertToFpOp::Types _BlockCodeSelector:
         case Type::Single: return ConvertToFpOp::Single;
         case Type::Double: return ConvertToFpOp::Double;
         case Type::Float:  return ConvertToFpOp::FloatFromUnsigned;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Single:
+                  if (dst_type->getLength () == 4)
+                    return ConvertToFpOp::VS_4;
+                case Type::Double:
+                  if (dst_type->getLength () == 2)
+                    return ConvertToFpOp::VD_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -364,6 +570,32 @@ ConvertToIntOp::Types _BlockCodeSelector
         case Type::IntPtr: 
         case Type::UIntPtr: 
             return ConvertToIntOp::I;
+        case Type::Vector:
+            {
+              VectorType *dst_type = inst->getDst()->getType()->asVectorType ();
+              assert (dst_type);
+              NamedType *elem_type = dst_type->getElemType ();
+
+              switch (elem_type->tag)
+                {
+                case Type::Int8:
+                  if (dst_type->getLength () == 16)
+                    return ConvertToIntOp::VI1_16;
+                case Type::Int16:
+                  if (dst_type->getLength () == 8)
+                    return ConvertToIntOp::VI2_8;
+                case Type::Int32:
+                  if (dst_type->getLength () == 4)
+                    return ConvertToIntOp::VI4_4;
+                case Type::Int64:
+                  if (dst_type->getLength () == 2)
+                    return ConvertToIntOp::VI8_2;
+                default:
+                  ;
+                }
+
+              assert (0);
+            }
         default: assert(0);
     }
     assert(0);
@@ -588,6 +820,14 @@ void _BlockCodeSelector::genInstCode(Ins
                     getCGInst(inst->getSrc(1)));
             }
             break;
+        case Op_AndNot:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.andnot_(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
         case Op_Not:
             {
                 assert(inst->getNumSrcOperands() == 1);
@@ -618,6 +858,11 @@ void _BlockCodeSelector::genInstCode(Ins
                     cgInst = instructionCallback.convUPtrToObject(dstType->asObjectType(), getCGInst(inst->getSrc(0)));
                 } else if (dstType->isUnmanagedPtr()) {
                     cgInst = instructionCallback.convToUPtr(dstType->asPtrType(), getCGInst(inst->getSrc(0)));
+                } else if (dstType->isVector()) {
+                    cgInst = instructionCallback.convToVector
+                      (dstType->asVectorType (),
+                       getCGInst (inst->getSrc (0)),
+                       inst->getOpcode() == Op_ConvZE);
                 } else {
                     bool isSigned = Type::isSignedInteger(inst->getType());
                     bool isZeroExtend = inst->getOpcode() == Op_ConvZE;
@@ -1786,6 +2031,83 @@ void _BlockCodeSelector::genInstCode(Ins
                 instructionCallback.prefetch(getCGInst(addr));
             }
             break;
+        case Op_VecAddSub:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.vecAddSub (inst->getDst()->getType (),
+                                                        getCGInst (inst->getSrc (0)),
+                                                        getCGInst (inst->getSrc (1)));
+            }
+            break;
+        case Op_VecHadd:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.vecHadd (inst->getDst()->getType (),
+                                                      getCGInst (inst->getSrc (0)),
+                                                      getCGInst (inst->getSrc (1)));
+            }
+            break;
+        case Op_VecHsub:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.vecHsub (inst->getDst()->getType (),
+                                                      getCGInst (inst->getSrc (0)),
+                                                      getCGInst (inst->getSrc (1)));
+            }
+            break;
+        case Op_VecShuffle:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                cgInst = instructionCallback.vecShuffle (inst->getDst()->getType (),
+                                                         getCGInst (inst->getSrc (0)),
+                                                         getCGInst (inst->getSrc (1)),
+                                                         getCGInst (inst->getSrc (2)));
+            }
+            break;
+        case Op_VecExtract:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Type *dst_type = inst->getDst()->getType ();
+                Opnd *vector = inst->getSrc(0);
+                Opnd *index = inst->getSrc(1);
+                cgInst = instructionCallback.vecExtract(dst_type, getCGInst(vector),
+                                                        getCGInst (index));
+            }
+            break;
+        case Op_VecPackScalars:
+            {
+                Type *dst_type = inst->getDst()->getType ();
+                U_32 numSrcs = inst->getNumSrcOperands();
+                CG_OpndHandle **srcs = genCallArgs(inst, 0);
+                cgInst = instructionCallback.vecPackScalars(dst_type, numSrcs, srcs);
+            }
+            break;
+        case Op_VecInterleaveHigh:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.vecInterleave
+                  (true, inst->getDst()->getType (),
+                   getCGInst (inst->getSrc (0)),
+                   getCGInst (inst->getSrc (1)));
+            }
+            break;
+        case Op_VecInterleaveLow:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.vecInterleave
+                  (false, inst->getDst()->getType (),
+                   getCGInst (inst->getSrc (0)),
+                   getCGInst (inst->getSrc (1)));
+            }
+            break;
+        case Op_VecCmpStr:
+            {
+                Type *dst_type = inst->getDst()->getType ();
+                U_32 numSrcs = inst->getNumSrcOperands();
+                CG_OpndHandle **srcs = genCallArgs(inst, 0);
+                cgInst = instructionCallback.vecCmpStr(dst_type, numSrcs, srcs);
+            }
+            break;
         case Op_TauPoint:
             {
                 assert(inst->getNumSrcOperands() == 0);

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.cpp Sun Jun  6 22:47:40 2010
@@ -446,6 +446,33 @@ Node* FlowGraph::duplicateRegion(IRManag
     return duplicateRegion(irm, entry, nodesInRegion, defUses, *nodeRenameTable, *opndRenameTable, newEntryFreq);
 }
 
+
+Node* FlowGraph::duplicateSingleNode(IRManager& irm, Node* node,
+                                     StlBitVector& nodesInRegion,
+                                     DefUseBuilder& defUses,
+                                     OpndRenameTable& opndRenameTable,
+                                     double newNodeFreq) {
+    NodeRenameTable* reverseNodeRenameTable = new (irm.getMemoryManager()) 
+        NodeRenameTable(irm.getMemoryManager(), nodesInRegion.size());     
+    Node* newNode = duplicateNode(irm, node, &nodesInRegion, &defUses, &opndRenameTable, reverseNodeRenameTable);
+    if(newNodeFreq == 0) {
+        return newNode;
+    }
+    double scale = newNodeFreq / node->getExecCount();
+    assert(scale >=0 && scale <= 1);
+    newNode->setExecCount(node->getExecCount()*scale);
+    node->setExecCount(node->getExecCount()*(1-scale));
+    return newNode;
+}
+
+Node* FlowGraph::duplicateSingleNode(IRManager& irm, Node* node, StlBitVector& nodesInRegion, DefUseBuilder& defUses, double newNodeFreq) {
+    MemoryManager dupMemManager("FlowGraph::duplicateRegion.dupMemManager");
+    // prepare the hashtable for the operand rename translation
+    OpndRenameTable *opndRenameTable = new (dupMemManager) OpndRenameTable(dupMemManager, nodesInRegion.size());
+    return duplicateSingleNode(irm, node, nodesInRegion, defUses, *opndRenameTable, newNodeFreq);
+}
+
+
 void FlowGraph::renameOperandsInNode(Node *node, OpndRenameTable *renameTable) {
     Inst *first = (Inst*)node->getFirstInst();
     for (Inst *inst = first->getNextInst(); inst != NULL; inst = inst->getNextInst()) {

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.h?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.h (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/FlowGraph.h Sun Jun  6 22:47:40 2010
@@ -71,6 +71,10 @@ public:
     static Node* duplicateRegion(IRManager& irm, Node* entry, StlBitVector& nodesInRegion, DefUseBuilder& defUses, NodeRenameTable& nodeRenameTable, OpndRenameTable& opndRenameTable, double newEntryFreq = 0.0);
     
 
+    static Node* duplicateSingleNode(IRManager& irm, Node* node, StlBitVector& nodesInRegion, DefUseBuilder& defUses, OpndRenameTable& opndRenameTable, double newNodeFreq=0.0);
+    static Node* duplicateSingleNode(IRManager& irm, Node* node, StlBitVector& nodesInRegion, DefUseBuilder& defUses, double newNodeFreq=0.0);
+
+
     static void  renameOperandsInNode(Node *node, OpndRenameTable *renameTable);
 
     static void doTranslatorCleanupPhase(IRManager& irm);

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.cpp Sun Jun  6 22:47:40 2010
@@ -885,6 +885,20 @@ IRBuilder::genXor(Type* dstType, Opnd* s
     return dst;
 }
 Opnd*
+IRBuilder::genAndNot(Type* dstType, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy(src1);
+    src2 = propagateCopy(src2);
+    Opnd* dst = lookupHash(Op_AndNot, src1, src2);
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd(dstType);
+        appendInst(instFactory->makeAndNot(dst, src1, src2));
+    }
+    insertHash(Op_AndNot, src1, src2, dst->getInst());
+    return dst;
+}
+Opnd*
 IRBuilder::genNot(Type* dstType, Opnd* src) {
     src = propagateCopy(src);
     Opnd* dst = lookupHash(Op_Not, src);
@@ -3233,6 +3247,226 @@ IRBuilder::genTauCheckFinite(Opnd* src) 
     return dst;
 }
 
+Opnd*
+IRBuilder::genVecAddSub (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecAddSub, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecAddSub (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecHadd (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecHadd, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecHadd (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecHsub (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecHsub, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecHsub (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genMaxVec (Type* dstType, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+    Operation operation (Op_Max, dstType->tag, Modifier ());
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+        
+    if (!dst) {
+        dst = createOpnd (dstType);
+        appendInst (instFactory->makeMax (dst, src1, src2));
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genMinVec (Type* dstType, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+    Operation operation (Op_Min, dstType->tag, Modifier ());
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+        
+    if (!dst) {
+        dst = createOpnd (dstType);
+        appendInst (instFactory->makeMin (dst, src1, src2));
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genAbsVec (Type* dstType, Opnd* src1) {
+    src1 = propagateCopy (src1);
+    Operation operation (Op_Abs, dstType->tag, Modifier ());
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1);
+
+    if (dst) return dst;
+        
+    if (!dst) {
+        dst = createOpnd (dstType);
+        appendInst (instFactory->makeAbs (dst, src1));
+    }
+
+    insertHash (hashcode, src1, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecShuffle (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2, Opnd* src3) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+    src3 = propagateCopy (src3);
+
+    Operation operation (Op_VecShuffle, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2, src3);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecShuffle (dst, src1, src2, src3);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, src3, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecExtract (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecExtract, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecExtract (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecPackScalars (Type* dstType, Modifier mod, U_32 numOpnds, Opnd **opnds) {
+    Opnd* dst = createOpnd (dstType);
+    Inst *newi = instFactory->makeVecPackScalars (dst, numOpnds, opnds);
+    appendInst (newi);
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecInterleaveHigh (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecInterleaveHigh, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecInterleaveHigh (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecInterleaveLow (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {
+    src1 = propagateCopy (src1);
+    src2 = propagateCopy (src2);
+
+    Operation operation (Op_VecInterleaveLow, dstType->tag, mod);
+    U_32 hashcode = operation.encodeForHashing ();
+    Opnd* dst = lookupHash (hashcode, src1, src2);
+
+    if (dst) return dst;
+
+    if (!dst) {
+        dst = createOpnd (dstType);
+        Inst *newi = instFactory->makeVecInterleaveLow (dst, src1, src2);
+        appendInst (newi);
+    }
+
+    insertHash (hashcode, src1, src2, dst->getInst ());
+    return dst;
+}
+
+Opnd*
+IRBuilder::genVecCmpStr (Type* dstType, U_32 numOpnds, Opnd **opnds) {
+    Opnd* dst = createOpnd (dstType);
+    Inst *newi = instFactory->makeVecCmpStr (dst, numOpnds, opnds);
+    appendInst (newi);
+    return dst;
+}
+
 //-----------------------------------------------------------------------------
 //
 // Methods for CSE hashing

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.h?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.h (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/IRBuilder.h Sun Jun  6 22:47:40 2010
@@ -101,6 +101,7 @@ public:
     Opnd* genAnd(Type* dstType, Opnd* src1, Opnd* src2); // TR //SI
     Opnd* genOr(Type* dstType, Opnd* src1, Opnd* src2);//TR //SI
     Opnd* genXor(Type* dstType, Opnd* src1, Opnd* src2);//TR //SI
+    Opnd* genAndNot(Type* dstType, Opnd* src1, Opnd* src2); // TR //SI
     Opnd* genNot(Type* dstType, Opnd* src);//TR //SI
     // Conversion
     Opnd* genConv(Type* dstType, Type::Tag toType, Modifier ovfMod, Opnd* src); //TR //SI
@@ -368,6 +369,19 @@ public:
     void       genMonitorEnterFence(Opnd *src);
     void       genMonitorExitFence(Opnd *src);
     
+    Opnd*      genMinVec (Type* dstType, Opnd* src1, Opnd* src2); //SI
+    Opnd*      genMaxVec (Type* dstType, Opnd* src1, Opnd* src2); //SI
+    Opnd*      genAbsVec (Type* dstType, Opnd* src1); //SI
+    Opnd*      genVecAddSub (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecHadd (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecHsub (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecShuffle (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2, Opnd* src3);
+    Opnd*      genVecExtract (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecPackScalars (Type* dstType, Modifier mod, U_32 numOpnds, Opnd **opnds);
+    Opnd*      genVecInterleaveHigh (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecInterleaveLow (Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd*      genVecCmpStr (Type* dstType, U_32 numOpnds, Opnd **opnds);
+
 private:
 
     void readFlagsFromCommandLine(SessionAction* argSource, const char* argPrefix);

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.cpp Sun Jun  6 22:47:40 2010
@@ -1775,6 +1775,10 @@ Inst* InstFactory::makeXor(Opnd* dst, Op
     return makeInst(Op_Xor, Modifier(), dst->getType()->tag, dst, src1, src2);
 }
 
+Inst* InstFactory::makeAndNot(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_AndNot, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
 Inst* InstFactory::makeNot(Opnd* dst, Opnd* src) {
     return makeInst(Op_Not, Modifier(), dst->getType()->tag, dst, src);
 }
@@ -2535,6 +2539,55 @@ Inst* InstFactory::makeIncCounter(U_32 v
     return makeTokenInst(Op_IncCounter, Modifier(), Type::Void, OpndManager::getNullOpnd(), val, NULL);
 }
 
+Inst*
+InstFactory::makeVecAddSub(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_VecAddSub, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
+Inst*
+InstFactory::makeVecHadd(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_VecHadd, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
+Inst*
+InstFactory::makeVecHsub(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_VecHsub, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
+Inst*
+InstFactory::makeVecShuffle(Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3) {
+    return makeMultiSrcInst(Op_VecShuffle, Modifier(), dst->getType()->tag, dst, src1, src2, src3);
+}
+
+Inst*
+InstFactory::makeVecExtract(Opnd *dst, Opnd *src, Opnd *index) {
+    return makeInst(Op_VecExtract, Modifier(), dst->getType()->tag, dst, src, index);
+}
+
+Inst*
+InstFactory::makeVecPackScalars(Opnd *dst, U_32 numOpnds, Opnd **opnds) {
+    Opnd** srcs = copyOpnds(opnds, numOpnds);
+    return makeMultiSrcInst(Op_VecPackScalars, Modifier(), dst->getType()->tag,
+                            dst, numOpnds, srcs);
+}
+
+Inst*
+InstFactory::makeVecInterleaveHigh(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_VecInterleaveHigh, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
+Inst*
+InstFactory::makeVecInterleaveLow(Opnd* dst, Opnd* src1, Opnd* src2) {
+    return makeInst(Op_VecInterleaveLow, Modifier(), dst->getType()->tag, dst, src1, src2);
+}
+
+Inst*
+InstFactory::makeVecCmpStr(Opnd *dst, U_32 numOpnds, Opnd **opnds) {
+    Opnd** srcs = copyOpnds(opnds, numOpnds);
+    return makeMultiSrcInst(Op_VecCmpStr, Modifier(), dst->getType()->tag,
+                            dst, numOpnds, srcs);
+}
+
 Inst* InstFactory::makeTauPoint(Opnd *dst) {
     assert(dst->getType()->tag == Type::Tau);
     return makeInst(Op_TauPoint, Modifier(), Type::Tau, dst);
@@ -2613,6 +2666,7 @@ InstOptimizer::dispatch(Inst* inst) {
     case Op_And:                return caseAnd(inst);
     case Op_Or:                 return caseOr(inst);
     case Op_Xor:                return caseXor(inst);
+    case Op_AndNot:             return caseAndNot(inst);
     case Op_Not:                return caseNot(inst);
     case Op_Select:             return caseSelect(inst);
     case Op_Conv:               return caseConv(inst);
@@ -2716,6 +2770,15 @@ InstOptimizer::dispatch(Inst* inst) {
     case Op_LdArrayLenOffsetPlusHeapbase:  return caseLdArrayLenOffsetPlusHeapbase(inst->asTypeInst());
     case Op_AddOffset:          return caseAddOffset(inst);
     case Op_AddOffsetPlusHeapbase: return caseAddOffsetPlusHeapbase(inst);
+    case Op_VecAddSub:          return caseVecAddSub(inst);
+    case Op_VecHadd:            return caseVecHadd(inst);
+    case Op_VecHsub:            return caseVecHsub(inst);
+    case Op_VecShuffle:         return caseVecShuffle(inst);
+    case Op_VecExtract:         return caseVecExtract(inst);
+    case Op_VecPackScalars:     return caseVecPackScalars(inst);
+    case Op_VecInterleaveHigh:  return caseVecInterleaveHigh(inst);
+    case Op_VecInterleaveLow:   return caseVecInterleaveLow(inst);
+    case Op_VecCmpStr:          return caseVecCmpStr(inst);
     case Op_TauPoint:           return caseTauPoint(inst);
     case Op_TauEdge:            return caseTauEdge(inst);
     case Op_TauAnd:             return caseTauAnd(inst);

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.h?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.h (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Inst.h Sun Jun  6 22:47:40 2010
@@ -1056,6 +1056,7 @@ public:
     Inst*    makeAnd(Opnd* dst, Opnd* src1, Opnd* src2);
     Inst*    makeOr(Opnd* dst, Opnd* src1, Opnd* src2);
     Inst*    makeXor(Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeAndNot(Opnd* dst, Opnd* src1, Opnd* src2);
     Inst*    makeNot(Opnd* dst, Opnd* src);
     // Selection
     Inst*    makeSelect(Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3);
@@ -1232,6 +1233,20 @@ public:
     Inst*    makeAddOffset(Opnd* dst, Opnd* ref, Opnd* offset);
     Inst*    makeAddOffsetPlusHeapbase(Opnd* dst, Opnd* ref, Opnd* offset);
 
+    // Vector operations
+    Inst*    makeVecAddSub (Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeVecHadd (Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeVecHsub (Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeVecShuffle (Opnd* dst, Opnd* src1, Opnd* src2, Opnd* src3);
+    // Make an instruction that extract the INDEX-th element from the
+    // vector SRC to DST.
+    Inst*    makeVecExtract (Opnd *dst, Opnd *src, Opnd *index);
+    // Pack OPNDS[0..n] into the vector DST.
+    Inst*    makeVecPackScalars (Opnd *dst, U_32 numOpnds, Opnd **opnds);
+    Inst*    makeVecInterleaveHigh (Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeVecInterleaveLow (Opnd* dst, Opnd* src1, Opnd* src2);
+    Inst*    makeVecCmpStr (Opnd *dst, U_32 numOpnds, Opnd **opnds);
+
     // new tau methods
     Inst*    makeTauPoint(Opnd *dst);
     Inst*    makeTauEdge(Opnd *dst);
@@ -1532,6 +1547,9 @@ public:
     caseXor(Inst* inst)=0;//                 {return caseDefault(inst);}
 
     virtual Inst*
+    caseAndNot(Inst* inst)=0;//              {return caseDefault(inst);}
+
+    virtual Inst*
     caseNot(Inst* inst)=0;//                 {return caseDefault(inst);}
 
     // selection
@@ -1879,6 +1897,33 @@ public:
     virtual Inst*
     caseAddOffsetPlusHeapbase(Inst* inst)=0;// {return caseDefault(inst);}
 
+    virtual Inst*
+    caseVecAddSub(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecHadd(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecHsub(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecShuffle(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecExtract(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecPackScalars(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecInterleaveHigh(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecInterleaveLow(Inst* inst)=0;
+
+    virtual Inst*
+    caseVecCmpStr(Inst* inst)=0;
+
     // new tau methods
     virtual Inst*
     caseTauPoint(Inst* inst)=0;//         {return caseDefault(inst);}

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.cpp Sun Jun  6 22:47:40 2010
@@ -88,6 +88,7 @@ static OpcodeInfo opcodeTable[] = {
     { Op_And,                   false, MB::Movable,       MK::None,                                  "and   ",        "and       %s -) %l",           },
     { Op_Or,                    false, MB::Movable,       MK::None,                                  "or    ",        "or        %s -) %l",           },
     { Op_Xor,                   false, MB::Movable,       MK::None,                                  "xor   ",        "xor       %s -) %l",           },
+    { Op_AndNot,                false, MB::Movable,       MK::None,                                  "andnot",        "andnot    %s -) %l",           },
     { Op_Not,                   false, MB::Movable,       MK::None,                                  "not   ",        "not       %s -) %l",           },
     { Op_Select,                false, MB::Movable,       MK::None,                                  "select",        "select %s -) %l",              }, // (src1 ? src2 : src3)
     { Op_Conv,                  false, MB::Movable,       MK::Overflow_and_Exception_and_Strict,     "conv  ",        "conv%t%m %s -) %l",            }, 
@@ -204,6 +205,15 @@ static OpcodeInfo opcodeTable[] = {
     { Op_AddOffset,             false, MB::Movable,       MK::None,                                  "addoffset",              "addoff %s -) %l",      },
     { Op_AddOffsetPlusHeapbase, false, MB::Movable,       MK::None,                                  "addoffphb",              "addoffphb %s -) %l",      },
 
+    { Op_VecAddSub,             false, MB::Movable,       MK::None,                                  "addsub",           "addsub       %s -) %l",           },
+    { Op_VecHadd,               false, MB::Movable,       MK::None,                                  "hadd",             "hadd         %s -) %l",           },
+    { Op_VecHsub,               false, MB::Movable,       MK::None,                                  "hsub",             "hsub         %s -) %l",           },
+    { Op_VecShuffle,            false, MB::Movable,       MK::None,                                  "shuffle",          "shuffle      %s -) %l",           },
+    { Op_VecExtract,            false, MB::Movable,       MK::None,                                  "vecextr",          "vecextr      %s -) %l",           },
+    { Op_VecPackScalars,        false, MB::Movable,       MK::None,                                  "vecpack",          "vecpack      %s -) %l",           },
+    { Op_VecInterleaveHigh,     false, MB::Movable,       MK::None,                                  "unpackh",          "unpackh      %s -) %l",           },
+    { Op_VecInterleaveLow,      false, MB::Movable,       MK::None,                                  "unpackl",          "unpackl      %s -) %l",           },
+    { Op_VecCmpStr,             false, MB::Movable,       MK::None,                                  "cmpstr",           "cmpstr       %s -) %l",           },
     { Op_TauPoint,              false, MB::None,          MK::None,                                  "taupoint ",        "taupoint() -) %l",           }, // mark
     { Op_TauEdge,              false, MB::None,          MK::None,                                   "tauedge ",        "tauedge() -) %l",           }, // mark
     { Op_TauAnd,                false, MB::Movable,       MK::None,                                  "tauand ",        "tauand       %s -) %l",        },

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.h?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opcode.h Sun Jun  6 22:47:40 2010
@@ -296,6 +296,7 @@ enum Opcode {
     Op_Min,   Op_Max,   Op_Abs,     // no modifiers
     // Bitwise
     Op_And,    Op_Or,    Op_Xor,
+    Op_AndNot,
     Op_Not,
     // Selection
     Op_Select,                      // (src1 ? src2 : src3)
@@ -438,6 +439,17 @@ enum Opcode {
     Op_AddOffset,                   // add uncompref+offset
     Op_AddOffsetPlusHeapbase,       // add compref+offsetPlusHeapbase (uncompressing)
 
+    // Vector operations:
+    Op_VecAddSub,                   // add odd elements and sub even elements
+    Op_VecHadd,                     // horizontal add pairs of elements
+    Op_VecHsub,                     // horizontal sub pairs of elements
+    Op_VecShuffle,                  // shuffle elements of a vector according to a given pattern
+    Op_VecExtract,                  // extract a scalar value from a vector
+    Op_VecPackScalars,              // pack multiple scalar values into a vector
+    Op_VecInterleaveHigh,           // interleave high parts of two vectors
+    Op_VecInterleaveLow,            // interleave low parts of two vectors
+    Op_VecCmpStr,                   // compare strings, return index
+
     // ADDED FOR TAU:
 
     Op_TauPoint,

Modified: harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opnd.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opnd.cpp?rev=952017&r1=952016&r2=952017&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opnd.cpp (original)
+++ harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/optimizer/Opnd.cpp Sun Jun  6 22:47:40 2010
@@ -151,6 +151,8 @@ OpndManager::getOpndTypeFromLdType(Type*
         return typeManager.getDoubleType();
     case Type::Float:
         return typeManager.getFloatType();
+    case Type::Vector:
+        return ldType;
         // object types
     case Type::CompressedSystemObject:
     case Type::CompressedUnresolvedObject:



Mime
View raw message