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