1 /*
   2  * Copyright (c) 2007, 2012, 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 
  50   virtual int Opcode() const;
  51 
  52   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
  53 
  54   static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
  55 
  56   static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
  57 
  58   static int  opcode(int opc, uint vlen, BasicType bt);
  59   static bool implemented(int opc, uint vlen, BasicType bt);
  60 
  61 };
  62 
  63 //===========================Vector=ALU=Operations====================================
  64 
  65 //------------------------------AddVBNode---------------------------------------
  66 // Vector add byte
  67 class AddVBNode : public VectorNode {
  68  public:
  69   AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  70   virtual int Opcode() const;
  71 };
  72 
  73 //------------------------------AddVSNode---------------------------------------
  74 // Vector add char/short
  75 class AddVSNode : public VectorNode {
  76  public:
  77   AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  78   virtual int Opcode() const;
  79 };
  80 
  81 //------------------------------AddVINode---------------------------------------
  82 // Vector add int
  83 class AddVINode : public VectorNode {
  84  public:
  85   AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  86   virtual int Opcode() const;
  87 };
  88 
  89 //------------------------------AddVLNode---------------------------------------
  90 // Vector add long
  91 class AddVLNode : public VectorNode {
  92  public:
  93   AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  94   virtual int Opcode() const;
  95 };
  96 
  97 //------------------------------AddVFNode---------------------------------------
  98 // Vector add float
  99 class AddVFNode : public VectorNode {
 100  public:
 101   AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 102   virtual int Opcode() const;
 103 };
 104 
 105 //------------------------------AddVDNode---------------------------------------
 106 // Vector add double
 107 class AddVDNode : public VectorNode {
 108  public:
 109   AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 110   virtual int Opcode() const;
 111 };
 112 
 113 //------------------------------SubVBNode---------------------------------------
 114 // Vector subtract byte
 115 class SubVBNode : public VectorNode {
 116  public:
 117   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 118   virtual int Opcode() const;
 119 };
 120 
 121 //------------------------------SubVSNode---------------------------------------
 122 // Vector subtract short
 123 class SubVSNode : public VectorNode {
 124  public:
 125   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 126   virtual int Opcode() const;
 127 };
 128 
 129 //------------------------------SubVINode---------------------------------------
 130 // Vector subtract int
 131 class SubVINode : public VectorNode {
 132  public:
 133   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 134   virtual int Opcode() const;
 135 };
 136 
 137 //------------------------------SubVLNode---------------------------------------
 138 // Vector subtract long
 139 class SubVLNode : public VectorNode {
 140  public:
 141   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 142   virtual int Opcode() const;
 143 };
 144 
 145 //------------------------------SubVFNode---------------------------------------
 146 // Vector subtract float
 147 class SubVFNode : public VectorNode {
 148  public:
 149   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 150   virtual int Opcode() const;
 151 };
 152 
 153 //------------------------------SubVDNode---------------------------------------
 154 // Vector subtract double
 155 class SubVDNode : public VectorNode {
 156  public:
 157   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 158   virtual int Opcode() const;
 159 };
 160 
 161 //------------------------------MulVFNode---------------------------------------
 162 // Vector multiply float
 163 class MulVFNode : public VectorNode {
 164  public:
 165   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 166   virtual int Opcode() const;
 167 };
 168 
 169 //------------------------------MulVDNode---------------------------------------
 170 // Vector multiply double
 171 class MulVDNode : public VectorNode {
 172  public:
 173   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 174   virtual int Opcode() const;
 175 };
 176 
 177 //------------------------------DivVFNode---------------------------------------
 178 // Vector divide float
 179 class DivVFNode : public VectorNode {
 180  public:
 181   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 182   virtual int Opcode() const;
 183 };
 184 
 185 //------------------------------DivVDNode---------------------------------------
 186 // Vector Divide double
 187 class DivVDNode : public VectorNode {
 188  public:
 189   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 190   virtual int Opcode() const;
 191 };
 192 
 193 //------------------------------LShiftVBNode---------------------------------------
 194 // Vector lshift byte
 195 class LShiftVBNode : public VectorNode {
 196  public:
 197   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 198   virtual int Opcode() const;
 199 };
 200 
 201 //------------------------------LShiftVSNode---------------------------------------
 202 // Vector lshift shorts
 203 class LShiftVSNode : public VectorNode {
 204  public:
 205   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 206   virtual int Opcode() const;
 207 };
 208 
 209 //------------------------------LShiftVINode---------------------------------------
 210 // Vector lshift ints
 211 class LShiftVINode : public VectorNode {
 212  public:
 213   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 214   virtual int Opcode() const;
 215 };
 216 
 217 //------------------------------URShiftVBNode---------------------------------------
 218 // Vector urshift bytes
 219 class RShiftVBNode : public VectorNode {
 220  public:
 221   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 222   virtual int Opcode() const;
 223 };
 224 
 225 //------------------------------URShiftVSNode---------------------------------------
 226 // Vector urshift shorts
 227 class RShiftVSNode : public VectorNode {
 228  public:
 229   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 230   virtual int Opcode() const;
 231 };
 232 
 233 //------------------------------URShiftVINode---------------------------------------
 234 // Vector urshift ints
 235 class RShiftVINode : public VectorNode {
 236  public:
 237   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 238   virtual int Opcode() const;
 239 };
 240 
 241 //------------------------------AndVNode---------------------------------------
 242 // Vector and
 243 class AndVNode : public VectorNode {
 244  public:
 245   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 246   virtual int Opcode() const;
 247 };
 248 
 249 //------------------------------OrVNode---------------------------------------
 250 // Vector or
 251 class OrVNode : public VectorNode {
 252  public:
 253   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 254   virtual int Opcode() const;
 255 };
 256 
 257 //------------------------------XorVNode---------------------------------------
 258 // Vector xor
 259 class XorVNode : public VectorNode {
 260  public:
 261   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 262   virtual int Opcode() const;
 263 };
 264 
 265 //================================= M E M O R Y ===============================
 266 
 267 //------------------------------LoadVectorNode---------------------------------
 268 // Load Vector from memory
 269 class LoadVectorNode : public LoadNode {
 270  public:
 271   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
 272     : LoadNode(c, mem, adr, at, vt) {
 273     init_class_id(Class_LoadVector);
 274   }
 275 
 276   const TypeVect* vect_type() const { return type()->is_vect(); }
 277   uint length() const { return vect_type()->length(); } // Vector length
 278 
 279   virtual int Opcode() const;
 280 
 281   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 282   virtual BasicType memory_type() const { return T_VOID; }
 283   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 284 
 285   virtual int store_Opcode() const { return Op_StoreVector; }
 286 
 287   static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
 288                               Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
 289 };
 290 
 291 //------------------------------StoreVectorNode--------------------------------
 292 // Store Vector to memory
 293 class StoreVectorNode : public StoreNode {
 294  public:
 295   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
 296     : StoreNode(c, mem, adr, at, val) {
 297     assert(val->is_Vector() || val->is_LoadVector(), "sanity");
 298     init_class_id(Class_StoreVector);
 299   }
 300 
 301   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
 302   uint length() const { return vect_type()->length(); } // Vector length
 303 
 304   virtual int Opcode() const;
 305 
 306   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 307   virtual BasicType memory_type() const { return T_VOID; }
 308   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 309 
 310   static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
 311                                Node* adr, const TypePtr* atyp, Node* val,
 312                                uint vlen);
 313 };
 314 
 315 
 316 //=========================Promote_Scalar_to_Vector============================
 317 
 318 //------------------------------ReplicateBNode---------------------------------
 319 // Replicate byte scalar to be vector
 320 class ReplicateBNode : public VectorNode {
 321  public:
 322   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 323   virtual int Opcode() const;
 324 };
 325 
 326 //------------------------------ReplicateSNode---------------------------------
 327 // Replicate short scalar to be vector
 328 class ReplicateSNode : public VectorNode {
 329  public:
 330   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 331   virtual int Opcode() const;
 332 };
 333 
 334 //------------------------------ReplicateINode---------------------------------
 335 // Replicate int scalar to be vector
 336 class ReplicateINode : public VectorNode {
 337  public:
 338   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 339   virtual int Opcode() const;
 340 };
 341 
 342 //------------------------------ReplicateLNode---------------------------------
 343 // Replicate long scalar to be vector
 344 class ReplicateLNode : public VectorNode {
 345  public:
 346   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 347   virtual int Opcode() const;
 348 };
 349 
 350 //------------------------------ReplicateFNode---------------------------------
 351 // Replicate float scalar to be vector
 352 class ReplicateFNode : public VectorNode {
 353  public:
 354   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 355   virtual int Opcode() const;
 356 };
 357 
 358 //------------------------------ReplicateDNode---------------------------------
 359 // Replicate double scalar to be vector
 360 class ReplicateDNode : public VectorNode {
 361  public:
 362   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 363   virtual int Opcode() const;
 364 };
 365 
 366 //========================Pack_Scalars_into_a_Vector===========================
 367 
 368 //------------------------------PackNode---------------------------------------
 369 // Pack parent class (not for code generation).
 370 class PackNode : public VectorNode {
 371  public:
 372   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 373   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
 374   virtual int Opcode() const;
 375 
 376   void add_opd(uint i, Node* n) {
 377     init_req(i+1, n);
 378   }
 379 
 380   // Create a binary tree form for Packs. [lo, hi) (half-open) range
 381   Node* binaryTreePack(Compile* C, int lo, int hi);
 382 
 383   static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
 384 };
 385 
 386 //------------------------------PackBNode---------------------------------------
 387 // Pack byte scalars into vector
 388 class PackBNode : public PackNode {
 389  public:
 390   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 391   virtual int Opcode() const;
 392 };
 393 
 394 //------------------------------PackSNode---------------------------------------
 395 // Pack short scalars into a vector
 396 class PackSNode : public PackNode {
 397  public:
 398   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 399   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 400   virtual int Opcode() const;
 401 };
 402 
 403 //------------------------------PackINode---------------------------------------
 404 // Pack integer scalars into a vector
 405 class PackINode : public PackNode {
 406  public:
 407   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 408   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 409   virtual int Opcode() const;
 410 };
 411 
 412 //------------------------------PackLNode---------------------------------------
 413 // Pack long scalars into a vector
 414 class PackLNode : public PackNode {
 415  public:
 416   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 417   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 418   virtual int Opcode() const;
 419 };
 420 
 421 //------------------------------Pack2LNode--------------------------------------
 422 // Pack 2 long scalars into a vector
 423 class Pack2LNode : public PackNode {
 424  public:
 425   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 426   virtual int Opcode() const;
 427 };
 428 
 429 //------------------------------PackFNode---------------------------------------
 430 // Pack float scalars into vector
 431 class PackFNode : public PackNode {
 432  public:
 433   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 434   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 435   virtual int Opcode() const;
 436 };
 437 
 438 //------------------------------PackDNode---------------------------------------
 439 // Pack double scalars into a vector
 440 class PackDNode : public PackNode {
 441  public:
 442   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
 443   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 444   virtual int Opcode() const;
 445 };
 446 
 447 //------------------------------Pack2DNode--------------------------------------
 448 // Pack 2 double scalars into a vector
 449 class Pack2DNode : public PackNode {
 450  public:
 451   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 452   virtual int Opcode() const;
 453 };
 454 
 455 
 456 //========================Extract_Scalar_from_Vector===============================
 457 
 458 //------------------------------ExtractNode---------------------------------------
 459 // Extract a scalar from a vector at position "pos"
 460 class ExtractNode : public Node {
 461  public:
 462   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
 463     assert(in(2)->get_int() >= 0, "positive constants");
 464   }
 465   virtual int Opcode() const;
 466   uint  pos() const { return in(2)->get_int(); }
 467 
 468   static Node* make(Compile* C, Node* v, uint position, BasicType bt);
 469 };
 470 
 471 //------------------------------ExtractBNode---------------------------------------
 472 // Extract a byte from a vector at position "pos"
 473 class ExtractBNode : public ExtractNode {
 474  public:
 475   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 476   virtual int Opcode() const;
 477   virtual const Type *bottom_type() const { return TypeInt::INT; }
 478   virtual uint ideal_reg() const { return Op_RegI; }
 479 };
 480 
 481 //------------------------------ExtractUBNode--------------------------------------
 482 // Extract a boolean from a vector at position "pos"
 483 class ExtractUBNode : public ExtractNode {
 484  public:
 485   ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 486   virtual int Opcode() const;
 487   virtual const Type *bottom_type() const { return TypeInt::INT; }
 488   virtual uint ideal_reg() const { return Op_RegI; }
 489 };
 490 
 491 //------------------------------ExtractCNode---------------------------------------
 492 // Extract a char from a vector at position "pos"
 493 class ExtractCNode : public ExtractNode {
 494  public:
 495   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 496   virtual int Opcode() const;
 497   virtual const Type *bottom_type() const { return TypeInt::INT; }
 498   virtual uint ideal_reg() const { return Op_RegI; }
 499 };
 500 
 501 //------------------------------ExtractSNode---------------------------------------
 502 // Extract a short from a vector at position "pos"
 503 class ExtractSNode : public ExtractNode {
 504  public:
 505   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 506   virtual int Opcode() const;
 507   virtual const Type *bottom_type() const { return TypeInt::INT; }
 508   virtual uint ideal_reg() const { return Op_RegI; }
 509 };
 510 
 511 //------------------------------ExtractINode---------------------------------------
 512 // Extract an int from a vector at position "pos"
 513 class ExtractINode : public ExtractNode {
 514  public:
 515   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 516   virtual int Opcode() const;
 517   virtual const Type *bottom_type() const { return TypeInt::INT; }
 518   virtual uint ideal_reg() const { return Op_RegI; }
 519 };
 520 
 521 //------------------------------ExtractLNode---------------------------------------
 522 // Extract a long from a vector at position "pos"
 523 class ExtractLNode : public ExtractNode {
 524  public:
 525   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 526   virtual int Opcode() const;
 527   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 528   virtual uint ideal_reg() const { return Op_RegL; }
 529 };
 530 
 531 //------------------------------ExtractFNode---------------------------------------
 532 // Extract a float from a vector at position "pos"
 533 class ExtractFNode : public ExtractNode {
 534  public:
 535   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 536   virtual int Opcode() const;
 537   virtual const Type *bottom_type() const { return Type::FLOAT; }
 538   virtual uint ideal_reg() const { return Op_RegF; }
 539 };
 540 
 541 //------------------------------ExtractDNode---------------------------------------
 542 // Extract a double from a vector at position "pos"
 543 class ExtractDNode : public ExtractNode {
 544  public:
 545   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 546   virtual int Opcode() const;
 547   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 548   virtual uint ideal_reg() const { return Op_RegD; }
 549 };
 550 
 551 #endif // SHARE_VM_OPTO_VECTORNODE_HPP