1 /*
   2  * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #ifndef SHARE_VM_OPTO_VECTORNODE_HPP
  25 #define SHARE_VM_OPTO_VECTORNODE_HPP
  26 
  27 #include "opto/matcher.hpp"
  28 #include "opto/memnode.hpp"
  29 #include "opto/node.hpp"
  30 #include "opto/opcodes.hpp"
  31 #include "opto/callnode.hpp"
  32 #include "opto/subnode.hpp"
  33 
  34 //------------------------------VectorNode-------------------------------------
  35 // Vector Operation
  36 class VectorNode : public TypeNode {
  37  public:
  38 
  39   VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
  40     init_class_id(Class_Vector);
  41     init_req(1, n1);
  42   }
  43   VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
  44     init_class_id(Class_Vector);
  45     init_req(1, n1);
  46     init_req(2, n2);
  47   }
  48 
  49   VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) {
  50     init_class_id(Class_Vector);
  51     init_req(1, n1);
  52     init_req(2, n2);
  53     init_req(3, n3);
  54   }
  55 
  56   const TypeVect* vect_type() const { return type()->is_vect(); }
  57   uint length() const { return vect_type()->length(); } // Vector length
  58   uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
  59 
  60   virtual int Opcode() const;
  61 
  62   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
  63 
  64   static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
  65   static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt);
  66   static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
  67   static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
  68 
  69   static int  opcode(int opc, BasicType bt);
  70   static int replicate_opcode(BasicType bt);
  71   static bool implemented(int opc, uint vlen, BasicType bt);
  72   static bool is_shift(Node* n);
  73   static bool is_invariant_vector(Node* n);
  74   // [Start, end) half-open range defining which operands are vectors
  75   static void vector_operands(Node* n, uint* start, uint* end);
  76 };
  77 
  78 //===========================Vector=ALU=Operations=============================
  79 
  80 //------------------------------AddVBNode--------------------------------------
  81 // Vector add byte
  82 class AddVBNode : public VectorNode {
  83  public:
  84   AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  85   virtual int Opcode() const;
  86 };
  87 
  88 //------------------------------AddVSNode--------------------------------------
  89 // Vector add char/short
  90 class AddVSNode : public VectorNode {
  91  public:
  92   AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  93   virtual int Opcode() const;
  94 };
  95 
  96 //------------------------------AddVINode--------------------------------------
  97 // Vector add int
  98 class AddVINode : public VectorNode {
  99  public:
 100   AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 101   virtual int Opcode() const;
 102 };
 103 
 104 //------------------------------AddVLNode--------------------------------------
 105 // Vector add long
 106 class AddVLNode : public VectorNode {
 107 public:
 108   AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 109   virtual int Opcode() const;
 110 };
 111 
 112 //------------------------------AddVFNode--------------------------------------
 113 // Vector add float
 114 class AddVFNode : public VectorNode {
 115 public:
 116   AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 117   virtual int Opcode() const;
 118 };
 119 
 120 //------------------------------AddVDNode--------------------------------------
 121 // Vector add double
 122 class AddVDNode : public VectorNode {
 123 public:
 124   AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 125   virtual int Opcode() const;
 126 };
 127 
 128 //------------------------------ReductionNode------------------------------------
 129 // Perform reduction of a vector
 130 class ReductionNode : public Node {
 131  public:
 132   ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {}
 133 
 134   static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt);
 135   static int  opcode(int opc, BasicType bt);
 136   static bool implemented(int opc, uint vlen, BasicType bt);
 137   static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt);
 138 };
 139 
 140 //------------------------------AddReductionVINode--------------------------------------
 141 // Vector add byte, short and int as a reduction
 142 class AddReductionVINode : public ReductionNode {
 143 public:
 144   AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {
 145     if (in1->bottom_type()->basic_type() == T_INT) {
 146       assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT ||
 147              in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE ||
 148              in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "");
 149     }
 150   }
 151   virtual int Opcode() const;
 152   virtual const Type* bottom_type() const {
 153     if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT)
 154       return TypeInt::INT; 
 155     else if(in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE)
 156       return TypeInt::BYTE;
 157     else
 158       return TypeInt::SHORT;
 159   }
 160   virtual uint ideal_reg() const { return Op_RegI; }
 161 };
 162 
 163 //------------------------------AddReductionVLNode--------------------------------------
 164 // Vector add long as a reduction
 165 class AddReductionVLNode : public ReductionNode {
 166 public:
 167   AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 168   virtual int Opcode() const;
 169   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 170   virtual uint ideal_reg() const { return Op_RegL; }
 171 };
 172 
 173 //------------------------------AddReductionVFNode--------------------------------------
 174 // Vector add float as a reduction
 175 class AddReductionVFNode : public ReductionNode {
 176 public:
 177   AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 178   virtual int Opcode() const;
 179   virtual const Type* bottom_type() const { return Type::FLOAT; }
 180   virtual uint ideal_reg() const { return Op_RegF; }
 181 };
 182 
 183 //------------------------------AddReductionVDNode--------------------------------------
 184 // Vector add double as a reduction
 185 class AddReductionVDNode : public ReductionNode {
 186 public:
 187   AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 188   virtual int Opcode() const;
 189   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 190   virtual uint ideal_reg() const { return Op_RegD; }
 191 };
 192 
 193 //------------------------------SubVBNode--------------------------------------
 194 // Vector subtract byte
 195 class SubVBNode : public VectorNode {
 196  public:
 197   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 198   virtual int Opcode() const;
 199 };
 200 
 201 //------------------------------SubVSNode--------------------------------------
 202 // Vector subtract short
 203 class SubVSNode : public VectorNode {
 204  public:
 205   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 206   virtual int Opcode() const;
 207 };
 208 
 209 //------------------------------SubVINode--------------------------------------
 210 // Vector subtract int
 211 class SubVINode : public VectorNode {
 212  public:
 213   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 214   virtual int Opcode() const;
 215 };
 216 
 217 //------------------------------SubVLNode--------------------------------------
 218 // Vector subtract long
 219 class SubVLNode : public VectorNode {
 220  public:
 221   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 222   virtual int Opcode() const;
 223 };
 224 
 225 //------------------------------SubVFNode--------------------------------------
 226 // Vector subtract float
 227 class SubVFNode : public VectorNode {
 228  public:
 229   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 230   virtual int Opcode() const;
 231 };
 232 
 233 //------------------------------SubVDNode--------------------------------------
 234 // Vector subtract double
 235 class SubVDNode : public VectorNode {
 236  public:
 237   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 238   virtual int Opcode() const;
 239 };
 240 
 241 //------------------------------SubReductionVNode--------------------------------------
 242 // Vector and int, long as a reduction
 243 class SubReductionVNode : public ReductionNode {
 244 public:
 245   SubReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 
 246     assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 
 247     assert(in1->bottom_type()->basic_type() == T_INT ||
 248            in1->bottom_type()->basic_type() == T_LONG, "");
 249   }
 250   virtual int Opcode() const;
 251   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 252   virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 
 253                                               return TypeInt::INT; else return TypeLong::LONG; }
 254   virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; }
 255 };
 256 
 257 //------------------------------MulVBNode--------------------------------------
 258 // Vector multiply byte
 259 class MulVBNode : public VectorNode {
 260  public:
 261   MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 262   virtual int Opcode() const;
 263 };
 264 
 265 //------------------------------MulVSNode--------------------------------------
 266 // Vector multiply short
 267 class MulVSNode : public VectorNode {
 268  public:
 269   MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 270   virtual int Opcode() const;
 271 };
 272 
 273 //------------------------------MulVINode--------------------------------------
 274 // Vector multiply int
 275 class MulVINode : public VectorNode {
 276  public:
 277   MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 278   virtual int Opcode() const;
 279 };
 280 
 281 //------------------------------MulVLNode--------------------------------------
 282 // Vector multiply long
 283 class MulVLNode : public VectorNode {
 284 public:
 285   MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 286   virtual int Opcode() const;
 287 };
 288 
 289 //------------------------------MulVFNode--------------------------------------
 290 // Vector multiply float
 291 class MulVFNode : public VectorNode {
 292 public:
 293   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 294   virtual int Opcode() const;
 295 };
 296 
 297 //------------------------------MulVDNode--------------------------------------
 298 // Vector multiply double
 299 class MulVDNode : public VectorNode {
 300 public:
 301   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 302   virtual int Opcode() const;
 303 };
 304 
 305 //------------------------------FmaVDNode--------------------------------------
 306 // Vector multiply double
 307 class FmaVDNode : public VectorNode {
 308 public:
 309   FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 310   virtual int Opcode() const;
 311 };
 312 
 313 //------------------------------FmaVFNode--------------------------------------
 314 // Vector multiply float
 315 class FmaVFNode : public VectorNode {
 316 public:
 317   FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 318   virtual int Opcode() const;
 319 };
 320 
 321 //------------------------------CMoveVFNode--------------------------------------
 322 // Vector float conditional move
 323 class CMoveVFNode : public VectorNode {
 324 public:
 325   CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 326   virtual int Opcode() const;
 327 };
 328 
 329 //------------------------------CMoveVDNode--------------------------------------
 330 // Vector double conditional move
 331 class CMoveVDNode : public VectorNode {
 332 public:
 333   CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 334   virtual int Opcode() const;
 335 };
 336 
 337 //------------------------------MulReductionVINode--------------------------------------
 338 // Vector multiply int as a reduction
 339 class MulReductionVINode : public ReductionNode {
 340 public:
 341   MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 342   virtual int Opcode() const;
 343   virtual const Type* bottom_type() const { return TypeInt::INT; }
 344   virtual uint ideal_reg() const { return Op_RegI; }
 345 };
 346 
 347 //------------------------------MulReductionVLNode--------------------------------------
 348 // Vector multiply int as a reduction
 349 class MulReductionVLNode : public ReductionNode {
 350 public:
 351   MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 352   virtual int Opcode() const;
 353   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 354   virtual uint ideal_reg() const { return Op_RegI; }
 355 };
 356 
 357 //------------------------------MulReductionVFNode--------------------------------------
 358 // Vector multiply float as a reduction
 359 class MulReductionVFNode : public ReductionNode {
 360 public:
 361   MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 362   virtual int Opcode() const;
 363   virtual const Type* bottom_type() const { return Type::FLOAT; }
 364   virtual uint ideal_reg() const { return Op_RegF; }
 365 };
 366 
 367 //------------------------------MulReductionVDNode--------------------------------------
 368 // Vector multiply double as a reduction
 369 class MulReductionVDNode : public ReductionNode {
 370 public:
 371   MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 372   virtual int Opcode() const;
 373   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 374   virtual uint ideal_reg() const { return Op_RegD; }
 375 };
 376 
 377 //------------------------------DivVFNode--------------------------------------
 378 // Vector divide float
 379 class DivVFNode : public VectorNode {
 380  public:
 381   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 382   virtual int Opcode() const;
 383 };
 384 
 385 //------------------------------DivVDNode--------------------------------------
 386 // Vector Divide double
 387 class DivVDNode : public VectorNode {
 388  public:
 389   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 390   virtual int Opcode() const;
 391 };
 392 
 393 //------------------------------MinVNode--------------------------------------
 394 // Vector Min
 395 class MinVNode : public VectorNode {
 396 public:
 397   MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 398   virtual int Opcode() const;
 399 };
 400 
 401 //------------------------------MaxVNode--------------------------------------
 402 // Vector Max
 403 class MaxVNode : public VectorNode {
 404 public:
 405   MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 406   virtual int Opcode() const;
 407 };
 408 
 409 //------------------------------AbsVNode--------------------------------------
 410 // Vector Abs
 411 class AbsVNode : public VectorNode {
 412 public:
 413   AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 414   virtual int Opcode() const;
 415 };
 416 
 417 //------------------------------AbsVFNode--------------------------------------
 418 // Vector Abs float
 419 class AbsVFNode : public VectorNode {
 420  public:
 421   AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 422   virtual int Opcode() const;
 423 };
 424 
 425 //------------------------------AbsVDNode--------------------------------------
 426 // Vector Abs double
 427 class AbsVDNode : public VectorNode {
 428  public:
 429   AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 430   virtual int Opcode() const;
 431 };
 432 
 433 //------------------------------NegVINode--------------------------------------
 434 // Vector Neg int
 435 class NegVINode : public VectorNode {
 436 public:
 437   NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 438   virtual int Opcode() const;
 439 };
 440 
 441 //------------------------------NegVFNode--------------------------------------
 442 // Vector Neg float
 443 class NegVFNode : public VectorNode {
 444  public:
 445   NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 446   virtual int Opcode() const;
 447 };
 448 
 449 //------------------------------NegVDNode--------------------------------------
 450 // Vector Neg double
 451 class NegVDNode : public VectorNode {
 452  public:
 453   NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 454   virtual int Opcode() const;
 455 };
 456 
 457 //------------------------------PopCountVINode---------------------------------
 458 // Vector popcount integer bits
 459 class PopCountVINode : public VectorNode {
 460  public:
 461   PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 462   virtual int Opcode() const;
 463 };
 464 
 465 //------------------------------SqrtVFNode--------------------------------------
 466 // Vector Sqrt float
 467 class SqrtVFNode : public VectorNode {
 468  public:
 469   SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 470   virtual int Opcode() const;
 471 };
 472 
 473 //------------------------------SqrtVDNode--------------------------------------
 474 // Vector Sqrt double
 475 class SqrtVDNode : public VectorNode {
 476  public:
 477   SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 478   virtual int Opcode() const;
 479 };
 480 
 481 //------------------------------NotVNode--------------------------------------
 482 // Vector Not
 483 class NotVNode : public VectorNode {
 484 public:
 485   NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 486   virtual int Opcode() const;
 487 };
 488 
 489 //------------------------------LShiftVBNode-----------------------------------
 490 // Vector left shift bytes
 491 class LShiftVBNode : public VectorNode {
 492  public:
 493   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 494   virtual int Opcode() const;
 495 };
 496 
 497 //------------------------------LShiftVSNode-----------------------------------
 498 // Vector left shift shorts
 499 class LShiftVSNode : public VectorNode {
 500  public:
 501   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 502   virtual int Opcode() const;
 503 };
 504 
 505 //------------------------------LShiftVINode-----------------------------------
 506 // Vector left shift ints
 507 class LShiftVINode : public VectorNode {
 508  public:
 509   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 510   virtual int Opcode() const;
 511 };
 512 
 513 //------------------------------LShiftVLNode-----------------------------------
 514 // Vector left shift longs
 515 class LShiftVLNode : public VectorNode {
 516  public:
 517   LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 518   virtual int Opcode() const;
 519 };
 520 
 521 //------------------------------RShiftVBNode-----------------------------------
 522 // Vector right arithmetic (signed) shift bytes
 523 class RShiftVBNode : public VectorNode {
 524  public:
 525   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 526   virtual int Opcode() const;
 527 };
 528 
 529 //------------------------------RShiftVSNode-----------------------------------
 530 // Vector right arithmetic (signed) shift shorts
 531 class RShiftVSNode : public VectorNode {
 532  public:
 533   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 534   virtual int Opcode() const;
 535 };
 536 
 537 //------------------------------RShiftVINode-----------------------------------
 538 // Vector right arithmetic (signed) shift ints
 539 class RShiftVINode : public VectorNode {
 540  public:
 541   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 542   virtual int Opcode() const;
 543 };
 544 
 545 //------------------------------RShiftVLNode-----------------------------------
 546 // Vector right arithmetic (signed) shift longs
 547 class RShiftVLNode : public VectorNode {
 548  public:
 549   RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 550   virtual int Opcode() const;
 551 };
 552 
 553 //------------------------------URShiftVBNode----------------------------------
 554 // Vector right logical (unsigned) shift bytes
 555 class URShiftVBNode : public VectorNode {
 556  public:
 557   URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 558   virtual int Opcode() const;
 559 };
 560 
 561 //------------------------------URShiftVSNode----------------------------------
 562 // Vector right logical (unsigned) shift shorts
 563 class URShiftVSNode : public VectorNode {
 564  public:
 565   URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 566   virtual int Opcode() const;
 567 };
 568 
 569 //------------------------------URShiftVINode----------------------------------
 570 // Vector right logical (unsigned) shift ints
 571 class URShiftVINode : public VectorNode {
 572  public:
 573   URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 574   virtual int Opcode() const;
 575 };
 576 
 577 //------------------------------URShiftVLNode----------------------------------
 578 // Vector right logical (unsigned) shift longs
 579 class URShiftVLNode : public VectorNode {
 580  public:
 581   URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 582   virtual int Opcode() const;
 583 };
 584 
 585 //------------------------------LShiftCntVNode---------------------------------
 586 // Vector left shift count
 587 class LShiftCntVNode : public VectorNode {
 588  public:
 589   LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 590   virtual int Opcode() const;
 591   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 592 };
 593 
 594 //------------------------------RShiftCntVNode---------------------------------
 595 // Vector right shift count
 596 class RShiftCntVNode : public VectorNode {
 597  public:
 598   RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 599   virtual int Opcode() const;
 600   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 601 };
 602 
 603 
 604 //------------------------------AndVNode---------------------------------------
 605 // Vector and integer
 606 class AndVNode : public VectorNode {
 607  public:
 608   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 609   virtual int Opcode() const;
 610 };
 611 
 612 //------------------------------AndReductionVNode--------------------------------------
 613 // Vector and byte, short, int, long as a reduction
 614 class AndReductionVNode : public ReductionNode {
 615 public:
 616   AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {
 617     if (in1->bottom_type()->basic_type() == T_INT) {
 618       assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT ||
 619         in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE ||
 620         in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "");
 621     }
 622     else if (in1->bottom_type()->basic_type() == T_LONG) {
 623       assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, "");
 624     }
 625   }
 626   virtual int Opcode() const;
 627   virtual const Type* bottom_type() const {
 628     if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT)
 629       return TypeInt::INT;
 630     else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE)
 631       return TypeInt::BYTE;
 632     else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT)
 633       return TypeInt::SHORT;
 634     else
 635       return TypeLong::LONG;
 636   }
 637   virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; }
 638 };
 639 
 640 //------------------------------OrVNode---------------------------------------
 641 // Vector or integer
 642 class OrVNode : public VectorNode {
 643  public:
 644   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 645   virtual int Opcode() const;
 646 };
 647 
 648 //------------------------------OrReductionVNode--------------------------------------
 649 // Vector and int, long as a reduction
 650 class OrReductionVNode : public ReductionNode {
 651 public:
 652   OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 
 653     assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 
 654     assert(in1->bottom_type()->basic_type() == T_INT ||
 655            in1->bottom_type()->basic_type() == T_LONG, "");
 656   }
 657   virtual int Opcode() const;
 658   virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 
 659                                               return TypeInt::INT; else return TypeLong::LONG; }
 660   virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; }
 661 };
 662 
 663 //------------------------------XorReductionVNode--------------------------------------
 664 // Vector and int, long as a reduction
 665 class XorReductionVNode : public ReductionNode {
 666 public:
 667   XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 
 668     assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 
 669     assert(in1->bottom_type()->basic_type() == T_INT ||
 670            in1->bottom_type()->basic_type() == T_LONG, "");
 671   }
 672   virtual int Opcode() const;
 673   virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 
 674                                               return TypeInt::INT; else return TypeLong::LONG; }
 675   virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; }
 676 };
 677 
 678 //------------------------------XorVNode---------------------------------------
 679 // Vector xor integer
 680 class XorVNode : public VectorNode {
 681  public:
 682   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 683   virtual int Opcode() const;
 684 };
 685 
 686 //================================= M E M O R Y ===============================
 687 
 688 //------------------------------LoadVectorNode---------------------------------
 689 // Load Vector from memory
 690 class LoadVectorNode : public LoadNode {
 691  public:
 692   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
 693     : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
 694     init_class_id(Class_LoadVector);
 695   }
 696 
 697   const TypeVect* vect_type() const { return type()->is_vect(); }
 698   uint length() const { return vect_type()->length(); } // Vector length
 699 
 700   virtual int Opcode() const;
 701 
 702   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 703   virtual BasicType memory_type() const { return T_VOID; }
 704   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 705 
 706   virtual int store_Opcode() const { return Op_StoreVector; }
 707 
 708   static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
 709                               Node* adr, const TypePtr* atyp,
 710                               uint vlen, BasicType bt,
 711                               ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
 712   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
 713 };
 714 
 715 //------------------------------StoreVectorNode--------------------------------
 716 // Store Vector to memory
 717 class StoreVectorNode : public StoreNode {
 718  public:
 719   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
 720     : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
 721     init_class_id(Class_StoreVector);
 722   }
 723 
 724   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
 725   uint length() const { return vect_type()->length(); } // Vector length
 726 
 727   virtual int Opcode() const;
 728 
 729   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 730   virtual BasicType memory_type() const { return T_VOID; }
 731   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 732 
 733   static StoreVectorNode* make(int opc, Node* ctl, Node* mem,
 734                                Node* adr, const TypePtr* atyp, Node* val,
 735                                uint vlen);
 736 
 737   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
 738 };
 739 
 740 
 741 //=========================Promote_Scalar_to_Vector============================
 742 
 743 //------------------------------ReplicateBNode---------------------------------
 744 // Replicate byte scalar to be vector
 745 class ReplicateBNode : public VectorNode {
 746  public:
 747   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 748   virtual int Opcode() const;
 749 };
 750 
 751 //------------------------------ReplicateSNode---------------------------------
 752 // Replicate short scalar to be vector
 753 class ReplicateSNode : public VectorNode {
 754  public:
 755   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 756   virtual int Opcode() const;
 757 };
 758 
 759 //------------------------------ReplicateINode---------------------------------
 760 // Replicate int scalar to be vector
 761 class ReplicateINode : public VectorNode {
 762  public:
 763   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 764   virtual int Opcode() const;
 765 };
 766 
 767 //------------------------------ReplicateLNode---------------------------------
 768 // Replicate long scalar to be vector
 769 class ReplicateLNode : public VectorNode {
 770  public:
 771   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 772   virtual int Opcode() const;
 773 };
 774 
 775 //------------------------------ReplicateFNode---------------------------------
 776 // Replicate float scalar to be vector
 777 class ReplicateFNode : public VectorNode {
 778  public:
 779   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 780   virtual int Opcode() const;
 781 };
 782 
 783 //------------------------------ReplicateDNode---------------------------------
 784 // Replicate double scalar to be vector
 785 class ReplicateDNode : public VectorNode {
 786  public:
 787   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 788   virtual int Opcode() const;
 789 };
 790 
 791 //========================Pack_Scalars_into_a_Vector===========================
 792 
 793 //------------------------------PackNode---------------------------------------
 794 // Pack parent class (not for code generation).
 795 class PackNode : public VectorNode {
 796  public:
 797   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 798   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
 799   virtual int Opcode() const;
 800 
 801   void add_opd(Node* n) {
 802     add_req(n);
 803   }
 804 
 805   // Create a binary tree form for Packs. [lo, hi) (half-open) range
 806   PackNode* binary_tree_pack(int lo, int hi);
 807 
 808   static PackNode* make(Node* s, uint vlen, BasicType bt);
 809 };
 810 
 811 //------------------------------PackBNode--------------------------------------
 812 // Pack byte scalars into vector
 813 class PackBNode : public PackNode {
 814  public:
 815   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 816   virtual int Opcode() const;
 817 };
 818 
 819 //------------------------------PackSNode--------------------------------------
 820 // Pack short scalars into a vector
 821 class PackSNode : public PackNode {
 822  public:
 823   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 824   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 825   virtual int Opcode() const;
 826 };
 827 
 828 //------------------------------PackINode--------------------------------------
 829 // Pack integer scalars into a vector
 830 class PackINode : public PackNode {
 831  public:
 832   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 833   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 834   virtual int Opcode() const;
 835 };
 836 
 837 //------------------------------PackLNode--------------------------------------
 838 // Pack long scalars into a vector
 839 class PackLNode : public PackNode {
 840  public:
 841   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 842   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 843   virtual int Opcode() const;
 844 };
 845 
 846 //------------------------------Pack2LNode-------------------------------------
 847 // Pack 2 long scalars into a vector
 848 class Pack2LNode : public PackNode {
 849  public:
 850   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 851   virtual int Opcode() const;
 852 };
 853 
 854 //------------------------------PackFNode--------------------------------------
 855 // Pack float scalars into vector
 856 class PackFNode : public PackNode {
 857  public:
 858   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 859   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 860   virtual int Opcode() const;
 861 };
 862 
 863 //------------------------------PackDNode--------------------------------------
 864 // Pack double scalars into a vector
 865 class PackDNode : public PackNode {
 866  public:
 867   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
 868   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 869   virtual int Opcode() const;
 870 };
 871 
 872 //------------------------------Pack2DNode-------------------------------------
 873 // Pack 2 double scalars into a vector
 874 class Pack2DNode : public PackNode {
 875  public:
 876   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 877   virtual int Opcode() const;
 878 };
 879 
 880 
 881 //========================Extract_Scalar_from_Vector===========================
 882 
 883 //------------------------------ExtractNode------------------------------------
 884 // Extract a scalar from a vector at position "pos"
 885 class ExtractNode : public Node {
 886  public:
 887   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
 888     assert(in(2)->get_int() >= 0, "positive constants");
 889   }
 890   virtual int Opcode() const;
 891   uint  pos() const { return in(2)->get_int(); }
 892 
 893   static Node* make(Node* v, uint position, BasicType bt);
 894 };
 895 
 896 //------------------------------ExtractBNode-----------------------------------
 897 // Extract a byte from a vector at position "pos"
 898 class ExtractBNode : public ExtractNode {
 899  public:
 900   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 901   virtual int Opcode() const;
 902   virtual const Type *bottom_type() const { return TypeInt::INT; }
 903   virtual uint ideal_reg() const { return Op_RegI; }
 904 };
 905 
 906 //------------------------------ExtractUBNode----------------------------------
 907 // Extract a boolean from a vector at position "pos"
 908 class ExtractUBNode : public ExtractNode {
 909  public:
 910   ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 911   virtual int Opcode() const;
 912   virtual const Type *bottom_type() const { return TypeInt::INT; }
 913   virtual uint ideal_reg() const { return Op_RegI; }
 914 };
 915 
 916 //------------------------------ExtractCNode-----------------------------------
 917 // Extract a char from a vector at position "pos"
 918 class ExtractCNode : public ExtractNode {
 919  public:
 920   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 921   virtual int Opcode() const;
 922   virtual const Type *bottom_type() const { return TypeInt::INT; }
 923   virtual uint ideal_reg() const { return Op_RegI; }
 924 };
 925 
 926 //------------------------------ExtractSNode-----------------------------------
 927 // Extract a short from a vector at position "pos"
 928 class ExtractSNode : public ExtractNode {
 929  public:
 930   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 931   virtual int Opcode() const;
 932   virtual const Type *bottom_type() const { return TypeInt::INT; }
 933   virtual uint ideal_reg() const { return Op_RegI; }
 934 };
 935 
 936 //------------------------------ExtractINode-----------------------------------
 937 // Extract an int from a vector at position "pos"
 938 class ExtractINode : public ExtractNode {
 939  public:
 940   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 941   virtual int Opcode() const;
 942   virtual const Type *bottom_type() const { return TypeInt::INT; }
 943   virtual uint ideal_reg() const { return Op_RegI; }
 944 };
 945 
 946 //------------------------------ExtractLNode-----------------------------------
 947 // Extract a long from a vector at position "pos"
 948 class ExtractLNode : public ExtractNode {
 949  public:
 950   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 951   virtual int Opcode() const;
 952   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 953   virtual uint ideal_reg() const { return Op_RegL; }
 954 };
 955 
 956 //------------------------------ExtractFNode-----------------------------------
 957 // Extract a float from a vector at position "pos"
 958 class ExtractFNode : public ExtractNode {
 959  public:
 960   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 961   virtual int Opcode() const;
 962   virtual const Type *bottom_type() const { return Type::FLOAT; }
 963   virtual uint ideal_reg() const { return Op_RegF; }
 964 };
 965 
 966 //------------------------------ExtractDNode-----------------------------------
 967 // Extract a double from a vector at position "pos"
 968 class ExtractDNode : public ExtractNode {
 969  public:
 970   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 971   virtual int Opcode() const;
 972   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 973   virtual uint ideal_reg() const { return Op_RegD; }
 974 };
 975 
 976 //------------------------------SetVectMaskINode-------------------------------
 977 // Provide a mask for a vector predicate machine
 978 class SetVectMaskINode : public Node {
 979 public:
 980   SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {}
 981   virtual int Opcode() const;
 982   const Type *bottom_type() const { return TypeInt::INT; }
 983   virtual uint ideal_reg() const { return Op_RegI; }
 984   virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; }
 985 };
 986 
 987 // Type conversion nodes
 988 class ConvertVF2VDNode : public VectorNode {
 989  public:
 990   ConvertVF2VDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 991   virtual int Opcode() const;
 992 };
 993 
 994 class VectorBoxNode : public Node {
 995  private:
 996   const TypeInstPtr* const _box_type;
 997   const TypeVect*    const _vec_type;
 998  public:
 999   enum {
1000      Box   = 1,
1001      Value = 2
1002   };
1003   VectorBoxNode(Compile* C, Node* box, Node* val,
1004                 const TypeInstPtr* box_type, const TypeVect* vt)
1005     : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) {
1006     init_flags(Flag_is_macro);
1007     C->add_macro_node(this);
1008   }
1009 
1010   const  TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; };
1011   const  TypeVect*    vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; };
1012 
1013   virtual int Opcode() const;
1014   virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ }
1015   virtual       uint  ideal_reg() const { return box_type()->ideal_reg(); }
1016   virtual       uint  size_of() const { return sizeof(*this); }
1017 
1018   static const TypeFunc* vec_box_type(const TypeInstPtr* box_type);
1019 };
1020 
1021 class VectorBoxAllocateNode : public CallStaticJavaNode {
1022  public:
1023   VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type)
1024     : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) {
1025     init_flags(Flag_is_macro);
1026     C->add_macro_node(this);
1027   }
1028 
1029   virtual int Opcode() const;
1030 #ifndef PRODUCT
1031   virtual void dump_spec(outputStream *st) const;
1032 #endif // PRODUCT
1033 };
1034 
1035 class VectorUnboxNode : public VectorNode {
1036  public:
1037   VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem)
1038     : VectorNode(mem, obj, vec_type) {
1039     init_flags(Flag_is_macro);
1040     C->add_macro_node(this);
1041   }
1042 
1043   virtual int Opcode() const;
1044   Node* obj() const { return in(2); }
1045   Node* mem() const { return in(1); }
1046   virtual Node *Identity(PhaseGVN *phase);
1047 };
1048 
1049 class VectorMaskCmpNode : public VectorNode {
1050  private:
1051   BoolTest::mask _predicate;
1052 
1053  protected:
1054   uint size_of() const { return sizeof(*this); }
1055 
1056  public:
1057   VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, const TypeVect* vt) :
1058       VectorNode(in1, in2, vt), _predicate(predicate) {
1059     assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1060            "VectorMaskCmp inputs must have same type for elements");
1061     assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1062            "VectorMaskCmp inputs must have same number of elements");
1063     init_class_id(Class_VectorMaskCmp);
1064   }
1065 
1066   virtual int Opcode() const;
1067   virtual uint hash() const { return VectorNode::hash() + _predicate; }
1068   virtual uint cmp( const Node &n ) const {
1069     return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate;
1070   }
1071   BoolTest::mask get_predicate() { return _predicate; }
1072 #ifndef PRODUCT
1073   virtual void dump_spec(outputStream *st) const;
1074 #endif // PRODUCT
1075 };
1076 
1077 // Used to wrap other vector nodes in order to add masking functionality.
1078 class VectorMaskWrapperNode : public VectorNode {
1079 public:
1080   VectorMaskWrapperNode(Node* vector, Node* mask)
1081     : VectorNode(vector, mask, vector->bottom_type()->is_vect()) {
1082     assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask");
1083   }
1084 
1085   virtual int Opcode() const;
1086   Node* vector_val() const { return in(1); }
1087   Node* vector_mask() const { return in(2); }
1088 };
1089 
1090 class VectorTestNode : public Node {
1091  private:
1092   Assembler::Condition _predicate;
1093 
1094  protected:
1095   uint size_of() const { return sizeof(*this); }
1096 
1097  public:
1098   VectorTestNode( Node *in1, Node *in2, Assembler::Condition predicate) : Node(NULL, in1, in2), _predicate(predicate) {
1099     assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector");
1100     assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector");
1101     assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1102            "same type elements are needed");
1103     assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1104            "same number of elements is needed");
1105   }
1106   virtual int Opcode() const;
1107   virtual uint hash() const { return Node::hash() + _predicate; }
1108   virtual uint cmp( const Node &n ) const {
1109     return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate;
1110   }
1111   virtual const Type *bottom_type() const { return TypeInt::BOOL; }
1112   virtual uint ideal_reg() const { return Op_RegI; }  // TODO Should be RegFlags but due to missing comparison flags for BoolTest
1113                                                       // in middle-end, we make it boolean result directly.
1114   Assembler::Condition get_predicate() const { return _predicate; }
1115 };
1116 
1117 class VectorBlendNode : public VectorNode {
1118 public:
1119   VectorBlendNode(Node* vec1, Node* vec2, Node* mask)
1120     : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) {
1121     // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1122   }
1123 
1124   virtual int Opcode() const;
1125   Node* vec1() const { return in(1); }
1126   Node* vec2() const { return in(2); }
1127   Node* vec_mask() const { return in(3); }
1128 };
1129 
1130 class VectorLoadMaskNode : public VectorNode {
1131  public:
1132   VectorLoadMaskNode(Node* in, const TypeVect* vt)
1133     : VectorNode(in, vt) {
1134     assert(in->is_LoadVector(), "expected load vector");
1135     assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean");
1136   }
1137 
1138   int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); }
1139   virtual int Opcode() const;
1140 };
1141 
1142 class VectorStoreMaskNode : public VectorNode {
1143  private:
1144   int _mask_size;
1145  protected:
1146   uint size_of() const { return sizeof(*this); }
1147 
1148  public:
1149   VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem)
1150     : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) {
1151     _mask_size = type2aelembytes(in_type);
1152   }
1153 
1154   virtual uint hash() const { return VectorNode::hash() + _mask_size; }
1155   virtual uint cmp( const Node &n ) const {
1156     return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size;
1157   }
1158   int GetInputMaskSize() const { return _mask_size; }
1159   virtual int Opcode() const;
1160 };
1161 
1162 // This is intended for use as a simple reinterpret node that has no cast.
1163 class VectorReinterpretNode : public VectorNode {
1164  private:
1165   const TypeVect* _src_vt;
1166  protected:
1167   uint size_of() const { return sizeof(*this); }
1168  public:
1169   VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt)
1170       : VectorNode(in, dst_vt), _src_vt(src_vt) { }
1171 
1172   virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); }
1173   virtual uint cmp( const Node &n ) const {
1174     return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt);
1175   }
1176 
1177   virtual int Opcode() const;
1178 };
1179 
1180 #endif // SHARE_VM_OPTO_VECTORNODE_HPP