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 class VectorLoadConstNode : public VectorNode { 1075 public: 1076 VectorLoadConstNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {} 1077 virtual int Opcode() const; 1078 }; 1079 1080 //========================Extract_Scalar_from_Vector=========================== 1081 1082 //------------------------------ExtractNode------------------------------------ 1083 // Extract a scalar from a vector at position "pos" 1084 class ExtractNode : public Node { 1085 public: 1086 ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) { 1087 assert(in(2)->get_int() >= 0, "positive constants"); 1088 } 1089 virtual int Opcode() const; 1090 uint pos() const { return in(2)->get_int(); } 1091 1092 static Node* make(Node* v, uint position, BasicType bt); 1093 static int opcode(BasicType bt); 1094 }; 1095 1096 //------------------------------ExtractBNode----------------------------------- 1097 // Extract a byte from a vector at position "pos" 1098 class ExtractBNode : public ExtractNode { 1099 public: 1100 ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1101 virtual int Opcode() const; 1102 virtual const Type *bottom_type() const { return TypeInt::INT; } 1103 virtual uint ideal_reg() const { return Op_RegI; } 1104 }; 1105 1106 //------------------------------ExtractUBNode---------------------------------- 1107 // Extract a boolean from a vector at position "pos" 1108 class ExtractUBNode : public ExtractNode { 1109 public: 1110 ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1111 virtual int Opcode() const; 1112 virtual const Type *bottom_type() const { return TypeInt::INT; } 1113 virtual uint ideal_reg() const { return Op_RegI; } 1114 }; 1115 1116 //------------------------------ExtractCNode----------------------------------- 1117 // Extract a char from a vector at position "pos" 1118 class ExtractCNode : public ExtractNode { 1119 public: 1120 ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1121 virtual int Opcode() const; 1122 virtual const Type *bottom_type() const { return TypeInt::CHAR; } 1123 virtual uint ideal_reg() const { return Op_RegI; } 1124 }; 1125 1126 //------------------------------ExtractSNode----------------------------------- 1127 // Extract a short from a vector at position "pos" 1128 class ExtractSNode : public ExtractNode { 1129 public: 1130 ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1131 virtual int Opcode() const; 1132 virtual const Type *bottom_type() const { return TypeInt::SHORT; } 1133 virtual uint ideal_reg() const { return Op_RegI; } 1134 }; 1135 1136 //------------------------------ExtractINode----------------------------------- 1137 // Extract an int from a vector at position "pos" 1138 class ExtractINode : public ExtractNode { 1139 public: 1140 ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1141 virtual int Opcode() const; 1142 virtual const Type *bottom_type() const { return TypeInt::INT; } 1143 virtual uint ideal_reg() const { return Op_RegI; } 1144 }; 1145 1146 //------------------------------ExtractLNode----------------------------------- 1147 // Extract a long from a vector at position "pos" 1148 class ExtractLNode : public ExtractNode { 1149 public: 1150 ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1151 virtual int Opcode() const; 1152 virtual const Type *bottom_type() const { return TypeLong::LONG; } 1153 virtual uint ideal_reg() const { return Op_RegL; } 1154 }; 1155 1156 //------------------------------ExtractFNode----------------------------------- 1157 // Extract a float from a vector at position "pos" 1158 class ExtractFNode : public ExtractNode { 1159 public: 1160 ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1161 virtual int Opcode() const; 1162 virtual const Type *bottom_type() const { return Type::FLOAT; } 1163 virtual uint ideal_reg() const { return Op_RegF; } 1164 }; 1165 1166 //------------------------------ExtractDNode----------------------------------- 1167 // Extract a double from a vector at position "pos" 1168 class ExtractDNode : public ExtractNode { 1169 public: 1170 ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {} 1171 virtual int Opcode() const; 1172 virtual const Type *bottom_type() const { return Type::DOUBLE; } 1173 virtual uint ideal_reg() const { return Op_RegD; } 1174 }; 1175 1176 //------------------------------SetVectMaskINode------------------------------- 1177 // Provide a mask for a vector predicate machine 1178 class SetVectMaskINode : public Node { 1179 public: 1180 SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {} 1181 virtual int Opcode() const; 1182 const Type *bottom_type() const { return TypeInt::INT; } 1183 virtual uint ideal_reg() const { return Op_RegI; } 1184 virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; } 1185 }; 1186 1187 class VectorBoxNode : public Node { 1188 private: 1189 const TypeInstPtr* const _box_type; 1190 const TypeVect* const _vec_type; 1191 public: 1192 enum { 1193 Box = 1, 1194 Value = 2 1195 }; 1196 VectorBoxNode(Compile* C, Node* box, Node* val, 1197 const TypeInstPtr* box_type, const TypeVect* vt) 1198 : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) { 1199 init_flags(Flag_is_macro); 1200 C->add_macro_node(this); 1201 } 1202 1203 const TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; }; 1204 const TypeVect* vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; }; 1205 1206 virtual int Opcode() const; 1207 virtual const Type *bottom_type() const { return _box_type; /* TypeInstPtr::BOTTOM? */ } 1208 virtual uint ideal_reg() const { return box_type()->ideal_reg(); } 1209 virtual uint size_of() const { return sizeof(*this); } 1210 1211 static const TypeFunc* vec_box_type(const TypeInstPtr* box_type); 1212 }; 1213 1214 class VectorBoxAllocateNode : public CallStaticJavaNode { 1215 public: 1216 VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type) 1217 : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) { 1218 init_flags(Flag_is_macro); 1219 C->add_macro_node(this); 1220 } 1221 1222 virtual int Opcode() const; 1223 #ifndef PRODUCT 1224 virtual void dump_spec(outputStream *st) const; 1225 #endif // PRODUCT 1226 }; 1227 1228 class VectorUnboxNode : public VectorNode { 1229 public: 1230 VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem) 1231 : VectorNode(mem, obj, vec_type) { 1232 init_flags(Flag_is_macro); 1233 C->add_macro_node(this); 1234 } 1235 1236 virtual int Opcode() const; 1237 Node* obj() const { return in(2); } 1238 Node* mem() const { return in(1); } 1239 virtual Node *Identity(PhaseGVN *phase); 1240 }; 1241 1242 class VectorMaskCmpNode : public VectorNode { 1243 private: 1244 BoolTest::mask _predicate; 1245 1246 protected: 1247 uint size_of() const { return sizeof(*this); } 1248 1249 public: 1250 VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, const TypeVect* vt) : 1251 VectorNode(in1, in2, vt), _predicate(predicate) { 1252 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1253 "VectorMaskCmp inputs must have same type for elements"); 1254 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1255 "VectorMaskCmp inputs must have same number of elements"); 1256 init_class_id(Class_VectorMaskCmp); 1257 } 1258 1259 virtual int Opcode() const; 1260 virtual uint hash() const { return VectorNode::hash() + _predicate; } 1261 virtual uint cmp( const Node &n ) const { 1262 return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; 1263 } 1264 BoolTest::mask get_predicate() { return _predicate; } 1265 #ifndef PRODUCT 1266 virtual void dump_spec(outputStream *st) const; 1267 #endif // PRODUCT 1268 }; 1269 1270 // Used to wrap other vector nodes in order to add masking functionality. 1271 class VectorMaskWrapperNode : public VectorNode { 1272 public: 1273 VectorMaskWrapperNode(Node* vector, Node* mask) 1274 : VectorNode(vector, mask, vector->bottom_type()->is_vect()) { 1275 assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask"); 1276 } 1277 1278 virtual int Opcode() const; 1279 Node* vector_val() const { return in(1); } 1280 Node* vector_mask() const { return in(2); } 1281 }; 1282 1283 class VectorTestNode : public Node { 1284 private: 1285 BoolTest::mask _predicate; 1286 1287 protected: 1288 uint size_of() const { return sizeof(*this); } 1289 1290 public: 1291 VectorTestNode( Node *in1, Node *in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) { 1292 assert(in1->is_Vector() || in1->is_LoadVector(), "must be vector"); 1293 assert(in2->is_Vector() || in2->is_LoadVector(), "must be vector"); 1294 assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(), 1295 "same type elements are needed"); 1296 assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(), 1297 "same number of elements is needed"); 1298 } 1299 virtual int Opcode() const; 1300 virtual uint hash() const { return Node::hash() + _predicate; } 1301 virtual uint cmp( const Node &n ) const { 1302 return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate; 1303 } 1304 virtual const Type *bottom_type() const { return TypeInt::BOOL; } 1305 virtual uint ideal_reg() const { return Op_RegI; } // TODO Should be RegFlags but due to missing comparison flags for BoolTest 1306 // in middle-end, we make it boolean result directly. 1307 BoolTest::mask get_predicate() const { return _predicate; } 1308 }; 1309 1310 class VectorBlendNode : public VectorNode { 1311 public: 1312 VectorBlendNode(Node* vec1, Node* vec2, Node* mask) 1313 : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) { 1314 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1315 } 1316 1317 virtual int Opcode() const; 1318 Node* vec1() const { return in(1); } 1319 Node* vec2() const { return in(2); } 1320 Node* vec_mask() const { return in(3); } 1321 }; 1322 1323 class VectorRearrangeNode : public VectorNode { 1324 public: 1325 VectorRearrangeNode(Node* vec1, Node* shuffle) 1326 : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) { 1327 // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask"); 1328 } 1329 1330 virtual int Opcode() const; 1331 Node* vec1() const { return in(1); } 1332 Node* vec_shuffle() const { return in(2); } 1333 }; 1334 1335 1336 class VectorLoadMaskNode : public VectorNode { 1337 public: 1338 VectorLoadMaskNode(Node* in, const TypeVect* vt) 1339 : VectorNode(in, vt) { 1340 assert(in->is_LoadVector(), "expected load vector"); 1341 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BOOLEAN, "must be boolean"); 1342 } 1343 1344 int GetOutMaskSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1345 virtual int Opcode() const; 1346 }; 1347 1348 class VectorLoadShuffleNode : public VectorNode { 1349 public: 1350 VectorLoadShuffleNode(Node* in, const TypeVect* vt) 1351 : VectorNode(in, vt) { 1352 assert(in->is_LoadVector(), "expected load vector"); 1353 assert(in->as_LoadVector()->vect_type()->element_basic_type() == T_BYTE, "must be BYTE"); 1354 } 1355 1356 int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); } 1357 virtual int Opcode() const; 1358 }; 1359 1360 class VectorStoreMaskNode : public VectorNode { 1361 private: 1362 int _mask_size; 1363 protected: 1364 uint size_of() const { return sizeof(*this); } 1365 1366 public: 1367 VectorStoreMaskNode(Node* in, BasicType in_type, uint num_elem) 1368 : VectorNode(in, TypeVect::make(T_BOOLEAN, num_elem)) { 1369 _mask_size = type2aelembytes(in_type); 1370 } 1371 1372 virtual uint hash() const { return VectorNode::hash() + _mask_size; } 1373 virtual uint cmp( const Node &n ) const { 1374 return VectorNode::cmp(n) && _mask_size == ((VectorStoreMaskNode&)n)._mask_size; 1375 } 1376 int GetInputMaskSize() const { return _mask_size; } 1377 virtual int Opcode() const; 1378 }; 1379 1380 // This is intended for use as a simple reinterpret node that has no cast. 1381 class VectorReinterpretNode : public VectorNode { 1382 private: 1383 const TypeVect* _src_vt; 1384 protected: 1385 uint size_of() const { return sizeof(*this); } 1386 public: 1387 VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt) 1388 : VectorNode(in, dst_vt), _src_vt(src_vt) { } 1389 1390 virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); } 1391 virtual uint cmp( const Node &n ) const { 1392 return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt); 1393 } 1394 virtual Node *Identity(PhaseGVN *phase); 1395 1396 virtual int Opcode() const; 1397 }; 1398 1399 class VectorCastNode : public VectorNode { 1400 public: 1401 VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} 1402 virtual int Opcode() const; 1403 1404 static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); 1405 static int opcode(BasicType bt); 1406 static bool implemented(BasicType bt, uint vlen); 1407 }; 1408 1409 class VectorCastB2XNode : public VectorCastNode { 1410 public: 1411 VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1412 assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); 1413 } 1414 virtual int Opcode() const; 1415 }; 1416 1417 class VectorCastS2XNode : public VectorCastNode { 1418 public: 1419 VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1420 assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); 1421 } 1422 virtual int Opcode() const; 1423 }; 1424 1425 class VectorCastI2XNode : public VectorCastNode { 1426 public: 1427 VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1428 assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); 1429 } 1430 virtual int Opcode() const; 1431 }; 1432 1433 class VectorCastL2XNode : public VectorCastNode { 1434 public: 1435 VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1436 assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long"); 1437 } 1438 virtual int Opcode() const; 1439 }; 1440 1441 class VectorCastF2XNode : public VectorCastNode { 1442 public: 1443 VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1444 assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); 1445 } 1446 virtual int Opcode() const; 1447 }; 1448 1449 class VectorCastD2XNode : public VectorCastNode { 1450 public: 1451 VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { 1452 assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); 1453 } 1454 virtual int Opcode() const; 1455 }; 1456 1457 class VectorInsertNode : public VectorNode { 1458 public: 1459 VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) { 1460 assert(pos->get_int() >= 0, "positive constants"); 1461 assert(pos->get_int() < (int)vt->length(), "index must be less than vector length"); 1462 assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type"); 1463 } 1464 virtual int Opcode() const; 1465 uint pos() const { return in(3)->get_int(); } 1466 1467 static Node* make(Node* vec, Node* new_val, int position); 1468 }; 1469 1470 #endif // SHARE_OPTO_VECTORNODE_HPP