1 /*
   2  * Copyright (c) 2007, 2012, 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 
  32 //------------------------------VectorNode--------------------------------------
  33 // Vector Operation
  34 class VectorNode : public TypeNode {
  35  public:
  36 
  37   VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
  38     init_class_id(Class_Vector);
  39     init_req(1, n1);
  40   }
  41   VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
  42     init_class_id(Class_Vector);
  43     init_req(1, n1);
  44     init_req(2, n2);
  45   }
  46 
  47   const TypeVect* vect_type() const { return type()->is_vect(); }
  48   uint length() const { return vect_type()->length(); } // Vector length
  49 
  50   virtual int Opcode() const;
  51 
  52   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
  53 
  54   static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
  55 
  56   static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
  57 
  58   static int  opcode(int opc, uint vlen, BasicType bt);
  59   static bool implemented(int opc, uint vlen, BasicType bt);
  60 
  61 };
  62 
  63 //===========================Vector=ALU=Operations====================================
  64 
  65 //------------------------------AddVBNode---------------------------------------
  66 // Vector add byte
  67 class AddVBNode : public VectorNode {
  68  public:
  69   AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  70   virtual int Opcode() const;
  71 };
  72 
  73 //------------------------------AddVCNode---------------------------------------
  74 // Vector add char
  75 class AddVCNode : public VectorNode {
  76  public:
  77   AddVCNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  78   virtual int Opcode() const;
  79 };
  80 
  81 //------------------------------AddVSNode---------------------------------------
  82 // Vector add short
  83 class AddVSNode : public VectorNode {
  84  public:
  85   AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  86   virtual int Opcode() const;
  87 };
  88 
  89 //------------------------------AddVINode---------------------------------------
  90 // Vector add int
  91 class AddVINode : public VectorNode {
  92  public:
  93   AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
  94   virtual int Opcode() const;
  95 };
  96 
  97 //------------------------------AddVLNode---------------------------------------
  98 // Vector add long
  99 class AddVLNode : public VectorNode {
 100  public:
 101   AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 102   virtual int Opcode() const;
 103 };
 104 
 105 //------------------------------AddVFNode---------------------------------------
 106 // Vector add float
 107 class AddVFNode : public VectorNode {
 108  public:
 109   AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 110   virtual int Opcode() const;
 111 };
 112 
 113 //------------------------------AddVDNode---------------------------------------
 114 // Vector add double
 115 class AddVDNode : public VectorNode {
 116  public:
 117   AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 118   virtual int Opcode() const;
 119 };
 120 
 121 //------------------------------SubVBNode---------------------------------------
 122 // Vector subtract byte
 123 class SubVBNode : public VectorNode {
 124  public:
 125   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 126   virtual int Opcode() const;
 127 };
 128 
 129 //------------------------------SubVCNode---------------------------------------
 130 // Vector subtract char
 131 class SubVCNode : public VectorNode {
 132  public:
 133   SubVCNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 134   virtual int Opcode() const;
 135 };
 136 
 137 //------------------------------SubVSNode---------------------------------------
 138 // Vector subtract short
 139 class SubVSNode : public VectorNode {
 140  public:
 141   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 142   virtual int Opcode() const;
 143 };
 144 
 145 //------------------------------SubVINode---------------------------------------
 146 // Vector subtract int
 147 class SubVINode : public VectorNode {
 148  public:
 149   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 150   virtual int Opcode() const;
 151 };
 152 
 153 //------------------------------SubVLNode---------------------------------------
 154 // Vector subtract long
 155 class SubVLNode : public VectorNode {
 156  public:
 157   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 158   virtual int Opcode() const;
 159 };
 160 
 161 //------------------------------SubVFNode---------------------------------------
 162 // Vector subtract float
 163 class SubVFNode : public VectorNode {
 164  public:
 165   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 166   virtual int Opcode() const;
 167 };
 168 
 169 //------------------------------SubVDNode---------------------------------------
 170 // Vector subtract double
 171 class SubVDNode : public VectorNode {
 172  public:
 173   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 174   virtual int Opcode() const;
 175 };
 176 
 177 //------------------------------MulVFNode---------------------------------------
 178 // Vector multiply float
 179 class MulVFNode : public VectorNode {
 180  public:
 181   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 182   virtual int Opcode() const;
 183 };
 184 
 185 //------------------------------MulVDNode---------------------------------------
 186 // Vector multiply double
 187 class MulVDNode : public VectorNode {
 188  public:
 189   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 190   virtual int Opcode() const;
 191 };
 192 
 193 //------------------------------DivVFNode---------------------------------------
 194 // Vector divide float
 195 class DivVFNode : public VectorNode {
 196  public:
 197   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 198   virtual int Opcode() const;
 199 };
 200 
 201 //------------------------------DivVDNode---------------------------------------
 202 // Vector Divide double
 203 class DivVDNode : public VectorNode {
 204  public:
 205   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 206   virtual int Opcode() const;
 207 };
 208 
 209 //------------------------------LShiftVBNode---------------------------------------
 210 // Vector lshift byte
 211 class LShiftVBNode : public VectorNode {
 212  public:
 213   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 214   virtual int Opcode() const;
 215 };
 216 
 217 //------------------------------LShiftVCNode---------------------------------------
 218 // Vector lshift chars
 219 class LShiftVCNode : public VectorNode {
 220  public:
 221   LShiftVCNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 222   virtual int Opcode() const;
 223 };
 224 
 225 //------------------------------LShiftVSNode---------------------------------------
 226 // Vector lshift shorts
 227 class LShiftVSNode : public VectorNode {
 228  public:
 229   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 230   virtual int Opcode() const;
 231 };
 232 
 233 //------------------------------LShiftVINode---------------------------------------
 234 // Vector lshift ints
 235 class LShiftVINode : public VectorNode {
 236  public:
 237   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 238   virtual int Opcode() const;
 239 };
 240 
 241 //------------------------------URShiftVBNode---------------------------------------
 242 // Vector urshift bytes
 243 class RShiftVBNode : public VectorNode {
 244  public:
 245   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 246   virtual int Opcode() const;
 247 };
 248 
 249 //------------------------------URShiftVCNode---------------------------------------
 250 // Vector urshift char
 251 class RShiftVCNode : public VectorNode {
 252  public:
 253   RShiftVCNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 254   virtual int Opcode() const;
 255 };
 256 
 257 //------------------------------URShiftVSNode---------------------------------------
 258 // Vector urshift shorts
 259 class RShiftVSNode : public VectorNode {
 260  public:
 261   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 262   virtual int Opcode() const;
 263 };
 264 
 265 //------------------------------URShiftVINode---------------------------------------
 266 // Vector urshift ints
 267 class RShiftVINode : public VectorNode {
 268  public:
 269   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 270   virtual int Opcode() const;
 271 };
 272 
 273 //------------------------------AndVNode---------------------------------------
 274 // Vector and
 275 class AndVNode : public VectorNode {
 276  public:
 277   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 278   virtual int Opcode() const;
 279 };
 280 
 281 //------------------------------OrVNode---------------------------------------
 282 // Vector or
 283 class OrVNode : public VectorNode {
 284  public:
 285   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 286   virtual int Opcode() const;
 287 };
 288 
 289 //------------------------------XorVNode---------------------------------------
 290 // Vector xor
 291 class XorVNode : public VectorNode {
 292  public:
 293   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
 294   virtual int Opcode() const;
 295 };
 296 
 297 //================================= M E M O R Y ===============================
 298 
 299 //------------------------------LoadVectorNode---------------------------------
 300 // Load Vector from memory
 301 class LoadVectorNode : public LoadNode {
 302  public:
 303   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
 304     : LoadNode(c, mem, adr, at, vt) {
 305     init_class_id(Class_LoadVector);
 306   }
 307 
 308   const TypeVect* vect_type() const { return type()->is_vect(); }
 309   uint length() const { return vect_type()->length(); } // Vector length
 310 
 311   virtual int Opcode() const;
 312 
 313   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 314   virtual BasicType memory_type() const { return T_VOID; }
 315   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 316 
 317   virtual int store_Opcode() const { return Op_StoreVector; }
 318 
 319   static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
 320                               Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
 321 };
 322 
 323 //------------------------------StoreVectorNode--------------------------------
 324 // Store Vector to memory
 325 class StoreVectorNode : public StoreNode {
 326  public:
 327   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
 328     : StoreNode(c, mem, adr, at, val) {
 329     assert(val->is_Vector() || val->is_LoadVector(), "sanity");
 330     init_class_id(Class_StoreVector);
 331   }
 332 
 333   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
 334   uint length() const { return vect_type()->length(); } // Vector length
 335 
 336   virtual int Opcode() const;
 337 
 338   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
 339   virtual BasicType memory_type() const { return T_VOID; }
 340   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 341 
 342   static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
 343                                Node* adr, const TypePtr* atyp, Node* val,
 344                                uint vlen);
 345 };
 346 
 347 
 348 //=========================Promote_Scalar_to_Vector============================
 349 
 350 //------------------------------ReplicateBNode---------------------------------
 351 // Replicate byte scalar to be vector
 352 class ReplicateBNode : public VectorNode {
 353  public:
 354   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 355   virtual int Opcode() const;
 356 };
 357 
 358 //------------------------------ReplicateCNode---------------------------------
 359 // Replicate char scalar to be vector
 360 class ReplicateCNode : public VectorNode {
 361  public:
 362   ReplicateCNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 363   virtual int Opcode() const;
 364 };
 365 
 366 //------------------------------ReplicateSNode---------------------------------
 367 // Replicate short scalar to be vector
 368 class ReplicateSNode : public VectorNode {
 369  public:
 370   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 371   virtual int Opcode() const;
 372 };
 373 
 374 //------------------------------ReplicateINode---------------------------------
 375 // Replicate int scalar to be vector
 376 class ReplicateINode : public VectorNode {
 377  public:
 378   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 379   virtual int Opcode() const;
 380 };
 381 
 382 //------------------------------ReplicateLNode---------------------------------
 383 // Replicate long scalar to be vector
 384 class ReplicateLNode : public VectorNode {
 385  public:
 386   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 387   virtual int Opcode() const;
 388 };
 389 
 390 //------------------------------ReplicateFNode---------------------------------
 391 // Replicate float scalar to be vector
 392 class ReplicateFNode : public VectorNode {
 393  public:
 394   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 395   virtual int Opcode() const;
 396 };
 397 
 398 //------------------------------ReplicateDNode---------------------------------
 399 // Replicate double scalar to be vector
 400 class ReplicateDNode : public VectorNode {
 401  public:
 402   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 403   virtual int Opcode() const;
 404 };
 405 
 406 //========================Pack_Scalars_into_a_Vector===========================
 407 
 408 //------------------------------PackNode---------------------------------------
 409 // Pack parent class (not for code generation).
 410 class PackNode : public VectorNode {
 411  public:
 412   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
 413   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
 414   virtual int Opcode() const;
 415 
 416   void add_opd(uint i, Node* n) {
 417     init_req(i+1, n);
 418   }
 419 
 420   // Create a binary tree form for Packs. [lo, hi) (half-open) range
 421   Node* binaryTreePack(Compile* C, int lo, int hi);
 422 
 423   static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
 424 };
 425 
 426 //------------------------------PackBNode---------------------------------------
 427 // Pack byte scalars into vector
 428 class PackBNode : public PackNode {
 429  public:
 430   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 431   virtual int Opcode() const;
 432 };
 433 
 434 //------------------------------PackCNode---------------------------------------
 435 // Pack char scalars into vector
 436 class PackCNode : public PackNode {
 437  public:
 438   PackCNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 439   virtual int Opcode() const;
 440 };
 441 
 442 //------------------------------PackSNode---------------------------------------
 443 // Pack short scalars into a vector
 444 class PackSNode : public PackNode {
 445  public:
 446   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 447   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 448   virtual int Opcode() const;
 449 };
 450 
 451 //------------------------------PackINode---------------------------------------
 452 // Pack integer scalars into a vector
 453 class PackINode : public PackNode {
 454  public:
 455   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 456   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 457   virtual int Opcode() const;
 458 };
 459 
 460 //------------------------------PackLNode---------------------------------------
 461 // Pack long scalars into a vector
 462 class PackLNode : public PackNode {
 463  public:
 464   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 465   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 466   virtual int Opcode() const;
 467 };
 468 
 469 //------------------------------Pack2LNode--------------------------------------
 470 // Pack 2 long scalars into a vector
 471 class Pack2LNode : public PackNode {
 472  public:
 473   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 474   virtual int Opcode() const;
 475 };
 476 
 477 //------------------------------PackFNode---------------------------------------
 478 // Pack float scalars into vector
 479 class PackFNode : public PackNode {
 480  public:
 481   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
 482   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 483   virtual int Opcode() const;
 484 };
 485 
 486 //------------------------------PackDNode---------------------------------------
 487 // Pack double scalars into a vector
 488 class PackDNode : public PackNode {
 489  public:
 490   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
 491   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 492   virtual int Opcode() const;
 493 };
 494 
 495 //------------------------------Pack2DNode--------------------------------------
 496 // Pack 2 double scalars into a vector
 497 class Pack2DNode : public PackNode {
 498  public:
 499   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
 500   virtual int Opcode() const;
 501 };
 502 
 503 
 504 //========================Extract_Scalar_from_Vector===============================
 505 
 506 //------------------------------ExtractNode---------------------------------------
 507 // Extract a scalar from a vector at position "pos"
 508 class ExtractNode : public Node {
 509  public:
 510   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
 511     assert(in(2)->get_int() >= 0, "positive constants");
 512   }
 513   virtual int Opcode() const;
 514   uint  pos() const { return in(2)->get_int(); }
 515 
 516   static Node* make(Compile* C, Node* v, uint position, BasicType bt);
 517 };
 518 
 519 //------------------------------ExtractBNode---------------------------------------
 520 // Extract a byte from a vector at position "pos"
 521 class ExtractBNode : public ExtractNode {
 522  public:
 523   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 524   virtual int Opcode() const;
 525   virtual const Type *bottom_type() const { return TypeInt::INT; }
 526   virtual uint ideal_reg() const { return Op_RegI; }
 527 };
 528 
 529 //------------------------------ExtractCNode---------------------------------------
 530 // Extract a char from a vector at position "pos"
 531 class ExtractCNode : public ExtractNode {
 532  public:
 533   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 534   virtual int Opcode() const;
 535   virtual const Type *bottom_type() const { return TypeInt::INT; }
 536   virtual uint ideal_reg() const { return Op_RegI; }
 537 };
 538 
 539 //------------------------------ExtractSNode---------------------------------------
 540 // Extract a short from a vector at position "pos"
 541 class ExtractSNode : public ExtractNode {
 542  public:
 543   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 544   virtual int Opcode() const;
 545   virtual const Type *bottom_type() const { return TypeInt::INT; }
 546   virtual uint ideal_reg() const { return Op_RegI; }
 547 };
 548 
 549 //------------------------------ExtractINode---------------------------------------
 550 // Extract an int from a vector at position "pos"
 551 class ExtractINode : public ExtractNode {
 552  public:
 553   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 554   virtual int Opcode() const;
 555   virtual const Type *bottom_type() const { return TypeInt::INT; }
 556   virtual uint ideal_reg() const { return Op_RegI; }
 557 };
 558 
 559 //------------------------------ExtractLNode---------------------------------------
 560 // Extract a long from a vector at position "pos"
 561 class ExtractLNode : public ExtractNode {
 562  public:
 563   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 564   virtual int Opcode() const;
 565   virtual const Type *bottom_type() const { return TypeLong::LONG; }
 566   virtual uint ideal_reg() const { return Op_RegL; }
 567 };
 568 
 569 //------------------------------ExtractFNode---------------------------------------
 570 // Extract a float from a vector at position "pos"
 571 class ExtractFNode : public ExtractNode {
 572  public:
 573   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 574   virtual int Opcode() const;
 575   virtual const Type *bottom_type() const { return Type::FLOAT; }
 576   virtual uint ideal_reg() const { return Op_RegF; }
 577 };
 578 
 579 //------------------------------ExtractDNode---------------------------------------
 580 // Extract a double from a vector at position "pos"
 581 class ExtractDNode : public ExtractNode {
 582  public:
 583   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
 584   virtual int Opcode() const;
 585   virtual const Type *bottom_type() const { return Type::DOUBLE; }
 586   virtual uint ideal_reg() const { return Op_RegD; }
 587 };
 588 
 589 #endif // SHARE_VM_OPTO_VECTORNODE_HPP