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