1 /*
   2  * Copyright (c) 2007, 2015, 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 
  32 //------------------------------VectorNode-------------------------------------
  33 // Vector Operation
  34 class VectorNode : public TypeNode {
  35  public:
  36 
  37   VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
  38     init_class_id(Class_Vector);
  39     init_req(1, n1);
  40   }
  41   VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
  42     init_class_id(Class_Vector);
  43     init_req(1, n1);
  44     init_req(2, n2);
  45   }
  46 
  47   const TypeVect* vect_type() const { return type()->is_vect(); }
  48   uint length() const { return vect_type()->length(); } // Vector length
  49   uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
  50 
  51   virtual int Opcode() const;
  52 
  53   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
  54 
  55   static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
  56   static VectorNode* shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt);
  57   static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
  58 
  59   static int  opcode(int opc, BasicType bt);
  60   static bool implemented(int opc, uint vlen, BasicType bt);
  61   static bool is_shift(Node* n);
  62   static bool is_invariant_vector(Node* n);
  63   // [Start, end) half-open range defining which operands are vectors
  64   static void vector_operands(Node* n, uint* start, uint* end);
  65 };
  66 
  67 //===========================Vector=ALU=Operations=============================
  68 
  69 //------------------------------AddVBNode--------------------------------------
  70 // Vector add byte
  71 class AddVBNode : public VectorNode {
  72  public:
  73   AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  74   virtual int Opcode() const;
  75 
  76 #ifndef PRODUCT
  77   REL_IN_DATA_OUT_1;
  78 #endif
  79 };
  80 
  81 //------------------------------AddVSNode--------------------------------------
  82 // Vector add char/short
  83 class AddVSNode : public VectorNode {
  84  public:
  85   AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  86   virtual int Opcode() const;
  87 
  88 #ifndef PRODUCT
  89   REL_IN_DATA_OUT_1;
  90 #endif
  91 };
  92 
  93 //------------------------------AddVINode--------------------------------------
  94 // Vector add int
  95 class AddVINode : public VectorNode {
  96  public:
  97   AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  98   virtual int Opcode() const;
  99 
 100 #ifndef PRODUCT
 101   REL_IN_DATA_OUT_1;
 102 #endif
 103 };
 104 
 105 //------------------------------AddVLNode--------------------------------------
 106 // Vector add long
 107 class AddVLNode : public VectorNode {
 108 public:
 109   AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 110   virtual int Opcode() const;
 111 
 112 #ifndef PRODUCT
 113   REL_IN_DATA_OUT_1;
 114 #endif
 115 };
 116 
 117 //------------------------------AddVFNode--------------------------------------
 118 // Vector add float
 119 class AddVFNode : public VectorNode {
 120 public:
 121   AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 122   virtual int Opcode() const;
 123 
 124 #ifndef PRODUCT
 125   REL_IN_DATA_OUT_1;
 126 #endif
 127 };
 128 
 129 //------------------------------AddVDNode--------------------------------------
 130 // Vector add double
 131 class AddVDNode : public VectorNode {
 132 public:
 133   AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 134   virtual int Opcode() const;
 135 
 136 #ifndef PRODUCT
 137   REL_IN_DATA_OUT_1;
 138 #endif
 139 };
 140 
 141 //------------------------------ReductionNode------------------------------------
 142 // Perform reduction of a vector
 143 class ReductionNode : public Node {
 144  public:
 145   ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {}
 146 
 147   static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt);
 148   static int  opcode(int opc, BasicType bt);
 149   static bool implemented(int opc, uint vlen, BasicType bt);
 150 
 151 #ifndef PRODUCT
 152   REL_IN_DATA_OUT_1;
 153 #endif
 154 };
 155 
 156 //------------------------------AddReductionVINode--------------------------------------
 157 // Vector add int as a reduction
 158 class AddReductionVINode : public ReductionNode {
 159 public:
 160   AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 161   virtual int Opcode() const;
 162   virtual const Type* bottom_type() const { return TypeInt::INT; }
 163   virtual uint ideal_reg() const { return Op_RegI; }
 164 };
 165 
 166 //------------------------------AddReductionVLNode--------------------------------------
 167 // Vector add long as a reduction
 168 class AddReductionVLNode : public ReductionNode {
 169 public:
 170   AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 171   virtual int Opcode() const;
 172   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 173   virtual uint ideal_reg() const { return Op_RegL; }
 174 };
 175 
 176 //------------------------------AddReductionVFNode--------------------------------------
 177 // Vector add float as a reduction
 178 class AddReductionVFNode : public ReductionNode {
 179 public:
 180   AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 181   virtual int Opcode() const;
 182   virtual const Type* bottom_type() const { return Type::FLOAT; }
 183   virtual uint ideal_reg() const { return Op_RegF; }
 184 };
 185 
 186 //------------------------------AddReductionVDNode--------------------------------------
 187 // Vector add double as a reduction
 188 class AddReductionVDNode : public ReductionNode {
 189 public:
 190   AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 191   virtual int Opcode() const;
 192   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 193   virtual uint ideal_reg() const { return Op_RegD; }
 194 };
 195 
 196 //------------------------------SubVBNode--------------------------------------
 197 // Vector subtract byte
 198 class SubVBNode : public VectorNode {
 199  public:
 200   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 201   virtual int Opcode() const;
 202 
 203 #ifndef PRODUCT
 204   REL_IN_DATA_OUT_1;
 205 #endif
 206 };
 207 
 208 //------------------------------SubVSNode--------------------------------------
 209 // Vector subtract short
 210 class SubVSNode : public VectorNode {
 211  public:
 212   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 213   virtual int Opcode() const;
 214 
 215 #ifndef PRODUCT
 216   REL_IN_DATA_OUT_1;
 217 #endif
 218 };
 219 
 220 //------------------------------SubVINode--------------------------------------
 221 // Vector subtract int
 222 class SubVINode : public VectorNode {
 223  public:
 224   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 225   virtual int Opcode() const;
 226 
 227 #ifndef PRODUCT
 228   REL_IN_DATA_OUT_1;
 229 #endif
 230 };
 231 
 232 //------------------------------SubVLNode--------------------------------------
 233 // Vector subtract long
 234 class SubVLNode : public VectorNode {
 235  public:
 236   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 237   virtual int Opcode() const;
 238 
 239 #ifndef PRODUCT
 240   REL_IN_DATA_OUT_1;
 241 #endif
 242 };
 243 
 244 //------------------------------SubVFNode--------------------------------------
 245 // Vector subtract float
 246 class SubVFNode : public VectorNode {
 247  public:
 248   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 249   virtual int Opcode() const;
 250 
 251 #ifndef PRODUCT
 252   REL_IN_DATA_OUT_1;
 253 #endif
 254 };
 255 
 256 //------------------------------SubVDNode--------------------------------------
 257 // Vector subtract double
 258 class SubVDNode : public VectorNode {
 259  public:
 260   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 261   virtual int Opcode() const;
 262 
 263 #ifndef PRODUCT
 264   REL_IN_DATA_OUT_1;
 265 #endif
 266 };
 267 
 268 //------------------------------MulVSNode--------------------------------------
 269 // Vector multiply short
 270 class MulVSNode : public VectorNode {
 271  public:
 272   MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 273   virtual int Opcode() const;
 274 
 275 #ifndef PRODUCT
 276   REL_IN_DATA_OUT_1;
 277 #endif
 278 };
 279 
 280 //------------------------------MulVINode--------------------------------------
 281 // Vector multiply int
 282 class MulVINode : public VectorNode {
 283  public:
 284   MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 285   virtual int Opcode() const;
 286 
 287 #ifndef PRODUCT
 288   REL_IN_DATA_OUT_1;
 289 #endif
 290 };
 291 
 292 //------------------------------MulVLNode--------------------------------------
 293 // Vector multiply long
 294 class MulVLNode : public VectorNode {
 295 public:
 296   MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 297   virtual int Opcode() const;
 298 };
 299 
 300 //------------------------------MulVFNode--------------------------------------
 301 // Vector multiply float
 302 class MulVFNode : public VectorNode {
 303 public:
 304   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 305   virtual int Opcode() const;
 306 
 307 #ifndef PRODUCT
 308   REL_IN_DATA_OUT_1;
 309 #endif
 310 };
 311 
 312 //------------------------------MulVDNode--------------------------------------
 313 // Vector multiply double
 314 class MulVDNode : public VectorNode {
 315 public:
 316   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 317   virtual int Opcode() const;
 318 
 319 #ifndef PRODUCT
 320   REL_IN_DATA_OUT_1;
 321 #endif
 322 };
 323 
 324 //------------------------------MulReductionVINode--------------------------------------
 325 // Vector multiply int as a reduction
 326 class MulReductionVINode : public ReductionNode {
 327 public:
 328   MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 329   virtual int Opcode() const;
 330   virtual const Type* bottom_type() const { return TypeInt::INT; }
 331   virtual uint ideal_reg() const { return Op_RegI; }
 332 };
 333 
 334 //------------------------------MulReductionVLNode--------------------------------------
 335 // Vector multiply int as a reduction
 336 class MulReductionVLNode : public ReductionNode {
 337 public:
 338   MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 339   virtual int Opcode() const;
 340   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 341   virtual uint ideal_reg() const { return Op_RegI; }
 342 };
 343 
 344 //------------------------------MulReductionVFNode--------------------------------------
 345 // Vector multiply float as a reduction
 346 class MulReductionVFNode : public ReductionNode {
 347 public:
 348   MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 349   virtual int Opcode() const;
 350   virtual const Type* bottom_type() const { return Type::FLOAT; }
 351   virtual uint ideal_reg() const { return Op_RegF; }
 352 };
 353 
 354 //------------------------------MulReductionVDNode--------------------------------------
 355 // Vector multiply double as a reduction
 356 class MulReductionVDNode : public ReductionNode {
 357 public:
 358   MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 359   virtual int Opcode() const;
 360   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 361   virtual uint ideal_reg() const { return Op_RegD; }
 362 };
 363 
 364 //------------------------------DivVFNode--------------------------------------
 365 // Vector divide float
 366 class DivVFNode : public VectorNode {
 367  public:
 368   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 369   virtual int Opcode() const;
 370 
 371 #ifndef PRODUCT
 372   REL_IN_DATA_OUT_1;
 373 #endif
 374 };
 375 
 376 //------------------------------DivVDNode--------------------------------------
 377 // Vector Divide double
 378 class DivVDNode : public VectorNode {
 379  public:
 380   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 381   virtual int Opcode() const;
 382 
 383 #ifndef PRODUCT
 384   REL_IN_DATA_OUT_1;
 385 #endif
 386 };
 387 
 388 //------------------------------LShiftVBNode-----------------------------------
 389 // Vector left shift bytes
 390 class LShiftVBNode : public VectorNode {
 391  public:
 392   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 393   virtual int Opcode() const;
 394 
 395 #ifndef PRODUCT
 396   REL_IN_DATA_OUT_1;
 397 #endif
 398 };
 399 
 400 //------------------------------LShiftVSNode-----------------------------------
 401 // Vector left shift shorts
 402 class LShiftVSNode : public VectorNode {
 403  public:
 404   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 405   virtual int Opcode() const;
 406 
 407 #ifndef PRODUCT
 408   REL_IN_DATA_OUT_1;
 409 #endif
 410 };
 411 
 412 //------------------------------LShiftVINode-----------------------------------
 413 // Vector left shift ints
 414 class LShiftVINode : public VectorNode {
 415  public:
 416   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 417   virtual int Opcode() const;
 418 
 419 #ifndef PRODUCT
 420   REL_IN_DATA_OUT_1;
 421 #endif
 422 };
 423 
 424 //------------------------------LShiftVLNode-----------------------------------
 425 // Vector left shift longs
 426 class LShiftVLNode : public VectorNode {
 427  public:
 428   LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 429   virtual int Opcode() const;
 430 
 431 #ifndef PRODUCT
 432   REL_IN_DATA_OUT_1;
 433 #endif
 434 };
 435 
 436 //------------------------------RShiftVBNode-----------------------------------
 437 // Vector right arithmetic (signed) shift bytes
 438 class RShiftVBNode : public VectorNode {
 439  public:
 440   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 441   virtual int Opcode() const;
 442 
 443 #ifndef PRODUCT
 444   REL_IN_DATA_OUT_1;
 445 #endif
 446 };
 447 
 448 //------------------------------RShiftVSNode-----------------------------------
 449 // Vector right arithmetic (signed) shift shorts
 450 class RShiftVSNode : public VectorNode {
 451  public:
 452   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 453   virtual int Opcode() const;
 454 
 455 #ifndef PRODUCT
 456   REL_IN_DATA_OUT_1;
 457 #endif
 458 };
 459 
 460 //------------------------------RShiftVINode-----------------------------------
 461 // Vector right arithmetic (signed) shift ints
 462 class RShiftVINode : public VectorNode {
 463  public:
 464   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 465   virtual int Opcode() const;
 466 
 467 #ifndef PRODUCT
 468   REL_IN_DATA_OUT_1;
 469 #endif
 470 };
 471 
 472 //------------------------------RShiftVLNode-----------------------------------
 473 // Vector right arithmetic (signed) shift longs
 474 class RShiftVLNode : public VectorNode {
 475  public:
 476   RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 477   virtual int Opcode() const;
 478 
 479 #ifndef PRODUCT
 480   REL_IN_DATA_OUT_1;
 481 #endif
 482 };
 483 
 484 //------------------------------URShiftVBNode----------------------------------
 485 // Vector right logical (unsigned) shift bytes
 486 class URShiftVBNode : public VectorNode {
 487  public:
 488   URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 489   virtual int Opcode() const;
 490 
 491 #ifndef PRODUCT
 492   REL_IN_DATA_OUT_1;
 493 #endif
 494 };
 495 
 496 //------------------------------URShiftVSNode----------------------------------
 497 // Vector right logical (unsigned) shift shorts
 498 class URShiftVSNode : public VectorNode {
 499  public:
 500   URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 501   virtual int Opcode() const;
 502 
 503 #ifndef PRODUCT
 504   REL_IN_DATA_OUT_1;
 505 #endif
 506 };
 507 
 508 //------------------------------URShiftVINode----------------------------------
 509 // Vector right logical (unsigned) shift ints
 510 class URShiftVINode : public VectorNode {
 511  public:
 512   URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 513   virtual int Opcode() const;
 514 
 515 #ifndef PRODUCT
 516   REL_IN_DATA_OUT_1;
 517 #endif
 518 };
 519 
 520 //------------------------------URShiftVLNode----------------------------------
 521 // Vector right logical (unsigned) shift longs
 522 class URShiftVLNode : public VectorNode {
 523  public:
 524   URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 525   virtual int Opcode() const;
 526 
 527 #ifndef PRODUCT
 528   REL_IN_DATA_OUT_1;
 529 #endif
 530 };
 531 
 532 //------------------------------LShiftCntVNode---------------------------------
 533 // Vector left shift count
 534 class LShiftCntVNode : public VectorNode {
 535  public:
 536   LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 537   virtual int Opcode() const;
 538   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 539 };
 540 
 541 //------------------------------RShiftCntVNode---------------------------------
 542 // Vector right shift count
 543 class RShiftCntVNode : public VectorNode {
 544  public:
 545   RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 546   virtual int Opcode() const;
 547   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 548 };
 549 
 550 
 551 //------------------------------AndVNode---------------------------------------
 552 // Vector and integer
 553 class AndVNode : public VectorNode {
 554  public:
 555   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 556   virtual int Opcode() const;
 557 
 558 #ifndef PRODUCT
 559   REL_IN_DATA_OUT_1;
 560 #endif
 561 };
 562 
 563 //------------------------------OrVNode---------------------------------------
 564 // Vector or integer
 565 class OrVNode : public VectorNode {
 566  public:
 567   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 568   virtual int Opcode() const;
 569 
 570 #ifndef PRODUCT
 571   REL_IN_DATA_OUT_1;
 572 #endif
 573 };
 574 
 575 //------------------------------XorVNode---------------------------------------
 576 // Vector xor integer
 577 class XorVNode : public VectorNode {
 578  public:
 579   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 580   virtual int Opcode() const;
 581 
 582 #ifndef PRODUCT
 583   REL_IN_DATA_OUT_1;
 584 #endif
 585 };
 586 
 587 //================================= M E M O R Y ===============================
 588 
 589 //------------------------------LoadVectorNode---------------------------------
 590 // Load Vector from memory
 591 class LoadVectorNode : public LoadNode {
 592  public:
 593   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
 594     : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
 595     init_class_id(Class_LoadVector);
 596   }
 597 
 598   const TypeVect* vect_type() const { return type()->is_vect(); }
 599   uint length() const { return vect_type()->length(); } // Vector length
 600 
 601   virtual int Opcode() const;
 602 
 603   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 604   virtual BasicType memory_type() const { return T_VOID; }
 605   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 606 
 607   virtual int store_Opcode() const { return Op_StoreVector; }
 608 
 609   static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
 610                               Node* adr, const TypePtr* atyp,
 611                               uint vlen, BasicType bt,
 612                               ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
 613 };
 614 
 615 //------------------------------StoreVectorNode--------------------------------
 616 // Store Vector to memory
 617 class StoreVectorNode : public StoreNode {
 618  public:
 619   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
 620     : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
 621     assert(val->is_Vector() || val->is_LoadVector(), "sanity");
 622     init_class_id(Class_StoreVector);
 623   }
 624 
 625   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
 626   uint length() const { return vect_type()->length(); } // Vector length
 627 
 628   virtual int Opcode() const;
 629 
 630   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 631   virtual BasicType memory_type() const { return T_VOID; }
 632   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 633 
 634   static StoreVectorNode* make(int opc, Node* ctl, Node* mem,
 635                                Node* adr, const TypePtr* atyp, Node* val,
 636                                uint vlen);
 637 };
 638 
 639 
 640 //=========================Promote_Scalar_to_Vector============================
 641 
 642 //------------------------------ReplicateBNode---------------------------------
 643 // Replicate byte scalar to be vector
 644 class ReplicateBNode : public VectorNode {
 645  public:
 646   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 647   virtual int Opcode() const;
 648 };
 649 
 650 //------------------------------ReplicateSNode---------------------------------
 651 // Replicate short scalar to be vector
 652 class ReplicateSNode : public VectorNode {
 653  public:
 654   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 655   virtual int Opcode() const;
 656 };
 657 
 658 //------------------------------ReplicateINode---------------------------------
 659 // Replicate int scalar to be vector
 660 class ReplicateINode : public VectorNode {
 661  public:
 662   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 663   virtual int Opcode() const;
 664 };
 665 
 666 //------------------------------ReplicateLNode---------------------------------
 667 // Replicate long scalar to be vector
 668 class ReplicateLNode : public VectorNode {
 669  public:
 670   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 671   virtual int Opcode() const;
 672 };
 673 
 674 //------------------------------ReplicateFNode---------------------------------
 675 // Replicate float scalar to be vector
 676 class ReplicateFNode : public VectorNode {
 677  public:
 678   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 679   virtual int Opcode() const;
 680 };
 681 
 682 //------------------------------ReplicateDNode---------------------------------
 683 // Replicate double scalar to be vector
 684 class ReplicateDNode : public VectorNode {
 685  public:
 686   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 687   virtual int Opcode() const;
 688 };
 689 
 690 //========================Pack_Scalars_into_a_Vector===========================
 691 
 692 //------------------------------PackNode---------------------------------------
 693 // Pack parent class (not for code generation).
 694 class PackNode : public VectorNode {
 695  public:
 696   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 697   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
 698   virtual int Opcode() const;
 699 
 700   void add_opd(Node* n) {
 701     add_req(n);
 702   }
 703 
 704   // Create a binary tree form for Packs. [lo, hi) (half-open) range
 705   PackNode* binary_tree_pack(int lo, int hi);
 706 
 707   static PackNode* make(Node* s, uint vlen, BasicType bt);
 708 };
 709 
 710 //------------------------------PackBNode--------------------------------------
 711 // Pack byte scalars into vector
 712 class PackBNode : public PackNode {
 713  public:
 714   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 715   virtual int Opcode() const;
 716 };
 717 
 718 //------------------------------PackSNode--------------------------------------
 719 // Pack short scalars into a vector
 720 class PackSNode : public PackNode {
 721  public:
 722   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 723   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 724   virtual int Opcode() const;
 725 };
 726 
 727 //------------------------------PackINode--------------------------------------
 728 // Pack integer scalars into a vector
 729 class PackINode : public PackNode {
 730  public:
 731   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 732   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 733   virtual int Opcode() const;
 734 };
 735 
 736 //------------------------------PackLNode--------------------------------------
 737 // Pack long scalars into a vector
 738 class PackLNode : public PackNode {
 739  public:
 740   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 741   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 742   virtual int Opcode() const;
 743 };
 744 
 745 //------------------------------Pack2LNode-------------------------------------
 746 // Pack 2 long scalars into a vector
 747 class Pack2LNode : public PackNode {
 748  public:
 749   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 750   virtual int Opcode() const;
 751 };
 752 
 753 //------------------------------PackFNode--------------------------------------
 754 // Pack float scalars into vector
 755 class PackFNode : public PackNode {
 756  public:
 757   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 758   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 759   virtual int Opcode() const;
 760 };
 761 
 762 //------------------------------PackDNode--------------------------------------
 763 // Pack double scalars into a vector
 764 class PackDNode : public PackNode {
 765  public:
 766   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
 767   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 768   virtual int Opcode() const;
 769 };
 770 
 771 //------------------------------Pack2DNode-------------------------------------
 772 // Pack 2 double scalars into a vector
 773 class Pack2DNode : public PackNode {
 774  public:
 775   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 776   virtual int Opcode() const;
 777 };
 778 
 779 
 780 //========================Extract_Scalar_from_Vector===========================
 781 
 782 //------------------------------ExtractNode------------------------------------
 783 // Extract a scalar from a vector at position "pos"
 784 class ExtractNode : public Node {
 785  public:
 786   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
 787     assert(in(2)->get_int() >= 0, "positive constants");
 788   }
 789   virtual int Opcode() const;
 790   uint  pos() const { return in(2)->get_int(); }
 791 
 792   static Node* make(Node* v, uint position, BasicType bt);
 793 };
 794 
 795 //------------------------------ExtractBNode-----------------------------------
 796 // Extract a byte from a vector at position "pos"
 797 class ExtractBNode : public ExtractNode {
 798  public:
 799   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 800   virtual int Opcode() const;
 801   virtual const Type *bottom_type() const { return TypeInt::INT; }
 802   virtual uint ideal_reg() const { return Op_RegI; }
 803 };
 804 
 805 //------------------------------ExtractUBNode----------------------------------
 806 // Extract a boolean from a vector at position "pos"
 807 class ExtractUBNode : public ExtractNode {
 808  public:
 809   ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 810   virtual int Opcode() const;
 811   virtual const Type *bottom_type() const { return TypeInt::INT; }
 812   virtual uint ideal_reg() const { return Op_RegI; }
 813 };
 814 
 815 //------------------------------ExtractCNode-----------------------------------
 816 // Extract a char from a vector at position "pos"
 817 class ExtractCNode : public ExtractNode {
 818  public:
 819   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 820   virtual int Opcode() const;
 821   virtual const Type *bottom_type() const { return TypeInt::INT; }
 822   virtual uint ideal_reg() const { return Op_RegI; }
 823 };
 824 
 825 //------------------------------ExtractSNode-----------------------------------
 826 // Extract a short from a vector at position "pos"
 827 class ExtractSNode : public ExtractNode {
 828  public:
 829   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 830   virtual int Opcode() const;
 831   virtual const Type *bottom_type() const { return TypeInt::INT; }
 832   virtual uint ideal_reg() const { return Op_RegI; }
 833 };
 834 
 835 //------------------------------ExtractINode-----------------------------------
 836 // Extract an int from a vector at position "pos"
 837 class ExtractINode : public ExtractNode {
 838  public:
 839   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 840   virtual int Opcode() const;
 841   virtual const Type *bottom_type() const { return TypeInt::INT; }
 842   virtual uint ideal_reg() const { return Op_RegI; }
 843 };
 844 
 845 //------------------------------ExtractLNode-----------------------------------
 846 // Extract a long from a vector at position "pos"
 847 class ExtractLNode : public ExtractNode {
 848  public:
 849   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 850   virtual int Opcode() const;
 851   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 852   virtual uint ideal_reg() const { return Op_RegL; }
 853 };
 854 
 855 //------------------------------ExtractFNode-----------------------------------
 856 // Extract a float from a vector at position "pos"
 857 class ExtractFNode : public ExtractNode {
 858  public:
 859   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 860   virtual int Opcode() const;
 861   virtual const Type *bottom_type() const { return Type::FLOAT; }
 862   virtual uint ideal_reg() const { return Op_RegF; }
 863 };
 864 
 865 //------------------------------ExtractDNode-----------------------------------
 866 // Extract a double from a vector at position "pos"
 867 class ExtractDNode : public ExtractNode {
 868  public:
 869   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 870   virtual int Opcode() const;
 871   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 872   virtual uint ideal_reg() const { return Op_RegD; }
 873 };
 874 
 875 #endif // SHARE_VM_OPTO_VECTORNODE_HPP