1 /* 2 * Copyright (c) 2007, 2014, 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 #include "opto/callnode.hpp" 32 #include "opto/subnode.hpp" 33 34 //------------------------------VectorNode------------------------------------- 35 // Vector Operation 36 class VectorNode : public TypeNode { 37 public: 38 39 VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) { 40 init_class_id(Class_Vector); 41 init_req(1, n1); 42 } 43 VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) { 44 init_class_id(Class_Vector); 45 init_req(1, n1); 46 init_req(2, n2); 47 } 48 49 VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) { 50 init_class_id(Class_Vector); 51 init_req(1, n1); 52 init_req(2, n2); 53 init_req(3, n3); 54 } 55 56 const TypeVect* vect_type() const { return type()->is_vect(); } 57 uint length() const { return vect_type()->length(); } // Vector length 58 uint length_in_bytes() const { return vect_type()->length_in_bytes(); } 59 60 virtual int Opcode() const; 61 62 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); } 63 64 static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t); 65 static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt); 66 static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt); 67 static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt); 68 69 static int opcode(int opc, BasicType bt); 70 static int replicate_opcode(BasicType bt); 71 static bool implemented(int opc, uint vlen, BasicType bt); 72 static bool is_shift(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 static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt); 138 }; 139 140 //------------------------------AddReductionVINode-------------------------------------- 141 // Vector add byte, short and int as a reduction 142 class AddReductionVINode : public ReductionNode { 143 public: 144 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 145 if (in1->bottom_type()->basic_type() == T_INT) { 146 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 147 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 148 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 149 } 150 } 151 virtual int Opcode() const; 152 virtual const Type* bottom_type() const { 153 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 154 return TypeInt::INT; 155 else if(in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 156 return TypeInt::BYTE; 157 else 158 return TypeInt::SHORT; 159 } 160 virtual uint ideal_reg() const { return Op_RegI; } 161 }; 162 163 //------------------------------AddReductionVLNode-------------------------------------- 164 // Vector add long as a reduction 165 class AddReductionVLNode : public ReductionNode { 166 public: 167 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 168 virtual int Opcode() const; 169 virtual const Type* bottom_type() const { return TypeLong::LONG; } 170 virtual uint ideal_reg() const { return Op_RegL; } 171 }; 172 173 //------------------------------AddReductionVFNode-------------------------------------- 174 // Vector add float as a reduction 175 class AddReductionVFNode : public ReductionNode { 176 public: 177 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 178 virtual int Opcode() const; 179 virtual const Type* bottom_type() const { return Type::FLOAT; } 180 virtual uint ideal_reg() const { return Op_RegF; } 181 }; 182 183 //------------------------------AddReductionVDNode-------------------------------------- 184 // Vector add double as a reduction 185 class AddReductionVDNode : public ReductionNode { 186 public: 187 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 188 virtual int Opcode() const; 189 virtual const Type* bottom_type() const { return Type::DOUBLE; } 190 virtual uint ideal_reg() const { return Op_RegD; } 191 }; 192 193 //------------------------------SubVBNode-------------------------------------- 194 // Vector subtract byte 195 class SubVBNode : public VectorNode { 196 public: 197 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 198 virtual int Opcode() const; 199 }; 200 201 //------------------------------SubVSNode-------------------------------------- 202 // Vector subtract short 203 class SubVSNode : public VectorNode { 204 public: 205 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 206 virtual int Opcode() const; 207 }; 208 209 //------------------------------SubVINode-------------------------------------- 210 // Vector subtract int 211 class SubVINode : public VectorNode { 212 public: 213 SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 214 virtual int Opcode() const; 215 }; 216 217 //------------------------------SubVLNode-------------------------------------- 218 // Vector subtract long 219 class SubVLNode : public VectorNode { 220 public: 221 SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 222 virtual int Opcode() const; 223 }; 224 225 //------------------------------SubVFNode-------------------------------------- 226 // Vector subtract float 227 class SubVFNode : public VectorNode { 228 public: 229 SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 230 virtual int Opcode() const; 231 }; 232 233 //------------------------------SubVDNode-------------------------------------- 234 // Vector subtract double 235 class SubVDNode : public VectorNode { 236 public: 237 SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 238 virtual int Opcode() const; 239 }; 240 241 //------------------------------SubReductionVNode-------------------------------------- 242 // Vector and int, long as a reduction 243 class SubReductionVNode : public ReductionNode { 244 public: 245 SubReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 246 assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 247 assert(in1->bottom_type()->basic_type() == T_INT || 248 in1->bottom_type()->basic_type() == T_LONG, ""); 249 } 250 virtual int Opcode() const; 251 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 252 virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 253 return TypeInt::INT; else return TypeLong::LONG; } 254 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 255 }; 256 257 //------------------------------MulVBNode-------------------------------------- 258 // Vector multiply byte 259 class MulVBNode : public VectorNode { 260 public: 261 MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 262 virtual int Opcode() const; 263 }; 264 265 //------------------------------MulVSNode-------------------------------------- 266 // Vector multiply short 267 class MulVSNode : public VectorNode { 268 public: 269 MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 270 virtual int Opcode() const; 271 }; 272 273 //------------------------------MulVINode-------------------------------------- 274 // Vector multiply int 275 class MulVINode : public VectorNode { 276 public: 277 MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 278 virtual int Opcode() const; 279 }; 280 281 //------------------------------MulVLNode-------------------------------------- 282 // Vector multiply long 283 class MulVLNode : public VectorNode { 284 public: 285 MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 286 virtual int Opcode() const; 287 }; 288 289 //------------------------------MulVFNode-------------------------------------- 290 // Vector multiply float 291 class MulVFNode : public VectorNode { 292 public: 293 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 294 virtual int Opcode() const; 295 }; 296 297 //------------------------------MulVDNode-------------------------------------- 298 // Vector multiply double 299 class MulVDNode : public VectorNode { 300 public: 301 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 302 virtual int Opcode() const; 303 }; 304 305 //------------------------------FmaVDNode-------------------------------------- 306 // Vector multiply double 307 class FmaVDNode : public VectorNode { 308 public: 309 FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 310 virtual int Opcode() const; 311 }; 312 313 //------------------------------FmaVFNode-------------------------------------- 314 // Vector multiply float 315 class FmaVFNode : public VectorNode { 316 public: 317 FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 318 virtual int Opcode() const; 319 }; 320 321 //------------------------------CMoveVFNode-------------------------------------- 322 // Vector float conditional move 323 class CMoveVFNode : public VectorNode { 324 public: 325 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 326 virtual int Opcode() const; 327 }; 328 329 //------------------------------CMoveVDNode-------------------------------------- 330 // Vector double conditional move 331 class CMoveVDNode : public VectorNode { 332 public: 333 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 334 virtual int Opcode() const; 335 }; 336 337 //------------------------------MulReductionVINode-------------------------------------- 338 // Vector multiply int as a reduction 339 class MulReductionVINode : public ReductionNode { 340 public: 341 MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 342 virtual int Opcode() const; 343 virtual const Type* bottom_type() const { return TypeInt::INT; } 344 virtual uint ideal_reg() const { return Op_RegI; } 345 }; 346 347 //------------------------------MulReductionVLNode-------------------------------------- 348 // Vector multiply int as a reduction 349 class MulReductionVLNode : public ReductionNode { 350 public: 351 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 352 virtual int Opcode() const; 353 virtual const Type* bottom_type() const { return TypeLong::LONG; } 354 virtual uint ideal_reg() const { return Op_RegI; } 355 }; 356 357 //------------------------------MulReductionVFNode-------------------------------------- 358 // Vector multiply float as a reduction 359 class MulReductionVFNode : public ReductionNode { 360 public: 361 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 362 virtual int Opcode() const; 363 virtual const Type* bottom_type() const { return Type::FLOAT; } 364 virtual uint ideal_reg() const { return Op_RegF; } 365 }; 366 367 //------------------------------MulReductionVDNode-------------------------------------- 368 // Vector multiply double as a reduction 369 class MulReductionVDNode : public ReductionNode { 370 public: 371 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 372 virtual int Opcode() const; 373 virtual const Type* bottom_type() const { return Type::DOUBLE; } 374 virtual uint ideal_reg() const { return Op_RegD; } 375 }; 376 377 //------------------------------DivVFNode-------------------------------------- 378 // Vector divide float 379 class DivVFNode : public VectorNode { 380 public: 381 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 382 virtual int Opcode() const; 383 }; 384 385 //------------------------------DivVDNode-------------------------------------- 386 // Vector Divide double 387 class DivVDNode : public VectorNode { 388 public: 389 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 390 virtual int Opcode() const; 391 }; 392 393 //------------------------------MinVNode-------------------------------------- 394 // Vector Min 395 class MinVNode : public VectorNode { 396 public: 397 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 398 virtual int Opcode() const; 399 }; 400 401 //------------------------------MaxVNode-------------------------------------- 402 // Vector Max 403 class MaxVNode : public VectorNode { 404 public: 405 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 406 virtual int Opcode() const; 407 }; 408 409 //------------------------------AbsVNode-------------------------------------- 410 // Vector Abs 411 class AbsVNode : public VectorNode { 412 public: 413 AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 414 virtual int Opcode() const; 415 }; 416 417 //------------------------------AbsVFNode-------------------------------------- 418 // Vector Abs float 419 class AbsVFNode : public VectorNode { 420 public: 421 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 422 virtual int Opcode() const; 423 }; 424 425 //------------------------------AbsVDNode-------------------------------------- 426 // Vector Abs double 427 class AbsVDNode : public VectorNode { 428 public: 429 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 430 virtual int Opcode() const; 431 }; 432 433 //------------------------------NegVINode-------------------------------------- 434 // Vector Neg int 435 class NegVINode : public VectorNode { 436 public: 437 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 438 virtual int Opcode() const; 439 }; 440 441 //------------------------------NegVFNode-------------------------------------- 442 // Vector Neg float 443 class NegVFNode : public VectorNode { 444 public: 445 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 446 virtual int Opcode() const; 447 }; 448 449 //------------------------------NegVDNode-------------------------------------- 450 // Vector Neg double 451 class NegVDNode : public VectorNode { 452 public: 453 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 454 virtual int Opcode() const; 455 }; 456 457 //------------------------------PopCountVINode--------------------------------- 458 // Vector popcount integer bits 459 class PopCountVINode : public VectorNode { 460 public: 461 PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 462 virtual int Opcode() const; 463 }; 464 465 //------------------------------SqrtVFNode-------------------------------------- 466 // Vector Sqrt float 467 class SqrtVFNode : public VectorNode { 468 public: 469 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 470 virtual int Opcode() const; 471 }; 472 473 //------------------------------SqrtVDNode-------------------------------------- 474 // Vector Sqrt double 475 class SqrtVDNode : public VectorNode { 476 public: 477 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 478 virtual int Opcode() const; 479 }; 480 481 //------------------------------NotVNode-------------------------------------- 482 // Vector Not 483 class NotVNode : public VectorNode { 484 public: 485 NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 486 virtual int Opcode() const; 487 }; 488 489 //------------------------------LShiftVBNode----------------------------------- 490 // Vector left shift bytes 491 class LShiftVBNode : public VectorNode { 492 public: 493 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 494 virtual int Opcode() const; 495 }; 496 497 //------------------------------LShiftVSNode----------------------------------- 498 // Vector left shift shorts 499 class LShiftVSNode : public VectorNode { 500 public: 501 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 502 virtual int Opcode() const; 503 }; 504 505 //------------------------------LShiftVINode----------------------------------- 506 // Vector left shift ints 507 class LShiftVINode : public VectorNode { 508 public: 509 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 510 virtual int Opcode() const; 511 }; 512 513 //------------------------------LShiftVLNode----------------------------------- 514 // Vector left shift longs 515 class LShiftVLNode : public VectorNode { 516 public: 517 LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 518 virtual int Opcode() const; 519 }; 520 521 //------------------------------RShiftVBNode----------------------------------- 522 // Vector right arithmetic (signed) shift bytes 523 class RShiftVBNode : public VectorNode { 524 public: 525 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 526 virtual int Opcode() const; 527 }; 528 529 //------------------------------RShiftVSNode----------------------------------- 530 // Vector right arithmetic (signed) shift shorts 531 class RShiftVSNode : public VectorNode { 532 public: 533 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 534 virtual int Opcode() const; 535 }; 536 537 //------------------------------RShiftVINode----------------------------------- 538 // Vector right arithmetic (signed) shift ints 539 class RShiftVINode : public VectorNode { 540 public: 541 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 542 virtual int Opcode() const; 543 }; 544 545 //------------------------------RShiftVLNode----------------------------------- 546 // Vector right arithmetic (signed) shift longs 547 class RShiftVLNode : public VectorNode { 548 public: 549 RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 550 virtual int Opcode() const; 551 }; 552 553 //------------------------------URShiftVBNode---------------------------------- 554 // Vector right logical (unsigned) shift bytes 555 class URShiftVBNode : public VectorNode { 556 public: 557 URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 558 virtual int Opcode() const; 559 }; 560 561 //------------------------------URShiftVSNode---------------------------------- 562 // Vector right logical (unsigned) shift shorts 563 class URShiftVSNode : public VectorNode { 564 public: 565 URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 566 virtual int Opcode() const; 567 }; 568 569 //------------------------------URShiftVINode---------------------------------- 570 // Vector right logical (unsigned) shift ints 571 class URShiftVINode : public VectorNode { 572 public: 573 URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 574 virtual int Opcode() const; 575 }; 576 577 //------------------------------URShiftVLNode---------------------------------- 578 // Vector right logical (unsigned) shift longs 579 class URShiftVLNode : public VectorNode { 580 public: 581 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 582 virtual int Opcode() const; 583 }; 584 585 //------------------------------LShiftCntVNode--------------------------------- 586 // Vector left shift count 587 class LShiftCntVNode : public VectorNode { 588 public: 589 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 590 virtual int Opcode() const; 591 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 592 }; 593 594 //------------------------------RShiftCntVNode--------------------------------- 595 // Vector right shift count 596 class RShiftCntVNode : public VectorNode { 597 public: 598 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 599 virtual int Opcode() const; 600 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 601 }; 602 603 604 //------------------------------AndVNode--------------------------------------- 605 // Vector and integer 606 class AndVNode : public VectorNode { 607 public: 608 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 609 virtual int Opcode() const; 610 }; 611 612 //------------------------------AndReductionVNode-------------------------------------- 613 // Vector and byte, short, int, long as a reduction 614 class AndReductionVNode : public ReductionNode { 615 public: 616 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 617 if (in1->bottom_type()->basic_type() == T_INT) { 618 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 619 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 620 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 621 } 622 else if (in1->bottom_type()->basic_type() == T_LONG) { 623 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 624 } 625 } 626 virtual int Opcode() const; 627 virtual const Type* bottom_type() const { 628 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 629 return TypeInt::INT; 630 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 631 return TypeInt::BYTE; 632 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 633 return TypeInt::SHORT; 634 else 635 return TypeLong::LONG; 636 } 637 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 638 }; 639 640 //------------------------------OrVNode--------------------------------------- 641 // Vector or integer 642 class OrVNode : public VectorNode { 643 public: 644 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 645 virtual int Opcode() const; 646 }; 647 648 //------------------------------OrReductionVNode-------------------------------------- 649 // Vector and int, long as a reduction 650 class OrReductionVNode : public ReductionNode { 651 public: 652 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 653 assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 654 assert(in1->bottom_type()->basic_type() == T_INT || 655 in1->bottom_type()->basic_type() == T_LONG, ""); 656 } 657 virtual int Opcode() const; 658 virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 659 return TypeInt::INT; else return TypeLong::LONG; } 660 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 661 }; 662 663 //------------------------------XorReductionVNode-------------------------------------- 664 // Vector and int, long as a reduction 665 class XorReductionVNode : public ReductionNode { 666 public: 667 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 668 assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 669 assert(in1->bottom_type()->basic_type() == T_INT || 670 in1->bottom_type()->basic_type() == T_LONG, ""); 671 } 672 virtual int Opcode() const; 673 virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 674 return TypeInt::INT; else return TypeLong::LONG; } 675 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 676 }; 677 678 //------------------------------XorVNode--------------------------------------- 679 // Vector xor integer 680 class XorVNode : public VectorNode { 681 public: 682 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 683 virtual int Opcode() const; 684 }; 685 686 //================================= M E M O R Y =============================== 687 688 //------------------------------LoadVectorNode--------------------------------- 689 // Load Vector from memory 690 class LoadVectorNode : public LoadNode { 691 public: 692 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest) 693 : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) { 694 init_class_id(Class_LoadVector); 695 } 696 697 const TypeVect* vect_type() const { return type()->is_vect(); } 698 uint length() const { return vect_type()->length(); } // Vector length 699 700 virtual int Opcode() const; 701 702 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 703 virtual BasicType memory_type() const { return T_VOID; } 704 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 705 706 virtual int store_Opcode() const { return Op_StoreVector; } 707 708 static LoadVectorNode* make(int opc, Node* ctl, Node* mem, 709 Node* adr, const TypePtr* atyp, 710 uint vlen, BasicType bt, 711 ControlDependency control_dependency = LoadNode::DependsOnlyOnTest); 712 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 713 }; 714 715 //------------------------------StoreVectorNode-------------------------------- 716 // Store Vector to memory 717 class StoreVectorNode : public StoreNode { 718 public: 719 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val) 720 : StoreNode(c, mem, adr, at, val, MemNode::unordered) { 721 init_class_id(Class_StoreVector); 722 } 723 724 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); } 725 uint length() const { return vect_type()->length(); } // Vector length 726 727 virtual int Opcode() const; 728 729 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 730 virtual BasicType memory_type() const { return T_VOID; } 731 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 732 733 static StoreVectorNode* make(int opc, Node* ctl, Node* mem, 734 Node* adr, const TypePtr* atyp, Node* val, 735 uint vlen); 736 737 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 738 }; 739 740 741 //=========================Promote_Scalar_to_Vector============================ 742 743 //------------------------------ReplicateBNode--------------------------------- 744 // Replicate byte scalar to be vector 745 class ReplicateBNode : public VectorNode { 746 public: 747 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 748 virtual int Opcode() const; 749 }; 750 751 //------------------------------ReplicateSNode--------------------------------- 752 // Replicate short scalar to be vector 753 class ReplicateSNode : public VectorNode { 754 public: 755 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 756 virtual int Opcode() const; 757 }; 758 759 //------------------------------ReplicateINode--------------------------------- 760 // Replicate int scalar to be vector 761 class ReplicateINode : public VectorNode { 762 public: 763 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 764 virtual int Opcode() const; 765 }; 766 767 //------------------------------ReplicateLNode--------------------------------- 768 // Replicate long scalar to be vector 769 class ReplicateLNode : public VectorNode { 770 public: 771 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 772 virtual int Opcode() const; 773 }; 774 775 //------------------------------ReplicateFNode--------------------------------- 776 // Replicate float scalar to be vector 777 class ReplicateFNode : public VectorNode { 778 public: 779 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 780 virtual int Opcode() const; 781 }; 782 783 //------------------------------ReplicateDNode--------------------------------- 784 // Replicate double scalar to be vector 785 class ReplicateDNode : public VectorNode { 786 public: 787 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 788 virtual int Opcode() const; 789 }; 790 791 //========================Pack_Scalars_into_a_Vector=========================== 792 793 //------------------------------PackNode--------------------------------------- 794 // Pack parent class (not for code generation). 795 class PackNode : public VectorNode { 796 public: 797 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 798 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {} 799 virtual int Opcode() const; 800 801 void add_opd(Node* n) { 802 add_req(n); 803 } 804 805 // Create a binary tree form for Packs. [lo, hi) (half-open) range 806 PackNode* binary_tree_pack(int lo, int hi); 807 808 static PackNode* make(Node* s, uint vlen, BasicType bt); 809 }; 810 811 //------------------------------PackBNode-------------------------------------- 812 // Pack byte scalars into vector 813 class PackBNode : public PackNode { 814 public: 815 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 816 virtual int Opcode() const; 817 }; 818 819 //------------------------------PackSNode-------------------------------------- 820 // Pack short scalars into a vector 821 class PackSNode : public PackNode { 822 public: 823 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 824 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 825 virtual int Opcode() const; 826 }; 827 828 //------------------------------PackINode-------------------------------------- 829 // Pack integer scalars into a vector 830 class PackINode : public PackNode { 831 public: 832 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 833 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 834 virtual int Opcode() const; 835 }; 836 837 //------------------------------PackLNode-------------------------------------- 838 // Pack long scalars into a vector 839 class PackLNode : public PackNode { 840 public: 841 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 842 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 843 virtual int Opcode() const; 844 }; 845 846 //------------------------------Pack2LNode------------------------------------- 847 // Pack 2 long scalars into a vector 848 class Pack2LNode : public PackNode { 849 public: 850 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 851 virtual int Opcode() const; 852 }; 853 854 //------------------------------PackFNode-------------------------------------- 855 // Pack float scalars into vector 856 class PackFNode : public PackNode { 857 public: 858 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 859 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 860 virtual int Opcode() const; 861 }; 862 863 //------------------------------PackDNode-------------------------------------- 864 // Pack double scalars into a vector 865 class PackDNode : public PackNode { 866 public: 867 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 868 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 869 virtual int Opcode() const; 870 }; 871 872 //------------------------------Pack2DNode------------------------------------- 873 // Pack 2 double scalars into a vector 874 class Pack2DNode : public PackNode { 875 public: 876 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 877 virtual int Opcode() const; 878 }; 879 880 881 //========================Extract_Scalar_from_Vector=========================== 882 883 //------------------------------ExtractNode------------------------------------ 884 // Extract a scalar from a vector at position "pos" 885 class ExtractNode : public Node { 886 public: 887 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { 888 assert(in(2)->get_int() >= 0, "positive constants"); 889 } 890 virtual int Opcode() const; 891 uint pos() const { return in(2)->get_int(); } 892 893 static Node* make(Node* v, uint position, BasicType bt); 894 }; 895 896 //------------------------------ExtractBNode----------------------------------- 897 // Extract a byte from a vector at position "pos" 898 class ExtractBNode : public ExtractNode { 899 public: 900 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 901 virtual int Opcode() const; 902 virtual const Type *bottom_type() const { return TypeInt::INT; } 903 virtual uint ideal_reg() const { return Op_RegI; } 904 }; 905 906 //------------------------------ExtractUBNode---------------------------------- 907 // Extract a boolean from a vector at position "pos" 908 class ExtractUBNode : public ExtractNode { 909 public: 910 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 911 virtual int Opcode() const; 912 virtual const Type *bottom_type() const { return TypeInt::INT; } 913 virtual uint ideal_reg() const { return Op_RegI; } 914 }; 915 916 //------------------------------ExtractCNode----------------------------------- 917 // Extract a char from a vector at position "pos" 918 class ExtractCNode : public ExtractNode { 919 public: 920 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 921 virtual int Opcode() const; 922 virtual const Type *bottom_type() const { return TypeInt::INT; } 923 virtual uint ideal_reg() const { return Op_RegI; } 924 }; 925 926 //------------------------------ExtractSNode----------------------------------- 927 // Extract a short from a vector at position "pos" 928 class ExtractSNode : public ExtractNode { 929 public: 930 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 931 virtual int Opcode() const; 932 virtual const Type *bottom_type() const { return TypeInt::INT; } 933 virtual uint ideal_reg() const { return Op_RegI; } 934 }; 935 936 //------------------------------ExtractINode----------------------------------- 937 // Extract an int from a vector at position "pos" 938 class ExtractINode : public ExtractNode { 939 public: 940 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 941 virtual int Opcode() const; 942 virtual const Type *bottom_type() const { return TypeInt::INT; } 943 virtual uint ideal_reg() const { return Op_RegI; } 944 }; 945 946 //------------------------------ExtractLNode----------------------------------- 947 // Extract a long from a vector at position "pos" 948 class ExtractLNode : public ExtractNode { 949 public: 950 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 951 virtual int Opcode() const; 952 virtual const Type *bottom_type() const { return TypeLong::LONG; } 953 virtual uint ideal_reg() const { return Op_RegL; } 954 }; 955 956 //------------------------------ExtractFNode----------------------------------- 957 // Extract a float from a vector at position "pos" 958 class ExtractFNode : public ExtractNode { 959 public: 960 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 961 virtual int Opcode() const; 962 virtual const Type *bottom_type() const { return Type::FLOAT; } 963 virtual uint ideal_reg() const { return Op_RegF; } 964 }; 965 966 //------------------------------ExtractDNode----------------------------------- 967 // Extract a double from a vector at position "pos" 968 class ExtractDNode : public ExtractNode { 969 public: 970 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 971 virtual int Opcode() const; 972 virtual const Type *bottom_type() const { return Type::DOUBLE; } 973 virtual uint ideal_reg() const { return Op_RegD; } 974 }; 975 976 //------------------------------SetVectMaskINode------------------------------- 977 // Provide a mask for a vector predicate machine 978 class SetVectMaskINode : public Node { 979 public: 980 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {} 981 virtual int Opcode() const; 982 const Type *bottom_type() const { return TypeInt::INT; } 983 virtual uint ideal_reg() const { return Op_RegI; } 984 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } 985 }; 986 987 // Type conversion nodes 988 class ConvertVF2VDNode : public VectorNode { 989 public: 990 ConvertVF2VDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 991 virtual int Opcode() const; 992 }; 993 994 class VectorBoxNode : public Node { 995 private: 996 const TypeInstPtr* const _box_type; 997 const TypeVect* const _vec_type; 998 public: 999 enum { 1000 Box = 1, 1001 Value = 2 1002 }; 1003 VectorBoxNode(Compile* C, Node* box, Node* val, 1004 const TypeInstPtr* box_type, const TypeVect* vt) 1005 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) { 1006 init_flags(Flag_is_macro); 1007 C->add_macro_node(this); 1008 } 1009 1010 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; }; 1011 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; }; 1012 1013 virtual int Opcode() const; 1014 virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ } 1015 virtual uint ideal_reg() const { return box_type()->ideal_reg(); } 1016 virtual uint size_of() const { return sizeof(*this); } 1017 1018 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); 1019 }; 1020 1021 class VectorBoxAllocateNode : public CallStaticJavaNode { 1022 public: 1023 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) 1024 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) { 1025 init_flags(Flag_is_macro); 1026 C->add_macro_node(this); 1027 } 1028 1029 virtual int Opcode() const; 1030 #ifndef PRODUCT 1031 virtual void dump_spec(outputStream *st) const; 1032 #endif // PRODUCT 1033 }; 1034 1035 class VectorUnboxNode : public VectorNode { 1036 public: 1037 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem) 1038 : VectorNode(mem, obj, vec_type) { 1039 init_flags(Flag_is_macro); 1040 C->add_macro_node(this); 1041 } 1042 1043 virtual int Opcode() const; 1044 Node* obj() const { return in(2); } 1045 Node* mem() const { return in(1); } 1046 virtual Node *Identity(PhaseGVN *phase); 1047 }; 1048 1049 class VectorMaskCmpNode : public VectorNode { 1050 private: 1051 BoolTest::mask _predicate; 1052 1053 protected: 1054 uint size_of() const { return sizeof(*this); } 1055 1056 public: 1057 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, const TypeVect* vt) : 1058 VectorNode(in1, in2, vt), _predicate(predicate) { 1059 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1060 "VectorMaskCmp inputs must have same type for elements"); 1061 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1062 "VectorMaskCmp inputs must have same number of elements"); 1063 init_class_id(Class_VectorMaskCmp); 1064 } 1065 1066 virtual int Opcode() const; 1067 virtual uint hash() const { return VectorNode::hash() + _predicate; } 1068 virtual uint cmp( const Node &n ) const { 1069 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; 1070 } 1071 BoolTest::mask get_predicate() { return _predicate; } 1072 #ifndef PRODUCT 1073 virtual void dump_spec(outputStream *st) const; 1074 #endif // PRODUCT 1075 }; 1076 1077 // Used to wrap other vector nodes in order to add masking functionality. 1078 class VectorMaskWrapperNode : public VectorNode { 1079 public: 1080 VectorMaskWrapperNode(Node* vector, Node* mask) 1081 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { 1082 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); 1083 } 1084 1085 virtual int Opcode() const; 1086 Node* vector_val() const { return in(1); } 1087 Node* vector_mask() const { return in(2); } 1088 }; 1089 1090 class VectorTestNode : public Node { 1091 private: 1092 Assembler::Condition _predicate; 1093 1094 protected: 1095 uint size_of() const { return sizeof(*this); } 1096 1097 public: 1098 VectorTestNode( Node *in1, Node *in2, Assembler::Condition predicate) : Node(NULL, in1, in2), _predicate(predicate) { 1099 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector"); 1100 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector"); 1101 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1102 "same type elements are needed"); 1103 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1104 "same number of elements is needed"); 1105 } 1106 virtual int Opcode() const; 1107 virtual uint hash() const { return Node::hash() + _predicate; } 1108 virtual uint cmp( const Node &n ) const { 1109 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; 1110 } 1111 virtual const Type *bottom_type() const { return TypeInt::BOOL; } 1112 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest 1113 // in middle-end, we make it boolean result directly. 1114 Assembler::Condition get_predicate() const { return _predicate; } 1115 }; 1116 1117 class VectorBlendNode : public VectorNode { 1118 public: 1119 VectorBlendNode(Node* vec1, Node* vec2, Node* mask) 1120 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { 1121 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1122 } 1123 1124 virtual int Opcode() const; 1125 Node* vec1() const { return in(1); } 1126 Node* vec2() const { return in(2); } 1127 Node* vec_mask() const { return in(3); } 1128 }; 1129 1130 class VectorLoadMaskNode : public VectorNode { 1131 public: 1132 VectorLoadMaskNode(Node* in, const TypeVect* vt) 1133 : VectorNode(in, vt) { 1134 assert(in->is_LoadVector(), "expected load vector"); 1135 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean"); 1136 } 1137 1138 int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1139 virtual int Opcode() const; 1140 }; 1141 1142 class VectorStoreMaskNode : public VectorNode { 1143 private: 1144 int _mask_size; 1145 protected: 1146 uint size_of() const { return sizeof(*this); } 1147 1148 public: 1149 VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem) 1150 : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) { 1151 _mask_size = type2aelembytes(in_type); 1152 } 1153 1154 virtual uint hash() const { return VectorNode::hash() + _mask_size; } 1155 virtual uint cmp( const Node &n ) const { 1156 return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size; 1157 } 1158 int GetInputMaskSize() const { return _mask_size; } 1159 virtual int Opcode() const; 1160 }; 1161 1162 // This is intended for use as a simple reinterpret node that has no cast. 1163 class VectorReinterpretNode : public VectorNode { 1164 private: 1165 const TypeVect* _src_vt; 1166 protected: 1167 uint size_of() const { return sizeof(*this); } 1168 public: 1169 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) 1170 : VectorNode(in, dst_vt), _src_vt(src_vt) { } 1171 1172 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } 1173 virtual uint cmp( const Node &n ) const { 1174 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); 1175 } 1176 1177 virtual int Opcode() const; 1178 }; 1179 1180 #endif // SHARE_VM_OPTO_VECTORNODE_HPP