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