1 /* 2 * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #ifndef SHARE_OPTO_VECTORNODE_HPP 25 #define SHARE_OPTO_VECTORNODE_HPP 26 27 #include "opto/matcher.hpp" 28 #include "opto/memnode.hpp" 29 #include "opto/node.hpp" 30 #include "opto/opcodes.hpp" 31 #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_vshift(Node* n); 74 static bool is_vshift_cnt(Node* n); 75 static bool is_type_transition_short_to_int(Node* n); 76 static bool is_type_transition_to_int(Node* n); 77 static bool is_muladds2i(Node* n); 78 static bool is_invariant_vector(Node* n); 79 // [Start, end) half-open range defining which operands are vectors 80 static void vector_operands(Node* n, uint* start, uint* end); 81 }; 82 83 //===========================Vector=ALU=Operations============================= 84 85 //------------------------------AddVBNode-------------------------------------- 86 // Vector add byte 87 class AddVBNode : public VectorNode { 88 public: 89 AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 90 virtual int Opcode() const; 91 }; 92 93 //------------------------------AddVSNode-------------------------------------- 94 // Vector add char/short 95 class AddVSNode : public VectorNode { 96 public: 97 AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 98 virtual int Opcode() const; 99 }; 100 101 //------------------------------AddVINode-------------------------------------- 102 // Vector add int 103 class AddVINode : public VectorNode { 104 public: 105 AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 106 virtual int Opcode() const; 107 }; 108 109 //------------------------------AddVLNode-------------------------------------- 110 // Vector add long 111 class AddVLNode : public VectorNode { 112 public: 113 AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 114 virtual int Opcode() const; 115 }; 116 117 //------------------------------AddVFNode-------------------------------------- 118 // Vector add float 119 class AddVFNode : public VectorNode { 120 public: 121 AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 122 virtual int Opcode() const; 123 }; 124 125 //------------------------------AddVDNode-------------------------------------- 126 // Vector add double 127 class AddVDNode : public VectorNode { 128 public: 129 AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 130 virtual int Opcode() const; 131 }; 132 133 //------------------------------ReductionNode------------------------------------ 134 // Perform reduction of a vector 135 class ReductionNode : public Node { 136 public: 137 ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {} 138 139 static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt); 140 static int opcode(int opc, BasicType bt); 141 static bool implemented(int opc, uint vlen, BasicType bt); 142 static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt); 143 }; 144 145 //------------------------------AddReductionVINode-------------------------------------- 146 // Vector add byte, short and int as a reduction 147 class AddReductionVINode : public ReductionNode { 148 public: 149 AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 150 if (in1->bottom_type()->basic_type() == T_INT) { 151 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 152 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 153 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 154 } 155 } 156 virtual int Opcode() const; 157 virtual const Type* bottom_type() const { 158 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 159 return TypeInt::INT; 160 else if(in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 161 return TypeInt::BYTE; 162 else 163 return TypeInt::SHORT; 164 } 165 virtual uint ideal_reg() const { return Op_RegI; } 166 }; 167 168 //------------------------------AddReductionVLNode-------------------------------------- 169 // Vector add long as a reduction 170 class AddReductionVLNode : public ReductionNode { 171 public: 172 AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 173 virtual int Opcode() const; 174 virtual const Type* bottom_type() const { return TypeLong::LONG; } 175 virtual uint ideal_reg() const { return Op_RegL; } 176 }; 177 178 //------------------------------AddReductionVFNode-------------------------------------- 179 // Vector add float as a reduction 180 class AddReductionVFNode : public ReductionNode { 181 public: 182 AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 183 virtual int Opcode() const; 184 virtual const Type* bottom_type() const { return Type::FLOAT; } 185 virtual uint ideal_reg() const { return Op_RegF; } 186 }; 187 188 //------------------------------AddReductionVDNode-------------------------------------- 189 // Vector add double as a reduction 190 class AddReductionVDNode : public ReductionNode { 191 public: 192 AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 193 virtual int Opcode() const; 194 virtual const Type* bottom_type() const { return Type::DOUBLE; } 195 virtual uint ideal_reg() const { return Op_RegD; } 196 }; 197 198 //------------------------------SubVBNode-------------------------------------- 199 // Vector subtract byte 200 class SubVBNode : public VectorNode { 201 public: 202 SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 203 virtual int Opcode() const; 204 }; 205 206 //------------------------------SubVSNode-------------------------------------- 207 // Vector subtract short 208 class SubVSNode : public VectorNode { 209 public: 210 SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 211 virtual int Opcode() const; 212 }; 213 214 //------------------------------SubVINode-------------------------------------- 215 // Vector subtract int 216 class SubVINode : public VectorNode { 217 public: 218 SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 219 virtual int Opcode() const; 220 }; 221 222 //------------------------------SubVLNode-------------------------------------- 223 // Vector subtract long 224 class SubVLNode : public VectorNode { 225 public: 226 SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 227 virtual int Opcode() const; 228 }; 229 230 //------------------------------SubVFNode-------------------------------------- 231 // Vector subtract float 232 class SubVFNode : public VectorNode { 233 public: 234 SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 235 virtual int Opcode() const; 236 }; 237 238 //------------------------------SubVDNode-------------------------------------- 239 // Vector subtract double 240 class SubVDNode : public VectorNode { 241 public: 242 SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 243 virtual int Opcode() const; 244 }; 245 246 //------------------------------SubReductionVNode-------------------------------------- 247 // Vector sub int, long as a reduction 248 class SubReductionVNode : public ReductionNode { 249 public: 250 SubReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 251 assert(in1->bottom_type()->basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),""); 252 assert(in1->bottom_type()->basic_type() == T_INT || 253 in1->bottom_type()->basic_type() == T_LONG, ""); 254 } 255 virtual int Opcode() const; 256 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 257 virtual const Type* bottom_type() const { if (in(1)->bottom_type()->basic_type() == T_INT) 258 return TypeInt::INT; else return TypeLong::LONG; } 259 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 260 }; 261 262 263 //------------------------------SubReductionVFPNode-------------------------------------- 264 // Vector sub float, double as a reduction 265 class SubReductionVFPNode : public ReductionNode { 266 public: 267 SubReductionVFPNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 268 assert(in1->bottom_type()->basic_type() == T_FLOAT || 269 in1->bottom_type()->basic_type() == T_DOUBLE, ""); 270 } 271 272 virtual int Opcode() const; 273 virtual const Type* bottom_type() const { 274 if (in(1)->bottom_type()->basic_type() == T_FLOAT) { 275 return Type::FLOAT; 276 } else { 277 return Type::DOUBLE; 278 } 279 } 280 281 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_FLOAT ? Op_RegF : Op_RegD; } 282 }; 283 284 //------------------------------MulVBNode-------------------------------------- 285 // Vector multiply byte 286 class MulVBNode : public VectorNode { 287 public: 288 MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 289 virtual int Opcode() const; 290 }; 291 292 //------------------------------MulVSNode-------------------------------------- 293 // Vector multiply short 294 class MulVSNode : public VectorNode { 295 public: 296 MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 297 virtual int Opcode() const; 298 }; 299 300 //------------------------------MulVINode-------------------------------------- 301 // Vector multiply int 302 class MulVINode : public VectorNode { 303 public: 304 MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 305 virtual int Opcode() const; 306 }; 307 308 //------------------------------MulVLNode-------------------------------------- 309 // Vector multiply long 310 class MulVLNode : public VectorNode { 311 public: 312 MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 313 virtual int Opcode() const; 314 }; 315 316 //------------------------------MulVFNode-------------------------------------- 317 // Vector multiply float 318 class MulVFNode : public VectorNode { 319 public: 320 MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 321 virtual int Opcode() const; 322 }; 323 324 //------------------------------MulVDNode-------------------------------------- 325 // Vector multiply double 326 class MulVDNode : public VectorNode { 327 public: 328 MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 329 virtual int Opcode() const; 330 }; 331 332 //------------------------------MulAddVS2VINode-------------------------------- 333 // Vector multiply shorts to int and add adjacent ints. 334 class MulAddVS2VINode : public VectorNode { 335 public: 336 MulAddVS2VINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 337 virtual int Opcode() const; 338 }; 339 340 //------------------------------FmaVDNode-------------------------------------- 341 // Vector multiply double 342 class FmaVDNode : public VectorNode { 343 public: 344 FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 345 virtual int Opcode() const; 346 }; 347 348 //------------------------------FmaVFNode-------------------------------------- 349 // Vector multiply float 350 class FmaVFNode : public VectorNode { 351 public: 352 FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 353 virtual int Opcode() const; 354 }; 355 356 //------------------------------CMoveVFNode-------------------------------------- 357 // Vector float conditional move 358 class CMoveVFNode : public VectorNode { 359 public: 360 CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 361 virtual int Opcode() const; 362 }; 363 364 //------------------------------CMoveVDNode-------------------------------------- 365 // Vector double conditional move 366 class CMoveVDNode : public VectorNode { 367 public: 368 CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} 369 virtual int Opcode() const; 370 }; 371 372 //------------------------------MulReductionVINode-------------------------------------- 373 // Vector multiply byte, short and int as a reduction 374 class MulReductionVINode : public ReductionNode { 375 public: 376 MulReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 377 if (in1->bottom_type()->basic_type() == T_INT) { 378 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 379 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 380 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 381 } 382 } 383 virtual int Opcode() const; 384 virtual const Type* bottom_type() const { 385 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 386 return TypeInt::INT; 387 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 388 return TypeInt::BYTE; 389 else 390 return TypeInt::SHORT; 391 } 392 virtual uint ideal_reg() const { return Op_RegI; } 393 }; 394 395 //------------------------------MulReductionVLNode-------------------------------------- 396 // Vector multiply int as a reduction 397 class MulReductionVLNode : public ReductionNode { 398 public: 399 MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 400 virtual int Opcode() const; 401 virtual const Type* bottom_type() const { return TypeLong::LONG; } 402 virtual uint ideal_reg() const { return Op_RegL; } 403 }; 404 405 //------------------------------MulReductionVFNode-------------------------------------- 406 // Vector multiply float as a reduction 407 class MulReductionVFNode : public ReductionNode { 408 public: 409 MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 410 virtual int Opcode() const; 411 virtual const Type* bottom_type() const { return Type::FLOAT; } 412 virtual uint ideal_reg() const { return Op_RegF; } 413 }; 414 415 //------------------------------MulReductionVDNode-------------------------------------- 416 // Vector multiply double as a reduction 417 class MulReductionVDNode : public ReductionNode { 418 public: 419 MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {} 420 virtual int Opcode() const; 421 virtual const Type* bottom_type() const { return Type::DOUBLE; } 422 virtual uint ideal_reg() const { return Op_RegD; } 423 }; 424 425 //------------------------------DivVFNode-------------------------------------- 426 // Vector divide float 427 class DivVFNode : public VectorNode { 428 public: 429 DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 430 virtual int Opcode() const; 431 }; 432 433 //------------------------------DivVDNode-------------------------------------- 434 // Vector Divide double 435 class DivVDNode : public VectorNode { 436 public: 437 DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 438 virtual int Opcode() const; 439 }; 440 441 //------------------------------MinVNode-------------------------------------- 442 // Vector Min 443 class MinVNode : public VectorNode { 444 public: 445 MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 446 virtual int Opcode() const; 447 }; 448 449 //------------------------------MaxVNode-------------------------------------- 450 // Vector Max 451 class MaxVNode : public VectorNode { 452 public: 453 MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} 454 virtual int Opcode() const; 455 }; 456 457 //------------------------------AbsVNode-------------------------------------- 458 // Vector Abs 459 class AbsVNode : public VectorNode { 460 public: 461 AbsVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 462 virtual int Opcode() const; 463 }; 464 465 //------------------------------AbsVFNode-------------------------------------- 466 // Vector Abs float 467 class AbsVFNode : public VectorNode { 468 public: 469 AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 470 virtual int Opcode() const; 471 }; 472 473 //------------------------------AbsVDNode-------------------------------------- 474 // Vector Abs double 475 class AbsVDNode : public VectorNode { 476 public: 477 AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 478 virtual int Opcode() const; 479 }; 480 481 //------------------------------NegVINode-------------------------------------- 482 // Vector Neg int 483 class NegVINode : public VectorNode { 484 public: 485 NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 486 virtual int Opcode() const; 487 }; 488 489 //------------------------------NegVFNode-------------------------------------- 490 // Vector Neg float 491 class NegVFNode : public VectorNode { 492 public: 493 NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 494 virtual int Opcode() const; 495 }; 496 497 //------------------------------NegVDNode-------------------------------------- 498 // Vector Neg double 499 class NegVDNode : public VectorNode { 500 public: 501 NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 502 virtual int Opcode() const; 503 }; 504 505 //------------------------------PopCountVINode--------------------------------- 506 // Vector popcount integer bits 507 class PopCountVINode : public VectorNode { 508 public: 509 PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 510 virtual int Opcode() const; 511 }; 512 513 //------------------------------SqrtVFNode-------------------------------------- 514 // Vector Sqrt float 515 class SqrtVFNode : public VectorNode { 516 public: 517 SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 518 virtual int Opcode() const; 519 }; 520 521 //------------------------------SqrtVDNode-------------------------------------- 522 // Vector Sqrt double 523 class SqrtVDNode : public VectorNode { 524 public: 525 SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {} 526 virtual int Opcode() const; 527 }; 528 529 //------------------------------NotVNode-------------------------------------- 530 // Vector Not 531 class NotVNode : public VectorNode { 532 public: 533 NotVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 534 virtual int Opcode() const; 535 }; 536 537 //------------------------------LShiftVBNode----------------------------------- 538 // Vector left shift bytes 539 class LShiftVBNode : public VectorNode { 540 public: 541 LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 542 virtual int Opcode() const; 543 }; 544 545 //------------------------------LShiftVSNode----------------------------------- 546 // Vector left shift shorts 547 class LShiftVSNode : public VectorNode { 548 public: 549 LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 550 virtual int Opcode() const; 551 }; 552 553 //------------------------------LShiftVINode----------------------------------- 554 // Vector left shift ints 555 class LShiftVINode : public VectorNode { 556 public: 557 LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 558 virtual int Opcode() const; 559 }; 560 561 //------------------------------LShiftVLNode----------------------------------- 562 // Vector left shift longs 563 class LShiftVLNode : public VectorNode { 564 public: 565 LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 566 virtual int Opcode() const; 567 }; 568 569 //------------------------------RShiftVBNode----------------------------------- 570 // Vector right arithmetic (signed) shift bytes 571 class RShiftVBNode : public VectorNode { 572 public: 573 RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 574 virtual int Opcode() const; 575 }; 576 577 //------------------------------RShiftVSNode----------------------------------- 578 // Vector right arithmetic (signed) shift shorts 579 class RShiftVSNode : public VectorNode { 580 public: 581 RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 582 virtual int Opcode() const; 583 }; 584 585 //------------------------------RShiftVINode----------------------------------- 586 // Vector right arithmetic (signed) shift ints 587 class RShiftVINode : public VectorNode { 588 public: 589 RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 590 virtual int Opcode() const; 591 }; 592 593 //------------------------------RShiftVLNode----------------------------------- 594 // Vector right arithmetic (signed) shift longs 595 class RShiftVLNode : public VectorNode { 596 public: 597 RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 598 virtual int Opcode() const; 599 }; 600 601 //------------------------------URShiftVBNode---------------------------------- 602 // Vector right logical (unsigned) shift bytes 603 class URShiftVBNode : public VectorNode { 604 public: 605 URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 606 virtual int Opcode() const; 607 }; 608 609 //------------------------------URShiftVSNode---------------------------------- 610 // Vector right logical (unsigned) shift shorts 611 class URShiftVSNode : public VectorNode { 612 public: 613 URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 614 virtual int Opcode() const; 615 }; 616 617 //------------------------------URShiftVINode---------------------------------- 618 // Vector right logical (unsigned) shift ints 619 class URShiftVINode : public VectorNode { 620 public: 621 URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 622 virtual int Opcode() const; 623 }; 624 625 //------------------------------URShiftVLNode---------------------------------- 626 // Vector right logical (unsigned) shift longs 627 class URShiftVLNode : public VectorNode { 628 public: 629 URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 630 virtual int Opcode() const; 631 }; 632 633 //------------------------------LShiftCntVNode--------------------------------- 634 // Vector left shift count 635 class LShiftCntVNode : public VectorNode { 636 public: 637 LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 638 virtual int Opcode() const; 639 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 640 }; 641 642 //------------------------------RShiftCntVNode--------------------------------- 643 // Vector right shift count 644 class RShiftCntVNode : public VectorNode { 645 public: 646 RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} 647 virtual int Opcode() const; 648 virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } 649 }; 650 651 652 //------------------------------AndVNode--------------------------------------- 653 // Vector and integer 654 class AndVNode : public VectorNode { 655 public: 656 AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 657 virtual int Opcode() const; 658 }; 659 660 //------------------------------AndReductionVNode-------------------------------------- 661 // Vector and byte, short, int, long as a reduction 662 class AndReductionVNode : public ReductionNode { 663 public: 664 AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 665 if (in1->bottom_type()->basic_type() == T_INT) { 666 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 667 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 668 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 669 } 670 else if (in1->bottom_type()->basic_type() == T_LONG) { 671 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 672 } 673 } 674 virtual int Opcode() const; 675 virtual const Type* bottom_type() const { 676 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 677 return TypeInt::INT; 678 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 679 return TypeInt::BYTE; 680 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 681 return TypeInt::SHORT; 682 else 683 return TypeLong::LONG; 684 } 685 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 686 }; 687 688 //------------------------------OrVNode--------------------------------------- 689 // Vector or integer 690 class OrVNode : public VectorNode { 691 public: 692 OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 693 virtual int Opcode() const; 694 }; 695 696 //------------------------------OrReductionVNode-------------------------------------- 697 // Vector or short, byte, int, long as a reduction 698 class OrReductionVNode : public ReductionNode { 699 public: 700 OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 701 assert(in1->bottom_type()->basic_type() == T_INT || 702 in1->bottom_type()->basic_type() == T_LONG || 703 in1->bottom_type()->basic_type() == T_SHORT || 704 in1->bottom_type()->basic_type() == T_BYTE, ""); 705 } 706 virtual int Opcode() const; 707 virtual const Type* bottom_type() const { 708 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 709 return TypeInt::INT; 710 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 711 return TypeInt::BYTE; 712 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 713 return TypeInt::SHORT; 714 else 715 return TypeLong::LONG; 716 } 717 718 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 719 }; 720 721 //------------------------------XorReductionVNode-------------------------------------- 722 // Vector and int, long as a reduction 723 class XorReductionVNode : public ReductionNode { 724 public: 725 XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 726 assert(in1->bottom_type()->basic_type() == T_INT || 727 in1->bottom_type()->basic_type() == T_LONG || 728 in1->bottom_type()->basic_type() == T_SHORT || 729 in1->bottom_type()->basic_type() == T_BYTE, ""); 730 } 731 virtual int Opcode() const; 732 virtual const Type* bottom_type() const { 733 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 734 return TypeInt::INT; 735 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 736 return TypeInt::BYTE; 737 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 738 return TypeInt::SHORT; 739 else 740 return TypeLong::LONG; 741 } 742 743 virtual uint ideal_reg() const { return in(1)->bottom_type()->basic_type() == T_INT ? Op_RegI : Op_RegL; } 744 }; 745 746 //------------------------------XorVNode--------------------------------------- 747 // Vector xor integer 748 class XorVNode : public VectorNode { 749 public: 750 XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} 751 virtual int Opcode() const; 752 }; 753 754 //------------------------------MinReductionVNode-------------------------------------- 755 // Vector min byte, short, int, long, float, double as a reduction 756 class MinReductionVNode : public ReductionNode { 757 public: 758 MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 759 if (in1->bottom_type()->basic_type() == T_INT) { 760 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 761 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 762 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 763 } 764 else if (in1->bottom_type()->basic_type() == T_LONG) { 765 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 766 } 767 else if (in1->bottom_type()->basic_type() == T_FLOAT) { 768 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, ""); 769 } 770 else if (in1->bottom_type()->basic_type() == T_DOUBLE) { 771 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, ""); 772 } 773 } 774 virtual int Opcode() const; 775 virtual const Type* bottom_type() const { 776 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 777 return TypeInt::INT; 778 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 779 return TypeInt::BYTE; 780 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 781 return TypeInt::SHORT; 782 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT) 783 return Type::FLOAT; 784 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE) 785 return Type::DOUBLE; 786 else return TypeLong::LONG; 787 } 788 virtual uint ideal_reg() const { 789 if (in(1)->bottom_type()->basic_type() == T_INT) 790 return Op_RegI; 791 else if (in(1)->bottom_type()->basic_type() == T_FLOAT) 792 return Op_RegF; 793 else if (in(1)->bottom_type()->basic_type() == T_DOUBLE) 794 return Op_RegD; 795 else return Op_RegL; 796 } 797 }; 798 799 //------------------------------MaxReductionVNode-------------------------------------- 800 // Vector min byte, short, int, long, float, double as a reduction 801 class MaxReductionVNode : public ReductionNode { 802 public: 803 MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) { 804 if (in1->bottom_type()->basic_type() == T_INT) { 805 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_INT || 806 in2->bottom_type()->is_vect()->element_basic_type() == T_BYTE || 807 in2->bottom_type()->is_vect()->element_basic_type() == T_SHORT, ""); 808 } 809 else if (in1->bottom_type()->basic_type() == T_LONG) { 810 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_LONG, ""); 811 } 812 else if (in1->bottom_type()->basic_type() == T_FLOAT) { 813 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, ""); 814 } 815 else if (in1->bottom_type()->basic_type() == T_DOUBLE) { 816 assert(in2->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, ""); 817 } 818 } 819 virtual int Opcode() const; 820 virtual const Type* bottom_type() const { 821 if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT) 822 return TypeInt::INT; 823 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE) 824 return TypeInt::BYTE; 825 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT) 826 return TypeInt::SHORT; 827 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT) 828 return Type::FLOAT; 829 else if (in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE) 830 return Type::DOUBLE; 831 else return TypeLong::LONG; 832 } 833 virtual uint ideal_reg() const { 834 if (in(1)->bottom_type()->basic_type() == T_INT) 835 return Op_RegI; 836 else if (in(1)->bottom_type()->basic_type() == T_FLOAT) 837 return Op_RegF; 838 else if (in(1)->bottom_type()->basic_type() == T_DOUBLE) 839 return Op_RegD; 840 else return Op_RegL; 841 } 842 }; 843 844 //================================= M E M O R Y =============================== 845 846 //------------------------------LoadVectorNode--------------------------------- 847 // Load Vector from memory 848 class LoadVectorNode : public LoadNode { 849 public: 850 LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest) 851 : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) { 852 init_class_id(Class_LoadVector); 853 set_mismatched_access(); 854 } 855 856 const TypeVect* vect_type() const { return type()->is_vect(); } 857 uint length() const { return vect_type()->length(); } // Vector length 858 859 virtual int Opcode() const; 860 861 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 862 virtual BasicType memory_type() const { return T_VOID; } 863 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 864 865 virtual int store_Opcode() const { return Op_StoreVector; } 866 867 static LoadVectorNode* make(int opc, Node* ctl, Node* mem, 868 Node* adr, const TypePtr* atyp, 869 uint vlen, BasicType bt, 870 ControlDependency control_dependency = LoadNode::DependsOnlyOnTest); 871 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 872 }; 873 874 //------------------------------LoadVectorGatherNode------------------------------ 875 // Load Vector from memory via index map 876 class LoadVectorGatherNode : public LoadVectorNode { 877 public: 878 LoadVectorGatherNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, Node* indices) 879 : LoadVectorNode(c, mem, adr, at, vt) { 880 init_class_id(Class_LoadVectorGather); 881 assert(indices->bottom_type()->is_vect(), "indices must be in vector"); 882 add_req(indices); 883 assert(req() == MemNode::ValueIn + 1, "match_edge expects that last input is in MemNode::ValueIn"); 884 } 885 886 virtual int Opcode() const; 887 virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } 888 }; 889 890 //------------------------------StoreVectorNode-------------------------------- 891 // Store Vector to memory 892 class StoreVectorNode : public StoreNode { 893 public: 894 StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val) 895 : StoreNode(c, mem, adr, at, val, MemNode::unordered) { 896 init_class_id(Class_StoreVector); 897 set_mismatched_access(); 898 } 899 900 const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); } 901 uint length() const { return vect_type()->length(); } // Vector length 902 903 virtual int Opcode() const; 904 905 virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(memory_size()); } 906 virtual BasicType memory_type() const { return T_VOID; } 907 virtual int memory_size() const { return vect_type()->length_in_bytes(); } 908 909 static StoreVectorNode* make(int opc, Node* ctl, Node* mem, 910 Node* adr, const TypePtr* atyp, Node* val, 911 uint vlen); 912 913 uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); } 914 }; 915 916 //------------------------------StoreVectorScatterNode------------------------------ 917 // Store Vector into memory via index map 918 919 class StoreVectorScatterNode : public StoreVectorNode { 920 public: 921 StoreVectorScatterNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices) 922 : StoreVectorNode(c, mem, adr, at, val) { 923 init_class_id(Class_StoreVectorScatter); 924 assert(indices->bottom_type()->is_vect(), "indices must be in vector"); 925 add_req(indices); 926 assert(req() == MemNode::ValueIn + 2, "match_edge expects that last input is in MemNode::ValueIn+1"); 927 } 928 virtual int Opcode() const; 929 virtual uint match_edge(uint idx) const { return idx == MemNode::Address || 930 idx == MemNode::ValueIn || 931 idx == MemNode::ValueIn + 1; } 932 }; 933 934 //=========================Promote_Scalar_to_Vector============================ 935 936 //------------------------------ReplicateBNode--------------------------------- 937 // Replicate byte scalar to be vector 938 class ReplicateBNode : public VectorNode { 939 public: 940 ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 941 virtual int Opcode() const; 942 }; 943 944 //------------------------------ReplicateSNode--------------------------------- 945 // Replicate short scalar to be vector 946 class ReplicateSNode : public VectorNode { 947 public: 948 ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 949 virtual int Opcode() const; 950 }; 951 952 //------------------------------ReplicateINode--------------------------------- 953 // Replicate int scalar to be vector 954 class ReplicateINode : public VectorNode { 955 public: 956 ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 957 virtual int Opcode() const; 958 }; 959 960 //------------------------------ReplicateLNode--------------------------------- 961 // Replicate long scalar to be vector 962 class ReplicateLNode : public VectorNode { 963 public: 964 ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 965 virtual int Opcode() const; 966 }; 967 968 //------------------------------ReplicateFNode--------------------------------- 969 // Replicate float scalar to be vector 970 class ReplicateFNode : public VectorNode { 971 public: 972 ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 973 virtual int Opcode() const; 974 }; 975 976 //------------------------------ReplicateDNode--------------------------------- 977 // Replicate double scalar to be vector 978 class ReplicateDNode : public VectorNode { 979 public: 980 ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 981 virtual int Opcode() const; 982 }; 983 984 //========================Pack_Scalars_into_a_Vector=========================== 985 986 //------------------------------PackNode--------------------------------------- 987 // Pack parent class (not for code generation). 988 class PackNode : public VectorNode { 989 public: 990 PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 991 PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {} 992 virtual int Opcode() const; 993 994 void add_opd(Node* n) { 995 add_req(n); 996 } 997 998 // Create a binary tree form for Packs. [lo, hi) (half-open) range 999 PackNode* binary_tree_pack(int lo, int hi); 1000 1001 static PackNode* make(Node* s, uint vlen, BasicType bt); 1002 }; 1003 1004 //------------------------------PackBNode-------------------------------------- 1005 // Pack byte scalars into vector 1006 class PackBNode : public PackNode { 1007 public: 1008 PackBNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1009 virtual int Opcode() const; 1010 }; 1011 1012 //------------------------------PackSNode-------------------------------------- 1013 // Pack short scalars into a vector 1014 class PackSNode : public PackNode { 1015 public: 1016 PackSNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1017 PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1018 virtual int Opcode() const; 1019 }; 1020 1021 //------------------------------PackINode-------------------------------------- 1022 // Pack integer scalars into a vector 1023 class PackINode : public PackNode { 1024 public: 1025 PackINode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1026 PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1027 virtual int Opcode() const; 1028 }; 1029 1030 //------------------------------PackLNode-------------------------------------- 1031 // Pack long scalars into a vector 1032 class PackLNode : public PackNode { 1033 public: 1034 PackLNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1035 PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1036 virtual int Opcode() const; 1037 }; 1038 1039 //------------------------------Pack2LNode------------------------------------- 1040 // Pack 2 long scalars into a vector 1041 class Pack2LNode : public PackNode { 1042 public: 1043 Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1044 virtual int Opcode() const; 1045 }; 1046 1047 //------------------------------PackFNode-------------------------------------- 1048 // Pack float scalars into vector 1049 class PackFNode : public PackNode { 1050 public: 1051 PackFNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1052 PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1053 virtual int Opcode() const; 1054 }; 1055 1056 //------------------------------PackDNode-------------------------------------- 1057 // Pack double scalars into a vector 1058 class PackDNode : public PackNode { 1059 public: 1060 PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {} 1061 PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1062 virtual int Opcode() const; 1063 }; 1064 1065 //------------------------------Pack2DNode------------------------------------- 1066 // Pack 2 double scalars into a vector 1067 class Pack2DNode : public PackNode { 1068 public: 1069 Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {} 1070 virtual int Opcode() const; 1071 }; 1072 1073 1074 //========================Extract_Scalar_from_Vector=========================== 1075 1076 //------------------------------ExtractNode------------------------------------ 1077 // Extract a scalar from a vector at position "pos" 1078 class ExtractNode : public Node { 1079 public: 1080 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { 1081 assert(in(2)->get_int() >= 0, "positive constants"); 1082 } 1083 virtual int Opcode() const; 1084 uint pos() const { return in(2)->get_int(); } 1085 1086 static Node* make(Node* v, uint position, BasicType bt); 1087 static int opcode(BasicType bt); 1088 }; 1089 1090 //------------------------------ExtractBNode----------------------------------- 1091 // Extract a byte from a vector at position "pos" 1092 class ExtractBNode : public ExtractNode { 1093 public: 1094 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1095 virtual int Opcode() const; 1096 virtual const Type *bottom_type() const { return TypeInt::INT; } 1097 virtual uint ideal_reg() const { return Op_RegI; } 1098 }; 1099 1100 //------------------------------ExtractUBNode---------------------------------- 1101 // Extract a boolean from a vector at position "pos" 1102 class ExtractUBNode : public ExtractNode { 1103 public: 1104 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1105 virtual int Opcode() const; 1106 virtual const Type *bottom_type() const { return TypeInt::INT; } 1107 virtual uint ideal_reg() const { return Op_RegI; } 1108 }; 1109 1110 //------------------------------ExtractCNode----------------------------------- 1111 // Extract a char from a vector at position "pos" 1112 class ExtractCNode : public ExtractNode { 1113 public: 1114 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1115 virtual int Opcode() const; 1116 virtual const Type *bottom_type() const { return TypeInt::CHAR; } 1117 virtual uint ideal_reg() const { return Op_RegI; } 1118 }; 1119 1120 //------------------------------ExtractSNode----------------------------------- 1121 // Extract a short from a vector at position "pos" 1122 class ExtractSNode : public ExtractNode { 1123 public: 1124 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1125 virtual int Opcode() const; 1126 virtual const Type *bottom_type() const { return TypeInt::SHORT; } 1127 virtual uint ideal_reg() const { return Op_RegI; } 1128 }; 1129 1130 //------------------------------ExtractINode----------------------------------- 1131 // Extract an int from a vector at position "pos" 1132 class ExtractINode : public ExtractNode { 1133 public: 1134 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1135 virtual int Opcode() const; 1136 virtual const Type *bottom_type() const { return TypeInt::INT; } 1137 virtual uint ideal_reg() const { return Op_RegI; } 1138 }; 1139 1140 //------------------------------ExtractLNode----------------------------------- 1141 // Extract a long from a vector at position "pos" 1142 class ExtractLNode : public ExtractNode { 1143 public: 1144 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1145 virtual int Opcode() const; 1146 virtual const Type *bottom_type() const { return TypeLong::LONG; } 1147 virtual uint ideal_reg() const { return Op_RegL; } 1148 }; 1149 1150 //------------------------------ExtractFNode----------------------------------- 1151 // Extract a float from a vector at position "pos" 1152 class ExtractFNode : public ExtractNode { 1153 public: 1154 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1155 virtual int Opcode() const; 1156 virtual const Type *bottom_type() const { return Type::FLOAT; } 1157 virtual uint ideal_reg() const { return Op_RegF; } 1158 }; 1159 1160 //------------------------------ExtractDNode----------------------------------- 1161 // Extract a double from a vector at position "pos" 1162 class ExtractDNode : public ExtractNode { 1163 public: 1164 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1165 virtual int Opcode() const; 1166 virtual const Type *bottom_type() const { return Type::DOUBLE; } 1167 virtual uint ideal_reg() const { return Op_RegD; } 1168 }; 1169 1170 //------------------------------SetVectMaskINode------------------------------- 1171 // Provide a mask for a vector predicate machine 1172 class SetVectMaskINode : public Node { 1173 public: 1174 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {} 1175 virtual int Opcode() const; 1176 const Type *bottom_type() const { return TypeInt::INT; } 1177 virtual uint ideal_reg() const { return Op_RegI; } 1178 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } 1179 }; 1180 1181 class VectorBoxNode : public Node { 1182 private: 1183 const TypeInstPtr* const _box_type; 1184 const TypeVect* const _vec_type; 1185 public: 1186 enum { 1187 Box = 1, 1188 Value = 2 1189 }; 1190 VectorBoxNode(Compile* C, Node* box, Node* val, 1191 const TypeInstPtr* box_type, const TypeVect* vt) 1192 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) { 1193 init_flags(Flag_is_macro); 1194 C->add_macro_node(this); 1195 } 1196 1197 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; }; 1198 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; }; 1199 1200 virtual int Opcode() const; 1201 virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ } 1202 virtual uint ideal_reg() const { return box_type()->ideal_reg(); } 1203 virtual uint size_of() const { return sizeof(*this); } 1204 1205 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); 1206 }; 1207 1208 class VectorBoxAllocateNode : public CallStaticJavaNode { 1209 public: 1210 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) 1211 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) { 1212 init_flags(Flag_is_macro); 1213 C->add_macro_node(this); 1214 } 1215 1216 virtual int Opcode() const; 1217 #ifndef PRODUCT 1218 virtual void dump_spec(outputStream *st) const; 1219 #endif // PRODUCT 1220 }; 1221 1222 class VectorUnboxNode : public VectorNode { 1223 public: 1224 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem) 1225 : VectorNode(mem, obj, vec_type) { 1226 init_flags(Flag_is_macro); 1227 C->add_macro_node(this); 1228 } 1229 1230 virtual int Opcode() const; 1231 Node* obj() const { return in(2); } 1232 Node* mem() const { return in(1); } 1233 virtual Node *Identity(PhaseGVN *phase); 1234 }; 1235 1236 class VectorMaskCmpNode : public VectorNode { 1237 private: 1238 BoolTest::mask _predicate; 1239 1240 protected: 1241 uint size_of() const { return sizeof(*this); } 1242 1243 public: 1244 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, const TypeVect* vt) : 1245 VectorNode(in1, in2, vt), _predicate(predicate) { 1246 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1247 "VectorMaskCmp inputs must have same type for elements"); 1248 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1249 "VectorMaskCmp inputs must have same number of elements"); 1250 init_class_id(Class_VectorMaskCmp); 1251 } 1252 1253 virtual int Opcode() const; 1254 virtual uint hash() const { return VectorNode::hash() + _predicate; } 1255 virtual uint cmp( const Node &n ) const { 1256 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; 1257 } 1258 BoolTest::mask get_predicate() { return _predicate; } 1259 #ifndef PRODUCT 1260 virtual void dump_spec(outputStream *st) const; 1261 #endif // PRODUCT 1262 }; 1263 1264 // Used to wrap other vector nodes in order to add masking functionality. 1265 class VectorMaskWrapperNode : public VectorNode { 1266 public: 1267 VectorMaskWrapperNode(Node* vector, Node* mask) 1268 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { 1269 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); 1270 } 1271 1272 virtual int Opcode() const; 1273 Node* vector_val() const { return in(1); } 1274 Node* vector_mask() const { return in(2); } 1275 }; 1276 1277 class VectorTestNode : public Node { 1278 private: 1279 BoolTest::mask _predicate; 1280 1281 protected: 1282 uint size_of() const { return sizeof(*this); } 1283 1284 public: 1285 VectorTestNode( Node *in1, Node *in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) { 1286 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector"); 1287 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector"); 1288 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1289 "same type elements are needed"); 1290 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1291 "same number of elements is needed"); 1292 } 1293 virtual int Opcode() const; 1294 virtual uint hash() const { return Node::hash() + _predicate; } 1295 virtual uint cmp( const Node &n ) const { 1296 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; 1297 } 1298 virtual const Type *bottom_type() const { return TypeInt::BOOL; } 1299 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest 1300 // in middle-end, we make it boolean result directly. 1301 BoolTest::mask get_predicate() const { return _predicate; } 1302 }; 1303 1304 class VectorBlendNode : public VectorNode { 1305 public: 1306 VectorBlendNode(Node* vec1, Node* vec2, Node* mask) 1307 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { 1308 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1309 } 1310 1311 virtual int Opcode() const; 1312 Node* vec1() const { return in(1); } 1313 Node* vec2() const { return in(2); } 1314 Node* vec_mask() const { return in(3); } 1315 }; 1316 1317 class VectorRearrangeNode : public VectorNode { 1318 public: 1319 VectorRearrangeNode(Node* vec1, Node* shuffle) 1320 : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) { 1321 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1322 } 1323 1324 virtual int Opcode() const; 1325 Node* vec1() const { return in(1); } 1326 Node* vec_shuffle() const { return in(2); } 1327 }; 1328 1329 1330 class VectorLoadMaskNode : public VectorNode { 1331 public: 1332 VectorLoadMaskNode(Node* in, const TypeVect* vt) 1333 : VectorNode(in, vt) { 1334 assert(in->is_LoadVector(), "expected load vector"); 1335 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean"); 1336 } 1337 1338 int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1339 virtual int Opcode() const; 1340 }; 1341 1342 class VectorLoadShuffleNode : public VectorNode { 1343 public: 1344 VectorLoadShuffleNode(Node* in, const TypeVect* vt) 1345 : VectorNode(in, vt) { 1346 assert(in->is_LoadVector(), "expected load vector"); 1347 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BYTE, "must be BYTE"); 1348 } 1349 1350 int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1351 virtual int Opcode() const; 1352 }; 1353 1354 class VectorStoreMaskNode : public VectorNode { 1355 private: 1356 int _mask_size; 1357 protected: 1358 uint size_of() const { return sizeof(*this); } 1359 1360 public: 1361 VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem) 1362 : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) { 1363 _mask_size = type2aelembytes(in_type); 1364 } 1365 1366 virtual uint hash() const { return VectorNode::hash() + _mask_size; } 1367 virtual uint cmp( const Node &n ) const { 1368 return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size; 1369 } 1370 int GetInputMaskSize() const { return _mask_size; } 1371 virtual int Opcode() const; 1372 }; 1373 1374 // This is intended for use as a simple reinterpret node that has no cast. 1375 class VectorReinterpretNode : public VectorNode { 1376 private: 1377 const TypeVect* _src_vt; 1378 protected: 1379 uint size_of() const { return sizeof(*this); } 1380 public: 1381 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) 1382 : VectorNode(in, dst_vt), _src_vt(src_vt) { } 1383 1384 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } 1385 virtual uint cmp( const Node &n ) const { 1386 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); 1387 } 1388 virtual Node *Identity(PhaseGVN *phase); 1389 1390 virtual int Opcode() const; 1391 }; 1392 1393 class VectorCastNode : public VectorNode { 1394 public: 1395 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 1396 virtual int Opcode() const; 1397 1398 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); 1399 static int opcode(BasicType bt); 1400 static bool implemented(BasicType bt, uint vlen); 1401 }; 1402 1403 class VectorCastB2XNode : public VectorCastNode { 1404 public: 1405 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1406 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); 1407 } 1408 virtual int Opcode() const; 1409 }; 1410 1411 class VectorCastS2XNode : public VectorCastNode { 1412 public: 1413 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1414 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); 1415 } 1416 virtual int Opcode() const; 1417 }; 1418 1419 class VectorCastI2XNode : public VectorCastNode { 1420 public: 1421 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1422 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); 1423 } 1424 virtual int Opcode() const; 1425 }; 1426 1427 class VectorCastL2XNode : public VectorCastNode { 1428 public: 1429 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1430 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long"); 1431 } 1432 virtual int Opcode() const; 1433 }; 1434 1435 class VectorCastF2XNode : public VectorCastNode { 1436 public: 1437 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1438 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); 1439 } 1440 virtual int Opcode() const; 1441 }; 1442 1443 class VectorCastD2XNode : public VectorCastNode { 1444 public: 1445 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1446 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); 1447 } 1448 virtual int Opcode() const; 1449 }; 1450 1451 class VectorInsertNode : public VectorNode { 1452 public: 1453 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { 1454 assert(pos->get_int() >= 0, "positive constants"); 1455 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length"); 1456 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type"); 1457 } 1458 virtual int Opcode() const; 1459 uint pos() const { return in(3)->get_int(); } 1460 1461 static Node* make(Node* vec, Node* new_val, int position); 1462 }; 1463 1464 #endif // SHARE_OPTO_VECTORNODE_HPP