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 sub 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 258 //------------------------------SubReductionVFPNode-------------------------------------- 259 // Vector sub float, double as a reduction 260 class SubReductionVFPNode : public ReductionNode { 261 public: 262 SubReductionVFPNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 263 assert(in1->bottom_type()->basic_type() == T_FLOAT || 264 in1->bottom_type()->basic_type() == T_DOUBLE, ""); 265 } 266 267 virtual int Opcode() const; 268 virtual const Type* bottom_type() const { 269 if (in(1)->bottom_type()->basic_type() == T_FLOAT) { 270 return Type::FLOAT; 271 } else { 272 return Type::DOUBLE; 273 } 274 } 275 276 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_FLOAT ? Op_RegF : Op_RegD; } 277 }; 278 279 //------------------------------MulVBNode-------------------------------------- 280 // Vector multiply byte 281 class MulVBNode : public VectorNode { 282 public: 283 MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 284 virtual int Opcode() const; 285 }; 286 287 //------------------------------MulVSNode-------------------------------------- 288 // Vector multiply short 289 class MulVSNode : public VectorNode { 290 public: 291 MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 292 virtual int Opcode() const; 293 }; 294 295 //------------------------------MulVINode-------------------------------------- 296 // Vector multiply int 297 class MulVINode : public VectorNode { 298 public: 299 MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 300 virtual int Opcode() const; 301 }; 302 303 //------------------------------MulVLNode-------------------------------------- 304 // Vector multiply long 305 class MulVLNode : public VectorNode { 306 public: 307 MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 308 virtual int Opcode() const; 309 }; 310 311 //------------------------------MulVFNode-------------------------------------- 312 // Vector multiply float 313 class MulVFNode : public VectorNode { 314 public: 315 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 316 virtual int Opcode() const; 317 }; 318 319 //------------------------------MulVDNode-------------------------------------- 320 // Vector multiply double 321 class MulVDNode : public VectorNode { 322 public: 323 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 324 virtual int Opcode() const; 325 }; 326 327 //------------------------------FmaVDNode-------------------------------------- 328 // Vector multiply double 329 class FmaVDNode : public VectorNode { 330 public: 331 FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 332 virtual int Opcode() const; 333 }; 334 335 //------------------------------FmaVFNode-------------------------------------- 336 // Vector multiply float 337 class FmaVFNode : public VectorNode { 338 public: 339 FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 340 virtual int Opcode() const; 341 }; 342 343 //------------------------------CMoveVFNode-------------------------------------- 344 // Vector float conditional move 345 class CMoveVFNode : public VectorNode { 346 public: 347 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 348 virtual int Opcode() const; 349 }; 350 351 //------------------------------CMoveVDNode-------------------------------------- 352 // Vector double conditional move 353 class CMoveVDNode : public VectorNode { 354 public: 355 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 356 virtual int Opcode() const; 357 }; 358 359 //------------------------------MulReductionVINode-------------------------------------- 360 // Vector multiply byte, short and int as a reduction 361 class MulReductionVINode : public ReductionNode { 362 public: 363 MulReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 364 if (in1->bottom_type()->basic_type() == T_INT) { 365 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 366 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 367 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 368 } 369 } 370 virtual int Opcode() const; 371 virtual const Type* bottom_type() const { 372 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 373 return TypeInt::INT; 374 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 375 return TypeInt::BYTE; 376 else 377 return TypeInt::SHORT; 378 } 379 virtual uint ideal_reg() const { return Op_RegI; } 380 }; 381 382 //------------------------------MulReductionVLNode-------------------------------------- 383 // Vector multiply int as a reduction 384 class MulReductionVLNode : public ReductionNode { 385 public: 386 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 387 virtual int Opcode() const; 388 virtual const Type* bottom_type() const { return TypeLong::LONG; } 389 virtual uint ideal_reg() const { return Op_RegL; } 390 }; 391 392 //------------------------------MulReductionVFNode-------------------------------------- 393 // Vector multiply float as a reduction 394 class MulReductionVFNode : public ReductionNode { 395 public: 396 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 397 virtual int Opcode() const; 398 virtual const Type* bottom_type() const { return Type::FLOAT; } 399 virtual uint ideal_reg() const { return Op_RegF; } 400 }; 401 402 //------------------------------MulReductionVDNode-------------------------------------- 403 // Vector multiply double as a reduction 404 class MulReductionVDNode : public ReductionNode { 405 public: 406 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 407 virtual int Opcode() const; 408 virtual const Type* bottom_type() const { return Type::DOUBLE; } 409 virtual uint ideal_reg() const { return Op_RegD; } 410 }; 411 412 //------------------------------DivVFNode-------------------------------------- 413 // Vector divide float 414 class DivVFNode : public VectorNode { 415 public: 416 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 417 virtual int Opcode() const; 418 }; 419 420 //------------------------------DivVDNode-------------------------------------- 421 // Vector Divide double 422 class DivVDNode : public VectorNode { 423 public: 424 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 425 virtual int Opcode() const; 426 }; 427 428 //------------------------------MinVNode-------------------------------------- 429 // Vector Min 430 class MinVNode : public VectorNode { 431 public: 432 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 433 virtual int Opcode() const; 434 }; 435 436 //------------------------------MaxVNode-------------------------------------- 437 // Vector Max 438 class MaxVNode : public VectorNode { 439 public: 440 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 441 virtual int Opcode() const; 442 }; 443 444 //------------------------------AbsVNode-------------------------------------- 445 // Vector Abs 446 class AbsVNode : public VectorNode { 447 public: 448 AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 449 virtual int Opcode() const; 450 }; 451 452 //------------------------------AbsVFNode-------------------------------------- 453 // Vector Abs float 454 class AbsVFNode : public VectorNode { 455 public: 456 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 457 virtual int Opcode() const; 458 }; 459 460 //------------------------------AbsVDNode-------------------------------------- 461 // Vector Abs double 462 class AbsVDNode : public VectorNode { 463 public: 464 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 465 virtual int Opcode() const; 466 }; 467 468 //------------------------------NegVINode-------------------------------------- 469 // Vector Neg int 470 class NegVINode : public VectorNode { 471 public: 472 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 473 virtual int Opcode() const; 474 }; 475 476 //------------------------------NegVFNode-------------------------------------- 477 // Vector Neg float 478 class NegVFNode : public VectorNode { 479 public: 480 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 481 virtual int Opcode() const; 482 }; 483 484 //------------------------------NegVDNode-------------------------------------- 485 // Vector Neg double 486 class NegVDNode : public VectorNode { 487 public: 488 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 489 virtual int Opcode() const; 490 }; 491 492 //------------------------------PopCountVINode--------------------------------- 493 // Vector popcount integer bits 494 class PopCountVINode : public VectorNode { 495 public: 496 PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 497 virtual int Opcode() const; 498 }; 499 500 //------------------------------SqrtVFNode-------------------------------------- 501 // Vector Sqrt float 502 class SqrtVFNode : public VectorNode { 503 public: 504 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 505 virtual int Opcode() const; 506 }; 507 508 //------------------------------SqrtVDNode-------------------------------------- 509 // Vector Sqrt double 510 class SqrtVDNode : public VectorNode { 511 public: 512 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 513 virtual int Opcode() const; 514 }; 515 516 //------------------------------NotVNode-------------------------------------- 517 // Vector Not 518 class NotVNode : public VectorNode { 519 public: 520 NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 521 virtual int Opcode() const; 522 }; 523 524 //------------------------------LShiftVBNode----------------------------------- 525 // Vector left shift bytes 526 class LShiftVBNode : public VectorNode { 527 public: 528 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 529 virtual int Opcode() const; 530 }; 531 532 //------------------------------LShiftVSNode----------------------------------- 533 // Vector left shift shorts 534 class LShiftVSNode : public VectorNode { 535 public: 536 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 537 virtual int Opcode() const; 538 }; 539 540 //------------------------------LShiftVINode----------------------------------- 541 // Vector left shift ints 542 class LShiftVINode : public VectorNode { 543 public: 544 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 545 virtual int Opcode() const; 546 }; 547 548 //------------------------------LShiftVLNode----------------------------------- 549 // Vector left shift longs 550 class LShiftVLNode : public VectorNode { 551 public: 552 LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 553 virtual int Opcode() const; 554 }; 555 556 //------------------------------RShiftVBNode----------------------------------- 557 // Vector right arithmetic (signed) shift bytes 558 class RShiftVBNode : public VectorNode { 559 public: 560 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 561 virtual int Opcode() const; 562 }; 563 564 //------------------------------RShiftVSNode----------------------------------- 565 // Vector right arithmetic (signed) shift shorts 566 class RShiftVSNode : public VectorNode { 567 public: 568 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 569 virtual int Opcode() const; 570 }; 571 572 //------------------------------RShiftVINode----------------------------------- 573 // Vector right arithmetic (signed) shift ints 574 class RShiftVINode : public VectorNode { 575 public: 576 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 577 virtual int Opcode() const; 578 }; 579 580 //------------------------------RShiftVLNode----------------------------------- 581 // Vector right arithmetic (signed) shift longs 582 class RShiftVLNode : public VectorNode { 583 public: 584 RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 585 virtual int Opcode() const; 586 }; 587 588 //------------------------------URShiftVBNode---------------------------------- 589 // Vector right logical (unsigned) shift bytes 590 class URShiftVBNode : public VectorNode { 591 public: 592 URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 593 virtual int Opcode() const; 594 }; 595 596 //------------------------------URShiftVSNode---------------------------------- 597 // Vector right logical (unsigned) shift shorts 598 class URShiftVSNode : public VectorNode { 599 public: 600 URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 601 virtual int Opcode() const; 602 }; 603 604 //------------------------------URShiftVINode---------------------------------- 605 // Vector right logical (unsigned) shift ints 606 class URShiftVINode : public VectorNode { 607 public: 608 URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 609 virtual int Opcode() const; 610 }; 611 612 //------------------------------URShiftVLNode---------------------------------- 613 // Vector right logical (unsigned) shift longs 614 class URShiftVLNode : public VectorNode { 615 public: 616 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 617 virtual int Opcode() const; 618 }; 619 620 //------------------------------LShiftCntVNode--------------------------------- 621 // Vector left shift count 622 class LShiftCntVNode : public VectorNode { 623 public: 624 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 625 virtual int Opcode() const; 626 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 627 }; 628 629 //------------------------------RShiftCntVNode--------------------------------- 630 // Vector right shift count 631 class RShiftCntVNode : public VectorNode { 632 public: 633 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 634 virtual int Opcode() const; 635 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 636 }; 637 638 639 //------------------------------AndVNode--------------------------------------- 640 // Vector and integer 641 class AndVNode : public VectorNode { 642 public: 643 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 644 virtual int Opcode() const; 645 }; 646 647 //------------------------------AndReductionVNode-------------------------------------- 648 // Vector and byte, short, int, long as a reduction 649 class AndReductionVNode : public ReductionNode { 650 public: 651 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 652 if (in1->bottom_type()->basic_type() == T_INT) { 653 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 654 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 655 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 656 } 657 else if (in1->bottom_type()->basic_type() == T_LONG) { 658 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 659 } 660 } 661 virtual int Opcode() const; 662 virtual const Type* bottom_type() const { 663 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 664 return TypeInt::INT; 665 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 666 return TypeInt::BYTE; 667 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 668 return TypeInt::SHORT; 669 else 670 return TypeLong::LONG; 671 } 672 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 673 }; 674 675 //------------------------------OrVNode--------------------------------------- 676 // Vector or integer 677 class OrVNode : public VectorNode { 678 public: 679 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 680 virtual int Opcode() const; 681 }; 682 683 //------------------------------OrReductionVNode-------------------------------------- 684 // Vector or short, byte, int, long as a reduction 685 class OrReductionVNode : public ReductionNode { 686 public: 687 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 688 assert(in1->bottom_type()->basic_type() == T_INT || 689 in1->bottom_type()->basic_type() == T_LONG || 690 in1->bottom_type()->basic_type() == T_SHORT || 691 in1->bottom_type()->basic_type() == T_BYTE, ""); 692 } 693 virtual int Opcode() const; 694 virtual const Type* bottom_type() const { 695 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 696 return TypeInt::INT; 697 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 698 return TypeInt::BYTE; 699 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 700 return TypeInt::SHORT; 701 else 702 return TypeLong::LONG; 703 } 704 705 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 706 }; 707 708 //------------------------------XorReductionVNode-------------------------------------- 709 // Vector and int, long as a reduction 710 class XorReductionVNode : public ReductionNode { 711 public: 712 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 713 assert(in1->bottom_type()->basic_type() == T_INT || 714 in1->bottom_type()->basic_type() == T_LONG || 715 in1->bottom_type()->basic_type() == T_SHORT || 716 in1->bottom_type()->basic_type() == T_BYTE, ""); 717 } 718 virtual int Opcode() const; 719 virtual const Type* bottom_type() const { 720 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 721 return TypeInt::INT; 722 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 723 return TypeInt::BYTE; 724 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 725 return TypeInt::SHORT; 726 else 727 return TypeLong::LONG; 728 } 729 730 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 731 }; 732 733 //------------------------------XorVNode--------------------------------------- 734 // Vector xor integer 735 class XorVNode : public VectorNode { 736 public: 737 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 738 virtual int Opcode() const; 739 }; 740 741 //------------------------------MinReductionVNode-------------------------------------- 742 // Vector min byte, short, int, long, float, double as a reduction 743 class MinReductionVNode : public ReductionNode { 744 public: 745 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 746 if (in1->bottom_type()->basic_type() == T_INT) { 747 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 748 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 749 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 750 } 751 else if (in1->bottom_type()->basic_type() == T_LONG) { 752 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 753 } 754 else if (in1->bottom_type()->basic_type() == T_FLOAT) { 755 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, ""); 756 } 757 else if (in1->bottom_type()->basic_type() == T_DOUBLE) { 758 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, ""); 759 } 760 } 761 virtual int Opcode() const; 762 virtual const Type* bottom_type() const { 763 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 764 return TypeInt::INT; 765 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 766 return TypeInt::BYTE; 767 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 768 return TypeInt::SHORT; 769 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT) 770 return Type::FLOAT; 771 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE) 772 return Type::DOUBLE; 773 else return TypeLong::LONG; 774 } 775 virtual uint ideal_reg() const { 776 if (in(1)->bottom_type()->basic_type() == T_INT) 777 return Op_RegI; 778 else if (in(1)->bottom_type()->basic_type() == T_FLOAT) 779 return Op_RegF; 780 else if (in(1)->bottom_type()->basic_type() == T_DOUBLE) 781 return Op_RegD; 782 else return Op_RegL; 783 } 784 }; 785 786 //------------------------------MaxReductionVNode-------------------------------------- 787 // Vector min byte, short, int, long, float, double as a reduction 788 class MaxReductionVNode : public ReductionNode { 789 public: 790 MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 791 if (in1->bottom_type()->basic_type() == T_INT) { 792 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 793 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 794 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 795 } 796 else if (in1->bottom_type()->basic_type() == T_LONG) { 797 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 798 } 799 else if (in1->bottom_type()->basic_type() == T_FLOAT) { 800 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, ""); 801 } 802 else if (in1->bottom_type()->basic_type() == T_DOUBLE) { 803 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, ""); 804 } 805 } 806 virtual int Opcode() const; 807 virtual const Type* bottom_type() const { 808 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 809 return TypeInt::INT; 810 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 811 return TypeInt::BYTE; 812 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 813 return TypeInt::SHORT; 814 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT) 815 return Type::FLOAT; 816 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE) 817 return Type::DOUBLE; 818 else return TypeLong::LONG; 819 } 820 virtual uint ideal_reg() const { 821 if (in(1)->bottom_type()->basic_type() == T_INT) 822 return Op_RegI; 823 else if (in(1)->bottom_type()->basic_type() == T_FLOAT) 824 return Op_RegF; 825 else if (in(1)->bottom_type()->basic_type() == T_DOUBLE) 826 return Op_RegD; 827 else return Op_RegL; 828 } 829 }; 830 831 //================================= M E M O R Y =============================== 832 833 //------------------------------LoadVectorNode--------------------------------- 834 // Load Vector from memory 835 class LoadVectorNode : public LoadNode { 836 public: 837 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest) 838 : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) { 839 init_class_id(Class_LoadVector); 840 } 841 842 const TypeVect* vect_type() const { return type()->is_vect(); } 843 uint length() const { return vect_type()->length(); } // Vector length 844 845 virtual int Opcode() const; 846 847 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 848 virtual BasicType memory_type() const { return T_VOID; } 849 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 850 851 virtual int store_Opcode() const { return Op_StoreVector; } 852 853 static LoadVectorNode* make(int opc, Node* ctl, Node* mem, 854 Node* adr, const TypePtr* atyp, 855 uint vlen, BasicType bt, 856 ControlDependency control_dependency = LoadNode::DependsOnlyOnTest); 857 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 858 }; 859 860 //------------------------------StoreVectorNode-------------------------------- 861 // Store Vector to memory 862 class StoreVectorNode : public StoreNode { 863 public: 864 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val) 865 : StoreNode(c, mem, adr, at, val, MemNode::unordered) { 866 init_class_id(Class_StoreVector); 867 } 868 869 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); } 870 uint length() const { return vect_type()->length(); } // Vector length 871 872 virtual int Opcode() const; 873 874 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 875 virtual BasicType memory_type() const { return T_VOID; } 876 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 877 878 static StoreVectorNode* make(int opc, Node* ctl, Node* mem, 879 Node* adr, const TypePtr* atyp, Node* val, 880 uint vlen); 881 882 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 883 }; 884 885 886 //=========================Promote_Scalar_to_Vector============================ 887 888 //------------------------------ReplicateBNode--------------------------------- 889 // Replicate byte scalar to be vector 890 class ReplicateBNode : public VectorNode { 891 public: 892 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 893 virtual int Opcode() const; 894 }; 895 896 //------------------------------ReplicateSNode--------------------------------- 897 // Replicate short scalar to be vector 898 class ReplicateSNode : public VectorNode { 899 public: 900 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 901 virtual int Opcode() const; 902 }; 903 904 //------------------------------ReplicateINode--------------------------------- 905 // Replicate int scalar to be vector 906 class ReplicateINode : public VectorNode { 907 public: 908 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 909 virtual int Opcode() const; 910 }; 911 912 //------------------------------ReplicateLNode--------------------------------- 913 // Replicate long scalar to be vector 914 class ReplicateLNode : public VectorNode { 915 public: 916 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 917 virtual int Opcode() const; 918 }; 919 920 //------------------------------ReplicateFNode--------------------------------- 921 // Replicate float scalar to be vector 922 class ReplicateFNode : public VectorNode { 923 public: 924 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 925 virtual int Opcode() const; 926 }; 927 928 //------------------------------ReplicateDNode--------------------------------- 929 // Replicate double scalar to be vector 930 class ReplicateDNode : public VectorNode { 931 public: 932 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 933 virtual int Opcode() const; 934 }; 935 936 //========================Pack_Scalars_into_a_Vector=========================== 937 938 //------------------------------PackNode--------------------------------------- 939 // Pack parent class (not for code generation). 940 class PackNode : public VectorNode { 941 public: 942 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 943 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {} 944 virtual int Opcode() const; 945 946 void add_opd(Node* n) { 947 add_req(n); 948 } 949 950 // Create a binary tree form for Packs. [lo, hi) (half-open) range 951 PackNode* binary_tree_pack(int lo, int hi); 952 953 static PackNode* make(Node* s, uint vlen, BasicType bt); 954 }; 955 956 //------------------------------PackBNode-------------------------------------- 957 // Pack byte scalars into vector 958 class PackBNode : public PackNode { 959 public: 960 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 961 virtual int Opcode() const; 962 }; 963 964 //------------------------------PackSNode-------------------------------------- 965 // Pack short scalars into a vector 966 class PackSNode : public PackNode { 967 public: 968 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 969 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 970 virtual int Opcode() const; 971 }; 972 973 //------------------------------PackINode-------------------------------------- 974 // Pack integer scalars into a vector 975 class PackINode : public PackNode { 976 public: 977 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 978 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 979 virtual int Opcode() const; 980 }; 981 982 //------------------------------PackLNode-------------------------------------- 983 // Pack long scalars into a vector 984 class PackLNode : public PackNode { 985 public: 986 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 987 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 988 virtual int Opcode() const; 989 }; 990 991 //------------------------------Pack2LNode------------------------------------- 992 // Pack 2 long scalars into a vector 993 class Pack2LNode : public PackNode { 994 public: 995 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 996 virtual int Opcode() const; 997 }; 998 999 //------------------------------PackFNode-------------------------------------- 1000 // Pack float scalars into vector 1001 class PackFNode : public PackNode { 1002 public: 1003 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1004 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1005 virtual int Opcode() const; 1006 }; 1007 1008 //------------------------------PackDNode-------------------------------------- 1009 // Pack double scalars into a vector 1010 class PackDNode : public PackNode { 1011 public: 1012 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1013 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1014 virtual int Opcode() const; 1015 }; 1016 1017 //------------------------------Pack2DNode------------------------------------- 1018 // Pack 2 double scalars into a vector 1019 class Pack2DNode : public PackNode { 1020 public: 1021 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1022 virtual int Opcode() const; 1023 }; 1024 1025 1026 //========================Extract_Scalar_from_Vector=========================== 1027 1028 //------------------------------ExtractNode------------------------------------ 1029 // Extract a scalar from a vector at position "pos" 1030 class ExtractNode : public Node { 1031 public: 1032 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { 1033 assert(in(2)->get_int() >= 0, "positive constants"); 1034 } 1035 virtual int Opcode() const; 1036 uint pos() const { return in(2)->get_int(); } 1037 1038 static Node* make(Node* v, uint position, BasicType bt); 1039 static int opcode(BasicType bt); 1040 }; 1041 1042 //------------------------------ExtractBNode----------------------------------- 1043 // Extract a byte from a vector at position "pos" 1044 class ExtractBNode : public ExtractNode { 1045 public: 1046 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1047 virtual int Opcode() const; 1048 virtual const Type *bottom_type() const { return TypeInt::INT; } 1049 virtual uint ideal_reg() const { return Op_RegI; } 1050 }; 1051 1052 //------------------------------ExtractUBNode---------------------------------- 1053 // Extract a boolean from a vector at position "pos" 1054 class ExtractUBNode : public ExtractNode { 1055 public: 1056 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1057 virtual int Opcode() const; 1058 virtual const Type *bottom_type() const { return TypeInt::INT; } 1059 virtual uint ideal_reg() const { return Op_RegI; } 1060 }; 1061 1062 //------------------------------ExtractCNode----------------------------------- 1063 // Extract a char from a vector at position "pos" 1064 class ExtractCNode : public ExtractNode { 1065 public: 1066 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1067 virtual int Opcode() const; 1068 virtual const Type *bottom_type() const { return TypeInt::CHAR; } 1069 virtual uint ideal_reg() const { return Op_RegI; } 1070 }; 1071 1072 //------------------------------ExtractSNode----------------------------------- 1073 // Extract a short from a vector at position "pos" 1074 class ExtractSNode : public ExtractNode { 1075 public: 1076 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1077 virtual int Opcode() const; 1078 virtual const Type *bottom_type() const { return TypeInt::SHORT; } 1079 virtual uint ideal_reg() const { return Op_RegI; } 1080 }; 1081 1082 //------------------------------ExtractINode----------------------------------- 1083 // Extract an int from a vector at position "pos" 1084 class ExtractINode : public ExtractNode { 1085 public: 1086 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1087 virtual int Opcode() const; 1088 virtual const Type *bottom_type() const { return TypeInt::INT; } 1089 virtual uint ideal_reg() const { return Op_RegI; } 1090 }; 1091 1092 //------------------------------ExtractLNode----------------------------------- 1093 // Extract a long from a vector at position "pos" 1094 class ExtractLNode : public ExtractNode { 1095 public: 1096 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1097 virtual int Opcode() const; 1098 virtual const Type *bottom_type() const { return TypeLong::LONG; } 1099 virtual uint ideal_reg() const { return Op_RegL; } 1100 }; 1101 1102 //------------------------------ExtractFNode----------------------------------- 1103 // Extract a float from a vector at position "pos" 1104 class ExtractFNode : public ExtractNode { 1105 public: 1106 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1107 virtual int Opcode() const; 1108 virtual const Type *bottom_type() const { return Type::FLOAT; } 1109 virtual uint ideal_reg() const { return Op_RegF; } 1110 }; 1111 1112 //------------------------------ExtractDNode----------------------------------- 1113 // Extract a double from a vector at position "pos" 1114 class ExtractDNode : public ExtractNode { 1115 public: 1116 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1117 virtual int Opcode() const; 1118 virtual const Type *bottom_type() const { return Type::DOUBLE; } 1119 virtual uint ideal_reg() const { return Op_RegD; } 1120 }; 1121 1122 //------------------------------SetVectMaskINode------------------------------- 1123 // Provide a mask for a vector predicate machine 1124 class SetVectMaskINode : public Node { 1125 public: 1126 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {} 1127 virtual int Opcode() const; 1128 const Type *bottom_type() const { return TypeInt::INT; } 1129 virtual uint ideal_reg() const { return Op_RegI; } 1130 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } 1131 }; 1132 1133 class VectorBoxNode : public Node { 1134 private: 1135 const TypeInstPtr* const _box_type; 1136 const TypeVect* const _vec_type; 1137 public: 1138 enum { 1139 Box = 1, 1140 Value = 2 1141 }; 1142 VectorBoxNode(Compile* C, Node* box, Node* val, 1143 const TypeInstPtr* box_type, const TypeVect* vt) 1144 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) { 1145 init_flags(Flag_is_macro); 1146 C->add_macro_node(this); 1147 } 1148 1149 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; }; 1150 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; }; 1151 1152 virtual int Opcode() const; 1153 virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ } 1154 virtual uint ideal_reg() const { return box_type()->ideal_reg(); } 1155 virtual uint size_of() const { return sizeof(*this); } 1156 1157 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); 1158 }; 1159 1160 class VectorBoxAllocateNode : public CallStaticJavaNode { 1161 public: 1162 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) 1163 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) { 1164 init_flags(Flag_is_macro); 1165 C->add_macro_node(this); 1166 } 1167 1168 virtual int Opcode() const; 1169 #ifndef PRODUCT 1170 virtual void dump_spec(outputStream *st) const; 1171 #endif // PRODUCT 1172 }; 1173 1174 class VectorUnboxNode : public VectorNode { 1175 public: 1176 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem) 1177 : VectorNode(mem, obj, vec_type) { 1178 init_flags(Flag_is_macro); 1179 C->add_macro_node(this); 1180 } 1181 1182 virtual int Opcode() const; 1183 Node* obj() const { return in(2); } 1184 Node* mem() const { return in(1); } 1185 virtual Node *Identity(PhaseGVN *phase); 1186 }; 1187 1188 class VectorMaskCmpNode : public VectorNode { 1189 private: 1190 BoolTest::mask _predicate; 1191 1192 protected: 1193 uint size_of() const { return sizeof(*this); } 1194 1195 public: 1196 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, const TypeVect* vt) : 1197 VectorNode(in1, in2, vt), _predicate(predicate) { 1198 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1199 "VectorMaskCmp inputs must have same type for elements"); 1200 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1201 "VectorMaskCmp inputs must have same number of elements"); 1202 init_class_id(Class_VectorMaskCmp); 1203 } 1204 1205 virtual int Opcode() const; 1206 virtual uint hash() const { return VectorNode::hash() + _predicate; } 1207 virtual uint cmp( const Node &n ) const { 1208 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; 1209 } 1210 BoolTest::mask get_predicate() { return _predicate; } 1211 #ifndef PRODUCT 1212 virtual void dump_spec(outputStream *st) const; 1213 #endif // PRODUCT 1214 }; 1215 1216 // Used to wrap other vector nodes in order to add masking functionality. 1217 class VectorMaskWrapperNode : public VectorNode { 1218 public: 1219 VectorMaskWrapperNode(Node* vector, Node* mask) 1220 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { 1221 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); 1222 } 1223 1224 virtual int Opcode() const; 1225 Node* vector_val() const { return in(1); } 1226 Node* vector_mask() const { return in(2); } 1227 }; 1228 1229 class VectorTestNode : public Node { 1230 private: 1231 Assembler::Condition _predicate; 1232 1233 protected: 1234 uint size_of() const { return sizeof(*this); } 1235 1236 public: 1237 VectorTestNode( Node *in1, Node *in2, Assembler::Condition predicate) : Node(NULL, in1, in2), _predicate(predicate) { 1238 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector"); 1239 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector"); 1240 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1241 "same type elements are needed"); 1242 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1243 "same number of elements is needed"); 1244 } 1245 virtual int Opcode() const; 1246 virtual uint hash() const { return Node::hash() + _predicate; } 1247 virtual uint cmp( const Node &n ) const { 1248 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; 1249 } 1250 virtual const Type *bottom_type() const { return TypeInt::BOOL; } 1251 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest 1252 // in middle-end, we make it boolean result directly. 1253 Assembler::Condition get_predicate() const { return _predicate; } 1254 }; 1255 1256 class VectorBlendNode : public VectorNode { 1257 public: 1258 VectorBlendNode(Node* vec1, Node* vec2, Node* mask) 1259 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { 1260 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1261 } 1262 1263 virtual int Opcode() const; 1264 Node* vec1() const { return in(1); } 1265 Node* vec2() const { return in(2); } 1266 Node* vec_mask() const { return in(3); } 1267 }; 1268 1269 class VectorLoadMaskNode : public VectorNode { 1270 public: 1271 VectorLoadMaskNode(Node* in, const TypeVect* vt) 1272 : VectorNode(in, vt) { 1273 assert(in->is_LoadVector(), "expected load vector"); 1274 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean"); 1275 } 1276 1277 int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1278 virtual int Opcode() const; 1279 }; 1280 1281 class VectorStoreMaskNode : public VectorNode { 1282 private: 1283 int _mask_size; 1284 protected: 1285 uint size_of() const { return sizeof(*this); } 1286 1287 public: 1288 VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem) 1289 : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) { 1290 _mask_size = type2aelembytes(in_type); 1291 } 1292 1293 virtual uint hash() const { return VectorNode::hash() + _mask_size; } 1294 virtual uint cmp( const Node &n ) const { 1295 return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size; 1296 } 1297 int GetInputMaskSize() const { return _mask_size; } 1298 virtual int Opcode() const; 1299 }; 1300 1301 // This is intended for use as a simple reinterpret node that has no cast. 1302 class VectorReinterpretNode : public VectorNode { 1303 private: 1304 const TypeVect* _src_vt; 1305 protected: 1306 uint size_of() const { return sizeof(*this); } 1307 public: 1308 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) 1309 : VectorNode(in, dst_vt), _src_vt(src_vt) { } 1310 1311 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } 1312 virtual uint cmp( const Node &n ) const { 1313 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); 1314 } 1315 virtual Node *Identity(PhaseGVN *phase); 1316 1317 virtual int Opcode() const; 1318 }; 1319 1320 class VectorCastNode : public VectorNode { 1321 public: 1322 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 1323 virtual int Opcode() const; 1324 1325 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); 1326 static int opcode(BasicType bt); 1327 static bool implemented(BasicType bt, uint vlen); 1328 }; 1329 1330 class VectorCastB2XNode : public VectorCastNode { 1331 public: 1332 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1333 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); 1334 } 1335 virtual int Opcode() const; 1336 }; 1337 1338 class VectorCastS2XNode : public VectorCastNode { 1339 public: 1340 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1341 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); 1342 } 1343 virtual int Opcode() const; 1344 }; 1345 1346 class VectorCastI2XNode : public VectorCastNode { 1347 public: 1348 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1349 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); 1350 } 1351 virtual int Opcode() const; 1352 }; 1353 1354 class VectorCastL2XNode : public VectorCastNode { 1355 public: 1356 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1357 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long"); 1358 } 1359 virtual int Opcode() const; 1360 }; 1361 1362 class VectorCastF2XNode : public VectorCastNode { 1363 public: 1364 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1365 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); 1366 } 1367 virtual int Opcode() const; 1368 }; 1369 1370 class VectorCastD2XNode : public VectorCastNode { 1371 public: 1372 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1373 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); 1374 } 1375 virtual int Opcode() const; 1376 }; 1377 1378 class VectorInsertNode : public VectorNode { 1379 public: 1380 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { 1381 assert(pos->get_int() >= 0, "positive constants"); 1382 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length"); 1383 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type"); 1384 } 1385 virtual int Opcode() const; 1386 uint pos() const { return in(3)->get_int(); } 1387 1388 static Node* make(Node* vec, Node* new_val, int position); 1389 }; 1390 1391 #endif // SHARE_VM_OPTO_VECTORNODE_HPP --- EOF ---