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/callnode.hpp"
28 #include "opto/matcher.hpp"
29 #include "opto/memnode.hpp"
30 #include "opto/node.hpp"
31 #include "opto/opcodes.hpp"
32 
33 //------------------------------VectorNode-------------------------------------
34 // Vector Operation
35 class VectorNode : public TypeNode {
36  public:
37 
VectorNode(Node * n1,const TypeVect * vt)38   VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
39     init_class_id(Class_Vector);
40     init_req(1, n1);
41   }
VectorNode(Node * n1,Node * n2,const TypeVect * vt)42   VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
43     init_class_id(Class_Vector);
44     init_req(1, n1);
45     init_req(2, n2);
46   }
47 
VectorNode(Node * n1,Node * n2,Node * n3,const TypeVect * vt)48   VectorNode(Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 4) {
49     init_class_id(Class_Vector);
50     init_req(1, n1);
51     init_req(2, n2);
52     init_req(3, n3);
53   }
54 
VectorNode(Node * n0,Node * n1,Node * n2,Node * n3,const TypeVect * vt)55   VectorNode(Node *n0, Node* n1, Node* n2, Node* n3, const TypeVect* vt) : TypeNode(vt, 5) {
56     init_class_id(Class_Vector);
57     init_req(1, n0);
58     init_req(2, n1);
59     init_req(3, n2);
60     init_req(4, n3);
61   }
62 
vect_type() const63   const TypeVect* vect_type() const { return type()->is_vect(); }
length() const64   uint length() const { return vect_type()->length(); } // Vector length
length_in_bytes() const65   uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
66 
67   virtual int Opcode() const;
68 
ideal_reg() const69   virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
70 
71   static VectorNode* scalar2vector(Node* s, uint vlen, const Type* opd_t);
72   static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt);
73   static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
74   static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt);
75   static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
76   static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
77 
78   static bool is_shift_opcode(int opc);
79 
80   static int  opcode(int opc, BasicType bt);
81   static int replicate_opcode(BasicType bt);
82   static bool implemented(int opc, uint vlen, BasicType bt);
83   static bool is_shift(Node* n);
84   static bool is_vshift_cnt(Node* n);
85   static bool is_type_transition_short_to_int(Node* n);
86   static bool is_type_transition_to_int(Node* n);
87   static bool is_muladds2i(Node* n);
88   static bool is_roundopD(Node* n);
89   static bool is_scalar_rotate(Node* n);
90   static bool is_vector_rotate_supported(int vopc, uint vlen, BasicType bt);
91   static bool is_invariant_vector(Node* n);
92   static bool is_all_ones_vector(Node* n);
93   static bool is_vector_bitwise_not_pattern(Node* n);
94   static Node* degenerate_vector_rotate(Node* n1, Node* n2, bool is_rotate_left, int vlen,
95                                         BasicType bt, PhaseGVN* phase);
96 
97   // [Start, end) half-open range defining which operands are vectors
98   static void vector_operands(Node* n, uint* start, uint* end);
99 
100   static bool is_vector_shift(int opc);
101   static bool is_vector_shift_count(int opc);
102 
is_vector_shift(Node * n)103   static bool is_vector_shift(Node* n) {
104     return is_vector_shift(n->Opcode());
105   }
is_vector_shift_count(Node * n)106   static bool is_vector_shift_count(Node* n) {
107     return is_vector_shift_count(n->Opcode());
108   }
109 };
110 
111 //===========================Vector=ALU=Operations=============================
112 
113 //------------------------------AddVBNode--------------------------------------
114 // Vector add byte
115 class AddVBNode : public VectorNode {
116  public:
AddVBNode(Node * in1,Node * in2,const TypeVect * vt)117   AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
118   virtual int Opcode() const;
119 };
120 
121 //------------------------------AddVSNode--------------------------------------
122 // Vector add char/short
123 class AddVSNode : public VectorNode {
124  public:
AddVSNode(Node * in1,Node * in2,const TypeVect * vt)125   AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
126   virtual int Opcode() const;
127 };
128 
129 //------------------------------AddVINode--------------------------------------
130 // Vector add int
131 class AddVINode : public VectorNode {
132  public:
AddVINode(Node * in1,Node * in2,const TypeVect * vt)133   AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
134   virtual int Opcode() const;
135 };
136 
137 //------------------------------AddVLNode--------------------------------------
138 // Vector add long
139 class AddVLNode : public VectorNode {
140 public:
AddVLNode(Node * in1,Node * in2,const TypeVect * vt)141   AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
142   virtual int Opcode() const;
143 };
144 
145 //------------------------------AddVFNode--------------------------------------
146 // Vector add float
147 class AddVFNode : public VectorNode {
148 public:
AddVFNode(Node * in1,Node * in2,const TypeVect * vt)149   AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
150   virtual int Opcode() const;
151 };
152 
153 //------------------------------AddVDNode--------------------------------------
154 // Vector add double
155 class AddVDNode : public VectorNode {
156 public:
AddVDNode(Node * in1,Node * in2,const TypeVect * vt)157   AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
158   virtual int Opcode() const;
159 };
160 
161 //------------------------------ReductionNode------------------------------------
162 // Perform reduction of a vector
163 class ReductionNode : public Node {
164  public:
ReductionNode(Node * ctrl,Node * in1,Node * in2)165   ReductionNode(Node *ctrl, Node* in1, Node* in2) : Node(ctrl, in1, in2) {}
166 
167   static ReductionNode* make(int opc, Node *ctrl, Node* in1, Node* in2, BasicType bt);
168   static int  opcode(int opc, BasicType bt);
169   static bool implemented(int opc, uint vlen, BasicType bt);
170   static Node* make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt);
171 
bottom_type() const172   virtual const Type* bottom_type() const {
173     BasicType vbt = in(1)->bottom_type()->basic_type();
174     return Type::get_const_basic_type(vbt);
175   }
176 
ideal_reg() const177   virtual uint ideal_reg() const {
178     return bottom_type()->ideal_reg();
179   }
180 };
181 
182 //------------------------------AddReductionVINode--------------------------------------
183 // Vector add byte, short and int as a reduction
184 class AddReductionVINode : public ReductionNode {
185 public:
AddReductionVINode(Node * ctrl,Node * in1,Node * in2)186   AddReductionVINode(Node * ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
187   virtual int Opcode() const;
188 };
189 
190 //------------------------------AddReductionVLNode--------------------------------------
191 // Vector add long as a reduction
192 class AddReductionVLNode : public ReductionNode {
193 public:
AddReductionVLNode(Node * ctrl,Node * in1,Node * in2)194   AddReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
195   virtual int Opcode() const;
196 };
197 
198 //------------------------------AddReductionVFNode--------------------------------------
199 // Vector add float as a reduction
200 class AddReductionVFNode : public ReductionNode {
201 public:
AddReductionVFNode(Node * ctrl,Node * in1,Node * in2)202   AddReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
203   virtual int Opcode() const;
204 };
205 
206 //------------------------------AddReductionVDNode--------------------------------------
207 // Vector add double as a reduction
208 class AddReductionVDNode : public ReductionNode {
209 public:
AddReductionVDNode(Node * ctrl,Node * in1,Node * in2)210   AddReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
211   virtual int Opcode() const;
212 };
213 
214 //------------------------------SubVBNode--------------------------------------
215 // Vector subtract byte
216 class SubVBNode : public VectorNode {
217  public:
SubVBNode(Node * in1,Node * in2,const TypeVect * vt)218   SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
219   virtual int Opcode() const;
220 };
221 
222 //------------------------------SubVSNode--------------------------------------
223 // Vector subtract short
224 class SubVSNode : public VectorNode {
225  public:
SubVSNode(Node * in1,Node * in2,const TypeVect * vt)226   SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
227   virtual int Opcode() const;
228 };
229 
230 //------------------------------SubVINode--------------------------------------
231 // Vector subtract int
232 class SubVINode : public VectorNode {
233  public:
SubVINode(Node * in1,Node * in2,const TypeVect * vt)234   SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
235   virtual int Opcode() const;
236 };
237 
238 //------------------------------SubVLNode--------------------------------------
239 // Vector subtract long
240 class SubVLNode : public VectorNode {
241  public:
SubVLNode(Node * in1,Node * in2,const TypeVect * vt)242   SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
243   virtual int Opcode() const;
244 };
245 
246 //------------------------------SubVFNode--------------------------------------
247 // Vector subtract float
248 class SubVFNode : public VectorNode {
249  public:
SubVFNode(Node * in1,Node * in2,const TypeVect * vt)250   SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
251   virtual int Opcode() const;
252 };
253 
254 //------------------------------SubVDNode--------------------------------------
255 // Vector subtract double
256 class SubVDNode : public VectorNode {
257  public:
SubVDNode(Node * in1,Node * in2,const TypeVect * vt)258   SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
259   virtual int Opcode() const;
260 };
261 
262 //------------------------------MulVBNode--------------------------------------
263 // Vector multiply byte
264 class MulVBNode : public VectorNode {
265  public:
MulVBNode(Node * in1,Node * in2,const TypeVect * vt)266   MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
267   virtual int Opcode() const;
268 };
269 
270 //------------------------------MulVSNode--------------------------------------
271 // Vector multiply short
272 class MulVSNode : public VectorNode {
273  public:
MulVSNode(Node * in1,Node * in2,const TypeVect * vt)274   MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
275   virtual int Opcode() const;
276 };
277 
278 //------------------------------MulVINode--------------------------------------
279 // Vector multiply int
280 class MulVINode : public VectorNode {
281  public:
MulVINode(Node * in1,Node * in2,const TypeVect * vt)282   MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
283   virtual int Opcode() const;
284 };
285 
286 //------------------------------MulVLNode--------------------------------------
287 // Vector multiply long
288 class MulVLNode : public VectorNode {
289 public:
MulVLNode(Node * in1,Node * in2,const TypeVect * vt)290   MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
291   virtual int Opcode() const;
292 };
293 
294 //------------------------------MulVFNode--------------------------------------
295 // Vector multiply float
296 class MulVFNode : public VectorNode {
297 public:
MulVFNode(Node * in1,Node * in2,const TypeVect * vt)298   MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
299   virtual int Opcode() const;
300 };
301 
302 //------------------------------MulVDNode--------------------------------------
303 // Vector multiply double
304 class MulVDNode : public VectorNode {
305 public:
MulVDNode(Node * in1,Node * in2,const TypeVect * vt)306   MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
307   virtual int Opcode() const;
308 };
309 
310 //------------------------------MulAddVS2VINode--------------------------------
311 // Vector multiply shorts to int and add adjacent ints.
312 class MulAddVS2VINode : public VectorNode {
313   public:
MulAddVS2VINode(Node * in1,Node * in2,const TypeVect * vt)314     MulAddVS2VINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
315     virtual int Opcode() const;
316 };
317 
318 //------------------------------FmaVDNode--------------------------------------
319 // Vector multiply double
320 class FmaVDNode : public VectorNode {
321 public:
FmaVDNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)322   FmaVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
323   virtual int Opcode() const;
324 };
325 
326 //------------------------------FmaVFNode--------------------------------------
327 // Vector multiply float
328 class FmaVFNode : public VectorNode {
329 public:
FmaVFNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)330   FmaVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
331   virtual int Opcode() const;
332 };
333 
334 //------------------------------CMoveVFNode--------------------------------------
335 // Vector float conditional move
336 class CMoveVFNode : public VectorNode {
337 public:
CMoveVFNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)338   CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
339   virtual int Opcode() const;
340 };
341 
342 //------------------------------CMoveVDNode--------------------------------------
343 // Vector double conditional move
344 class CMoveVDNode : public VectorNode {
345 public:
CMoveVDNode(Node * in1,Node * in2,Node * in3,const TypeVect * vt)346   CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {}
347   virtual int Opcode() const;
348 };
349 
350 //------------------------------MulReductionVINode--------------------------------------
351 // Vector multiply byte, short and int as a reduction
352 class MulReductionVINode : public ReductionNode {
353 public:
MulReductionVINode(Node * ctrl,Node * in1,Node * in2)354   MulReductionVINode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
355   virtual int Opcode() const;
356 };
357 
358 //------------------------------MulReductionVLNode--------------------------------------
359 // Vector multiply int as a reduction
360 class MulReductionVLNode : public ReductionNode {
361 public:
MulReductionVLNode(Node * ctrl,Node * in1,Node * in2)362   MulReductionVLNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
363   virtual int Opcode() const;
364 };
365 
366 //------------------------------MulReductionVFNode--------------------------------------
367 // Vector multiply float as a reduction
368 class MulReductionVFNode : public ReductionNode {
369 public:
MulReductionVFNode(Node * ctrl,Node * in1,Node * in2)370   MulReductionVFNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
371   virtual int Opcode() const;
372 };
373 
374 //------------------------------MulReductionVDNode--------------------------------------
375 // Vector multiply double as a reduction
376 class MulReductionVDNode : public ReductionNode {
377 public:
MulReductionVDNode(Node * ctrl,Node * in1,Node * in2)378   MulReductionVDNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
379   virtual int Opcode() const;
380 };
381 
382 //------------------------------DivVFNode--------------------------------------
383 // Vector divide float
384 class DivVFNode : public VectorNode {
385  public:
DivVFNode(Node * in1,Node * in2,const TypeVect * vt)386   DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
387   virtual int Opcode() const;
388 };
389 
390 //------------------------------DivVDNode--------------------------------------
391 // Vector Divide double
392 class DivVDNode : public VectorNode {
393  public:
DivVDNode(Node * in1,Node * in2,const TypeVect * vt)394   DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
395   virtual int Opcode() const;
396 };
397 
398 //------------------------------AbsVBNode--------------------------------------
399 // Vector Abs byte
400 class AbsVBNode : public VectorNode {
401 public:
AbsVBNode(Node * in,const TypeVect * vt)402   AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
403   virtual int Opcode() const;
404 };
405 
406 //------------------------------AbsVSNode--------------------------------------
407 // Vector Abs short
408 class AbsVSNode : public VectorNode {
409 public:
AbsVSNode(Node * in,const TypeVect * vt)410   AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
411   virtual int Opcode() const;
412 };
413 
414 //------------------------------MinVNode--------------------------------------
415 // Vector Min
416 class MinVNode : public VectorNode {
417 public:
MinVNode(Node * in1,Node * in2,const TypeVect * vt)418   MinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
419   virtual int Opcode() const;
420 };
421 
422 //------------------------------MaxVNode--------------------------------------
423 // Vector Max
424 class MaxVNode : public VectorNode {
425  public:
MaxVNode(Node * in1,Node * in2,const TypeVect * vt)426   MaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
427   virtual int Opcode() const;
428 };
429 
430 //------------------------------AbsVINode--------------------------------------
431 // Vector Abs int
432 class AbsVINode : public VectorNode {
433  public:
AbsVINode(Node * in,const TypeVect * vt)434   AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
435   virtual int Opcode() const;
436 };
437 
438 //------------------------------AbsVLNode--------------------------------------
439 // Vector Abs long
440 class AbsVLNode : public VectorNode {
441 public:
AbsVLNode(Node * in,const TypeVect * vt)442   AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
443   virtual int Opcode() const;
444 };
445 
446 //------------------------------AbsVFNode--------------------------------------
447 // Vector Abs float
448 class AbsVFNode : public VectorNode {
449  public:
AbsVFNode(Node * in,const TypeVect * vt)450   AbsVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
451   virtual int Opcode() const;
452 };
453 
454 //------------------------------AbsVDNode--------------------------------------
455 // Vector Abs double
456 class AbsVDNode : public VectorNode {
457  public:
AbsVDNode(Node * in,const TypeVect * vt)458   AbsVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
459   virtual int Opcode() const;
460 };
461 
462 //------------------------------NegVINode--------------------------------------
463 // Vector Neg int
464 class NegVINode : public VectorNode {
465  public:
NegVINode(Node * in,const TypeVect * vt)466   NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
467   virtual int Opcode() const;
468 };
469 
470 //------------------------------NegVFNode--------------------------------------
471 // Vector Neg float
472 class NegVFNode : public VectorNode {
473  public:
NegVFNode(Node * in,const TypeVect * vt)474   NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
475   virtual int Opcode() const;
476 };
477 
478 //------------------------------NegVDNode--------------------------------------
479 // Vector Neg double
480 class NegVDNode : public VectorNode {
481  public:
NegVDNode(Node * in,const TypeVect * vt)482   NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
483   virtual int Opcode() const;
484 };
485 
486 //------------------------------PopCountVINode---------------------------------
487 // Vector popcount integer bits
488 class PopCountVINode : public VectorNode {
489  public:
PopCountVINode(Node * in,const TypeVect * vt)490   PopCountVINode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
491   virtual int Opcode() const;
492 };
493 
494 //------------------------------SqrtVFNode--------------------------------------
495 // Vector Sqrt float
496 class SqrtVFNode : public VectorNode {
497  public:
SqrtVFNode(Node * in,const TypeVect * vt)498   SqrtVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
499   virtual int Opcode() const;
500 };
501 //------------------------------RoundDoubleVNode--------------------------------
502 // Vector round double
503 class RoundDoubleModeVNode : public VectorNode {
504  public:
RoundDoubleModeVNode(Node * in1,Node * in2,const TypeVect * vt)505   RoundDoubleModeVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
506   virtual int Opcode() const;
507 };
508 
509 //------------------------------SqrtVDNode--------------------------------------
510 // Vector Sqrt double
511 class SqrtVDNode : public VectorNode {
512  public:
SqrtVDNode(Node * in,const TypeVect * vt)513   SqrtVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
514   virtual int Opcode() const;
515 };
516 
517 //------------------------------LShiftVBNode-----------------------------------
518 // Vector left shift bytes
519 class LShiftVBNode : public VectorNode {
520  public:
LShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)521   LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
522   virtual int Opcode() const;
523 };
524 
525 //------------------------------LShiftVSNode-----------------------------------
526 // Vector left shift shorts
527 class LShiftVSNode : public VectorNode {
528  public:
LShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)529   LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
530   virtual int Opcode() const;
531 };
532 
533 //------------------------------LShiftVINode-----------------------------------
534 // Vector left shift ints
535 class LShiftVINode : public VectorNode {
536  public:
LShiftVINode(Node * in1,Node * in2,const TypeVect * vt)537   LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
538   virtual int Opcode() const;
539 };
540 
541 //------------------------------LShiftVLNode-----------------------------------
542 // Vector left shift longs
543 class LShiftVLNode : public VectorNode {
544  public:
LShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)545   LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
546   virtual int Opcode() const;
547 };
548 
549 //------------------------------RShiftVBNode-----------------------------------
550 // Vector right arithmetic (signed) shift bytes
551 class RShiftVBNode : public VectorNode {
552  public:
RShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)553   RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
554   virtual int Opcode() const;
555 };
556 
557 //------------------------------RShiftVSNode-----------------------------------
558 // Vector right arithmetic (signed) shift shorts
559 class RShiftVSNode : public VectorNode {
560  public:
RShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)561   RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
562   virtual int Opcode() const;
563 };
564 
565 //------------------------------RShiftVINode-----------------------------------
566 // Vector right arithmetic (signed) shift ints
567 class RShiftVINode : public VectorNode {
568  public:
RShiftVINode(Node * in1,Node * in2,const TypeVect * vt)569   RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
570   virtual int Opcode() const;
571 };
572 
573 //------------------------------RShiftVLNode-----------------------------------
574 // Vector right arithmetic (signed) shift longs
575 class RShiftVLNode : public VectorNode {
576  public:
RShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)577   RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
578   virtual int Opcode() const;
579 };
580 
581 //------------------------------URShiftVBNode----------------------------------
582 // Vector right logical (unsigned) shift bytes
583 class URShiftVBNode : public VectorNode {
584  public:
URShiftVBNode(Node * in1,Node * in2,const TypeVect * vt)585   URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
586   virtual int Opcode() const;
587 };
588 
589 //------------------------------URShiftVSNode----------------------------------
590 // Vector right logical (unsigned) shift shorts
591 class URShiftVSNode : public VectorNode {
592  public:
URShiftVSNode(Node * in1,Node * in2,const TypeVect * vt)593   URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
594   virtual int Opcode() const;
595 };
596 
597 //------------------------------URShiftVINode----------------------------------
598 // Vector right logical (unsigned) shift ints
599 class URShiftVINode : public VectorNode {
600  public:
URShiftVINode(Node * in1,Node * in2,const TypeVect * vt)601   URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
602   virtual int Opcode() const;
603 };
604 
605 //------------------------------URShiftVLNode----------------------------------
606 // Vector right logical (unsigned) shift longs
607 class URShiftVLNode : public VectorNode {
608  public:
URShiftVLNode(Node * in1,Node * in2,const TypeVect * vt)609   URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
610   virtual int Opcode() const;
611 };
612 
613 //------------------------------LShiftCntVNode---------------------------------
614 // Vector left shift count
615 class LShiftCntVNode : public VectorNode {
616  public:
LShiftCntVNode(Node * cnt,const TypeVect * vt)617   LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
618   virtual int Opcode() const;
619 };
620 
621 //------------------------------RShiftCntVNode---------------------------------
622 // Vector right shift count
623 class RShiftCntVNode : public VectorNode {
624  public:
RShiftCntVNode(Node * cnt,const TypeVect * vt)625   RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
626   virtual int Opcode() const;
627 };
628 
629 //------------------------------AndVNode---------------------------------------
630 // Vector and integer
631 class AndVNode : public VectorNode {
632  public:
AndVNode(Node * in1,Node * in2,const TypeVect * vt)633   AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
634   virtual int Opcode() const;
635 };
636 
637 //------------------------------AndReductionVNode--------------------------------------
638 // Vector and byte, short, int, long as a reduction
639 class AndReductionVNode : public ReductionNode {
640  public:
AndReductionVNode(Node * ctrl,Node * in1,Node * in2)641   AndReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
642   virtual int Opcode() const;
643 };
644 
645 //------------------------------OrVNode---------------------------------------
646 // Vector or byte, short, int, long as a reduction
647 class OrVNode : public VectorNode {
648  public:
OrVNode(Node * in1,Node * in2,const TypeVect * vt)649   OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
650   virtual int Opcode() const;
651 };
652 
653 //------------------------------OrReductionVNode--------------------------------------
654 // Vector xor byte, short, int, long as a reduction
655 class OrReductionVNode : public ReductionNode {
656  public:
OrReductionVNode(Node * ctrl,Node * in1,Node * in2)657   OrReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
658   virtual int Opcode() const;
659 };
660 
661 //------------------------------XorReductionVNode--------------------------------------
662 // Vector and int, long as a reduction
663 class XorReductionVNode : public ReductionNode {
664  public:
XorReductionVNode(Node * ctrl,Node * in1,Node * in2)665   XorReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
666   virtual int Opcode() const;
667 };
668 
669 //------------------------------XorVNode---------------------------------------
670 // Vector xor integer
671 class XorVNode : public VectorNode {
672  public:
XorVNode(Node * in1,Node * in2,const TypeVect * vt)673   XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
674   virtual int Opcode() const;
675 };
676 
677 //------------------------------MinReductionVNode--------------------------------------
678 // Vector min byte, short, int, long, float, double as a reduction
679 class MinReductionVNode : public ReductionNode {
680 public:
MinReductionVNode(Node * ctrl,Node * in1,Node * in2)681   MinReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
682   virtual int Opcode() const;
683 };
684 
685 //------------------------------MaxReductionVNode--------------------------------------
686 // Vector min byte, short, int, long, float, double as a reduction
687 class MaxReductionVNode : public ReductionNode {
688 public:
MaxReductionVNode(Node * ctrl,Node * in1,Node * in2)689   MaxReductionVNode(Node *ctrl, Node* in1, Node* in2) : ReductionNode(ctrl, in1, in2) {}
690   virtual int Opcode() const;
691 };
692 
693 //================================= M E M O R Y ===============================
694 
695 //------------------------------LoadVectorNode---------------------------------
696 // Load Vector from memory
697 class LoadVectorNode : public LoadNode {
698  public:
LoadVectorNode(Node * c,Node * mem,Node * adr,const TypePtr * at,const TypeVect * vt,ControlDependency control_dependency=LoadNode::DependsOnlyOnTest)699   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
700     : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
701     init_class_id(Class_LoadVector);
702     set_mismatched_access();
703   }
704 
vect_type() const705   const TypeVect* vect_type() const { return type()->is_vect(); }
length() const706   uint length() const { return vect_type()->length(); } // Vector length
707 
708   virtual int Opcode() const;
709 
ideal_reg() const710   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
memory_type() const711   virtual BasicType memory_type() const { return T_VOID; }
memory_size() const712   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
713 
store_Opcode() const714   virtual int store_Opcode() const { return Op_StoreVector; }
715 
716   static LoadVectorNode* make(int opc, Node* ctl, Node* mem,
717                               Node* adr, const TypePtr* atyp,
718                               uint vlen, BasicType bt,
719                               ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
element_size(void)720   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
721 };
722 
723 //------------------------------LoadVectorGatherNode------------------------------
724 // Load Vector from memory via index map
725 class LoadVectorGatherNode : public LoadVectorNode {
726  public:
LoadVectorGatherNode(Node * c,Node * mem,Node * adr,const TypePtr * at,const TypeVect * vt,Node * indices)727   LoadVectorGatherNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, Node* indices)
728     : LoadVectorNode(c, mem, adr, at, vt) {
729     init_class_id(Class_LoadVectorGather);
730     assert(indices->bottom_type()->is_vect(), "indices must be in vector");
731     add_req(indices);
732     assert(req() == MemNode::ValueIn + 1, "match_edge expects that last input is in MemNode::ValueIn");
733   }
734 
735   virtual int Opcode() const;
match_edge(uint idx) const736   virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; }
737 };
738 
739 //------------------------------StoreVectorNode--------------------------------
740 // Store Vector to memory
741 class StoreVectorNode : public StoreNode {
742  public:
StoreVectorNode(Node * c,Node * mem,Node * adr,const TypePtr * at,Node * val)743   StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
744     : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
745     init_class_id(Class_StoreVector);
746     set_mismatched_access();
747   }
748 
vect_type() const749   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
length() const750   uint length() const { return vect_type()->length(); } // Vector length
751 
752   virtual int Opcode() const;
753 
ideal_reg() const754   virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
memory_type() const755   virtual BasicType memory_type() const { return T_VOID; }
memory_size() const756   virtual int memory_size() const { return vect_type()->length_in_bytes(); }
757 
758   static StoreVectorNode* make(int opc, Node* ctl, Node* mem,
759                                Node* adr, const TypePtr* atyp, Node* val,
760                                uint vlen);
761 
element_size(void)762   uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
763 };
764 
765 //------------------------------StoreVectorScatterNode------------------------------
766 // Store Vector into memory via index map
767 
768  class StoreVectorScatterNode : public StoreVectorNode {
769   public:
StoreVectorScatterNode(Node * c,Node * mem,Node * adr,const TypePtr * at,Node * val,Node * indices)770    StoreVectorScatterNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices)
771      : StoreVectorNode(c, mem, adr, at, val) {
772      init_class_id(Class_StoreVectorScatter);
773      assert(indices->bottom_type()->is_vect(), "indices must be in vector");
774      add_req(indices);
775      assert(req() == MemNode::ValueIn + 2, "match_edge expects that last input is in MemNode::ValueIn+1");
776    }
777    virtual int Opcode() const;
match_edge(uint idx) const778    virtual uint match_edge(uint idx) const { return idx == MemNode::Address ||
779                                                      idx == MemNode::ValueIn ||
780                                                      idx == MemNode::ValueIn + 1; }
781 };
782 
783 class StoreVectorMaskedNode : public StoreVectorNode {
784  public:
StoreVectorMaskedNode(Node * c,Node * mem,Node * dst,Node * src,const TypePtr * at,Node * mask)785   StoreVectorMaskedNode(Node* c, Node* mem, Node* dst, Node* src, const TypePtr* at, Node* mask)
786    : StoreVectorNode(c, mem, dst, at, src) {
787     assert(mask->bottom_type()->is_long(), "sanity");
788     init_class_id(Class_StoreVector);
789     set_mismatched_access();
790     add_req(mask);
791   }
792 
793   virtual int Opcode() const;
794 
match_edge(uint idx) const795   virtual uint match_edge(uint idx) const {
796     return idx > 1;
797   }
798   Node* Ideal(PhaseGVN* phase, bool can_reshape);
799 };
800 
801 class LoadVectorMaskedNode : public LoadVectorNode {
802  public:
LoadVectorMaskedNode(Node * c,Node * mem,Node * src,const TypePtr * at,const TypeVect * vt,Node * mask)803   LoadVectorMaskedNode(Node* c, Node* mem, Node* src, const TypePtr* at, const TypeVect* vt, Node* mask)
804    : LoadVectorNode(c, mem, src, at, vt) {
805     assert(mask->bottom_type()->is_long(), "sanity");
806     init_class_id(Class_LoadVector);
807     set_mismatched_access();
808     add_req(mask);
809   }
810 
811   virtual int Opcode() const;
812 
match_edge(uint idx) const813   virtual uint match_edge(uint idx) const {
814     return idx > 1;
815   }
816   Node* Ideal(PhaseGVN* phase, bool can_reshape);
817 };
818 
819 class VectorMaskGenNode : public TypeNode {
820  public:
VectorMaskGenNode(Node * length,const Type * ty,const Type * ety)821   VectorMaskGenNode(Node* length, const Type* ty, const Type* ety): TypeNode(ty, 2), _elemType(ety) {
822     init_req(1, length);
823   }
824 
825   virtual int Opcode() const;
get_elem_type()826   const Type* get_elem_type()  { return _elemType;}
size_of() const827   virtual  uint  size_of() const { return sizeof(VectorMaskGenNode); }
828 
829   private:
830    const Type* _elemType;
831 };
832 
833 //=========================Promote_Scalar_to_Vector============================
834 
835 //------------------------------ReplicateBNode---------------------------------
836 // Replicate byte scalar to be vector
837 class ReplicateBNode : public VectorNode {
838  public:
ReplicateBNode(Node * in1,const TypeVect * vt)839   ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
840   virtual int Opcode() const;
841 };
842 
843 //------------------------------ReplicateSNode---------------------------------
844 // Replicate short scalar to be vector
845 class ReplicateSNode : public VectorNode {
846  public:
ReplicateSNode(Node * in1,const TypeVect * vt)847   ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
848   virtual int Opcode() const;
849 };
850 
851 //------------------------------ReplicateINode---------------------------------
852 // Replicate int scalar to be vector
853 class ReplicateINode : public VectorNode {
854  public:
ReplicateINode(Node * in1,const TypeVect * vt)855   ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
856   virtual int Opcode() const;
857 };
858 
859 //------------------------------ReplicateLNode---------------------------------
860 // Replicate long scalar to be vector
861 class ReplicateLNode : public VectorNode {
862  public:
ReplicateLNode(Node * in1,const TypeVect * vt)863   ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
864   virtual int Opcode() const;
865 };
866 
867 //------------------------------ReplicateFNode---------------------------------
868 // Replicate float scalar to be vector
869 class ReplicateFNode : public VectorNode {
870  public:
ReplicateFNode(Node * in1,const TypeVect * vt)871   ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
872   virtual int Opcode() const;
873 };
874 
875 //------------------------------ReplicateDNode---------------------------------
876 // Replicate double scalar to be vector
877 class ReplicateDNode : public VectorNode {
878  public:
ReplicateDNode(Node * in1,const TypeVect * vt)879   ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
880   virtual int Opcode() const;
881 };
882 
883 //========================Pack_Scalars_into_a_Vector===========================
884 
885 //------------------------------PackNode---------------------------------------
886 // Pack parent class (not for code generation).
887 class PackNode : public VectorNode {
888  public:
PackNode(Node * in1,const TypeVect * vt)889   PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
PackNode(Node * in1,Node * n2,const TypeVect * vt)890   PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
891   virtual int Opcode() const;
892 
add_opd(Node * n)893   void add_opd(Node* n) {
894     add_req(n);
895   }
896 
897   // Create a binary tree form for Packs. [lo, hi) (half-open) range
898   PackNode* binary_tree_pack(int lo, int hi);
899 
900   static PackNode* make(Node* s, uint vlen, BasicType bt);
901 };
902 
903 //------------------------------PackBNode--------------------------------------
904 // Pack byte scalars into vector
905 class PackBNode : public PackNode {
906  public:
PackBNode(Node * in1,const TypeVect * vt)907   PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
908   virtual int Opcode() const;
909 };
910 
911 //------------------------------PackSNode--------------------------------------
912 // Pack short scalars into a vector
913 class PackSNode : public PackNode {
914  public:
PackSNode(Node * in1,const TypeVect * vt)915   PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
PackSNode(Node * in1,Node * in2,const TypeVect * vt)916   PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
917   virtual int Opcode() const;
918 };
919 
920 //------------------------------PackINode--------------------------------------
921 // Pack integer scalars into a vector
922 class PackINode : public PackNode {
923  public:
PackINode(Node * in1,const TypeVect * vt)924   PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
PackINode(Node * in1,Node * in2,const TypeVect * vt)925   PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
926   virtual int Opcode() const;
927 };
928 
929 //------------------------------PackLNode--------------------------------------
930 // Pack long scalars into a vector
931 class PackLNode : public PackNode {
932  public:
PackLNode(Node * in1,const TypeVect * vt)933   PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
PackLNode(Node * in1,Node * in2,const TypeVect * vt)934   PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
935   virtual int Opcode() const;
936 };
937 
938 //------------------------------Pack2LNode-------------------------------------
939 // Pack 2 long scalars into a vector
940 class Pack2LNode : public PackNode {
941  public:
Pack2LNode(Node * in1,Node * in2,const TypeVect * vt)942   Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
943   virtual int Opcode() const;
944 };
945 
946 //------------------------------PackFNode--------------------------------------
947 // Pack float scalars into vector
948 class PackFNode : public PackNode {
949  public:
PackFNode(Node * in1,const TypeVect * vt)950   PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
PackFNode(Node * in1,Node * in2,const TypeVect * vt)951   PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
952   virtual int Opcode() const;
953 };
954 
955 //------------------------------PackDNode--------------------------------------
956 // Pack double scalars into a vector
957 class PackDNode : public PackNode {
958  public:
PackDNode(Node * in1,const TypeVect * vt)959   PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
PackDNode(Node * in1,Node * in2,const TypeVect * vt)960   PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
961   virtual int Opcode() const;
962 };
963 
964 //------------------------------Pack2DNode-------------------------------------
965 // Pack 2 double scalars into a vector
966 class Pack2DNode : public PackNode {
967  public:
Pack2DNode(Node * in1,Node * in2,const TypeVect * vt)968   Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
969   virtual int Opcode() const;
970 };
971 
972 
973 class VectorLoadConstNode : public VectorNode {
974  public:
VectorLoadConstNode(Node * in1,const TypeVect * vt)975   VectorLoadConstNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
976   virtual int Opcode() const;
977 };
978 
979 //========================Extract_Scalar_from_Vector===========================
980 
981 //------------------------------ExtractNode------------------------------------
982 // Extract a scalar from a vector at position "pos"
983 class ExtractNode : public Node {
984  public:
ExtractNode(Node * src,ConINode * pos)985   ExtractNode(Node* src, ConINode* pos) : Node(NULL, src, (Node*)pos) {
986     assert(in(2)->get_int() >= 0, "positive constants");
987   }
988   virtual int Opcode() const;
pos() const989   uint  pos() const { return in(2)->get_int(); }
990 
991   static Node* make(Node* v, uint position, BasicType bt);
992   static int opcode(BasicType bt);
993 };
994 
995 //------------------------------ExtractBNode-----------------------------------
996 // Extract a byte from a vector at position "pos"
997 class ExtractBNode : public ExtractNode {
998  public:
ExtractBNode(Node * src,ConINode * pos)999   ExtractBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1000   virtual int Opcode() const;
bottom_type() const1001   virtual const Type *bottom_type() const { return TypeInt::INT; }
ideal_reg() const1002   virtual uint ideal_reg() const { return Op_RegI; }
1003 };
1004 
1005 //------------------------------ExtractUBNode----------------------------------
1006 // Extract a boolean from a vector at position "pos"
1007 class ExtractUBNode : public ExtractNode {
1008  public:
ExtractUBNode(Node * src,ConINode * pos)1009   ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1010   virtual int Opcode() const;
bottom_type() const1011   virtual const Type *bottom_type() const { return TypeInt::INT; }
ideal_reg() const1012   virtual uint ideal_reg() const { return Op_RegI; }
1013 };
1014 
1015 //------------------------------ExtractCNode-----------------------------------
1016 // Extract a char from a vector at position "pos"
1017 class ExtractCNode : public ExtractNode {
1018  public:
ExtractCNode(Node * src,ConINode * pos)1019   ExtractCNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1020   virtual int Opcode() const;
bottom_type() const1021   virtual const Type *bottom_type() const { return TypeInt::CHAR; }
ideal_reg() const1022   virtual uint ideal_reg() const { return Op_RegI; }
1023 };
1024 
1025 //------------------------------ExtractSNode-----------------------------------
1026 // Extract a short from a vector at position "pos"
1027 class ExtractSNode : public ExtractNode {
1028  public:
ExtractSNode(Node * src,ConINode * pos)1029   ExtractSNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1030   virtual int Opcode() const;
bottom_type() const1031   virtual const Type *bottom_type() const { return TypeInt::SHORT; }
ideal_reg() const1032   virtual uint ideal_reg() const { return Op_RegI; }
1033 };
1034 
1035 //------------------------------ExtractINode-----------------------------------
1036 // Extract an int from a vector at position "pos"
1037 class ExtractINode : public ExtractNode {
1038  public:
ExtractINode(Node * src,ConINode * pos)1039   ExtractINode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1040   virtual int Opcode() const;
bottom_type() const1041   virtual const Type *bottom_type() const { return TypeInt::INT; }
ideal_reg() const1042   virtual uint ideal_reg() const { return Op_RegI; }
1043 };
1044 
1045 //------------------------------ExtractLNode-----------------------------------
1046 // Extract a long from a vector at position "pos"
1047 class ExtractLNode : public ExtractNode {
1048  public:
ExtractLNode(Node * src,ConINode * pos)1049   ExtractLNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1050   virtual int Opcode() const;
bottom_type() const1051   virtual const Type *bottom_type() const { return TypeLong::LONG; }
ideal_reg() const1052   virtual uint ideal_reg() const { return Op_RegL; }
1053 };
1054 
1055 //------------------------------ExtractFNode-----------------------------------
1056 // Extract a float from a vector at position "pos"
1057 class ExtractFNode : public ExtractNode {
1058  public:
ExtractFNode(Node * src,ConINode * pos)1059   ExtractFNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1060   virtual int Opcode() const;
bottom_type() const1061   virtual const Type *bottom_type() const { return Type::FLOAT; }
ideal_reg() const1062   virtual uint ideal_reg() const { return Op_RegF; }
1063 };
1064 
1065 //------------------------------ExtractDNode-----------------------------------
1066 // Extract a double from a vector at position "pos"
1067 class ExtractDNode : public ExtractNode {
1068  public:
ExtractDNode(Node * src,ConINode * pos)1069   ExtractDNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
1070   virtual int Opcode() const;
bottom_type() const1071   virtual const Type *bottom_type() const { return Type::DOUBLE; }
ideal_reg() const1072   virtual uint ideal_reg() const { return Op_RegD; }
1073 };
1074 
1075 //------------------------------SetVectMaskINode-------------------------------
1076 // Provide a mask for a vector predicate machine
1077 class SetVectMaskINode : public Node {
1078 public:
SetVectMaskINode(Node * c,Node * in1)1079   SetVectMaskINode(Node *c, Node *in1) : Node(c, in1) {}
1080   virtual int Opcode() const;
bottom_type() const1081   const Type *bottom_type() const { return TypeInt::INT; }
ideal_reg() const1082   virtual uint ideal_reg() const { return Op_RegI; }
Value(PhaseGVN * phase) const1083   virtual const Type *Value(PhaseGVN *phase) const { return TypeInt::INT; }
1084 };
1085 
1086 //------------------------------MacroLogicVNode-------------------------------
1087 // Vector logical operations packing node.
1088 class MacroLogicVNode : public VectorNode {
1089 private:
MacroLogicVNode(Node * in1,Node * in2,Node * in3,Node * fn,const TypeVect * vt)1090   MacroLogicVNode(Node* in1, Node* in2, Node* in3, Node* fn, const TypeVect* vt)
1091   : VectorNode(in1, in2, in3, fn, vt) {}
1092 
1093 public:
1094   virtual int Opcode() const;
1095 
1096   static MacroLogicVNode* make(PhaseGVN& igvn, Node* in1, Node* in2, Node* in3, uint truth_table, const TypeVect* vt);
1097 };
1098 
1099 class VectorMaskCmpNode : public VectorNode {
1100  private:
1101   BoolTest::mask _predicate;
1102 
1103  protected:
size_of() const1104   uint size_of() const { return sizeof(*this); }
1105 
1106  public:
VectorMaskCmpNode(BoolTest::mask predicate,Node * in1,Node * in2,ConINode * predicate_node,const TypeVect * vt)1107   VectorMaskCmpNode(BoolTest::mask predicate, Node* in1, Node* in2, ConINode* predicate_node, const TypeVect* vt) :
1108       VectorNode(in1, in2, predicate_node, vt),
1109       _predicate(predicate) {
1110     assert(in1->bottom_type()->is_vect()->element_basic_type() == in2->bottom_type()->is_vect()->element_basic_type(),
1111            "VectorMaskCmp inputs must have same type for elements");
1112     assert(in1->bottom_type()->is_vect()->length() == in2->bottom_type()->is_vect()->length(),
1113            "VectorMaskCmp inputs must have same number of elements");
1114     init_class_id(Class_VectorMaskCmp);
1115   }
1116 
1117   virtual int Opcode() const;
hash() const1118   virtual uint hash() const { return VectorNode::hash() + _predicate; }
cmp(const Node & n) const1119   virtual bool cmp( const Node &n ) const {
1120     return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate;
1121   }
get_predicate()1122   BoolTest::mask get_predicate() { return _predicate; }
1123 #ifndef PRODUCT
1124   virtual void dump_spec(outputStream *st) const;
1125 #endif // !PRODUCT
1126 };
1127 
1128 // Used to wrap other vector nodes in order to add masking functionality.
1129 class VectorMaskWrapperNode : public VectorNode {
1130  public:
VectorMaskWrapperNode(Node * vector,Node * mask)1131   VectorMaskWrapperNode(Node* vector, Node* mask)
1132     : VectorNode(vector, mask, vector->bottom_type()->is_vect()) {
1133     assert(mask->is_VectorMaskCmp(), "VectorMaskWrapper requires that second argument be a mask");
1134   }
1135 
1136   virtual int Opcode() const;
vector_val() const1137   Node* vector_val() const { return in(1); }
vector_mask() const1138   Node* vector_mask() const { return in(2); }
1139 };
1140 
1141 class VectorTestNode : public Node {
1142  private:
1143   BoolTest::mask _predicate;
1144 
1145  protected:
size_of() const1146   uint size_of() const { return sizeof(*this); }
1147 
1148  public:
VectorTestNode(Node * in1,Node * in2,BoolTest::mask predicate)1149   VectorTestNode(Node* in1, Node* in2, BoolTest::mask predicate) : Node(NULL, in1, in2), _predicate(predicate) {
1150     assert(in2->bottom_type()->is_vect() == in2->bottom_type()->is_vect(), "same vector type");
1151   }
1152   virtual int Opcode() const;
hash() const1153   virtual uint hash() const { return Node::hash() + _predicate; }
cmp(const Node & n) const1154   virtual bool cmp( const Node &n ) const {
1155     return Node::cmp(n) && _predicate == ((VectorTestNode&)n)._predicate;
1156   }
bottom_type() const1157   virtual const Type *bottom_type() const { return TypeInt::BOOL; }
ideal_reg() const1158   virtual uint ideal_reg() const { return Op_RegI; }  // TODO Should be RegFlags but due to missing comparison flags for BoolTest
1159                                                       // in middle-end, we make it boolean result directly.
get_predicate() const1160   BoolTest::mask get_predicate() const { return _predicate; }
1161 };
1162 
1163 class VectorBlendNode : public VectorNode {
1164  public:
VectorBlendNode(Node * vec1,Node * vec2,Node * mask)1165   VectorBlendNode(Node* vec1, Node* vec2, Node* mask)
1166     : VectorNode(vec1, vec2, mask, vec1->bottom_type()->is_vect()) {
1167     // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1168   }
1169 
1170   virtual int Opcode() const;
vec1() const1171   Node* vec1() const { return in(1); }
vec2() const1172   Node* vec2() const { return in(2); }
vec_mask() const1173   Node* vec_mask() const { return in(3); }
1174 };
1175 
1176 class VectorRearrangeNode : public VectorNode {
1177  public:
VectorRearrangeNode(Node * vec1,Node * shuffle)1178   VectorRearrangeNode(Node* vec1, Node* shuffle)
1179     : VectorNode(vec1, shuffle, vec1->bottom_type()->is_vect()) {
1180     // assert(mask->is_VectorMask(), "VectorBlendNode requires that third argument be a mask");
1181   }
1182 
1183   virtual int Opcode() const;
vec1() const1184   Node* vec1() const { return in(1); }
vec_shuffle() const1185   Node* vec_shuffle() const { return in(2); }
1186 };
1187 
1188 class VectorLoadShuffleNode : public VectorNode {
1189  public:
VectorLoadShuffleNode(Node * in,const TypeVect * vt)1190   VectorLoadShuffleNode(Node* in, const TypeVect* vt)
1191     : VectorNode(in, vt) {
1192     assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be BYTE");
1193   }
1194 
GetOutShuffleSize() const1195   int GetOutShuffleSize() const { return type2aelembytes(vect_type()->element_basic_type()); }
1196   virtual int Opcode() const;
1197 };
1198 
1199 class VectorLoadMaskNode : public VectorNode {
1200  public:
VectorLoadMaskNode(Node * in,const TypeVect * vt)1201   VectorLoadMaskNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {
1202     assert(in->bottom_type()->is_vect()->element_basic_type() == T_BOOLEAN, "must be boolean");
1203   }
1204 
1205   virtual int Opcode() const;
1206   virtual Node* Identity(PhaseGVN* phase);
1207 };
1208 
1209 class VectorStoreMaskNode : public VectorNode {
1210  protected:
VectorStoreMaskNode(Node * in1,ConINode * in2,const TypeVect * vt)1211   VectorStoreMaskNode(Node* in1, ConINode* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
1212 
1213  public:
1214   virtual int Opcode() const;
1215   virtual Node* Identity(PhaseGVN* phase);
1216 
1217   static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem);
1218 };
1219 
1220 // This is intended for use as a simple reinterpret node that has no cast.
1221 class VectorReinterpretNode : public VectorNode {
1222  private:
1223   const TypeVect* _src_vt;
1224  protected:
size_of() const1225   uint size_of() const { return sizeof(*this); }
1226  public:
VectorReinterpretNode(Node * in,const TypeVect * src_vt,const TypeVect * dst_vt)1227   VectorReinterpretNode(Node* in, const TypeVect* src_vt, const TypeVect* dst_vt)
1228       : VectorNode(in, dst_vt), _src_vt(src_vt) { }
1229 
hash() const1230   virtual uint hash() const { return VectorNode::hash() + _src_vt->hash(); }
cmp(const Node & n) const1231   virtual bool cmp( const Node &n ) const {
1232     return VectorNode::cmp(n) && !Type::cmp(_src_vt,((VectorReinterpretNode&)n)._src_vt);
1233   }
1234   virtual Node* Identity(PhaseGVN* phase);
1235 
1236   virtual int Opcode() const;
1237 };
1238 
1239 class VectorCastNode : public VectorNode {
1240  public:
VectorCastNode(Node * in,const TypeVect * vt)1241   VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
1242   virtual int Opcode() const;
1243 
1244   static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen);
1245   static int  opcode(BasicType bt);
1246   static bool implemented(BasicType bt, uint vlen);
1247 
1248   virtual Node* Identity(PhaseGVN* phase);
1249 };
1250 
1251 class VectorCastB2XNode : public VectorCastNode {
1252  public:
VectorCastB2XNode(Node * in,const TypeVect * vt)1253   VectorCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1254     assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte");
1255   }
1256   virtual int Opcode() const;
1257 };
1258 
1259 class VectorCastS2XNode : public VectorCastNode {
1260  public:
VectorCastS2XNode(Node * in,const TypeVect * vt)1261   VectorCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1262     assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short");
1263   }
1264   virtual int Opcode() const;
1265 };
1266 
1267 class VectorCastI2XNode : public VectorCastNode {
1268  public:
VectorCastI2XNode(Node * in,const TypeVect * vt)1269   VectorCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1270     assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int");
1271   }
1272   virtual int Opcode() const;
1273 };
1274 
1275 class VectorCastL2XNode : public VectorCastNode {
1276  public:
VectorCastL2XNode(Node * in,const TypeVect * vt)1277   VectorCastL2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1278     assert(in->bottom_type()->is_vect()->element_basic_type() == T_LONG, "must be long");
1279   }
1280   virtual int Opcode() const;
1281 };
1282 
1283 class VectorCastF2XNode : public VectorCastNode {
1284  public:
VectorCastF2XNode(Node * in,const TypeVect * vt)1285   VectorCastF2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1286     assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float");
1287   }
1288   virtual int Opcode() const;
1289 };
1290 
1291 class VectorCastD2XNode : public VectorCastNode {
1292  public:
VectorCastD2XNode(Node * in,const TypeVect * vt)1293   VectorCastD2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
1294     assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double");
1295   }
1296   virtual int Opcode() const;
1297 };
1298 
1299 class VectorInsertNode : public VectorNode {
1300  public:
VectorInsertNode(Node * vsrc,Node * new_val,ConINode * pos,const TypeVect * vt)1301   VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) {
1302    assert(pos->get_int() >= 0, "positive constants");
1303    assert(pos->get_int() < (int)vt->length(), "index must be less than vector length");
1304    assert(Type::cmp(vt, vsrc->bottom_type()) == 0, "input and output must be same type");
1305   }
1306   virtual int Opcode() const;
pos() const1307   uint pos() const { return in(3)->get_int(); }
1308 
1309   static Node* make(Node* vec, Node* new_val, int position);
1310 };
1311 
1312 class VectorBoxNode : public Node {
1313  private:
1314   const TypeInstPtr* const _box_type;
1315   const TypeVect*    const _vec_type;
1316  public:
1317   enum {
1318      Box   = 1,
1319      Value = 2
1320   };
VectorBoxNode(Compile * C,Node * box,Node * val,const TypeInstPtr * box_type,const TypeVect * vt)1321   VectorBoxNode(Compile* C, Node* box, Node* val,
1322                 const TypeInstPtr* box_type, const TypeVect* vt)
1323     : Node(NULL, box, val), _box_type(box_type), _vec_type(vt) {
1324     init_flags(Flag_is_macro);
1325     C->add_macro_node(this);
1326   }
1327 
box_type() const1328   const  TypeInstPtr* box_type() const { assert(_box_type != NULL, ""); return _box_type; };
vec_type() const1329   const  TypeVect*    vec_type() const { assert(_vec_type != NULL, ""); return _vec_type; };
1330 
1331   virtual int Opcode() const;
bottom_type() const1332   virtual const Type* bottom_type() const { return _box_type; }
ideal_reg() const1333   virtual       uint  ideal_reg() const { return box_type()->ideal_reg(); }
size_of() const1334   virtual       uint  size_of() const { return sizeof(*this); }
1335 
1336   static const TypeFunc* vec_box_type(const TypeInstPtr* box_type);
1337 };
1338 
1339 class VectorBoxAllocateNode : public CallStaticJavaNode {
1340  public:
VectorBoxAllocateNode(Compile * C,const TypeInstPtr * vbox_type)1341   VectorBoxAllocateNode(Compile* C, const TypeInstPtr* vbox_type)
1342     : CallStaticJavaNode(C, VectorBoxNode::vec_box_type(vbox_type), NULL, NULL, -1) {
1343     init_flags(Flag_is_macro);
1344     C->add_macro_node(this);
1345   }
1346 
1347   virtual int Opcode() const;
1348 #ifndef PRODUCT
1349   virtual void dump_spec(outputStream *st) const;
1350 #endif // !PRODUCT
1351 };
1352 
1353 class VectorUnboxNode : public VectorNode {
1354  private:
1355   bool _shuffle_to_vector;
1356  protected:
size_of() const1357   uint size_of() const { return sizeof(*this); }
1358  public:
VectorUnboxNode(Compile * C,const TypeVect * vec_type,Node * obj,Node * mem,bool shuffle_to_vector)1359   VectorUnboxNode(Compile* C, const TypeVect* vec_type, Node* obj, Node* mem, bool shuffle_to_vector)
1360     : VectorNode(mem, obj, vec_type) {
1361     _shuffle_to_vector = shuffle_to_vector;
1362     init_flags(Flag_is_macro);
1363     C->add_macro_node(this);
1364   }
1365 
1366   virtual int Opcode() const;
obj() const1367   Node* obj() const { return in(2); }
mem() const1368   Node* mem() const { return in(1); }
1369   virtual Node* Identity(PhaseGVN* phase);
1370   Node* Ideal(PhaseGVN* phase, bool can_reshape);
is_shuffle_to_vector()1371   bool is_shuffle_to_vector() { return _shuffle_to_vector; }
1372 };
1373 
1374 class RotateRightVNode : public VectorNode {
1375 public:
RotateRightVNode(Node * in1,Node * in2,const TypeVect * vt)1376   RotateRightVNode(Node* in1, Node* in2, const TypeVect* vt)
1377   : VectorNode(in1, in2, vt) {}
1378 
1379   virtual int Opcode() const;
1380   Node* Ideal(PhaseGVN* phase, bool can_reshape);
1381 };
1382 
1383 class RotateLeftVNode : public VectorNode {
1384 public:
RotateLeftVNode(Node * in1,Node * in2,const TypeVect * vt)1385   RotateLeftVNode(Node* in1, Node* in2, const TypeVect* vt)
1386   : VectorNode(in1, in2, vt) {}
1387 
1388   virtual int Opcode() const;
1389   Node* Ideal(PhaseGVN* phase, bool can_reshape);
1390 };
1391 
1392 #endif // SHARE_OPTO_VECTORNODE_HPP
1393