1 /*
   2  * Copyright (c) 2007, 2019, 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_OPTO_VECTORNODE_HPP
  25 #define SHARE_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   VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) {
  48     init_class_id(Class_Vector);
  49     init_req(1, n1);
  50     init_req(2, n2);
  51     init_req(3, n3);
  52   }
  53 
  54   const TypeVect* vect_type() const { return type()->is_vect(); }
  55   uint length() const { return vect_type()->length(); } // Vector length
  56   uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
  57 
  58   virtual int Opcode() const;
  59 
  60   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
  61 
  62   static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
  63   static VectorNode* shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt);
  64   static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
  65   static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
  66 
  67   static int  opcode(int opc, BasicType bt);
  68   static bool implemented(int opc, uint vlen, BasicType bt);
  69   static bool is_shift(Node* n);
  70   static bool is_type_transition_short_to_int(Node* n);
  71   static bool is_type_transition_to_int(Node* n);
  72   static bool is_muladds2i(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 };
 138 
 139 //------------------------------AddReductionVINode--------------------------------------
 140 // Vector add int as a reduction
 141 class AddReductionVINode : public ReductionNode {
 142 public:
 143   AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 144   virtual int Opcode() const;
 145   virtual const Type* bottom_type() const { return TypeInt::INT; }
 146   virtual uint ideal_reg() const { return Op_RegI; }
 147 };
 148 
 149 //------------------------------AddReductionVLNode--------------------------------------
 150 // Vector add long as a reduction
 151 class AddReductionVLNode : public ReductionNode {
 152 public:
 153   AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 154   virtual int Opcode() const;
 155   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 156   virtual uint ideal_reg() const { return Op_RegL; }
 157 };
 158 
 159 //------------------------------AddReductionVFNode--------------------------------------
 160 // Vector add float as a reduction
 161 class AddReductionVFNode : public ReductionNode {
 162 public:
 163   AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 164   virtual int Opcode() const;
 165   virtual const Type* bottom_type() const { return Type::FLOAT; }
 166   virtual uint ideal_reg() const { return Op_RegF; }
 167 };
 168 
 169 //------------------------------AddReductionVDNode--------------------------------------
 170 // Vector add double as a reduction
 171 class AddReductionVDNode : public ReductionNode {
 172 public:
 173   AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 174   virtual int Opcode() const;
 175   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 176   virtual uint ideal_reg() const { return Op_RegD; }
 177 };
 178 
 179 //------------------------------SubVBNode--------------------------------------
 180 // Vector subtract byte
 181 class SubVBNode : public VectorNode {
 182  public:
 183   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 184   virtual int Opcode() const;
 185 };
 186 
 187 //------------------------------SubVSNode--------------------------------------
 188 // Vector subtract short
 189 class SubVSNode : public VectorNode {
 190  public:
 191   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 192   virtual int Opcode() const;
 193 };
 194 
 195 //------------------------------SubVINode--------------------------------------
 196 // Vector subtract int
 197 class SubVINode : public VectorNode {
 198  public:
 199   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 200   virtual int Opcode() const;
 201 };
 202 
 203 //------------------------------SubVLNode--------------------------------------
 204 // Vector subtract long
 205 class SubVLNode : public VectorNode {
 206  public:
 207   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 208   virtual int Opcode() const;
 209 };
 210 
 211 //------------------------------SubVFNode--------------------------------------
 212 // Vector subtract float
 213 class SubVFNode : public VectorNode {
 214  public:
 215   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 216   virtual int Opcode() const;
 217 };
 218 
 219 //------------------------------SubVDNode--------------------------------------
 220 // Vector subtract double
 221 class SubVDNode : public VectorNode {
 222  public:
 223   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 224   virtual int Opcode() const;
 225 };
 226 
 227 //------------------------------MulVBNode--------------------------------------
 228 // Vector multiply byte
 229 class MulVBNode : public VectorNode {
 230  public:
 231   MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 232   virtual int Opcode() const;
 233 };
 234 
 235 //------------------------------MulVSNode--------------------------------------
 236 // Vector multiply short
 237 class MulVSNode : public VectorNode {
 238  public:
 239   MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 240   virtual int Opcode() const;
 241 };
 242 
 243 //------------------------------MulVINode--------------------------------------
 244 // Vector multiply int
 245 class MulVINode : public VectorNode {
 246  public:
 247   MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 248   virtual int Opcode() const;
 249 };
 250 
 251 //------------------------------MulVLNode--------------------------------------
 252 // Vector multiply long
 253 class MulVLNode : public VectorNode {
 254 public:
 255   MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 256   virtual int Opcode() const;
 257 };
 258 
 259 //------------------------------MulVFNode--------------------------------------
 260 // Vector multiply float
 261 class MulVFNode : public VectorNode {
 262 public:
 263   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 264   virtual int Opcode() const;
 265 };
 266 
 267 //------------------------------MulVDNode--------------------------------------
 268 // Vector multiply double
 269 class MulVDNode : public VectorNode {
 270 public:
 271   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 272   virtual int Opcode() const;
 273 };
 274 
 275 //------------------------------MulAddVS2VINode--------------------------------
 276 // Vector multiply shorts to int and add adjacent ints.
 277 class MulAddVS2VINode : public VectorNode {
 278   public:
 279     MulAddVS2VINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 280     virtual int Opcode() const;
 281 };
 282 
 283 //------------------------------FmaVDNode--------------------------------------
 284 // Vector multiply double
 285 class FmaVDNode : public VectorNode {
 286 public:
 287   FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 288   virtual int Opcode() const;
 289 };
 290 
 291 //------------------------------FmaVFNode--------------------------------------
 292 // Vector multiply float
 293 class FmaVFNode : public VectorNode {
 294 public:
 295   FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 296   virtual int Opcode() const;
 297 };
 298 
 299 //------------------------------CMoveVFNode--------------------------------------
 300 // Vector float conditional move
 301 class CMoveVFNode : public VectorNode {
 302 public:
 303   CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 304   virtual int Opcode() const;
 305 };
 306 
 307 //------------------------------CMoveVDNode--------------------------------------
 308 // Vector double conditional move
 309 class CMoveVDNode : public VectorNode {
 310 public:
 311   CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
 312   virtual int Opcode() const;
 313 };
 314 
 315 //------------------------------MulReductionVINode--------------------------------------
 316 // Vector multiply int as a reduction
 317 class MulReductionVINode : public ReductionNode {
 318 public:
 319   MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 320   virtual int Opcode() const;
 321   virtual const Type* bottom_type() const { return TypeInt::INT; }
 322   virtual uint ideal_reg() const { return Op_RegI; }
 323 };
 324 
 325 //------------------------------MulReductionVLNode--------------------------------------
 326 // Vector multiply int as a reduction
 327 class MulReductionVLNode : public ReductionNode {
 328 public:
 329   MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 330   virtual int Opcode() const;
 331   virtual const Type* bottom_type() const { return TypeLong::LONG; }
 332   virtual uint ideal_reg() const { return Op_RegI; }
 333 };
 334 
 335 //------------------------------MulReductionVFNode--------------------------------------
 336 // Vector multiply float as a reduction
 337 class MulReductionVFNode : public ReductionNode {
 338 public:
 339   MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 340   virtual int Opcode() const;
 341   virtual const Type* bottom_type() const { return Type::FLOAT; }
 342   virtual uint ideal_reg() const { return Op_RegF; }
 343 };
 344 
 345 //------------------------------MulReductionVDNode--------------------------------------
 346 // Vector multiply double as a reduction
 347 class MulReductionVDNode : public ReductionNode {
 348 public:
 349   MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 350   virtual int Opcode() const;
 351   virtual const Type* bottom_type() const { return Type::DOUBLE; }
 352   virtual uint ideal_reg() const { return Op_RegD; }
 353 };
 354 
 355 //------------------------------DivVFNode--------------------------------------
 356 // Vector divide float
 357 class DivVFNode : public VectorNode {
 358  public:
 359   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 360   virtual int Opcode() const;
 361 };
 362 
 363 //------------------------------DivVDNode--------------------------------------
 364 // Vector Divide double
 365 class DivVDNode : public VectorNode {
 366  public:
 367   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 368   virtual int Opcode() const;
 369 };
 370 
 371 //------------------------------AbsVBNode--------------------------------------
 372 // Vector Abs byte
 373 class AbsVBNode : public VectorNode {
 374 public:
 375   AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 376   virtual int Opcode() const;
 377 };
 378 
 379 //------------------------------AbsVSNode--------------------------------------
 380 // Vector Abs short
 381 class AbsVSNode : public VectorNode {
 382 public:
 383   AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 384   virtual int Opcode() const;
 385 };
 386 
 387 //------------------------------AbsVINode--------------------------------------
 388 // Vector Abs int
 389 class AbsVINode : public VectorNode {
 390 public:
 391   AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 392   virtual int Opcode() const;
 393 };
 394 
 395 //------------------------------AbsVLNode--------------------------------------
 396 // Vector Abs long
 397 class AbsVLNode : public VectorNode {
 398 public:
 399   AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
 400   virtual int Opcode() const;
 401 };
 402 
 403 //------------------------------AbsVFNode--------------------------------------
 404 // Vector Abs float
 405 class AbsVFNode : public VectorNode {
 406  public:
 407   AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 408   virtual int Opcode() const;
 409 };
 410 
 411 //------------------------------AbsVDNode--------------------------------------
 412 // Vector Abs double
 413 class AbsVDNode : public VectorNode {
 414  public:
 415   AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 416   virtual int Opcode() const;
 417 };
 418 
 419 //------------------------------NegVFNode--------------------------------------
 420 // Vector Neg float
 421 class NegVFNode : public VectorNode {
 422  public:
 423   NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 424   virtual int Opcode() const;
 425 };
 426 
 427 //------------------------------NegVDNode--------------------------------------
 428 // Vector Neg double
 429 class NegVDNode : public VectorNode {
 430  public:
 431   NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 432   virtual int Opcode() const;
 433 };
 434 
 435 //------------------------------PopCountVINode---------------------------------
 436 // Vector popcount integer bits
 437 class PopCountVINode : public VectorNode {
 438  public:
 439   PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 440   virtual int Opcode() const;
 441 };
 442 
 443 //------------------------------SqrtVFNode--------------------------------------
 444 // Vector Sqrt float
 445 class SqrtVFNode : public VectorNode {
 446  public:
 447   SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 448   virtual int Opcode() const;
 449 };
 450 
 451 //------------------------------SqrtVDNode--------------------------------------
 452 // Vector Sqrt double
 453 class SqrtVDNode : public VectorNode {
 454  public:
 455   SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
 456   virtual int Opcode() const;
 457 };
 458 
 459 //------------------------------LShiftVBNode-----------------------------------
 460 // Vector left shift bytes
 461 class LShiftVBNode : public VectorNode {
 462  public:
 463   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 464   virtual int Opcode() const;
 465 };
 466 
 467 //------------------------------LShiftVSNode-----------------------------------
 468 // Vector left shift shorts
 469 class LShiftVSNode : public VectorNode {
 470  public:
 471   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 472   virtual int Opcode() const;
 473 };
 474 
 475 //------------------------------LShiftVINode-----------------------------------
 476 // Vector left shift ints
 477 class LShiftVINode : public VectorNode {
 478  public:
 479   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 480   virtual int Opcode() const;
 481 };
 482 
 483 //------------------------------LShiftVLNode-----------------------------------
 484 // Vector left shift longs
 485 class LShiftVLNode : public VectorNode {
 486  public:
 487   LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 488   virtual int Opcode() const;
 489 };
 490 
 491 //------------------------------RShiftVBNode-----------------------------------
 492 // Vector right arithmetic (signed) shift bytes
 493 class RShiftVBNode : public VectorNode {
 494  public:
 495   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 496   virtual int Opcode() const;
 497 };
 498 
 499 //------------------------------RShiftVSNode-----------------------------------
 500 // Vector right arithmetic (signed) shift shorts
 501 class RShiftVSNode : public VectorNode {
 502  public:
 503   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 504   virtual int Opcode() const;
 505 };
 506 
 507 //------------------------------RShiftVINode-----------------------------------
 508 // Vector right arithmetic (signed) shift ints
 509 class RShiftVINode : public VectorNode {
 510  public:
 511   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 512   virtual int Opcode() const;
 513 };
 514 
 515 //------------------------------RShiftVLNode-----------------------------------
 516 // Vector right arithmetic (signed) shift longs
 517 class RShiftVLNode : public VectorNode {
 518  public:
 519   RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 520   virtual int Opcode() const;
 521 };
 522 
 523 //------------------------------URShiftVBNode----------------------------------
 524 // Vector right logical (unsigned) shift bytes
 525 class URShiftVBNode : public VectorNode {
 526  public:
 527   URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 528   virtual int Opcode() const;
 529 };
 530 
 531 //------------------------------URShiftVSNode----------------------------------
 532 // Vector right logical (unsigned) shift shorts
 533 class URShiftVSNode : public VectorNode {
 534  public:
 535   URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 536   virtual int Opcode() const;
 537 };
 538 
 539 //------------------------------URShiftVINode----------------------------------
 540 // Vector right logical (unsigned) shift ints
 541 class URShiftVINode : public VectorNode {
 542  public:
 543   URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 544   virtual int Opcode() const;
 545 };
 546 
 547 //------------------------------URShiftVLNode----------------------------------
 548 // Vector right logical (unsigned) shift longs
 549 class URShiftVLNode : public VectorNode {
 550  public:
 551   URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 552   virtual int Opcode() const;
 553 };
 554 
 555 //------------------------------LShiftCntVNode---------------------------------
 556 // Vector left shift count
 557 class LShiftCntVNode : public VectorNode {
 558  public:
 559   LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 560   virtual int Opcode() const;
 561   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 562 };
 563 
 564 //------------------------------RShiftCntVNode---------------------------------
 565 // Vector right shift count
 566 class RShiftCntVNode : public VectorNode {
 567  public:
 568   RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
 569   virtual int Opcode() const;
 570   virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
 571 };
 572 
 573 
 574 //------------------------------AndVNode---------------------------------------
 575 // Vector and integer
 576 class AndVNode : public VectorNode {
 577  public:
 578   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 579   virtual int Opcode() const;
 580 };
 581 
 582 //------------------------------OrVNode---------------------------------------
 583 // Vector or integer
 584 class OrVNode : public VectorNode {
 585  public:
 586   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 587   virtual int Opcode() const;
 588 };
 589 
 590 //------------------------------XorVNode---------------------------------------
 591 // Vector xor integer
 592 class XorVNode : public VectorNode {
 593  public:
 594   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 595   virtual int Opcode() const;
 596 };
 597 
 598 //------------------------------MinVNode--------------------------------------
 599 // Vector min
 600 class MinVNode : public VectorNode {
 601 public:
 602   MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 603   virtual int Opcode() const;
 604 };
 605 
 606 //------------------------------MaxVNode--------------------------------------
 607 // Vector max
 608 class MaxVNode : public VectorNode {
 609 public:
 610   MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
 611   virtual int Opcode() const;
 612 };
 613 
 614 //------------------------------MinReductionVNode--------------------------------------
 615 // Vector min as a reduction
 616 class MinReductionVNode : public ReductionNode {
 617 public:
 618   MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 619   virtual int Opcode() const;
 620   virtual const Type* bottom_type() const {
 621     BasicType bt = in(1)->bottom_type()->basic_type();
 622     if (bt == T_FLOAT) {
 623       return Type::FLOAT;
 624     } else if (bt == T_DOUBLE) {
 625       return Type::DOUBLE;
 626     }
 627     assert(false, "unsupported basic type");
 628     return NULL;
 629   }
 630   virtual uint ideal_reg() const {
 631     BasicType bt = in(1)->bottom_type()->basic_type();
 632     if (bt == T_FLOAT) {
 633       return Op_RegF;
 634     } else if (bt == T_DOUBLE) {
 635       return Op_RegD;
 636     }
 637     assert(false, "unsupported basic type");
 638     return 0;
 639   }
 640 };
 641 
 642 //------------------------------MaxReductionVNode--------------------------------------
 643 // Vector max as a reduction
 644 class MaxReductionVNode : public ReductionNode {
 645 public:
 646   MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
 647   virtual int Opcode() const;
 648   virtual const Type* bottom_type() const {
 649     BasicType bt = in(1)->bottom_type()->basic_type();
 650     if (bt == T_FLOAT) {
 651       return Type::FLOAT;
 652     } else {
 653       return Type::DOUBLE;
 654     }
 655     assert(false, "unsupported basic type");
 656     return NULL;
 657   }
 658   virtual uint ideal_reg() const {
 659     BasicType bt = in(1)->bottom_type()->basic_type();
 660     if (bt == T_FLOAT) {
 661       return Op_RegF;
 662     } else {
 663       return Op_RegD;
 664     }
 665     assert(false, "unsupported basic type");
 666     return 0;
 667   }
 668 };
 669 
 670 //================================= M E M O R Y ===============================
 671 
 672 //------------------------------LoadVectorNode---------------------------------
 673 // Load Vector from memory
 674 class LoadVectorNode : public LoadNode {
 675  public:
 676   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
 677     : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
 678     init_class_id(Class_LoadVector);
 679     set_mismatched_access();
 680   }
 681 
 682   const TypeVect* vect_type() const { return type()->is_vect(); }
 683   uint length() const { return vect_type()->length(); } // Vector length
 684 
 685   virtual int Opcode() const;
 686 
 687   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 688   virtual BasicType memory_type() const { return T_VOID; }
 689   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 690 
 691   virtual int store_Opcode() const { return Op_StoreVector; }
 692 
 693   static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
 694                               Node* adr, const TypePtr* atyp,
 695                               uint vlen, BasicType bt,
 696                               ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
 697   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
 698 };
 699 
 700 //------------------------------StoreVectorNode--------------------------------
 701 // Store Vector to memory
 702 class StoreVectorNode : public StoreNode {
 703  public:
 704   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
 705     : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
 706     assert(val->is_Vector() || val->is_LoadVector(), "sanity");
 707     init_class_id(Class_StoreVector);
 708     set_mismatched_access();
 709   }
 710 
 711   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
 712   uint length() const { return vect_type()->length(); } // Vector length
 713 
 714   virtual int Opcode() const;
 715 
 716   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 717   virtual BasicType memory_type() const { return T_VOID; }
 718   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 719 
 720   static StoreVectorNode* make(int opc, Node* ctl, Node* mem,
 721                                Node* adr, const TypePtr* atyp, Node* val,
 722                                uint vlen);
 723 
 724   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
 725 };
 726 
 727 
 728 //=========================Promote_Scalar_to_Vector============================
 729 
 730 //------------------------------ReplicateBNode---------------------------------
 731 // Replicate byte scalar to be vector
 732 class ReplicateBNode : public VectorNode {
 733  public:
 734   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 735   virtual int Opcode() const;
 736 };
 737 
 738 //------------------------------ReplicateSNode---------------------------------
 739 // Replicate short scalar to be vector
 740 class ReplicateSNode : public VectorNode {
 741  public:
 742   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 743   virtual int Opcode() const;
 744 };
 745 
 746 //------------------------------ReplicateINode---------------------------------
 747 // Replicate int scalar to be vector
 748 class ReplicateINode : public VectorNode {
 749  public:
 750   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 751   virtual int Opcode() const;
 752 };
 753 
 754 //------------------------------ReplicateLNode---------------------------------
 755 // Replicate long scalar to be vector
 756 class ReplicateLNode : public VectorNode {
 757  public:
 758   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 759   virtual int Opcode() const;
 760 };
 761 
 762 //------------------------------ReplicateFNode---------------------------------
 763 // Replicate float scalar to be vector
 764 class ReplicateFNode : public VectorNode {
 765  public:
 766   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 767   virtual int Opcode() const;
 768 };
 769 
 770 //------------------------------ReplicateDNode---------------------------------
 771 // Replicate double scalar to be vector
 772 class ReplicateDNode : public VectorNode {
 773  public:
 774   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 775   virtual int Opcode() const;
 776 };
 777 
 778 //========================Pack_Scalars_into_a_Vector===========================
 779 
 780 //------------------------------PackNode---------------------------------------
 781 // Pack parent class (not for code generation).
 782 class PackNode : public VectorNode {
 783  public:
 784   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 785   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
 786   virtual int Opcode() const;
 787 
 788   void add_opd(Node* n) {
 789     add_req(n);
 790   }
 791 
 792   // Create a binary tree form for Packs. [lo, hi) (half-open) range
 793   PackNode* binary_tree_pack(int lo, int hi);
 794 
 795   static PackNode* make(Node* s, uint vlen, BasicType bt);
 796 };
 797 
 798 //------------------------------PackBNode--------------------------------------
 799 // Pack byte scalars into vector
 800 class PackBNode : public PackNode {
 801  public:
 802   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 803   virtual int Opcode() const;
 804 };
 805 
 806 //------------------------------PackSNode--------------------------------------
 807 // Pack short scalars into a vector
 808 class PackSNode : public PackNode {
 809  public:
 810   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 811   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 812   virtual int Opcode() const;
 813 };
 814 
 815 //------------------------------PackINode--------------------------------------
 816 // Pack integer scalars into a vector
 817 class PackINode : public PackNode {
 818  public:
 819   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 820   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 821   virtual int Opcode() const;
 822 };
 823 
 824 //------------------------------PackLNode--------------------------------------
 825 // Pack long scalars into a vector
 826 class PackLNode : public PackNode {
 827  public:
 828   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 829   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 830   virtual int Opcode() const;
 831 };
 832 
 833 //------------------------------Pack2LNode-------------------------------------
 834 // Pack 2 long scalars into a vector
 835 class Pack2LNode : public PackNode {
 836  public:
 837   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 838   virtual int Opcode() const;
 839 };
 840 
 841 //------------------------------PackFNode--------------------------------------
 842 // Pack float scalars into vector
 843 class PackFNode : public PackNode {
 844  public:
 845   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 846   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 847   virtual int Opcode() const;
 848 };
 849 
 850 //------------------------------PackDNode--------------------------------------
 851 // Pack double scalars into a vector
 852 class PackDNode : public PackNode {
 853  public:
 854   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
 855   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 856   virtual int Opcode() const;
 857 };
 858 
 859 //------------------------------Pack2DNode-------------------------------------
 860 // Pack 2 double scalars into a vector
 861 class Pack2DNode : public PackNode {
 862  public:
 863   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 864   virtual int Opcode() const;
 865 };
 866 
 867 
 868 //========================Extract_Scalar_from_Vector===========================
 869 
 870 //------------------------------ExtractNode------------------------------------
 871 // Extract a scalar from a vector at position "pos"
 872 class ExtractNode : public Node {
 873  public:
 874   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
 875     assert(in(2)->get_int() >= 0, "positive constants");
 876   }
 877   virtual int Opcode() const;
 878   uint  pos() const { return in(2)->get_int(); }
 879 
 880   static Node* make(Node* v, uint position, BasicType bt);
 881 };
 882 
 883 //------------------------------ExtractBNode-----------------------------------
 884 // Extract a byte from a vector at position "pos"
 885 class ExtractBNode : public ExtractNode {
 886  public:
 887   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 888   virtual int Opcode() const;
 889   virtual const Type *bottom_type() const { return TypeInt::INT; }
 890   virtual uint ideal_reg() const { return Op_RegI; }
 891 };
 892 
 893 //------------------------------ExtractUBNode----------------------------------
 894 // Extract a boolean from a vector at position "pos"
 895 class ExtractUBNode : public ExtractNode {
 896  public:
 897   ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 898   virtual int Opcode() const;
 899   virtual const Type *bottom_type() const { return TypeInt::INT; }
 900   virtual uint ideal_reg() const { return Op_RegI; }
 901 };
 902 
 903 //------------------------------ExtractCNode-----------------------------------
 904 // Extract a char from a vector at position "pos"
 905 class ExtractCNode : public ExtractNode {
 906  public:
 907   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 908   virtual int Opcode() const;
 909   virtual const Type *bottom_type() const { return TypeInt::INT; }
 910   virtual uint ideal_reg() const { return Op_RegI; }
 911 };
 912 
 913 //------------------------------ExtractSNode-----------------------------------
 914 // Extract a short from a vector at position "pos"
 915 class ExtractSNode : public ExtractNode {
 916  public:
 917   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 918   virtual int Opcode() const;
 919   virtual const Type *bottom_type() const { return TypeInt::INT; }
 920   virtual uint ideal_reg() const { return Op_RegI; }
 921 };
 922 
 923 //------------------------------ExtractINode-----------------------------------
 924 // Extract an int from a vector at position "pos"
 925 class ExtractINode : public ExtractNode {
 926  public:
 927   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 928   virtual int Opcode() const;
 929   virtual const Type *bottom_type() const { return TypeInt::INT; }
 930   virtual uint ideal_reg() const { return Op_RegI; }
 931 };
 932 
 933 //------------------------------ExtractLNode-----------------------------------
 934 // Extract a long from a vector at position "pos"
 935 class ExtractLNode : public ExtractNode {
 936  public:
 937   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 938   virtual int Opcode() const;
 939   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 940   virtual uint ideal_reg() const { return Op_RegL; }
 941 };
 942 
 943 //------------------------------ExtractFNode-----------------------------------
 944 // Extract a float from a vector at position "pos"
 945 class ExtractFNode : public ExtractNode {
 946  public:
 947   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 948   virtual int Opcode() const;
 949   virtual const Type *bottom_type() const { return Type::FLOAT; }
 950   virtual uint ideal_reg() const { return Op_RegF; }
 951 };
 952 
 953 //------------------------------ExtractDNode-----------------------------------
 954 // Extract a double from a vector at position "pos"
 955 class ExtractDNode : public ExtractNode {
 956  public:
 957   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 958   virtual int Opcode() const;
 959   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 960   virtual uint ideal_reg() const { return Op_RegD; }
 961 };
 962 
 963 //------------------------------SetVectMaskINode-------------------------------
 964 // Provide a mask for a vector predicate machine
 965 class SetVectMaskINode : public Node {
 966 public:
 967   SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {}
 968   virtual int Opcode() const;
 969   const Type *bottom_type() const { return TypeInt::INT; }
 970   virtual uint ideal_reg() const { return Op_RegI; }
 971   virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; }
 972 };
 973 
 974 #endif // SHARE_OPTO_VECTORNODE_HPP