src/share/vm/opto/vectornode.cpp

changeset 3882
8c92982cbbc4
parent 3040
c7b60b601eb4
child 4001
006050192a5a
     1.1 --- a/src/share/vm/opto/vectornode.cpp	Thu Jun 14 14:59:52 2012 -0700
     1.2 +++ b/src/share/vm/opto/vectornode.cpp	Fri Jun 15 01:25:19 2012 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -28,147 +28,16 @@
    1.11  
    1.12  //------------------------------VectorNode--------------------------------------
    1.13  
    1.14 -// Return vector type for an element type and vector length.
    1.15 -const Type* VectorNode::vect_type(BasicType elt_bt, uint len) {
    1.16 -  assert(len <= VectorNode::max_vlen(elt_bt), "len in range");
    1.17 -  switch(elt_bt) {
    1.18 -  case T_BOOLEAN:
    1.19 -  case T_BYTE:
    1.20 -    switch(len) {
    1.21 -    case 2:  return TypeInt::CHAR;
    1.22 -    case 4:  return TypeInt::INT;
    1.23 -    case 8:  return TypeLong::LONG;
    1.24 -    }
    1.25 -    break;
    1.26 -  case T_CHAR:
    1.27 -  case T_SHORT:
    1.28 -    switch(len) {
    1.29 -    case 2:  return TypeInt::INT;
    1.30 -    case 4:  return TypeLong::LONG;
    1.31 -    }
    1.32 -    break;
    1.33 -  case T_INT:
    1.34 -    switch(len) {
    1.35 -    case 2:  return TypeLong::LONG;
    1.36 -    }
    1.37 -    break;
    1.38 -  case T_LONG:
    1.39 -    break;
    1.40 -  case T_FLOAT:
    1.41 -    switch(len) {
    1.42 -    case 2:  return Type::DOUBLE;
    1.43 -    }
    1.44 -    break;
    1.45 -  case T_DOUBLE:
    1.46 -    break;
    1.47 -  }
    1.48 -  ShouldNotReachHere();
    1.49 -  return NULL;
    1.50 -}
    1.51 -
    1.52 -// Scalar promotion
    1.53 -VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) {
    1.54 -  BasicType bt = opd_t->array_element_basic_type();
    1.55 -  assert(vlen <= VectorNode::max_vlen(bt), "vlen in range");
    1.56 -  switch (bt) {
    1.57 -  case T_BOOLEAN:
    1.58 -  case T_BYTE:
    1.59 -    if (vlen == 16) return new (C, 2) Replicate16BNode(s);
    1.60 -    if (vlen ==  8) return new (C, 2) Replicate8BNode(s);
    1.61 -    if (vlen ==  4) return new (C, 2) Replicate4BNode(s);
    1.62 -    break;
    1.63 -  case T_CHAR:
    1.64 -    if (vlen == 8) return new (C, 2) Replicate8CNode(s);
    1.65 -    if (vlen == 4) return new (C, 2) Replicate4CNode(s);
    1.66 -    if (vlen == 2) return new (C, 2) Replicate2CNode(s);
    1.67 -    break;
    1.68 -  case T_SHORT:
    1.69 -    if (vlen == 8) return new (C, 2) Replicate8SNode(s);
    1.70 -    if (vlen == 4) return new (C, 2) Replicate4SNode(s);
    1.71 -    if (vlen == 2) return new (C, 2) Replicate2SNode(s);
    1.72 -    break;
    1.73 -  case T_INT:
    1.74 -    if (vlen == 4) return new (C, 2) Replicate4INode(s);
    1.75 -    if (vlen == 2) return new (C, 2) Replicate2INode(s);
    1.76 -    break;
    1.77 -  case T_LONG:
    1.78 -    if (vlen == 2) return new (C, 2) Replicate2LNode(s);
    1.79 -    break;
    1.80 -  case T_FLOAT:
    1.81 -    if (vlen == 4) return new (C, 2) Replicate4FNode(s);
    1.82 -    if (vlen == 2) return new (C, 2) Replicate2FNode(s);
    1.83 -    break;
    1.84 -  case T_DOUBLE:
    1.85 -    if (vlen == 2) return new (C, 2) Replicate2DNode(s);
    1.86 -    break;
    1.87 -  }
    1.88 -  ShouldNotReachHere();
    1.89 -  return NULL;
    1.90 -}
    1.91 -
    1.92 -// Return initial Pack node. Additional operands added with add_opd() calls.
    1.93 -PackNode* PackNode::make(Compile* C, Node* s, const Type* opd_t) {
    1.94 -  BasicType bt = opd_t->array_element_basic_type();
    1.95 -  switch (bt) {
    1.96 -  case T_BOOLEAN:
    1.97 -  case T_BYTE:
    1.98 -    return new (C, 2) PackBNode(s);
    1.99 -  case T_CHAR:
   1.100 -    return new (C, 2) PackCNode(s);
   1.101 -  case T_SHORT:
   1.102 -    return new (C, 2) PackSNode(s);
   1.103 -  case T_INT:
   1.104 -    return new (C, 2) PackINode(s);
   1.105 -  case T_LONG:
   1.106 -    return new (C, 2) PackLNode(s);
   1.107 -  case T_FLOAT:
   1.108 -    return new (C, 2) PackFNode(s);
   1.109 -  case T_DOUBLE:
   1.110 -    return new (C, 2) PackDNode(s);
   1.111 -  }
   1.112 -  ShouldNotReachHere();
   1.113 -  return NULL;
   1.114 -}
   1.115 -
   1.116 -// Create a binary tree form for Packs. [lo, hi) (half-open) range
   1.117 -Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) {
   1.118 -  int ct = hi - lo;
   1.119 -  assert(is_power_of_2(ct), "power of 2");
   1.120 -  int mid = lo + ct/2;
   1.121 -  Node* n1 = ct == 2 ? in(lo)   : binaryTreePack(C, lo,  mid);
   1.122 -  Node* n2 = ct == 2 ? in(lo+1) : binaryTreePack(C, mid, hi );
   1.123 -  int rslt_bsize = ct * type2aelembytes(elt_basic_type());
   1.124 -  if (bottom_type()->is_floatingpoint()) {
   1.125 -    switch (rslt_bsize) {
   1.126 -    case  8: return new (C, 3) PackFNode(n1, n2);
   1.127 -    case 16: return new (C, 3) PackDNode(n1, n2);
   1.128 -    }
   1.129 -  } else {
   1.130 -    assert(bottom_type()->isa_int() || bottom_type()->isa_long(), "int or long");
   1.131 -    switch (rslt_bsize) {
   1.132 -    case  2: return new (C, 3) Pack2x1BNode(n1, n2);
   1.133 -    case  4: return new (C, 3) Pack2x2BNode(n1, n2);
   1.134 -    case  8: return new (C, 3) PackINode(n1, n2);
   1.135 -    case 16: return new (C, 3) PackLNode(n1, n2);
   1.136 -    }
   1.137 -  }
   1.138 -  ShouldNotReachHere();
   1.139 -  return NULL;
   1.140 -}
   1.141 -
   1.142  // Return the vector operator for the specified scalar operation
   1.143 -// and vector length.  One use is to check if the code generator
   1.144 +// and vector length.  Also used to check if the code generator
   1.145  // supports the vector operation.
   1.146 -int VectorNode::opcode(int sopc, uint vlen, const Type* opd_t) {
   1.147 -  BasicType bt = opd_t->array_element_basic_type();
   1.148 -  if (!(is_power_of_2(vlen) && vlen <= max_vlen(bt)))
   1.149 -    return 0; // unimplemented
   1.150 +int VectorNode::opcode(int sopc, uint vlen, BasicType bt) {
   1.151    switch (sopc) {
   1.152    case Op_AddI:
   1.153      switch (bt) {
   1.154      case T_BOOLEAN:
   1.155      case T_BYTE:      return Op_AddVB;
   1.156 -    case T_CHAR:      return Op_AddVC;
   1.157 +    case T_CHAR:
   1.158      case T_SHORT:     return Op_AddVS;
   1.159      case T_INT:       return Op_AddVI;
   1.160      }
   1.161 @@ -186,7 +55,7 @@
   1.162      switch (bt) {
   1.163      case T_BOOLEAN:
   1.164      case T_BYTE:   return Op_SubVB;
   1.165 -    case T_CHAR:   return Op_SubVC;
   1.166 +    case T_CHAR:
   1.167      case T_SHORT:  return Op_SubVS;
   1.168      case T_INT:    return Op_SubVI;
   1.169      }
   1.170 @@ -216,18 +85,18 @@
   1.171      switch (bt) {
   1.172      case T_BOOLEAN:
   1.173      case T_BYTE:   return Op_LShiftVB;
   1.174 -    case T_CHAR:   return Op_LShiftVC;
   1.175 +    case T_CHAR:
   1.176      case T_SHORT:  return Op_LShiftVS;
   1.177      case T_INT:    return Op_LShiftVI;
   1.178      }
   1.179      ShouldNotReachHere();
   1.180 -  case Op_URShiftI:
   1.181 +  case Op_RShiftI:
   1.182      switch (bt) {
   1.183      case T_BOOLEAN:
   1.184 -    case T_BYTE:   return Op_URShiftVB;
   1.185 -    case T_CHAR:   return Op_URShiftVC;
   1.186 -    case T_SHORT:  return Op_URShiftVS;
   1.187 -    case T_INT:    return Op_URShiftVI;
   1.188 +    case T_BYTE:   return Op_RShiftVB;
   1.189 +    case T_CHAR:
   1.190 +    case T_SHORT:  return Op_RShiftVS;
   1.191 +    case T_INT:    return Op_RShiftVI;
   1.192      }
   1.193      ShouldNotReachHere();
   1.194    case Op_AndI:
   1.195 @@ -241,13 +110,14 @@
   1.196      return Op_XorV;
   1.197  
   1.198    case Op_LoadB:
   1.199 +  case Op_LoadUB:
   1.200    case Op_LoadUS:
   1.201    case Op_LoadS:
   1.202    case Op_LoadI:
   1.203    case Op_LoadL:
   1.204    case Op_LoadF:
   1.205    case Op_LoadD:
   1.206 -    return VectorLoadNode::opcode(sopc, vlen);
   1.207 +    return Op_LoadVector;
   1.208  
   1.209    case Op_StoreB:
   1.210    case Op_StoreC:
   1.211 @@ -255,211 +125,170 @@
   1.212    case Op_StoreL:
   1.213    case Op_StoreF:
   1.214    case Op_StoreD:
   1.215 -    return VectorStoreNode::opcode(sopc, vlen);
   1.216 +    return Op_StoreVector;
   1.217    }
   1.218    return 0; // Unimplemented
   1.219  }
   1.220  
   1.221 -// Helper for above.
   1.222 -int VectorLoadNode::opcode(int sopc, uint vlen) {
   1.223 -  switch (sopc) {
   1.224 -  case Op_LoadB:
   1.225 -    switch (vlen) {
   1.226 -    case  2:       return 0; // Unimplemented
   1.227 -    case  4:       return Op_Load4B;
   1.228 -    case  8:       return Op_Load8B;
   1.229 -    case 16:       return Op_Load16B;
   1.230 -    }
   1.231 -    break;
   1.232 -  case Op_LoadUS:
   1.233 -    switch (vlen) {
   1.234 -    case  2:       return Op_Load2C;
   1.235 -    case  4:       return Op_Load4C;
   1.236 -    case  8:       return Op_Load8C;
   1.237 -    }
   1.238 -    break;
   1.239 -  case Op_LoadS:
   1.240 -    switch (vlen) {
   1.241 -    case  2:       return Op_Load2S;
   1.242 -    case  4:       return Op_Load4S;
   1.243 -    case  8:       return Op_Load8S;
   1.244 -    }
   1.245 -    break;
   1.246 -  case Op_LoadI:
   1.247 -    switch (vlen) {
   1.248 -    case  2:       return Op_Load2I;
   1.249 -    case  4:       return Op_Load4I;
   1.250 -    }
   1.251 -    break;
   1.252 -  case Op_LoadL:
   1.253 -    if (vlen == 2) return Op_Load2L;
   1.254 -    break;
   1.255 -  case Op_LoadF:
   1.256 -    switch (vlen) {
   1.257 -    case  2:       return Op_Load2F;
   1.258 -    case  4:       return Op_Load4F;
   1.259 -    }
   1.260 -    break;
   1.261 -  case Op_LoadD:
   1.262 -    if (vlen == 2) return Op_Load2D;
   1.263 -    break;
   1.264 +bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
   1.265 +  if (is_java_primitive(bt) &&
   1.266 +      (vlen > 1) && is_power_of_2(vlen) &&
   1.267 +      Matcher::vector_size_supported(bt, vlen)) {
   1.268 +    int vopc = VectorNode::opcode(opc, vlen, bt);
   1.269 +    return vopc > 0 && Matcher::has_match_rule(vopc);
   1.270    }
   1.271 -  return 0; // Unimplemented
   1.272 -}
   1.273 -
   1.274 -// Helper for above
   1.275 -int VectorStoreNode::opcode(int sopc, uint vlen) {
   1.276 -  switch (sopc) {
   1.277 -  case Op_StoreB:
   1.278 -    switch (vlen) {
   1.279 -    case  2:       return 0; // Unimplemented
   1.280 -    case  4:       return Op_Store4B;
   1.281 -    case  8:       return Op_Store8B;
   1.282 -    case 16:       return Op_Store16B;
   1.283 -    }
   1.284 -    break;
   1.285 -  case Op_StoreC:
   1.286 -    switch (vlen) {
   1.287 -    case  2:       return Op_Store2C;
   1.288 -    case  4:       return Op_Store4C;
   1.289 -    case  8:       return Op_Store8C;
   1.290 -    }
   1.291 -    break;
   1.292 -  case Op_StoreI:
   1.293 -    switch (vlen) {
   1.294 -    case  2:       return Op_Store2I;
   1.295 -    case  4:       return Op_Store4I;
   1.296 -    }
   1.297 -    break;
   1.298 -  case Op_StoreL:
   1.299 -    if (vlen == 2) return Op_Store2L;
   1.300 -    break;
   1.301 -  case Op_StoreF:
   1.302 -    switch (vlen) {
   1.303 -    case  2:       return Op_Store2F;
   1.304 -    case  4:       return Op_Store4F;
   1.305 -    }
   1.306 -    break;
   1.307 -  case Op_StoreD:
   1.308 -    if (vlen == 2) return Op_Store2D;
   1.309 -    break;
   1.310 -  }
   1.311 -  return 0; // Unimplemented
   1.312 +  return false;
   1.313  }
   1.314  
   1.315  // Return the vector version of a scalar operation node.
   1.316 -VectorNode* VectorNode::make(Compile* C, int sopc, Node* n1, Node* n2, uint vlen, const Type* opd_t) {
   1.317 -  int vopc = opcode(sopc, vlen, opd_t);
   1.318 +VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
   1.319 +  const TypeVect* vt = TypeVect::make(bt, vlen);
   1.320 +  int vopc = VectorNode::opcode(opc, vlen, bt);
   1.321  
   1.322    switch (vopc) {
   1.323 -  case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vlen);
   1.324 -  case Op_AddVC: return new (C, 3) AddVCNode(n1, n2, vlen);
   1.325 -  case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vlen);
   1.326 -  case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vlen);
   1.327 -  case Op_AddVL: return new (C, 3) AddVLNode(n1, n2, vlen);
   1.328 -  case Op_AddVF: return new (C, 3) AddVFNode(n1, n2, vlen);
   1.329 -  case Op_AddVD: return new (C, 3) AddVDNode(n1, n2, vlen);
   1.330 +  case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt);
   1.331 +  case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt);
   1.332 +  case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt);
   1.333 +  case Op_AddVL: return new (C, 3) AddVLNode(n1, n2, vt);
   1.334 +  case Op_AddVF: return new (C, 3) AddVFNode(n1, n2, vt);
   1.335 +  case Op_AddVD: return new (C, 3) AddVDNode(n1, n2, vt);
   1.336  
   1.337 -  case Op_SubVB: return new (C, 3) SubVBNode(n1, n2, vlen);
   1.338 -  case Op_SubVC: return new (C, 3) SubVCNode(n1, n2, vlen);
   1.339 -  case Op_SubVS: return new (C, 3) SubVSNode(n1, n2, vlen);
   1.340 -  case Op_SubVI: return new (C, 3) SubVINode(n1, n2, vlen);
   1.341 -  case Op_SubVL: return new (C, 3) SubVLNode(n1, n2, vlen);
   1.342 -  case Op_SubVF: return new (C, 3) SubVFNode(n1, n2, vlen);
   1.343 -  case Op_SubVD: return new (C, 3) SubVDNode(n1, n2, vlen);
   1.344 +  case Op_SubVB: return new (C, 3) SubVBNode(n1, n2, vt);
   1.345 +  case Op_SubVS: return new (C, 3) SubVSNode(n1, n2, vt);
   1.346 +  case Op_SubVI: return new (C, 3) SubVINode(n1, n2, vt);
   1.347 +  case Op_SubVL: return new (C, 3) SubVLNode(n1, n2, vt);
   1.348 +  case Op_SubVF: return new (C, 3) SubVFNode(n1, n2, vt);
   1.349 +  case Op_SubVD: return new (C, 3) SubVDNode(n1, n2, vt);
   1.350  
   1.351 -  case Op_MulVF: return new (C, 3) MulVFNode(n1, n2, vlen);
   1.352 -  case Op_MulVD: return new (C, 3) MulVDNode(n1, n2, vlen);
   1.353 +  case Op_MulVF: return new (C, 3) MulVFNode(n1, n2, vt);
   1.354 +  case Op_MulVD: return new (C, 3) MulVDNode(n1, n2, vt);
   1.355  
   1.356 -  case Op_DivVF: return new (C, 3) DivVFNode(n1, n2, vlen);
   1.357 -  case Op_DivVD: return new (C, 3) DivVDNode(n1, n2, vlen);
   1.358 +  case Op_DivVF: return new (C, 3) DivVFNode(n1, n2, vt);
   1.359 +  case Op_DivVD: return new (C, 3) DivVDNode(n1, n2, vt);
   1.360  
   1.361 -  case Op_LShiftVB: return new (C, 3) LShiftVBNode(n1, n2, vlen);
   1.362 -  case Op_LShiftVC: return new (C, 3) LShiftVCNode(n1, n2, vlen);
   1.363 -  case Op_LShiftVS: return new (C, 3) LShiftVSNode(n1, n2, vlen);
   1.364 -  case Op_LShiftVI: return new (C, 3) LShiftVINode(n1, n2, vlen);
   1.365 +  case Op_LShiftVB: return new (C, 3) LShiftVBNode(n1, n2, vt);
   1.366 +  case Op_LShiftVS: return new (C, 3) LShiftVSNode(n1, n2, vt);
   1.367 +  case Op_LShiftVI: return new (C, 3) LShiftVINode(n1, n2, vt);
   1.368  
   1.369 -  case Op_URShiftVB: return new (C, 3) URShiftVBNode(n1, n2, vlen);
   1.370 -  case Op_URShiftVC: return new (C, 3) URShiftVCNode(n1, n2, vlen);
   1.371 -  case Op_URShiftVS: return new (C, 3) URShiftVSNode(n1, n2, vlen);
   1.372 -  case Op_URShiftVI: return new (C, 3) URShiftVINode(n1, n2, vlen);
   1.373 +  case Op_RShiftVB: return new (C, 3) RShiftVBNode(n1, n2, vt);
   1.374 +  case Op_RShiftVS: return new (C, 3) RShiftVSNode(n1, n2, vt);
   1.375 +  case Op_RShiftVI: return new (C, 3) RShiftVINode(n1, n2, vt);
   1.376  
   1.377 -  case Op_AndV: return new (C, 3) AndVNode(n1, n2, vlen, opd_t->array_element_basic_type());
   1.378 -  case Op_OrV:  return new (C, 3) OrVNode (n1, n2, vlen, opd_t->array_element_basic_type());
   1.379 -  case Op_XorV: return new (C, 3) XorVNode(n1, n2, vlen, opd_t->array_element_basic_type());
   1.380 +  case Op_AndV: return new (C, 3) AndVNode(n1, n2, vt);
   1.381 +  case Op_OrV:  return new (C, 3) OrVNode (n1, n2, vt);
   1.382 +  case Op_XorV: return new (C, 3) XorVNode(n1, n2, vt);
   1.383 +  }
   1.384 +  ShouldNotReachHere();
   1.385 +  return NULL;
   1.386 +
   1.387 +}
   1.388 +
   1.389 +// Scalar promotion
   1.390 +VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) {
   1.391 +  BasicType bt = opd_t->array_element_basic_type();
   1.392 +  const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
   1.393 +                                          : TypeVect::make(bt, vlen);
   1.394 +  switch (bt) {
   1.395 +  case T_BOOLEAN:
   1.396 +  case T_BYTE:
   1.397 +    return new (C, 2) ReplicateBNode(s, vt);
   1.398 +  case T_CHAR:
   1.399 +  case T_SHORT:
   1.400 +    return new (C, 2) ReplicateSNode(s, vt);
   1.401 +  case T_INT:
   1.402 +    return new (C, 2) ReplicateINode(s, vt);
   1.403 +  case T_LONG:
   1.404 +    return new (C, 2) ReplicateLNode(s, vt);
   1.405 +  case T_FLOAT:
   1.406 +    return new (C, 2) ReplicateFNode(s, vt);
   1.407 +  case T_DOUBLE:
   1.408 +    return new (C, 2) ReplicateDNode(s, vt);
   1.409    }
   1.410    ShouldNotReachHere();
   1.411    return NULL;
   1.412  }
   1.413  
   1.414 -// Return the vector version of a scalar load node.
   1.415 -VectorLoadNode* VectorLoadNode::make(Compile* C, int opc, Node* ctl, Node* mem,
   1.416 -                                     Node* adr, const TypePtr* atyp, uint vlen) {
   1.417 -  int vopc = opcode(opc, vlen);
   1.418 -
   1.419 -  switch(vopc) {
   1.420 -  case Op_Load16B: return new (C, 3) Load16BNode(ctl, mem, adr, atyp);
   1.421 -  case Op_Load8B:  return new (C, 3) Load8BNode(ctl, mem, adr, atyp);
   1.422 -  case Op_Load4B:  return new (C, 3) Load4BNode(ctl, mem, adr, atyp);
   1.423 -
   1.424 -  case Op_Load8C:  return new (C, 3) Load8CNode(ctl, mem, adr, atyp);
   1.425 -  case Op_Load4C:  return new (C, 3) Load4CNode(ctl, mem, adr, atyp);
   1.426 -  case Op_Load2C:  return new (C, 3) Load2CNode(ctl, mem, adr, atyp);
   1.427 -
   1.428 -  case Op_Load8S:  return new (C, 3) Load8SNode(ctl, mem, adr, atyp);
   1.429 -  case Op_Load4S:  return new (C, 3) Load4SNode(ctl, mem, adr, atyp);
   1.430 -  case Op_Load2S:  return new (C, 3) Load2SNode(ctl, mem, adr, atyp);
   1.431 -
   1.432 -  case Op_Load4I:  return new (C, 3) Load4INode(ctl, mem, adr, atyp);
   1.433 -  case Op_Load2I:  return new (C, 3) Load2INode(ctl, mem, adr, atyp);
   1.434 -
   1.435 -  case Op_Load2L:  return new (C, 3) Load2LNode(ctl, mem, adr, atyp);
   1.436 -
   1.437 -  case Op_Load4F:  return new (C, 3) Load4FNode(ctl, mem, adr, atyp);
   1.438 -  case Op_Load2F:  return new (C, 3) Load2FNode(ctl, mem, adr, atyp);
   1.439 -
   1.440 -  case Op_Load2D:  return new (C, 3) Load2DNode(ctl, mem, adr, atyp);
   1.441 +// Return initial Pack node. Additional operands added with add_opd() calls.
   1.442 +PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) {
   1.443 +  const TypeVect* vt = TypeVect::make(bt, vlen);
   1.444 +  switch (bt) {
   1.445 +  case T_BOOLEAN:
   1.446 +  case T_BYTE:
   1.447 +    return new (C, vlen+1) PackBNode(s, vt);
   1.448 +  case T_CHAR:
   1.449 +  case T_SHORT:
   1.450 +    return new (C, vlen+1) PackSNode(s, vt);
   1.451 +  case T_INT:
   1.452 +    return new (C, vlen+1) PackINode(s, vt);
   1.453 +  case T_LONG:
   1.454 +    return new (C, vlen+1) PackLNode(s, vt);
   1.455 +  case T_FLOAT:
   1.456 +    return new (C, vlen+1) PackFNode(s, vt);
   1.457 +  case T_DOUBLE:
   1.458 +    return new (C, vlen+1) PackDNode(s, vt);
   1.459    }
   1.460    ShouldNotReachHere();
   1.461    return NULL;
   1.462  }
   1.463  
   1.464 -// Return the vector version of a scalar store node.
   1.465 -VectorStoreNode* VectorStoreNode::make(Compile* C, int opc, Node* ctl, Node* mem,
   1.466 -                                       Node* adr, const TypePtr* atyp, Node* val,
   1.467 -                                       uint vlen) {
   1.468 -  int vopc = opcode(opc, vlen);
   1.469 +// Create a binary tree form for Packs. [lo, hi) (half-open) range
   1.470 +Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) {
   1.471 +  int ct = hi - lo;
   1.472 +  assert(is_power_of_2(ct), "power of 2");
   1.473 +  if (ct == 2) {
   1.474 +    PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type());
   1.475 +    pk->add_opd(1, in(lo+1));
   1.476 +    return pk;
   1.477  
   1.478 -  switch(vopc) {
   1.479 -  case Op_Store16B: return new (C, 4) Store16BNode(ctl, mem, adr, atyp, val);
   1.480 -  case Op_Store8B: return new (C, 4) Store8BNode(ctl, mem, adr, atyp, val);
   1.481 -  case Op_Store4B: return new (C, 4) Store4BNode(ctl, mem, adr, atyp, val);
   1.482 +  } else {
   1.483 +    int mid = lo + ct/2;
   1.484 +    Node* n1 = binaryTreePack(C, lo,  mid);
   1.485 +    Node* n2 = binaryTreePack(C, mid, hi );
   1.486  
   1.487 -  case Op_Store8C: return new (C, 4) Store8CNode(ctl, mem, adr, atyp, val);
   1.488 -  case Op_Store4C: return new (C, 4) Store4CNode(ctl, mem, adr, atyp, val);
   1.489 -  case Op_Store2C: return new (C, 4) Store2CNode(ctl, mem, adr, atyp, val);
   1.490 -
   1.491 -  case Op_Store4I: return new (C, 4) Store4INode(ctl, mem, adr, atyp, val);
   1.492 -  case Op_Store2I: return new (C, 4) Store2INode(ctl, mem, adr, atyp, val);
   1.493 -
   1.494 -  case Op_Store2L: return new (C, 4) Store2LNode(ctl, mem, adr, atyp, val);
   1.495 -
   1.496 -  case Op_Store4F: return new (C, 4) Store4FNode(ctl, mem, adr, atyp, val);
   1.497 -  case Op_Store2F: return new (C, 4) Store2FNode(ctl, mem, adr, atyp, val);
   1.498 -
   1.499 -  case Op_Store2D: return new (C, 4) Store2DNode(ctl, mem, adr, atyp, val);
   1.500 +    BasicType bt = vect_type()->element_basic_type();
   1.501 +    switch (bt) {
   1.502 +    case T_BOOLEAN:
   1.503 +    case T_BYTE:
   1.504 +      return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2));
   1.505 +    case T_CHAR:
   1.506 +    case T_SHORT:
   1.507 +      return new (C, 3) PackINode(n1, n2, TypeVect::make(T_INT, 2));
   1.508 +    case T_INT:
   1.509 +      return new (C, 3) PackLNode(n1, n2, TypeVect::make(T_LONG, 2));
   1.510 +    case T_LONG:
   1.511 +      return new (C, 3) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
   1.512 +    case T_FLOAT:
   1.513 +      return new (C, 3) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
   1.514 +    case T_DOUBLE:
   1.515 +      return new (C, 3) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
   1.516 +    }
   1.517 +    ShouldNotReachHere();
   1.518    }
   1.519 -  ShouldNotReachHere();
   1.520    return NULL;
   1.521  }
   1.522  
   1.523 +// Return the vector version of a scalar load node.
   1.524 +LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
   1.525 +                                     Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
   1.526 +  const TypeVect* vt = TypeVect::make(bt, vlen);
   1.527 +  return new (C, 3) LoadVectorNode(ctl, mem, adr, atyp, vt);
   1.528 +  return NULL;
   1.529 +}
   1.530 +
   1.531 +// Return the vector version of a scalar store node.
   1.532 +StoreVectorNode* StoreVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
   1.533 +                                       Node* adr, const TypePtr* atyp, Node* val,
   1.534 +                                       uint vlen) {
   1.535 +  return new (C, 4) StoreVectorNode(ctl, mem, adr, atyp, val);
   1.536 +}
   1.537 +
   1.538  // Extract a scalar element of vector.
   1.539 -Node* ExtractNode::make(Compile* C, Node* v, uint position, const Type* opd_t) {
   1.540 -  BasicType bt = opd_t->array_element_basic_type();
   1.541 -  assert(position < VectorNode::max_vlen(bt), "pos in range");
   1.542 +Node* ExtractNode::make(Compile* C, Node* v, uint position, BasicType bt) {
   1.543 +  assert((int)position < Matcher::max_vector_size(bt), "pos in range");
   1.544    ConINode* pos = ConINode::make(C, (int)position);
   1.545    switch (bt) {
   1.546    case T_BOOLEAN:
   1.547 +    return new (C, 3) ExtractUBNode(v, pos);
   1.548    case T_BYTE:
   1.549      return new (C, 3) ExtractBNode(v, pos);
   1.550    case T_CHAR:
   1.551 @@ -478,3 +307,4 @@
   1.552    ShouldNotReachHere();
   1.553    return NULL;
   1.554  }
   1.555 +

mercurial