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